mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-04 16:15:25 +00:00
156 lines
6.4 KiB
JavaScript
156 lines
6.4 KiB
JavaScript
/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
|
/* 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");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "openChatWindow", "resource://gre/modules/MozSocialAPI.jsm");
|
|
|
|
this.EXPORTED_SYMBOLS = ["WorkerAPI"];
|
|
|
|
this.WorkerAPI = function WorkerAPI(provider, port) {
|
|
if (!port)
|
|
throw new Error("Can't initialize WorkerAPI with a null port");
|
|
|
|
this._provider = provider;
|
|
this._port = port;
|
|
this._port.onmessage = this._handleMessage.bind(this);
|
|
|
|
// 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"});
|
|
}
|
|
|
|
WorkerAPI.prototype = {
|
|
terminate: function terminate() {
|
|
this._port.close();
|
|
},
|
|
|
|
_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 + "'");
|
|
return;
|
|
}
|
|
try {
|
|
handler.call(this, data);
|
|
} catch (ex) {
|
|
Cu.reportError("WorkerAPI: failed to handle message '" + topic + "': " + ex + "\n" + ex.stack);
|
|
}
|
|
},
|
|
|
|
handlers: {
|
|
"social.manifest-get": function(data) {
|
|
// retreive the currently installed manifest from firefox
|
|
this._port.postMessage({topic: "social.manifest", data: this._provider.manifest});
|
|
},
|
|
"social.manifest-set": function(data) {
|
|
// the provider will get reloaded as a result of this call
|
|
let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
|
|
let origin = this._provider.origin;
|
|
SocialService.updateProvider(origin, data);
|
|
},
|
|
"social.reload-worker": function(data) {
|
|
getFrameWorkerHandle(this._provider.workerURL, null)._worker.reload();
|
|
// the frameworker is going to be reloaded, send the initialization
|
|
// so it can have the same startup sequence as if it were loaded
|
|
// the first time. This will be queued until the frameworker is ready.
|
|
this._port.postMessage({topic: "social.initialize"});
|
|
},
|
|
"social.user-profile": function (data) {
|
|
this._provider.updateUserProfile(data);
|
|
},
|
|
"social.ambient-notification": function (data) {
|
|
this._provider.setAmbientNotification(data);
|
|
},
|
|
"social.cookies-get": function(data) {
|
|
// We don't want to trust provider.origin etc, just incase the provider
|
|
// redirected away or something else bad is going on. So we want to
|
|
// reach into the Worker's document and fetch the actual cookies it has.
|
|
// We need to do this via our own message dance.
|
|
let port = this._port;
|
|
let whandle = getFrameWorkerHandle(this._provider.workerURL, null);
|
|
whandle.port.close();
|
|
whandle._worker.browserPromise.then(browser => {
|
|
let mm = browser.messageManager;
|
|
mm.addMessageListener("frameworker:cookie-get-response", function _onCookieResponse(msg) {
|
|
mm.removeMessageListener("frameworker:cookie-get-response", _onCookieResponse);
|
|
let cookies = msg.json.split(";");
|
|
let results = [];
|
|
cookies.forEach(function(aCookie) {
|
|
let [name, value] = aCookie.split("=");
|
|
if (name || value) {
|
|
results.push({name: unescape(name.trim()),
|
|
value: value ? unescape(value.trim()) : ""});
|
|
}
|
|
});
|
|
port.postMessage({topic: "social.cookies-get-response",
|
|
data: results});
|
|
});
|
|
mm.sendAsyncMessage("frameworker:cookie-get");
|
|
});
|
|
},
|
|
'social.request-chat': function(data) {
|
|
openChatWindow(null, this._provider, data);
|
|
},
|
|
'social.notification-create': function(data) {
|
|
if (!Services.prefs.getBoolPref("social.toast-notifications.enabled"))
|
|
return;
|
|
|
|
let port = this._port;
|
|
let provider = this._provider;
|
|
let {id, type, icon, body, action, actionArgs} = data;
|
|
let alertsService = Cc["@mozilla.org/alerts-service;1"]
|
|
.getService(Ci.nsIAlertsService);
|
|
function listener(subject, topic, data) {
|
|
if (topic === "alertclickcallback") {
|
|
// we always post back the click
|
|
port.postMessage({topic: "social.notification-action",
|
|
data: {id: id,
|
|
action: action,
|
|
actionArgs: actionArgs}});
|
|
switch (action) {
|
|
case "link":
|
|
// if there is a url, make it open a tab
|
|
if (actionArgs.toURL) {
|
|
let uriToOpen = provider.resolveUri(actionArgs.toURL);
|
|
// Bug 815970 - facebook gives us http:// links even though
|
|
// the origin is https:// - so we perform a fixup here.
|
|
let pUri = Services.io.newURI(provider.origin, null, null);
|
|
if (uriToOpen.scheme != pUri.scheme)
|
|
uriToOpen.scheme = pUri.scheme;
|
|
if (provider.isSameOrigin(uriToOpen)) {
|
|
let xulWindow = Services.wm.getMostRecentWindow("navigator:browser");
|
|
xulWindow.openUILinkIn(uriToOpen.spec, "tab");
|
|
} else {
|
|
Cu.reportError("Not opening notification link " + actionArgs.toURL
|
|
+ " as not in provider origin");
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
alertsService.showAlertNotification(icon,
|
|
this._provider.name, // title
|
|
body,
|
|
!!action, // text clickable if an
|
|
// action was provided.
|
|
null,
|
|
listener,
|
|
type);
|
|
},
|
|
}
|
|
}
|