toolkit/components/social/WorkerAPI.jsm

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:334388ae9634
1 /* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 "use strict";
8
9 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
10 Cu.import("resource://gre/modules/Services.jsm");
11 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
12
13 XPCOMUtils.defineLazyModuleGetter(this, "getFrameWorkerHandle", "resource://gre/modules/FrameWorker.jsm");
14 XPCOMUtils.defineLazyModuleGetter(this, "openChatWindow", "resource://gre/modules/MozSocialAPI.jsm");
15
16 this.EXPORTED_SYMBOLS = ["WorkerAPI"];
17
18 this.WorkerAPI = function WorkerAPI(provider, port) {
19 if (!port)
20 throw new Error("Can't initialize WorkerAPI with a null port");
21
22 this._provider = provider;
23 this._port = port;
24 this._port.onmessage = this._handleMessage.bind(this);
25
26 // Send an "intro" message so the worker knows this is the port
27 // used for the api.
28 // later we might even include an API version - version 0 for now!
29 this._port.postMessage({topic: "social.initialize"});
30 }
31
32 WorkerAPI.prototype = {
33 terminate: function terminate() {
34 this._port.close();
35 },
36
37 _handleMessage: function _handleMessage(event) {
38 let {topic, data} = event.data;
39 let handler = this.handlers[topic];
40 if (!handler) {
41 Cu.reportError("WorkerAPI: topic doesn't have a handler: '" + topic + "'");
42 return;
43 }
44 try {
45 handler.call(this, data);
46 } catch (ex) {
47 Cu.reportError("WorkerAPI: failed to handle message '" + topic + "': " + ex + "\n" + ex.stack);
48 }
49 },
50
51 handlers: {
52 "social.manifest-get": function(data) {
53 // retreive the currently installed manifest from firefox
54 this._port.postMessage({topic: "social.manifest", data: this._provider.manifest});
55 },
56 "social.manifest-set": function(data) {
57 // the provider will get reloaded as a result of this call
58 let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
59 let origin = this._provider.origin;
60 SocialService.updateProvider(origin, data);
61 },
62 "social.reload-worker": function(data) {
63 this._provider.reload();
64 },
65 "social.user-profile": function (data) {
66 this._provider.updateUserProfile(data);
67 },
68 "social.ambient-notification": function (data) {
69 this._provider.setAmbientNotification(data);
70 },
71 "social.cookies-get": function(data) {
72 // We don't want to trust provider.origin etc, just incase the provider
73 // redirected away or something else bad is going on. So we want to
74 // reach into the Worker's document and fetch the actual cookies it has.
75 // We need to do this via our own message dance.
76 let port = this._port;
77 let whandle = getFrameWorkerHandle(this._provider.workerURL, null);
78 whandle.port.close();
79 whandle._worker.browserPromise.then(browser => {
80 let mm = browser.messageManager;
81 mm.addMessageListener("frameworker:cookie-get-response", function _onCookieResponse(msg) {
82 mm.removeMessageListener("frameworker:cookie-get-response", _onCookieResponse);
83 let cookies = msg.json.split(";");
84 let results = [];
85 cookies.forEach(function(aCookie) {
86 let [name, value] = aCookie.split("=");
87 if (name || value) {
88 results.push({name: unescape(name.trim()),
89 value: value ? unescape(value.trim()) : ""});
90 }
91 });
92 port.postMessage({topic: "social.cookies-get-response",
93 data: results});
94 });
95 mm.sendAsyncMessage("frameworker:cookie-get");
96 });
97 },
98 'social.request-chat': function(data) {
99 openChatWindow(null, this._provider, data);
100 },
101 'social.notification-create': function(data) {
102 if (!Services.prefs.getBoolPref("social.toast-notifications.enabled"))
103 return;
104
105 let port = this._port;
106 let provider = this._provider;
107 let {id, type, icon, body, action, actionArgs} = data;
108 let alertsService = Cc["@mozilla.org/alerts-service;1"]
109 .getService(Ci.nsIAlertsService);
110 function listener(subject, topic, data) {
111 if (topic === "alertclickcallback") {
112 // we always post back the click
113 port.postMessage({topic: "social.notification-action",
114 data: {id: id,
115 action: action,
116 actionArgs: actionArgs}});
117 switch (action) {
118 case "link":
119 // if there is a url, make it open a tab
120 if (actionArgs.toURL) {
121 let uriToOpen = provider.resolveUri(actionArgs.toURL);
122 // Bug 815970 - facebook gives us http:// links even though
123 // the origin is https:// - so we perform a fixup here.
124 let pUri = Services.io.newURI(provider.origin, null, null);
125 if (uriToOpen.scheme != pUri.scheme)
126 uriToOpen.scheme = pUri.scheme;
127 if (provider.isSameOrigin(uriToOpen)) {
128 let xulWindow = Services.wm.getMostRecentWindow("navigator:browser");
129 xulWindow.openUILinkIn(uriToOpen.spec, "tab");
130 } else {
131 Cu.reportError("Not opening notification link " + actionArgs.toURL
132 + " as not in provider origin");
133 }
134 }
135 break;
136 default:
137 break;
138 }
139 }
140 }
141 alertsService.showAlertNotification(icon,
142 this._provider.name, // title
143 body,
144 !!action, // text clickable if an
145 // action was provided.
146 null,
147 listener,
148 type);
149 },
150 }
151 }

mercurial