<?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>soledad penadés &#187; javascript</title>
	<atom:link href="http://soledadpenades.com/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://soledadpenades.com</link>
	<description>repeat 4[fd 100 rt 90]</description>
	<lastBuildDate>Sun, 29 Jan 2012 23:03:40 +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>London-New York (and back), via Hong Kong, Macau, Tokyo and San Francisco</title>
		<link>http://soledadpenades.com/2012/01/29/london-new-york-and-back-via-hong-kong-macau-tokyo-and-san-francisco/</link>
		<comments>http://soledadpenades.com/2012/01/29/london-new-york-and-back-via-hong-kong-macau-tokyo-and-san-francisco/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 23:03:40 +0000</pubDate>
		<dc:creator>sole</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[hong kong]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[london]]></category>
		<category><![CDATA[macau]]></category>
		<category><![CDATA[new york]]></category>
		<category><![CDATA[san francisco]]></category>
		<category><![CDATA[sketches]]></category>
		<category><![CDATA[tokyo]]></category>

		<guid isPermaLink="false">http://soledadpenades.com/?p=3891</guid>
		<description><![CDATA[The sketch book I mentioned a couple weeks ago has finally been released! To recap (just in case you accidentally ended here and have no context), it is a travel sketchbook depicting our experiences while travelling around the world these past April and May. I&#8217;ve finally settled on building a simple HTML(5) page with a [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://5013.es/data/projects/b/proj_big.jpg" alt="London-New York (and back), via Hong Kong, Macau, Tokyo and San Francisco" /></p>
<p>The sketch book I mentioned <a href="http://soledadpenades.com/2012/01/12/the-end-of-the-world/">a couple weeks ago</a> has finally been <a href="http://5013.es/sketches/london-newyork/">released</a>! To recap (just in case you accidentally ended here and have no context), it is a travel sketchbook depicting our experiences while travelling <em>around the world</em> these past April and May.</p>
<p>I&#8217;ve finally settled on building a simple HTML(5) page with a sprinkle of Javascript to navigate the bigger images. Something that gets the job done, which is showing you my crazy sketches!</p>
<p>I might possibly build a Kindle version in the near future, so if you&#8217;re a Kindle user, stay tuned ;-)</p>
<p>In the meantime you can read a bit about the background and the &#8220;tools&#8221; in the <a href="http://5013.es/p/b">project page</a>.</p>
 <p><a href="http://soledadpenades.com/?flattrss_redirect&amp;id=3891&amp;md5=e135772421736291f5d9213e7cab3282" title="Flattr" target="_blank"><img src="http://soledadpenades.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://soledadpenades.com/2012/01/29/london-new-york-and-back-via-hong-kong-macau-tokyo-and-san-francisco/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Some notes from Google DevFest Barcelona 2011</title>
		<link>http://soledadpenades.com/2011/11/10/some-notes-from-google-devfest-barcelona-2011/</link>
		<comments>http://soledadpenades.com/2011/11/10/some-notes-from-google-devfest-barcelona-2011/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 16:32:14 +0000</pubDate>
		<dc:creator>sole</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[webgl]]></category>

		<guid isPermaLink="false">http://soledadpenades.com/?p=3822</guid>
		<description><![CDATA[I thought I wouldn&#8217;t make it to the place. Barcelona&#8217;s metro system is still pretty much unknown to me and it&#8217;s hard to find navigational help using the official web from the transport entity. Maps are confusing (we need a Beck!). A shame, but I finally did it, after walking the same loooong underground exchange [...]]]></description>
			<content:encoded><![CDATA[<p>I thought I wouldn&#8217;t make it to the place. Barcelona&#8217;s metro system is still pretty much unknown to me and it&#8217;s hard to find navigational help using the official web from the transport entity. Maps are confusing (we need a <a href="http://en.wikipedia.org/wiki/Harry_Beck">Beck</a>!). A shame, but I finally did it, after walking the same loooong underground exchange that Fuzzion guys used for recording their famous <a href="http://www.youtube.com/watch?v=Txv8pC2niXk">kukka:r0kasit7e!aarku</a> demo. I arrived a tad late, but I did it! Yay! :-) </p>
<p>And while most of the attendees brought their laptops, I went oldschool and brought a trusty notepad and a ballpen to jot down whatever caught my attention.<br />
<span id="more-3822"></span><br />
First in the morning was the HTML session. I didn&#8217;t write anything down about this one, since I was concentrated on looking at the stuff <a href="http://paul.kinlan.me/">Paul Kinlan</a> was showing. I knew about most of the stuff he talked about, but it was a nice reminder. It was cool that the slides were interactive themselves, so he could demonstrate things without getting out of the &#8220;slides environment&#8221;. Then went <a href="http://mrdoob.com">Mr.doob</a> and his short GLSL + WebGL talk. I think it was too short for the topic! Anyway, people were quite impressed with the patterns one could generate by writing a shader, and since he&#8217;s released <a href="http://mrdoob.com/projects/glsl_sandbox/">an improved version</a> of the interactive GLSL sandbox tool he used, you can now experiment in the same way he did! :-)</p>
<p>Then came the break time and I got talking and after that I sadly missed much of the talk about Google+ from <a href="http://www.oshineye.com/">Ade Oshineye</a>, confiding that I would be able to catch up later on by looking at the docs :-P</p>
<p>I entered the conference area again for the Android sessions with <a href="https://plus.google.com/102451193315916178828/about">Bruno Oliveira</a>. I was quite interested in hearing what they had to say, after the recent &#8220;events&#8221;: 4.0 announced, the Android git repo being taken down, the (in)famous fragmentation chart, etc&#8230;</p>
<p>&#8230; and what I heard was a bit disappointing. It seems to me there&#8217;s a <strong>fundamental disconnection</strong> between what Android developers want and what Google/Android has to offer. It was very obvious when questions time arrived and most of the attendees were asking questions about monetising the apps (or in other words, being able to recover the investment on the platform), and pretty much all Bruno had to answer was that Android intended to be <q>a democratic platform, focused on what the user wants</q>, and not forcing them to do something like entering credit card information when turning on the device for the first time. He also added that Android wasn&#8217;t targeted to any specific income range as <q>other platforms</q> do.</p>
<p>When asked about &#8220;fragmentation&#8221; he said that:<br />
<blockquote>[...] diversity is a feature of the platform, is not really fragmentation. Different operating system versions [...] is what people call fragmentation [...]<br />
It&#8217;s a consequence of being open source [...] we don&#8217;t want to put pressure on manufacturers. Maybe in a friendly way, releasing cool inspiring phones like the Nexus S, etc&#8230; [...]</p></blockquote>
<p>He was also asked about the agreement between Android and manufacturers regarding updates that was announced and widely discussed on past Google I/O, but after digressing for a while he didn&#8217;t give any definite statement on that matter.</p>
<p>Then he went on to give some advice on how to make great apps, suggesting we should <strong>detect the available features</strong> on each device and act accordingly, activating or deactivating features in our apps, because <q>not being compatible with a certain phone is being arrogant, like saying to the user that he bought the wrong phone</q>.</p>
<p>This is something that particularly irks me, as sometimes there&#8217;s no written specification that app developers can consult and be confident will be followed to the letter, as each phone diverges a lot on its behaviour. It&#8217;s impossible to know in advance what will happen unless you test it with the real phone. Yes, there&#8217;s the emulator, and that famous esoteric compatibility suite that a phone must passed in order to have the Google apps (Market, Gmail&#8230;) installed, but that doesn&#8217;t guarantee that a real phone will have a proper, complete GL ES implementation, for example.</p>
<p>So making that type of statements did actually sound wildly arrogant on <em>his</em> side. And he went on, happily adding there wasn&#8217;t no excuse for not creating all the different versions of resources for all the different screen sizes and densities. This was followed by a general moaning and mumbling in the public, as with each new release of the SDK not only are there new features that need to be used if you want a &#8220;cool app&#8221; that uses the latest stuff in new phones, but there are also new resources to be created and maintained, thus increasing the complexity required to build something &#8220;great&#8221; for Android versions &le; X.</p>
<p>Something else that really worries/annoys me is the <strong>insistence in showing raw activation and installation numbers</strong> in every presentation they do. It doesn&#8217;t make much sense on the long term: I have probably activated four devices but that doesn&#8217;t mean I use all of them (as I use them for testing), or that I am four different potential users. Another use case: people using carrier-subsidised phones change them quite often, but that doesn&#8217;t mean a new user is created from void each time a new phone is activated. It&#8217;s still the <em>same</em> user and he&#8217;s not going to expand the market&#8211;it actually stays the same, as the old phone will probably get thrown in a drawer. Same goes for installation numbers: that you install an application doesn&#8217;t mean you actually use or keep it on your device. They could show uninstallation numbers too, and the ratio between installs and uninstalls would be a way better indicator (but probably not as attractive).</p>
<p>Moving on, it was lunch time, which we used to discuss the above points. Most people dismissed Bruno&#8217;s compatibility strategy as it&#8217;s plain unrealistic (unless you have an infinite number of testing resources, or simply build very basic and unexciting apps). Some jokes were made about the fragmentation &#8220;feature&#8221;: <q>it&#8217;s not a defective phone, it&#8217;s a feature!</q>.</p>
<p>After lunch we got Paul Kinlan again, explaining several strategies for &#8220;making a business out of apps&#8221;. Again he relied massively on AdSense, which has proven to be a very unreliable and arbitrary source of income. He also mentioned the Chrome Webstore, of course, but it&#8217;s not very widely extended yet. This session wasn&#8217;t as enlightening as the HTML session, as the concepts weren&#8217;t new and &#8230; well, you can imagine the rest.</p>
<p>Next was Danny Hermes with an strange session on the Shopping API. He sounded slightly apologetic and felt like out of place since there wasn&#8217;t even a &#8220;Shopping&#8221; icon on the banner, whereas there were G+, Android and Chrome icons, but at least was really enthusiastic about his topic. I guess this talk could be interesting for people integrating Google&#8217;s Product Search with online shops, but this is not something I&#8217;m currently interested at so I didn&#8217;t pay much attention.</p>
<p>Sam Dutton&#8217;s Chrome Dev Tools session was way more interesting. It was funny that we were commenting: <q>it would be cool if you could save the changes you do live&#8230;</q> And then he said: <q>here&#8217;s this new feature: now you can save the changes you made to the document!</q>. </p>
<p>It also made me slightly envious: the Chrome developer tools are an amazing platform for developing, and the Android toolset pales in comparison. It&#8217;s all &#8220;hacks&#8221; here and there: a separate app for tracing, another one for viewing the layout, an app for debugging&#8230; Seems like Google should invest more in the Android team ;-)</p>
<p>It was time for &#8220;snacks&#8221; again. I had a coffee, thanks to the help of <a href="http://www.clicktorelease.com/code/">@thespite</a> which showed me how to use a Nespresso machine. Yes, I had never used one before&#8211;I&#8217;m a slow-food sort of person and generally use a french coffee maker instead ;-)</p>
<p>And finally it was time for more Ade Oshineye talks, this time on the Google+ Hangouts API, but for some reason (saturation?) my brain squarely refused to pay attention. I&#8217;m so sorry Ade! See, if the talks had been recorded I might be able to watch them ;-)</p>
<p>After the talk finished, it was &#8220;Pitch your app&#8221; time, where several attendees tried to convince us that their app was the best ever. The best demonstration got a voucher redeemable for a Nexus S, since the phone is not available for sale yet. I was nicely surprised by the level of English demonstrated by the guys pitching the app. They still have a lot of Spanish accent but they aren&#8217;t kicking the grammar like a punch bag every two words, and that&#8217;s something you can&#8217;t say about most mono-English speakers! So well done on that front!</p>
<p>Regarding the apps, I was a bit less impressed, as most of them weren&#8217;t really surprising: weather aggregation services, GPS tracking+Maps, cloud CMS integration, a football game, a chess game, bike rental locations aggregation/visualisation&#8230; nothing that got me enthusiastic about :-P</p>
<p>What <em>did</em> surprise me in fact was that one of the pitchers connected his laptop to the projector and I could see how he opened a terminal and wrote &#8220;pm-suspend&#8221; prior to disconnecting the computer from the projector. Now that is hardcore! Who needs widgets to suspend the computer? A terminal is all you need! \o/</p>
<p>So to sum up, it was quite an event-packed day, quite professionally organised. Thanks and well done, Google! It not only provide me with some new ideas and tricks, but it also got me thinking about the true Google strategy on Android. Unfortunately the post was getting too long, and that discourse seemed slightly out of place, so I cut that part out and will refine and publish it in the near future as a separate post.</p>
<p>Here&#8217;s hoping there&#8217;ll be a future DevFest BCN 2012! :-)</p>
 <p><a href="http://soledadpenades.com/?flattrss_redirect&amp;id=3822&amp;md5=6d2d33ee58f0ef1b8893fb9725ee817c" title="Flattr" target="_blank"><img src="http://soledadpenades.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://soledadpenades.com/2011/11/10/some-notes-from-google-devfest-barcelona-2011/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Macabre Pool</title>
		<link>http://soledadpenades.com/2011/10/31/macabre-pool/</link>
		<comments>http://soledadpenades.com/2011/10/31/macabre-pool/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 17:49:04 +0000</pubDate>
		<dc:creator>sole</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[box2d]]></category>
		<category><![CDATA[box2dweb]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[canvg]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[svg]]></category>

		<guid isPermaLink="false">http://soledadpenades.com/?p=3788</guid>
		<description><![CDATA[This is the result of my fascination with skeletons* and me wanting to learn about Box2D in Javascript. Since everything is randomised, you might get two big skeletons or a big one and a small one, or two small ones. They sometimes look like they are alive, with spasms and all, while they jump around [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://5013.es/toys/macabre_pool/"><img src="/imgs/2011/macabre_pool.png" alt="Macabre Pool" /></a></p>
<p>This is the result of my fascination with skeletons* and me wanting to learn about Box2D in Javascript.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/Wdp1SoMXC_I" frameborder="0" allowfullscreen></iframe></p>
<p>Since everything is randomised, you might get two big skeletons or a big one and a small one, or two small ones. They sometimes look like they are alive, with spasms and all, while they jump around the screen with the head in their hands. It&#8217;s very creepy.</p>
<p><a href="http://5013.es/toys/macabre_pool/">Try it if you dare!</a></p>
<p><a href="http://code.google.com/p/box2dweb/">Box2DWeb</a> is quite funny; I should do more stuff with it. I had tried to learn Box2D.js before, without success, but this time I stumbled upon Seth Ladd&#8217;s <a href="http://blog.sethladd.com/2011/08/box2d-orientation-for-javascript.html">series</a> of brilliant Box2DWeb tutorials, and you can deduct the rest.</p>
<p>The graphics are SVG based. I drew them all with Inkscape. I then use <a href="http://canvg.googlecode.com">CanVG</a> for loading SVGs into Canvas (everything is rendered into a big Canvas), as there isn&#8217;t a native SVG method for getting a bitmap from a rendered SVG object. <a href="http://mrdoob.com">Mr.doob</a> suggests using SVG directly instead of going through canvas, because it might be faster. I guess I&#8217;ll try that with something else; for now I&#8217;m just rendering to bitmap/canvas once, so it&#8217;s a relatively low overhead. I also cache the SVG to Canvas results, so even if you request the same asset several times it won&#8217;t be read and regenerated each time.</p>
<p>Finally I also used a couple of <a href="http://www.google.com/webfonts/specimen/IM+Fell+DW+Pica">web fonts</a> and some CSS 3 stuff such as box and text shadows, which can be finally used without -moz or -webkit prefixes (at least with Chromium 15 and Firefox 7). Pretty cool!</p>
<p>And of course a huge source of inspiration was Mr.doob&#8217;s <a href="http://mrdoob.com/projects/chromeexperiments/ball_pool/">Ball Pool</a>!</p>
<p><small>* <a href="http://soledadpenades.com/2006/10/10/using-skeletons-for-selling-books/">Proof</a> and <a href="http://p.soledadpenades.com/photo/1379/">proof</a> of my skeleton-mania.</small></p>
 <p><a href="http://soledadpenades.com/?flattrss_redirect&amp;id=3788&amp;md5=6471ff501956b8df69f9c0f0a2cb15b0" title="Flattr" target="_blank"><img src="http://soledadpenades.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://soledadpenades.com/2011/10/31/macabre-pool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5&#8242;s custom attributes minigotcha</title>
		<link>http://soledadpenades.com/2011/10/16/html5s-custom-attributes-minigotcha/</link>
		<comments>http://soledadpenades.com/2011/10/16/html5s-custom-attributes-minigotcha/#comments</comments>
		<pubDate>Sun, 16 Oct 2011 19:29:27 +0000</pubDate>
		<dc:creator>sole</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[custom attributes]]></category>
		<category><![CDATA[dataset]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[notes to self]]></category>

		<guid isPermaLink="false">http://soledadpenades.com/?p=3760</guid>
		<description><![CDATA[I was trying to set a Javascript Object as the value for a custom attribute, but I was just getting &#8220;[Object object]&#8221; as the value when reading it back. This is actually the toString() version of my object, and was also my &#8216;fault&#8217; for not reading the specs (or for daring to attempt something risky!), [...]]]></description>
			<content:encoded><![CDATA[<p>I was trying to set a Javascript Object as the value for a custom attribute, but I was just getting &#8220;[Object object]&#8221; as the value when reading it back. This is actually the toString() version of my object, and was also my &#8216;fault&#8217; for not reading the specs (or for daring to attempt something risky!), as <strong>the custom attributes can only contain strings</strong>:</p>
<blockquote><p>
element . dataset<br />
Returns a DOMStringMap object for the element&#8217;s data-* attributes.
</p></blockquote>
<p> (<a href="http://dev.w3.org/html5/spec/elements.html#embedding-custom-non-visible-data-with-the-data-attributes"># source</a>)</p>
<blockquote><p>
[...] The custom data attributes is transformed to a key for the DOMStringMap entry [...]
</p></blockquote>
<p> (<a href="https://developer.mozilla.org/en/DOM/element.dataset"># source</a>)</p>
<p>Or more specifically, only &#8216;DOMStrings&#8217; are allowed.</p>
 <p><a href="http://soledadpenades.com/?flattrss_redirect&amp;id=3760&amp;md5=4258a2b75d70e87ab75adc3911957b48" title="Flattr" target="_blank"><img src="http://soledadpenades.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://soledadpenades.com/2011/10/16/html5s-custom-attributes-minigotcha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>File upload &amp; drag and drop with HTML5</title>
		<link>http://soledadpenades.com/2010/11/08/file-upload-drag-and-drop-with-html5/</link>
		<comments>http://soledadpenades.com/2010/11/08/file-upload-drag-and-drop-with-html5/#comments</comments>
		<pubDate>Mon, 08 Nov 2010 17:40:44 +0000</pubDate>
		<dc:creator>sole</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://soledadpenades.com/?p=3133</guid>
		<description><![CDATA[My use case: I want to drag a file from my local filesystem and drop it into a web page. Then I want to do stuff with the data in the file. This wasn&#8217;t possible until recently, but thanks to HTML5 we can do this natively, without using external plug-ins. Yay! First thing is to [...]]]></description>
			<content:encoded><![CDATA[<p>My use case: I want to drag a file from my local filesystem and drop it into a web page. Then I want to do stuff with the data in the file.</p>
<p>This wasn&#8217;t possible until recently, but thanks to HTML5 we can do this natively, without using external plug-ins. Yay!<br />
<span id="more-3133"></span><br />
First thing is to <strong>make an HTML element draggable</strong>. In practice, this means adding two event listeners to it that, in turn, <em>cancel</em> the event. In my case, I want to make the entire web page the &#8220;target&#8221; of the dragging, so I&#8217;ll add these listeners to the <strong>window</strong> object:</p>
<div class="syhi_block"><code><span style="color: #003366; font-weight: bold;">var</span> cancel <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><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>event.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
window.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'dragover'</span><span style="color: #339933;">,</span> cancel<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><br />
window.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'dragenter'</span><span style="color: #339933;">,</span> cancel<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></code></div>
<p>As you see, first we declare a cancel function, then use it as the event handler for both <strong>dragover</strong> and <strong>dragenter</strong> events.</p>
<p>Now we need to <strong>add a listener for the drop event</strong>. Again, we add it to the <strong>window</strong> object:</p>
<div class="syhi_block"><code>window.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'drop'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> files <span style="color: #339933;">=</span> event.<span style="color: #660066;">dataTransfer</span>.<span style="color: #660066;">files</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <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;">==</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> file <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: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <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><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reader.<span style="color: #000066;">onerror</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><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">switch</span><span style="color: #009900;">&#40;</span>e.<span style="color: #660066;">target</span>.<span style="color: #660066;">error</span>.<span style="color: #660066;">code</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">case</span> e.<span style="color: #660066;">target</span>.<span style="color: #660066;">error</span>.<span style="color: #660066;">NOT_FOUND_ERR</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">log</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><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">case</span> e.<span style="color: #660066;">target</span>.<span style="color: #660066;">error</span>.<span style="color: #660066;">NOT_READABLE_ERR</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;file not readable&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">case</span> e.<span style="color: #660066;">target</span>.<span style="color: #660066;">error</span>.<span style="color: #660066;">ABORT_ERR</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;aborted&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'generic error?'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reader.<span style="color: #000066;">onload</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>theFile<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</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><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> file_contents <span style="color: #339933;">=</span> e.<span style="color: #660066;">target</span>.<span style="color: #660066;">result</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; do_stuff<span style="color: #009900;">&#40;</span>file_contents<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reader.<span style="color: #660066;">readAsText</span><span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<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></code></div>
<p>Let&#8217;s go through the code.</p>
<p>First we look at <em>event.dataTransfer.files</em>. This will contain a representation of the files that have been dropped into the browser window. Since I want to accept exactly one file only, I check for the length of the files property. If it&#8217;s not 1, nothing else happens.</p>
<p>And if it is, we create a <a href="http://www.w3.org/TR/file-upload/#dfn-filereader">FileReader</a>, which is a nifty Javascript object that takes care of asynchronously loading the file. We need to define at least the <strong>onload</strong> event for the FileReader, since that gets called when our file is ready for consumption. We can also define the <strong>onerror</strong> event, just in case things go awry.</p>
<p>The <em>onerror</em> handler is quite simple conceptually &#8211;it simply dumps an error to the console.</p>
<p>The <em>onload</em> handler is a bit more elaborated: we use a function which returns a function which is finally the handler. This might seem overly complicated, but the explanation is that this code can be extended to handle more than one file, and in that case you definitely need this closure-style of function, or otherwise the function will get bound to the wrong argument. The way it is now, <em>onload</em> is finally this:</p>
<div class="syhi_block"><code><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>file<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> file_contents <span style="color: #339933;">=</span> file.<span style="color: #660066;">target</span>.<span style="color: #660066;">result</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; do_stuff<span style="color: #009900;">&#40;</span>file_contents<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></code></div>
<p>&#8230; and that&#8217;s because that &#8220;<em>(file);</em>&#8221; at the end of the &#8220;<em>(function {} )</em>&#8221; block makes it execute in place :)</p>
<p>If you&#8217;re confused, don&#8217;t worry. Just re-read everything carefully.</p>
<p>Finally, we just tell the reader to <strong>read the file contents plain text</strong>. As I said before, this is an asynchronous process, so we don&#8217;t get the result instantly. Instead, we get it in the <em>onload</em> handler.</p>
<p>It&#8217;s important to understand this, specially if you come from a background of traditional sequential programming, where you would have expected something like this instead:</p>
<div class="syhi_block"><code><span style="color: #000088;">$file_contents</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/file_get_contents"><span style="color: #990000;">file_get_contents</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'filename.txt'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></code></div>
<p>and would have the results immediately in $file_contents, once the read is done. It would also be blocking, i.e. your script would get stuck in file_get_contents until everything is read.</p>
<h3>THE Gotcha</h3>
<p><strong>You will never get the contents of the dragged file if you&#8217;re working with a local page</strong> (i.e. the url starts with file:///). <em>Never</em>. This was driving me insane, until I decided to implement the <em>onerror</em> handler, and got a NOT_READABLE_ERR error. That helped me track the error to this <a href="http://code.google.com/p/chromium/issues/detail?id=59241">bug</a>, but still&#8230; I didn&#8217;t find it mentioned anywhere else.</p>
<p>So when developing <strong>you&#8217;ll need to use a local server</strong>, and access your code from within it (e.g. <em>http://localhost/test/draganddrop.html</em>). Not that it&#8217;s complicated to get a working local web server nowadays, but it&#8217;s something to take into account.</p>
<p><strong>Note</strong>: <a href="http://mrdoob.com/">Mr.doob</a> has told me about a command line option for enabling local file access with Chrome:</p>
<div class="syhi_block"><code>--allow-file-access-from-files</code></div>
<p>You need to modify your launcher or whatever you use to launch Chrome, so that it uses that flag. E.g.
<div class="syhi_block"><code>chrome --allow-file-access-from-files</code></div>
<h3>An example?</h3>
<p>I used this technique (and pretty much all the sample codes are taken from there without modification) in my <a href="lab.soledadpenades.com/android/kml/">KML to DDMS tool</a>. The code is not obfuscated, so you might want to take a look at it :-)</p>
<h3>More information</h3>
<ul>
<li><a href="http://www.html5rocks.com/features/file">HTML5 Rocks &#8211; File Access</a></li>
<li><a href="http://www.w3.org/TR/file-upload">W3C&#8217;s File API specs</a></li>
<li><a href="https://developer.mozilla.org/en/JavaScript/Guide/Closures">Javascript closures</a></li>
</ul>
 <p><a href="http://soledadpenades.com/?flattrss_redirect&amp;id=3133&amp;md5=f4411b067d7bafe59d4cb7a657abf020" title="Flattr" target="_blank"><img src="http://soledadpenades.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://soledadpenades.com/2010/11/08/file-upload-drag-and-drop-with-html5/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

