Sending Notifications

As of OS X 10.8 Mountain Lion, web pages in Safari can post notifications to the systemwide notification system known as Notification Center. Notifications are dispatched by the WebKit Notification object and follow the implementation outlined by the W3C specification.

../art/noti1.png

Users can set notification preferences for Safari in two places. Notifications from Safari respect the user’s system setting in the Notifications pane of System Preferences. Some users might desire Safari’s notifications to display as alerts, which stay on the screen until dismissed, while others might choose not to display notifications at all. Additionally, users can set their notification preference on a per-domain basis in the Notifications pane in Safari’s preferences as shown in Figure 1, granting permission for some websites to send notifications while denying permission to others.

Figure 1  Notification preference pane in Safari

Because some users may have configured their system or browser to block your notifications, be sure you present only information that is informative—but not crucial.

Requesting Permission

Because your website’s visitors could be running other operating systems, you should first determine whether notifications are supported by their browser. You can do this by asserting that the window.Notification object is not undefined.

If the window.Notification object does indeed exist, you can continue to check for permissions by accessing the permission property. There are three possible states permission can return:

If the permission level is default, it is likely that the user hasn’t yet been prompted to grant access to notifications from your domain. Prompt your users with the Safari native dialog box, as shown in Figure 2, by calling the requestPermission() function. This function accepts one parameter, a callback function, which executes when the user grants or denies permission.

Figure 2  Dialog box prompting for permission

Creating and Interacting with Notifications

Creating a notification is as simple as creating a new object.

var n = new Notification(in String title [, in Object options]);

The only required parameter is the title. Available keys that can be included in the options object are as follows:

The notification is placed in a queue and will be shown when no notifications precede it. The subtitle is always the domain or extension name from which the notification originated, and the icon is always the Safari icon.

../art/noti4.png

The notification stays in Notification Center until the user explicitly clears all notifications from Safari, or until you close the notification programmatically. To close notifications programmatically, call the close() function on the notification object. If you want to, for example, remove notifications from Notification Center immediately after they are clicked, call close() in the notification’s onclick event handler. The onclick event handler, among others, are further described in Table 1.

To add functionality to notifications, attach functions to event listeners on the notification objects. The following events are available:

Table 1  Available notification events

Event handler

Description

onshow

An event that fires when the notification is first presented onscreen.

onclick

An event that fires if the user clicks on the notification as an alert, a banner, or in Notification Center. By default, clicking a notification brings the receiving window into focus, even if another application is in the foreground.

onclose

An event that fires when the notification is dismissed, or closed in Notification Center. Calling close() on the notification object will trigger the onclose event handler.

onerror

An event that fires when the notification cannot be presented to the user. This event is fired if the permission level is set to denied or default.

Listing 1 illustrates how to send a notification while adhering to the user’s permission level.

Listing 1  JavaScript implementation of notification support

var notify = function() {
    // check for notification compatibility
    if(!window.Notification) {
        // if browser version is unsupported, be silent
        return;
    }
    // log current permission level
    console.log(Notification.permission);
    // if the user has not been asked to grant or deny notifications from this domain
    if(Notification.permission === 'default') {
        Notification.requestPermission(function() {
            // callback this function once a permission level has been set
            notify();
        });
    }
    // if the user has granted permission for this domain to send notifications
    else if(Notification.permission === 'granted') {
        var n = new Notification(
                    '1 new friend request',
                    {
                      'body': 'Jill would like to add you as a friend',
                      // prevent duplicate notifications
                      'tag' : 'unique string'
                    }
                );
        // remove the notification from Notification Center when it is clicked
        n.onclick = function() {
            this.close();
        };
        // callback function when the notification is closed
        n.onclose = function() {
            console.log('Notification closed');
        };
    }
    // if the user does not want notifications to come from this domain
    else if(Notification.permission === 'denied') {
        // be silent
        return;
    }
};