/* * Copyright 2014 * @author Loic J. Duros lduros@member.fsf.org * @author Joshua Cornutt jcornutt@gmail.com * 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 { Cc, Ci } = require("chrome"); const { getMostRecentBrowserWindow } = require('sdk/window/utils'); /* I haven't found this sort of validation functions in the SDK, except for the deprecated api-utils module. */ let isString = function (str) { if ( !str ) return false; return typeof(str) == 'string' || str instanceof String; }; let isArray = function (obj) { if ( !obj || typeof(obj) === 'undefined' ) return false; return Object.prototype.toString.call(obj) === '[object Array]'; }; let isObject = function(obj) { if ( !obj || typeof(obj) === 'undefined' ) return false; return obj instanceof Object; } let isInteger = function(val) { if ((undefined === val) || (null === val)) return false; return !isNaN(val); } let isFunction = function(obj) { if ( !obj || typeof(obj) === 'undefined' ) return false; return {}.toString.call(obj) === '[object Function]'; } exports.NotificationBox = function (options) { options = options || {}; let mainWindow = getMostRecentBrowserWindow(); let nbObj = mainWindow.gBrowser.getNotificationBox(); let priority = nbObj[PRIORITY.INFO_LOW], label = '', image = 'chrome://browser/skin/Info.png', value = '', persistence = 0, eventCallback = function(){}, buttons = []; if (options.value && isString(options.value)) value = options.value; // Set how many page changes the notification will remain active for. if ( options.persistence && isInteger(options.persistence) ) persistence = options.persistence; // Set if the user wants to be notified when the notification closes if ( options.eventCallback && isFunction(options.eventCallback) ) eventCallback = options.eventCallback; // Add label or create empty notification. if (options.label && isString(options.label)) label = options.label; // Set priority of the notification (from INFO_LOW to CRITICAL_BLOCK) if (options.priority && options.priority in PRIORITY) priority = nbObj[PRIORITY[options.priority]]; // Set a custom icon for the notification or use the stock info icon. if (options.image && isString(options.image)) image = options.image; // Sanitize and format each notification button if ( isArray(options.buttons) ) for (let i = 0, length = options.buttons.length; i < length; i++) buttons.push(NotificationButton(options.buttons[i])); else if ( isObject(options.buttons) ) // If it's not an array of buttons, then it should be a single button. buttons.push(NotificationButton(options.buttons)); else buttons = null; // Add a new notification to the notificationbox. var nObj = nbObj.appendNotification(label, value, image, priority, buttons, eventCallback); // Set how many page changes the notification will stay active for nObj.persistence = persistence; // Timeout for closing the notification automatically if( options.timeout && isInteger(options.timeout) ) { require('sdk/timers').setTimeout( function() { if( isFunction(nObj.close) ) nObj.close(); }, options.timeout ); } // Expose both the NotificationBox and Notification itself return {'notificationbox': nbObj, 'notification': nObj}; }; // Notification button santizing function var NotificationButton = function (options) { options = options || {}; let accessKey = '', onClick = function(){}, label = "", popup = null, // no popup for now... maybe we can use a panel later. timeout = 0; if ( options.accessKey ) accessKey = options.accessKey; if ( isFunction(options.onClick) ) onClick = options.onClick; if ( options.label ) label = options.label; if ( isInteger(options.timeout) ) timeout = options.timeout; return {label: label, accessKey: accessKey, callback: onClick, popup: popup, timeout: timeout}; }; const PRIORITY = { 'INFO_LOW': 'PRIORITY_INFO_LOW', 'INFO_MEDIUM': 'PRIORITY_INFO_MEDIUM', 'INFO_HIGH': 'PRIORITY_INFO_HIGH', 'WARNING_LOW': 'PRIORITY_WARNING_LOW', 'WARNING_MEDIUM': 'PRIORITY_WARNING_MEDIUM', 'WARNING_HIGH': 'PRIORITY_WARNING_HIGH', 'CRITICAL_LOW': 'PRIORITY_CRITICAL_LOW', 'CRITICAL_MEDIUM': 'PRIORITY_CRITICAL_MEDIUM', 'CRITICAL_HIGH': 'PRIORITY_CRITICAL_HIGH', 'CRITICAL_BLOCK': 'PRIORITY_CRITICAL_BLOCK' }; exports.PRIORITY = PRIORITY;