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

<channel>
	<title>The CSS Ninja &#187; javascript</title>
	<atom:link href="http://www.thecssninja.com/category/javascript/feed" rel="self" type="application/rss+xml" />
	<link>http://www.thecssninja.com</link>
	<description>All things CSS, JavaScript &#38; HTML</description>
	<lastBuildDate>Sat, 21 Jan 2012 02:06:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>A short Modernizr course</title>
		<link>http://www.thecssninja.com/javascript/modernizr-course</link>
		<comments>http://www.thecssninja.com/javascript/modernizr-course#comments</comments>
		<pubDate>Wed, 11 Jan 2012 22:57:34 +0000</pubDate>
		<dc:creator>Ryan Seddon</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=955</guid>
		<description><![CDATA[Last year, I did a quick 5 min presentation on some of the features available in Modernizr for Web Directions What Do You Know event. From there, Sitepoint &#038; Learnable&#8217;s Kevin Yank asked me to put together a short course for learnable.com based on the presentation. So after working on the occasional weekend I put [...]]]></description>
			<content:encoded><![CDATA[<p>Last year, I did a quick 5 min presentation on some of the features available in Modernizr for <a href="http://whatdoyouknow.webdirections.org/videos/all-up-in-your-grill-with-modernizr"><em>Web Directions What Do You Know</em></a> event. From there, Sitepoint &#038; Learnable&#8217;s Kevin Yank asked me to put together a short course for <a href="http://learnable.com">learnable.com</a> based on the presentation. So after working on the occasional weekend I put it all together and got it launched just before xmas 2011.<span id="more-955"></span></p>
<div class="clear">&nbsp;</div>
<p><a href="https://learnable.com/courses/modernizr-front-end-development-done-right-2561"><img src="http://www.thecssninja.com/wp-content/uploads/2012/01/mzr_sml.png" alt="Modernizr: front-end development done right" width="609" height="207" class="article-img main-img" /></a></p>
<p><a href="https://learnable.com/courses/modernizr-front-end-development-done-right-2561">Go check it out</a>! As a thank you for reading I will give away some free passes to the first 10 people who can answer this question correctly:</p>
<p>&#8220;Who created the Modernizr project?&#8221;</p>
<p>Mention me on twitter, <a href="http://twitter.com/ryanseddon">@ryanseddon</a>, with your answer to the question.</p>
<p>I will let the winners know via twitter.</p>
<p>If you don&#8217;t answer in time, don&#8217;t fret! It&#8217;s super cheap to get access to <a href="https://learnable.com/courses/modernizr-front-end-development-done-right-2561">my course</a> and many others at <a href="http://learnable.com">learnable.com</a>, 2012 is the year of upskilling so get onto it!</p>
<p class="shorty01">Short URL: <a href="http://cssn.in/ja/038">http://cssn.in/ja/038</a></p>
<div class="clear">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/modernizr-course/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Playing with the clipboard in iOS safari</title>
		<link>http://www.thecssninja.com/javascript/ios-clipboard</link>
		<comments>http://www.thecssninja.com/javascript/ios-clipboard#comments</comments>
		<pubDate>Wed, 21 Dec 2011 10:33:16 +0000</pubDate>
		<dc:creator>Ryan Seddon</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=940</guid>
		<description><![CDATA[So the other day it hit me that since iOS safari supports contenteditbale it should surely have support the clipboard events and other handy bits and pieces. Like any good hacker I created a testcase to find out basic support of events and getting selection range values, and as expected the support is pretty good. [...]]]></description>
			<content:encoded><![CDATA[<p>So the other day it hit me that since iOS safari supports contenteditbale it should surely have support the clipboard events and other handy bits and pieces. Like any good hacker I created a <a href="http://www.thecssninja.com/demo/clipboard/">testcase</a> to find out basic support of events and getting selection range values, and as expected the support is pretty good. Let&#8217;s dive deeper.<span id="more-940"></span></p>
<div class="clear">&nbsp;</div>
<div class="resources01"><a href="http://www.thecssninja.com/demo/clipboard/" title="Playing with the clipboard in iOS safari" class="demo" target="_blank">View a live demo</a> <a href="http://www.thecssninja.com/demo/clipboard/clipboard.zip" title="Download the source of the Playing with the clipboard in iOS safari demo" class="demo source" target="_blank">Download the source files</a></div>
<h2 class="subtitle02">Clipboard events</h2>
<p>The testcase above hooks into six events that will trigger when the user does a clipboard operation, unfortunately the before[cut/copy/paste] events don&#8217;t seem to trigger.</p>
<h2 class="subtitle02">Range objects</h2>
<p>Range objects are what you&#8217;ve selected on the page allowing you to alter the selection or simply just return what a user has selected. Ranges also allow you to programmatically set a selection within your document, both of these work in iOS safari.</p>
<p>When setting a range iOS Safari won&#8217;t actually show the selection as highlighted but if you were to check the document selection it would return the correct content, desktop browsers will show the range selected in the document. </p>
<p>However if you do the same with a user action like tapping the &#8220;set selection range&#8221; button in the demo the iOS highlight will show up. Another interesting quirk is if I tap the content and bring the keyboard up but don&#8217;t dismiss it then refresh the page the programmatically set selection will show the iOS selection highlight.</p>
<p>Another interesting find is if you perform <code>execCommand</code>, which I&#8217;ll touch on later in the article, like bold it will apply the command to the selection made and make the iOS selection UI appear.</p>
<div class="code syntax">
<pre><span class="kd">var</span> <span class="nx">sel</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">getSelection</span><span class="p">(),</span>
    <span class="nx">range</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createRange</span><span class="p">();</span>

<span class="nx">range</span><span class="p">.</span><span class="nx">setStart</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s2">"h1"</span><span class="p">)[</span><span class="mi">0</span><span class="p">].</span><span class="nx">firstChild</span><span class="p">,</span> <span class="mi">5</span><span class="p">);</span>
<span class="nx">range</span><span class="p">.</span><span class="nx">setEnd</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s2">"p"</span><span class="p">)[</span><span class="mi">2</span><span class="p">].</span><span class="nx">firstChild</span><span class="p">,</span> <span class="mi">50</span><span class="p">);</span>
<span class="nx">sel</span><span class="p">.</span><span class="nx">removeAllRanges</span><span class="p">();</span>
<span class="nx">sel</span><span class="p">.</span><span class="nx">addRange</span><span class="p">(</span><span class="nx">range</span><span class="p">);</span>
</pre>
</div>
<p>You&#8217;ll notice that when selecting an element I get its <code>firstChild</code>, which is a textnode, this is so the offset value will work and allows you to select half a textnode. </p>
<p>The code is saying create a range starting at the documents first h1 element offsetting the selection by 5 characters and ending at the 3rd paragraph offsetting the end of the paragraph by 50 characters.</p>
<h2 class="subtitle02">Setting clipboard data</h2>
<p>Accessing the clipboard is an incredibly sporadic task, there is sort of access in some browsers. IE has the most consistent behaviour similar to how DnD data setting works you have a <code>clipboardData</code> interface which has get and <code>setData</code> methods on it. Other browsers have semi-reversed engineered the IE API with the exception that <code>clipboardData</code> is on the event object rather than the window. iOS Safari allows you to get the clipboard data on a paste event but doesn&#8217;t allow you to set it.</p>
<p>There is hope that clipboard access will one day have some consistent support through the <a href="http://dev.w3.org/2006/webapi/clipops/">Clipboard API editor spec</a> but that&#8217;s a long way off for now.</p>
<p>In the demo if you&#8217;ve copied text from another location and paste it it will alert the clipboard contents before being pasted.</p>
<div class="code syntax">
<pre><span class="k">if</span><span class="p">(</span><span class="s2">"clipboardData"</span> <span class="k">in</span> <span class="nx">e</span> <span class="o">&amp;&amp;</span> <span class="nx">e</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"paste"</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">alert</span><span class="p">(</span><span class="s2">"Clipboard data: "</span> <span class="o">+</span> <span class="nx">e</span><span class="p">.</span><span class="nx">clipboardData</span><span class="p">.</span><span class="nx">getData</span><span class="p">(</span><span class="s1">'text/plain'</span><span class="p">));</span>
<span class="p">}</span>
</pre>
</div>
<h2 class="subtitle02">WYSIWYG</h2>
<p>By adding support for the contenteditable attribute comes a whole swoth of API&#8217;s available for manipulating the contents, one of those is execCommand.</p>
<p><code>execCommand</code> allows you to do a whole bunch things to the content. Take a look at this <a href="http://help.dottoro.com/larpvnhw.php">great resource</a> which shows all the commands available and its support in the major browsers. These commands allow you to manipulate the style and html of the editable content (this is how all those fancy WYSIWYG editors work).</p>
<p>I would be keen to know if this works on other smart phone browsers, leave a comment if you know more details.</p>
<p class="shorty01">Short URL: <a href="http://cssn.in/ja/037">http://cssn.in/ja/037</a></p>
<div class="clear">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/ios-clipboard/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>addEventListener, handleEvent and passing objects</title>
		<link>http://www.thecssninja.com/javascript/handleevent</link>
		<comments>http://www.thecssninja.com/javascript/handleevent#comments</comments>
		<pubDate>Fri, 21 Oct 2011 09:47:20 +0000</pubDate>
		<dc:creator>Ryan Seddon</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=898</guid>
		<description><![CDATA[Here&#8217;s a super awesome trick I had no idea about until someone pointed out you could do this. addEventListener can take an object as a second argument that will look for a method called handleEvent and call it! No need for binding &#8220;this&#8221; so it will pass around the context correctly, the context is the [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a super awesome trick I had no idea about until someone pointed out you could do this. <code>addEventListener</code> can take an object as a second argument that will look for a method called <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener-handleEvent"><code>handleEvent</code></a> and call it! No need for binding &#8220;this&#8221; so it will pass around the context correctly, the context is the object you&#8217;ve just set as the event listener callback.<span id="more-898"></span></p>
<div class="clear">&nbsp;</div>
<div class="code">
<pre style='color:#d1d1d1;background:#000000;'><span style='color:#e66170; font-weight:bold; '>var</span> obj <span style='color:#d2cd86; '>=</span> <span style='color:#b060b0; '>{</span>
    handleEvent<span style='color:#b060b0; '>:</span> <span style='color:#e66170; font-weight:bold; '>function</span><span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
        alert<span style='color:#d2cd86; '>(</span><span style='color:#e66170; font-weight:bold; '>this</span><span style='color:#d2cd86; '>.</span>dude<span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
    <span style='color:#b060b0; '>}</span><span style='color:#d2cd86; '>,</span>
    dude<span style='color:#b060b0; '>:</span> <span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>holla</span><span style='color:#02d045; '>"</span>
<span style='color:#b060b0; '>}</span><span style='color:#b060b0; '>;</span>

element<span style='color:#d2cd86; '>.</span>addEventListener<span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>click</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>,</span> obj<span style='color:#d2cd86; '>,</span> <span style='color:#0f4d75; '>false</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
</pre>
</div>
<div class="resources01"><a target="_blank" class="demo" title="A demo showing handleEvent" href="http://www.thecssninja.com/demo/handleEvent/">View a live demo</a> <a target="_blank" class="demo source" title="Download the source of the handleEvent demo" href="http://www.thecssninja.com/demo/handleEvent/handleEvent.zip">Download the source files</a></div>
<h2 class="subtitle02">Why is this awesome?</h2>
<p>We can do things like this:</p>
<div class="code">
<pre style='color:#d1d1d1;background:#000000;'><span style='color:#e66170; font-weight:bold; '>var</span> obj  <span style='color:#d2cd86; '>=</span>  <span style='color:#b060b0; '>{</span>
    init<span style='color:#b060b0; '>:</span> <span style='color:#e66170; font-weight:bold; '>function</span><span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
        document<span style='color:#d2cd86; '>.</span>getElementById<span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>btn</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>)</span><span style='color:#d2cd86; '>.</span>addEventListener<span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>click</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>,</span> <span style='color:#e66170; font-weight:bold; '>this</span><span style='color:#d2cd86; '>,</span> <span style='color:#0f4d75; '>false</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
        document<span style='color:#d2cd86; '>.</span>getElementById<span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>btn</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>)</span><span style='color:#d2cd86; '>.</span>addEventListener<span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>touchstart</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>,</span> <span style='color:#e66170; font-weight:bold; '>this</span><span style='color:#d2cd86; '>,</span> <span style='color:#0f4d75; '>false</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
    <span style='color:#b060b0; '>}</span><span style='color:#d2cd86; '>,</span>
    handleEvent<span style='color:#b060b0; '>:</span> <span style='color:#e66170; font-weight:bold; '>function</span><span style='color:#d2cd86; '>(</span>e<span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
        <span style='color:#e66170; font-weight:bold; '>switch</span><span style='color:#d2cd86; '>(</span>e<span style='color:#d2cd86; '>.</span>type<span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
            <span style='color:#e66170; font-weight:bold; '>case</span> <span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>click</span><span style='color:#02d045; '>"</span><span style='color:#b060b0; '>:</span>
                <span style='color:#e66170; font-weight:bold; '>this</span><span style='color:#d2cd86; '>.</span>button<span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
                <span style='color:#e66170; font-weight:bold; '>break</span><span style='color:#b060b0; '>;</span>
            <span style='color:#e66170; font-weight:bold; '>case</span> <span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>touchstart</span><span style='color:#02d045; '>"</span><span style='color:#b060b0; '>:</span>
                <span style='color:#e66170; font-weight:bold; '>this</span><span style='color:#d2cd86; '>.</span>button<span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
                <span style='color:#e66170; font-weight:bold; '>break</span><span style='color:#b060b0; '>;</span>
        <span style='color:#b060b0; '>}</span>
    <span style='color:#b060b0; '>}</span><span style='color:#d2cd86; '>,</span>
    dude<span style='color:#b060b0; '>:</span> <span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>holla</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>,</span>
    button<span style='color:#b060b0; '>:</span> <span style='color:#e66170; font-weight:bold; '>function</span><span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
        alert<span style='color:#d2cd86; '>(</span><span style='color:#e66170; font-weight:bold; '>this</span><span style='color:#d2cd86; '>.</span>dude<span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
    <span style='color:#b060b0; '>}</span>
<span style='color:#b060b0; '>}</span><span style='color:#b060b0; '>;</span>

obj<span style='color:#d2cd86; '>.</span>init<span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
</pre>
</div>
<p>As you can see our object has an <code>init()</code> method which binds all the events and just passes in &#8220;this&#8221; as the callback, <code>handleEvent</code> then delegates off to whatever method it needs based on the event being triggered, rad.</p>
<h2 class="subtitle02">But wait there&#8217;s more</h2>
<p>Another awesome thing we can do is change the buttons behaviour without having to remove and re-attach the event handler. The second button in the demo changes what the first button does by redefining the handleEvent method. </p>
<div class="code">
<pre style='color:#d1d1d1;background:#000000;'>changeHandleEvent<span style='color:#b060b0; '>:</span> <span style='color:#e66170; font-weight:bold; '>function</span><span style='color:#d2cd86; '>(</span>evt<span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
    <span style='color:#e66170; font-weight:bold; '>this</span><span style='color:#d2cd86; '>.</span>_handleEvent <span style='color:#d2cd86; '>=</span> <span style='color:#e66170; font-weight:bold; '>this</span><span style='color:#d2cd86; '>.</span>handleEvent<span style='color:#b060b0; '>;</span>
    <span style='color:#9999a9; '>// Change the the handleEvent method without needing to remove </span>
    <span style='color:#9999a9; '>// and re-attach the event(s)</span>
    <span style='color:#e66170; font-weight:bold; '>this</span><span style='color:#d2cd86; '>.</span>handleEvent <span style='color:#d2cd86; '>=</span> <span style='color:#e66170; font-weight:bold; '>function</span><span style='color:#d2cd86; '>(</span>e<span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
        <span style='color:#e66170; font-weight:bold; '>var</span> t <span style='color:#d2cd86; '>=</span> evt<span style='color:#d2cd86; '>.</span>target<span style='color:#b060b0; '>;</span>

        <span style='color:#e66170; font-weight:bold; '>if</span> <span style='color:#d2cd86; '>(</span>t<span style='color:#d2cd86; '>.</span>id <span style='color:#d2cd86; '>===</span> <span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>btn</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
            <span style='color:#9999a9; '>// Check the button being clicked and do new stuff</span>
        <span style='color:#b060b0; '>}</span> <span style='color:#e66170; font-weight:bold; '>else</span> <span style='color:#e66170; font-weight:bold; '>if</span><span style='color:#d2cd86; '>(</span>t<span style='color:#d2cd86; '>.</span>id <span style='color:#d2cd86; '>===</span> <span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>btn3</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
            <span style='color:#e66170; font-weight:bold; '>this</span><span style='color:#d2cd86; '>.</span>revertHandleEvent<span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
        <span style='color:#b060b0; '>}</span>
    <span style='color:#b060b0; '>}</span>
<span style='color:#b060b0; '>}</span>
</pre>
</div>
<p>Makes for some pretty powerful stuff. The third button re-instates the first buttons behaviour back to its original form.</p>
<p>This works in nearly all browsers that support addEventListener, Blackberry 6 browser being one that doesn&#8217;t. Blackberry OS7 has fixed this bug.</p>
<h2 class="subtitle02">Polyfill it</h2>
<p>IE9 was the first to support addEventListener + handleEvent in the IE family, so for the older ones we can polyfill in support for &lt;IE8 and other non-supporting browsers (BBOS6).</p>
<div class="code">
<pre style='color:#d1d1d1;background:#000000;'><span style='color:#9999a9; '>// fn arg can be an object or a function, thanks to handleEvent</span>
<span style='color:#e66170; font-weight:bold; '>function</span> on<span style='color:#d2cd86; '>(</span>el<span style='color:#d2cd86; '>,</span> evt<span style='color:#d2cd86; '>,</span> fn<span style='color:#d2cd86; '>,</span> bubble<span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
    <span style='color:#e66170; font-weight:bold; '>if</span><span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>addEventListener</span><span style='color:#02d045; '>"</span> <span style='color:#e66170; font-weight:bold; '>in</span> el<span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
        <span style='color:#9999a9; '>// BBOS6 doesn't support handleEvent, catch and polyfill</span>
        <span style='color:#e66170; font-weight:bold; '>try</span> <span style='color:#b060b0; '>{</span>
            el<span style='color:#d2cd86; '>.</span>addEventListener<span style='color:#d2cd86; '>(</span>evt<span style='color:#d2cd86; '>,</span> fn<span style='color:#d2cd86; '>,</span> bubble<span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
        <span style='color:#b060b0; '>}</span> <span style='color:#e66170; font-weight:bold; '>catch</span><span style='color:#d2cd86; '>(</span>e<span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
            <span style='color:#e66170; font-weight:bold; '>if</span><span style='color:#d2cd86; '>(</span><span style='color:#e66170; font-weight:bold; '>typeof</span> fn <span style='color:#d2cd86; '>==</span> <span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>object</span><span style='color:#02d045; '>"</span> <span style='color:#d2cd86; '>&amp;&amp;</span> fn<span style='color:#d2cd86; '>.</span>handleEvent<span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
                el<span style='color:#d2cd86; '>.</span>addEventListener<span style='color:#d2cd86; '>(</span>evt<span style='color:#d2cd86; '>,</span> <span style='color:#e66170; font-weight:bold; '>function</span><span style='color:#d2cd86; '>(</span>e<span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>{</span>
                    <span style='color:#9999a9; '>// Bind fn as this and set first arg as event object</span>
                    fn<span style='color:#d2cd86; '>.</span>handleEvent<span style='color:#d2cd86; '>.</span>call<span style='color:#d2cd86; '>(</span>fn<span style='color:#d2cd86; '>,</span>e<span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
                <span style='color:#b060b0; '>}</span><span style='color:#d2cd86; '>,</span> bubble<span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
            <span style='color:#b060b0; '>}</span> <span style='color:#e66170; font-weight:bold; '>else</span> <span style='color:#b060b0; '>{</span>
                <span style='color:#e66170; font-weight:bold; '>throw</span> e<span style='color:#b060b0; '>;</span>
            <span style='color:#b060b0; '>}</span>
        <span style='color:#b060b0; '>}</span>
    <span style='color:#b060b0; '>}</span> <span style='color:#e66170; font-weight:bold; '>else</span> <span style='color:#e66170; font-weight:bold; '>if</span><span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>attachEvent</span><span style='color:#02d045; '>"</span> <span style='color:#e66170; font-weight:bold; '>in</span> el<span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
        <span style='color:#9999a9; '>// check if the callback is an object and contains handleEvent</span>
        <span style='color:#e66170; font-weight:bold; '>if</span><span style='color:#d2cd86; '>(</span><span style='color:#e66170; font-weight:bold; '>typeof</span> fn <span style='color:#d2cd86; '>==</span> <span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>object</span><span style='color:#02d045; '>"</span> <span style='color:#d2cd86; '>&amp;&amp;</span> fn<span style='color:#d2cd86; '>.</span>handleEvent<span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
            el<span style='color:#d2cd86; '>.</span>attachEvent<span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>on</span><span style='color:#02d045; '>"</span> <span style='color:#d2cd86; '>+</span> evt<span style='color:#d2cd86; '>,</span> <span style='color:#e66170; font-weight:bold; '>function</span><span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>{</span>
                <span style='color:#9999a9; '>// Bind fn as this</span>
                fn<span style='color:#d2cd86; '>.</span>handleEvent<span style='color:#d2cd86; '>.</span>call<span style='color:#d2cd86; '>(</span>fn<span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
            <span style='color:#b060b0; '>}</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
        <span style='color:#b060b0; '>}</span> <span style='color:#e66170; font-weight:bold; '>else</span> <span style='color:#b060b0; '>{</span>
            el<span style='color:#d2cd86; '>.</span>attachEvent<span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>on</span><span style='color:#02d045; '>"</span> <span style='color:#d2cd86; '>+</span> evt<span style='color:#d2cd86; '>,</span> fn<span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
        <span style='color:#b060b0; '>}</span>
    <span style='color:#b060b0; '>}</span>
<span style='color:#b060b0; '>}</span>
</pre>
</div>
<p>For oldIE it checks if the callback is an object and if it contains <code>handleEvent</code>. Using call we can change the &#8220;this&#8221; context to the object passed. </p>
<p>For BBOS6 we wrap a try catch around addEventListener and if the attaching throws, check the callback is an object and has the handleEvent method otherwise don&#8217;t swallow the error.</p>
<p>We handle all this by wrapping up the event attaching into a nice method which handles the process for us.</p>
<h2 class="subtitle02">Resources</h2>
<p>I&#8217;m certainly not the first to document this, see <a href="http://ajaxian.com/archives/an-alternative-way-to-addeventlistener">ajaxian article</a> with some great examples.</p>
<p>Even HTML5 boilerplate mobile uses <a href="https://github.com/h5bp/mobile-boilerplate/blob/master/js/mylibs/helper.js#L70">this technique</a> for their fast touch event handling.</p>
<p class="shorty01">Short URL: <a href="http://cssn.in/ja/036">http://cssn.in/ja/036</a></p>
<div class="clear">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/handleevent/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Fullscreen HTML5 video</title>
		<link>http://www.thecssninja.com/javascript/fullscreen</link>
		<comments>http://www.thecssninja.com/javascript/fullscreen#comments</comments>
		<pubDate>Mon, 10 Oct 2011 09:38:10 +0000</pubDate>
		<dc:creator>Ryan Seddon</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=882</guid>
		<description><![CDATA[In preparation for a talk I&#8217;m doing at Web Directions South I needed to be able to put video into fullscreen mode from within my HTML based slides. In order to do this I imagined I would of needed to use flash but thankfully Webkit nightly, Chrome dev and Firefox nightly have added the ability [...]]]></description>
			<content:encoded><![CDATA[<p>In preparation for a talk I&#8217;m doing at <a href="south11.webdirections.org/program/development#remote-debugging-landscape" title="Remote debugging landscape">Web Directions South</a> I needed to be able to put video into fullscreen mode from within my HTML based slides. In order to do this I imagined I would of needed to use flash but thankfully Webkit nightly, Chrome dev and Firefox nightly have added the ability to put HTML5 videos, and other elements, into fullscreen mode using javascript. The <a href="http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html" title="FullScreen Editor Draft API specification">FullScreen API</a> now updated to point to official editor draft, thanks <a href="#comment-2743">Hans</a>!.<br />
<span id="more-882"></span></p>
<h2 class="subtitle02">Fullscreen, finally</h2>
<p>HTML5 video has come a long way but still lacks consistent codec support and the ability to go fullscreen, until now of course.</p>
<div class="resources01"><a target="_blank" class="demo" title="Using the Fullscreen API" href="http://www.thecssninja.com/demo/fullscreen/">View a live demo</a> <a target="_blank" class="demo source" title="Download the source of the fullscreen demo" href="http://www.thecssninja.com/demo/fullscreen/fullscreen.zip">Download the source files</a></div>
<p>As you can see I&#8217;ve created a very simple demo showing HTML5 video in full screen, make sure you&#8217;re using Chrome dev, webkit or firefox nightly. In Firefox you&#8217;ll need to enable it in about:config, search for <strong>&#8220;full-screen-api.enabled&#8221;</strong> and set it to true. Webkit nightly will require the <strong>&#8220;&#8211;enable-fullscreen-api&#8221;</strong> flag when launching. Chrome dev has it enabled by default.</p>
<h2 class="subtitle02">API differences</h2>
<p>If you poked around the source you&#8217;ll notice that Webkit uses <del datetime="2011-10-16T06:15:46+00:00">slightly different method to trigger fullscreen.</del> <ins datetime="2011-10-16T06:15:46+00:00">Turns out webkit only uses a different API for videos but uses the same as firefox for all other elements.</ins> Mozilla initially created a draft spec for <a href="https://wiki.mozilla.org/index.php?title=Gecko:FullScreenAPI" title="Proposed FullScreen API specification">fullscreen elements</a> but Webkit decided to change the name slightly, for the better I think.</p>
<div class="code">
<pre style='color:#d1d1d1;background:#000000;' lang="javascript"><span style='color:#e66170; font-weight:bold; '>var</span> video <span style='color:#d2cd86; '>=</span> document<span style='color:#d2cd86; '>.</span>getElementById<span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>video</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>

<span style='color:#9999a9; '>// Mozilla</span>
video<span style='color:#d2cd86; '>.</span>mozRequestFullScreen<span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>

<span style='color:#9999a9; '>// Webkit for video elements only</span>
video<span style='color:#d2cd86; '>.</span>webkitEnterFullScreen<span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
</pre>
</div>
<p>As with entering fullscreen you can also cancel it. Using the cancelFullScreen method will exit any element currently in fullscreen mode.</p>
<div class="code">
<pre style='color:#d1d1d1;background:#000000;'><span style='color:#9999a9; '>// Mozilla</span>
video<span style='color:#d2cd86; '>.</span>mozCancelFullScreen<span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>

<span style='color:#9999a9; '>// Webkit</span>
video<span style='color:#d2cd86; '>.</span>webkitCancelFullScreen<span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
</pre>
</div>
<h2 class="subtitle02">Fullscreen CSS, DOM properties and events</h2>
<p>Along with the ability to force a video into fullscreen there is also some CSS pseudo-classes and DOM properties. </p>
<div class="code">
<pre style='color:#d1d1d1;background:#000000;'>video<span style='color:#b060b0; '>:</span>-webkit-full-screen     <span style='color:#b060b0; '>{</span> <span style='color:#904050; '>max-height</span><span style='color:#d2cd86; '>:</span> <span style='color:#00a800; '>100</span><span style='color:#006600; '>%</span><span style='color:#b060b0; '>;</span> <span style='color:#b060b0; '>}</span>
video<span style='color:#b060b0; '>:</span>-moz-full-screen        <span style='color:#b060b0; '>{</span> <span style='color:#904050; '>max-height</span><span style='color:#d2cd86; '>:</span> <span style='color:#00a800; '>100</span><span style='color:#006600; '>%</span><span style='color:#b060b0; '>;</span> <span style='color:#b060b0; '>}</span>
</pre>
</div>
<p>The FullScreen API adds one notable pseudo-class that lets you change the element when it&#8217;s in fullscreen mode. A good example is if you had a <code>max-height</code> set on your video element and you triggered fullscreen mode you can then reset the <code>max-height</code> to be 100%.</p>
<p>If you want to do something when the browser is in full screen mode the document object gets the <code>fullScreen</code> property. This is slightly different in webkit compared to mozilla.</p>
<div class="code">
<pre style='color:#d1d1d1;background:#000000;'><span style='color:#9999a9; '>// Mozilla</span>
document<span style='color:#d2cd86; '>.</span>mozFullscreen<span style='color:#b060b0; '>;</span>

<span style='color:#9999a9; '>// Webkit</span>
document<span style='color:#d2cd86; '>.</span>webkitIsFullscreen<span style='color:#b060b0; '>;</span>
</pre>
</div>
<p>As you can see mozilla doesn&#8217;t include the <code>Is</code> in the property like webkit does. So we have this boolean property on the document how do we know when to check it? Well luckily the API also includes an event that triggers called <code>[moz/webkit]fullscreenchange</code>.</p>
<div class="code">
<pre style='color:#d1d1d1;background:#000000;'>video<span style='color:#d2cd86; '>.</span>addEventListener<span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>mozfullscreenchange</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>,</span><span style='color:#e66170; font-weight:bold; '>function</span><span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>{</span>
    console<span style='color:#d2cd86; '>.</span><span style='color:#e66170; font-weight:bold; '>log</span><span style='color:#d2cd86; '>(</span>document<span style='color:#d2cd86; '>.</span>mozFullScreen<span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
<span style='color:#b060b0; '>}</span><span style='color:#d2cd86; '>,</span> <span style='color:#0f4d75; '>false</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>

video<span style='color:#d2cd86; '>.</span>addEventListener<span style='color:#d2cd86; '>(</span><span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>webkitfullscreenchange</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>,</span><span style='color:#e66170; font-weight:bold; '>function</span><span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>{</span>
    console<span style='color:#d2cd86; '>.</span><span style='color:#e66170; font-weight:bold; '>log</span><span style='color:#d2cd86; '>(</span>document<span style='color:#d2cd86; '>.</span>webkitIsFullScreen<span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
<span style='color:#b060b0; '>}</span><span style='color:#d2cd86; '>,</span> <span style='color:#0f4d75; '>false</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
</pre>
</div>
<p>The event will trigger whenever fullscreen mode changes so you can then check the document <code>fullScreen</code> property if it&#8217;s currently in or out of fullscreen mode. The event is currently prefixed in both Webkit and Firefox.</p>
<h2 class="subtitle02">Some quirks</h2>
<p>API differences aside the mozilla spec highly recommends that hitting the Esc key will exit the browser from fullscreen, <del datetime="2011-10-18T21:49:24+00:00">unfortunately Chrome doesn&#8217;t adhere to this (<a href="http://code.google.com/p/chromium/issues/detail?id=99869">see bug</a>)</del> (Bug has been fixed for linux/windows still needs a fix for mac). If you&#8217;re on OSX Lion it will put the browser into full screen mode so to exit you have to hit <code>Cmd+Shift+F</code> on windows <code>F11</code>.</p>
<p>API changes are almost guaranteed. There is already a <a href="https://bugs.webkit.org/show_bug.cgi?id=36081">webkit bug</a> which mentions changing to &#8220;Fullscreen&#8221; rather than &#8220;FullScreen&#8221; but for now both are enabled.</p>
<p><strong>UPDATE:</strong> There is an official editor draft of the spec and looks like Mozilla&#8217;s implementation will be the final one. The API is slighty changing to make FullScreen lowercase in all API calls except where it isn&#8217;t the first word e.g. <code>requestFullscreen</code>.</p>
<h2 class="subtitle02">Much more than just video</h2>
<p>I only wanted to cover video elements in this article but the API allows fullscreen on almost any element, <del datetime="2011-10-16T06:15:46+00:00">this functionality is much more limited in Webkit.</del> <ins datetime="2011-10-16T06:15:46+00:00">Webkit uses <code>webkitRequestFullscreen</code> for all other elements.</ins> Using the <code>allowfullscreen</code> attribute on iframes for example will allow youtube or vimeo to put their iframe embeds into fullscreen mode. Firefox works with more elements in their nightly build e.g. if you add the <code>mozallowfullscreen</code> attribute to the iframe you can put it into fullscreen mode.</p>
<p>There is also some security restrictions around key events and characters allowed.</p>
<h2 class="subtitle02">Further reading</h2>
<ul>
<li>Mozilla has a <a href="http://pearce.org.nz/full-screen/">full on demo</a> showing all the support currently in nightly builds, see <a href="http://blog.pearce.org.nz/2011/09/mozilla-full-screen-api-progress-update.html">blog post</a> too.</li>
<li>Make sure to read over the <a href="http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html">editor draft spec</a>.</li>
<li>Apple developer docs mentions support for some of the <a href="http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/DocumentAdditionsReference/DocumentAdditions/DocumentAdditions.html">events and properties</a>.</li>
<li>Check out <a href="http://mediaelementjs.com/">MEjs</a> which recently added support for the fullscreen APIs</li>
</ul>
<p class="shorty01">Short URL: <a href="http://cssn.in/ja/035">http://cssn.in/ja/035</a></p>
<div class="clear">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/fullscreen/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>I scope, you scope, we all scope for NoScope! JS style element injection quirks in IE</title>
		<link>http://www.thecssninja.com/javascript/noscope</link>
		<comments>http://www.thecssninja.com/javascript/noscope#comments</comments>
		<pubDate>Wed, 13 Apr 2011 12:18:09 +0000</pubDate>
		<dc:creator>Ryan Seddon</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=831</guid>
		<description><![CDATA[The other day I was writing some updates and improvements for Modernizr, one to detect for generated content support and two to improve stylesheet and element injection. Modernizr already in a few places inserts a stylesheet and a corresponding element to do some tests e.g. generatedcontent, touch, css3transforms and a few others. All this happened [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I was writing some updates and improvements for <a href="http://www.modernizr.com/">Modernizr</a>, one to detect for generated content support and two to improve stylesheet and element injection. Modernizr already in a few places inserts a stylesheet and a corresponding element to do some tests e.g. generatedcontent, touch, css3transforms and a few others. All this happened multiple times; each test would inject an element and an inline style element, do its test then remove both elements. All this happens while the page is loading and as you can see the more tests that involve these steps exponentially grow the number of times it needs to touch the DOM.<span id="more-831"></span></p>
<p>Modernizrs&#8217; previous method of injecting the elements revolves around forking for IE, IE<9 uses <code>addRule()</code> rather than <code>insertRule()</code>, this makes it hard to write a simple re-useable method for doing such a test that is cross browser. So I began thinking how this could be re-written to be simplified for re-usability. Rather than inject a style element into the head of a document we could use <code>innerHTML</code> and inject into the element that Modernizr will test against.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">elem.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&lt;style&gt;&quot;</span><span style="color: #339933;">+</span>css<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;&lt;/style&gt;&quot;</span>;
doc.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>elem<span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>Simple, easy and certainly re-usable. But something that stumped me for a while is IE6-9 would not append the style element inside the test element?</p>
<h2 class="subtitle02">IE and the case of the NoScope element</h2>
<p>After searching high and low I found some useful information about scope and <a href="http://msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx">NoScope</a> elements in IE. Basically IE has a few elements that are considered NoScope which when trying to insert with <code>innerHTML</code> will be stripped! On this infamous page however it mentions if you precede a NoScope element with a scoped element they will not be stripped and we can then insert our style element.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">elem.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> scopeElem<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;&lt;style&gt;&quot;</span><span style="color: #339933;">+</span>css<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;&lt;/style&gt;&quot;</span>;
doc.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>elem<span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>Huzzah! It works in IE6-9. We now have a simpler easier way to inject an element with associative styles and we've halved our touching of the DOM by bundling the test element and style element into one <code>appendChild</code> operation.</p>
<h2 class="subtitle02">What's considered a scoped element?</h2>
<p>A scoped element can be anything other than a style, script or comment element. In Modernizrs' case it uses the soft hyphen entity (&amp;shy;) so as not to interfere with measurements done on the injected element. We could very well prepend the <code>innerHTML</code> string with the test element we wish to inject, but for easier referencing I create it in the method and pass it to the callback. This way we can keep the reference to the node and not have to query the DOM again.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">injectElementWithStyles <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>rule<span style="color: #339933;">,</span>callback<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    ...
    <span style="color: #003366; font-weight: bold;">var</span> style<span style="color: #339933;">,</span> div <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div'</span><span style="color: #009900;">&#41;</span>;
&nbsp;
    style <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'&amp;shy;'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'&lt;style&gt;'</span><span style="color: #339933;">,</span>rule<span style="color: #339933;">,</span><span style="color: #3366CC;">'&lt;/style&gt;'</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span>;
    div.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> mod;
    div.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">+=</span> style;
    docElement.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>div<span style="color: #009900;">&#41;</span>;
&nbsp;
    ret <span style="color: #339933;">=</span> callback<span style="color: #009900;">&#40;</span>div<span style="color: #339933;">,</span>rule<span style="color: #009900;">&#41;</span>;
    ...
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>There's also a few other additions that centre around the <code>injectElementWithStyles()</code> method such as the <code>test_bundle()</code> method which does the DOM injection test in one fell swoop. If you want to know more go check out the <a href="https://github.com/Modernizr/Modernizr/blob/master/modernizr.js">source</a> or hit me up on <a href="http://twitter.com/thecssninja">twitter</a>.</p>
<p class="shorty01">Short URL: <a href="http://cssn.in/ja/033">http://cssn.in/ja/033</a></p>
<div class="clear">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/noscope/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Remote debugging with jsconsole, a different take</title>
		<link>http://www.thecssninja.com/javascript/remote-debug</link>
		<comments>http://www.thecssninja.com/javascript/remote-debug#comments</comments>
		<pubDate>Mon, 07 Mar 2011 11:15:05 +0000</pubDate>
		<dc:creator>Ryan Seddon</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=814</guid>
		<description><![CDATA[Ever wanted to remotely access the DOM of a mobile device so you could make changes, test ideas and generally just have a bit of fun. I know I have and I&#8217;ve been hacking to create a proof of concept piggy backed on the development of two great projects. The first is Remy Sharps awesome [...]]]></description>
			<content:encoded><![CDATA[<p>Ever wanted to remotely access the DOM of a mobile device so you could make changes, test ideas and generally just have a bit of fun. I know I have and I&#8217;ve been hacking to create a proof of concept piggy backed on the development of two great projects. The first is Remy Sharps awesome little <a href="http://jsconsole.com/">jsconsole web app</a> that lets you do a bunch of cool stuff using a simple yet elegant interface. The second is a <a href="http://browsersocket.org/">Firefox plugin</a> that allows Firefox to act as a WebSocket server and receive and delegate messages sent from a client.<span id="more-814"></span></p>
<p>Remy recently added <a href="http://www.jsconsole.com/remote-debugging.html">remote debug functionality</a> by the way of an intermediate server to delegate commands, mine works differently and the two solutions could work well together.</p>
<p>In order to use the demo you&#8217;ll need to install the <a href="https://addons.mozilla.org/en-US/firefox/addon/242722">BrowserSocket add-on</a> first.</p>
<div class="resources01"><a href="http://labs.thecssninja.com/jsconsole/" title="remote debugging example for jsconsole" class="demo">View a live demo</a> <a href="https://github.com/ryanseddon/jsconsole/archives/master" title="Download the source of the jsconsole remote debug demo" class="demo source">Download the source files</a></div>
<p>For a quick intro on what you can do, watch the screencast below. I&#8217;ll go into how it works on a technical level in the rest of the article. I&#8217;ve also filmed a super dodgy looking video of the <a href="http://vid.ly/6k1p0i">remote debugging on the iPad</a>.</p>
<p><object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='609' height='375'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=181264' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=181264' allowFullScreen='true' width='609' height='375' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object></p>
<h2 class="subtitle02">Browser to browser connections</h2>
<p>As mentioned in the intro and screencast this requires the very clever, and awesome, <a href="http://browsersocket.org/">BrowserSocket</a> Firefox addon which allows you to let a browser window act as a WebSocket server that can be connected to by a client using the standard WebSocket API. The beauty of this is it requires very little setup and no actual server, browser to browser communication. In order to communicate with external devices they just need to be on the same local network as your current browser, you can even create an adhoc network between your computer and the device and remote debug that way.</p>
<h2 class="subtitle02">Connecting the client to the console</h2>
<p>There a two ways you can connect a client to the jsconsole webapp.</p>
<p>Using the client <a href="javascript:(function(doc) {var script = document.createElement('script');script.src = 'http://labs.thecssninja.com/jsconsole/client.js';doc.body.appendChild(script);})(this.document);" title="Drag me to your bookmarks">bookmarklet</a> you can load it on any website and connect to the generated websocket address, make sure the client and the remote device are on the same network. Once an active connection is obtained any console calls will be sent to both the client and the jsconsole webapp, all JavaScript calls will be executed on the client including loading of js libraries.</p>
<p>The second is including the JavaScript file in your project the advantage of this is you can setup automatic connections so any console calls will be sent to the web app.</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jsconsole&quot;</span> </span>
<span style="color: #009900;">    data-socketaddress<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;ws://127.0.0.1:56187/bs/15917705/&quot;</span> </span>
<span style="color: #009900;">    <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;client.js&quot;</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></pre></div></div>

<h2 class="subtitle02">How it works on a technical level</h2>
<p>Once you have installed the BrowserSocket addon in jsconsole you can call the <code>:createServer</code> command which will generate a WebSocket address that you will connect the client to.</p>
<p><img width="609" height="72" class="article-img main-img" alt="createServer command opens a BrowserSocket instance and gives you a WeSocket address to connect to" src="http://www.thecssninja.com/wp-content/uploads/2011/03/gr_createServer.png"><br />
<small style="margin: -30px 0pt 0pt; display: block;"><code>:createServer</code> command opens a BrowserSocket instance and gives you a WeSocket address to connect to</small></p>
<p>Behind the scenes the BrowserSocket addon exposes the <code>BrowserSocket()</code> constructor which uses the <a href="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIServerSocket">nsIServerSocket interface</a> available to Firefox addons to create a socket server with the ability to accept incoming connections. </p>
<p>Using the constructor we create a new instance and supply a connection handler which will initialise the server instance and allow you to attach functions to the various events i.e. onopen/message/close etc same API as WebSockets.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> bs <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> BrowserSocket<span style="color: #009900;">&#40;</span>bsHandler<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
     bsConnection;
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> bsHandler<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">new</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>
        bsConnection <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>;
        bsConnection.<span style="color: #660066;">onmessage</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>msg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #006600; font-style: italic;">// Handle messages sent to browsersocket</span>
        <span style="color: #009900;">&#125;</span>
        bsConnection.<span style="color: #660066;">onopen</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;">// Run stuff once connection is open</span>
        <span style="color: #009900;">&#125;</span>
        bsConnection.<span style="color: #660066;">onclose</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;">// Revert changes once connection is closed</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>On the client side we simply use the native WebSocket API to connect to our BrowserSocket instance upon successful connection it will log a success message to both client and jsconsole webapp. Very simple and very powerful.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> ws <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> WebSocket<span style="color: #009900;">&#40;</span>url<span style="color: #009900;">&#41;</span>;
&nbsp;
ws.<span style="color: #660066;">onmessage</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>msg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #006600; font-style: italic;">// Eval code sent from jsconsole</span>
<span style="color: #009900;">&#125;</span>
ws.<span style="color: #660066;">onopen</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;">// Run stuff once connection is open</span>
<span style="color: #009900;">&#125;</span>
ws.<span style="color: #660066;">onclose</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;">// Revert changes once connection is closed</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>There is one more command called <code>:killServer</code> which does just that, kills the BrowserSocket instance and disconnects jsconsole from the client.</p>
<p><img width="609" height="72" class="article-img main-img" alt="killServer command kills the BrowserSocket instance and if there is an active connection closes that too" src="http://www.thecssninja.com/wp-content/uploads/2011/03/gr_killServer.png"><br />
<small style="margin: -30px 0pt 0pt; display: block;"><code>:killServer</code> command kills the BrowserSocket instance and if there is an active connection closes that too</small></p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">bsConnection.<span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
bs.<span style="color: #000066;">stop</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<h2 class="subtitle02">It&#8217;s only the beginning</h2>
<p>I have many ideas that I will be implementing such as a <code>:cd</code> command so you can switch between connected device and jsconsole web app. I&#8217;ll add a roadmap/ideas wiki on my <a href="https://github.com/ryanseddon/jsconsole">github fork</a> soon. If you wish to suggest a feature create an issue for now.</p>
<p>I have also created a fork of the <a href="https://github.com/ryanseddon/BrowserSocket">BrowserSocket</a> addon on github that will eventually have some minor updates to help with remote debugging such as returning your local ip to make it easier to connect to remote devices. You can check out the <a href="https://launchpad.net/bs-ff-ext">master repository</a> on launchpad to follow the actual developments of the addon.</p>
<p class="shorty01">Short URL: <a href="http://cssn.in/ja/032">http://cssn.in/ja/032</a></p>
<div class="clear">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/remote-debug/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Getting fancy with the console</title>
		<link>http://www.thecssninja.com/javascript/console</link>
		<comments>http://www.thecssninja.com/javascript/console#comments</comments>
		<pubDate>Wed, 23 Feb 2011 11:36:42 +0000</pubDate>
		<dc:creator>Ryan Seddon</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=778</guid>
		<description><![CDATA[The trusty console.log() method serves a great functional purpose to write messages to the developer console. But did you know the console object has around twenty other methods you can use? I rarely see developers tapping into the extra power the console provides other than using it as a non-blocking alert. Let&#8217;s change that. I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>The trusty <code>console.log()</code> method serves a great functional purpose to write messages to the developer console. But did you know the console object has around twenty other methods you can use? I rarely see developers tapping into the extra power the console provides other than using it as a non-blocking alert. Let&#8217;s change that.<span id="more-778"></span></p>
<p>I&#8217;ve put the following article ideas into real world practice by using <a href="http://www.modernizr.com/">Modernizr</a> as a test subject since it uses a fair amount of the concepts discussed in this article. Make sure your console is open and you&#8217;re using a good browser.</p>
<div class="resources01"><a href="http://www.thecssninja.com/demo/console/output.html" title="Modernizr example using extra console methods" class="demo" target="_blank">Demo of logging and timing</a> <a href="http://www.thecssninja.com/demo/console/test/" title="Modernizr unit tests using console.assert()" class="demo" target="_blank">Unit tests</a> <a href="http://www.thecssninja.com/demo/console/test/fail.html" title="Modernizr unit tests that will fail using console.assert()" class="demo" target="_blank">Failing unit tests</a></div>
<p>Just a side note that since I&#8217;m doing some hefty logging and using ternary statements inside some of the logs, the actual execution speed of Modernizr is affected. Always remove logs from production code.</p>
<h2 class="subtitle02">More than just messages</h2>
<p>Before we dig into the other console methods let&#8217;s show some of the powerful functionality <code>console.log()</code> has, such as the ability to pass as many arguments as you want.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>baz<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;tubular&quot;</span><span style="color: #339933;">,</span> goo<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;rad&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> bar <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;baz&quot;</span>;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;string&quot;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>foo.<span style="color: #660066;">goo</span><span style="color: #339933;">,</span>bar<span style="color: #339933;">,</span>foo.<span style="color: #660066;">baz</span><span style="color: #009900;">&#41;</span>; <span style="color: #006600; font-style: italic;">// string 1 rad baz tubular</span></pre></div></div>

<p>This will print out each argument and display it on the one line. That&#8217;s kinda useful but what would be better is if we could somehow intertwine all those arguments into a nicely formatted message in the console. Wait we can.</p>
<p>If you&#8217;re familiar with <a href="http://en.wikipedia.org/wiki/Printf"><code>printf()</code></a> in other languages <code>console.log()</code> shares some similarities. Taking the last example and passing in all those extra arguments we can reference them and create a nicely formatted string.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>baz<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;tubular&quot;</span><span style="color: #339933;">,</span> goo<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;rad&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> bar <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;baz&quot;</span>;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>
     <span style="color: #3366CC;">&quot;%s theory is %d %s concept. I can only describe it as %s and %s&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;string&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> foo.<span style="color: #660066;">goo</span><span style="color: #339933;">,</span> bar<span style="color: #339933;">,</span> foo.<span style="color: #660066;">baz</span> 
<span style="color: #009900;">&#41;</span>;
<span style="color: #006600; font-style: italic;">// string theory is 1 rad concept. I can only describe it as baz and tubular</span></pre></div></div>

<h2 class="subtitle02">What do those %s and %d do?</h2>
<p>Glad you asked, these are special characters so we can do string formatting within our log message. Basically <code>%s</code> says print the argument as a string, <code>%d</code> says to print the argument as an integer you can also use <code>%i</code> or <code>%f</code>.</p>
<p>Each appearance of the string formatting operator will choose the corresponding argument. First replacement operator will use the first argument and so on so forth. </p>
<p>We can adjust the order in which an argument will appear within the string by using the <code>$</code> parameter preceded by the argument we wish to print.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>baz<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;tubular&quot;</span><span style="color: #339933;">,</span> goo<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;rad&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> bar <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;baz&quot;</span>;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>
     <span style="color: #3366CC;">&quot;%2$d theory is %d %s concept. I can only describe it as %s and %s&quot;</span><span style="color: #339933;">,</span>
     <span style="color: #3366CC;">&quot;string&quot;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>foo.<span style="color: #660066;">goo</span><span style="color: #339933;">,</span>bar<span style="color: #339933;">,</span>foo.<span style="color: #660066;">baz</span>
<span style="color: #009900;">&#41;</span>;
<span style="color: #006600; font-style: italic;">// 1 theory is 0 baz concept. I can only describe it as tubular and %s string</span></pre></div></div>

<p>What this string replacement is saying is I&#8217;ll start at the second argument and progress from there which as you can see causes an issue. </p>
<p>Essentially the first argument gets appended to the end of our arguments giving us six arguments but we only specified five locations for the strings to be replaced in and since we started at argument two it only prints four of them followed by <code>%s</code> and string.</p>
<p>We can fix this by adjusting the above log message and reset the position so everything will be printed as expected.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>baz<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;tubular&quot;</span><span style="color: #339933;">,</span> goo<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;rad&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> bar <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;baz&quot;</span>;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>
     <span style="color: #3366CC;">&quot;%2$d theory is %1$s %3$s concept. I can only describe it as %s and %s&quot;</span><span style="color: #339933;">,</span>
     <span style="color: #3366CC;">&quot;string&quot;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>foo.<span style="color: #660066;">goo</span><span style="color: #339933;">,</span>bar<span style="color: #339933;">,</span>foo.<span style="color: #660066;">baz</span>
<span style="color: #009900;">&#41;</span>;
<span style="color: #006600; font-style: italic;">// 1 theory is string rad concept. I can only describe it as baz and tubular</span></pre></div></div>

<p>In order to get the arguments to print out correctly we need to change the starting order of the second and third replaced items. The others are in the correct order so we don&#8217;t need to adjust where they should start looking. The string will use the arguments in this order 2,1,3,4,5.</p>
<p>String formatting is a powerful tool and I&#8217;ve only scratched the surface. Try experimenting to see what you can get it to do and take a read of some of <a href="http://www.joehewitt.com/software/firebug/docs.php">Joe Hewitts docs</a> on the console.</p>
<h2 class="subtitle02">Different kind of messages</h2>
<p>Like log there a few other methods that will allows us to present a message to the console with different styling. Those are <code>console.info()</code>, <code>console.warn()</code> and <code>console.error()</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">console.<span style="color: #660066;">info</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;%s numbers %d, %d and %d&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;hello&quot;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span>; <span style="color: #006600; font-style: italic;">// hello numbers 1, 2 and 3</span>
console.<span style="color: #660066;">warn</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;%s numbers %d, %d and %d&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;hello&quot;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span>;
console.<span style="color: #660066;">error</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;%s numbers %d, %d and %d&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;hello&quot;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p><img src="http://www.thecssninja.com/wp-content/uploads/2011/02/gr_info-warn-error.png" alt="Firebug example of console.info, console.warn and console.error" width="609" height="72" class="article-img main-img" /><br />
<small style="margin: -30px 0pt 0pt; display: block;">Firebug example of <code>console.info()</code>, <code>console.warn()</code> and <code>console.error()</code></small></p>
<p>All three can also use string formatting and be passed as many arguments as you want. These can obviously give you much clearer visual clues as to what is going on in your code.</p>
<h2 class="subtitle02">Logging the DOM</h2>
<p>When you log a reference to a DOM element the default behaviour is to provide a link to that DOM element with <code>console.dir()</code> and <code>console.dirxml()</code> methods we can inspect the elements properties or create a little subset of the html outline of the element.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">console.<span style="color: #660066;">dir</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">documentElement</span><span style="color: #009900;">&#41;</span>;
console.<span style="color: #660066;">dirxml</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">documentElement</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p><img src="http://www.thecssninja.com/wp-content/uploads/2011/02/gr_dir-dirxml.png" alt="Chrome example of console.dir and console.dirxml" width="609" height="110" class="article-img main-img" /><br />
<small style="margin: -30px 0pt 0pt; display: block;">Chrome example of <code>console.dir()</code> and <code>console.dirxml()</code></small></p>
<h2 class="subtitle02">Grouping</h2>
<p>Sometimes it would be useful to be able to group a bunch console calls for easier referencing we can do that with <code>console.group()</code>, <code>console.groupCollapsed()</code> and <code>console.groupEnd()</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">console.<span style="color: #660066;">group</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Overlord&quot;</span><span style="color: #009900;">&#41;</span>;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Overlord stuff&quot;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
console.<span style="color: #660066;">group</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Lord&quot;</span><span style="color: #009900;">&#41;</span>;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Overlord stuff&quot;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
console.<span style="color: #660066;">group</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Minion&quot;</span><span style="color: #009900;">&#41;</span>;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Minion stuff&quot;</span><span style="color: #009900;">&#41;</span>;
console.<span style="color: #660066;">groupEnd</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
console.<span style="color: #660066;">groupCollapsed</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Servant&quot;</span><span style="color: #009900;">&#41;</span>;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Servant stuff&quot;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p><img src="http://www.thecssninja.com/wp-content/uploads/2011/02/gr_grouping.png" alt="Safari example of console.group and console.groupEnd" width="609" height="110" class="article-img main-img" /><br />
<small style="margin: -30px 0pt 0pt; display: block;">Safari example of <code>console.group()</code> and <code>console.groupEnd()</code></small></p>
<p>As you can see nesting <code>console.group()</code> will further nest the results, in order to end a particular group you use the <code>console.groupEnd()</code>. <code>console.groupCollapsed()</code> is the same as <code>console.group()</code> but the group and its related information will be collapsed.</p>
<h2 class="subtitle02">Code timing and profiling</h2>
<p>The console also allows you get fairly accurate timings useing <code>console.time()</code> and <code>console.timeEnd()</code>. These two methods need to be placed at the start and end of what you want to time in your code.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">console.<span style="color: #660066;">time</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Execution time took&quot;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #006600; font-style: italic;">// Some code to execute</span>
console.<span style="color: #660066;">timeEnd</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Execution time took&quot;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p><img src="http://www.thecssninja.com/wp-content/uploads/2011/02/gr_timing.png" alt="Firefox example of console.time and console.timeEnd" width="609" height="37" class="article-img main-img" /><br />
<small style="margin: -30px 0pt 0pt; display: block;">Firefox example of <code>console.time()</code> and <code>console.timeEnd()</code></small></p>
<p>The timers are associated with each other via their labels, this way you can have multiple timers throughout your code. When a timer hits a <code>console.timeEnd()</code> it will output a message with your label and the time it took in milliseconds to execute.</p>
<p>Along with timings we can also profile a subset of your code and output the profile stack, giving lots of juicy information about how much time the browser spent where.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">console.<span style="color: #660066;">profile</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #006600; font-style: italic;">// Some code to execute</span>
console.<span style="color: #660066;">profileEnd</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<h2 class="subtitle02">Asserting your code</h2>
<p>When you begin working on a complex project it&#8217;s important to start unit testing your code. This allows you to avoid simple mistakes and possible regressions. Luckily the console also includes assertions.</p>
<p>Assertions allow you to enforce rules in your code and to make sure the results it&#8217;s producing are the results you expect. The <code>console.assert()</code> method allows us to do rudimentary unit tests on our code, if something fails the console will throw an exception. The first argument can be anything, function, equality check or checking existence of an object.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> b <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;1&quot;</span>;
console.<span style="color: #660066;">assert</span><span style="color: #009900;">&#40;</span>a <span style="color: #339933;">===</span> b<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;A doesn't equal B&quot;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p><img src="http://www.thecssninja.com/wp-content/uploads/2011/02/gr_assertion.png" alt="Chrome example of console.assert" width="609" height="110" class="article-img main-img" /><br />
<small style="margin: -30px 0pt 0pt; display: block;">Chrome example of <code>console.assert()</code></small></p>
<p>The assert method takes the assertion you want to enforce as the first argument, in this case a simple strict equality check, and the second argument is the message to display if it fails.</p>
<h2 class="subtitle02">Browser support</h2>
<p>Most of the following console methods discussed have quite good browser support. IE8+, Firefox with firebug, Opera or a webkit browser such as Safari or Chrome. There are a few differences between the browsers, Firefox, Safari and Chrome having the widest support. A good way of finding support is to do <code>console.dir(console)</code> which gives you nice look at the console object and it&#8217;s methods.</p>
<p>Opera with Dragonfly does support most of the methods on the console with the exception of string formatting so no fancy logging with argument re-ordering in dragonfly. There is <del datetime="2011-02-23T22:40:24+00:00">no</del> timing <ins datetime="2011-02-23T22:40:24+00:00">but no</ins> profiling (although there is profile and profileEnd available it will log saying this feature is not yet available).</p>
<p>iOS Safari also has pretty rubbish support, no <a href="#comment-2410">string formatting</a>, timing, profiling or grouping but the limited screen real estate could be the reason some of these aren&#8217;t supported. It does however support assertions.</p>
<p>IE8 has support for a pretty wide range too including string formatting and assertions but no timing, profiling, dir or dirxml.</p>
<p>Having said that using <a href="http://getfirebug.com/firebuglite">firebug lite</a> can add some of the console methods to unsupporting browsers.</p>
<p>I haven&#8217;t discussed everything available in the console but what I did cover would be the most useful features available to make debugging and testing a much smoother process. Go forth and enrich you development with more than just string logging.</p>
<p class="shorty01">Short URL: <a href="http://cssn.in/ja/031">http://cssn.in/ja/031</a></p>
<div class="clear">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/console/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>I&#8217;ll have the DOMFileSystem with a side of read/write access please&#8230;</title>
		<link>http://www.thecssninja.com/javascript/filesystem</link>
		<comments>http://www.thecssninja.com/javascript/filesystem#comments</comments>
		<pubDate>Thu, 02 Dec 2010 13:44:42 +0000</pubDate>
		<dc:creator>Ryan Seddon</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=746</guid>
		<description><![CDATA[Filesystem access has been a pipe dream for web developers for many years. With the ever evolving complexity of web apps and their need to potentially process large amounts of data, filesystem access is the next evolutionary step in order to push web apps to the next level. Thankfully, smart people have been thinking about [...]]]></description>
			<content:encoded><![CDATA[<p>Filesystem access has been a pipe dream for web developers for many years. With the ever evolving complexity of web apps and their need to potentially process large amounts of data, filesystem access is the next evolutionary step in order to push web apps to the next level. Thankfully, smart people have been thinking about these issues and defining new and useful specifications that fill those gaps. Eric Uhrhane of Google has been working on the working draft of the <a href="http://dev.w3.org/2009/dap/file-system/file-dir-sys.html">File API: Directories and System</a> specification which defines a set of APIs to create a sandboxed filesystem where a web app can read and write data to.<span id="more-746"></span></p>
<p>A recent release on the Chrome Dev channel shipped early support of this new specification allowing us to play around with the new API.</p>
<p><strong>Update:</strong> The API is now prefixed with webkit for File System Access and the BlobBuilder, <a href="http://groups.google.com/a/chromium.org/group/chromium-html5/browse_thread/thread/2c963f6ecdae0573?hl=en">see announcement</a>.</p>
<p><strong>Update 2:</strong> requesting PERSISTENT storage needs to go through the <a href="http://updates.html5rocks.com/2011/11/Quota-Management-API-Fast-Facts">Quota Management API</a>, I&#8217;ve updated the demo and source files to use TEMPORARY instead, to use <a href="http://www.html5rocks.com/en/tutorials/file/filesystem/#toc-requesting-quota">PERSISTENT see HTML5Rocks article</a>.</p>
<h2 class="subtitle02">Isn&#8217;t this what indexedDB/WebSQL, applicationCache and WebStorage is for?</h2>
<p>What this API offers over <a href="http://www.w3.org/TR/IndexedDB/">indexedDB</a>/<a href="http://dev.w3.org/html5/webdatabase/">WebSQL</a>, <a href="http://www.w3.org/TR/offline-webapps/#offline">applicationCache</a> or <a href="http://dev.w3.org/html5/webstorage/">WebStorage</a> is the ability to process, store and organise very large amounts of data, such as videos. The specification mentions some potentially useful <a href="http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#use-cases">use cases</a> where this API would be advantageous. The developer has the ability to store these large files in a sandboxed environment. If the browser closes or crashes we can access the previously loaded files from our sandboxed filesystem.</p>
<p>However the WebSQL and indexedDB both have the ability to store &#8220;Blob&#8221; objects which could potentially be used to polyfill support for the Filesystem API. Although indexedDB Blob support has only just landed in Firefox 11.</p>
<p><del datetime="2012-01-17T03:32:25+00:00">If you don&#8217;t have Chrome Dev installed you can watch the screencast below showing the demo in action. If you do have Chrome dev installed you need to launch chrome with this flag <strong>&#8211;unlimited-quota-for-files</strong>.</del><ins datetime="2012-01-17T03:32:25+00:00">Chrome no longer needs to be started with this flag for the FileSystem APIs to work!</ins> If you&#8217;re not running the demo in your localhost but from a file:// protocol you&#8217;ll also need to do the additional <strong>&#8211;allow-file-access-from-files</strong> flag for filesystem access to work.</p>
<p><object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='609' height='366'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=138640' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=138640' allowFullScreen='true' width='609' height='366' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object></p>
<div class="resources01"><a href="http://www.thecssninja.com/demo/filesystem_readwrite/" title="How to read and write files and directories to a a sandboxed filesystem" class="demo" target="_blank">View a live demo</a> <a href="http://www.thecssninja.com/demo/filesystem_readwrite/filesystem_readwrite.zip" title="Download the source of the Filesystem demo" class="demo source" target="_blank">Download the source files</a></div>
<p>The above demo has a few buttons which run some code to create files/directories or write text to a file. You can also drag and drop files which will be copied into your new sandboxed filesystem.</p>
<h2 class="subtitle02">Requesting access</h2>
<p>In order to gain access so we can read and write to our filesystem we need to request access which will create our filesystem based on a few parameters we pass to the <code>requestFileSystem()</code> method.</p>
<div class="code syntax">
<pre><span class="nb">window</span><span class="p">.</span><span class="nx">webkitRequestFileSystem</span><span class="p">(</span> <span class="nx">TEMPORARY</span><span class="p">,</span> <span class="mi">5242880</span> <span class="cm">/* ~5MB */</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">fs</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">fsys</span> <span class="o">=</span> <span class="nx">fs</span><span class="p">;</span>
    <span class="nx">root</span> <span class="o">=</span> <span class="nx">fsys</span><span class="p">.</span><span class="nx">root</span><span class="p">;</span>
<span class="p">},</span> <span class="nx">FSA</span><span class="p">.</span><span class="nx">error</span><span class="p">);</span>
</pre>
</div>
<p>On the window object we have the <code>requestFileSystem()</code> method that takes four arguments (type, size, successCallback and errorCallback), the last one being optional.</p>
<ul>
<li><strong>type:</strong> Can either be PERSISTENT or TEMPORARY either it needs to stick around or we only wish to use it for a while and don&#8217;t care if the browser needs to remove it.</li>
<li><strong>size:</strong> How much storage we need, in bytes, for our filesystem. This is ignored at the moment since we&#8217;re setting the <strong>&#8211;unlimited-quota-for-files</strong> when launching Chrome.</li>
<li><strong>successCallback:</strong> Upon successful creation or successfully accessing a previously created file system we can run some code. In the above example I store the DOMFileSystem object so we can access it later.</li>
<li><strong>errorCallback:</strong> If something goes wrong such as requesting too much storage space we can capture the error and display a useful message to the user.</li>
</ul>
<p>In the specification it mentions asking permission from the user to create a filesystem. As of writing it never asks the user for permission but I imagine this will eventually trigger a permission request much like geolocation and web notifications currently do.</p>
<h2 class="subtitle02">Creating files and directories</h2>
<p>We now have access and have created a reference to our DOMFileSystem inside our immediately-invoked function expression, <code>(function(){})()</code>. This way we don&#8217;t pollute the global scope and can have private variables only accessible within the execution context. Let&#8217;s dive into creating files and directories.</p>
<h2 class="subtitle02">Create a file</h2>
<p>In order to create a file inside our DOMFileSystem we have the <code>getFile()</code> method, which is oddly named for creation but it will make sense in a second.</p>
<div class="code syntax">
<pre><span class="nx">FSA</span><span class="p">.</span><span class="nx">createFile</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">path</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">root</span><span class="p">.</span><span class="nx">getFile</span><span class="p">(</span><span class="nx">path</span><span class="p">,</span>
        <span class="p">{</span> <span class="nx">create</span><span class="o">:</span><span class="kc">true</span><span class="p">,</span> <span class="nx">exclusive</span><span class="o">:</span><span class="kc">true</span> <span class="p">},</span>
        <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
            <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">path</span><span class="o">+</span> <span class="s2">" file created"</span><span class="p">);</span>
        <span class="p">},</span>
        <span class="nx">FSA</span><span class="p">.</span><span class="nx">error</span> <span class="p">);</span>
<span class="p">};</span>
</pre>
</div>
<p>Inside the <code>FSA.createFile()</code> method we pass a path argument and access our DOMFileSystem using root variable we created on the inital filesystem request. On root we have the <code>getFile()</code> method which takes four arguments (path, flags, entryCallback, errorCallback) , the first being the only required one.</p>
<p>The flags object has two properties, create and exclusive. In the above code example I specify both create and exclusive to be true which means if the file doesn&#8217;t exist create it and if it already exists throw an error. If we don&#8217;t specify create and the file doesn&#8217;t exist it will trigger the errorCallback if specified. The entryCallback will let you add data to the current file, which I&#8217;ll go into later in article. </p>
<h2 class="subtitle02">Create a directory</h2>
<p>Creating a directory works exactly the same as creating a file except we have the <code>getDirectory()</code> method which takes the same arguments as <code>getFile()</code>.</p>
<div class="code syntax">
<pre><span class="nx">FSA</span><span class="p">.</span><span class="nx">createDirectory</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">path</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">root</span><span class="p">.</span><span class="nx">getDirectory</span><span class="p">(</span><span class="nx">path</span><span class="p">,</span>
        <span class="p">{</span> <span class="nx">create</span><span class="o">:</span><span class="kc">true</span><span class="p">,</span> <span class="nx">exclusive</span><span class="o">:</span><span class="kc">true</span> <span class="p">},</span>
        <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
            <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">path</span><span class="o">+</span> <span class="s2">" directory created"</span><span class="p">);</span>
        <span class="p">},</span>
        <span class="nx">FSA</span><span class="p">.</span><span class="nx">error</span> <span class="p">);</span>
<span class="p">};</span>
</pre>
</div>
<p>Within the path argument we can specify a relative path but we can&#8217;t create a folder more than one folder deep if none of its parents exist e.g. setting path to &#8220;multiple/levels/deep&#8221; will fail if &#8220;multiple&#8221; and &#8220;levels&#8221; folders don&#8217;t exist.</p>
<p>If the folder structure root > multiple > levels exists we can then create nested folders easily by passing our path argument as &#8220;multiple/levels/deep&#8221;. We can also get fancy using &#8220;..&#8221; in our path argument e.g. If I want to create a folder at the same level at &#8220;levels&#8221; I can pass &#8220;multiple/levels/../samelevel&#8221; to the path argument and get &#8220;levels&#8221; and &#8220;samelevel&#8221; inside &#8220;multiple&#8221;. This concept also applies to <code>getFiles()</code>.</p>
<h2 class="subtitle02">Writing to files</h2>
<p><code>getFile()</code> and <code>getDirectory()</code> also have the ability to write content to a file or create a file within a directory. This is done through the successCallback which passes in either the fileEntry or directoryEntry reference so we can further manipulate it.</p>
<h2 class="subtitle02">Write content to a text file</h2>
<p>In the callback when we have access to the fileEntry which has two methods we can use, <code>createWriter()</code> and file(). To write to a file we utilise the <code>createWriter()</code> method.</p>
<div class="code syntax">
<pre><span class="kd">function</span><span class="p">(</span><span class="nx">fileEntry</span><span class="p">)</span> <span class="p">{</span>
   <span class="nx">fileEntry</span><span class="p">.</span><span class="nx">createWriter</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">writer</span><span class="p">)</span> <span class="p">{</span>  <span class="c1">// FileWriter </span>

       <span class="nx">writer</span><span class="p">.</span><span class="nx">onwrite</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
           <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Write completed.'</span><span class="p">);</span>
           <span class="nx">dir</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
       <span class="p">};</span> 

       <span class="nx">writer</span><span class="p">.</span><span class="nx">onerror</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
           <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Write failed: '</span> <span class="o">+</span> <span class="nx">e</span><span class="p">);</span>
       <span class="p">};</span> 

       <span class="kd">var</span> <span class="nx">bb</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebKitBlobBuilder</span><span class="p">();</span>
       <span class="nx">bb</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>
       <span class="nx">writer</span><span class="p">.</span><span class="nx">seek</span><span class="p">(</span><span class="nx">writer</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span> <span class="c1">// Always append text to end of file. </span>
       <span class="nx">writer</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">bb</span><span class="p">.</span><span class="nx">getBlob</span><span class="p">(</span><span class="nx">mimetype</span><span class="p">));</span> 

   <span class="p">});</span>
<span class="p">}</span>
</pre>
</div>
<p>In the <code>getFile()</code> successCallback we initialise the <code>createWriter()</code> method on the current fileEntry, attach a few listeners to the writer, onwrite and onerror so we can trigger some code when it&#8217;s done or if something goes wrong. There are several other events that are currently not listed in the spec:</p>
<ul>
<li>onabort</li>
<li>onprogress</li>
<li>onwriteend</li>
<li>onwritestart</li>
</ul>
<p>To append the data to the file we create a new <code>BlobBuilder</code>, this is part of another File API extension specification called <a href="http://dev.w3.org/2009/dap/file-system/file-writer.html">File API: Writer</a>. We append our passed in data to the blob, we then set the <code>seek()</code> method to the writer length so we append our text to the file rather than insert it over the top of existing data. Using the <code>write()</code> method we then get the blob data to write to the file.</p>
<h2 class="subtitle02">Getting fancy, drag and drop to your filesystem</h2>
<p>The above example may have looked over complicated for just adding some text to a file but it becomes much more powerful when playing with advanced file creation. If you watched the demo screencast or played around with the actual demo you would have noticed that you can drag and drop files to the drop area and it will add those files to your sandboxed filesystem.</p>
<div class="code syntax">
<pre><span class="nx">FSA</span><span class="p">.</span><span class="nx">handleDrop</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
   <span class="kd">var</span> <span class="nx">dt</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">dataTransfer</span><span class="p">,</span>
       <span class="nx">files</span> <span class="o">=</span> <span class="nx">dt</span><span class="p">.</span><span class="nx">files</span><span class="p">,</span>
       <span class="nx">count</span> <span class="o">=</span> <span class="nx">files</span><span class="p">.</span><span class="nx">length</span><span class="p">,</span>
       <span class="nx">file</span><span class="p">,</span> <span class="nx">fileType</span><span class="p">,</span>
       <span class="nx">droppedFileName</span><span class="p">;</span> 

   <span class="nx">e</span><span class="p">.</span><span class="nx">stopPropagation</span><span class="p">();</span>
   <span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span> 

   <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">count</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
       <span class="nx">file</span> <span class="o">=</span> <span class="nx">files</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
       <span class="nx">fileType</span> <span class="o">=</span> <span class="nx">file</span><span class="p">.</span><span class="nx">type</span><span class="p">;</span>
       <span class="nx">droppedFileName</span> <span class="o">=</span> <span class="nx">file</span><span class="p">.</span><span class="nx">name</span><span class="p">;</span> 

       <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"File type: "</span> <span class="o">+</span> <span class="nx">fileType</span> <span class="o">+</span> <span class="s2">"\n"</span> <span class="o">+</span> <span class="s2">"File name: "</span> <span class="o">+</span> <span class="nx">droppedFileName</span><span class="p">);</span> 

       <span class="nx">dropReader</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">FileReader</span><span class="p">();</span>
       <span class="nx">dropReader</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">droppedFileName</span><span class="p">;</span>
       <span class="nx">dropReader</span><span class="p">.</span><span class="nx">type</span> <span class="o">=</span> <span class="nx">fileType</span><span class="p">;</span> 

       <span class="nx">dropReader</span><span class="p">.</span><span class="nx">onloadend</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="nx">FSA</span><span class="p">.</span><span class="nx">write2File</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span> <span class="p">};</span>
       <span class="nx">dropReader</span><span class="p">.</span><span class="nx">readAsArrayBuffer</span><span class="p">(</span><span class="nx">file</span><span class="p">);</span>
   <span class="p">}</span>
<span class="p">};</span>
</pre>
</div>
<p>In order to create copies of your dropped files we read in each file, using the File API, as an ArrayBuffer. ArrayBuffer support is recent addition to the File API spec. That way we can pass in the ArrayBuffer to the <code>BlobBuilder</code>, which also had the recent addition of accepting ArrayBuffers, and write it to the file using the Blob data. This allows us to handle just about any file.</p>
<h2 class="subtitle02">That was fancy, but let&#8217;s get really fancy</h2>
<p>All the interaction in the demo has been creating files from either in the demo or adding locally available files through drag and drop. How about adding files pulled down from a web server. Better yet how about pulling down a tarball file through an XHR request, parsing and extracting its contents and adding all the files to your sandboxed filesystem? Sounds crazy but we can do that.</p>
<p>Using the very clever <a href="http://fhtr.blogspot.com/2010/05/parsing-tarballs-with-javascript.html ">MultiFile tarball parser</a> by <a href="http://fhtr.blogspot.com/ ">Ilmari Heikkinen</a> and the new <a href="https://developer.mozilla.org/en/JavaScript_typed_arrays/Uint8Array ">Uint8Array</a> type to convert the returned binary data to a <a href="https://developer.mozilla.org/en/JavaScript_typed_arrays">typed array</a>. We can accomplish just that.</p>
<div class="code syntax">
<pre><span class="nx">MultiFile</span><span class="p">.</span><span class="nx">stream</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">f</span><span class="p">)</span> <span class="p">{</span>
   <span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">f</span><span class="p">.</span><span class="nx">filename</span><span class="p">,</span>
       <span class="nx">data</span> <span class="o">=</span> <span class="nx">f</span><span class="p">.</span><span class="nx">data</span><span class="p">,</span>
       <span class="nx">mime</span> <span class="o">=</span> <span class="s2">"application/octet-stream"</span><span class="p">,</span>
       <span class="nx">ui8a</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Uint8Array</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">length</span><span class="p">),</span>
       <span class="nx">bb</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebKitBlobBuilder</span><span class="p">();</span> 

   <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">ui8a</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
       <span class="nx">ui8a</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
   <span class="p">}</span> 

   <span class="nx">bb</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="nx">ui8a</span><span class="p">.</span><span class="nx">buffer</span><span class="p">);</span> 

   <span class="nx">FSA</span><span class="p">.</span><span class="nx">write2File</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span><span class="nx">bb</span><span class="p">.</span><span class="nx">getBlob</span><span class="p">(</span><span class="nx">mime</span><span class="p">),</span><span class="nx">mime</span><span class="p">);</span>
<span class="p">});</span>
</pre>
</div>
<p>Using the <code>MultiFile.stream()</code> method we can stream each file extracted from the tarball and run a callback function. We then convert the raw binary to a typed array, append it to a blob as an ArrayBuffer using the buffer attribute (thanks Eric Bidelman for <a href="http://api.twitter.com/ebidel/status/9694498074394624 ">the tip</a>) and pass of the information to the <code>FSA.write2File()</code> method. This takes the blob and writes it to our sandboxed filesystem.</p>
<p>XMLHttpRequest Level 2 specification does have the <a href="http://www.w3.org/TR/XMLHttpRequest2/#the-responseblob-attribute">responseBlob attribute</a> defined which would allow us to avoid the memory intensive operation of looping over the binary bits to convert it to an ArrayBuffer. Instead we could append the response straight into the BlobBuilder. Unfortunately Chrome doesn&#8217;t yet have this response type so we have to resort to the above method</p>
<p>This opens up some really great possibilities for some really powerful web apps of the future. Ilmari even has a <a href="http://fhtr.blogspot.com/2010/05/loading-targz-with-javascript.html">gzip parser</a> so we could also stream a compressed tarball.</p>
<h2 class="subtitle02">Iterating over directory contents</h2>
<p>In the demo if you&#8217;ve added any images by dragging and dropping them. You can click the &#8220;get images&#8221; button which will iterate over the root directory and find any images and append them to the inside the drop area. This is also executed on window load so any previously added images will be displayed onload.</p>
<div class="code syntax">
<pre><span class="nx">FSA</span><span class="p">.</span><span class="nx">getFiles</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
   <span class="kd">var</span> <span class="nx">dirReader</span> <span class="o">=</span> <span class="nx">root</span><span class="p">.</span><span class="nx">createReader</span><span class="p">();</span> 

   <span class="nx">dropContainer</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="s2">""</span><span class="p">;</span> 

   <span class="nx">dirReader</span><span class="p">.</span><span class="nx">readEntries</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">files</span><span class="p">)</span> <span class="p">{</span>
       <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">len</span> <span class="o">=</span> <span class="nx">files</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">len</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
           <span class="k">if</span><span class="p">(</span><span class="nx">files</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">isFile</span><span class="p">)</span> <span class="p">{</span>
               <span class="nx">FSA</span><span class="p">.</span><span class="nx">getFile</span><span class="p">(</span><span class="nx">files</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">name</span><span class="p">);</span>
           <span class="p">}</span>
       <span class="p">}</span>
   <span class="p">},</span> <span class="nx">FSA</span><span class="p">.</span><span class="nx">error</span><span class="p">);</span>
<span class="p">};</span>
</pre>
</div>
<p>In order to iterate over the root directory we use the <code>createReader()</code> method which creates a new DirectoryReader. Then we use the <code>readEntries()</code> method to read each entry. Using a for loop we go over every file check the <code>isFile</code> flag to make sure we&#8217;re dealing with a file, directories have <code>isDirectory</code>, and then pass of the file name to the <code>FSA.getFile()</code> method.</p>
<div class="code syntax">
<pre><span class="nx">FSA</span><span class="p">.</span><span class="nx">getFile</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
   <span class="nx">root</span><span class="p">.</span><span class="nx">getFile</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">fileEntry</span><span class="p">)</span> <span class="p">{</span>
       <span class="nx">fileEntry</span><span class="p">.</span><span class="nx">file</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">file</span><span class="p">)</span> <span class="p">{</span> 

           <span class="k">if</span><span class="p">(</span><span class="s2">"createObjectURL"</span> <span class="k">in</span> <span class="nx">w</span> <span class="o">&amp;&amp;</span> <span class="nx">img</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">file</span><span class="p">.</span><span class="nx">type</span><span class="p">))</span> <span class="p">{</span>
               <span class="kd">var</span> <span class="nx">url</span> <span class="o">=</span> <span class="nx">w</span><span class="p">.</span><span class="nx">createObjectURL</span><span class="p">(</span><span class="nx">file</span><span class="p">),</span>
                   <span class="nx">image</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s2">"img"</span><span class="p">);</span> 

               <span class="nx">image</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="nx">url</span><span class="p">;</span>
               <span class="nx">image</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="mi">300</span><span class="p">;</span>
               <span class="nx">image</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="mi">200</span><span class="p">;</span> 

               <span class="nx">dropContainer</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">image</span><span class="p">);</span>
           <span class="p">}</span> 

       <span class="p">},</span> <span class="nx">FSA</span><span class="p">.</span><span class="nx">error</span><span class="p">);</span>
   <span class="p">},</span> <span class="nx">FSA</span><span class="p">.</span><span class="nx">error</span> <span class="p">);</span>
<span class="p">};</span>
</pre>
</div>
<p>In the above code we pass the name to the DOMFileSystem <code>getFile()</code> method, inside the success callback we access the file in question, test to make sure <code>createObjectURL</code> is supported and that the file is of an image type.</p>
<p><code>createObjectURL()</code> allows us to avoid loading each file into memory and rather generate a blob URL that points to the file. So rather than setting the source of an image as a base64 string we set it as the blob URL and it works like referencing a normal image url.</p>
<h2 class="subtitle02">Removing directories and its contents</h2>
<p>If you need to remove any directories and all its containing files you can use the <code>removeRecursively()</code> method on a directory entry.</p>
<div class="code syntax">
<pre><span class="nx">FSA</span><span class="p">.</span><span class="nx">removeDirectory</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">path</span><span class="p">)</span> <span class="p">{</span>
   <span class="nx">root</span><span class="p">.</span><span class="nx">getDirectory</span><span class="p">(</span><span class="nx">path</span><span class="p">,</span><span class="kc">null</span><span class="p">,</span><span class="kd">function</span><span class="p">(</span><span class="nx">dir</span><span class="p">)</span> <span class="p">{</span>
       <span class="nx">dir</span><span class="p">.</span><span class="nx">removeRecursively</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
           <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"'"</span> <span class="o">+</span> <span class="nx">path</span> <span class="o">+</span> <span class="s2">"' and all its contents was succesfully removed"</span><span class="p">);</span>
       <span class="p">},</span> <span class="nx">FSA</span><span class="p">.</span><span class="nx">error</span><span class="p">);</span>
   <span class="p">},</span> <span class="nx">FSA</span><span class="p">.</span><span class="nx">error</span><span class="p">);</span>
