services/sync/modules/notifications.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/services/sync/modules/notifications.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,128 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +this.EXPORTED_SYMBOLS = ["Notifications", "Notification", "NotificationButton"];
     1.9 +
    1.10 +const Cc = Components.classes;
    1.11 +const Ci = Components.interfaces;
    1.12 +const Cr = Components.results;
    1.13 +const Cu = Components.utils;
    1.14 +
    1.15 +Cu.import("resource://services-common/observers.js");
    1.16 +Cu.import("resource://gre/modules/Log.jsm");
    1.17 +Cu.import("resource://services-sync/util.js");
    1.18 +
    1.19 +this.Notifications = {
    1.20 +  // Match the referenced values in toolkit/content/widgets/notification.xml.
    1.21 +  get PRIORITY_INFO()     1, // PRIORITY_INFO_LOW
    1.22 +  get PRIORITY_WARNING()  4, // PRIORITY_WARNING_LOW
    1.23 +  get PRIORITY_ERROR()    7, // PRIORITY_CRITICAL_LOW
    1.24 +
    1.25 +  // FIXME: instead of making this public, dress the Notifications object
    1.26 +  // to behave like an iterator (using generators?) and have callers access
    1.27 +  // this array through the Notifications object.
    1.28 +  notifications: [],
    1.29 +
    1.30 +  _observers: [],
    1.31 +
    1.32 +  // XXX Should we have a helper method for adding a simple notification?
    1.33 +  // I.e. something like |function notify(title, description, priority)|.
    1.34 +
    1.35 +  add: function Notifications_add(notification) {
    1.36 +    this.notifications.push(notification);
    1.37 +    Observers.notify("weave:notification:added", notification, null);
    1.38 +  },
    1.39 +
    1.40 +  remove: function Notifications_remove(notification) {
    1.41 +    let index = this.notifications.indexOf(notification);
    1.42 +
    1.43 +    if (index != -1) {
    1.44 +      this.notifications.splice(index, 1);
    1.45 +      Observers.notify("weave:notification:removed", notification, null);
    1.46 +    }
    1.47 +  },
    1.48 +
    1.49 +  /**
    1.50 +   * Replace an existing notification.
    1.51 +   */
    1.52 +  replace: function Notifications_replace(oldNotification, newNotification) {
    1.53 +    let index = this.notifications.indexOf(oldNotification);
    1.54 +
    1.55 +    if (index != -1)
    1.56 +      this.notifications.splice(index, 1, newNotification);
    1.57 +    else {
    1.58 +      this.notifications.push(newNotification);
    1.59 +      // XXX Should we throw because we didn't find the existing notification?
    1.60 +      // XXX Should we notify observers about weave:notification:added?
    1.61 +    }
    1.62 +
    1.63 +    // XXX Should we notify observers about weave:notification:replaced?
    1.64 +  },
    1.65 +
    1.66 +  /**
    1.67 +   * Remove all notifications that match a title. If no title is provided, all
    1.68 +   * notifications are removed.
    1.69 +   *
    1.70 +   * @param title [optional]
    1.71 +   *        Title of notifications to remove; falsy value means remove all
    1.72 +   */
    1.73 +  removeAll: function Notifications_removeAll(title) {
    1.74 +    this.notifications.filter(function(old) old.title == title || !title).
    1.75 +      forEach(function(old) this.remove(old), this);
    1.76 +  },
    1.77 +
    1.78 +  // replaces all existing notifications with the same title as the new one
    1.79 +  replaceTitle: function Notifications_replaceTitle(notification) {
    1.80 +    this.removeAll(notification.title);
    1.81 +    this.add(notification);
    1.82 +  }
    1.83 +};
    1.84 +
    1.85 +
    1.86 +/**
    1.87 + * A basic notification.  Subclass this to create more complex notifications.
    1.88 + */
    1.89 +this.Notification =
    1.90 + function Notification(title, description, iconURL, priority, buttons) {
    1.91 +  this.title = title;
    1.92 +  this.description = description;
    1.93 +
    1.94 +  if (iconURL)
    1.95 +    this.iconURL = iconURL;
    1.96 +
    1.97 +  if (priority)
    1.98 +    this.priority = priority;
    1.99 +
   1.100 +  if (buttons)
   1.101 +    this.buttons = buttons;
   1.102 +}
   1.103 +
   1.104 +// We set each prototype property individually instead of redefining
   1.105 +// the entire prototype to avoid blowing away existing properties
   1.106 +// of the prototype like the the "constructor" property, which we use
   1.107 +// to bind notification objects to their XBL representations.
   1.108 +Notification.prototype.priority = Notifications.PRIORITY_INFO;
   1.109 +Notification.prototype.iconURL = null;
   1.110 +Notification.prototype.buttons = [];
   1.111 +
   1.112 +/**
   1.113 + * A button to display in a notification.
   1.114 + */
   1.115 +this.NotificationButton =
   1.116 + function NotificationButton(label, accessKey, callback) {
   1.117 +  function callbackWrapper() {
   1.118 +    try {
   1.119 +      callback.apply(this, arguments);
   1.120 +    } catch (e) {
   1.121 +      let logger = Log.repository.getLogger("Sync.Notifications");
   1.122 +      logger.error("An exception occurred: " + Utils.exceptionStr(e));
   1.123 +      logger.info(Utils.stackTrace(e));
   1.124 +      throw e;
   1.125 +    }
   1.126 +  }
   1.127 +
   1.128 +  this.label = label;
   1.129 +  this.accessKey = accessKey;
   1.130 +  this.callback = callbackWrapper;
   1.131 +}

mercurial