Bug 1082450 - Rip exposedProps out of Social API code. r=Gijs
authorBobby Holley <bobbyholley@gmail.com>
Wed, 15 Oct 2014 15:05:08 +0200
changeset 210538 687aa81bd41c42d6e9755242b32874362d577967
parent 210537 1f19fa816c9746f423736068f6ebbabf282eb0e6
child 210539 84aa4151a88a559af4ba110bf84336e785cacdbe
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersGijs
bugs1082450
milestone36.0a1
Bug 1082450 - Rip exposedProps out of Social API code. r=Gijs
toolkit/components/social/FrameWorker.jsm
toolkit/components/social/FrameWorkerContent.js
toolkit/components/social/MozSocialAPI.jsm
--- a/toolkit/components/social/FrameWorker.jsm
+++ b/toolkit/components/social/FrameWorker.jsm
@@ -144,22 +144,16 @@ WorkerHandle.prototype = {
 // shim which shuttles messages to/from the worker itself.
 function ParentPort(portid, browserPromise, clientWindow) {
   this._clientWindow = clientWindow;
   this._browserPromise = browserPromise;
   AbstractPort.call(this, portid);
 }
 
 ParentPort.prototype = {
-  __exposedProps__: {
-    onmessage: "rw",
-    postMessage: "r",
-    close: "r",
-    toString: "r"
-  },
   __proto__: AbstractPort.prototype,
   _portType: "parent",
 
   _dopost: function(data) {
     this._browserPromise.then(browser => {
       browser.messageManager.sendAsyncMessage("frameworker:port-message", data);
     });
   },
--- a/toolkit/components/social/FrameWorkerContent.js
+++ b/toolkit/components/social/FrameWorkerContent.js
@@ -111,32 +111,27 @@ FrameWorker.prototype = {
           sandbox[fn] = workerWindow[fn];
       }
       catch(e) {
         Cu.reportError("FrameWorker: failed to import API "+fn+"\n"+e+"\n");
       }
     });
     // the "navigator" object in a worker is a subset of the full navigator;
     // specifically, just the interfaces 'NavigatorID' and 'NavigatorOnLine'
-    let navigator = {
-      __exposedProps__: {
-        "appName": "r",
-        "appVersion": "r",
-        "platform": "r",
-        "userAgent": "r",
-        "onLine": "r"
-      },
+    let navigator = Cu.cloneInto({
       // interface NavigatorID
       appName: workerWindow.navigator.appName,
       appVersion: workerWindow.navigator.appVersion,
       platform: workerWindow.navigator.platform,
       userAgent: workerWindow.navigator.userAgent,
-      // interface NavigatorOnLine
-      get onLine() workerWindow.navigator.onLine
-    };
+    }, sandbox);
+    Object.defineProperty(Cu.waiveXrays(navigator), 'onLine', {
+      configurable: true, enumerable: true,
+      get: Cu.exportFunction(() => workerWindow.navigator.onLine, sandbox)
+    });
     sandbox.navigator = navigator;
 
     // Our importScripts function needs to 'eval' the script code from inside
     // a function, but using eval() directly means functions in the script
     // don't end up in the global scope.
     sandbox._evalInSandbox = function(s, url) {
       let baseURI = Services.io.newURI(workerWindow.location.href, null, null);
       Cu.evalInSandbox(s, sandbox, "1.8",
--- a/toolkit/components/social/MozSocialAPI.jsm
+++ b/toolkit/components/social/MozSocialAPI.jsm
@@ -103,22 +103,37 @@ function attachToWindow(provider, target
   let mozSocialObj = {
     // Use a method for backwards compat with existing providers, but we
     // should deprecate this in favor of a simple .port getter.
     getWorker: {
       enumerable: true,
       configurable: true,
       writable: true,
       value: function() {
-        return {
-          port: port,
-          __exposedProps__: {
-            port: "r"
+
+        // We do a bunch of hacky stuff to expose this API to content without
+        // relying on ChromeObjectWrapper functionality that is now unsupported.
+        // The content-facing API here should really move to JS-Implemented
+        // WebIDL.
+        let workerAPI = Cu.cloneInto({
+          port: {
+            postMessage: port.postMessage.bind(port),
+            close: port.close.bind(port),
+            toString: port.toString.bind(port)
           }
-        };
+        }, targetWindow, {cloneFunctions: true});
+
+        // Jump through hoops to define the accessor property.
+        let abstractPortPrototype = Object.getPrototypeOf(Object.getPrototypeOf(port));
+        let desc = Object.getOwnPropertyDescriptor(port.__proto__.__proto__, 'onmessage');
+        desc.get = Cu.exportFunction(desc.get.bind(port), targetWindow);
+        desc.set = Cu.exportFunction(desc.set.bind(port), targetWindow);
+        Object.defineProperty(workerAPI.wrappedJSObject.port, 'onmessage', desc);
+
+        return workerAPI;
       }
     },
     hasBeenIdleFor: {
       enumerable: true,
       configurable: true,
       writable: true,
       value: function() {
         return false;