<?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>onenaught.com</title>
	<atom:link href="http://www.onenaught.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.onenaught.com</link>
	<description>A blog on web standards, accessibility, css, javascript, xslt, and more</description>
	<lastBuildDate>Sun, 22 Apr 2012 18:22:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<image>
		<title>One Naught</title>
		<url>http://www.onenaught.com/wp-content/themes/onenaught/images/onenaught.png</url>
		<link>http://www.onenaught.com</link>
		<width>116</width>
		<height>130</height>
		<description>OneNaught.com</description>
	</image>		<item>
		<title>SEOMoz&#8217;s intro to SEO</title>
		<link>http://www.onenaught.com/posts/405/seomozs-intro-to-seo</link>
		<comments>http://www.onenaught.com/posts/405/seomozs-intro-to-seo#comments</comments>
		<pubDate>Sun, 22 Aug 2010 09:35:19 +0000</pubDate>
		<dc:creator>Anup Shah</dc:creator>
				<category><![CDATA[SEO]]></category>

		<guid isPermaLink="false">http://www.onenaught.com/?p=405</guid>
		<description><![CDATA[A comprehensive intro to SEO from SEOMoz in the form of a slide deck. This covers a lot of areas. The pyramids, for example, are a nice visualisation to the different layers of SEO.]]></description>
			<content:encoded><![CDATA[<p>This is a great intro to SEO from SEOMoz:</p>
<p><a href="http://www.slideshare.net/randfish/introduction-to-seo-5003433" title="Introduction to SEO">Introduction to SEO</a></strong><object id="__sse5003433" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=seo-training-2010-100818134052-phpapp02&#038;stripped_title=introduction-to-seo-5003433" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse5003433" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=seo-training-2010-100818134052-phpapp02&#038;stripped_title=introduction-to-seo-5003433" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></p>
<p>View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/randfish">randfish</a>.</p>
<p>More info from the <a href="http://www.seomoz.org/blog/a-comprehensive-intro-to-seo-powerpoint-slide-deck-">original SEOMoz blog post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onenaught.com/posts/405/seomozs-intro-to-seo/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Firefox 4 change: input type image only submits x and y, not name when clicked. Keyboard as before</title>
		<link>http://www.onenaught.com/posts/382/firefox-4-change-input-type-image-only-submits-x-and-y-not-name</link>
		<comments>http://www.onenaught.com/posts/382/firefox-4-change-input-type-image-only-submits-x-and-y-not-name#comments</comments>
		<pubDate>Fri, 30 Jul 2010 10:41:02 +0000</pubDate>
		<dc:creator>Anup Shah</dc:creator>
				<category><![CDATA[Browsers]]></category>

		<guid isPermaLink="false">http://www.onenaught.com/?p=382</guid>
		<description><![CDATA[Partly a note to self, and further details for a bug logged in Firefox's bugzilla:

Firefox 4.0 (and IE) do not send name/value for input type="image"; only .x and .y coordinates

Earlier Firefox, Chrome (latest) and Safari do send name/value, which is what we'd expect...]]></description>
			<content:encoded><![CDATA[<p>(This post is partly a note to self, and a place to further describe the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=583211">Firefox bug</a> I raised.)</p>
<p><strong>Update</strong>: &#8220;not a bug, it&#8217;s a feature&#8221;! See below for more, but the gist of it is that Firefox&#8217;s behaviour here is right according to the HTML 5 specs, but not according to the HTML 4.01 specs&#8230;</p>
<h3 id="toc-the-problem-change">The <del datetime="2010-07-30T13:05:34+00:00">problem</del> change</h3>
<p>Firefox 4.0 beta &#8212; as well as IE and Opera &#8212; do not send name/value for input type=&#8221;image&#8221;; only .x and .y coordinates are sent.</p>
<p>Note, this is when clicking the input image with a mouse. When navigating using keyboard, focusing on it, and pressing enter, then the name does get submitted.</p>
<p>Earlier Firefox, Chrome (latest) do send name/value, which is what we&#8217;d expect&#8230;</p>
<h3 id="toc-example">Example</h3>
<p>This form submits using a GET so you can see the submitted name/value pairs in the querystring:</p>
<form action="" method="get">
<p>Click this:<br />
<input type="image" name="image-button" value="image-button-value" src="http://www.onenaught.com/wp-content/themes/onenaught/images/favicon.ico" alt="some useful alt text" /></p>
</form>
<h3 id="toc-what-does-w3c-spec-say">What does W3C spec say?</h3>
<p><a href="http://www.w3.org/TR/html401/interact/forms.html#h-17.4.1">17.4.1 Control types created with INPUT</a> says this for input type image:</p>
<blockquote cite="http://www.w3.org/TR/html401/interact/forms.html#h-17.4.1">
<p>When a pointing device is used to click on the image, the form is submitted and the click coordinates passed to the server. The x value is measured in pixels from the left of the image, and the y value in pixels from the top of the image. The submitted data includes name.x=x-value and name.y=y-value where &#8220;name&#8221; is the value of the name attribute, and x-value and y-value are the x and y coordinate values, respectively.</p>
</blockquote>
<p>The previous quote implies name=value should not be sent for input type=image</p>
<p>But <a href="http://www.w3.org/TR/html401/interact/forms.html#h-17.4">17.4 The <code>Input</code> Element</a> says this as part of the input name attribute formal definition:</p>
<pre><code> name        CDATA          #IMPLIED  -- submit as part of form --</code></pre>
<p>That implies the name should be submitted too, even for input type=image (and assuming that, then the value of the input should be submitted too, which seems to be confirmed by section <a href="http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2">17.13.2 Successful controls</a> in the spec, which notes: <q>A successful control is &#8220;valid&#8221; for submission. Every successful control has its control name paired with its current value as part of the submitted form data set.</q>)</p>
<p>So, I think Firefox 4 has introduced a bug&#8230;?</p>
<h4 id="toc-update-not-a-bug">Update: not a bug</h4>
<p>The <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=583211">bug</a> I raised has been updated and turns out that this is per HTML <strong>5</strong> spec, while I was comparing what I saw with the implementations in earlier versions of Firefox and with the HTML <strong>4.01</strong> spec&#8230;</p>
<p>IE (and Opera) also only send .x and .y, so I guess they settled on that given most sites are probably still catered for/assume IE as the predominant browser&#8230;</p>
<h3 id="toc-workarounds">Workarounds</h3>
<p>One possible workaround is this, but ugly:</p>
<ol>
<li>Detect the browsers to do this for (feature detection would be better&#8230;)</li>
<li>Capture the form submit event and find the button that caused this, or capture the button click event</li>
<li>Append a hidden input like this (jQuery example, assuming button is the button you have captured):
<p>
			<code>$(form).append('&lt;input type="hidden" name="' + button.name + '" value="' + button.name + '" /&gt;').submit();</code>
		</p>
</li>
</ol>
<p>If you&#8217;ve already been working around this for IE, as the problem has been there for ages, then apply this for firefox 4 too (annoying and ugly to do browser specific code, I know)</p>
<p>Third workaround: don&#8217;t use input type=image, use input type=submit + CSS, or button etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onenaught.com/posts/382/firefox-4-change-input-type-image-only-submits-x-and-y-not-name/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>XSLT Performance tip: don&#8217;t indent output</title>
		<link>http://www.onenaught.com/posts/352/xslt-performance-tip-dont-indent-output</link>
		<comments>http://www.onenaught.com/posts/352/xslt-performance-tip-dont-indent-output#comments</comments>
		<pubDate>Tue, 20 Oct 2009 11:01:01 +0000</pubDate>
		<dc:creator>Anup Shah</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[XSLT]]></category>

		<guid isPermaLink="false">http://www.onenaught.com/?p=352</guid>
		<description><![CDATA[When transforming XML via XSLT, make sure the output setting for indenting is turned off and honoured by your code.

Turning it off will often speed up the transform and save a bit of output size.]]></description>
			<content:encoded><![CDATA[<h3 id="toc-summary-turn-off-xsl-output-indenting">Summary: turn off xsl output indenting</h3>
<p>When transforming XML via XSLT, make sure the output setting for indenting is turned off and honoured by your code.</p>
<p>Turning it off will</p>
<ul>
<li>Speed up the transform time</li>
<li>Reduce the output size</li>
</ul>
<h3 id="toc-how-is-xslt-output-indent-turned-off">How is XSLT output indent turned off?</h3>
<p>Indenting output should be off by default. If for whatever reason it is not, it can be turned off simply by using this:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;xsl:output indent=&quot;no&quot; /&gt;
</pre>
<p>I have seen a lot of .NET XSLT ignore this important setting. Sometimes it is because the output is written to a stream or something else which doesn’t take the output settings from the XSLT.</p>
<p>When transforming to an <code>XmlWriter</code> in .NET, be sure to correctly create the XML Writer using the overload that takes in output settings obtained from a loaded XSLT. E.g:</p>
<pre class="brush: csharp; title: ; notranslate">
XslCompiledTransform xslt = GetXslt(XsltPath);

// The 2nd argument honours XSLT the output settings!
using (XmlWriter w = XmlWriter.Create(sb, xslt.OutputSettings))
{
    XsltArgumentList args = GetXsltArgs();

    XPathNavigator navigator = _someXmlData.CreateNavigator();

    if (navigator == null)
        throw new NullReferenceException(&quot;navigator&quot;);

    if (w == null)
        throw new NullReferenceException(&quot;w&quot;);

    xslt.Transform(navigator, args, w);
}
</pre>
<p>(<a href="http://www.w3schools.com/xsl/el_output.asp"><code>xsl:output</code></a> has many other useful attributes worth looking into.)</p>
<h3 id="toc-what-kind-of-savings-do-you-get">What kind of savings do you get?</h3>
<p>The savings will differ for many reasons (the XML document size, the structure of the XML, the types of transformation being done etc etc), so it is hard to give a definitive savings. But here&#8217;s an illustrative example:</p>
<p>A few weeks back, a colleague at work was having trouble with an XSLT that was taking a long time to transform.</p>
<p>We started to have a look; I was expecting to find inefficient XPath, or an XML document structure that wasn&#8217;t conducive to decent transformation speed, or something like that.</p>
<p>However, I noticed the first thing was his output was set to be indented, and the XML input was HUGE.</p>
<p>So, the first thing we did was turn it off.</p>
<p>That alone <strong>reduced a 12 minute transform (on a 300MB document) to just 1 minute!</strong></p>
<p>In another scenario, a 70K XML document was taking about 0.25 seconds to transform. Turning off indenting shaved a few more  milliseconds (can&#8217;t remember exact amount now) &#8212; and saved about 2K in the output HTML that it generated.</p>
<h3 id="toc-why-can-this-make-such-a-difference">Why can this make such a difference?</h3>
<p>I think the specifics may vary depending on the XSLT parser you are using, but I believe it is basically this:</p>
<ul>
<li>Each newline/white space/tab(s) created for the indent requires an extra text node to contain these characters which requires extra memory (though at this point may not add that much time to the transformation).</li>
<li>When the transform is then saved to a file, or written out to an output stream strings are often involved. String processing can be expensive in many programming languages, so each of these indented text nodes needs handling. For very large documents (as above) this can require a lot of unnecessary processing.</li>
</ul>
<h3 id="toc-but-doesnt-this-make-the-output-harder-to-read">But doesn&#8217;t this make the output harder to read?</h3>
<p>The consumer of a transformation result is likely to be another process such as another XSLT in a pipeline, another process, or even a web browser.</p>
<p>None of these typically care about the extra white space, which also would require more processing when loading.</p>
<p>If you need to view the XML, it may be worth keeping the indent off and manually opening it in a text editor that has the ability to &#8220;pretty print&#8221; it for you. (Warning: some editors and IDEs, e.g. Visual Studio, can do automatically pretty print an XML document for you when you open it, making you think the XML itself had the indented output!)</p>
<h3 id="toc-other-savings-are-still-possible">Other savings are still possible</h3>
<p>Turning off the indent is just one of many things you can look into. Other things include the following (though your mileage may vary):</p>
<ul>
<li>Use attributes instead of elements (where possible; usually this is for simple values, such as numbers, dates, and very limited strings, and where the element is not expected to be indented)</li>
<li>Look at the XML structure to see if can be improved to make XSLT processing easier</li>
<li>Cache the XSLT Processor</li>
<li>Cache the output</li>
</ul>
<p>I&#8217;ll try to expand on some of those in future posts.</p>
<p>Some more detailed <a href="http://www.onenaught.com/posts/23/xslt-tips-for-cleaner-code-and-better-performance">XSLT performance tips which also created cleaner code</a> were covered in an earlier post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onenaught.com/posts/352/xslt-performance-tip-dont-indent-output/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CSS: inner elements breaking border-radius</title>
		<link>http://www.onenaught.com/posts/266/css-inner-elements-breaking-border-radius</link>
		<comments>http://www.onenaught.com/posts/266/css-inner-elements-breaking-border-radius#comments</comments>
		<pubDate>Thu, 09 Jul 2009 08:34:39 +0000</pubDate>
		<dc:creator>Anup Shah</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[General Web Development]]></category>

		<guid isPermaLink="false">http://www.onenaught.com/?p=266</guid>
		<description><![CDATA[Some browsers support border-radius for rounded corners. But inner elements may break those corners. Sometimes, applying border-radius to those inner elements can resolve the issue.]]></description>
			<content:encoded><![CDATA[<p>Browsers such as Firefox 2+ and Webkit-based browsers (Chrome, Safari) support the useful css <a href="http://www.w3.org/TR/2005/WD-css3-background-20050216/#the-border-radius">border-radius</a> feature (via -moz-border-radius and -webkit-border-radius, respectively).</p>
<p>Unfortunately inner elements can break rounded borders as Richard Rutter described when <a href="http://clagnut.com/blog/2273/">using <code>&lt;img&gt;</code> elements inside an element with <code>border-radius</code></a>. He also provided a useful solution which is webkit only, unfortunately.</p>
<p>Inner elements with background colors can also break border-radius. But there is a way around that too: <strong>apply <code>border-radius</code> to the offending inner elements too</strong>.</p>
<h3 id="toc-the-problem">The problem</h3>
<p>Here&#8217;s an example (view in Firefox 2+ or Safari/Chrome) where <code>border-radius</code> gets broken:</p>
<p>(If you are reading this in an RSS feed reader, you might need to <a href="http://www.onenaught.com/posts/266/css-inner-elements-breaking-border-radius">go to the page to see the example properly</a>)</p>
<p>A <code>div</code> containing a <code>blockquote</code> and a paragraph to mention the source of the quote:</p>
<div class="blockquote-with-source">
<blockquote>
<p>Fear is the path to the Dark Side&#8230; Fear leads to anger&#8230; anger leads to hate&#8230; hate leads to suffering&#8230;</p>
</blockquote>
<p class="source">— Yoda, <cite>Star Wars, Episode 1: The Phantom Menace</cite></p>
</div>
<p>Notice the bottom corners aren&#8217;t right: the background of the source paragraph breaks through the rounded corners.</p>
<p>The rounded corners are achieved using something like this:</p>
<pre class="brush: css; title: ; notranslate">
.blockquote-with-source {
  border:1px solid #e8eac8;
  border-radius:10px;
  -moz-border-radius:10px;
  -webkit-border-radius:10px;
}
</pre>
<p>(The above code is of course slightly more than necessary due to both mozilla and webkit implementing them via their rendering prefixes.)</p>
<h3 id="toc-the-ideal-solution">The ideal solution</h3>
<p><code>overflow:hidden</code> on inner elements should do the trick, but doesn&#8217;t work in Safari, Chrome or Firefox (although will work for the webkit-based ones for images as Richard Rutter points out in the above link).</p>
<h3 id="toc-workaround-for-non-image-elements-with-backgrounds">Workaround for non-image elements with backgrounds</h3>
<p>There are a few ways to work around this:</p>
<h4 id="toc-apply-border-radius-to-the-inner-element-breaking-the-rounded-corners">Apply border-radius to the inner element breaking the rounded corners</h4>
<p>If you are using background color (or background image) on the inner HTML element, you can apply <code>border-radius</code> to them too:</p>
<p>In the case of the above example, we just need rounded corners on the bottom left and bottom right of the source paragraph:</p>
<pre class="brush: css; title: ; notranslate">
.source {
    border-radius-bottomleft:10px;
    border-radius-bottomright:10px;
    -moz-border-radius-bottomleft:10px;
    -moz-border-radius-bottomright:10px;
    -webkit-border-bottom-left-radius:10px;
    -webkit-border-bottom-right-radius:10px;
}
</pre>
<p>The final styled quote would then look like this:</p>
<div class="blockquote-with-source">
<blockquote>
<p>Fear is the path to the Dark Side&#8230; Fear leads to anger&#8230; anger leads to hate&#8230; hate leads to suffering&#8230;</p>
</blockquote>
<p class="source with-fix">— Yoda, <cite>Star Wars, Episode 1: The Phantom Menace</cite></p>
</div>
<p>(If you inspect the above with Firebug or equivalent, you&#8217;ll notice I used slightly different CSS classes so it just fits with the current theme on this blog, but the principle is the same.)</p>
<h5 id="toc-drawback-to-the-above-workaround">Drawback to the above workaround</h5>
<p>The main one I can think of is that you have to maintain the border radius value in more than one place &#8212; CSS variables would be nice here <img src='http://www.onenaught.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4 id="toc-thick-enough-borders-hide-the-problem">Thick enough borders hide the problem</h4>
<p>If your design allows it, thick borders on the element using border-radius may do the trick.</p>
<p>In the example below, I use a thick border on the left side of the containing div, with border radius only on the bottom right of the source paragraph:</p>
<div class="blockquote-with-source with-thick-left-border">
<blockquote>
<p>Fear is the path to the Dark Side&#8230; Fear leads to anger&#8230; anger leads to hate&#8230; hate leads to suffering&#8230;</p>
</blockquote>
<p class="source with-fix">— Yoda, <cite>Star Wars, Episode 1: The Phantom Menace</cite></p>
</div>
<p>The thickness of the border is the same as the size of the radius, though you don&#8217;t have to do that.</p>
<h5 id="toc-drawback-to-the-above-workaround1">Drawback to the above workaround</h5>
<p>When using one thick border as above, it doesn&#8217;t render as nicely in webkit as it does in gecko. Don&#8217;t know if that is vagueness in the spec, or what&#8230;</p>
<p>However, if all four borders are given the same width, then it seems ok.</p>
<h3 id="toc-workaround-for-image-elements">Workaround for image elements</h3>
<p>As Richard Rutter commented, putting an image as a CSS background image would do the trick, but that isn&#8217;t always ideal or possible (e.g. an image that is important as part of the content is better marked up as <code>&lt;img&gt;</code>).</p>
<p>Are there other, perhaps better, ways to deal with this?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onenaught.com/posts/266/css-inner-elements-breaking-border-radius/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Web Standards &#8211; a good thing, but won&#8217;t help with SEO</title>
		<link>http://www.onenaught.com/posts/256/web-standards-a-good-thing-but-wont-help-with-seo</link>
		<comments>http://www.onenaught.com/posts/256/web-standards-a-good-thing-but-wont-help-with-seo#comments</comments>
		<pubDate>Tue, 30 Jun 2009 13:16:02 +0000</pubDate>
		<dc:creator>Anup Shah</dc:creator>
				<category><![CDATA[General Web Development]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[web standards]]></category>

		<guid isPermaLink="false">http://www.onenaught.com/?p=256</guid>
		<description><![CDATA[There are many good reasons to follow web standards principles, to use CSS-based layout and progressive enhancement but SEO, unfortunately, is not one of them.]]></description>
			<content:encoded><![CDATA[<p><strong>Update 30 June 2009</strong>: Added a couple of links at the end of this post for additional information from some recent research/experimenting.</p>
<p>Web standards is generally a good thing. When done well, it can help to create lean pages, improve markup quality, provide better accessibility and can be easier to maintain (even while supporting IE6!)</p>
<p>One claim often made in the past to promote web standards is that following web standards (using CSS-based layouts, proper use of heading elements in markup, etc) will improve SEO.</p>
<p>Though this might be desirable, it is not the case; most sites on the web don&#8217;t follow web standards and most rank very high in their areas. Search engines are not going to penalize the 90+ % of sites that don&#8217;t follow web standards; that&#8217;s like shooting themselves in the foot!</p>
<p>As I describe in an earlier post on <a href="http://www.onenaught.com/posts/30/explaining-natural-seo-search-engine-ranking-vs-indexing">search engine ranking vs indexing</a> while there are technical things one can do to ensure the site gets indexed well (e.g. URL canonicalization, good use of the &lt;title /&gt; element, etc), for ranking it is mostly about having good content that people will link to.</p>
<p>But as Matt Cutts, head of Google&#8217;s web spam team notes in this very short video, <a href="http://www.youtube.com/watch?v=fL_GZwoC2uQ">using CSS-based layouts or table-based layouts will have no bearing on search engine friendliness</a>:</p>
<p><object width="480" height="295"><param name="movie" value="http://www.youtube.com/v/fL_GZwoC2uQ&#038;hl=en&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/fL_GZwoC2uQ&#038;hl=en&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"></embed></object></p>
<p>There are many good reasons to follow web standards principles, to use CSS-based layout and progressive enhancement but SEO, unfortunately, is not one of them.</p>
<p><strong>Update 30 June 2009</strong>: A couple of decent articles recently talk about similar things:</p>
<ol>
<li><a href="http://www.seomoz.org/blog/seo-best-practices-seomozs-new-policies-based-on-updated-correlation-data">SEO Best Practices: SEOmoz&#8217;s New Policies Based on Updated Correlation Data</a></li>
<li><a href="http://www.thegooglecache.com/uncategorized/the-triviality-of-on-page-html-tag-optimization/">The Triviality of On-Page HTML Tag Optimization<br />
</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.onenaught.com/posts/256/web-standards-a-good-thing-but-wont-help-with-seo/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Use CSS display:table for Layout</title>
		<link>http://www.onenaught.com/posts/201/use-css-displaytable-for-layout</link>
		<comments>http://www.onenaught.com/posts/201/use-css-displaytable-for-layout#comments</comments>
		<pubDate>Sun, 15 Feb 2009 22:34:38 +0000</pubDate>
		<dc:creator>Anup Shah</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[General Web Development]]></category>

		<guid isPermaLink="false">http://www.onenaught.com/?p=201</guid>
		<description><![CDATA[<img class="post-img" align="left" src="/wp-content/uploads/ffx-css-display-table-post-img.jpg" alt="" /> For a few years now, web developers doing CSS-based layouts have used floats or absolute positioning for layout web sites to avoid using non-semantic HTML <code>&#60;table&#62;</code>s.

While doable, extra hoops often have to be jumped through (mostly for IE) and some seemingly simple things can be harder than necessary (like equal height columns).

However, for a simpler solution, CSS-based <code>display:table</code>, <code>display:table-row</code>, <code>display:table-cell</code> etc are all usable today across Firefox 2+, Safari 3+, Opera 9+ and IE8.]]></description>
			<content:encoded><![CDATA[<p><img class="post-img" align="left" src="http://www.onenaught.com/wp-content/uploads/ffx-css-display-table-post-img.jpg" alt="" /> I had this post in draft since October 2008. I thought I&#8217;d redesign this blog site using <code>display:table</code> and explain that in a series of posts, starting with this one. But I never found the time for the redesign! </p>
<p>Still, I have been using <code>display:table</code> on a much larger site for about 6 months now, so I thought I might as well post this as it is, and perhaps follow up with more examples later.</p>
<p>Also, about 3 weeks after I started this draft, <a href="http://www.digital-web.com/articles/everything_you_know_about_CSS_Is_wrong/">Rachel Andrew and Kevin Yank wrote a book on CSS <code>display:table</code> for layout, as well as a useful summary article</a>! I do recommend looking at that article for finer details.</p>
<h3 id="toc-no-need-for-css-float-for-layout-in-modern-browsers">No need for css float for layout in modern browsers</h3>
<p>For a few years now, web developers doing CSS-based layouts have used floats or absolute positioning for layout web sites to avoid using non-semantic HTML <code>&lt;table&gt;</code>s.</p>
<p>While doable, extra hoops often have to be jumped through (mostly for IE) and some seemingly simple things can be harder than necessary (like equal height columns).</p>
<p>However, for a simpler solution, CSS-based <code>display:table</code>, <code>display:table-row</code>, <code>display:table-cell</code> etc are all usable today across Firefox 2+, Safari 3+, Opera 9+ and IE8.</p>
<p>Example:</p>
<p>Consider the following HTML:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;body&gt;
	&lt;div id=&quot;header&quot;&gt;
		&lt;!-- header --&gt;
	&lt;/div&gt;

	&lt;div id=&quot;content-body-wrapper&quot;&gt;
		&lt;div id=&quot;content-body&quot;&gt;
			&lt;div id=&quot;primary-nav&quot;&gt;
				&lt;!-- some navigation column here --&gt;
			&lt;/div&gt;
			&lt;div id=&quot;secondary-nav&quot;&gt;
				&lt;!-- some additional column here --&gt;
			&lt;/div&gt;
			&lt;div id=&quot;content&quot;&gt;
				&lt;!-- main content here --&gt;
			&lt;/div&gt;
		&lt;/div&gt;
	&lt;/div&gt;

	&lt;div id=&quot;footer&quot;&gt;
		&lt;!-- footer --&gt;
	&lt;/div&gt;
&lt;/body&gt;
</pre>
<p>And the CSS to style it to get equal height columns:</p>
<pre class="brush: css; title: ; notranslate">
#content-body-wrapper {
    display:table;
    border-collapse:collapse;
}

#content-body {
    display:table-row;
}

#primary-nav, #secondary-nav, #content {
    display:table-cell;
}

#primary-nav, #secondary-nav {
    width:20%;
}

#content {
    width:60%;
}
</pre>
<p>And that&#8217;s it!</p>
<p>The above is just the layout bit of the CSS. Here are some screenshots (click for full size) with content and very basic styling just to see the equal height column effect:</p>
<p><a href='/wp-content/uploads/ffx-css-display-table.jpg' title='ffx-css-display-table'><img src="http://www.onenaught.com/wp-content/uploads/ffx-css-display-table-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a> <a href='/wp-content/uploads/ie8-css-display-table.jpg' title='ie8-css-display-table'><img src="http://www.onenaught.com/wp-content/uploads/ie8-css-display-table-150x150.jpg" width="150" height="150" class="attachment-thumbnail" alt="" /></a></p>
<p>The first is with Firefox 3 and the second with IE8.</p>
<p>You can actually omit extra divs, even the one that gets display:table and the browser is required to create an anonymous table for you.</p>
<h3 id="toc-isnt-using-table-for-layout-wrong">Isn&#8217;t using table for layout wrong?</h3>
<p>This is not the same as using the <em>structural</em> html table elements for layout purposes &#8212; that indeed is an inappropriate use for tables.</p>
<p>This is using CSS to give table-like <em>display</em>, which is fine as it leaves the HTML (and document structure) in tact.</p>
<h3 id="toc-what-about-ie-7-and-6">What about IE 7 and 6?</h3>
<p>IE7 and 6 of course remain problems, but you can use conditional comments and give them older techniques that attempt to achieve this.</p>
<h3 id="toc-some-limitations-or-issues">Some limitations or issues</h3>
<p>Some limitations of css display:table I have come across, however, include these:</p>
<ul>
<li>Lack of colspan/rowspan equivalents</li>
<li>Like HTML tables, a CSS cell can expand in width based on content (as well as height).</li>
</ul>
<p>On the last one I noticed this when using things like <code>&lt;pre&gt;</code> even with overflow:auto with the thought that just like inside floated columns with widths assigned this would result in those <code>&lt;pre&gt;</code> blocks getting horizontal scrolls if they became too wide.</p>
<p>Instead, as with HTML tables, they push out the cell they are in. The only workaround I knew to this was to give a px or em width to such elements. (It also applies to large images in a cell.)</p>
<p>That being said, <code>display:table</code> seems a lot cleaner!</p>
<p>CSS3 has an advanced layout module in the works but there are not any browser implementations of it (that I am aware of), so in the interim this could be a useful approach.</p>
<h3 id="toc-more-info">More info</h3>
<ul>
<li><a href="http://www.w3.org/TR/CSS21/tables.html">W3C specifications on CSS display:table</a></li>
<li><a href="http://www.digital-web.com/articles/everything_you_know_about_CSS_Is_wrong/">Rachel Andrew: Everything you know about CSS is wrong</a></li>
</ul>
<h3 id="toc-translations">Translations</h3>
<p>Update: May 2010. Translated into <a href="http://ucallweconn.net/be/vykarystanne-css-display-table-be">Belorussian</a>, by <a href="http://ucallweconn.net/">Ucallweconn</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.onenaught.com/posts/201/use-css-displaytable-for-layout/feed</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Google App Engine as your own Content Delivery Network</title>
		<link>http://www.onenaught.com/posts/204/google-app-engine-as-cdn</link>
		<comments>http://www.onenaught.com/posts/204/google-app-engine-as-cdn#comments</comments>
		<pubDate>Sat, 06 Dec 2008 14:45:37 +0000</pubDate>
		<dc:creator>Anup Shah</dc:creator>
				<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://www.onenaught.com/?p=204</guid>
		<description><![CDATA[<img class="post-img" align="left" src="/wp-content/uploads/appengine.gif" alt="" /> 24 Ways has an excellent article on using Google App Engine as your own Content Delivery Network.

A CDN is a network of servers around the world to serve content from your site from the nearest physical location. All the large sites (Yahoo, Google, Amazon, etc) use them.

After reading the above post, I was also curious to find out how if Google App Engine helps in the following: compression, expires headers and versioning. It looks like it does.]]></description>
			<content:encoded><![CDATA[<p><img class="post-img" align="left" src="http://www.onenaught.com/wp-content/uploads/appengine.gif" alt="" /> 24 Ways has an excellent article on <a href="http://24ways.org/2008/using-google-app-engine-as-your-own-cdn">using Google App Engine as your own Content Delivery Network</a>, showing you how easy it is to set one up.</p>
<p>A CDN is a network of servers around the world to serve content from your site from the nearest physical location. All the large sites (Yahoo, Google, Amazon, etc) use them.</p>
<p>After reading the above post, I was also curious to find out how if Google App Engine helps in the following:</p>
<ul>
<li>Compression</li>
<li>Expires headers and versioning</li>
</ul>
<p>A comment in the original post implies compression is on by default, which is what I&#8217;d expect.</p>
<p><a href="http://www.onenaught.com/posts/17/web-site-performance-expires-header">Using far future expires headers can be a great performance boost for your site</a>, and is easy to apply to assets such as images, CSS, and JavaScript files.</p>
<p>At the same time, if you change such a file you want to be sure your repeat visitors will not see the old one because it was cached far into the future.</p>
<p>So, with a simple URL Rewrite Rule we can make things like <code>/css/version-1/site.css</code> point to <code>/css/site.css</code>.</p>
<p>If you update <code>site.css</code>, you can change the version number. Browsers will not have a file from this new path in their cache so will download it and cache it into the future again.</p>
<p>Is it possible to do this with Google App Engine? <a href="http://code.google.com/appengine/docs/configuringanapp.html">It looks promising</a>&#8230;</p>
<p>If I can find a spare moment, I may try this out on this site (which, admittedly doesn&#8217;t get that much traffic to make it worth bothering about!) &#8212; and then I&#8217;ll try it on a site that takes up most of my spare time, which gets a LOT of traffic, where it would actually be worth doing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onenaught.com/posts/204/google-app-engine-as-cdn/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Jonathan Snook&#8217;s jQuery Background Animation as a Plugin</title>
		<link>http://www.onenaught.com/posts/171/jonathan-snooks-jquery-background-animation-as-a-plugin</link>
		<comments>http://www.onenaught.com/posts/171/jonathan-snooks-jquery-background-animation-as-a-plugin#comments</comments>
		<pubDate>Wed, 01 Oct 2008 06:53:34 +0000</pubDate>
		<dc:creator>Anup Shah</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jquery plugins]]></category>

		<guid isPermaLink="false">http://www.onenaught.com/?p=171</guid>
		<description><![CDATA[<img class="post-img" align="left" src="/wp-content/uploads/animated-bg.png" alt="" /> Jonathan Snook recently posted a really neat <a href="http://snook.ca/archives/javascript/jquery-bg-image-animations/">background animation technique using jQuery</a>. This was something I was looking for and it seemed like a good candidate for a jQuery plugin.

So, following on from my recent post about <a href="http://www.onenaught.com/posts/85/turn-your-jquery-code-into-a-richer-unit-testable-plugin">turning jQuery code into richer, unit testable plugin code</a>, I thought I'd describe the quick process of doing so here. (It's worth reading Snook's post first though!)]]></description>
			<content:encoded><![CDATA[<p><img class="post-img" align="left" src="http://www.onenaught.com/wp-content/uploads/animated-bg.png" alt="" /> Jonathan Snook recently posted a really neat <a href="http://snook.ca/archives/javascript/jquery-bg-image-animations/">background animation technique using jQuery</a>. This was something I was looking for and it seemed like a good candidate for a jQuery plugin.</p>
<p>So, following on from my recent post about <a href="http://www.onenaught.com/posts/85/turn-your-jquery-code-into-a-richer-unit-testable-plugin">turning jQuery code into richer, unit testable plugin code</a>, I thought I&#8217;d describe the quick process of doing so here. (It&#8217;s worth reading Snook&#8217;s post first though!)</p>
<p>The general steps discussed to achieve this are as follows:</p>
<ol>
<li>Add additional keyboard accessibility</li>
<li>A first attempt plugin</li>
<li>A plugin that might be unit testable</li>
</ol>
<h3 id="toc-add-additional-keyboard-accessibility">Add additional keyboard accessibility</h3>
<p>I posted a comment on Snook&#8217;s post to say additional hover and blur events should do the trick, so here is an example applied to one of the four demo menus he had with those events added:</p>
<pre class="brush: jscript; title: ; notranslate">
$('#d a')
    .css( {backgroundPosition: &quot;0 0&quot;} )
    .mouseover(function(){
        $(this).stop().animate({backgroundPosition:&quot;(0 -250px)&quot;}, {duration:500})
    })
    .mouseout(function(){
        $(this).stop().animate({backgroundPosition:&quot;(0 0)&quot;}, {duration:500})
    })
// I added these event handlers:
    .focus(function(){
        $(this).stop().animate({backgroundPosition:&quot;(0 -250px)&quot;}, {duration:500})
    })
    .blur(function(){
        $(this).stop().animate({backgroundPosition:&quot;(0 0)&quot;}, {duration:500})
    })
</pre>
<h3 id="toc-a-first-attempt-plugin">A first attempt plugin</h3>
<p>The above code as a plugin might look something like this:</p>
<pre class="brush: jscript; title: ; notranslate">
(function($) {
    $.fn.animatedBackground = function(options) {

    // build main options before element iteration by extending the default ones
    var opts = $.extend({}, $.fn.animatedBackground.defaults, options);

    function startAnimation() {
        $(this).stop().animate(
           {backgroundPosition:opts.backgroundPositionStart},
           {duration:opts.duration}
        );
    }

    function stopAnimation() {
        var animationConfig = { duration:opts.duration };
        if (opts.complete)
            animationConfig.complete = opts.complete;

        $(this).stop().animate(
            {backgroundPosition:opts.backgroundPositionEnd},
            animationConfig
        );
    }

    // for each side note, do the magic.
    return $(this)
        .css( {backgroundPosition: opts.backgroundPositionInit} )
        .mouseover(startAnimation)
        .mouseout(stopAnimation)
        .focus(startAnimation)
        .blur(stopAnimation)
    };

    // plugin defaults
    $.fn.animatedBackground.defaults = {
        backgroundPositionInit : &quot;0 0&quot;,
        backgroundPositionStart : &quot;(0 0)&quot;,
        backgroundPositionEnd : &quot;(0 0)&quot;,
        durationStart : 500,
        durationEnd : 500,
        complete : null
    };
})(jQuery);
</pre>
<p>The above is just a quick 2 minute thing &#8212; I am sure with more thought the plugin options could be made even more flexible. But this will do for the purpose of this post.</p>
<p>For each of the 4 demo menus Snook provided, you could then call them as follows:</p>
<pre class="brush: jscript; title: ; notranslate">
$(function(){
    $('#a a')
        .animatedBackground(
            {
                backgroundPositionInit : &quot;-20px 35px&quot;,
                backgroundPositionStart : &quot;(-20px 94px)&quot;,
                backgroundPositionEnd : &quot;(40px 35px)&quot;,
                durationEnd : 200,
                complete : function(){
                    $(this).css({backgroundPosition: &quot;-20px 35px&quot;});
                }
            }
        );

    $('#b a')
        .animatedBackground(
            {
                backgroundPositionStart : &quot;(-150px 0)&quot;,
                backgroundPositionEnd : &quot;(-300px 0)&quot;,
                durationEnd : 200,
                complete : function(){
                    $(this).css({backgroundPosition: &quot;0 0&quot;});
                }
            }
        );

    $('#c a, #d a')
        .animatedBackground(
            { backgroundPositionStart : &quot;(0 -250px)&quot; }
        );
});
</pre>
<p>(Examples c and d are combined with one selector, while a and b each have more complex options.)</p>
<p>In the &#8220;simple&#8221; cases (c and d) a very small amount of code is needed to use the plugin. For (a and b) if you were only going to use this once, it might be questionable whether the plugin for this is worth the effort!</p>
<h3 id="toc-unit-testable-plugin">Unit testable plugin?</h3>
<p>Some plugins might be so small that unit testing them may not seem beneficial or worth the effort. In this particular case, it is not clear if it is necessary. However, for the purpose of this post at least it may be a useful exercise. So, these might be some things to bear in mind:</p>
<ul>
<li>The bulk of the plugin relies on <code>animate()</code> which works asynchronously. Unit testing asynchronous calls can be tricky with QUnit. More importantly, we are not trying to unit test <code>animate()</code> but our plugin code instead.</li>
<li>The function handler for each mouse/focus/blur event could be made into a default plugin function</li>
<li>Unit tests can then replace the default function with a mock function to confirm that the rest of the plugin works with the various configuration options passed in.</li>
</ul>
<p>To achieve the above, a simple step might just be to make the private <code>startAnimation()</code> and <code>stopAnimation()</code> methods public.</p>
<p>This can be done a few ways, e.g. keep those private methods and make them call the public ones, or wherever the private ones are called, make them call the public ones, etc.</p>
<p>The two public methods would look something like this:</p>
<pre class="brush: jscript; title: ; notranslate">
$.fn.animatedBackground.startAnimation = function($el, opts) {
    $el.stop().animate(
        {backgroundPosition:opts.backgroundPositionEnd},
        {duration:opts.duration}
    );
}

$.fn.animatedBackground.stopAnimation = function($el, opts) {
    var animationConfig = { duration:opts.duration };
    if (opts.complete)
        animationConfig.complete = opts.complete;

    $el.stop().animate(
        {backgroundPosition:opts.backgroundPositionEnd},
        animationConfig
    );
}
</pre>
<p><a class="try-it" href="/examples/jquery/animatedBackground/jquery.animatedBackground.test.html">Here&#8217;s a page with a unit testable version of the plugin which also has the original menu examples</a></p>
<h3 id="toc-was-it-worth-adding-extra-code-to-make-it-unit-testable">Was it worth adding extra code to make it unit testable?</h3>
<p>The testable plugin version is a bit larger than the original (ignoring minification and gzipping benefits to remove a lot of the difference).</p>
<p>Was it therefore worth changing in this way from the original?</p>
<p>In my opinion, the initial plugin version would probably suffice, especially if likely to be used across a few small projects.</p>
<p>If, on the other hand, you were going to use it in a more critical scenario, then unit testing what you can could be useful.</p>
<p>A principle of test driven development is to write unit tests first. In this case as it was existing code, it seemed okay to do it in the order described above. Furthermore, sometimes it feels tricky to always stick to that principle religiously, and writing unit tests afterwords might be okay if the plugin is smallish, perhaps?</p>
<h3 id="toc-summary">Summary</h3>
<p>So, many thanks for Jonathan Snook for his post. That technique is useful for me in some other projects.</p>
<p>This post hopefully shows that even small snippets of code can be turned into a plugin, sometimes unit testable ones. Whether that is worth your efforts depends on your need and audience.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onenaught.com/posts/171/jonathan-snooks-jquery-background-animation-as-a-plugin/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Turn your jQuery code into a richer, unit testable, plugin</title>
		<link>http://www.onenaught.com/posts/85/turn-your-jquery-code-into-a-richer-unit-testable-plugin</link>
		<comments>http://www.onenaught.com/posts/85/turn-your-jquery-code-into-a-richer-unit-testable-plugin#comments</comments>
		<pubDate>Sun, 28 Sep 2008 20:07:53 +0000</pubDate>
		<dc:creator>Anup Shah</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jquery plugins]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.onenaught.com/?p=85</guid>
		<description><![CDATA[<img class="post-img" align="left" src="/wp-content/uploads/qunit.png" alt="" /> I find myself increasingly using <a href="http://jquery.com">jQuery</a> as my JavaScript framework of choice.

It's by-line of "write less, do more" really seems apt.

But sometimes, by writing just that little bit extra, you can do even more.

For example, I often try to do the following:
<ul>
	<li>Make most jQuery code into reusable plugins</li>
	<li>Use the jQuery plugin development pattern for added flexibility</li>
	<li>Use QUnit to unit test JavaScript</li>
	<li>Combine the two approaches to drive out a richer API for the plugin</li>
</ul>

By unit testing with QUnit, I find I often need to trigger additional events or add additional code from within the plugin so the test can be meaningful.

But this extra code isn't only useful for testing, it becomes a useful part of the plugin's API, improving its functionality and flexibility without sacrificing maintainability and readability of the code.

I'll try to demonstrate that in this post.]]></description>
			<content:encoded><![CDATA[<p><img class="post-img" align="left" src="http://www.onenaught.com/wp-content/uploads/qunit.png" alt="" /> I find myself increasingly using <a href="http://jquery.com">jQuery</a> as my JavaScript framework of choice.</p>
<p>It&#8217;s by-line of &#8220;write less, do more&#8221; really seems apt.</p>
<p>But sometimes, by writing just that little bit extra, you can do even more.</p>
<p>For example, I often try to do the following:</p>
<ul>
<li>Make most jQuery code into reusable plugins</li>
<li>Use the jQuery plugin development pattern for added flexibility</li>
<li>Use QUnit to unit test JavaScript</li>
<li>Combine the two approaches to drive out a richer API for the plugin</li>
</ul>
<p>By unit testing with QUnit, I find I often need to trigger additional events or add additional code from within the plugin so the test can be meaningful.</p>
<p>But this extra code isn&#8217;t only useful for testing, it becomes a useful part of the plugin&#8217;s API, improving its functionality and flexibility without sacrificing maintainability and readability of the code.</p>
<p>I&#8217;ll try to demonstrate that in this post.</p>
<h3 id="toc-make-most-of-your-jquery-code-into-reusable-plugins">Make most of your jQuery code into reusable plugins</h3>
<p>In many cases, where there is a block of jQuery code initializing something, it is a candidate for a plugin.</p>
<p>It took me a little while before I gave jquery plugins a go, thinking it will be complex and I won&#8217;t have time. But, it turns out to be really simple, elegant and useful for both simple and complicated scenarios.</p>
<h4 id="toc-example-to-create-a-dynamic-side-note-toggler">Example to create a dynamic side note toggler</h4>
<p>Lets take a simple example for illustration: suppose I have some HTML that acts as an aside, or side note, and that I want to toggle its appearance.</p>
<p>Lets say we agree this kind of HTML format for it (or microformat):</p>
<pre class="brush: xml; title: ; notranslate">
&lt;p&gt;Some text before the side note.&lt;/p&gt;

&lt;div class=&quot;side-note&quot;&gt;
	&lt;p&gt;Any HTML could go here including&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;Bulleted lists&lt;/li&gt;
		&lt;li&gt;Tabular data&lt;/li&gt;
		&lt;li&gt;Images&lt;/li&gt;
	&lt;/ul&gt;

	&lt;div class=&quot;side-note&quot;&gt;
		&lt;p&gt;Even nested side notes, if that is of any use!&lt;/p&gt;
	&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Some text after the side note.&lt;/p&gt;
</pre>
<p>The first way I&#8217;d do it might be something like this:</p>
<pre class="brush: jscript; title: ; notranslate">
$(document).ready(function() {
    $('.side-note').each(function() {
        $(this)
            .addClass('dynamic-side-note')
            .hide()
            .wrap('&lt;div class=&quot;dynamic-side-note-container&quot;&gt;&lt;/div&gt;')
            .before('&lt;h3 class=&quot;toggler&quot;&gt;&lt;a href=&quot;#&quot;&gt;Side note:&lt;/a&gt;&lt;/h3&gt;')
            .parent(0).find('&gt; h3.toggler &gt; a').click(function() {
                $(this).parents('.dynamic-side-note-container').eq(0).find('&gt; .dynamic-side-note').slideToggle();
                return false;
            });
    });
});
</pre>
<p>I could have added a click event handler to the <code>h3</code> header above, but using an anchor adds keyboard accessibility.</p>
<p>(The CSS selector could also be improved, e.g. to narrow it down to only side-notes in some content div, e.g. <code>$('#content .side-note')</code>.)</p>
<p><a class="try-it" href="/examples/jquery/side-notes/no-plugin/">Here is a working example</a></p>
<h4 id="toc-as-a-simple-jquery-plugin">As a simple jQuery plugin</h4>
<p>The above works. But, we can move most of the above code into a jQuery plugin.</p>
<p>Why bother? We can gain a bit more flexibility, such as the ability to use any selector, not rely on a <code>side-note</code> class. We could pass in other parameters such as what the text for the side note toggler/header should be, etc.</p>
<p>As a first attempt, the plugin might look something like this:</p>
<pre class="brush: jscript; title: ; notranslate">
$.fn.sideNotes = function() {
    // returning this way allows chaining
    return $(this)
        .addClass('dynamic-side-note')
        .hide()
        .wrap('&lt;div class=&quot;dynamic-side-note-container&quot;&gt;&lt;/div&gt;')
        .before('&lt;h3 class=&quot;toggler&quot;&gt;&lt;a href=&quot;#&quot;&gt;Side note:&lt;/a&gt;&lt;/h3&gt;')
        .parent(0).find('&gt; h3.toggler &gt; a').click(function() {
            $(this).parents('.dynamic-side-note-container').eq(0).find('&gt; .dynamic-side-note').slideToggle();
            return false;
        });
};
</pre>
<p>We then just need to invoke the plugin:</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery(function() {
    $('.side-note').sideNotes();
});
</pre>
<p>(Note how you could use any selector now not just <code>.side-note</code> as above.)</p>
<p><a class="try-it" href="/examples/jquery/side-notes/plugin-1-simple/">Here is a working example using the simple plugin</a></p>
<p>Plugins also make it easier to pass in more options for configuration. The next example uses a useful pattern for plugin development that also shows a nice way to handle plugin options:</p>
<h3 id="toc-use-the-jquery-plugin-development-pattern-for-added-flexibility">Use the jQuery plugin development pattern for added flexibility</h3>
<p>The post, <a href="http://www.learningjquery.com/2007/10/a-plugin-development-pattern">A Plugin Development Pattern (for jQuery)</a>, from the <a href="http://www.learningjquery.com">Learning jQuery</a> blog is really useful.</p>
<p>It provides a good way to write plugins that also get the following features:</p>
<ul>
<li>Configurability by passing in options</li>
<li>Default options to keep invoking code small and neat</li>
<li>A closure where you split your code out into manageable private functions, etc., if you need</li>
<li>Ensuring that your plugin support chaining</li>
<li>And more</li>
</ul>
<p>Using some of those ideas, here is what we might come up with for the sideNotes plugin:</p>
<pre class="brush: jscript; title: ; notranslate">
(function($) {
    $.fn.sideNotes = function(options) {

    // build main options before element iteration by extending the default ones
    var opts = $.extend({}, $.fn.sideNotes.defaults, options);

    // for each side note, do the magic.
    return $(this)
        .hide()
        .wrap('&lt;div class=&quot;dynamic-side-note&quot;&gt;&lt;/div&gt;')
        .before('&lt;h3 class=&quot;toggler&quot;&gt;&lt;a href=&quot;#&quot;&gt;' + opts.sideNoteToggleText +'&lt;/a&gt;&lt;/h3&gt;')
        .parent(0).find('&gt; h3.toggler &gt; a').click(function() {
            $(this).parents('.dynamic-side-note').eq(0).find('&gt; .side-note').slideToggle();
            return false;
        });
    };

    // plugin defaults
    $.fn.sideNotes.defaults = {
        sideNoteToggleText : 'Side note:'
    };
})(jQuery);
</pre>
<p>And invoking the plugin is the same as before:</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery(function() {
    $('.side-note').sideNotes();

    // or overriding the default side note toggle text:
    // $('.side-note').sideNotes({ sideNoteToggleText : 'As an aside:' });
});
</pre>
<p><a class="try-it" href="/examples/jquery/side-notes/plugin-2-pattern/">Here is a working example using the plugin pattern</a></p>
<h3 id="toc-unit-testing-the-jquery-plugin">Unit testing the jQuery plugin</h3>
<p>As the plugin code is reasonably well encapsulated, we can create some unit tests for this plugin. </p>
<p>Unit testing jQuery (as with any code) gives you confidence in maintaining it. For example, when refactoring code, unit tests give you confidence that you can do it without breaking things. Plugins, almost by definition are good candidates for unit testing.</p>
<h4 id="toc-examples-of-unit-tests-for-this-plugin">Examples of unit tests for this plugin</h4>
<p>Our example side note plugin is quite simple, so the unit tests will likely be small in number. Types of tests we might include are the following:</p>
<ul>
<li>Test that we can expand/collapse a side note</li>
<li>Test that we can expand/collapse a side note many times and ensure the toggle state reported is correct each time</li>
<li>Test that when the side note plugin has run, all the side notes are collapsed initially</li>
<li>Test that we can change the toggle text to something else</li>
</ul>
<p>And so on.</p>
<p>Remember, the unit tests should not test the <code>slideToggle()</code> method we happened to use (as that should be unit tested itself, and we may use other ways of toggling the side note in the future). Instead, we just need to unit test our code and plugin functionality.</p>
<p>So ideally, we might even want to &#8220;mock&#8221; the <code>slideToggle()</code>, if necessary.</p>
<h4 id="toc-use-qunit-to-unit-test-javascript">Use QUnit to unit test JavaScript</h4>
<p><a href="http://docs.jquery.com/QUnit">QUnit</a> is a unit testing framework, used internally by jQuery itself for all its core JavaScript, and now opened up and documented for others to use, too. It is a simple framework to support the creation and execution of tests.</p>
<p>The tests are run in a browser. You could automate it against all your target browsers by using something like <a href="http://selenium.openqa.org/">Selenium</a>.</p>
<p>The framework is in its early days (a setup and teardown set of methods would be nice, for example), but is rich enough to get started with it.</p>
<p><a class="try-it" href="/examples/jquery/side-notes/plugin-3-unit-tested/jquery.sideNotes.test.html">Here is a QUnit test page for the side note plugin</a></p>
<p>(I included a manual test area as this can sometimes be useful where visual confirmation is useful or automated tests of some parts is not possible/easy. Having this all in one place can be handy.)</p>
<h3 id="toc-using-unit-tests-and-plugins-helps-create-a-richer-api-for-the-plugin">Using unit tests and plugins helps create a richer API for the plugin</h3>
<p>To write testable code, you may find you need to provide more hooks in the code. Yet, you probably don&#8217;t want to pollute your code so much that it is detrimental to performance or maintainability.</p>
<h4 id="toc-triggering-events-on-the-plugin-for-added-flexibility">Triggering events on the plugin for added flexibility</h4>
<p>In the unit test example page, how did we manage to get unit tests to confirm a side note had been toggled when we didn&#8217;t have any callback for it?</p>
<p>The first idea people might have is to pass a callback that a plugin user can point to in the options when invoking the plugin, something like this:</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery(function() {
    $('.side-note').sideNotes(
        {
            toggled : function() { console.log('side note was toggled'); }
        }
    );
});
</pre>
<p>That looks useful; the unit test can provide a callback when it invokes the plugin.</p>
<p>However, that limits us to just one observer, the one that invoked the side note plugin in the first place.</p>
<p>But we can go one step further: trigger events. This allows more than one observer to watch for the event. This is achieved using jQuery&#8217;s <code>trigger()</code> and <code>bind()</code> methods.</p>
<p>By having unit tests watching for these events, it does not distort the plugin code; it enhances its API making the event useful for a real plugin user, if they need it.</p>
<p>In our side note plugin example, when we call <code>slideToggle()</code> we can trigger an event when the toggling has completed:</p>
<pre class="brush: jscript; title: ; notranslate">
// all the stuff that gets to the
// slide toggle bit comes here!
.slideToggle( function() {
    $(this).trigger('sideNoteToggled');
});
</pre>
<p>If your code cares when this happens, you can bind to this event, something like this:</p>
<pre class="brush: jscript; title: ; notranslate">
$('.side-note').bind('sideNoteToggled', eventHandlerGoesHere);
</pre>
<p>(A fuller example below uses <code>trigger()</code> to also pass the expanded/collapsed state in conjunction with some ARIA information.)</p>
<h4 id="toc-providing-default-implementations-that-can-be-replaced-or-mocked-for-unit-testing">Providing default implementations that can be replaced (or mocked for unit testing)</h4>
<p>One particular challenge I had with unit testing this side note example was that the <code>slideToggle()</code> method used by the plugin, internally runs asynchronously (using setTimeout etc).</p>
<p>Writing normal unit test code means the test can finish before the animation has run.</p>
<p>Even though I tried to use <code>setTimeout()</code> on the tests themselves to try and make them wait for the sideNote to finish toggling, and passing in the fastest speed possible to the slideToggle method, it wasn&#8217;t always right, and not consistent across all browsers.</p>
<p>This gave me the opportunity to do a few things:</p>
<ul>
<li>Encapsulate the call to slideToggle in another method</li>
<li>Make that method the default implementation, but overrideable</li>
<li>Use this to provide a mock slide toggler for testing purposes</li>
</ul>
<p>With jQuery&#8217;s plugin architecture providing a default implementation is quite straight forward:</p>
<pre class="brush: jscript; title: ; notranslate">
$.fn.sideNotes.toggle = function() {
    $(this).slideToggle(function() {
        $(this).trigger('sideNoteToggled');
    });
};
</pre>
<p>Mocking the <code>slideToggle()</code> call is nice because we don&#8217;t want to test external code in our unit tests; that should have been unit tested by whoever wrote that (the jQuery team I imagine! I&#8217;ll have to look at their unit tests when I get a moment to see how they overcome asynchronous issue &#8212; there is some mechanism to provide <code>stop()</code> and <code>start()</code> methods for AJAX testing and I tried this here, but still wasn&#8217;t getting consistent results).</p>
<p>In our example, we can overwrite the the default toggle method to simply use <code>toggle()</code> instead of <code>slideToggle()</code>, which is a non-animated version that runs and completes immediately.</p>
<p>This makes writing the testing code a bit simpler too. (There are one or two bits that I did that didn&#8217;t feel too great in my opinion, such as the way I chose to expose the post toggle action, but that is perhaps for another day to sort out!)</p>
<p>To override the default implementation, you can redefine <code>sideNotes.toggle</code> in your code, something like this:</p>
<pre class="brush: jscript; title: ; notranslate">
$.fn.sideNotes.toggle = function() {
    $(this).toggle().trigger('sideNoteToggled');
};
</pre>
<h4 id="toc-example-qunit-test-code">Example QUnit test code</h4>
<p>So taking the above considerations this is what we might have in our QUnit unit test code:</p>
<p>This code block shows a test util object to help instrument the test, and then at the bottom, an example of a mock object to replace the <code>slideToggle()</code> call.</p>
<pre class="brush: jscript; title: ; notranslate">
(function(){
    var testUtils = {
        isExpandedCount : 0,
        isCollapsedCount : 0,

        defaultTestOptions : {
            selector : '#example .side-note',
            sideNoteOptions : {},
            speed : 'fast'
        },

        // a crude setup like method, which QUnit currently doesn't have
        init : function(options) {
            testUtils.reset();

            var opts = $.extend({ sideNoteOptions : {} }, testUtils.defaultTestOptions, options);

            // tests assume the relevant HTML is present on the page the test is running
            $(opts.selector)
                .bind('sideNoteToggled', testUtils.sideNoteToggled)
                    .sideNotes(opts.sideNoteOptions);

            return $(opts.selector);
        },

        sideNoteToggled : function(event, isExpanded) {
            isExpanded ? testUtils.isExpandedCount++ : testUtils.isCollapsedCount++;

            $(event.target).trigger('sideNoteToggleCaptured');
        },

        // until there is an explicit tear down method this will have to do
        reset : function() {
            $('#example .side-note').unbind('sideNoteToggled');
            testUtils.isExpandedCount = 0;
            testUtils.isCollapsedCount = 0;
        }
    };

    // mock the slideToggle. We are not testing that.
    function mockSideNoteToggle() {
        $(this).toggle();

        $.fn.sideNotes.toggled.call(this);
    }

    // keep the original implementation if we want to use it later
    $.fn.sideNotes.originalToggler = $.fn.sideNotes.toggle;

    // override the default toggle method with the mock
    $.fn.sideNotes.toggle = mockSideNoteToggle;
})();
</pre>
<p>We can then write unit tests, such as this one (note this code would go inside the anonymous function used above):</p>
<pre class="brush: jscript; title: ; notranslate">
module(&quot;Single toggle tests&quot;);

test(&quot;Test side note is expanded when toggled&quot;, function() {
    var $sideNote = testUtils.init();

    $sideNote.each(function() {
        equals($(this).attr('aria-expanded'), 'false', &quot;Side not starts as collapsed&quot;);
    });

    $('#example')
        .find('.side-note:eq(0)').bind('sideNoteToggleCaptured', function() {
            equals(testUtils.isExpandedCount, 1, &quot;A node has been expanded&quot;);
            equals(testUtils.isCollapsedCount, 0, &quot;No nodes have been collapsed after initialization&quot;);
            equals(this['aria-expanded'], true, &quot;Node’s aria state is expanded&quot;);
        })
        .end()
            .find('.toggler &gt; a:eq(0)').click();
            // calling click() is like simulating the user action to start the test
});
</pre>
<p>In the above example, the following is happening:</p>
<ol>
<li>The call to init() creates/initializes the sideNote plugin</li>
<li>We then assert that the ARIA state reports each side note is not expanded</li>
<li>We then find each side note and bind to the sideNoteToggleCaptured event (which is raised by the unit test utility shown earlier, not by the plugin itself)</li>
<li>We then simulate a user action by finding the toggler and clicking it</li>
<li>The simulated click() makes the plugin eventually trigger the <code>sideNoteToggled</code> event, which the testUtils object will catch.</li>
<li>The test util will catch that event and update the various testing counters and itself trigger the <code>sideNoteToggleCaptured</code> event.</li>
<li>Finally at this point, we can run our assertions, such as confirming the expected number of times the side note was expanded/collapsed and what the expected ARIA state should be (in this example seen by the use of the <code>equals()</code> function).</li>
</ol>
<p><a class="try-it" href="/examples/jquery/side-notes/plugin-3-unit-tested/jquery.sideNotes.test.html">See the full example for more unit tests</a></p>
<p>The additional tests in the full example also show the side note being dynamically created per test run, so you don&#8217;t always have to have the HTML set up exactly as needed for every test, manually.</p>
<p>The unit test code in that example can probably be further improved by refactoring those test() functions into a helper function where you pass in callbacks to run when the test has completed, how many clicks you want to invoke, etc, but that is for another time!</p>
<h4 id="toc-final-plugin-code">Final plugin code</h4>
<p>Here is the final plugin code (with some additional options not discussed above):</p>
<pre class="brush: jscript; title: ; notranslate">
(function($) {
    $.fn.sideNotes = function(options) {

        // build main options before element iteration
        var opts = $.extend({}, $.fn.sideNotes.defaults, options);

        // iterate and process each matched element
        return $(this)
            .addClass('dynamic-side-note').hide()
            .attr('aria-expanded', false)
            .wrap('&lt;div class=&quot;dynamic-side-note-container&quot;&gt;&lt;/div&gt;')
            .before('&lt;' + opts.toggleElement + '&gt;&lt;a class=&quot;toggler&quot; href=&quot;#&quot;&gt;' + opts.sideNoteToggleText +'&lt;/a&gt;&lt;/' + opts.toggleElement + '&gt;')
            .parent(0)
                .find(opts.toggleElement + '.toggler &gt; a')
                    .click(doToggle);

        // example of private method
        function doToggle() {
            $(this)
                .parents('.dynamic-side-note-container').eq(0)
                    .find('&gt; .dynamic-side-note').each( function() {
                        $.fn.sideNotes.toggle.call(this, options);
                    });

            return false;
        }
    };

    // plugin defaults
    $.fn.sideNotes.defaults = {
        sideNoteToggleText : 'Side note:',
        speed : 'normal',
        toggleElement : 'h3'
    };

    // default implementation for the toggler (public. i.e. overrideable)
    $.fn.sideNotes.toggle = function(options) {
        $(this).slideToggle(options.speed, $.fn.sideNotes.toggled);
    };

    // default callback when toggle completed (public. i.e. overrideable)
    $.fn.sideNotes.toggled = function() {
        this['aria-expanded'] = this['aria-expanded'] === true ? false : true;

        $(this).trigger('sideNoteToggled', this['aria-expanded']);
    };
})(jQuery);
</pre>
<h4 id="toc-is-the-additional-lines-of-code-for-a-plugin-worth-it">Is the additional lines of code for a plugin worth it?</h4>
<p>The plugin used in the unit tested example is larger in terms of lines of code than the very first attempt, above.</p>
<p>In this case, the lines of code is still quite small, and as plugins get even larger the percentage difference is likely to be small (the size difference is more noticeable in smaller code samples, such as this contrived side note example).</p>
<p>Minimizing and gzipping JavaScript, plus using <a href="http://www.onenaught.com/posts/17/web-site-performance-expires-header">far future expires header for better caching</a> would further reduce the percentage difference in file sizes of the two approaches.</p>
<p>Depending on your needs, this may be a reasonable trade-off in return for additional flexibility.</p>
<h3 id="toc-summary">Summary</h3>
<p>So, in many cases, jQuery code can be made reusable by making it into a plugin. Any time you find yourself writing a block of code, say inside a $(document).ready() block, consider converting it into a plugin and calling it.</p>
<p>When making the plugin, consider the following:</p>
<ul>
<li>Provide various options for flexibility</li>
<li>Write unit tests to test your plugin</li>
<li>Trigger important events inside your plugin to aide unit testability, and in doing so, increase flexibility of your plugin even more.</li>
</ul>
<p>When you get the hang of this, it is probably better to write the unit tests before the actual plugin code. This will help focus on what is needed and what the plugin needs to expose in terms of capability. To be honest, at times I have found it easier to retrofit a plugin with unit tests. I probably need to be a bit more disciplined to write tests first!</p>
<p>(While there are a number of enhancements that could be added to this, the main thing I&#8217;d probably do is rename the plugin to something more generic than just a side note toggler, but I will leave that for the reader to do, and remember to refactor the unit tests accordingly!)</p>
<p>Hope that is useful?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onenaught.com/posts/85/turn-your-jquery-code-into-a-richer-unit-testable-plugin/feed</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Google to host a number of JavaScript libraries</title>
		<link>http://www.onenaught.com/posts/80/google-to-host-a-number-of-javascript-libraries</link>
		<comments>http://www.onenaught.com/posts/80/google-to-host-a-number-of-javascript-libraries#comments</comments>
		<pubDate>Wed, 28 May 2008 13:01:32 +0000</pubDate>
		<dc:creator>Anup Shah</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://www.onenaught.com/?p=80</guid>
		<description><![CDATA[<img src="http://www.onenaught.com/wp-content/uploads/js-libraries.png" alt="" class="post-img" align="left" /> <a href="http://ajaxian.com/archives/announcing-ajax-libraries-api-speed-up-your-ajax-apps-with-googles-infrastructure">Google just announced their AJAX Library API</a>, where Google will host many major JavaScript frameworks for you, such as jQuery, Prototype, Mootools, Dojo, etc.

This will allow you to write web pages that refer to those scripts rather than copies on your own site, reducing your bandwidth, but also leveraging the infrastructure capabilities of Google, such as their content distributed network (which means users would be served those files from a location much closer to them), properly compressed, minified, cacheable files, etc.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.onenaught.com/wp-content/uploads/js-libraries.png" alt="" class="post-img" align="left" /> <a href="http://ajaxian.com/archives/announcing-ajax-libraries-api-speed-up-your-ajax-apps-with-googles-infrastructure">Google just announced their AJAX Library API</a>, where Google will host many major JavaScript frameworks for you, such as jQuery, Prototype, Mootools, Dojo, etc.</p>
<p>This will allow you to write web pages that refer to those scripts rather than copies on your own site, reducing your bandwidth, but also leveraging the infrastructure capabilities of Google, such as their content distributed network (which means users would be served those files from a location much closer to them), properly compressed, minified, cacheable files, etc.</p>
<p>In addition, if your visitors have been to other sites using the same technique, they would not need to download the same libraries all over again, and with increasingly rich web sites, these files can get quite large.</p>
<p>So, if you use jQuery, you can use this in your web pages:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js&quot;&gt;&lt;/script&gt;
</pre>
<p>Of course, this is not for everyone, and it may be worth bearing in mind some <a href="http://peter.michaux.ca/article/7906">concerns</a> raised by Peter Michaux, who also provides a useful way to handle the scenario where you think access to Google from the user&#8217;s location might be restricted (e.g. blocked from a paranoid office!):</p>
<pre class="brush: xml; title: ; notranslate">
&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
  if (!jQuery) {
    // load from your own server
    document.write('&lt;script type=&quot;text/javascript&quot; src=&quot;/js/jquery.min.js&quot;&gt;&lt;\/script&gt;');
  }
&lt;/script&gt;
</pre>
<p>Still, it could be a useful technique to further improve the download/load performance for a number of sites.</p>
<p>A number of months back, Yahoo was the first to announce something like this when they said they would <a href="http://yuiblog.com/blog/2007/02/22/free-yui-hosting">host their YUI library for you</a> so it is good to see others getting into this.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.onenaught.com/posts/80/google-to-host-a-number-of-javascript-libraries/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 1.120 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-05-17 13:50:12 -->
<!-- Compression = gzip -->
