andy-h
2/12/2014 - 7:49 PM

Cross-browser desktop notifications (for supporting browsers)

Cross-browser desktop notifications (for supporting browsers)

<html>
<head>
	
	<title>Notifications Test Page</title>
	
	<style type="text/css" media="all">
		#log {
			padding:0.5em;
			background-color:#EEE;
			font-family:"Envy Code R", Monaco, Arial, Helvetica, sans-serif;
			font-size:80%;
			overflow:auto;
			width:99%;
		}
		#log div {
			transition-property:background-color, color;
			transition-duration:0.75s, 0.25s;
			transition-delay:0.01s, 0.2s;
		}
		#log div:hover {
			background-color:#AAA;
			color:white;
		}
	</style>
	<script type="text/javascript">
		function log(s,top){var l=document.getElementById("log");var h=l.innerHTML;l.innerHTML=top?"<div>"+s+"</div>"+h:h+"<div>"+s+"</div>"}
	</script>
	
	<script type="text/javascript" src="notifications.js"></script>
	<script type="text/javascript">
		
		var n = 0;
		
		window.onload = function (evt){
			
			function requestPermission(evt){
				
				if(Notifier.permission === "default"){
					log("Click \"Allow\" to authorize this site to display notifications.");
				}
				
				Notifier.requestPermission(function (permission){ log("Permission: "+permission); });
				
			}
			
			function notify(evt){
				
				Notifier.notify("Test #"+(++n), {
						body: Date(),
						tag: "foo"+n,
						onError: function (){
								if(Notifier.permission === "default"){
									log("#"+this.tag.slice(3)+" error: Notifications have not yet been authorized. Permission: "+Notifier.permission);
									askForAuthorization();
								}
								else{
									log("#"+this.tag.slice(3)+" error: Notifications have been blocked for this site. Permission: "+Notifier.permission);
								}
							},
						onShow: function (){
								log("#"+this.tag.slice(3)+" shown");
								this.timer = setTimeout((function (nt){ return function (){ nt.close(); }; })(this), 5000);
							},
						onClick: function (){
								log("#"+this.tag.slice(3)+" clicked");
								//this.close();
								clearTimeout(this.timer);
							},
						onClose: function (){ log("#"+this.tag.slice(3)+" closed"); }
					});
				
			}
			
			function askForAuthorization(){
				log("Click \"Request Permission\" to set notification permissions for this site.");
			}
			
			if(Notifier.isSupported){
				document.getElementById("requestPermission").addEventListener("click", requestPermission, false);
				document.getElementById("notify").addEventListener("click", notify, false);
				
				log("Permission: "+Notifier.permission);
				if(Notifier.permission === "default") askForAuthorization();
			}
			else{
				log("Desktop notifications are not supported in this browser.");
			}
			
		};
		
	</script>
	
</head>
<body>
	
	<div><input type="button" id="requestPermission" value="Request Permission"></div>
	<div><input type="button" id="notify" value="Notify"></div>
	
	<div id="log"></div>
	
</body>
</html>
//http://www.w3.org/TR/notifications/
//https://developer.mozilla.org/en-US/docs/Web/API/notification

//Notifier.isSupported
//
//Notifier.permission	//"granted", "denied", or "default"
//
//Notifier.requestPermission([callback])	//first argument of callback is the current permission
//
//Notifier.notify(title[, options])
//	options:	tag, icon, body, dir, lang, onError, onShow, onClick, onClose

var Notifier = {};

(function (window){
	
	"use strict";
	
	var permissions = ["granted", "default", "denied"];
	
	this.isSupported = true;
	
	if(window.Notification){
		//console.log("Notification");
		
		this.permission = window.Notification.permission;
		if(!this.permission && window.webkitNotifications){
			this.permission = permissions[window.webkitNotifications.checkPermission()];
		}
		
		this.requestPermission = function requestPermission(callback){
			var that = this;
			window.Notification.requestPermission(function (permission){
					that.permission = permission;
					callback(permission);
				});
		};
		
		this.notify = function notify(title, options){
			var that = this,
				ntf = new window.Notification(title, options);
			options = options || {};
			ntf.onerror = function (evt){
					that.permission = window.Notification.permission;
					options.onError(evt);
				};
			ntf.onshow = options.onShow;
			ntf.onclick = options.onClick;
			ntf.onclose = options.onClose;
			return ntf;
		};
		
	}
	else if(window.mozNotification){	//before Firefox 22 (Firefox Mobile only)
		//console.log("mozNotification");
		
		this.permission = window.mozNotification.permission;
		
		this.requestPermission = function requestPermission(callback){
			var that = this;
			window.mozNotification.requestPermission(function (permission){
					that.permission = permission;
					callback(permission);
				});
		};
		
		this.notify = function notify(title, options){
			var that = this,
				ntf = window.mozNotification.createNotification(title, options.body || "", options.icon);
			options = options || {};
			ntf.onerror = function (evt){
					that.permission = window.mozNotification.permission;
					options.onError(evt);
				};
			ntf.onshow = options.onShow;	//not supported
			ntf.onclick = options.onClick;
			ntf.onclose = options.onClose;
			ntf.show();
			return ntf;
		};
		
	}
	else if(window.webkitNotifications){	//before Chrome 22
		//console.log("webkitNotifications");
		
		this.permission = permissions[window.webkitNotifications.checkPermission()];
		
		this.requestPermission = function requestPermission(callback){
			var that = this;
			window.webkitNotifications.requestPermission(function (permission){
					that.permission = permission;
					callback(permission);
				});
		};
		
		this.notify = function notify(title, options){
			var that = this,
				ntf = window.webkitNotifications.createNotification(options.icon || null, title, options.body || "");
			options = options || {};
			ntf.onerror = function (evt){
					that.permission = permissions[window.webkitNotifications.checkPermission()];
					options.onError(evt);
				};
			ntf.ondisplay = options.onShow;
			ntf.onclick = options.onClick;
			ntf.onclose = options.onClose;
			ntf.close = ntf.cancel;
			ntf.show();
			return ntf;
		};
		
	}
	else {
		
		this.isSupported = false;
		
	}
	
}).call(Notifier, this);