<?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; Drag and Drop</title>
	<atom:link href="http://hacks.mozilla.org/category/drag-and-drop/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>The shortest image uploader &#8211; ever!</title>
		<link>http://hacks.mozilla.org/2011/03/the-shortest-image-uploader-ever/</link>
		<comments>http://hacks.mozilla.org/2011/03/the-shortest-image-uploader-ever/#comments</comments>
		<pubDate>Fri, 11 Mar 2011 10:43:10 +0000</pubDate>
		<dc:creator>Paul Rouget</dc:creator>
				<category><![CDATA[Demo]]></category>
		<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[FileAPI]]></category>
		<category><![CDATA[Firefox 4]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=7496</guid>
		<description><![CDATA[A couple of line of JavaScript. That&#8217;s all you need. This is a very short Image Uploader, based on imgur.com API. If you want to do more complex stuff (like resize, crop, drawing, colors, &#8230;) see my previous post. Back-story. I&#8217;ve been talking to Imgur.com&#8216;s owner (Hi Alan!). He recently added Drag&#8217;n Drop support to [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of line of JavaScript. That&#8217;s all you need.</p>
<p><em>This is a very short Image Uploader, based on <a href="http://api.imgur.com">imgur.com API</a>. If you want to do more complex stuff (like resize, crop, drawing, colors, &#8230;) see my <a href="https://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/">previous post</a>.</em></p>
<p>Back-story. I&#8217;ve been talking to <a href="http://imgur.com">Imgur.com</a>&#8216;s owner (Hi Alan!). He <a href="http://imgur.com/blog/2010/12/08/drag-and-dropload/">recently added Drag&#8217;n Drop support</a> to his image sharing website. But also, Alan allows <a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">Cross-Domain XMLHttpRequest</a> (thank you!). So basically, you can use his <a href="http://api.imgur.com">API</a> to upload pictures to his website, from your HTML page, with no server side code involved &#8211; at all.</p>
<p>And here is an example of what you can do:</p>
<p>(see the full working code on <a href="https://github.com/paulrouget/miniuploader/tree/gh-pages">github</a> &#8211; live version <a href="http://paulrouget.github.com/miniuploader">there</a> )</p>
<p>(also, you&#8217;ll need to understand FormData, see <a href="https://hacks.mozilla.org/2010/05/formdata-interface-coming-to-firefox/">here</a>)</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> upload<span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// file is from a &lt;input&gt; tag or from Drag'n Drop</span>
  <span style="color: #006600; font-style: italic;">// Is the file an image?</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>file <span style="color: #339933;">||</span> <span style="color: #339933;">!</span>file.<span style="color: #660066;">type</span>.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/image.*/</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// It is!</span>
  <span style="color: #006600; font-style: italic;">// Let's build a FormData object</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> fd <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> FormData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  fd.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;image&quot;</span><span style="color: #339933;">,</span> file<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// Append the file</span>
  fd.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;key&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;6528448c258cff474ca9701c5bab6927&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// Get your own key: http://api.imgur.com/</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Create the XHR (Cross-Domain XHR FTW!!!)</span>
  <span style="color: #003366; font-weight: bold;">var</span> xhr <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> XMLHttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  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;http://api.imgur.com/2/upload.json&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// Boooom!</span>
  xhr.<span style="color: #000066;">onload</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: #006600; font-style: italic;">// Big win!</span>
    <span style="color: #006600; font-style: italic;">// The URL of the image is:</span>
    JSON.<span style="color: #660066;">parse</span><span style="color: #009900;">&#40;</span>xhr.<span style="color: #660066;">responseText</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">upload</span>.<span style="color: #660066;">links</span>.<span style="color: #660066;">imgur_page</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
   <span style="color: #006600; font-style: italic;">// Ok, I don't handle the errors. An exercice for the reader.</span>
   <span style="color: #006600; font-style: italic;">// And now, we send the formdata</span>
   xhr.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span>fd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span></pre></div></div>

<p>That&#8217;s all :)</p>
<p>Works on Chrome and Firefox 4 (<strong>Edit:</strong>) and Safari.</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2011/03/the-shortest-image-uploader-ever/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>How to develop a HTML5 Image Uploader</title>
		<link>http://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/</link>
		<comments>http://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 10:40:16 +0000</pubDate>
		<dc:creator>Paul Rouget</dc:creator>
				<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[FileAPI]]></category>
		<category><![CDATA[Firefox 4]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=6846</guid>
		<description><![CDATA[HTML5 comes with a set of really awesome APIs. If you combine these APIs with the &#60;canvas&#62; element, you could create a super/modern/awesome Image Uploader. This article shows you how. All these tips work well in Firefox 4. I also describe some alternative ways to make sure it works on Webkit-based browsers. Most of these [...]]]></description>
			<content:encoded><![CDATA[<p><em>HTML5 comes with a set of really awesome APIs. If you combine these APIs with the &lt;canvas&gt; element, you could create a super/modern/awesome Image Uploader. This article shows you how.</em></p>
<p><em>All these tips work well in Firefox 4. I also describe some alternative ways to make sure it works on Webkit-based browsers. Most of these APIs don&#8217;t work in IE, but it&#8217;s quite easy to use a normal form as a fallback.</em></p>
<p><em>Please let us know if you use one of these technologies in your project!</em></p>
<h1>Retrieve the images</h1>
<h2>Drag and drop</h2>
<p>To upload files, you&#8217;ll need an <a href="https://developer.mozilla.org/en/HTML/element/input#attr-type">&lt;input type=&#8221;file&#8221;&gt;</a> element. But you should also allow the user to drag and drop images from the desktop directly to your web page.</p>
<p>I&#8217;ve written a detailed article about <a href="http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/">implementing drag-and-drop support for your web pages</a>.</p>
<p>Also, take a look at the <a href="https://developer.mozilla.org/en/Using_files_from_web_applications#Selecting_files_using_drag_and_drop">Mozilla tutorial on drag-and-drop</a>.</p>
<h2>Multiple input</h2>
<p>Allow the user the select several files to upload at the same time from the File Picker:</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;input</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;file&quot;</span> multiple<span style="color: #000000; font-weight: bold;">&gt;</span></span></pre></div></div>

<p>Again, here is an article I&#8217;ve written about <a href="http://hacks.mozilla.org/2009/12/multiple-file-input-in-firefox-3-6/">multiple file selection</a>.</p>
<h1>Pre-process the files</h1>
<h2>Use the File API</h2>
<p>(See the <a href="https://developer.mozilla.org/en/using_files_from_web_applications">File API documentation</a> for details.)</p>
<p>From drag-and-drop or from the <a href="https://developer.mozilla.org/en/HTML/element/input">&lt;input&gt;</a> element, you have a list a files ready to be used:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// from an input element</span>
<span style="color: #003366; font-weight: bold;">var</span> filesToUpload <span style="color: #339933;">=</span> input.<span style="color: #660066;">files</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// from drag-and-drop</span>
<span style="color: #003366; font-weight: bold;">function</span> onDrop<span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  filesToUpload <span style="color: #339933;">=</span> e.<span style="color: #660066;">dataTransfer</span>.<span style="color: #660066;">files</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Make sure these files are actually images:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>file.<span style="color: #660066;">type</span>.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/image.*/</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// this file is not an image.</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Show a thumbnail/preview</h2>
<p>There are two options here. You can either use a <a href="https://developer.mozilla.org/en/DOM/FileReader">FileReader</a> (from the File API) or use the new <a href="https://developer.mozilla.org/en/DOM/window.URL.createObjectURL"><code>createObjectURL()</code></a> method.</p>
<h3>createObjectURL()</h3>

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

<h3>FileReader</h3>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> img <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;img&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<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><span style="color: #339933;">;</span>  
reader.<span style="color: #000066;">onload</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>img.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> e.<span style="color: #660066;">target</span>.<span style="color: #660066;">result</span><span style="color: #009900;">&#125;</span>
reader.<span style="color: #660066;">readAsDataURL</span><span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Use a canvas</h2>
<p>Once you have the image preview in an <a href="https://developer.mozilla.org/en/HTML/element/img">&lt;img&gt;</a> element, you can draw this image in a <a href="https://developer.mozilla.org/en/HTML/element/canvas">&lt;canvas&gt;</a> element to pre-process the file.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><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;">drawImage</span><span style="color: #009900;">&#40;</span>img<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></pre></div></div>

<h2>Resize the image</h2>
<p>People are used to uploading images straight from their camera. This gives high resolution and extremely heavy (several megabyte) files. Depending on the usage, you may want to resize such images. A super easy trick is to simply have a small canvas (800&#215;600 for example) and to draw the image tag into this canvas. Of course, you&#8217;ll have to update the canvas dimensions to keep the ratio of the image.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> MAX_WIDTH <span style="color: #339933;">=</span> <span style="color: #CC0000;">800</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> MAX_HEIGHT <span style="color: #339933;">=</span> <span style="color: #CC0000;">600</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> width <span style="color: #339933;">=</span> img.<span style="color: #660066;">width</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> height <span style="color: #339933;">=</span> img.<span style="color: #660066;">height</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>width <span style="color: #339933;">&gt;</span> height<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>width <span style="color: #339933;">&gt;</span> MAX_WIDTH<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    height <span style="color: #339933;">*=</span> MAX_WIDTH <span style="color: #339933;">/</span> width<span style="color: #339933;">;</span>
    width <span style="color: #339933;">=</span> MAX_WIDTH<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</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; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>height <span style="color: #339933;">&gt;</span> MAX_HEIGHT<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    width <span style="color: #339933;">*=</span> MAX_HEIGHT <span style="color: #339933;">/</span> height<span style="color: #339933;">;</span>
    height <span style="color: #339933;">=</span> MAX_HEIGHT<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
canvas.<span style="color: #660066;">width</span> <span style="color: #339933;">=</span> width<span style="color: #339933;">;</span>
canvas.<span style="color: #660066;">height</span> <span style="color: #339933;">=</span> height<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>
ctx.<span style="color: #660066;">drawImage</span><span style="color: #009900;">&#40;</span>img<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> width<span style="color: #339933;">,</span> height<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Edit the image</h2>
<p>Now, you have your image in a canvas. Basically, the possibilities are infinite. Let&#8217;s say you want to apply a sepia filter:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> imgData <span style="color: #339933;">=</span> ctx.<span style="color: #660066;">createImageData</span><span style="color: #009900;">&#40;</span>width<span style="color: #339933;">,</span> height<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> imgData.<span style="color: #660066;">data</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> pixels <span style="color: #339933;">=</span> ctx.<span style="color: #660066;">getImageData</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> width<span style="color: #339933;">,</span> height<span style="color: #009900;">&#41;</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> ii <span style="color: #339933;">=</span> pixels.<span style="color: #660066;">data</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> ii<span style="color: #339933;">;</span> i <span style="color: #339933;">+=</span> <span style="color: #CC0000;">4</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> r <span style="color: #339933;">=</span> pixels.<span style="color: #660066;">data</span><span style="color: #009900;">&#91;</span>i <span style="color: #339933;">+</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> g <span style="color: #339933;">=</span>pixels.<span style="color: #660066;">data</span><span style="color: #009900;">&#91;</span>i <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> b <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">pixels</span>.<span style="color: #660066;">data</span><span style="color: #009900;">&#91;</span>i <span style="color: #339933;">+</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    data<span style="color: #009900;">&#91;</span>i <span style="color: #339933;">+</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>r <span style="color: #339933;">*</span> .393<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>g <span style="color: #339933;">*</span>.769<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>b <span style="color: #339933;">*</span> .189<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    data<span style="color: #009900;">&#91;</span>i <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>r <span style="color: #339933;">*</span> .349<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>g <span style="color: #339933;">*</span>.686<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>b <span style="color: #339933;">*</span> .168<span style="color: #009900;">&#41;</span>
    data<span style="color: #009900;">&#91;</span>i <span style="color: #339933;">+</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>r <span style="color: #339933;">*</span> .272<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>g <span style="color: #339933;">*</span>.534<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>b <span style="color: #339933;">*</span> .131<span style="color: #009900;">&#41;</span>
    data<span style="color: #009900;">&#91;</span>i <span style="color: #339933;">+</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">255</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
ctx.<span style="color: #660066;">putImageData</span><span style="color: #009900;">&#40;</span>imgData<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></pre></div></div>

<h1>Upload with XMLHttpRequest</h1>
<p>Now that you have loaded the images on the client, eventually you want to send them to the server.</p>
<h2>How to send a canvas</h2>
<p>Again, you have two options. You can <a href="https://developer.mozilla.org/en/DOM/HTMLCanvasElement">convert the canvas to a data URL</a> or (in Firefox) <a href="https://developer.mozilla.org/en/Code_snippets/Canvas#Saving_a_canvas_image_to_a_file">create a file from the canvas</a>.</p>
<h3>canvas.toDataURL()</h3>

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

<h3>Create a file from the canvas</h3>

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

<h2>Atomic upload</h2>
<p>Allow the user to upload just one file or all the files at the same time.</p>
<h2>Show progress of the upload</h2>
<p>Use the upload events to create a progress bar:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">xhr.<span style="color: #660066;">upload</span>.<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> <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>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>e.<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>e.<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> e.<span style="color: #660066;">total</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// do something</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>Use FormData</h2>
<p>You probably don&#8217;t want to just upload the file (which could be easily done via: <code>xhr.send(file)</code>) but add side information (like a key and a name).</p>
<p>In that case, you&#8217;ll need to create a <code>multipart/form-data</code> request via a <a href="https://developer.mozilla.org/en/XMLHttpRequest/FormData"><code>FormData</code></a> object. (See <a href="http://hacks.mozilla.org/2010/05/formdata-interface-coming-to-firefox/">Firefox 4: easier JS form handling with FormData</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> fd <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> FormData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
fd.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;paul&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
fd.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;image&quot;</span><span style="color: #339933;">,</span> canvas.<span style="color: #660066;">mozGetAsFile</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;foo.png&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
fd.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;key&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;××××××××××××&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> xhr <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> XMLHttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
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;http://your.api.com/upload.json&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
xhr.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span>fd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h1>Open your API</h1>
<p>Maybe you want to allow other websites to use your service.</p>
<h2>Allow cross-domain requests</h2>
<p>By default, your API is only reachable from a request created from your own domain. If you want to allow people use your API, allow Cross-XHR in your HTTP header:</p>
<pre>
Access-Control-Allow-Origin: *
</pre>
<p>You can also allow just a pre-defined list of domains.</p>
<p>Read about <a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">Cross-Origin Resource Sharing</a>.</p>
<h2>postMessage</h2>
<p>(Thanks to <a href="http://twitter.com/dsg">Daniel Goodwin</a> for this tip.)</p>
<p>Also, listen to messages sent from <a href="https://developer.mozilla.org/en/DOM/window.postMessage"><code>postMessage</code></a>. You could allow people to use your API through postMessage:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">document.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;message&quot;</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>
    <span style="color: #006600; font-style: italic;">// retrieve parameters from e.data</span>
    <span style="color: #003366; font-weight: bold;">var</span> key <span style="color: #339933;">=</span> e.<span style="color: #660066;">data</span>.<span style="color: #660066;">key</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> <span style="color: #000066;">name</span> <span style="color: #339933;">=</span> e.<span style="color: #660066;">data</span>.<span style="color: #000066;">name</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> dataurl <span style="color: #339933;">=</span> e.<span style="color: #660066;">data</span>.<span style="color: #660066;">dataurl</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// Upload</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #006600; font-style: italic;">// Once the upload is done, you can send a postMessage to the original window, with URL</span></pre></div></div>

<p><em>That&#8217;s all. If you have any other tips to share, feel free to drop a comment.</em></p>
<p><strong>Enjoy ;)</strong></p>
<style>
.post h1 {
  font-size: 27px;
  margin-bottom: 7px;
  font-style: italic;
}
.post h2 {
  margin-bottom: 10px;
}
</style>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>HTML5 adoption stories: box.net and html5 drag and drop</title>
		<link>http://hacks.mozilla.org/2010/06/html5-adoption-stories-box-net-and-html5-drag-and-drop/</link>
		<comments>http://hacks.mozilla.org/2010/06/html5-adoption-stories-box-net-and-html5-drag-and-drop/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 15:46:12 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[Device APIs]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[FileAPI]]></category>
		<category><![CDATA[Firefox 3.6]]></category>
		<category><![CDATA[Firefox 4]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=5012</guid>
		<description><![CDATA[This is a guest post from Tomas Barreto, a developer who works at box.net. They recently adopted HTML5 drag and drop as a way to share files with other people using new features in Firefox. The included video is a pitch for the feature and service, but shows how easy it is to do simple [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is a guest post from Tomas Barreto, a developer who works at <a href="http://box.net/">box.net</a>.  They recently adopted HTML5 drag and drop as a way to share files with other people using new features in Firefox.  The included video is a pitch for the feature and service, but shows how easy it is to do simple HTML5-based upload progress even with multiple files.  Tomas gives an overview of the relatively simple JavaScript required to do this, and how improvements in Firefox 4 will make things even easier.  Also have a quick look at the bottom of the post for links to additional docs and resources.<br />
</em></p>
<p>At Box.net, we’re always exploring new ways to help users get content quickly and securely onto our cloud content management platform. So when asked, “What feature would make you use Box more?” during the Box Hack Olympics in April, my colleague CJ and I decided to tackle the most intuitive way to upload files: simply dragging them from the desktop into Box.</p>
<p>We considered technologies ranging from Gears to Firefox plugins, but only HTML5 had sufficient adoption. By using some of the JavaScript APIs defined in the HTML5 standard, CJ and I could create a seamless drag and drop experience for our users on supporting browsers. Furthermore, using an HTML5-based upload feature would allow us to enable users to select multiple files at once, and also display progress on the client without polling. And with HTML5 adoption across the latest versions of three of the top four browsers, we felt confident about building an upload method based on this new technology without the trade-offs of using a third-party plug-in.</p>
<p>We rolled out the first rev of our drag and drop feature a few weeks ago, and we’re impressed with how quickly it has been adopted. It’s already one of the most popular ways to get files onto Box, and in its first week it surpassed our old AJAX upload method. You can check out our demo video to get a feel for the feature:</p>
<p><object width="500" height="304"><param name="movie" value="http://www.youtube-nocookie.com/v/rkY7MGilQZY&#038;hl=en_US&#038;fs=1&#038;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube-nocookie.com/v/rkY7MGilQZY&#038;hl=en_US&#038;fs=1&#038;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="304"></embed></object></p>
<p>To build this feature, we referenced a handful of online examples that explained how to use Firefox 3 <a href="https://developer.mozilla.org/en/DOM/FileReader">FileReader</a> object and the drag and drop file event support. Our first implementation used this object to load the file into memory and then took advantage of the latest <a href="https://developer.mozilla.org/En/Using_XMLHttpRequest">XMLHttpRequest</a> events to track progress on the client.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> files <span style="color: #339933;">=</span> event.<span style="color: #660066;">originalEvent</span>.<span style="color: #660066;">dataTransfer</span>.<span style="color: #660066;">files</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// drop event</span>
<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><span style="color: #339933;">;</span>
&nbsp;
reader.<span style="color: #000066;">onload</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: #003366; font-weight: bold;">var</span> file_contents <span style="color: #339933;">=</span> event.<span style="color: #660066;">target</span>.<span style="color: #660066;">result</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> request <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> XMLHttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  ... <span style="color: #006600; font-style: italic;">// attach event listeners to monitor progress and detect errors</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> post_body <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
&nbsp;
  .. <span style="color: #006600; font-style: italic;">// build post body</span>
&nbsp;
  post_body <span style="color: #339933;">+=</span> file_contents<span style="color: #339933;">;</span>
&nbsp;
  .. <span style="color: #006600; font-style: italic;">// finish post body</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> url <span style="color: #339933;">=</span> <span style="color: #3366CC;">'http://example.com/file_upload'</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> request <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> XMLHttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  request.<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>  url<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// open asynchronous post request</span>
  request.<span style="color: #660066;">setRequestHeader</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'content-type'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'multipart/form-data; boundary=&quot;&quot;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// make sure to set a boundary</span>
  request.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span>post_body<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
reader.<span style="color: #660066;">readAsBinaryString</span><span style="color: #009900;">&#40;</span>files<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This approach worked well because we could use the same server processing code that we previously used for uploads. The main disadvantage here is that the FileReader object reads the entire file into memory, which is not optimal for a general upload use case. Our current HTML5 implementation uses this logic and has forced us to restrict drag and drop uploads to just 25mb.  However, thanks to recommendations from the Mozilla team, we’ll be taking an alternative approach for V2 of drag and drop, where the file is read chunks as needed by the request. Here’s how we’re going to do it:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> files <span style="color: #339933;">=</span> event.<span style="color: #660066;">originalEvent</span>.<span style="color: #660066;">dataTransfer</span>.<span style="color: #660066;">files</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// drop event</span>
<span style="color: #003366; font-weight: bold;">var</span> url <span style="color: #339933;">=</span> <span style="color: #3366CC;">'http://example.com/file_upload'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> request <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> XMLHttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
request.<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>  url<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// open asynchronous post request</span>
request.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span>files<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Since this approach is not formatted as a multipart form-data, it will require some adjustments on our back-end to support receiving file uploads in this way. However, it&#8217;s definitely worth the trade-off since we’ll get all the benefits of the previous method and we don&#8217;t need special file size restrictions. In the future, we&#8217;ll consider using <a href="http://hacks.mozilla.org/2010/05/formdata-interface-coming-to-firefox/">yet another way to efficiently upload files that is supported in Firefox 4 and uses the traditional multi-part form</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> files <span style="color: #339933;">=</span> event.<span style="color: #660066;">originalEvent</span>.<span style="color: #660066;">dataTransfer</span>.<span style="color: #660066;">files</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// drop event</span>
<span style="color: #003366; font-weight: bold;">var</span> url <span style="color: #339933;">=</span> <span style="color: #3366CC;">'http://example.com/file_upload'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> request <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> XMLHttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> fd <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> FormData<span style="color: #339933;">;</span>
fd.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;myFile&quot;</span><span style="color: #339933;">,</span> files<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
request.<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>  url<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// open asynchronous post request</span>
request.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span>fd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>We’re already exploring more ways to enrich the Box experience using HTML5. With HTML5, we can build faster, richer and more interactive features with native browser support, and bridge the traditional gap between desktop software and web applications. Here are just a few cool new upload-related features on our roadmap:</p>
<ul>
<li>Pause/Resume uploads using the Blob slice API to split files into chunks (this will be a huge robustness boost, especially for large uploads)</li>
<li>Allowing uploads to resume even after the browser closes by caching the file using <a href="http://hacks.mozilla.org/2010/06/comparing-indexeddb-and-webdatabase/">IndexedDB</a> support (possibly in Firefox 4)</li>
</ul>
<p>We’d also like to begin a discussion about supporting the reverse drag and drop use case: dragging files from the browser to the desktop. Based on our users’ enthusiasm around the drag and drop upload feature, we think the reverse functionality would well received. If you are interested in contributing to a specification for this feature, please let us know (html5 [-at$] box.net)!</p>
<p>Resources:</p>
<ul>
<li><a href="https://developer.mozilla.org/en/using_files_from_web_applications">Using File APIs from web applications</a>
<li><a href="https://developer.mozilla.org/En/Using_XMLHttpRequest">Using XMLHttpRequest</a>
<li><a href="https://developer.mozilla.org/En/DragDrop/Drag_and_Drop">Using HTML5 Drag and Drop</a><br />
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2010/06/html5-adoption-stories-box-net-and-html5-drag-and-drop/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>an HTML5 offline image editor and uploader application</title>
		<link>http://hacks.mozilla.org/2010/02/an-html5-offline-image-editor-and-uploader-application/</link>
		<comments>http://hacks.mozilla.org/2010/02/an-html5-offline-image-editor-and-uploader-application/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 16:00:14 +0000</pubDate>
		<dc:creator>Paul Rouget</dc:creator>
				<category><![CDATA[Demo]]></category>
		<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[Featured Demo]]></category>
		<category><![CDATA[FileAPI]]></category>
		<category><![CDATA[Firefox 3.6]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Offline]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=3569</guid>
		<description><![CDATA[Many web applications use image uploaders: image hosting websites, blog publishing applications, social networks, among many others. Such uploaders have limitations: you can&#8217;t upload more than one file at a time and you can&#8217;t edit the image before sending it. A plugin is the usual workaround for uploading more than one image, and image modifications [...]]]></description>
			<content:encoded><![CDATA[<p>Many web applications use image uploaders: image hosting websites, blog publishing applications, social networks, among many others. Such uploaders have limitations: you can&#8217;t upload more than one file at a time and you can&#8217;t edit the image before sending it. A plugin is the usual workaround for uploading more than one image, and image modifications are usually done on the server side, which can make the editing process more cumbersome.</p>
<p>Firefox 3.6 offers many <a href="https://developer.mozilla.org/en/Firefox_3.6_for_developers">new Open Web features</a> to web developers, including even more HTML5 support. This post describes how to create a sophisticated image editor and uploader built using Open Web technologies.</p>
<p>See below for a video of the demo with some background.</p>
<h2>Hosted on hacks, publishes to twitpic</h2>
<p>Our web application uploads pictures to twitpic, an image hosting service for Twitter.</p>
<p>Note that code for this application is actually hosted on the <a href="http://hacks.mozilla.org/">hacks web server</a> but can still upload to Twitpic. Uploading to Twitpic is possible because they opened up their API to <a href="https://developer.mozilla.org/En/HTTP_Access_Control">Cross Domain XMLHttpRequests</a> for applications like this. (Thank you <a href="http://twitpic.com">twitpic</a>!).</p>
<p><a href="http://twitpic.com"><img src="http://hacks.mozilla.org/wp-content/uploads/2010/01/twitpic.png" title="twitpic" style="border: 0" class="aligncenter"/></a></p>
<h2>Web Features</h2>
<p>The <a href="http://demos.hacks.mozilla.org/openweb/imageUploader/">demo</a> uses the following features from HTML5 included in Firefox 3.6:</p>
<ul>
<li><a href="http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/">HTML5 Drag and Drop</a>: You can drag and drop items inside of the web page and drag images from your desktop directly into the browser.</li>
<li><a href="http://hacks.mozilla.org/2009/06/localstorage/">HTML5 <code>localStorage</code></a>: to store the image data across browser restarts</li>
<li><a href="http://hacks.mozilla.org/2010/01/offline-web-applications/">HTML5 Application Cache</a>: This allows you to create applications that can be used when the browser isn&#8217;t connected to the Internet.  It stores the entire app in the browser and also gives you access to online and offline events so you know when you need to re-sync data with a server.</li>
<li><a href="http://hacks.mozilla.org/2009/06/pushing-pixels-with-canvas/">HTML5 Canvas</a>: The HTML5 Canvas element is used through this demo to edit and render images.
<li><a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">Cross-Origin Resource Sharing</a> to host an application at one site and publish data to another.
</ul>
<p><video controls="true"><br />
<source src="http://videos.mozilla.org/serv/marketing/html5_img_uploader/html5_img_uploader.ogv" type="video/ogg"/><br />
<source src="http://videos.mozilla.org/serv/marketing/html5_img_uploader/html5_img_uploader.mp4" type="video/mp4"/><br />
<embed src="http://www.youtube.com/v/wbSoSCStodA&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500"></embed><br />
</video></p>
<h2>What&#8217;s in the demo?</h2>
<p>See the <a href="http://demos.hacks.mozilla.org/openweb/imageUploader/">live demo</a> to try the image uploader for yourself. You will need <a href="http://www.firefox.com">Firefox 3.6</a> and a <a href="http://twitter.com/">twitter</a> account.</p>
<p>Here&#8217;s a full list of the things that this application can do:</p>
<ul>
<li>You can drag images from your desktop or the web into the application.</li>
<li>You can see a preview of each image you want to upload.</li>
<li>You can drag previews to the trash to delete an image.</li>
<li>Images are automatically made smaller if they are bigger than 600px wide.</li>
<li>You can edit any of the images before uploading.  This includes being able to rotate, flip, crop or turn an image black and white.</li>
<li>If you edit an image it&#8217;s saved locally so you can still edit when you&#8217;re offline.  If you close the tab, restart Firefox or your computer they will be there when you load the page again so you can upload when you&#8217;re re-connected.</li>
<li>It will upload several files at once and provide feedback as the upload progresses.</li>
<li>The HTML5 Offline Application Cache makes the application load very quickly since it&#8217;s all stored offline.</li>
</ul>
<h2>Under the Hood</h2>
<p>Let&#8217;s quickly go over all of the technology that we&#8217;re using in this application.</p>
<h3>Cross-XMLHttpRequest</h3>
<p><a href="http://twitpic.com/">Twitpic</a> was nice enough to open their API to allow XMLHttpRequests from any other domain. This means that you can now use their API from your own website and offer your own image uploader.</p>
<p>If you&#8217;re running a web site with an API you want people to use from other web sites, you can do that with <a href="https://developer.mozilla.org/En/HTTP_Access_Control">Cross-site HTTP requests</a>.  In order for you to support it you will need to add an HTTP header to responses from your web server that says which domains you allow.  As an example, here&#8217;s how twitpic allows access from all domains:</p>
<pre>
Access-Control-Allow-Origin: *
</pre>
<p>It&#8217;s important to note that opening your API does have security implications so you should be careful to understand those issues before blindly opening an API.  For more details, <a href="https://developer.mozilla.org/En/HTTP_access_control">see MDC documentation on CORS</a>.</p>
<h3>Drag and Drop</h3>
<p><a href="https://developer.mozilla.org/En/DragDrop/DataTransfer">Drag and Drop</a> is a mechanism with two important features:</p>
<ul>
<li>Dragging files from your Desktop to your web page.</li>
<li>Native Drag and Drop inside your web page (not just changing the coordinates of your elements).</li>
</ul>
<p>The image uploader uses Drag and Drop to allow the user the add files from the Desktop, to remove files (drag them to the trash) and to insert a new image into a current image.</p>
<p>For more on <a href="http://hacks.mozilla.org/category/drag-and-drop/">Drag and Drop</a>, see previous hacks articles, in particular <a href="http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/">how to use Drag and Drop in your application</a>.</p>
<h3>Canvas to Edit Images</h3>
<p>Once images have been dragged and dropped into the web page, the image uploader lets you edit them before uploading. This is possible because images are actually copied to <code>canvas</code> elements via the <a href="http://hacks.mozilla.org/category/fileapi/">File API</a>.</p>
<p>In this case, the editing process is really basic: rotate, flip, add text, black and white, crop. However, you can imagine offering many other features in your version of the editor (see <a href="http://editor.pixastic.com/">Pixastic</a> for example, or this inlay feature <a href="http://people.mozilla.com/~prouget/demos/fennec/imgManipulation/">here</a>).</p>
<p>Using <code>canvas</code> and the <a href="http://hacks.mozilla.org/category/fileapi/">File API</a> also let you resize the image before sending it. Here, every image is converted to a new image (canvas) that is less than 600px.</p>
<h3>localStorage: Save Local Data</h3>
<p>It&#8217;s possible to <a href="http://hacks.mozilla.org/2010/01/offline-web-applications/">store local data</a> persistently in a web page using <code>localStorage</code>, up to 5Mb of data per domain. </p>
<p>In the image uploader, localStorage is used to store images and credentials. Since images are actually <code>canvas</code>, you can store them as data URLs:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> url <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: #660066;">toDataURL</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;image/png&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
localStorage.<span style="color: #660066;">setItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;image1&quot;</span><span style="color: #339933;">,</span> url<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>LocalStorage support means that you can edit an image, close Firefox, switch off your computer, and the edited image will still be there when you restart Firefox.</p>
<h3>Offline</h3>
<p>If you add a manifest file listing all remote files needed to display your web application it will work even when you aren&#8217;t connected to the Internet. A nice side effect is that it will also make your application load much faster.</p>
<p>Here, the <code>html</code> element refers to a manifest file:</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;html</span> <span style="color: #000066;">manifest</span>=<span style="color: #ff0000;">&quot;offline.manifest&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></pre></div></div>

<p>And the manifest file looks like:</p>
<pre style="border-left: 2px solid grey; padding-left: 10px;">
CACHE MANIFEST

# v2.4
index.xhtml
fonts/MarketingScript.ttf
css/desktop.css
css/fonts.css
css/mobile.css
[...]
</pre>
<p>You can also catch offline and online events to know if the connection status changes.<br />
<a href="http://hacks.mozilla.org/2010/01/offline-web-applications/">For more information see our last article about offline</a>.</p>
<h2>Conclusion</h2>
<p>Firefox 3.6 allows millions of people to take advantage of modern standards, including HTML5.<br />
The image uploader described here shows how a web page should really be considered as an application since it interacts with your Desktop and works offline. </p>
<p>Here are a few tips for writing your next application using Open Web technologies:</p>
<p><em><strong>Allow Cross-XMLHttpRequest:</strong></em><br />
If it makes sense for your service, allow people to access your API from a different domain, you&#8217;ll be amazed at the apps people will come up with.</p>
<p><em><strong>Allow multiple input:</strong></em><br />
Let people Drag files to your application and use <code>&lt;input&nbsp;type="file"&nbsp;multiple=""&gt;</code> so they can select several files at once. <em>In this demo, we use a multiple input which is visible only in the mobile version, but for accessibility consideration, don&#8217;t forget to use it to propose an alternative to Drag&#8217;n Drop.</em></p>
<p><em><strong>Use native Drag and Drop:</strong></em><br />
Drag and Drop mechanisms are usually simulated (updating coordinates on the mousemove event.)  When you can, use the native mechanism.</p>
<p><em><strong>Use the File API</strong></em><br />
To pre-process a file before even talking to a server.</p>
<p><em><strong>Support offline</strong></em><br />
Store data and use a manifest to make your application data persistent while offline.</p>
<p><em><strong>Use Canvas</strong></em><br />
Canvas is the most widely implemented HTML5 element. It works everywhere (even if it has to be <a href="http://code.google.com/p/explorercanvas/">simulated</a>), use it!</p>
<p><em>Think &#8220;Client Side&#8221;</em>: HTML5, CSS3 and the new powerful JavaScript  engines let you create amazing applications, take advantage of them!</p>
<p>We look forward to seeing the great new applications you&#8217;ll come up with using Open Web technologies! </p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2010/02/an-html5-offline-image-editor-and-uploader-application/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
<enclosure url="http://videos.mozilla.org/serv/marketing/html5_img_uploader/html5_img_uploader.ogv" length="5921036" type="video/ogg" />
		</item>
		<item>
		<title>interactive file uploads with Drag and Drop, FileAPI and XMLHttpRequest</title>
		<link>http://hacks.mozilla.org/2009/12/uploading-files-with-xmlhttprequest/</link>
		<comments>http://hacks.mozilla.org/2009/12/uploading-files-with-xmlhttprequest/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 18:01:35 +0000</pubDate>
		<dc:creator>Paul Rouget</dc:creator>
				<category><![CDATA[Demo]]></category>
		<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[Featured Demo]]></category>
		<category><![CDATA[FileAPI]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Firefox 3.6]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=2931</guid>
		<description><![CDATA[In previous posts, we showed how to access a file through the input tag or through the Drag and Drop mechanism. In both cases, you can use XMLHttpRequest to upload the files and follow the upload progress. Demo If you&#8217;re running the latest beta of Firefox 3.6, check out our file upload demo. Uploading XMLHttpRequest [...]]]></description>
			<content:encoded><![CDATA[<p>In previous posts, we showed how to access a file through the <a href="http://hacks.mozilla.org/2009/12/multiple-file-input-in-firefox-3-6/">input tag</a> or through the <a href="http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/">Drag and Drop mechanism</a>. In both cases, you can use <a href="https://developer.mozilla.org/En/Using_XMLHttpRequest"><code>XMLHttpRequest</code></a> to upload the files and follow the upload progress.</p>
<h3>Demo</h3>
<p><video controls><br />
<source src="http://videos.mozilla.org/serv/blizzard/image-upload/2009-12-11-ImageUpload.ogv" type="video/ogg"/><br />
<source src="http://videos.mozilla.org/serv/blizzard/image-upload/2009-12-11-ImageUpload.mov" type="video/mp4"/><br />
<embed src="http://www.youtube.com/v/YG894djaF9o&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></video></p>
<p>If you&#8217;re running the latest beta of <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.6</a>, check out our <a href="http://demos.hacks.mozilla.org/openweb/uploadingFiles/">file upload demo</a>.</p>
<h3>Uploading</h3>
<p><a href="https://developer.mozilla.org/En/Using_XMLHttpRequest"><code>XMLHttpRequest</code></a> will send a given file to the server as a binary array, so you first need to read the content of the file as a binary string, using the <a href="http://hacks.mozilla.org/2009/12/w3c-fileapi-in-firefox-3-6/">File API.</a> Because both <a href="http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/">Drag and Drop</a> and the <code>input</code> tag allow you to handle multiple files at once, you&#8217;ll need to create as many requests as there are files.</p>

<div class="wp_syntax"><div class="code"><pre class="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><span style="color: #339933;">;</span>
reader.<span style="color: #000066;">onload</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>
  <span style="color: #003366; font-weight: bold;">var</span> bin <span style="color: #339933;">=</span> e.<span style="color: #660066;">target</span>.<span style="color: #660066;">result</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// bin is the binaryString</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
reader.<span style="color: #660066;">readAsBinaryString</span><span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Once the file is read, send it to the server with XMLHttpRequest:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> xhr <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> XMLHttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
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><span style="color: #339933;">;</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><span style="color: #339933;">;</span>
xhr.<span style="color: #660066;">sendAsBinary</span><span style="color: #009900;">&#40;</span>bin<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>You can choose to be notified when specific events,  such as error, success, or abort, occur during the request (see the <a href="https://developer.mozilla.org/En/Using_XMLHttpRequest#In_Firefox_3.5_and_later">MDC documentation</a> for more details).</p>
<h3>Following the Upload Progress</h3>
<p>The <code>progress</code> event provides the size of the uploaded portion of the binary content. This allows you to easily compute how much of the file has been uploaded.</p>
<p>Here&#8217;s an example showing the percentage of the file that has been uploaded so far:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">xhr.<span style="color: #660066;">upload</span>.<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> <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>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>e.<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>e.<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> e.<span style="color: #660066;">total</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// do something</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>

]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/12/uploading-files-with-xmlhttprequest/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
<enclosure url="http://videos.mozilla.org/serv/blizzard/image-upload/2009-12-11-ImageUpload.ogv" length="2273855" type="video/ogg" />
<enclosure url="http://videos.mozilla.org/serv/blizzard/image-upload/2009-12-11-ImageUpload.mov" length="2968459" type="video/quicktime" />
		</item>
		<item>
		<title>file drag and drop in Firefox 3.6</title>
		<link>http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/</link>
		<comments>http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 19:37:21 +0000</pubDate>
		<dc:creator>Paul Rouget</dc:creator>
				<category><![CDATA[Demo]]></category>
		<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[FileAPI]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Firefox 3.6]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=2913</guid>
		<description><![CDATA[In a previous post, we showed you how to upload several files using the input element. In Firefox 3.6, you can let your users drag and drop files directly into your web page, without going through the file picker. Demo If you&#8217;re running the latest Firefox 3.6 beta, check out our interactive demo of drag [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://hacks.mozilla.org/2009/12/multiple-file-input-in-firefox-3-6/">previous post</a>, we showed you how to upload several files using the <code>input</code> element. In Firefox 3.6, you can let your users drag and drop files directly into your web page, without going through the file picker.</p>
<h3>Demo</h3>
<p>If you&#8217;re running the latest <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.6 beta</a>, check out our <a href="http://demos.hacks.mozilla.org/openweb/DnD/">interactive demo of drag and drop</a>.  It showcases two technologies: the <a href="https://developer.mozilla.org/En/DragDrop/DataTransfer">Drag and Drop API</a> and the <a href="https://developer.mozilla.org/en/DOM/FileReader">File API</a>.</p>
<p><video width="500" controls><br />
<source src="http://videos.mozilla.org/serv/blizzard/drag-and-drop/2009-12-11-dnd.ogv" type="video/ogg"/><br />
<source src="http://videos.mozilla.org/serv/blizzard/drag-and-drop/2009-12-11-dnd.mov" type="video/mp4"/><br />
<embed src="http://www.youtube.com/v/4Us6S0fDV7U&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed><br />
</video></p>
<h3>Drag and Drop Events</h3>
<p>To use drag and drop, you first need to tell the browser that a given element can handle dropped objects and will respond to a drop action, using the <code>dragover</code> and <code>drop</code> events.</p>
<p>You also need to prevent the browser&#8217;s default behavior, which is to simply load the dropped object in the browser window.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">dropzone.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;dragover&quot;</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>
  event.<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;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dropzone.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;drop&quot;</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>
  event.<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: #006600; font-style: italic;">// Ready to do something with the dropped object</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>You may also want to use the <code>dragenter</code> and <code>dragleave</code> events to be notified when a drag session starts or stops.</p>
<p>Your element is now ready to receive files with the <code>drop</code> event.</p>
<h3>Manipulating the Files</h3>
<p>On the <code>drop</code> event, you can access the files with the <code>files</code> property of the <a href="https://developer.mozilla.org/en/DragDrop/DataTransfer">DataTransfer</a> object:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">dropzone.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;drop&quot;</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>
  event.<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: #006600; font-style: italic;">// Ready to do something with the dropped object</span>
  <span style="color: #003366; font-weight: bold;">var</span> allTheFiles <span style="color: #339933;">=</span> event.<span style="color: #660066;">dataTransfer</span>.<span style="color: #660066;">files</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;You've just dropped &quot;</span> <span style="color: #339933;">+</span> allTheFiles.<span style="color: #660066;">length</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot; files&quot;</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;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Once you&#8217;ve accessed the files, the <a href="http://hacks.mozilla.org/2009/12/w3c-fileapi-in-firefox-3-6/">File API</a> lets you do much more, like parsing files as a binary array, or displaying a preview of an image by reading the file as a <a href="https://developer.mozilla.org/en/data_URIs">DataURL</a>.</p>
<p>Of course, you can still drag and drop data other than files (e.g. text, URLs, remote images &#8230;) using the <a href="https://developer.mozilla.org/En/DragDrop/DataTransfer">drag and drop API</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
<enclosure url="http://videos.mozilla.org/serv/blizzard/drag-and-drop/2009-12-11-dnd.ogv" length="3178328" type="video/ogg" />
<enclosure url="http://videos.mozilla.org/serv/blizzard/drag-and-drop/2009-12-11-dnd.mov" length="3427652" type="video/quicktime" />
		</item>
		<item>
		<title>W3C FileAPI in Firefox 3.6</title>
		<link>http://hacks.mozilla.org/2009/12/w3c-fileapi-in-firefox-3-6/</link>
		<comments>http://hacks.mozilla.org/2009/12/w3c-fileapi-in-firefox-3-6/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 22:52:55 +0000</pubDate>
		<dc:creator>Arun Ranganathan</dc:creator>
				<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[Featured Article]]></category>
		<category><![CDATA[FileAPI]]></category>
		<category><![CDATA[Firefox 3.6]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=2781</guid>
		<description><![CDATA[Often, web applications will prompt the user to select a file, typically to upload to a server. Unless the web application makes use of a plugin, file selection occurs through an HTML input element, of the sort &#60;input type="file"/&#62;. Firefox 3.6 now supports much of the W3C File API, which specifies the ability to asynchronously [...]]]></description>
			<content:encoded><![CDATA[<p>Often, web applications will prompt the user to select a file, typically to upload to a server.  Unless the web application makes use of a plugin, file selection occurs through an HTML input element, of the sort <code>&lt;input type="file"/&gt;</code>.  Firefox 3.6 now supports much of the <a href="http://www.w3.org/TR/FileAPI/">W3C File API</a>, which specifies the ability to <em>asynchronously read</em> the selected file into memory, and perform operations on the file data within the web application (for example, to display a thumbnail preview of an image, before it is uploaded, or to look for ID3 tags within an MP3 file, or to look for EXIF data in JPEG files, all on the client side).  This is a new API, and replaces the file API that was introduced in Firefox 3.</p>
<p>It is important to note that even before the advent of the <a href="http://www.w3.org/TR/FileAPI/">W3C File API</a> draft (which only became a Working Draft in November 2009), Firefox 3 and later provide the ability to <a href="https://developer.mozilla.org/en/nsIDOMFile">read files into memory <em>synchronously</em></a> but that capability should be considered <em>deprecated</em> in favor of the new implementation in Firefox 3.6 of <a href="https://developer.mozilla.org/en/Using_files_from_web_applications">the asynchronous File API</a>.  The deprecated API allowed you synchronously access a file:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// After obtaining a handle to a file</span>
<span style="color: #006600; font-style: italic;">// access the file data</span>
<span style="color: #003366; font-weight: bold;">var</span> dataURL <span style="color: #339933;">=</span> file.<span style="color: #660066;">getAsDataURL</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
img.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> dataURL<span style="color: #339933;">;</span></pre></div></div>

<p>While Firefox 3.6 will continue to support code usage of the sort above, it should be considered <em>deprecated</em> since it reads files <em>synchronously</em> on the main thread.  For large files, this could result in blocking on the result of the read, which isn&#8217;t desirable.  Moreover, the file object itself provides a method to read from it, rather than having a separate reader object.  These considerations informed the technical direction of the <a href="https://developer.mozilla.org/en/Using_files_from_web_applications">new File API in Firefox 3.6</a> (and the direction of the <a href="http://www.w3.org/TR/FileAPI/">specification</a>).  The rest of this article is about the newly introduced File API.</p>
<p><strong>Accessing file selections</strong></p>
<p>Firefox 3.6 supports <em>multiple file selections</em> on an input element, and returns all the files selected using the <a href="https://developer.mozilla.org/en/DOM/FileList">FileList</a> interface.  Previous versions of Firefox only supported one selection of a file using the input element.  Additionally, the <a href="https://developer.mozilla.org/en/DOM/FileList">FileList</a> interface is also exposed to the <a href="https://developer.mozilla.org/En/DragDrop/Drag_and_Drop">HTML5 Drag and Drop API</a> as a property of the <a href="https://developer.mozilla.org/En/DragDrop/DataTransfer">DataTransfer</a> interface.  Users can drag and drop multiple files to a drop target within a web page as well.</p>
<p>The following HTML spawns the standard file picker, with which you can select multiple files:</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;">input</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;inputFiles&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">multiple</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>Note that if you don&#8217;t use the <code>multiple</code> attribute, you only enable single file selection.</p>
<p>You can work with all the selected files obtained either through the file picker (using the <code>input</code> element) or through the <a href="https://developer.mozilla.org/En/DragDrop/DataTransfer">DataTransfer</a> object by iterating through the FileList:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> files <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;inputFiles&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">files</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// or, for a drag event e:</span>
<span style="color: #006600; font-style: italic;">// var dt = e.dataTransfer; var files = dt.files</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;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> files.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> file <span style="color: #339933;">=</span> files<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  handleFile<span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Properties of files</strong></p>
<p>Once you obtain a reference to an individually selected file from a <a href="https://developer.mozilla.org/en/DOM/FileList">FileList</a>, you get a <a href="https://developer.mozilla.org/en/DOM/File">File</a> object, which has <code>name</code>, <code>type</code>, and <code>size</code> properties.  Continuing with the code snippet above:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> handleFile<span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// RegExp for JPEG mime type</span>
    <span style="color: #003366; font-weight: bold;">var</span> imageType <span style="color: #339933;">=</span> <span style="color: #009966; font-style: italic;">/image\/jpeg/</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Check if match</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>file.<span style="color: #660066;">type</span>.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span>imageType<span style="color: #009900;">&#41;</span><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: #006600; font-style: italic;">// Check if the picture exceeds set limit</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>file.<span style="color: #660066;">size</span> <span style="color: #339933;">&gt;</span> maxSize<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Choose a smaller photo!&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;">false</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
  <span style="color: #006600; font-style: italic;">// Add file name to page</span>
  <span style="color: #003366; font-weight: bold;">var</span> picData <span style="color: #339933;">=</span> document.<span style="color: #660066;">createTextNode</span><span style="color: #009900;">&#40;</span>file.<span style="color: #000066;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  dataGrid.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>picData<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></pre></div></div>

<p>The <code>size</code> attribute is the file&#8217;s size, in bytes.  The <code>name</code> attribute is the file&#8217;s name, without path information.  The <code>type</code> attribute is an ASCII-encoded string in lower case representing the media type of the file, expressed as an <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC2046 MIME type</a>.  The <code>type</code> attribute in particular is useful in sniffing file type, as in the example above, where the script determines if the file in question is a JPEG file.  If Firefox 3.6 cannot determine the file&#8217;s <code>type</code>, it will return the empty string.</p>
<p><strong>Reading Files</strong></p>
<p>Firefox 3.6 and beyond support the <a href="https://developer.mozilla.org/en/DOM/FileReader">FileReader</a> object to read file data asynchronously into memory, using event callbacks to mark progress.  The object is instantiated in the standard way:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> binaryReader <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><span style="color: #339933;">;</span></pre></div></div>

<p>Event handler attributes are used to work with the <code>result</code> of the file read operation.  For very large files, it is possible to watch for <em>progress events</em> as the file is being read into memory (using the <code>onprogress</code> event handler attribute to set the event handler function).  This is useful in scenarios where the drives in question may not be local to the hardware, or if the file in question is particularly big.</p>
<p>The <a href="https://developer.mozilla.org/en/DOM/FileReader">FileReader</a> object supports three methods to read files into memory.  Each allows programmatic access to the files data in a different format, though in practice only one read method should be called on a given <a href="https://developer.mozilla.org/en/DOM/FileReader">FileReader</a> object:</p>
<ul>
<li><code>filereader.readAsBinaryString(file);</code> will asynchronously return a binary string with each byte represented by an integer in the range [0..255].  This is useful for binary manipulations of a file&#8217;s data, for example to look for <a href="http://en.wikipedia.org/wiki/ID3">ID3 tags in an MP3 file</a>, or to look for <a href="http://en.wikipedia.org/wiki/Exchangeable_image_file_format">EXIF data</a> in a JPEG image.</li>
<li><code>filereader.readAsText(file, encoding);</code> will asynchronously return a string in the format solicited by the encoding parameter (for example <code>encoding = "UTF-8"</code>).  This is useful for working with a text file, for example to parse an XML file.</li>
<li><code>filereader.readAsDataURL(file);</code> will asynchronously return a <a href="https://developer.mozilla.org/en/data_URIs">Data URL</a>.  Firefox 3.6 allows large URLs, and so this feature is particularly useful when a URL could help display media content in a web page, for example for image data, video data, or audio data.</li>
</ul>
<p>An example helps tie this all together:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>files.<span style="color: #660066;">length</span> <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</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><span style="color: #339933;">!</span>handleFile<span style="color: #009900;">&#40;</span>files<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        invalid.<span style="color: #660066;">style</span>.<span style="color: #660066;">visibility</span><span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;visible&quot;</span><span style="color: #339933;">;</span>
        invalid.<span style="color: #660066;">msg</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;Select a JPEG Image&quot;</span><span style="color: #339933;">;</span>
     <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> binaryReader <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><span style="color: #339933;">;</span>
binaryReader.<span style="color: #000066;">onload</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> exif <span style="color: #339933;">=</span> findEXIFInJPG<span style="color: #009900;">&#40;</span>binaryReader.<span style="color: #660066;">result</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><span style="color: #339933;">!</span>exif<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #006600; font-style: italic;">// ...set up conditions for lack of data</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;">// ...write out exif data</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
binaryReader.<span style="color: #660066;">onprogress</span> <span style="color: #339933;">=</span> updateProgress<span style="color: #339933;">;</span>
binaryReader.<span style="color: #000066;">onerror</span> <span style="color: #339933;">=</span> errorHandler<span style="color: #339933;">;</span>
&nbsp;
binaryReader.<span style="color: #660066;">readAsBinaryString</span><span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> updateProgress<span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
   <span style="color: #006600; font-style: italic;">// use lengthComputable, loaded, and total on ProgressEvent</span>
   <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>evt.<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> loaded <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>evt.<span style="color: #660066;">loaded</span> <span style="color: #339933;">/</span> evt.<span style="color: #660066;">total</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>loaded <span style="color: #339933;">&lt;</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;">// update progress meter</span>
            progMeter.<span style="color: #660066;">style</span>.<span style="color: #660066;">width</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>loaded <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: #3366CC;">&quot;px&quot;</span><span style="color: #339933;">;</span>
          <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> errorHandler<span style="color: #009900;">&#40;</span>evt<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>evt.<span style="color: #660066;">target</span>.<span style="color: #660066;">error</span>.<span style="color: #660066;">code</span> <span style="color: #339933;">==</span> evt.<span style="color: #660066;">target</span>.<span style="color: #660066;">error</span>.<span style="color: #660066;">NOT_FOUND_ERR</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;File Not Found!&quot;</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>In order to work with binary data, the use of the <a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/String/CharCodeAt">charCodeAt</a> function exposed on strings will be particularly useful.  For instance, an utility of the sort:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> getByteAt<span style="color: #009900;">&#40;</span>file<span style="color: #339933;">,</span> idx<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> file.<span style="color: #660066;">charCodeAt</span><span style="color: #009900;">&#40;</span>idx<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>allows extraction of the Unicode value of the character at the given index.</p>
<p>An example of similar code in action in Firefox 3.6, including use of the <code>readAsDataURL</code> method to render an image, as well as binary analysis of a JPEG for EXIF detection (using the <code>readAsBinaryString</code> method), can be found in <a href="http://hacks.mozilla.org/2009/12/firefox-36-fileapi-demo-reading-exif-data-from-a-local-jpeg-file/">Paul Rouget&#8217;s great demo of the File API.</a>.</p>
<p><strong>A word on the specification</strong></p>
<p>The existence of a W3C public working draft of <a href="http://www.w3.org/TR/FileAPI/">the File API</a> holds the promise of other browsers implementing it shortly.  Firefox 3.6&#8242;s implementation is fairly complete, but is missing some of the technology mentioned in the specification.  Notably, the <code>urn</code> feature on the <a href="https://developer.mozilla.org/en/DOM/File">File</a> object isn&#8217;t yet implemented, and neither is the ability to extract byte-ranges of files using the <code>slice</code> method.  A synchronous way to read files isn&#8217;t yet implemented as part of <a href="https://developer.mozilla.org/En/DOM/Worker">Worker Threads</a>.  These features will come in future versions of Firefox.</p>
<p><strong>References</strong></p>
<ul>
<li><a href="http://www.w3.org/TR/FileAPI/">The W3C File API Specification</a></li>
<li><a href="https://developer.mozilla.org/en/Using_files_from_web_applications">MDC: Using files within web applications</a></li>
<li><a href="https://developer.mozilla.org/en/DOM/FileList">MDC: FileList</a></li>
<li><a href="https://developer.mozilla.org/en/DOM/File">MDC: File</a></li>
<li><a href="https://developer.mozilla.org/en/DOM/FileReader">MDC: FileReader</a></li>
<li><a href="https://developer.mozilla.org/En/DragDrop/Drag_and_Drop">MDC: Drag and Drop</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/12/w3c-fileapi-in-firefox-3-6/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>font_dragr: a drag and drop preview tool for fonts</title>
		<link>http://hacks.mozilla.org/2009/10/font_dragr-a-drag-and-drop-preview-tool-for-fonts/</link>
		<comments>http://hacks.mozilla.org/2009/10/font_dragr-a-drag-and-drop-preview-tool-for-fonts/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 17:00:22 +0000</pubDate>
		<dc:creator>Christopher Blizzard</dc:creator>
				<category><![CDATA[@font-face]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[Firefox 3.6]]></category>

		<guid isPermaLink="false">http://hacks.mozilla.org/?p=2086</guid>
		<description><![CDATA[This demo is from our good friend Ryan Seddon who came up with a demo that seems deeply appropriate for this week, given our focus on the future of fonts on the web. If you&#8217;ve ever been editing a page and wanted to know what a particular font looked like without having to upload files [...]]]></description>
			<content:encoded><![CDATA[<p>This demo is from our good friend <a href="http://twitter.com/thecssninja">Ryan Seddon</a> who came up with a demo that seems deeply appropriate for this week, given our focus on the <a href="http://hacks.mozilla.org/2009/10/font-control-for-designers/ ">future</a> of <a href="http://hacks.mozilla.org/2009/10/woff/">fonts on the web</a>.</p>
<p>If you&#8217;ve ever been editing a page and wanted to know what a particular font looked like without having to upload files to a web server and update CSS (so tedious, that!) then this demo is for you.</p>
<p>He&#8217;s come up with a demo that shows what&#8217;s possible when you&#8217;ve got downloadable fonts, drag and drop and editable content.  (If you want to know more about drag and drop we suggest you read his excellent overview of using <a href="http://www.thecssninja.com/javascript/drag-and-drop-upload">drag and drop to do file uploading</a>.)</p>
<p>From <a href="http://www.thecssninja.com/javascript/font-dragr">Ryan&#8217;s description</a>:</p>
<blockquote><p><a href="http://labs.thecssninja.com/font_dragr/">Font dragr</a> is an experimental web app that uses HTML5 &amp; CSS3 to create a useful standalone web based application for testing custom fonts, once you visit it for the first time you don’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></blockquote>
<p>You can either <a href="http://www.thecssninja.com/javascript/font-dragr">read the full description</a>, which contains a lot of useful technical information about how the demo works, or you can <a href="http://labs.thecssninja.com/font_dragr/">view the demo</a> below.  Either way, it&#8217;s nice to see the excellent HTML5 support in Firefox 3.6 coming together with everything else we&#8217;ve added to bring a lot of new capabilities to web developers and users.</p>
<p>Thanks, Ryan!</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="500" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="flashvars" value="i=20449" /><param name="allowFullScreen" value="true" /><param name="src" value="http://screenr.com/Content/assets/screenr_0817090731.swf" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="500" height="300" src="http://screenr.com/Content/assets/screenr_0817090731.swf" allowfullscreen="true" flashvars="i=20449"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://hacks.mozilla.org/2009/10/font_dragr-a-drag-and-drop-preview-tool-for-fonts/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

