Bug 1300811 - Part 2 - Add support for TabContext to android r?mixedpuppy draft
authorMatthew Wein <mwein@mozilla.com>
Mon, 12 Jun 2017 21:34:30 -0400
changeset 593752 9ccc5d5fc954519dbdb342420535e1c37253dc87
parent 593751 d1d577cb9ba7deffeb052b3e4eeb74eb48bff944
child 593753 194e89c930125dcb79f9307fff6ccd345cb14009
push id63787
push usermwein@mozilla.com
push dateWed, 14 Jun 2017 03:28:10 +0000
reviewersmixedpuppy
bugs1300811
milestone56.0a1
Bug 1300811 - Part 2 - Add support for TabContext to android r?mixedpuppy MozReview-Commit-ID: 9eetOAUs61R
mobile/android/components/extensions/ext-android.js
mobile/android/components/extensions/ext-utils.js
--- a/mobile/android/components/extensions/ext-android.js
+++ b/mobile/android/components/extensions/ext-android.js
@@ -1,10 +1,13 @@
 "use strict";
 
+XPCOMUtils.defineLazyModuleGetter(global, "EventEmitter",
+                                  "resource://gre/modules/EventEmitter.jsm");
+
 // This function is pretty tightly tied to Extension.jsm.
 // Its job is to fill in the |tab| property of the sender.
 function getSender(extension, target, sender) {
   let tabId;
   if ("tabId" in sender) {
     // The message came from a privileged extension page running in a tab. In
     // that case, it should include a tabId property (which is filled in by the
     // page-open listener below).
--- a/mobile/android/components/extensions/ext-utils.js
+++ b/mobile/android/components/extensions/ext-utils.js
@@ -425,16 +425,68 @@ class Tab extends TabBase {
     return this.browser.ownerGlobal;
   }
 
   get windowId() {
     return windowTracker.getId(this.window);
   }
 }
 
+// Manages tab-specific context data and dispatches tab select and close events.
+class TabContext {
+  constructor(getDefaults, extension) {
+    this.extension = extension;
+    this.getDefaults = getDefaults;
+    this.tabData = new Map();
+
+    GlobalEventDispatcher.registerListener(this, [
+      "Tab:Selected",
+      "Tab:Closed",
+    ]);
+
+    EventEmitter.decorate(this);
+  }
+
+  get(tabId) {
+    if (!this.tabData.has(tabId)) {
+      this.tabData.set(tabId, this.getDefaults());
+    }
+
+    return this.tabData.get(tabId);
+  }
+
+  clear(tabId) {
+    this.tabData.delete(tabId);
+  }
+
+  /**
+   * Required by the GlobalEventDispatcher module. This event will get
+   * called whenever one of the registered listeners fires.
+   * @param {string} event The event which fired.
+   * @param {object} data Information about the event which fired.
+   */
+  onEvent(event, data) {
+    switch (event) {
+      case "Tab:Selected":
+        this.emit("tab-selected", data.id);
+        break;
+      case "Tab:Closed":
+        this.emit("tab-closed", data.tabId);
+        break;
+    }
+  }
+
+  shutdown() {
+    GlobalEventDispatcher.unregisterListener(this, [
+      "Tab:Selected",
+      "Tab:Closed",
+    ]);
+  }
+}
+
 class Window extends WindowBase {
   get focused() {
     return this.window.document.hasFocus();
   }
 
   get top() {
     return this.window.screenY;
   }
@@ -471,17 +523,17 @@ class Window extends WindowBase {
     let {tabManager} = this.extension;
 
     for (let nativeTab of this.window.BrowserApp.tabs) {
       yield tabManager.getWrapper(nativeTab);
     }
   }
 }
 
-Object.assign(global, {Tab, Window});
+Object.assign(global, {Tab, TabContext, Window});
 
 class TabManager extends TabManagerBase {
   get(tabId, default_ = undefined) {
     let nativeTab = tabTracker.getTab(tabId, default_);
 
     if (nativeTab) {
       return this.getWrapper(nativeTab);
     }