Why HTML5?
Shakeel Mahate

Based on the draft book Dive Into HTML5 by Mark Pilgrim under the CC-BY-3.0 license and the various W3C specifications. This derivative work is also under the CC-BY-3.0 license.

HTML is more than just markup. It is now the most prominent platform for delivery of web applications. It has support for the following technologies that will impact all software developers:

The following seven principles were identified by the W3C Workshop on Web Applications and Compound documents held in June 2004 which form the basis for the HTML5 work done by the WHAT working group.

Backwards compatibility, clear migration path
Web application technologies should be based on technologies authors are familiar with, including HTML, CSS, DOM, and JavaScript.
Basic Web application features should be implementable using behaviors, scripting, and style sheets in IE6 today so that authors have a clear migration path. Any solution that cannot be used with the current high-market-share user agent without the need for binary plug-ins is highly unlikely to be successful.
Well-defined error handling
Error handling in Web applications must be defined to a level of detail where User Agents do not have to invent their own error handling mechanisms or reverse engineer other User Agents.
Users should not be exposed to authoring errors
Specifications must specify exact error recovery behaviour for each possible error scenario. Error handling should for the most part be defined in terms of graceful error recovery (as in CSS), rather than obvious and catastrophic failure (as in XML).
Practical use
Every feature that goes into the Web Applications specifications must be justified by a practical use case. The reverse is not necessarily true: every use case does not necessarily warrant a new feature.
Use cases should preferably be based on real sites where the authors previously used a poor solution to work around the limitation.
Scripting is here to stay
But should be avoided where more convenient declarative markup can be used.
Scripting should be device and presentation neutral unless scoped in a device-specific way (e.g. unless included in XBL).
Device-specific profiling should be avoided
Authors should be able to depend on the same features being implemented in desktop and mobile versions of the same UA.
Open process
The Web has benefited from being developed in an open environment. Web Applications will be core to the web, and its development should also take place in the open. Mailing lists, archives and draft specifications should continuously be visible to the public.

In October 2006, Tim Berners-Lee announced that the W3C will collaborate with WHATWG to evolve HTML. He renamed the W3C HTML Working Group from Web Applications 1.0 to HTML5. Gradually W3C abandoned their effort to move the world to well-formed XML tags and draconian error handling.

HTML5 Features

HTML5 is not one big thing; it is a collection of individual features. So you can’t detect “HTML5 support,” because that doesn’t make any sense. But you CAN detect support for individual features, like canvas, video, or geolocation and use the new features today.

HTML5 Canvas

HTML5 defines the <canvas> element as “a resolution-dependent bitmap canvas which can be used for rendering graphs, game graphics, or other visual images on the fly.” A canvas is a rectangle in your page where you can use JavaScript to draw anything you want. HTML5 defines a set of functions (“the canvas API”) for drawing shapes, defining paths, creating gradients, and applying transformations.

HTML5 Canvas Example

<canvas width="800" height="450"></canvas>
<script> 
 
 var context = document.getElementsByTagName('canvas')[0].getContext('2d');
 
 var lastX = context.canvas.width * Math.random();
 var lastY = context.canvas.height * Math.random();
 var hue = 0;
 
 function line() {
   context.save();
   context.translate(context.canvas.width/2, context.canvas.height/2);
   context.scale(0.9, 0.9);
   context.translate(-context.canvas.width/2, -context.canvas.height/2);
   context.beginPath();
   context.lineWidth = 5 + Math.random() * 10;
   context.moveTo(lastX, lastY);
   lastX = context.canvas.width * Math.random();
   lastY = context.canvas.height * Math.random();
   context.bezierCurveTo(context.canvas.width * Math.random(),
                         context.canvas.height * Math.random(),
                         context.canvas.width * Math.random(),
                         context.canvas.height * Math.random(),
                         lastX, lastY);
 
   hue = hue + 10 * Math.random();
   context.strokeStyle = 'hsl(' + hue + ', 50%, 50%)';
   context.shadowColor = 'white';
   context.shadowBlur = 10;
   context.stroke();
   context.restore();
 }
 setInterval(line, 50);
 
 function blank() {
   context.fillStyle = 'rgba(0,0,0,0.1)';
   context.fillRect(0, 0, context.canvas.width, context.canvas.height);
 }
 setInterval(blank, 40);
 
</script> 

More HTML5 Canvas Demos

Harmony is a Canvas based drawing tool written by mrdoob. The source code for the editor shows how to attach event handlers to Canvas.

canvas.addEventListener('mousedown', onCanvasMouseDown, false);

function onCanvasMouseDown(event) {
	var data, position;

	clearTimeout(saveTimeOut);
	cleanPopUps();

	if (altKeyIsDown) {
		flatten();
		data = flattenCanvas.getContext("2d").getImageData(0, 0, 
		         flattenCanvas.width, flattenCanvas.height).data;
		position = (event.clientX + (event.clientY * canvas.width)) * 4;
		foregroundColorSelector.setColor([data[position], data[position + 1], data[position + 2]]);
		return;
	}

	brush.strokeStart( event.clientX, event.clientY );
	window.addEventListener('mousemove', onCanvasMouseMove, false);
	window.addEventListener('mouseup', onCanvasMouseUp, false);
}

