<?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>patspam &#187; Javascript</title>
	<atom:link href="http://blog.patspam.com/category/comp/javascript/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.patspam.com</link>
	<description>patspam patspam patspam</description>
	<lastBuildDate>Fri, 18 Jun 2010 23:44:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=880</generator>
		<item>
		<title>Plack Apps in Javascript</title>
		<link>http://blog.patspam.com/2010/plack-apps-in-javascript</link>
		<comments>http://blog.patspam.com/2010/plack-apps-in-javascript#comments</comments>
		<pubDate>Thu, 17 Jun 2010 16:03:40 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://blog.patspam.com/?p=1384</guid>
		<description><![CDATA[Love Plack web apps but feel like writing some Javascript today instead of Perl? # app.psgi use Plack::App::JSP; Plack::App::JSP-&#62;new( js =&#62; q{ [ 200, [ 'Content-type', 'text/html' ], [ 'Hello, World!' ] ] }); # displays: Hello, World! Given the similarities between Perl and JSON you can&#8217;t actually tell if I&#8217;m cheating or not from [...]]]></description>
			<content:encoded><![CDATA[<p>Love <a href="http://plackperl.org/">Plack web apps</a> but feel like writing some Javascript today instead of Perl?</p>
<pre class="brush: perl;">
# app.psgi
use Plack::App::JSP;
Plack::App::JSP-&gt;new( js =&gt; q{
[ 200, [ 'Content-type', 'text/html' ], [ 'Hello, World!' ] ]
});

# displays: Hello, World!
</pre>
<p>Given the similarities between Perl and JSON you can&#8217;t actually tell if I&#8217;m cheating or not from the above snippet. </p>
<p>Let&#8217;s try something more convincing:</p>
<pre class="brush: perl;">
Plack::App::JSP-&gt;new( js =&gt; q{
function respond(body) {
    return [ 200, [ 'Content-type', 'text/html' ], [ body ] ]
}

respond(&quot;Five factorial is &quot; +
    (function(x) {
      if ( x&lt;2 ) return 1;
      return x * arguments.callee(x - 1);
    })(5)
);
});

# displays: Five factorial is 120
</pre>
<p>I just pushed <a href="http://search.cpan.org/perldoc?Plack::App::JSP">Plack::App::JSP</a> to the CPAN.<br />
Thanks to Salvador Ortiz and Miguel Ibarra whose recently released <a href="http://search.cpan.org/perldoc?JSP">JSP</a> module makes this possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.patspam.com/2010/plack-apps-in-javascript/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Shout-out to the translators</title>
		<link>http://blog.patspam.com/2010/shout-out-to-the-translators</link>
		<comments>http://blog.patspam.com/2010/shout-out-to-the-translators#comments</comments>
		<pubDate>Wed, 12 May 2010 19:10:10 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://blog.patspam.com/?p=1362</guid>
		<description><![CDATA[This morning I had an email from someone in the ExtJS community letting me know that they&#8217;d translated my Extending Ext Components article into German. I had a look and all of my ExtJS articles have been translated into at least one other language. My record is Playing With ExtJS The Easy Way which has [...]]]></description>
			<content:encoded><![CDATA[<p>This morning I had an email from someone in the ExtJS community letting me know that they&#8217;d translated my <a href="http://www.extjs.com/learn/Manual:Component:Extending_Ext_Components">Extending Ext Components</a> article into German. I had a look and <a href="http://www.extjs.com/learn/Manual:RESTful_Web_Services">all</a> <a href="http://www.extjs.com/learn/Manual:Ext_Source_Overview">of</a> <a href="http://www.extjs.com/learn/Manual:Intro:Patterns:Flyweight">my</a> <a href="http://www.extjs.com/learn/Manual:Intro:Inheritance">ExtJS</a> <a href="http://www.extjs.com/learn/Manual:Core:Working_with_JSON">articles</a> <a href="http://www.extjs.com/learn/Tutorial:Playing_With_Ext_The_Easy_Way">have</a> been translated into at least one other language. My record is <a href="http://www.extjs.com/learn/Tutorial:Playing_With_Ext_The_Easy_Way">Playing With ExtJS The Easy Way</a> which has been translated into 10 different languages: Deutsch, Chinese,  Korean,  Japanese, French, Russian, Spanish, Turkish, Portuguese and Hungarian. Page views of the English versions of these articles are just about to tick over the 500,000 mark.</p>
<p>Recently <a href="http://search.cpan.org/perldoc?Padre::Plugin::Plack">Padre::Plugin::Plack</a>, my <a href="http://plackperl.org">Plack</a> (the Perl Web Server) plugin for <a href="http://padre.perlide.org/">Padre</a> (the Perl IDE) was translated into Dutch, Brazilian Portuguese and French.</p>
<p>I always get such a buzz when I find out that something I&#8217;ve worked on has been translated into another language. It sends a clear message that someone found your work useful enough to go to the effort of translating it so that a new community of people could use it. That&#8217;s an awesome form of positive feedback, and a great motivator for being involved in open source software.</p>
<p>Thanks translators!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.patspam.com/2010/shout-out-to-the-translators/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Plack helps with Javascript development too</title>
		<link>http://blog.patspam.com/2009/plack-helps-with-javascript-development-too</link>
		<comments>http://blog.patspam.com/2009/plack-helps-with-javascript-development-too#comments</comments>
		<pubDate>Fri, 18 Dec 2009 19:23:36 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[Comp]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://blog.patspam.com/?p=1291</guid>
		<description><![CDATA[Today I was debugging a Javascript bug in ExtJS + AIR, and I wanted to check rendering in another browser. I created a static html file with the minimal javascript test case embedded in it, but then realised that I needed to load in the ExtJS files from somewhere. With other JS libraries you can [...]]]></description>
			<content:encoded><![CDATA[<p>Today I was debugging a Javascript bug in ExtJS + AIR, and I wanted to check rendering in another browser. I created a static html file with the minimal javascript test case embedded in it, but then realised that I needed to load in the ExtJS files from somewhere. With other JS libraries you can use <a href="http://code.google.com/apis/ajaxlibs/">freely available CDNs</a> for this sort of thing, but because ExtJS has funky ideas about licensing, this isn&#8217;t an option. What I needed was a quick and easy way to serve up the ExtJS files, which were sitting in a folder on my computer, over http. This sort of thing happens frequently with custom code too, when you attempt to create a static (minimal test case) version of a live site.</p>
<p>Plack has a really neat solution to this problem.</p>
<p>Following a tip from <a href="http://advent.plackperl.org/2009/12/day-5-run-a-static-file-web-server-with-plack.html">day #5 of Miyagawa&#8217;s Plack advent calendar</a>, serving up the current directory over http is as simple as this Perl one-liner:</p>
<pre class="brush: bash;">

$ plackup -MPlack::App::Directory -e 'Plack::App::Directory-&gt;new

Plack::Server::Standalone: Accepting connections at http://0:5000/
</pre>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 91px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">$ plackup -MPlack::App::Directory -e &#8216;Plack::App::Directory-&gt;new&#8217;Plack::Server::Standalone: Accepting connections at http://0:5000/$ plackup -MPlack::App::Directory -e &#8216;Plack::App::Directory-&gt;new&#8217;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 91px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Plack::Server::Standalone: Accepting connections at http://0:5000/</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 91px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"># Or if you need the files over port 80:</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 91px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">$ sudo plackup -MPlack::App::Directory -e &#8216;Plack::App::Directory-&gt;new&#8217; -p 80</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 91px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Plack::Server::Standalone: Accepting connections at http://0:80/</div>
<p>Or if you need the files served over port 80:</p>
<pre class="brush: bash;">

$ sudo plackup -MPlack::App::Directory -e 'Plack::App::Directory-&gt;new' -p 80

Plack::Server::Standalone: Accepting connections at http://0:80/
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.patspam.com/2009/plack-helps-with-javascript-development-too/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tarpo now on GitHub</title>
		<link>http://blog.patspam.com/2009/tarpo-now-on-github</link>
		<comments>http://blog.patspam.com/2009/tarpo-now-on-github#comments</comments>
		<pubDate>Mon, 30 Nov 2009 01:57:41 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[Air]]></category>
		<category><![CDATA[Comp]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://blog.patspam.com/?p=1277</guid>
		<description><![CDATA[At about 11pm on the night before I headed off for the States, Ted the Vet and I sat down to talk Tarpo. In case you&#8217;re wondering, Tarpo is an open source, cross platform Data Management desktop application for Dog Health programs in rural and remote Indigenous Australian communities, written entirely in Javascript. The last [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;"><a href="http://blog.patspam.com/wp-content/uploads/2009/11/tarpo.jpg"><img class="aligncenter size-medium wp-image-1279" title="Tarpo Logo" src="http://blog.patspam.com/wp-content/uploads/2009/11/tarpo-267x300.jpg" alt="Tarpo Logo" width="267" height="300" /></a></p>
<p style="text-align: left;">At about 11pm on the night before I headed off for the States, Ted the Vet and I sat down to talk <a href="http://pdonelan.github.com/tarpo">Tarpo</a>.</p>
<p>In case you&#8217;re wondering, Tarpo is an open source, cross platform Data Management desktop application for <a href="http://www.amrric.org/">Dog Health programs in rural and remote Indigenous Australian communities</a>, written entirely in Javascript.</p>
<p>The last time I <a href="http://blog.patspam.com/2008/tarpo">blogged about Tarpo</a> was way back in April 2008, and since then I haven&#8217;t really touched the code, but in the meantime Ted and his team of helpers have used it to record several thousand House Visits, Medical and Surgical Cases as part of the Maningrida Dog Health program.</p>
<p>Several other Veterinarians have started expressing interest in using Tarpo for their own Dog Health programs, and needless to say, we&#8217;ve accumulated a long list of bugs and feature requests over the past 18 months. So this afternoon, with a bit of spare time up my sleeve, I decided to get the ball rolling again.</p>
<p>Tarpo now has a proper project page, which you can visit at: <a href="http://pdonelan.github.com/tarpo/">http://pdonelan.github.com/tarpo</a></p>
<p>As you can see from the url, the code now lives on GitHub. Apart from the front page which has the all-important &#8220;Install Tarpo&#8221; button, the most important page on the GitHub project page is the <a href="http://github.com/pdonelan/tarpo/issues">Issue Tracker</a>, which I&#8217;m hoping Ted and other Vets will use to report all Bugs and Feature requests. With a bit of luck, that will also make it easier for other developers to get involved too.</p>
<p>With these things in place, I started attacking the bit rot. Firstly I had to install <a href="http://aptana.com">Aptana</a> and the Adobe Air plugin, which took several hours and reminded me how much I prefer doing development in <a href="http://padre.perlide.org">Padre</a>! On a side note, I spent a few hours trying to think if there was some way I could rewrite the entire app in Perl (I like Javascript in a twisted sort of way, but I&#8217;d rather ditch Adobe Air since it&#8217;s a proprietary framework) &#8211; but in the end I decided to stuck with the existing architecture, at least for now.</p>
<p>I though about doing it as a <a href="http://wxperl.sourceforge.net">wxPerl</a> app (like Padre), but I&#8217;d hate to lose the HTML widget set that <a href="http://extjs.com">ExtJS</a> gives me.. hmm that gets me thinking (help me out if you&#8217;re reading Gábor or any of the other Padre gurus..) does wxPerl have a modern embedded browser that I could use? Maybe webkit-based one..? Then the backend could be rewritten as a standalone <a href="http://plackperl.org/">Plack</a>-powered webapp and I&#8217;d have all of CPAN at my disposal.. hmm maybe that&#8217;s too ambitious, but it does feel like the sort of thing you *should* be able to do with Perl..</p>
<p>I didn&#8217;t have much time left to do any real coding after that, except for updating a few dependencies so that Tarpo at least starts up ok on the latest version of Adobe Air (a small victory). But at least now in a position to start attacking the <a href="http://github.com/pdonelan/tarpo/issues">ticket list</a>, which means that real progress can&#8217;t be too far off..</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.patspam.com/2009/tarpo-now-on-github/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WebGUI Carousel Wobject</title>
		<link>http://blog.patspam.com/2009/webgui-carousel-wobject</link>
		<comments>http://blog.patspam.com/2009/webgui-carousel-wobject#comments</comments>
		<pubDate>Mon, 06 Apr 2009 06:41:32 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[WebGUI]]></category>

		<guid isPermaLink="false">http://blog.patspam.com/?p=1111</guid>
		<description><![CDATA[There&#8217;s a new wobject coming in the latest WebGUI beta (version 7.7.3), called Carousel. On the surface, it&#8217;s a nice little integration between WebGUI and YUI, but below the surface it&#8217;s a great multi-purpose tool for rendering content dynamically in Javascript or Flash. It&#8217;s a common requirement to want to display rich text via Javascript [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="size-full wp-image-1114 aligncenter" title="Carousel Wobject" src="http://blog.patspam.com/wp-content/uploads/2009/04/mailgooglecom.jpeg" alt="Carousel Wobject" width="322" height="192" /></p>
<p>There&#8217;s a new wobject coming in the latest WebGUI beta (version 7.7.3), called Carousel. On the surface, it&#8217;s a nice little integration between WebGUI and YUI, but below the surface it&#8217;s a great multi-purpose tool for rendering content dynamically in Javascript or Flash.</p>
<p>It&#8217;s a common requirement to want to display rich text via Javascript or Flash. For example you might have a clickable diagram that shows different text depending on what part of the diagram a user clicks on.</p>
<p>Giving content managers access to the dynamic text can be rather cumbersome. In the worst case scenario the text is hard-coded in the Flash or Javascript source, out of reach of the content manager. Better solutions are where you have a bunch of editable Articles or Snippets that the Flash or Javascript reads from.</p>
<p>None of these solutions are very satisfactory though, because as far as the content manager is concerned the dynamic object is a single asset, and they really want a simple way to edit all of the text elements from the same place.</p>
<p>We designed the new Wobject specifically for this scenario. The Edit Screen of the wobject allows content managers to add as many rich text editor (RTE) boxes as they like (dynamically, a la FilePile). These RTEs are displayed one after the other on a single screen, allowing the content manager to edit all of the text in a single place. For each RTE, the content manager can also specify a unique ID.</p>
<p><a href="http://blog.patspam.com/wp-content/uploads/2009/04/carousel-edit.png"><img class="alignnone size-medium wp-image-1112" title="carousel-edit" src="http://blog.patspam.com/wp-content/uploads/2009/04/carousel-edit-300x225.png" alt="carousel-edit" width="300" height="225" /></a></p>
<p>By default, the template for the Carousel wobject renders your RTE items into an attractive YUI Carousel widget:</p>
<p><a href="http://blog.patspam.com/wp-content/uploads/2009/04/carousel-view.png"><img class="alignnone size-medium wp-image-1113" title="carousel-view" src="http://blog.patspam.com/wp-content/uploads/2009/04/carousel-view-300x38.png" alt="carousel-view" width="300" height="38" /></a></p>
<p>The Wobject template does this by looping over all of the RTEs and generating markup expected by the YUI Carousel widget. This has the nice side-effect of allowing your widget to gracefully degrade in non-js browsers.</p>
<p>Taking a step back, we have a WebGUI wobject that lets us manipulate a collection of RTEs. The only part of the wobject specific to the YUI Carousel is the template. Let&#8217;s have a look at it:</p>
<pre class="brush: xml;">
&lt;div class=&quot;yui-skin-sam&quot;&gt;

...

&lt;tmpl_if item_loop&gt;
&lt;div id=&quot;&lt;tmpl_var assetId&gt;&quot;&gt;
&lt;ol&gt;
 &lt;tmpl_loop item_loop&gt;
	&lt;li class=&quot;item&quot; id=&quot;&lt;tmpl_var itemId&gt;&quot;&gt;
 &lt;tmpl_var text&gt;&lt;/li&gt;
&lt;/tmpl_loop&gt;&lt;/ol&gt;
&lt;/div&gt;
&lt;script&gt;
 YAHOO.util.Event.onDOMReady(function (ev) {
 var carousel = new YAHOO.widget.Carousel(&quot;&lt;tmpl_var assetId&gt;&quot;, {
 isCircular: true,
 numVisible: 1,
 animation: { speed: 0.5 }
 });
 carousel.render(); // get ready for rendering the widget
 carousel.show();   // display the widget
 });
 &lt;/script&gt;

&lt;/tmpl_if&gt;&lt;/div&gt;
&lt;/script&gt;
</pre>
<p>We can just as easily create our own template to do something else with the data. Returning to our original example, say you want to use the RTE text in a Flash diagram. All you have to do is change the template to output the contents of each RTE into a textarea dom element, styled to be hidden from view, with the id attribute set to the RTE unique id. Then, your Flash (or Javascript for that matter) can easily read in the rich text via DOM methods (e.g. <em>document.getElementById(RTE_unique_id).value</em>) and display it dynamically and/or do whatever it likes with it.</p>
<p>For example, we might use a template such as:</p>
<pre class="brush: xml;">

&lt;tmpl_loop item_loop&gt;
 &lt;textarea id=&quot;&lt;tmpl_var itemId&gt;&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;tmpl_var text&gt;&lt;/textarea&gt;
 &lt;/tmpl_loop&gt;
</pre>
<p>The only coordination required is that the person deploying the wobject would need to know how many text blocks the flash/javascript expects, and what unique ids to use.  For some flash/javascript widgets you could ignore unique ids altogether by adding a special class attribute to the generated textareas and then using a class selector to dynamically select all matching textareas on the page.</p>
<p>This should make it easier to use dynamic flash/javascript widgets in WebGUI whilst still retaining the power and ease of use of a content management system.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.patspam.com/2009/webgui-carousel-wobject/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The curse of console.log</title>
		<link>http://blog.patspam.com/2009/the-curse-of-consolelog</link>
		<comments>http://blog.patspam.com/2009/the-curse-of-consolelog#comments</comments>
		<pubDate>Fri, 03 Apr 2009 06:19:12 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://blog.patspam.com/?p=1068</guid>
		<description><![CDATA[Here&#8217;s a common scenario, you&#8217;re on-site demonstrating some fancy new Javascript interface you&#8217;ve written, only to discover that some part of it that was working so beautifully on your dev box inexplicably breaks. hmm you think, must be a bloody IE bug. You try it in Firefox.. it still doesn&#8217;t work, what the?! Later that [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a common scenario, you&#8217;re on-site demonstrating some fancy new Javascript interface you&#8217;ve written, only to discover that some part of it that was working so beautifully on your dev box inexplicably breaks. hmm you think, must be a bloody IE bug. You try it in Firefox.. it still doesn&#8217;t work, what the?!</p>
<p>Later that day you get home and on a hunch run a quick search through your source tree:</p>
<p><em>&gt; ack  &#8216;console.log&#8217;<br />
www/extras/wobject/Survey/dd.js<br />
96:console.log(destEl);</em></p>
<p>The culprit is Firebug&#8217;s console.log() function. The damn thing is just too handy. So handy that a few years ago the collective web development community abandoned alert() as the #1 debugging weapon of choice. Now we all use console.log(). Forget the firebug debugger, nobody can be bothered bringing up their js source in the script tab and clicking the break button or setting a watch variable, that&#8217;s like, 4 clicks too many man! Whack in a of <em>console.log(a, b, c)</em>s and it&#8217;s all there, plain as day in the firebug console, ready to be clicked on and examined further  in the DOM tab.</p>
<p>Until you forget that not everyone in the world runs firebug. Hard to believe, I know. But actually, the problem occurs for anyone who hasn&#8217;t got the firebug console turned on for YOUR SITE. The problem being of course that you probably always have the firebug console turned on for your site, but no-one else in the world does. So the likelihood of being bitten are pretty high.</p>
<p>Of course, there are lots of workarounds. One approach is to just define console.log as an empty function (and while you&#8217;re at it, you may as well define all the other Firebug functions too):</p>
<pre class="brush: jscript;">

if (!(&quot;console&quot; in window) || !(&quot;firebug&quot; in console)) {
 var names = [&quot;log&quot;, &quot;debug&quot;, &quot;info&quot;, &quot;warn&quot;, &quot;error&quot;, &quot;assert&quot;, &quot;dir&quot;, &quot;dirxml&quot;, &quot;group&quot;, &quot;groupEnd&quot;, &quot;time&quot;, &quot;timeEnd&quot;, &quot;count&quot;, &quot;trace&quot;, &quot;profile&quot;, &quot;profileEnd&quot;];
 window.console = {};
 for (var i = 0, len = names.length; i &lt; len; ++i) {
 window.console[names[i]] = function(){};
 }
}
</pre>
<p>In my case the code was part of a drag and drop method used in <a href="http://webgui.org">WebGUI</a>. And like all sane web projects, WebGUI oursources its cross-browser Javascript concerns to a library (in our case YUI). And it turns out YUI has a perfectly good logger of its own, guaranteed to be available on any page that YUI is loaded onto. Hello <em>YAHOO.log();</em></p>
<p>Now, &#8220;YAHOO.log&#8221; is 1 letter shorter than &#8220;console.log&#8221;, so why does everyone end up using console.log() all the same? Maybe they don&#8217;t like typing in upper-case. More probably they noticed that when they use YAHOO.log(&#8216;blah&#8217;); nothing appears in the firebug console. What gives? Well, you need to tell YAHOO to pass on log  messages to the console, that&#8217;s what. Type the following line first, and everything will work out just fine:</p>
<pre class="brush: jscript;">

YAHOO.widget.Logger.enableBrowserConsole();
</pre>
<p>Of course, that&#8217;s a lot more letters than just typing console.log(), and what&#8217;s more you need to use YAHOO.lang.dump() to serialise objects passed to log() (no nice firebug object examination), which admittedly is a lot less fun. But it does mean a little less broken code in production.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.patspam.com/2009/the-curse-of-consolelog/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UTF8, JSON, Perl, and MySQL (guess where this is heading..)</title>
		<link>http://blog.patspam.com/2009/utf8-json-perl-and-mysql-guess-where-this-is-heading</link>
		<comments>http://blog.patspam.com/2009/utf8-json-perl-and-mysql-guess-where-this-is-heading#comments</comments>
		<pubDate>Tue, 27 Jan 2009 05:47:51 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://blog.patspam.com/?p=1055</guid>
		<description><![CDATA[Today I learned a little bit about UTF8 in the context of JSON, Perl and MySQL. Recently one of my clients who was using the Survey wobject in WebGUI noticed their modperl server grinding to a halt. Funny how one little decision can trigger such a catastrophic failure. Funny in the sense that it takes [...]]]></description>
			<content:encoded><![CDATA[<p>Today I learned a little bit about UTF8 in the context of JSON, Perl and MySQL.</p>
<p>Recently one of my clients who was using the Survey wobject in WebGUI noticed their modperl server grinding to a halt. Funny how one little decision can trigger such a catastrophic failure. Funny in the sense that it takes you a few days to repair the damage and track down the root cause of the problem.</p>
<p>The reason modperl was grinding to a halt was easy enough to find &#8211; child processes chewing up as much memory as they could whenever a web request touched a Survey instance. The cause of <em>that</em> was also quickly apparent.. one of the text fields in a Survey instance was filled with ~150Mb of rubbish data. The smoking gun looked like this:</p>
<p style="padding-left: 30px;"><strong>In contrast to obsessions, your worries don\x{c3}\x{83}\x{c2}\x{83}\x{c3}\x{82}\x{c2}&#8230;</strong></p>
<p>An apostrophe in the text and then BAM! everything goes haywire (that <em>\x{blah}</em> unicode text goes on for 150Mb..)</p>
<p>Turns out the user who triggered the problem was cutting and pasting text from Microsoft Word. As anyone who has worked with people who cut and paste text from Word into content management systems knows, Word uses non-ASCII characters for &#8220;smart quotes&#8221;, apostrophes, dashes, triple periods, etc.. Those non-ASCII characters usually show up in HTML as garbage characters. In this case it looked like those characters were causing the Survey internals to break.</p>
<p>On closer inspection Survey was breaking as follows: any non-ASCII text was converted to a few garbage characters. On the next view/edit, each of these garbage characters were turned into a few more garbage characters, and so on.. which meant that in no time at all the web server had ground to a halt and the Survey table was weighing in at hundreds of Mb. Fun!</p>
<p>Now, I knew that JSON was supposed to be UTF8 encoded, and Survey serialises its data to JSON, so somewhere along the way the JSON string/Perl String/MySQL string encoding was breaking.</p>
<p>Best practices in WebGUI dictate that you work with JSON as non-encoded, non-binary, Perl UTF8 strings and then let wg modules such as WebGUI::Session::Form do the encoding for you (via the Encode module). Most of the time you don&#8217;t need to care if a string in Perl is UTF8 or not, and doing things this way means that most of the time you can remain blissfully unaware of what&#8217;s happening under the hood.</p>
<p>In accordance with this, Survey uses <a href="http://search.cpan.org/~makamaka/JSON-2.12/lib/JSON.pm">JSON</a>::to_json/from_json everywhere. On a hunch I switched all the from_json calls to decode_json, which expects a binary, UTF8-encoded string instead of a non-binary string, and voila, the problem disappeared. So somewhere along the way our JSON-encoded string was being converted to a binary string. The question was: where?</p>
<p>The plot thickened when I noticed that calling Encode::decode_utf8() immediately after reading the string from mysql also removed the issue (decode_utf8 turns a binary UTF8 string into a non-binary utf8 string).</p>
<p>With the help of perlmonkey2 and perlDreamer on #webgui, we found the root cause.. the json-encoded string was being stored in a mysql field of type <strong>longblob</strong> as opposed to a non-binary type (such as text, mediumtext, etc..). Something was transparently converting it to a binary UTF-encoded string (perhaps DBD::mysql?), and when  Survey then pulled this binary string out the database, it was trying to use from_json() to decode it (which expects a non-binary string).</p>
<p>A quick change to the field type:</p>
<p style="padding-left: 30px;"><strong>alter table Survey modify surveyJSON long</strong></p>
<p>and all was well again with the universe, but if you&#8217;d asked me 4 hours ago what mysql field type should be used for json my first thought would probably have been a binary type, because all I knew was the JSON is UTF8 encoded. A little bit of knowledge can be a dangerous thing..</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.patspam.com/2009/utf8-json-perl-and-mysql-guess-where-this-is-heading/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The halting problem in Javascript</title>
		<link>http://blog.patspam.com/2008/the-halting-problem-in-javascript</link>
		<comments>http://blog.patspam.com/2008/the-halting-problem-in-javascript#comments</comments>
		<pubDate>Wed, 10 Sep 2008 04:39:53 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://blog.patspam.com/?p=1054</guid>
		<description><![CDATA[I&#8217;ve been getting a lot out of The Little Schemer recently. It&#8217;s an amazingly little book. One topic covered is the Halting Problem which I first came across back when I was studying Theory of Computation at university. The authors use Scheme throughout the book, but I thought it&#8217;d be useful to translate the discussion [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been getting a lot out of <a href="http://www.amazon.com/Little-Schemer-Daniel-P-Friedman/dp/0262560992/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1221018132&amp;sr=1-1">The Little Schemer</a> recently. It&#8217;s an amazingly little book. One topic covered is the <a href="http://en.wikipedia.org/wiki/Halting_problem">Halting Problem</a> which I first came across back when I was studying Theory of Computation at university. The authors use Scheme throughout the book, but I thought it&#8217;d be useful to translate the discussion into Javascript since Javascript is quite accessible for newcomers to functional programming.</p>
<p>Some functions always return a value. For example, the following simple function always returns the value of PI:</p>
<pre class="brush: jscript;">
function pi(){
    return Math.PI;
}
</pre>
<p>Some functions go into infinite loops and never halt. For example, the following function enters a while loop and never comes out:</p>
<pre class="brush: jscript;">
function eternity(){
    while(true) {
        // goodbye, cruel world
    }
}
</pre>
<p>Wouldn&#8217;t it be nice to be able to tell ahead of time whether a function is going to halt or go into an infinite loop? (cue evil laughter from the computer scientists in the back row)</p>
<p>Let&#8217;s write a function that tells us whether another function halts. (It&#8217;s easy to write functions that take other functions as arguments in Javascript because it&#8217;s a <a href="http://en.wikipedia.org/wiki/Functional_programming">functional programming language</a>). What would such a function look like?</p>
<pre class="brush: jscript;">
function halts(fn){ // takes one argument, fn (a function)
    // code that determines if fn halts goes here
}
</pre>
<p>We&#8217;re not sure yet what code to put into the function body, but let&#8217;s start by looking at what we know about this function. It has to return <strong>True</strong> or <strong>False</strong>. <strong>True</strong> if the argument fn halts and returns a value, <strong>False</strong> if not. Simple right?</p>
<p>Let&#8217;s try out halts() on some functions we&#8217;ve already talked about to get a feel for how it&#8217;s supposed to work.</p>
<pre class="brush: jscript;">
halts(pi); // returns true because pi() halts
halts(eternity); // returns false because eternity() doesn't halt
</pre>
<p>So far so good. Ok, let&#8217;s create one last function just for fun and see how halts() goes.</p>
<pre class="brush: jscript;">
function maybe() {
    if (halts(maybe)) {
        eternity(); // never ends..
    } else {
        return &quot;ok I halted!&quot;;
    }
}
</pre>
<p>The question is, does maybe() halt? Well let&#8217;s see..</p>
<ul>
<li>Let&#8217;s assume that maybe() halts. Therefore the <em>if</em> clause is true and so eternity() gets called.. meaning that maybe() never halts. Wait! That can&#8217;t be right! We just contradicted ourselves. We must have guessed wrong.</li>
<li>Ok, in that case, let&#8217;s say that maybe() doesn&#8217;t halt. Therefore the <em>else</em> clause gets called instead, and we return a value. Meaning that we halted. But that&#8217;s a contradiction too!</li>
</ul>
<p>What this means is that it&#8217;s impossible to write a function like halts() that determines whether another arbitrary function halts or not, because the very definition of such a function leads to a contradiction. Sucks to be a programmer huh?</p>
<p>Thanks Alan M. Turing (1912-1954), and Kurt Gödel (1906-1978).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.patspam.com/2008/the-halting-problem-in-javascript/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tarpo</title>
		<link>http://blog.patspam.com/2008/tarpo</link>
		<comments>http://blog.patspam.com/2008/tarpo#comments</comments>
		<pubDate>Tue, 15 Apr 2008 02:53:15 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[Air]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://blog.patspam.com/?p=1030</guid>
		<description><![CDATA[A huge class of applications are nothing more than a bunch of relational database tables with a simple Create Read Update Delete (CRUD) user interface. More and more these applications are being built as web-apps, eg. the user interface is HTML/CSS/Javascript running inside a users&#8217; browser, and the backend is a simple server-side layer (Perl/PHP/Ruby/J2EE/..) [...]]]></description>
			<content:encoded><![CDATA[<p>A huge class of applications are nothing more than a bunch of relational database tables with a simple <strong>C</strong>reate <strong>R</strong>ead <strong>U</strong>pdate <strong>D</strong>elete (CRUD) user interface. More and more these applications are being built as web-apps, eg. the user interface is HTML/CSS/Javascript running inside a users&#8217; browser, and the backend is a simple server-side layer (Perl/PHP/Ruby/J2EE/..) controlling access to an online database. This architecture is becoming increasingly easy to implement with the advent of server-side web/application frameworks (Catalyst/Rails/Spring) and database <strong>O</strong>bject <strong>R</strong>elational <strong>M</strong>appers (DBIx::Class/ActiveRecord/Hibernate,..) that remove most of the tedium, along with awesome Javascript libraries in the front-end (ExtJS/jQuery/Dojo/..) that let you make the user interface much more engaging and adaptable.</p>
<p><a href="http://blog.patspam.com/wp-content/uploads/2008/04/maningrida_surgery.jpg"><img class="alignleft size-thumbnail wp-image-1035" style="float: left; margin: 5px;" title="maningrida_surgery" src="http://blog.patspam.com/wp-content/uploads/2008/04/maningrida_surgery-150x150.jpg" alt="" width="150" height="150" /></a><a href="http://blog.patspam.com/wp-content/uploads/2008/04/maningrida_tech.jpg"><img class="alignright size-thumbnail wp-image-1036" style="float: right; margin: 5px;" title="maningrida_tech" src="http://blog.patspam.com/wp-content/uploads/2008/04/maningrida_tech-150x150.jpg" alt="" width="150" height="150" /></a>What happens, however, when your intended users have no internet access? I was recently faced with that exact problem: My Dad (Dr Ted Donelan) runs a pro bono dog health program in Maningrida, a self-governing aboriginal community in Arnhem Land (500km east of Darwin) where, unless you want to pay through the teeth for that Telstra NextG internet rubbish, there&#8217;s no easy access to the internet. And certainly no way of logging into a website while you&#8217;re riding around from house to house in a ute or carrying out surgery on an outdoor trestle table  underneath the local grog-shelter. Dr Ted wanted a way to record the statistical information that he collects (dog body conditions, mange scores, fleas, ticks, etc..) along with his formal veterinary records of surgical cases, medical cases, etc.. All of which can be neatly captured in a handful of relational tables (attested by the fact that previously he had been recording his data in hand-written tables, later to be transferred to Excel). I suppose I could have stepped back into the C#/Java world and implemented a stand-alone app to solve the problem, but I&#8217;m not familiar enough with any frameworks in those languages to whip up something quickly. And that was the point, I only had a small amount of time to come up with a solution. And what I really wanted was a way to build him a stand-alone app using my existing HTML/Javascript/CSS-fu..</p>
<p>Cue <a href="http://www.adobe.com/products/air/">Adobe AIR</a>.. a desktop framework that lets you build traditional dektop apps using web technologies. Now I&#8217;m not the biggest fan of proprietary technology (Adobe Flash being a prime example) since it goes against the grain of the Open Web, but there&#8217;s really no open-source alternatives at the moment.</p>
<p>The first really awesome AIR app I saw was ExtJS creator Jack Slockum&#8217;s &#8220;<a href="http://extjs.com/blog/2008/02/24/tasks2/">Simple Tasks</a>&#8220;. Check out the screen-shots and you&#8217;ll see why I was excited: here was a desktop application with an embedded (SQLite) database running pure HTML/CSS/Javascript. And not just any Javascript either. ExtJS shines most when used to create windows application-style interfaces, and as such it&#8217;s the perfect library to use in an AIR app when you really are building a desktop application.</p>
<p>Simple Tasks is released under GPL v3, so I decided to base my code on Jack&#8217;s. It was the right decision. With no prior experience with AIR it took less than a day to have a working prototype, and by working I mean a full database implementation, an editable data grid and an Add/Edit form for individual rows, all with the trademark ExtJS polish. That&#8217;s ridiculously fast.</p>
<p>After about 4 days with lots of feedback from Dr. Ted we had a finished app, named <strong><a href="http://patspam.com/tarpo">Tarpo</a></strong>, complete with polished input forms, reporting, backup, CSV/XML export, &#8230;</p>
<p><a href="http://blog.patspam.com/wp-content/uploads/2008/04/tarpo.jpg"><img class="alignnone size-thumbnail wp-image-1032" title="tarpo" src="http://blog.patspam.com/wp-content/uploads/2008/04/tarpo-150x150.jpg" alt="" width="150" height="150" /></a><br />
<a href="http://blog.patspam.com/wp-content/uploads/2008/04/tarpo-2.jpg"><img class="alignnone size-thumbnail wp-image-1033" title="tarpo-2" src="http://blog.patspam.com/wp-content/uploads/2008/04/tarpo-2-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>I&#8217;ll be releasing <a href="http://patspam.com/tarpo">Tarpo</a> under GPL v3. Until then I&#8217;ve got a little <a href="http://patspam.com/tarpo">page</a> where you can install it straight off the web and have a play. Dr. Ted is heading up to Maningrida next week so I&#8217;m excited to see how <a href="http://patspam.com/tarpo">Tarpo</a> goes on her first test-run. If everything works well we&#8217;ll make her available to other Vets running similar programs in other indigenous communities. One cool follow-on from this will be that vets running <a href="http://amrric.org">AMRRIC</a>-endorsed programs could use <a href="http://patspam.com/tarpo">Tarpo</a> to submit their activity reports direct to the <a href="http://amrric.org">AMRRIC</a> website (which I recently developed).</p>
<p>Andy (also of <a href="http://sdhconsulting.com.au">SDH</a>) is whipping up a <a href="http://patspam.com/tarpo">Tarpo</a> logo for me, which I&#8217;ll post up here as soon as he&#8217;s finished inking it!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.patspam.com/2008/tarpo/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Multiple Columns Bookmarklet</title>
		<link>http://blog.patspam.com/2007/multiple-columns-bookmarklet</link>
		<comments>http://blog.patspam.com/2007/multiple-columns-bookmarklet#comments</comments>
		<pubDate>Fri, 05 Oct 2007 10:23:40 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://blog.patspam.com/2007/10/05/multiple-columns-bookmarklet/</guid>
		<description><![CDATA[Reading large chunks of text on a widescreen monitor can be a real pain if your eyes have to read across long horizontal lines. That&#8217;s why newspapers print articles in columns! Ideally, websites should too, at least when you&#8217;re trying to view them on a large monitor. Obviously you can&#8217;t expect webpage designers to predict [...]]]></description>
			<content:encoded><![CDATA[<p>Reading large chunks of text on a widescreen monitor can be a real pain if your eyes have to read across long horizontal lines. That&#8217;s why newspapers print articles in columns! Ideally, websites should too, at least when you&#8217;re trying to view them on a large monitor. Obviously you can&#8217;t expect webpage designers to predict the size of your screen, but if you&#8217;re using Firefox you can use this simple <a href="http://en.wikipedia.org/wiki/Bookmarklet">bookmarklet</a> I wrote to reformat a selection of text (or the whole page) into multiple columns yourself.</p>
<p><strong>How to use it the Multiple Columns Bookmarklet:</strong><br />
This is the link to my <a href="javascript:(function(){var a = getSelection();if (a.isCollapsed) {	a=document.body;} else {	a = a.getRangeAt(0).commonAncestorContainer;	if (a.nodeType == 3) {	    a = a.parentNode;	}}if ('%s' == 'max') {a.style.height = window.innerHeight - 40;}a.style.MozColumnWidth = '200px';a.style.MozColumnGap = '20px';})();">Multiple Columns Bookmarklet</a>.</p>
<p>For starters, try it out yourself on this page! Select a few words in the first paragraph of this page and click the bookmarklet link. You should see it magically reformat into multiple columns 200px wide.</p>
<p>Now select two continuous paragraphs and click the bookmarklet link. You should see the entire article reformatted into easy to read columns. Cool huh?</p>
<p>If you want to use the bookmarklet on other pages, bookmark it now. When you&#8217;re on a page that you want to reformat select the chunk of text and click on the bookmarklet. voila!</p>
<p>If you select text a single paragraph, only that paragraph will be turned into columns. If you select multiple paragraphs, the containing DOM element will be reformated (this isn&#8217;t perfect but it usually does what you want). If no text is selected when you launch the bookmarklet, the entire page will be turned into multiple columns (that won&#8217;t look great on my blog, but it&#8217;s handy on pages with <a href="http://www.prescod.net/rest/encoding/">minimal styling</a>)</p>
<p>If you add a keyword such as <strong>col</strong> to your bookmarklet link (Right Click &gt; Properties), then you can launch the bookmarklet from the location bar by typing <strong>col</strong> rather than clicking on the link.</p>
<p>Finally, if you provide an argument of <strong>max</strong>, eg. <strong>col max</strong> then the maximum height of the columns will be set to the size of your web browser window. This is really handy if you&#8217;re viewing a long document and you don&#8217;t want the columns to scroll vertically for miles and miles (by setting the column height the columns will instead continue horizonally, just like a large-format newspaper).</p>
<p>In case you&#8217;re wondering, the bookmarklet is only intended for Firefox because none of the other browsers have implemented any column-related CSS features.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.patspam.com/2007/multiple-columns-bookmarklet/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
