<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>HTML5 Doctor &#187; JavaScript APIs</title>
	<atom:link href="http://html5doctor.com/category/javascript-apis/feed/" rel="self" type="application/rss+xml" />
	<link>http://html5doctor.com</link>
	<description>helping you implement HTML5 today</description>
	<lastBuildDate>Wed, 01 Feb 2012 09:28:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Server-Sent Events</title>
		<link>http://html5doctor.com/server-sent-events/</link>
		<comments>http://html5doctor.com/server-sent-events/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 14:30:33 +0000</pubDate>
		<dc:creator>Remy Sharp</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[JavaScript APIs]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[eventsource]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[realtime]]></category>
		<category><![CDATA[serversentevents]]></category>
		<category><![CDATA[websockets]]></category>

		<guid isPermaLink="false">http://html5doctor.com/?p=4181</guid>
		<description><![CDATA[We've already had a glimpse at Server-Sent Events (also known as EventSource, and I'll switch between the two to keep you on your toes) in my Methods of Communication article from last year. In this article, I want to delve in to more detail about the SSE API, demonstrate its features, and even show you how to polyfill browsers that lack EventSource support.]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve already had a glimpse at <a href="http://dev.w3.org/html5/eventsource/">Server-Sent Events</a> (also known as EventSource<sup>†</sup>, and I&#8217;ll switch between the two to keep you on your toes) in my <a href="http://html5doctor.com/methods-of-communication/">Methods of Communication</a> article from last year. In this article, I want to delve in to more detail about the SSE API, demonstrate its features, and even show you how to polyfill browsers that lack EventSource support.</p>

<p>Server-Sent Events are real-time events emitted by the server and received by the browser. They&#8217;re similar to WebSockets in that they happen in real time, but they&#8217;re very much a one-way communication method <em>from</em> the server.</p>

<p>These events are similar to ordinary JavaScript events that occur in the browser — like <em>click</em> events — except we can control the name of the event and the data associated with it.</p>

<p>All the code for this article is <a href="https://github.com/remy/eventsource-h5d">available on github</a>, and a <a href="http://node.remysharp.com:8004/">live demo is available online</a>.
<span id="more-4181"></span></p>

<p><small>† Is it Server-Sent Events or EventSource? Well, they both work. Server-Sent Events is the name of the API and specification. EventSource is the name of the JavaScript object you&#8217;re instantiating. It&#8217;s a bit like Ajax and XHR, where XHR refers to the XMLHttpRequest object…kinda.</small></p>

<p><small>Two notes: a) the uptime for this example is, I&#8217;m afraid, usually rather low — good for my server, bad for you. If you test the demo locally it will give you more interesting figures. b) IE6 isn&#8217;t supported in any of this article.</small></p>

<p><section id="applications"></p>

<h2>Possible Applications <a href="#applications" class="permalink">#</a></h2>

<p>A few simple examples of applications that could make use of Server-Sent Events:</p>

<ul>
<li>A real-time chart of streaming stock prices</li>
<li>Real-time news coverage of an important event (posting links, tweets, and images)</li>
<li>A live Twitter wall fed by Twitter&#8217;s streaming API</li>
<li>A monitor for server statistics like uptime, health, and running processes</li>
</ul>

<p>We&#8217;ll use the server monitor for this article&#8217;s examples. If this application were to be used in the wild, we could also check the <code>EventSource</code>&#8216;s connection state to indicate when there&#8217;s a potential problem connecting to the server.</p>

<p></section></p>

<p><section id="api"></p>

<h2>Overview of the API <a href="#api" class="permalink">#</a></h2>

<p>The client-side API is rather simple, and it hands-down beats the insane hacks required to get real-time events to the browser back in the bad old days.</p>

<p>The main points of interest:</p>

<ul>
<li><code>new EventSource(url)</code> — this creates our <code>EventSource</code> object, which immediately starts listening for events on the given URL.</li>
<li><code>readyState</code> — as with XHR, we have a <code>readyState</code> for the <code>EventSource</code> that tells us if we&#8217;re connecting (0), open (1), or closed (2).</li>
<li><code>onopen</code>, <code>onmessage</code> — two events that we can listen for on the new <code>EventSource</code> object. By default, the <code>message</code> event will fire when new messages are received, <em>unless</em> the server explicitly sets the event type.</li>
<li><code>addEventListener</code> — not only can we listen for the default <code>message</code> event, but we can also listen for custom messages using the <code>addEventListener</code> on the <code>EventSource</code> object, just as if we were listening for a <code>click</code> event.</li>
<li><code>event.data</code> — as with most messaging APIs, the contents of the message reside in the <code>data</code> property of the <code>event</code> object. This is a string, so if we want to pass around an object, we need to encode and decode it with JSON.</li>
<li><code>close</code> — closes the connection from the client side.</li>
</ul>

<p>In the future, EventSource will also support <a href="http://www.w3.org/TR/cors/">CORS</a> using an <code>options</code> argument to the <code>EventSource</code> object: <code>{ withCredentials: true }</code>. But at the time of writing, no stable release includes this property.</p>

<p></section></p>

<p><section id="example"></p>

<h2>Simple Example <a href="#example" class="permalink">#</a></h2>

<p>Our simple web app will notify us of server status messages — things like the load average, number of currently connected users, and most CPU-intensive processes. If I were using this application in anger, I&#8217;d probably build server modules that emit specific event types when they cross specific thresholds, so that I&#8217;m only notified when something gets to warning level.</p>

<p>This snippet of JavaScript connects to our server, listens for messages, and handles the data that comes with the messages:</p>

<pre><code>var source = new EventSource('/stats');
source.onopen = function () {
  connectionOpen(true);
};

source.onerror = function () {
  connectionOpen(false);
};

source.addEventListener('connections', updateConnections, false);
source.addEventListener('requests', updateRequests, false);
source.addEventListener('uptime', updateUptime, false);

source.onmessage = function (event) {
  // a message without a type was fired
};
</code></pre>

<p></section></p>

<p><section id="properties"></p>

<h2>Properties of Server-Sent Events <a href="#properties" class="permalink">#</a></h2>

<p>Server-Sent Events are more than just a one-way web socket. They have some unique features:</p>

<ul>
<li>The connection stream is <em>from</em> the server and read-only. This suits lots of applications, some examples of which I listed above.</li>
<li>They use regular HTTP requests for the persistent connection, not a special protocol, which means we can polyfill using vanilla JavaScript.</li>
<li>If the connection drops, the <code>EventSource</code> fires an error event and automatically tries to reconnect. The server can also control the timeout before the client tries to reconnect.</li>
<li>Clients can send a unique ID with messages. When a client tries to reconnect after a dropped connection, it will send the last known ID. Then the server can see that the client missed <em>n</em> messages and send the backlog of missed messages on reconnect.</li>
</ul>

<p></section></p>

<p><section id="message-format"></p>

<h2>Message Format <a href="#message-format" class="permalink">#</a></h2>

<p>A simple message doesn&#8217;t require much:</p>

<pre><code>data: this is a simple message
&lt;blank line&gt;
</code></pre>

<p>Note that the end of a message is indicated by a blank line (obviously not the literal characters <code>&lt;blank line&gt;</code>).</p>

<p>For a message with multiple lines:</p>

<pre><code>data: this is line one
data: and this is line two
</code></pre>

<p>You can send message IDs to be used if the connection is dropped:</p>

<pre><code>id: 33
data: this is line one
data: this is line two
</code></pre>

<p>You can even send multiple messages in a single response so long as you separate the messages by blank lines:</p>

<pre><code>id: 34
data: Remy is awesome

id: 35
data: Bruce is stinky
</code></pre>

<p>And you can specify your own event types (the above messages will all trigger the <code>message</code> event):</p>

<pre><code>id: 36
event: price
data: 103.34

id: 37
event: news
data: Bruce sells his collection of replica bananas
</code></pre>

<p>You don&#8217;t have to worry about this structure on the client side. It only applies to the server, which I&#8217;ll touch on next.</p>

<p></section></p>

<p><section id="server"></p>

<h2>Typical Server <a href="#server" class="permalink">#</a></h2>

<p>I&#8217;m not going to give a full walkthrough of the server-side code, since this is an HTML5 web site <img src='http://html5doctor.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  But there are a few important and simple features that you need to know to build the server (you&#8217;ll need this part anyway if you&#8217;re going to use EventSource).</p>

<p>I&#8217;ve included <a href="https://github.com/remy/eventsource-h5d">all the files for this demo on GitHub</a> for you to peruse at your own leisure, and I&#8217;ve also deployed a <a href="http://node.remysharp.com:8004">live example of this code</a>.</p>

