Bug 774003: let social workers request their cookies via the Social API, r=gavin
authorShane Caraveo <mixedpuppy@gmail.com>
Wed, 25 Jul 2012 15:26:39 -0700
changeset 100557 677cdab1da6a1e6a8bcb1c56d2f65b10022c0575
parent 100556 9d8cc914ad36c644a37344b9b118916fc7e68d3d
child 100558 98c2a42a3aefb716b570b5e6b746f09e442e3a87
push id23183
push usergsharp@mozilla.com
push dateThu, 26 Jul 2012 16:17:10 +0000
treeherdermozilla-central@98c2a42a3aef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs774003
milestone17.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 774003: let social workers request their cookies via the Social API, r=gavin
toolkit/components/social/FrameWorker.jsm
toolkit/components/social/WorkerAPI.jsm
toolkit/components/social/test/browser/browser_workerAPI.js
toolkit/components/social/test/browser/worker_social.js
--- a/toolkit/components/social/FrameWorker.jsm
+++ b/toolkit/components/social/FrameWorker.jsm
@@ -248,16 +248,20 @@ function makeHiddenFrame() {
   return iframe;
 }
 
 function WorkerHandle(port, worker) {
   this.port = port;
   this._worker = worker;
 }
 WorkerHandle.prototype = {
+  get document() {
+    return this._worker.frame.contentDocument;
+  },
+
   // XXX - workers have no .close() method, but *do* have a .terminate()
   // method which we should implement. However, the worker spec doesn't define
   // a callback to be made in the worker when this happens - it all just dies.
   // TODO: work out a sane impl for 'terminate'.
   terminate: function terminate() {
     this._worker.terminate();
   }
 };
