The future is HTML5

HTML5


HTML5 Authors: Elizabeth White, Marcin Warpechowski, Kevin Benedict, Xenia von Wedel, Pat Romanski

Related Topics: RIA Developer's Journal, JavaScript, HTML5

Article

Book Excerpt: Introducing HTML5

HTML5 marks a groundbreaking change in how we interact with the browser

Web Storage
Web Storage provides several APIs for saving data on the client in a fashion similar to browser cookies. There is a Storage object for data that needs to persist between restarts named localStorage and one for data that will be purged once the session ends named sessionStorage. The data is stored as key/value pairs. These two objects implement the functions listed in Table 1.

Table 1 Web Storage Functions

 

Function Name

 

setItem(key:String, value)

Creates a key/value pair given the specified values. Some implementations require the value to be a string.

getItem(key:String)

Returns the item specified by the given key.

removeItem(key:String)

Removes the item identified by the given key.

clear()

Clears all key/value pairs from the Storage object.

key(index:long)

Returns the key for the specific index.

Each Storage object also has a length property indicating the number of present key/value pairs.

Web Storage offers a more fluent API we can use in lieu of the getItem and setItem functions listed in Table 1. The alternate API uses an array-like means of referencing a key. To set a localStorage key/value pair with the values of a hometown newspaper, we could use the following, for example:

localStorage['newspaper'] = 'The Baltimore Sun';

Likewise, we could retrieve that value with just the left half of the preceding expression:

localStorage['newspaper'];

In the context of game programming, we could use Web Storage to store user high scores as well as data for saved games.

Geolocation
The Geolocation API doesn't have an explicit function to ask for the user's permission to track his or her position. Instead, the browser handles this transparently for us. When the Geolocation API first requests position information from a website for which it doesn't have permission, a contextual pop-up appears to request permission from the user.

We can check to see if the browser supports the Geolocation API by checking for the following object:

navigator.geolocation

If it resolves to a non-null value, we have the ability to geolocate.

The calculated position of a user is defined by the Position object, which contains a Coordinates object named coords and a timestamp indicating when the fix was retrieved. Table 2 shows the properties of the coords object.

Table 2: Coordinates Object Properties

 

 

Property NameValue

 

 

latitude

double

The latitude of the position fix.

longitude

double

The longitude of the position fix.

altitude

double

The altitude of the position fix in meters.

If this is unavailable, the value will be null.

 

 

accuracy

double

The margin of error of the lat-long fix in meters.

If this is unavailable, the value will be null.

 

 

altitudeAccuracy

double

The margin of error of the altitude value.

If this is unavailable, the value will be null.

 

 

heading

double

The direction in which the device is traveling

in degrees (0° to 360°, inclusive). If this is

 

 

unavailable, the value will be NaN.

 

 

speed

double

The speed in meters that the device is traveling.

If this is unavailable, the value will be null.

 

 

After we have verified that geolocation is available, obtaining a position fix on a device is simple. We just call getCurrentPosition with either one, two, or three parameters, corresponding to the functions to run if getting a fix is successful, if it fails, and the options on the request, respectively.

Listing 5 shows the code needed to retrieve a location, draw it on a map with a marker, and draw a proximity circle around the marker.

Listing 5: Drawing a Map with Geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(pos) {
var latitude = pos.coords.latitude;
var longitude = pos.coords.longitude;

var options = {
position:new google.maps.LatLng(latitude, longitude)
,title:"Your location"} ;

var marker = new google.maps.Marker(options);

var circle = new google.maps.Circle({
map:map, radius:pos.coords.accuracy
} );
circle.bindTo('center', marker, 'position');

marker.setMap(map);

map.setCenter( new google.maps.LatLng(latitude, longitude));
} ,
function(error) {
console.log(error.message);
} );
}

After verifying that geolocation is available, we first attempt to retrieve a fix on the position of the device. In this example, we are passing in the two parameter functions of getCurrentPosition to execute if successful, an error occurs, or if the user declines geolocation. After getting the latitude and longitude portions, we create a marker centered at that position with the title "Your location." To the marker, we attach a circle whose radius is equivalent to the accuracy of the position fix. Lastly, if there is an error, our error-handling function prints out the error message to the console. Figure 4 shows a sample position fix using the OpenStreetMap tile set.

Although we did not use it, we could have also specified an options object that indicates several preferences on the retrieved data. We could also set up a listener to execute every time there is a position change returned from the watchPosition function. Geolocation is an expensive API. Use it judiciously and don't be afraid to cache the location.

Figure 4 Geolocation from the browser

We could use geolocation to create localized leader boards, or on a multiplayer server to match players who are physically close to one another.

Getting Users' Attention with Notifications
In HTML4, the options to communicate messages to the user were limited. You could show the user an alert window or show a message in a div element. Showing an alert window is well supported on all browsers, but it is highly disruptive. It is something that requires immediate attention and doesn't let you move on until you have handled it. One sure way to annoy a user is by making him lose a life because some message obscured his view. Showing a message in a div element fares slightly better, but there isn't a standard way to add them. These types of messages can be easily ignored. On one side we have notifications that crave attention, and on the other we have notifications that can be easily ignored. There has to be a middle ground. Enter web notifications.

On the Mac OS X and Ubuntu platforms natively, and with a plugin on Windows, an application can send configurable messages to users and notify them of events or changes it deems important. An example of such a notification is shown in Figure 5.

Figure 5: Desktop notification message

Like their desktop counterparts, web notifications can contain an image along with a contextual message.

