diff --git a/.changeset/lovely-pumas-fix.md b/.changeset/lovely-pumas-fix.md new file mode 100644 index 0000000000..a54afa6466 --- /dev/null +++ b/.changeset/lovely-pumas-fix.md @@ -0,0 +1,5 @@ +--- +'slate-react': patch +--- + +Revert #4876 & #4910 to restore original decorations behavior diff --git a/packages/slate-react/src/components/editable.tsx b/packages/slate-react/src/components/editable.tsx index 31a7061126..3d22cfa80b 100644 --- a/packages/slate-react/src/components/editable.tsx +++ b/packages/slate-react/src/components/editable.tsx @@ -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 && diff --git a/packages/slate-react/src/hooks/use-children.tsx b/packages/slate-react/src/hooks/use-children.tsx index b7ef712306..4153e71c32 100644 --- a/packages/slate-react/src/hooks/use-children.tsx +++ b/packages/slate-react/src/hooks/use-children.tsx @@ -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((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( diff --git a/packages/slate-react/test/index.spec.tsx b/packages/slate-react/test/index.spec.tsx index 0cd5d12e68..6ac7c43d03 100644 --- a/packages/slate-react/test/index.spec.tsx +++ b/packages/slate-react/test/index.spec.tsx @@ -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(entry => []) - - let el: ReactTestRenderer - - act(() => { - el = create( - {}}> - - , - { 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(() => []) - - const renderElement = jest.fn( - DefaultElement - ) - - const onChange = jest.fn() - - let el: ReactTestRenderer - - act(() => { - el = create( - - - , - { 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( - - - - ) - }) - - 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(([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(DefaultLeaf) - const onChange = jest.fn() - let el: ReactTestRenderer - - act(() => { - el = create( - - - , - { 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()) diff --git a/yarn.lock b/yarn.lock index 78ea39b691..9fb28f9121 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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" @@ -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 @@ -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" @@ -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 @@ -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: @@ -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