<?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>Mozilla Hacks - the Web developer blog &#187; Firefox 3.5</title>
	<atom:link href="http://hacks.mozilla.org/category/fx-35/feed/" rel="self" type="application/rss+xml" />
	<link>http://hacks.mozilla.org</link>
	<description>hacks.mozilla.org</description>
	<lastBuildDate>Wed, 08 Feb 2012 22:52:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Spirit of Indiana (Jones) &#8211; syncing HTML5 Video with Maps</title>
		<link>http://hacks.mozilla.org/2010/12/spirit-of-indiana-jones-syncing-html5-video-with-maps/</link>
		<comments>http://hacks.mozilla.org/2010/12/spirit-of-indiana-jones-syncing-html5-video-with-maps/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 14:24:16 +0000</pubDate>
		<dc:creator>Chris Heilmann</dc:creator>
				<category><![CDATA[Audio]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[Firefox 3.6]]></category>
		<category><![CDATA[Firefox 4]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[googlemaps]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[indianajones]]></category>
		<category><![CDATA[maps]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=6815</guid>
		<description><![CDATA[I&#8217;ve always been a big fan of the travel/flight sequences in the Indiana Jones movies and judging by the amount of copy attempts on YouTube I am not alone in this. As I don&#8217;t own any video editing software I thought it should be possible to create the same effect with web technologies and Google [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve always been a big fan of the travel/flight sequences in the Indiana Jones movies and judging by the amount of <a href="http://www.youtube.com/results?search_query=indiana+jones+map+animation&#038;aq=f">copy attempts on YouTube</a> I am not alone in this.  As I don&#8217;t own any video editing software I thought it should be possible to create the same effect with web technologies and Google Maps and lo and behold it is:</p>
<p><iframe title="YouTube video player" class="youtube-player" type="text/html" width="480" height="390" src="http://www.youtube.com/embed/KNNzP6fyOyQ?rel=0" frameborder="0"></iframe></p>
<p><a href="http://isithackday.com/spirit-of-indiana/">See the demo online</a></p>
<p>You can <a href="https://github.com/codepo8/HTML5---map-and-video-syncing">download the animation demo</a> for yourself and try it out locally &#8211; all you need is a browser that supports HTML5 video. I know &#8211; the music is not quite the same as in the movies, but at least this one is not copyright infringing and it came from the heart (5 minutes in a meeting room in the Mozilla office). </p>
<p>So how was this done and what are problems that needed solving? Here&#8217;s how and what.</p>
<h2>Step 1: Find the movie and get it to the right format</h2>
<p>That was the easy part. <a href="http://www.archive.org/">Archive.org</a> has a lot of awesome public domain movies available for you and they are already in the formats needed to use in an HTML5 video element. In this case, I took the short <a href="http://www.archive.org/details/CharlesLindbergTakesOff">movie of Charles Lindbergh</a> taking off for <a href="http://en.wikipedia.org/wiki/Charles_Lindbergh">his record breaking flight from New York to fly to Paris in 1927</a>.</p>
<h2>Step 2: Displaying the video</h2>
<p>Using the video <a href="http://isithackday.com/spirit-of-indiana/video.html">is pretty simple</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;stage&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;video<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;source</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;http://www.archive.org/download/</span>
<span style="color: #009900;">CharlesLindbergTakesOff/CharlesLindbergTakesOff_512kb.mp4&quot;</span> </span>
<span style="color: #009900;"><span style="color: #000066;">type</span>=<span style="color: #ff0000;">'video/mp4; codecs=&quot;avc1.42E01E, mp4a.40.2&quot;'</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;source</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;http://www.archive.org/download/</span>
<span style="color: #009900;">CharlesLindbergTakesOff/CharlesLindbergTakesOff.ogv&quot;</span></span>
<span style="color: #009900;"> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">'video/ogg; codecs=&quot;theora, vorbis&quot;'</span><span style="color: #000000; font-weight: bold;">&gt;</span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/video<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The MP4 format will be used by Webkit based browsers and the Ogg version by Firefox and others. As we want to control the video we omit the <code>controls</code> attribute on the <code>video</code> element &#8211; instead we create a button to play the video with JavaScript:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">window.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'load'</span><span style="color: #339933;">,</span> 
  <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> stage <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'stage'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> v <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'video'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    but <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'button'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    but.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'Click to see Lindbergh<span style="color: #000099; font-weight: bold;">\'</span>s flight'</span><span style="color: #339933;">;</span>
    stage.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>but<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    but.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      v.<span style="color: #660066;">play</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      e.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> 
<span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>As the video is markup we can do whatever we please with it &#8211; the power of open technologies. For example as we will do here we can set its opacity in CSS and put in on top of a map.</p>
<h2>Step 3: Create the map path animation</h2>
<p>Talking of which, let&#8217;s get that moving path done. Google Earth has an API to do that, but it needs a special plugin. Google Maps allows you to paint paths on maps (which actually are SVG, another open standard). Put that in a recursive function and you <a href="http://isithackday.com/spirit-of-indiana/map.html">get the desired effect</a>: </p>
<p><a href="http://isithackday.com/spirit-of-indiana/map.html" title="Animated Google Maps path synced with HTML5 video by codepo8, on Flickr"><img src="http://farm6.static.flickr.com/5169/5264317406_20886eefb9.jpg" width="500" height="444" alt="Animated Google Maps path synced with HTML5 video" /></a></p>
<p>In essence, what I did was take the latitude and longitude of the start and end points and calculate as many points in between the two as I need for the duration of the animation. I store the points in an array called <code>pos</code> and then paint a path from the start to the current point and move the map centre to this point on every iteration.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">spirit.<span style="color: #660066;">draw</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> path <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">Polyline</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
        path<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>startpos<span style="color: #339933;">,</span>pos<span style="color: #009900;">&#91;</span>now<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        strokeColor<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;#c00&quot;</span><span style="color: #339933;">,</span>
        strokeOpacity<span style="color: #339933;">:</span> .7<span style="color: #339933;">,</span>
        strokeWeight<span style="color: #339933;">:</span> <span style="color: #CC0000;">10</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  path.<span style="color: #660066;">setMap</span><span style="color: #009900;">&#40;</span>map<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  map.<span style="color: #660066;">panTo</span><span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#91;</span>now<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
  now <span style="color: #339933;">=</span> now <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>now <span style="color: #339933;">&lt;</span> animationend<span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    setTimeout<span style="color: #009900;">&#40;</span>spirit.<span style="color: #660066;">draw</span><span style="color: #339933;">,</span><span style="color: #CC0000;">200</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Check the <a href="https://github.com/codepo8/HTML5---map-and-video-syncing/blob/master/map.js">highly commented source of the map example</a> for the details. Now, we could use this kind of animation and play the video over it &#8211; the problem though is that they may get out of sync. When the movie stalls (as it frequently does on this hotel wireless connection) we don&#8217;t want the animation to keep moving, right?</p>
<h2>Step 4: Syncing video and the map movement</h2>
<p>Instead of having two sources of timing information we have to limit ourselves to one source of truth. This is the time stamp of the currently playing movie. </p>
<p>By the way &#8211; you might have noticed that I wrapped the map code in a <code>tilesloaded</code> event handler. This is another safeguard for keeping things in sync. I found that on slow connections the tile loading can delay the whole interface immensely (because of all the subdomain lookups), so I make the whole interface dependent on the loading of the map and only proceed when the tiles have finished loading. As the <code>tilesloaded</code> event also fires when the map pans we need to use a boolean to stop it from starting the effect several times:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">event</span>.<span style="color: #660066;">addListener</span><span style="color: #009900;">&#40;</span>map<span style="color: #339933;">,</span><span style="color: #3366CC;">'tilesloaded'</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>played <span style="color: #339933;">===</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// [...other code...]</span>
    played <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>You can read the current timestamp of a video with <code>video.currentTime</code> and whilst the movie is playing it constantly fires an event called <code>timeupdate</code>. As the event fires a lot we need to throttle it somehow. The trick here is to only take the full seconds and increase a counter when a new second is reached. You can see the timestamp and the second interval firing in <a href="http://isithackday.com/spirit-of-indiana/video-sync.html">the video syncing demo</a>:</p>
<p><a href="http://isithackday.com/spirit-of-indiana/video-sync.html" title="HTML5 video with timestamp by codepo8, on Flickr"><img src="http://farm6.static.flickr.com/5289/5264312358_59392bd2f9.jpg" width="500" height="491" alt="HTML5 video with timestamp" /></a></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> now <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
v.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'timeupdate'</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>o<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  log.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> v.<span style="color: #660066;">currentTime</span><span style="color: #339933;">;</span> <span style="color: #009966; font-style: italic;">/* logging the real timestamp */</span>
  <span style="color: #003366; font-weight: bold;">var</span> full <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>v.<span style="color: #660066;">currentTime</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>full <span style="color: #339933;">&gt;=</span> now<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    seqlog.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> now<span style="color: #339933;">;</span>  <span style="color: #009966; font-style: italic;">/* logging the seconds firing */</span>
    now <span style="color: #339933;">=</span> now <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That way the movie can lag in between and the sequence still stays in sync. Check the <a href="https://github.com/codepo8/HTML5---map-and-video-syncing/blob/master/video-sync.html">source of this demo on Github</a>.</p>
<h2>Putting it all together</h2>
<p>And that was about it &#8211; all I had to do is to set the movie&#8217;s opacity at a certain time stamp, start the sound at another and show and hide the copyright complaint at another. As we rely on the timestamp for the other effects we needed a boolean switch to avoid repeated firing:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">v.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'timeupdate'</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>o<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  full <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>v.<span style="color: #660066;">currentTime</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>full <span style="color: #339933;">===</span> now<span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    mapelm.<span style="color: #660066;">style</span>.<span style="color: #660066;">opacity</span> <span style="color: #339933;">=</span> .8<span style="color: #339933;">;</span>
    v.<span style="color: #660066;">style</span>.<span style="color: #660066;">opacity</span> <span style="color: #339933;">=</span> .4<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>full <span style="color: #339933;">===</span> animationstart<span style="color: #339933;">+</span><span style="color: #CC0000;">1</span> <span style="color: #339933;">&amp;&amp;</span> audioplay <span style="color: #339933;">===</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    a.<span style="color: #660066;">play</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    audioplay <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>full <span style="color: #339933;">===</span> animationstart<span style="color: #339933;">+</span><span style="color: #CC0000;">2</span> <span style="color: #339933;">&amp;&amp;</span> hidden <span style="color: #339933;">===</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    drmbedamned.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'block'</span><span style="color: #339933;">;</span>
    hidden <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>full <span style="color: #339933;">===</span> animationstart<span style="color: #339933;">+</span><span style="color: #CC0000;">3</span> <span style="color: #339933;">&amp;&amp;</span> hidden <span style="color: #339933;">===</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    drmbedamned.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'none'</span><span style="color: #339933;">;</span>
    hidden <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>full <span style="color: #339933;">&gt;=</span> now<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    path <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> google.<span style="color: #660066;">maps</span>.<span style="color: #660066;">Polyline</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
        path<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>startpos<span style="color: #339933;">,</span>pos<span style="color: #009900;">&#91;</span>full<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        strokeColor<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;#c00&quot;</span><span style="color: #339933;">,</span>
        strokeOpacity<span style="color: #339933;">:</span> .7<span style="color: #339933;">,</span>
        strokeWeight<span style="color: #339933;">:</span> <span style="color: #CC0000;">10</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    path.<span style="color: #660066;">setMap</span><span style="color: #009900;">&#40;</span>map<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    map.<span style="color: #660066;">panTo</span><span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#91;</span>full<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
    now <span style="color: #339933;">=</span> now <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Another event we needed to subscribe to was the movie ending so we can stop the music and start to roll the credits:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">v.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ended'</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>o<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  a.<span style="color: #660066;">pause</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  spirit.<span style="color: #660066;">credslist</span>.<span style="color: #660066;">parentNode</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'block'</span><span style="color: #339933;">;</span>
  spirit.<span style="color: #660066;">creds</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>As the theme is too short for the whole animation we need to loop it. This can be done by testing for the <code>ended</code> event and rolling back the time to 0:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">a.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ended'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>o<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  a.<span style="color: #660066;">currentTime</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Summary</h2>
<p>And there you have it &#8211; Indiana Jones style maps using open services and open technologies. A workaround for the copyrighted audio (recorded, edited and converted with the free <a href="http://audacity.sourceforge.net/">Audacity</a> sound editor) and using <a href="http://code.google.com/webfonts/">Google&#8217;s Web Fonts</a> as graphics. </p>
<p>You can now take this and change it for even more awesome:</p>
<ul>
<li>Replace Google Maps with Openstreetmap to avoid going over the limit</li>
<li>Add a slight curve to the path from NYC to Paris to make it more accurate (but then again the time is not accurate either &#8211; it took charles a tad longer)</li>
<li>Use a static map and paint the path with Canvas to speed up and smoothen the animation</li>
</ul>
<p>Why not have a go &#8211; it is free and fun to play.</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2010/12/spirit-of-indiana-jones-syncing-html5-video-with-maps/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Delivering the good message of local storage</title>
		<link>http://hacks.mozilla.org/2010/12/delivering-the-good-message-of-local-storage/</link>
		<comments>http://hacks.mozilla.org/2010/12/delivering-the-good-message-of-local-storage/#comments</comments>
		<pubDate>Tue, 07 Dec 2010 01:21:03 +0000</pubDate>
		<dc:creator>Chris Heilmann</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[Firefox 3.6]]></category>
		<category><![CDATA[Firefox 4]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Standards]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[local storage]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=6770</guid>
		<description><![CDATA[As you might know there are an incredible amount of advent calendar blogs out at the moment each delivering one cool article for each day of December until Christmas. Today (6/12/11) two calendar blogs delivered an article of mine talking about the benefits of using local storage in browsers and how to implement it. You [...]]]></description>
			<content:encoded><![CDATA[<p>As you might know there are an incredible amount of advent calendar blogs out at the moment each delivering one cool article for each day of December until Christmas. </p>
<p>Today (6/12/11) two calendar blogs delivered an article of mine talking about the benefits of using local storage in browsers and how to implement it.</p>
<p>You can find <a href="http://24ways.org/2010/html5-local-storage">the English version on the 24ways.org calendar</a> and <a href="http://www.webkrauts.de/2010/12/06/html5-als-geschenkverpackung-von-daten/">a German translation at the Webkrauts calendar</a>.</p>
<p>In essence, the article explains why it is a good idea to use local storage, explains how to use it, how to work around the issue that local storage can only store strings and gives example code on how to speed up web service use by caching information client-side much like you would do it on a server.</p>
<p>Have a read and go speed up your own solutions by using what browsers provide you these days. </p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2010/12/delivering-the-good-message-of-local-storage/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>what&#8217;s new in Firebug 1.5?</title>
		<link>http://hacks.mozilla.org/2009/11/whats-new-in-firebug-1-5/</link>
		<comments>http://hacks.mozilla.org/2009/11/whats-new-in-firebug-1-5/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 14:57:22 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[Featured Article]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[Firefox 3.6]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=2338</guid>
		<description><![CDATA[This is a re-post from Rob Cambell&#8217;s personal weblog. Firebug 1.5 is the first release that will work with the upcoming Firefox 3.6 and also also works with Firefox 3.5. It&#8217;s currently in beta and will be available before the release of Firefox 3.6. As of this minute, Firebug 1.5 is sitting comfortably in its [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is a re-post from <a href="http://antennasoft.net/robcee/2009/11/12/firebug-1-5-new-features-revealed/">Rob Cambell&#8217;s personal weblog</a>.  Firebug 1.5 is the first release that will work with the upcoming Firefox 3.6 and also also works with Firefox 3.5.  It&#8217;s currently in beta and will be available before the release of Firefox 3.6.</em></p>
<p>As of this minute, Firebug 1.5 is sitting comfortably in its third beta and available for <a href="http://getfirebug.com/releases/firebug/1.5X/firebug-1.5X.0b3.xpi" target="_blank">download</a>. This version is shaping up to be our best release yet and initial reports have been very positive regarding its stability, UI improvements and new features. So let’s take a look at some of the new features.</p>
<p><strong>Improved Net Panel accuracy</strong></p>
<p>One of the problems with Firebug&#8217;s Net panel in the past has been inaccurate timings. Because Firebug is entirely written in JavaScript some network and UI activity could block Firebug during long operations and cause the timings displayed there to be less than accurate. This has finally been corrected with the landing of a new service called the http-activity-distributor. For more details on the implementation and use of the newly-improved Net panel, see Honza&#8217;s <a href="http://www.softwareishard.com/blog/firebug/firebug-http-time-monitor/" target="_blank">blog post</a> on the topic.</p>
<p><strong>New Break Functionality</strong></p>
<p>In Firebug 1.4, we introduced the concept of “break-on-next” to the Script panel. This was a “pause” button sitting between the inspect icon and the Console tab. In 1.5, we’ve extended this concept to the Console, HTML and Net panels to allow more exciting types of breaks.</p>
<div><a title="break on xhr by robceemoz, on Flickr" href="http://www.flickr.com/photos/robceemoz/4098694166/"><img src="http://farm3.static.flickr.com/2527/4098694166_e8217cdf05.jpg" alt="break on xhr" width="500" height="268" /></a></div>
<p>In the Console, we’ve replaced the mini-menu <strong>Break-on-Errors</strong> option with the pause button. The reasons for this possibly contentious change was it made for a more consistent use of menus and the break button. Now, to enable Break on Errors, select the Console panel and hit the pause button. You’ll see that familiar glow to indicate that it’s waiting for an error. Now whenever an error occurs on the page, you’ll be dropped into the script panel at the line where the error occurred.</p>
<p>The HTML panel’s break button is a little different. This is the <strong>Break-on-Mutation</strong> feature. When this is enabled, whenever a bit of JavaScript modifies an HTML element, you’ll be taken to the Script panel and the modifying code while be highlighted. Related to this, you should be able to see modified HTML occurring in real-time in the HTML panel with affected elements and attributes being highlighted as they change in the page.</p>
<p>Finally in the Net panel, the break button acts as a <strong>Break-on-XHR</strong> button. This is intended to help debug AJAX apps by allowing you to halt the debugger during an XmlHttpRequest send. As in the other break types, you’ll be transported to the script panel when an XHR object fires off its request and you’ll be given the option to copy the message.</p>
<p>John Barton and Honza have written a great interactive demo page describing these new features on <a href="http://getfirebug.com/doc/breakpoints/demo.html" target="_blank">getfirebug.com</a>.</p>
<p><strong>Mixed Development</strong></p>
<ul>
<li>We made a few tweaks to the UI in this version. We replaced the “Off” label with a single “power” button (or window close button on Mac) as promised during the last release.</li>
<li>Kevin Decker added the search panel originally intended for version 1.4 with some nice options.</li>
<li>Persist option on Console and Net Panel. Save your data!</li>
<li>Improvements to the Inspector.</li>
<li>Still more to come. Between now and final release we plan on hunting down a few more bugs to make this even more stable. Feel free to download and give it a try.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/11/whats-new-in-firebug-1-5/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>experimenting with HTML5 video at the BBC</title>
		<link>http://hacks.mozilla.org/2009/08/html5-video-bbc/</link>
		<comments>http://hacks.mozilla.org/2009/08/html5-video-bbc/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 03:52:47 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[Demo]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Standards]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1578</guid>
		<description><![CDATA[The BBC has a post up describing an experiment that they have put together that uses HTML5 video that works in Firefox 3.5 and Safari. The demo uses jQuery and drives a simple carousel that shows the current chapter as the video plays. It also shows subtitles as the video plays. One really great, and [...]]]></description>
			<content:encoded><![CDATA[<p>The BBC has a <a href="http://www.bbc.co.uk/blogs/rad/2009/08/html5.html">post up</a> describing an <a href="http://open.bbc.co.uk/rad/demos/html5/rdtv/episode2/index.html">experiment</a> that they have put together that uses HTML5 video that works in Firefox 3.5 and Safari.</p>
<p><a href="http://open.bbc.co.uk/rad/demos/html5/rdtv/episode2/index.html"><img src="http://hacks.mozilla.org/wp-content/uploads/2009/08/bbc-video-experiment-300x283.png" alt="BBC HTML5 Video Experiment" title="BBC HTML5 Video Experiment" width="300" height="283" class="aligncenter size-medium wp-image-1579" /></a></p>
<p>The demo uses jQuery and drives a simple carousel that shows the current chapter as the video plays.  It also shows subtitles as the video plays.</p>
<p>One really great, and somewhat subtle thing about this experiment?  You can select the subtitles.  They are just text.</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/08/html5-video-bbc/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>an overview of TraceMonkey</title>
		<link>http://hacks.mozilla.org/2009/07/tracemonkey-overview/</link>
		<comments>http://hacks.mozilla.org/2009/07/tracemonkey-overview/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 12:28:27 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[TraceMonkey]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1462</guid>
		<description><![CDATA[This post was written by David Mandelin who works on Mozilla&#8217;s JavaScript team. Firefox 3.5 has a new JavaScript engine, TraceMonkey, that runs many JavaScript programs 3-4x faster than Firefox 3, speeding up existing web apps and enabling new ones. This article gives a peek under the hood at the major parts of TraceMonkey and [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post was written by <a href="http://blog.mozilla.com/dmandelin/">David Mandelin</a> who works on Mozilla&#8217;s JavaScript team.</em></p>
<p>Firefox 3.5 has a new JavaScript engine, TraceMonkey, that runs many JavaScript programs 3-4x faster than Firefox 3, speeding up existing web apps and enabling new ones. This article gives a peek under the hood at the major parts of TraceMonkey and how they speed up JS. This will also explain what kinds of programs get the best speedup from TraceMonkey and what kinds of things you can do to get your program to run faster. </p>
<p><strong>Why it&#8217;s hard to run JS fast: dynamic typing</strong></p>
<p>High-level dynamic languages such as JavaScript and Python make programming more productive, but they have always been slow compared to statically typed languages like Java or C. A typical rule of thumb was that a JS program might be 10x slower than an equivalent Java program.</p>
<p>There are two main reasons JS and other dynamic scripting languages usually run slower than Java or C. The first reason is that in dynamic languages it is generally not possible to determine the types of values ahead of time. Because of this, the language must store all values in a generic format and process values using generic operations.</p>
<p>In Java, by contrast, the programmer declares types for variables and methods, so the compiler can determine the types of values ahead of time. The compiler can then generate code that uses specialized formats and operations that run much faster than generic operations. I will call these <strong>type-specialized</strong> operations.</p>
<p>The second main reason that dynamic languages run slower is that scripting languages are usually implemented with interpreters, while statically typed languages are compiled to native code. Interpreters are easier to create, but they incur extra runtime overhead for tracking their internal state. Languages like Java compile to machine language, which requires almost no state tracking overhead.</p>
<p>Let&#8217;s make this concrete with a picture.  Here are the slowdowns in picture form for a simple numeric add operation: <code>a + b</code>, where <code>a</code> and <code>b</code> are integers. For now, ignore the rightmost bar and focus on the comparison of the Firefox 3 JavaScript interpreter vs. a Java JIT.  Each column shows the steps that have to be done to complete the add operation in each programming language. Time goes downward, and the height of each box is proportional to the time it takes to finish the steps in the box.</p>
<p><a target="_blank" href="http://hacks.mozilla.org/wp-content/uploads/2009/07/complexity.png"><img width="500" src="http://hacks.mozilla.org/wp-content/uploads/2009/07/complexity.png" alt='time diagram of add operation'/></a></p>
<p>In the middle, Java simply runs one machine language add instruction, which runs in time T (one processor cycle). Because the Java compiler knows that the operands are standard machine integers, it can use a standard integer add machine language instruction. That&#8217;s it.</p>
<p>On the left, SpiderMonkey (the JS interpreter in FF3) takes about 40 times as long. The brown boxes are interpreter overhead: the interpreter must read the add operation and jump to the interpreter&#8217;s code for a generic add. The orange boxes represent extra work that has to be done because the interpreter doesn&#8217;t know the operand types. The interpreter has to unpack the generic representations of <code>a</code> and <code>i</code>, figure out their types, select the specific addition operation, convert the values to the right types, and at the end, convert the result back to a generic format.</p>
<p>The diagram shows that using an interpreter instead of a compiler is slowing things down a little bit, but not having type information is slowing things down a lot. If we want JS to run more than a little faster than in FF3, by <a href="http://en.wikipedia.org/wiki/Amdahl%27s_law">Amdahl&#8217;s law</a>, we need to do something about types.</p>
<p><strong>Getting types by tracing</strong></p>
<p>Our goal in TraceMonkey is to compile type-specialized code. To do that, TraceMonkey needs to know the types of variables. But JavaScript doesn&#8217;t have type declarations, and we also said that it&#8217;s practically impossible for a JS engine to figure out the types ahead of time. So if we want to just compile everything ahead of time, we&#8217;re stuck.</p>
<p>So let&#8217;s turn the problem around. If we let the program run for a bit in an interpreter, the engine can directly <em>observe</em> the types of values. Then, the engine can use those types to compile fast type-specialized code. Finally, the engine can start running the type-specialized code, and it will run much faster.</p>
<p>There are a few key details about this idea. First, when the program runs, even if there are many if statements and other branches, the program always goes only one way. So the engine doesn&#8217;t get to observe types for a whole method &mdash; the engine observes types through the paths, which we call <em>traces</em>, that the program actually takes. Thus, while standard compilers compile methods, TraceMonkey compiles traces. One side benefit of trace-at-a-time compilation is that function calls that happen on a trace are inlined, making traced function calls very fast.</p>
<p>Second, compiling type-specialized code takes time. If a piece of code is going to run only one or a few times, which is common with web code, it can easily take more time to compile and run the code than it would take to simply run the code in an interpreter. So it only pays to compile <em>hot code</em> (code that is executed many times). In TraceMonkey, we arrange this by tracing only loops. TraceMonkey initially runs everything in the interpreter, and starts recording traces through a loop once it gets hot (runs more than a few times).</p>
<p>Tracing only hot loops has an important consequence: code that runs only a few times won&#8217;t speed up in TraceMonkey. Note that this usually doesn&#8217;t matter in practice, because code that runs only a few times usually runs too fast to be noticeable. Another consequence is that paths through a loop that are not taken at all never need to be compiled, saving compile time.</p>
<p>Finally, above we said that TraceMonkey figures out the types of values by observing execution, but as we all know, past performance does not guarantee future results: the types might be different the next time the code is run, or the 500th next time. And if we try to run code that was compiled for numbers when the values are actually strings, very bad things will happen. So TraceMonkey must insert type checks into the compiled code. If a check doesn&#8217;t pass, TraceMonkey must leave the current trace and compile a new trace for the new types. This means that code with many branches or type changes tends to run a little slower in TraceMonkey, because it takes time to compile the extra traces and jump from one to another.</p>
<p><strong>TraceMonkey in action</strong></p>
<p>Now, we&#8217;ll show tracing in action by example on this sample program, which adds the first N whole numbers to a starting value:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"> <span style="color: #003366; font-weight: bold;">function</span> addTo<span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> n<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> n<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
     a <span style="color: #339933;">=</span> a <span style="color: #339933;">+</span> i<span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">return</span> a<span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
&nbsp;
 <span style="color: #003366; font-weight: bold;">var</span> t0 <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #003366; font-weight: bold;">var</span> n <span style="color: #339933;">=</span> addTo<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10000000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #000066;">print</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> t0<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>TraceMonkey always starts running the program in the <em>interpreter</em>. Every time the program starts a loop iteration, TraceMonkey briefly enters <em>monitoring</em> mode to increment a counter for that loop. In FF3.5, when the counter reaches 2, the loop is considered hot and it&#8217;s time to trace.</p>
<p>Now TraceMonkey continues running in the interpreter but starts <em>recording</em> a trace as the code runs. The trace is simply the code that runs up to the end of the loop, along with the types used. The types are determined by looking at the actual values. In our example, the loop executes this sequence of JavaScript statements, which becomes our trace:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    a <span style="color: #339933;">=</span> a <span style="color: #339933;">+</span> i<span style="color: #339933;">;</span>    <span style="color: #006600; font-style: italic;">// a is an integer number (0 before, 1 after)</span>
    <span style="color: #339933;">++</span>i<span style="color: #339933;">;</span>          <span style="color: #006600; font-style: italic;">// i is an integer number (1 before, 2 after)</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&lt;</span> n<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">// n is an integer number (10000000)</span>
      <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span></pre></div></div>

<p>That&#8217;s what the trace looks like in a JavaScript-like notation. But TraceMonkey needs more information in order to compile the trace. The real trace looks more like this:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">  trace_1_start<span style="color: #339933;">:</span>
    <span style="color: #339933;">++</span>i<span style="color: #339933;">;</span>            <span style="color: #666666; font-style: italic;">// i is an integer number (0 before, 1 after)</span>
    temp <span style="color: #339933;">=</span> a <span style="color: #339933;">+</span> i<span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// a is an integer number (1 before, 2 after)</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>lastOperationOverflowed<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      exit_trace<span style="color: #009900;">&#40;</span>OVERFLOWED<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    a <span style="color: #339933;">=</span> temp<span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&lt;</span> n<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>   <span style="color: #666666; font-style: italic;">// n is an integer number (10000000)</span>
      exit_trace<span style="color: #009900;">&#40;</span>BRANCHED<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">goto</span> trace_1_start<span style="color: #339933;">;</span></pre></div></div>

<p>This trace represents a loop, and it should be compiled as a loop, so we express that directly using a <code>goto</code>. Also, integer addition can overflow, which requires special handling (for example, redoing with floating-point addition), which in turn requires exiting the trace. So the trace must include an overflow check. Finally, the trace exits in the same way if the loop condition is false. The exit codes tell TraceMonkey why the trace was exited, so that TraceMonkey can decide what to do next (such as whether to redo the add or exit the loop). Note that traces are recorded in a special internal format that is never exposed to the programmer &mdash; the notation used above is just for expository purposes.</p>
<p>After recording, the trace is ready to be <em>compiled</em> to type-specialized machine code.  This compilation is performed by a tiny JIT compiler (named, appropriately enough, <em>nanojit</em>) and the results are stored in memory, ready to be executed by the CPU.</p>
<p>The next time the interpreter passes the loop header, TraceMonkey will start <em>executing</em> the compiled trace. The program now runs very fast.</p>
<p>On iteration 65537, the integer addition will overflow. (2147450880 + 65537 = 2147516417, which is greater than 2^31-1 = 2147483647, the largest signed 32-bit integer.) At this point, the trace exits with an <code>OVERFLOWED</code> code. Seeing this, TraceMonkey will return to interpreter mode and redo the addition. Because the interpreter does everything generically, the addition overflow is handled and everything works as normal. TraceMonkey will also start monitoring this exit point, and if the overflow exit point ever becomes hot, a new trace will be started from that point.</p>
<p>But in this particular program, what happens instead is that the program passes the loop header again. TraceMonkey knows it has a trace for this point, but TraceMonkey also knows it can&#8217;t use that trace because that trace was for integer values, but <code>a</code> is now in a floating-point format. So TraceMonkey records a new trace:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">  trace_2_start<span style="color: #339933;">:</span>
    <span style="color: #339933;">++</span>i<span style="color: #339933;">;</span>            <span style="color: #666666; font-style: italic;">// i is an integer number</span>
    a <span style="color: #339933;">=</span> a <span style="color: #339933;">+</span> i<span style="color: #339933;">;</span>      <span style="color: #666666; font-style: italic;">// a is a floating-point number</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&lt;</span> n<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>   <span style="color: #666666; font-style: italic;">// n is an integer number (10000000)</span>
      exit_trace<span style="color: #009900;">&#40;</span>BRANCHED<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">goto</span> trace_2_start<span style="color: #339933;">;</span></pre></div></div>

<p>TraceMonkey then compiles the new trace, and on the next loop iteration, starts executing it.  In this way, TraceMonkey keeps the JavaScript running as machine code, even when types change.  Eventually the trace will exit with a BRANCHED code. At this point, TraceMonkey will return to the interpreter, which takes over and finishes running the program.</p>
<p>Here are the run times for this program on my laptop (2.2GHz MacBook Pro):</p>
<table>
<tr>
<td>System</td>
<td>Run Time (ms)</td>
</tr>
<tr>
<td>SpiderMonkey (FF3)</td>
<td>990</td>
</tr>
<tr>
<td>TraceMonkey (FF3.5)</td>
<td>45</td>
</tr>
<tr>
<td>Java (using int)</td>
<td>25</td>
</tr>
<tr>
<td>Java (using double)</td>
<td>74</td>
</tr>
<tr>
<td>C (using int)</td>
<td>5</td>
</tr>
<tr>
<td>C (using double)</td>
<td>15</td>
</tr>
</table>
<p>This program gets a huge 22x speedup from tracing and runs about as fast as Java! Functions that do simple arithmetic inside loops usually get big speedups from tracing. Many of the bit operation and math SunSpider benchmarks, such <code>bitops-3bit-bits-in-byte</code>, <code>ctrypto-sha1</code>, and <code>math-spectral-norm</code> get 6x-22x speedups.</p>
<p>Functions that use more complex operations, such as object manipulation, get a smaller speedup, usually 2-5x. This follows mathematically from Amdahl&#8217;s law and the fact that complex operations take longer. Looking back at the time diagram, consider a more complex operation that takes time 30T for the green part. The orange and brown parts will still be about 30T together, so eliminating them gives a 2x speedup. The SunSpider benchmark <code>string-fasta</code> is an example of this kind of program: most of the time is taken by string operations that have a relatively long time for the green box.</p>
<p>Here is a version of our example program you can try in the browser:</p>
<p><script type="text/javascript">
<!--
function addTo(a, n) {
  for (var i = 0; i < n; ++i)
    a = a + i;
  return a;
}
var dts = 0;
var dtn = 0;
function runExample() {
  var t0 = new Date;
  var n = addTo(0, 10000000);
  var dt = new Date-t0;
  dts += dt;
  dtn += 1;
  var avg = Math.round(dts/dtn);
  document.getElementById('example_result').innerHTML = n + '';
  document.getElementById('example_time').innerHTML = dt + ' ms';
  document.getElementById('example_avg').innerHTML = avg + ' ms';
}
//--></script></p>
<div style='border: 1px solid black; padding: 8px; margin: 12px'>
<button onclick='runExample()'>Run Example</button></p>
<p>Numerical result: <span id='example_result'> </span></p>
<p>Run time: <span id='example_time'> </span></p>
<p>Average run time: <span id='example_avg'> </span></p>
</div>
<p><strong>Understanding and fixing performance problems</strong></p>
<p>Our goal is to make TraceMonkey reliably fast enough that you can write your code in the way that best expresses your ideas, without worrying about performance. If TraceMonkey isn&#8217;t speeding up your program, we hope you&#8217;ll report it as a bug so we can improve the engine. That said, of course, you may need your program to run faster in today&#8217;s FF3.5. In this section, we&#8217;ll explain some tools and techniques for fixing performance of a program that doesn&#8217;t get a good (2x or more) speedup with the tracing JIT enabled. (You can disable the jit by going to <strong>about:config</strong> and setting the pref <strong>javascript.options.jit.content</strong> to <code>false</code>.)</p>
<p>The first step is understanding the cause of the problem. The most common cause is a <em>trace abort</em>, which simply means that TraceMonkey was unable to finish recording a trace, and gave up. The usual result is that the loop containing the abort will run in the interpreter, so you won&#8217;t get a speedup on that loop. Sometimes, one path through the loop is traced, but there is an abort on another path, which will cause TraceMonkey to switch back and forth between interpreting and running native code. This can leave you with a reduced speedup, no speedup, or even a slowdown: switching modes takes time, so rapid switching can lead to poor performance.</p>
<p>With a debug build of the browser or a JS shell (which I <a href="https://developer.mozilla.org/en/Build_Documentation">build</a> myself &#8211; we don&#8217;t publish these builds) you can tell TraceMonkey to print information about aborts by setting the <code>TMFLAGS</code> environment variable. I usually do it like this:</p>
<pre>
TMFLAGS=minimal,abort
dist/MinefieldDebug.app/Contents/MacOS/firefox
</pre>
<p>The <code>minimal</code> option prints out all the points where recording starts and where recording successfully finishes. This gives a basic idea of what the tracer is trying to do. The <code>abort</code> option prints out all the points where recording was aborted due to an unsupported construct. (Setting <code>TMFLAGS=help</code> will print the list of other <code>TMFLAGS</code> options and then exit.)</p>
<p>(Note also that <code>TMFLAGS</code> is the new way to print the debug information. If you are using a debug build of the FF3.5 release, the environment variable setting is <code>TRACEMONKEY=abort</code>.)</p>
<p>Here&#8217;s an example program that doesn&#8217;t get much of a speedup in TraceMonkey.</p>
<p><script type="text/javascript">
<!--
function runExample2() {
  var t0 = new Date;
  var sum = 0;
  for (var i = 0; i < 100000; ++i) {
    sum += i;
  }
  var prod = 1;
  for (var i = 1; i < 100000; ++i) {
    eval("prod *= i");
  }
  var dt = new Date - t0;
  document.getElementById('example2_time').innerHTML = dt + ' ms';
}
//--></script></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> runExample2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> t0 <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> sum <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">100000</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    sum <span style="color: #339933;">+=</span> i<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> prod <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">100000</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;prod *= i&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #003366; font-weight: bold;">var</span> dt <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date <span style="color: #339933;">-</span> t0<span style="color: #339933;">;</span>
  document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>example2_time<span style="color: #3366CC;">').innerHTML = dt + '</span> ms<span style="color: #3366CC;">';
}</span></pre></div></div>

<div style='border: 1px solid black; padding: 8px; margin: 12px'>
<button onclick='runExample2();' style='margin-right:32px'>Run Example 2</button><br />
Run time: <span id='example2_time'> </span>
</div>
<p>If we set <code>TMFLAGS=minimal,abort</code>, we&#8217;ll get this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Recording starting from ab.js:5@23
recording completed at  ab.js:5@23 via closeLoop
&nbsp;
Recording starting from ab.js:5@23
recording completed at  ab.js:5@23 via closeLoop
&nbsp;
Recording starting from ab.js:10@63
Abort recording of tree ab.js:10@63 at ab.js:11@70: eval.
&nbsp;
Recording starting from ab.js:10@63
Abort recording of tree ab.js:10@63 at ab.js:11@70: eval.
&nbsp;
Recording starting from ab.js:10@63
Abort recording of tree ab.js:10@63 at ab.js:11@70: eval.</pre></div></div>

<p>The first two pairs of lines show that the first loop, starting at line 5, traced fine. The following lines showed that TraceMonkey started tracing the loop on line 10, but failed each time because of an <code>eval</code>.</p>
<p>An important note about this debug output is that you will typically see some messages referring to <em>inner trees</em> growing, stabilizing, and so on. These really aren&#8217;t problems: they usually just indicate a <em>delay</em> in finishing tracing a loop because of the way TraceMonkey links inner and outer loops. And in fact, if you look further down the output after such aborts, you will usually see that the loops eventually do trace.</p>
<p>Otherwise, aborts are mainly caused by JavaScript constructs that are not yet supported by tracing. The trace recording process is easier to implement for a basic operation like <code>+</code> than it is for an advanced feature like <code>arguments</code>. We didn&#8217;t have time to do robust, secure tracing of every last JavaScript feature in time for the FF3.5 release, so some of the more advanced ones, like <code>arguments</code>, aren&#8217;t traced in FF3.5.0. Other advanced features that are not traced include getters and setters, with, and eval. There is partial support for closures, depending on exactly how they are used. Refactoring to avoid these constructs can help performance.</p>
<p>Two particularly important JavaScript features that are not traced are:</p>
<ul>
<li>Recursion. TraceMonkey doesn&#8217;t see repetition that occurs through recursion as a loop, so it doesn&#8217;t try to trace it. Refactoring to use explicit <code>for</code> or <code>while</code> loops will generally give better performance.
<li>Getting or setting a DOM property. (DOM method calls are fine.) Avoiding these constructs is generally impossible, but refactoring the code to move DOM property access out of hot loops and performance-critical segments should help.
</ul>
<p>We are actively working on tracing all the features named above. For example, support for tracing <code>arguments</code> is already available in nightly builds.</p>
<p>Here is the slow example program refactored to avoid <code>eval</code>. Of course, I could have simply done the multiplication inline. Instead, I used a function created by <code>eval</code> because that&#8217;s a more general way of refactoring an <code>eval</code>. Note that the <code>eval</code> still can&#8217;t be traced, but it only runs once so it doesn&#8217;t matter.</p>
<p><script type="text/javascript">
<!--
function runExample3() {
  var t0 = new Date;
  var sum = 0;
  for (var i = 0; i < 100000; ++i) {
    sum += i;
  }
  var prod = 1;
  var mul = eval("(function(i) { return prod * i; })");
  for (var i = 1; i < 100000; ++i) {
    prod = mul(i);
  }
  var dt = new Date - t0;
  document.getElementById('example3_time').innerHTML = dt + ' ms';
}
//--></script></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> runExample3<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> t0 <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> sum <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">100000</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    sum <span style="color: #339933;">+=</span> i<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> prod <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> mul <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;(function(i) { return prod * i; })&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">100000</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    prod <span style="color: #339933;">=</span> mul<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #003366; font-weight: bold;">var</span> dt <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date <span style="color: #339933;">-</span> t0<span style="color: #339933;">;</span>
  document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'example3_time'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> dt <span style="color: #339933;">+</span> <span style="color: #3366CC;">' ms'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<div style='border: 1px solid black; padding: 8px; margin: 12px'>
<button onclick='runExample3();' style='margin-right:32px'>Run Example 3</button><br />
Run time: <span id='example3_time'> </span>
</div>
<p>There are a few more esoteric situations that can also hurt tracing performance. One of them is <em>trace explosion</em>, which happens when a loop has many paths through it. Consider a loop with 10 <code>if</code> statements in a row: the loop has 1024 paths, potentially causing 1024 traces to be recorded. That would use up too much memory, so TraceMonkey caps each loop at 32 traces. If the loop has fewer than 32 hot traces, it will perform well. But if each path occurs with equal frequency, then only 3% of the paths are traced, and performance will suffer.</p>
<p>This kind of problem is best analyzed with <a href='https://developer.mozilla.org/en/TraceVis'<strong>TraceVis</strong></a>, which creates visualizations of TraceMonkey performance. Currently, the build system only supports enabling TraceVis for shell builds, but the basic system can also run in the browser, and there is <a href='https://bugzilla.mozilla.org/show_bug.cgi?id=497999'>ongoing work</a> to enable TraceVis in a convenient form in the browser.</p>
<p>The <a href='http://blog.mozilla.com/dmandelin/2009/02/26/tracevis-performance-visualization-for-tracemonkey/'>blog post</a> on TraceVis is currently the most detailed explanation of what the diagrams mean and how to use them to diagnose performance problems. The post also contains a detailed analysis of a diagram that is helpful in understanding how TraceMonkey works in general.</p>
<p><strong>Comparative JITerature</strong></p>
<p>Here I will give a few comparisons to other JavaScript JIT designs. I&#8217;ll focus more on hypothetical designs than competing engines, because I don&#8217;t know details about them &mdash; I&#8217;ve read the release information and skimmed a few bits of code. Another big caveat is that real-world performance depends at least as much on engineering details as it does on engine architecture.</p>
<p>One design option could be a called a <em>per-method non-specializing JIT</em>. By this, I mean a JIT compiler that compiles a method at a time and generates generic code, just like what the interpreter does. Thus, the brown boxes from our diagrams are cut out. This kind of JIT doesn&#8217;t need to take time to record and compile traces, but it also does not type-specialize, so the orange boxes remain. Such an engine can still be made pretty fast by carefully designing and optimizing the orange box code. But the orange box can&#8217;t be completely eliminated in this design, so the maximum performance on numeric programs won&#8217;t be as good as a type-specializing engine.</p>
<p>As far as I can tell, as of this writing Nitro and V8 are both lightweight non-specializing JITs. (I&#8217;m told that V8 does try to guess a few types by looking at the source code (such as guessing that <code>a</code> is an integer in <code>a >> 2</code>) in order to do a bit of type specialization.) It seem that TraceMonkey is generally faster on numeric benchmarks, as predicted above. But TraceMonkey suffers a bit on benchmarks that use more objects, because our object operations and memory management haven&#8217;t been optimized as heavily.</p>
<p>A further development of the basic JIT is the <em>per-method type-specializing JIT</em>. This kind of a JIT tries to type-specialize a method based on the argument types the method is called with. Like TraceMonkey, this requires some runtime observation: the basic design checks the argument types each time a method is called, and if those types have not been seen before, compiles a new version of the method. Also like TraceMonkey, this design can heavily specialize code and remove both the brown and orange boxes.</p>
<p>I&#8217;m not aware that anyone has deployed a per-method type-specializing JIT for JavaScript, but I wouldn&#8217;t be surprised if people are working on it.</p>
<p>The main disadvantage of a per-method type-specializing JIT compared to a tracing JIT is that the basic per-method JIT only directly observes the input types to a method. It must try to infer types for variables inside the method algorithmically, which is difficult for JavaScript, especially if the method reads object properties. Thus, I would expect that a per-method type-specializing JIT would have to use generic operations for some parts of the method. The main advantage of the per-method design is that the method needs to be compiled exactly once per set of input types, so it&#8217;s not vulnerable to trace explosion. In turn, I think a per-method JIT would tend to be faster on methods that have many paths, and a tracing JIT would tend to be faster on highly type-specializable methods, especially if the method also reads a lot of values from properties.</p>
<p><strong>Conclusion</strong></p>
<p>By now, hopefully you have a good idea of what makes JavaScript engines fast, how TraceMonkey works, and how to analyze and fix some performance issues that may occur running JavaScript under TraceMonkey. Please report bugs if you run into any significant performance problems. Bug reports are also a good place for us to give additional tuning advice. Finally, we&#8217;re trying to improve constantly, so check out nightly TraceMonkey builds if you&#8217;re into the bleeding edge.</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/07/tracemonkey-overview/feed/</wfw:commentRss>
		<slash:comments>67</slash:comments>
		</item>
		<item>
		<title>HTML5 drag and drop in Firefox 3.5</title>
		<link>http://hacks.mozilla.org/2009/07/html5-drag-and-drop/</link>
		<comments>http://hacks.mozilla.org/2009/07/html5-drag-and-drop/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 01:57:32 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1420</guid>
		<description><![CDATA[This post is from Les Orchard, who works on Mozilla’s web development team. Introduction Drag and drop is one of the most fundamental interactions afforded by graphical user interfaces. In one gesture, it allows users to pair the selection of an object with the execution of an action, often including a second object in the [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post is from <a href="http://decafbad.com/blog/lifestream">Les Orchard</a>, who works on Mozilla’s web development team.</em></p>
<p><b>Introduction</b></p>
<p>Drag and drop is one of the most fundamental interactions afforded by graphical user interfaces.  In one gesture, it allows users to pair the selection of an object with the execution of an action, often including a second object in the operation.  It&#8217;s a simple yet powerful UI concept used to support copying, list reordering, deletion (ala the Trash / Recycle Bin), and even the creation of link relationships.</p>
<p>Since it&#8217;s so fundamental, offering drag and drop in web applications has been a no-brainer ever since browsers first offered mouse events in DHTML.  But, although <code>mousedown</code>, <code>mousemove</code>, and <code>mouseup</code> made it possible, the implementation has been limited to the bounds of the browser window.  Additionally, since these events refer only to the object being dragged, there&#8217;s a challenge to find the subject of the drop when the interaction is completed.</p>
<p>Of course, that doesn&#8217;t prevent most modern JavaScript frameworks from abstracting away most of the problems and throwing in some flourishes while they&#8217;re at it.  But, wouldn&#8217;t it be nice if browsers offered first-class support for drag and drop, and maybe even extended it beyond the window sandbox?
</p>
<p>
As it turns out, this very wish is answered by the HTML 5 specification <a target="_new" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#dnd">section on new drag-and-drop events</a>, and  <a target="_new" href="https://developer.mozilla.org/En/DragDrop/Drag_and_Drop">Firefox 3.5 includes an implementation</a> of those events.</p>
<p>If you want to jump straight to the code, I&#8217;ve put together <a target="_new" target="_new" target="_new" href="http://decafbad.com/2009/07/drag-and-drop/api-demos.html">some simple demos</a> of the new events.  </p>
<p>I&#8217;ve even scratched an itch of my own and built <a target="_new" target="_new" target="_new" href="http://decafbad.com/2009/07/drag-and-drop/outline.html">the beginnings of an outline editor</a>, where every draggable element is also a drop target—of which there could be dozens to hundreds in a complex document, something that gave me some minor hair-tearing moments in the past while trying to make do with plain old mouse events.</p>
<p>And, all the above can be downloaded or cloned from <a href="http://github.com/lmorchard/fx35-drag-and-drop">a GitHub repository</a> I&#8217;ve created expecially for this article.</p>
<p><b>The New Drag and Drop Events</b></p>
<p>So, with no further ado, here are the new drag and drop events, in roughly the order you might expect to see them fired:</p>
<dl>
<dt><code>dragstart</code></dt>
<dd>
A drag has been initiated, with the dragged element as the event target.
</dd>
<dt><code>drag</code></dt>
<dd>
The mouse has moved, with the dragged element as the event target.
</dd>
<dt><code>dragenter</code></dt>
<dd>
The dragged element has been moved into a drop listener, with the drop listener element as the event target.
</dd>
<dt><code>dragover</code></dt>
<dd>
The dragged element has been moved over a drop listener, with the drop listener element as the event target.  Since the default behavior is to cancel drops, returning <code>false</code> or calling <code>preventDefault()</code> in the event handler indicates that a drop is allowed here.
</dd>
<dt><code>dragleave</code></dt>
<dd>
The dragged element has been moved out of a drop listener, with the drop listener element as the event target.
</dd>
<dt><code>drop</code></dt>
<dd>
The dragged element has been successfully dropped on a drop listener, with the drop listener element as the event target.
</dd>
<dt><code>dragend</code></dt>
<dd>
A drag has been ended, successfully or not, with the dragged element as the event target.
</dd>
</dl>
<p>Like the mouse events of yore, listeners can be attached to elements using <code>addEventListener()</code> directly or by way of your favorite JS library.  </p>
<p>Consider the following example using jQuery, <a target="_new" target="_new" target="_new" href="http://decafbad.com/2009/07/drag-and-drop/api-demos.html#newschool">also available as a live demo</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    &lt;div id=&quot;newschool&quot;&gt;
        &lt;div class=&quot;dragme&quot;&gt;Drag me!&lt;/div&gt;
        &lt;div class=&quot;drophere&quot;&gt;Drop here!&lt;/div&gt;
    &lt;/div&gt;
&nbsp;
    <span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
        $<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#newschool .dragme'</span><span style="color: #009900;">&#41;</span>
                .<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'draggable'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'true'</span><span style="color: #009900;">&#41;</span>
                .<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'dragstart'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ev<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #003366; font-weight: bold;">var</span> dt <span style="color: #339933;">=</span> ev.<span style="color: #660066;">originalEvent</span>.<span style="color: #660066;">dataTransfer</span><span style="color: #339933;">;</span>
                    dt.<span style="color: #660066;">setData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Text&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;Dropped in zone!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
                .<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'dragend'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ev<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#newschool .drophere'</span><span style="color: #009900;">&#41;</span>
                .<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'dragenter'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ev<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    $<span style="color: #009900;">&#40;</span>ev.<span style="color: #660066;">target</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">addClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'dragover'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
                .<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'dragleave'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ev<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    $<span style="color: #009900;">&#40;</span>ev.<span style="color: #660066;">target</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">removeClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'dragover'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
                .<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'dragover'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ev<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
                .<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'drop'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ev<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #003366; font-weight: bold;">var</span> dt <span style="color: #339933;">=</span> ev.<span style="color: #660066;">originalEvent</span>.<span style="color: #660066;">dataTransfer</span><span style="color: #339933;">;</span>
                    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>dt.<span style="color: #660066;">getData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Text'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>Thanks to the new events and jQuery, this example is both short and simple—but it packs in a lot of functionality, as the rest of this article will explain.  </p>
<p>Before moving on, there are at least three things about the above code that are worth mentioning:</p>
<ul>
<li>
Drop targets are enabled by virtue of having listeners for drop events.  But, <a target="_new" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#drag-and-drop-processing-model">per the HTML 5 spec</a>, draggable elements need an attribute of <code>draggable="true"</code>, set either in markup or in JavaScript.  </p>
<p>Thus, <code>$('#newschool&nbsp;.dragme').attr('draggable', 'true')</code>.
</li>
<li>
The original DOM event (as opposed to jQuery&#8217;s event wrapper) offers a property called <code>dataTransfer</code>. Beyond just manipulating elements, the new drag and drop events accomodate the transmission of user-definable data during the course of the interaction.
</li>
<li>
Since these are first-class events, you can apply <a target="_new" href="http://icant.co.uk/sandbox/eventdelegation/">the technique of Event Delegation</a>.</p>
<p>What&#8217;s that?  Well, imagine you have a list of 1000 list items—as part of a deeply-nested outline document, for instance.  Rather than needing to attach listeners or otherwise fiddle with all 1000 items, simply attach a listener to the parent node (eg. the <code>&lt;ul&gt;</code> element) and all events from the children will propagate up to the single parent listener. As a bonus, all new child elements added after page load will enjoy the same benefits.</p>
<p><a target="_new" target="_new" target="_new" href="http://decafbad.com/2009/07/drag-and-drop/api-demos.html#delegated">Check out this demo</a>, and <a target="_new" target="_new" href="http://decafbad.com/2009/07/drag-and-drop/js/drag-delegated.js">the associated JS code</a> to see more about these events and Event Delegation.
</li>
</ul>
<p><b>Using dataTransfer</b></p>
<p>As mentioned in the last section, the new drag and drop events let you send data along with a dragged element.  But, it&#8217;s even better than that:  Your drop targets can receive data transferred by content objects dragged into the window from other browser windows, and even <i>other applications</i>.</p>
<p>Since the example is a bit longer,  <a target="_new" target="_new" href="http://decafbad.com/2009/07/drag-and-drop/api-demos.html#data_transfer">check out the live demo</a> and <a target="_new" href="http://decafbad.com/2009/07/drag-and-drop/js/drag-datatransfer.js">associated code</a> to get an idea of what&#8217;s possible with <code>dataTransfer</code>.</p>
<p>In a nutshell, the stars of this show are the <code>setData()</code> and <code>getData()</code> methods of the <code>dataTransfer</code> property exposed by the Event object.</p>
<p>The <code>setData()</code> method is typically called in the <code>dragstart</code> listener, loading <code>dataTransfer</code> up with one or more strings of content with associated <a href="https://developer.mozilla.org/En/DragDrop/Recommended_Drag_Types#link">recommended content types</a>.</p>
<p>For illustration, here&#8217;s a quick snippet from the example code:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> dt <span style="color: #339933;">=</span> ev.<span style="color: #660066;">originalEvent</span>.<span style="color: #660066;">dataTransfer</span><span style="color: #339933;">;</span>    
    dt.<span style="color: #660066;">setData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'text/plain'</span><span style="color: #339933;">,</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#logo'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">parent</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    dt.<span style="color: #660066;">setData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'text/html'</span><span style="color: #339933;">,</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#logo'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">parent</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    dt.<span style="color: #660066;">setData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'text/uri-list'</span><span style="color: #339933;">,</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#logo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">src</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>On the other end, <code>getData()</code> allows you to query for content by type (eg. <code>text/html</code> followed by <code>text/plain</code>).  This, in turn, allows you to decide on acceptable content types at the time of the <code>drop</code> event or even during <code>dragover</code> to offer feedback for unacceptable types during the drag.</p>
<p>Here&#8217;s another example from the receiving end of the example code:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> dt <span style="color: #339933;">=</span> ev.<span style="color: #660066;">originalEvent</span>.<span style="color: #660066;">dataTransfer</span><span style="color: #339933;">;</span>    
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.content_url .content'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span>dt.<span style="color: #660066;">getData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'text/uri-list'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.content_text .content'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span>dt.<span style="color: #660066;">getData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'text/plain'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.content_html .content'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span>dt.<span style="color: #660066;">getData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'text/html'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Where <code>dataTransfer</code> really shines, though, is that it allows your drop targets to receive content from sources outside your defined draggable elements and even from outside the browser altogether.  Firefox accepts such drags, and attempts to populate <code>dataTransfer</code> with appropriate content types extracted from the external object.</p>
<p>Thus, you could select some text in a word processor window and drop it into one of your elements, and at least expect to find it available as <code>text/plain</code> content.  </p>
<p>You can also select content in another browser window, and expect to see <code>text/html</code> appear in your events.  Check out the <a target="_new" href="http://decafbad.com/2009/07/drag-and-drop/outline.html">outline editing demo</a> and see what happens when you try dragging various elements (eg. images, tables, and lists) and highlighted content from other windows onto the items there.</p>
<p><b>Using Drag Feedback Images</b></p>
<p>An important aspect of the drag and drop interaction is a representation of the thing being dragged.  By default in Firefox, this is a &#8220;ghost&#8221; image of the dragged element itself.  But, the <code>dataTransfer</code> property of the original Event object exposes the method <code>setDragImage()</code> for use in customizing this representation.</p>
<p>There&#8217;s <a target="_new" href="http://decafbad.com/2009/07/drag-and-drop/api-demos.html#feedback_image">a live demo</a> of this feature, as well as <a target="_new" href="http://decafbad.com/2009/07/drag-and-drop/js/drag-feedback-images.js">associated JS code</a> available.  The gist, however, is sketched out in these code snippets:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> dt <span style="color: #339933;">=</span> ev.<span style="color: #660066;">originalEvent</span>.<span style="color: #660066;">dataTransfer</span><span style="color: #339933;">;</span>    
&nbsp;
    dt.<span style="color: #660066;">setDragImage</span><span style="color: #009900;">&#40;</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#feedback_image h2'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    dt.<span style="color: #660066;">setDragImage</span><span style="color: #009900;">&#40;</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#logo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">32</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">32</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> canvas <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;canvas&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    canvas.<span style="color: #660066;">width</span> <span style="color: #339933;">=</span> canvas.<span style="color: #660066;">height</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">50</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> ctx <span style="color: #339933;">=</span> canvas.<span style="color: #660066;">getContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;2d&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    ctx.<span style="color: #660066;">lineWidth</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">;</span>
    ctx.<span style="color: #660066;">moveTo</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">25</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    ctx.<span style="color: #660066;">lineTo</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">50</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    ctx.<span style="color: #660066;">lineTo</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    ctx.<span style="color: #660066;">lineTo</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">25</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    ctx.<span style="color: #660066;">stroke</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    dt.<span style="color: #660066;">setDragImage</span><span style="color: #009900;">&#40;</span>canvas<span style="color: #339933;">,</span> <span style="color: #CC0000;">25</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">25</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>You can supply a DOM node as the first parameter to <code>setDragImage()</code>, which includes everything from text to images to <code>&lt;canvas&gt;</code> elements.  The second two parameters indicate at what left and top offset the mouse should appear in the image while dragging.</p>
<p>For example, since the <code>#logo</code> image is 64&#215;64, the parameters in the second <code>setDragImage()</code> method places the mouse right in the center of the image. On the other hand, the first call positions the feedback image such that the mouse rests in the upper left corner.</p>
<p><b>Using Drop Effects</b></p>
<p>As mentioned at the start of this article, the drag and drop interaction has been used to support actions such as copying, moving, and linking.  Accordingly, the HTML 5 specification accomodates these operations in the form of the <code>effectAllowed</code> and <code>dropEffect</code> properties exposed by the Event object.</p>
<p>For a quick fix, check out the <a target="_new" href="http://decafbad.com/2009/07/drag-and-drop/api-demos.html#drag_effects">a live demo</a> of this feature, as well as the <a target="_new" href="http://decafbad.com/2009/07/drag-and-drop/js/drag-effects.js">associated JS code</a>.</p>
<p>The basic idea is that the <code>dragstart</code> event listener can set a value for <code>effectAllowed</code> like so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> dt <span style="color: #339933;">=</span> ev.<span style="color: #660066;">originalEvent</span>.<span style="color: #660066;">dataTransfer</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">switch</span> <span style="color: #009900;">&#40;</span>ev.<span style="color: #660066;">target</span>.<span style="color: #660066;">id</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'effectdrag0'</span><span style="color: #339933;">:</span> dt.<span style="color: #660066;">effectAllowed</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'copy'</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'effectdrag1'</span><span style="color: #339933;">:</span> dt.<span style="color: #660066;">effectAllowed</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'move'</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'effectdrag2'</span><span style="color: #339933;">:</span> dt.<span style="color: #660066;">effectAllowed</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'link'</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'effectdrag3'</span><span style="color: #339933;">:</span> dt.<span style="color: #660066;">effectAllowed</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'all'</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'effectdrag4'</span><span style="color: #339933;">:</span> dt.<span style="color: #660066;">effectAllowed</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'none'</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>The choices available for this property include the following:</p>
<dl>
<dt><code>none</code></dt>
<dd>no operation is permitted </dd>
<dt><code>copy</code></dt>
<dd>copy only </dd>
<dt><code>move</code></dt>
<dd>move only </dd>
<dt><code>link</code></dt>
<dd>link only </dd>
<dt><code>copyMove</code></dt>
<dd>copy or move only </dd>
<dt><code>copyLink</code></dt>
<dd>copy or link only </dd>
<dt><code>linkMove</code></dt>
<dd>link or move only </dd>
<dt><code>all</code></dt>
<dd>copy, move, or link </dd>
</dl>
<p>On the other end, the <code>dragover</code> event listener can set the value of the <code>dropEffect</code> property to indicate the expected effect invoked on a successful drop.  If the value does not match up with <code>effectAllowed</code>, the drop will be considered cancelled on completion.</p>
<p>In the <a target="_new" href="http://decafbad.com/2009/07/drag-and-drop/api-demos.html#drag_effects">a live demo</a>, you should be able to see that only elements with matching effects can be dropped into the appropriate drop zones.  This is accomplished with code like the follwoing:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> dt <span style="color: #339933;">=</span> ev.<span style="color: #660066;">originalEvent</span>.<span style="color: #660066;">dataTransfer</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">switch</span> <span style="color: #009900;">&#40;</span>ev.<span style="color: #660066;">target</span>.<span style="color: #660066;">id</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'effectdrop0'</span><span style="color: #339933;">:</span> dt.<span style="color: #660066;">dropEffect</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'copy'</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'effectdrop1'</span><span style="color: #339933;">:</span> dt.<span style="color: #660066;">dropEffect</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'move'</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'effectdrop2'</span><span style="color: #339933;">:</span> dt.<span style="color: #660066;">dropEffect</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'link'</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'effectdrop3'</span><span style="color: #339933;">:</span> dt.<span style="color: #660066;">dropEffect</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'all'</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'effectdrop4'</span><span style="color: #339933;">:</span> dt.<span style="color: #660066;">dropEffect</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'none'</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Although the OS itself can provide some feedback, you can also use these properties to update your own visible feedback, both on the dragged element and on the drop zone itself.</p>
<p><b>Conclusion</b></p>
<p>The new first-class drag and drop events in HTML5 and Firefox make supporting this form of UI interaction simple, concise, and powerful in the browser.  But beyond the new simplicity of these events, the ability to transfer content between applications opens brand new avenues for web-based applications and collaboration with desktop software in general.</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/07/html5-drag-and-drop/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>elliptical borders in Firefox 3.5</title>
		<link>http://hacks.mozilla.org/2009/07/elliptical-border-radius/</link>
		<comments>http://hacks.mozilla.org/2009/07/elliptical-border-radius/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 15:14:44 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Firefox 3.5]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1396</guid>
		<description><![CDATA[Today&#8217;s demo comes from Lim Chee Aun, the creator of the Phoenity icons and themes, and web developer in Malaysia. The border-radius property is probably one of the most interesting parts of the CSS3 specification, where it allows you to create rounded corners on elements. For example: div &#123; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; [...]]]></description>
			<content:encoded><![CDATA[<p><em>Today&#8217;s demo comes from <a href="http://cheeaun.com/">Lim Chee Aun</a>, the creator of the <a href="http://phoenity.com/">Phoenity</a> icons and themes, and web developer in Malaysia.</em></p>
<p>The <code>border-radius </code>property is probably one of the most interesting parts of the <a href="http://www.w3.org/TR/css3-background/#the-border-radius">CSS3 specification</a>, where it allows you to create rounded corners on elements.  For example:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">div <span style="color: #00AA00;">&#123;</span>
  border-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span>
  -moz-border-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span>
  -webkit-border-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>In Firefox 3.5, <code>-moz-border-radius</code> has been updated to match the latest revision to the CSS3 specification. Thus now, we can create <strong>elliptical borders</strong>.</p>
<p>So, what does that mean? According to the specification, the syntax is:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">-moz-border-radius<span style="color: #00AA00;">:</span> &lt;border-radius<span style="color: #00AA00;">&gt;</span><span style="color: #00AA00;">&#123;</span><span style="color: #cc66cc;">1</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">4</span><span style="color: #00AA00;">&#125;</span> <span style="color: #00AA00;">&#91;</span> / &lt;border-radius<span style="color: #00AA00;">&gt;</span><span style="color: #00AA00;">&#123;</span><span style="color: #cc66cc;">1</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">4</span><span style="color: #00AA00;">&#125;</span><span style="color: #00AA00;">&#93;</span>?</pre></div></div>

<p>It shows the set of values accepted for this property, plus an optional slash with another set of values. This is where the magic comes from. If two sets of values are given, values before the slash set the horizontal radius and values after it set the vertical radius.</p>
<p>This opens a few interesting possibilities. This demo shows some experiments on certain types of shapes that you can play with.</p>
<div align="center" style="font-size: 120%"><a target="_blank" href="http://cheeaun.com/experiments/border-radius-fun/">View the Demo in Firefox 3.5<br/><img src="http://cheeaun.com/experiments/border-radius-fun/border-radius-fun.png"></a></div>
<p>In the demo, it&#8217;s not only possible to modify the border width, style and radius, but also the <strong>style</strong> as well, such as <code>ridge</code>, <code>double</code> and <code>groove</code>. As of now, <code>dotted</code> and <code>dashed</code> doesn&#8217;t work yet and being rendered as solid. For more information, see <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=431176">Mozilla bug 431176 </a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/07/elliptical-border-radius/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>css3 columns on the web</title>
		<link>http://hacks.mozilla.org/2009/07/css3-columns/</link>
		<comments>http://hacks.mozilla.org/2009/07/css3-columns/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 21:05:57 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[Standards]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1378</guid>
		<description><![CDATA[Today&#8217;s Demo covers the use of CSS3 Columns and was written by Karl Dubost. Karl is a self-proclaimed hedonist, dreamer and always exploring the Open Web for creative spaces. Read About CSS3 Columns and View the Demo in Firefox 3.5]]></description>
			<content:encoded><![CDATA[<p><em>Today&#8217;s Demo covers the use of <a href="https://developer.mozilla.org/en/CSS3_Columns">CSS3 Columns</a> and was written by <a href="http://www.la-grange.net/karl/">Karl Dubost</a>.  Karl is a self-proclaimed hedonist, dreamer and always exploring the Open Web for creative spaces.</em></p>
<div style="font-size: 120%"><a href="http://www.la-grange.net/2009/06/13/column" target="_blank">Read About CSS3 Columns and View the Demo in Firefox 3.5<br />
<img src="http://hacks.mozilla.org/wp-content/uploads/2009/07/css3-columns.png" alt="" /></a></div>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/07/css3-columns/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>video &#8211; more than just a tag</title>
		<link>http://hacks.mozilla.org/2009/07/video-more-than-just-a-tag/</link>
		<comments>http://hacks.mozilla.org/2009/07/video-more-than-just-a-tag/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 03:04:54 +0000</pubDate>
		<dc:creator>Arun Ranganathan</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[Standards]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1313</guid>
		<description><![CDATA[This article is written by Paul Rouget, Mozilla contributor and purveyor of extraordinary Open Web demos. Starting with Firefox 3.5, you can embed a video in a web page like an image. This means video is now a part of the document, and finally, a first class citizen of the Open Web. Like all other [...]]]></description>
			<content:encoded><![CDATA[<p><em>This article is written by <a href="http://blog.mozbox.org/">Paul Rouget</a>, Mozilla contributor and purveyor of <a href="http://people.mozilla.com/~prouget/demos/">extraordinary Open Web demos</a>.</em></p>
<p>Starting with Firefox 3.5, you can embed a video in a web page like an image. This means video is now <em>a part</em> of the document, and finally, a first class citizen of the Open Web. Like all other elements, you can use it with CSS and JavaScript. Let&#8217;s see what this all means &#8230; </p>
<p><strong>The Basics</strong></p>
<p>First, you need a video to play. Firefox supports the Theora codec (<a href="https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements">see here to know all media formats supported by the audio and video elements</a>).</p>
<p>Add the video to your document:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;video <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myVideo&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myFile.ogv&quot;</span><span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>You might need to add some &#8220;fallback&#8221; code if the browser doesn&#8217;t support the video tag.  Just include some HTML (which could be a warning, or even some Flash) inside the video tag.</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;video <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myVideo&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myFile.ogv&quot;</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">strong</span>&gt;</span>Your browser is not awesome enough!<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">strong</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span>video&gt;</span></pre></div></div>

<p>Here&#8217;s some more information <a href="http://hacks.mozilla.org/2009/06/html5-video-fallbacks-markup/">about the fallback mechanism</a>.</p>
<p><strong>HTML Attributes</strong></p>
<p>You can find <a href="https://developer.mozilla.org/En/HTML/Element/Video">all the available attributes here</a>. </p>
<p>Some important attributes:</p>
<ul>
<li>autoplay: The video will be played just after the page loads.</li>
<li>autobuffer: By default (without this attribute), the video file is not downloaded unless you click on the play button. Adding this attribute starts downloading the video just after the page loads.</li>
<li>controls: by default (without this attribute), the video doesn&#8217;t include any controls (play/pause button, volume, etc.). Use this attribute if you want the default controls.</li>
<li>height/width: The size of the video</li>
</ul>
<p>Example:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;video <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myVideo&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myFile.ogv&quot;</span> </span>
<span style="color: #009900;">   autobuffer<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;true&quot;</span> controls<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>You don&#8217;t have to add the &#8220;true&#8221; value to some of these attributes in HTML5, but it&#8217;s neater to do so. If you&#8217;re not in an XML document, you can simply write:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;video <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myVideo&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myFile.ogv&quot;</span> autobuffer controls<span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p><strong>JavaScript API</strong></p>
<p>Like any other HTML element, you have access to the video element via the Document Object Model (DOM):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> myVideo <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;myVideo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Once you obtain a handle to the video element, you can use the JavaScript API for video.</p>
<p>Here is a short list of some useful methods and properties (and see here <a href="https://developer.mozilla.org/en/nsIDOMHTMLMediaElement">for more of the DOM API</a> for audio and video elements):</p>
<ul>
<li>play() / pause(): Play and pause your video.</li>
<li>currentTime: The current playback time, in seconds. You can change this to seek.</li>
<li>duration: The duration of the video.</li>
<li>muted: Is the sound muted?</li>
<li>ended: Has the video ended?</li>
<li>paused: Is the video paused?</li>
<li>volume: To determine the volume, and to change it.</li>
</ul>
<p>Example:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">onclick</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myVideo.play()&quot;</span>&gt;</span>Play<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">onclick</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myVideo.volume = 0.5&quot;</span>&gt;</span>Set Volume<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">onclick</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;alert(myVideo.volume)&quot;</span>&gt;</span>Volume?<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span></pre></div></div>

<p><strong>Events</strong></p>
<p>You know how to control a video (play/pause, seek, change the volume, etc.). You have almost everything you need to create your own controls. But you need some feedback from the video, and for that, let&#8217;s see the different events you can listen to:</p>
<ul>
<li>canplay: The video is ready to play</li>
<li>canplaythrough: The video is ready to play without interruption (if the download rate doesn&#8217;t change)</li>
<li>load: The video is ready to play without interruption (the video has been downloaded entirely)</li>
<li>ended: The video just ended</li>
<li>play: The video just started playing</li>
<li>pause: The video has been paused</li>
<li>seeking: The video is seeking (it can take some seconds)</li>
<li>seeked: The seeking process just finished</li>
<li>timeupdate: While the video is playing, the currentTime is updated. Every time the currentTime is updated, timeupdate is fired. </li>
</ul>
<p>Here&#8217;s <a href="https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox">a full list of events</a>.</p>
<p>For example, you can follow the percentage of the video that has just been played:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> video <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;myVideo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> textbox <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;sometext&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  video.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;timeupdate&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  textbox.<span style="color: #660066;">value</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">100</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span>video.<span style="color: #660066;">currentTime</span> <span style="color: #339933;">/</span> video.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;%&quot;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;video <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myVideo&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myFile.ogv&quot;</span> </span>
<span style="color: #009900;">            autoplay<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;true&quot;</span> onplay<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;init()&quot;</span><span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;sometext&quot;</span><span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>Showing all this in action, <a href="http://www.tapper-ware.net/devel/js/JS.TinyVidPlayer/index.xhtml">here&#8217;s a nice open video player using the Video API</a>.</p>
<p>Now that you&#8217;re familiar with some of the broad concepts behind the Video API, let&#8217;s really delve into the video as a part of the Open Web, introducing video to CSS, SVG, and Canvas.</p>
<p><strong>CSS and SVG</strong></p>
<p>A video element is an HTML element. That means you can use CSS to style it.</p>
<p>A simple example: using the CSS Image Border rule (a new CSS 3 feature introduced in Firefox 3.5). <a href="https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas">You can view how it works on the Mozilla Developer Wiki</a>.</p>
<p>And obviously, you can use it with the video tag:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;">&nbsp;
<span style="color: #009900;">&lt;video <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myVideo&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myFile.ogv&quot;</span> </span>
<span style="color: #009900;"><span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;-moz-border-image: </span>
<span style="color: #009900;">           url(tv-border.jpg) 25 31 37 31 stretch stretch; </span>
<span style="color: #009900;">           border-width: 20px;&quot;</span><span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>One of my demos <a href="http://people.mozilla.com/~prouget/demos/srt/index.xhtml">uses this very trick</a>.</p>
<p>Since Firefox 3.5 provides some new snazzy new CSS features, you can do some really fantastic things. Take a look at the <a href="http://hacks.mozilla.org/2009/06/tristan-washing-machine/">infamous washing machine demo</a>, in which I subject an esteemed colleague to some rotation.  </p>
<p>It uses some CSS rules:</p>
<ul>
<li><a href="https://developer.mozilla.org/En/Applying_SVG_effects_to_HTML_content">filter, clip-path.</a></li>
<li><a href="https://developer.mozilla.org/En/CSS/Using_CSS_transforms">css transform.</a></li>
</ul>
<p>And some SVG:</p>
<ul>
<li><a href="http://www.w3.org/TR/SVG11/extend.html#ForeignObjectElement">SVG &#038; foreignobject.</a></li>
</ul>
<p>Because the video element is like any other HTML element, you can add some HTML content over the video itself, <a href="http://people.mozilla.com/~prouget/demos/srt/index2.xhtml">like I do in this demo</a>. As you can see, there is a <code>&lt;div></code> element on top of the video (<code>position: absolute;</code>).</p>
<p><strong>Time for a Break</strong></p>
<p>Well, we&#8217;ve just seen how far we can go with the video element, both how to control it and how to style it. That&#8217;s great, and it&#8217;s powerful. I strongly encourage you to read about <a href="https://developer.mozilla.org/en/Firefox_3.5_for_developers">the new web features available in Firefox 3.5</a>, and to think about what you can do with such features and the video element.</p>
<p>You can do <em>so much</em> with the power of the Open Web. You can compute the pixels of the video. You can, for example, try to find some shapes in the video, follow the shapes, and draw something as an attachment to these shapes. That&#8217;s <a href="http://people.mozilla.com/~prouget/demos/DynamicContentInjection/play.xhtml">what I do here!</a> Let&#8217;s see how it actually works.</p>
<p><strong>Canvas &#038; Video</strong></p>
<p>Another HTML 5 element is <code>canvas</code>. With this element, you can draw bitmap data (see the <a href="https://developer.mozilla.org/En/HTML/Canvas"><code>canvas</code> reference</a>, and I strongly suggest t<a href="http://blog.nihilogic.dk/2009/02/html5-canvas-cheat-sheet.html">his canvas overview</a>). But something you might not know is that you can copy the content of an <code>&lt;img/></code> element, a <code>&lt;canvas/></code> element and a <code>&lt;video/></code> element.</p>
<p>That&#8217;s a really important point for the <code>video</code> element. It gives you a way to play with the values of the pixels of the video frames.</p>
<p>You can do a &#8220;screenshot&#8221; of the current frame of the video in a canvas.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> screenshot<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #003366; font-weight: bold;">var</span> video <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;myVideo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #003366; font-weight: bold;">var</span> canvas <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;myCanvas&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #003366; font-weight: bold;">var</span> ctx <span style="color: #339933;">=</span> canvas.<span style="color: #660066;">getContext</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;2d&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
 ctx.<span style="color: #660066;">drawImage</span><span style="color: #009900;">&#40;</span>video<span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> canvas.<span style="color: #660066;">width</span><span style="color: #339933;">,</span> canvas.<span style="color: #660066;">height</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;video <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myVideo&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myFile.ogv&quot;</span> autoplay<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;true&quot;</span> with<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;600&quot;</span> <span style="color: #000066;">height</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;400&quot;</span><span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;canvas <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;myCanvas&quot;</span> with<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;600&quot;</span> <span style="color: #000066;">height</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;400&quot;</span><span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">onclick</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;screenshot()&quot;</span>&gt;</span>Copy current frame to canvas<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span></pre></div></div>

<p>You can first apply a transformation to your canvas (<a href="https://developer.mozilla.org/en/Canvas_tutorial/Transformations">see the documentation</a>). You can also <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage">copy a thumbnail of the video</a>.</p>
<p>If you draw every frame in a canvas, your canvas will look like a video element. And you can draw what you want in this canvas, after drawing the frame. That&#8217;s <a href="http://people.mozilla.com/~prouget/demos/DynamicContentInjection/play.xhtml">what I do in this demo</a>.</p>
<p>Once you have a video frame in your canvas, <a href="https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas">you can compute the values of the pixels</a>.</p>
<p>Some things you should know if you want to compute the pixels values of a frame:</p>
<ul>
<li>you can&#8217;t use this mechanism with a video from another domain.</li>
<li>you can&#8217;t use this mechanism with a video from a file:/// URL (which would be useful during the development of your web application). But you can change this behavior for testing: in about:config, change the value of &#8220;security.fileuri.strict_origin_policy&#8221; to &#8220;false&#8221;.  But <em>be very careful!</em> editing about:config &#8212; that&#8217;s an expert feature!</li>
<li>There are two ways to display the result of your application on the top of the video:
<ul>
<li>use your canvas as a video (if you draw the frame every time), and then draw directly into the canvas</li>
<li>use a transparent canvas on the top of the video</li>
</ul>
</li>
<li>the canvas element can be &#8220;display: none&#8221;</li>
<li> the video element can be &#8220;display: none&#8221; </li>
</ul>
<p><strong>About JavaScript</strong></p>
<p>For the image processing, you will need to do a lot of computation.  Here are some tricks:</p>
<ul>
<li>copy your frame in a small canvas. If the canvas is three times smaller than the video, it means nine times fewer pixels to compute.</li>
<li>avoid recursion. In a recursion, the script engine doesn&#8217;t <a href="https://wiki.mozilla.org/JavaScript:TraceMonkey">use the JIT optimization.</a>
</li>
<li>if you want to do a distance between colors, use the <a href="http://en.wikipedia.org/wiki/Lab_color_space">L.A.B colorspace.</a></li>
<li>if you want to find the center of an object, <a href="http://en.wikipedia.org/wiki/Centroid">compute its centroid</a>. See the &#8220;computeFrame&#8221; function <a href="http://people.mozilla.com/~prouget/demos/DynamicContentInjection/main.js">that I use in this JavaScript snippet</a> for my demo.</li>
<li>if the algorithm is really heavy, you can use a <a href="https://developer.mozilla.org/En/DOM/Worker">Worker thread</a>, but take into account that you will need to send the content of the canvas to the thread. It&#8217;s a big array, and objects are automatically JSONified before being sent. It can take a while. </li>
</ul>
<p><strong>Conclusion</strong></p>
<p>As you can see, you can do powerful things with the video element, the canvas element, CSS3, SVG and the new JavaScript engine. You have everything in your hands to create a completely new way to use Video on the web.  It&#8217;s up to you now &#8212; upgrade the web!</p>
<p><strong>References</strong></p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Lab_color_space">LAB Color Space &#8211; for color space distances.</a></li>
<li><a href="https://developer.mozilla.org/En/DOM/Worker">How to use threads in your JavaScript code.</a></li>
<li><a href="http://en.wikipedia.org/wiki/Centroid">The centroid definition &#8211; good way to compute the center of an object from its pixels.</a></li>
<li><a href="https://wiki.mozilla.org/JavaScript:TraceMonkey">TraceMonkey &#8211; the new Firefox JavaScript engine</a></li>
<li><a href="https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas"> Pixel manipulation with canvas.</a></li>
<li><a href="http://people.mozilla.com/~prouget/demos/DynamicContentInjection/play.xhtml">The &#8220;Dynamic Content Injection&#8221; demo.</a></li>
<li><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage">The canvas.drawImage API &#8211; useful to inject the frame of a video into a canvas element.</a></li>
<li><a href="https://developer.mozilla.org/en/Canvas_tutorial/Transformations">How to do transformation in your canvas.</a></li>
<li><a href="http://blog.nihilogic.dk/2009/02/html5-canvas-cheat-sheet.html">A good overview of the canvas API.</a></li>
<li><a href="https://developer.mozilla.org/En/HTML/Canvas">Everything you need to know about canvas.</a></li>
<li><a href="https://developer.mozilla.org/en/Firefox_3.5_for_developers">All the new OpenWeb features in Firefox 3.5.</a></li>
<li><a href="http://people.mozilla.com/~prouget/demos/srt/index2.xhtml">Layering a div over a video.</a></li>
<li><a href="https://developer.mozilla.org/En/CSS/Using_CSS_transforms">Transformation with CSS 3.</a></li>
<li><a href="http://www.w3.org/TR/SVG11/extend.html#ForeignObjectElement">Including HTML inside SVG.</a></li>
<li><a href="https://developer.mozilla.org/En/Applying_SVG_effects_to_HTML_content"> Applying SVG effects to HTML content.</a></li>
<li><a href="http://www.tapper-ware.net/devel/js/JS.TinyVidPlayer/index.xhtml">A 100% OpenVideo player.</a></li>
<li><a href="https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox">The reference for the video and the audio HTML5 tags.</a></li>
<li><a href="https://developer.mozilla.org/en/nsIDOMHTMLMediaElement">The Javascript API for the video and the audio tags.</a></li>
<li><a href="https://developer.mozilla.org/En/HTML/Element/Video">The video HTML attributes.</a></li>
<li><a href="http://hacks.mozilla.org/2009/06/html5-video-fallbacks/">The video fallback mechanism.</a></li>
<li><a href="https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements"> Media formats supported by the audio and video elements. </a></li>
<li><a href="http://people.mozilla.com/~prouget/demos/">My demos.</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/07/video-more-than-just-a-tag/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>slick tables with css 3 selectors</title>
		<link>http://hacks.mozilla.org/2009/07/slick-tables-with-css-3-selectors/</link>
		<comments>http://hacks.mozilla.org/2009/07/slick-tables-with-css-3-selectors/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 07:17:06 +0000</pubDate>
		<dc:creator>Eric Shepherd</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[Firefox 3.5]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1257</guid>
		<description><![CDATA[This article and demo come to us courtesy of Ivan Enderlin, author of the HOA Framework and longtime web developer. This is the article that accompanies the demo below, showing the use of CSS3 selectors implemented in Firefox 3.5 for easy and stylish tables. See this demo step by step. Basic HTML Table First, we [...]]]></description>
			<content:encoded><![CDATA[<p><em>This article and demo come to us courtesy of Ivan Enderlin, author of the <a href="http://hoa-project.net/">HOA Framework</a> and longtime web developer.</em></p>
<p>This is the article that accompanies the demo below, showing the use of CSS3 selectors implemented in Firefox 3.5 for easy and stylish tables.</p>
<p><div id="attachment_1279" class="wp-caption aligncenter" style="width: 529px"><a href="http://mozilla.hoa-project.net/Demo/Css_3_selectors/Demonstration.html"><img src="http://hacks.mozilla.org/wp-content/uploads/2009/07/result.png" alt="CSS3 Selectors for Quick and Pretty Tables" title="result" width="519" height="195" class="size-full wp-image-1279" /></a><p class="wp-caption-text">View the Demo | CSS3 Selectors for Quick and Pretty Tables</p></div><br />
<a href="http://mozilla.hoa-project.net/Demo/Css_3_selectors/Demonstration.html">See this demo step by step</a>.</p>
<p><strong>Basic HTML Table</strong></p>
<p>First, we start by writing a simple HTML table. Note: we do not have any <code>class</code>es or <code>id</code>s, which is what makes this all so fantastic:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">table</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">thead</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">th</span>&gt;</span>...<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">th</span>&gt;</span>
    ...
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">th</span>&gt;</span>...<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">th</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">thead</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">tbody</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">tr</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">td</span>&gt;</span>...<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">td</span>&gt;</span>
      ...
      <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">td</span>&gt;</span>...<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">td</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">tr</span>&gt;</span>
    ...
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">tr</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">td</span>&gt;</span>...<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">td</span>&gt;</span>
      ...
      <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">td</span>&gt;</span>...<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">td</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">tr</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">tbody</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">table</span>&gt;</span></pre></div></div>

<p>And now, let us write some CSS to make the plain old table look a bit more stylish:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">table <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">font</span><span style="color: #00AA00;">:</span> <span style="color: #933;">90%</span>/<span style="color: #933;">1.5em</span> <span style="color: #ff0000;">&quot;Lucida Grande&quot;</span><span style="color: #00AA00;">,</span> Geneva<span style="color: #00AA00;">,</span>
                    <span style="color: #ff0000;">&quot;DejaVu Sans&quot;</span><span style="color: #00AA00;">,</span> <span style="color: #ff0000;">&quot;Bitstream Vera Sans&quot;</span><span style="color: #00AA00;">,</span> AnjaliOldLipi<span style="color: #00AA00;">,</span>
                    <span style="color: #ff0000;">&quot;Lucida sans&quot;</span><span style="color: #00AA00;">,</span> <span style="color: #ff0000;">&quot;Trebuchet MS&quot;</span><span style="color: #00AA00;">,</span> Arial<span style="color: #00AA00;">,</span> Verdana<span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">text-align</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">center</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">border</span><span style="color: #00AA00;">:</span> <span style="color: #933;">4px</span> <span style="color: #000000; font-weight: bold;">black</span> <span style="color: #993333;">double</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">border-spacing</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
    -moz-border-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">12px</span><span style="color: #00AA00;">;</span>
    -moz-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#6a3d37</span> <span style="color: #933;">5px</span> <span style="color: #933;">5px</span> <span style="color: #933;">6px</span><span style="color: #00AA00;">;</span>
    -webkit-border-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">12px</span><span style="color: #00AA00;">;</span>
    -webkit-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#6a3d37</span> <span style="color: #933;">5px</span> <span style="color: #933;">5px</span> <span style="color: #933;">6px</span><span style="color: #00AA00;">;</span>
    border-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">12px</span><span style="color: #00AA00;">;</span>
    box-shadow<span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#6a3d37</span> <span style="color: #933;">5px</span> <span style="color: #933;">5px</span> <span style="color: #933;">6px</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#b59d5c</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>The use of <code>border-spacing, border-radius</code> and <code>box-shadow</code> properties make for a quick and easy way to inject a little beauty into the table.</p>
<p><strong>First Selection</strong></p>
<p>Now, we would like to style all the <code>th</code> tags.  This is easy with CSS Selectors:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">th <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#fff</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00AA00;">:</span> <span style="color: #933;">110%</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">text-shadow</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#6a3d37</span> <span style="color: #933;">2px</span> <span style="color: #933;">2px</span> <span style="color: #933;">2px</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>Reminder: if we write <code>table th</code> we intend to select all the <code>th</code> elements which are child elements of the the table element, and if we write <code>thead > th</code>, we intend to select all the <code>th</code> elements which are direct children of the <code>thead</code> element. Well, it was just a reminder :-)</p>
<p><strong>More Nuanced Selection</strong></p>
<p>The <code>th</code> tag represents a table header. We would like to select the <em>first</em> table header. Hmm… maybe we should use the <code>first-of-type</code> pseudo-class. It represents an element that is the first sibling of its type in the list of children of its parent element. So now we have:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">&nbsp;
th<span style="color: #3333ff;">:first-of-type </span><span style="color: #00AA00;">&#123;</span>
<span style="color: #000000; font-weight: bold;">font-weight</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">bold</span><span style="color: #00AA00;">;</span>
<span style="color: #000000; font-weight: bold;">font-style</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">italic</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p><strong>Even and odd rows</strong></p>
<p>A recurrent problem with tables is: how to select even and odd rows? The solution is the nth-child() pseudo-class. All these pseudo-classes understand the <code>an+b</code> syntax &#8212; to select all the even elements, we use 2n; to select all the odd elements, we use the 2n+1 elements; to select all third elements, we use 3n. In other words, this matches the <code>bth </code>child of an element after all the children have been split into groups of <code>a</code> elements each.</p>
<p>So, let&#8217;s style the even and odd rows:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">&nbsp;
tr<span style="color: #3333ff;">:nth-</span>child<span style="color: #00AA00;">&#40;</span>odd<span style="color: #00AA00;">&#41;</span> <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#e0d8cb</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#474644</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
tr<span style="color: #3333ff;">:nth-</span>child<span style="color: #00AA00;">&#40;</span>even<span style="color: #00AA00;">&#41;</span> <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#6a3d37</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p><strong>Padding on first and last columns</strong></p>
<p>Now, we want to add a padding to the first and the last column. I remind you again that we do not have any classes or IDs, and that the number of columns is unknown.</p>
<p>The solution is the <code>first-of-type</code> and the <code>last-of-type</code> pseudo-classes. We select all the first and last <code>th</code> and <code>td</code> like this:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">&nbsp;
th<span style="color: #3333ff;">:first-of-type</span><span style="color: #00AA00;">,</span>
td<span style="color: #3333ff;">:first-of-type </span><span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">4em</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
th<span style="color: #3333ff;">:last-of-type</span><span style="color: #00AA00;">,</span>
td<span style="color: #3333ff;">:last-of-type </span><span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">4em</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p><strong>The two last rows</strong></p>
<p>Now, we would like to combine many pseudo-classes (and introduce a new one).</p>
<p>Let&#8217;s say we would like to select row number 1, number 4 and number 7. The mathematical expression is not so simple as we hoped. The tips is to split our rows in groups of 3, like this: 3n. But, that will select rows number 3, 6 and 9.  Almost there!  In these groups, we will select the first element, so 3n+1 (or 3n-2 if you like to complicate things).</p>
<p>That&#8217;s good, but that will select a row in our two last non-opaque rows. Ideally, we should say: &#8220;select the first row of each groups of three rows, but not the last row (which will be selected, because the last is the 7th row).&#8221;  Simple.  We are going to use the <code>not</code> pseudo-class, combined with the <code>last-child</code> pseudo-class (or <code>last-of-type</code>, which also works here).</p>
<p>Thus:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">&nbsp;
tr<span style="color: #3333ff;">:nth-last-</span>child<span style="color: #00AA00;">&#40;</span>-n<span style="color: #00AA00;">+</span><span style="color: #cc66cc;">2</span><span style="color: #00AA00;">&#41;</span> <span style="color: #00AA00;">&#123;</span>
    opacity<span style="color: #00AA00;">:</span> .75
<span style="color: #00AA00;">&#125;</span>
&nbsp;
tr<span style="color: #3333ff;">:nth-</span>child<span style="color: #00AA00;">&#40;</span>3n<span style="color: #00AA00;">+</span><span style="color: #cc66cc;">1</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">:</span>not<span style="color: #00AA00;">&#40;</span><span style="color: #3333ff;">:last-</span>child<span style="color: #00AA00;">&#41;</span> td <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">text-shadow</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">red</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">8px</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p><strong>The final source is:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">table <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> table<span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">font</span><span style="color: #00AA00;">:</span> <span style="color: #933;">90%</span>/<span style="color: #933;">1.5em</span> <span style="color: #ff0000;">&quot;Lucida Grande&quot;</span><span style="color: #00AA00;">,</span> Geneva<span style="color: #00AA00;">,</span>
                    <span style="color: #ff0000;">&quot;DejaVu Sans&quot;</span><span style="color: #00AA00;">,</span> <span style="color: #ff0000;">&quot;Bitstream Vera Sans&quot;</span><span style="color: #00AA00;">,</span> AnjaliOldLipi<span style="color: #00AA00;">,</span>
                    <span style="color: #ff0000;">&quot;Lucida sans&quot;</span><span style="color: #00AA00;">,</span> <span style="color: #ff0000;">&quot;Trebuchet MS&quot;</span><span style="color: #00AA00;">,</span> Arial<span style="color: #00AA00;">,</span> Verdana<span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">text-align</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">center</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">border</span><span style="color: #00AA00;">:</span> <span style="color: #933;">4px</span> <span style="color: #000000; font-weight: bold;">black</span> <span style="color: #993333;">double</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">border-spacing</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
    -moz-border-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">12px</span><span style="color: #00AA00;">;</span>
    -moz-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#6a3d37</span> <span style="color: #933;">5px</span> <span style="color: #933;">5px</span> <span style="color: #933;">6px</span><span style="color: #00AA00;">;</span>
    -webkit-border-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">12px</span><span style="color: #00AA00;">;</span>
    -webkit-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#6a3d37</span> <span style="color: #933;">5px</span> <span style="color: #933;">5px</span> <span style="color: #933;">6px</span><span style="color: #00AA00;">;</span>
    border-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">12px</span><span style="color: #00AA00;">;</span>
    box-shadow<span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#6a3d37</span> <span style="color: #933;">5px</span> <span style="color: #933;">5px</span> <span style="color: #933;">6px</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#b59d5c</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
th <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#fff</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00AA00;">:</span> <span style="color: #933;">110%</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">text-shadow</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#6a3d37</span> <span style="color: #933;">2px</span> <span style="color: #933;">2px</span> <span style="color: #933;">2px</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
    th<span style="color: #3333ff;">:first-of-type </span><span style="color: #00AA00;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">font-weight</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">bold</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">font-style</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">italic</span>
    <span style="color: #00AA00;">&#125;</span>
&nbsp;
tr<span style="color: #3333ff;">:nth-</span>child<span style="color: #00AA00;">&#40;</span>odd<span style="color: #00AA00;">&#41;</span> <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#e0d8cb</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#474644</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
tr<span style="color: #3333ff;">:nth-</span>child<span style="color: #00AA00;">&#40;</span>even<span style="color: #00AA00;">&#41;</span> <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#6a3d37</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
th<span style="color: #3333ff;">:first-of-type</span><span style="color: #00AA00;">,</span>
td<span style="color: #3333ff;">:first-of-type </span><span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">4em</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
th<span style="color: #3333ff;">:last-of-type</span><span style="color: #00AA00;">,</span>
td<span style="color: #3333ff;">:last-of-type </span><span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">4em</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
tr<span style="color: #3333ff;">:nth-last-</span>child<span style="color: #00AA00;">&#40;</span>-n<span style="color: #00AA00;">+</span><span style="color: #cc66cc;">2</span><span style="color: #00AA00;">&#41;</span> <span style="color: #00AA00;">&#123;</span>
    opacity<span style="color: #00AA00;">:</span> .75
<span style="color: #00AA00;">&#125;</span>
&nbsp;
tr<span style="color: #3333ff;">:nth-</span>child<span style="color: #00AA00;">&#40;</span>3n<span style="color: #00AA00;">+</span><span style="color: #cc66cc;">1</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">:</span>not<span style="color: #00AA00;">&#40;</span><span style="color: #3333ff;">:last-</span>child<span style="color: #00AA00;">&#41;</span> td <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">text-shadow</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">red</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">8px</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p><a href="http://mozilla.hoa-project.net/Demo/Css_3_selectors/Demonstration.html"><br />
View this demo step by step</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/07/slick-tables-with-css-3-selectors/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>(r)evolution number 5</title>
		<link>http://hacks.mozilla.org/2009/07/revolution-number-5/</link>
		<comments>http://hacks.mozilla.org/2009/07/revolution-number-5/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 03:39:57 +0000</pubDate>
		<dc:creator>Arun Ranganathan</dc:creator>
				<category><![CDATA[@font-face]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[Geolocation]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Standards]]></category>
		<category><![CDATA[w3c]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1204</guid>
		<description><![CDATA[We&#8217;ve just launched Firefox 3.5, and we&#8217;re incredibly proud. Naturally, we have engaged in plentiful Mozilla advocacy &#8212; this site is, amongst other things, a vehicle for showcasing the latest browser&#8217;s new capabilities. We like to think about this release as an upgrade for the whole World Wide Web, because of the new developer-facing features [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve just launched <a href="http://www.mozilla.com/en-US/">Firefox 3.5</a>, and <a href="http://www.flickr.com/photos/gen/3677579248/"/> we&#8217;re</a> <a href="http://www.flickr.com/photos/nitot/3675934390/">incredibly</a> <a href="http://www.flickr.com/photos/29142435@N08/3674981992/">proud</a>.  Naturally, we have engaged in plentiful Mozilla advocacy &#8212; this site is, amongst other things, a vehicle for showcasing the latest browser&#8217;s new capabilities.  We like to think about this release as an upgrade for the <em>whole World Wide Web</em>, because of the new developer-facing features that have just been introduced into the web platform.  When talking about some of the next generation standards, the appearance of the number &#8220;5&#8243; is almost uncanny &#8212; consider <a href="http://dev.w3.org/html5/spec/Overview.html">HTML5</a> and <a href="http://www.ecma-international.org/publications/files/drafts/tc39-2009-025.pdf">ECMAScript 5 (PDF)</a>.   The recent (and very welcome) hype around HTML5 in the press is what motivates this article.  Let&#8217;s take a step back, and consider some of Mozilla&#8217;s web advocacy in the context of events leading up to the release of Firefox 3.5.</p>
<p>Standardization of many of these features often came after much spirited discussion, and we&#8217;re pleased to see the prominent placement of HTML5 as a <a href="http://radar.oreilly.com/2009/05/google-bets-big-on-html-5.html">key strategic initiative</a> by major web development companies.  Indeed, <a href="http://news.cnet.com/8301-17939_109-10252252-2.html">exciting new web applications</a> hold a great deal of promise, and really showcase what the future of the web platform holds in store for aspiring developers.  Many herald the triumphant arrival of the <a href="http://news.cnet.com/8301-17939_109-10250196-2.html">browser as the computer</a>, an old theme that <a href="http://developer.palm.com/webos_book/book1.html">gets bolstered</a> with the arrival of <a href="http://htmlfive.appspot.com/">attractive HTML5 platform features</a> that are implemented across <a href="http://www.apple.com/safari/">Safari</a>, <a href="http://www.google.com/chrome/intl/en/features.html">Chrome</a>, <a href="http://www.opera.com/">Opera</a>, and of course, <a href="http://www.getfirefox.com/">Firefox</a> (with <a href="http://www.microsoft.com/windows/internet-explorer/default.aspx">IE8</a> getting an honorable mention for having both some HTML5 features and some ECMAScript, 5th Edition features).</p>
<p>Call it what you will &#8212; Web 5.0, Open Web 5th Generation (wince!), or, (R)evolution # 5, the future is now.  But lest anyone forget, HTML5 is not a completed standard yet, as the <a href="http://www.w3.org/QA/2009/05/_watching_the_google_io.html">W3C was quick to point out</a>.  The editor doesn&#8217;t anticipate completion till 2010.  The path taken from the start of what is now called HTML5 to the present-day era of (very welcome) hype has been a long one, and Mozilla has been part of the journey from the very beginning.</p>
<p>For one thing, we were there to <a href="http://weblogs.mozillazine.org/roadmap/archives/2004/06/the_nonworld_no_1.html">point out, in no uncertain terms</a>, that the <a href="http://www.w3.org/">W3C</a> had perhaps <a href="http://dbaron.org/log/2004-06#e20040609a">lost its way</a>.  Exactly 5 summers ago (again, with that magic number!), it became evident that the W3C was no longer able to serve as sole custodian of the standards governing the open web of browser-based applications, so Mozilla, along with Opera, started the <a href="http://www.whatwg.org/">WHATWG</a>.  Of course, back then, we didn&#8217;t call it HTML5, and while Firefox itself made a splash in 2004, the steps taken towards standardization were <a href="http://ln.hixie.ch/?start=1088526392&#038;count=1">definitive but tentative</a>.  Soon, other browser vendors joined us, and by the time <a href="http://dig.csail.mit.edu/breadcrumbs/node/166">the reconciliation with W3C</a> occurred two years later, the innovations introduced into the web platform via the movement initiated by Mozilla had gained substantial momentum.  </p>
<p>The net result is a specification that is not yet complete called &#8220;HTML5&#8243; which is implemented piecemeal by most modern browsers.  The features we choose to implement as an industry are in response to developers, and our <em>modus operandi</em> is (for the most part) <a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/">in</a> the <a href="http://lists.w3.org/Archives/Public/public-html/">open</a>.  Mozilla funds the <a href="http://validator.nu/">HTML5 Validator</a>, producing the first real HTML5 parser, which now drives <a href="http://validator.w3.org/">W3C&#8217;s markup validation</a> for HTML5.  That parser has made its way back into Firefox.  It&#8217;s important to note that capabilities that are of greatest interest (many of which are showcased on this blog) are not only developed within the HTML5 specification, but also as part of the <a href="http://www.w3.org/2008/geolocation/">W3C Geolocation WG</a>, the <a href="http://www.w3.org/2008/webapps/">Web Apps WG</a>, and the <a href="http://www.w3.org/Style/CSS/current-work">CSS WG</a>.</p>
<p>The release of Firefox 3.5, along with updates to other modern browsers, seems to declare that HTML5 has arrived.  But with the foresight that comes with having been around this for a while, we also know that we have a lot of work ahead of us.  For one thing, we&#8217;ve got to finish HTML5, or at least publish a subset of it that we all agree is ready for implementation, <strong>soon</strong>.  We&#8217;ve also got to ensure that <a href="http://lists.w3.org/Archives/Public/public-html/2009Jun/0661.html">accessibility serves as an important design principle</a> in the emerging web platform, and resolve sticky differences here.  Also, an open standard <em>does not</em> an open platform make, as debates about <a href="http://cwilso.com/2008/07/23/fonts-embedding-vs-linking/">web</a> <a href="http://dbaron.org/log/20090317-fonts">fonts</a> and <a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-June/020363.html">audio/video</a> <a href="http://lists.w3.org/Archives/Public/public-html/2009Jun/0825.html">codecs</a> show.  We&#8217;ve got a lot of work ahead of us, but for now, 5 years after the summer we started the ball rolling, we&#8217;re enjoying the hype around (R)evolution Number 5.</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/07/revolution-number-5/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>another great CSS media query demo</title>
		<link>http://hacks.mozilla.org/2009/07/media-queries-demo/</link>
		<comments>http://hacks.mozilla.org/2009/07/media-queries-demo/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 16:20:20 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[Standards]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1174</guid>
		<description><![CDATA[This demo is from Daniel Glazman who works actively on web standards and is a long-time mozilla contributor. CSS Media Queries were originally a proposal submitted to the CSS Working Group by Opera Software and are now implemented in Firefox 3.5. In short, Media Queries extend the media declaration attached to a stylesheet to allow [...]]]></description>
			<content:encoded><![CDATA[<p><em>This demo is from <a href="http://www.glazman.org/weblog/">Daniel Glazman</a> who works actively on web standards and is a long-time mozilla contributor.</em></p>
<p><a href="http://www.w3.org/TR/css3-mediaqueries/">CSS Media Queries</a> were originally a proposal submitted to the CSS Working Group by Opera Software and are now implemented in Firefox 3.5. In short, Media Queries extend the media declaration attached to a stylesheet to allow matching based on the rendering device&#8217;s intrinsic properties.</p>
<p>Let&#8217;s take a link element declaring a stylesheet inside an HTML document:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;style.css&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">media</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;screen&quot;</span>&gt;</span></pre></div></div>

<p>Now imagine you want this stylesheet to apply to the document if and only if the width of the content window is less than 300 pixels&#8230; CSS Media Queries make it simple to declare:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;style.css&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">media</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;screen and (max-width: 300px)&quot;</span>&gt;</span></pre></div></div>

<p>Available properties include viewport&#8217;s width and height, device&#8217;s width and height, orientation (portrait or landscape), viewport&#8217;s aspect ratio, device&#8217;s aspect ratio, colormap, resolution and type of device.</p>
<p>It&#8217;s then very easy to have one single web page ready for consumption on a wide variety of devices, ranging from mobile devices to monochrome tty displays.</p>
<p>When viewing the demo, please <strong>don&#8217;t forget to resize the window from large to very very small (less than 100px!) to see it in action.</strong></p>
<div align="center" style="font-size: 120%"><a href="#" onclick="open('http://disruptive-innovations.com/zoo/hmo/CSSMQdemo.html', 'CSS Media Queries Demo','width=800,height=500,resizable=1,location=0,scrollbars=1')" >View the Demo in Firefox 3.5<br/><img src="http://hacks.mozilla.org/wp-content/uploads/2009/07/glazman.png"/></a></div>
<p><a href="http://disruptive-innovations.com/zoo/hmo/CSSMQdemo.html">Loading via planet, RSS or a reader without JavaScript?  Click here instead.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/07/media-queries-demo/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>new CSS3 properties in Firefox 3.5 &#8211; *-of-type</title>
		<link>http://hacks.mozilla.org/2009/06/css3-of-type/</link>
		<comments>http://hacks.mozilla.org/2009/06/css3-of-type/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 03:26:54 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[Firefox 3.5]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1093</guid>
		<description><![CDATA[In today&#8217;s feature post we&#8217;ll talk briefly about three new CSS3 pseudo-classes: only-of-type, first-of-type and last-of-type. These are all very similar to the *-nth classes we covered in an earlier post. first-of-type and last-of-type These two pseudo-classes allow you to select the first and last item in a list of siblings within a particular element. [...]]]></description>
			<content:encoded><![CDATA[<p>In today&#8217;s feature post we&#8217;ll talk briefly about three new CSS3 pseudo-classes: <a href="https://developer.mozilla.org/en/CSS/%3aonly-of-type"><code>only-of-type</code></a>, <a href="https://developer.mozilla.org/en/CSS/%3afirst-of-type"><code>first-of-type</code></a> and <a href="https://developer.mozilla.org/en/CSS/%3alast-of-type"><code>last-of-type</code></a>.  These are all very similar to the <a href="http://hacks.mozilla.org/2009/06/css3-nth/"><code>*-nth</code></a> classes we covered in an earlier post.</p>
<p><strong><a href="https://developer.mozilla.org/en/CSS/%3afirst-of-type"><code>first-of-type</code></a> and <a href="https://developer.mozilla.org/en/CSS/%3alast-of-type"><code>last-of-type</code></a></strong></p>
<p>These two pseudo-classes allow you to select the first and last item in a list of siblings within a particular element.  You can use this to color the first item in a list, use <a href="http://hacks.mozilla.org/2009/06/opacity/"><code>opacity</code></a> to make the last paragraph on a page fade out or a number of other things.  Here&#8217;s an example that sets small caps on the first paragraph of a document:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #cc00cc;">#type-ex1</span> div<span style="color: #3333ff;">:first-of-type </span><span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">font-variant</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">small-caps</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<style type="text/css">
#type-ex1 div:first-of-type {
    font-variant: small-caps;
}
</style>
<div id="type-ex1" class="wp_syntax">
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nulla neque, cursus venenatis vehicula ac, rutrum id libero. Nullam porttitor ultricies eros, laoreet mollis nunc vestibulum in. Sed iaculis nibh nec tellus vulputate pulvinar. Aliquam ultricies mauris vel nulla semper ac dignissim arcu sollicitudin.
</div>
<div>
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras molestie elit sed libero pretium faucibus. Ut sed lacus eget est gravida aliquet sed sed risus. Maecenas vitae volutpat purus. Fusce porttitor aliquam lectus sit amet vehicula. Nulla molestie mi lacus.
</div>
</div>
<p><strong><a href="https://developer.mozilla.org/en/CSS/%3aonly-of-type"><code>only-of-type</code></a></strong></p>
<p><code>only-of-type</code> is similar to the previous two, but only selects an element if it has no siblings with the same name.  Here&#8217;s a somewhat contrived example* that will hide single images inside of a <code>div</code>.  If there&#8217;s more than one image in the  <code>div</code> they will be visible:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #6666ff;">.type-ex2</span> img<span style="color: #3333ff;">:only-of-type </span><span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<style type="text/css">
.type-ex2 img:only-of-type {
    display: none;
}
</style>
<div class="type-ex2 wp_syntax">
<div>This is some text before a single image.</div>
<p><img src="http://farm4.static.flickr.com/3093/3666371567_fe7cccb760_m.jpg"/></p>
<div>This is some text after a single image.</div>
</div>
<div class="type-ex2 wp_syntax">
<div>This is some text before two images.</div>
<p><img src="http://farm3.static.flickr.com/2607/3667176568_561ca88a34_m.jpg"/><br />
<img src="http://farm3.static.flickr.com/2469/3667176010_29180dc097_m.jpg"/></p>
<div>This is some text after two images.</div>
</div>
<p>And that&#8217;s it.  Enjoy!</p>
<p>[ * Note: if someone can come up with a better example for <code>only-of-type</code> I'm all ears.  There are very few examples of where this is useful. ]</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/06/css3-of-type/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>exploring music with the audio tag</title>
		<link>http://hacks.mozilla.org/2009/06/exploring-music-audio/</link>
		<comments>http://hacks.mozilla.org/2009/06/exploring-music-audio/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 00:28:49 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[Audio]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[SVG]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1066</guid>
		<description><![CDATA[Today&#8217;s demo comes to us from Samuel Goldszmidt. He&#8217;s a web developer specializing in audio applications at Institut de Recherche et Coordination Acoustique/Musique (IRCAM). IRCAM is a European institute covering science, sound and avant garde electro-acoustical art music. The demo uses XML to describe the various segments of a piece of music &#8211; Florence Baschet&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p><em>Today&#8217;s <a href="http://apm.ircam.fr/page/audio-tag/">demo</a> comes to us from Samuel Goldszmidt.  He&#8217;s a web developer specializing in audio applications at Institut de Recherche et Coordination Acoustique/Musique (<a href="http://www.ircam.fr/ircam.html?&#038;L=1">IRCAM</a>).  IRCAM is a European institute covering science, sound and avant garde electro-acoustical art music.</em></p>
<p>The demo uses XML to describe the various segments of a piece of music &#8211; Florence Baschet&#8217;s <em>StreicherKreis (Circle of Strings)</em>.  The music itself is a combination of stringed instruments and electronic effects.  From the XML, SVG is generated for each section of the music.  You can click on each section to listen to that part of the piece and a description is shown on how that particular section was created.</p>
<p>As far as demos go, this is relatively simple.  But it&#8217;s worth highlighting because it shows how easy it is to build a timeline around a piece of music and add descriptive information.  In this case, it&#8217;s information meant to teach people how a particular effect was created.  But it could be anything, from showing different camera angles of people playing the music to links about different covers of a popular piece.  Opening up media to the web means that we can combine it with text, images and other media.  This is just a small example.</p>
<div align="center" style="font-size: 120%"><a target="_blank" href="http://apm.ircam.fr/page/audio-tag/">View the Demo in Firefox 3.5<br/><img src="http://hacks.mozilla.org/wp-content/uploads/2009/06/ircam.png"/></a></div>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/06/exploring-music-audio/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Firefox 3.5 is out</title>
		<link>http://hacks.mozilla.org/2009/06/firefox-35-is-out/</link>
		<comments>http://hacks.mozilla.org/2009/06/firefox-35-is-out/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 15:21:16 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[Firefox 3.5]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1054</guid>
		<description><![CDATA[Today we released Firefox 3.5, which as we said at the beginning of the 35 days project is a huge upgrade for both end users but also for the web. In the past we&#8217;ve always published a list of web developer features for a release. But the feature list for developers for 3.5 is so [...]]]></description>
			<content:encoded><![CDATA[<p>Today we <a href="http://bit.ly/firefox35">released Firefox 3.5</a>, which as we said at the <a href="http://hacks.mozilla.org/2009/06/35-days/">beginning of the 35 days project</a> is a huge upgrade for both end users but also for the web.</p>
<p>In the past we&#8217;ve always published a list of web developer features for a release.  But the <a href="https://developer.mozilla.org/En/Firefox_3.5_for_developers">feature list for developers for 3.5</a> is so long that we thought it might be useful to try and break it down into easy-to-swallow bites.  And my suspicion, given the number of comments and the number of daily views this weblog gets, is that it&#8217;s actually been useful to people.</p>
<p>We&#8217;ve been writing articles on features to get people informed on what the changes are, but we&#8217;ve also been featuring demos to get people inspired.  Some of them have been built by people at the Mozilla core, but the really great thing that we&#8217;ve seen is that people have started to show up and build demos for our project without us having to ask.  I think that this points to the fact that people are really bullish on the future of the web.  People want to see change, they want to see improvements and they understand that every individual has a role to play in that.  To everyone involved, I say thank you.  You&#8217;re helping to improve the web, one action at a time.</p>
<p>We&#8217;re about half way through our 35 days posts and we will continue to make posts.  And we&#8217;re still looking for help.  If you want to get involved, you&#8217;re more than welcome to <a href="https://wiki.mozilla.org/Evangelism">join us</a>.  There&#8217;s always something that you can do &#8211; <a href="http://twitter.com/mozhacks">follow our twitter account</a>, <a href="https://wiki.mozilla.org/Firefox3.1/Demos">write a demo</a>, <a href="https://developer.mozilla.org/En/Firefox_3.5_for_developers">document a feature</a> or, really, just start using this stuff.  We&#8217;re helping to write the future of the web and everyone has a part to play.</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/06/firefox-35-is-out/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>taming long words with word-wrap</title>
		<link>http://hacks.mozilla.org/2009/06/word-wrap/</link>
		<comments>http://hacks.mozilla.org/2009/06/word-wrap/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 21:47:17 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[Standards]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1018</guid>
		<description><![CDATA[This post is from Les Orchard, who works on Mozilla&#8217;s web development team. Web browsers have a long history of sharing features between them. The word-wrap CSS property is a feature that originally came from Microsoft and is included in CSS3. Now available in Firefox 3.5, this CSS property allows the browser to arbitrarily break [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post is from <a href="http://decafbad.com/blog/lifestream">Les Orchard</a>, who works on Mozilla&#8217;s web development team.</em></p>
<style type="text/css">
            p { width: 70ex }
            #lmo-word-wrap-demo {
            }
            #lmo-word-wrap-demo textarea {
                width: 70ex;
                margin: 0.5em 1em;
            }
            #lmo-word-wrap-demo form {
                margin: 0.5em 1em;
            }
            #lmo-word-wrap-demo div {
                width: 70ex;
                margin: 1em;
                padding: 1em;
                border: 1px solid #000;
                font-family: monospace;
            }
            #lmo-word-wrap-demo div.hidden {
                overflow: hidden;
            }
            #lmo-word-wrap-demo div.auto {
                overflow: auto;
            }
            #lmo-word-wrap-demo div.wordwrap-breakword {
                word-wrap: break-word;
            }
            #lmo-word-wrap-demo div.wordwrap-normal {
                word-wrap: normal;
            }
</style>
<div id="lmo-word-wrap-demo">
<p>Web browsers have a long history of sharing features between them.  The <code>word-wrap </code>CSS property is <a href="http://msdn.microsoft.com/en-us/library/ms531186(VS.85,loband).aspx">a feature that originally came from Microsoft</a> and is included in <a href="http://www.w3.org/TR/css3-text/#word-wrap">CSS3</a>.</p>
<p><a href="https://developer.mozilla.org/en/CSS/word-wrap">Now available in Firefox 3.5</a>, this CSS property allows the browser to arbitrarily break up long words or strings of characters to fit within a given element.</p>
<p>How is this helpful?  Well, have you ever had to display an extremely long URL or block of data on a page?  Sure, URL shortening services have helped, but the basic layout issue still remained.</p>
<p>Consider the following URL using <a href="http://en.wikipedia.org/wiki/Data_URI_scheme">the <code>data</code> scheme</a>:</p>
<p>            <textarea rows="2" cols="70" wrap="virtual">data:text/html;charset=utf-8;base64,Q29uZ3JhdHVsYXRpb25zISBZb3UndmUgZm91bmQgdGhlIGhpZGRlbiBtZXNzYWdlIQ0KDQpUbyBjbGFpbSB5b3VyIHByaXplLCB2aXNpdCBodHRwOi8vZ2V0ZmlyZWZveC5jb20gdG9kYXkhDQoNCkZyZWUgYnJvd3NlciBpbiBldmVyeSBib3ghDQo%3D</textarea></p>
<p>Presented in a <code>&lt;textarea&gt;</code>, this huge URL behaves well enough to at least not break the layout of this page.  But, it&#8217;s not really handled all that gracefully beyond that.  Most browsers don&#8217;t quite know what to do with the scrollbar, styling is a pain, and presenting the URL in an editable field isn&#8217;t really the intent here.</p>
<p>Alternatively, you could stuff the URL into a <code>&lt;div&gt;</code> and slap an <code>overflow:&nbsp;hidden</code> style on it, like so:</p>
<div class="hidden">data:text/html;charset=utf-8;base64,Q29uZ3JhdHVsYXRpb25zISBZb3UndmUgZm91bmQgdGhlIGhpZGRlbiBtZXNzYWdlIQ0KDQpUbyBjbGFpbSB5b3VyIHByaXplLCB2aXNpdCBodHRwOi8vZ2V0ZmlyZWZveC5jb20gdG9kYXkhDQoNCkZyZWUgYnJvd3NlciBpbiBldmVyeSBib3ghDQo%3D</div>
<p>Again, the page layout isn&#8217;t broken, but now the URL is cut off.  So, why not try an <code>overflow:&nbsp;auto</code> style instead?  </p>
<p> This will give you a scrollbar, at least:</p>
<div class="auto">data:text/html;charset=utf-8;base64,Q29uZ3JhdHVsYXRpb25zISBZb3UndmUgZm91bmQgdGhlIGhpZGRlbiBtZXNzYWdlIQ0KDQpUbyBjbGFpbSB5b3VyIHByaXplLCB2aXNpdCBodHRwOi8vZ2V0ZmlyZWZveC5jb20gdG9kYXkhDQoNCkZyZWUgYnJvd3NlciBpbiBldmVyeSBib3ghDQo%3D</div>
<p>But now, visitors to your page have to scroll to see the whole<br />
thing, and highlighting the text for copy &amp; paste can be<br />
cumbersome.</p>
<p>So, finally, here&#8217;s the <code>word-wrap:&nbsp;break-word</code> payoff:</p>
<div id="wordwrap-breakword" class="wordwrap-breakword">data:text/html;charset=utf-8;base64,Q29uZ3JhdHVsYXRpb25zISBZb3UndmUgZm91bmQgdGhlIGhpZGRlbiBtZXNzYWdlIQ0KDQpUbyBjbGFpbSB5b3VyIHByaXplLCB2aXNpdCBodHRwOi8vZ2V0ZmlyZWZveC5jb20gdG9kYXkhDQoNCkZyZWUgYnJvd3NlciBpbiBldmVyeSBib3ghDQo%3D</div>
<form>
<code>word-wrap:</code></p>
<input type="radio" value="wordwrap-normal" name="breakword"><code>normal</code></p>
<input type="radio" value="wordwrap-breakword" name="breakword" checked="checked"><code>break-word</code><br />
</form>
<p><script type="text/javascript">
<!--
(function($) {
    $("input[name=breakword]").click(function() {
        $('#wordwrap-breakword').attr('class', $(this).attr('value'));
     });
     $('input[value=wordwrap-breakword]').attr('checked','checked');
})(jQuery);
//--></script></p>
<p>See the difference for yourself: Use the radio buttons above to switch between the values <code>normal</code> (the default) and <code>break-word</code>. The <code>normal</code> value will cause the URL to spill out of the containing <code>&lt;div&gt;</code>, possibly breaking the layout of this page.</p>
<p>On the other hand, using <code>word-wrap:&nbsp;break-word</code> will allow the browser to coerce the text into the confines of the <code>&lt;div&gt;</code>, thus preserving your page layout and quite possibly your sanity.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/06/word-wrap/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>the potential of web typography</title>
		<link>http://hacks.mozilla.org/2009/06/web-typography/</link>
		<comments>http://hacks.mozilla.org/2009/06/web-typography/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 18:56:16 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[@font-face]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[Standards]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=1000</guid>
		<description><![CDATA[This post counts as both a demo and commentary about the changing nature of typography on the web. Ian Lynam and Craig Mod have put together a page that is an excellent example of typography in action, but also offer some suggestions on what the next steps for typography on the web might look like. [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post counts as both a demo and commentary about the changing nature of typography on the web.  <a href="http://ianlynam.com/">Ian Lynam </a> and <a href="http://craigmod.com/">Craig Mod</a> have <a href="http://craigmod.com/journal/font-face/">put together a page</a> that is an excellent example of typography in action, but also offer some suggestions on what the next steps for typography on the web might look like.  The page itself takes advantage of a number of typefaces that Craig and Ian got permission to use and uses a pleasing multi-column layout.  Please click through to the complete article to get the full effect.</em></p>
<div align="center" style="font-size: 120%"><a target="_blank" href="http://craigmod.com/journal/font-face/">View the Demo in Firefox 3.5<br/><img src="http://hacks.mozilla.org/wp-content/uploads/2009/06/potential.png" alt="potential" title="potential" width="500" height="372" class="aligncenter size-full wp-image-1006" /></a></div>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/06/web-typography/feed/</wfw:commentRss>
		<slash:comments>44</slash:comments>
		</item>
		<item>
		<title>the script defer attribute</title>
		<link>http://hacks.mozilla.org/2009/06/defer/</link>
		<comments>http://hacks.mozilla.org/2009/06/defer/#comments</comments>
		<pubDate>Sat, 27 Jun 2009 04:00:34 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=953</guid>
		<description><![CDATA[This post is by Olivier Rochard. Olivier does research at Orange Labs in France. In HTML, the script element allows authors to include dynamic script in their documents. The defer attribute is boolean attribute that indicates how the script should be executed. If the defer attribute is present, then the script is executed when the [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post is by Olivier Rochard.  Olivier does research at Orange Labs in France.</em></p>
<p>In HTML, the <code>script</code> element allows authors to include dynamic script in their documents. The <a href="http://www.w3.org/TR/html5/semantics.html#attr-script-defer"><code>defer</code></a> attribute is boolean attribute that indicates how the script should be executed.  If the <code>defer</code> attribute is present, then the script is executed when the page has finished parsing. The element is added to the end of the list of scripts that will execute when the document has finished parsing. Think about a FIFO processing queue : the first script element to be added to the queue will be the first script to be executed, then processing proceeds sequentially in the same order.</p>
<p>There is one very good reason for using the <code>defer</code> attribute: performance.  If you include a <code>script</code> element in your HTML page the script must be evaluated immediately while the page is being parsed.  This means that objects have to be created, styles must be flushed, etc.  This can make page loading slower.  The <code>defer</code> attribute implies that the script has no side effects on the document as it&#8217;s being loaded and can safely be evaluated at the end of the page load.</p>
<p>The <code>defer</code> attribute was first introduced in Internet Explorer 4, and added in the <a href="http://www.w3.org/TR/html401/interact/scripts.html#h-18.2.1">HTML 4 specification</a>.</p>
<p><strong>A simple test.</strong></p>
<p>Here is a simple first test to see how the attribute works. The following lines are in the head element of a page:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;">‹script›
	var test1 = &quot;Test 1 : fail&quot;;
‹/script›
‹script defer›
  	console.log(test1);
‹/script›
‹script›
	test1 = &quot;Test 1 : pass&quot;;
‹/script›</pre></div></div>

<p>If the <code>defer</code> attribute for the script element is correctly implemented the browser will:</p>
<ol>
<li>Render the page.
<li>Execute the second script element after all the others.
<li>Display &#8220;Test 1 : pass&#8221; on the Firebug console.
</ol>
<p>If the console displays &#8220;Test 1 : fail&#8221; it&#8217;s because the scripts are executed in the same order as in the source code.</p>
<p>Note that the correct syntax for XHTML documents is:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">defer</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;defer&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></pre></div></div>

<p><strong>A more advanced test</strong></p>
<p>This second test is a way to see how the feature works in a webpage with multiple script elements inserted:</p>
<ul>
<li>Inline in the <code>head</code> and <code>body</code> elements
<li>External via <code>src</code> attribute in <code>head</code> and <code>body</code> elements
<li>With dynamic DOM insertion
</ul>
<p>Here is partial source code of a webpage that tests how defer affects script loading and parsing order:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">‹!doctype html›
‹html›
    ‹head›
        ‹title› Test 2 ‹/title›
        ‹script› var test2 = &quot;Test 2 :\n\n&quot;; ‹/script›
        ‹script› document.addEventListener(&quot;DOMContentLoaded&quot;,
                function(){
                        test2 += &quot;\tDOMContentLoaded\n&quot;;
                }, false);
        ‹/script›
        ‹script defer› test2 += &quot;\tInline HEAD deferred\n&quot;; ‹/script›
        ‹script› test2 += &quot;\tInline HEAD\n&quot;; ‹/script›
        ‹script src=&quot;script1.js&quot; defer›
                // External HEAD deferred (script1.js) 
        ‹/script›
        ‹script src=&quot;script2.js&quot;›
                // External HEAD  (script2.js)
        ‹/script›
	‹script›
            // Dynamic DOM insertion of a script (script3.js)
            head = document.getElementsByTagName('head')[0];
            script3 = document.createElement('script');
            script3.setAttribute('src', 'script3.js');
            head.appendChild(script3);
            // Dynamic DOM insertion of a deferred script (script4.js)
            script4 = document.createElement('script');
            script4.setAttribute('defer', 'defer');
            script4.setAttribute('src', 'script4.js');
            head.appendChild(script4);
	‹/script›
	‹script defer›
            // Deferred dynamic DOM insertion of a script (script5.js)
            head = document.getElementsByTagName('head')[0];
            script5 = document.createElement('script');
            script5.setAttribute('src', 'script5.js');
            head.appendChild(script5);
            // Deferred dynamic DOM insertion of a deferred script
            // (script6.js)
            script6 = document.createElement('script');
            script6.setAttribute('defer', 'defer');
            script6.setAttribute('src', 'script6.js');
            head.appendChild(script6);
	‹/script›
    ‹/head›
    ‹body onload=&quot;test2 += '\tBody onLoad\n';&quot;›
        ‹script defer› test2 += &quot;\tInline BODY deferred\n&quot;; ‹/script›
        ‹script› test2 += &quot;\tInline BODY\n&quot;; ‹/script›
&nbsp;
	... other body content ...
&nbsp;
		&lt;a onclick=&quot;alert(test2);&quot;&gt;Launch test 2&lt;/a&gt;
&nbsp;
	... other body content ...
&nbsp;
        ‹script src=&quot;script7.js&quot; defer›
                // External BODY deferred (script7.js)
        ‹/script›
        ‹script src=&quot;script8.js&quot;›
                // External BODY (script8.js)
        ‹/script›
    ‹/body›
‹/html›</pre></div></div>

<p>When you click on the &#8220;Launch test 2&#8243; link in the document a pop-up appears with a list in it. This list shows the order of script elements loaded during the session.</p>
<p>The test also displays the <code>DOMContentLoaded</code> and <code>body.onload</code> events when they are fired.</p>
<p>If the <code>defer</code> attribute is correctly implemented in the browser, all the deferred lines should be near the bottom of the list.</p>
<p>Results of the second test for each browser are below (deferred scripts are in green color) :</p>
<ul>
<li> <b>The <tt>defer</tt> attribute behavior in the Firefox 3.5 browser is correct</b>:</p>
<ol>
<li>Inline HEAD
</li>
<li>External HEAD (script2.js)
</li>
<li>Dynamic DOM insertion of a script (script3.js)
</li>
<li>Inline BODY
</li>
<li>External BODY (script8.js)
</li>
<li><font style="color: green;">Inline HEAD deferred</font>
</li>
<li><font style="color: green;">External HEAD deferred (script1.js)</font>
</li>
<li><font style="color: green;">Dynamic DOM insertion of a deferred script (script4.js)</font>
</li>
<li><font style="color: green;">Inline BODY deferred</font>
</li>
<li><font style="color: green;">External BODY deferred (script7.js)</font>
</li>
<li><font style="color: green;">Deferred dynamic DOM insertion of a script (script5.js)</font>
</li>
<li><font style="color: green;">Deferred dynamic DOM insertion of a deferred script (script6.js)</font>
</li>
<li>DOMContentLoaded
</li>
<li>Body onLoad
</li>
</ol>
</li>
</ul>
<ul>
<li> <b>The <tt>defer</tt> attribute behavior in the IE 8 browser is <i>erratic</i>: the order is different at each reload</b>&nbsp;:</p>
<ol>
<li>Inline HEAD
</li>
<li>External HEAD (script2.js)
</li>
<li>Inline BODY
</li>
<li>External BODY (script8.js)
</li>
<li>Dynamic DOM insertion of a script (script3.js)
</li>
<li><font style="color: green;">Dynamic DOM insertion of a deferred script (script4.js)</font>
</li>
<li><font style="color: green;">Inline HEAD deferred</font>
</li>
<li><font style="color: green;">External HEAD deferred (script1.js)</font>
</li>
<li><font style="color: green;">Inline BODY deferred</font>
</li>
<li><font style="color: green;">External BODY deferred (script7.js)</font>
</li>
<li>Body onLoad
</li>
<li><font style="color: green;">Deferred dynamic DOM insertion of a script (script5.js)</font>
</li>
<li><font style="color: green;">Deferred dynamic DOM insertion of a deferred script (script6.js)</font>
</li>
</ol>
</li>
</ul>
<ul>
<li> <b>The <tt>defer</tt> attribute behavior in a WebKit browser (Safari 4.0) is <i>erratic</i>&nbsp;: the order is different at each reload</b>&nbsp;:</p>
<ol>
<li><font style="color: green;">Inline HEAD deferred</font>
</li>
<li>Inline HEAD
</li>
<li><font style="color: green;">External HEAD deferred (script1.js)</font>
</li>
<li>External HEAD (script2.js)
</li>
<li><font style="color: green;">Inline BODY deferred</font>
</li>
<li>Inline BODY
</li>
<li><font style="color: green;">External BODY deferred (script7.js)</font>
</li>
<li><font style="color: green;">Deferred dynamic DOM insertion of a script (script5.js)</font>
</li>
<li><font style="color: green;">Dynamic DOM insertion of a deferred script (script4.js)</font>
</li>
<li><font style="color: green;">Deferred dynamic DOM insertion of a deferred script (script6.js)</font>
</li>
<li>Dynamic DOM insertion of a script (script3.js)
</li>
<li>External BODY (script8.js)
</li>
<li>DOMContentLoaded
</li>
<li>Body onLoad
</li>
</ol>
</li>
</ul>
<ul>
<li> <b>The <tt>defer</tt> attribute behavior in the Opera 10.00 Beta browser</b>:</p>
<ol>
<li><font style="color: green;">Inline HEAD deferred</font>
</li>
<li>Inline HEAD
</li>
<li><font style="color: green;">External HEAD deferred (script1.js)</font>
</li>
<li>External HEAD (script2.js)
</li>
<li>Dynamic DOM insertion of a script (script3.js)
</li>
<li><font style="color: green;">Dynamic DOM insertion of a deferred script (script4.js)</font>
</li>
<li><font style="color: green;">Deferred dynamic DOM insertion of a script (script5.js)</font>
</li>
<li><font style="color: green;">Deferred dynamic DOM insertion of a deferred script (script6.js)</font>
</li>
<li><font style="color: green;">Inline BODY deferred</font>
</li>
<li>Inline BODY
</li>
<li><font style="color: green;">External BODY deferred (script7.js)</font>
</li>
<li>External BODY (script8.js)
</li>
<li>DOMContentLoaded
</li>
<li>Body onLoad
</li>
</ol>
</li>
</ul>
<p>We hope that this has been a useful introduction to how the <code>defer</code> attribute works in Firefox 3.5.  The tests above will also help you predict behavior in other browsers as well.</p>
<p><strong>Resources</strong></p>
<ul>
<li> The fixed bug 28293 &#8211; (defer) scripts with defer attribute not deferred&nbsp;: <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=28293" class="external text" title="https://bugzilla.mozilla.org/show_bug.cgi?id=28293" rel="nofollow">bug 28293</a>
<li> The &#8220;JavaScript: Defer Execution&#8221; article on the WebsiteOptimization website&nbsp;: <a href="http://www.websiteoptimization.com/speed/tweak/defer/" class="external free" title="http://www.websiteoptimization.com/speed/tweak/defer/" rel="nofollow">http://www.websiteoptimization.com/speed/tweak/defer/</a>
<li> The <tt>script</tt> article on Mozilla Developer Center&nbsp;: <a href="https://developer.mozilla.org/En/HTML/Element/Script" class="external free" title="https://developer.mozilla.org/En/HTML/Element/Script" rel="nofollow">https://developer.mozilla.org/En/HTML/Element/Script</a>
<li> The &#8220;<tt>script</tt> element&#8221; part of the HTML 5 Draft&nbsp;: <a href="http://www.whatwg.org/specs/web-apps/current-work/#script" class="external free" title="http://www.whatwg.org/specs/web-apps/current-work/#script" rel="nofollow">http://www.whatwg.org/specs/web-apps/current-work/#script</a>
<li> The &#8220;Parsing HTML documents&nbsp;: the end&#8221; part of the HTML 5 Draft&nbsp;: <a href="http://www.whatwg.org/specs/web-apps/current-work/#the-end" class="external free" title="http://www.whatwg.org/specs/web-apps/current-work/#the-end" rel="nofollow">http://www.whatwg.org/specs/web-apps/current-work/#the-end</a>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/06/defer/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>creating pop art with html5 video</title>
		<link>http://hacks.mozilla.org/2009/06/pop-art-video/</link>
		<comments>http://hacks.mozilla.org/2009/06/pop-art-video/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 23:42:16 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Firefox 3.5]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=932</guid>
		<description><![CDATA[This post is by Felipe Gomez, a long-time Mozilla contributor and really awesome dude. Felipe attends school in Brazil. This demo contains another interesting effect that can be done with the HTML5 elements present in Firefox 3.5. What better way to create a cool effect than mixing the open web with pop art? This demo [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post is by <a href="http://felipe.wordpress.com/">Felipe Gomez</a>, a long-time Mozilla contributor and really awesome dude.  Felipe attends school in Brazil.</em></p>
<p>This demo contains another interesting effect that can be done with the HTML5 elements present in Firefox 3.5.  What better way to create a cool effect than mixing the open web with pop art?  This demo uses only JavaScript, &lt;video&gt; and &lt;canvas&gt;.  We&#8217;ll use them to create an effect similar to the famous Andy Warhol style art on a live video.</p>
<div align="center" style="font-size: 120%"><a target="_blank" href="http://grad.icmc.usp.br/~felipc/videotag/video.xhtml">View the Demo in Firefox 3.5<img src="http://hacks.mozilla.org/wp-content/uploads/2009/06/pop-art.png" width="500"/></a></div>
<p>The effect is quite simple. What we want to do is to create a stamp effect based on the brightness of the image. We calculate the brightness of each pixel and separate them into 3 groups, from darkest to brightest. Them, for each of our four frames we use a different color palette to convert the original pixels into our desired colors for the best effect.</p>
<p><img src="http://grad.icmc.usp.br/~felipc/videotag/article/colortable.png"/></p>
<p>With that, we already have a cool effect, but it lacks a bit of detail:</p>
<p><img src="http://grad.icmc.usp.br/~felipc/videotag/article/firstversion.png"/></p>
<p>So we mix our colors with 30% of the original image, and now we have the final version, with more shades of color while preserving the nice colorization in Andy Warhol style.</p>
<p><img src="http://grad.icmc.usp.br/~felipc/videotag/article/finalversion.png"/></p>
<p>We can access the pixels of each frame of the video using &lt;video&gt; and &lt;canvas&gt;, creating a live effect while the video plays.</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/06/pop-art-video/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>the text-shadow spotlight</title>
		<link>http://hacks.mozilla.org/2009/06/text-shadow-spotlight/</link>
		<comments>http://hacks.mozilla.org/2009/06/text-shadow-spotlight/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 04:55:12 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[35 Days]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Firefox 3.5]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=914</guid>
		<description><![CDATA[Zachary Johnson has put together another fun demo. He&#8217;s using some JavaScript and the new text-shadow property to build a spotlight effect. It&#8217;s embedded below. If you can&#8217;t view it, click through to his post. View the Demo in Firefox 3.5]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zachstronaut.com/posts/2009/06/22/css-text-shadow-lighting-demo.html">Zachary Johnson has put together another fun demo</a>.  He&#8217;s using some JavaScript and the new <code><a href="http://hacks.mozilla.org/2009/06/text-shadow/">text-shadow</a></code> property to build a spotlight effect.  It&#8217;s embedded below.  If you can&#8217;t view it, <a href="http://www.zachstronaut.com/posts/2009/06/22/css-text-shadow-lighting-demo.html">click through to his post</a>.</p>
<div align="center" style="font-size: 120%"><a target="_blank" href="http://www.zachstronaut.com/posts/2009/06/22/css-text-shadow-lighting-demo.html">View the Demo in Firefox 3.5</a><br/><br />
<iframe src="http://www.zachstronaut.com/lab/text-shadow-box/text-shadow-box.html" width="500" height="408" scrolling="no"></iframe>
</div>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/06/text-shadow-spotlight/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>