<span class="p">};</span>
</pre>
</div>
<p>Basically you call the <code>getDirectory()</code> method and in its successCallback use the <code>removeRecursively()</code> method which takes two arguments; successCallback and errorCallback. Trying to delete the root directory will throw an error as you cannot do that.</p>
<h2 class="subtitle02">Removing individual files</h2>
<p>In the spec on a fileEntry there is a <code>remove()</code> method, as well as several other methods like <code>copyTo()</code>, unfortunately these aren&#8217;t available in the current dev build of Chrome. You cannot delete individual files at the time of writing.</p>
<h2 class="subtitle02">Handling Errors</h2>
<p>In my demo I set all the error callback arguments to my <code>FSA.error()</code> method this allows for easy logging of errors in a central place.</p>
<div class="code syntax">
<pre><span class="nx">FSA</span><span class="p">.</span><span class="nx">error</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
   <span class="k">switch</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span>
       <span class="k">case</span> <span class="mi">1</span><span class="o">:</span>
           <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"File doesn't exist"</span><span class="p">);</span>
           <span class="k">break</span><span class="p">;</span>
       <span class="k">case</span> <span class="mi">2</span><span class="o">:</span>
           <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"Stop being silly"</span><span class="p">);</span>
           <span class="k">break</span><span class="p">;</span>
       <span class="k">case</span> <span class="mi">9</span><span class="o">:</span>
           <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"You've already created it"</span><span class="p">);</span>
           <span class="k">break</span><span class="p">;</span>
       <span class="k">case</span> <span class="mi">10</span><span class="o">:</span>
           <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"You've either exceeded your storage quota..."</span><span class="p">);</span>
           <span class="k">break</span><span class="p">;</span>
       <span class="k">default</span><span class="o">:</span>
           <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span>
   <span class="p">}</span>
