Bug 1443923 - part9: Listen to "customelementdefined" in inspector actor;r=bgrins draft
authorJulian Descottes <jdescottes@mozilla.com>
Fri, 20 Jul 2018 11:06:42 +0200
changeset 821453 e40283f9d621fe47af20391250302f5a08f56a24
parent 821452 7c7ec0aebcfdf5e1c7a13837ea9100c8b680d1d5
push id117098
push userjdescottes@mozilla.com
push dateMon, 23 Jul 2018 10:19:47 +0000
reviewersbgrins
bugs1443923
milestone63.0a1
Bug 1443923 - part9: Listen to "customelementdefined" in inspector actor;r=bgrins MozReview-Commit-ID: 5VLwHGaWJLu
devtools/server/actors/inspector/custom-element-watcher.js
devtools/server/actors/inspector/walker.js
--- a/devtools/server/actors/inspector/custom-element-watcher.js
+++ b/devtools/server/actors/inspector/custom-element-watcher.js
@@ -10,34 +10,42 @@ const EventEmitter = require("devtools/s
 /**
  * The CustomElementWatcher can be used to be notified if a custom element definition
  * is created for a node.
  *
  * When a custom element is defined for a monitored name, an "element-defined" event is
  * fired with the Set of impacted node actors as argument.
  */
 class CustomElementWatcher extends EventEmitter {
-  constructor() {
+  constructor(chromeEventHandler) {
     super();
+    this.chromeEventHandler = chromeEventHandler;
+
+    this._onCustomElementDefined = this._onCustomElementDefined.bind(this);
+    this.chromeEventHandler.addEventListener("customelementdefined",
+      this._onCustomElementDefined);
+
     /**
      * Each window keeps its own custom element registry, all of them are watched
      * separately. The struture of the watchedRegistries is as follows
      *
      * WeakMap(
      *   registry -> Map (
      *     name -> Set(NodeActors)
      *   )
      * )
      */
     this.watchedRegistries = new WeakMap();
   }
 
   destroy() {
     this.destroyed = true;
     this.watchedRegistries = null;
+    this.chromeEventHandler.removeEventListener("customelementdefined",
+      this.onCustomElementDefined);
   }
 
   /**
    * Watch for custom element definitions matching the name of the provided NodeActor.
    */
   manageNode(nodeActor) {
     if (!this._shouldWatchDefinition(nodeActor)) {
       return;
@@ -46,18 +54,16 @@ class CustomElementWatcher extends Event
     const registry = nodeActor.rawNode.ownerGlobal.customElements;
     if (!this.watchedRegistries.has(registry)) {
       this.watchedRegistries.set(registry, new Map());
     }
     const registryMap = this.watchedRegistries.get(registry);
 
     const name = nodeActor.rawNode.localName;
     if (!registryMap.has(name)) {
-      // Add a listener to be notified if this name gets a custom element definition.
-      registry.whenDefined(name).then(() => this._onCustomElementDefined(name, registry));
       // Create a new entry in the Map for this name.
       registryMap.set(name, new Set());
     }
     registryMap.get(name).add(nodeActor);
   }
 
   /**
    * Stop watching the provided NodeActor.
@@ -85,21 +91,26 @@ class CustomElementWatcher extends Event
     const namespaceURI = doc.documentElement.namespaceURI;
     const name = nodeActor.rawNode.localName;
     const isValidName = InspectorUtils.isCustomElementName(name, namespaceURI);
 
     const customElements = doc.defaultView.customElements;
     return isValidName && !customElements.get(name);
   }
 
-  _onCustomElementDefined(name, registry) {
+  _onCustomElementDefined(event) {
     if (this.destroyed) {
       return;
     }
 
+    const doc = event.target;
+    const registry = doc.defaultView.customElements;
     const registryMap = this.watchedRegistries.get(registry);
+
+    const name = event.detail;
     const nodeActors = registryMap.get(name);
+
     this.emit("element-defined", nodeActors);
     registryMap.delete(name);
   }
 }
 
 exports.CustomElementWatcher = CustomElementWatcher;
--- a/devtools/server/actors/inspector/walker.js
+++ b/devtools/server/actors/inspector/walker.js
@@ -124,17 +124,17 @@ var WalkerActor = protocol.ActorClassWit
   initialize: function(conn, targetActor, options) {
     protocol.Actor.prototype.initialize.call(this, conn);
     this.targetActor = targetActor;
     this.rootWin = targetActor.window;
     this.rootDoc = this.rootWin.document;
     this._refMap = new Map();
     this._pendingMutations = [];
     this._activePseudoClassLocks = new Set();
-    this.customElementWatcher = new CustomElementWatcher();
+    this.customElementWatcher = new CustomElementWatcher(targetActor.chromeEventHandler);
 
     this.showAllAnonymousContent = options.showAllAnonymousContent;
 
     this.walkerSearch = new WalkerSearch(this);
 
     // Nodes which have been removed from the client's known
     // ownership tree are considered "orphaned", and stored in
     // this set.