<?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>The CSS Ninja &#187; html5</title>
	<atom:link href="http://www.thecssninja.com/category/html5/feed" rel="self" type="application/rss+xml" />
	<link>http://www.thecssninja.com</link>
	<description>All things CSS, Javascript &#38; xhtml</description>
	<lastBuildDate>Mon, 30 Aug 2010 10:21:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Drag out files like Gmail</title>
		<link>http://www.thecssninja.com/javascript/gmail-dragout</link>
		<comments>http://www.thecssninja.com/javascript/gmail-dragout#comments</comments>
		<pubDate>Mon, 16 Aug 2010 12:53:42 +0000</pubDate>
		<dc:creator>The Css Ninja</dc:creator>
				<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=703</guid>
		<description><![CDATA[Google in their quest to keep me busy in trying to figure out how they do their innovative features in Gmail are at it again. First it was drag and drop uploading which used a clever trick to make it work in Chrome which currently doesn&#8217;t support the FileReader in their stable release. Now they&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>Google in their quest to keep me busy in trying to figure out how they do their innovative features in Gmail are at it again. First it was <a href="http://www.thecssninja.com/javascript/gmail-upload ">drag and drop uploading</a> which used a clever trick to make it work in Chrome which currently doesn&#8217;t support the FileReader in their stable release. Now they&#8217;ve added the ability to drag out attachments to your file system, allowing you to bypass the usual method of the save dialog.<span id="more-703"></span></p>
<p>While the first feature of drag and drop uploading I figured out quite easily, this drag out feature was a doozy.</p>
<h2 class="subtitle02">How did I figure it out?</h2>
<p>There were two clues which got me started. One it only works in Chrome so it had to be an extension to the current Drag and Drop API. Two, after some poking around in gmail, there was a custom attribute on the attachment link called download_url which colon separated the attachments mime type, file name and download link.</p>
<p>Since Gmails JavaScript is obfuscated to within in an inch of its life there was no easy way to attach the built in debugger to anything that might give it away. So I tried downloading the script and running it through various unobfuscaters which made it format nicely but I still had to work with function names like vHG etc.</p>
<p>My last hope was <a href="http://code.google.com/p/chromium/issues/list">chromiums bug tracker</a> and searching to see if any bugs or feature requests were filed that could help give it away. I knew the download_url attribute played a role and it would be set using setData method on the dataTransfer object. So I searched high and low on Chromiums bug tracker for matches to &#8220;download_url&#8221;, &#8220;downloadurl&#8221; &#038; &#8220;downloadurl setData&#8221; nothing nada, zip. So I turned to the <a href="https://bugs.webkit.org/">webkit bug tracker</a>, still nothing! So I thought maybe Mozilla had discussed it on their bug tracker, a long shot but worth a try. Bingo! This <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=570164">bug</a> led me to this <a href="https://bugs.webkit.org/show_bug.cgi?id=31090">bug</a>, on webkits bug tracker don&#8217;t ask why the search didn&#8217;t bring this up, and then onto this <a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-August/022118.html">proposal</a>. We&#8217;re in business!</p>
<h2 class="subtitle02">How does it work?</h2>
<p>So we&#8217;ve found the details let&#8217;s play with it.</p>
<div class="resources01"><a target="_blank" class="demo" title="How to drag out files like gmail" href="http://www.thecssninja.com/demo/gmail_dragout/">View a live demo</a> <a target="_blank" class="demo source" title="Download the source of the Gmail drag out demo" href="http://www.thecssninja.com/demo/gmail_dragout/gmail_dragout.zip">Download the source files</a></div>
<p>Update: I&#8217;ve rolled out drag to desktop across my site for all my demo source files. If you&#8217;re using Chrome 5+ just drag the &#8220;Download the source files&#8221; link to your desktop!</p>
<p>The above demo will, in Chrome 5+, allow you to drag any of the items to your desktop and save them without having to go through the usual save dialog process.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> file <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;dragout&quot;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
file.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;dragstart&quot;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    evt.<span style="color: #660066;">dataTransfer</span>.<span style="color: #660066;">setData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;DownloadURL&quot;</span><span style="color: #339933;">,</span>fileDetails<span style="color: #009900;">&#41;</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>From the code above you attach an ondragstart event listener to something you want to &#8220;drag out&#8221; and save to your file system. On the dragstart event you set the data using the new &#8220;DownloadURL&#8221; type and pass file information to it.</p>
<p>In order to pass the correct information to the event we access the download_url attribute and use that for our setData call. I&#8217;ve made one change that is slightly different to how Gmail sets and gets the attribute.</p>

<div class="wp_syntax"><div class="code"><pre class="htrml4strict" style="font-family:monospace;">&lt;a href=&quot;Eadui.ttf&quot; id=&quot;dragout&quot; draggable=&quot;true&quot; data-downloadurl=&quot;
    application/octet-stream
    :Eadui.ttf
    :http://thecssninja.com/gmail_dragout/Eadui.ttf&quot;&gt;Font file&lt;/a&gt;</pre></div></div>

<p>Instead of creating a new attribute I have instead used the new <a href="http://www.w3.org/TR/html5/common-dom-interfaces.html#domstringmap-0">custom data attributes</a> specified in the HTML5 spec. While not officially supported by Chrome yet we can still use it and add a simple test for support and fork the code either way.</p>
<p>The custom attribute needs three things specified that are separated by colons in order for it to work. The files mime type, the name you wish it to be saved as (this can be anything) and the url to where the file can be downloaded from.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> fileDetails;
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> file.<span style="color: #660066;">dataset</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;undefined&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Grab it the old way</span>
    fileDetails <span style="color: #339933;">=</span> file.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;data-downloadurl&quot;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    fileDetails <span style="color: #339933;">=</span> file.<span style="color: #660066;">dataset</span>.<span style="color: #660066;">downloadurl</span>;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Above I do a check to see if the element supports the dataset attribute if not use getAttribute to grab the value.</p>
<h2 class="subtitle02">A cool finding</h2>
<p>Playing around with this new functionality I did find a cool side effect that if I drag a file that&#8217;s set the DownloadURL type on the setData method into a page using Firefox 3.6+ that will capture a drop event the dataTransfer file attribute will act as though it&#8217;s captured a local file and can be manipulated with the FileAPI e.g. In my <a href="http://labs.thecssninja.com/font_dragr/">font dragr</a> web app if I drag a font file that&#8217;s been attached to an email it will render the font as though I&#8217;ve dragged it from my local file system! Doing the same with Chrome 6, which also supports file attribute on the dataTransfer property, will ignore the drop.</p>
<h2 class="subtitle02">Predicting the next challenge from Google</h2>
<p>So what do I think the Gmail team will do next? Since they announced, and are now starting, their 6 week release cycle of chrome. I foresee the ability to upload folders not just individual files, being able to capture a photo from your web cam straight into an embedded picture using the proposed <a href="http://www.w3.org/TR/html-media-capture/">media capture proposal</a>. Whatever it is I&#8217;m sure it&#8217;ll knock everyone&#8217;s socks off and make me rack my brain in trying to figure it out.</p>
<p class="shorty01">Short URL: <a href="http://cssn.in/ja/028">http://cssn.in/ja/028</a></p>
<div class="clear">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/gmail-dragout/feed</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Is that a Speedo in your pocket?</title>
		<link>http://www.thecssninja.com/javascript/pocket-speedo</link>
		<comments>http://www.thecssninja.com/javascript/pocket-speedo#comments</comments>
		<pubDate>Sat, 13 Mar 2010 04:11:25 +0000</pubDate>
		<dc:creator>The Css Ninja</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=623</guid>
		<description><![CDATA[Why yes it is&#8230; I&#8217;ve been sitting on this little idea for a while and as a bit of fun I finally got around to putting it together and properly testing it. Basically on an iPhone with geolocation support (3.0+), I have set up a little web app that will get the speed from the [...]]]></description>
			<content:encoded><![CDATA[<p>Why yes it is&#8230;</p>
<p>I&#8217;ve been sitting on this little idea for a while and as a bit of fun I finally got around to putting it together and properly testing it. Basically on an iPhone with geolocation support (3.0+), I have set up a little web app that will get the speed from the GPS and move the speedometer needle according to your current speed in kilometres.<span id="more-623"></span></p>
<h2 class="subtitle02">But speed returns null?</h2>
<p>When I originally played around with the <a href="http://www.thecssninja.com/javascript/geolocation-iphone">geolocation API on the iPhone</a> checking the speed attribute always returned null, what I failed to actually do was test this value while actually moving. The speed attribute is capable of getting speeds as low as 2km/h so walking with the phone will start to register speeds.</p>
<div class="resources01"><a target="_blank" class="demo" title="Pocket speedo web app" href="http://labs.thecssninja.com/pocket_speedo/">View a live demo</a> <a target="_blank" class="demo source" title="Download the source of the Pocket speedo web app demo" href="http://labs.thecssninja.com/pocket_speedo/pocket_speedo.zip">Download the source files</a></div>
<h2 class="subtitle02">So we can get the speed let&#8217;s use it</h2>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>navigator.<span style="color: #660066;">geolocation</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    navigator.<span style="color: #660066;">geolocation</span>.<span style="color: #660066;">getCurrentPosition</span><span style="color: #009900;">&#40;</span>getSpeed<span style="color: #339933;">,</span> handleError<span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">function</span> getSpeed<span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    updateStats<span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#41;</span>;
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> coordsListener <span style="color: #339933;">=</span> navigator.<span style="color: #660066;">geolocation</span>.<span style="color: #660066;">watchPosition</span><span style="color: #009900;">&#40;</span>updateStats<span style="color: #339933;">,</span> handleError<span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Here we get the current position and upon success tell it to execute the <code>getSpeed</code> function. Inside that function I call another function which does all the hard work which I&#8217;ll explain below, next I call the watchPosition method and pass it the same updateStats function so we can get constant updates from the GPS about our speed and adjust our speedometer needle.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> updateStats<span style="color: #009900;">&#40;</span>pos<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> speed <span style="color: #339933;">=</span> pos.<span style="color: #660066;">coords</span>.<span style="color: #660066;">speed</span><span style="color: #339933;">,</span>
         speedVariation <span style="color: #339933;">=</span> <span style="color: #CC0000;">3.6</span><span style="color: #339933;">,</span>
         currentSpeed <span style="color: #339933;">=</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>speed<span style="color: #339933;">*</span>speedVariation<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
         angleVariation <span style="color: #339933;">=</span> <span style="color: #CC0000;">0.8</span><span style="color: #339933;">,</span>
         initSpeedAngle <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">105</span><span style="color: #339933;">,</span>
         speedAngle <span style="color: #339933;">=</span> initSpeedAngle <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>currentSpeed <span style="color: #339933;">*</span> angleVariation<span style="color: #009900;">&#41;</span>;
&nbsp;
    needle.<span style="color: #660066;">style</span>.<span style="color: #660066;">webkitTransitionDuration</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'500ms'</span>;
    needle.<span style="color: #660066;">style</span>.<span style="color: #660066;">webkitTransform</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;rotate(&quot;</span> <span style="color: #339933;">+</span> speedAngle <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;deg)&quot;</span>;
    speedVal.<span style="color: #660066;">textContent</span> <span style="color: #339933;">=</span> currentSpeed <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;km/h&quot;</span>;
<span style="color: #009900;">&#125;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> speed <span style="color: #339933;">=</span> pos.<span style="color: #660066;">coords</span>.<span style="color: #660066;">speed</span><span style="color: #339933;">,</span>
     speedVariation <span style="color: #339933;">=</span> <span style="color: #CC0000;">3.6</span><span style="color: #339933;">,</span>
     currentSpeed <span style="color: #339933;">=</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>speed<span style="color: #339933;">*</span>speedVariation<span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>When I get my initial position and my subsequent position updates through the watchPosition method, I access the current speed, in metres, through the coords attribute. To work out the rough speed I times the speed by the speedVariation var which is 3.6 which will give me the speed in km/h, for miles/hour the variation is 2.237. I do this calculation inside the Math.round function so I get a whole rounded number with no decimal places.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> angleVariation <span style="color: #339933;">=</span> <span style="color: #CC0000;">0.8</span><span style="color: #339933;">,</span>
     initSpeedAngle <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">105</span><span style="color: #339933;">,</span>
     speedAngle <span style="color: #339933;">=</span> initSpeedAngle <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>currentSpeed <span style="color: #339933;">*</span> angleVariation<span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>To calculate the corresponding angle to the equivalent speed we are currently getting from the GPS I had to work out the angle variation per kilometre. I knew there was 16&deg; between each 20km/h block. The angle variation then could be worked out to be 0.8&deg; per kilometre, I also needed to have the starting angle of 0km/h and that is exactly -105&deg; from our middle point. With those 2 values plus the currentSpeed I could then work out the angle so the speedometer needle could be correctly rotated to the right spot.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">needle.<span style="color: #660066;">style</span>.<span style="color: #660066;">webkitTransitionDuration</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'500ms'</span>;
needle.<span style="color: #660066;">style</span>.<span style="color: #660066;">webkitTransform</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;rotate(&quot;</span> <span style="color: #339933;">+</span> speedAngle <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;deg)&quot;</span>;
speedVal.<span style="color: #660066;">textContent</span> <span style="color: #339933;">=</span> currentSpeed <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;km/h&quot;</span>;</pre></div></div>

<p>To move the needle when the speed changes and to make that change animate between the two points I use CSS3 transforms and transitions. By setting our <code>-webkit-transition-duration</code> any changes done using the <code>-webkit-transform</code> property will be transitioned smoothly between the current angle and the new angle. The last bit is just to print out the speed so we can compare the needle position to the actual speed being read.</p>
<h2 class="subtitle02">Some CSS3</h2>
<p>I&#8217;ve added some extra CSS3 to the speedo including animations and box-shadow</p>

<div class="wp_syntax"><div class="code"><pre class="css css" style="font-family:monospace;"><span style="color: #cc00cc;">#dial</span> <span style="color: #cc00cc;">#needle</span>
<span style="color: #00AA00;">&#123;</span>
    -moz-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #933;">1px</span> <span style="color: #933;">1px</span> <span style="color: #933;">3px</span> <span style="color: #cc00cc;">#ffd712</span><span style="color: #00AA00;">,</span> <span style="color: #933;">-1px</span> <span style="color: #933;">-1px</span> <span style="color: #933;">3px</span> <span style="color: #cc00cc;">#feb018</span>;
    -webkit-box-shadow<span style="color: #00AA00;">:</span> <span style="color: #933;">1px</span> <span style="color: #933;">1px</span> <span style="color: #933;">3px</span> <span style="color: #cc00cc;">#ffd712</span><span style="color: #00AA00;">,</span> <span style="color: #933;">-1px</span> <span style="color: #933;">-1px</span> <span style="color: #933;">3px</span> <span style="color: #cc00cc;">#feb018</span>;
&nbsp;
    -webkit-animation-name<span style="color: #00AA00;">:</span> speedorgo;
    -webkit-animation-duration<span style="color: #00AA00;">:</span> 2s;
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>To add the slight glow around speedo needle by using a dual box-shadow so it appears on both edges. The <a href="http://webkit.org/blog/324/css-animation-2/">-webkit-animation-</a> properties allows me to specify a predefined animation that can be applied to different elements.</p>

<div class="wp_syntax"><div class="code"><pre class="css css" style="font-family:monospace;"><span style="color: #a1a100;">@-webkit-keyframes speedorgo {</span>
    <span style="color: #933;">0%</span>   <span style="color: #00AA00;">&#123;</span> -webkit-transform<span style="color: #00AA00;">:</span> rotate<span style="color: #00AA00;">&#40;</span>-105deg<span style="color: #00AA00;">&#41;</span>; <span style="color: #00AA00;">&#125;</span>
    <span style="color: #933;"><span style="color: #cc66cc;">20</span>%</span>  <span style="color: #00AA00;">&#123;</span> -webkit-transform<span style="color: #00AA00;">:</span> rotate<span style="color: #00AA00;">&#40;</span>41deg<span style="color: #00AA00;">&#41;</span>; <span style="color: #00AA00;">&#125;</span>
    <span style="color: #933;"><span style="color: #cc66cc;">100</span>%</span> <span style="color: #00AA00;">&#123;</span> -webkit-transform<span style="color: #00AA00;">:</span> rotate<span style="color: #00AA00;">&#40;</span>-105deg<span style="color: #00AA00;">&#41;</span>; <span style="color: #00AA00;">&#125;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>By using webkits @-webkit-keyframes rule and giving it a unique name which we applied to our speedo needle in the previous CSS using the -webkit-animation-name property we can do some pretty cool animations. Inside this animation rule I set up the animation to rotate any element it&#8217;s applied to to go from -105&deg; to 41&deg; then back to -105&deg; when you rotate the phone into landscape mode it&#8217;ll trigger the animation and do the animation over a 2 second period.</p>
<h2 class="subtitle02">Pfft! Who needs the internet&#8230;</h2>
<p>Well technically we initially need the internet but after we load the web app for the first time no connection is required for this to work. By taking advantage of the <a href="http://www.thecssninja.com/javascript/how-to-create-offline-webapps-on-the-iphone">application cache</a> we can store all our assets on the phone, and since the GPS can still work without a network connection the speedo will still function fine.</p>
<h2 class="subtitle02">A clear sky</h2>
<p>In order to pick up a consistent speed reading from the GPS you will need to have the phone with a good clear view of the sky. I&#8217;ve found when using it while walking the speed reading will fluctuate quite a lot, going from 0 to the actual speed your doing and back to 0 and back up etc. It becomes more reliable the faster you are moving. I&#8217;m sure with some adjustments to the code getting a more consistent speed reading will be possible.</p>
<h2 class="subtitle02">Go forth and hack</h2>
<p>We have a fun little tech demo that shows what can with some simple JavaScript and CSS3. I don&#8217;t see why this couldn&#8217;t work on an Android, Palm Pre or a Blackberry with the new webkit browser, all of these should or should very soon support the features required for the web app to work. If you get this working in any other smart phone please leave a comment.</p>
<p class="shorty01">Short URL: <a href="http://cssn.in/ja/024">http://cssn.in/ja/024</a></p>
<div class="clear">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/pocket-speedo/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Web Notifications</title>
		<link>http://www.thecssninja.com/javascript/web-notifications</link>
		<comments>http://www.thecssninja.com/javascript/web-notifications#comments</comments>
		<pubDate>Sat, 06 Feb 2010 06:40:58 +0000</pubDate>
		<dc:creator>The Css Ninja</dc:creator>
				<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[editor draft]]></category>
		<category><![CDATA[web notifications]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=584</guid>
		<description><![CDATA[Google Chrome has recently updated their stable release with some extra goodies; probably most notable is the inclusion of @font-face support which is very welcome. Another not so well know proposal by the Chromium team is to have web notifications which was shipped with the stable release (v4.0.249.78). Web Notifications allows users to get updates [...]]]></description>
			<content:encoded><![CDATA[<p>Google Chrome has recently updated their stable release with some extra goodies; probably most notable is the inclusion of @font-face support which is very welcome. Another not so well know proposal by the Chromium team is to have <a href="http://dev.w3.org/2006/webapi/WebNotifications/publish/">web notifications</a> which was shipped with the stable release (v4.0.249.78).<span id="more-584"></span></p>
<p>Web Notifications allows users to get updates on a webpage even if they&#8217;re not looking at it, shown to them through small notification boxes, think <a href="http://growl.info/screenshots.php">growl</a>. This opens up some great potential for the current web apps out there. When you get a new email it could popup a little notification much like our desktop email clients do now or your twitter page could let you know when new @replies have come in, the possibilities are endless.</p>
<p>Interaction with your web app no longer needs the focus of the user to be informed that something has occurred, I know I would find notifications very useful.</p>
<p>Since this is a proposal and neither a working draft nor an agreed upon API, anything written about in this article is almost guaranteed to change. I will however try to make updates when changes are made. We have our <a href="http://code.google.com/p/chromium/issues/detail?id=34961">first bug</a>. If you&#8217;re using the latest dev version (5.0.317.2) Web Notifications will crash the browser, all previous versions still work fine.</p>
<div id="usermessagea" class="cf_info failure"><strong>Update:</strong> Web notifications spec has been updated <a href="#specchange01">see here for changes</a>.</div>
<h2 class="subtitle02">You&#8217;ve got mail</h2>
<p>I&#8217;ll go through a few examples I have put together on how to setup and start using notifications today.</p>
<p><img src="http://www.thecssninja.com/wp-content/uploads/2010/02/notification01.png" alt="First example of Web Notifications in Chrome" title="First example of Web Notifications in Chrome" width="609" height="353" class="article-img main-img" /><br />
<small style="margin: -30px 0pt 0pt; display: block;">This is what a notification looks like using the <code>createNotification()</code> method</small></p>
<div class="resources01"><a target="_blank" class="demo" title="HTML5 web notifications" href="http://www.thecssninja.com/demo/web_notifications/">View live demos</a> <a target="_blank" class="demo source" title="Download the source of the web notification demo" href="http://www.thecssninja.com/demo/web_notifications/web_notifications.zip">Download the source files</a></div>
<p>Everyone loves the classic &#8220;you&#8217;ve got mail&#8221; voice, so let&#8217;s go through how to do that with Chromes Web Notifications.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">TCNWN.<span style="color: #660066;">myNotifications</span> <span style="color: #339933;">=</span> window.<span style="color: #660066;">webkitNotifications</span>;
&nbsp;
TCNWN.<span style="color: #660066;">setup</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>TCNWN.<span style="color: #660066;">myNotifications</span>.<span style="color: #660066;">checkPermission</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// 1 = Permission is uknown so we request permission</span>
        TCNWN.<span style="color: #660066;">myNotifications</span>.<span style="color: #660066;">requestPermission</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>TCNWN.<span style="color: #660066;">myNotifications</span>.<span style="color: #660066;">checkPermission</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> 0<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// 0 = Permission has been granted to show notifications</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>  
        <span style="color: #006600; font-style: italic;">// 2 = Permission has been denied	</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>;</pre></div></div>

<p>A few things are happening here, for notifications to ever work you need to ask the user for permission. So we use the <code>checkPermission()</code> method to see what status web notifications are in and act on the status accordingly. Once permission has been granted notifications can then be used. <strong id="specchange01">Update:</strong> <code>checkPermission()</code> has been changed to <code>permissionLevel()</code> in the spec, this hasn&#8217;t been pushed out in any release of Chrome so <code>checkPermission()</code> still works.</p>
<p>A bizarre bug with web notifications is asking for permission by calling the <code>requestPermission()</code> method within the page will throw a security exception and won&#8217;t display the permission window where the user can either deny, allow or ignore the notifications request. To get around this I have to run the <code>requestPermission()</code> method as either <del datetime="2010-02-08T00:44:29+00:00">a javascript: URL as this code only works when run in the address bar</del> a <code>javascript:</code> link or by using an <code>onclick</code> function, but still cannot be called programatically (see <a href="http://code.google.com/p/chromium/issues/detail?id=31736">Issue 31736</a>). That&#8217;s why you need to click the first link in the demo. Once permission has been granted we no longer need to resort to that god awful hack, hopefully this is fixed ASAP. You&#8217;ll also notice the notifications object is prefixed with webkit, for similar reason why they prefix new CSS3 properties.</p>
<p>Once permission is allowed the <code>requestPermission()</code> method has a callback parameter where we can setup all our notifications. In this case we pass a function to display our got mail message.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">TCNWN.<span style="color: #660066;">gotMail</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>TCNWN.<span style="color: #660066;">myNotifications</span>.<span style="color: #660066;">checkPermission</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> 0<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		TCNWN.<span style="color: #660066;">notification</span> <span style="color: #339933;">=</span> TCNWN.<span style="color: #660066;">myNotifications</span>.<span style="color: #660066;">createNotification</span><span style="color: #009900;">&#40;</span>
			<span style="color: #3366CC;">&quot;http://www.thecssninja.com/demo/web_notifications/icon.png&quot;</span><span style="color: #339933;">,</span>
			<span style="color: #3366CC;">&quot;You've got mail&quot;</span><span style="color: #339933;">,</span>
			<span style="color: #3366CC;">&quot;The CSS Ninja has sent you an email&quot;</span>
		<span style="color: #009900;">&#41;</span>;
		TCNWN.<span style="color: #660066;">notification</span>.<span style="color: #660066;">ondisplay</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> audio <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Audio<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;youvegotmail.mp3&quot;</span><span style="color: #009900;">&#41;</span>;
			audio.<span style="color: #660066;">play</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
			window.<span style="color: #660066;">setTimeout</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;TCNWN.notification.cancel()&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">5000</span><span style="color: #009900;">&#41;</span>;
		<span style="color: #009900;">&#125;</span>
		TCNWN.<span style="color: #660066;">notification</span>.<span style="color: #660066;">show</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
	<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;You need to allow web notifications for this to work&quot;</span><span style="color: #009900;">&#41;</span>;
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>;</pre></div></div>

<p>In the callback function we create our new notification object using <code>createNotification()</code> method which accepts an icon url, title and body text. To display nothing for any one of these parameters passing in empty quotes (&#8220;&#8221;) will work, otherwise it will display undefined. We then attach an <code>ondisplay</code> event listener so we can run some code when the notification displays. For this demo we load an mp3 to play &#8220;you&#8217;ve got mail&#8221; using HTML5 audio. We then create a <code>setTimeout</code> function to close the notification after 5 seconds. Lastly we execute the <code>show()</code> method so the actual notification displays.</p>
<h2 class="subtitle02">Custom notifications</h2>
<p>Along with the <code>createNotification()</code> we also have the <code>createHTMLNotification()</code> method which allows us to pass an url to a html page to be displayed as the notification. The second example on the demo page will load a notification that fetches a new tweet every 15 seconds and dynamically updates the content.</p>
<p><img src="http://www.thecssninja.com/wp-content/uploads/2010/02/notification02.png" alt="The second example using custom notifications method" title="notification02" width="609" height="353" class="article-img main-img" /><br />
<small style="margin: -30px 0pt 0pt; display: block;">Using <code>createHTMLNotification()</code> method, we can pass a url to be loaded in the notification window</small></p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">TCNWN.<span style="color: #660066;">loadTweet</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>TCNWN.<span style="color: #660066;">myNotifications</span>.<span style="color: #660066;">checkPermission</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> 0<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        TCNWN.<span style="color: #660066;">notification</span> <span style="color: #339933;">=</span> TCNWN.<span style="color: #660066;">myNotifications</span>.<span style="color: #660066;">createHTMLNotification</span><span style="color: #009900;">&#40;</span>url<span style="color: #009900;">&#41;</span>;
        TCNWN.<span style="color: #660066;">notification</span>.<span style="color: #660066;">show</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;You need to allow web notifications for this to work&quot;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>;</pre></div></div>

<p>The only difference here is we specify 1 parameter for the <code>createHTMLNotification()</code> method which is the url for the notification we wish to display. I won&#8217;t be going into detail on loading the tweets, to touch on it quickly it uses a JSONP call.</p>
<h2 class="subtitle02">Some observations</h2>
<p>Since playing around with this and trying to figure out how it works I have come across some quirks/bugs. </p>
<p>If you go to the first example that does the &#8220;you&#8217;ve got mail&#8221; notification and click back in the browser before the audio finishes playing, it will stop the audio and the setTimeout function that closes the notification will never fire.</p>
<p>As discussed earlier in the article you can&#8217;t actually request permission to display web notifications from within your code, you have to create a <code>javascript:</code> link that will execute the code. I tried programmatically changing the window.location to a JavaScript url which would fire the <code>requestPermission()</code> method but that wouldn&#8217;t work.</p>
<p>Bringing focus back to the window that called the notification, as stated in the proposal by using <code>window.opener.focus()</code>, doesn&#8217;t currently work.</p>
<p>Finally the last quirk I came across with the twitter demo is that for some tweets with long unbroken strings it will cause the notification window to flicker uncontrollably. Setting <code>white-space: pre-wrap</code> to force long string to be broken can help fix the issue.</p>
<h2 class="subtitle02">Looks promising</h2>
<p>Web notifications do look like a promising addition to the browser land and can create some really useful feedback to a user. With today’s web applications pushing the limits of the current technology available in the browser, I&#8217;m sure many developers will embrace web notifications in clever and exciting new ways.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/web-notifications/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>The File API has changed</title>
		<link>http://www.thecssninja.com/javascript/fileapi</link>
		<comments>http://www.thecssninja.com/javascript/fileapi#comments</comments>
		<pubDate>Thu, 10 Dec 2009 06:53:52 +0000</pubDate>
		<dc:creator>The Css Ninja</dc:creator>
				<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=530</guid>
		<description><![CDATA[Recently I have been touting how awesome and revolutionary the File API is through a few demo&#8217;s. After some feedback on webapps mailing list there have been some major changes to the API and how it works. I have updated my previous drag and drop upload demo to reflect the API changes, as of Firefox [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I have been touting how awesome and revolutionary the <a href="http://www.w3.org/TR/FileAPI/">File API</a> is through a <a href="http://www.thecssninja.com/javascript/drag-and-drop-upload">few</a> <a href="http://www.thecssninja.com/javascript/font-dragr">demo&#8217;s</a>. After some feedback on webapps mailing list there have been some major changes to the API and how it works.<span id="more-530"></span></p>
<p>I have updated my <a href="http://www.thecssninja.com/demo/drag-drop_upload/">previous drag and drop upload demo</a> to reflect the API changes, as of Firefox 3.6b3 the API supports both the original API and the updated one. The older model will eventually be dropped, it&#8217;s only in there for legacy purposes. To use the demo you will need <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.6</a> installed. You can also watch the <a href="http://screenr.com/i18">screencast of it in action</a>.</p>
<div class="resources01"><a target="_blank" class="demo" title="Drag and drop files from your computer and they're uploaded using a XMLHttpRequest" href="http://www.thecssninja.com/demo/drag-drop_upload/v2/">View a live demo</a> <a target="_blank" class="demo source" title="Download the source of the Drag and drop upload demo" href="http://www.thecssninja.com/demo/drag-drop_upload/v2/drag-drop_upload.zip">Download the source files</a></div>
<p>The biggest change is with the file handling, it is now processed asynchronously with progress events so we can attach listeners. The advantage of this is if a user drags in many files or a large file the UI won&#8217;t be locked up while it&#8217;s processing the data, much like XmlHttpRequest works.</p>
<h2 class="subtitle02">The File object</h2>
<p>The <a href="https://developer.mozilla.org/en/DOM/File">File object</a> has been updated to reflect the new specs changes and has deprecated all the previous methods we used to get the file in various formats e.g. <em>getAsDataUrl()</em>, <em>getAsText()</em>, <em>getAsBinary()</em>. We now handle these methods in the new <a href="https://developer.mozilla.org/en/DOM/FileReader">FileReader object</a>.</p>
<p>It has also renamed the 2 properties for accessing the files name and size from <em>fileName</em>/<em>fileSize</em> to <em>name</em>/<em>size</em> respectively.</p>
<h2 class="subtitle02">The FileReader object</h2>
<p>This new object allows us to asynchronously read the contents of a file from a drop event.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> reader <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> FileReader<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
reader.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;loadend&quot;</span><span style="color: #339933;">,</span> TCNDDU.<span style="color: #660066;">buildImageListItem</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>;
reader.<span style="color: #660066;">readAsDataURL</span><span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>Instead of locking the UI while we wait for it to loop through all the dropped files and then convert them to a DataUrl. The <em>FileReader</em> does this asynchronously. We attach to the <em>onloadend</em> event handler which will fire once the current file has been read into the <em>result</em> attribute. Upon the event firing we then take the event <em>result</em> and add the DataURL to the source of the image to be displayed to the user while it uploads.</p>
<h2 class="subtitle02">Send the binary data</h2>
<p>Once we have the file we send it to be processed for an XHR call so we can upload it to the server. Same as above we need to create a file reader and attach to the <em>onloadend</em> event which we then pass to the <em>sendAsBinary()</em> method.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> getBinaryDataReader <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> FileReader<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
getBinaryDataReader.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;loadend&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>xhr.<span style="color: #660066;">sendAsBinary</span><span style="color: #009900;">&#40;</span>evt.<span style="color: #660066;">target</span>.<span style="color: #660066;">result</span><span style="color: #009900;">&#41;</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>;
getBinaryDataReader.<span style="color: #660066;">readAsBinaryString</span><span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>Similar code we used for the image display handling, but we use the <em>readAsBinaryString()</em> method to return the files binary data for uploading.</p>
<h2 class="subtitle02">Further reading</h2>
<p>As the 3.6 final release date is coming closer Mozilla has been ramping up demos and documentation about the File API. Some good documentation on <a href="https://developer.mozilla.org/en/Using_files_from_web_applications">handling files in web applications</a>.</p>
<p>The <a href="http://hacks.mozilla.org/">hacks blog</a> has recently put up some <a href="http://hacks.mozilla.org/2009/12/w3c-fileapi-in-firefox-3-6/">great information about the File API</a> along with an excellent demo extracting <a href="http://hacks.mozilla.org/2009/12/firefox-36-fileapi-demo-reading-exif-data-from-a-local-jpeg-file/">EXIF data from an image</a>. </p>
<p>Now we just need webkit to push out the File API to their nightly builds.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/fileapi/feed</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>Font Dragr: A drag and drop font tester</title>
		<link>http://www.thecssninja.com/javascript/font-dragr</link>
		<comments>http://www.thecssninja.com/javascript/font-dragr#comments</comments>
		<pubDate>Tue, 13 Oct 2009 07:39:27 +0000</pubDate>
		<dc:creator>The Css Ninja</dc:creator>
				<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[@font-face]]></category>
		<category><![CDATA[Firefox]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=484</guid>
		<description><![CDATA[After playing with the new file API draft spec available in Firefox 3.6 with my drag and drop upload article. I had another idea when I was playing with custom fonts, @font-face, in the browser. What if you could drag an drop a font file (otf, ttf, svg, woff) from your desktop into the browser [...]]]></description>
			<content:encoded><![CDATA[<p>After playing with the new file API draft spec available in Firefox 3.6 with my <a href="http://www.thecssninja.com/javascript/drag-and-drop-upload">drag and drop upload article</a>. I had another idea when I was playing with custom fonts, @font-face, in the browser. What if you could drag an drop a font file (otf, ttf, svg, woff) from your desktop into the browser and have text rendered on the fly using any available valid font.<span id="more-484"></span></p>
<p>In conjunction with Mozilla&#8217;s official announcement for the <a href="http://hacks.mozilla.org/2009/10/woff/">Web Open Font Format (WOFF)</a> and continuing the wanky tradition of removing vowels from web app names, I introduce font dragr.</p>
<div class="resources01"><a href="http://labs.thecssninja.com/font_dragr/" title="HTML5 web app for testing custom font files, drag and drop font testing" class="demo" target="_blank">View the web app</a></div>
<h2 class="subtitle02">What is it?</h2>
<p><a href="http://labs.thecssninja.com/font_dragr/" title="HTML5 web app for testing custom font files, drag and drop font testing" class="demo" target="_blank">Font dragr</a> is an experimental web app that uses HTML5 &#038; CSS3 to create a useful standalone web based application for testing custom fonts, once you visit it for the first time you don&#8217;t need to be online to use it after the initial visit. It allows you, in Firefox 3.6+, to drag and drop font files from your file system into the drop area. The browser will then create a data URL encoded copy to use in the page and render the content in the dropped font.</p>
<h2 class="subtitle02">See it in action</h2>
<p><object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='609' height='366'><param name='movie' value='http://screenr.com/Content/assets/screenr_0817090731.swf' /><param name='flashvars' value='i=20449' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_0817090731.swf' flashvars='i=20449' allowFullScreen='true' width='609' height='366' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object></p>
<h2 class="subtitle02">Encoded files</h2>
<p>I went about testing out a few theories on how I could dynamically add a dropped font to be used in the page. I saw this article on embedding <a href="http://robert.accettura.com/blog/2009/07/03/optimizing-font-face-for-performance/">custom fonts using a base64</a> encoded string. In the file API we have the <em>getAsDataURL()</em> method to return a file as a data url for using in a page, I used the same method in my <a href="http://www.thecssninja.com/demo/drag-drop_upload/" class="external-link">drag drop upload demo</a> to display the images.</p>
<h2 class="subtitle02">Inserting into the stylesheet</h2>
<p>The next hurdle was taking that data url and inserting it into the style sheet referenced on the page.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> styleSheet <span style="color: #339933;">=</span> document.<span style="color: #660066;">styleSheets</span><span style="color: #009900;">&#91;</span>0<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	fontFaceStyle <span style="color: #339933;">=</span> 
	<span style="color: #3366CC;">&quot;@font-face{font-family: CustomFont;src:url(&quot;</span><span style="color: #339933;">+</span>files<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">getAsDataURL</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;);}&quot;</span>;
&nbsp;
styleSheet.<span style="color: #660066;">insertRule</span><span style="color: #009900;">&#40;</span>fontFaceStyle<span style="color: #339933;">,</span> 0<span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>In the above code we reference our style sheet using <em>document.styleSheet[0]</em>. We then build our style from the dropped file that we want to insert, notice the <em>files[i].getAsDataURL()</em> is where the magic happens and the current file is converted to a dataURL. We then use the <em>insertRule</em> method to prepend it to the style sheet.</p>
<h2 class="subtitle02">Getting file information and applying the font</h2>
<p>We also get the <em>fileSize</em> of the font and the <em>fileName</em> so we can populate the list item that we create on drop. With the file name I also do some crude validation and I also sanitise the file name in case there is any non alpha numeric characters, it will stop the font from being applied to the container if we have invalid characters.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">acceptedFileExtensions <span style="color: #339933;">=</span> <span style="color: #009966; font-style: italic;">/^.*\.(ttf|otf|svg|woff)$/i</span>
&nbsp;
droppedFileName <span style="color: #339933;">=</span> droppedFullFileName.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\..+$/</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span>;
droppedFileName <span style="color: #339933;">=</span> droppedFileName.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\W+/g</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;-&quot;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>For the validation I have a regexp of accepted file extensions so it will only accept font types that work in Firefox. I remove the file extension from the fileName and then replace any non alphanumeric characters, <strong>\W</strong>, with hyphens.</p>
<p>Once we have a semi-friendly name we use that to apply the font family style to the newly created list item and the content container.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">displayContainer.<span style="color: #660066;">style</span>.<span style="color: #660066;">fontFamily</span> <span style="color: #339933;">=</span> droppedFileName;</pre></div></div>

<h2 class="subtitle02">International font friendly</h2>
<p>Dragging in an international based font file will cause the text to render in a default sans serif font. To fix that I have made the main content area editable, you can type some text in your own language which should render in your international based font, this hasn&#8217;t been thoroughly tested. I would appreciate any feedback on using this demo with international fonts.</p>
<h2 class="subtitle02">Work in progress</h2>
<p>I am still very much actively refining and adding more features to this web app. If you have any of your own features/ideas please feel free to suggest/request any improvements or changes. Some I&#8217;m working on now.</p>
<ul>
<li>Using localStorage object to store users dropped fonts and <del datetime="2009-10-28T06:04:17+00:00">save edits to main content area</del>. Main content edits are now stored in localStorage, hit size limit capacity with dropped fonts will look into webDB for font storage.</li>
<li>Better indicating to the user that the content can be edited</li>
<li>Making the drop area highlight on drag</li>
</ul>
<p>I built this to fill a need I had, to quickly test custom fonts, and the idea has grown in to something much bigger and better than I thought it would be. I can see this as not only something cool to show off where HTML5 is heading but something genuinely useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/font-dragr/feed</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Make IE awesome by turning it into Google Chrome</title>
		<link>http://www.thecssninja.com/javascript/make-ie-awesome</link>
		<comments>http://www.thecssninja.com/javascript/make-ie-awesome#comments</comments>
		<pubDate>Wed, 23 Sep 2009 12:15:15 +0000</pubDate>
		<dc:creator>The Css Ninja</dc:creator>
				<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=455</guid>
		<description><![CDATA[As I&#8217;m sure you all know by now Google made an announcement about their Chrome Frame plugin for IE that turns the Trident rendering engine into the Chrome rendering engine giving IE access to the awesome power that is Chrome. No longer will IE miss out on those awesome new features in CSS3 &#038; HTML5 [...]]]></description>
			<content:encoded><![CDATA[<p>As I&#8217;m sure you all know by now Google made an announcement about their <a href="http://blog.chromium.org/2009/09/introducing-google-chrome-frame.html">Chrome Frame plugin for IE</a> that turns the Trident rendering engine into the Chrome rendering engine giving IE access to the awesome power that is <a href="http://code.google.com/chrome/chromeframe/">Chrome</a>. No longer will IE miss out on those awesome new features in CSS3 &#038; HTML5 the more competent browsers enjoy today such as the soon to be released <a href="http://wave.google.com/">Google Wave</a>.<span id="more-455"></span></p>
<p>I did a post a while back on how <a href="http://www.thecssninja.com/rant/chroming-how-google-is-changing-the-browser">Google Chrome is changing the browser</a>, the landscape is rapidly progressing thanks to Google and the likes of Mozilla, Webkit &#038; Opera. <a href="http://code.google.com/chrome/chromeframe/">This plugin</a> helps push that final frontier into fruition bringing the next set of tools to all major browsers.</p>
<div class="resources01"><a target="_blank" class="demo" title="A demo using canvas that's works in IE with Chrome Frame installed" href="http://www.thecssninja.com/demo/particle_fountain/">View a live demo</a> <a target="_blank" class="demo source" title="Download the source of the canvas demo" href="http://www.thecssninja.com/demo/particle_fountain/particle_fountain.zip">Download the source files</a></div>
<p><small>This demo was slightly modified from the awesome work of http://iterationsix.com/posts/16 particle fountain.</small></p>
<h2 class="subtitle02">How does it work?</h2>
<p>The above demo uses the HTML5 canvas tag to simulate particle effects. If you load this in IE you will be prompted to install Chrome Frame. Setting up a site to make it render using Chrome Frame is a simple meta tag.</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">http-equiv</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;X-UA-Compatible&quot;</span> <span style="color: #000066;">content</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;chrome=1&quot;</span>&gt;</span></pre></div></div>

<p>Look familiar? It&#8217;s the same meta tag that IE uses to force IE8 to render in <a href="http://msdn.microsoft.com/en-au/library/cc817574.aspx" target="_blank">compatibility mode</a>. </p>
<p>If IE goes to a site that has this meta tag it will kick-in and render the page using Chrome Frame giving the full power of Google Chrome in IE. Pretty simple and incredibly powerful.</p>
<p><object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='609' height='366'><param name='movie' value='http://screenr.com/Content/assets/screenr_0817090731.swf' /><param name='flashvars' value='i=14065' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_0817090731.swf' flashvars='i=14065' allowFullScreen='true' width='609' height='366' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object><br />
<small>IE8 vs IE8 with <em>cf:</em> protocol to force use of Chrome Frame</small></p>
<h2 class="subtitle02">Prompt the user to install Chrome Frame</h2>
<p>What if the user doesn&#8217;t know about or have the Chrome Frame installed on their machine? There&#8217;s a solution for that. Using a script available on Google Ajax APIs</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js&quot;</span>&gt;</span> <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span>
CFInstall.check();
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></pre></div></div>

<p>The above code will check if Chrome Frame is installed if not it will prompt the user to install it by loading up an iframe with the Chrome Frame site. The <em>check</em> method gives you quite a <a href="http://code.google.com/chrome/chromeframe/developers_guide.html#CFInstall_check_Options">few options</a> all of them are optional the previous link gives a good run down of all the options and what they do.</p>
<h2 class="subtitle02">Force it</h2>
<p>If your are keen to use it before sites start adding the meta tag you can force the site to render using Chrome Frame by appending the <b>cf:</b> protocol to the beginning of any url e.g. <a href="cf:http://bespin.mozilla.com/">cf:http://bespin.mozilla.com/</a> if loaded in IE with Chrome Frame installed it will force the website to render using the Chrome engine.</p>
<h2 class="subtitle02">Early stages</h2>
<p>Right now this plugin is in early development stages but I&#8217;m sure it will move along rapidly to coincide with Google Wave public release.</p>
<p>This is truly an exciting plugin that opens the flood gates to a massive user base being able to use the latest and greatest web apps.<!--more--></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/make-ie-awesome/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Drag and drop file uploading using JavaScript</title>
		<link>http://www.thecssninja.com/javascript/drag-and-drop-upload</link>
		<comments>http://www.thecssninja.com/javascript/drag-and-drop-upload#comments</comments>
		<pubDate>Wed, 26 Aug 2009 08:52:39 +0000</pubDate>
		<dc:creator>The Css Ninja</dc:creator>
				<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[draganddrop]]></category>
		<category><![CDATA[fileapi]]></category>
		<category><![CDATA[xhr2]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=430</guid>
		<description><![CDATA[With the recent announcement of the File API draft specification being published I&#8217;m sure a lot of people were confused as to what it could really do and why it is truly a powerful API. Firefox&#8217;s latest alpha release of their 3.6 browser, aka Namoroka, is the first to implement this new draft specification. One [...]]]></description>
			<content:encoded><![CDATA[<p>With the recent announcement of the <a href="http://dev.w3.org/2006/webapi/FileUpload/publish/FileAPI.html">File API</a> draft specification being published I&#8217;m sure a lot of people were confused as to what it could really do and why it is truly a powerful API. Firefox&#8217;s latest alpha release of their 3.6 browser, aka Namoroka, is the first to implement this new draft specification.<span id="more-430"></span></p>
<p>One of those powerful things we can do with it is create a file uploader where the user can drag &#038; drop multiple files from their desktop straight into the browser avoiding the previous method of using the file input creating the ultimate killer feature that browsers so badly need.</p>
<p>The below demo only works in <a href="http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/3.6a1-candidates/build1/">Firefox 3.6 Alpha 1</a> if you don&#8217;t want to install it you can watch the screencast below.</p>
<div class="cf_info failure" id="usermessagea"><strong>Update:</strong> File API has changed see new article on changes. <a href="http://www.thecssninja.com/javascript/fileapi">The File API has changed</a></div>
<p><object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='609' height='366'><param name='movie' value='http://screenr.com/Content/assets/screenr_0817090731.swf' /><param name='flashvars' value='i=8363' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_0817090731.swf' flashvars='i=8363' allowFullScreen='true' width='609' height='366' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object></p>
<div class="resources01"><a href="http://www.thecssninja.com/demo/drag-drop_upload/" title="Drag and drop files from your computer and they're uploaded using a XMLHttpRequest" class="demo" target="_blank">View a live demo</a> <a href="http://www.thecssninja.com/demo/drag-drop_upload/drag-drop_upload.zip" title="Download the source of the Drag and drop upload demo" class="demo source" target="_blank">Download the source files</a></div>
<h2 class="subtitle02">Drag &#038; drop it like it&#8217;s hot</h2>
<p>Now I&#8217;m sure a few people would have seen this functionality already if they watched the Google Wave presentation where they demonstrated drag and drop file uploading, but they used Google Gears to accomplish this. They did mention they will be working on a draft spec to get this functionality into HTML5. This hasn&#8217;t happened yet and instead <a href="http://arunranga.com/blog/about/">Arun Ranganathan</a> of Mozilla wrote the first draft spec for such functionality to be possible.</p>
<p><object width="609" height="366"><param name="movie" value="http://www.youtube.com/v/v_UyVmITiYQ&#038;hl=en&#038;fs=1&#038;start=922"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/v_UyVmITiYQ&#038;hl=en&#038;fs=1&#038;start=922" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="609" height="366"></embed></object><br />
<small>Video will automatically start at 15m22s, where the drag drop is shown</small></p>
<h2 class="subtitle02">The File API</h2>
<p>The File API is what makes this whole thing possible, on the <em>dataTransfer</em> object it has been extended with the <em>file</em> attribute so it can read and convert the files you are dropping which then sends the file information as binary using an xhr <em>upload</em> attribute creating a desktop like behaviour but in the browser, opening great possibilities and much needed functionality that a user will find more intuitive.</p>
<h2 class="subtitle02">XMLHttpRequest 2</h2>
<p>The second revision of the <a href="http://www.w3.org/TR/2009/WD-XMLHttpRequest2-20090820/">XMLHTTPRequest specification</a> adds further functionality so we can actually send our dropped files to the server asynchronously. There are several additions which I use in this demo such as the <a href="http://www.w3.org/TR/2009/WD-XMLHttpRequest2-20090820/#the-upload-attribute"><em>upload</em> attribute</a> and the <a href="http://www.w3.org/TR/2009/WD-XMLHttpRequest2-20090820/#events">progress events</a> like <em>progress</em> and <em>load</em>. With those events we can give the user some detailed feedback such as a percentage loader used in this example.</p>
<h2 class="subtitle02">How it works</h2>
<p>This example uses a few emerging technologies such as xhr2, local file access and the drag and drop API. The order in which the events happen are as follows:</p>
<ul>
<li>The user drags images from their desktop to the drop area in the browser and fires the <em>TCNDDU.handleDrop</em> function.</li>
<li>The <em>dataTransfer</em> object passes through the local files dragged over through the <em>files</em> attribute</li>
<li>Using the <em>getAsDataURL</em> method we can convert the file to a base64 encoded string create an image and sets its source to that string.</li>
<li>The file is then passed into an xhr request where we use the new <em>sendAsBinary</em> method available since Firefox 3.0 and pass in the file as binary data using the <em>getAsBinary</em> method</li>
<li>We attach some <a href="http://www.w3.org/TR/XMLHttpRequest2/#events">progress events</a> to the <a href="http://www.w3.org/TR/XMLHttpRequest2/#the-upload-attribute">upload</a> attribute so we can create a progress bar with percentage feedback and a load progress event so we can remove the progress bar once the image has uploaded successfully</li>
</ul>
<p>I&#8217;ll go through some of the code in the demo to explain a few things in more detail.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><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> 0; i <span style="color: #339933;">&lt;</span> count; i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	domElements <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span>
		document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'li'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'a'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'img'</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#93;</span>;
&nbsp;
	domElements<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> files<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">getAsDataURL</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>; <span style="color: #006600; font-style: italic;">// base64 encodes local file(s)</span>
	domElements<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">width</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">300</span>;
	domElements<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">height</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">200</span>;
	domElements<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>domElements<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>;
	domElements<span style="color: #009900;">&#91;</span>0<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;item&quot;</span><span style="color: #339933;">+</span>i;
	domElements<span style="color: #009900;">&#91;</span>0<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>domElements<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
	imgPreviewFragment.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>domElements<span style="color: #009900;">&#91;</span>0<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
	dropListing.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>imgPreviewFragment<span style="color: #009900;">&#41;</span>;
&nbsp;
	TCNDDU.<span style="color: #660066;">processXHR</span><span style="color: #009900;">&#40;</span>files.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> i<span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This for loop is inside the <em>TCNDDU.handleDrop</em> function which will loop through the files, the count var in the for loop is pointing to <em>event.dataTransfer.files.length</em> so we know how many files we are working with.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">domElements<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> files<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">getAsDataURL</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>This line sets the source of the image as a base64 encoded string so we can display the local file to the user straight away.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">fileUpload.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;progress&quot;</span><span style="color: #339933;">,</span> TCNDDU.<span style="color: #660066;">uploadProgressXHR</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>;
fileUpload.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;load&quot;</span><span style="color: #339933;">,</span> TCNDDU.<span style="color: #660066;">loadedXHR</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>;
fileUpload.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;error&quot;</span><span style="color: #339933;">,</span> TCNDDU.<span style="color: #660066;">uploadError</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>These lines are in the <em>TCNDDU.processXHR</em> that gets fired for each file dragged into the window. The <em>fileUpload</em> points to a <em>new XMLHttpRequest().upload</em> which we attach a few event listeners for progress, load and error so we can give useful feedback to the user.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">xhr.<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;upload.php&quot;</span><span style="color: #009900;">&#41;</span>;
xhr.<span style="color: #660066;">overrideMimeType</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'text/plain; charset=x-user-defined-binary'</span><span style="color: #009900;">&#41;</span>;
xhr.<span style="color: #660066;">sendAsBinary</span><span style="color: #009900;">&#40;</span>file.<span style="color: #660066;">getAsBinary</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>Here we post the data to the PHP file for possible further processing etc. We also use the <em>overrideMimeType</em> method to user defined binary and finally use the new <em>sendAsBinary</em> method which has the local file passed in as binary.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">TCNDDU.<span style="color: #660066;">uploadProgressXHR</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>event<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>event.<span style="color: #660066;">lengthComputable</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> percentage <span style="color: #339933;">=</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>event.<span style="color: #660066;">loaded</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> event.<span style="color: #660066;">total</span><span style="color: #009900;">&#41;</span>;
		<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>percentage <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			event.<span style="color: #660066;">target</span>.<span style="color: #660066;">log</span>.<span style="color: #660066;">firstChild</span>.<span style="color: #660066;">nextSibling</span>.<span style="color: #660066;">firstChild</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">width</span> <span style="color: #339933;">=</span> 
			<span style="color: #009900;">&#40;</span>percentage<span style="color: #339933;">*</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;px&quot;</span>;
&nbsp;
			event.<span style="color: #660066;">target</span>.<span style="color: #660066;">log</span>.<span style="color: #660066;">firstChild</span>.<span style="color: #660066;">nextSibling</span>.<span style="color: #660066;">firstChild</span>.<span style="color: #660066;">textContent</span> <span style="color: #339933;">=</span> 
			percentage <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;%&quot;</span>;
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>;</pre></div></div>

<p>For the progress event we attached earlier we can check if it will return the right information so we can do a progress bar by checking for the <em>lengthComputable</em> property if that’s available we know the progress event will return two values of <em>loaded</em> and <em>total</em> from there we can work out the percentage that has loaded and adjust our visual cues, in our case a progress bar.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">event.<span style="color: #660066;">target</span>.<span style="color: #660066;">log</span>.<span style="color: #660066;">firstChild</span>.<span style="color: #660066;">nextSibling</span>.<span style="color: #660066;">firstChild</span></pre></div></div>

<p>This line allows us to get access to the current container of the image that is being calculated. <em>event.target</em> will always point back to the xhr object in the <em>TCNDDU.processXHR</em> we added a link to the container by adding <em>log</em> to <em>event.target</em> and pointing it to container variable.</p>
<h2 class="subtitle02">Not without issues</h2>
<p>There are two issues I came across with this demo and most likely are something I have done wrong or it could possibly be a bug.</p>
<p>The first issue I came across was the <em>event.target.log</em> suddenly losing its reference to itself and no longer being able to update the progress bar as the link to the current container is suddenly undefined, this also causes the load event to never get fired and the progress bar never gets removed.</p>
<p>The other issue is the <em>progress</em> event won&#8217;t fire if the file size is below around 140-150kb so no feedback will be given to the user. I&#8217;m not sure if this is intentional or a bug. I hope it&#8217;s the latter as feedback on any sized file would be necessary. You can see this happening on the toucan image in the screencast above.</p>
<p>I took a sceencast of the issues you can watch below.</p>
<p><object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='609' height='366'><param name='movie' value='http://screenr.com/Content/assets/screenr_0817090731.swf' /><param name='flashvars' value='i=8364' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_0817090731.swf' flashvars='i=8364' allowFullScreen='true' width='609' height='366' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object></p>
<h2 class="subtitle02">Heading in a great direction</h2>
<p>This functionality is exactly what the web needs going forward and will hopefully see it in other browsers very soon, Google Wave could benefit from this greatly and would make one of their coolest features work without any need for external plugins.</p>
<h2 class="subtitle02">Resources</h2>
<p>This article was inspired from a few examples I have seen throughout my searches for such functionality, what sparked my imagination and got me developing a drag and drop uploader was <a href="https://bug503598.bugzilla.mozilla.org/attachment.cgi?id=388413">this demo</a> found on the Mozilla bug list.</p>
<p>A few people have already figured out and <a href="http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html">demonstrated multiple file uploading</a> in safari 4 and a <a href="http://hacks.mozilla.org/2009/06/xhr-progress-and-richer-file-uploading-feedback/">similar version</a> that works in Firefox 3.5, although you can&#8217;t select multiple files you can upload more than one at a time. That example I used a slightly modified version in this demo to send binary data to the server.</p>
<p>There is also another great article on <a href="http://blog.igstan.ro/2009/01/pure-javascript-file-upload.html">uploading files and posting forms</a> using Ajax. This articles demo works in Firefox 3+.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/drag-and-drop-upload/feed</wfw:commentRss>
		<slash:comments>46</slash:comments>
		</item>
	</channel>
</rss>
