<?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>Otaqui.Com</title>
	<atom:link href="http://otaqui.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://otaqui.com/blog</link>
	<description>Pete Otaqui's blog about web development and everything else</description>
	<lastBuildDate>Fri, 11 May 2012 13:19:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Some notes about extracting (or splitting) a folder from a large repository into a git submodule</title>
		<link>http://otaqui.com/blog/1237/some-notes-about-extracting-or-splitting-a-folder-from-a-large-repository-into-a-git-submodule/</link>
		<comments>http://otaqui.com/blog/1237/some-notes-about-extracting-or-splitting-a-folder-from-a-large-repository-into-a-git-submodule/#comments</comments>
		<pubDate>Thu, 19 Apr 2012 08:39:46 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1237</guid>
		<description><![CDATA[There is a lot of great information on StackOverflow about splitting git trees into submodules. We followed this guide that suggests copying the repository and then using git-filter-branch. We are in the situation where we had quite a lot of branches (around 30) that we wanted to maintain, and many of these included commits to...  <a href="http://otaqui.com/blog/1237/some-notes-about-extracting-or-splitting-a-folder-from-a-large-repository-into-a-git-submodule/" class="more-link" title="Read Some notes about extracting (or splitting) a folder from a large repository into a git submodule">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>There is a lot of great information on StackOverflow about splitting git trees into submodules.  We followed <a href="http://stackoverflow.com/a/930286">this guide that suggests copying the repository and then using git-filter-branch</a>.</p>
<p>We are in the situation where we had quite a lot of branches (around 30) that we wanted to maintain, and many of these included commits to the main repository and the directory that we were splitting off.  We&#8217;ve discovered a few things along the way.</p>
<p><span id="more-1237"></span></p>
<ul>
<li>Make sure you&#8217;ve done as much merging as you can, and minimise the number of branches you want to move across.</li>
<li>Take this as blocking project, and assume other work can&#8217;t really continue until this change has made it to master.</li>
<li>Apply this change to all active unmerged branches asap.</li>
<li>Where branches have commits across the new submodule boundary, you may need to create and apply patches since &#8216;git merge&#8217; won&#8217;t work across the boundary, but &#8216;diff&#8217; and &#8216;patch&#8217; can.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1237/some-notes-about-extracting-or-splitting-a-folder-from-a-large-repository-into-a-git-submodule/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Project Idea: minit</title>
		<link>http://otaqui.com/blog/1230/project-idea-minit/</link>
		<comments>http://otaqui.com/blog/1230/project-idea-minit/#comments</comments>
		<pubDate>Wed, 18 Apr 2012 13:17:26 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1230</guid>
		<description><![CDATA[minit [-o project_option1 -o project_option2 val ... ] project_type project_name minit sets up projects for you, utilising native generators where available (e.g. `jasmine init`). It can also initialize cvs repositories for your project on github, bitbucket or google code; create packages on npm or jquery-plugins. Project types include: cli html5 js-jquery-plugin js-lib node-express node-module node-cli...  <a href="http://otaqui.com/blog/1230/project-idea-minit/" class="more-link" title="Read Project Idea: minit">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<pre class="brush: bash">
minit [-o project_option1 -o project_option2 val ... ] project_type project_name
</pre>
<p>minit sets up projects for you, utilising native generators where available (e.g. `jasmine init`). It can also initialize cvs repositories for your project on github, bitbucket or google code; create packages on npm or jquery-plugins.</p>
<p><span id="more-1230"></span></p>
<p>Project types include:</p>
<ul>
<li>cli</li>
<li>html5</li>
<li>js-jquery-plugin</li>
<li>js-lib</li>
<li>node-express</li>
<li>node-module</li>
<li>node-cli</li>
<li>php-silex</li>
<li>python-flask</li>
<li>ruby-sinatra</li>
</ul>
<p>Options for all projects include:</p>
<ul>
<li>&#8211;jasmine: add jasmine support</li>
<li>&#8211;local: don&#8217;t create any repositories or packages</li>
<li>&#8211;latest: try and get the development version of dependencies (like silex)</li>
</ul>
<p>minit can be configured by editing the ~/.minit file. Configuration options include repository host user details, and global options for &#8220;jasmine&#8221;, &#8220;local&#8221;, etc.</p>
<p>Why not Grunt / Make / Rake / Jake / etc?</p>
<p>Minit will *only ever generate the setup*, and then defers to the best tool for the job. It&#8217;s similar to `grunt init`, but less specific to JS. It&#8217;s clear focus is to ease the process of setting up projects, not to manage them.</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1230/project-idea-minit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Google Glass, Darkly</title>
		<link>http://otaqui.com/blog/1227/a-google-glass-darkly/</link>
		<comments>http://otaqui.com/blog/1227/a-google-glass-darkly/#comments</comments>
		<pubDate>Thu, 05 Apr 2012 10:28:49 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1227</guid>
		<description><![CDATA[Google&#8217;s &#8220;Project Glass,&#8221; the as-yet not very well explained augmented reality project, tends to incite quite a strong reaction from people. If you read through comments on the Guardian&#8217;s piece, you&#8217;ll see comments ranging from desperation to have the technology and also &#8220;I would not want to live in such a world.&#8221; I find the...  <a href="http://otaqui.com/blog/1227/a-google-glass-darkly/" class="more-link" title="Read A Google Glass, Darkly">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>Google&#8217;s &#8220;Project Glass,&#8221; the as-yet not very well explained augmented reality project, tends to incite quite a strong reaction from people.</p>
<p><span id="more-1227"></span></p>
<p>If you read through comments on the <a title="Google Project Glass" href="http://www.guardian.co.uk/world/us-news-blog/2012/apr/05/google">Guardian&#8217;s piece</a>, you&#8217;ll see comments ranging from desperation to have the technology and also &#8220;I would not want to live in such a world.&#8221;</p>
<p>I find the latter kind of comment particularly amusing &#8211; the author seems not to appreciate that engaging in a computer-mediated global discussion is exactly the kind of thing they seem to be against.</p>
<p>Augmented reality is something that has, in truth, been around a long time.  I happen to know a little bit about flying, and about the &#8220;instrument  rating&#8221; &#8211; the qualification that allows a pilot to fly at night or in bad weather.  When you are flying at night or in cloud, you can&#8217;t see the horizon and your senses can deceive you as to which way is up and what direction you are moving.  The reason that pilots don&#8217;t fly straight into the ground or mountains is that they use their instruments as an extra layer of understanding on the situation around them.  This is a fairly clear form &#8220;augmenting reality.&#8221; If you&#8217;re overly obsessed by the specifics of having such information planted right there in front of your face, rather than having to look at a dashboard, then picture the kind of HUDs (heads up displays) that have been in use in military aircraft for many years.</p>
<p>The expansion of these technologies both in scope and use, should hardly be surprising or even taken as some kind of revelatory experience.   Really an overlay on reality is a new and slick interface, and will have all sorts of uses, but the *real* revelation is having a smartphone in your pocket that (aside from the visual overlay) can more or less do everything the video demonstrates &#8211; contact people all round the world, video conference, set reminders, search localised information, and so on.</p>
<p>All that being said, I&#8217;d quite like one :)</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1227/a-google-glass-darkly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sheaf &#8211; a little library for serial Promise management</title>
		<link>http://otaqui.com/blog/1217/sheaf-a-little-library-for-serial-promise-management/</link>
		<comments>http://otaqui.com/blog/1217/sheaf-a-little-library-for-serial-promise-management/#comments</comments>
		<pubDate>Sat, 24 Mar 2012 08:56:24 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1217</guid>
		<description><![CDATA[I&#8217;ve released sheaf, a library for looping over promises in a non-concurrent fashion. It helps you treat async operations as though they were synchronous instead (but doesn&#8217;t &#8220;block&#8221;). This is useful if you want to use a series of asynchronous functions on a list of initial items, but want one series to complete before the...  <a href="http://otaqui.com/blog/1217/sheaf-a-little-library-for-serial-promise-management/" class="more-link" title="Read Sheaf &#8211; a little library for serial Promise management">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released <a href="https://github.com/pete-otaqui/sheaf">sheaf</a>, a library for looping over promises in a non-concurrent fashion. It helps you treat async operations as though they were synchronous instead (but doesn&#8217;t &#8220;block&#8221;).</p>
<p>This is useful if you want to use a series of asynchronous functions on a list of initial items, but want one series to complete before the next one starts.</p>
<p><span id="more-1217"></span></p>
<p>The use case I had which prompted writing the library was loading results from a database, generating a jsdom page from each result, and taking a screenshot of each one. With 8000 results, I really didn&#8217;t want to try running them all concurrently, but since jsdom in asynchronous, I actually wanted to wait for each item to resolve before moving on to the next.</p>
<p>Sheaf is available via <a href="http://npmjs.org">npm</a>, and also works fine in browsers. It depends on <a href="https://github.com/pete-otaqui/bond">bond</a> to provide it&#8217;s returned promise.</p>
<p>The API looks like this:</p>
<pre class="brush: javascript">

var aList = [&#039;/one.json&#039;, &#039;/two.json&#039;]
var fn1Async = function() { /* return a promise */ }
var fn2Async = function() { /* return a promise */ }
var fn3Sync = function() { /* return a value */ }
var fn4Async = function() { /* return a promise */ }

sheaf( aList, fn1Async, fn2Async, fn3Sync, fn4Async );
</pre>
<p>The first argument to sheaf is the list of things you want to loop over.  Subsequent arguments are functions that either return promises or values.  The first such function is given each items from the array as sole argument, each function after that is given the return value (or promise resolution arguments) from the previous function as parameters.</p>
<p>Each complete cycle of the functions is run through before started again on the next member of the initial array.</p>
<p>A diagram might help:</p>
<img src="https://docs.google.com/drawings/pub?id=1TggGPBZUpjIygkfsE4A98Udc0Obx8wnjD-j4034z-Og&#038;w=619&#038;h=217" alt="Sheaf's flow" />
<p>Sheaf itself returns a promise, which will notify on each iteration and resolve when all iterations are complete, e.g.</p>
<pre class="brush: javascript">

sheaf( aList, fn1Async, fn2Async, fn3Sync, fn4Async )
  .progress(function() {console.log(&#039;one loop completed&#039;, arguments})
  .done(function(newList) {console.log(&#039;all loops completed&#039;, newList)});
</pre>
<p>Since sheaf and bond are designed to work with multiple arguments, the &#8220;newList&#8221; with which the promise is resolved will be an array of arrays (one per item in the initial aList);</p>
<p>Sheaf can be useful if you want to perform even a single async function over and over again but wait for completion each time before running again.  It&#8217;s main purpose though is to loop over asynchronous chains in a non-concurrent way.  You can imagine that trying to load 8000 URLs, create 8000 DOMs pages in memory and take 8000 screenshots all at once is not a very good idea!</p>
<p>However, you probably don&#8217;t want to use this if you are responding to HTTP calls, since you never know how long these operations will take.  It would make more sense to fire off a worker process, and then return much faster.</p>
<p>As I have the time I&#8217;ll be trying to write up some more examples for sheaf, so stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1217/sheaf-a-little-library-for-serial-promise-management/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bond &#8211; a simple Promises library, available with npm</title>
		<link>http://otaqui.com/blog/1190/bond-a-simple-promises-library-available-with-npm/</link>
		<comments>http://otaqui.com/blog/1190/bond-a-simple-promises-library-available-with-npm/#comments</comments>
		<pubDate>Sat, 24 Mar 2012 06:39:45 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1190</guid>
		<description><![CDATA[I&#8217;ve released bond &#8211; a simple Promises/A implementation. The only reasons to use this library rather than something like node-promise are that it can be used in a browser as well as nodejs, it supports multiple arguments for promise callbacks (this is actually why I wrote it) and it has a cool name. Bond installation is...  <a href="http://otaqui.com/blog/1190/bond-a-simple-promises-library-available-with-npm/" class="more-link" title="Read Bond &#8211; a simple Promises library, available with npm">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released <a href="https://github.com/pete-otaqui/bond">bond</a> &#8211; a simple Promises/A implementation. The only reasons to use this library rather than something like node-promise are that it can be used in a browser as well as nodejs, it supports multiple arguments for promise callbacks (this is actually why I wrote it) and it has a cool name.</p>
<p><span id="more-1190"></span></p>
<p>Bond installation is extremely easy with <a href="http://npmjs.org">npm</a> by adding it to your package.json file and executing &#8220;npm install&#8221;.</p>
<p>It provides two equivalent options for usage &#8220;new bond.Deferred()&#8221; or &#8220;bond.defer()&#8221;. This returns a deferred object with the usual methods:</p>
<ul>
<li>my_deferred.resolve(arg1, &#8230;, argN)</li>
<li>my_deferred.reject(arg1, &#8230;, argN)</li>
<li>my_deferred.notify(arg1, &#8230;, argN)</li>
<li>my_promise = my_deferred.promise() *</li>
<li>my_promise.then(successFn, failureFn, progressFn)</li>
<li>my_promise.done(successFn)</li>
<li>my_promise.fail(failureFn)</li>
<li>my_promise.progress(progressFn)</li>
</ul>
<p>* nb &#8211; providing &#8220;promise()&#8221; as a method rather than a property violates <a href="http://wiki.commonjs.org/wiki/Promises/A">the CommonJS Promises/A spec</a>, but I&#8217;ve seen it elsewhere and prefer it.</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1190/bond-a-simple-promises-library-available-with-npm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Use tmux for code reviews</title>
		<link>http://otaqui.com/blog/1188/use-tmux-for-code-reviews/</link>
		<comments>http://otaqui.com/blog/1188/use-tmux-for-code-reviews/#comments</comments>
		<pubDate>Tue, 13 Mar 2012 18:08:44 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1188</guid>
		<description><![CDATA[If you ever do code reviews with a) more than about 3 people or b) a distributed team, you&#8217;ll know that everybody sitting around a desk is not workable all the time. A great workaround is to use &#8216;tmux&#8217; (think GNU Screen for grown ups). It instantly offers you multiple-users attached to the same session....  <a href="http://otaqui.com/blog/1188/use-tmux-for-code-reviews/" class="more-link" title="Read Use tmux for code reviews">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>If you ever do code reviews with a) more than about 3 people or b) a distributed team, you&#8217;ll know that everybody sitting around a desk is not workable all the time.</p>
<p>A great workaround is to use &#8216;tmux&#8217; (think GNU Screen for grown ups). It instantly offers you multiple-users attached to the same session.</p>
<p>[Update 2012-04-14] Even better &#8211; use <a href="https://github.com/zolrath/wemux">wemux</a>!</p>
<p><span id="more-1188"></span></p>
<p>You might, if you care about such things, want to do a bit of setup first. Assuming you&#8217;re using a *nix-based operating system (not too unlikely if tmux is an option for you) I recommend the following:</p>
<p>* Setup a single user account on a machine to be used for code reviews<br />
* Log in as that user and start tmux.<br />
* Open up a few windows and files relating to the review ready to go<br />
* Bonus points for some panes containing command line invocations; log tails; load monitors<br />
* I recommend that you use a chat mechanism out of this window, preferably with voice + typing capabilities (Skype, Google+ Hangout, whatever)<br />
* Extra bonus points if window 0 in your tmux session has a review agenda</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1188/use-tmux-for-code-reviews/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unity Launcher for Sublime Text 2</title>
		<link>http://otaqui.com/blog/1180/unity-launcher-for-sublime-text-2/</link>
		<comments>http://otaqui.com/blog/1180/unity-launcher-for-sublime-text-2/#comments</comments>
		<pubDate>Tue, 06 Mar 2012 14:59:08 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1180</guid>
		<description><![CDATA[If you&#8217;re using Ubuntu 11.10 Oneiric Ocelot, you might have noticed that it&#8217;s not straightforward to add custom launchers to the Unity Panel. This is fine as long as you only ever install software using apt-get, aptitude or the a software manager GUI. With software that isn&#8217;t in any of the repositories though, you&#8217;re a...  <a href="http://otaqui.com/blog/1180/unity-launcher-for-sublime-text-2/" class="more-link" title="Read Unity Launcher for Sublime Text 2">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re using Ubuntu 11.10 Oneiric Ocelot, you might have noticed that it&#8217;s not straightforward to add custom launchers to the Unity Panel.</p>
<p>This is fine as long as you only ever install software using apt-get, aptitude or the a software manager GUI.  With software that isn&#8217;t in any of the repositories though, you&#8217;re a little stuck &#8211; for example with Sublime Text 2.</p>
<p><span id="more-1180"></span></p>
<p>There is an unofficial repository for ST2, but I have had some bad experiences with these so try and avoid them.  I manually installed ST2 into /opt/sublimetext2 and added the following as /usr/share/applications/sublime_text.desktop:</p>
<pre style="width:100%;overflow:auto;"><code>[Desktop Entry]
Type=Application
Terminal=false
Name=Sublime Text 2
StartupNotify=true
GenericName=Text Editor
Comment=Edit text files
Exec=/opt/sublimetext-2/sublime_text %U
Icon=/opt/sublimetext-2/Icon/128x128/sublime_text.png
MimeType=text/plain;text/x-chdr;text/x-csrc;text/x-c++hdr;text/x-c++src;text/x-java;text/x-dsrc;text/x-pascal;text/x-perl;text/x-python;application/x-php;application/x-httpd-php3;application/x-httpd-php4;application/x-httpd-php5;application/xml;text/html;text/css;text/x-sql;text/x-diff;x-directory/normal;inode/directory;
Categories=GNOME;GTK;Utility;TextEditor;Application;Development;
Name[en_US]=Sublime Text 2
X-Ayatana-Desktop-Shortcuts=NewWindow;

[NewWindow Shortcut Group]
Name=New Editor Window
Exec=/opt/sublimetext-2/sublime_text --new-window
TargetEnvironment=Unity</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1180/unity-launcher-for-sublime-text-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Phone Contracts</title>
		<link>http://otaqui.com/blog/1176/phone-contracts/</link>
		<comments>http://otaqui.com/blog/1176/phone-contracts/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 09:53:36 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[shopping]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1176</guid>
		<description><![CDATA[My mobile phone contract is due for renewal. I&#8217;ve been calculating some costs and it seems that getting a &#8220;free&#8221; phone on an 18 or 24 month contract is not actually all that economical &#8211; you end up paying more than you would by buying the phone outright and then choosing a &#8220;sim-only&#8221; deal. You...  <a href="http://otaqui.com/blog/1176/phone-contracts/" class="more-link" title="Read Phone Contracts">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>My mobile phone contract is due for renewal. I&#8217;ve been calculating some costs and it seems that getting a &#8220;free&#8221; phone on an 18 or 24 month contract is not actually all that economical &#8211; you end up paying more than you would by buying the phone outright and then choosing a &#8220;sim-only&#8221; deal. You obviously also tend to get the freedom to change your deal more easily and you will get an unlocked phone that can be used with any network.</p>
<p>An exception to this rule seems to be if you get a bundle of not only mobile phone provision, but also broadband. One of the best in terms of price when you do get a bundle seems to be <a href="http://www.o2.co.uk/broadband/">O2 Broadband</a>. I also like the idea of just getting one bill. Unfortunately for me, we don&#8217;t have the BT wiring in our house so can&#8217;t get that deal.</p>
<p><span id="more-1176"></span></p>
<p>Virgin, who I get my broadband from, don&#8217;t seem to be nearly so competitive &#8211; at least in the brackets of broadband and mobile usage that I&#8217;m interested in.</p>
<p>So I&#8217;m looking at unlocked providers like <a href="http://www.clove.co.uk">Clove</a> to buy the phone and a truly budget service provider like <a href="http://www.talkmobile.co.uk">Talk Mobile</a>.</p>
<p>If you&#8217;re interested, I&#8217;m particularly looking at a &#8220;tough phone&#8221; like the Motorola Defy, or even better the Xperia Play. I currently have an iPhone and while I&#8217;ve been very happy with it, I think I&#8217;ll be able to make the jump to Android, especially since you can now use a Google Apps account as the main one, rather than only a Gmail account. I&#8217;m also very keen to try in Mozilla&#8217;s <a href="https://wiki.mozilla.org/B2G">Boot to Gecko</a> project when that reaches some level of maturity (I was very keen on HPs WebOS too, but that never took off).</p>
<p>You might guess that my requirements are a) cost and b) durability. That&#8217;s right: I&#8217;m a father.</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1176/phone-contracts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multiple jQuery instances can&#8217;t unbind each others events</title>
		<link>http://otaqui.com/blog/1115/multiple-jquery-instances-cant-unbind-each-others-events/</link>
		<comments>http://otaqui.com/blog/1115/multiple-jquery-instances-cant-unbind-each-others-events/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 10:56:05 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1115</guid>
		<description><![CDATA[If you have multiple versions (or indeed instances of the same version) of jQuery on a page, you may end up with the problem of not being able to unbind events between them. Here&#8217;s an example:]]></description>
			<content:encoded><![CDATA[<p>If you have multiple versions (or indeed instances of the same version) of jQuery on a page, you may end up with the problem of not being able to unbind events between them.</p>
<p><span id="more-1115"></span></p>
<p>Here&#8217;s an example:</p>
<script>document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')

document.write('<div id=\"gist-1267113\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"cp\">&lt;!DOCTYPE html&gt;<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"nt\">&lt;html&gt;<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;head&gt;<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;title&gt;<\/span>Multiple jQuery Hell<span class=\"nt\">&lt;/title&gt;<\/span><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;script <\/span><span class=\"na\">src=<\/span><span class=\"s\">&quot;jquery-1.6.3.min.js&quot;<\/span><span class=\"nt\">&gt;&lt;/script&gt;<\/span><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;script&gt;<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"c1\">// keep a reference to jQuery 1.6.3, and clear the name from the global scope<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">jQuery163<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">jQuery<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">jQuery<\/span><span class=\"p\">.<\/span><span class=\"nx\">noConflict<\/span><span class=\"p\">(<\/span><span class=\"kc\">true<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;/script&gt;<\/span><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;script <\/span><span class=\"na\">src=<\/span><span class=\"s\">&quot;jquery-1.6.4.min.js&quot;<\/span><span class=\"nt\">&gt;&lt;/script&gt;<\/span><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;script&gt;<\/span><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"c1\">// keep a reference to jQuery 1.6.4, and clear the name from the global scope<\/span><\/div><div class=\'line\' id=\'LC14\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">jQuery164<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">jQuery<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC15\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">jQuery<\/span><span class=\"p\">.<\/span><span class=\"nx\">noConflict<\/span><span class=\"p\">(<\/span><span class=\"kc\">true<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC16\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;/script&gt;<\/span><\/div><div class=\'line\' id=\'LC17\'><br/><\/div><div class=\'line\' id=\'LC18\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;script&gt;<\/span><\/div><div class=\'line\' id=\'LC19\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"c1\">// check that we have two distinct jQueries<\/span><\/div><div class=\'line\' id=\'LC20\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">jQuery163<\/span><span class=\"p\">().<\/span><span class=\"nx\">jquery<\/span><span class=\"p\">);<\/span> <span class=\"c1\">// 1.6.3<\/span><\/div><div class=\'line\' id=\'LC21\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">jQuery164<\/span><span class=\"p\">().<\/span><span class=\"nx\">jquery<\/span><span class=\"p\">);<\/span> <span class=\"c1\">// 1.6.4<\/span><\/div><div class=\'line\' id=\'LC22\'><br/><\/div><div class=\'line\' id=\'LC23\'><br/><\/div><div class=\'line\' id=\'LC24\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"c1\">// we could use either for the onDomReady bit ...<\/span><\/div><div class=\'line\' id=\'LC25\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">jQuery163<\/span><span class=\"p\">(<\/span><span class=\"kd\">function<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC26\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"c1\">// bind a click event callback<\/span><\/div><div class=\'line\' id=\'LC27\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">jQuery163<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;a&#39;<\/span><span class=\"p\">).<\/span><span class=\"nx\">bind<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;click&#39;<\/span><span class=\"p\">,<\/span> <span class=\"kd\">function<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC28\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;clicky!&#39;<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC29\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">});<\/span><\/div><div class=\'line\' id=\'LC30\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"c1\">// now try and unbind it<\/span><\/div><div class=\'line\' id=\'LC31\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">jQuery164<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;a&#39;<\/span><span class=\"p\">).<\/span><span class=\"nx\">unbind<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;click&#39;<\/span><span class=\"p\">);<\/span> <span class=\"c1\">// this doesn&#39;t unbind the click event callback<\/span><\/div><div class=\'line\' id=\'LC32\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">});<\/span><\/div><div class=\'line\' id=\'LC33\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;/script&gt;<\/span><\/div><div class=\'line\' id=\'LC34\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;/head&gt;<\/span><\/div><div class=\'line\' id=\'LC35\'><br/><\/div><div class=\'line\' id=\'LC36\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;body&gt;<\/span><\/div><div class=\'line\' id=\'LC37\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;h1&gt;<\/span>Multiple jQuery Hell<span class=\"nt\">&lt;/h1&gt;<\/span><\/div><div class=\'line\' id=\'LC38\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;a<\/span> <span class=\"na\">href=<\/span><span class=\"s\">&quot;#&quot;<\/span><span class=\"nt\">&gt;<\/span>Clicky<span class=\"nt\">&lt;/a&gt;<\/span><\/div><div class=\'line\' id=\'LC39\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;/body&gt;<\/span><\/div><div class=\'line\' id=\'LC40\'><span class=\"nt\">&lt;/html&gt;<\/span><\/div><div class=\'line\' id=\'LC41\'><br/><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1267113/8d9e58d2020e2c02ecee46b7797f7996f6e495f8/multiple_jquery_hell.html\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1267113#file_multiple_jquery_hell.html\" style=\"float:right;margin-right:10px;color:#666\">multiple_jquery_hell.html<\/a>\n            <a href=\"https://gist.github.com/1267113\">This Gist<\/a> brought to you by <a href=\"http://wordpress.org/extend/plugins/github-gist/\">GitHub Gist WordPress Plugin<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')
</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1267113/multiple_jquery_hell.html&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1115/multiple-jquery-instances-cant-unbind-each-others-events/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stop console.log causing errors in IE6 and other browsers</title>
		<link>http://otaqui.com/blog/1079/stop-console-log-causing-errors-in-ie6-and-other-browsers/</link>
		<comments>http://otaqui.com/blog/1079/stop-console-log-causing-errors-in-ie6-and-other-browsers/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 09:13:26 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1079</guid>
		<description><![CDATA[You know what it&#8217;s like &#8230; you leave a console.log buried somewhere in your code, and the error that causes in IE stops your javascript from running. Well, this little snippet will create a fake copy of the Firebug API if it can&#8217;t find a window.console.]]></description>
			<content:encoded><![CDATA[<p>You know what it&#8217;s like &#8230; you leave a console.log buried somewhere in your code, and the error that causes in IE stops your javascript from running.  Well, this little snippet will create a fake copy of the Firebug API if it can&#8217;t find a window.console.</p>
<p><span id="more-1079"></span></p>
<script>document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')

document.write('<div id=\"gist-1234379\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><br/><\/div><div class=\'line\' id=\'LC2\'><span class=\"cm\">/**<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"cm\"> * Create a fake console api, mimicing Firebug.<\/span><\/div><div class=\'line\' id=\'LC4\'><span class=\"cm\">*/<\/span><\/div><div class=\'line\' id=\'LC5\'><span class=\"p\">(<\/span><span class=\"kd\">function<\/span><span class=\"p\">(<\/span><span class=\"nx\">global<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"kd\">var<\/span> <span class=\"nx\">noop<\/span> <span class=\"o\">=<\/span> <span class=\"kd\">function<\/span><span class=\"p\">(){};<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">if<\/span> <span class=\"p\">(<\/span> <span class=\"o\">!<\/span><span class=\"nx\">global<\/span><span class=\"p\">[<\/span><span class=\"s1\">&#39;console&#39;<\/span><span class=\"p\">]<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">global<\/span><span class=\"p\">.<\/span><span class=\"nx\">console<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">log<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">debug<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">info<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">warn<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">error<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC14\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">assert<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC15\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">clear<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC16\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">dir<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC17\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">dirxml<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC18\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">trace<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC19\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">group<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC20\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">groupCollapsed<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC21\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">groupEnd<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC22\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">time<\/span><span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC23\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">timeEnd<\/span><span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC24\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">profile<\/span><span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC25\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">profileEnd<\/span><span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC26\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">count<\/span><span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC27\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">exception<\/span><span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><span class=\"p\">,<\/span><\/div><div class=\'line\' id=\'LC28\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nx\">table<\/span><span class=\"o\">:<\/span> <span class=\"nx\">noop<\/span><\/div><div class=\'line\' id=\'LC29\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC30\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC31\'><span class=\"p\">})(<\/span><span class=\"nb\">window<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC32\'><br/><\/div><div class=\'line\' id=\'LC33\'><br/><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1234379/370a74da3b3fcfcf1bfc1d5641fdc75430b656f9/fake_console.js\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1234379#file_fake_console.js\" style=\"float:right;margin-right:10px;color:#666\">fake_console.js<\/a>\n            <a href=\"https://gist.github.com/1234379\">This Gist<\/a> brought to you by <a href=\"http://wordpress.org/extend/plugins/github-gist/\">GitHub Gist WordPress Plugin<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')
</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1234379/fake_console.js&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1079/stop-console-log-causing-errors-in-ie6-and-other-browsers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Javascript Validator Library &#8211; Validator.js</title>
		<link>http://otaqui.com/blog/1076/simple-javascript-validator-library-validator-js/</link>
		<comments>http://otaqui.com/blog/1076/simple-javascript-validator-library-validator-js/#comments</comments>
		<pubDate>Sun, 14 Aug 2011 05:58:36 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1076</guid>
		<description><![CDATA[I had a need to do some data validation in javascript, and all the libraries I looked at seemed quite opinionated about *what* you were going to validate &#8211; i.e. form data &#8211; let alone the increase in server-side javascript in the last couple of years. My data wasn&#8217;t directly tied to a form, so...  <a href="http://otaqui.com/blog/1076/simple-javascript-validator-library-validator-js/" class="more-link" title="Read Simple Javascript Validator Library &#8211; Validator.js">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>I had a need to do some data validation in javascript, and all the libraries I looked at seemed quite opinionated about *what* you were going to validate &#8211; i.e. form data &#8211; let alone the increase in server-side javascript in the last couple of years. My data wasn&#8217;t directly tied to a form, so it didn&#8217;t quite seem worthwhile trying to shoe horn my needs into what the libraries expected, and I could also see a need for a validation library that could be adapted for Node.</p>
<p>Enter <a href="https://pete-otaqui.github.com/Validator.js">Validator.js</a>.</p>
<p>Validator&#8217;s only dependency is on <a href="http://documentcloud.github.com/underscore.js">underscore.js</a> from Document Cloud.</p>
<p>Validator has two usage forms: the first for very quick and simple one-off cases:</p>
<pre class="brush: javascript">
// Simple use:
var result
result = Validator.isEmail(&#039;not_an_email&#039;);
console.log(result); // false
result = Validator.isEmail(&#039;joe@example.com&#039;);
console.log(result); // true
</pre>
<p>I found this on its own quite a lot more flexible than most of the form-driven libraries out there.  However, I also wanted to be able to create more complex sets of validations to run on a piece of data.  For that case, you create an instance of Validator and use it&#8217;s add() method:</p>
<pre class="brush: javascript">
var result,
    myValidator

myValidator = new Validator();

myValidator.add(&#039;unique&#039;);
myValidator.add(&#039;minLength&#039;, 6);

result = myValidator.validate( [1, 2, 3, 4, 5, 6, 6] );
console.log(result); // false, the array is long enough but contains non-unique members
</pre>
<p>This got me a fair bit closer to what I wanted, but you don&#8217;t know which part failed, so it&#8217;s harder to give reasonable feedback. I added a set of error messages to validator instances which gets populated after a call to validate():</p>
<pre class="brush: javascript">
var result,
    myValidator

myValidator = new Validator();

myValidator.add(&#039;unique&#039;);
myValidator.add(&#039;minLength&#039;, 6);
myValidator.add(&#039;maxLength&#039;, 8);

result = myValidator.validate( [1, 2, 3, 4, 5, 6, 6, 8, 9, 10] );
console.log(result); // false, the array is long enough but contains non-unique members
console.log(myValidator.errors);
/*
myValidator.errors == [
    &#039;The list must be made up of unique items&#039;,
    &#039;The list is too long&#039;
]
*/
</pre>
<p>Again, this is pretty good but even though Validator supports adding messages in any language you want and falling back (by default) to English (see the source code), default error messages still aren&#8217;t always what you need.  I also added the ability to set a custom error message per &#8220;validation&#8221;.</p>
<pre class="brush: javascript">
var result,
    myValidator

myValidator = new Validator();

myValidator.add(&#039;unique&#039;).message(&#039;You are repeating yourself&#039;);
myValidator.add(&#039;minLength&#039;, 6).message(&#039;Too tiny!&#039;);
myValidator.add(&#039;maxLength&#039;, 8).message(&#039;Too bloated!&#039;);

result = myValidator.validate( [1, 2, 3, 4, 5, 6, 6, 8, 9, 10] );
console.log(result); // false, the array is long enough but contains non-unique members
console.log(myValidator.errors);
/*
myValidator.errors == [
    &#039;You are repeating yourself&#039;,
    &#039;Too bloated!&#039;
]
*/
</pre>
<p>You can also chain calls to add() and message():</p>
<pre class="brush: javascript">
var result,
    myValidator

myValidator = new Validator();

myValidator.add(&#039;unique&#039;).message(&#039;You are repeating yourself&#039;)
    .add(&#039;minLength&#039;, 6).message(&#039;Too tiny!&#039;)
    .add(&#039;maxLength&#039;, 8).message(&#039;Too bloated!&#039;);
</pre>
<p>I&#8217;ve added some code which should make it easy to use this as a CommonJS AMD javascript module.  In it&#8217;s default form you can just include it with a script tag.</p>
<p>If you&#8217;re interested in developing Validator itself, the project is tested with <a href="http://pivotal.github.com/jasmine/">Jasmine</a> and documented with <a href="http://code.google.com/p/jsdoc-toolkit/">JSDoc</a>.  Both of these can be run with Rake, and the easiest way to get setup is to use <a href="http://gembundler.com/">Bundler</a>.  Once you&#8217;ve got the dependencies you get three rake tasks:</p>
<pre class="brush: bash">
# Start the jasmine server, and open http://localhost:8888/ to run the test suite:
$ rake jasmine
# Start the jasmine server and also run a browser through the tests automatically:
$ rake jasmine:ci
# Generate the docs
$ rake jsdoc
</pre>
<p>If you fork the project and add any more validations, please also add tests and docs.</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1076/simple-javascript-validator-library-validator-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing remote (PHP) websites with Capybara, Cucumber, Mechanize, Selenium 2 Webdriver &#8230; and SauceLabs</title>
		<link>http://otaqui.com/blog/1072/testing-remote-php-websites-with-capybara-cucumber-mechanize-selenium-2-webdriver-and-saucelabs/</link>
		<comments>http://otaqui.com/blog/1072/testing-remote-php-websites-with-capybara-cucumber-mechanize-selenium-2-webdriver-and-saucelabs/#comments</comments>
		<pubDate>Thu, 11 Aug 2011 14:40:16 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[capybara]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1072</guid>
		<description><![CDATA[This is more or less the perfect setup for me, and it lets us run our tests against our PHP web application using the very fast mechanize driver where possible, and for tests that require javascript we can use either the &#8220;normal&#8221; selenium driver in capybara, or send the tests off to your local grid,...  <a href="http://otaqui.com/blog/1072/testing-remote-php-websites-with-capybara-cucumber-mechanize-selenium-2-webdriver-and-saucelabs/" class="more-link" title="Read Testing remote (PHP) websites with Capybara, Cucumber, Mechanize, Selenium 2 Webdriver &#8230; and SauceLabs">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>This is more or less the perfect setup for me, and it lets us run our tests against our PHP web application using the very fast mechanize driver where possible, and for tests that require javascript we can use either the &#8220;normal&#8221; selenium driver in capybara, or send the tests off to your local grid, or even send them off to Sauce Labs where we want to cover more platforms and versions than we have setup locally.</p>
<p>https://gist.github.com/1139797</p>
<p><script src="https://gist.github.com/1139797.js"> </script></p>
<p>Next step &#8230; running the tests in parallel!</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1072/testing-remote-php-websites-with-capybara-cucumber-mechanize-selenium-2-webdriver-and-saucelabs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Conway&#8217;s Game of Life in Javascript</title>
		<link>http://otaqui.com/blog/1020/building-conways-game-of-life-in-javascript/</link>
		<comments>http://otaqui.com/blog/1020/building-conways-game-of-life-in-javascript/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 12:00:06 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1020</guid>
		<description><![CDATA[As part of an interesting exercise at work, I built an implementation of Conway&#8217;s Game Of Life in Javascript. If you haven&#8217;t come across the Game Of Life, it&#8217;s really quite interesting and worth looking at. My colleagues also made variations, including canvas-based and Web GL 3 dimensional (there was even discussion about n-dimensional, with...  <a href="http://otaqui.com/blog/1020/building-conways-game-of-life-in-javascript/" class="more-link" title="Read Building Conway&#8217;s Game of Life in Javascript">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>As part of an interesting exercise at work, I built an implementation of <a href="http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Conway&#8217;s Game Of Life</a> in Javascript.  If you haven&#8217;t come across the Game Of Life, it&#8217;s really quite interesting and worth looking at.  My colleagues also made variations, including canvas-based and Web GL 3 dimensional (there was even discussion about n-dimensional, with sliders to view the 4th, 5th and further dimensions).  My particular take was to make the game space &#8220;infinite&#8221; rather than a fixed grid.</p>
<p>It&#8217;s not really infinite of course, I haven&#8217;t made any attempt to have a position greater than Number.MAX_VALUE.  The real point is that it is possible to have a huge playing area, and only the living &#038; possibly-living-next-round cells are taken into account.</p>
<p>I avoided using any ready-made frameworks, in part so that it could be transported to the server-side on top of something like <a href="http://nodejs.org">NodeJS</a> &#8211; I was imagining a multi-player game where each user could &#8220;paint&#8221; cells onto the canvas, and maybe even that next-generation cells would take an identifier from their parents, letting people &#8220;fight&#8221;.  I haven&#8217;t really got the time for that at the moment, but it seemed a nice idea.</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1020/building-conways-game-of-life-in-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting a reference to an unselected radiobutton (using jQuery)</title>
		<link>http://otaqui.com/blog/1033/getting-a-reference-to-an-unselected-radiobutton-using-jquery/</link>
		<comments>http://otaqui.com/blog/1033/getting-a-reference-to-an-unselected-radiobutton-using-jquery/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 11:59:09 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1033</guid>
		<description><![CDATA[The &#8220;change&#8221; event on a radiobutton input only fires when it becomes selected. If you want to trigger some behaviour on an unselected radiobutton, then you have to bind to the change event of the radiogroup, which you can do like so: &#60;ul&#62; &#60;li&#62; &#60;input id=&#34;r1&#34; name=&#34;something&#34; type=&#34;radio&#34; value=&#34;basic&#34; /&#62; &#60;label for=&#34;r1&#34;&#62;Basic&#60;/label&#62; &#60;/li&#62; &#60;li&#62; &#60;input...  <a href="http://otaqui.com/blog/1033/getting-a-reference-to-an-unselected-radiobutton-using-jquery/" class="more-link" title="Read Getting a reference to an unselected radiobutton (using jQuery)">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>The &#8220;change&#8221; event on a radiobutton input only fires when it becomes selected.  If you want to trigger some behaviour on an unselected radiobutton, then you have to bind to the change event of the radiogroup, which you can do like so:</p>
<pre class="brush: html">
&lt;ul&gt;
  &lt;li&gt;
    &lt;input id=&quot;r1&quot; name=&quot;something&quot; type=&quot;radio&quot; value=&quot;basic&quot; /&gt;
    &lt;label for=&quot;r1&quot;&gt;Basic&lt;/label&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;input id=&quot;r2&quot; name=&quot;something&quot; type=&quot;radio&quot; value=&quot;standard&quot; /&gt;
    &lt;label for=&quot;r2&quot;&gt;Standard&lt;/label&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;input id=&quot;r3&quot; name=&quot;something&quot; type=&quot;radio&quot; value=&quot;advanced&quot; /&gt;
    &lt;label for=&quot;r3&quot;&gt;Advanced&lt;/label&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;script&gt;
$(&quot;input[name=&#039;inputName&#039;]&quot;).change(function(ev) {

});
&lt;/script&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1033/getting-a-reference-to-an-unselected-radiobutton-using-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RTL Input text with large text-indent value &#8220;magically scrolls&#8221; in Opera</title>
		<link>http://otaqui.com/blog/1028/rtl-input-text-with-large-text-indent-value-magically-scrolls-in-opera/</link>
		<comments>http://otaqui.com/blog/1028/rtl-input-text-with-large-text-indent-value-magically-scrolls-in-opera/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 16:32:31 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1028</guid>
		<description><![CDATA[This is a pretty weird browser bug. Opera RTL Scrolly Text Indent Bug. If your content is RTL and you are using the large text-indent CSS property on an input tag (so that you can use a background image, while keeping the text invisible to most users but still available to screen readers) you get...  <a href="http://otaqui.com/blog/1028/rtl-input-text-with-large-text-indent-value-magically-scrolls-in-opera/" class="more-link" title="Read RTL Input text with large text-indent value &#8220;magically scrolls&#8221; in Opera">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>This is a pretty weird browser bug.</p>
<p><a href="http://otaqui.com/code/opera-rtl-scrolly-text-indent/">Opera RTL Scrolly Text Indent Bug</a>.</p>
<p>If your content is RTL and you are using the large text-indent CSS property on an input tag (so that you can use a background image, while keeping the text invisible to most users but still available to screen readers) you get a couple of odd behaviours in Opera:</p>
<ol>
<li>The text is not indented.  Well ok, that&#8217;s at least a &#8220;normal&#8221; kind of bug.</li>
<li>If you right-click on the button, and leave the menu open for a few seconds, the text <em><strong>magically starts scrolling out of the way</strong></em>.</li>
</ol>
<p>I&#8217;ve submitted a bug report to Opera.  I&#8217;d be interested if anyone else is seeing the same behaviour, or any related RTL weirdness.</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1028/rtl-input-text-with-large-text-indent-value-magically-scrolls-in-opera/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript EventEmitter Redux, now on github</title>
		<link>http://otaqui.com/blog/1025/javascript-eventemitter-redux-now-on-github/</link>
		<comments>http://otaqui.com/blog/1025/javascript-eventemitter-redux-now-on-github/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 14:37:00 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1025</guid>
		<description><![CDATA[I&#8217;ve added some more features to the EventEmitter mixin (like actually working listener removal) and posted it to github: EventEmitter on github It&#8217;s fairly simple to use &#8230; something like this: var MyKlass = function() {}; EventEmitter.augment(MyKlass.prototype); /** * Show me * * @fires shown */ MyKlass.prototype.showMe = function() { this.trigger(&#039;shown&#039;, {&#039;visible&#039;:true}); } var myInstance...  <a href="http://otaqui.com/blog/1025/javascript-eventemitter-redux-now-on-github/" class="more-link" title="Read Javascript EventEmitter Redux, now on github">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve added some more features to the EventEmitter mixin (like actually working listener removal) and posted it to github:</p>
<p><a href="https://github.com/pete-otaqui/EventEmitter">EventEmitter on github</a></p>
<p>It&#8217;s fairly simple to use &#8230; something like this:</p>
<pre class="brush: javascript">
var MyKlass = function() {};
EventEmitter.augment(MyKlass.prototype);

/**
 * Show me
 *
 * @fires shown
 */
MyKlass.prototype.showMe = function() {
  this.trigger(&#039;shown&#039;, {&#039;visible&#039;:true});
}

var myInstance = new MyKlass();
myInstance.on(&#039;shown&#039;, function(e) {
  console.log(e.visible);
}
myInstance.showMe();
</pre>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1025/javascript-eventemitter-redux-now-on-github/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding Vertical Split support to GNU Screen in Mac OS X Snow Leopard</title>
		<link>http://otaqui.com/blog/1011/adding-vertical-split-support-to-gnu-screen-in-mac-os-x-snow-leopard/</link>
		<comments>http://otaqui.com/blog/1011/adding-vertical-split-support-to-gnu-screen-in-mac-os-x-snow-leopard/#comments</comments>
		<pubDate>Thu, 06 Jan 2011 09:27:44 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[command-line]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=1011</guid>
		<description><![CDATA[Evan Meagher supplies a great patch to the source of GNU Screen which adds vertical split support on OS X. This is really useful, since so many displays are widescreen these days, and it also means you can create a reasonable dashboard with screen. The patch has worked without a hitch for me so far....  <a href="http://otaqui.com/blog/1011/adding-vertical-split-support-to-gnu-screen-in-mac-os-x-snow-leopard/" class="more-link" title="Read Adding Vertical Split support to GNU Screen in Mac OS X Snow Leopard">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://evanmeagher.net/2010/12/patching-screen-with-vertical-split-in-os">Evan Meagher supplies a great patch</a> to the source of GNU Screen which adds vertical split support on OS X.</p>
<p>This is really useful, since so many displays are widescreen these days, and it also means you can create a reasonable dashboard with screen.  The patch has worked without a hitch for me so far.</p>
<p>Thanks Evan!</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/1011/adding-vertical-split-support-to-gnu-screen-in-mac-os-x-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript EventEmitter Mixin</title>
		<link>http://otaqui.com/blog/953/javascript-eventemitter-mixin/</link>
		<comments>http://otaqui.com/blog/953/javascript-eventemitter-mixin/#comments</comments>
		<pubDate>Mon, 15 Nov 2010 21:18:58 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=953</guid>
		<description><![CDATA[/** * EventEmitter Mixin * * Designed to be used in conjunction with a mixin &#34;augment&#34; function, * such as http://chamnapchhorn.blogspot.com/2009/05/javascript-mixins.html * * @usage augment(MyClass, EventEmitter); * my_inst = new MyClass(); * my_inst.on(&#039;someEvent&#039;, function(e){ console.dir(e); }); * my_inst.trigger(&#039;someEvent&#039;, {eventProp:&#039;value&#039;}); */ var EventEmitter = function() {}; EventEmitter.prototype.on = function(name, callback, context) { if ( !context )...  <a href="http://otaqui.com/blog/953/javascript-eventemitter-mixin/" class="more-link" title="Read Javascript EventEmitter Mixin">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<pre class="brush: javascript">
/**
 * EventEmitter Mixin
 *
 * Designed to be used in conjunction with a mixin &quot;augment&quot; function,
 * such as http://chamnapchhorn.blogspot.com/2009/05/javascript-mixins.html
 *
 * @usage augment(MyClass, EventEmitter);
 * my_inst = new MyClass();
 * my_inst.on(&#039;someEvent&#039;, function(e){ console.dir(e); });
 * my_inst.trigger(&#039;someEvent&#039;, {eventProp:&#039;value&#039;});
 */
var EventEmitter = function() {};
EventEmitter.prototype.on = function(name, callback, context) {
  if ( !context ) context = this;
  if ( !this._listeners ) this._listeners = {};
  if ( !this._listeners[name] ) this._listeners[name] = [];
  var f = function(e) { callback.apply(context, [e]); };
  this._listeners[name].push(f);
};
EventEmitter.prototype.trigger = function(name, event) {
  if ( !this._listeners ) this._listeners = {};
  if ( !this._listeners[name] ) return;
  var i = this._listeners[name].length;
  while ( i-- ) this._listeners[name][i](event);
};
EventEmitter.prototype.removeListener = function(name, callback) {
  if ( !this._listeners ) this._listeners = {};
  if ( !this._listeners[name] ) return;
  var i = this._listeners[name].length;
  while ( i-- ) {
    if ( this._listeners[name][i] === callback ) {
      this._listeners[name].splice(i, 1);
    }
  }
};
</pre>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/953/javascript-eventemitter-mixin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Started work on jQuery UI Modal widget</title>
		<link>http://otaqui.com/blog/919/started-work-on-jquery-ui-modal-widget/</link>
		<comments>http://otaqui.com/blog/919/started-work-on-jquery-ui-modal-widget/#comments</comments>
		<pubDate>Wed, 13 Oct 2010 14:26:49 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=919</guid>
		<description><![CDATA[I&#8217;ve started working a jQuery UI Modal widget, for use in a project built on top of the widget library. We have very high accessibility standards, and the current &#8220;{modal:true}&#8221; option for the dialog widget unfortunately wasn&#8217;t as good as we needed. Seeing that the team had identified the need for a standalone Modal widget,...  <a href="http://otaqui.com/blog/919/started-work-on-jquery-ui-modal-widget/" class="more-link" title="Read Started work on jQuery UI Modal widget">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve started working a jQuery UI Modal widget, for use in a project built on top of the widget library.</p>
<p>We have very high accessibility standards, and the current &#8220;{modal:true}&#8221; option for the dialog widget unfortunately wasn&#8217;t as good as we needed.  Seeing that the team had identified the need for <a href="http://wiki.jqueryui.com/Modal">a standalone Modal widget</a>, the team thought we could try and get the ball rolling.</p>
<p>You can see the work in progress here in <a href="http://github.com/pete-otaqui/jquery-ui/blob/master/ui/jquery.ui.modal.js">the modal widget in my fork of jquery ui</a>.</p>
<p>I&#8217;ve also been having <a href="http://forum.jquery.com/topic/refactoring-dialog-overlay-in-preparation-for-modal-better-keyboard-accessibility">a discssion about the modal widget</a> with Scott Gonzalez of the jQuery UI team.</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/919/started-work-on-jquery-ui-modal-widget/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSSP: Loading CSS with Javascript &#8211; and getting an onload callback.</title>
		<link>http://otaqui.com/blog/890/cssp-loading-css-with-javascript-and-getting-an-onload-callback/</link>
		<comments>http://otaqui.com/blog/890/cssp-loading-css-with-javascript-and-getting-an-onload-callback/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 14:16:18 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[Professional]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://otaqui.com/blog/?p=890</guid>
		<description><![CDATA[It seems fairly straightforward to require CSS with Javascript. The most obvious method that I thought of was creating a &#60;link&#62; tag and appending it to the head of the document. An alternative would be to load the text of the css file with an ajax XHR call, and then inject that into a &#60;style&#62;...  <a href="http://otaqui.com/blog/890/cssp-loading-css-with-javascript-and-getting-an-onload-callback/" class="more-link" title="Read CSSP: Loading CSS with Javascript &#8211; and getting an onload callback.">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>It seems fairly straightforward to require CSS with Javascript.  The most obvious method that I thought of was creating a &lt;link&gt; tag and appending it to the head of the document. An alternative would be to load the text of the css file with an ajax XHR call, and then inject that into a &lt;style&gt; tag.</p>
<p>These are both fine for most cases, but what about a situation where you have a hard dependency on the css for the javascript to work correctly?  You could take a best-guess at a wait time for the CSS to load, or even set the XHR to be synchronous &#8211; however both of these are very poor for both actual and perceived performance of your page (and the former may simply fail).</p>
<p>When might this be the case?  Let&#8217;s say you have some asynchronously loaded javascript that is intended to create a widget on the page, something like this (which assumes you are using jQuery as your dom library):</p>
<pre class="brush: javascript">

function moveLargePanels() {
    // make a panel container for large panels
    $(&#039;&lt;div id=&quot;largePanelContainer&quot;&gt;&lt;/div&gt;&#039;)
        .appendTo(&#039;body&#039;);
    $(&#039;.panel&#039;).each( function(i, panel) {
        if ( panel.outerWidth() &gt; 300 ) {
            panel.appendTo(&#039;#largePanelContainer&#039;);
        }
    }
}
</pre>
<p>And some corresponding CSS:</p>
<pre class="brush: css">
.panel {
    border:1px solid #000;
    padding: 20px;
}
</pre>
<p>The idea here is that, since there is some interaction between the logic in the javascript (a test for the &#8220;outerWidth&#8221;) and the styling in the CSS (setting the padding) that the javascript can only work correctly once the CSS has been loaded and applied.</p>
<p>This should be fine right?  Start the javascript and the css loading, and have events attached to the load of each letting you know when everything is ready and it&#8217;s safe to fire &#8220;moveLargePanels()&#8221;.  Wrong, or at least tricky, and essentially impossible if the CSS is loaded from a different domain to the hosting webpage.</p>
<p>You can get James Burke&#8217;s excellent description of this problem here:<br />
<a href="http://requirejs.org/docs/faq-advanced.html#css">http://requirejs.org/docs/faq-advanced.html#css</a><br />
And a first pass at solving this (in some browsers) here:<br />
<a href="http://bugs.dojotoolkit.org/ticket/5402">http://bugs.dojotoolkit.org/ticket/5402</a></p>
<p>Burke mentions a using a &#8220;well known&#8221; style rule to test whether the style is loaded.  I suggest a standard pattern for the rule, and also a mechanism for dynamically setting it.</p>
<h2>Enter CSSP</h2>
<p>You may have heard of <a href="http://remysharp.com/2007/10/08/what-is-jsonp/">JsonP</a> &#8211; a way of serving dynamically generated JSON which is padded with a method call (the method name is supplied in the query string of the URL), which allows for cross domain loading of javascript.  The idea behind CSSP is similar &#8211; it defines a pattern for loading css cross domain.  Instead of wrapping in a callback though, we can use the URL query string mechanism to supply the special &#8220;test rule&#8221; that we use.</p>
<h3>Dynamic Rule Pattern</h3>
<p>Given this url:</p>
<p>http://someserver.com/stylefile.css?cssp=123456</p>
<pre class="brush: php">
.panel { ... }
.largePanelsContainer { .. }

/* and the special rule: */
cssp { zIndex:123456; }
</pre>
<p>So, in whatever loader we want to build, we can add something like this (n.b. this isn&#8217;t tested code):</p>
<pre class="brush: javascript">
var cssp_counter = 0;
function loadCss(url, callback, className, zIndex) {
    // create a counter for special class names, so they are unique
    className = className || &#039;cssp&#039; + (cssp_counter++);
    zIndex = zIndex || 123456;
    url = url + &#039;?&#039; + className + &#039;=&#039; + zIndex;
    $(&#039;&lt;link&gt;&#039;)
        .attr({
            rel: &quot;stylesheet&quot;,
            type: &quot;text/css&quot;,
            href: url
        .appendTo(&#039;head&#039;);
    // append a dummy div to the body for the test
    var div = $(&#039;&lt;div&gt;&lt;/div&gt;&#039;)
        .addClass(className)
        .appendTo(&#039;body&#039;);
    // now poll for the z-index value:
    var cssp_interval = setInterval( function() {
        // if the zIndex is applied, we know the css has loaded
        if ( div.css(&#039;zIndex&#039;) == zIndex ) {
            div.remove();
            // callback:
            callback();
            clearInterval( cssp_interval );
        }
    }, 100);

}
</pre>
<p>The code above to do the loading and fire a callback is very naive.  It would be much better to have an event that can have listeners added, and to have some tests and some failure management like a maximum timeout.</p>
<h3>Default Rule Pattern</h3>
<p>This obviously presupposes that the CSS is dynamically generated to some degree, even just by adding the special rule to an otherwise static file.  I think that an alternative to the performance-conscious would be a &#8220;default&#8221; special rule, based on the css filename.  This needs some thought, and could well be tied to a build-step in your deployment process (you do have one, right?).  The pattern comes in two parts:</p>
<ul>
<li>There is a standard zIndex that is always used.</li>
<li>The filename includes the &#8220;special class name&#8221; that is used within.</li>
</ul>
<p>For example:</p>
<p>Given the file: <strong>styles.fhddgso9j.css</strong></p>
<pre class="brush: css">
.someclass { ... }
.otherclass { ... }

/* and the special rule */
.fhddgso9j { z-index: 123456; }
</pre>
<p>The javascript to go alone with this might look something like:</p>
<pre class="brush: javascript">
var cssp_counter = 0;
function loadCss(url, callback) {
    // create a counter for special class names, so they are unique
    className = getSpecialClassName(url);
    zIndex = 123456;
    $(&#039;&lt;link&gt;&#039;)
        .attr({
            rel: &quot;stylesheet&quot;,
            type: &quot;text/css&quot;,
            href: url
        .appendTo(&#039;head&#039;);
    // append a dummy div to the body for the test
    var div = $(&#039;&lt;div&gt;&lt;/div&gt;&#039;)
        .addClass(className)
        .appendTo(&#039;body&#039;);
    // now poll for the z-index value:
    var cssp_interval = setInterval( function() {
        // if the zIndex is applied, we know the css has loaded
        if ( div.css(&#039;zIndex&#039;) == zIndex ) {
            div.remove();
            // callback:
            callback();
            clearInterval( cssp_interval );
        }
    }, 100);
}
function getSpecialClassName(url) {
  // get just the filename, e.g. &quot;styles.9ufosdfij.css&quot;
  var filename = url.substring( url.lastIndexOf(&#039;/&#039;)+1, url.length);
  // split on the &quot;.&quot; marks
  var parts = filename.split(&#039;.&#039;);
  // assume it will be the second-to-last part (since the last should be &quot;css&quot;)
  var className = parts[ parts.length-2 ];
  return className;
}
</pre>
<p>As noted above, this naive, untested code.</p>
<h2>Wrapping Up</h2>
<p>Ideally I&#8217;d like any &#8220;css loader&#8221; to use actual browser events (or properties) where possible, and to fallback on this setup as a last resort.</p>
<p>If I get time I&#8217;ll implement this and put the code on github.  Please do get in touch if you&#8217;d like to pair on this!</p>
]]></content:encoded>
			<wfw:commentRss>http://otaqui.com/blog/890/cssp-loading-css-with-javascript-and-getting-an-onload-callback/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

