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

<channel>
	<title>Web 3.0, 6 Bladed Razors, 7 Minute Abs &#187; Web Browsers</title>
	<atom:link href="http://www.zachleat.com/web/category/web-browsers/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zachleat.com/web</link>
	<description></description>
	<lastBuildDate>Fri, 30 Jul 2010 01:59:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Point, Charset, Match: Character Encoding in JavaScript</title>
		<link>http://www.zachleat.com/web/2010/03/26/charset/</link>
		<comments>http://www.zachleat.com/web/2010/03/26/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>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/03/26/charset/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CSS 3 Text: A Tale of writing-mode Woe</title>
		<link>http://www.zachleat.com/web/2010/02/12/css3-text-writing-mode/</link>
		<comments>http://www.zachleat.com/web/2010/02/12/css3-text-writing-mode/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 04:45:54 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Web Browsers]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=496</guid>
		<description><![CDATA[After reading an interesting article on using the writing-mode CSS property to display vertical text (I&#8217;m always interested in how to abuse what browsers currently support into something new and exciting), I decided to look into this writing-mode property and see what opportunities it might present. Generally when exploring a development opportunity, I tend to [...]]]></description>
			<content:encoded><![CDATA[<p>After reading an interesting article on using the <a href="http://www.thecssninja.com/css/real-text-rotation-with-css">writing-mode CSS property</a> to display vertical text (I&#8217;m always interested in how to abuse what browsers currently support into something new and exciting), I decided to look into this <code>writing-mode</code> property and see what opportunities it might present.</p>
<p>Generally when exploring a development opportunity, I tend to prioritize my adventures towards things that are supported in Internet Explorer first.  This often has the biggest cross-browser payoff, since the other browser vendors tend to have a quicker draw than the Microsoft Team.  However, surprisingly enough, this <code>writing-mode</code> study proved the opposite to be true.  It seems very interesting that Microsoft has decided to implement a portion of the CSS 3 specification, given its general stance of moving slower than an iceberg to avoid &#8220;breaking the web.&#8221;  But I, for one, welcome our new choose-your-own-adventure standards loving overlords.</p>
<p>As far as my tests go, the only browser to support the <code><a href="http://www.w3.org/TR/2003/CR-css3-text-20030514/#writing-mode">writing-mode</a></code> property at all is Internet Explorer, which was very surprising.  At it&#8217;s heart, though, <code>writing-mode</code> is just shorthand for two other properties: <code><a href="http://www.w3.org/TR/2003/CR-css3-text-20030514/#direction">direction</a></code> and <code><a href="http://www.w3.org/TR/2003/CR-css3-text-20030514/#block-progression">block-progression</a></code>.  Luckily, <strong>Firefox, Safari, Chrome and IE back through at least version 6 support the <code><a href="https://developer.mozilla.org/en/CSS/direction">direction</a></code> property</strong> and have proprietary options for rotation, which <strong>allows for emulation of a few of the unsupported <code>writing-mode</code>&#8216;s</strong>, but not all of them.  The missing piece of <code>writing-mode</code> emulation belongs to the <code>block-progression</code> property, which isn&#8217;t supported by anyone, and would allow elements to flow reverse vertically (start at the bottom of a block and flow upwards).</p>
<p><em>It&#8217;s important to note that while <a href="http://blogs.msdn.com/ie/archive/2009/05/29/the-css-corner-writing-mode.aspx">IE8 has really set the bar for implementation here</a> and has chosen to support <code>writing-mode: lr-bt</code> and <code>writing-mode: rl-bt</code>, they aren&#8217;t used to display any known language text.  They&#8217;re just included for completeness, and aren&#8217;t a part of the <a href="http://www.w3.org/TR/2003/CR-css3-text-20030514/">W3C CSS 3 Text Module specification.</a></em></p>
<h2><a href="http://zachleat.com/test/writing-mode/">View the Demo / Test Page</a></h2>
<h2>Compatibility Table</h2>
<style type="text/css">
#compatibility td { font-family: Verdana; }
#compatibility td.yes { background-color: #00882D; color: #fff; }
#compatibility td.no { background-color: #CB000F; color: #fff; }
#compatibility td.emulate { background-color: #40A662; color: #fff; }</p>
</style>
<table id="compatibility">
<thead>
<tr>
<th rowspan="2">writing-mode</th>
<th colspan="3">Internet Explorer<br/>(Trident)</th>
<th>Mozilla Firefox<br/>(Gecko)</th>
<th>Apple Safari<br/>(Webkit)</th>
<th>Google Chrome<br/>(Webkit)</th>
</tr>
<tr>
<th>6</th>
<th>7</th>
<th>8</th>
<th>3.6</th>
<th>4</th>
<th>4</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>lr-tb</code></td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
</tr>
<tr>
<td><code>rl-tb</code></td>
<td class="emulate">emulatable</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
</tr>
<tr style="background-color: #eee;">
<td><code>lr-bt</code></td>
<td class="no">no</td>
<td class="no">no</td>
<td class="yes">yes</td>
<td class="no">no</td>
<td class="no">no</td>
<td class="no">no</td>
</tr>
<tr style="background-color: #eee;">
<td><code>rl-bt</code></td>
<td class="no">no</td>
<td class="no">no</td>
<td class="yes">yes</td>
<td class="no">no</td>
<td class="no">no</td>
<td class="no">no</td>
</tr>
<tr>
<td><code>tb-lr</code></td>
<td class="no">no</td>
<td class="no">no</td>
<td class="yes">yes</td>
<td class="no">no</td>
<td class="no">no</td>
<td class="no">no</td>
</tr>
<tr>
<td><code>tb-rl</code></td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
</tr>
<tr>
<td><code>bt-lr</code></td>
<td class="no">no</td>
<td class="no">no</td>
<td class="yes">yes</td>
<td class="no">no</td>
<td class="no">no</td>
<td class="no">no</td>
</tr>
<tr>
<td><code>bt-rl</code></td>
<td class="emulate">emulatable</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
</tr>
</tbody>
</table>
<h2>CSS Code for Emulation</h2>
<table>
<thead>
<tr>
<th>writing-mode</th>
<th>CSS</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>lr-tb</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">// Default</pre></div></div>

</td>
</tr>
<tr>
<td><code>rl-tb</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">direction</span><span style="color: #00AA00;">:</span> rtl<span style="color: #00AA00;">;</span></pre></div></div>

</td>
</tr>
<tr style="background-color: #eee;">
<td><code>lr-bt</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">// Not possible using W3C spec</pre></div></div>

</td>
</tr>
<tr style="background-color: #eee;">
<td><code>rl-bt</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">// Not possible using W3C spec</pre></div></div>

</td>
</tr>
<tr>
<td><code>tb-lr</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">// Not possible using W3C spec</pre></div></div>

</td>
</tr>
<tr>
<td><code>tb-rl</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">-webkit-transform<span style="color: #00AA00;">:</span> rotate<span style="color: #00AA00;">&#40;</span>90deg<span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
-moz-transform<span style="color: #00AA00;">:</span> rotate<span style="color: #00AA00;">&#40;</span>90deg<span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
filter<span style="color: #00AA00;">:</span> progid<span style="color: #3333ff;">:DXImageTransform</span><span style="color: #6666ff;">.Microsoft</span>.BasicImage<span style="color: #00AA00;">&#40;</span>rotation<span style="color: #00AA00;">=</span><span style="color: #cc66cc;">1</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span></pre></div></div>

</td>
</tr>
<tr>
<td><code>bt-lr</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">// Not possible using W3C spec</pre></div></div>

</td>
</tr>
<tr>
<td><code>bt-rl</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">direction</span><span style="color: #00AA00;">:</span> rtl<span style="color: #00AA00;">;</span>
-webkit-transform<span style="color: #00AA00;">:</span> rotate<span style="color: #00AA00;">&#40;</span>90deg<span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
-moz-transform<span style="color: #00AA00;">:</span> rotate<span style="color: #00AA00;">&#40;</span>90deg<span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
filter<span style="color: #00AA00;">:</span> progid<span style="color: #3333ff;">:DXImageTransform</span><span style="color: #6666ff;">.Microsoft</span>.BasicImage<span style="color: #00AA00;">&#40;</span>rotation<span style="color: #00AA00;">=</span><span style="color: #cc66cc;">1</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span></pre></div></div>

</td>
</tr>
</tbody>
</table>
<h2>Conclusion</h2>
<p>Given that <strong>4 of the 6 known writing modes are available</strong> or available through CSS emulation means we&#8217;re in pretty good shape on the internationalization front.  Consulting the Microsoft provided table for common use cases, we&#8217;re only in trouble when trying to use the &#8220;Mongolian script writing system&#8221; and an &#8220;Arabic script block quote embedded in Mongolian script document.&#8221;</p>
<p>In some far fetched fantasy-world legacy application where a page may use tables for layout, I could see an application team possibly using the <code>direction</code> property to redistribute the tables for a print stylesheet.  But that certainly wouldn&#8217;t be a common use case, since using CSS for layouts is going to give you much more flexibility in that regard.  If you can think of any other off the wall uses for <code>writing-mode</code> or <code>direction</code>, I&#8217;d love to hear them!</p>
<h2>Related</h2>
<ul>
<li>Very <a href="http://fantasai.inkedblade.net/style/discuss/vertical-text/#logical">complete article on CSS 3 writing-mode</a>, including some <code>direction</code> properties that don&#8217;t exist in the specification (like <code>ttb</code>, <code>ltr-ttb</code>, and <code>ltr-btt</code>)</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=writing-mode">Bugzilla Bug for writing-mode in Firefox</a></li>
<li>As of the time of this writing, I was unable to find any results for writing-mode on the Webkit bug tracker.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/02/12/css3-text-writing-mode/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t Give Up on Internet Explorer Yet</title>
		<link>http://www.zachleat.com/web/2009/12/09/dont-give-up-on-ie/</link>
		<comments>http://www.zachleat.com/web/2009/12/09/dont-give-up-on-ie/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 03:24:46 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Google Wave]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Zombies]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=351</guid>
		<description><![CDATA[These days, the browser landscape is more fragmented than ever. Were times easier back when IE6 and Firefox ruled the internet? Easier perhaps in terms of the number of browsers you had to launch for testing, but not better for any user&#8217;s experience. We are in a new world, where more web browsers are causing [...]]]></description>
			<content:encoded><![CDATA[<p>These days, the browser landscape is more fragmented than ever.  Were times easier back when IE6 and Firefox ruled the internet? Easier perhaps in terms of the number of browsers you had to launch for testing, but <strong>not better</strong> for any user&#8217;s experience. We are in a new world, where more web browsers are causing developers to become <strong>increasingly pragmatic</strong> with their designs and code. Sure, standards have created a safe haven under the newest versions of the Big 3 (Firefox, IE, Safari), but the lay majority are still using whatever default has been installed onto their computer, and they probably can&#8217;t tell you <a href="http://googlesystem.blogspot.com/2009/06/browser-is-search-engine.html">the difference between their web browser and a search engine</a>.</p>
<p>We must be resilient to resist the transformation from development pragmatism to user abandonment, especially considering a developer&#8217;s trend of being insulated with the latest equipment.  We use the newest hardware and download the most sophisticated browser software because we want the best experiences.  We stack the cards in our favor.  The difficulty lies with the populace that <strong>want a good experience</strong> (they can tell a fast site from a slow site), but they <strong>don&#8217;t want to buy new equipment or install a better browser.</strong>  So the question has become: Where do you place your chips on the spectrum balancing modern hardware/software and the user experience?</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2009/12/zombies.png" alt="zombie" title="zombie" width="200" height="234" class="alignright size-full wp-image-361" />As web developers, it has become increasingly easy to become disenfranchised with the lay majority&#8217;s computing environment.  I&#8217;ve witnessed this personally after purchasing my first Apple computer, a device curiously immune to the plague of IE 6/7 (8 as well, but I would hesitate to label it as a plague, more like a normal run of the mill flesh eating virus).  It&#8217;s an interesting phenomenon, being cutoff from the Windows environment (save virtualization) during development.  It&#8217;s delightfully tempting to declare damnation upon the plague ridden Internet Explorer Zombies, and develop your web presence to standards alone, allowing less focus on the harshest development environment imaginable and more on actual problem solving.</p>
<p>When developers engage in quasi-web development, perhaps in the form of an iPhone specific web application or an Adobe AIR desktop application, it fosters similar feelings.   The work shares many languages and technologies with real (wide-open) web development, but is targeted towards a single web browser.  This benefits of this sort of tunnel vision device targeting must be carefully weighed against the penalties you&#8217;re paying in narrowed default-install client compatibility.  At that point, it&#8217;s just <strong>friends with benefits</strong>.</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2009/12/google-wave-ie8.png" alt="Denial of Access with Internet Explorer Screenshot" title="Denial of Access with Internet Explorer Screenshot" width="454" height="339" class="aligncenter size-full wp-image-363" /><br />
Google Wave, in fact, requires the use of Safari, Firefox, Chrome, or the Google Chrome Frame plugin (which doesn&#8217;t count as actual browser support).  As of the time this article was written, as many as <strong>64% of all users</strong> (<a href="http://en.wikipedia.org/wiki/Usage_share_of_web_browsers">source</a>) are met with the above screen when trying to access Google Wave. Let&#8217;s be clear: <strong>Ease of development is not an excuse to abandon users.</strong>  Whatever happened to <a href="http://www.zachleat.com/web/2009/08/29/device-independence/">Device Independence</a>?</p>
<p>Not surprisingly, Google Wave&#8217;s stand against Internet Explorer <strong>has not started a trend</strong>.  Instead of all out war, the community at large has decided that subtlety is what&#8217;s needed to win this fight.  Let&#8217;s hold back the <a href="http://en.wikipedia.org/wiki/Sexual_Healing">sexual healing</a> of rounded corners, even though perhaps users will call our design harsh or cold.  Let&#8217;s give them plain buttons instead of nice three dimensional buttons with text and box shadows, even though they may be less actionable.</p>
<p>Let&#8217;s make it easier on ourselves at the expense of the user experience of The Zombie Majority.  We make this sacrifice because we assume that Zombies won&#8217;t be able to tell the difference between eating a big juicy Einstein brain and a smaller but nonetheless still tasty brush clearing George W.  And you know what, <strong>I think we&#8217;re right.</strong></p>
<p><em><strong>Updated</strong> to include a few more thoughts on Adobe AIR and the iPhone.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2009/12/09/dont-give-up-on-ie/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>DOMContentLoaded Inconsistencies (in Browsers and JavaScript Libraries)</title>
		<link>http://www.zachleat.com/web/2008/12/04/domcontentloaded-inconsistencies/</link>
		<comments>http://www.zachleat.com/web/2008/12/04/domcontentloaded-inconsistencies/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 04:54:24 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[linkedin]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=153</guid>
		<description><![CDATA[We all know the problem, but we may not all call it the same thing: DOMContentLoaded.  Every popular JavaScript library has its own name for the DOMContentLoaded event, and they're all implemented differently.  This, of course, partly due to the fact that web browsers are also inconsistent in their implementations.  Here's a run-down of those inconsistencies.]]></description>
			<content:encoded><![CDATA[<p><strong>Quick Summary</strong></p>
<ul>
<li><em>Prototype and Dojo are the only major JavaScript frameworks that correctly time the DOMContentLoaded inside of an iframe in Internet Explorer.  MooTools comes close and both YUI and jQuery both exhibit incorrect behavior.</em></li>
<li><em>Usually, browsers that have a native DOMContentLoaded event will fire it after both JavaScript and CSS (external script, link tags) have loaded.  But Opera fires prior to CSS link tags loading.</em></li>
</ul>
<p>We all know the problem, but we may not all call it the same thing.  Every popular JavaScript library has its own name for the DOMContentLoaded event.</p>
<table>
<thead>
<tr>
<th>JavaScript Library</th>
<th>Event Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>YUI</td>
<td><a href="http://developer.yahoo.com/yui/docs/YAHOO.util.Event.html#method_onDOMReady">DOMReady</a></td>
</tr>
<tr>
<td>jQuery</td>
<td><a href="http://docs.jquery.com/Events/ready">ready</a></td>
</tr>
<tr>
<td>MooTools</td>
<td><a href="http://mootools.net/docs/Utilities/DomReady">domready</a></td>
</tr>
<tr>
<td>Prototype</td>
<td><a href="http://www.prototypejs.org/api/document/observe">dom:loaded</a></td>
</tr>
<tr>
<td>Dojo</td>
<td><a href="http://api.dojotoolkit.org/jsdoc/dojo/1.2/dojo.addOnLoad">addOnLoad</a></td>
</tr>
</tbody>
</table>
<p>But the naming scheme isn&#8217;t the only part about this event that&#8217;s inconsistent.  There are a few hacks strewn around the net that have been bastardized (read: modified to the will of library authors) into each individual framework.  These have been posted time and time again, but for post completeness are the following:</p>
<table>
<thead>
<tr>
<th>IE DOMContentLoaded Hack</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code><a href="http://javascript.nwbox.com/IEContentLoaded/">doScroll</a></code> by Diego Perini</td>
<td>Uses a <code>doScroll</code> method call, which will throw an error if the <code>ondocumentready</code> event hasn&#8217;t fired on the <strong>primary document</strong> (take note of the usage of the word primary).  Once <code>doScroll</code> doesn&#8217;t throw an error, it is assumed the DOM has loaded.</td>
</tr>
<tr>
<td><code><a href="http://msdn.microsoft.com/en-us/library/ms536957(VS.85).aspx">onreadystatechange</a></code> and <code><a href="http://msdn.microsoft.com/en-us/library/ms534359.aspx">readyState</a></code></td>
<td><code>onreadystatechange</code> <em>&#8220;fires when the state of the object has changed,&#8221;</em> and changes the <code>readyState</code> property of the object through the following states (not all apply to every type of element): <code>uninitialized</code>, <code>loading</code>, <code>loaded</code>, <code>interactive</code>, and <code>complete</code>.  (source: MSDN) Usually set on the document object, or a script element (as used in the Script Defer method described next.</td>
</tr>
<tr>
<td><a href="http://dean.edwards.name/weblog/2005/09/busted/">Script Defer</a> by Dean Edwards</td>
<td>document.write&#8217;s a script tag with a <code>defer</code> attribute.  Defer will cause the browser to delay execution of the script until the DOM has successfully loaded (using onreadystatechange on the script tag until its readyState is &#8220;complete&#8221;).  Without defer, the browser would execute any script tag immediately.</td>
</tr>
<tr>
<td><a href="http://dean.edwards.name/weblog/2005/09/busted2/">HTC Behavior</a> by Dean Edwards</td>
<td>Much less popular approach using proprietary HTC Behavior files.  Generally avoided due to the addition of an extra HTTP request to the page in order to download the external .htc file.  As a side note, if using this approach, the <code><a href="http://msdn.microsoft.com/en-us/library/ms531021.aspx">"oncontentready"</a></code> event will work better than the <a href="http://msdn.microsoft.com/en-us/library/ms531024.aspx">&#8220;ondocumentready&#8221;</a> event used by Mr. Edwards.</td>
</tr>
<tr>
<td>Ghetto Method</td>
<td>Of course, the easiest way to do it is to put a script tag right above your ending <code>&lt;/body&gt;</code> tag that triggers the event manually.  This really only works if you have full control of the content, and isn&#8217;t really a library solution.  Worth noting though.</td>
</tr>
</tbody>
</table>
<p><a href='http://zachleat.com/Projects/domcontentloaded/'><img src="http://www.zachleat.com/web/wp-content/uploads/2008/12/domcontentloaded.png" alt="Benchmark for Library DOMContentLoaded Implementations" title="domcontentloaded" width="500" height="224" class="aligncenter size-full wp-image-154" /><br/><br />
<em>Benchmark for Library DOMContentLoaded Implementations</em></a></p>
<p>I created a benchmark trying to answer the simple question: when does the DOMContentLoaded event fire?  Each implementation has different effects, especially in iframes and with stylesheets.</p>
<h1>What Works</h1>
<p>The Internet Explorer hacks presented above are reliable when used on a standalone document (not inside of an iframe).</p>
<p>Mozilla Firefox, Safari, Chrome, and Opera all contain a native DOMContentLoaded event that each framework uses to consistently fire at the correct time.  So, it isn&#8217;t even worth summarizing the results for tests in every browser with a native DOMContentLoaded event, except Opera.  Opera took a different design approach with their DOMContentLoaded event (certainly not wrong, just different), which we&#8217;ll analyze below.</p>
<h1>Internet Explorer inside an Iframe</h1>
<p><em>All libraries below did no branching based on IE versions, all used the same method for IE6, IE7, or IE8.  I performed no tests in IE8, however.</em></p>
<table>
<thead>
<tr>
<th rowspan="2">JavaScript Library</th>
<th rowspan="2">Method</th>
<th colspan="4">Waited for:</th>
</tr>
<tr>
<th>&lt;body&gt; &lt;script&gt;</th>
<th>&lt;head&gt; &lt;script&gt;</th>
<th>&lt;link&gt; CSS</th>
<th>&lt;img&gt;</th>
</tr>
</thead>
<tbody>
<tr>
<td>YUI 2.6.0</td>
<td>doScroll, setTimeout</td>
<td colspan="4">Incorrect: Fires almost immediately (~20ms)</td>
</tr>
<tr>
<td>jQuery 1.2.6</td>
<td>window onload</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
</tr>
<tr>
<td>Prototype 1.6.0.3</td>
<td>Script Defer</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
<tr>
<td>MooTools 1.2.1</td>
<td>doScroll and set innerHTML, setTimeout</td>
<td>*</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
<tr>
<td>Dojo 1.2.0</td>
<td>Script Defer</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
<tr>
<td><a href="http://javascript.nwbox.com/IEContentLoaded/">IEContentLoaded</a></td>
<td>doScroll, document.onreadystatechange</td>
<td colspan="4">Incorrect: JavaScript error.</td>
</tr>
<tr>
<td><a href="http://www.thefutureoftheweb.com/blog/adddomloadevent">addDOMLoadEvent</a></td>
<td>Script Defer</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
</tbody>
</table>
<p>* <em>For some reason, not only did the MooTools library not wait for the body script to trigger DOMContentLoaded, the body script never executed at all.</em></p>
<p>The <strong>most important takeaway</strong> from this blog post are the successful methods of faking DOMContentLoaded in Internet Explorer.  The obvious <strong>library winners here are Prototype and Dojo</strong>, with the addDOMLoadEvent script also exhibiting correct behavior.  MooTools is a close runner up, and I would be interested to find out why it didn&#8217;t execute the body script (that&#8217;s left for another day, or perhaps a generous commenter).</p>
<h1>Opera 9.6</h1>
<table>
<thead>
<tr>
<th rowspan="2">JavaScript Library</th>
<th rowspan="2">Method</th>
<th colspan="4">Waited for:</th>
</tr>
<tr>
<th>&lt;body&gt; &lt;script&gt;</th>
<th>&lt;head&gt; &lt;script&gt;</th>
<th>&lt;link&gt; CSS</th>
<th>&lt;img&gt;</th>
</tr>
</thead>
<tbody>
<tr>
<td>YUI 2.6.0</td>
<td>Native DOMContentLoaded</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<td>jQuery 1.2.6</td>
<td>Native DOMContentLoaded + Code to wait for Stylesheets</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
<tr>
<td>Prototype 1.6.0.3</td>
<td>Native DOMContentLoaded</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<td>MooTools 1.2.1</td>
<td>Native DOMContentLoaded</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Dojo 1.2.0</td>
<td>Native DOMContentLoaded</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<td><a href="http://javascript.nwbox.com/IEContentLoaded/">IEContentLoaded</a></td>
<td>N/A to Opera</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
<tr>
<td><a href="http://www.thefutureoftheweb.com/blog/adddomloadevent">addDOMLoadEvent</a></td>
<td>Native DOMContentLoaded</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p>As you can see above, <strong>Opera typically will fire DOMContentLoaded prior to stylesheets loading</strong> successfully (ignoring the jQuery specific code to provide consistency cross-browser)</p>
<p><em>Thanks to <a href="http://www.adamkoch.com/">Adam Koch</a> for first pointing me in the direction of jQuery in an iframe ignoring DOMContentLoaded in IE.</em></p>
<p><strong>Update:</strong> There is an open ticket for <a href="http://sourceforge.net/tracker/index.php?func=detail&#038;aid=2008289&#038;group_id=165715&#038;atid=836476">YUI on Sourceforge</a>, and I&#8217;ve opened a ticket for <a href="http://dev.jquery.com/ticket/3693">jQuery on their Trac site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2008/12/04/domcontentloaded-inconsistencies/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Relative URLs including the Domain</title>
		<link>http://www.zachleat.com/web/2008/10/16/relative-urls-including-the-domain/</link>
		<comments>http://www.zachleat.com/web/2008/10/16/relative-urls-including-the-domain/#comments</comments>
		<pubDate>Thu, 16 Oct 2008 06:45:24 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[linkedin]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=148</guid>
		<description><![CDATA[Just a neat little trick I saw while browsing the source code of Google Calendar.  In some of their CSS files, they link to background-images using URLs that include everything but the protocol, which is something I hadn't seen before.]]></description>
			<content:encoded><![CDATA[<p>Just a neat little trick I saw while browsing the source code of Google Calendar.  In some of their CSS files, they link to background-images using URLs that include everything but the protocol, which is something I hadn&#8217;t seen before.</p>
<p>The most common usage of a relative URL is linked from the root (note the slash at the beginning), like so:</p>
<p><img src="/web/wp-content/themes/hemingway/images/title.png"/><br />
&lt;img src=&#8221;<strong>/web/wp-content/themes/hemingway/images/title.png</strong>&#8220;/&gt;</p>
<p>You can also use <code>../</code> to navigate up a directory in your path, but that&#8217;s boring.  The interesting question is: what if I wanted to load content from a separate domain, while at the same time transparently using the protocol used on my page?</p>
<p>Do what Google Calendar does and use the following style:<br />
<img src="//calendar.google.com/googlecalendar/images/calendar_sm2_en.gif"/><br />
&lt;img src=&#8221;<strong>//calendar.google.com/googlecalendar/images/calendar_sm2_en.gif</strong>&#8220;/&gt;</p>
<p>Note the lack of <code>http:</code> or <code>https:</code> from the URL.  If this page <a href="https://www.zachleat.com/web/2008/10/16/relative-urls-including-the-domain/">were hosted on https</a> (we don&#8217;t pay for certificates around here, so you&#8217;ll have to put up with the security warning), the last image source will load from https as well at no additional development cost.</p>
<p>This seems like it would be especially useful if you were using the YDN Performance tip to <a href="http://developer.yahoo.com/performance/rules.html#split">Split Components Across Domains</a>.  Remember, we&#8217;re not just talking images. This involves how the browser resolves URLs, so could be used inside href tags, css urls (as Google Calendar did), etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2008/10/16/relative-urls-including-the-domain/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t Let the Door Hit You Onunload and Onbeforeunload</title>
		<link>http://www.zachleat.com/web/2008/04/22/dont-let-the-door-hit-you-onunload-and-onbeforeunload/</link>
		<comments>http://www.zachleat.com/web/2008/04/22/dont-let-the-door-hit-you-onunload-and-onbeforeunload/#comments</comments>
		<pubDate>Wed, 23 Apr 2008 04:51:08 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Interface Design]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Gmail]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[Undo]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=126</guid>
		<description><![CDATA[Many people attempt a last ditch effort to save page state in the browser by using the onunload or onbeforeunload events. This has been studied at great length by Patrick Hunlock, who uses the perhaps now common knowledge of using a Synchronous Ajax call to perform the page state save. Another use for the onbeforeunload [...]]]></description>
			<content:encoded><![CDATA[<p>Many people attempt a last ditch effort to save page state in the browser by using the onunload or onbeforeunload events.  This has been studied at great length by <a href="http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript">Patrick Hunlock</a>,  who uses the perhaps now common knowledge of using a Synchronous Ajax call to perform the page state save.</p>
<p>Another use for the onbeforeunload event to allow the user to cancel the action that initiated the user leaving in the first place.  Gmail uses this technique when the user is in the middle of writing a draft of an e-mail and attempts to leave the page.</p>
<p><a href='http://www.zachleat.com/web/wp-content/uploads/2008/04/gmail-confirm.png'><img src="http://www.zachleat.com/web/wp-content/uploads/2008/04/gmail-confirm.png" alt="" title="gmail-confirm" width="455" height="157" class="aligncenter size-full wp-image-129" /></a><br />
<em>Gmail&#8217;s pops up this prompt when the user attempts to leave the page while drafting an email.</em></p>
<p>Worthy to note, however, is that Opera <a href="http://www.quirksmode.org/bugreports/archives/2004/11/load_and_unload.html">doesn&#8217;t fire the unload event</a> when the browser refreshes the page, or uses the back/forward buttons to browse off of the page (I had no success with the fix posted in the comments on that page).  What&#8217;s worse, Opera never fires the onbeforeunload event.  This creates a serious problem with attempting to save page state prior to a user leaving your page.</p>
<p>Browser support aside, I believe that the onbeforeunload prompt is not an ideal way to protect the user from lost work (or unsaved page state).  Humanized has argued, and I agree, that <a href="http://www.alistapart.com/articles/neveruseawarning">an undo operation is much easier on the end user than a warning message</a>.  The strange thing is, Gmail could save the draft in a synchronous Ajax request in the onunload event.  They aren&#8217;t using the prompt to save Opera users from losing their drafts, since the Opera web browser doesn&#8217;t even fire the onbeforeunload event.  (Interestingly enough, they are using some sort of browser history management to fire a warning to the user when they press back, or forward, in Opera &#8212; but Reload can&#8217;t be caught using this method, so your could draft email be lost).</p>
<p>From a User Interface design standpoint, I would recommend just sticking with onunload.  You can still perform your synchronous Ajax call in the method to save the state of your page, so that the user can later resume their state or undo the operation. (Except for Back/Forward/Refresh in Opera, until they support a better onunload or any onbeforeunload).  The onbeforeunload prompt is an unnecessary evil, and doesn&#8217;t do much besides annoy the end user with another warning message and a mouse click.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2008/04/22/dont-let-the-door-hit-you-onunload-and-onbeforeunload/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Minor Annoyances with Firefox Development</title>
		<link>http://www.zachleat.com/web/2008/03/23/minor-annoyances-with-firefox-development/</link>
		<comments>http://www.zachleat.com/web/2008/03/23/minor-annoyances-with-firefox-development/#comments</comments>
		<pubDate>Sun, 23 Mar 2008 20:39:40 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Caching]]></category>
		<category><![CDATA[Firefox]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/2008/03/23/minor-annoyances-with-firefox-development/</guid>
		<description><![CDATA[When you&#8217;re developing web applications in Firefox, do you find yourself constantly clearing your cache? Cache is a useful facet of web browsing for everything but the continuous testing environment of web development. Here&#8217;s a nice alternative so that you don&#8217;t have to disable your cache entirely: Use the Firefox Plug-In called (humorously enough) JohnnyCache. [...]]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re developing web applications in Firefox, do you find yourself constantly clearing your cache?  Cache is a useful facet of web browsing for everything but the continuous testing environment of web development.  Here&#8217;s a nice alternative so that you don&#8217;t have to disable your cache entirely:</p>
<p>Use the Firefox Plug-In called (humorously enough) <a href="https://addons.mozilla.org/en-US/firefox/addon/3817"><strong>JohnnyCache</strong></a>.  I added the pattern &#8216;http://localhost/&#8217; to my preferences and now I don&#8217;t have to worry about cache on my local machine anymore.  Simple, easy, effective.</p>
<p>Now only if I knew how to disable the Firefox preference that autopopulates form fields with default values when F5 is hit to refresh the page.  Try creating a page with a single text field, type a value into the form, and then hit F5 to refresh the page.  Your value will be prefilled into the form.</p>
<p>I find myself always hitting &#8220;CTRL+L&#8221; (goes to the Location Bar) and &#8220;Enter&#8221; to avoid that one.  I looked through about:config, but only found: signon.prefillForms (related to usernames and passwords), and browser.formfill.enable (related to autocomplete dropdowns for forms, not default values).</p>
<p>Anyone know an easier method?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2008/03/23/minor-annoyances-with-firefox-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problems with Looping through window.setInterval</title>
		<link>http://www.zachleat.com/web/2007/12/23/problems-with-looping-through-windowsetinterval/</link>
		<comments>http://www.zachleat.com/web/2007/12/23/problems-with-looping-through-windowsetinterval/#comments</comments>
		<pubDate>Mon, 24 Dec 2007 03:46:24 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Timers]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/2007/12/23/problems-with-looping-through-windowsetinterval/</guid>
		<description><![CDATA[Look at this code. What do you expect to be the outcome? var d = new Date&#40;&#41;; var r = &#91;&#93;; for&#40;var j=0,k=2;j&#60;k ;j++&#41; &#123; window.setInterval&#40;function&#40;&#41; &#123; var next = new Date&#40;&#41;; r.push&#40;next.getTime&#40;&#41; - d.getTime&#40;&#41;&#41;; &#125;,1000&#41;; &#125; Every 1000 milliseconds (1 second), the r array should have three delta timestamps added into it (one for [...]]]></description>
			<content:encoded><![CDATA[<p>Look at this code.  What do you expect to be the outcome?</p>
<p><span id="more-104"></span></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> d <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> r <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;">2</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>
    window.<span style="color: #660066;">setInterval</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> next <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        r.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>next.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> d.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Every 1000 milliseconds (1 second), the <code>r array should have three delta timestamps added into it (one for each interval set in the for loop).  In FireFox, however, there are exactly nine delta timestamps added per second.  If you set <code>k=10</code>, the result is one hundred delta timestamps per second.  If anyone has the answer, I am curious, even if the result is that I'm an idiot.  It seems to work correctly in Internet Explorer 7.  Thanks for your help, internet.</k></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2007/12/23/problems-with-looping-through-windowsetinterval/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Forward Compatibility and JavaScript</title>
		<link>http://www.zachleat.com/web/2007/11/01/forward-compatibility-and-javascript/</link>
		<comments>http://www.zachleat.com/web/2007/11/01/forward-compatibility-and-javascript/#comments</comments>
		<pubDate>Fri, 02 Nov 2007 01:53:20 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Rendering Modes]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/2007/11/01/forward-compatibility-and-javascript/</guid>
		<description><![CDATA[Many developers (myself included) complain endlessly about the problematic ECMAScript implementation that Internet Explorer uses called JScript. And after reading one such very detailed complaint in the comments on Dave Massy&#8217;s website at MSDN, and reading Chris Wilson&#8217;s post about ECMAScript 3, it has become increasingly obvious of Microsoft&#8217;s opinion on the subject of Forward [...]]]></description>
			<content:encoded><![CDATA[<p>Many developers (myself included) complain endlessly about the problematic ECMAScript implementation that Internet Explorer uses called JScript.  And after reading <a href="http://blogs.msdn.com/dmassy/archive/2006/11/30/vpc-to-run-ie6-and-ie7-on-the-same-machine.aspx">one such very detailed complaint</a> in the comments on Dave Massy&#8217;s website at MSDN, and reading <a href="http://blogs.msdn.com/ie/archive/2007/10/30/ecmascript-3-and-beyond.aspx">Chris Wilson&#8217;s post about ECMAScript 3</a>, it has become increasingly obvious of Microsoft&#8217;s opinion on the subject of Forward Compatibility with JavaScript.  It&#8217;s something they keep pounding their fists on the ground about, how they are adamant that new versions of their browser not &#8220;Break the Web.&#8221;</p>
<p>Of course, &#8220;Breaking the Web&#8221; refers to the amount of code on the internet today that is an equal and opposite reaction to the broken bug-ridden JavaScript implementation of their browser.  It describes the unimaginable future in which Internet Explorer fixed the many well documented <em>intricacies</em> of JScript and thereby ruins the code that was originally written to support the problem.  What a conundrum.</p>
<p>But haven&#8217;t we already been through this problem?  Isn&#8217;t this the same exact thing we saw in the early days of CSS?  And how did the major browser players react?  By implementing both a <a href="http://www.quirksmode.org/css/quirksmode.html">Quirks and Standards mode for CSS through DocType switching</a>.  Now my question is:</p>
<p><strong>Why haven&#8217;t we seen a Quirks and Standards Compatibility Mode for JavaScript?</strong></p>
<p>I&#8217;m not necessarily encouraging the Quirks and Standards modes to be toggled with the DocType (as with CSS), but why not have these two modes?  To enable your site to use the Standards mode of JavaScript, the browser might require a certain DocType to be declared, or it might require a different script type in the browser:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;script type=&quot;text/javascript&quot; mode=&quot;standards&quot;&gt;</pre></div></div>

<p>Either that, or <a href="http://dean.edwards.name/weblog/2007/03/yet-another/">I could just use Base2</a>.</script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2007/11/01/forward-compatibility-and-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cross Domain XHR with Firefox 2</title>
		<link>http://www.zachleat.com/web/2007/08/30/cross-domain-xhr-with-firefox/</link>
		<comments>http://www.zachleat.com/web/2007/08/30/cross-domain-xhr-with-firefox/#comments</comments>
		<pubDate>Thu, 30 Aug 2007 23:40:20 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Firefox]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/2007/08/30/cross-domain-xhr-with-firefox/</guid>
		<description><![CDATA[By now know you know that trying to do an XMLHttpRequest (XHR or AJAX) call to a domain that is different from the domain of the hosted JavaScript in Firefox will throw an exception. Error: uncaught exception: Permission denied to call method XMLHttpRequest.open If you don&#8217;t want a history of the past solutions, page down [...]]]></description>
			<content:encoded><![CDATA[<p>By now know you know that trying to do an XMLHttpRequest (XHR or AJAX) call to a domain that is different from the domain of the hosted JavaScript in Firefox will throw an exception.</p>
<p><code>Error: uncaught exception: Permission denied to call method XMLHttpRequest.open</code></p>
<p>If you don&#8217;t want a history of the past solutions, page down to see the final solution.</p>
<p>The web has solutions to this problem, but most of them involve changing your JavaScript code, which I thought to be less than ideal.  A common solution involves setting the UniversalBrowserRead security property in your JavaScript code [<a href="http://almaer.com/blog/archives/000794.html">Dion Almaer</a>, of Ajaxian fame]:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">netscape.<span style="color: #660066;">security</span>.<span style="color: #660066;">PrivilegeManager</span>.<span style="color: #660066;">enablePrivilege</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'UniversalBrowserRead'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The problem with that solution (obviously) lies in single browser proprietary JavaScript polluting your code.  And you have to set this property inside the scope of any usage (ie: inside your library file that does your AJAX calls and inside your callbacks, etc).</p>
<p>Why can&#8217;t it just be as easy as Internet Explorer?  They just pop-up a little security dialog asking you if you want to allow this access (which is also what the <code>enablePrivilege</code> function does as well).</p>
<p>Another solution involves setting the <code>capability.policy.default.XMLHttpRequest.open</code> preference inside your prefs.js Firefox preference file [<a href="http://blog.dirolf.com/2007/06/enabling-cross-domain-ajax-in-firefox.html">Mike Dirolf</a>].  This worked as desired and allowed the AJAX call, but anytime you attempt to access the resulting XML you received a nice exception as well.  It turns out this is the solution we wanted, it&#8217;s just incomplete.</p>
<h2><a name="solution">The Final Solution</a></h2>
<ol>
<li>Close Firefox.  It will overwrite your changes to the prefs.js file if you have it open.</li>
<li><em>Optional step</em>: This approach will open up your Firefox security quite a bit, so I&#8217;d recommend setting up a separate profile in Firefox to use when testing.  It will <strong>not </strong>pop up a security dialog when a cross-domain AJAX call is made.</li>
<li>Find your prefs.js file.  In Windows, it is typically located in the <code>C:\Documents and Settings\{YOUR_USERNAME}\ApplicationData\Mozilla\Firefox\Profiles\{YOUR_TEST_USER_PROFILE_ID}\prefs.js</code></li>
<li>Open it up and add the following lines:

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.XMLHttpRequest.open&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.CDATASection.nodeValue&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.Element.attributes&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.Element.childNodes&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.Element.firstChild&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.Element.getElementsByTagName&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.Element.tagName&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.HTMLCollection.length&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.HTMLCollection.item&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.Text.nodeValue&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.XMLDocument.documentElement&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.XMLDocument.getElementsByTagName&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.XMLHttpRequest.channel&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.XMLHttpRequest.open&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.XMLHttpRequest.responseText&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.XMLHttpRequest.responseXML&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.XMLHttpRequest.send&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
user_pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;capability.policy.default.XMLHttpRequest.setRequestHeader&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;allAccess&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

</li>
</ol>
<p>This code was copied (with the exception of 1 line) from a source repository at [<a href="http://svn.kryogenix.org/filedetails.php?repname=kryogenix.org&#038;path=%2Fjackfield%2Ftrunk%2Fhtmlui%2Fprefs.js&#038;rev=0&#038;sc=0">kryogenix.org</a>]<br />
used in jackfield.  It wasn&#8217;t intended to be used for this purpose, but it works.</p>
<p>If you still get <code>Error: uncaught exception: Permission denied to call method _________</code> errors, you can add the method to your prefs.js.  I would appreciate a comment with any commonly used methods not included above.  Thanks.</p>
<p><strong>Update:</strong> Because this article is deprecated (applies to an older version of Firefox), I&#8217;m updating the blog title in the interest of minimizing the number of disappointed users.  Some might think this is a stupid thing to do, since it&#8217;s the most popular page on my blog, but I&#8217;m more interested in helping people than getting traffic.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2007/08/30/cross-domain-xhr-with-firefox/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Screen Readers and Listening at the Speed of Sound</title>
		<link>http://www.zachleat.com/web/2007/05/17/screen-readers-and-listening-at-the-speed-of-sound/</link>
		<comments>http://www.zachleat.com/web/2007/05/17/screen-readers-and-listening-at-the-speed-of-sound/#comments</comments>
		<pubDate>Fri, 18 May 2007 00:23:38 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Application Design]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Accessibility]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/2007/05/17/screen-readers-and-listening-at-the-speed-of-sound/</guid>
		<description><![CDATA[Here is a presentation given by a guy named Victor Tsaran on how he personally uses screen readers to browse the web. As web developers, accessibility is an important aspect of our work and cannot be ignored. How many websites have you browsed that had flash navigation? If you&#8217;re not a web developer, you need [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a <a href="http://yuiblog.com/blog/2007/05/14/video-intro-to-screenreaders/">presentation</a> given by a guy named Victor Tsaran on how he personally uses screen readers to browse the web.  As web developers, accessibility is an important aspect of our work and cannot be ignored.  How many websites have you browsed that had flash navigation?  If you&#8217;re not a web developer, you need to skip ahead to time stamp 25:44 to see the mega-fast speed this guy uses the screen reader at.  I couldn&#8217;t understand a single word coming out of my speaker.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2007/05/17/screen-readers-and-listening-at-the-speed-of-sound/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I-Frame Shims or How I Learned to Stop Worrying and Love the Bomb</title>
		<link>http://www.zachleat.com/web/2007/04/24/adventures-in-i-frame-shims-or-how-i-learned-to-love-the-bomb/</link>
		<comments>http://www.zachleat.com/web/2007/04/24/adventures-in-i-frame-shims-or-how-i-learned-to-love-the-bomb/#comments</comments>
		<pubDate>Tue, 24 Apr 2007 21:51:55 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Internet Explorer]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/2007/04/24/adventures-in-i-frame-shims-or-how-i-learned-to-love-the-bomb/</guid>
		<description><![CDATA[So again, I show up late to the party. IE7 is already out, but my target customers are still using IE6. So today, boys and girls, we&#8217;re going to discover the magical world of using I-Frame shims to hide those bleeding heart select boxes from showing through our layered elements. Typically, when creating an I-Frame [...]]]></description>
			<content:encoded><![CDATA[<p>So again, I show up late to the party.  IE7 is already out, but my target customers are still using IE6.  So today, boys and girls, we&#8217;re going to discover the magical world of using I-Frame shims to hide those bleeding heart select boxes from showing through our layered elements.</p>
<p>Typically, when creating an I-Frame shim, you&#8217;re going to create the i-frame dynamically using document.createElement.  Let&#8217;s start out with some successful code.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> iframeShim <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">'iframe'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
iframeShim.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">'src'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'javascript:&quot;&quot;;'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
iframeShim.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">'frameBorder'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'0'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now for some caveats you might have encountered with code not matching the above:</p>
<p><strong>I-Frame frameBorder attribute</strong><br />
Are you trying to get rid of that nasty i-frame border in Internet Explorer 6 (IE6)?  Tried CSS properties?  Tried setting the frameBorder attribute?  It turns out that when setting the frameBorder attribute, the name of the attribute is case sensitive.  Using frameborder will not work correctly, but using frameBorder (with a capital B) will give the desired result.  [Source: <a href="http://www.visible-form.com/blog/createelement-and-events-and-iframe-borders/">FlashApe</a>]</p>
<p><strong>HTTPS and I-Frame src attribute</strong><br />
Is your page hosted on a secure domain (https instead of just http)?  Is the dynamically created iframe causing the following error message in Internet Explorer?</p>
<p><em>This page contains both secure and nonsecure items.  Do you want to display the nonsecure items?</em></p>
<p>Some have suggested that changing the src attribute to point to a blank html page with no content is the solution, but that&#8217;s an extra http request on your page that is unnecessary.  Others have suggested that that changing the src attribute to javascript:false works.  It does, in fact, but writes the text &#8216;false&#8217; to your iframe content.  Others have suggested javascript:void(0) as your src attribute value [Source: <a href="http://ewbi.blogs.com/develops/2004/07/ie_iframe_and_h.html">ewbi.develops</a>], but some Internet Explorer clients still have secure and nonsecure items alert popup.  I have not figured out the factors that separate these Internet Explorer clients.  </p>
<p><strong>Update</strong>: <del datetime="2008-12-02T05:19:37+00:00">The correct solution is in face setting &#8220;javascript:false;document.write(&#8220;&#8221;);&#8221; as your src value, as I found in the <a href="http://malsup.com/jquery/block/">jQuery BlockUI</a> plugin.  This is a silver bullet fix that will avoid all the problems I have encountered.</del></p>
<p><strong>Update Again</strong>: I have revisited this problem and it looks like (as mentioned in the comments) there is a problem with the solution presented in the first update (infinite load).  After researching some DOMContentLoaded solutions, I thought to try the &#8220;//:&#8221; source they were attempting for their deferred script source.  Alas, it didn&#8217;t work.  However, <code>javascript:"";</code> <strong>does work</strong>, so the above solution has been modified.  Keep in mind, the whole point of this solution is to <strong>avoid</strong> an additional unnecessary HTTP request.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2007/04/24/adventures-in-i-frame-shims-or-how-i-learned-to-love-the-bomb/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>JavaScript Code Coverage Tool for Firebug</title>
		<link>http://www.zachleat.com/web/2007/04/18/javascript-code-coverage-tool-for-firebug/</link>
		<comments>http://www.zachleat.com/web/2007/04/18/javascript-code-coverage-tool-for-firebug/#comments</comments>
		<pubDate>Wed, 18 Apr 2007 20:08:06 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Code Coverage]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Selenium]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/2007/04/18/javascript-code-coverage-tool-for-firebug/</guid>
		<description><![CDATA[Download FirebugCodeCoverage-0.1.xpi Recently, I&#8217;ve become interested in client side automated testing tools. When I found the Selenium plug-in for Firefox, I was blown away. I can record actions in my browser and play them back! No more manual testing of JavaScript code! Researching a little bit more about automated testing tools led to the discovery [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zachleat.com/Projects/firebugCodeCoverage/FirebugCodeCoverage-0.1.xpi"><strong>Download FirebugCodeCoverage-0.1.xpi</strong></a></p>
<p>Recently, I&#8217;ve become interested in client side automated testing tools.  When I found the <a href="http://www.openqa.org/selenium-ide/">Selenium</a> plug-in for Firefox, I was blown away.  I can record actions in my browser and play them back!  No more manual testing of JavaScript code!</p>
<p>Researching a little bit more about automated testing tools led to the discovery of a metric called &#8216;Code Coverage&#8217;, a statistic that gives you a percentage of how much of your code executed during a certain period of time (usually while your automated test was executing).</p>
<p>Of course, I immediately thought of <a href="http://www.getfirebug.com/">Joe Hewitt&#8217;s Firebug</a> extension for Firefox, which includes a feature for JavaScript Profiling.  The Profile feature of Firebug was similar to a Function Entry Code Coverage report, so I decided to modify the feature and release an add-on for Firefox that showed (at a file level) a list of which functions executed and which functions did not.</p>
<p><img src='http://www.zachleat.com/web/wp-content/uploads/2007/04/coverage.gif' alt='coverage.gif' /></p>
<p>So, now, to test my JavaScript code coverage, I will write automated tests using the Selenium IDE plug-in for Firefox, hit the Code Coverage button in Firebug, and try to get my Code Coverage statistics in the upper 90%&#8217;s.</p>
<p>Screenshot Example of running the tool at yahoo.com<br />
<img src='http://www.zachleat.com/web/wp-content/uploads/2007/04/coverage2.gif' alt='Code Coverage' /></p>
<p><a href="http://www.zachleat.com/Projects/firebugCodeCoverage/FirebugCodeCoverage-0.1.xpi"><strong>Download FirebugCodeCoverage-0.1.xpi</strong></a>.</p>
<p><strong>Requirements (obviously)</strong></p>
<ul>
<li>Mozilla Firefox</li>
<li>Firebug Extension for Mozilla Firefox</li>
</ul>
<p><strong>Limitations</strong>:</p>
<ul>
<li>Does not include statistics on anonymous functions.</li>
<li>Is limited to function (entry) code coverage, does not include other forms such as exit, statement, condition, or path code coverage. (Description: <a href="http://en.wikipedia.org/wiki/Code_coverage">Wikipedia</a>)</li>
<li>Is my first Firefox add-on, so there was a learning curve involved.</li>
</ul>
<p><strong>Future Improvements</strong>:</p>
<ul>
<li>Automated integration with Selenium IDE (one button to run tests and do code coverage)</li>
<li>Better display of results, instead of a big kludge of function names</li>
<li>Additional types of coverage, depending on what options are available from <a href="http://www.xulplanet.com/references/xpcomref/ifaces/jsdIDebuggerService.html">jsdIDebuggerService</a></li>
</ul>
<p><strong>Update:</strong> After many requests and much self deliberation, I have decided not to update the plugin to work with newer versions of Firefox.  Code Coverage doesn&#8217;t belong in the browser, it&#8217;s just the wrong place in the tool chain to have something like this.  Code Coverage results need to be exportable, and the utility must be executable from the command line to use with unit tests and continuous integration.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2007/04/18/javascript-code-coverage-tool-for-firebug/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
	</channel>
</rss>
