<?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; Firefox Addon</title>
	<atom:link href="http://www.julianwong.net/blog/category/firefox-addon/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>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>
	</channel>
</rss>