function onCanvasMouseMove(event) {
	brush.stroke( event.clientX, event.clientY );
}

function onCanvasMouseUp() {
	brush.strokeEnd();

	window.removeEventListener('mousemove', onCanvasMouseMove, false);
	window.removeEventListener('mouseup', onCanvasMouseUp, false);

	if (STORAGE) {
		clearTimeout(saveTimeOut);
		saveTimeOut = setTimeout(saveToLocalStorage, 2000, true);
	}
}

Captcha Decoder loads a captcha in a Canvas and then uses a Javascript based neural net OCR to decode the captcha.

John Resig's description of the Captcha Decoder

  1. The HTML 5 Canvas getImageData API is used to get at the pixel data from the Captcha image. Canvas gives you the ability to embed an image into a canvas (from which you can later extract the pixel data back out again).
  2. The script includes an implementation of a neural network, written in pure JavaScript.
  3. The pixel data, extracted from the image using Canvas, is fed into the neural network in an attempt to divine the exact characters being used - in a sort of crude form of Optical Character Recognition (OCR).

HTML5 Web Workers

Web Workers provide a standard way for browsers to run JavaScript in the background. With web workers, You can spawn multiple “threads” that all run at the same time, more or less. These “background threads” can do complex mathematical calculations, make network requests, or access local storage while the main web page responds to the user scrolling, clicking, or typing.

HTML5 Web Workers Example

The simplest use of workers is for performing a computationally expensive task without interrupting the user interface.

In this example, the main document spawns a worker to (naïvely) compute prime numbers, and progressively displays the most recently found prime number.

The main page is as follows:

<!DOCTYPE HTML>
<html>
 <head>
  <title>Worker example: One-core computation</title>
 </head>
 <body>
  <p>The highest prime number discovered so far is: <output id="result"></output></p>
  <script>
   var worker = new Worker('worker.js');
   worker.onmessage = function (event) {
     document.getElementById('result').textContent = event.data;
   };
  </script>
 </body>
</html>

The Worker() constructor call creates a worker and returns a Worker object representing that worker, which is used to communicate with the worker. That object's onmessage event handler allows the code to receive messages from the worker.

The worker itself is as follows:

var n = 1;
search: while (true) {
  n += 1;
  for (var i = 2; i <= Math.sqrt(n); i += 1)
    if (n % i == 0)
     continue search;
  // found a prime!
  postMessage(n);
}

The bulk of this code is simply an unoptimized search for a prime number. To send a message back to the page, the postMessage() method is used to post a message when a prime is found.

View this example online.

Ray Tracer implemented using Web Workers.

HTML5 Local Storage

HTML5 storage provides a way for web sites to store information on your computer and retrieve it later. The concept is similar to cookies, but it’s designed for larger quantities of information. Cookies are limited in size, and your browser sends them back to the web server every time it requests a new page (which takes extra time and precious bandwidth). HTML5 storage stays on your computer, and web sites can access it with JavaScript after the page is loaded.

HTML5 Local Storage Example

Sites can add data to the session storage, and it will be accessible to any page from the same site opened in that window.

For example, a page could have a checkbox that the user ticks to indicate that he wants insurance:

<label>
 <input type="checkbox" onchange="sessionStorage.insurance = checked">
 I want insurance on this trip.
</label>

A later page could then check, from script, whether the user had checked the checkbox or not:

if (sessionStorage.insurance) { ... }

If the user had multiple windows opened on the site, each one would have its own individual copy of the session storage object.

The second storage mechanism is designed for storage that spans multiple windows, and lasts beyond the current session. In particular, Web applications may wish to store megabytes of user data, such as entire user-authored documents or a user's mailbox, on the client side for performance reasons.

The site at example.com can display a count of how many times the user has loaded its page by putting the following at the bottom of its page:

<p>
  You have viewed this page
  <span id="count">an untold number of</span>
  time(s).
</p>
<script>
  if (!localStorage.pageLoadCount)
    localStorage.pageLoadCount = 0;
  localStorage.pageLoadCount += 1;
  document.getElementById('count').textContent = localStorage.pageLoadCount;
</script>

Each site has its own separate storage area.

HTML5 Offline Web Applications

In order to enable users to continue interacting with Web applications and documents even when their network connection is unavailable — for instance, because they are traveling outside of their ISP's coverage area — authors can provide a manifest which lists the files that are needed for the Web application to work offline and which causes the user's browser to keep a copy of the files for use offline.

HTML5 Offline Web Applications Example

Consider a simple clock applet consisting of an HTML page "clock.html", a CSS style sheet "clock.css", and a JavaScript script "clock.js".

Before adding the manifest, these three files might look like this:

<!-- clock.html -->
<!DOCTYPE HTML>
<html>
 <head>
  <title>Clock
  <script src="clock.js">
  <link rel="stylesheet" href="clock.css">
 </head>
 <body>
  <p>The time is: 

