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

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

mercurial