--- a/toolkit/components/social/WorkerAPI.jsm
+++ b/toolkit/components/social/WorkerAPI.jsm
@@ -3,16 +3,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "getFrameWorkerHandle", "resource://gre/modules/FrameWorker.jsm");
 
 const EXPORTED_SYMBOLS = ["WorkerAPI"];
 
 function WorkerAPI(provider, port) {
   if (!port)
     throw new Error("Can't initialize WorkerAPI with a null port");
 
   this._provider = provider;
@@ -20,16 +23,19 @@ function WorkerAPI(provider, port) {
   this._port.onmessage = this._handleMessage.bind(this);
 
   this.initialized = false;
 
   // Send an "intro" message so the worker knows this is the port
   // used for the api.
   // later we might even include an API version - version 0 for now!
   this._port.postMessage({topic: "social.initialize"});
+  
+  // backwards compat, remove after Aug 1.
+  this._port.postMessage({topic: "social.cookie-changed"});
 }
 
 WorkerAPI.prototype = {
   _handleMessage: function _handleMessage(event) {
     let {topic, data} = event.data;
     let handler = this.handlers[topic];
     if (!handler) {
       Cu.reportError("WorkerAPI: topic doesn't have a handler: '" + topic + "'");
@@ -47,16 +53,28 @@ WorkerAPI.prototype = {
       this.initialized = true;
     },
     "social.user-profile": function (data) {
       this._provider.updateUserProfile(data);
     },
     "social.ambient-notification": function (data) {
       this._provider.setAmbientNotification(data);
     },
+    "social.cookies-get": function(data) {
+      let document = getFrameWorkerHandle(this._provider.workerURL, null).document;
+      let cookies = document.cookie.split(";");
+      let results = [];
+      cookies.forEach(function(aCookie) {
+        let [name, value] = aCookie.split("=");
+        results.push({name: unescape(name.trim()),
+                      value: unescape(value.trim())});
+      });
+      this._port.postMessage({topic: "social.cookies-get-response",
+                              data: results});
+    },
     
     // XXX backwards compat for existing providers, remove these eventually
     "social.ambient-notification-area": function (data) {
       // replaced with social.user-profile
       // handle the provider icon and user profile for the primary provider menu
       if (data.background) {
         // backwards compat
         try {
--- a/toolkit/components/social/test/browser/browser_workerAPI.js
+++ b/toolkit/components/social/test/browser/browser_workerAPI.js
@@ -55,43 +55,60 @@ let tests = {
       is(profile.portrait, expect.portrait, "portrait is set");
       is(profile.userName, expect.userName, "userName is set");
       is(profile.displayName, expect.displayName, "displayName is set");
       is(profile.profileURL, expect.profileURL, "profileURL is set");
 
       next();
     }
     Services.obs.addObserver(ob, "social:profile-changed", false);
-    provider.workerAPI._port.postMessage({topic: "test-profile", data: expect});
+    provider.port.postMessage({topic: "test-profile", data: expect});
   },
 
   testAmbientNotification: function(next) {
     let expect = {
       name: "test-ambient"
     }
     function ob(aSubject, aTopic, aData) {
       Services.obs.removeObserver(ob, "social:ambient-notification-changed", false);
       is(aData, provider.origin, "update is from our provider");
       let notif = provider.ambientNotificationIcons[expect.name];
       is(notif.name, expect.name, "ambientNotification reflected");
 
       next();
     }
     Services.obs.addObserver(ob, "social:ambient-notification-changed", false);
-    provider.workerAPI._port.postMessage({topic: "test-ambient", data: expect});
+    provider.port.postMessage({topic: "test-ambient", data: expect});
   },
 
   testProfileCleared: function(next) {
     let sent = {
       userName: ""
     };
     function ob(aSubject, aTopic, aData) {
       Services.obs.removeObserver(ob, "social:profile-changed", false);
       is(aData, provider.origin, "update of profile from our provider");
       is(Object.keys(provider.profile).length, 0, "profile was cleared by empty username");
       is(Object.keys(provider.ambientNotificationIcons).length, 0, "icons were cleared by empty username");
 
       next();
     }
     Services.obs.addObserver(ob, "social:profile-changed", false);
     provider.workerAPI._port.postMessage({topic: "test-profile", data: sent});
+  },
+
+  testCookies: function(next) {
+    provider.port.onmessage = function onMessage(event) {
+      let {topic, data} = event.data;
+      if (topic == "test.cookies-get-response") {
+        is(data.length, 1, "got one cookie");
+        is(data[0].name, "cheez", "cookie has the correct name");
+        is(data[0].value, "burger", "cookie has the correct value");
+        Services.cookies.remove('.example.com', '/', 'cheez', false);
+        next();
+      }
+    }
+    var MAX_EXPIRY = Math.pow(2, 62);
+    Services.cookies.add('.example.com', '/', 'cheez', 'burger', false, false, true, MAX_EXPIRY);
+    provider.port.postMessage({topic: "test.cookies-get"});
   }
+
 };
--- a/toolkit/components/social/test/browser/worker_social.js
+++ b/toolkit/components/social/test/browser/worker_social.js
@@ -1,24 +1,39 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+// apiPort is our port to WorkerAPI
+let apiPort;
+// testerPort is whatever port a test calls us on
+let testerPort;
+
 onconnect = function(e) {
+  // assume this is a test connecting, but if we get
+  // social.initialize, we know it is our WorkerAPI
+  // instance connecting and we'll set apiPort
   let port = e.ports[0];
   port.onmessage = function onMessage(event) {
     let {topic, data} = event.data;
     switch (topic) {
       case "social.initialize":
-        port.postMessage({topic: "social.initialize-response"});
+        apiPort = port;
+        apiPort.postMessage({topic: "social.initialize-response"});
         break;
       case "test-initialization":
+        testerPort = port;
         port.postMessage({topic: "test-initialization-complete"});
         break;
       case "test-profile":
-        port.postMessage({topic: "social.user-profile", data: data});
+        apiPort.postMessage({topic: "social.user-profile", data: data});
         break;
       case "test-ambient":
-        port.postMessage({topic: "social.ambient-notification", data: data});
+        apiPort.postMessage({topic: "social.ambient-notification", data: data});
         break;
+      case "test.cookies-get":
+        apiPort.postMessage({topic: "social.cookies-get"});
+        break;
+      case "social.cookies-get-response":
+        testerPort.postMessage({topic: "test.cookies-get-response", data: data});
     }
   }
 }