Bug 1414597: Fix devtools inspector load events to correctly listen to XUL documents. r=ochameau
authorBrad Werth <bwerth@mozilla.com>
Mon, 10 Sep 2018 19:20:01 +0000
changeset 435513 8b1229ed285023b775f076caf9213424a9590e80
parent 435512 bb4d2474abdf4f1c54115250a7a71545f80137c1
child 435514 a08e6206cd972abb5a2569842d71291d220abc7d
push id69029
push userbwerth@mozilla.com
push dateMon, 10 Sep 2018 19:21:48 +0000
treeherderautoland@8b1229ed2850 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersochameau
bugs1414597
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1414597: Fix devtools inspector load events to correctly listen to XUL documents. r=ochameau Differential Revision: https://phabricator.services.mozilla.com/D4495
devtools/server/actors/inspector/inspector.js
devtools/server/actors/inspector/walker.js
--- a/devtools/server/actors/inspector/inspector.js
+++ b/devtools/server/actors/inspector/inspector.js
@@ -101,31 +101,35 @@ exports.InspectorActor = protocol.ActorC
   getWalker: function(options = {}) {
     if (this._walkerPromise) {
       return this._walkerPromise;
     }
 
     const deferred = defer();
     this._walkerPromise = deferred.promise;
 
+    const isXULDocument =
+      this.targetActor.window.document.documentElement.namespaceURI === XUL_NS;
+    const loadEvent = isXULDocument ? "load" : "DOMContentLoaded";
+
     const window = this.window;
     const domReady = () => {
       const targetActor = this.targetActor;
-      window.removeEventListener("DOMContentLoaded", domReady, true);
+      window.removeEventListener(loadEvent, domReady, true);
       this.walker = WalkerActor(this.conn, targetActor, options);
       this.manage(this.walker);
       this.walker.once("destroyed", () => {
         this._walkerPromise = null;
         this._pageStylePromise = null;
       });
       deferred.resolve(this.walker);
     };
 
     if (window.document.readyState === "loading") {
-      window.addEventListener("DOMContentLoaded", domReady, true);
+      window.addEventListener(loadEvent, domReady, true);
     } else {
       domReady();
     }
 
     return this._walkerPromise;
   },
 
   getPageStyle: function() {
--- a/devtools/server/actors/inspector/walker.js
+++ b/devtools/server/actors/inspector/walker.js
@@ -37,16 +37,18 @@ loader.lazyRequireGetter(this, "NodeList
 loader.lazyRequireGetter(this, "LayoutActor", "devtools/server/actors/layout", true);
 loader.lazyRequireGetter(this, "getLayoutChangesObserver", "devtools/server/actors/reflow", true);
 loader.lazyRequireGetter(this, "releaseLayoutChangesObserver", "devtools/server/actors/reflow", true);
 loader.lazyRequireGetter(this, "WalkerSearch", "devtools/server/actors/utils/walker-search", true);
 
 loader.lazyServiceGetter(this, "eventListenerService",
   "@mozilla.org/eventlistenerservice;1", "nsIEventListenerService");
 
+loader.lazyRequireGetter(this, "ChromeUtils");
+
 // Minimum delay between two "new-mutations" events.
 const MUTATIONS_THROTTLING_DELAY = 100;
 // List of mutation types that should -not- be throttled.
 const IMMEDIATE_MUTATIONS = [
   "documentUnload",
   "frameLoad",
   "newRoot",
   "pseudoClassLock",
@@ -1839,17 +1841,25 @@ var WalkerActor = protocol.ActorClassWit
       target: actor.actorID,
     };
     this.queueMutation(mutation);
   },
 
   onFrameLoad: function({ window, isTopLevel }) {
     const { readyState } = window.document;
     if (readyState != "interactive" && readyState != "complete") {
-      window.addEventListener("DOMContentLoaded",
+      // The document is not loaded, so we want to register to fire again when the
+      // DOM has been loaded. To do this, we need to know if this is a XUL document.
+      // We listen for "DOMContentLoaded" on HTML documents, but XUL documents don't
+      // fire this event, so we fallback to the "load" event for XUL. Unfortunately,
+      // since the document isn't loaded yet, we can't check its namespace declaration
+      // to determine if it is XUL. Instead, we use ChromeUtils to see if the document
+      // object class is XULDocument.
+      const isXULDocument = (ChromeUtils.getClassName(window.document) == "XULDocument");
+      window.addEventListener(isXULDocument ? "load" : "DOMContentLoaded",
         this.onFrameLoad.bind(this, { window, isTopLevel }),
         { once: true });
       return;
     }
     if (isTopLevel) {
       // If we initialize the inspector while the document is loading,
       // we may already have a root document set in the constructor.
       if (this.rootDoc && !Cu.isDeadWrapper(this.rootDoc) &&