<?xml version="1.0" encoding="UTF-8"?>
<rss 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/" version="2.0">

<channel>
	<title>Web 3.0, 6 Bladed Razors, 7 Minute Abs</title>
	
	<link>http://www.zachleat.com/web</link>
	<description />
	<lastBuildDate>Wed, 16 May 2012 16:42:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/zachleat" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="zachleat" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>CSS3 Job Transition</title>
		<link>http://www.zachleat.com/web/css3-job-transition/</link>
		<comments>http://www.zachleat.com/web/css3-job-transition/#comments</comments>
		<pubDate>Wed, 16 May 2012 16:42:13 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=1249</guid>
		<description><![CDATA[I&#8217;m extremely excited to announce that I have accepted a full time position with Filament Group. I will be working alongside web developer titans of industry Todd Parker, Scott Jehl, Mat &#8216;Wilto&#8217; Marquis, Patty Toland, and Maggie Costello Wachs. #zachleat &#123; transition-property: employment; transition-delay: 1209600s; /* 14d */ &#125; If you&#8217;ve been living under a [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m extremely excited to announce that I have accepted a full time position with <a href="http://filamentgroup.com/">Filament Group</a>. I will be working alongside web developer titans of industry <a href="http://twitter.com/toddmparker">Todd Parker</a>, <a href="http://twitter.com/scottjehl">Scott Jehl</a>, <a href="http://twitter.com/wilto">Mat &#8216;Wilto&#8217; Marquis</a>, <a href="http://twitter.com/pattytoland">Patty Toland</a>, and <a href="http://twitter.com/maggiewachs">Maggie Costello Wachs</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #cc00cc;">#zachleat</span> <span style="color: #00AA00;">&#123;</span>
  transition-property<span style="color: #00AA00;">:</span> employment<span style="color: #00AA00;">;</span>
  transition-delay<span style="color: #00AA00;">:</span> 1209600s<span style="color: #00AA00;">;</span> <span style="color: #808080; font-style: italic;">/* 14d */</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>If you&#8217;ve been living under a block-level element and aren&#8217;t familiar with Filament Group, I&#8217;m sure you&#8217;re familiar with a few of their contributions to the web development world. They&#8217;re well known for their advocacy and real world application of development practices that are important for the future of the web: Accessibility, Progressive Enhancement, and Responsive Design. They&#8217;ve literally <a href="http://filamentgroup.com/dwpe/">written the book on Progressive Enhancement</a>, and their recent redesign of the <a href="http://bostonglobe.com/">Boston Globe</a> was one of the first major large scale implementations of Responsive Design.  If that weren&#8217;t enough, they are also leading the development of the <a href="http://jquerymobile.com/">jQuery Mobile</a> project.</p>
<p>Woooooo!</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/8Cja_-YUTmE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/css3-job-transition/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Let’s get parseIntimate.</title>
		<link>http://www.zachleat.com/web/lets-get-parseintimate/</link>
		<comments>http://www.zachleat.com/web/lets-get-parseintimate/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 05:08:28 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[parseInt]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=1238</guid>
		<description><![CDATA[This Valentine&#8217;s Day, spend a little quality time with JavaScript. Don&#8217;t be afraid to get parseIntimate. In all seriousness, I do still see new JavaScript developers that are unaware of the parseInt problem. I&#8217;m hoping this will raise awareness or failing that at least make some people smile.]]></description>
			<content:encoded><![CDATA[<p>This Valentine&#8217;s Day, spend a little quality time with JavaScript. Don&#8217;t be afraid to <a href="http://parseintimate.com">get parseIntimate</a>.</p>
<p><em>In all seriousness, I do still see new JavaScript developers that are unaware of the parseInt problem. I&#8217;m hoping this will raise awareness or failing that at least make some people smile.</em></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/u4VFpPhuKCk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/lets-get-parseintimate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Placeholder Title for Article about HTML5 Placeholders</title>
		<link>http://www.zachleat.com/web/placeholder/</link>
		<comments>http://www.zachleat.com/web/placeholder/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 04:52:29 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Compatibility Tests]]></category>
		<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=1188</guid>
		<description><![CDATA[When I&#8217;m not out fighting crime, I spend my days developing reusable components for the web. One of those reusable components I wrote was an implementation of a placeholder plugin. For the sake of privacy, all component names have been anonymized so I&#8217;ll refer to this home-grown implementation as The Mankini (if for no other [...]]]></description>
			<content:encoded><![CDATA[<p>When I&#8217;m not out fighting crime, I spend my days developing reusable components for the web. One of those reusable components I wrote was an implementation of a placeholder plugin. For the sake of privacy, all component names have been anonymized so I&#8217;ll refer to this home-grown implementation as The Mankini (if for no other reason than to drive some swimwear shopping traffic to my blog).</p>
<p>The Mankini&#8217;s development predated the HTML5 specification but the end result was functionally similar. The difference being that in addition to operating on text inputs and textareas, it also worked with <def title="Line Feed/Carriage Return">LF/CR</def> and selects (injects an option with an empty value).  The HTML5 specification requires that <def title="Line Feed/Carriage Return">LF/CR</def> be stripped from the placeholder value.</p>
<p>One of the most important design considerations our interaction design team specified for The Mankini was that it was not to be used as a replacement for a form label. It was a complement to the form label and nothing more.  The <a href="http://dev.w3.org/html5/spec/Overview.html#the-placeholder-attribute">HTML5 specification came to the same conclusion</a>: <em>&#8220;The placeholder attribute should not be used as an alternative to a label.&#8221;</em>  The reasoning is obvious: if the form field has a non-empty value, you need to be able to easily identify the value&#8217;s semantic meaning.</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2012/02/Screen-Shot-2012-02-05-at-12.12.09-AM.png" alt="" title="An example of misused placeholders" width="364" height="115" class="aligncenter size-full wp-image-1189" /><br />
Instead of putting the label text into the placeholder, use the placeholder to supplement the labels with an example e-mail and URL to provide more of a hint to the user for proper formatting.  This example isn&#8217;t a huge usability issue since the three fields&#8217; values would be easily identifiable, but it&#8217;s important to keep in mind.</p>
<h2>Placeholder Testing</h2>
<p>I decided to run a <a href="/test/placeholder.html">few compatibility tests</a> on the placeholder attribute to see where I could reuse the HTML5 placeholder inside of The Mankini (the test results are also available on <a href="https://github.com/zachleat/Compatibility-Tests/blob/master/placeholder.html">GitHub</a>). This yielded a few interesting things about some consistent and inconsistent cross-browser incompatibilities with the specification that I thought were worth sharing.</p>
<ol>
<li>The HTML5 spec states that the placeholder should be visible when <em>&#8220;element&#8217;s value is the empty string and/or the control is not focused.&#8221;</em> The and/or presents the implementor with a decision. Do they keep the placeholder text visible when the field is focused but the value is still empty? Or do I remove the placeholder when focusing into an empty field?<br/><br />
My personal preference is that the text remains until the user starts to type. Safari 5.1, iOS 5, and Chrome 17+ were the only browser implementations to agree with this as of time of writing.</li>
<li>The HTML5 spec has suggested (not required) that placeholders <em>only</em> apply to <code>&lt;input type="text, search, password, tel, url, email, number"&gt;</code> and <code>&lt;textarea&gt;</code>. For some input types such as <code>hidden</code>, <code>radio</code>, or <code>checkbox</code> this limitation makes sense, the placeholder would add nothing to these elements. But for others like <code>datetime</code>, <code>date</code>, <code>month</code>, <code>week</code>, <code>time</code>, <code>datetime-local</code>, <code>color</code>, or <code>file</code> the argument can be made that it would be useful.</li>
<li>There is <a href="https://bugs.webkit.org/show_bug.cgi?id=21286">an open WebKit issue</a> to add placeholder support to contenteditable. Hopefully the specification gets modified and this gets added, as it would have been useful for my <a href="http://www.zachleat.com/web/bigtext-makes-text-big/">BigText Demo Wizard</a> which manually implemented that same feature.</li>
<li><code>&lt;input type="number"&gt;</code> support is broken in Safari and it&#8217;s already been <a href="https://bugs.webkit.org/show_bug.cgi?id=61095">reported and fixed</a>. &#8220;The future is here, just not evenly distributed.&#8221;</li>
</ol>
<p>As a side note, it should be said that both Opera and iOS both have comprehensively badass support of the new HTML5 form element types.</p>
<h2>Overlooked Polyfill Considerations</h2>
<ul>
<li>For those browsers that did implement the placeholder, it was well supported in password fields, showing as plaintext and then converting to masked input when the user started to enter data. This was a nice surprise, but polyfilling that behavior in old Internet Explorers will require additional lifting since dynamically changing the type attribute is not permitted.</li>
<li>Placeholder text should not be included with form submit.</li>
<li>Placeholder text should reinitialize on form reset (note: there is no <code>delegate</code> event for <code>reset</code> in jQuery)</li>
<li>Performance. Is the component required to iterate over all elements and add a class to initialize each one individually? For best performance, use CSS attribute selectors (<code>input[type="text"][placeholder]</code>) for the default style and iterate only to remove the light gray color on form elements with non-empty values. This only requires a className modification for a much smaller set of elements, only the ones with non-empty values. Remember that the browsers we polyfill are often the slowest.<br/><br />
Does the component modify the <code>className</code> property on <code>focus</code> and <code>blur</code>? I found this to be a huge performance issue for the Mankini in IE7 and IE8 on pages with large DOM trees and was a lot faster if the Mankini only modified one element&#8217;s style (think jQuery&#8217;s <code>$(this).css('color', '#000')</code>).</li>
<li>Clear the values on page unload. After page refresh, some browsers will attempt to save unsubmitted form values and re-enter the values when the page reloads (added after reviewing <a href="https://github.com/mathiasbynens/jquery-placeholder">Mathias Bynen&#8217;s jQuery-placeholder</a>).</li>
</ul>
<h2>Bathwater, No Babies</h2>
<p><a href="http://html5please.us/#placeholder">HTML5 Please</a> recommends that we use the new and shiny responsibly and gives the go-ahead to use the placeholder polyfill on our pages. I humbly disagree. This seems to be the same trap we fell into for rounded corners and box shadows. We put extra effort into trying to get our sites to render and behave identically cross-browser, when we should have just let them render in old browsers without rounded corners or box-shadows at all. To test whether or not a polyfill is necessary, I created a super complex decision workflow called <strong>The Polyfill Test</strong>. It consists of 2 steps:</p>
<ol>
<li>Look at your own browser statistics. If the feature is at >50%, continue to Step 2.</li>
<li>Determine if the user be able to complete their task without the feature. If the task is still completable without significant impairment, the polyfill isn&#8217;t necessary.</li>
</ol>
<p>Globally, placeholder support is sitting at 60% and growing. This particular feature has passed the tipping point.  If your audience isn&#8217;t a representative sample of the global web browser statistics (big enterprise intranets with 97% Internet Explorer), your mileage may vary.</p>
<p>If you&#8217;re already using validation on the form fields (client and/or server side) and you&#8217;re correctly using the placeholder to supplement (not replace) the field labels, I would argue that the polyfill isn&#8217;t needed. It&#8217;s an implementation nice-to-have, not a requirement.</p>
<p><em>Update: Added note about Chrome 17+ support for placeholder text remaining on focus per Mathias&#8217; feedback below.</em></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/W9ZBgsavXME" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/placeholder/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Deferreds and a Better Geolocation API</title>
		<link>http://www.zachleat.com/web/deferred-geolocation/</link>
		<comments>http://www.zachleat.com/web/deferred-geolocation/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 04:54:04 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=1159</guid>
		<description><![CDATA[Warning, this article is intended for Deferred unbelievers to convince them that Deferred objects are both easy and useful. If you&#8217;re already a Deferred object expert, you might want to skip this one. Earlier this year I was given the opportunity to attend the jQuery Conference in San Francisco. I was delighted to go, able [...]]]></description>
			<content:encoded><![CDATA[<p><em style="font-size: 90%">Warning, this article is intended for Deferred unbelievers to convince them that Deferred objects are both easy and useful.  If you&#8217;re already a Deferred object expert, you might want to skip this one.</em></p>
<p>Earlier this year I was given the opportunity to attend the jQuery Conference in San Francisco. I was delighted to go, able to finally meet some of the JavaScript greats I&#8217;d been <del datetime="2011-11-05T22:11:29+00:00">stalking</del> following online for years.</p>
<p>Looking back on the conference, the one presentation that had the <strong>biggest impact on the way that I code</strong> had to have been <a href="https://twitter.com/danheberden">Dan Heberden</a>&#8216;s &#8220;<a href="http://danheberden.com/presentations/deferreds-putting-laziness-to-work/">Deferreds, Putting Laziness to Work.</a>&#8221;  (I would be remiss if I didn&#8217;t also mention inspiration from a <a href="http://speakerdeck.com/u/eliperelman/p/jquery-deferreds-and-promises">recent presentation</a> by <a href="https://twitter.com/eliperelman">Eli Perelman</a> at the <a href="http://www.meetup.com/jquery-omaha/">Omaha jQuery Meetup</a>.)</p>
<p>At first, Deferred objects sound scary.  I can assure you that they&#8217;re actually incredibly easy and incredibly useful. Today we&#8217;ll go through the simple task of <strong>reworking the <a href="http://www.w3.org/TR/geolocation-API/">Geolocation API</a> to use jQuery Deferred objects</strong>.</p>
<p>Here is the standard Geolocation API to retrieve the user&#8217;s current position:</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">navigator.geolocation.getCurrentPosition(function(position) {
  // success
}, function(error) {
  // failure
}, {
  // options
  enableHighAccuracy: true
});</pre></div></div>

<p>When the above API is called, a prompt is shown to the user asking if they want to divulge their location information to the domain of the currently active web site.  Typically this prompt is a non-blocking asynchronous operation (although not explicitly defined in the specification).</p>
<p>Let&#8217;s go ahead and change it to use a jQuery Deferred object:</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">function getCurrentPositionDeferred(options) {
  var deferred = $.Deferred();
&nbsp;
  navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.reject, options);
&nbsp;
  return deferred.promise();
};</pre></div></div>

<p>Notice that the success callback is replaced by the deferred object&#8217;s resolve method and the error callback is replaced by the reject method.  All of our function arguments are removed from the API. We&#8217;re left with one simple options argument.</p>
<p>This allows us to do things like:</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">getCurrentPositionDeferred({
  enableHighAccuracy: true
}).done(function() {
  // success
}).fail(function() {
  // failure
}).always(function() {
  // executes no matter what happens. I've used this to hide loading messages.
});
// You can add an arbitrary number of callbacks using done, fail, or always.</pre></div></div>

<p>We could also use <code>$.when</code> to run code upon completion of two arbitrary and contrived operations like a Geolocation call and an Ajax request. Awesome.</p>
<p>To coordinate between multiple Deferred objects, use $.when:</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">$.when(getCurrentPositionDeferred(), $.ajax(&quot;/someUrl&quot;)).done(function() {
  // both the ajax call and the geolocation call have finished successfully.
});</pre></div></div>

<p>I wonder what other browser native APIs could be better served by using Deferred objects instead of function arguments.</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/PZ2QSLWnLzw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/deferred-geolocation/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A Mobile Web Divided</title>
		<link>http://www.zachleat.com/web/a-mobile-web-divided/</link>
		<comments>http://www.zachleat.com/web/a-mobile-web-divided/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 03:25:57 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Application Design]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=1079</guid>
		<description><![CDATA[Unless you&#8217;ve been living comfortably under an elaborate dwelling constructed entirely out of rock, you&#8217;re aware of the growing popularity of smartphones and other mobile devices. With that growth we&#8217;ve witnessed a bumper crop of component libraries and frameworks to enable us to create mobile web sites and applications. One Web, Two Web Primer There [...]]]></description>
			<content:encoded><![CDATA[<p>Unless you&#8217;ve been living comfortably under an elaborate dwelling constructed entirely out of rock, you&#8217;re aware of the growing popularity of smartphones and other mobile devices.  With that growth we&#8217;ve witnessed a bumper crop of component libraries and frameworks to enable us to create mobile web sites and applications.</p>
<h2 id="primer">One Web, Two Web Primer</h2>
<p>There are two different approaches one can take when developing a mobile web site.  The first approach has been assigned the delightfully inclusive moniker <a href="http://www.w3.org/TR/mobile-bp/#OneWeb">&#8216;<em>One Web</em>&#8216;</a>. <em>One Web</em> involves creating a single web site accessible from both mobile and desktop web browsers and the site&#8217;s presentation is custom tailored at run time to the capabilities of the user&#8217;s device.</p>
<p>The second approach involves creating two completely separate web sites, one for mobile and one for the desktop.  The advantage with this approach is that content and the user interface can be tailored specifically for mobile, as the user&#8217;s context while using each site is likely to be drastically different.  An obvious nickname for this approach might be <em>&#8216;Two Web&#8217;</em>.</p>
<p><em>Two Web</em> involves a white list of mobile User Agents that server side code uses to detect mobile devices and redirects them to a mobile specific site.  The remaining User Agents are left to view the desktop version.  An improvement to this approach allows end users to opt-out of the mobile version by simply clicking on a link that redirects to the desktop version and persists the setting (often using a cookie).</p>
<p>With <em>One Web</em> the site is customized and adapted based primarily on screen dimension, orientation, and pixel density. Contrast that to <em>Two Web</em>, which usually divides touch screen and non touch screen devices. While this may make it easier on developers, it&#8217;s awkward for users. For example, consider Google Plus on an iPad. The entire experience feels like it was intended for a small screen, and feels barren and feature-poor on the larger tablet screen. The full Google Plus web site would be better for the iPad.</p>
<p>Other downsides to <em>Two Web</em> include maintenance of two separate code bases, maintenance of the User Agent white list as new devices are released, and dependency on server side code to redirect mobile User Agents to the mobile site.</p>
<p>Developers should also be aware of the historical precedence of browser vendors <em>borrowing</em> User Agent strings from other devices as they become popular. That&#8217;s why almost all User Agents in existence today contain the string &#8220;Mozilla&#8221; and why WebKit User Agents contain &#8220;like Gecko.&#8221;  Come to think of it, User Agent theft happens most often when the target is Netscape or Netscape progeny.</p>
<h2 id="choice">Make Your Choice</h2>
<p>An informed reader might already be aware of the choice between One and <em>Two Web</em>.  What you might not be aware of is that your mobile JavaScript libraries and toolkits may have already made this choice for you.  The mobile web development space is clouded with tools that don&#8217;t document their requirement of <em>Two Web</em>.</p>
<p>Most of the tools that have been reviewed below have focused on WebKit support only.  It is not the author&#8217;s desire to simply suggest that these tools should work on non-WebKit mobile browsers.  <strong>The tools we use should not create a web divided between mobile and desktop.</strong>  In a theoretical world where WebKit has a global monopoly on both mobile and desktop web browsing, it would still create problems if sites are restricted to mobile only or desktop only. Developers must be aware of the compromises we&#8217;ve inherited from our tools.</p>
<p>As of June 2011, mobile web browsing is <a href="http://en.wikipedia.org/wiki/Usage_share_of_web_browsers#Summary_table">only 6.5% of all web browsing</a>, while 24.5% of all web browsing is desktop WebKit (non-mobile browsers like Chrome or Safari).  While evidence would suggest that the share of mobile web browsing will increase, we should be very cautious to assume that WebKit (mobile or desktop) will ever reach anything close to 100% market share.</p>
<p>Let&#8217;s look at how a few sample pages render in a few desktop browsers.  (<em>Keep in mind that I did not test in the other major rendering engine, Presto currently used by Opera 11.5</em>)</p>
<h3><a href="http://dev.sencha.com/deploy/touch/examples/nestedlist/">Sencha Touch 1.1.0</a></h3>
<table>
<thead>
<tr>
<th>Trident (IE9)<br/><br />
Not Supported</th>
<th>Gecko (Firefox 5)<br/><br />
Not Supported</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="http://www.zachleat.com/web/wp-content/uploads/2011/07/Screen-Shot-2011-07-26-at-10.48.51-PM.png"><img src="http://www.zachleat.com/web/wp-content/uploads/2011/07/Screen-Shot-2011-07-26-at-10.48.51-PM.png" alt="" title="Sencha Touch in IE9" width="275" height="362" class="alignnone size-full wp-image-1120" /></a></td>
<td><img src="http://www.zachleat.com/web/wp-content/uploads/2011/07/Screen-Shot-2011-07-26-at-10.31.41-PM.png" alt="" title="Sencha Touch in Firefox" width="272" height="362" class="alignnone size-full wp-image-1118" /></td>
</tr>
</tbody>
</table>
<p>Instead of a nice list with large click targets, we&#8217;re greeted with a simple white screen. No error messages detailing a JavaScript error occurred on the page. No warning saying the web browser being used here isn&#8217;t supported (the bane of Progressive Enhancement advocates). Really bad user experience here.</p>
<p>Officially, Sencha Touch support is not &#8220;anything WebKit&#8221; as some have suggested.  It officially supports Apple iOS 3+, Android 2.1+, and BlackBerry 6+ devices.  It does not include WebOS, which is a WebKit browser, <strong>nor does it include any desktop web browsers.</strong></p>
<h3><a href="http://www.dhtmlx.com/touch/samples/apps/uidemo/index.html">DHTMLx Touch v.1.0 RC</a></h3>
<table>
<thead>
<tr>
<th>Trident (IE9)<br/><br />
Not Supported</th>
<th>Gecko (Firefox 5)<br/><br />
Not Supported</th>
</tr>
</thead>
<tbody>
<tr>
<td><img src="http://www.zachleat.com/web/wp-content/uploads/2011/07/Screen-Shot-2011-07-27-at-6.26.50-PM.png" alt="" title="DHTMLx Touch in IE9" width="275" height="364" class="alignnone size-full wp-image-1130" /></td>
<td><img src="http://www.zachleat.com/web/wp-content/uploads/2011/07/Screen-Shot-2011-07-26-at-10.16.48-PM.png" alt="" title="DHTMLx Touch in Firefox" width="272" height="361" class="alignnone size-full wp-image-1115" /></td>
</tr>
</tbody>
</table>
<p>DHTMLx Touch operated much better than Sencha Touch on desktop browsers. Despite the fact that many of the demos on their website are hidden behind QR codes.  You can use a <a href="http://zxing.org/w/decode.jspx">QR decoder</a> to get the URLs for viewing on your desktop device. As for official web browser support, the DHTMLx Touch web site states:</p>
<blockquote><p>While browsing the demos of DHTMLX Touch, note that the framework requires a mobile device to display and work correctly. You can also run the demos on standard PCs in Firefox 3.6 and above, and WebKit browsers (Safari, Chrome, etc.), but there still can be some issues since DHTMLX Touch is optimized for mobile devices.</p></blockquote>
<p>Unfortunately, even though it works for the most part, desktop web browsers are still unsupported.  It should also be noted that DHTMLx isn&#8217;t full WebKit either, as Blackberry 6 is not yet officially supported.</p>
<h3><a href="http://chrism.dojotoolkit.org/mobile-0.2/make_samples/dojo-samples/demos/mobile-gallery/demo.html">Dojo Mobile 0.2</a></h3>
<table>
<thead>
<tr>
<th>Trident (IE9)<br/><br />
Supported</th>
<th>Gecko (Firefox 5)<br/><br />
Supported</th>
</tr>
</thead>
<tbody>
<tr>
<td><img src="http://www.zachleat.com/web/wp-content/uploads/2011/08/Screen-Shot-2011-08-08-at-9.51.41-PM.png" alt="" title="Dojo Mobile in IE9" width="277" height="366" class="alignnone size-full wp-image-1140" /></td>
<td><img src="http://www.zachleat.com/web/wp-content/uploads/2011/07/Screen-Shot-2011-07-26-at-10.18.51-PM.png" alt="" title="Dojo Mobile in Firefox" width="271" height="363" class="alignnone size-full wp-image-1116" /></td>
</tr>
</tbody>
</table>
<p>Dojo Mobile also did fairly well. There were a few minor rendering issues with WebKit prefixed gradients (and no background color fallback) which I would consider to be very minor bugs.  Here&#8217;s the good news from the <a href="http://dojotoolkit.org/reference-guide/dojox/mobile.html#id5">Dojo documentation</a>:</p>
<blockquote><p>Dojox.mobile supports not only webkit-based mobile browsers, but also non-CSS3 desktop browsers such as IE and (older) Firefox.</p></blockquote>
<h3><a href="http://jquerymobile.com/demos/1.0b2/#/demos/1.0b2/docs/lists/index.html">jQuery Mobile 1.0b2</a></h3>
<table>
<thead>
<tr>
<th>Trident (IE9)<br/><br />
Supported</th>
<th>Gecko (Firefox 5)<br/><br />
Supported</th>
</tr>
</thead>
<tbody>
<tr>
<td><img src="http://www.zachleat.com/web/wp-content/uploads/2011/08/Screen-Shot-2011-08-08-at-10.05.50-PM.png" alt="" title="jQuery Mobile in IE9" width="277" height="365" class="alignnone size-full wp-image-1143" /></td>
<td><img src="http://www.zachleat.com/web/wp-content/uploads/2011/07/Screen-Shot-2011-07-26-at-10.08.24-PM.png" alt="" title="jQuery Mobile in Firefox" width="272" height="361" class="alignnone size-full wp-image-1111" /></td>
</tr>
</tbody>
</table>
<p>In most of the other frameworks, cross browser compatibility documentation felt like an afterthought mentioned in passing.  Not jQuery Mobile. It has the most complete <a href="http://jquerymobile.com/gbs/">web browser support documentation</a> of any mobile component framework.  Not only is their documentation the best, their device support is the most comprehensive.  The project officially supports Internet Explorer all the way back to version 7, which speaks volumes to their commitment to allow the developer to make the choice between <em>One Web</em> and <em>Two Web</em>.</p>
<h2>Conclusion</h2>
<p>If you&#8217;re developing Hybrid Native applications using software like <a href="http://www.phonegap.com/">PhoneGap</a>, desktop web browser support doesn&#8217;t matter here.  Feel free to disregard this entire article.</p>
<p>However, if you are developing for the web I would encourage you to look strongly at <em>One Web</em> as the default choice, and use <em>Two Web</em> as the exception when your content and context require drastically different non-adaptable versions of the site for mobile devices.  Certainly I&#8217;m not suggesting that either <em>One or Two Web</em> are silver bullets.  But we should all be aware of how the tools we choose weigh on our decision, and how this decision will affect our users in the future.</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/5oT7H5q6o8A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/a-mobile-web-divided/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>FitText + BigText: A Tale of Two Plugins</title>
		<link>http://www.zachleat.com/web/fittext-and-bigtext/</link>
		<comments>http://www.zachleat.com/web/fittext-and-bigtext/#comments</comments>
		<pubDate>Fri, 13 May 2011 04:40:20 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=1014</guid>
		<description><![CDATA[Earlier this week, @TrentWalton tweeted: We at @paravelinc happily present to you FitText—a jQuery plugin for inflating web type: http://t.co/1NuQg5z Naturally, I wondered how it compared to BigText, a plugin of my own creation to Make Text Big. Trent continued: It&#8217;s in the GitHub readme, but I want to recognize BigText from @zachleat as another [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this week, <a href="http://twitter.com/trentwalton">@TrentWalton</a> <a href="http://twitter.com/TrentWalton/status/67972022776508416">tweeted</a>:</p>
<blockquote><p>We at <a href="http://twitter.com/paravelinc">@paravelinc</a> happily present to you FitText—a jQuery plugin for inflating web type: <a href="http://t.co/1NuQg5z">http://t.co/1NuQg5z</a></p></blockquote>
<p>Naturally, I wondered how it compared to BigText, a plugin of my own creation to Make Text Big.  Trent <a href="http://twitter.com/TrentWalton/status/67989004427079682">continued</a>:</p>
<blockquote><p>It&#8217;s in the GitHub readme, but I want to recognize BigText from <a href="http://twitter.com/zachleat">@zachleat</a> as another font sizer for non-fluid sites: <a href="http://t.co/dXw607P">http://t.co/dXw607P</a></p></blockquote>
<p>I was delighted to get some attribution from Trent, and even more delighted to see their plugin. It&#8217;s really a great piece of work.  However, his statement that BigText is just for non-fluid sites is not quite accurate. Let&#8217;s dive in.</p>
<p><a href="http://www.zachleat.com/web/bigtext-makes-text-big/"><img src="http://www.zachleat.com/web/wp-content/uploads/2011/05/Screen-shot-2011-05-12-at-11.05.26-PM.png" alt="" title="BigText" width="300" height="205" class="size-full wp-image-1052" /></a></p>
<p><a href="http://fittextjs.com/"><img src="http://www.zachleat.com/web/wp-content/uploads/2011/05/Screen-shot-2011-05-12-at-11.10.01-PM.png" alt="" title="FitText" width="300" height="199" class="size-full wp-image-1053" /></a></p>
<p>On the surface, BigText and FitText might seem very similar. In fact, they are quite different and approach what might seem to be a similar problem (resizing text to fit a container) in very different ways.</p>
<p>At its simplest, we can boil it down like this: If you&#8217;re crafting a specific design with <strong>copy that is not going to change</strong>, use FitText. If your <strong>text is dynamic</strong> (maybe user generated), use BigText.</p>
<p>Here&#8217;s more detail:</p>
<table>
<thead>
<tr>
<th>&#160;</th>
<th>BigText</th>
<th>FitText</th>
</tr>
</thead>
<tbody>
<tr>
<td>Demos</td>
<td><a href="http://jsfiddle.net/zachleat/anJpE/">BigText Fiddle</a></td>
<td><a href="http://jsfiddle.net/zachleat/ExhDC/">FitText Fiddle</a></td>
</tr>
<tr>
<td>&#160;</td>
<td colspan="2"><em>Try resizing the demo windows above.</em></td>
</tr>
<tr>
<td>Algorithm</td>
<td><strong>Sizes text automatically</strong> from a base up to fit the element width, regardless of initial font size.</td>
<td>Uses the width of the element and a configurable JavaScript argument (the ratio) to <strong>scale text down</strong> to smaller widths. This ratio argument must be set manually.</td>
</tr>
<tr>
<td>Responsive Design</td>
<td colspan="2">Both plugins work with <strong>responsive design techniques</strong>, operating correctly with media queries, fluid designs, and window resizing.</td>
</tr>
<tr>
<td>Speed</td>
<td>Fast</td>
<td>Faster</td>
</tr>
<tr>
<td>Text</td>
<td>Works with user generated text, or any text isn&#8217;t cemented at design time. See the <a href="http://www.zachleat.com/bigtext/demo/">BigText Demo Wizard</a>.</td>
<td>Requires up front configuration to specific text.</td>
</tr>
<tr>
<td>Resize Event</td>
<td>Works with existing debounced resize libraries, if they exist on the page.</td>
<td>Does not use a debounced resize event.</td>
</tr>
<tr>
<td>Unobtrusive</td>
<td>CSS and BigText font-sizes are independent of each other.</td>
<td>FitText uses your CSS font-size as a maximum font size.</td>
</tr>
<tr>
<td>&#160;</td>
<td colspan="2"><em>Don&#8217;t forget to set sane CSS font-size defaults when JavaScript isn&#8217;t available.</em></td>
</tr>
<tr>
<td>Unit Tested</td>
<td>Full Test Suite</td>
<td>-</td>
</tr>
</tbody>
</table>
<p><strong>FitText is very lightweight and fast</strong>, even considering it doesn&#8217;t yet use a debounced resize event. The <a href="https://github.com/davatron5000/FitText.js/blob/master/jquery.fittext.js">FitText algorithm</a> is <strong>quite beautiful</strong>.  A huge well done to <a href="http://paravelinc.com/">Paravel</a>.</p>
<p>FitText relies on the fact that there is a <strong>linear relationship between font-sizes and element widths</strong>.  Once you&#8217;ve established the ratio between the two, it&#8217;s off to the races. In fact, it would probably be technically possible to determine the ratio solely on the initial inner-width of the text and the initial font-size.  I&#8217;ll have to play around with that approach but if it works it would give an amazing speed improvement to BigText.</p>
<div style="text-align: center; font-size: 160%; margin-bottom: 1em"><code>font-size = outer-width / configurable-ratio</code></div>
<p>In a perfect world, BigText and FitText could be combined, to create a <em>mutant auto-text-sizing plugin baby</em> that gives the best of both worlds.</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/13BqWBSFeOw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/fittext-and-bigtext/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Pragmatic Progressive Enhancement</title>
		<link>http://www.zachleat.com/web/pragmatic/</link>
		<comments>http://www.zachleat.com/web/pragmatic/#comments</comments>
		<pubDate>Tue, 10 May 2011 04:11:47 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Application Design]]></category>
		<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=990</guid>
		<description><![CDATA[A few weeks ago at the jQuery Conference (San Francisco 2011), Nicholas Zakas delivered a wildly entertaining presentation entitled &#8220;Progressive Enhancement 2.0&#8243; (slides 65-79 are especially great), updating the basic rules of PE for a modern age. While prior Progressive Enhancement techniques included layering content, presentation, and behavior (conveniently represented as HTML, CSS, and JavaScript). [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.zachleat.com/web/wp-content/uploads/2011/05/juniper.jpg" alt="" title="Juniper Plant" style="width: 100%" class="alignnone size-full wp-image-1006" /></p>
<p>A few weeks ago at the jQuery Conference (San Francisco 2011), Nicholas Zakas delivered a wildly entertaining presentation entitled <strong><a href="http://www.slideshare.net/nzakas/progressive-enhancement-20">&#8220;Progressive Enhancement 2.0&#8243;</a></strong> (slides 65-79 are especially great), updating the basic rules of <abbr title="Progressive Enhancement">PE</abbr> for a modern age.  While prior Progressive Enhancement techniques included layering content, presentation, and behavior (conveniently represented as HTML, CSS, and JavaScript). <abbr title="Progressive Enhancement">PE</abbr> 2.0 (not to be confused with our other 2nd generation friend, the Web) involves <strong>multiple layers of CSS</strong> for differing device capabilities (rounded corners for example) and <strong>multiple layers of JavaScript</strong> (ECMAScript 5 capable browsers, for example).  He made the argument that this also included <strong>ignoring older browsers</strong> (in some cases) and only moving forward with new functionality for newer, more capable devices.</p>
<p>Like any web developer that believes in getting actual work done, I agree with his argument but not without exemption.</p>
<h2>Pieces of Flair</h2>
<p>The benefit of Progressive Enhancement pays off when your code encounters a device is <strong>incapable of interpreting the CSS or JavaScript correctly</strong> in a way the code was intended.  This could be because of a bug in the rendering or JavaScript engine (or God-forbid an error in the code itself), or it could be because the feature being utilized is newer than the device itself and it could not have supported it without clairvoyance or a time machine.</p>
<p>The example Nicholas used to display this case was the Twitter home page, which uses CSS border-radius to display rounded corners.  In user agents that don&#8217;t support border-radius, such as IE &lt;9, the elements have sharp rectangular corners.  Using Progressive Enhancement here is a no-brainer, especially for features (like rounded corners) that have no bearing on the actual meat of the page, the content.</p>
<p>But <strong>when the feature is the content</strong> and degradation requires additional work, the decision is more complex.  <strong>HTML5 &lt;video&gt; and &lt;audio&gt; probably aren&#8217;t an acceptible baseline</strong> for progressive enhancement yet (based on current web browser statistics), and (video/audio) may never be an acceptable baseline depending on your views on universal accessible content.  The best baseline might be a text-only transcript of the media.  It really depends on how much importance the video/audio is to the core functionality of the page.</p>
<h2>Input</h2>
<p>Historically speaking, in order of mainstream application the progression of input devices used to interact with (even back before web) applications was: keyboard, mouse, touch, and (even more recently) speech (see <a href="http://nooshu.com/experimenting-with-webkit-form-speech-input">the speech attribute on text inputs in Google Chrome</a>).  Logical progression concludes that we&#8217;ll see gesture APIs (think Microsoft Kinect) available at some point as well.  It&#8217;s very important to consider that the <strong>the mechanism of input must also be carefully layered</strong>. Start with a good baseline of keyboard support for your application, then add mouse interactions, then layer any specific (multi-)touch interactions on top of that, and so on.  You don&#8217;t want to skip any intermediate input layers.</p>
<p>In Nicholas&#8217; presentation, he presented an example of the Yahoo! homepage, specifically modified for tablet devices (slide 115).  He went on to describe that the carousel functionality on the main image on the page was not available when viewing the page in Firefox.  I think this is a good example of what happens when you skip layers of input interactions, moving straight to touch, without first layering mouse-based input.  The approach the Yahoo! team took might be okay if you can afford to develop multiple independent code bases for a single home page, but most teams are going to want to get as much out of a single code-base as they can.</p>
<h2>Cutting Fat</h2>
<p>A side benefit of targeting Progressive Enhancement to your core functionality allows you to easily add ancillary features that <strong>don&#8217;t need to span the entirety of your browser support spectrum</strong>.  Some might argue that the Carousel functionality in the Yahoo! tablet example could be considered ancillary, but the positioning and screen real estate dedicated to it suggests otherwise. Facebook&#8217;s chat in IE6 is a good example of this (slide 114).  Is chat part of the core functionality that Facebook wants to guarantee device independent access to?  Apparently not.  Making decisions in this realm involves a real cost benefit analysis, <strong>weighing the feature against user benefit, browser market share, and development/implementation time</strong>.</p>
<h2>Exceptions</h2>
<p>It&#8217;s important to note that <strong>not all things can be developed using Progressive Enhancement</strong>.  There are certain use cases in which viewing the content in a lower fidelity than the author originally intended would destroy the value of content altogether.  While these use cases are rare for most sites, most artistic endeavors can be classified as such.  Consider <a href="http://www.thewildernessdowntown.com/">The Wilderness Downtown</a>, an amazing and beautiful interactive film built by Chris Milk using HTML5.  The strong, vivid emotional connection between the film and the viewer would have been destroyed had the content been a text-based transcript, or just audio, or even just a video.  <strong>Art must not be compromised.</strong></p>
<p>Now, some of you probably read the above paragraph and are thinking to yourself that your blog also qualifies under the above exemption (you&#8217;re the guy that doesn&#8217;t have full text feeds on his RSS aren&#8217;t you?).  Just be real with yourself, most things probably don&#8217;t fit into the same level of interactivity as The Wilderness Downtown.  <strong>Don&#8217;t use art as an excuse.</strong></p>
<h2>Conclusion</h2>
<p>Start with the <strong>primary goal</strong> of each individual page, this <strong>must be universally accessible</strong>.  If the goal is to display text content, the text must be available sans-JavaScript.  If the goal is to show a video or play audio, consider a transcript as your baseline.  If the goal is to solicit form input from the end user, don&#8217;t skip input interaction layers.  But don&#8217;t be afraid to shirk best practices on things that aren&#8217;t necessary to that goal, like social media links, a real-time chat client, trends/statistics, etc. <strong>You&#8217;ll know what matters.</strong></p>
<p><em>Update: Changed the title of the article.</em><br />
<em>Update: Rather than My Yahoo!, Nicholas informed me that it was just the Yahoo! homepage.</em></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/qlXyd8CSl7g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/pragmatic/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>HTML5 vs. Native Applications, The Presentation</title>
		<link>http://www.zachleat.com/web/html5-vs-native-applications/</link>
		<comments>http://www.zachleat.com/web/html5-vs-native-applications/#comments</comments>
		<pubDate>Sat, 05 Mar 2011 22:04:14 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Presentations]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[LocalStorage]]></category>
		<category><![CDATA[Media Queries]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Native Applications]]></category>
		<category><![CDATA[Offline]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=961</guid>
		<description><![CDATA[This slide deck was prepared for my guest lecture at the University of Nebraska-Omaha&#8217;s spring course on Mobile Application Development (BSAD 8916-005). The course was developed in partnership with Google&#8217;s University Relations program and included a variety of business and management students with limited programming experience. My lecture was approximately six weeks into the course, [...]]]></description>
			<content:encoded><![CDATA[<p>This slide deck was prepared for my guest lecture at the University of Nebraska-Omaha&#8217;s spring course on Mobile Application Development (BSAD 8916-005).  The course was developed <a href="http://googleresearch.blogspot.com/2009/07/app-inventor-for-android.html">in partnership with Google&#8217;s University Relations program</a> and included a variety of business and management students with <em>limited programming experience</em>.  My lecture was approximately six weeks into the course, and the students had already developed a few simple Android applications.  My task was to convince them that HTML5 and Web Development is a viable alternative to native application development, for most use cases.</p>
<p><em>(I appreciate the irony of sharing these slides using the flash plugin)</em></p>
<p><object id="__sse7160947" width="510" height="426"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=presentation-110305125324-phpapp02&#038;stripped_title=html5-vs-native-applications&#038;userName=zachleat" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse7160947" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=presentation-110305125324-phpapp02&#038;stripped_title=html5-vs-native-applications&#038;userName=zachleat" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="510" height="426"></embed></object></p>
<ul>
<li><a href="http://www.slideshare.net/zachleat/html5-vs-native-applications/download">Download the original PDF (exported from Keynote)</a></li>
<li><a href="http://www.zachleat.com/mobile/uno/Laundry-Timer/">Download the source code</a></li>
</ul>
<p>If there&#8217;s demand, I do have a video of the talk. Let me know and I can do a bit more work to package the video and upload it.</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/EGDOWQuAuAY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/html5-vs-native-applications/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Raging Netflix Queue, a Google Chrome Extension</title>
		<link>http://www.zachleat.com/web/raging-netflix-queue/</link>
		<comments>http://www.zachleat.com/web/raging-netflix-queue/#comments</comments>
		<pubDate>Mon, 21 Feb 2011 16:46:46 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Chrome Extension]]></category>
		<category><![CDATA[Google Chrome]]></category>
		<category><![CDATA[Movies]]></category>
		<category><![CDATA[Netflix]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=921</guid>
		<description><![CDATA[The premise is simple. When attempting to find movies to watch in my local theater, I often stumble upon titles that I feel to be more rental quality than theater quality. So I wanted an easier way to add those movies to my Netflix queue. I created a Google Chrome extension to accomplish just that. [...]]]></description>
			<content:encoded><![CDATA[<p>The premise is simple. When attempting to find movies to watch in my local theater, I often stumble upon titles that I feel to be more rental quality than theater quality. So I wanted an easier way to add those movies to my Netflix queue.  I created a Google Chrome extension to accomplish just that.</p>
<p><a href="http://www.zachleat.com/web/wp-content/uploads/2011/02/Screen-shot-2011-02-21-at-10.15.44-AM.png"><img src="http://www.zachleat.com/web/wp-content/uploads/2011/02/Screen-shot-2011-02-21-at-10.15.44-AM-300x147.png" alt="" title="Screenshot of Raging Netflix Queue" width="300" height="147" class="alignright size-medium wp-image-947" /></a>When Raging Netflix Queue recognizes the site you&#8217;re browsing to be a movie web site, it will show a small green Netflix icon in the address bar.  Clicking that icon will add the title to your queue.  If the title is available for Instant Viewing, it will go into your Instant Queue.  If not available for Instant View, it will go into your DVD Queue.  If the title is still in theaters and not yet available on DVD, it will go into the Saved portion of your DVD Queue, and Netflix will automatically add it to your DVD Queue when it becomes available.</p>
<p>Raging Netflix Queue supports Rotten Tomatoes, IMDB, Google Movies, Apple Trailers, Movie Fone, movies.com, Yahoo Movies, and Fandango.  Let me know if you have others you&#8217;d like to see added.</p>
<h2><a href="https://chrome.google.com/extensions/detail/nbnnepgogimidfbfkbcfmdeimmfadmmp">Download Raging Netflix Queue</a></h2>
<h2>Screencast</h2>
<p><iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/YuRuYdfvTA0" frameborder="0" allowfullscreen></iframe></p>
<h2>Hiccups</h2>
<h3>Years</h3>
<p>The extension will parse the release year from the movie page, in order to guarantee better accuracy of results (There are a ton of remakes out there with the same titles).  However, the actual year may vary. Some sites report theater release date, while others DVD release date, or the movie may have gone through a small showing and then a larger showing later.  Thus, we allow plus or minus one year leverage when searching Netflix. See <a href="http://www.rottentomatoes.com/m/cedar_rapids_2010/">Cedar Rapids (2011) on Rotten Tomatoes</a>.</p>
<h3>Use of &#8220;The&#8221; or And/&amp;</h3>
<p>Apple&#8217;s entry for <a href="http://trailers.apple.com/trailers/universal/adjustmentbureau/">The Adjustment Bureau</a> does not include &#8220;The&#8221; in the title.  While this would be solved if Netflix allowed partial name matches in their OData API, Raging Netflix Queue does an additional search prepending &#8220;The&#8221; to the title, if no titles were found on the first go.</p>
<p>Netflix requires exact name matches in their API and prefers &#8220;and&#8221; over &#8220;&amp;&#8221; in my tests.  Raging Netflix Queue does a simple string replace there.</p>
<h3>Single Quotes</h3>
<p>Titles like &#8220;The King&#8217;s Speech&#8221; don&#8217;t match, due to another limitation with the <a href="http://developer.netflix.com/docs/oData_Catalog">Netflix OData API</a>.  There is no way to escape single quotes in the query string.  I&#8217;m waiting on Netflix for an answer there.</p>
<h2>Hindsight</h2>
<p>It&#8217;s true that I have built a <a href="/web/2007/04/18/javascript-code-coverage-tool-for-firebug/">web browser plugin (to an add-on) before</a>, and even a <a href="/web/2010/07/19/dom-sailbloat/">plug-in to a ported web browser add-on</a>, but it was a great experience to build an actual web browser extension and Google Chrome has made it very easy to do so.  This was also a <strong>jQuery-free project</strong>, as I would think that all Google Chrome extensions would be.  jQuery is intended to solve cross browser compatibility issues, and a web browser specific extension shouldn&#8217;t have any of those.  Sure, it feels like you&#8217;re being spoiled to use native String <code>trim()</code>, Array <code>forEach</code>, and <code>document.querySelector</code>. But damn it, I deserve nice things every once in awhile.</p>
<p><a href="http://www.southparkstudios.com/clips/155280/raging-clues" style="font-size: 80%"><em>I&#8217;m getting such a huge queue right now.</em></a></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/vUr65bzLv8o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/raging-netflix-queue/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>The JavaScript Testing Challenge Winner</title>
		<link>http://www.zachleat.com/web/javascript-tdd-winner/</link>
		<comments>http://www.zachleat.com/web/javascript-tdd-winner/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 03:58:34 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Contests]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JsTestDriver]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=923</guid>
		<description><![CDATA[Congratulations to Steve Love, who was the first to complete The JavaScript Testing Challenge. He wins a copy of Christian Johansen&#8216;s book, Test-Driven JavaScript Development. If you code for a living, testing will make your life easier. Even though the contest is over, I encourage you to go through the steps and complete the original [...]]]></description>
			<content:encoded><![CDATA[<p>Congratulations to <a href="http://twitter.com/stevelove">Steve Love</a>, who was the first to complete <a href="/web/2010/11/13/javascript-tdd/">The JavaScript Testing Challenge</a>.</p>
<p><a href="http://tddjs.com/"><img src="http://www.zachleat.com/web/wp-content/uploads/2011/02/ttdjs.png" alt="" title="ttdjs" width="300" height="386" class="alignright size-full wp-image-925" /></a>He wins a copy of <a href="http://twitter.com/cjno">Christian Johansen</a>&#8216;s book, <a href="http://tddjs.com/">Test-Driven JavaScript Development</a>.</p>
<p>If you code for a living, testing will make your life easier.  Even though the contest is over, I encourage you to go through the steps and complete the original challenge, if for no other reason than to see how easy it is to get a simple testing environment set up with JsTestDriver.</p>
<p>Stay tuned for more coding challenges!</p>
<div style="clear: both"></div>
<p>Related: <a href="/web/2011/01/09/javascript-tdd-update/">An Update to The JavaScript Testing Challenge</a></p>
<p>Here&#8217;s Steve&#8217;s screencast (using, I assume, a mechanical keyboard?):<br />
<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='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' ></param><param name='flashvars' value='i=170158' ></param><param name='allowFullScreen' value='true' ></param><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=170158' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer' ></embed></object></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/nmQq9leZw9A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/javascript-tdd-winner/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Et tu, X-UA-Compatible?</title>
		<link>http://www.zachleat.com/web/et-tu-x-ua-compatible/</link>
		<comments>http://www.zachleat.com/web/et-tu-x-ua-compatible/#comments</comments>
		<pubDate>Mon, 07 Feb 2011 05:34:14 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[User Agent Sniffing]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=889</guid>
		<description><![CDATA[Or, the story of how I learned that the X-UA-Compatible header/meta tag is NOT the same as the Internet Explorer 8+ Compatibility View button. Please note that the following information may be common knowledge, as this behavior is as described in the pre-requisite Microsoft documentation on the subject. However, I feel this behavior to be [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/jedibfa/5067647765/"><img src="http://www.zachleat.com/web/wp-content/uploads/2011/02/juliusceasar.jpg" alt="" title="Julius Ceasar" style="width: 300px" class="alignright size-full wp-image-899" /></a>Or, the story of how I learned that <strong>the X-UA-Compatible header/meta tag is NOT the same as the Internet Explorer 8+ Compatibility View button</strong>.</p>
<p><em>Please note that the following information may be common knowledge, as this behavior is as described in the pre-requisite <a href="http://blogs.msdn.com/b/ie/archive/2010/10/19/testing-sites-with-browser-mode-vs-doc-mode.aspx">Microsoft documentation</a> on the subject. However, I feel this behavior to be unintuitive and requiring more explicit communication.</em></p>
<div style="clear: both"></div>
<p>Library developers live in a much different world from full stack developers.  If you&#8217;re supplying code that will be used by others, you&#8217;re faced with a different set of priorities.  As such, the library I manage provides certain user agent sniffing conveniences, namely classes to replace CSS Hacks (similar to the approach used in HTML Boilerplate to provide ie6 through ie9 classes on the <code>&lt;html&gt;</code> tag) and JavaScript booleans (similar to <a href="http://api.jquery.com/jQuery.browser"><code>jQuery.browser</code></a>).  Much like jQuery, <a href="http://docs.jquery.com/Release:jQuery_1.3#No_More_Browser_Sniffing">these conveniences remain</a> for backwards compatibility.</p>
<p>The purpose of this post is in fact not to convince you whether or not User Agent Sniffing is a <a href="http://infrequently.org/2011/01/cutting-the-interrogation-short/">good tradeoff for performance</a> (even though, in some cases I believe it is), but instead to provide further evidence that using the User Agent alone is an unreliable method to determine the rendering engine of the web browser, and must be complemented with other approaches.  <strong>If you&#8217;re going to sniff, you have to sniff harder.</strong></p>
<h2>X-UA-Compatible Breaks navigator.userAgent</h2>
<p>Microsoft defines two terms to help communicate how new versions of Internet Explorer render a page: Browser Mode and Document Mode.  Browser Modes are determined prior to any request made to the server (and cannot be changed by web developers).  If the user triggers an IE7 Browser Mode using the Compatibility View Button, a new request is made to the server.  Document Modes are determined in the page response.</p>
<h3>Compatibility View Button Flow</h3>
<ol>
<li>User presses the Compatibility View button. This changes the Browser Mode.</li>
<li>Request sent (since the Browser Mode has changed, <strong>the User-Agent is also changed</strong> to MSIE 7.0)</li>
<li>Response from Server</li>
<li>Document Mode determined</li>
</ol>
<h3>X-UA-Compatible Flow</h3>
<ol>
<li>Internet Explorer uses the default Browser Mode (newest available in the browser)</li>
<li>Request sent (Browser Mode determines User-Agent to send, probably MSIE 8.0 or MSIE 9.0)</li>
<li>Response from Server.  Content may include X-UA-Compatible <code>&lt;meta&gt;</code> tag and/or Response HTTP headers such as X-UA-Compatible).</li>
<li>Document Mode determined, using X-UA-Compatible and the DocType</li>
</ol>
<p>If a X-UA-Compatible header is sent back in the Compatibility View flow, it will take precedence but obviously will not change the request User-Agent HTTP header.</p>
<p>It&#8217;s important to note that since the request has already gone before the Document Mode is determined, the Document Mode has no bearing on the request User-Agent HTTP header.  <del datetime="2011-11-05T19:40:06+00:00">While Microsoft probably could have changed <code>navigator.userAgent</code> to be different than the request User-Agent HTTP header, I feel they made the correct decision is keeping the same value.</del>  <code>navigator.userAgent</code> remains the same value as the request User-Agent HTTP header in IE8, but Microsoft changed this behavior in IE9. In IE9, <code>navigator.userAgent</code> represents the document mode, not the request User-Agent header.</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2011/02/Screen-shot-2011-02-06-at-1.27.14-PM.png" alt="" title="Screenshot of Microsoft Documentation" width="379" height="139" class="alignright size-full wp-image-896" />The User Agent isn&#8217;t the only thing being determined. The prerequisite Microsoft documentation states that the Browser Mode determines the User Agent, Default Document Mode, and Conditional Comments.  This is not accurate.  <strong>The Document Mode determines which Conditional Comments execute, not the Browser Mode.</strong></p>
<p>Also note that using IE&#8217;s <strong>Conditional Compilation</strong> feature to return the version of JScript will be the same, independent of Document Mode.</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">var ie = /*@cc_on @_jscript_version+@*/0;
// Always returns 5.8 in IE8, independent of Document Mode.</pre></div></div>

<p><em>Example Code from <a href="https://github.com/scottjehl/Respond/blob/aedc482328a4cbd9d74c5de178eb2cb974b67af5/respond.src.js#L171">Scott Jehl&#8217;s respond.js</a></em></p>
<h3>Test Pages</h3>
<p>Try the following tests in Internet Explorer 8+ to test for yourself.</p>
<ul>
<li><a href="/test/x-ua-compatible/index.html">Stock Page</a></li>
<li><a href="/test/x-ua-compatible/ie7.html">Setting X-UA-Compatible IE=7 using a Meta Tag</a> (or <a href="/test/x-ua-compatible/emulateie7.html">IE=EmulateIE7</a>)</li>
<li><a href="/test/x-ua-compatible/header-ie7/ie7.html">Setting X-UA-Compatible IE=7 using an HTTP Header</a> (or <a href="/test/x-ua-compatible/header-emulateie7/emulateie7.html">IE=EmulateIE7</a>)</li>
</ul>
<h2>What Does This Mean?</h2>
<p>If you use X-UA-Compatible to change the Document Mode/IE Trident rendering engine, any client side code relying on <code>navigator.userAgent</code> (such as jQuery.browser) or server side code relying on the User-Agent HTTP Header will be incorrect.  Since we can&#8217;t rely on the User Agent, what can we use?  Microsoft does provide a <code>document.documentMode</code> integer we could use, pretty easily.  But, I think there is a better approach.</p>
<p>Consider <a href="https://gist.github.com/527683">a great piece of JavaScript written by James Padosley</a> to find Internet Explorer version numbers using Conditional Comments.  His code seemed to meld perfectly with the above realization that the Document Mode determines Conditional Comment execution.  We can use this to fix <code>jQuery.browser</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// Place this script after jQuery, but before any code that uses jQuery.browser
// Modified to only test for IE 6+, since jQuery only supports 6+
(function($)
{
    if(!$.browser.msie) {
        return;
    }
&nbsp;
    var v = 5,
        div = document.createElement('div'),
        all = div.getElementsByTagName('i');
&nbsp;
    while (
        div.innerHTML = '&lt;!--[if gt IE ' + (++v) + ']&gt;&lt;i&gt;&lt;/i&gt;&lt;![endif]--&gt;',
        all[0]
    );
&nbsp;
    $.browser.version = v;
})(jQuery);</pre></div></div>

<p>Now, of course, since we&#8217;re creating nodes there is a small performance penalty in using the above script over Regular Expressions and document.documentMode.  I feel this to be worthwhile, given that I&#8217;ve been <a href="/web/2008/10/19/jquery-bug-ie-reports-incorrect-browserversion/">burned by Internet Explorer&#8217;s version number before</a>.  But next time, I reserve the right to choose performance over simplicity.</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/XuRQQpzi2Hg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/et-tu-x-ua-compatible/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>BigText Makes Text Big</title>
		<link>http://www.zachleat.com/web/bigtext-makes-text-big/</link>
		<comments>http://www.zachleat.com/web/bigtext-makes-text-big/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 02:49:35 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Typography]]></category>
		<category><![CDATA[3D Transforms]]></category>
		<category><![CDATA[BigText]]></category>
		<category><![CDATA[contenteditable]]></category>
		<category><![CDATA[Flexbox]]></category>
		<category><![CDATA[font-face]]></category>
		<category><![CDATA[jQuery UI]]></category>
		<category><![CDATA[Throttle]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=838</guid>
		<description><![CDATA[I like shortcuts:]]></description>
			<content:encoded><![CDATA[<p><em style="font-size: 90%">I like shortcuts: <a href="https://github.com/zachleat/BigText"">Fork BigText on Github</a> or <a href="/bigtext/demo/">Check out the BigText Demo Wizard</a></em></p>
<p>It all began with a simple web foray to <a href="http://designingmonsters.com/">Designing Monsters</a>.  Their simple, typographic design was beautiful. But why? Their combination of the beautiful League Gothic font, use of <a href="http://letteringjs.com/">Lettering.JS</a>, and some simple font scaling gave the page a wonderful consistent vertical alignment. Like the Million Dollar Homepage, I wanted to rebuild it &#8212; but I didn&#8217;t want to spend a lot of time manually adjusting font sizes. So I did what any programmer with the jQuery Golden Hammer would do, I turned my problem into a nail.</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2011/01/Screen-shot-2011-01-11-at-7.37.54-PM.png" alt="" title="The elusive BIGTEXT plugin exclusively caputured on film" width="287" height="332" class="alignright size-full wp-image-843" /><br />
At it&#8217;s simplest, the BigText jQuery plugin takes a single element and <strong>sizes the text inside of its child <code>&lt;div&gt;</code>s to fit the width of the parent elemen</strong>t.  Gives the text that lovely vertical alignment.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;div id=&quot;bigtext&quot; style=&quot;width: 300px&quot;&gt;
    &lt;div&gt;The elusive&lt;/div&gt;
    &lt;div&gt;BIGTEXT&lt;/div&gt;
    &lt;div&gt;plugin exclusively&lt;/div&gt;
    &lt;div&gt;captured on film&lt;/div&gt;
&lt;/div&gt;</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">$('#bigtext').bigtext();</pre></div></div>

<p>See <a href="http://jsfiddle.net/zachleat/WzN6d/">the above at JSFiddle</a>.</p>
<h3>Implementation Details</h3>
<p>The plugin itself is more than just a simple font-size incrementer.  I wasn&#8217;t happy with the performance of simply iterating through font sizes with a single fixed interval.  I decided it would be better to test multiple decreasing intervals.  For each line, it increments first by 16em until it detects a line break, backs off an interval then increments by <code>8em</code>. It continues with <code>4em</code>, <code>2em</code>, <code>1em</code>, <code>0.1em</code>, until it finds the correct <code>font-size</code> to the nearest hundredth of an em.  It&#8217;s noteworthy that Webkit does not respect font-sizes to the nearest hundredth, it&#8217;s precision is maxed out at tenths.  This algorithm results in fewer tests in most cases, especially where the resulting font-size will be very large. Performance is always important. After font-size, it moves to word-spacing as a backup for extra precision, especially needed on Webkit.</p>
<h2><em>The BigText Demo Wizard</em></h2>
<h3 style="text-align: center"><a href="/bigtext/demo/">Check out the Demo</a></h3>
<p>This is where the magic happens.</p>
<ul>
<li>Editable text (<code>contenteditable</code>), and BigText will run on every keyup event to resize what you&#8217;re typing.</li>
<li>Dynamic horizontal and vertical centering using <a href="http://infrequently.org/2009/08/css-3-progress/">Alex Russell&#8217;s Flex Box CSS classes</a> (This is easy now, hooray!)</li>
<li>3D transforms (browser support checked using <a href="http://www.modernizr.com/">Modernizr</a>, currently only available in Safari. Note: Chrome flattens to 2D space)</li>
<li>Custom fonts are loaded using <a href="http://code.google.com/apis/webfonts/docs/webfont_loader.html">Google&#8217;s Font Loader JavaScript API</a></li>
<li><a href="http://benalman.com/projects/jquery-throttle-debounce-plugin/">Ben Alman&#8217;s Throttle Plugin</a></li>
<li>The rest is mostly jQuery UI with the <a href="http://taitems.tumblr.com/post/482577430/introducing-aristo-a-jquery-ui-theme">Aristo theme</a></li>
</ul>
<p>Turns out, the <em>BigText Demo Wizard</em> makes for really easy <a href="http://vimeo.com/channels/kinetictypography">Kinetic Typography</a> screencasts (not amazing, but surely easy):</p>
<p><iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/OuqB6e6NPRM" frameborder="0"><br />
</iframe></p>
<p>The above is simply the manual process of typing lyrics into the <em>BigText Demo Wizard</em>.  You can easily make one of these too, with the help of the following keyboard shortcuts:</p>
<ul style="font-size: 90%">
<li>CTRL + ALT + X: Set the text to a random 3D transform angle.</li>
<li>CTRL + ALT + C: Toggles between white and black background.</li>
<li>CTRL + ALT + R: Reset 3D to default state.</li>
<li><strong>CTRL + ALT + SPACE: Fade out current text, clears the text, sets a random 3D transform angle, ready to type!</strong></li>
<li>CTRL + ALT + ENTER: Same as CTRL + ALT + SPACE, but keeps the same 3D transform angle.</li>
</ul>
<p>The fun part about the <em>BigText Demo Wizard</em> for me was that it almost turned into a non-musical instrument when I used it real-time to complement music.  Feel free to cruise Pandora and type lyrics to the music until your wrists get sore. <strong>What can you make with it?</strong></p>
<p><em>The BigText Demo Wizard was tested manually in Safari 5, Chrome 8, Opera 11, Firefox 3.6, and Internet Explorer 8.  The BigText jQuery plugin has a full JsTestDriver suite, available on <a href="https://github.com/zachleat/BigText">GitHub</a>.  Just run <code>./test.sh</code> or <code>test.bat</code></em></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/n9RfsZEOq4w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/bigtext-makes-text-big/feed/</wfw:commentRss>
		<slash:comments>65</slash:comments>
		</item>
		<item>
		<title>An Update to The JavaScript Testing Challenge</title>
		<link>http://www.zachleat.com/web/javascript-tdd-update/</link>
		<comments>http://www.zachleat.com/web/javascript-tdd-update/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 02:48:12 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Contests]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JsTestDriver]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=832</guid>
		<description><![CDATA[Update: The JavaScript Testing Challenge Winner In The JavaScript Testing Challenge, I asked JavaScript developers of the world to change their heathen ways and embrace the future of automated testing for a healthier and brighter tomorrow. However, due to seasonal timing or otherwise real life related reasons, the challenge was greeted with a worldwide chorus [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Update</strong>: <a href="/web/2011/02/14/javascript-tdd-winner/">The JavaScript Testing Challenge Winner</a></em></p>
<p>In <a href="/web/2010/11/13/javascript-tdd/">The JavaScript Testing Challenge</a>, I asked JavaScript developers of the world to change their heathen ways and embrace the future of automated testing for a healthier and brighter tomorrow.</p>
<p>However, due to seasonal timing or otherwise real life related reasons, the challenge was greeted with a worldwide chorus of universally blank stares.  So, in the true spirit of Christmas, I&#8217;m removing the deadline and <strong>will award the grand prize to the developer with the first correct and complete PrimeFactors code kata screencast</strong>.  That&#8217;s right, be the first to answer the challenge will win a copy of Test-Driven JavaScript Development by Christian Johansen (PDF or Print version, your choice).</p>
<p>If you have any questions or need help getting started, let me know! I&#8217;d be glad to help. Good luck!</p>
<div style="font-size: 90%"><em>Time of entry will be based on the twitter at message sent to @zachleat.  Full restrictions and rules posted <a href="/web/2010/11/13/javascript-tdd/">here</a>.</em></div>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/FvulT8FVcxQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/javascript-tdd-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The JavaScript Testing Challenge</title>
		<link>http://www.zachleat.com/web/javascript-tdd/</link>
		<comments>http://www.zachleat.com/web/javascript-tdd/#comments</comments>
		<pubDate>Sat, 13 Nov 2010 21:10:16 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Contests]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Code Kata]]></category>
		<category><![CDATA[JsTestDriver]]></category>
		<category><![CDATA[QUnit]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=773</guid>
		<description><![CDATA[Update 2: The JavaScript Testing Challenge Winner Update: An Update to The JavaScript Testing Challenge Think back to the last time you wrote new code from scratch. Not autogenerated Dreamweaver image hovers or a pasted script from Dynamic Drive, but pure unadulterated new code. What was your process? I&#8217;m betting it&#8217;s probably similar to: (1) [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Update 2</strong>: <a href="/web/2011/02/14/javascript-tdd-winner/">The JavaScript Testing Challenge Winner</a></em></p>
<p><em><strong>Update</strong>: <a href="/web/2011/01/09/javascript-tdd-update/">An Update to The JavaScript Testing Challenge</a></em></p>
<p>Think back to the last time you wrote new code from scratch. Not autogenerated Dreamweaver image hovers or a pasted script from Dynamic Drive, but pure unadulterated new code. What was your process? I&#8217;m betting it&#8217;s probably similar to: (1) code, (2) switch to a browser, (3) confirm desired behavior for the change you&#8217;ve made, and (4) repeat.</p>
<p>Comrades, let me assure you that there is a better way, and it starts with writing unit tests. As a Front End Engineer that&#8217;s been doing it bareback without tests since I started in 1997, let me assure you that adopting automated testing strategies is one of the <strong>single best changes I&#8217;ve made to my development cycle</strong> to make myself more productive. Enough fluff. Let&#8217;s get started!</p>
<h2>Testing Environment Setup in 3 Steps</h2>
<p>Prerequisite: Java on the classpath</p>
<ol>
<li>Download the <a href="https://github.com/zachleat/JavaScript-Code-Katas/zipball/master">JavaScript-Code-Katas Source (ZIP)</a> (or checkout the code from the <a href="https://github.com/zachleat/JavaScript-Code-Katas">Github Repository</a>, if you have git available)</li>
<li>Extract and browse to it using your operating system&#8217;s command line.</li>
<li>Run (Windows)<br />
<code>&gt; JsTestDriver.bat Template</code></p>
<p>Run (MacOS)<br />
<code>$ ./JsTestDriver.sh Template</code><br />
<em>This script will close Safari (be careful if you&#8217;re using Safari in other windows)</em>
</li>
</ol>
<p>If a web browser popped up on your screen, congratulations! You have an automated testing environment set up and running.  Easy, right?</p>
<h2>Writing a Test</h2>
<p>Now, let&#8217;s write our first test!</p>
<ol>
<li>Open up <code>templateTest.js</code> in your favorite IDE.</li>
<li>Add the following:

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">TemplateTest = TestCase('TemplateTest');
TemplateTest.prototype.testSample = function()
{
    assertTrue(true);
    assertFalse(false);
    assertEquals(true, true);
};</pre></div></div>

</li>
<li>Re-run the JsTestDriver shell script from Step #3 above.</li>
</ol>
<p>Now you should see something like the following:</p>
<pre>
Total 1 tests (Passed: 1; Fails: 0; Errors: 0) (2.00 ms)
  Safari 533.18.5 Mac OS: Run 1 tests (Passed: 1; Fails: 0; Errors 0) (2.00 ms)
</pre>
<p><strong>Notice how you didn&#8217;t have to touch any HTML boilerplate code or manually bring up a web browser?</strong> Productivity ensues! You&#8217;ve made it this far, are you brave enough to dive into a Code Kata?</p>
<h2>Prime Factors Code Kata</h2>
<p>Code Katas are just small programs used as practice.  They&#8217;re a great way to introduce Test Driven Development and improve proficiency with your IDE.</p>
<p>The Prime Factors Code Kata requires a function that takes a single integer argument and returns an array of prime factors of that argument in ascending numerical order.  For example, passing in <code>8</code> should return <code>2, 2, 2</code>.</p>
<ul>
<li><a href="https://docs.google.com/present/edit?id=0AVz1CG9ZSGbWZG5iajc4c18zN2R2NzJnZmRq&#038;hl=en&#038;authkey=CO38t6gL">Original Java version by Uncle Bob Martin</a> (see <a href="http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata">original post</a>).</li>
<li><a href="https://github.com/zachleat/JavaScript-Code-Katas/blob/master/PrimeFactors/primeFactors.js">JavaScript implementation of the Prime Factors algorithm</a></li>
</ul>
<p>I&#8217;ve recorded an unmodified single-take screencast of myself performing the kata below. I&#8217;m using the same source code I provided above, but with the <a href="http://code.google.com/p/js-test-driver/wiki/UsingTheEclipsePlugin">JsTestDriver Eclipse plugin</a> instead of using the command line to run the tests.  The plugin is great for the screencast, because it very easily shows when the tests are failing or passing. You might also notice that it reruns the tests automatically every time I save.</p>
<p><object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/zsCYkmAJBAY?fs=1&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/zsCYkmAJBAY?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object></p>
<h2>JsTestDriver</h2>
<p>If you want to learn more a about JsTestDriver, check out their <a href="http://code.google.com/p/js-test-driver/">Google Code</a> page.  &#8220;But I use QUnit!&#8221; you say. That&#8217;s fine, <a href="http://code.google.com/p/js-test-driver/wiki/QUnitAdapter">there is an adaptor for that</a>.  Using both tools together, you won&#8217;t need to launch each individual browser manually and trigger the tests to start.  It will save you time.</p>
<div style="font-size: 90%">
In the interest of full disclosure, here are the issues I&#8217;ve ran into so far using JsTestDriver:</p>
<ul>
<li>Doesn&#8217;t apply CSS in some browsers. <a href="http://code.google.com/p/js-test-driver/issues/detail?id=81">Issue #81</a></li>
<li>Defaults to quirks mode. <a href="http://code.google.com/p/js-test-driver/issues/detail?id=79">Issue #79</a></li>
</ul>
</div>
<h2 id="challenge">Challenge</h2>
<p>Testing will help you. It will improve your the quality of your code and your productivity. I challenge you to practice the JavaScript Prime Factors Code Kata in your own IDE with your own automated testing process. Send a link to  me on Twitter (<a href="http://twitter.com/zachleat">@zachleat</a>) with an unmodified single-take screencast of you performing the kata (in JavaScript) by December 25, 2010 and <strong>the fastest kata screencast will win a copy of <a href="http://tddjs.com/">Test-Driven JavaScript Development</a></strong> by <a href="http://twitter.com/cjno/">Christian Johansen</a> (PDF or Print version, your choice*).</p>
<p><a href="http://screenr.com/">Screenr</a> is a great tool for recording screencasts, if you need one.</p>
<p>Good luck!</p>
<div style="font-size: 90%"><em>Coding must follow every step performed by myself in the above version. Templates and keyboard shortcuts can be used at your leisure, but no code can be generated specific to the kata itself (it must be a generic).  Use your best judgement here, I reserve the right to disqualify any entries submitted that don&#8217;t follow the true spirit of the competition.</p>
<p>Don&#8217;t fuck with the speed of the video. I&#8217;m spending my own money on this, so if you&#8217;re cheating then you&#8217;re just stealing from me. Just be cool about it, okay?</p>
<p>* The Print version of the prize is restricted to USA or Canada, PDF version is available internationally (unless you want to work something out for shipping costs).</em></div>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/PUzJb37Fg98" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/javascript-tdd/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Faking Onload for Link Elements</title>
		<link>http://www.zachleat.com/web/load-css-dynamically/</link>
		<comments>http://www.zachleat.com/web/load-css-dynamically/#comments</comments>
		<pubDate>Fri, 30 Jul 2010 01:50:24 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=733</guid>
		<description><![CDATA[Updated 2011/09/27: Rejoice! This issue has now been fixed in Firefox. Or, I Am Dynamically Loaded CSS (and So Can You!) Dynamic resource loading is one of the keys to have a performance happy web application. There are generally three different criteria we must address when making a request: cross domain security policies, asynchronous/synchronous (will [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Updated 2011/09/27: Rejoice! This issue has now <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=185236">been fixed in Firefox</a>.</strong></p>
<hr/>
<p>Or, <strong>I Am Dynamically Loaded CSS (and So Can You!)</strong></p>
<p>Dynamic resource loading is one of the keys to have a performance happy web application.  There are generally three different criteria we must address when making a request: cross domain security policies, asynchronous/synchronous (will it block the host page while loading), and whether or not events are triggered when the request completes.</p>
<p>If the resource and host page are on the same domain, obviously <code>XMLHttpRequest</code> works the best.  We can control whether or not the resource is loaded asynchronously or synchronously, and we know exactly when it gets done.</p>
<p>If the resource and host page are on different domains (increasingly more common with CDN&#8217;s), our options narrow. Loading the JavaScript is a solved problem, just use the <code>onload</code> event on the <code>&lt;script&gt;</code> tag and you&#8217;re good to go (<code>onreadystatechange</code> for IE).  But CSS is more complicated.</p>
<table>
<thead>
<tr>
<th>Resource</th>
<th>Method</th>
<th>Option for (a)synchronous</th>
<th>Event</th>
</tr>
</thead>
<tbody>
<tr>
<td>JavaScript/CSS Same Domain</td>
<td><code>XMLHttpRequest</code></td>
<td>Both</td>
<td><code>onreadystatechange</code></td>
</tr>
<tr>
<td>JavaScript Different Domain</td>
<td><code>&lt;script&gt;</code></td>
<td>Synchronous (Asynchronous where <a href="https://developer.mozilla.org/en/html/element/script">async property</a> is supported)</td>
<td><code>onload</code><br />
<code>onreadystatechange</code> for IE</td>
</tr>
<tr>
<td>CSS  Different Domain</td>
<td><code>&lt;link&gt;</code></td>
<td>Asynchronous</td>
<td><em>What this blog post is about.</em></td>
</tr>
</tbody>
</table>
<h2>Existing Solutions</h2>
<p>In all of the library source code I evaluated, Internet Explorer didn&#8217;t cause any issues.  It fires both the <code>onload</code> and <code>onreadystatechange</code> events for <code>&lt;link&gt;</code> nodes.  Obviously this is ideal behavior, and IE got it right. But what about Firefox and Safari/Chrome?</p>
<h3>YUI 2.8.1 and 3.1.1</h3>
<p><a href="http://github.com/yui/yui3/blob/master/build/yui/get.js#L311">Original Source</a></p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// FireFox does not support the onload event for link nodes, so there is
// no way to make the css requests synchronous. This means that the css 
// rules in multiple files could be applied out of order in this browser
// if a later request returns before an earlier one.  Safari too.
if ((ua.webkit || ua.gecko) &amp;&amp; q.type === &quot;css&quot;) {
    _next(id, url);
}</pre></div></div>

<p>I wouldn&#8217;t be surprised if the commit log there was from Bon Jovi; that code is living on a prayer.</p>
<h3>LazyLoad</h3>
<p><a href="http://github.com/rgrove/lazyload/blob/master/lazyload.js#L283">Original Source</a></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Gecko and WebKit don't support the onload event on link nodes. In</span>
<span style="color: #006600; font-style: italic;">// WebKit, we can poll for changes to document.styleSheets to figure out</span>
<span style="color: #006600; font-style: italic;">// when stylesheets have loaded, but in Gecko we just have to finish</span>
<span style="color: #006600; font-style: italic;">// after a brief delay and hope for the best.</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>ua.<span style="color: #660066;">webkit</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    p.<span style="color: #660066;">urls</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> node.<span style="color: #660066;">href</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// resolve relative URLs (or polling won't work)</span>
    poll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    setTimeout<span style="color: #009900;">&#40;</span>_finish<span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span> <span style="color: #339933;">*</span> len<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Better, closer, warmer.  This includes a nice method for working with webkit browsers.  The poll method compares <code>document.styleSheets</code>, since Webkit has the nice option of only appending to the styleSheets object when the styleSheet has successfully loaded.</p>
<p>So we have working solutions for IE and Safari/Chrome. The only unsolved piece of the puzzle here is Firefox.</p>
<p><a href="http://wonko.com/post/how-to-prevent-yui-get-race-conditions">This post</a> from the same author as LazyLoad also describes another solution which involves modifying the source CSS and polling against it.  But that&#8217;s not really ideal. Can we do better?</p>
<h2>Solution</h2>
<p>Here&#8217;s what I came up with (using jQuery for brevity, note that this solution <strong>only fixes Firefox</strong>, and does not incorporate the above already solved solutions):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> url <span style="color: #339933;">=</span> <span style="color: #3366CC;">'css.php'</span><span style="color: #339933;">,</span>
    id <span style="color: #339933;">=</span> <span style="color: #3366CC;">'dynamicCss'</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;style/&gt;'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    id<span style="color: #339933;">:</span> id<span style="color: #339933;">,</span>
    type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'text/css'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'@import url('</span> <span style="color: #339933;">+</span> url <span style="color: #339933;">+</span> <span style="color: #3366CC;">')'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'head'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> poll<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;">try</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> sheets <span style="color: #339933;">=</span> document.<span style="color: #660066;">styleSheets</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> k<span style="color: #339933;">=</span>sheets.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> j<span style="color: #339933;">&lt;</span>k<span style="color: #339933;">;</span> j<span style="color: #339933;">++</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>sheets<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">ownerNode</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">==</span> id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                sheets<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">cssRules</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #006600; font-style: italic;">// If you made it here, success!</span>
        <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'success!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">catch</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;">// Keep polling</span>
        window.<span style="color: #660066;">setTimeout</span><span style="color: #009900;">&#40;</span>poll<span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
window.<span style="color: #660066;">setTimeout</span><span style="color: #009900;">&#40;</span>poll<span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3><a href="http://zachleat.com/javascript/loadcss/load.html">See this demo in action.</a> (Firefox only)</h3>
<p><br/><br />
<strong>Update</strong>: After much joy and celebration, I have discovered that an approach similar to the above was written by Oleg Slobodskoi in his <a href="http://plugins.jquery.com/files/jquery.xLazyLoader.js.txt">xLazyLoader</a> plugin for jQuery.  It shouldn&#8217;t be surprising that two independent developers might reach the same solution, and is just more proof that software patents are stupid. :)</p>
<p><strong>Update #2</strong> Added note about HTML5 async property on script tags.</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/fnv4r5UoREI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/load-css-dynamically/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ALARMd is now on Github</title>
		<link>http://www.zachleat.com/web/alarmd-is-now-on-github/</link>
		<comments>http://www.zachleat.com/web/alarmd-is-now-on-github/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 01:47:40 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[Alarmd]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Github]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=726</guid>
		<description><![CDATA[In an effort to mindlessly copy what everyone else on the internet is doing keep current on the latest and greatest Source Code Management tools, I decided that it would be good practice to move my open source project ALARMd (as seen on Lifehacker) from Google Code to Github. Feel free to fork/contribute at your [...]]]></description>
			<content:encoded><![CDATA[<p>In an effort to <del datetime="2010-07-22T00:54:05+00:00">mindlessly copy what everyone else on the internet is doing</del> keep current on the latest and greatest Source Code Management tools, I decided that it would be good practice to move my open source project ALARMd (as seen on <a href="http://lifehacker.com/271043/wake-up-to-a-youtube-video-with-alarmd">Lifehacker</a>) from <a href="/web/2008/10/08/alarmd-is-a-google-code-project/">Google Code</a> to Github.</p>
<p>Feel free to fork/contribute at your leisure.<br />
<a href="http://github.com/zachleat/ALARMd">http://github.com/zachleat/ALARMd</a></p>
<p>If you&#8217;re new, you can check out <a href="http://www.alarmd.com/">ALARMd.com</a> to see what I&#8217;m talking about.</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/PNeINiLAWGw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/alarmd-is-now-on-github/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Maiden Voyage of the DOM Sailbloat</title>
		<link>http://www.zachleat.com/web/dom-sailbloat/</link>
		<comments>http://www.zachleat.com/web/dom-sailbloat/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 04:09:28 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[DOM]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Firebug Lite]]></category>
		<category><![CDATA[log4javascript]]></category>
		<category><![CDATA[YUI Logger]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=698</guid>
		<description><![CDATA[As many of you may already know, my day job includes managing a large and complex enterprise jQuery-based user interface component library. It&#8217;s used by all new web applications at the company, which boasts over an IT department of approximately 1500 people and hundreds of web applications. Needless to say, I get a fair volume [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.zachleat.com/web/wp-content/uploads/2010/07/typhoon-in-macao.jpg" alt="" title="typhoon-in-macao" width="680" height="503" class="aligncenter size-full wp-image-710" /></p>
<p>As many of you may already know, my day job includes managing a large and complex enterprise jQuery-based user interface component library. It&#8217;s used by all new web applications at the company, which boasts over an IT department of approximately 1500 people and hundreds of web applications.  Needless to say, I get a fair volume of interesting support tickets that come my way.  A few weeks ago, I had the pleasure of receiving one such ticket.</p>
<p>The support ticket&#8217;s symptoms included a oft-heard complaint: poor performance.  On the web, poor performance can be attributed to a great many things, but most often can be boiled down to a bottleneck in JavaScript code using the DOM API.  This time, strangely enough, the culprit was something else entirely.</p>
<p>One of the first things I check when an application complains of poor performance is the total size of the document, or how many nodes it has.  One of the best ways to ensure good performance is to keep your document small, especially on projects using heavy dynamic element selection and filtering (think jQuery, Mootools, Prototype, Dojo, or any code using a selector engine like Sizzle).  Any JavaScript library emulating CSS selectors executing over a very large document is going to take quite a bit longer than querying a small document, especially when the user&#8217;s browser doesn&#8217;t support native <code>querySelector</code> or <code>getElementsByClassName</code>.</p>
<p>To get an idea of what the size of a large document is, I usually go to a site with some fairly advanced JavaScript and query their size.</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// Returns the total number of nodes in the document
document.getElementsByTagName('*').length;
// note: this number will not include any child nodes inside of iframes.</pre></div></div>

<table>
<thead>
<tr>
<th>URL</th>
<th>Total Element Count</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>maps.google.com</code></td>
<td><code>731</code></td>
</tr>
<tr>
<td><code>my.yahoo.com</code></td>
<td><code>1508</code></td>
</tr>
<tr>
<td><code>calendar.google.com (Authenticated)</code></td>
<td><code>681</code></td>
</tr>
<tr>
<td><code>reader.google.com (Authenticated)</code></td>
<td><code>4866</code></td>
</tr>
</tbody>
</table>
<p>Getting back to the support ticket in question.  After querying the document, I quickly found that the page contained over <strong>50000 nodes</strong>.  Wow.  So, we&#8217;ve caught a big one.  You&#8217;re going to be telling your grandkids about this some day.  But, now what?</p>
<p>I decided it would be beneficial to find out where and what all of those nodes were.  After clicking around the live document in the Firebug&#8217;s HTML tab for awhile, looking at View Source, and Ajax requests in the Console, I successfully determined the culprit.  This particular application was using <a href="http://wicket.apache.org/">Wicket</a>, a popular Java library for web applications, which includes its own <em>Ajax Logger</em> component (similar to my favorite <a href="http://log4javascript.org/">log4javascript</a>; or something like the <a href="http://developer.yahoo.com/yui/logger/">YUI Logger</a>), used to keep track of an application&#8217;s Ajax calls and JavaScript page manipulations with an inline GUI embedded in the parent document.  On one page load, this application&#8217;s Ajax logger component had <strong>created 40000 nodes of log content</strong>.</p>
<p>It&#8217;s important to realize that embedding unnecessary content of that magnitude on the page can be very detrimental to performance. <strong>JavaScript loggers should log to a new child window, rather than be embedded in the parent document.</strong>  This way they won&#8217;t bloat the document, but still provide you with much needed logging information.</p>
<p>But, in the future, how might this type of problem be more easily diagnosed and prevented?  Ideally, when confronted with large documents, we want to see where in the document the majority of those nodes are located.  But there isn&#8217;t an easy way to see which portion of the document is using the largest number of nodes, especially if the culprit is deep into the document tree.  We can go through the source code manually, but that isn&#8217;t  very efficient.</p>
<p>So in the spirit of exploratory development to help troubleshoot real-world problems, I decided to make a Firebug Lite plugin.  This would give me an easy cross-browser tool to diagnose my problem in a familiar interface.  Load up Firebug Lite, load the <em>DOM Sailbloat</em> JavaScript file, and easily spot the HTML love handles.</p>
<p>Here&#8217;s what it looks like in action:<br />
<img src="http://www.zachleat.com/web/wp-content/uploads/2010/07/Screen-shot-2010-07-19-at-9.59.49-PM.png" alt="" title="Screen shot of the DOM Sailbloat Firebug Lite plugin" class="aligncenter size-full wp-image-714" /></p>
<h2>Go Forth</h2>
<ol>
<li><a href="http://www.zachleat.com/domsailbloat/">See the demo</a></li>
<li><a href="http://www.zachleat.com/domsailbloat/domsailbloat.js">Download the source</a></li>
<li><a href="http://github.com/zachleat/DOM-Sailbloat">Fork the Sailbloat on GitHub</a></li>
</ol>
<p><em>Note: there is currently an undiagnosed issue with the Sailbloat and it fails to load intermittently.  If you know why, I&#8217;d be happy to put your name in the source code credits.</em></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/hxL1ltMzdA4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/dom-sailbloat/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Race Against Time Pickers</title>
		<link>http://www.zachleat.com/web/a-race-against-time-pickers/</link>
		<comments>http://www.zachleat.com/web/a-race-against-time-pickers/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 23:57:25 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Interface Design]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[Usability]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=633</guid>
		<description><![CDATA[The Date Picker component is one of the most popular user interface components on the web today. Its operation is very simple: focus into a field (sometimes a click on a dedicated calendar button is required) intended to contain a specific date and an on-screen calendar will be shown next to the form field, allowing [...]]]></description>
			<content:encoded><![CDATA[<p>The Date Picker component is one of the most popular user interface components on the web today.  Its operation is very simple: focus into a field (sometimes a click on a dedicated calendar button is required) intended to contain a specific date and an on-screen calendar will be shown next to the form field, allowing the user to click on a specific date to populate the form field.</p>
<p><a href="http://www.zachleat.com/web/wp-content/uploads/2010/06/Screen-shot-2010-06-01-at-8.57.37-PM.png"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/Screen-shot-2010-06-01-at-8.57.37-PM.png" alt="" title="Date Picker Component" width="314" height="235" class="alignnone size-full wp-image-640" /></a></p>
<p>Date Pickers are helpful components that are useful for a couple of reasons:</p>
<ol>
<li>They allow you to easily <strong>map an existing real-world mental model</strong> (the Calendar) to form input (a text field). This provides <strong>additional context</strong> beyond what the simple string value of a date represents: days of the week, Calendar month labels, leap year information.</li>
<li>They allow for more usable and actionable data restrictions and error feedback.  Want the user to select a weekday?  Just show them on the calendar which days are available.</li>
<li>Visual cue as to what the form field&#8217;s data format should be.  If a calendar icon is next to the form field, it becomes very obvious what kind of data the user should put into the field.</li>
</ol>
<p>Now, the last two reasons are all well and good, but carry no intrinsic incentive for the user to actually click on and use the Date Picker component.  <strong>The first reason is what actually motivates a user</strong> to bring up the Date Picker and select a date on it.</p>
<p>Now, consider the following Time Picker component, popularized by <a href="http://ejohn.org/blog/picking-time/">a John Resig blog post</a>:<br />
<a href="http://haineault.com/media/jquery/ui-timepickr/page/"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/Screen-shot-2010-06-06-at-3.28.22-PM.png" alt="" title="Time Picker Example #2" width="462" height="128" class="alignnone size-full wp-image-642" /></a></p>
<p>Comparing to the Date Picker component above, one could easily make the argument that it offers little to <strong>no incentive over simple keyboard input</strong>.  It offers no additional context, extra data, or an existing physical mental model for the user to associate with.  The only advantage it might offer is an easy calculator for those unfamiliar with 24-hour (military) time.  I would argue that placing the AM/PM selection at the beginning of the selection creates a reversal of the closest established mental model a person typically uses to represent a time: the digital clock (hours, minutes, seconds, and AM/PM at the end).</p>
<div style="font-style:italic; font-size: 86%; width: 400px; margin: auto;">
Here&#8217;s a sampling of some other time picker implementations:</p>
<p><a href="http://pttimeselect.sourceforge.net/example/index.html"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/pttimeselect.png" alt="" title="Another Time Picker" width="271" height="239" class="alignnone size-full wp-image-670" /></a><br />
This implementation is very similar to the first example, just organized differently.  We can do better.</p>
<p><a href="http://www.pit-r.de/timepicker/demo/pickerDemo.htm"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/picker.png" alt="" title="Yet Another Time Picker, Two Analog Clocks, one for hours and one for minutes" width="294" height="203" class="alignleft size-full wp-image-674" /></a></p>
<div style="clear: both"></div>
<p>Reading an analog clock isn&#8217;t the problem.  When we think of time, we start with numeric representations of the hours and minutes.  The first thing that pops into the average person&#8217;s head when they hear &#8220;6:00 PM&#8221; probably isn&#8217;t: the little hand on the 6 and the big hand on the 12.  The analog clock representation is <strong>a mental hurdle</strong>.</p>
<p><a href="http://www.zachleat.com/web/wp-content/uploads/2010/06/timedatepicker.png"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/timedatepicker.png" alt="" title="A simple time picker" width="108" height="230" class="alignnone size-full wp-image-679" /></a><br />
Now we&#8217;re getting closer.  The user selects a full representation of the time, not just the last piece of the puzzle.  I like the intuitive and simple organization of this time picker.  You know immediately what you&#8217;re selecting.  I think we can organize the times a little bit better though, give them a visual hierarchy.</p>
<p><a href="http://www.jnathanson.com/index.cfm?page=jquery/clockpick/ClockPick#demog"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/clockpick.png" alt="" title="Yet Another Time Picker" width="146" height="123" class="alignnone size-full wp-image-672" /></a><br />
This picker represents more of the spirit of what we&#8217;re looking for.  It shows a simple list of the hourly options and progressively discloses the minute selections.  I think switching to a single column layout would be more intuitive for keyboard navigation (combining the above two implementations into one super-component) and would do well with larger click targets.
</div>
<p>These implementation examples speak to a larger trend of front end engineers that concentrate too much on code optimization and cross browser compatibility, and <strong>not enough on usability and user driven design</strong>.  It&#8217;s an easy trap to fall prey to, but one we must be wary of.  A Time Picker might offer benefit in terms of data restriction (e.g.: select an hour in the range of a normal workday), but it does very little for the efficiency and usability of data entry.  So, before you start putting Time Pickers on all of your forms, make sure the Time Picker you add represents something like this:</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/ISPKA4134_large.jpg" alt="" title="Digital Clock" width="320" height="320" class="alignnone size-full wp-image-691" /></p>
<p>and not this:</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/Screen-shot-2010-06-06-at-4.04.50-PM.png" alt="" title="Onscreen Keyboard" width="489" height="176" class="alignnone size-full wp-image-646" /></p>
<ol style="font-size:70%; font-style:italic;">
Image Sources:</p>
<li><a href="http://www.tesora.com.au/Digibell_Retro_Alarm_Clock_.htm">tesora.com.au</a></li>
<li><a href="http://www.codeproject.com/">codeproject.com</a></li>
</ol>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/_HzOee0d_cM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/a-race-against-time-pickers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Point, Charset, Match: Character Encoding in JavaScript</title>
		<link>http://www.zachleat.com/web/charset/</link>
		<comments>http://www.zachleat.com/web/charset/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 00:16:47 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Character Encoding]]></category>
		<category><![CDATA[Closure Compiler]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=589</guid>
		<description><![CDATA[If you&#8217;re not familiar with the principles of character encoding, read the prerequisite Dive Into HTML 5 section on the subject. When you see issues with Character Encoding, it&#8217;s traditionally in the form of text on your page that looks like this: in Firefox or in IE. Usually, those characters mean that the character encoding [...]]]></description>
			<content:encoded><![CDATA[<p><em>If you&#8217;re not familiar with the principles of <strong>character encoding</strong>, read the prerequisite <a href="http://diveintohtml5.org/semantics.html#encoding">Dive Into HTML 5 section</a> on the subject.</em></p>
<p>When you see issues with Character Encoding, it&#8217;s traditionally in the form of text on your page that looks like this: <img src="http://www.zachleat.com/web/wp-content/uploads/2010/03/unencoded.png" alt="" title="unencoded" width="16" height="19" class="size-full wp-image-593" style="vertical-align: bottom; margin-bottom: 0" /> in Firefox or <img src="http://www.zachleat.com/web/wp-content/uploads/2010/03/unencoded-ie.png" alt="" title="unencoded-ie" width="11" height="14" class="size-full wp-image-592" style="vertical-align: bottom; margin-bottom: 0" /> in IE.</p>
<p>Usually, those characters mean that the character encoding used on the page is either ambiguous (not specified), or incorrect.  We can use Firefox to determine that Character Encoding of a web page (Right Click and go to View Page Info; or use the &#8220;Character Encoding&#8221; entry in the View menu).  Check to make sure that the encoding reported by Firefox is the same encoding used in your IDE.  For example, Eclipse 3.5 has a &#8220;Set Encoding&#8221; option in the Edit menu.</p>
<p>The reason most English alphabetic and numeric characters are consistent independent of character encoding is due to consistency in the lower characters in each encoding.  The characters making up the <a href="http://www.asciitable.com/">ASCII character set</a> (0-127) are the same as the lowest 128 characters of <a href="http://en.wikipedia.org/wiki/ISO/IEC_8859-1#ISO-8859-1">ISO-8859-1</a>, <a href="http://www.utf8-chartable.de/">UTF-8</a>, and others.</p>
<p>Managing your character encodings gets trickier as you add more architectural layers to your application.  For example, character encodings may differ in your database, the properties files used to configure your application (java.util.Properties uses ISO-8859-1 by default), or maybe the XML or JSON file you&#8217;re loading from an external API.</p>
<p>Ever heard of HTML character entities?  That&#8217;s the primary reason they exist &#8212; as a sort of encoding independent reference to a particular character.  So, for example, the Œ character does not exist in the ISO-8859-1 character set.  To display this character in a document with ISO-8859-1 encoding, use the equivalent HTML character entity: <code>&amp;OElig;</code>.  For an easier reference, check out this full table of <a href="http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references">HTML character entities</a>.  If using ISO-8859-1 for your HTML document, any entity above Unicode index 255 will need to be escaped.  If you&#8217;re using UTF-8 encoding, HTML character entities shouldn&#8217;t be required.</p>
<h2>Setting the Character Encoding</h2>
<p>To specify the character encoding for any file, you can set a <code>Content-Type</code> header <a href="http://www.w3.org/International/O-HTTP-charset">by configuring your web server or application</a>.  Apache lets you easily set different default character encodings for each individual file extension (<code>.js</code> for example).  Using the <code>Content-Type</code> header is the most full proof and efficient <sup><a href="#performance">1</a></sup> method to serve content.</p>
<p>But without access to the Apache configuration, how do we specify the character encoding?</p>
<h3>For external JavaScript Files</h3>
<h4>In the HTML File</h4>
<p>Just add the <code>charset</code> attribute.  If not specified, the HTML document&#8217;s character encoding is used by default (specified in the <code>Content-Type</code> header or the appropriate meta tag, for example: <code>&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;</code>).</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;script type=&quot;text/javascript&quot; src=&quot;script.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;</pre></div></div>

<h4>In the JavaScript File</h4>
<p>To my knowledge, <strong>there is no way for a JavaScript file to report its own character encoding</strong>.  To me, this seems like an omission.  Each individual document should be able to report its own character encoding without a header.  CSS files can do it (<code>@charset</code> at-rule).  HTML files can do it (<code>&lt;meta&gt;</code> tag).  Why not JavaScript files?</p>
<h4>For Dynamically Created Script Tags</h4>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">var s = document.createElement('script');
s.src = 'script.js';
s.type = 'text/javascript';
s.charset = 'utf-8';</pre></div></div>

<p>If you&#8217;re using <a href="http://api.jquery.com/jQuery.ajax/">jQuery&#8217;s Ajax</a> functions to load external JavaScript files, perhaps you might be inclined to use the <code>script dataType</code>.  jQuery even provides a <code>scriptCharset</code> option for wrapping the above method for changing the charset on a dynamic script tag. <strong>Be warned</strong>, the jQuery Ajax function uses two different methods to load external script files (as of version 1.4.2).  If a same-domain request, it uses an <code>XMLHttpRequest</code>.  If a cross-domain request, it uses a dynamic <code>script</code> tag.  So the <strong><code>scriptCharset</code> jQuery option only applies to cross-domain requests</strong>.  We&#8217;ll need some other method to mitigate our character encoding issues (or just use dynamic script tags).</p>
<h4>For XMLHttpRequest Objects</h4>
<p>Our saving grace would be the <a href="https://developer.mozilla.org/en/XMLHttpRequest#overrideMimeType()"><code>overrideMimeType</code></a> method, if it weren&#8217;t poetically unavailable in Internet Explorer.  Using this method, we can override the mime type and character encoding.</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">var xhr = new XMLHttpRequest();
// Not available in Internet Explorer (up to version 8 at time of writing)
if (xhr.overrideMimeType) {
    xhr.overrideMimeType('application/x-javascript; charset=utf-8');
}</pre></div></div>

<h3>Portable non-ASCII JavaScript</h3>
<p>The best way to make non-ASCII characters in JavaScript files portable is to escape the characters properly.  If the character is destined for HTML, use an HTML character entity (if available, not all Unicode or ISO-8559-1 characters have entities).  Or, escape the characters using the proper Latin or <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Unicode">Unicode escape sequence</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// Raw characters
var string = &quot;ñó&quot;;</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// HTML character entities
var string = &quot;&amp;ntilde;&amp;oacute;&quot;;</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// Escaped to Latin
var string = &quot;\xf1\xf3&quot;;</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// Escaped to Unicode
var string = &quot;\u00f1\u00f3&quot;;</pre></div></div>

<p>If you use the Google Closure Compiler, you&#8217;ll get the Unicode escape sequences for free (see issues <a href="http://code.google.com/p/closure-compiler/issues/detail?id=24">24</a> and <a href="http://code.google.com/p/closure-compiler/issues/detail?id=68">68</a>).  Make sure to read the tickets for more benefits of serving your JavaScript files using Unicode escape sequences to output only ASCII characters.</p>
<h2>Summary</h2>
<p>The easiest way to preemptively solve a lot of character encoding issues is to use UTF-8 for everything, and configure your web server/application to serve the UTF-8 <code>Content-Type</code> header. If you&#8217;re writing JavaScript code that you&#8217;re going to distribute to the masses, convert any non-ASCII characters using the proper escape sequences. Your JavaScript will be more portable, and will work out of the box on more server configurations.</p>
<h4>Sources</h4>
<ol>
<li><a id="performance" href="http://www.kylescholz.com/blog/2010/01/performance_implications_of_charset.html">Performance Implications of Charset, an article by Kyle Scholz</a></li>
</ol>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/EqcdQuGQ4FM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/charset/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Internet Explorer Array.sort Unreliable</title>
		<link>http://www.zachleat.com/web/array-sort/</link>
		<comments>http://www.zachleat.com/web/array-sort/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 02:09:52 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[JScript]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=568</guid>
		<description><![CDATA[What would you expect to be the result of executing the following code? // Create a medium size array, at least 100 items var obj = &#91;&#93;; for&#40;var j=0, k=150; j&#60;k; j++&#41; &#123; // the value here doesn't matter. obj.push&#40;'ABCD'+j&#41;; &#125; &#160; // Sort the array alphabetically. obj.sort&#40;function&#40;m,p&#41;&#123; m=&#40;''+m&#41;.toLowerCase&#40;&#41;; p=&#40;''+p&#41;.toLowerCase&#40;&#41;; &#160; if&#40;m &#62; p&#41; return [...]]]></description>
			<content:encoded><![CDATA[<p>What would you expect to be the result of executing the following code?</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Create a medium size array, at least 100 items</span>
<span style="color: #003366; font-weight: bold;">var</span> obj <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> k<span style="color: #339933;">=</span><span style="color: #CC0000;">150</span><span style="color: #339933;">;</span> j<span style="color: #339933;">&lt;</span>k<span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// the value here doesn't matter.</span>
    obj.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ABCD'</span><span style="color: #339933;">+</span>j<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Sort the array alphabetically.</span>
obj.<span style="color: #660066;">sort</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>m<span style="color: #339933;">,</span>p<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    m<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    p<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #339933;">+</span>p<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>m <span style="color: #339933;">&gt;</span> p<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>m <span style="color: #339933;">&lt;</span> p<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The <code>obj</code> Array should now be sorted, in alphabetical order based on value.  <strong>BUT, in our best friend Internet Explorer, a <code>Number Expected</code> error may be the result.</strong>  Don&#8217;t be fooled if your test array behaves correctly, it only happens intermittently for arrays of varying size!</p>
<p>So, I <a href="http://www.zachleat.com/test/numberexpected/">whipped up a quick test to check the damage</a>.  Iterating over array sizes from 1 to 150, running the Array sort algorithm.  The following failures resulted:</p>
<table>
<thead>
<tr>
<th>Browser</th>
<th>Failures *</th>
</tr>
</thead>
<tbody>
<tr>
<td>Internet Explorer 6</td>
<td>4 sizes out of 150</td>
</tr>
<tr>
<td>Internet Explorer 7</td>
<td>18 sizes out of 150</td>
</tr>
<tr>
<td>Internet Explorer 8 (and Compatibility Mode)</td>
<td>2 sizes out of 150</td>
</tr>
<tr>
<td>Internet Explorer 9 (and Compatibility Mode)</td>
<td>0 sizes out of 150 (Fixed!)</td>
</tr>
</tbody>
</table>
<p>* Failures may vary to the specifications of the test machine.</p>
<p>Of course, the <code>Number Expected</code> error is going to result whenever your code doesn&#8217;t return a number inside of the function callback.  But the problem here is something deeper than simple application code failure.  The problem is in JScript itself.  Any modification to the sort arguments may result in the <code>Number Expected</code> error.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    m<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// modifies the argument m and is unreliable.</span></pre></div></div>

<p>This problem will manifest itself more frequently if you use the Google Closure Compiler, which restructures JavaScript to reuse argument variables if possible, probably to save the 4 character penalty of a &#8220;var &#8221; declaration.</p>
<p>Normally, reusing argument variables is a safe practice for primitives, since they are passed by value and not by reference, as is the case in this Array sort example <sup><a href="#by-ref">1</a></sup>.  So, what exactly is going on here?  One commenter at the <a href="http://code.google.com/p/closure-compiler/issues/detail?id=58">Google Closure Compiler bug</a> seems to think that the actual array values are being passed by reference instead of by value.  I&#8217;m not completely convinced that&#8217;s the case.</p>
<h2>The Fix</h2>
<p><strong>Don&#8217;t reuse the argument variables inside of an Array sort function.</strong></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Changing the above example</span>
obj.<span style="color: #660066;">sort</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>m1<span style="color: #339933;">,</span>p1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> m<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #339933;">+</span>m1<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        p<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #339933;">+</span>p1<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>m <span style="color: #339933;">&gt;</span> p<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>m <span style="color: #339933;">&lt;</span> p<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><em>Check the <a href="http://www.zachleat.com/test/numberexpected/">source code of the demo file</a> to see the different methods of modifying the arguments that I attempted.</em></p>
<ol>
<li id="by-ref">If you want to learn more about passing by value or reference, <a href="http://snook.ca/archives/javascript/javascript_pass">Jonathan Snook has a nice explanation</a>.</li>
</ol>
<p><em style="font-size: 80%">Internet Explorer can&#8217;t make you do anything, it can only make you wish you hadn&#8217;t.</em></p>
<p><strong>Updated: Added note about Internet Explorer 9 and its Compatibility View. Looks like it&#8217;s fixed!</strong></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/kDkb2uGBlLk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/array-sort/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic page generated in 1.082 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-05-16 23:57:29 -->

