UNPKG

angular-extended-notifications

Version:

Highly customizable notifications with AngularJS

145 lines (130 loc) 5 kB
// ==UserScript== // @name webkitNotifications shim for Firefox 22+ // @namespace https://github.com/Rob--w/ // @author Rob Wu <gwnRob@gmail.com> // @description Enable desktop notifications on Firefox 22+ for websites which use the webkitNotification API. // @include * // @version 1.0.2 // @grant none // ==/UserScript== /** * (c) 2013 Rob Wu <gwnRob@gmail.com> * adapted by https://github.com/adambom * adapted by https://github.com/Ornthalas * License: WTFPL * * This shim fully implements the legacy webkitNotifications API * Usable as a library or user script. * * References: * - http://www.chromium.org/developers/design-documents/desktop-notifications/api-specification * - http://notifications.spec.whatwg.org/ * - chromium/src/third_party/WebKit/Source/modules/notifications/Notification.h * - chromium/src/third_party/WebKit/Source/modules/notifications/Notification.idl */ (function(global) { 'use strict'; if (global.webkitNotifications || typeof Notification == 'undefined') return; var permission; // Default permission = "Not allowed" if (Notification.permission === 'granted') { permission = 0; } else if (Notification.permission === 'denied') { permission = 2; } else if (Notification.permission === 'default') { permission = 1; } function createNotification(iconURL, title, text) { var notificationOptions = {}; if (text) notificationOptions.body = text; if (iconURL) notificationOptions.icon = iconURL; notificationOptions.title = title || ''; var notification; // List of events which we want to expose var eventNames = [ 'onshow', 'onerror', 'onclose', 'onclick' ]; // Object which holds the DOM0 event listener until the notification is shown. var eventTarget = {}; // An implementation of the webkitNotification interface var webkitNotification = { show: function show() { if (notification) return; notification = new Notification(title, notificationOptions); // Call delayed addEventListener, removeEventListener, ... var o; while( (o = replayQueue.shift()) ) { notification[o.methodName].apply(notification, o.arguments); } // Synchronize DOM0 events eventNames.forEach(function(eventName) { notification[eventName] = eventTarget[eventName]; }); eventTarget = notification; }, cancel: function cancel() { if (notification) notification.close(); }, // Not in spec, but present in Chrome. Included for consistency. close: function close() { if (notification) notification.close(); } }; global.webkitNotifications = { createNotification: createNotification, PERMISSION_ALLOWED: 0, PERMISSION_NOT_ALLOWED: 1, PERMISSION_DENIED: 2, checkPermission: function() { return permission; }, requestPermission: requestPermission }; // Implement EventTarget on webkitNotification var replayQueue = []; [ 'addEventListener', 'removeEventListener', 'dispatchEvent' ].forEach(function(methodName) { webkitNotification[methodName] = function() { // Call method directly on the notification object, if available. if (notification) return notification[methodName].apply(notification, arguments); // Notification not yet visible, queue the call for later use. replayQueue.push({methodName: methodName, arguments: arguments}); }; }); // Shorthand for defining properties on webkitNotification function defProp(propertyName, descriptor) { descriptor.enumerable = true; Object.defineProperty(webkitNotification, propertyName, descriptor); } // Implement DOM0 event binding. eventNames.forEach(function(eventName) { defProp(eventName, { get: function() { return eventTarget[eventName] || null; }, set: function(f) { eventTarget[eventName] = typeof f == 'function' ? f : null; } }); }); // Alias ondisplay <> onshow defProp('ondisplay', Object.getOwnPropertyDescriptor(webkitNotification, 'onshow')); // dir and tag setters. Only relevant before the show() method has been called. ['dir', 'tag'].forEach(function(propertyName) { defProp(propertyName, { get: function() { return notificationOptions[propertyName] || ''; }, set: function(value) { notificationOptions[propertyName] = value; } }); }); // Alias replaceId <> tag defProp('replaceid', Object.getOwnPropertyDescriptor(webkitNotification, 'tag')); return webkitNotification; } function requestPermission(callback) { Notification.requestPermission(function(p) { permission = p == 'granted' ? 0 : p == 'denied' ? 2 : /*'default*/ 1; if (callback) { callback(); } }); } })(typeof unsafeWindow == 'undefined' ? this : unsafeWindow);