mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 02:09:05 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			212 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			212 lines
		
	
	
	
		
			5.4 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 ToolkitModules = {};
 | 
						|
 | 
						|
ChromeUtils.defineESModuleGetters(ToolkitModules, {
 | 
						|
  EventEmitter: "resource://gre/modules/EventEmitter.sys.mjs",
 | 
						|
});
 | 
						|
 | 
						|
var { ignoreEvent } = ExtensionCommon;
 | 
						|
 | 
						|
// Manages a notification popup (notifications API) created by the extension.
 | 
						|
function Notification(context, notificationsMap, id, options) {
 | 
						|
  this.notificationsMap = notificationsMap;
 | 
						|
  this.id = id;
 | 
						|
  this.options = options;
 | 
						|
 | 
						|
  let imageURL;
 | 
						|
  if (options.iconUrl) {
 | 
						|
    imageURL = context.extension.baseURI.resolve(options.iconUrl);
 | 
						|
  }
 | 
						|
 | 
						|
  // Set before calling into nsIAlertsService, because the notification may be
 | 
						|
  // closed during the call.
 | 
						|
  notificationsMap.set(id, this);
 | 
						|
 | 
						|
  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,
 | 
						|
      undefined,
 | 
						|
      undefined,
 | 
						|
      undefined,
 | 
						|
      // Principal is not set because doing so reveals buttons to control
 | 
						|
      // notification preferences, which are currently not implemented for
 | 
						|
      // notifications triggered via this extension API (bug 1589693).
 | 
						|
      undefined,
 | 
						|
      context.incognito
 | 
						|
    );
 | 
						|
  } catch (e) {
 | 
						|
    // This will fail if alerts aren't available on the system.
 | 
						|
 | 
						|
    this.observe(null, "alertfinished", id);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
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.
 | 
						|
    }
 | 
						|
    this.notificationsMap.delete(this.id);
 | 
						|
  },
 | 
						|
 | 
						|
  observe(subject, topic, data) {
 | 
						|
    switch (topic) {
 | 
						|
      case "alertclickcallback":
 | 
						|
        this.notificationsMap.emit("clicked", data);
 | 
						|
        break;
 | 
						|
      case "alertfinished":
 | 
						|
        this.notificationsMap.emit("closed", data);
 | 
						|
        this.notificationsMap.delete(this.id);
 | 
						|
        break;
 | 
						|
      case "alertshow":
 | 
						|
        this.notificationsMap.emit("shown", data);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  },
 | 
						|
};
 | 
						|
 | 
						|
this.notifications = class extends ExtensionAPIPersistent {
 | 
						|
  constructor(extension) {
 | 
						|
    super(extension);
 | 
						|
 | 
						|
    this.nextId = 0;
 | 
						|
    this.notificationsMap = new Map();
 | 
						|
    ToolkitModules.EventEmitter.decorate(this.notificationsMap);
 | 
						|
  }
 | 
						|
 | 
						|
  onShutdown() {
 | 
						|
    for (let notification of this.notificationsMap.values()) {
 | 
						|
      notification.clear();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  PERSISTENT_EVENTS = {
 | 
						|
    onClosed({ fire }) {
 | 
						|
      let listener = (event, notificationId) => {
 | 
						|
        // TODO Bug 1413188, Support the byUser argument.
 | 
						|
        fire.async(notificationId, true);
 | 
						|
      };
 | 
						|
 | 
						|
      this.notificationsMap.on("closed", listener);
 | 
						|
      return {
 | 
						|
        unregister: () => {
 | 
						|
          this.notificationsMap.off("closed", listener);
 | 
						|
        },
 | 
						|
        convert(_fire) {
 | 
						|
          fire = _fire;
 | 
						|
        },
 | 
						|
      };
 | 
						|
    },
 | 
						|
    onClicked({ fire }) {
 | 
						|
      let listener = (event, notificationId) => {
 | 
						|
        fire.async(notificationId);
 | 
						|
      };
 | 
						|
 | 
						|
      this.notificationsMap.on("clicked", listener);
 | 
						|
      return {
 | 
						|
        unregister: () => {
 | 
						|
          this.notificationsMap.off("clicked", listener);
 | 
						|
        },
 | 
						|
        convert(_fire) {
 | 
						|
          fire = _fire;
 | 
						|
        },
 | 
						|
      };
 | 
						|
    },
 | 
						|
    onShown({ fire }) {
 | 
						|
      let listener = (event, notificationId) => {
 | 
						|
        fire.async(notificationId);
 | 
						|
      };
 | 
						|
 | 
						|
      this.notificationsMap.on("shown", listener);
 | 
						|
      return {
 | 
						|
        unregister: () => {
 | 
						|
          this.notificationsMap.off("shown", listener);
 | 
						|
        },
 | 
						|
        convert(_fire) {
 | 
						|
          fire = _fire;
 | 
						|
        },
 | 
						|
      };
 | 
						|
    },
 | 
						|
  };
 | 
						|
 | 
						|
  getAPI(context) {
 | 
						|
    let notificationsMap = this.notificationsMap;
 | 
						|
 | 
						|
    return {
 | 
						|
      notifications: {
 | 
						|
        create: (notificationId, options) => {
 | 
						|
          if (!notificationId) {
 | 
						|
            notificationId = String(this.nextId++);
 | 
						|
          }
 | 
						|
 | 
						|
          if (notificationsMap.has(notificationId)) {
 | 
						|
            notificationsMap.get(notificationId).clear();
 | 
						|
          }
 | 
						|
 | 
						|
          new Notification(context, notificationsMap, notificationId, options);
 | 
						|
 | 
						|
          return Promise.resolve(notificationId);
 | 
						|
        },
 | 
						|
 | 
						|
        clear: function (notificationId) {
 | 
						|
          if (notificationsMap.has(notificationId)) {
 | 
						|
            notificationsMap.get(notificationId).clear();
 | 
						|
            return Promise.resolve(true);
 | 
						|
          }
 | 
						|
          return Promise.resolve(false);
 | 
						|
        },
 | 
						|
 | 
						|
        getAll: function () {
 | 
						|
          let result = {};
 | 
						|
          notificationsMap.forEach((value, key) => {
 | 
						|
            result[key] = value.options;
 | 
						|
          });
 | 
						|
          return Promise.resolve(result);
 | 
						|
        },
 | 
						|
 | 
						|
        onClosed: new EventManager({
 | 
						|
          context,
 | 
						|
          module: "notifications",
 | 
						|
          event: "onClosed",
 | 
						|
          extensionApi: this,
 | 
						|
        }).api(),
 | 
						|
 | 
						|
        onClicked: new EventManager({
 | 
						|
          context,
 | 
						|
          module: "notifications",
 | 
						|
          event: "onClicked",
 | 
						|
          extensionApi: this,
 | 
						|
        }).api(),
 | 
						|
 | 
						|
        onShown: new EventManager({
 | 
						|
          context,
 | 
						|
          module: "notifications",
 | 
						|
          event: "onShown",
 | 
						|
          extensionApi: this,
 | 
						|
        }).api(),
 | 
						|
 | 
						|
        // TODO Bug 1190681, implement button support.
 | 
						|
        onButtonClicked: ignoreEvent(context, "notifications.onButtonClicked"),
 | 
						|
      },
 | 
						|
    };
 | 
						|
  }
 | 
						|
};
 |