<p>Ideally, you should use a server that has an <a href="http://en.wikipedia.org/wiki/Event_loop">event loop</a>. This means you should <em>not</em> use Apache, but instead use a platform such as <a href="http://nodejs.org">Node.js</a> (which I&#8217;ve used) or <a href="http://twistedmatrix.com/trac/">Twisted</a> for Python.</p>

<p>Key properties:</p>

<ol>
<li>You can only accept EventSource requests if the HTTP request says it can accept the <code>event-stream</code> MIME type.</li>
<li>You need to maintain a list of all the connected users in order to emit new events.</li>
<li>You should listen for dropped connections and remove them from the list of connected users.</li>
<li>You should optionally maintain a history of messages so that reconnecting clients can catch up on missed messages.</li>
</ol>

<p>Here&#8217;s a sample of my Node.js based server.  It&#8217;s using <a href="http://senchalabs.github.com/connect/">Connect</a> (a simple webby framework for Node). When it receives a request for <code>/stats</code>, it calls the following function. I&#8217;ve commented the code so you can follow along:</p>

<pre><code>function stats(request, response) {
  // only response to an event-stream if the request 
  // actually accepts an event-stream
  if (request.headers.accept == 'text/event-stream') {

    // send the header to tell the client that we're going
    // to be streaming content down the connection
    response.writeHead(200, {
      'content-type': 'text/event-stream',
      'cache-control': 'no-cache',
      'connection': 'keep-alive'
    });

    // support the polyfill - we'll come on to this later
    if (request.headers['x-requested-with'] == 'XMLHttpRequest') {
      response.xhr = null;
    }

    // if there was a lastEventId sent in the header, send
    // the history of messages we've already stored up
    if (request.headers['last-event-id']) {
      var id = parseInt(request.headers['last-event-id']);
      for (var i = 0; i &lt; history.length; i++) {
        if (history[i].id &gt;= id) {
          sendSSE(response, history[i].id, history[i].event, history[i].message);
        }
      }
    } else {
      // if the client didn't send a lastEventId, it's the
      // first time they've come to our service, so send an
      // initial empty message with no id - this will reset
      // their id counter too.
      response.write('id\n\n');
    }

    // cache their connection - the response is where we write
    // to send messages
    connections.push(response);

    // send a broadcast message to all connected clients with
    // the total number of connections we have.
    broadcast('connections', connections.length);

    // if the connection closes to the client, remove them
    // from the connections array.
    request.on('close', function () {
      removeConnection(response);
    });
  } else {
    // if the client doesn't accept event-stream mime type,
    // send them the regular index.html page - you could do
    // anything here, including sending the client an error.
    response.writeHead(302, { location: "/index.html" });
    response.end();
  }
}
</code></pre>

<p>The important trick on the server is to ensure you <em>don&#8217;t</em> close the connection to the <code>EventSource</code> object. If you do, it will of course handle the closed connection, fire an error event, and try to reconnect. So you&#8217;ll just want to maintain the persistent connection.</p>

<p></section></p>

<p><section id="polyfills"></p>

<h2>Polyfills and Tweaks to the Server <a href="#polyfills" class="permalink">#</a></h2>

<p>There are two good polyfills I know of, and though I prefer the one I wrote, I&#8217;ll still lay them both out for you.</p>

<p><section id="yaffle"></p>

<h3>Yaffle&#8217;s Polyfill <a href="#yaffle" class="permalink">#</a></h3>

<p>The first is one by <a href="https://github.com/Yaffle">Yaffle</a> (on github), available on <a href="https://github.com/Yaffle/EventSource">github/Yaffle/eventsource</a>. </p>

<p>The cons:</p>

<ul>
<li>It doesn&#8217;t send the <code>accepts</code> header, and</li>
<li>It completely replaces the <code>EventSource</code> object, so even if your browser supports <code>EventSource</code> natively, this script will replace it. But there&#8217;s a good reason for that.</li>
</ul>

<p>The pros:</p>

<ul>
<li>It maintains a persistent connection (whereas the one we&#8217;re using doesn&#8217;t), and</li>
<li>More interestingly, it supports CORS (which I imagine is why it replaces the native <code>EventSource</code>).</li>
</ul>

<p>These two pros are quite compelling. But when I was testing, I couldn&#8217;t get it working in IE7 (which was my minimum browser target), so that might be a blocker for you…or not.</p>

<p></section></p>

<p><section id="remy"></p>

<h3>Remy&#8217;s Polyfill <a href="#remy" class="permalink">#</a></h3>

<p>The second is my own, available on <a href="https://github.com/remy/polyfills/blob/master/EventSource.js">github.com/remy/polyfills</a>.</p>

<p>The cons:</p>

<ul>
<li>It uses polling, so once a small group of messages come down, it re-establishes the connection, which could lead to significant overhead (though less so on a Node-based server). You have to add about 4 extra lines to your server code.</li>
</ul>

<p>The pros:</p>

<ul>
<li>It doesn&#8217;t replace the native <code>EventSource</code> object (but that also implies that, for now, it won&#8217;t support CORS), and</li>
<li>It supports IE7.</li>
</ul>

<p><small>Retrospectively, I might choose Yaffle&#8217;s polyfill over mine in the future if I wasn&#8217;t bothered about IE7 support.</small></p>

<p></section></p>

<p><section id="using-the-polyfill"></p>

<h3>Using the Polyfill <a href="#using-the-polyfill" class="permalink">#</a></h3>

<p>By including the <code>EventSource.js</code> JavaScript library before my client-side code, I just need a couple of small changes to my server-side code. Other than that, everything on the client side works without any changes (as a polyfill <em>should</em> work).</p>

<p>When posting the server&#8217;s reply to the client, instead of keeping the connection open, I include the following in my server when it&#8217;s finished writing the response:</p>

<pre><code>// send the data (event type, id, message, etc)
response.write(data);

// if our response contains our custom xhr property, then...
if (response.hasOwnProperty('xhr')) {
  // clear any previous timers using the xhr prop as the value
  clearTimeout(response.xhr);

  // now set a timer for 1/4 second (abritrary number) that
  // then closes the connection and removes itself from the
  // connection array.
  // The delay is in place so that a burst of messages can 
  // go out on the same connection *before* it's closed.
  response.xhr = setTimeout(function () {
    response.end();
    removeConnection(response);
  }, 250);
}
</code></pre>

<p></section>
</section></p>

<p><section id="bugs"></p>

<h2>Bugs? <a href="#bugs" class="permalink">#</a></h2>

<p>The <code>error</code> event should always fire when the <code>readyState</code> changes, assuming you didn&#8217;t explicitly call the <code>close</code> method. This works nearly all the time, but in writing this article, I found a few edge cases where it doesn&#8217;t fire. In Chrome, if I put my machine to sleep and then woke it back up, it would close the connection but not fire the event, therefore never triggering a reconnection. As I said, this is an edge case and I&#8217;ll file a bug against it, so I don&#8217;t expect it to hang around for long.</p>

<p></section></p>

<p><section id="why-not-websockets"></p>

<h2>Why Not Use WebSockets? <a href="#why-not-websockets" class="permalink">#</a></h2>

<p>There are two reasons I&#8217;d advocate using EventSource over WebSockets, as they&#8217;re currently the two contenders for sending real-time events to the browser.</p>

<p>The first is that EventSource (as we saw earlier) works over regular HTTP and can therefore be replicated entirely using JavaScript if it&#8217;s not available natively. That means that we can polyfill browsers without support, like IE9.</p>

<p>The second is probably more important: you should always use the right technology for the job. If your real-time data is sourced from your web site, <em>and</em> the user doesn&#8217;t interact in real-time, it&#8217;s likely you need Server-Sent Events. </p>

<p>I recently saw a cool <a href="http://paynedigital.com/2011/12/nodeflakes">demo of snowflakes</a> drifting down a web site. Each snowflake is a tweet based around the Christmas theme — like if someone mentions a particular Christmas-y term, it&#8217;s sucked in to the snowflake. Don&#8217;t get me wrong, I know this is a demo, and it&#8217;s very cool (if you wrote it, this is me sending you hugs), but it&#8217;s based on WebSockets. I&#8217;d suggest this demo should be based on EventSource since all the data is read-only and the user doesn&#8217;t interact with it at all.</p>

<p>The point: evaluate the technology against your problem, and aim to get good fit.</p>

<p></section>
<div id="crp_related"><h3>Related Posts:</h3><ul class="related"><li><a href="http://html5doctor.com/methods-of-communication/" rel="bookmark" class="crp_title">Methods of communication</a></li><li><a href="http://html5doctor.com/storing-data-the-simple-html5-way-and-a-few-tricks-you-might-not-have-known/" rel="bookmark" class="crp_title">Storing Data the Simple HTML5 Way (and a few tricks you might not have known)</a></li><li><a href="http://html5doctor.com/history-api/" rel="bookmark" class="crp_title">Pushing and Popping with the History API</a></li><li><a href="http://html5doctor.com/how-to-get-all-the-browsers-playing-ball/" rel="bookmark" class="crp_title">How to get all the browsers playing ball</a></li><li><a href="http://html5doctor.com/native-drag-and-drop/" rel="bookmark" class="crp_title">Native Drag and Drop</a></li></ul></div></p>
<p><a href="http://html5doctor.com/server-sent-events/" rel="bookmark">Server-Sent Events</a> originally appeared on <a href="http://html5doctor.com">HTML5 Doctor</a> on January 24, 2012.</p>
]]></content:encoded>
			<wfw:commentRss>http://html5doctor.com/server-sent-events/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Pushing and Popping with the History API</title>
		<link>http://html5doctor.com/history-api/</link>
		<comments>http://html5doctor.com/history-api/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 13:09:47 +0000</pubDate>
		<dc:creator>Mike Robinson</dc:creator>
				<category><![CDATA[JavaScript APIs]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[history]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://html5doctor.com/?p=3897</guid>
		<description><![CDATA[Until recently, we developers couldn’t to do much with the state and history of the browser. We could check the number of items in the history and push users forwards and backwards, but this provides little benefit to the user. With the rise of more dynamic web pages, we need more control. Thankfully, HTML5 gives [...]]]></description>
			<content:encoded><![CDATA[<p>Until recently, we developers couldn’t to do much with the state and history of the browser. We could check the number of items in the history and push users forwards and backwards, but this provides little benefit to the user. With the rise of more dynamic web pages, we need more control. Thankfully, HTML5 gives us that control by extending the JavaScript History API.</p>
<section id="the-point">
<h2>What’s the point? <a class="permalink" href="#the-point">#</a></h2>
<p>It goes without saying that URLs are important. They’re <em>the</em> method of accessing the vast collections of information and resources on the web, and more recently, they’ve begun representing the intended state of a web application. You can copy these URLs and share them with your friends or use them to create links from any HTML document. They’re the veins of the web, and they need to be looked after.</p>
<p>Previously, the JavaScript History API offered some very simple functionality:</p>
<pre><code>// Check the length of the history stack
console.log(history.length);

// Send the user agent forward
console.log(history.forward());

// Send the user agent back
console.log(history.back());

// Send the user agent back (negative) or forward (positive)
// by a given number of items
console.log(history.go(-3));
</code></pre>
<p>With dynamic Ajax web applications, where the browser updates the page in parts instead of changing location entirely, it’s difficult to give the user a URL to bookmark or share the current application state. <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-id-attribute">Fragment identifiers</a>, like those used on this article’s headings via the <code>id</code> attribute, provide some state information, but they’re entirely dependent on client-side scripts.</p>
<p>The changes to the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html">History API</a> are intended to give developers ways to push history items to the browser so the native back and forward actions can cycle through those items. These history items can also hold data that you can later extract to restore the page state.</p>
<blockquote>
<p>Pages can <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#dom-history-pushstate" title="dom-history-pushState">add</a> <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#state-object" title="state object">state objects</a> between their entry in the session history and the next (“forward”) entry. These are then <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#event-popstate" title="event-popstate">returned to the script</a> when the user (or script) goes back in the history, thus enabling authors to use the “navigation” metaphor even in one-page applications.</p>
<footer>- <cite><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html" title="6.4 Session history and navigation">WHATWG</a></cite></footer>
</blockquote>
<p>If the user copies or bookmarks a stateful URL and visits it later, your back-end can be configured to interpret such a URL and jump the user right to the correct page and/or state.</p>
<p>In this article, I’ll cover the client-side use of the History API, so make sure you set up your server to work with the new URLs. If you’ve already built an accessible website that provide these entry points, you’re laughing!</p>
<section id="those-fking-hashbangs">
<h4>Those <em>f#!king</em> hashbangs… <a class="permalink" href="#those-fking-hashbangs">#</a></h4>
<p>You may have already seen articles fussing over the adoption of the “hashbang” (#!) pattern on sites like <a href="http://twitter.com">Twitter</a>. This technique updates the address bar with a fragment identifier that can then be used by JavaScript to determine which page and state should be displayed.</p>
<p>This works as a method of creating a bookmarkable, shareable URL for a page’s state in the absense of a standard API. While the Twitter implementation accepts both <code>http://twitter.com/#!/akamike</code> and <code>http://twitter.com/akamike</code>, it has some disadvantages:</p>
<ul>
<li>The fragment identifier is only accessible on the client side. This means that only JavaScript can utilise it, so browsers without JavaScript enabled are out of luck.</li>
<li>As the server does not receive the path following the hashbang, removing that JavaScript drops support for all those URLs. That’s a lot of broken links, so you’re stuck with that JavaScript <em>forever</em>.</li>
<li>It’s ugly. It’s a hack and it looks like one.</li>
</ul>
<p>The hashbang was never intended to be a long-term solution, so don’t rely on it. If you do use hashbangs, be prepared to deal with the consequences (and possible backlash from web purists).</p>
</section>
</section>
<section id="making-history">
<h2>Making History <a class="permalink" href="#making-history">#</a></h2>
<p>These examples will build on top of each other. We’ll start with a <a href="http://html5doctor.com/wp-content/uploads/2011/10/history_base.html">basic HTML document</a> with some inline styles and scripts for your convenience.</p>
<aside class="sidenote">
<p>For a simple HTTP server, open the command line, <code>cd</code> to the directory you would like to serve, run <code>python -m SimpleHTTPServer 8080</code>, then open <code>localhost:8080</code> in your browser. Alternatively, try a bundled setup like <a href="http://www.apachefriends.org/en/xampp.html">XAMPP</a> or <a href="http://www.mamp.info/en/index.html">MAMP</a>.</p>
</aside>
<p>Save this file and open it in your favourite editor. It must be accessed via HTTP, so that means you need either a local server (e.g. <code>http://localhost/</code>) or an online web server you can upload to. <strong>Viewing the file directly using your browser’s Open File function will not work</strong>, since it uses the <code>file://</code> protocol and not HTTP. Also be sure to update the <code>href</code> attributes on each of the navigation links to ensure the correct directory structure is used. Personally, I’m viewing the demo locally at <code>http://localhost/history</code>.</p>
<p>We’ll be working exclusively within the <code>&lt;script&gt;</code> element at the end of the <code>&lt;body&gt;</code>. The code includes some simple styles and dynamically changes the content as you click the links. In reality, this could be loaded from your server via <code>XMLHttpRequest</code>, but for the purposes of this demonstration I’ve bundled it up into a self-contained file. The important part is that we have a quick-and-dirty dynamic page to work with, so let the fun begin!</p>
<p>At the moment there, is no bookmarkable URL for the different states of this page. If you click around the navigation items, then click Back in your browser, you won’t be taken back to the previous state and may even be taken away from the page to whatever you viewed before (depending on your browser). It would be nice if you could share “Socks” with your friends, right? We can do that via <code>history.pushState()</code>.</p>
<p>The <code>history.pushState()</code> method takes three parameters:</p>
<dl>
<dt><code>data</code></dt>
<dd>Some structured data, such as settings or content, assigned to the history item.</dd>
<dt><code>title</code></dt>
<dd>The name of the item in the history drop-down shown by the browser’s back and forward buttons. (Note: this is not currently supported by any major browsers.)</dd>
<dt><code>url</code> <em>(optional)</em></dt>
<dd>The URL to this state that should be displayed in the address bar.</dd>
</dl>
<p>With these parameters, you can define the state of the page, give that state a name, and even provide a bookmarkable address, as if the page had reloaded entirely. Let’s dive right in and add this to the <code>clickHandler</code> function, right above the <code>return</code> statement:</p>
<figure>
<pre><code>function clickHandler(e) {
  /* Snip... */

  // Add an item to the history log
  history.pushState(data, event.target.textContent, event.target.href);

  return event.preventDefault();
}
</code></pre>
</figure>
<p>The single line of code we added informs the <code>history</code> object that:</p>
<ul>
<li>we want to add an item to the log,</li>
<li>it should remember the data that we’ve already loaded,</li>
<li>it should assign a name to this state based on the text of the link we clicked (even though this isn’t used — it’s good to get into the habit of recording a name for the state), and</li>
<li>it should update the address bar with the <code>href</code> attribute of that link.</li>
</ul>
<p>Reload the page in your browser and click a few of the links, keeping an eye on the address bar. Notice how it changes on each click, despite the fact that you aren’t actually navigating away from this page. If you also have a look at your history log, you’ll see a long list of page titles (in this case ”Kittens!” over and over). Provided your server is set up to serve the correct page upon access, the user could copy that URL and paste it into a new browser window to jump straight to that kitten.</p>
<p>At the moment, clicking the back button will pop you through the history items, but the page won’t react to these changes. That&#8217;s because so far, we’ve only created the history records. How can we allow active users to return to a previous state? We listen to the <code>popstate</code> event.</p>
</section>
<section id="historical-events">
<h2>Historical Events in Navigation <a class="permalink" href="#historical-events">#</a></h2>
<p>The user agent fires a <code>popstate</code> event when the user navigates through their history, whether backwards or forwards, provided it isn’t taking the user away from the current page. That is, all those <code>pushState</code>s we called will keep the user on the current page, so the <code>popstate</code> event will fire for each history item they pop through.</p>
<p>Before the closing <code>&lt;/script&gt;</code> tag, add a new listener for the <code>popstate</code> event:</p>
<figure>
<pre><code>// Revert to a previously saved state
window.addEventListener('popstate', function(event) {
  console.log('popstate fired!');

  updateContent(event.state);
});
</code></pre>
</figure>
<p>We attach the event listener to the <code>window</code>, which is responsible for firing the event, and pass this event into our handler. We log a message (so we can see when this event is firing), and then we update the content using the state we saved previously. The state is attached to the <code>event</code> object via the <code>state</code> property.</p>
<p>Open up the page fresh in your browser, click around like before, and then click back. As before, the URL in the address bar changes as you cycle through states, but now the content is also restored back to what it should be. Click forward, and the content is likewise correctly restored.</p>
<div class="callout warning-block">
<p>If you look at the developer console in Chrome when you load the page for the first time, you’ll see the <code>popstate</code> event fired immediately, before you’ve even clicked a link. This is because Chrome considers the initial page load to be a change in state, and so it fires the event. In this instance, the <code>state</code> property is <code>null</code>, but thankfully the <code>updateContent</code> function deals with this. Keep this in mind when developing as it could catch you out, especially if other browsers assume this behavior.</p>
</p></div>
</section>
<section id="rewriting-history">
<h2>Rewriting history <a class="permalink" href="#rewriting-history">#</a></h2>
<p>Unfortunately, as fantastic as HTML5 is, it doesn’t allow us actual time travel. If it did, I would be going back to my childhood and telling a younger me, “Yes, you should have a slice of cake”. Take that as you will.</p>
<p>The History API does, however, allow us to make amends to our history log items. For example, we could update the current state in response to fresh user input in a form. We can do this with <code>history.replaceState</code>.</p>
<p><code>replaceState</code> works just as <code>pushState</code> does, with the exact same parameters, except that it updates the current entry instead of adding a new one. I can think of one situation in our demo where this could be used: the initial page load. If you click back for long enough, you’ll find that going back to the original URL doesn’t provide you the original content. Let’s fix that by adding the following to the bottom of our script:</p>
<figure>
<pre><code>// Store the initial content so we can revisit it later
history.replaceState({
  content: contentEl.textContent,
  photo: photoEl.src
}, document.title, document.location.href);
</code></pre>
</figure>
<p>As this runs when the page loads, it saves the initial page state. We can later load this state when the user browses back to this point via the event listener we set up previously. You can try it out by loading up the page, clicking a few links, and then hitting back until you return to the original URL. The initial content has returned!</p>
</section>
<section id="demo">
<h2>Demo <a class="permalink" href="#demo">#</a></h2>
<p>I’ve set up a demo of our completed code. I’ve also added a little back-end magic to make our <code>history.pushState</code> URLs work like a real site. Remember that the URLs you push should be live URLs that the user can bookmark and share as real entry points to your site.</p>
<p class="btn half"><a href="http://html5doctor.com/demos/history/">View the History API demo</a></p>
</section>
<section id="browser-support">
<h2>Browser support <a class="permalink" href="#browser-support">#</a></h2>
<p>Up-to-date copies of Chrome (5+), Safari (5.0+), Firefox (4.0+), and Opera (11.50+) have support for the new History API. Even some mobile browsers work just fine, like Mobile Safari on iOS 4+. Unfortunately, IE 9 and below lack support, but it <a href="http://msdn.microsoft.com/en-us/ie/hh272905.aspx#_HTML5History">should work in IE 10</a> when it arrives.</p>
<p>Safari 5.0 sometimes exhibits one oddity: navigating between states causes the loading spinner to appear and stay even when the state has been loaded. This stops when you navigate away using a link or action that does not involve a state saved by the History API.</p>
<section id="polyfill">
<h3>Polyfill <a class="permalink" href="#polyfill">#</a></h3>
<p>A polyfill does exist for the History API. The aptly named <a href="https://github.com/balupton/history.js">History.js</a> uses HTML4’s <code>hashchange</code> event with document fragment identifiers to mimic the history API in older browsers. If one of the hash URLs is used by a modern browser, it uses <code>replaceState</code> to quietly correct the URL.</p>
<p>It sounds like magic, but make sure you’re aware of the consequences of using fragment identifiers, as mentioned previously in this article. As such, the author of History.js has put together a guide titled <a href="https://github.com/balupton/history.js/wiki/Intelligent-State-Handling">Intelligent State Handling</a>.</p>
</section>
</section>
<section id="closing">
<h2>Closing thoughts <a class="permalink" href="#closing">#</a></h2>
<p>URLs go beyond just the browsing session of a user. They’re historically important markers for resources that could very well remain in use for many years to come. Before you embark on developing your site’s JavaScript, you should give thought to the <a href="http://warpspire.com/posts/url-design/">design of your URLs</a>. Make them meaningful and organised. Make sure you can directly access them without JavaScript. Only then should you add your JavaScript to enhance the browsing experience.</p>
</section>
<div id="crp_related">
<h3>Related Posts:</h3>
<ul class="related">
<li><a href="http://html5doctor.com/server-sent-events/" rel="bookmark" class="crp_title">Server-Sent Events</a></li>
<li><a href="http://html5doctor.com/how-to-get-all-the-browsers-playing-ball/" rel="bookmark" class="crp_title">How to get all the browsers playing ball</a></li>
<li><a href="http://html5doctor.com/methods-of-communication/" rel="bookmark" class="crp_title">Methods of communication</a></li>
<li><a href="http://html5doctor.com/storing-data-the-simple-html5-way-and-a-few-tricks-you-might-not-have-known/" rel="bookmark" class="crp_title">Storing Data the Simple HTML5 Way (and a few tricks you might not have known)</a></li>
<li><a href="http://html5doctor.com/native-drag-and-drop/" rel="bookmark" class="crp_title">Native Drag and Drop</a></li>
</ul>
</div>
<p><a href="http://html5doctor.com/history-api/" rel="bookmark">Pushing and Popping with the History API</a> originally appeared on <a href="http://html5doctor.com">HTML5 Doctor</a> on November 15, 2011.</p>
]]></content:encoded>
			<wfw:commentRss>http://html5doctor.com/history-api/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Storing Data the Simple HTML5 Way (and a few tricks you might not have known)</title>
		<link>http://html5doctor.com/storing-data-the-simple-html5-way-and-a-few-tricks-you-might-not-have-known/</link>
		<comments>http://html5doctor.com/storing-data-the-simple-html5-way-and-a-few-tricks-you-might-not-have-known/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 14:00:36 +0000</pubDate>
		<dc:creator>Remy Sharp</dc:creator>
				<category><![CDATA[JavaScript APIs]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://html5doctor.com/?p=3600</guid>
		<description><![CDATA[This post is about the Web Storage API. Technically it's been shifted out of the HTML5 specification and can now be found in it's very own dedicated spec. But if it counts at all - it *used* to be part of the Web Applications spec.]]></description>
			<content:encoded><![CDATA[<p>Yes indeed people, it&#8217;s your favourite HTML5 Doctor with JavaScript knowledge who lives in Brighton near a golf course! I&#8217;m also shooting for the longest title we&#8217;ve published so far &#8211; and I think I&#8217;m in the lead.</p>

<p>This post is about the Web Storage API. Technically it&#8217;s been shifted out of the HTML5 specification and can now be found in it&#8217;s very own dedicated spec. But if it counts at all &#8211; it <em>used</em> to be part of the Web Applications spec.</p>

<p>Web Storage is a very, <strong>very</strong> simple way to store data in the client &#8211; i.e. the browser. What&#8217;s more, the support is fabulous: IE8 and upwards has support natively, and there&#8217;s lots of good <a href="http://remysharp.com/2010/10/08/what-is-a-polyfill/">polyfills</a> in the <a href="http://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills">wild already</a>.</p>

<p>This post however will just focus on the features of Web Storage and hopefully show you a trick or two you may not have known about.</p>

<h2>What Web Storage Does</h2>

<p>Using JavaScript, Web Storage makes it possible to easily store arbitrary values in the browser. Storage is different from cookies in that it&#8217;s <em>not shared</em> with the server. It&#8217;s also different from cookies in that it&#8217;s dead simple to work with.</p>

<p>There are two versions of Web Storage: local and session. Local means that it&#8217;s persistent, and session is simply that the data is lost when the session ends (i.e. when you close you browser window or tab). It&#8217;s also worth noting that a session is tied to a single browser window or tab. The session <em>doesn&#8217;t</em> leak out in to other open windows on that same domain.</p>

<p>Any data stored is tied to the document origin, in that it&#8217;s tied to the specific protocol (http or https, etc), the host (html5doctor.com) and the port (usually port 80).</p>

<h2>Get Storing</h2>

<p>The API for <code>localStorage</code> and <code>sessionStorage</code> is exactly the same, and distills down to the following methods:</p>

<ul>
<li>.setItem(key, value);</li>
<li>.getItem(key)</li>
<li>.removeItem(key)</li>
<li>.clear()</li>
<li>.key(index)</li>
<li>.length</li>
</ul>

<p>You can probably guess what most of those methods do, maybe not the last two, but ignore all that syntax for a moment.</p>

<p>Due to the way that the storage API has been defined, the set/get/remove methods all are getters, setters and deleters. What that means to you is you can use localStorage <a href="http://jsconsole.com/?localStorage.name%20%3D%20'Remy'%3B">as follows</a>:</p>

<pre><code>localStorage.name = 'Remy';
</code></pre>

<p>If you tried using the link above, this will save a property called &#8220;name&#8221; against localStorage. Completely closing your browser, and going back to <a href="http://jsconsole.com">http://jsconsole.com</a> and <a href="http://jsconsole.com/?console.log(localStorage.name)%3B">test the name property again</a>:</p>

<pre><code>console.log(localStorage.name);
</code></pre>

<p>Still holds the value doesn&#8217;t it? Pretty easy eh? And no faffing around with cookies, for that, we can be thankful!</p>

<p>Equally deleting data is <a href="http://jsconsole.com/?delete%20localStorage.name%3B%20localStorage.name">very easy</a>:</p>

<pre><code>delete localStorage.name;
console.log(localStorage.name);
</code></pre>

<p>You&#8217;ll see the value is undefined. </p>

<p>What&#8217;s happening under the hood is that when you set a property on <code>localStorage</code> (or <code>sessionStorage</code>) it&#8217;s calling the .setItem method. When you get a property, it&#8217;s calling .getItem and when you delete, it&#8217;s calling removeItem. That way you can treat the Web Storage interface as any other regular object in JavaScript, except you&#8217;ll know it&#8217;ll hang around after the page has unloaded.</p>

<h2>Hey everyone! I&#8217;m storing some data!</h2>

<p>That&#8217;s what your browser does when you store some data. It announces it via events. </p>

<p>When you set some data on localStorage or sessionStorage, an event, called &#8220;storage&#8221;, fires on all the other windows on the same origin.</p>

<p>To listen for events the following code is used:</p>

<pre><code>function storageEvent(event) {
  event = event || window.event; // give IE8 some love
  alert('Yo people! Something just got stored!');
}

if (window.attachEvent) { // ::sigh:: IE8 support
   window.attachEvent('onstorage', storageEvent);
} else {
    window.addEventListener('storage', storageEvent, false);
}
</code></pre>

<p><small>Note that as IE8 has support, if you don&#8217;t want to use <code>onstorage</code> you&#8217;ll want to double up your event listeners with <code>attachEvent</code>.</small></p>

<p>Clearly a massive alert box isn&#8217;t useful, but what is useful is what you capture inside of the event object:</p>

<ul>
<li>key &#8211; the property name of the value stored</li>
<li>newValue &#8211; the newly set value (duh!)</li>
<li>oldValue &#8211; the previous value before being overwritten by .newValue</li>
<li>url &#8211; the full url path of the origin of the storage event</li>
<li>storageArea &#8211; the storage object, either localStorage or sessionStorage</li>
</ul>

<p>With this information, you can do a lot with the storage event, like perhaps keep tabs that are open synchronised. Here&#8217;s a simple, contrived example of using localStorage to echo a value across different windows on <a href="http://html5demos.com/storage-events">html5demos.com</a>. </p>

<p>Or for a real world example, <a href="http://blog.fontdeck.com/post/8470748087/localstorage">Font Deck recently implemented this very feature</a>, if you change the sample text in one window, all other open tabs (or windows) mirror that <a href="http://fontdeck.com/typefaces/serif/garalde">same sample text</a>.</p>

<h2>Gotchas to watch out for</h2>

<p>The main gotcha with Web Storage is that although the specification <em>used to say</em><sup>&dagger;</sup> that any object type can be stored, in fact all browsers currently coerce to strings. That means if you want to store a JavaScript object (or an array perhaps), you&#8217;ll need to use <a href="http://www.json.org/">JSON</a> to <a href="http://jsbin.com/elicop/edit#preview">encode and decode</a>:</p>

<pre><code>var doctors = [
  'rem', 
  'rich_clark', 
  'brucel', 
  'jackosborne', 
  'leads', 
  'akamike', 
  'boblet'];
localStorage.doctors = JSON.stringify(doctors);

// later that evening…
var html5docs = JSON.parse(localStorage.doctors);
alert('There be ' + html5docs.length + ' doctors in the house');
</code></pre>

<p><small>&dagger; Edited thanks to <a href="http://html5doctor.com/storing-data-the-simple-html5-way-and-a-few-tricks-you-might-not-have-known/#comment-17291">feedback</a> from zcorpan</small></p>

<p>When working with storage events, a couple of things to also watch out for &#8211; this is on purpose of course, but still just about qualify for gotcha status:</p>

<ol>
<li>The event only fires on the <em>other</em> windows &#8211; it won&#8217;t fire on the window that did the storing.</li>
<li>The event won&#8217;t fire if the data doesn&#8217;t change, i.e. if you store .name = &#8216;Remy&#8217; and set it to &#8216;Remy&#8217; again it won&#8217;t fire the storage event (obviously, since nothing was stored).</li>
</ol>

<h2>and finally&#8230;</h2>

<p>If you want to use web storage in browsers like IE6 and IE7 (or rather than <em>want</em>: <em>need</em> to in your particular case) &#8211; then there&#8217;s no shortage of polyfills for Web Storage. However be wary that you&#8217;ll need to stick to the regular <code>setItem</code> syntax rather than being able to use the sexy setter/getter syntax &#8211; and I&#8217;ve yet to see a polyfill that supports the storage events.</p>

<p>Maybe that isn&#8217;t a problem for you though &#8211; maybe the sheer simplicity and spiffingness of Web Storage is enough to just support IE8 and above with this enhanced client storage model.<div id="crp_related"><h3>Related Posts:</h3><ul class="related"><li><a href="http://html5doctor.com/methods-of-communication/" rel="bookmark" class="crp_title">Methods of communication</a></li><li><a href="http://html5doctor.com/server-sent-events/" rel="bookmark" class="crp_title">Server-Sent Events</a></li><li><a href="http://html5doctor.com/how-to-get-all-the-browsers-playing-ball/" rel="bookmark" class="crp_title">How to get all the browsers playing ball</a></li><li><a href="http://html5doctor.com/history-api/" rel="bookmark" class="crp_title">Pushing and Popping with the History API</a></li><li><a href="http://html5doctor.com/native-drag-and-drop/" rel="bookmark" class="crp_title">Native Drag and Drop</a></li></ul></div></p>
<p><a href="http://html5doctor.com/storing-data-the-simple-html5-way-and-a-few-tricks-you-might-not-have-known/" rel="bookmark">Storing Data the Simple HTML5 Way (and a few tricks you might not have known)</a> originally appeared on <a href="http://html5doctor.com">HTML5 Doctor</a> on August 23, 2011.</p>
]]></content:encoded>
			<wfw:commentRss>http://html5doctor.com/storing-data-the-simple-html5-way-and-a-few-tricks-you-might-not-have-known/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Finding your position with Geolocation</title>
		<link>http://html5doctor.com/finding-your-position-with-geolocation/</link>
		<comments>http://html5doctor.com/finding-your-position-with-geolocation/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 14:35:07 +0000</pubDate>
		<dc:creator>Ian Devlin</dc:creator>
				<category><![CDATA[JavaScript APIs]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[geolocation]]></category>

		<guid isPermaLink="false">http://html5doctor.com/?p=3324</guid>
		<description><![CDATA[<p>The Geolocation API provides a method to locate the user's exact (more or less - see below) position. This is useful in a number of ways ranging from providing a user with location specific information to providing route navigation.</p>]]></description>
			<content:encoded><![CDATA[		<p>The Geolocation API provides a method to locate the user&#8217;s exact (more or less &#8211; see below) position. This is useful in a number of ways ranging from providing a user with location specific information to providing route navigation.</p>
		
		<p>Although it&#8217;s not actually part of the HTML5 specification, as it was developed as a separate specification by the <a href="http://dev.w3.org/geo/api/spec-source.html">W3C</a>, rather than the <a href="http://www.whatwg.org/">WHATWG</a>, if the esteemed HTML5 Doctors <A href="http://html5doctor.com/author/remys/">Remy Sharp</a> and <a href="http://html5doctor.com/author/brucel/">Bruce Lawson</a> felt it was fitting enough to include in <a href="http://introducinghtml5.com/">their book</a>, then it&#8217;s perfectly ok to write about it here.</p>
		<p>The API is actually remarkably simple to use and this article aims to introduce the API and show just how easy it is.</p>	
	
		<section>
			<h2>Browser Compatibility</h2>		
			<p>Currently the W3C Geolocation API is supported by the following desktop browsers:</p>
			<ul>
				<li>Firefox 3.5+</li>
				<li>Chrome 5.0+</li>
				<li>Safari 5.0+</li>
				<li>Opera 10.60+</li>
				<li>Internet Explorer 9.0+</li>
			</ul>
			<p>There is also support for the W3C Geolocation API on mobile devices:</p>
			<ul>
				<li>Android 2.0+</li>
				<li>iPhone 3.0+</li>
				<li>Opera Mobile 10.1+</li>
				<li>Symbian (S60 3rd &#038; 5th generation)</li>
				<li>Blackberry OS 6</li>			
				<li>Maemo</li>
			</ul>
		</section>
		
		<section>
			<h2>Data Protection</h2>
			<p>The specification explicitly states that since the nature of the API also exposes the user&#8217;s location and therefore could compromise their privacy, the user&#8217;s permission to attempt to obtain the geolocation information must be sought before proceeding. The browser will take care of this, and a message will either appear as a popup box, or at the top of the browser (implementation is browser specific) requesting the user&#8217;s permission.</p>
			<figure>
				<img src="http://html5doctor.com/wp-content/uploads/2011/06/safari-geolocation-permission.jpg" alt="Screenshot of Safari's popup box asking for Geolocation permission" />
				<figcaption>Safari asking the user for permission to obtain their Geolocation information</figcaption>
			</figure>
		</section>
		
		<section>
			<h2>Geolocation sources</h2>
			<p>A number of different sources are used to attempt to obtain the user&#8217;s location, and each has their own varying degree of accuracy. A desktop browser is likely to use WiFi (accurate to 20m) or IP Geolocation which is only accurate to the city level and can provide false positives. Mobile devices tend to use <em>triangulation</em> techniques such as <dfn title="Global Positioning System">GPS</dfn> (accurate to 10m and only works outside), WiFi and <dfn title="Global System for Mobile">GSM</dfn>/<dfn title="Code division multiple access">CDMA</dfn> cell IDs (accurate to 1000m).</p>
		</section>		
		
		<section>
			<h2>Using the API</h2>
			<p>Before you actually attempt to use the Geolocation API, you first need to check if the browser actually supports it. The API usefully provides a function for this which can be called as follows:</p>
			<pre><code>if (navigator.geolocation) {
  // do fancy stuff
}</code></pre>
			<p>Obviously if this returns false, you should optionally inform the user of the inferiority of their browser and laugh in their face (not really).</p>
			<p>Through the API, there are two functions available to obtain a user&#8217;s location:</p>
			
			<section>
			<h3>getCurrentPosition and watchPosition</h3>
			<p>Both of these methods return immediately, and then asynchronously attempt to obtain the current location. They take the same number of arguments, two of which are optional:</p>
			<ol>
				<li><code>successCallback</code> &ndash; called if the method returns successfully</li>
				<li><code>[errorCallback]</code> &ndash; called if the method returns with an error</li>
				<li>[options] &ndash; a number of options are available:
					<ul>
						<li><code>enableHighAccuracy</code> &ndash; provides a hint that the application would like the best possible results. This may cause a slower response time and in the case of a mobile device, greater power consumption as it may use GPS. Boolean with a default setting of false.</li>
						<li><code>timeout</code> &ndash; indicates the maximum length of time to wait for a response. In milliseconds with a default of 0 &#8211; infinite.</li>
						<li><code>maximumAge</code> &ndash; denotes the maximum age of a cached position that the application will be willing to accept. In milliseconds, with a default value of 0, which means that an attempt must be made to obtain a new position object immediately.</li>
					</ul>
				</li>
			</ol>
			<p>Before mentioning the differences between the two, another method needs to be introduced:</p>
			</section>
			
			<section>
			<h3>clearWatch</h3>
			<p>This method takes one argument, the <code>watchID</code> of the watch process to clear (which is returned by <code>watchPosition</code>)</p>
			<p>Now, the main difference between <code>getCurrentPosition</code> and <code>watchPosition</code> is that <code>watchPosition</code> keeps informing your code should the position change, so basically it keeps updating the user&#8217;s position. This is very useful if they&#8217;re on the move and you want to keep track of their position, whereas <code>getCurrentPosition</code> is a once off.	This method also returns a <code>watchID</code> which is required when you want to stop the position constantly being updated by calling <code>clearWatch</code> method is called.</p>			
			<p>When the user&#8217;s position is returned, it is contained within a <code>Position</code> object which contains a number of properties:</p>
			<table>
			<thead>
				<tr>
					<th scope="col">Property</th>
					<th scope="col">Details</th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<th scope="row">coords.latitude</th>
					<td>Decimal degrees of the latitude</td>
				</tr>
				<tr>
					<th scope="row">coords.longitude</th>
					<td>Decimal degress of the longitude</td>
				</tr>
				<tr>
					<th scope="row">coords.altitude</th>
					<td>Height in metres of the position above the <a href="http://en.wikipedia.org/wiki/Reference_ellipsoid">reference ellipsoid</a></td>
				</tr>
				<tr>
					<th scope="row">coords.accuracy</th>
					<td>The accuracy in metres of the returned result. The value of this setting informs the application how useful the returned latitude/longitude value actually is. This can help in determining if the returned result is accurate enough for the purpose it is intended for, e.g. values for streetview locations will need to be more accurate than those for a country based location</td>
				</tr>
				<tr>
					<th scope="row">coords.altitudeAccuracy</th>
					<td>The accuracy in metres of the returned altitude</td>
				</tr>
				<tr>
					<th scope="row">coords.heading</th>
					<td>Direction of travel of the hosting device, clockwise from true north</td>
				</tr>
				<tr>
					<th scope="row">coords.speed</th>
					<td>The current ground speed of the hosting device in metres per second</td>
				</tr>
				<tr>
					<th scope="row">timestamp</th>
					<td>Timestamp of when the position was acquired</td>
				</tr>
			</tbody>
			</table>
			
			<p>Amongst these only which is <code>coords.latitude</code>, <code>coords.longitude</code> and <code>coords.accuracy</code> are guaranteed to be returned (all others may be <code>null</code>), and the first two are by and large the most relevant, as it is from these that a position can be plotted on a Google Map, for example.</p>
			<p>You can read more about the <a href="http://www.w3.org/TR/geolocation-API/#position_interface"><code>Position</code> object</a> and the <a href="http://www.w3.org/TR/geolocation-API/#coordinates_interface">coordinates interface</a> on the W3 specification itself.</p>
			</section>
		</section>
		
		<section>
			<h2>Putting it all together</h2>
			
			<p>Putting this altogether, the following code will attempt to obtain a user&#8217;s location, calling the method <code>displayPosition</code> on success which simply pops up an alert box with the captured latitude and longitude:</p>
			<pre><code>if (navigator.geolocation) {
  var timeoutVal = 10 * 1000 * 1000;
  navigator.geolocation.getCurrentPosition(
    displayPosition, 
    displayError,
    { enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 }
  );
}
else {
  alert("Geolocation is not supported by this browser");
}

function displayPosition(position) {
  alert("Latitude: " + position.coords.latitude + ", Longitude: " + position.coords.longitude);
}</code></pre>
			<p>The code above also calls the <code>displayError</code> method when attempt to fetch the user&#8217;s location data. This function simple converts the returned error code to an appropriate message:</p>
	<pre><code>function displayError(error) {
  var errors = { 
    1: 'Permission denied',
    2: 'Position unavailable',
    3: 'Request timeout'
  };
  alert("Error: " + errors[error.code]);
}</code></pre>
		<section>
			<h3>A final word</h3>
			<p>This is just a simple introduction to using the Geolocation API and one of it&#8217;s uses.</p>
			<p>Of course the API can be used for more than simply plotting a position on a map (although that in itself is quite useful). The specification itself offers a list of potential
			<a href="http://www.w3.org/TR/geolocation-API/#usecases_section">use cases</a> for the API such as:</p>
			<ul>
				<li>Finding and plotting points of interest in the user&#8217;s area</li>
				<li>Annotating content with location information</li.
				<li>Showing a user&#8217;s position on a map (helping with directions of course!)</li>
				<li>Turn-by-turn route navigation &#8211; using <code>watchPosition</code></li>
				<li>Up-to-date local information &#8211; updates as you move</li>
			</ul>
		</section>	
		</section>
		
		
		<section>
			<h2>Examples</h2>
			<p>To see geolocation in action, I&#8217;ve put together a couple of quick examples in which I encourage you to view source and then go and try it out for yourself.</p>
			<ul>
				<li><a href="http://html5doctor.com/demos/geolocation/geolocation-getcurrentposition-example.html">Plot a location on a Google Map using <code>getPosition</code></a></li>
				<li><a href="http://html5doctor.com/demos/geolocation/geolocation-watchposition-example.html">Plot and update a location on a Google Map using <code>watchPosition</code></a> &ndash; this is best viewed on a moving device so you can see the position updating</li>
			</ul>
		</section><div id="crp_related"><h3>Related Posts:</h3><ul class="related"><li><a href="http://html5doctor.com/html5-briefing-notes-journalists-analysts/" rel="bookmark" class="crp_title">HTML5: briefing notes for journalists and analysts</a></li><li><a href="http://html5doctor.com/introducing-web-sql-databases/" rel="bookmark" class="crp_title">Introducing Web SQL Databases</a></li><li><a href="http://html5doctor.com/your-questions-answered-8/" rel="bookmark" class="crp_title">Your Questions Answered #8</a></li><li><a href="http://html5doctor.com/the-output-element/" rel="bookmark" class="crp_title">The output element</a></li><li><a href="http://html5doctor.com/the-contenteditable-attribute/" rel="bookmark" class="crp_title">The contenteditable attribute</a></li></ul></div><p><a href="http://html5doctor.com/finding-your-position-with-geolocation/" rel="bookmark">Finding your position with Geolocation</a> originally appeared on <a href="http://html5doctor.com">HTML5 Doctor</a> on June 14, 2011.</p>
]]></content:encoded>
			<wfw:commentRss>http://html5doctor.com/finding-your-position-with-geolocation/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Go offline with application cache</title>
		<link>http://html5doctor.com/go-offline-with-application-cache/</link>
		<comments>http://html5doctor.com/go-offline-with-application-cache/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 15:00:48 +0000</pubDate>
		<dc:creator>Mike Robinson</dc:creator>
				<category><![CDATA[JavaScript APIs]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[manifest]]></category>
		<category><![CDATA[offline]]></category>

		<guid isPermaLink="false">http://html5doctor.com/?p=2729</guid>
		<description><![CDATA[<p>HTML5 introduces new methods for enabling a web site or web application to function without a network connection. When you're working on a mobile connection and your signal drops, or you just have no connection to the internet for whatever reason, having some level of access is better than nothing. In this article, we'll look at how the application cache can store resources to be used by the browser when it's offline, granting your users partial access to your web site or application.</p>]]></description>
			<content:encoded><![CDATA[<p><abbr>HTML</abbr>5 introduces new methods for enabling a web site or web application to function without a network connection. When you&#8217;re working on a mobile connection and your signal drops, or you just have no connection to the internet for whatever reason, having some level of access is better than nothing. In this article, we&#8217;ll look at how the application cache can store resources to be used by the browser when it&#8217;s offline, granting your users partial access to your web site or application.</p>

<p>The <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html">application cache</a> is controlled by a plain text file called a manifest, which contains a list of resources to be stored for use when there is no network connectivity. The list can also define the conditions for caching, such as which pages should never be cached and even what to show the user when he follows a link to an uncached page.</p>

<p>If the user goes offline but has visited the site while online, the cached resources will be loaded so the user can still view the site in a limited form. By carefully considering the contents of your manifest file, you can offer a suitable web experience to a disconnected user.</p>

<section id="manifest">
  <h2>The manifest file</h2>
  <p>Let&#8217;s start with an example of a full manifest file. (Don&#8217;t worry, I&#8217;ll explain it all in detail!)</p>
  
  <figure>
    <pre><code>CACHE MANIFEST
      
# This is a comment

CACHE:
/css/screen.css
/css/offline.css
/js/screen.js
/img/logo.png

http://example.com/css/styles.css

FALLBACK:
/ /offline.html

NETWORK:
*
</code></pre>
    <figcaption>An example application cache manifest file</figcaption>
  </figure>
  
  <p>Each directive is placed on a new line, with comments prefixed by a hash (#). The first line, <code>CACHE MANIFEST</code>, tells the browser that this is a manifest file. The uppercased lines with trailing colons are section headings.</p>
  
  <p>There are three different sections in a manifest file:</p>
  
  <dl>
    <dt>CACHE</dt>
    <dd>A list of explicit <abbr>URL</abbr>s to request and store</dd>
    <dt>FALLBACK</dt>
    <dd>What to do when an offline user attempts to access an uncached file</dd>
    <dt>NETWORK</dt>
    <dd>Which resources are available only while online</dd>
  </dl>
  
  <p>Each section serves a specific purpose that you must understand in order to successfully and effectively cache your resources.</p>
  
  <section id="cache">
    <h3>CACHE</h3>
    <p>The <code>CACHE</code> section is considered the default — i.e., if no section heading has been defined, the browser will assume this is the <code>CACHE</code> section. Beneath this heading, you can list <abbr>URI</abbr>s to resources you want the browser to download and cache for offline use, including <abbr>URI</abbr>s hosted externally.</p>
  
    <figure>
      <pre><code>CACHE MANIFEST

/css/screen.css
/css/offline.css
/js/screen.js
/img/logo.png

http://example.com/css/widget.css</code></pre>

      <figcaption>Telling the browser to cache some stylesheets, an image, and a JavaScript file</figcaption>
    </figure>
  
    <p>In this example, I&#8217;ve omitted the <code>CACHE:</code> heading to take advantage of the default behaviour. I have provided the browser with four paths relative to the root of the domain plus one external resource. When the browser downloads the cache manifest file, it will read these five resources, fetch them over <abbr>HTTP</abbr>, and store them for later use.</p>
  
    <p>Every single resource that you want to cache explicitly should be listed here, right down to the last image. The browser is not aware of a resource unless you provide the full path to it. This means <strong>you can&#8217;t use wildcards</strong>. If you list <code>/images/*</code> as a resource, the browser will request that <abbr>URI</abbr> as if you typed it into your address bar.</p>
  
    <p>But don&#8217;t run off and shove <abbr>URI</abbr>s for every single page on your site into your manifest! When a user visits a page that points to the manifest file, that page will also be cached. This means that if you want to allow users access to pages they&#8217;ve already viewed, just make those pages point to the manifest file and the browser will cache them appropriately.</p>
  
    <p>Now let&#8217;s tell the browser what to do with uncached resources.</p>
  </section>
  
  <section id="fallback">
    <h3>FALLBACK</h3>
  
    <p>The <code>FALLBACK</code> section tells the browser what to serve when the user tries to access an uncached resource while offline. Because of this, it looks a bit different than <code>CACHE</code> and <code>NETWORK</code>. It contains two values per line, separated by a space. The first value is the request <abbr>URI</abbr> to match, and the second is the resource sent upon matching. It caches the resource on the right for offline use, so this should be an explicit path.</p>
    
    <p>Lost? Take a look at this example:</p>
  
    <figure>
      <pre><code>CACHE MANIFEST

FALLBACK:
/status.html /offline.html</code></pre>
      <figcaption>Declaring a <code>FALLBACK</code> section</figcaption>
    </figure>
  
    <p>On the line below <code>FALLBACK:</code>, we have the <abbr>URI</abbr> &#8220;/status.html&#8221; followed by a second <abbr>URI</abbr>, &#8220;/offline.html&#8221;. We&#8217;re telling the browser that when an offline user requests a <abbr>URI</abbr> matching &#8220;/status.html&#8221;, it should instead serve the cached file &#8220;offline.html&#8221;.</p>
    
    <p>However, the <code>FALLBACK</code> section can be far more powerful:</p>
  
    <figure>
      <pre><code>CACHE MANIFEST

FALLBACK:
/ /offline.html</code></pre>
      <figcaption>Matching all resources</figcaption>
    </figure>
  
    <p>In this example, I&#8217;ve dropped &#8220;status.html&#8221; and simply provided &#8220;/&#8221; as the request <abbr>URI</abbr> to match. Now when an offline user requests a resource that matches &#8220;/&#8221;, he will be served &#8220;offline.html&#8221; in its place. So if the user clicked on a link for &#8220;/status.html&#8221;, &#8220;/about.html&#8221;, or even &#8220;/my/nested/resource.html&#8221;, the browser would match the &#8220;/&#8221; at the start and serve up &#8220;offline.html&#8221;. Since I&#8217;ve used the root path, every uncached resource under this domain will point to &#8220;offline.html&#8221;.</p>
  
    <p class="disclaimer"><strong>Errata 23 June 2011:</strong> this article has been corrected as you <em>can&#8217;t</em> use a wildcard with the <code>FALLBACK</code> or <code>NETWORK</code> namespaces &#8211; though you can use the asterisk symbol under <code>NETWORK</code> as it&#8217;s a special flag to indicate all urls should be whitelisted.</p>

    <p>The <code>CACHE</code> section, both the <code>FALLBACK</code> and <code>NETWORK</code> namespaces support a prefix rule that aid their <abbr>URI</abbr> matching. In that any requests to the <code>/avatar</code> directory, whilst offline, if the asset is unavailable the browser can serve up an alternative.</p>
    
    <figure>
      <pre><code>CACHE MANIFEST

FALLBACK:
/images/avatars/ /offline_avatar.png</code></pre>
      <figcaption>A smarter fallback declaration</figcaption>
    </figure>
  
    <p>The first line tells the browser to serve &#8220;/offline_avatar.png&#8221; in place of user-uploaded avatars.</p>
  
    <p>Remember when I said that any document referencing the manifest will also be cached? Well, you can use this to your advantage! You can cache each page the user visits while online so that they will have access to that page while offline. Then anything they didn&#8217;t view will be caught by the <code>FALLBACK</code> section. This keeps you from explicitly stating you want all your pages cached, and, more importantly, avoids the huge performance penalty of serving all the resources you want cached every time someone first visits your site.</p>
  </section>
  
  <section id="network">
    <h3>NETWORK</h3>
    <p>Finally, we have the <code>NETWORK</code> section, used to tell the browser explicitly which resources are only available while online. By default, this uses the asterisk <code>*</code> symbol, meaning all resources that are not cached will require a connection. Alternatively we can whitelist specific url prefixes, like all the avatars if we wish.</p>
  
    <figure>
      <pre><code>CACHE MANIFEST

NETWORK:
*</code></pre>
      <figcaption>Adding a <code>NETWORK</code> section</figcaption>
    </figure>
  
    <p>You can explicitly define resources not to cache by providing a list of <abbr>URI</abbr>s — essentially a whitelist of online-only assets.</p>
  
    <figure>
      <pre><code>CACHE MANIFEST

NETWORK:
register.php
login.php</code></pre>
      <figcaption>Excluding certain pages from caching</figcaption>
    </figure>
  </section>

</section>

<section id="serving-manifest">
  <h2>Serving the manifest</h2>
  
  <p>You can reference a manifest file on a web page by adding the <code>manifest</code> attribute to your opening <code>&lt;html&gt;</code> tag. The browser will only cache pages that include this attribute (in addition to those specified in the manifest itself, though in that instance, the user would have to visit a page including the manifest in order for the browser to be aware of it).</p>
  
  <figure>
    <pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en" manifest="/offline.appcache"&gt;
  // your html document
&lt;/html&gt;
</code></pre>
    <figcaption>Referencing the manifest file from an <abbr>HTML</abbr> page</figcaption>
  </figure>

  <p>The linked file should also be served with a <abbr>MIME</abbr>-type of <code>text/cache-manifest</code>. If you&#8217;re using <a href="http://httpd.apache.org/">Apache</a> as your web server, add this to your <code>.htaccess</code> file:</p>
  
  <figure>
    <pre><code>AddType text/cache-manifest .appcache
</code></pre>
  </figure>
  
  <p>And there you have it! Supporting browsers will retrieve the manifest file and cache each item on the list for offline use. Won&#8217;t your parents be proud?</p>
</section>

<section id="trigger-refresh">
  <h2>Triggering a cache refresh</h2>
  
  <p>Once a cache has been successfully downloaded, the browser will retain those assets until either the user clears the cache or you trigger an update. Triggering an update with your manifest file requires that the contents of that file change, not just the assets themselves.</p>
  
  <p><strong>Updating the assets on your server will not trigger a cache update. You must modify the manifest file.</strong></p>
  
  <p>If you&#8217;re adding or removing resources completely, you&#8217;ll have to edit your manifest file anyway. But what if you&#8217;re just amending an already cached stylesheet?</p>
  
  <p>This is where comments come in handy. Just throw in a simple version number comment that you change when you want to trigger an update:</p>
  
  <figure>
    <pre><code>CACHE MANIFEST
      
# Version 9

CACHE:
/css/screen.css</code></pre>
    <figcaption>A version comment in a manifest file</figcaption>
  </figure>

  <p>The next time you want to trigger a cache refresh, just increment the version number. When the user next visits the online version of a page including this manifest, it will re-download the manifest file, notice the change, download the listed assets, and purge the existing cache.</p>
  
  <p><strong>Browser bug:</strong> Firefox caches the manifest file itself and will not update it even if the manifest has changed on the server. With some server config wizardry, you can tell browsers that the cache of the manifest file is instantly invalidated and should be requested from the server every time it&#8217;s referenced. Add this to your <code>.htaccess</code> to put Firefox in its place:</p>
  
  <figure>
    <pre><code>&lt;IfModule mod_expires.c&gt;
  ExpiresActive On
  ExpiresByType text/cache-manifest "access plus 0 seconds"
&lt;/IfModule&gt;
</code></pre>
  </figure>
</section>

<section id="conclusion">
  <h2>Conclusion</h2>
  
  <p>The application cache is a powerful beast, and to tame it you need to be clear on what&#8217;s involved. Give thought to your <code>CACHE</code>, <code>FALLBACK</code>, and <code>NETWORK</code> sections to provide a suitable offline experience to your users.</p>
  
  <p>In a future article, we&#8217;ll show you how to use the <code>applicationCache</code> JavaScript object to manipulate the cache. Until then, this should be enough to get you started on the path to offline web content.</p>
  
  <p>You can see a live demo using the application cache over on Doctor Remy&#8217;s <a href="http://html5demos.com/offlineapp">HTML5 Demos</a>. Happy caching!</p>
</section>
<div id="crp_related"><h3>Related Posts:</h3><ul class="related"><li><a href="http://html5doctor.com/your-questions-answered-9/" rel="bookmark" class="crp_title">Your Questions Answered 9</a></li><li><a href="http://html5doctor.com/your-questions-answered-10/" rel="bookmark" class="crp_title">Your Questions Answered #10</a></li><li><a href="http://html5doctor.com/the-nsfw-element/" rel="bookmark" class="crp_title">The nsfw element</a></li><li><a href="http://html5doctor.com/server-sent-events/" rel="bookmark" class="crp_title">Server-Sent Events</a></li><li><a href="http://html5doctor.com/your-questions-answered-3/" rel="bookmark" class="crp_title">Your Questions Answered #3</a></li></ul></div><p><a href="http://html5doctor.com/go-offline-with-application-cache/" rel="bookmark">Go offline with application cache</a> originally appeared on <a href="http://html5doctor.com">HTML5 Doctor</a> on January 25, 2011.</p>
]]></content:encoded>
			<wfw:commentRss>http://html5doctor.com/go-offline-with-application-cache/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Methods of communication</title>
		<link>http://html5doctor.com/methods-of-communication/</link>
		<comments>http://html5doctor.com/methods-of-communication/#comments</comments>
		<pubDate>Tue, 18 Jan 2011 14:30:41 +0000</pubDate>
		<dc:creator>Remy Sharp</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[JavaScript APIs]]></category>
		<category><![CDATA[apis]]></category>
		<category><![CDATA[cors]]></category>
		<category><![CDATA[eventsource]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[messaging]]></category>
		<category><![CDATA[websockets]]></category>
		<category><![CDATA[xhr]]></category>

		<guid isPermaLink="false">http://html5doctor.com/?p=2847</guid>
		<description><![CDATA[By now, you've surely realised that 'HTML5' is so much more than just markup. There's also an army of associated JavaScript APIs. Among the ranks are a few new technologies that open up how we communicate between client and server and across documents. Let's take a look.]]></description>
			<content:encoded><![CDATA[<p>By now, you&#8217;ve surely realised that &#8220;<abbr>HTML</abbr>5&#8221; is so much more than just markup. There&#8217;s also an army of associated JavaScript <abbr>API</abbr>s. Among the ranks are a few new technologies that open up how we communicate between client and server and across documents. Let&#8217;s take a look.</p>

<p>This post will be an overview of the technologies available, how well they&#8217;re currently supported, and, where possible, live demos. I&#8217;m going to touch on the following technologies:</p>

<ul>
<li><abbr title="XML HTTP Request">XHR</abbr> &amp; <abbr>XHR</abbr>2 with <abbr title="Cross-Origin Resource Sharing">CORS</abbr></li>
<li>Web Messaging</li>
<li>Web Sockets</li>
<li>Server Sent Events</li>
<li>Web Workers</li>
</ul>

<p>Before I get on to the <abbr>API</abbr>s, I want to outline a fairly common communication model that several of these <abbr>API</abbr>s use. </p>

<h2 id="a_common_communication_event_model">A common communication event model</h2>

<p>All event handlers (with the exception of <abbr>XHR</abbr>) receive an <code>event</code> object containing a <code>data</code> property. This property includes the data sent as part of the message.</p>

<p>The event model (again with the exception of <abbr>XHR</abbr>) is <em>mostly</em> based around <code>onmessage</code> and <code>postMessage</code> or <code>send</code>. For example:</p>

<pre><code>// in the recipient code
recipient.onmessage = function (event) {
  console.log('received message: ' + event.data);
};

// from the sender code
recipient.postMessage('hi there'); // or recipient.send('hi there');
</code></pre>

<p>This is just a common model and isn&#8217;t the exactly the same among all these technologies. The two key similarities are that they use:</p>

<ul>
<li>a sending method (<code>postMessage</code> or <code>send</code>) on the recipient object, and</li>
<li>an event handler that listens for the <code>message</code> event and receives an <code>event</code> object containing a <code>data</code> property.</li>
</ul>

<p>Very importantly, <em>most</em> browsers only support sending strings from sender to recipient, so we often need to <abbr>JSON</abbr> <code>stringify</code> and <code>parse</code> if we want to send anything other than a string.</p>

<h2 id="xhr_xhr2_with_cors"><abbr>XHR</abbr> &amp; <abbr>XHR</abbr>2 with <abbr>CORS</abbr></h2>

<p><abbr>XHR</abbr> can be both synchronous and asynchronous. <abbr>XHR</abbr> is the only <abbr>API</abbr> that (purposely) supports synchronous requests, meaning the execution of code will block until the callback fires. </p>

<p>There&#8217;s nothing particularly new about <abbr>XHR</abbr>, but in <abbr>XHR</abbr>2 we can handle uploads, and there&#8217;s a <code>progress</code> event to tell you how the upload or download is getting on.  </p>

<p>The super shiny new toy in <abbr>XHR</abbr>2 is its support for <a href="http://www.w3.org/TR/cors/">Cross-Origin Resource Sharing</a> (CORS). This means you can make an <abbr>XHR</abbr> request across domains, but <strong>only if the server you&#8217;re connecting to allows it</strong>.</p>

<p>The request is as you&#8217;d expect from <abbr>XHR</abbr>:</p>

<pre><code>var client = new XMLHttpRequest();
client.onreadystatechange = function () {
  if (this.readyState == 4 &amp;&amp; this.status == 200) {
    alert('The most awesome-est person to follow: ' + this.responseText);
  }
};
client.open('GET', '/no-cors');
client.send();</code></pre>

<p>If our server responds with a <abbr>CORS</abbr> header, however, we can put our <abbr>XHR</abbr> responder on another server. So on the <abbr>URL</abbr> <a href="http://remysharp.com/demo/cors.php">http://remysharp.com/demo/cors.php</a>, I have the following PHP script:</p>

<pre><code>&lt;?php
header('Access-Control-Allow-Origin: *');
?&gt;
@rem
</code></pre>

<p>This says that anyone can make an <abbr>XHR</abbr> request to this particular script. Now when I run the following code in a browser that supports <abbr>XHR</abbr>2, the cross domain request succeeds!</p>

<pre><code>var client = new XMLHttpRequest();
client.onreadystatechange = function () {
  if (this.readyState == 4 &amp;&amp; this.status == 200) {
    alert('The most awesome-est person to follow: ' + this.responseText);
  }
};
client.open('GET', 'http://remysharp.com/demo/cors.php');
client.send();</code></pre>

<p>Here&#8217;s a <a href="http://jsbin.com/oxiyi4">live example of CORS</a>. (You can also <a href="http://jsbin.com/oxiyi4/edit">edit it here</a>.)</p>

<p>Note that <abbr>IE</abbr>8 supports <abbr>CORS</abbr>, but not <abbr>XHR</abbr>2 (no surprise there then). You need to use their proprietary (booo!) <code>XDomainRequest</code> object. Nicholas C. Zakas has <a href="http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/">an excellent article</a> explaining how to handle these differences.</p>

<p><abbr>XHR</abbr> usage is pretty common already, but <abbr>XHR</abbr>2 with <abbr>CORS</abbr> is a winner over <abbr>JSON-P</abbr>, particularly as you have finer control over the request, can handle timeouts, and can handle errors correctly.</p>

<h3 id="support_for_xhr_xhr2_with_cors">Support for <abbr>XHR</abbr> &amp; <abbr>XHR</abbr>2 with <abbr>CORS</abbr></h3>

<ul>
<li><abbr>XHR</abbr> support is pretty solid nowadays (even though <abbr>IE</abbr>6 uses <code>ActiveXObject</code> to get it going)</li>
<li><abbr>XHR</abbr>2 with <abbr>CORS</abbr>: Safari &amp; MobileSafari, Firefox 3.5, Chrome and <abbr>IE</abbr>8 (via XDomainRequest)</li>
</ul>

<h2 id="postmessage">postMessage</h2>

<p>This <abbr>API</abbr> is older, but it&#8217;s very useful if you want to get around the <abbr>XHR</abbr> same-origin rules. If you have an <code>&lt;iframe&gt;</code> document that can accept <code>onmessage</code> events from your origin (i.e., your site), then you can communicate across domains (and origins).</p>

<p>For example, a page that accepts an <code>onmessage</code> event might contain code such as this:</p>

<pre><code>window.onmessage = function (event) {
  if (event.origin == 'mytrustedsite.com') {
    alert('my trusted site said: ' + event.data);
  }
};
</code></pre>

<p>Now you can include an <code>&lt;iframe&gt;</code> that contains that code, and using the <code>&lt;iframe&gt;</code> <abbr>DOM</abbr> node, you can post to the <code>&lt;iframe&gt;</code>:</p>

<pre><code>// where iframe is the actual iframe DOM node
iframe.contentWindow.postMessage("hello there", location.host);
</code></pre>

<p>This gives you the ability to send strings across two mutually trusted domains. (Remember that you can use <code>JSON.stringify</code> and <code>JSON.parse</code> to convert to an object to and from string format.)</p>

<h3 id="support_for_postmessage">Support for postMessage</h3>

<ul>
<li>Chrome</li>
<li>Safari</li>
<li>Opera</li>
<li>Firefox</li>
<li>IE8</li>
</ul>

<p>Here&#8217;s a <a href="http://html5demos.com/postmessage2">demo using <code>postMessage</code></a>.</p>

<p>There&#8217;s also a project called <a href="http://easyxdm.net/" title="easyXDM - Cross-domain messaging made easy">EasyXDM</a>, which adds cross domain messaging to <abbr>IE</abbr>6 and upwards (along with all the other browsers) through the library&#8217;s abstraction.  Definitely worth a look if this is a route you need to take.</p>

<h2 id="web_sockets">Web Sockets</h2>

<p>It&#8217;s my opinion that Web Sockets replaces Comet. Comet is a way of hacking the browser to giving us real-time server messages. The Web Sockets API provides that natively.</p>

<p>Web Sockets are used to send messages to <em>and</em> from the server — i.e., a bi-directional socket. In contrast to other similar technologies, with Web Sockets, you <em>can</em> go across domains, and you&#8217;re not bound by the same-origin policy. This means you can host your normal &#8220;apps&#8221; server while another server is for streaming content. Or you could host your own pages and connect to a live Twitter stream if your users turn on Web Socket support.</p>

<p>You can only send messages once the socket is open (duh). The communication model looks like this:</p>

<pre><code>var ws = new WebSocket('ws://somesite.com/updates');

ws.onmessage = function (event) {
  alert(event.data);
};

ws.onopen = function () {
  ws.send('yay! we connected!');
};
</code></pre>

<p>Once the socket is closed, you can&#8217;t reuse it. Similarly, there&#8217;s no explicit method for opening a socket. That just happens when you create the <code>WebSocket</code> object.</p>

<p>This <abbr>API</abbr> is extremely simple. I most often get asked, &#8220;What do you put on the server side?&#8221; I personally use <a href="http://nodejs.org">Node</a>, but you could use an <a href="http://nginx.net/" title="nginx news">Nginx</a> server or something like <a href="http://www.mortbay.org/" title="jetty - Jetty WebServer">Jetty</a>. I&#8217;m no expert on the latter servers, but I can vouch that a Node-based server is very, very simple to get going. The live demo below also includes a link to the code that I used to run the server.</p>

<p>Check out this <a href="http://html5demos.com/web-socket">demo of Web Sockets</a>.</p>

<h3 id="support_for_web_sockets">Support for Web Sockets</h3>

<ul>
<li>Chrome</li>
<li>Safari &amp; MobileSafari</li>
</ul>

<p>There&#8217;s also an excellent Flash poly-fill called <a href="https://github.com/gimite/web-socket-js/">web-socket-js</a>. Drop this into an application and it provides Web Sockets support as if it were native. I&#8217;ve used this on a few projects of my own, and it works very well.</p>

<p>In early December 2010, there was a security notice posted about Web Sockets, and both Firefox and Opera pulled it from their upcoming releases. Mozilla have said that they expect Web Sockets to be back in Firefox by version 4.0.1.</p>

<h2 id="server_sent_events">Server-Sent Events</h2>

<p>The <a href="http://dev.w3.org/html5/eventsource/">Server-Sent Events</a> <abbr>API</abbr> is something that originated from Opera back in 2006 and is used for pushing events from the server to the client. Note that the client cannot send messages to the server through an <code>EventSource</code> (<abbr>SSE</abbr>) — it can only listen for messages.  </p>

<p>This <abbr>API</abbr> uses the <code>onmessage</code> model. It&#8217;s constructed using the <code>EventSource</code> object and is limited by the same origin rules:</p>

<pre><code>var es = new EventSource('/sse');
es.onopen = function () {
  console.log('opened stream');
};

es.onmessage = function (event) {
  console.log('new message: ' + event.data);
};
</code></pre>

<p>The <abbr>SSE</abbr> automatically connects when you create the object (similar to Web Sockets), and once open will trigger the <code>onopen</code> event. </p>

<p>Here&#8217;s a live <a href="http://node.remysharp.com:8001/sse-client.html">demo of Server-Sent Events</a></p>

<p>Here&#8217;s how this is to work: when a new message is pushed from the server to the client, it triggers the <code>onmessage</code> callback.</p>

<p>The key to your server is ensuring it doesn't close the connection on the client - the browser. Most of the examples around the web are doing this: closing the connection which tells the API to switch in to polling mode (note that this is the exact problem I hit when I first published this article).</p>

<p>When the API is in polling mode, it's no more different from an XHR poll, and the <code>onopen</code> will continually fire.</p>

Al the code the server side can be viewed here: <a href="http://node.remysharp.com:8001/custom-echo.js">custom-echo.js</a> (note that it's running on a <a href="http://nodejs.org/" title="node.js">Node.js</a> server).  There's a bit more code than you'd expect, because it's doing a few things:

1. Handling HTTP requests for files (and therefore is able to serve itself)
2. Handling the server-sent events and <strong>not</strong> closing the connection
3. Setting up a Web Socket server, and when a new connection comes in, it sends a server-sent event to all the currently connected sessions.

<h3 id="support_for_server_sent_events">Support for Server-Sent Events</h3>

<ul>
<li>Opera 11</li>
<li>Safari &amp; MobileSafari</li>
<li>Chrome</li>
</ul>

<h2 id="web_workers">Web Workers</h2>

<p>Web Workers are a way of creating a new thread of execution inside the browser. I&#8217;m including this because you still need to communicate with your Web Workers, and the method of communication is similar to some of those techniques discussed above. Do note, however, that this is not a method communicating from a client (browser) to a server. It&#8217;s more like there&#8217;s another browser window executing a particular block of JavaScript.</p>

<p>As an example of when to use a Web Worker, say you&#8217;re running a lot of JavaScript and the <abbr>UI</abbr> becomes unresponsive. The browser <abbr>UI</abbr> hangs because, in a way, it&#8217;s a &#8220;single-threaded application&#8221;. (Under the hood it isn&#8217;t really, but from a rendering and JavaScript perspective it is). This JavaScript task could be given to a Web Worker so that the <abbr>UI</abbr> can continue functioning.</p>

<p>It&#8217;s vital to understand that a Web Worker lives in a sand-boxed environment that doesn&#8217;t have access to things like the <abbr>DOM</abbr>. What&#8217;s more, you can only communicate with it using the <code>onmessage</code> and <code>postMessage</code> functions.</p>

<p>Our application can create and send messages to a worker using the following code:</p>

<pre><code>var worker = new Worker('bigjob.js');
worker.onmessage = function (event) {
  alert('Message from worker: ' + event.data); // remember event.data is a string!
};

worker.postMessage('task=job1');
</code></pre>

<p>In the JavaScript file <code>bigjob.js</code>, we run some computationally intensive task and listen for messages in a way similar to what we&#8217;ve done in the previous examples. We can also post messages back to the invoking application:</p>

<pre><code>this.onmessage = function (event) {
  var job = event.data;
  if (job == 'task=job1') {
    job1();
  } else if (job == 'task=job2') {
    job2();
  }
};

// just a pseudo example
function job1() {
  // do some big task
  while (working) {
    // continue task
    this.postMessage('job1 ' + amountComplete + '% complete');
  }
  this.postMessage('job1 100% complete');
}
</code></pre>

<p>There&#8217;s a lot more to Web Workers than just running a couple of small tasks, and no doubt we <abbr>HTML</abbr>5 Doctors will be posting a detailed article soon. This example just demonstrates how to communicate with Web Workers and how similar that is to the other technologies we&#8217;ve discussed here.</p>

<h3 id="support_for_web_workers">Support for Web Workers</h3>

<ul>
<li>Chrome</li>
<li>Safari</li>
<li>Opera</li>
<li>Firefox</li>
</ul>

<h2 id="a_final_word">A final word</h2>

<p>Hopefully you agree that this is just the tip of the iceberg of communicating between client and server in <abbr>HTML</abbr>5. We&#8217;re no longer stuck with the same origin policy we had with vanilla Ajax. In fact, when you think about it, since <abbr>IE</abbr>8, we&#8217;ve actually had decent cross-domain messaging.</p>

<p>I&#8217;m personally most excited about Web Sockets and the support of <abbr>CORS</abbr> in services that have <abbr>API</abbr>s, like Flickr, Twitter, and <abbr>URL</abbr> shorteners. What could you build with this?</p>
<div id="crp_related"><h3>Related Posts:</h3><ul class="related"><li><a href="http://html5doctor.com/server-sent-events/" rel="bookmark" class="crp_title">Server-Sent Events</a></li><li><a href="http://html5doctor.com/native-drag-and-drop/" rel="bookmark" class="crp_title">Native Drag and Drop</a></li><li><a href="http://html5doctor.com/storing-data-the-simple-html5-way-and-a-few-tricks-you-might-not-have-known/" rel="bookmark" class="crp_title">Storing Data the Simple HTML5 Way (and a few tricks you might not have known)</a></li><li><a href="http://html5doctor.com/history-api/" rel="bookmark" class="crp_title">Pushing and Popping with the History API</a></li><li><a href="http://html5doctor.com/designing-a-blog-with-html5/" rel="bookmark" class="crp_title">Designing a blog with html5</a></li></ul></div><p><a href="http://html5doctor.com/methods-of-communication/" rel="bookmark">Methods of communication</a> originally appeared on <a href="http://html5doctor.com">HTML5 Doctor</a> on January 18, 2011.</p>
]]></content:encoded>
			<wfw:commentRss>http://html5doctor.com/methods-of-communication/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>video + canvas = magic</title>
		<link>http://html5doctor.com/video-canvas-magic/</link>
		<comments>http://html5doctor.com/video-canvas-magic/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 14:34:53 +0000</pubDate>
		<dc:creator>Tab Atkins Jnr</dc:creator>
				<category><![CDATA[Elements]]></category>
		<category><![CDATA[JavaScript APIs]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://html5doctor.com/?p=2554</guid>
		<description><![CDATA[<p>You've already learned about the <code>&#60;video&#62;</code> and <code>&#60;canvas&#62;</code> elements, but did you know that they were designed to be used together?  In fact, the two elements are absolutely wondrous when you combine them together.  I'm going to show off a few super-simple demos using the two elements together, which should help suggest cool future projects for you fellow web authors.</p>]]></description>
			<content:encoded><![CDATA[<p>You&#8217;ve already learned about the <a href="http://html5doctor.com/the-video-element/"><code>&lt;video&gt;</code></a> and <a href="http://html5doctor.com/an-introduction-to-the-canvas-2d-api/"><code>&lt;canvas&gt;</code></a> elements, but did you know that they were designed to be used together? In fact, the two elements are absolutely wondrous when you combine them! I&#8217;m going to show off a few super-simple demos using these two elements, which I hope will prompt cool future projects from you fellow web authors. (All of these demos work in every modern browser except Internet Explorer.)</p>

<h2>First, the basics</h2>

<p>If you&#8217;re just starting with <abbr>HTML</abbr>5, you may not be familiar with the <code>&lt;video&gt;</code> element and how to use it. Here&#8217;s a simple example that we&#8217;ll be using in the later demos:</p>

<pre><code>&lt;video controls loop&gt;
    &lt;source src=video.webm type=video/webm&gt;
    &lt;source src=video.ogg type=video/ogg&gt;
    &lt;source src=video.mp4 type=video/mp4&gt;
&lt;/video&gt;
</code></pre>

<p>The <code>&lt;video&gt;</code> element contains two attributes: <code>@controls</code> and <code>@loop</code>. <code>@controls</code> tells the browser to give the video the standard set of video controls: play/pause, scrubber, volume, etc. <code>@loop</code> tells the browser to start the video over again from the beginning once it ends.</p>

<p>Then, inside the <code>&lt;video&gt;</code> element, we have three child <code>&lt;source&gt;</code> elements, each pointing to a different encoding of the same video. The browser will try each source in order and play the first one that it understands.</p>

<p><a href="http://html5doctor.com/demos/video-canvas-magic/demo0.html">See this code in action</a>, playing the intro to one of the greatest cartoon series of all time.</p>

<figure>
  <img src="http://html5doctor.com/wp-content/uploads/2010/10/video_canvas_fig1.jpg" alt="" />
  <figcaption>HTML5 Video playing in Chrome</figcaption>
</figure>

<p>(A note about fallback: all of these demos assume that your browser has <code>&lt;video&gt;</code> support, which isn&#8217;t true in <abbr>IE</abbr>8 or earlier. Normally, it&#8217;s good practice to specify a Flash fallback or similar for those browsers, but that wouldn&#8217;t accomplish much here — all of the techniques I demonstrate rely on basic integration between the <code>&lt;video&gt;</code> element and the <code>&lt;canvas&gt;</code> element, which you can&#8217;t achieve with a Flash player. So I&#8217;ve omitted any non-<code>&lt;video&gt;</code> fallback content in these examples. I&#8217;ve still provided multiple sources, though, so all current browsers that do support <code>&lt;video&gt;</code> will be able to play it.)</p>

<h2>Now, a simple example</h2>

<p>Now that we know how to play a video, let&#8217;s mix in some <code>&lt;canvas&gt;</code> shenanigans. First, <a href="http://html5doctor.com/demos/video-canvas-magic/demo1.html">check out the demo</a>, then come back here for a code walkthrough.  I&#8217;ll wait.</p>

<p>&hellip;</p>

<figure>
  <img src="http://html5doctor.com/wp-content/uploads/2010/10/video_canvas_fig2.jpg" alt="" />
  <figcaption>Drawing video onto the canvas at full screen</figcaption>
</figure>

<p>Done? Cool! Now, how does this work? Surely it requires a few hundred lines of JavaScript, right? If you&#8217;ve cheated and already looked at the source code of the demo page, you&#8217;ll know how easy it is.</p>
  
<p>We start with this <abbr>HTML</abbr>:</p>

<pre><code>&lt;!DOCTYPE html&gt;
&lt;title&gt;Video/Canvas Demo 1&lt;/title&gt;

&lt;canvas id=c&gt;&lt;/canvas&gt;
&lt;video id=v controls loop&gt;
    &lt;source src=video.webm type=video/webm&gt;
    &lt;source src=video.ogg type=video/ogg&gt;

    &lt;source src=video.mp4 type=video/mp4&gt;
&lt;/video&gt;
</code></pre>

<p>Same video code as before, but now with a <code>&lt;canvas&gt;</code> element thrown into the mix. Kinda empty and useless at the moment, though. We&#8217;ll script it into action later.</p>

<p>Now, let&#8217;s pair that with some <abbr>CSS</abbr> to get things positioned right:</p>

<pre><code>&lt;style&gt;

body {
    background: black;
}

#c {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: 100%;
}

#v {
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -180px 0 0 -240px;
}
&lt;/style&gt;
</code></pre>

<p>This just centers the video in the screen and stretches the canvas to the full width and height of the browser window. Since the canvas comes first in the document, it&#8217;ll be behind the video, exactly where we want it.</p>

<p>Now, here comes the magic!</p>

<pre><code>&lt;script&gt;
document.addEventListener('DOMContentLoaded', function(){
    var v = document.getElementById('v');
    var canvas = document.getElementById('c');
    var context = canvas.getContext('2d');

    var cw = Math.floor(canvas.clientWidth / 100);
    var ch = Math.floor(canvas.clientHeight / 100);
    canvas.width = cw;
    canvas.height = ch;

    v.addEventListener('play', function(){
        draw(this,context,cw,ch);
    },false);

},false);

function draw(v,c,w,h) {
    if(v.paused || v.ended) return false;
    c.drawImage(v,0,0,w,h);
    setTimeout(draw,20,v,c,w,h);
}
&lt;/script&gt;
</code></pre>

<p>Take that in for a moment. Just breathe deeply and absorb it. So short, so sweet, so pretty&hellip;</p>

<p>Now, let&#8217;s step through it.</p>

<pre><code>    var v = document.getElementById('v');
    var canvas = document.getElementById('c');
    var context = canvas.getContext('2d');

    var cw = Math.floor(canvas.clientWidth / 100);
    var ch = Math.floor(canvas.clientHeight / 100);
    canvas.width = cw;
    canvas.height = ch;
</code></pre>

<p>This part is simple. I grab hold of the video and canvas elements on the page, and I grab the canvas&#8217;s 2D-context so I can draw on it. Then I do some quick calculating to find out how wide and tall I want the canvas&#8217;s drawing surface to be. The <code>&lt;canvas&gt;</code> element itself is already stretched to the size of the screen via <abbr>CSS</abbr>, so this&#8217;ll make each pixel of the drawing surface equal to about 100&#215;100 pixels on the screen.</p>

<p>That last bit may need some explanation if you&#8217;re new to canvas. Normally, the visual size and the drawing-surface size of a <code>&lt;canvas&gt;</code> element will be the same. In that case, drawing a line 50px long will display a line 50px long. But that doesn&#8217;t have to be true — you can set the drawing surface&#8217;s size through the <code>@width</code> and <code>@height</code> properties on the <code>&lt;canvas&gt;</code> element itself, and then change the visual size of the canvas with <abbr>CSS</abbr> to be something different. The browser will then automatically upscale or downscale the drawing appropriately to make the drawing surface fill the visual size. In this case, I&#8217;m setting the drawing surface of the canvas to be very small — on most screens, it&#8217;ll be about 10px wide and 7px tall — and then stretching the visual size with <abbr>CSS</abbr> so that each pixel I draw gets blown up 100-fold by the browser. That&#8217;s what causes the cool visual effect in the demo.</p>

<pre><code>    v.addEventListener('play', function(){
        draw(v,context,cw,ch);
    },false);
</code></pre>

<p>Another simple part. Here I attach some code to the &#8220;play&#8221; event on the video element. This event gets fired whenever the user hits the &#8220;play&#8221; button to start watching the video. All I do is call the <code>draw()</code> function with the appropriate parameters: the video itself, the canvas&#8217;s drawing context, and the canvas&#8217;s width and height.</p>

<pre><code>function draw(v,c,w,h) {
    if(v.paused || v.ended) return false;
    c.drawImage(v,0,0,w,h);
    setTimeout(draw,20,v,c,w,h);
}
</code></pre>

<p>The first line just makes the function stop immediately if the user pauses or stops the video, so it&#8217;s not burning <abbr>CPU</abbr> when nothing&#8217;s changing. The third line calls the <code>draw()</code> function again, allowing the browser a little breathing space to do other things like update the video itself. I&#8217;m putting in a 20ms delay, so we&#8217;ll get roughly 50fps, which is more than enough.</p>

<p>The second line is where the magic happens — it draws the current frame of the video directly onto the canvas.  Yes, it&#8217;s exactly as simple as it looks. Just pass the video element and the x, y, width, and height of the rectangle on the canvas you want it to draw into. In this case, it&#8217;s filling up the entire canvas, but you could do less (or more!) if you wanted.</p>

<p>I&#8217;m using another trick here. Remember how the canvas is really tiny? The video will be at least 20 times bigger than the canvas on most screens, so how do we draw it onto such a tiny canvas? The <code>drawImage()</code> function handles that for us — it automatically scales whatever you hand it in the first argument so that it fills the rectangle you specify. That means we authors don&#8217;t have to worry about averaging the pixel colors (or extrapolating, if you&#8217;re drawing a small video into a big rectangle) because the browser does it all for us. I&#8217;ll use this trick more in the future, so watch out for it.</p>

<p>And&hellip;that&#8217;s it! The entire demo is done in 20 lines of easy-to-read JavaScript code, instantly producing a nifty background effect for any video you wish to play. You can trivially adjust the size of the &#8220;pixels&#8221; on the canvas by adjusting the lines that set the <var>cw</var> and <var>ch</var> variables.</p>

<h2>Directly manipulating video pixels</h2>

<p>The last demo was cool, but it just let the browser do all the heavy lifting. The browser downscaled the video, drew it onto the canvas, and then upscaled the canvas pixels, all automatically. Let&#8217;s try our hand at doing some of this ourselves! <a href="http://html5doctor.com/demos/video-canvas-magic/demo2.html">Check out the demo</a> to see this in action, where I convert the video to grayscale on the fly.</p>

<figure>
  <img src="http://html5doctor.com/wp-content/uploads/2010/10/video_canvas_fig3.jpg" alt="" />
  <figcaption>Video made greyscale with canvas manipulation</figcaption>
</figure>

<p>The HTML for the page is basically identical:</p>

<pre><code>&lt;video id=v controls loop&gt;
    &lt;source src=video.webm type=video/webm&gt;
    &lt;source src=video.ogg type=video/ogg&gt;
    &lt;source src=video.mp4 type=video/mp4&gt;
&lt;/video&gt;
&lt;canvas id=c&gt;&lt;/canvas&gt;

</code></pre>

<p>Nothing new here, so let&#8217;s move onto the script.</p>

<pre><code>document.addEventListener('DOMContentLoaded', function(){
    var v = document.getElementById('v');
    var canvas = document.getElementById('c');
    var context = canvas.getContext('2d');
    var back = document.createElement('canvas');
    var backcontext = back.getContext('2d');

    var cw,ch;

    v.addEventListener('play', function(){
        cw = v.clientWidth;
        ch = v.clientHeight;
        canvas.width = cw;
        canvas.height = ch;
        back.width = cw;
        back.height = ch;
        draw(v,context,backcontext,cw,ch);
    },false);

},false);

function draw(v,c,bc,w,h) {
    if(v.paused || v.ended) return false;
    // First, draw it into the backing canvas
    bc.drawImage(v,0,0,w,h);
    // Grab the pixel data from the backing canvas
    var idata = bc.getImageData(0,0,w,h);
    var data = idata.data;
    // Loop through the pixels, turning them grayscale
    for(var i = 0; i &lt; data.length; i+=4) {
        var r = data[i];
        var g = data[i+1];
        var b = data[i+2];
        var brightness = (3*r+4*g+b)&gt;&gt;&gt;3;
        data[i] = brightness;
        data[i+1] = brightness;
        data[i+2] = brightness;
    }
    idata.data = data;
    // Draw the pixels onto the visible canvas
    c.putImageData(idata,0,0);
    // Start over!
    setTimeout(function(){ draw(v,c,bc,w,h); }, 0);
}
</code></pre>

<p>The script is a bit longer this time, because we&#8217;re actually doing some work. But it&#8217;s still really simple!</p>

<pre><code>document.addEventListener('DOMContentLoaded', function(){
    var v = document.getElementById('v');
    var canvas = document.getElementById('c');
    var context = canvas.getContext('2d');
    var back = document.createElement('canvas');
    var backcontext = back.getContext('2d');

    var cw,ch;

    v.addEventListener('play', function(){
        cw = v.clientWidth;
        ch = v.clientHeight;
        canvas.width = cw;
        canvas.height = ch;
        back.width = cw;
        back.height = ch;
        draw(v,context,backcontext,cw,ch);
    },false);
</code></pre>

<p>This is almost the same as I had before, with two real differences.</p>

<p>First, I&#8217;m creating a second canvas and pulling the context out of it as well. This is a &#8220;backing canvas&#8221;, which I&#8217;ll use to perform intermediate operations before painting the final result into the visible canvas in the markup. The backing canvas doesn&#8217;t even need to be added to the document. It can just hang out here in my script. This strategy will be used a lot in later examples, and it&#8217;s quite useful in general, so take note of it.</p>

<p>Second, I&#8217;m waiting to resize the canvases until the video is played, rather than just sizing them immediately.  This is because the <code>&lt;video&gt;</code> element probably hasn&#8217;t loaded its video up when the <code>DOMContentLoaded</code> event fires, so it&#8217;s still using the default size for the element. By the time it&#8217;s ready to play, though, it knows the size of the video and has sized itself appropriately. At that point, we can set up the canvases to be the same size as the video.</p>

<pre><code>function draw(v,c,bc,w,h) {
    if(v.paused || v.ended) return false;
    bc.drawImage(v,0,0,w,h);
</code></pre>

<p>Same as the first demo, the <code>draw()</code> function begins by checking if it should stop, then just draws the video onto a canvas. Note that I&#8217;m drawing it onto the <em>backing</em> canvas, which, again, is just sitting in my script and isn&#8217;t displayed in the document. The visible canvas is reserved for the displaying the grayscale version, so I use the backing canvas to load up the initial video data.</p>

<pre><code>    var idata = bc.getImageData(0,0,w,h);
    var data = idata.data;
</code></pre>

<p>Here&#8217;s the first new bit. You can draw something onto a canvas with either the normal canvas drawing functions or <code>drawImage()</code>, or you can just manipulate the pixels directly through the ImageData object.  <code>getImageData()</code> returns the pixels from a rectangle of the canvas. In this case, I&#8217;m just getting the whole thing.</p>

<p><strong>Warning!</strong> If you&#8217;re following along and trying to run these demos on your desktop, this is where you&#8217;ll probably run into trouble. The <code>&lt;canvas&gt;</code> element keeps track of where the data inside of it comes from, and if it knows that you got something from another website (for example, if the <code>&lt;video&gt;</code> element you painted into the canvas is pointing to a cross-origin file), it&#8217;ll &#8220;taint&#8221; the canvas. You&#8217;re not allowed to grab the pixel data from a tainted canvas. Unfortunately, <code>file:</code> urls count as &#8220;cross-origin&#8221; for this purpose, so you can&#8217;t run this on your desktop. Either fire up a web server on your computer and view the page from localhost, or upload it to some other server you control.</p>

<pre><code>    for(var i = 0; i &lt; data.length; i+=4) {
        var r = data[i];
        var g = data[i+1];
        var b = data[i+2];
</code></pre>

<p>Now, a quick note about the ImageData object. It returns the pixels in a special way in order to make them easy to manipulate. If you have, say, a 100&#215;100 pixel canvas, it contains a total of 10,000 pixels. The ImageData array for it will then have 40,000 elements, because the pixels are broken up by component and listed sequentially. Each group of four elements in the ImageData array represent the red, green, blue, and alpha channels for that pixel. To loop through the pixels, just increment your counter by 4 every time, like I do here. Each channel, then, is an integer between 0 and 255.</p>

<pre><code>        var brightness = (3*r+4*g+b)&gt;&gt;&gt;3;
        data[i] = brightness;
        data[i+1] = brightness;
        data[i+2] = brightness;
</code></pre>

<p>Here, a quick bit of math converts the <abbr>RGB</abbr> value of the pixel into a single &#8220;brightness&#8221; value. As it turns out, our eyes respond most strongly to green light, slightly less so to red, and much less so to blue. So, I weight the channels appropriately before taking the average. Then, we just feed that single value back to all three channels. As we probably all know, when the red, green, and blue values of a color are equal, you get gray. (During this whole process, I&#8217;m completely ignoring the fourth member of each group, the alpha channel, because it&#8217;s always going to be 255.)</p>

<pre><code>    idata.data = data;
</code></pre>

<p>Shove the modified pixel array back into the ImageData object&hellip;</p>

<pre><code>    c.putImageData(idata,0,0);
</code></pre>

<p>&hellip;and then shove the whole thing into the visible canvas! We didn&#8217;t need to do any complicated drawing at all! Just grab the pixels, manipulate them, and shove them back in. So easy!</p>

<p>A final note: real-time full-video pixel manipulation is one of those rare places where micro-optimizations actually matter. You can see their effects in my code here. Originally, I didn&#8217;t pull the pixel data out of the ImageData object, and just wrote &#8220;var r = idata.data[i];&#8221; and so on each time, which meant several extra property lookups in every iteration of the loop. I also originally just divided the brightness by 8 and floored the value, which is slightly slower than bit-shifting by 3 places. In normal code, these sorts of things are <em>completely</em> insignificant, but when you&#8217;re doing them several million times per second (the video is 480&#215;360, and thus contains nearly 200,000 pixels, each of which is individually handled roughly 100 times a second), those tiny delays add up into a noticeable lag.</p>

<h2>More advanced pixel manipulation</h2>

<p>You can operate on more than just a single pixel at a time, too, composing some fairly complex visual effects. As I noted at the end of the previous section, performance matters a lot here, but you&#8217;d be surprised what you can squeeze out with a little creativity. <a href="http://html5doctor.com/demos/video-canvas-magic/demo4.html">As you can see in the demo</a>, I&#8217;ll be creating an emboss effect in this example, which requires you to use several input pixels together to compute the value of each output pixel.</p>

<figure>
  <img src="http://html5doctor.com/wp-content/uploads/2010/10/video_canvas_fig4.jpg" alt="" />
  <figcaption>Embossed video with canvas manipulation</figcaption>
</figure>

<p>Here&#8217;s the code. The <abbr>HTML</abbr> and most of the beginning code is identical to the previous example, so I&#8217;ve omitted everything but the <code>draw()</code> function:</p>

<pre><code>function draw(v,c,bc,cw,ch) {
    if(v.paused || v.ended) return false;
    // First, draw it into the backing canvas
    bc.drawImage(v,0,0,cw,ch);
    // Grab the pixel data from the backing canvas
    var idata = bc.getImageData(0,0,cw,ch);
    var data = idata.data;
    var w = idata.width;
    var limit = data.length
    // Loop through the subpixels, convoluting each using an edge-detection matrix.
    for(var i = 0; i &lt; limit; i++) {
        if( i%4 == 3 ) continue;
        data[i] = 127 + 2*data[i] - data[i + 4] - data[i + w*4];
    }
    // Draw the pixels onto the visible canvas
    c.putImageData(idata,0,0);
    // Start over!
    setTimeout(draw,20,v,c,bc,cw,ch);
}
</code></pre>

<p>Now let&#8217;s step through that.</p>

<pre><code>function draw(v,c,bc,cw,ch) {
    if(v.paused || v.ended) return false;
    // First, draw it into the backing canvas
    bc.drawImage(v,0,0,cw,ch);
    // Grab the pixel data from the backing canvas
    var idata = bc.getImageData(0,0,cw,ch);
    var data = idata.data;
</code></pre>

<p>Same as the last example. Check to see if we should stop, then draw the video onto the backing canvas and grab the pixel data from it.</p>

<pre><code>var w = idata.width;
</code></pre>

<p>The significance of this line needs some explanation. I&#8217;m already passing the canvas&#8217;s width into the function (as the <var>cw</var> variable), so why am I re-measuring its width here? Well, I was actually lying to you earlier when I explained how large the pixel array will be. The browser <em>might</em> have one pixel of canvas map to one pixel of ImageData, but browsers are allowed to use higher resolutions in the image data, representing each pixel of canvas as a 2&#215;2 block of ImageData pixels, or maybe 3&#215;3, or maybe even greater!</p>

<p>If they use a &#8220;high-resolution backing store&#8221;, as this is called, it means better display, as aliasing artifacts (jagged edges on diagonal lines) become much smaller and less noticeable. It also means that rather than a 100&#215;100 pixel canvas giving you an ImageData.data object with 40,000 numbers, it might have 160,000 numbers instead. By asking the ImageData for its width and height, we ensure that we loop through the pixel data properly no matter whether the browser uses a low-res or high-res backing store for it.</p>

<p>It&#8217;s very important that you use this properly whenever you need the width or height of the data you pulled out as an ImageData object. If too many people screw it up and just use the canvas&#8217;s width and height instead, then browsers will be forced to always use a low-res backing store to be compatible with those broken scripts!</p>

<pre><code>    var limit = data.length;
    for(var i = 0; i &lt; limit; i++) {
        if( i%4 == 3 ) continue;
        data[i] = 127 + 2*data[i] - data[i + 4] - data[i + w*4];
    }
</code></pre>

<p>I&#8217;m grabbing the data&#8217;s length and stuffing it into a variable, so I don&#8217;t have to pay for a property access on every single iteration of the loop. (Remember, micro-optimizations matter when you&#8217;re doing real-time video manipulation!) Then I just loop through the pixels, like I did before. If the pixel happens to be for the alpha channel (every fourth number in the array), I can just skip it — I don&#8217;t want to change the transparency. Otherwise, I&#8217;ll do a little math to find the difference between the current pixel&#8217;s color channel and the similar channels of the pixels below and to the right, then just combine that difference with the &#8220;average&#8221; gray value of 127. This has the effect of making areas where the pixels are the same color a flat medium gray, but edges where the color suddenly changes will turn either bright or dark.</p>

<p>There&#8217;s another optimization here. Because I&#8217;m only comparing the current pixel with pixels &#8220;further ahead&#8221; in the data which I haven&#8217;t looked at yet, I can just store the changed value right back in the original data, because nothing will ever look at the current pixel&#8217;s data again after this point. This means I don&#8217;t have to allocate a big array to hold the results before turning it back into an ImageData object.</p>

<pre><code>    c.putImageData(idata,0,0);
    setTimeout(draw,20,v,c,bc,cw,ch);
</code></pre>

<p>Finally, draw the modified ImageData object into the visible canvas, and set up another call to the function in 20 milliseconds. This is the same as the previous example.</p>

<h2>Wrapping up</h2>

<p>So, we&#8217;ve explored the basics of combining <abbr>HTML</abbr>5&#8242;s <code>&lt;canvas&gt;</code> and <code>&lt;video&gt;</code> elements today. The demos were very basic, but they illustrated all the essential techniques you&#8217;ll need to do something even cooler on your own:</p>

<ol>
<li>You can draw a video directly onto a canvas.</li>
<li>When you draw onto a canvas, the browser will automatically scale the image for you if necessary.</li>
<li>When you display a canvas, the browser will again scale it automatically if the visible size is different from the size of the backing-store.</li>
<li>You can do direct pixel-level manipulation of a canvas by just grabbing the ImageData, changing it, and drawing it back in.</li>
</ol>

<p>In Part 2 of this article [Ed: coming soon!], I&#8217;ll explore some more interesting applications of video/canvas integration, including a real-time video-to-ASCII converter!</p>
<div id="crp_related"><h3>Related Posts:</h3><ul class="related"><li><a href="http://html5doctor.com/an-introduction-to-the-canvas-2d-api/" rel="bookmark" class="crp_title">An introduction to the Canvas 2D API</a></li><li><a href="http://html5doctor.com/the-video-element/" rel="bookmark" class="crp_title">The video element</a></li><li><a href="http://html5doctor.com/review-html5-now-dvd/" rel="bookmark" class="crp_title">Review: HTML5 Now (DVD)</a></li><li><a href="http://html5doctor.com/your-questions-16/" rel="bookmark" class="crp_title">Your Questions #16</a></li><li><a href="http://html5doctor.com/native-drag-and-drop/" rel="bookmark" class="crp_title">Native Drag and Drop</a></li></ul></div><p><a href="http://html5doctor.com/video-canvas-magic/" rel="bookmark">video + canvas = magic</a> originally appeared on <a href="http://html5doctor.com">HTML5 Doctor</a> on October 20, 2010.</p>
]]></content:encoded>
			<wfw:commentRss>http://html5doctor.com/video-canvas-magic/feed/</wfw:commentRss>
		<slash:comments>47</slash:comments>
		</item>
		<item>
		<title>HTML5 Simplequiz #3: how to mute a video</title>
		<link>http://html5doctor.com/html5-simplequiz-3-how-to-mute-a-video/</link>
		<comments>http://html5doctor.com/html5-simplequiz-3-how-to-mute-a-video/#comments</comments>
		<pubDate>Fri, 15 Oct 2010 08:35:16 +0000</pubDate>
		<dc:creator>Bruce Lawson</dc:creator>
				<category><![CDATA[Attributes]]></category>
		<category><![CDATA[JavaScript APIs]]></category>
		<category><![CDATA[multimedia]]></category>
		<category><![CDATA[Simplequiz]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[muted]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://html5doctor.com/?p=2628</guid>
		<description><![CDATA[This is a bit of a special Simplequiz this week. Simon Pieters, who works on multimedia QA for Opera and is one of those working on the HTML5 spec, asked us to run a quiz that would help the spec writers decide on a new aspect of the language. ]]></description>
			<content:encoded><![CDATA[<p>This is a bit of a special Simplequiz this week. Simon Pieters (<a href="http://twitter.com/zcorpan">@zcorpan</a>), who works on multimedia QA for Opera and is one of those working on the HTML5 spec, asked us to run a quiz that would help the spec writers decide on a new aspect of the language. What power you wield, gentle reader! Over to Simon&hellip;</p>
<p>This SimpleQuiz is a bit different to previous SimpleQuizzes, since we&#8217;d like to use the result of this quiz to inform a design decision in the HTML5 spec. The question concerns how to mute a video in markup, and how this should be reflected in the DOM.</p>
<p>The use case is wanting to have multiple videos playing at once, but with all but one being muted at a time. This can be done today by setting <code>.muted = true</code> with script, but it would be more convenient to be able to mute with markup.</p>
<p>The <code>.muted</code> IDL attribute reflects the user setting of muted for the video element &#8212; if the user clicks &#8220;mute&#8221; in the native video controls, then the value of <code>.muted</code> changes, and vice versa. It would make sense for the browser to remember the mute setting for individual video elements on page reload (or later visit), so that the user doesn&#8217;t have to re-mute them.</p>
<p>This is where it starts to get hairy if we introduce a content attribute for muting. (Note that code fragments below aren&#8217;t real code, just suggestions.)</p>
<p>We could introduce <code>muted=""</code> which is reflected by <code>.muted</code> (i.e. if one changes, so does the other), but this would cause the DOM to mutate during parsing if the remembered setting doesn&#8217;t match the markup, i.e. you would get <code>muted=""</code> to appear in the DOM if the video is muted by the user even though there was no such attribute in the markup, which could confuse your scripts or style sheets if it&#8217;s not what you expected to happen.</p>
<p>We could introduce <code>defaultmuted=""</code> which is reflected by <code>.defaultMuted</code>, and just let the user setting change <code>.muted</code>, but <code>defaultmuted=""</code> is a bit long and ugly in markup.</p>
<p>We could have <code>muted=""</code> which is reflected by <code>.defaultMuted</code> and let the user setting change <code>.muted</code>, but it might be confusing for some people. On the other hand it is consistent with <code>&lt;input value&gt;</code> and <code>.defaultValue</code>.</p>
<p>What do you think? Which is the best option? Is there another option that is better than any of the above?
<div id="crp_related">
<h3>Related Posts:</h3>
<ul class="related">
<li><a href="http://html5doctor.com/the-nsfw-element/" rel="bookmark" class="crp_title">The nsfw element</a></li>
<li><a href="http://html5doctor.com/html5-simplequiz-4-figures-captions-and-alt-text/" rel="bookmark" class="crp_title">HTML5 Simplequiz #4: figures, captions and alt text</a></li>
<li><a href="http://html5doctor.com/the-video-element/" rel="bookmark" class="crp_title">The video element</a></li>
<li><a href="http://html5doctor.com/html5-custom-data-attributes/" rel="bookmark" class="crp_title">HTML5 Custom Data Attributes (data-*)</a></li>
<li><a href="http://html5doctor.com/html5-simplequiz-2-citing-people/" rel="bookmark" class="crp_title">HTML5 Simplequiz #2: citing people</a></li>
</ul>
</div>
<p><a href="http://html5doctor.com/html5-simplequiz-3-how-to-mute-a-video/" rel="bookmark">HTML5 Simplequiz #3: how to mute a video</a> originally appeared on <a href="http://html5doctor.com">HTML5 Doctor</a> on October 15, 2010.</p>
]]></content:encoded>
			<wfw:commentRss>http://html5doctor.com/html5-simplequiz-3-how-to-mute-a-video/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>An introduction to the Canvas 2D API</title>
		<link>http://html5doctor.com/an-introduction-to-the-canvas-2d-api/</link>
		<comments>http://html5doctor.com/an-introduction-to-the-canvas-2d-api/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 13:30:06 +0000</pubDate>
		<dc:creator>Remy Sharp</dc:creator>
				<category><![CDATA[Elements]]></category>
		<category><![CDATA[JavaScript APIs]]></category>
		<category><![CDATA[2d context]]></category>
		<category><![CDATA[canvas]]></category>

		<guid isPermaLink="false">http://html5doctor.com/?p=2264</guid>
		<description><![CDATA[<p>If the video element is the poster boy of <abbr>HTML</abbr>5, then canvas is definitely Danny Zuko. The canvas element is (still) part of the HTML5 specification, but the 2D drawing <abbr>API</abbr> has been moved into a separate document (in case you go looking and can't find it).</p>]]></description>
			<content:encoded><![CDATA[<p>If the <code>&lt;video&gt;</code> element is the poster boy of <abbr>HTML</abbr>5, then <code>&lt;canvas&gt;</code> is definitely <a href="http://en.wikipedia.org/wiki/Danny_Zuko">Danny Zuko</a>. The <code>&lt;canvas&gt;</code> element is (still) <a href="http://dev.w3.org/html5/spec/the-canvas-element.html#the-canvas-element">part of the HTML5 specification</a>, but the <a href="http://dev.w3.org/html5/2dcontext/">2D drawing <abbr>API</abbr></a> has been moved into a separate document (in case you go looking and can&#8217;t find it).</p>

<p><code>&lt;canvas&gt;</code> has a wealth of features, like:</p>

<ul>
<li>drawing shapes,</li>
<li>filling colours,</li>
<li>creating gradients and patterns,</li>
<li>rendering text,</li>
<li>copying images, video frames, and other canvases,</li>
<li>manipulating pixels, and</li>
<li>exporting the contents of a <code>&lt;canvas&gt;</code> to a static file. </li>
</ul>

<p>In fact, the canvas <abbr>API</abbr> is so interesting, I wouldn&#8217;t be surprised to see entire books dedicated to it (and no, I don&#8217;t plan to write <em>that</em> book!).</p>

<p>It&#8217;s important when working with <code>&lt;canvas&gt;</code> to treat it like a real painting canvas. Say you lay down a strip of red paint on a real canvas. If you paint over it in blue, you can&#8217;t get back to your original red paint. It&#8217;s the same with the canvas element. There&#8217;s no concept of layers. The <code>&lt;canvas&gt;</code> element is a <strong>bitmap</strong> drawing <abbr>API</abbr>, and once you&#8217;ve committed to a set of pixels, you&#8217;re stuck with them. </p>

<p>Four of the Big Five browsers support canvas. We&#8217;re naturally missing <abbr>IE</abbr>8, but there&#8217;s hope: <abbr>IE</abbr>9 <em>does</em> support canvas. In fact, it supports <em>hardware accelerated drawing to the canvas</em> — other browsers currently don&#8217;t, making <abbr>IE</abbr>9 preview 3 the fastest (canvas) kid on the block!</p>

<h2>Always consider the options</h2>

<p>Before we dive in to the canvas <abbr>API</abbr>, I want to remind you to make sure you&#8217;re using the right technology for the job.</p>

<p><a href="http://www.w3.org/TR/SVG/"><abbr>SVG</abbr></a> is the alternative drawing <abbr>API</abbr>. It&#8217;s vector-based and <em>does</em> support layers. <abbr>SVG</abbr> also exists in the <abbr>DOM</abbr>, making it easy to attach event handlers for interactivity, and it&#8217;s easier to deal with collision detection (in games, for example). It also supports animation either through <abbr>SMIL</abbr> or JavaScript. There&#8217;s an excellent JavaScript library called <a href="http://raphaeljs.com/">Raphaël</a> that uses <abbr>SVG</abbr> to render images and animations.</p>

<p>The <code>&lt;canvas&gt;</code> element is good for pixel manipulation and highly active animations. Brad Neuberg does a <a href="http://www.youtube.com/watch?v=siOHh0uzcuY#t=17m00s">really good job of explaining the differences</a> in his Google <abbr>IO</abbr> talk from back in 2009.</p>

<p>With all that in mind, let&#8217;s crack on with the canvas <abbr>API</abbr>.</p>

<h2>Hello Canvas</h2>

<p>The <code>&lt;canvas&gt;</code> element by itself is an invisible block of space, by default 300&#215;150 pixels (in all browsers):</p>

<pre><code>&lt;canvas id="c"&gt;&lt;/canvas&gt;
</code></pre>

<p>So now we&#8217;ve got a blank canvas in front of us. To draw, we need the <em>drawing context</em>, which we can get using JavaScript. Once we have the context, we can draw abominations to our hearts&#8217; content:</p>

<pre><code>&lt;script&gt;
// declare the two variables at once using a comma
var canvas = document.getElementById("c"),
    context = canvas.getContext("2d");

// now you're ready to draw
&lt;/script&gt;
</code></pre>

<p><small><a href="http://jsbin.com/abagi3/edit">Code snippet</a></small></p>

<p>The context is our direct access to draw and paint on the canvas. Without it, we can&#8217;t paint a thing.</p>

<h2>Painting Shapes</h2>

<p>The 2D drawing API is fairly large (not too huge, but bigger than most other <abbr>HTML</abbr>-esque <abbr>API</abbr>s), so I&#8217;m just going to show you how to draw something simple: a solid blue rectangle and a pink semi-circle.</p>

<p>Using the <code>context</code> object from earlier, we&#8217;re going to call <code>fillRect()</code>, passing the method the coordinates of the top left corner (x, y) and the width and height of the rectangle we want to paint:</p>

<pre><code>&lt;script&gt;
var canvas = document.getElementById("c"),
    context = canvas.getContext("2d");

// x = 10, y = 20, width = 200, height = 100
context.fillRect(10, 20, 200, 100);
&lt;/script&gt;
</code></pre>

<p><small><a href="http://jsbin.com/abagi3/2/edit">Code snippet</a></small></p>

<p><figure><img style="border: 1px solid #ccc;" src="http://html5doctor.com/wp-content/uploads/2010/07/canvas1.png" alt="Simple filled rectangle" title="Simple filled rectangle" width="300" height="150" class="alignnone size-full wp-image-2269" /><figcaption>Simple filled rectangle created with canvas</figcaption></figure></p>

<p>If you don&#8217;t specify a colour, the default fill and stroke colours will be black. So let&#8217;s change that to blue by setting the <code>fillStyle()</code> <em>before</em> we call <code>fillRect()</code>. We&#8217;re choosing our colour before drawing because this <code>&lt;canvas&gt;</code> is just like a real canvas — if you&#8217;re going to paint, you need to dip your brush in to the paint pot first:</p>

<pre><code>var canvas = document.getElementById("c"),
    context = canvas.getContext("2d");

context.fillStyle = 'blue';
context.fillRect(10, 20, 200, 100);
</code></pre>

<p><small><a href="http://jsbin.com/abagi3/3/edit">Code snippet</a></small></p>

<p><figure><img style="border: 1px solid #ccc;" src="http://html5doctor.com/wp-content/uploads/2010/07/canvas2.png" alt="" title="Blue filled rectangle" width="300" height="150" class="alignnone size-full wp-image-2270" /><figcaption>Blue filled rectangle created with canvas</figcaption></figure></p>

<p>Being the eagle-eyed <abbr>HTML</abbr>5 ninja that you are, you noticed that I&#8217;ve used the string <code>blue</code> as the fill colour. You can use any CSS colour properties in the canvas <abbr>API</abbr>. That means <code>blue</code>, <code>#0000ff</code>, <code>#00f</code>, <code>rgb(0, 0, 255)</code>, and even <code>rgba(0, 0, 255, 0.5)</code> are all valid colours.</p>

<p>How about we turn this thing up to eleven? Let&#8217;s add a pink semi-circle. <a href="http://www.youtube.com/watch?v=cbpccXp6Swo">Oh yeah! Let&#8217;s do this!</a></p>

<pre><code>var canvas = document.getElementById("c"),
    context = canvas.getContext("2d");

context.fillStyle = 'blue';
context.fillRect(10, 20, 200, 100);

// setup the line style
context.strokeStyle = '#fa00ff';
context.lineWidth = 5;
context.lineCap = 'round';

// draw the arc path
// (I'll walk you through these values momentarily - bear with me!)
context.arc(50, 50, 20, 0, Math.PI, false);

// colour the path
context.stroke();
</code></pre>

<p><small><a href="http://jsbin.com/abagi3/4/edit">Code snippet</a></small></p>

<p><figure><img style="border:1px solid #ccc;" src="http://html5doctor.com/wp-content/uploads/2010/07/canvas3.png" alt="" title="Blue filled rectangle with semi-circle" width="300" height="150" class="alignnone size-full wp-image-2271" /><figcaption>Blue filled rectangle with a semi-circle created with canvas</figcaption></figure></p>

<p>There are three things that we&#8217;ve added to our JavaScript:</p>

<ol>
<li>Configuring the line style</li>
<li>Drawing the semi-circle <strong>path</strong></li>
<li>Stroking the path (i.e., painting the line)</li>
</ol>

<p>When drawing paths, until you <code>fill</code> or <code>stroke</code> the path, nothing appears on the canvas. In this case, our path is an arc of a 180 degrees. The <code>arc()</code> method takes the following arguments: x coordinate, y coordinate, radius, start angle, end angle, and whether the arc should be drawn anti-clockwise. All of these arguments are required. (Technically, if you&#8217;re drawing a circle, it doesn&#8217;t matter whether you&#8217;re going clockwise or anti-clockwise, but you still need the argument.)</p>

<p>The tricky parts are the start and end angle. They&#8217;re both in radians. Remember those? I didn&#8217;t, so I&#8217;ll forgive you if you don&#8217;t! Here&#8217;s how to convert from degrees to radians:</p>

<pre><code>var radians = degrees * Math.PI / 180;
</code></pre>

<p>It&#8217;s common to pass 360 degrees to the drawing methods, which is simply <code>Math.PI * 2</code>. Similarly, 180 degrees is <code>Math.PI</code>, which we used to create our semi-circle.</p>

<p>Once you have your path, you need to <code>stroke</code> (or <code>fill</code>) it. This applies the line style and colours to the path and completes our drawing. Do please remember that with this drawing: a) you can&#8217;t recover those lost blue pixels under the pink semi-circle, and b) this example would be much simpler in <abbr>SVG</abbr>!</p>

<p>So remember to choose the <code>&lt;canvas&gt;</code> element based on its strengths as I outlined at the top of this article.</p>

<h2>Exporting &#038; Saving</h2>

<p>One thing that <abbr>SVG</abbr> <em>can&#8217;t</em> do is save the resulting image as a bitmap. It&#8217;s easy for <code>&lt;canvas&gt;</code> because the element is already a bitmap in the first place! The canvas can export its image to a data <abbr>URL</abbr> (e.g., <code>data:image/png;base64,iVBORw0KGg...</code>). This data may then be rendered in the browser, which could then be saved or dragged to the desktop, used in a new canvas, and so on.</p>

<p>The browser must support <abbr>PNG</abbr> images, and it may have varying support for <abbr>GIF</abbr> and <abbr>JPG</abbr>. For our example, we&#8217;ll stick with <abbr>PNG</abbr> since it supports alpha transparency, and where we haven&#8217;t drawn on the canvas, it&#8217;ll be transparent.</p>

<p>To get the data <abbr>URL</abbr>, we simply call <code>canvas.toDataURL('image/png')</code>. Note that we&#8217;re calling <code>toDataURL()</code> on the <code>&lt;canvas&gt;</code> element, <em>not</em> on the 2D context. This is because we&#8217;re getting all the pixels in the canvas, not just the pixels in a particular context.</p>

<p>So taking the example we&#8217;ve put together already, we&#8217;ll make the browser redirect to a <abbr>PNG</abbr> version of the image when a user clicks on the <code>&lt;canvas&gt;</code> element (a contrived example, I know!):</p>

<pre><code>canvas.onclick = function () {
  window.location = canvas.toDataURL('image/png');
};
</code></pre>

<p><small><a href="http://jsbin.com/abagi3/5/edit">Code snippet</a></small></p>

<p>If you go to the <a href="http://jsbin.com/abagi3/5/">live canvas example</a> and click on the <code>&lt;canvas&gt;</code> element, it will load a <abbr>PNG</abbr> version of the canvas. Now you can save that to your desktop, email it to your friends, or even tweet it to your followers!</p>

<h2>That&#8217;s just the start</h2>

<p>This is just a small preview of what the canvas 2D <abbr>API</abbr> can do. There&#8217;s a whole lot more:</p>

<ul>
<li>Gradients, fills, and patterns</li>
<li>Paths</li>
<li>Text</li>
<li>Pixel manipulation</li>
<li>Animations (though old school, flip book style)</li>
</ul>

<p>And don&#8217;t worry, the <abbr>HTML</abbr>5 Doctors will publish more articles explaining the canvas <abbr>API</abbr> in the future. We&#8217;ll even have special guest <a href="http://twitter.com/tabatkins">Tab Atkins</a> explaining how he got a video to render entirely in <abbr>ASCII</abbr>!</p>

<p>In the meantime, here are a few useful resources to keep you going.</p>

<h2>Further reading</h2>

<ul>
<li><a href="https://developer.mozilla.org/en/canvas_tutorial">Mozilla&#8217;s canvas tutorial</a></li>
<li><a href="http://dev.opera.com/articles/view/html-5-canvas-the-basics/">Opera&#8217;s canvas tutorial</a></li>
<li><a href="http://billmill.org/static/canvastutorial/">Breakout game live tutorial</a></li>
<li><a href="http://diveinto.html5doctor.com/canvas.html">Mark Pilgrim&#8217;s Dive in to HTML5 canvas chapter</a> — but don&#8217;t forget there are <a href="http://introducinghtml5.com">other good books</a> you can buy too <img src='http://html5doctor.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> 
<div id="crp_related"><h3>Related Posts:</h3><ul class="related"><li><a href="http://html5doctor.com/video-canvas-magic/" rel="bookmark" class="crp_title">video + canvas = magic</a></li><li><a href="http://html5doctor.com/your-questions-16/" rel="bookmark" class="crp_title">Your Questions #16</a></li><li><a href="http://html5doctor.com/your-questions-13/" rel="bookmark" class="crp_title">Your Questions #13</a></li><li><a href="http://html5doctor.com/your-questions-answered-11/" rel="bookmark" class="crp_title">Your Questions Answered #11</a></li><li><a href="http://html5doctor.com/review-html5-now-dvd/" rel="bookmark" class="crp_title">Review: HTML5 Now (DVD)</a></li></ul></div></li>
</ul>
<p><a href="http://html5doctor.com/an-introduction-to-the-canvas-2d-api/" rel="bookmark">An introduction to the Canvas 2D API</a> originally appeared on <a href="http://html5doctor.com">HTML5 Doctor</a> on August 3, 2010.</p>
]]></content:encoded>
			<wfw:commentRss>http://html5doctor.com/an-introduction-to-the-canvas-2d-api/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Introducing Web SQL Databases</title>
		<link>http://html5doctor.com/introducing-web-sql-databases/</link>
		<comments>http://html5doctor.com/introducing-web-sql-databases/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 10:15:39 +0000</pubDate>
		<dc:creator>Remy Sharp</dc:creator>
				<category><![CDATA[JavaScript APIs]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://html5doctor.com/?p=1408</guid>
		<description><![CDATA[The Web SQL database API isn't actually part of the HTML5 specification, but it is part of the suite of specifications that allows us developers to build fully fledged web applications, so it was about time we dug around and checked out the deal.]]></description>
			<content:encoded><![CDATA[<p>The Web SQL database API isn&#8217;t actually part of the HTML5 specification, but it is part of the suite of specifications that allows us developers to build fully fledged web applications, so it&#8217;s about time we dig in and check it out.</p>

<p><span id="more-1408"></span></p>

<h2>What&#8217;s in the box?</h2>

<p>If you haven&#8217;t guessed from the overly verbose specification title, Web SQL Databases is a spec that brings SQL to the client side. If you have a back-end developer&#8217;s background, then you&#8217;ll probably be familiar with SQL and happy as a pig in muck. If not, you might want to learn some SQL before you start hacking around, Google&#8217;s your friend here.</p>

<p>The specification is based around SQLite (3.1.19), but having come from MySQL myself, it&#8217;s all pretty much the same (sorry for the sweeping statement!).</p>

<p>For an example of Web SQL Databases working, have a look at the <a href="http://rem.im/html5-tweet-time-range.html">Twitter HTML5 chatter demo</a> I put together. It uses SQL and the WHERE clause to narrow down the recent chat about HTML5 on Twitter (it will work in Safari, Chrome and Opera 10.50).</p>

<p>There are three core methods in the spec that I&#8217;m going to cover in this article:</p>

<ol>
<li><code>openDatabase</code></li>
<li><code>transaction</code></li>
<li><code>executeSql</code></li>
</ol>

<p>Support is a little patchy at the moment. Only Webkit (Safari, SafariMobile and Chrome) and Opera 10.50 (<abbr title="at time of writing">ATOW</abbr> alpha on Mac) support web databases. Fellow Doctor <a href="http://html5doctor.com/author/brucel/">Bruce Lawson</a> has told me that Firefox are holding off as they feel there&#8217;s a better implementation than SQLite (though I hope it&#8217;s similar, whatever they pick). Either way, I&#8217;d definitely recommend checking out the <a href="http://sqlite.org">SQLite</a> documentation for the functions that are available.</p>

<p>Because of this patchy support and the simple fact that Webkit had implemented the database spec some time ago, the spec on the W3C is now slightly ahead of the implementations in Safari, while Webkit is still catching up. On the other hand, since Opera has only just added support, it&#8217;s closer to the spec (I&#8217;ll mention the differences as we go along).</p>

<p>Nonetheless, it&#8217;s fun to play with, so let&#8217;s get playing!</p>

<h2>Creating and Opening Databases</h2>

<p>If you try to open a database that doesn&#8217;t exist, the API will create it on the fly for you. You also don&#8217;t have to worry about closing databases.</p>

<p>To create and open a database, use the following code:</p>

<pre><code>var db = openDatabase('mydb', '1.0', 'my first database', 2 * 1024 * 1024);</code></pre>

<p>I&#8217;ve passed four arguments to the <code>openDatabase</code> method. These are:</p>

<ol>
<li>Database name</li>
<li>Version number</li>
<li>Text description</li>
<li>Estimated size of database</li>
</ol>

<p>The missing feature of <code>openDatabase</code> (I&#8217;m not sure when it was added) is the fifth argument:</p>

<ol start="5"><li>Creation callback</li></ol>

<p>The creation callback will be called if the database is being created. Without this feature, however, the databases are still being created on the fly and correctly versioned.</p>

<p>The return value from <code>openDatabase</code> contains the transaction methods, so we&#8217;ll need to capture this to be able to perform SQL queries.</p>

<h3>Estimated database size</h3>

<p>From the tests I&#8217;ve run, only Safari prompts the user if you try to create a database over the size of the default database size, 5MB. The prompt is shown the image below, asking whether you want to grant the database permission to scale up to the next size of database &#8212; 5, 10, 50, 100 and 500MB. Opera, on the other hand, builds the database without complaining, which I expect might change later as it&#8217;s still in alpha.</p>

<p><img src="http://html5doctor.com/wp-content/uploads/2010/02/webkit-db-size-prompt-e1266517048880.png" alt="Webkit database size prompt" title="Webkit database size prompt" /></p>

<h3>Versions</h3>

<p>I could be wrong, but everything I&#8217;ve tested so far says that versioning in SQL databases is borked. The problem is this:</p>

<p>If you upgrade your database to version 2.0 (e.g., there are some important schema changes since version 1.0), how do you know which visitors are on version 1.0 and which are on version 2.0?</p>

<p>The version number is a <strong>required</strong> argument to <code>openDatabase</code>, so you must <em>know</em> the version number before you try to open it. Otherwise, an exception is thrown.</p>

<p>Also, <code>changeVersion</code>, the method to change the database version, is not fully supported in Webkit. It works in Chrome and Opera, but not in Safari or Webkit. Regardless, if I can&#8217;t determine which version of database the user is on, then I can&#8217;t upgrade the user.</p>

<p>A possible workaround is to maintain a state database, something like the &#8216;mysql&#8217; database in MySQL. This way, you would only have <strong>one</strong> version of this state database, and within this you would record the current version of any databases that control your application. It&#8217;s a hack, but it works.</p>

<h2>Transactions</h2>

<p>Now that we&#8217;ve opened our database, we can create transactions. Why bother with transactions instead of just running our SQL? Transactions give us the ability to <em>rollback</em>. This means that if a transaction &#8212; which could contain one or more SQL statements &#8212; fails (either the SQL or the code in the transaction), the updates to the database are never committed &#8212; i.e. it&#8217;s as if the transaction <em>never happened</em>.</p>

<p>There are also error and success callbacks on the transaction, so you can manage errors, but it&#8217;s important to understand that transactions have the ability to rollback changes.</p>

<p>The transaction is simply a function that contains <em>some code</em>:</p>

<pre><code>var db = openDatabase('mydb', '1.0', 'my first database', 2 * 1024 * 1024);
db.transaction(function (tx) {
  // here be the transaction
  // do SQL magic here using the tx object
});</code></pre>

<p>I recently uploaded a demo to <a href="http://html5demos.com">html5demos.com</a> that demonstrates a transaction rollback in  action: <a href="http://html5demos.com/database-rollback">Web SQL database rollback demo</a></p>

<p>In the nightly builds of the browsers, we also have <code>db.readTransaction</code>, which allows only read statements to run on the database. I assume there are performance benefits to using a read-only <code>readTransaction</code> instead of a read/write <code>transaction</code>, most probably to do with table locking.</p>

<p>Now that we&#8217;ve got our transaction object (named <code>tx</code> in my example) we&#8217;re ready to run some SQL!</p>

<h2>executeSql</h2>

<p>This is the funnel of love for all your SQL goodness. <code>executeSql</code> is used for both read and write statements, includes SQL injection projection, and provides a callback method to process the results of any queries you may have written.</p>

<p>Once we have a transaction object, we can call <code>executeSql</code>:</p>

<pre><code>var db = openDatabase('mydb', '1.0', 'my first database', 2 * 1024 * 1024);
db.transaction(function (tx) {
  tx.executeSql('CREATE TABLE foo (id unique, text)');
});</code></pre>

<p>This will now create a simple table called &#8220;foo&#8221; in our database called &#8220;mydb&#8221;. Note that if the database already exists the transaction will fail, so any successive SQL wouldn&#8217;t run. So we can either use another transaction, or we can only create the table if it doesn&#8217;t exist, which I&#8217;ll do now so I can insert a new row in the same transaction:</p>

<pre><code>var db = openDatabase('mydb', '1.0', 'my first database', 2 * 1024 * 1024);
db.transaction(function (tx) {
  tx.executeSql('CREATE TABLE IF NOT EXISTS foo (id unique, text)');
  tx.executeSql('INSERT INTO foo (id, text) VALUES (1, "synergies")');
});</code></pre>

<p>Now our table has a single row inside it. What if we want to capture the text from the user or some external source? We&#8217;d want to ensure it can&#8217;t compromise the security of our database (using something nasty like SQL injection). The second argument to <code>executeSql</code> maps field data to the query, like so:</p>

<pre><code>tx.executeSql('INSERT INTO foo (id, text) VALUES (?, ?)', [id, userValue]);</code></pre>

<p><code>id</code> and <code>userValue</code> are external variables, and <code>executeSql</code> maps each item in the array argument to the <abbr title="question mark">&#8220;?&#8221;</abbr>s.</p>

<p>Finally, if we want to select values from the table, we use a callback to capture the results:</p>

<pre><code>tx.executeSql('SELECT * FROM foo', [], function (tx, results) {
  var len = results.rows.length, i;
  for (i = 0; i &lt; len; i++) {
    alert(results.rows.item(i).text);
  }
});</code></pre>

<p>(Notice that in this query, there are no fields being mapped, but in order to use the third argument, I need to pass in an empty array for the second argument.)</p>

<p>The callback receives the transaction object (again) and the results object. The results object contains a <code>rows</code> object, which is array-like but <strong>isn&#8217;t</strong> an array. It has a length, but to get to the individual rows, you need to use <code>results.rows.item(i)</code>, where <code>i</code> is the index of the row. This will return an object representation of the row. For example, if your database has a <code>name</code> and an <code>age</code> field, the row will contain a <code>name</code> and an <code>age</code> property. The value of the <code>age</code> field could be accessed using <code>results.rows.item(i).age</code>.</p>

<p>That&#8217;s all you should need to get started with Web SQL Databases. I&#8217;m certain that mini JavaScript libraries are going to emerge to help support working with databases. If you want to find out more about SQL databases (shameless self promotion begins) I just finished the storage chapter for <a href="http://www.amazon.com/Introduction-Html-5-Bruce-Lawson/dp/0321687299">Introducing HTML5</a>, which I&#8217;m writing with fellow Doc Bruce, so check that bad boy out too!</p>

<h2>Demos</h2>

<ul>
<li><a href="http://html5demos.com/database">HTML5 demo showing simple database usage</a></li>
<li><a href="http://html5demos.com/database-rollback">HTML5 demonstration of a transaction rolling back</a></li>
<li><a href="http://rem.im/html5-tweet-time-range.html">Demo showing time range selection using SQLite</a></li>
</ul>

<div id="crp_related"><h3>Related Posts:</h3><ul class="related"><li><a href="http://html5doctor.com/methods-of-communication/" rel="bookmark" class="crp_title">Methods of communication</a></li><li><a href="http://html5doctor.com/native-drag-and-drop/" rel="bookmark" class="crp_title">Native Drag and Drop</a></li><li><a href="http://html5doctor.com/finding-your-position-with-geolocation/" rel="bookmark" class="crp_title">Finding your position with Geolocation</a></li><li><a href="http://html5doctor.com/video-canvas-magic/" rel="bookmark" class="crp_title">video + canvas = magic</a></li><li><a href="http://html5doctor.com/html5-custom-data-attributes/" rel="bookmark" class="crp_title">HTML5 Custom Data Attributes (data-*)</a></li></ul></div>
<p><a href="http://html5doctor.com/introducing-web-sql-databases/" rel="bookmark">Introducing Web SQL Databases</a> originally appeared on <a href="http://html5doctor.com">HTML5 Doctor</a> on February 24, 2010.</p>
]]></content:encoded>
			<wfw:commentRss>http://html5doctor.com/introducing-web-sql-databases/feed/</wfw:commentRss>
		<slash:comments>67</slash:comments>
		</item>
	</channel>
</rss>

