Configuring Local Notifications

As of OS X v10.8, webpages in Safari can post notifications to the systemwide notification system known as Notification Center. Local notifications are dispatched by the WebKit Notification object and follow the implementation outlined by the W3C specification.

Requesting Permission

Because your website’s visitors could be running an older version of OS X, first determine whether notifications are supported by their browser. Do this by making sure that the window.Notification object is defined.

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

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

Figure 3-1  A dialog box prompting for permission

Creating and Interacting with Local Notifications

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

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

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

The notification is placed in a queue and is shown when it isn’t preceded by another notification. The subtitle is always the domain or extension name from which the notification originated, and the icon is always the Safari icon, as shown in Figure 3-2.

Figure 3-2  A notification banner

A notification stays in Notification Center (see Figure 3-3) 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.

Figure 3-3  A notification in Notification Center

To remove a local notification from Notification Center immediately after it is clicked, call close() in the notification’s onclick event handler. The onclick event handler, and other JavaScript event handlers, are listed in Table 3-1.

Table 3-1  Available notification events

Event handler

Description

onshow

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

onclick

An event that triggers 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 app is in the foreground.

onclose

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

onerror

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

Listing 3-1 shows how to send a local notification while adhering to the permission level a user has set.

Listing 3-1  Implementing local notification support

var notify = function () {
    // Check for notification compatibility.
    if (!'Notification' in window) {
        // If the browser version is unsupported, remain 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(
                    'New message from Liz',
                    {
                      'body': 'Liz: "Hi there!"',
                      // ...prevent duplicate notifications
                      'tag' : 'unique string'
                    }
                );
        // Remove the notification from Notification Center when 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') {
        // ...remain silent.
        return;
    }
};