mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-17 12:41:44 +02:00
fix undo rendering and leaf rendering logic
This commit is contained in:
@@ -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}
|
||||||
>
|
>
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user