Last active
April 27, 2020 01:12
-
-
Save Rob--W/5926727 to your computer and use it in GitHub Desktop.
Full implementation of webkitNotifications API for Firefox 22+.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name webkitNotifications shim for Firefox 22+ | |
// @namespace https://github.com/Rob--w/ | |
// @author Rob Wu <[email protected]> | |
// @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 <[email protected]> | |
* 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; | |
global.webkitNotifications = { | |
createNotification: createNotification, | |
PERMISSION_ALLOWED: 0, | |
PERMISSION_NOT_ALLOWED: 1, | |
PERMISSION_DENIED: 2, | |
checkPermission: function() { return permission; }, | |
requestPermission: requestPermission | |
}; | |
var permission = 1; // Default permission = "Not allowed" | |
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(); | |
} | |
}; | |
// 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}); | |
}; | |
}); | |
// 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')); | |
// Shorthand for defining properties on webkitNotification | |
function defProp(propertyName, descriptor) { | |
descriptor.enumerable = true; | |
Object.defineProperty(webkitNotification, propertyName, descriptor); | |
} | |
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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@Eraiph fixed in my fork https://gist.github.com/adambom/7755821