Bug 1477252 - Check whether editor is destroyed before using it; review=nchevobbe. r=nchevobbe a=jcristau DEVEDITION_64_0b7_BUILD1 DEVEDITION_64_0b7_RELEASE FENNEC_64_0b7_BUILD1 FENNEC_64_0b7_RELEASE FIREFOX_64_0b7_BUILD1 FIREFOX_64_0b7_RELEASE
authorJan Odvarko <odvarko@gmail.com>
Fri, 19 Oct 2018 14:21:23 +0000
changeset 498333 013f4e5f93fdcb87ee41e26057e56e19f80428d7
parent 498332 f9639e65bc99f3a2ced65aab2ec17d1f2095734a
child 498334 eda3f99c273cdcec7800c1448012ffa338ef4a46
push id10110
push usernerli@mozilla.com
push dateMon, 05 Nov 2018 16:46:54 +0000
treeherdermozilla-beta@013f4e5f93fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnchevobbe, jcristau
bugs1477252
milestone64.0
Bug 1477252 - Check whether editor is destroyed before using it; review=nchevobbe. r=nchevobbe a=jcristau Differential Revision: https://phabricator.services.mozilla.com/D9251
devtools/client/netmonitor/src/components/SourceEditor.js
devtools/client/sourceeditor/editor.js
--- a/devtools/client/netmonitor/src/components/SourceEditor.js
+++ b/devtools/client/netmonitor/src/components/SourceEditor.js
@@ -33,43 +33,56 @@ class SourceEditor extends Component {
       mode: null, // Disable auto syntax detection, but then we set mode asynchronously
       readOnly: true,
       theme: "mozilla",
       value: text,
     });
 
     // Delay to CodeMirror initialization content to prevent UI freezing
     this.editorTimeout = setTimeout(() => {
+      this.editorTimeout = null;
       this.editor.appendToLocalElement(this.refs.editorElement);
+
       // CodeMirror's setMode() (syntax highlight) is the performance bottleneck when
       // processing large content, so we enable it asynchronously within the setTimeout
       // to avoid UI blocking. (rendering source code -> drawing syntax highlight)
       this.editorSetModeTimeout = setTimeout(() => {
+        this.editorSetModeTimeout = null;
         this.editor.setMode(mode);
       });
     });
   }
 
   shouldComponentUpdate(nextProps) {
     return nextProps.mode !== this.props.mode || nextProps.text !== this.props.text;
   }
 
   componentDidUpdate(prevProps) {
     const { mode, text } = this.props;
 
+    // Bail out if the editor has been destroyed in the meantime.
+    if (this.editor.isDestroyed()) {
+      return;
+    }
+
     if (prevProps.text !== text) {
       // Reset the existed 'mode' attribute in order to make setText() process faster
       // to prevent drawing unnecessary syntax highlight.
       this.editor.setMode(null);
       this.editor.setText(text);
 
+      if (this.editorSetModeTimeout) {
+        clearTimeout(this.editorSetModeTimeout);
+      }
+
       // CodeMirror's setMode() (syntax highlight) is the performance bottleneck when
       // processing large content, so we enable it asynchronously within the setTimeout
       // to avoid UI blocking. (rendering source code -> drawing syntax highlight)
       this.editorSetModeTimeout = setTimeout(() => {
+        this.editorSetModeTimeout = null;
         this.editor.setMode(mode);
       });
     }
   }
 
   componentWillUnmount() {
     clearTimeout(this.editorTimeout);
     clearTimeout(this.editorSetModeTimeout);
--- a/devtools/client/sourceeditor/editor.js
+++ b/devtools/client/sourceeditor/editor.js
@@ -1344,16 +1344,20 @@ Editor.prototype = {
         funcs[name](ctx);
         return;
       }
 
       this[name] = funcs[name].bind(null, ctx);
     });
   },
 
+  isDestroyed: function() {
+    return !editors.get(this);
+  },
+
   destroy: function() {
     this.container = null;
     this.config = null;
     this.version = null;
 
     if (this._prefObserver) {
       this._prefObserver.off(TAB_SIZE, this.reloadPreferences);
       this._prefObserver.off(EXPAND_TAB, this.reloadPreferences);