1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/lib/sdk/notifications.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,103 @@ 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 +"use strict"; 1.9 + 1.10 +module.metadata = { 1.11 + "stability": "stable" 1.12 +}; 1.13 + 1.14 +const { Cc, Ci, Cr } = require("chrome"); 1.15 +const apiUtils = require("./deprecated/api-utils"); 1.16 +const errors = require("./deprecated/errors"); 1.17 +const { isString, isUndefined, instanceOf } = require('./lang/type'); 1.18 +const { URL } = require('./url'); 1.19 + 1.20 +const NOTIFICATION_DIRECTIONS = ["auto", "ltr", "rtl"]; 1.21 + 1.22 +try { 1.23 + let alertServ = Cc["@mozilla.org/alerts-service;1"]. 1.24 + getService(Ci.nsIAlertsService); 1.25 + 1.26 + // The unit test sets this to a mock notification function. 1.27 + var notify = alertServ.showAlertNotification.bind(alertServ); 1.28 +} 1.29 +catch (err) { 1.30 + // An exception will be thrown if the platform doesn't provide an alert 1.31 + // service, e.g., if Growl is not installed on OS X. In that case, use a 1.32 + // mock notification function that just logs to the console. 1.33 + notify = notifyUsingConsole; 1.34 +} 1.35 + 1.36 +exports.notify = function notifications_notify(options) { 1.37 + let valOpts = validateOptions(options); 1.38 + let clickObserver = !valOpts.onClick ? null : { 1.39 + observe: function notificationClickObserved(subject, topic, data) { 1.40 + if (topic === "alertclickcallback") 1.41 + errors.catchAndLog(valOpts.onClick).call(exports, valOpts.data); 1.42 + } 1.43 + }; 1.44 + function notifyWithOpts(notifyFn) { 1.45 + notifyFn(valOpts.iconURL, valOpts.title, valOpts.text, !!clickObserver, 1.46 + valOpts.data, clickObserver, valOpts.tag, valOpts.dir, valOpts.lang); 1.47 + } 1.48 + try { 1.49 + notifyWithOpts(notify); 1.50 + } 1.51 + catch (err) { 1.52 + if (err instanceof Ci.nsIException && err.result == Cr.NS_ERROR_FILE_NOT_FOUND) { 1.53 + console.warn("The notification icon named by " + valOpts.iconURL + 1.54 + " does not exist. A default icon will be used instead."); 1.55 + delete valOpts.iconURL; 1.56 + notifyWithOpts(notify); 1.57 + } 1.58 + else { 1.59 + notifyWithOpts(notifyUsingConsole); 1.60 + } 1.61 + } 1.62 +}; 1.63 + 1.64 +function notifyUsingConsole(iconURL, title, text) { 1.65 + title = title ? "[" + title + "]" : ""; 1.66 + text = text || ""; 1.67 + let str = [title, text].filter(function (s) s).join(" "); 1.68 + console.log(str); 1.69 +} 1.70 + 1.71 +function validateOptions(options) { 1.72 + return apiUtils.validateOptions(options, { 1.73 + data: { 1.74 + is: ["string", "undefined"] 1.75 + }, 1.76 + iconURL: { 1.77 + is: ["string", "undefined", "object"], 1.78 + ok: function(value) { 1.79 + return isUndefined(value) || isString(value) || (value instanceof URL); 1.80 + }, 1.81 + msg: "`iconURL` must be a string or an URL instance." 1.82 + }, 1.83 + onClick: { 1.84 + is: ["function", "undefined"] 1.85 + }, 1.86 + text: { 1.87 + is: ["string", "undefined", "number"] 1.88 + }, 1.89 + title: { 1.90 + is: ["string", "undefined", "number"] 1.91 + }, 1.92 + tag: { 1.93 + is: ["string", "undefined", "number"] 1.94 + }, 1.95 + dir: { 1.96 + is: ["string", "undefined"], 1.97 + ok: function(value) { 1.98 + return isUndefined(value) || ~NOTIFICATION_DIRECTIONS.indexOf(value); 1.99 + }, 1.100 + msg: '`dir` option must be one of: "auto", "ltr" or "rtl".' 1.101 + }, 1.102 + lang: { 1.103 + is: ["string", "undefined"] 1.104 + } 1.105 + }); 1.106 +}