Requesting Permission to Display Notifications
Before we can display notifications to users, we first have to get their permission. Explicit permission protects the users from being bombarded with unwanted notifications. We can request permission to display notifications by executing the following:

window.webkitNotifications.requestPermission();

This will show a contextual message in the browser to allow the user to approve or deny access, as shown in Figure 6. Instead of a no-argument function call, we can also pass a function to execute when the user responds to the prompt.

Figure 6: Web notification permissions message

We can likewise verify permission by running the following command:

window.webkitNotifications.checkPermission();

In this case, checkPermission() returns an integer that indicates the permission level, as shown in Table 3.

Table 3: Notification Permission Level

 

Constant Name

 

PERMISSION_ALLOWED

0

PERMISSION_UNKNOWN

1

PERMISSION_DENIED

2

Looking at the name, you would expect notifications to work in at least the major Webkit browsers, namely Chrome and Apple Safari. Although Safari uses Webkit, it
doesn't implement the Notification API. If the spec is implemented globally, the namespace could presumably change from webkitNotifications to simply notifications.

Creating Notifications
You can create two types of notifications: simple and HTML. Simple notifications display a simple message with an optional title and icon image, whereas HTML notifications display an arbitrary URL. For example, we can create a simple notification by executing the following:

var msg = window.webkitNotifications.createNotification(
'', 'Test Notification', 'Hello World'
);

Our notification will have the title "Test Notification" with the message "Hello World." Because we passed an empty string for the icon image, the API omits it. We can do this for any other parameter. Do this to hide parameters you don't want displayed. Passing no value to the function will cause a text message of "undefined" or a broken image link. Figure 1-7 shows our notification running in the browser. As you can see, it is pretty Spartan, and we have no control over the design besides the parameters we passed it.

Figure 7: Simple web notification

As mentioned before, HTML notifications can get their content from an arbitrary URL such as a website or an image. The function just takes the desired URL to display in the form:

var msg =window.webkitNotifications.createHTMLNotification(
'http://example.com'
);

HTML notifications give you no means to resize them, and unless the URL has code to optimize the notification for small screens, scroll bars will probably be included. On a 1680¥1050 screen, the default size seems to be approximately 300 pixels wide by 50 pixels high, but because the notifications API is still a draft at the time of this writing, that is certainly subject to change. Until fine-grained height and width attributes are added, stick with simple notifications.

Interacting with Notifications
The resulting notification has two basic functions for controlling it: show(), which surfaces the notification to the user, and cancel(), which hides the notification if it's currently visible or prevents it from being displayed if it is not visible. Web notifications can also execute functions in response to notification events. Table 1-4 shows a list of the applicable functions you can specify to respond to events.

Table 4: Web Notification Functions

 

Function Name

 

onclick

This function will execute if the notification is clicked and the underlying platform supports it. Avoid this event if at all possible.

onclose

This function will execute after the close event is fired. This could be when the user closes the notification or if it is closed programmatically.

ondisplay

This function will execute after the show() function is called and the notification is visible to the user.

onerror

This function executes after show() is called in the event of an error.

You can check the current status of the draft specification at http://dev.chromium.org/developers/design-documents/desktop-notification....

Media Elements
When HTML was originally designed, it was concerned with mostly textual links. Native display of images would come much later. It is not hard to understand why you would need a plugin or browser extension to play audio or video. In most cases, this meant Flash. HTML5 has tried to address that issue with the inclusion of the audio and video tags.

The audio and video tags allow us to play media in the browser natively. Also, a group of properties can be set to control playback. Here is the most basic HTML form for embedded media (in this case, an audio file):

<audio src="song.mp3" autoplay />

This creates an audio HTML element, assigns the source to song.mp3, and instructs the page to "autoplay" the content. It is equivalent to the following JavaScript code:

var song = new Audio();
song.src = "song.mp3";
song.autoplay = true;
song.load();

Controlling Media
In addition to the autoplay attribute listed in the previous example, several other attri-butes can be used to control our media. For example,

<video src="vid.avi" controls />

or

var vid = new Video();
vid.src = "vid.avi";
vid.controls = true;

tells the browser to provide a default set of controls for starting and pausing playback, setting the volume level, and seeking in the stream. In the absence of such a property, the developer can provide a custom set of controls using the JavaScript functions and properties listed in Tables 5 and 6.

Table 5: Media Tag Functions

 

Function Name

 

play()

Starts playing the media from the current position and sets the paused property to false

pause()

Halts playing the media and sets the paused property to true

load()

Resets the element and applies any settings, such as pre-fetching

 

Table 6: Media Element Properties

 

 

Property NameValues

 

 

currentTime

integer

Sets the position in the media stream for playback

duration

N/A (read-only)

Indicates the length of the source media in seconds

loop

true or false

Specifies whether or not to play the media from the

beginning when the end of the stream is reached

 

 

autoplay

true or false

Specifies whether or not to play the media as soon as

possible

 

 

muted

true or false

Specifies whether or not to set the volume at 0.0

The list of properties has been truncated for brevity and usefulness. To see a full list of available properties, check out the HTML5 draft spec at http://dev.w3.org/html5/spec.

More Stories By James Williams

James Williams is an experienced developer and speaker who has given presentations all over the world on Java, user interfaces, and Google Wave. He is the creator of SwingXBuilder, a DSL for creating user interfaces using SwingX components, and a co-despot of Griffon, a framework to make rich applications using Groovy. James is based in the San Francisco Bay Area and you can follow his blog at http://jameswilliams.be/blog

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.