Skip to content

Commit

Permalink
Fix stale decorations (ianstormtaylor#4876)
Browse files Browse the repository at this point in the history
* test changes

* fix decoration not updating

* Add changeset

* Fix lint issues

* Tests with earlier version of Node.js

* Bump node version on CI

The base typescript config uses ESNext as target, so presumably the
latest node should be used.

Co-authored-by: Dylan Schiemann <dylan@dojotoolkit.org>
  • Loading branch information
2 people authored and DougReeder committed Apr 3, 2022
1 parent dc268bc commit 08e5364
Show file tree
Hide file tree
Showing 11 changed files with 357 additions and 87 deletions.
5 changes: 5 additions & 0 deletions .changeset/twelve-kings-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'slate-react': patch
---

Fix decorations not getting applied for children unless parent changes
7 changes: 7 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
const config = {
testMatch: ['<rootDir>/packages/slate-react/test/**/*.{js,ts,tsx,jsx}'],
preset: 'ts-jest',
globals: {
'ts-jest': {
tsconfig: '<rootDir>/packages/slate-react/tsconfig.json',
},
},
testEnvironment: 'jsdom',
}

module.exports = config
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
"slate-hyperscript": "workspace:*",
"slate-react": "workspace:*",
"source-map-loader": "^0.2.4",
"ts-jest": "^27.1.3",
"typescript": "3.9.7"
},
"simple-git-hooks": {
Expand Down
4 changes: 3 additions & 1 deletion packages/slate-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
},
"devDependencies": {
"@babel/runtime": "^7.7.4",
"@types/jest": "^27.4.1",
"@types/jsdom": "^16.2.14",
"@types/react": "^16.9.13",
"@types/react-dom": "^16.9.4",
"jsdom": "^16.6.0",
"@types/react-test-renderer": "^16.8.0",
"react": ">=16.8.0",
"react-dom": ">=16.8.0",
"react-test-renderer": ">=16.8.0",
Expand Down
4 changes: 3 additions & 1 deletion packages/slate-react/src/components/editable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,9 @@ export const Editable = (props: EditableProps) => {
}
}, [scheduleOnDOMSelectionChange])

const decorations = decorate([editor, []])
const decorations = [...Node.nodes(editor)].flatMap(([n, p]) =>
decorate([n, p])
)

if (
placeholder &&
Expand Down
2 changes: 1 addition & 1 deletion packages/slate-react/src/custom-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ declare module 'slate' {
interface CustomTypes {
Editor: ReactEditor
Text: BaseText & {
placeholder: string
placeholder?: string
}
Range: BaseRange & {
placeholder?: string
Expand Down
9 changes: 1 addition & 8 deletions packages/slate-react/src/hooks/use-children.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,8 @@ 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])

for (const dec of decorations) {
const d = Range.intersection(dec, range)

if (d) {
ds.push(d)
}
}
const ds = decorations.filter(dec => Range.intersection(dec, range))

if (Element.isElement(n)) {
children.push(
Expand Down
46 changes: 0 additions & 46 deletions packages/slate-react/test/index.js

This file was deleted.

101 changes: 101 additions & 0 deletions packages/slate-react/test/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react'
import { createEditor, NodeEntry, Range } from 'slate'
import { create, act, ReactTestRenderer } from 'react-test-renderer'
import {
Slate,
withReact,
DefaultEditable,
RenderElementProps,
DefaultElement,
} from '../src'

describe('slate-react', () => {
describe('Editable', () => {
describe('decorate', () => {
const createNodeMock = () => ({
ownerDocument: global.document,
getRootNode: () => global.document,
})

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)
})
})
})
})
4 changes: 4 additions & 0 deletions packages/slate-react/test/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../../../config/typescript/tsconfig.json",
"references": [{ "path": "../" }]
}
Loading

0 comments on commit 08e5364

Please sign in to comment.