<?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>JavaScript Infected &#187; Javascript</title>
	<atom:link href="http://www.julianwong.net/blog/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.julianwong.net/blog</link>
	<description>Do everything with javascript</description>
	<lastBuildDate>Sat, 13 Aug 2011 07:32:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>A play with HTML5 &#8211; audio mixer with canvas</title>
		<link>http://www.julianwong.net/blog/2010/09/a-play-with-html5-audio-mixer-with-canvas/</link>
		<comments>http://www.julianwong.net/blog/2010/09/a-play-with-html5-audio-mixer-with-canvas/#comments</comments>
		<pubDate>Fri, 17 Sep 2010 07:26:11 +0000</pubDate>
		<dc:creator>julian</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[blur filter]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.julianwong.net/blog/?p=277</guid>
		<description><![CDATA[Finished a prototype with the audio and canvas feature in HTML5. It is quite a sad thing that no single audio format can work cross browsers. HTML5 Doctor had a table showing the supported audio format from different browsers. In the prototype I implemented the box filter documented out at Gamasutra. The blur function is [...]]]></description>
			<content:encoded><![CDATA[<p>Finished a prototype with the audio and canvas feature in HTML5. It is quite a sad thing that no single audio format can work cross browsers. <a href="http://html5doctor.com/native-audio-in-the-browser/">HTML5 Doctor</a> had a table showing the supported audio format from different browsers.</p>
<p>In the prototype I implemented the box filter documented out at <a href="http://www.gamasutra.com/view/feature/3102/four_tricks_for_fast_blurring_in_.php">Gamasutra</a>. The blur function is applied to 6 canvas at every 100ms. Just chrome can run it smoothly&#8230;.Maybe Firefox 4 can do that too, but I didn&#8217;t test it on FF4, also the mp3 may not be able to play on it&#8230;The link to the <a href="http://www.julianwong.net/app/mixer/blur.html">prototype</a> (Google Chrome Only).</p>
<p><a href="http://www.julianwong.net/app/mixer/blur.html"><img src="http://www.julianwong.net/blog/wp-content/uploads/2010/09/mixer.png" alt="" title="HTML5 audio mixer" width="369" height="362" class="alignnone size-full wp-image-278" /></a><br />
Screen shot with the audio mixer. Let&#8217;s play~</p>
]]></content:encoded>
			<wfw:commentRss>http://www.julianwong.net/blog/2010/09/a-play-with-html5-audio-mixer-with-canvas/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dumping Firefox XUL object</title>
		<link>http://www.julianwong.net/blog/2009/11/dumping-firefox-xul-object/</link>
		<comments>http://www.julianwong.net/blog/2009/11/dumping-firefox-xul-object/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 07:22:01 +0000</pubDate>
		<dc:creator>julian</dc:creator>
				<category><![CDATA[Firefox Addon]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.julianwong.net/blog/?p=222</guid>
		<description><![CDATA[I am not sure is it correct to call it XUL object, what I mean to do is transversing javascript object. It sounds silly as we got firebug but it makes sense when working on firefox addon where the script debugger in firebug doesn&#8217;t work for javascript running in chrome. There is a XUL reference [...]]]></description>
			<content:encoded><![CDATA[<p>I am not sure is it correct to call it XUL object, what I mean to do is transversing javascript object. It sounds silly as we got firebug but it makes sense when working on firefox addon where the script debugger in firebug doesn&#8217;t work for javascript running in chrome.</p>
<p>There is a XUL reference in MDC(<a href="https://developer.mozilla.org/en/XUL_Reference">https://developer.mozilla.org/en/XUL_Reference</a>). It listing out objects and its associated attributes, properties, and methods, but seems not all the reference are update and complete. Sometimes I don&#8217;t even know what kind of xul object I am dealing with, I need to have something like var_dump or print_r in PHP. And I have written my own object dumping function.<br />
<span id="more-222"></span><br />
My dump function:</p>
<pre style="height:500px;overflow:auto;">
myUtil = {
dump:function(o,depth,name,filter,filterMode) {
    var doc = gBrowser.contentDocument,
        el = doc.getElementById("fduDump"),
        str = "" || name + "\n",
        depthLimit = depth || 1,
        filterDefaultMode = filterMode || 1;
    // filterMode is either 1 or -1.
    // 1 =&gt; Like the iptable Allow all, it dig into all object exclude object name in the filter object
    // -1 =&gt; Like the iptable Deny all, it will not dig into any object unless object name is inside the filter

    if ( !el ) {
        el = doc.createElement("pre");
        el.id = "fduDump";
        doc.body.appendChild(el);
    }

    var transverse = function(o,thisLv,name,filter) {
        var indent = "", i, tmp, filterMode, dig, f;
        if ( filter &amp;&amp; filter.__mode ) {
            filterMode = filter.__mode;
        } else {
            filterMode = filterDefaultMode;
        }
        for ( i = 0 ; i &lt; thisLv ; i++ ) {
            indent += "    ";
        }

        if ( name ) {
            str += "\n" + indent + "=== lv "+thisLv+", Start "+name+" ===\n";
        }

        if ( o &amp;&amp; thisLv &lt; depthLimit ) {
            for ( k in o ) {
                try{
                    tmp = o[k] + "";
                    tmp = tmp.split("\n");
                    tmp = tmp.join("\n"+indent);
                    str += indent + k + " : " + tmp + "\n";
                    if (typeof(o[k]) === "object" &amp;&amp; o[k] &amp;&amp; thisLv + 1 &lt; depthLimit ) {
                        if ( filter &amp;&amp; typeof filter[k] !== "undefined") {
                            dig = (filterMode === -1);
                        } else {
                            dig = (filterMode === 1);
                        }
                        if ( dig ) {
                            if ( filter &amp;&amp; filter[k] ) {
                                f = filter;
                            } else {
                                f = null;
                            }
                            transverse(o[k], thisLv + 1, k, f);
                        }
                    }
                } catch (e) {
                }
            }
        }

        if ( name ) {
            str += indent + "=== lv "+thisLv+", End "+name+" ===\n\n";
        }
    }
    transverse(o,0,"",filter);
    el.innerHTML = str;
}
}</pre>
<p>Calling the dump function:</p>
<pre>
// e.g. here I amd dumping the event object form a "TabSelect" event
// 1st param is object to be dumped
// 2nd param is the depth (optional, default = 1)
// 3rd is just a string to be shown in the first line of the dump (optional default = "")
// 4th is filter (optional)
// 5th is default filter mode (optional default = 1, dump all properties exclude specified in filter object)
myUtil.dump(evt,2,"tabEvent",{"__mode":-1,"target":null});

// if you just want to dump an object itself, you can simply: myUtil.dump(evt);
</pre>
<p>Sample output of the dump</p>
<pre>tabEvent
originalTarget : [object XULElement]
preventCapture : function preventCapture() {
    [native code]
}
target : [object XULElement]

    === lv 1, Start target ===
    _tPos : 0
    linkedBrowser : [object XULElement]
    ...
    selected : true
    _selected : undefined
    linkedPanel : panel1259045062233
    ...
    tagName : xul:tab
    ...
    nodeName : xul:tab
    ...
    className : tabbrowser-tab
    ...
    === lv 1, End target ===

cancelable : false
currentTarget : [object XULElement]
timeStamp : 1172581376
bubbles : true
type : TabSelect
eventPhase : 3
preventDefault : function preventDefault() {
    [native code]
}
initEvent : function initEvent() {
    [native code]
}
stopPropagation : function stopPropagation() {
    [native code]
}
CAPTURING_PHASE : 1
AT_TARGET : 2
BUBBLING_PHASE : 3
explicitOriginalTarget : [object XULElement]
preventBubble : function preventBubble() {
    [native code]
}
...
</pre>
<p>By dumping the event object and the target in the event object, there are something useful can be found. In the TabSelect Event, there is target, originalTarget, currentTarget, explicitOriginalTarget!?<br />
And in the target object, it has a tagName and nodeName equals to &#8220;xul:tab&#8221;, so now I can be sure it is a &#8220;tab&#8221; object instead of tabPanel, tabbox, or tabbrowser&#8230;.Also it has a linkedBrowser object which is the browser object contained in the tab. This is not documented in the xul reference&#8230;maybe they don&#8217;t want us to use it? Have fun dumping.</p>
<p>Other resources on message logging and debugging in writing Firefox addon:</p>
<p>https://developer.mozilla.org/en/JavaScript_Console</p>
<p>http://www.borngeek.com/firefox/toolbar-tutorial/chapter-8/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.julianwong.net/blog/2009/11/dumping-firefox-xul-object/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nice way to check dom node className</title>
		<link>http://www.julianwong.net/blog/2009/10/nice-way-to-check-dom-node-classname/</link>
		<comments>http://www.julianwong.net/blog/2009/10/nice-way-to-check-dom-node-classname/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 09:43:58 +0000</pubDate>
		<dc:creator>julian</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.julianwong.net/blog/?p=196</guid>
		<description><![CDATA[It happen quite often to me that I need to check the element className in the event handler and to determine what function to trigger. element.className contains all the class name separated by space. e.g. &#8220;classA classB classCCC&#8221;. So it is bad to check the className like: if (element.className === "classA") {...} or if (element.className.indexOf("classC") [...]]]></description>
			<content:encoded><![CDATA[<p>It happen quite often to me that I need to check the element className in the event handler and to determine what function to trigger. element.className contains all the class name separated by space. e.g. &#8220;classA classB classCCC&#8221;. So it is bad to check the className like:</p>
<pre>if (element.className === "classA") {...}</pre>
<p> or
<pre>if (element.className.indexOf("classC") > -1) {...}</pre>
<p>Sure we can do it with regular expression but there are faster way to do it.</p>
<p>I use YUI all the time and there is a YAHOO.util.Dom.hasClass, I read the source code and found they got a clever way to do it. It just add space in front and behide the className and do a indexOf. But one thing to note that you should not add the space to the className property directly instead you obtain a copy of the className string by getAttribute.</p>
<p>The code will look like:</p>
<pre>
function hasClass(el, class_to_match) {
    var c;
    if (el &#038;&#038; el.className &#038;&#038; typeof class_to_match === "string") {
        c = el.getAttribute("class");
        c = " "+ c + " ";
        return c.indexOf(" " + class_to_match + " ") > -1;
    } else {
        return false;
    }
}
</pre>
<p>Tidy and neat!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.julianwong.net/blog/2009/10/nice-way-to-check-dom-node-classname/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Detecting page dimension with Javascript</title>
		<link>http://www.julianwong.net/blog/2009/10/detectinge-page-dimension-with-javascript/</link>
		<comments>http://www.julianwong.net/blog/2009/10/detectinge-page-dimension-with-javascript/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 12:26:48 +0000</pubDate>
		<dc:creator>julian</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.julianwong.net/blog/?p=179</guid>
		<description><![CDATA[I just come to a problem that need to create a canvas element the will cover on top of the whole page. This prevented me from using style.width and style.height as the drawing will become scaled by the style setting. So I have to calculate the exact page width and height then assign it to [...]]]></description>
			<content:encoded><![CDATA[<p>I just come to a problem that need to create a canvas element the will cover on top of the whole page. This prevented me from using style.width and style.height as the drawing will become scaled by the style setting. So I have to calculate the exact page width and height then assign it to the canvas element.</p>
<p>IE 6 had a handy <code>document.body.scrollWidth</code> and <code>document.body.scrollHeight</code> to check the size of body element. Just one thing to note with <code>document.body.scrollHeight</code> is that If the total height of the content is less than the view port / screen size, you will need to use <code>document.body.clientHeight</code>.</p>
<p>While for Firefox, I just need to go through different properties in the window object and body element to find the correct numbers for the calculation.</p>
<pre>width = window.scrollMaxX + document.body.clientWidth;
height = window.scrollMaxY + document.body.clientHeight;
</pre>
<p>Do not mistaken <code>window.innerWidth</code> and <code>window.innerHeight</code> into above as innerWidth and innerHeight will include the scrollbar (if there aren&#8217;t any scrollbar, <code>window.innerWidth</code> will equals to <code>document.body.clientWidth</code> and <code>window.innerHeight</code> will equals to <code>document.body.clientHeight</code>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.julianwong.net/blog/2009/10/detectinge-page-dimension-with-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using custom event on jQuery</title>
		<link>http://www.julianwong.net/blog/2009/09/using-custom-event-on-jquery/</link>
		<comments>http://www.julianwong.net/blog/2009/09/using-custom-event-on-jquery/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 08:04:33 +0000</pubDate>
		<dc:creator>julian</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://julianwong.net/blog/?p=155</guid>
		<description><![CDATA[When doing Javascript, it is common to handle different DOM event like click, mouseover, keydown&#8230; This is cool that with the DOM triggering those events, we can create custom handling / behaviors on it. Say, when user click on the button, a edit panel fade in. But this is not good enough when we have [...]]]></description>
			<content:encoded><![CDATA[<p>When doing Javascript, it is common to handle different DOM event like click, mouseover, keydown&#8230; This is cool that with the DOM triggering those events, we can create custom handling / behaviors on it. Say, when user click on the button, a edit panel fade in. But this is not good enough when we have to deal with a complex / feature rich interface. For instance, if a feature require a series of action on different components, how can we do it in a proper way? Here is custom event come into play.</p>
<p>There are different ways of making custom event to works, following will show:<br />
1. Using jQuery.bind and jQuery.trigger<br />
2. Using the jQuery plugin jQuery.mhub<br />
<span id="more-155"></span></p>
<h3>Using jQuery.bind and jQuery.trigger</h3>
<p>Have searched for how to have custom event on jQuery, found that <a href="http://yoan.dosimple.ch/blog/2008/04/30/">yoan&#8217;s Introduction to jQuery’s custom event</a> had some good insight. He had achieved it by using the bind and trigger function in jQuery. I have referenced his blog and the API from jQuery and created a rather primitive sample.</p>
<pre>var count = 0;
var elLog = document.getElementById("log");

// trigger the ticker event into body element
setInterval(function() {
    <strong>$("body").trigger("ticker",{name:"my name is foo",count:count++});</strong>
},3000);

<strong>$("body").bind("ticker",gFunc);</strong>

function gFunc(evt,msg) {
    elLog.innerHTML += "gFunc triggered&lt;br/&gt;&lt;br/&gt;";
}

var myApp = {
    name:"app1",

    init:function() {
        var that = this;
        // bind the _handlerTicker function to the ticker event of body element
        <strong>$("body").bind("ticker",function() {that._handlerTicker.apply(that,arguments)});</strong>
    },

    _handlerTicker:function(evt,msg) {
        elLog.innerHTML += this.name + "&lt;br/&gt;";
        elLog.innerHTML += "event name: " + evt.type + "&lt;br/&gt;";
        elLog.innerHTML += "msg content: name = " + msg.name + ", count = " + msg.count + "&lt;br/&gt;&lt;br/&gt;";
    }
}
myApp.init();</pre>
<p><a href="http://julianwong.net/samples/custom-event/dom.html">The sample in action</a></p>
<p>My sample code above works but with some draw backs:<br />
1. The custom event need to associated with a dom element which have nothing to do with it, here is the body element.<br />
2. When dealing with a large application / working with different plugin / mashup, we could end up with a name collision on the custom event.<br />
<a name="jQuery.mhub"></a></p>
<h3>Using the jQuery plugin jQuery.mhub</h3>
<p>To tackle the problems listed above, I created a <a href="http://plugins.jquery.com/project/mhub">message hub plugin, jQuery.mhub</a>. This jQuery.mhub employ a factory design. It only contains one single method:</p>
<pre>var demoHub = jQuery.mhub.create();</pre>
<p>Which return a message hub object with the following methods:</p>
<pre>demoHub.add(String NAME);
demoHub.remove(String NAME);
demoHub.send(String NAME, Object MESSAGE );
demoHub.listen(String NAME, Function HANDLE_FN, Object SCOPE );</pre>
<p>Here is a <a href="http://www.julianwong.net/samples/custom-event/mhub.html">sample</a> to see how the jQuery.mhub works. By using the jQuery.mhub, the above 2 problems state can be solved.</p>
<p>1. The custom event no longer tide up with a dom element.<br />
2. mhub object are created from jQuery.mhub.create();, you can get your own mhub without sharing it to other component and avoid name collision</p>
<p>A primitive <a href="http://www.julianwong.net/samples/custom-event/mhub.html">sample of jQuery.mhub</a>.</p>
<p>The source code:</p>
<pre>var count = 0;
var elLog = document.getElementById("log");
var demoHub = jQuery.mhub.create();

<strong>demoHub.add("ticker");</strong>

setInterval(function() {
    <strong>demoHub.send("ticker",{name:"my name is foo",count:count++});</strong>
},3000);

<strong>demoHub.listen("ticker", globalFunc);</strong>

function globalFunc(evt,msg) {
    elLog.innerHTML += "globalFunc triggered&lt;br/&gt;&lt;br/&gt;";
}

var myApp = {
    name:"app1",

    init:function() {
        <strong>demoHub.listen("ticker", this._handlerTicker, this);</strong>
    },

    _handlerTicker:function(name,msg) {
        elLog.innerHTML += this.name + "&lt;br/&gt;";
        elLog.innerHTML += "event name: " + name + "&lt;br/&gt;";
        elLog.innerHTML += "msg content: name = " + msg.name + ", count = " + msg.count + "&lt;br/&gt;";
    }
}

myApp.init();</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.julianwong.net/blog/2009/09/using-custom-event-on-jquery/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A play with &quot;frontend application&quot;</title>
		<link>http://www.julianwong.net/blog/2009/08/a-play-with-frontend-application/</link>
		<comments>http://www.julianwong.net/blog/2009/08/a-play-with-frontend-application/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 13:52:31 +0000</pubDate>
		<dc:creator>julian</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://julianwong.net/blog/?p=120</guid>
		<description><![CDATA[After created the yqlClient, it looks like I can do something fun with it. I love investing in stock market that sounds good if I can do something about it. Here i created a quote panel which use YUI, jquery, flot extension on jquery, my yqlClient&#8230;etc. Everything done with HTML, CSS, Javascript. 0 lines PHP. [...]]]></description>
			<content:encoded><![CDATA[<p>After created the yqlClient, it looks like I can do something fun with it. I love investing in stock market that sounds good if I can do something about it.</p>
<p>Here i created a <a href="http://www.julianwong.net/app/Qpanel/index.html">quote panel</a> which use YUI, jquery, flot extension on jquery, my yqlClient&#8230;etc. Everything done with HTML, CSS, Javascript. 0 lines PHP. But there are problems that as cookie was used as a permanent storage, so user cannot bring along the data when they switched a browser / computer&#8230;</p>
<p>This application used a <a href="http://finance.yahoo.com/q?s=YHOO,AIG&amp;d=s">html page in Yahoo! Finance</a>, a <a href="http://chartapi.finance.yahoo.com/instrument/1.0/^DJI/chartdata;type=quote;range=1d/csv/">xml call from the flash chart</a>, <a href="http://finance.yahoo.com/rss/headline?s=^DJI">Yahoo news RSS feed</a>. Then use YQL to pulling the data and re-construct the interface in the way I want. This is fun that with the help of YQL, data can be pulled together quickly and creating some demo app in a short time to get user feedback and change again.</p>
<p>The <a href="http://www.julianwong.net/app/Qpanel/index.html">quote panel</a>.</p>
<div id="attachment_144" class="wp-caption alignnone" style="width: 440px"><a href="http://www.julianwong.net/app/Qpanel/index.html"><img src="http://www.julianwong.net/blog/wp-content/uploads/2009/09/qp_img.png" alt="Screen cap of the quote panel"  width="430" height="398" class="alignnone size-full wp-image-157" /></a><p class="wp-caption-text">Screen cap of the quote panel</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.julianwong.net/blog/2009/08/a-play-with-frontend-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Javascript YQL client</title>
		<link>http://www.julianwong.net/blog/2009/07/a-javascript-yql-client/</link>
		<comments>http://www.julianwong.net/blog/2009/07/a-javascript-yql-client/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 18:37:43 +0000</pubDate>
		<dc:creator>julian</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://julianwong.net/blog/?p=106</guid>
		<description><![CDATA[The YQL API support the JSONP format which allow you to specify a Javascript function to handle the data (XML / JSON) return from the API. A normal JSON will return a string which is a javascript object like: {key1:&#8221;value1&#8243;,key2:10.35} While a JSONP will look like: js_function({key1:&#8221;value1&#8243;,key2:10.35}); Which the return string from server will be [...]]]></description>
			<content:encoded><![CDATA[<p>
The YQL API support the JSONP format which allow you to specify a Javascript function to handle the data (XML / JSON) return from the API. A normal JSON will return a string which is a javascript object like:<br />
{key1:&#8221;value1&#8243;,key2:10.35}</p>
<p>While a JSONP will look like:<br />
js_function({key1:&#8221;value1&#8243;,key2:10.35});</p>
<p>Which the return string from server will be a valid javascript function call and passing a object literal (or the original JSON string) into the function. For more on JSONP, there is an <a href="http://ajaxian.com/archives/jsonp-json-with-padding">article on Ajaxian</a>.</p>
<p>As you can see above, the handling function will be a global functions in order to make the JSONP to work. Also, the scope of the calling function / object will be completely loss. So I created a simple YQL client which do the auto scope fixing. It works like YUI2&#8242;s connection manager and support a callback object which you can specify a method to handle the JSON return, the scope of &#8220;this&#8221; object, timeout of your YQL call, and pass on argument to the handling function.
</p>
<p>
Here is a simple <a href="http://julianwong.net/samples/javascript-yql-client/yql_demo.html" target="_blank">demo</a> using the javascript yql client to get the digg&#8217;s rss feed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.julianwong.net/blog/2009/07/a-javascript-yql-client/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using YQL as crawler for Javascript</title>
		<link>http://www.julianwong.net/blog/2009/06/using-yql-as-crawler-for-javascript/</link>
		<comments>http://www.julianwong.net/blog/2009/06/using-yql-as-crawler-for-javascript/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 08:48:51 +0000</pubDate>
		<dc:creator>julian</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://julianwong.net/blog/?p=97</guid>
		<description><![CDATA[It is a good fun to play with Yahoo! Query Language (YQL). YQL is a service enables applications to query, filter, and combine data from different sources across the Internet. Many data in the Yahoo! network can be retrieved from YQL with a SQL like syntax. SELECT * FROM flickr.photos.search WHERE text="cat" Means to do [...]]]></description>
			<content:encoded><![CDATA[<p>It is a good fun to play with <a href="http://developer.yahoo.com/yql/">Yahoo! Query Language (YQL)</a>. YQL is a service enables applications to query, filter, and combine data from different sources across the Internet. Many data in the Yahoo! network can be retrieved from YQL with a SQL like syntax.</p>
<pre>SELECT * FROM flickr.photos.search WHERE text="cat"</pre>
<p>Means to do a flickr search on photo with the text equals to cat. But the thing that catch me is the capability to convert the content (HTML page) from an external site to a well formatted XML / JSON.</p>
<pre>select * from html where url="http://news.yahoo.com/"
and xpath="/html/body/div[@id='doc4']/div[@id='bd']/div[@id='yui-main']/div/div[@id='top-story']/div/div[1]/div[2]/h2/a"</pre>
<p>The YQL above will return the headline from Yahoo! news. The xpath part looks pretty scary, but with the <a href="https://addons.mozilla.org/en-US/firefox/addon/1192">xpather firefox addon</a>, you can get the xpath on any DOM element with right click -> Show in XPather. (P.S. One thing to notice with xpather is the tbody tag, which firefox will add to its DOM tree for table which might not really exist in the source HTML. This extra tbody will make YQL returns nothing as it never exists in the HTML code.)</p>
<p>This is an excellent tool for the Javascript. Imagine that if you are going implement a RSS reader, without YQL, the RSS reader application must prepare all the data at the server side and send back to the client (like Fig.1). This is bad for performance as curl call are blocking calls while consuming YQL at client browser can be asynchronous and parallel. This sounds wise to offload those data crawling process to the client (like Fig.2).</p>
<div>
<img src="http://www.julianwong.net/samples/yql-as-crawler/YQL-as-crawler-01.png" /><br />
Fig. 1 The web application prepare all the data at the server side
</div>
<div>
<img src="http://www.julianwong.net/samples/yql-as-crawler/YQL-as-crawler-02.png" /><br />
Fig. 2 Offloading the blocking curl calls to client side parallel YQL request.
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.julianwong.net/blog/2009/06/using-yql-as-crawler-for-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Timestamp convertor</title>
		<link>http://www.julianwong.net/blog/2009/06/timestamp-convertor/</link>
		<comments>http://www.julianwong.net/blog/2009/06/timestamp-convertor/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 15:18:17 +0000</pubDate>
		<dc:creator>julian</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://julianwong.net/blog/?p=78</guid>
		<description><![CDATA[I just come across to work with an API related to timestamp and need to do some time unit conversion. Have tried to found some timestamp converter from the web and firefox addon, but none of converter I find suit my need. So just spend a day to create a converter with a calendar on [...]]]></description>
			<content:encoded><![CDATA[<p>
I just come across to work with an API related to timestamp and need to do some time unit conversion. Have tried to found some timestamp converter from the web and firefox addon, but none of converter I find suit my need. So just spend a day to create a converter with a calendar on it.
</p>
<p>Features:</p>
<ol>
<li>Convert timestamp to date, click on the log to navigate the calendar</li>
<li>Convert seconds / minutes into number of days, hours</li>
<li>Arrow key to navigate the calendar (only when focus is not on the text field )</li>
</ol>
<div id="attachment_83" class="wp-caption alignnone" style="width: 436px"><img src="http://www.julianwong.net/blog/wp-content/uploads/2009/09/Timestamp-Converter.png" alt="Screen cap of the &lt;a href=&quot;http://www.julianwong.net/app/tscon/index.html&quot;&gt;timestamp converter&lt;/a&gt;" title="Timestamp-Converter" width="426" height="242" class="alignnone size-full wp-image-158" /><p class="wp-caption-text">Screen cap of the <a href='http://www.julianwong.net/app/tscon/index.html'>timestamp converter</a></p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.julianwong.net/blog/2009/06/timestamp-convertor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

