Unmount cleanly

This commit is contained in:
Chi Vinh Le
2018-03-25 01:58:35 +01:00
parent 939df89842
commit 69e194f648
3 changed files with 39 additions and 13 deletions
@@ -40,6 +40,9 @@ class Editor extends React.Component {
}
});
}
if (this.props.isReply) {
this.ref.focus();
}
}
componentWillUnmount() {
@@ -66,6 +69,7 @@ class Editor extends React.Component {
value={this.getHTML()}
disabled={disabled}
placeholder={placeholder}
ref={this.handleRef}
buttons={[
<Bold key="bold" title={t('talk-plugin-rich-text.format_bold')}>
<Icon className={styles.icon} name="format_bold" />
@@ -12,6 +12,7 @@ import {
cloneNodeAndRange,
replaceNodeChildren,
selectEndOfNode,
isSelectionInside,
} from './lib/dom';
import API from './lib/api';
import Undo from './lib/undo';
@@ -31,6 +32,11 @@ class RTE extends React.Component {
// Refs to the buttons.
buttonsRef = {};
// Export this for parent components.
focus = () => this.ref.htmlEl.focus();
unmounted = false;
// Should be called on every change to feed
// our Undo stack. We save the innerHTML and if available
// a copy of the contentEditable node and a copy of the range.
@@ -61,14 +67,16 @@ class RTE extends React.Component {
// Ref to react-contenteditable.
handleRef = ref => (
(this.ref = ref),
(this.api = new API(
this.ref.htmlEl,
this.handleChange,
() => this.undo.canUndo(),
() => this.undo.canRedo(),
this.handleUndo,
this.handleRedo
))
(this.api =
ref &&
new API(
this.ref.htmlEl,
this.handleChange,
() => this.undo.canUndo(),
() => this.undo.canRedo(),
this.handleUndo,
this.handleRedo
))
);
forEachButton(callback) {
@@ -80,9 +88,18 @@ class RTE extends React.Component {
if (props.value !== this.ref.htmlEl.innerHTML) {
this.undo.clear();
this.saveCheckpoint(props.value);
if (isSelectionInside(this.ref.htmlEl)) {
setTimeout(() => !this.unmounted && selectEndOfNode(this.ref.htmlEl));
}
}
}
componentWillUnmount() {
// Cancel pending stuff.
this.saveCheckpoint.cancel();
this.unmounted = true;
}
handleChange = () => {
this.handleSelectionChange();
this.props.onChange({
@@ -127,7 +144,7 @@ class RTE extends React.Component {
handleCut = () => {
// IE has issues not firing the onChange event.
if (bowser.msie) {
setTimeout(this.handleChange);
setTimeout(() => !this.unmounted && this.handleChange());
}
};
@@ -149,13 +166,13 @@ class RTE extends React.Component {
};
handleMouseUp = () => {
setTimeout(() => this.handleSelectionChange());
setTimeout(() => !this.unmounted && this.handleSelectionChange());
};
handleKeyDown = e => {
// IE has issues not firing the onChange event.
if (bowser.msie) {
setTimeout(this.handleChange);
setTimeout(() => !this.unmounted && this.handleChange);
}
// Undo Redo
@@ -188,7 +205,7 @@ class RTE extends React.Component {
handleKeyUp = () => {
// IE has issues not firing the onChange event.
if (bowser.msie) {
setTimeout(this.handleChange);
setTimeout(() => !this.unmounted && this.handleChange);
}
this.handleSelectionChange();
};
@@ -20,6 +20,11 @@ const createToggle = (
isActive = () => isActive.apply(this.props.api);
isDisabled = () => isDisabled.apply(this.props.api);
onEnter = (...args) => onEnter && onEnter.apply(this.props.api, args);
unmounted = false;
componentWillUnmount() {
this.unmounted = true;
}
formatToggle = () => {
this.execCommand();
@@ -29,7 +34,7 @@ const createToggle = (
this.props.api.focus();
this.formatToggle();
this.props.api.focus();
setTimeout(this.syncState);
setTimeout(() => !this.unmounted && this.syncState());
};
syncState = () => {