1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-17 20:51:20 +02:00

fix undo rendering and leaf rendering logic

This commit is contained in:
Ian Storm Taylor
2016-07-25 18:42:31 -07:00
parent 6637a8ab64
commit cdebdb1400
3 changed files with 39 additions and 37 deletions

View File

@@ -22,6 +22,18 @@ class Leaf extends React.Component {
text: React.PropTypes.string.isRequired text: React.PropTypes.string.isRequired
}; };
/**
* Constructor.
*
* @param {Object} props
*/
constructor(props) {
super(props)
this.tmp = {}
this.tmp.renders = 0
}
/** /**
* Should component update? * Should component update?
* *
@@ -35,8 +47,9 @@ class Leaf extends React.Component {
if ( if (
props.index != this.props.index || props.index != this.props.index ||
props.text != this.props.text || props.marks != this.props.marks ||
props.marks != this.props.marks props.renderMark != this.props.renderMark ||
props.text != this.props.text
) { ) {
return true return true
} }
@@ -136,8 +149,15 @@ class Leaf extends React.Component {
return memo return memo
}, {}) }, {})
// Increment the renders key, which forces a re-render whenever this
// component is told it should update. This is required because "native"
// renders where we don't update the leaves cause React's internal state to
// get out of sync, causing it to not realize the DOM needs updating.
this.tmp.renders++
return ( return (
<span <span
key={this.tmp.renders}
data-offset-key={offsetKey} data-offset-key={offsetKey}
style={style} style={style}
> >

View File

@@ -338,7 +338,13 @@ class Transform extends new Record(DEFAULT_PROPERTIES) {
// Return the previous state, with the updated history. // Return the previous state, with the updated history.
let { document, selection } = previous let { document, selection } = previous
history = history.merge({ undos, redos }) history = history.merge({ undos, redos })
state = state.merge({ document, selection, history }) state = state.merge({
document,
selection,
history,
isNative: false
})
return state return state
} }
@@ -368,7 +374,13 @@ class Transform extends new Record(DEFAULT_PROPERTIES) {
// Return the next state, with the updated history. // Return the next state, with the updated history.
let { document, selection } = next let { document, selection } = next
history = history.merge({ undos, redos }) history = history.merge({ undos, redos })
state = state.merge({ document, selection, history }) state = state.merge({
document,
selection,
history,
isNative: false
})
return state return state
} }

View File

@@ -31,21 +31,6 @@ function Plugin(options = {}) {
*/ */
class DEFAULT_BLOCK extends React.Component { class DEFAULT_BLOCK extends React.Component {
static propTypes = {
attributes: React.PropTypes.object.isRequired,
children: React.PropTypes.any.isRequired,
node: React.PropTypes.object.isRequired,
state: React.PropTypes.object.isRequired
};
shouldComponentUpdate = (props, state) => {
return (
props.node != this.props.node ||
props.state.selection.hasEdgeIn(props.node)
)
}
render = () => { render = () => {
const { attributes, children } = this.props const { attributes, children } = this.props
return ( return (
@@ -80,26 +65,10 @@ function Plugin(options = {}) {
*/ */
class DEFAULT_INLINE extends React.Component { class DEFAULT_INLINE extends React.Component {
static propTypes = {
attributes: React.PropTypes.object.isRequired,
children: React.PropTypes.any.isRequired,
node: React.PropTypes.object.isRequired,
state: React.PropTypes.object.isRequired
};
shouldComponentUpdate = (props, state) => {
return (
props.node != this.props.node ||
props.state.selection.hasEdgeIn(props.node)
)
}
render = () => { render = () => {
const { attributes, children } = this.props const { attributes, children } = this.props
return <span {...attributes}>{children}</span> return <span {...attributes}>{children}</span>
} }
} }
/** /**
@@ -123,11 +92,12 @@ function Plugin(options = {}) {
const resolved = editor.resolveState(synthetic) const resolved = editor.resolveState(synthetic)
// We do not have to re-render if the current selection is collapsed, the // We do not have to re-render if the current selection is collapsed, the
// current node is not empty, and the new state has the same decorations // current node is not empty, there are no marks on the cursor, and the
// as the current one. // new state has the same decorations as the current one.
const isNative = ( const isNative = (
state.isCollapsed && state.isCollapsed &&
state.startText.text != '' && state.startText.text != '' &&
state.cursorMarks == null &&
resolved.equals(synthetic) resolved.equals(synthetic)
) )