Bug 1336308: Part 5 - Add documentation for the Android-specific tab API helpers. r=aswan
authorKris Maglione <maglione.k@gmail.com>
Fri, 03 Feb 2017 15:29:46 -0800
changeset 340949 7129bea759429f6670c350db880431cfed385456
parent 340948 ed963c260aef0284094facd6cd14cca29a4fd1e4
child 340950 7b1c47953224fa956a138915fc998efcf6ac5226
push id86601
push usermaglione.k@gmail.com
push dateMon, 06 Feb 2017 20:27:30 +0000
treeherdermozilla-inbound@7129bea75942 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan
bugs1336308
milestone54.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 1336308: Part 5 - Add documentation for the Android-specific tab API helpers. r=aswan MozReview-Commit-ID: UN78mhAArC
browser/components/extensions/ext-utils.js
mobile/android/components/extensions/ext-utils.js
--- a/browser/components/extensions/ext-utils.js
+++ b/browser/components/extensions/ext-utils.js
@@ -101,16 +101,31 @@ class WindowTracker extends WindowTracke
     window.gBrowser.addTabsProgressListener(listener);
   }
 
   removeProgressListener(window, listener) {
     window.gBrowser.removeTabsProgressListener(listener);
   }
 }
 
+/**
+ * An event manager API provider which listens for a DOM event in any browser
+ * window, and calls the given listener function whenever an event is received.
+ * That listener function receives a `fire` object, which it can use to dispatch
+ * events to the extension, and a DOM event object.
+ *
+ * @param {BaseContext} context
+ *        The extension context which the event manager belongs to.
+ * @param {string} name
+ *        The API name of the event manager, e.g.,"runtime.onMessage".
+ * @param {string} event
+ *        The name of the DOM event to listen for.
+ * @param {function} listener
+ *        The listener function to call when a DOM event is received.
+ */
 global.WindowEventManager = class extends SingletonEventManager {
   constructor(context, name, event, listener) {
     super(context, name, fire => {
       let listener2 = listener.bind(null, fire);
 
       windowTracker.addListener(event, listener2);
       return () => {
         windowTracker.removeListener(event, listener2);
--- a/mobile/android/components/extensions/ext-utils.js
+++ b/mobile/android/components/extensions/ext-utils.js
@@ -23,27 +23,56 @@ global.GlobalEventDispatcher = EventDisp
 
 const BrowserStatusFilter = Components.Constructor(
   "@mozilla.org/appshell/component/browser-status-filter;1", "nsIWebProgress",
   "addProgressListener");
 
 let tabTracker;
 let windowTracker;
 
+/**
+ * A nsIWebProgressListener for a specific XUL browser, which delegates the
+ * events that it receives to a tab progress listener, and prepends the browser
+ * to their arguments list.
+ *
+ * @param {XULElement} browser
+ *        A XUL browser element.
+ * @param {object} listener
+ *        A tab progress listener object.
+ * @param {integer} flags
+ *        The web progress notification flags with which to filter events.
+ */
 class BrowserProgressListener {
   constructor(browser, listener, flags) {
     this.listener = listener;
     this.browser = browser;
     this.filter = new BrowserStatusFilter(this, flags);
+    this.browser.addProgressListener(this.filter, flags);
   }
 
+  /**
+   * Destroy the listener, and perform any necessary cleanup.
+   */
   destroy() {
+    this.browser.removeProgressListener(this.filter);
     this.filter.removeProgressListener(this);
   }
 
+  /**
+   * Calls the appropriate listener in the wrapped tab progress listener, with
+   * the wrapped XUL browser object as its first argument, and the additional
+   * arguments in `args`.
+   *
+   * @param {string} method
+   *        The name of the nsIWebProgressListener method which is being
+   *        delegated.
+   * @param {*} args
+   *        The arguments to pass to the delegated listener.
+   * @private
+   */
   delegate(method, ...args) {
     if (this.listener[method]) {
       this.listener[method](this.browser, ...args);
     }
   }
 
   onLocationChange(webProgress, request, locationURI, flags) {
     this.delegate("onLocationChange", webProgress, request, locationURI, flags);
@@ -52,67 +81,98 @@ class BrowserProgressListener {
     this.delegate("onStateChange", webProgress, request, stateFlags, status);
   }
 
   onProgressChange(webProgress, request, curSelfProgress, maxSelfProgress, curTotalProgress, maxTotalProgress) {}
   onStatusChange(webProgress, request, status, message) {}
   onSecurityChange(webProgress, request, state) {}
 }
 
+/**
+ * Handles wrapping a tab progress listener in browser-specific
+ * BrowserProgressListener instances, an attaching them to each tab in a given
+ * browser window.
+ *
+ * @param {DOMWindow} window
+ *        The browser window to which to attach the listeners.
+ * @param {object} listener
+ *        The tab progress listener to wrap.
+ */
 class ProgressListenerWrapper {
   constructor(window, listener) {
     this.window = window;
     this.listener = listener;
     this.listeners = new WeakMap();
 
     this.flags = Ci.nsIWebProgress.NOTIFY_STATE_ALL |
                  Ci.nsIWebProgress.NOTIFY_LOCATION;
 
     for (let nativeTab of this.window.BrowserApp.tabs) {
       this.addBrowserProgressListener(nativeTab.browser);
     }
 
     this.window.BrowserApp.deck.addEventListener("TabOpen", this);
   }
 
+  /**
+   * Destroy the wrapper, removing any remaining listeners it has added.
+   */
   destroy() {
     this.window.BrowserApp.deck.removeEventListener("TabOpen", this);
 
     for (let nativeTab of this.window.BrowserApp.tabs) {
       this.removeProgressListener(nativeTab.browser);
     }
   }
 
+  /**
+   * Adds a progress listener to the given XUL browser element.
+   *
+   * @param {XULElement} browser
+   *        The XUL browser to add the listener to.
+   * @private
+   */
   addBrowserProgressListener(browser) {
     this.removeProgressListener(browser);
 
     let listener = new BrowserProgressListener(browser, this.listener, this.flags);
     this.listeners.set(browser, listener);
-
-    browser.addProgressListener(listener.filter, this.flags);
   }
 
+  /**
+   * Removes a progress listener from the given XUL browser element.
+   *
+   * @param {XULElement} browser
+   *        The XUL browser to remove the listener from.
+   * @private
+   */
   removeProgressListener(browser) {
     let listener = this.listeners.get(browser);
     if (listener) {
-      browser.removeProgressListener(listener.filter);
       listener.destroy();
       this.listeners.delete(browser);
     }
   }
 
+  /**
+   * Handles tab open events, and adds the necessary progress listeners to the
+   * new tabs.
+   *
+   * @param {Event} event
+   *        The DOM event to handle.
+   * @private
+   */
   handleEvent(event) {
     if (event.type === "TabOpen") {
       this.addBrowserProgressListener(event.originalTarget);
     }
   }
 
 }
 
-
 class WindowTracker extends WindowTrackerBase {
   constructor(...args) {
     super(...args);
 
     this.progressListeners = new DefaultWeakMap(() => new WeakMap());
   }
 
   addProgressListener(window, listener) {
@@ -127,16 +187,34 @@ class WindowTracker extends WindowTracke
     let listeners = this.progressListeners.get(window);
     let wrapper = listeners.get(listener);
     if (wrapper) {
       wrapper.destroy();
       listeners.delete(listener);
     }
   }
 }
+
+/**
+ * An event manager API provider which listens for an event in the Android
+ * global EventDispatcher, and calls the given listener function whenever an event
+ * is received. That listener function receives a `fire` object, which it can
+ * use to dispatch events to the extension, and an object detailing the
+ * EventDispatcher event that was received.
+ *
+ * @param {BaseContext} context
+ *        The extension context which the event manager belongs to.
+ * @param {string} name
+ *        The API name of the event manager, e.g.,"runtime.onMessage".
+ * @param {string} event
+ *        The name of the EventDispatcher event to listen for.
+ * @param {function} listener
+ *        The listener function to call when an EventDispatcher event is
+ *        recieved.
+ */
 global.GlobalEventManager = class extends SingletonEventManager {
   constructor(context, name, event, listener) {
     super(context, name, fire => {
       let listener2 = {
         onEvent(event, data, callback) {
           listener(fire, data);
         },
       };
@@ -144,16 +222,31 @@ global.GlobalEventManager = class extend
       GlobalEventDispatcher.registerListener(listener2, [event]);
       return () => {
         GlobalEventDispatcher.unregisterListener(listener2, [event]);
       };
     });
   }
 };
 
+/**
+ * An event manager API provider which listens for a DOM event in any browser
+ * window, and calls the given listener function whenever an event is received.
+ * That listener function receives a `fire` object, which it can use to dispatch
+ * events to the extension, and a DOM event object.
+ *
+ * @param {BaseContext} context
+ *        The extension context which the event manager belongs to.
+ * @param {string} name
+ *        The API name of the event manager, e.g.,"runtime.onMessage".
+ * @param {string} event
+ *        The name of the DOM event to listen for.
+ * @param {function} listener
+ *        The listener function to call when a DOM event is received.
+ */
 global.WindowEventManager = class extends SingletonEventManager {
   constructor(context, name, event, listener) {
     super(context, name, fire => {
       let listener2 = listener.bind(null, fire);
 
       windowTracker.addListener(event, listener2);
       return () => {
         windowTracker.removeListener(event, listener2);
@@ -186,35 +279,60 @@ class TabTracker extends TabTrackerBase 
       }
     }
     if (default_ !== undefined) {
       return default_;
     }
     throw new ExtensionError(`Invalid tab ID: ${id}`);
   }
 
+  /**
+   * Handles tab open and close events, and emits the appropriate internal
+   * events for them.
+   *
+   * @param {Event} event
+   *        A DOM event to handle.
+   * @private
+   */
   handleEvent(event) {
     const {BrowserApp} = event.target.ownerGlobal;
     let nativeTab = BrowserApp.getTabForBrowser(event.target);
 
     switch (event.type) {
       case "TabOpen":
         this.emitCreated(nativeTab);
         break;
 
       case "TabClose":
         this.emitRemoved(nativeTab, false);
         break;
     }
   }
 
+  /**
+   * Emits a "tab-created" event for the given tab element.
+   *
+   * @param {NativeTab} nativeTab
+   *        The tab element which is being created.
+   * @private
+   */
   emitCreated(nativeTab) {
     this.emit("tab-created", {nativeTab});
   }
 
+  /**
+   * Emits a "tab-removed" event for the given tab element.
+   *
+   * @param {NativeTab} nativeTab
+   *        The tab element which is being removed.
+   * @param {boolean} isWindowClosing
+   *        True if the tab is being removed because the browser window is
+   *        closing.
+   * @private
+   */
   emitRemoved(nativeTab, isWindowClosing) {
     let windowId = windowTracker.getId(nativeTab.browser.ownerGlobal);
     let tabId = this.getId(nativeTab);
 
     Services.tm.mainThread.dispatch(() => {
       this.emit("tab-removed", {nativeTab, tabId, windowId, isWindowClosing});
     }, Ci.nsIThread.DISPATCH_NORMAL);
   }