forked from mirrors/gecko-dev
CLOSED TREE Backed out changeset 2d42350d209a (bug 1203330) Backed out changeset 3a12c51c3eca (bug 1203330) Backed out changeset 31fac390e15d (bug 1203330)
161 lines
4.7 KiB
JavaScript
161 lines
4.7 KiB
JavaScript
"use strict";
|
|
|
|
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
|
|
|
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "EventEmitter",
|
|
"resource://devtools/shared/event-emitter.js");
|
|
|
|
var {
|
|
SingletonEventManager,
|
|
ignoreEvent,
|
|
} = ExtensionUtils;
|
|
|
|
// WeakMap[Extension -> Map[id -> Notification]]
|
|
var notificationsMap = new WeakMap();
|
|
|
|
// Manages a notification popup (notifications API) created by the extension.
|
|
function Notification(extension, id, options) {
|
|
this.extension = extension;
|
|
this.id = id;
|
|
this.options = options;
|
|
|
|
let imageURL;
|
|
if (options.iconUrl) {
|
|
imageURL = this.extension.baseURI.resolve(options.iconUrl);
|
|
}
|
|
|
|
try {
|
|
let svc = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
|
|
svc.showAlertNotification(imageURL,
|
|
options.title,
|
|
options.message,
|
|
true, // textClickable
|
|
this.id,
|
|
this,
|
|
this.id);
|
|
} catch (e) {
|
|
// This will fail if alerts aren't available on the system.
|
|
}
|
|
}
|
|
|
|
Notification.prototype = {
|
|
clear() {
|
|
try {
|
|
let svc = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
|
|
svc.closeAlert(this.id);
|
|
} catch (e) {
|
|
// This will fail if the OS doesn't support this function.
|
|
}
|
|
notificationsMap.get(this.extension).delete(this.id);
|
|
},
|
|
|
|
observe(subject, topic, data) {
|
|
let notifications = notificationsMap.get(this.extension);
|
|
|
|
let emitAndDelete = event => {
|
|
notifications.emit(event, data);
|
|
notifications.delete(this.id);
|
|
};
|
|
|
|
// Don't try to emit events if the extension has been unloaded
|
|
if (!notifications) {
|
|
return;
|
|
}
|
|
|
|
if (topic === "alertclickcallback") {
|
|
emitAndDelete("clicked");
|
|
}
|
|
if (topic === "alertfinished") {
|
|
emitAndDelete("closed");
|
|
}
|
|
},
|
|
};
|
|
|
|
/* eslint-disable mozilla/balanced-listeners */
|
|
extensions.on("startup", (type, extension) => {
|
|
let map = new Map();
|
|
EventEmitter.decorate(map);
|
|
notificationsMap.set(extension, map);
|
|
});
|
|
|
|
extensions.on("shutdown", (type, extension) => {
|
|
if (notificationsMap.has(extension)) {
|
|
for (let notification of notificationsMap.get(extension).values()) {
|
|
notification.clear();
|
|
}
|
|
notificationsMap.delete(extension);
|
|
}
|
|
});
|
|
/* eslint-enable mozilla/balanced-listeners */
|
|
|
|
var nextId = 0;
|
|
|
|
extensions.registerSchemaAPI("notifications", "addon_parent", context => {
|
|
let {extension} = context;
|
|
return {
|
|
notifications: {
|
|
create: function(notificationId, options) {
|
|
if (!notificationId) {
|
|
notificationId = String(nextId++);
|
|
}
|
|
|
|
let notifications = notificationsMap.get(extension);
|
|
if (notifications.has(notificationId)) {
|
|
notifications.get(notificationId).clear();
|
|
}
|
|
|
|
// FIXME: Lots of options still aren't supported, especially
|
|
// buttons.
|
|
let notification = new Notification(extension, notificationId, options);
|
|
notificationsMap.get(extension).set(notificationId, notification);
|
|
|
|
return Promise.resolve(notificationId);
|
|
},
|
|
|
|
clear: function(notificationId) {
|
|
let notifications = notificationsMap.get(extension);
|
|
if (notifications.has(notificationId)) {
|
|
notifications.get(notificationId).clear();
|
|
return Promise.resolve(true);
|
|
}
|
|
return Promise.resolve(false);
|
|
},
|
|
|
|
getAll: function() {
|
|
let result = {};
|
|
notificationsMap.get(extension).forEach((value, key) => {
|
|
result[key] = value.options;
|
|
});
|
|
return Promise.resolve(result);
|
|
},
|
|
|
|
onClosed: new SingletonEventManager(context, "notifications.onClosed", fire => {
|
|
let listener = (event, notificationId) => {
|
|
// FIXME: Support the byUser argument.
|
|
fire.async(notificationId, true);
|
|
};
|
|
|
|
notificationsMap.get(extension).on("closed", listener);
|
|
return () => {
|
|
notificationsMap.get(extension).off("closed", listener);
|
|
};
|
|
}).api(),
|
|
|
|
onClicked: new SingletonEventManager(context, "notifications.onClicked", fire => {
|
|
let listener = (event, notificationId) => {
|
|
fire.async(notificationId, true);
|
|
};
|
|
|
|
notificationsMap.get(extension).on("clicked", listener);
|
|
return () => {
|
|
notificationsMap.get(extension).off("clicked", listener);
|
|
};
|
|
}).api(),
|
|
|
|
// Intend to implement this later: https://bugzilla.mozilla.org/show_bug.cgi?id=1190681
|
|
onButtonClicked: ignoreEvent(context, "notifications.onButtonClicked"),
|
|
},
|
|
};
|
|
});
|