Something that’s coming down the pike pretty soon in tandem with HTML5 is the related, but independent W3C draft of a “Notifications” interface.  Basically, this new interface provides a way for the browser to send notification messages on your desktop or device.  So as example, while Facebook Chat will currently use AJAX to update the content on the browser page (causing the annoying tab “flicker” when a new message arrives), using the Notifications interface will allow a browser-independent message to be displayed directly on your desktop.

As with the other items we’ve been exploring in our look at HTML5-related technologies, Notifications are really easy to work with.  A word of warning, however.  Right now, this is only implemented in Chrome, and the W3C spec is itself based upon a webkit-specific API.  So in order to make these work right now, you have to use the Chromium API, not the W3C spec.  The fundamental principles are precisely the same (since the latter is based on the former), but has some minor differences.

So now for the obligatory example–let’s get my (or someone else’s…) most recent Twitter post and display a notification.

First, let’s create a reference to the Notifications object:

var notification = window.webkitNotifications;

(Notice the “webkit” syntax)

Now that we have a reference to our Notifications interface, let’s handle the entering and submitting of a Twitter username:

function SetNotification() {
     var username = Ext.get('twitterusername').getValue();
     if(username=='') {
          Ext.Msg.alert('Attention!','Please enter a Twitter username');
          return false;
     }
     if(notification.checkPermission()==0) {
          GetTwitterData();
     }
     else {
          notification.requestPermission(PermissionDelegate);
     }
}

A few things to point out here.  First, as part of the spec, the user has to grant permissions to the service to create Notifications.  Before we actually handle the requesting of permissions, we can check if permissions already exist by invoking the checkPermission() method.  This will return three possible values:

  1. PERMISSION_ALLOWED = 0;
  2. PERMISSION_NOT_ALLOWED = 1;
  3. PERMISSION_DENIED = 2;

To me, the numbering is a bit counter-intuitive (0 == allowed?), but it’s easy enough to work with.

So if we’ve already obtained permissions, we simply call our main function for retrieving Twitter data.  If permissions do not exist, however, we invoke the requestPermission() method.  This will create a browser prompt, and the user can either Allow or Deny permissions for Notifications.  requestPermission() takes one argument: a callback function.  This can be invoked to handle post-permission granting/denying.  In this example, the callback is PermissionDelegate():

function PermissionDelegate() {    �
     // if permissions have been granted (checkpermission()==0), proceed; otherwise, show error message and cancel operation�
     if(notification.checkPermission()==0) {
          GetTwitterData();
     }
     else {
          Ext.Msg.alert('Notice','To receive notifications from this application, please grant permissions when prompted.<br /><br />Please try again.');
     }
}

Simple enough.  If the user grants permissions (checkPermission()==0), we continue with the processing.  If not, we display an error message and suggest that the users tries the operation again.

So on with the example.  I won’t bore you with the process of getting the Twitter post.  If you want, you can check the source code, but it boils down to the nifty JSONP hack

Now that we’ve been granted permission to create Notifications, and finally have the Twitter data, let’s create a notification!

function TweetSuccess(req) {
     if(req.length) {
          var type = Ext.getCmp('radiogroup').getValue().value;
          var img     = req[0].user.profile_image_url;
          var name    = req[0].user.screen_name;
          var tweet    = req[0].text;
          if(type==1) {
               var tweet    = tweet.parseURL().parseUsername().parseHashtag();
               notification.createHTMLNotification("notification_helper.cfm?title="+name+"&img="+img+"&content="+tweet).show();
          }
          else {
               notification.createNotification(img,name,tweet).show();
          }
      }
      else {
           Ext.Msg.alert('Uh-oh','Sorry, that\'s not a valid Twitter username. Please try again!');
           return false;
      }
}

Most of this function is just getting the values from the returned data, so we’ll skip to the important stuff: createNotification() and createHTMLNotification().

Why two methods?  Well, each provides a little bit different way of displaying notifications, of course! 🙂

createNotification() creates a standard, vanilla notification that inherits whatever styles the browser has defined for its notifications.  This method takes three arguments:

  1. iconUrl – This is the path (absolute) of the icon that you would like displayed in the notification
  2. title – Um, the title of the notification 🙂
  3. body –  The main content to be displayed in the notification.

While this works pretty nicely, I wasn’t thrilled with the look of the notification.  And although I didn’t pursue it very far, I couldn’t get links or any other styling to show up in the notification.

createHTMLNotifications() picks up where createNotification() falls short in the customization department.  Whereas you pass icons, titles, and body content to createNotification(), you simply pass a url to a page that defines your notification content for createHTMLNotifications().  While this creates a bit more work for arranging icons, titles, and body content, it does allow you to be a bit more creative in how the notifications look.  Plus, since it’s an HTML notification, you can use some nifty CSS3, and who doesn’t love that!

Wrapping Up

There’s a bunch more to Notifications that I didn’t cover (like closing them programmatically, etc.), but hopefully this is a nice introduction to the concepts behind what will hopefully be embraced by all browsers in the very near future.  I see a lot of promise to these, and can’t wait until all the environments are more unified to start utilizing them to their full potential.

As always, be sure to check out the demo (remember, Chrome only :)) and let me know what you think.