mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 05:35:31 +00:00
1294cccf48
Bug 1337467 - 1. Convert "Window:Resize" observer to event; r=rbarker Bug 1337467 - 2. Convert "ScrollTo:FocusedInput" observer to event; r=rbarker Bug 1337467 - 3. Convert "Update:CheckResult" observer to event; r=sebastian Also remove notifyCheckUpdateResult from GeckoInterface. Bug 1337467 - 4. Convert "GeckoView:ImportScript" observer to event; r=sebastian Bug 1337467 - 5. Convert accessibility observers to events; r=sebastian Bug 1337467 - 6. Convert media/casting observers to events; r=sebastian Bug 1337467 - 7. Convert "Sanitize:ClearData" observer to event; r=sebastian Bug 1337467 - 8. Convert "Notification:Event" observer to event; r=sebastian Bug 1337467 - 9. Convert BrowserApp observers to events; r=sebastian Bug 1337467 - 10. Convert Tab observers to events; r=sebastian Bug 1337467 - 11. Convert "Passwords:Init" and "FormHistory:Init" observers to events; r=sebastian Bug 1337467 - 12. Convert Reader observers to events; r=sebastian Bug 1337467 - 13. Convert Distribution observers to events; r=sebastian Bug 1337467 - 14. Convert "Fonts:Reload" observer to event; r=sebastian Bug 1337467 - 15. Convert RecentTabsAdapter observers to events; r=sebastian Bug 1337467 - 16. Convert "Session:Prefetch" observer to event; r=sebastian Bug 1337467 - 17. Convert "Browser:Quit" and "FullScreen:Exit" observers to events; r=sebastian Bug 1337467 - 18. Convert SessionStore observers to events; r=sebastian The "Session:NotifyLocationChange" observer is sent by browser.js and requires passing a browser reference, so it's left as an observer. Bug 1337467 - 19. Remove unused "Tab:Screenshot:Cancel" notifyObserver call; r=me Bug 1337467 - 20. Convert "Session:Navigate" observer to event; r=sebastian Bug 1337467 - 21. Convert "Locale:*" observers to events; r=sebastian Bug 1337467 - Add log for unhandled events; r=me Add back the log indicating no listener for an event, which can be useful when reading logcat. r=me for trivial change. Bug 1337467 - Don't return error from EventDispatcher when OnEvent fails; r=me When a listener's OnEvent method returns an error, continue to dispatch to other listeners and don't return an error from the dispatch function. This avoids unexpected errors when dispatching events. r=me for trivial patch.
251 lines
6.6 KiB
JavaScript
251 lines
6.6 KiB
JavaScript
/* 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/Messaging.jsm");
|
|
|
|
this.EXPORTED_SYMBOLS = ["Notifications"];
|
|
|
|
var _notificationsMap = {};
|
|
var _handlersMap = {};
|
|
|
|
function Notification(aId, aOptions) {
|
|
this._id = aId;
|
|
this._when = (new Date()).getTime();
|
|
this.fillWithOptions(aOptions);
|
|
}
|
|
|
|
Notification.prototype = {
|
|
fillWithOptions: function(aOptions) {
|
|
if ("icon" in aOptions && aOptions.icon != null)
|
|
this._icon = aOptions.icon;
|
|
else
|
|
throw "Notification icon is mandatory";
|
|
|
|
if ("title" in aOptions && aOptions.title != null)
|
|
this._title = aOptions.title;
|
|
else
|
|
throw "Notification title is mandatory";
|
|
|
|
if ("message" in aOptions && aOptions.message != null)
|
|
this._message = aOptions.message;
|
|
else
|
|
this._message = null;
|
|
|
|
if ("priority" in aOptions && aOptions.priority != null)
|
|
this._priority = aOptions.priority;
|
|
|
|
if ("buttons" in aOptions && aOptions.buttons != null) {
|
|
if (aOptions.buttons.length > 3)
|
|
throw "Too many buttons provided. The max number is 3";
|
|
|
|
this._buttons = {};
|
|
for (let i = 0; i < aOptions.buttons.length; i++) {
|
|
let button_id = aOptions.buttons[i].buttonId;
|
|
this._buttons[button_id] = aOptions.buttons[i];
|
|
}
|
|
} else {
|
|
this._buttons = null;
|
|
}
|
|
|
|
if ("ongoing" in aOptions && aOptions.ongoing != null)
|
|
this._ongoing = aOptions.ongoing;
|
|
else
|
|
this._ongoing = false;
|
|
|
|
if ("progress" in aOptions && aOptions.progress != null)
|
|
this._progress = aOptions.progress;
|
|
else
|
|
this._progress = null;
|
|
|
|
if ("onCancel" in aOptions && aOptions.onCancel != null)
|
|
this._onCancel = aOptions.onCancel;
|
|
else
|
|
this._onCancel = null;
|
|
|
|
if ("onClick" in aOptions && aOptions.onClick != null)
|
|
this._onClick = aOptions.onClick;
|
|
else
|
|
this._onClick = null;
|
|
|
|
if ("cookie" in aOptions && aOptions.cookie != null)
|
|
this._cookie = aOptions.cookie;
|
|
else
|
|
this._cookie = null;
|
|
|
|
if ("handlerKey" in aOptions && aOptions.handlerKey != null)
|
|
this._handlerKey = aOptions.handlerKey;
|
|
|
|
if ("persistent" in aOptions && aOptions.persistent != null)
|
|
this._persistent = aOptions.persistent;
|
|
else
|
|
this._persistent = false;
|
|
},
|
|
|
|
show: function() {
|
|
let msg = {
|
|
id: this._id,
|
|
title: this._title,
|
|
smallIcon: this._icon,
|
|
ongoing: this._ongoing,
|
|
when: this._when,
|
|
persistent: this._persistent,
|
|
};
|
|
|
|
if (this._message)
|
|
msg.text = this._message;
|
|
|
|
if (this._progress) {
|
|
msg.progress_value = this._progress;
|
|
msg.progress_max = 100;
|
|
msg.progress_indeterminate = false;
|
|
} else if (Number.isNaN(this._progress)) {
|
|
msg.progress_value = 0;
|
|
msg.progress_max = 0;
|
|
msg.progress_indeterminate = true;
|
|
}
|
|
|
|
if (this._cookie)
|
|
msg.cookie = JSON.stringify(this._cookie);
|
|
|
|
if (this._priority)
|
|
msg.priority = this._priority;
|
|
|
|
if (this._buttons) {
|
|
msg.actions = [];
|
|
let buttonName;
|
|
for (buttonName in this._buttons) {
|
|
let button = this._buttons[buttonName];
|
|
let obj = {
|
|
buttonId: button.buttonId,
|
|
title : button.title,
|
|
icon : button.icon
|
|
};
|
|
msg.actions.push(obj);
|
|
}
|
|
}
|
|
|
|
if (this._light)
|
|
msg.light = this._light;
|
|
|
|
if (this._handlerKey)
|
|
msg.handlerKey = this._handlerKey;
|
|
|
|
EventDispatcher.instance.dispatch("Notification:Show", msg);
|
|
return this;
|
|
},
|
|
|
|
cancel: function() {
|
|
let msg = {
|
|
id: this._id,
|
|
handlerKey: this._handlerKey,
|
|
cookie: JSON.stringify(this._cookie),
|
|
};
|
|
EventDispatcher.instance.dispatch("Notification:Hide", msg);
|
|
}
|
|
}
|
|
|
|
var Notifications = {
|
|
get idService() {
|
|
delete this.idService;
|
|
return this.idService = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
|
|
},
|
|
|
|
registerHandler: function(key, handler) {
|
|
if (!_handlersMap[key]) {
|
|
_handlersMap[key] = [];
|
|
}
|
|
_handlersMap[key].push(handler);
|
|
},
|
|
|
|
unregisterHandler: function(key, handler) {
|
|
let h = _handlersMap[key];
|
|
if (!h) {
|
|
return;
|
|
}
|
|
let i = h.indexOf(handler);
|
|
if (i > -1) {
|
|
h.splice(i, 1);
|
|
}
|
|
},
|
|
|
|
create: function notif_notify(aOptions) {
|
|
let id = this.idService.generateUUID().toString();
|
|
|
|
let notification = new Notification(id, aOptions);
|
|
_notificationsMap[id] = notification;
|
|
notification.show();
|
|
|
|
return id;
|
|
},
|
|
|
|
update: function notif_update(aId, aOptions) {
|
|
let notification = _notificationsMap[aId];
|
|
if (!notification)
|
|
throw "Unknown notification id";
|
|
notification.fillWithOptions(aOptions);
|
|
notification.show();
|
|
},
|
|
|
|
cancel: function notif_cancel(aId) {
|
|
let notification = _notificationsMap[aId];
|
|
if (notification)
|
|
notification.cancel();
|
|
},
|
|
|
|
onEvent: function notif_onEvent(event, data, callback) {
|
|
let id = data.id;
|
|
let handlerKey = data.handlerKey;
|
|
let cookie = data.cookie ? JSON.parse(data.cookie) : undefined;
|
|
let notification = _notificationsMap[id];
|
|
|
|
switch (data.eventType) {
|
|
case "notification-clicked":
|
|
if (notification && notification._onClick)
|
|
notification._onClick(id, notification._cookie);
|
|
|
|
if (handlerKey) {
|
|
_handlersMap[handlerKey].forEach(function(handler) {
|
|
handler.onClick(cookie);
|
|
});
|
|
}
|
|
|
|
break;
|
|
case "notification-button-clicked":
|
|
if (handlerKey) {
|
|
_handlersMap[handlerKey].forEach(function(handler) {
|
|
handler.onButtonClick(data.buttonId, cookie);
|
|
});
|
|
}
|
|
|
|
break;
|
|
case "notification-cleared":
|
|
case "notification-closed":
|
|
if (handlerKey) {
|
|
_handlersMap[handlerKey].forEach(function(handler) {
|
|
handler.onCancel(cookie);
|
|
});
|
|
}
|
|
|
|
if (notification && notification._onCancel)
|
|
notification._onCancel(id, notification._cookie);
|
|
delete _notificationsMap[id]; // since the notification was dismissed, we no longer need to hold a reference.
|
|
break;
|
|
}
|
|
},
|
|
|
|
QueryInterface: function (aIID) {
|
|
if (!aIID.equals(Ci.nsISupports) &&
|
|
!aIID.equals(Ci.nsIObserver) &&
|
|
!aIID.equals(Ci.nsISupportsWeakReference))
|
|
throw Components.results.NS_ERROR_NO_INTERFACE;
|
|
return this;
|
|
}
|
|
};
|
|
|
|
EventDispatcher.instance.registerListener(Notifications, "Notification:Event");
|