<span class="p">};</span>
</pre>
</div>
<p>Inside this function I have a switch statement that lets me fork for certain errors. You can then either do what I&#8217;m doing and log a message to the console or run another function. You see a full list of <a href="http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#dealing-with-errors-and-exceptions">FileErrors</a> and what number means what.</p>
<p>Also check out the <a href="https://chrome.google.com/webstore/detail/nhnjmpbdkieehidddbaeajffijockaea">Peephole Chrome extension</a> which makes it very easy to debug the FileSystem API.</p>
<h2 class="subtitle02">Can I use it?</h2>
<p><del datetime="2012-01-21T01:56:12+00:00">Not really, browser support is Chrome Dev and you need to launch it with a flag in order to use it. This is very early days but it&#8217;s exciting to be able to play with the future APIs in the browser and get a real feel for them.</del></p>
<p>If it&#8217;s Chrome only, sure, it&#8217;ll be fine to use to add some extra functionality to your web app. You could fallback to WebSQL/indexedDB Blobs for other browsers.</p>
<p>I&#8217;ve only scratched the surface of what is coming. I&#8217;m sure this article will become out of date as the discussion progresses for the API. I&#8217;ll try to keep pace with it. You should always refer to the specifications for the latest information.</p>
<p class="shorty01">Short URL: <a href="http://cssn.in/ja/030">http://cssn.in/ja/030</a></p>
<div class="clear">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/filesystem/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>The H5F library, emulate the HTML5 forms chapter</title>
		<link>http://www.thecssninja.com/javascript/h5f</link>
		<comments>http://www.thecssninja.com/javascript/h5f#comments</comments>
		<pubDate>Wed, 29 Sep 2010 11:33:17 +0000</pubDate>
		<dc:creator>Ryan Seddon</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[constraint validation api]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.thecssninja.com/?p=723</guid>
		<description><![CDATA[Recently I wrote an article for A List Apart about Forward thinking form validation and I introduced a script I wrote that emulates some of the new HTML Forms chapter functionality in older browsers, allowing a developer to use all these new features and have it work the same across the board. In the spirit [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I wrote an article for A List Apart about <a href="http://www.alistapart.com/articles/forward-thinking-form-validation">Forward thinking form validation</a> and I introduced a script I wrote that emulates some of the new HTML Forms chapter functionality in older browsers, allowing a developer to use all these new features and have it work the same across the board.<span id="more-723"></span></p>
<p>In the spirit of giving back to the community I have released it under a dual BSD and MIT license so you can do as you please with it. I&#8217;ve setup a <a href="http://github.com/ryanseddon/H5F">github repository</a> so you can fork it, watch it suggest ways to improve it and submit any issues.</p>
<p>This script doesn&#8217;t rely on any libraries. It uses feature detection to find out if the browser already supports the constraint validation API and either hooks into the native support or creates methods to emulate it.</p>
<div class="resources01"><a href="http://www.alistapart.com/d/forward-thinking-form-validation/enhanced_2.html" title="Example HTML5 form using the H5F library" class="demo" target="_blank">View a live demo</a> <a href="http://github.com/ryanseddon/H5F/archives/master" title="Download the H5F library" class="demo source" target="_blank">Download the source files</a></div>
<h2 class="subtitle02">How does it work?</h2>
<p>Let&#8217;s dive into the inner workings of the script and see how some of it works. As discussed in the <a href="http://www.alistapart.com/articles/forward-thinking-form-validation">Forward thinking form validation</a> article the script adds the support for some of the HTML5 forms chapter input types and attributes as well as the constraint validation API.</p>
<p>On page load you run the <code>H5F.setup()</code> method which accepts two arguments, the second being optional. The first argument can be a <code>HTMLFormElement</code>, <code>HTMLCollection </code>of form elements or an array of <code>HTMLFormElements</code>. The second optional argument is an object to setup the class names to be applied to the fields in their different validity states.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">H5F.<span style="color: #660066;">setup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>d.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;signup&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>d.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;anotherform&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
    validClass<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;valid&quot;</span><span style="color: #339933;">,</span>
    invalidClass<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;invalid&quot;</span><span style="color: #339933;">,</span>
    requiredClass<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;required&quot;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>The above example passes an array of two <code>HTMLFormElements</code>. The script will then detect that more than one form is being passed and loop through the array and attach the functionality. The second argument specifies the class names to be applied when a field is valid, invalid or required.</p>
<h2 class="subtitle02">Event capturing</h2>
<p>In order to avoid potentially adding hundreds of event listeners we use the event models capturing behaviour and attach it to the parent form. This way when a field triggers an event we want to use, it will start at the window object work its way down the DOM tree and the form will capture it. To work around IE not bubbling blur and focus events we use the focusout and focusin events which do bubble.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>type <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;blur&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    type <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;focusout&quot;</span>;
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>type <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;focus&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    type <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;focusin&quot;</span>;
<span style="color: #009900;">&#125;</span>
node.<span style="color: #660066;">attachEvent</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;on&quot;</span> <span style="color: #339933;">+</span> type<span style="color: #339933;">,</span> fn <span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>The above code is taken from the <code>H5F.listen()</code> method which inside the IE fork will check if we are using blur or focus and change them to focusout and focusin respectively.</p>
<h2 class="subtitle02">Detecting native support</h2>
<p>Opera 9.6, Chrome 4, Firefox 4 and Safari 5 all support the constraints validation API natively so in order to not overwrite any built in functionality we use feature detection.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">H5F.<span style="color: #660066;">support</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>H5F.<span style="color: #660066;">isHostMethod</span><span style="color: #009900;">&#40;</span>field<span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;validity&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> H5F.<span style="color: #660066;">isHostMethod</span><span style="color: #009900;">&#40;</span>field<span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;checkValidity&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span>;</pre></div></div>

<p>The <code>H5F.support()</code> method will return a boolean value depending on the browsers support level. We check for native support of the <code>checkValidity()</code> method and the <code>validity</code> attribute.</p>
<h2 class="subtitle02">Adding support</h2>
<p>If the browser doesn&#8217;t support the necessary features we add them. Each form will have the <code>checkValidity()</code> method and we loop through each form control and also add <code>checkValidity</code> and the form controls <code>validity</code> attribute.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>H5F.<span style="color: #660066;">support</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    form.<span style="color: #660066;">checkValidity</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> H5F.<span style="color: #660066;">checkValidity</span><span style="color: #009900;">&#40;</span>form<span style="color: #009900;">&#41;</span>; <span style="color: #009900;">&#125;</span>;
&nbsp;
    <span style="color: #000066; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>flen<span style="color: #339933;">--</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        isRequired <span style="color: #339933;">=</span> <span style="color: #339933;">!!</span><span style="color: #009900;">&#40;</span>f<span style="color: #009900;">&#91;</span>flen<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">attributes</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;required&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>f<span style="color: #009900;">&#91;</span>flen<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">nodeName</span> <span style="color: #339933;">!==</span> <span style="color: #3366CC;">&quot;FIELDSET&quot;</span> <span style="color: #339933;">&amp;&amp;</span> isRequired<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            H5F.<span style="color: #660066;">validity</span><span style="color: #009900;">&#40;</span>f<span style="color: #009900;">&#91;</span>flen<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>; <span style="color: #006600; font-style: italic;">// Add validity object to field</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Looping over each form control we check that it isn&#8217;t a fieldset (Firefox includes fieldsets in the elements array whereas webkit doesn&#8217;t) and that it is required. We only check the existence of the required attribute and not its value since it is a <a href="http://www.whatwg.org/specs/web-apps/current-work/#boolean-attributes">boolean attribute</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">H5F.<span style="color: #660066;">validity</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #003366; font-weight: bold;">var</span> elem <span style="color: #339933;">=</span> el<span style="color: #339933;">,</span>
       missing <span style="color: #339933;">=</span> H5F.<span style="color: #660066;">valueMissing</span><span style="color: #009900;">&#40;</span>elem<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
       type <span style="color: #339933;">=</span> elem.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
       pattern <span style="color: #339933;">=</span> elem.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;pattern&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
       placeholder <span style="color: #339933;">=</span> elem.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;placeholder&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
       isType <span style="color: #339933;">=</span> <span style="color: #009966; font-style: italic;">/^(email|url)$/i</span><span style="color: #339933;">,</span>
       evt <span style="color: #339933;">=</span> <span style="color: #009966; font-style: italic;">/^(input|keyup)$/i</span><span style="color: #339933;">,</span>
       fType <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>isType.<span style="color: #660066;">test</span><span style="color: #009900;">&#40;</span>type<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> type <span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>pattern<span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> pattern <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
       patt <span style="color: #339933;">=</span> H5F.<span style="color: #660066;">pattern</span><span style="color: #009900;">&#40;</span>elem<span style="color: #339933;">,</span>fType<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
       step <span style="color: #339933;">=</span> H5F.<span style="color: #660066;">range</span><span style="color: #009900;">&#40;</span>elem<span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;step&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
       min <span style="color: #339933;">=</span> H5F.<span style="color: #660066;">range</span><span style="color: #009900;">&#40;</span>elem<span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;min&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
       max <span style="color: #339933;">=</span> H5F.<span style="color: #660066;">range</span><span style="color: #009900;">&#40;</span>elem<span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;max&quot;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
   elem.<span style="color: #660066;">validity</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
       patternMismatch<span style="color: #339933;">:</span> patt<span style="color: #339933;">,</span>
       rangeOverflow<span style="color: #339933;">:</span> max<span style="color: #339933;">,</span>
       rangeUnderflow<span style="color: #339933;">:</span> min<span style="color: #339933;">,</span>
       stepMismatch<span style="color: #339933;">:</span> step<span style="color: #339933;">,</span>
       valid<span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>missing <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>patt <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>step <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>min <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>max<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
       valueMissing<span style="color: #339933;">:</span> missing
   <span style="color: #009900;">&#125;</span>;
&nbsp;
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>placeholder <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>evt.<span style="color: #660066;">test</span><span style="color: #009900;">&#40;</span>curEvt<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> H5F.<span style="color: #660066;">placeholder</span><span style="color: #009900;">&#40;</span>elem<span style="color: #009900;">&#41;</span>; <span style="color: #009900;">&#125;</span>
   elem.<span style="color: #660066;">checkValidity</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> H5F.<span style="color: #660066;">checkValidity</span><span style="color: #009900;">&#40;</span>elem<span style="color: #009900;">&#41;</span>; <span style="color: #009900;">&#125;</span>;
<span style="color: #009900;">&#125;</span>;</pre></div></div>

<p>In native supporting browsers each form control has the <a href="http://www.whatwg.org/specs/web-apps/current-work/#dom-cva-validity">validity attribute</a> that has boolean values to know what state the control is in.</p>
<h2 class="subtitle02">Compare with regular expressions</h2>
<p>When a pattern attribute is used we first check the field&#8217;s type against a regular expression.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> isType <span style="color: #339933;">=</span> <span style="color: #009966; font-style: italic;">/^(email|url)$/i</span><span style="color: #339933;">,</span>
   fType <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>isType.<span style="color: #660066;">test</span><span style="color: #009900;">&#40;</span>type<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> type <span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>pattern<span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> pattern <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>If a fields type is either email or url we want to handle that differently compared to just a normal text input with the pattern attribute.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">H5F.<span style="color: #660066;">pattern</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #339933;">,</span> type<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>type <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;email&quot;</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: #339933;">!</span>emailPatt.<span style="color: #660066;">test</span><span style="color: #009900;">&#40;</span>el.<span style="color: #660066;">value</span><span style="color: #009900;">&#41;</span>;
   <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>type <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;url&quot;</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: #339933;">!</span>urlPatt.<span style="color: #660066;">test</span><span style="color: #009900;">&#40;</span>el.<span style="color: #660066;">value</span><span style="color: #009900;">&#41;</span>;
   <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
       usrPatt <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> RegExp<span style="color: #009900;">&#40;</span>type<span style="color: #009900;">&#41;</span>;
       <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #339933;">!</span>usrPatt.<span style="color: #660066;">test</span><span style="color: #009900;">&#40;</span>el.<span style="color: #660066;">value</span><span style="color: #009900;">&#41;</span>;
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>;</pre></div></div>

<p>Knowing what type the form control is we can than fork it to handle emails and url&#8217;s by using our predefined regular expressions.</p>
<p>For all other form controls which don&#8217;t match any of our predefined types we pass in the pattern attribute value to a regular expression and test the field&#8217;s value against that.</p>
<h2 class="subtitle02">Keep a form control within range</h2>
<p>H5F also supports a simplified version of min, max and step attributes. It will only support whole numbers and in the demo we use it for a postcode example, although most international postcodes aren&#8217;t all numbers like Australia but we&#8217;ll use this example just to demonstrate the feature.</p>
<p>The postcode form control has both the min and max attributes set to keep it within two values, 1001 &#8211; 8000 in our case. Since min, max and step are all related I created a single method called <code>H5F.range()</code> to handle it all.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">H5F.<span style="color: #660066;">range</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #339933;">,</span>type<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
    <span style="color: #003366; font-weight: bold;">var</span> min <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>el.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;min&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> || 0<span style="color: #339933;">,</span> 
        max <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>el.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;max&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> || <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> 
        step <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>el.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;step&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> || <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> 
        val <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>el.<span style="color: #660066;">value</span><span style="color: #339933;">,</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> 
        mismatch <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>val<span style="color: #339933;">-</span>min<span style="color: #009900;">&#41;</span><span style="color: #339933;">%</span>step; 
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>H5F.<span style="color: #660066;">valueMissing</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>isNaN<span style="color: #009900;">&#40;</span>val<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;">if</span><span style="color: #009900;">&#40;</span>type <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;step&quot;</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: #009900;">&#40;</span>el.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;step&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #009900;">&#40;</span>mismatch <span style="color: #339933;">!==</span> 0<span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span>; 
        <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>type <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;min&quot;</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: #009900;">&#40;</span>el.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;min&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #009900;">&#40;</span>val <span style="color: #339933;">&lt;</span> min<span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span>; 
        <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>type <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;max&quot;</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: #009900;">&#40;</span>el.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;max&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #009900;">&#40;</span>val <span style="color: #339933;">&gt;</span> max<span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</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: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>el.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;number&quot;</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;">true</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;">return</span> <span style="color: #003366; font-weight: bold;">false</span>; 
    <span style="color: #009900;">&#125;</span> 
<span style="color: #009900;">&#125;</span>;</pre></div></div>

<p>If a form control specifies only the step attribute the <code>H5F.range()</code> method works around that by using the OR (||) operator to give the variables fallback values so the calculations can still be made. To emulate the step attribute we use modulus (%) which will divide our value by our minimum value, will fallback to 0 if it isn&#8217;t specified, and return the remainder.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">...
<span style="color: #660066;">mismatch</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>val<span style="color: #339933;">-</span>min<span style="color: #009900;">&#41;</span><span style="color: #339933;">%</span>step; 
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>H5F.<span style="color: #660066;">valueMissing</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>isNaN<span style="color: #009900;">&#40;</span>val<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;">if</span><span style="color: #009900;">&#40;</span>type <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;step&quot;</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: #009900;">&#40;</span>el.<span style="color: #660066;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;step&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #009900;">&#40;</span>mismatch <span style="color: #339933;">!==</span> 0<span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span>; 
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Using the modulus value we can find out if it is conforming to the specified increment. We make sure the field isn&#8217;t empty and that it is actually a number. Then we do a check to make sure it doesn&#8217;t equal zero, if it does it will return true which will indicate that there is a step mismatch if false the number is conforming. E.g. If the field has a step value of 3 and the user enters 11 we work out the remainder: (11-0)%3, 3 goes into 11 three times and leaves us with a remainder of 2 which tells us there is a step mismatch.</p>
<h2 class="subtitle02">Browser differences</h2>
<p>Since HTML5 is still a working draft there a few difference between browsers and browser version, I&#8217;ve listed some of them I&#8217;ve come across here:</p>
<ul>
<li>In Firefox 4 invalid form controls have a red box-shadow applied to them; this can be reset by setting the box-shadow to none.</li>
<li>Firefox 4 will override the title tooltip value depending on the validity state of the form control.</li>
<li>Safari 5<sup>1</sup>, Chrome 4-6<sup>1</sup> and Opera 9.6+ all block form submission until all form control validation constraints are met.</li>
<li>Opera 9.6+ upon form submission will focus to the first invalid field and bring up a UI block indicating that it is invalid.</li>
</ul>
<p><strong>1.</strong> Safari 5.0.1, and Chrome 7 have removed form submission blocking if a form is invalid, most likely due to legacy forms now not submitting on older sites.</p>
<p class="shorty01">Short URL: <a href="http://cssn.in/ja/029">http://cssn.in/ja/029</a></p>
<div class="clear">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.thecssninja.com/javascript/h5f/feed</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Drag out files like Gmail</title>
		<link>http://www.thecssninja.com/javascript/gmail-dragout</link>
		<comments>http://www.thecssninja.com/javascript/gmail-dragout#comments</comments>
		<pubDate>Mon, 16 Aug 2010 12:53:42 +0000</pubDate>
		<dc:creator>Ryan Seddon</dc:creator>
				<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

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

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> file <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;dragout&quot;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
file.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;dragstart&quot;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    evt.<span style="color: #660066;">dataTransfer</span>.<span style="color: #660066;">setData</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;DownloadURL&quot;</span><span style="color: #339933;">,</span>fileDetails<span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>From the code above you attach an ondragstart event listener to something you want to &#8220;drag out&#8221; and save to your file system. On the dragstart event you set the data using the new &#8220;DownloadURL&#8221; type and pass file information to it.</p>
<p>In order to pass the correct information to the event we access the download_url attribute and use that for our setData call. I&#8217;ve made one change that is slightly different to how Gmail sets and gets the attribute.</p>

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

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

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

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