</body> </html> /* clock.css */ output { font: 2em sans-serif; } /* clock.js */ setTimeout(function () { document.getElementById('clock').value = new Date(); }, 1000);

If the user tries to open the "clock.html" page while offline, though, the user agent (unless it happens to have it still in the local cache) will fail with an error.

The author can instead provide a manifest of the three files:

CACHE MANIFEST
clock.html
clock.css
clock.js

With a small change to the HTML file, the manifest (served as text/cache-manifest) is linked to the application:

<!-- clock.html -->
<!DOCTYPE HTML>
<html manifest="clock.manifest">
 <head>
  <title>Clock
  <script src="clock.js">
  <link rel="stylesheet" href="clock.css">
 </head>
 <body>
  <p>The time is: 

</body> </html>

Now, if the user goes to the page, the browser will cache the files and make them available even when the user is offline.

You can specify files that should never be stored in the application cache by creating a NETWORK section and then listing the files in the manifest.

HTML5 Web Sockets

The Web Sockets API enables web applications to handle bidirectional communications with server-side process in a straightforward way. Developers have been using XMLHttpRequest ("XHR") for such purposes, but XHR makes developing web applications that communicate back and forth to the server unnecessarily complex. XHR is basically asynchronous HTTP, and because you need to use a tricky technique like long-hanging GET for sending data from the server to the browser, simple tasks rapidly become complex. As opposed to XMLHttpRequest, Web Sockets provide a real bidirectional communication channel in your browser. Once you get a Web Socket connection, you can send data from browser to server by calling a send() method, and receive data from server to browser by an onmessage event handler.

In addition to the new Web Sockets API, there is also a new protocol (the "web socket protocol") that the browser uses to communicate with servers. The protocol is not raw TCP because it needs to provide the browser's "same-origin" security model. It's also not HTTP because web socket traffic differers from HTTP's request-response model. Web socket communications using the new web socket protocol should use less bandwidth because, unlike a series of XHRs and hanging GETs, no headers are exchanged once the single connection has been established. To use this new API and protocol and take advantage of the simpler programming model and more efficient network traffic, you do need a new server implementation to communicate with.

Google has developed pywebsocket, which can be used as an Apache extension module, or can even be run as standalone server. The Google Chrome browser developer channel release has implemented the Web Sockets protocol and you can use it in conjunction with the pywebsocket server implementation.

HTML5 Web Sockets Example

if ("WebSocket" in window) {
  var ws = new WebSocket("ws://example.com/service");
  ws.onopen = function() {
    // Web Socket is connected. You can send data by send() method.
    ws.send("message to send"); ....
  };
  ws.onmessage = function (evt) { var received_msg = evt.data; ... };
  ws.onclose = function() { // websocket is closed. };
} else {
  // the browser doesn't support WebSocket.
}

HTML5 Microdata

The HTML5 specification includes a description of microdata, a new markup standard for specifying structured information within web pages. Microdata annotations are meant to be read by search engines and other non-human actors. Microdata allows nested groups of name-value pairs to be added to documents, in parallel with the existing content. At a high level, microdata consists of a group of name-value pairs. The groups are called items, and each name-value pair is a property. Items and properties are represented by regular elements.

HTML5 Microdata Example

Before HTML5
<div>
  <h1>Review: Neomonde Restaurant</h1>
  Written by Shakeel Mahate
  January 1, 2004
  Rated <b>4.5</b> Excellent
</div>

With HTML5 Microdata support
<div itemscope itemtype="http://data-vocabulary.org/Review">
  <h1>Review: <span itemprop="itemreviewed">Neomonde Restaurant</span></h1>
  Written by <span itemprop="reviewer">Shakeel Mahate</span>
  <time itemprop="dtreviewed" datetime="2004-01-01">January 1, 2004</time>
  Rated <b itemprop="rating">4.5</b> Excellent
</div>

When Google search engine comes across the above review, it then displays it in the Rich Snippet view.

Image of a Google rich snippet for a restaurant

Quake II HTML5 Version

The Quake II GWT port brings the 3d gaming experience of Quake II to the browser.

It uses WebGL, Canvas API, Audio, Local storage API, and WebSockets to demonstrate the possibilities of pure web applications in modern browsers such as Safari and Chrome.

The port is based on the Jake2 project, compiled to Javascript using the Google Web Toolkit (GWT). Jake 2 is a Java port of the original Quake II source code, which was open sourced by id software.

To make the Jake 2 code work with GWT, Google had to do the following:

  1. Created a new WebGL based renderer
  2. Ported the network layer for multiplayer games from UDP to the WebSocket API
  3. Made all resource loading calls asynchronous
  4. Created a GWT implementation of Java nio buffers based on WebGL arrays (to be ported to ECMAScript Typed Arrays)
  5. Implemented a simple file system emulation for saving games and preferences using the Web Storage API

SVG Filters on HTML5 Video

Paul Irish has a nice example of using SVG filters on HTML5 Video.

Further Reading

Questions

Interested in following up with more details, please contact me at shakeel.mahate@gmail.com. You can also follow me @smahate or Friendfeed shakeel or Google Buzz shakeel.mahate