Bug 1464548: Part 1a - Add defineLazyGlobalGetters helper. r?mccr8 draft
authorKris Maglione <maglione.k@gmail.com>
Fri, 25 May 2018 22:28:27 -0700
changeset 800180 78e8b515a3bcc6b41b3d32e972c69c11ac0e08ce
parent 800171 dcf6fe15ea5210fcfbe2813fa49ed9f595a1eff5
child 800181 b2e725c1d21f1cbbdec5d78f13b81c1aa730c1d0
push id111294
push usermaglione.k@gmail.com
push dateSat, 26 May 2018 05:34:03 +0000
reviewersmccr8
bugs1464548
milestone62.0a1
Bug 1464548: Part 1a - Add defineLazyGlobalGetters helper. r?mccr8 This allows us to lazily import global properties using Cu.importGlobalProperties. Aside from making it easier to avoid lazily importing these properties, it also defines them all in the shared JSM global so that we don't risk re-creating them in Sandboxes or frameloader globals. MozReview-Commit-ID: GV6shguUlIG
js/xpconnect/loader/XPCOMUtils.jsm
--- a/js/xpconnect/loader/XPCOMUtils.jsm
+++ b/js/xpconnect/loader/XPCOMUtils.jsm
@@ -85,16 +85,18 @@
  *
  * 3. Define the NSGetFactory entry point:
  *  this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
  */
 
 
 var EXPORTED_SYMBOLS = [ "XPCOMUtils" ];
 
+let global = Cu.getGlobalForObject({});
+
 var XPCOMUtils = {
   /**
    * Generate a QueryInterface implementation. The returned function must be
    * assigned to the 'QueryInterface' property of a JS object. When invoked on
    * that object, it checks if the given iid is listed in the |interfaces|
    * param, and if it is, returns |this| (the object it was called on).
    * If the JS object has a classInfo property it'll be returned for the
    * nsIClassInfo IID, generateCI can be used to generate the classInfo
@@ -225,16 +227,39 @@ var XPCOMUtils = {
         },
         configurable: true,
         enumerable: true
       });
     }
   },
 
   /**
+   * Defines a getter property on the given object for each of the given
+   * global names as accepted by Cu.importGlobalProperties. These
+   * properties are imported into the shared JSM module global, and then
+   * copied onto the given object, no matter which global the object
+   * belongs to.
+   *
+   * @param {object} aObject
+   *        The object on which to define the properties.
+   * @param {string[]} aNames
+   *        The list of global properties to define.
+   */
+  defineLazyGlobalGetters(aObject, aNames) {
+    for (let name of aNames) {
+      this.defineLazyGetter(aObject, name, () => {
+        if (!(name in global)) {
+          Cu.importGlobalProperties([name]);
+        }
+        return global[name];
+      });
+    }
+  },
+
+  /**
    * Defines a getter on a specified object for a service.  The service will not
    * be obtained until first use.
    *
    * @param aObject
    *        The object to define the lazy getter on.
    * @param aName
    *        The name of the getter to define on aObject for the service.
    * @param aContract