dom/src/notification/NotificationStorage.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 "use strict";
michael@0 6
michael@0 7 const DEBUG = false;
michael@0 8 function debug(s) { dump("-*- NotificationStorage.js: " + s + "\n"); }
michael@0 9
michael@0 10 const Cc = Components.classes;
michael@0 11 const Ci = Components.interfaces;
michael@0 12 const Cu = Components.utils;
michael@0 13
michael@0 14 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 15
michael@0 16 const NOTIFICATIONSTORAGE_CID = "{37f819b0-0b5c-11e3-8ffd-0800200c9a66}";
michael@0 17 const NOTIFICATIONSTORAGE_CONTRACTID = "@mozilla.org/notificationStorage;1";
michael@0 18
michael@0 19 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
michael@0 20 "@mozilla.org/childprocessmessagemanager;1",
michael@0 21 "nsIMessageSender");
michael@0 22
michael@0 23
michael@0 24 function NotificationStorage() {
michael@0 25 // cache objects
michael@0 26 this._notifications = {};
michael@0 27 this._byTag = {};
michael@0 28 this._cached = false;
michael@0 29
michael@0 30 this._requests = {};
michael@0 31 this._requestCount = 0;
michael@0 32
michael@0 33 // Register for message listeners.
michael@0 34 cpmm.addMessageListener("Notification:GetAll:Return:OK", this);
michael@0 35 }
michael@0 36
michael@0 37 NotificationStorage.prototype = {
michael@0 38
michael@0 39 put: function(origin, id, title, dir, lang, body, tag, icon) {
michael@0 40 if (DEBUG) { debug("PUT: " + id + ": " + title); }
michael@0 41 var notification = {
michael@0 42 id: id,
michael@0 43 title: title,
michael@0 44 dir: dir,
michael@0 45 lang: lang,
michael@0 46 body: body,
michael@0 47 tag: tag,
michael@0 48 icon: icon,
michael@0 49 origin: origin
michael@0 50 };
michael@0 51
michael@0 52 this._notifications[id] = notification;
michael@0 53 if (tag) {
michael@0 54 if (!this._byTag[origin]) {
michael@0 55 this._byTag[origin] = {};
michael@0 56 }
michael@0 57
michael@0 58 // We might have existing notification with this tag,
michael@0 59 // if so we need to remove it from our cache.
michael@0 60 if (this._byTag[origin][tag]) {
michael@0 61 var oldNotification = this._byTag[origin][tag];
michael@0 62 delete this._notifications[oldNotification.id];
michael@0 63 }
michael@0 64
michael@0 65 this._byTag[origin][tag] = notification;
michael@0 66 };
michael@0 67
michael@0 68 cpmm.sendAsyncMessage("Notification:Save", {
michael@0 69 origin: origin,
michael@0 70 notification: notification
michael@0 71 });
michael@0 72 },
michael@0 73
michael@0 74 get: function(origin, tag, callback) {
michael@0 75 if (DEBUG) { debug("GET: " + origin + " " + tag); }
michael@0 76 if (this._cached) {
michael@0 77 this._fetchFromCache(origin, tag, callback);
michael@0 78 } else {
michael@0 79 this._fetchFromDB(origin, tag, callback);
michael@0 80 }
michael@0 81 },
michael@0 82
michael@0 83 delete: function(origin, id) {
michael@0 84 if (DEBUG) { debug("DELETE: " + id); }
michael@0 85 var notification = this._notifications[id];
michael@0 86 if (notification) {
michael@0 87 if (notification.tag) {
michael@0 88 delete this._byTag[origin][notification.tag];
michael@0 89 }
michael@0 90 delete this._notifications[id];
michael@0 91 }
michael@0 92
michael@0 93 cpmm.sendAsyncMessage("Notification:Delete", {
michael@0 94 origin: origin,
michael@0 95 id: id
michael@0 96 });
michael@0 97 },
michael@0 98
michael@0 99 receiveMessage: function(message) {
michael@0 100 switch (message.name) {
michael@0 101 case "Notification:GetAll:Return:OK":
michael@0 102 var request = this._requests[message.data.requestID];
michael@0 103 delete this._requests[message.data.requestID];
michael@0 104 this._populateCache(message.data.notifications);
michael@0 105 this._fetchFromCache(request.origin, request.tag, request.callback);
michael@0 106 break;
michael@0 107
michael@0 108 default:
michael@0 109 if (DEBUG) debug("Unrecognized message: " + message.name);
michael@0 110 break;
michael@0 111 }
michael@0 112 },
michael@0 113
michael@0 114 _fetchFromDB: function(origin, tag, callback) {
michael@0 115 var request = {
michael@0 116 origin: origin,
michael@0 117 tag: tag,
michael@0 118 callback: callback
michael@0 119 };
michael@0 120 var requestID = this._requestCount++;
michael@0 121 this._requests[requestID] = request;
michael@0 122 cpmm.sendAsyncMessage("Notification:GetAll", {
michael@0 123 origin: origin,
michael@0 124 requestID: requestID
michael@0 125 });
michael@0 126 },
michael@0 127
michael@0 128 _fetchFromCache: function(origin, tag, callback) {
michael@0 129 var notifications = [];
michael@0 130 // If a tag was specified and we have a notification
michael@0 131 // with this tag, return that. If no tag was specified
michael@0 132 // simple return all stored notifications.
michael@0 133 if (tag && this._byTag[origin] && this._byTag[origin][tag]) {
michael@0 134 notifications.push(this._byTag[origin][tag]);
michael@0 135 } else if (!tag) {
michael@0 136 for (var id in this._notifications) {
michael@0 137 if (this._notifications[id].origin === origin) {
michael@0 138 notifications.push(this._notifications[id]);
michael@0 139 }
michael@0 140 }
michael@0 141 }
michael@0 142
michael@0 143 // Pass each notification back separately.
michael@0 144 notifications.forEach(function(notification) {
michael@0 145 try {
michael@0 146 callback.handle(notification.id,
michael@0 147 notification.title,
michael@0 148 notification.dir,
michael@0 149 notification.lang,
michael@0 150 notification.body,
michael@0 151 notification.tag,
michael@0 152 notification.icon);
michael@0 153 } catch (e) {
michael@0 154 if (DEBUG) { debug("Error calling callback handle: " + e); }
michael@0 155 }
michael@0 156 });
michael@0 157 try {
michael@0 158 callback.done();
michael@0 159 } catch (e) {
michael@0 160 if (DEBUG) { debug("Error calling callback done: " + e); }
michael@0 161 }
michael@0 162 },
michael@0 163
michael@0 164 _populateCache: function(notifications) {
michael@0 165 notifications.forEach(function(notification) {
michael@0 166 this._notifications[notification.id] = notification;
michael@0 167 if (notification.tag && notification.origin) {
michael@0 168 let tag = notification.tag;
michael@0 169 let origin = notification.origin;
michael@0 170 if (!this._byTag[origin]) {
michael@0 171 this._byTag[origin] = {};
michael@0 172 }
michael@0 173 this._byTag[origin][tag] = notification;
michael@0 174 }
michael@0 175 }.bind(this));
michael@0 176 this._cached = true;
michael@0 177 },
michael@0 178
michael@0 179 classID : Components.ID(NOTIFICATIONSTORAGE_CID),
michael@0 180 contractID : NOTIFICATIONSTORAGE_CONTRACTID,
michael@0 181 QueryInterface: XPCOMUtils.generateQI([Ci.nsINotificationStorage,
michael@0 182 Ci.nsIMessageListener]),
michael@0 183 };
michael@0 184
michael@0 185
michael@0 186 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NotificationStorage]);

mercurial