<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Howto: XHR Listening by a Firefox Addon</title>
	<atom:link href="http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/</link>
	<description></description>
	<lastBuildDate>Mon, 19 Dec 2011 08:17:01 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: Sasha</title>
		<link>http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/comment-page-1/#comment-2232</link>
		<dc:creator>Sasha</dc:creator>
		<pubDate>Mon, 19 Dec 2011 08:17:01 +0000</pubDate>
		<guid isPermaLink="false">http://ashita.org/?p=307#comment-2232</guid>
		<description>By the way.

The code works!

The problem was just that Firefox must do a new &#039;GET&#039; of the code when you view source.  The source is changed correctly in Firebug.  :-)</description>
		<content:encoded><![CDATA[<p>By the way.</p>
<p>The code works!</p>
<p>The problem was just that Firefox must do a new &#8216;GET&#8217; of the code when you view source.  The source is changed correctly in Firebug.  :-)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jonathan Fingland</title>
		<link>http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/comment-page-1/#comment-2231</link>
		<dc:creator>Jonathan Fingland</dc:creator>
		<pubDate>Sun, 18 Dec 2011 22:34:53 +0000</pubDate>
		<guid isPermaLink="false">http://ashita.org/?p=307#comment-2231</guid>
		<description>Hi Sasha,

The post was originally written around the time of Firefox 3.5, so a lot of things may have changed since then. For example, I wouldn&#039;t be surprised if Firefox handles the case where a listener in the chain drops the ball, or does something unexpected. I haven&#039;t tested the code in question in a while, but did you try the technique I used in the previous comment? (Just to be sure that everything else is working correctly)

I see why you would want to consolidate the buffer (subtring replacement or, preferably, document creation, modification, and then getting the string representation). I&#039;ll try putting something together using your example. Any chance you could post additional code? What you&#039;re trying to do should work according to all of the documentation (which is sadly out of date).

Basically, I see a few ways that the browser is not getting the modified html:

&lt;ul&gt;
	&lt;li&gt;the browser listener is added &lt;em&gt;after&lt;/em&gt; yours (and thus your listener is downstream)&lt;/li&gt;
	&lt;li&gt;your listener is not passing it on correctly and the browser is correcting for this somehow&lt;/li&gt;
	&lt;li&gt;you are inserting something that is not valid html and is then ignored when the browser is parsing and rendering the page&lt;/li&gt;
	&lt;li&gt;the onDataAvailable method isn&#039;t doing what you expect (you said you verified the contents passed on by onStopRequest so this is unlikely, but...)&lt;/li&gt;
&lt;/ul&gt;

There are probably more possibilities but that&#039;s all I&#039;ve got right now. As I said, I&#039;ll try whipping up an example like yours and see if I can figure out what went wrong.</description>
		<content:encoded><![CDATA[<p>Hi Sasha,</p>
<p>The post was originally written around the time of Firefox 3.5, so a lot of things may have changed since then. For example, I wouldn&#8217;t be surprised if Firefox handles the case where a listener in the chain drops the ball, or does something unexpected. I haven&#8217;t tested the code in question in a while, but did you try the technique I used in the previous comment? (Just to be sure that everything else is working correctly)</p>
<p>I see why you would want to consolidate the buffer (subtring replacement or, preferably, document creation, modification, and then getting the string representation). I&#8217;ll try putting something together using your example. Any chance you could post additional code? What you&#8217;re trying to do should work according to all of the documentation (which is sadly out of date).</p>
<p>Basically, I see a few ways that the browser is not getting the modified html:</p>
<ul>
<li>the browser listener is added <em>after</em> yours (and thus your listener is downstream)</li>
<li>your listener is not passing it on correctly and the browser is correcting for this somehow</li>
<li>you are inserting something that is not valid html and is then ignored when the browser is parsing and rendering the page</li>
<li>the onDataAvailable method isn&#8217;t doing what you expect (you said you verified the contents passed on by onStopRequest so this is unlikely, but&#8230;)</li>
</ul>
<p>There are probably more possibilities but that&#8217;s all I&#8217;ve got right now. As I said, I&#8217;ll try whipping up an example like yours and see if I can figure out what went wrong.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sasha</title>
		<link>http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/comment-page-1/#comment-2230</link>
		<dc:creator>Sasha</dc:creator>
		<pubDate>Sun, 18 Dec 2011 18:50:13 +0000</pubDate>
		<guid isPermaLink="false">http://ashita.org/?p=307#comment-2230</guid>
		<description>Hey Jonathan &amp; all...

FIRST, GREAT ARTICLE!

I know that I&#039;m late to the party but I&#039;m trying your suggestion for storing up all the data from the onDataAvailable callbacks and then creating my own calls to originalListener.onDataAvailable and originalListener.onStopRequest.

In my solution I actually build one large buffer and try to make one call to originalListener.onDataAvailable and one call to originalListener.onStopRequest.

MY PROBLEM:  The browser has the original source (HTML) and not my modified version.  I inspect all the variables and know for sure that I modified the text and I know for sure that I&#039;m not passing the onDataAvailable calls to the original listener until the onStopRequest.  I don&#039;t see how this is possible.

I&#039;ve tried things like caching the first request and context but that doesn&#039;t do it.

ANY IDEAS?

Here is a code snippet from onStopRequest....

	onStopRequest: function (request, context, statusCode)
	{
		try
		{
			// QueryInterface into HttpChannel to access originalURI and requestMethod properties
			request.QueryInterface(Ci.nsIHttpChannel);

			var storageStream = CCIN(&quot;@mozilla.org/storagestream;1&quot;, &quot;nsIStorageStream&quot;);
			storageStream.init(8192, this.m_nDataSize, null);  //8192 is the segment size in bytes, count is the maximum size of the stream in bytes

			var binaryOutputStream = CCIN(&quot;@mozilla.org/binaryoutputstream;1&quot;, &quot;nsIBinaryOutputStream&quot;);
			binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));
			binaryOutputStream.writeBytes(this.m_strData, this.m_nDataSize);

			this.originalListener.onDataAvailable(request,
                                          context,
                                          storageStream.newInputStream(0),
                                          0,
                                          this.m_nDataSize);
		}
		catch (e)
		{
			dump(e);
		}

		//Pass it on down the chain
		this.originalListener.onStopRequest(request, context, statusCode);
	},</description>
		<content:encoded><![CDATA[<p>Hey Jonathan &amp; all&#8230;</p>
<p>FIRST, GREAT ARTICLE!</p>
<p>I know that I&#8217;m late to the party but I&#8217;m trying your suggestion for storing up all the data from the onDataAvailable callbacks and then creating my own calls to originalListener.onDataAvailable and originalListener.onStopRequest.</p>
<p>In my solution I actually build one large buffer and try to make one call to originalListener.onDataAvailable and one call to originalListener.onStopRequest.</p>
<p>MY PROBLEM:  The browser has the original source (HTML) and not my modified version.  I inspect all the variables and know for sure that I modified the text and I know for sure that I&#8217;m not passing the onDataAvailable calls to the original listener until the onStopRequest.  I don&#8217;t see how this is possible.</p>
<p>I&#8217;ve tried things like caching the first request and context but that doesn&#8217;t do it.</p>
<p>ANY IDEAS?</p>
<p>Here is a code snippet from onStopRequest&#8230;.</p>
<p>	onStopRequest: function (request, context, statusCode)<br />
	{<br />
		try<br />
		{<br />
			// QueryInterface into HttpChannel to access originalURI and requestMethod properties<br />
			request.QueryInterface(Ci.nsIHttpChannel);</p>
<p>			var storageStream = CCIN(&#8220;@mozilla.org/storagestream;1&#8243;, &#8220;nsIStorageStream&#8221;);<br />
			storageStream.init(8192, this.m_nDataSize, null);  //8192 is the segment size in bytes, count is the maximum size of the stream in bytes</p>
<p>			var binaryOutputStream = CCIN(&#8220;@mozilla.org/binaryoutputstream;1&#8243;, &#8220;nsIBinaryOutputStream&#8221;);<br />
			binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));<br />
			binaryOutputStream.writeBytes(this.m_strData, this.m_nDataSize);</p>
<p>			this.originalListener.onDataAvailable(request,<br />
                                          context,<br />
                                          storageStream.newInputStream(0),<br />
                                          0,<br />
                                          this.m_nDataSize);<br />
		}<br />
		catch (e)<br />
		{<br />
			dump(e);<br />
		}</p>
<p>		//Pass it on down the chain<br />
		this.originalListener.onStopRequest(request, context, statusCode);<br />
	},</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jonathan Fingland</title>
		<link>http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/comment-page-1/#comment-1550</link>
		<dc:creator>Jonathan Fingland</dc:creator>
		<pubDate>Wed, 06 Apr 2011 13:23:14 +0000</pubDate>
		<guid isPermaLink="false">http://ashita.org/?p=307#comment-1550</guid>
		<description>Ahh, well I&#039;ve fixed the previous comment now, thanks. I suppose both versions would work, though the first would be preferable.</description>
		<content:encoded><![CDATA[<p>Ahh, well I&#8217;ve fixed the previous comment now, thanks. I suppose both versions would work, though the first would be preferable.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Divya</title>
		<link>http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/comment-page-1/#comment-1549</link>
		<dc:creator>Divya</dc:creator>
		<pubDate>Wed, 06 Apr 2011 11:11:39 +0000</pubDate>
		<guid isPermaLink="false">http://ashita.org/?p=307#comment-1549</guid>
		<description>I am sorry I did not respond immedialtely..
This was not working bcoz of a typo..

this.buffer.push({request:request, context:context, inputSteam:storageStream.newInputStream(0), offset:offset, count:count});

it should be 
inputStream:storageStream.newInputStream(0)

an &#039;r&#039; was missing

Thanks a lot dude..</description>
		<content:encoded><![CDATA[<p>I am sorry I did not respond immedialtely..<br />
This was not working bcoz of a typo..</p>
<p>this.buffer.push({request:request, context:context, inputSteam:storageStream.newInputStream(0), offset:offset, count:count});</p>
<p>it should be<br />
inputStream:storageStream.newInputStream(0)</p>
<p>an &#8216;r&#8217; was missing</p>
<p>Thanks a lot dude..</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jonathan Fingland</title>
		<link>http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/comment-page-1/#comment-1542</link>
		<dc:creator>Jonathan Fingland</dc:creator>
		<pubDate>Thu, 31 Mar 2011 22:20:25 +0000</pubDate>
		<guid isPermaLink="false">http://ashita.org/?p=307#comment-1542</guid>
		<description>Divya, my guess is that it is failing when passing to the next listener. To minimize differences from the original code, I created the new input streams on the onDataAvailable and tried to use them later on in the onStopRequest. 

Below is a rather different approach, but may work better

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;
TracingListener.prototype =
{
    originalListener: null,
    receivedData: null,
    buffer: null,

    onStartRequest: function(request, context) {
    	this.receivedData = []; //initialize the array
    	this.buffer = []; //initialize the array

	//Pass on the onStartRequest call to the next listener in the chain -- VERY IMPORTANT
	this.originalListener.onStartRequest(request, context);
    },
    onDataAvailable: function(request, context, inputStream, offset, count)
    {
       var binaryInputStream = CCIN(&quot;@mozilla.org/binaryinputstream;1&quot;,
                                 &quot;nsIBinaryInputStream&quot;);
        binaryInputStream.setInputStream(inputStream);

        // Copy received data as they come.
        var data = binaryInputStream.readBytes(count);

        this.receivedData.push(data);

        this.buffer.push({request:request, context:context, data:data, offset:offset, count:count});
    },

    onStopRequest: function(request, context, statusCode)
    {
	try
	{
                //QueryInterface into HttpChannel to access originalURI and requestMethod properties
		request.QueryInterface(Ci.nsIHttpChannel);

                //this is specific to the PirateQuesting Add-on, but is left here as an example of how to modify behaviour based on the requested URL
		if (request.originalURI
                    &amp;&amp; piratequesting.baseURL == request.originalURI.prePath
                    &amp;&amp; request.originalURI.path.indexOf(&quot;/index.php?ajax=&quot;) == 0)
		{

			var data = null;
			if (request.requestMethod.toLowerCase() == &quot;post&quot;)
			{
				var postText = this.readPostTextFromRequest(request, context);
				if (postText)
					data = ((String)(postText)).parseQuery();

			}

                        //Combine the response into a single string
			var responseSource = this.receivedData.join(&#039;&#039;);

			//fix leading spaces bug
			//(FM occasionally adds spaces to the beginning of their ajax responses...
                        //which breaks the XML)
			responseSource = responseSource.replace(/^\s+(\S[\s\S]+)/, &quot;$1&quot;);

                        //gets the date from the response headers on the request.
                        //For PirateQuesting this was preferred over the date on the user&#039;s machine
			var date = Date.parse(request.getResponseHeader(&quot;Date&quot;));

                        //Again a PQ specific function call, but left as an example.
                        //This just passes a string URL, the text of the response,
                        //the date, and the data in the POST request (if applicable)
			piratequesting.ProcessRawResponse(request.originalURI.spec,
                                               responseSource,
                                               date,
                                               data);
		}

		//Now that we:re done with the data for our part, we can pass it on.
		var buffItem;
		for (var i=0, len=this.buffer.length;i&lt;len;i++) {
                       buffItem = this.buffer[i];
                       
                       var storageStream = CCIN(&quot;@mozilla.org/storagestream;1&quot;,
                                 &quot;nsIStorageStream&quot;);
                       //8192 is the segment size in bytes, count is the maximum size of the stream in bytes
                       storageStream.init(8192, buffItem.count, null); 

                      	var binaryOutputStream = CCIN(&quot;@mozilla.org/binaryoutputstream;1&quot;,
                                 &quot;nsIBinaryOutputStream&quot;);
                       binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));

                       
                       binaryOutputStream.writeBytes(buffItem.data, buffItem.count);

                       
		        this.originalListener.onDataAvailable(buffItem.request,
                                          buffItem.context,
                                          storageStream.newInputStream(0),
                                          buffItem.offset,
                                          buffItem.count);
		}

	}
	catch (e)
	{
		//standard function to dump a formatted version of the error to console
		dumpError(e);
	}
	//Pass it on down the chain
	this.originalListener.onStopRequest(request,
                                         context,
                                         statusCode);
    },
.
.
.
(etc)
&lt;/code&gt;&lt;/pre&gt;

What this attempts to do is create new input streams immediately before passing it on to the next listener.</description>
		<content:encoded><![CDATA[<p>Divya, my guess is that it is failing when passing to the next listener. To minimize differences from the original code, I created the new input streams on the onDataAvailable and tried to use them later on in the onStopRequest. </p>
<p>Below is a rather different approach, but may work better</p>
<pre><code class="javascript">
TracingListener.prototype =
{
    originalListener: null,
    receivedData: null,
    buffer: null,

    onStartRequest: function(request, context) {
    	this.receivedData = []; //initialize the array
    	this.buffer = []; //initialize the array

	//Pass on the onStartRequest call to the next listener in the chain -- VERY IMPORTANT
	this.originalListener.onStartRequest(request, context);
    },
    onDataAvailable: function(request, context, inputStream, offset, count)
    {
       var binaryInputStream = CCIN("@mozilla.org/binaryinputstream;1",
                                 "nsIBinaryInputStream");
        binaryInputStream.setInputStream(inputStream);

        // Copy received data as they come.
        var data = binaryInputStream.readBytes(count);

        this.receivedData.push(data);

        this.buffer.push({request:request, context:context, data:data, offset:offset, count:count});
    },

    onStopRequest: function(request, context, statusCode)
    {
	try
	{
                //QueryInterface into HttpChannel to access originalURI and requestMethod properties
		request.QueryInterface(Ci.nsIHttpChannel);

                //this is specific to the PirateQuesting Add-on, but is left here as an example of how to modify behaviour based on the requested URL
		if (request.originalURI
                    &amp;&amp; piratequesting.baseURL == request.originalURI.prePath
                    &amp;&amp; request.originalURI.path.indexOf("/index.php?ajax=") == 0)
		{

			var data = null;
			if (request.requestMethod.toLowerCase() == "post")
			{
				var postText = this.readPostTextFromRequest(request, context);
				if (postText)
					data = ((String)(postText)).parseQuery();

			}

                        //Combine the response into a single string
			var responseSource = this.receivedData.join('');

			//fix leading spaces bug
			//(FM occasionally adds spaces to the beginning of their ajax responses...
                        //which breaks the XML)
			responseSource = responseSource.replace(/^\s+(\S[\s\S]+)/, "$1");

                        //gets the date from the response headers on the request.
                        //For PirateQuesting this was preferred over the date on the user's machine
			var date = Date.parse(request.getResponseHeader("Date"));

                        //Again a PQ specific function call, but left as an example.
                        //This just passes a string URL, the text of the response,
                        //the date, and the data in the POST request (if applicable)
			piratequesting.ProcessRawResponse(request.originalURI.spec,
                                               responseSource,
                                               date,
                                               data);
		}

		//Now that we:re done with the data for our part, we can pass it on.
		var buffItem;
		for (var i=0, len=this.buffer.length;i&lt;len;i++) {
                       buffItem = this.buffer[i];

                       var storageStream = CCIN("@mozilla.org/storagestream;1",
                                 "nsIStorageStream");
                       //8192 is the segment size in bytes, count is the maximum size of the stream in bytes
                       storageStream.init(8192, buffItem.count, null); 

                      	var binaryOutputStream = CCIN("@mozilla.org/binaryoutputstream;1",
                                 "nsIBinaryOutputStream");
                       binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));

                       binaryOutputStream.writeBytes(buffItem.data, buffItem.count);

		        this.originalListener.onDataAvailable(buffItem.request,
                                          buffItem.context,
                                          storageStream.newInputStream(0),
                                          buffItem.offset,
                                          buffItem.count);
		}

	}
	catch (e)
	{
		//standard function to dump a formatted version of the error to console
		dumpError(e);
	}
	//Pass it on down the chain
	this.originalListener.onStopRequest(request,
                                         context,
                                         statusCode);
    },
.
.
.
(etc)
</code></pre>
<p>What this attempts to do is create new input streams immediately before passing it on to the next listener.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Divya</title>
		<link>http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/comment-page-1/#comment-1539</link>
		<dc:creator>Divya</dc:creator>
		<pubDate>Thu, 31 Mar 2011 09:00:14 +0000</pubDate>
		<guid isPermaLink="false">http://ashita.org/?p=307#comment-1539</guid>
		<description>I think I spoke too early..
[Exception... &quot;Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIBinaryInputStream.setInputStream]&quot;  nsresult: &quot;0x80004003 (NS_ERROR_INVALID_POINTER)&quot;
Any comments?</description>
		<content:encoded><![CDATA[<p>I think I spoke too early..<br />
[Exception... "Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIBinaryInputStream.setInputStream]&#8221;  nsresult: &#8220;0&#215;80004003 (NS_ERROR_INVALID_POINTER)&#8221;<br />
Any comments?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Divya</title>
		<link>http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/comment-page-1/#comment-1538</link>
		<dc:creator>Divya</dc:creator>
		<pubDate>Thu, 31 Mar 2011 07:38:01 +0000</pubDate>
		<guid isPermaLink="false">http://ashita.org/?p=307#comment-1538</guid>
		<description>Thanks dude..
The code definitely works...
But my firefox crashes the moment I use this approach..Any ideas as to why this might be happening?</description>
		<content:encoded><![CDATA[<p>Thanks dude..<br />
The code definitely works&#8230;<br />
But my firefox crashes the moment I use this approach..Any ideas as to why this might be happening?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jonathan Fingland</title>
		<link>http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/comment-page-1/#comment-1536</link>
		<dc:creator>Jonathan Fingland</dc:creator>
		<pubDate>Tue, 29 Mar 2011 22:12:02 +0000</pubDate>
		<guid isPermaLink="false">http://ashita.org/?p=307#comment-1536</guid>
		<description>Divya, One option, I suppose, would be to not pass it on to the next listener in the chain at the end of onDataAvailable. Then, in the onStopRequest, pass all of the accumulated data to the next listener in the onDataAvailable chain. The only trick is that all of the parameters have to be preserved as the other listeners may rely on them.

For example:

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;
TracingListener.prototype =
{
    originalListener: null,
    receivedData: null,
    buffer: null,

    onStartRequest: function(request, context) {
    	this.receivedData = []; //initialize the array
    	this.buffer = []; //initialize the array

	//Pass on the onStartRequest call to the next listener in the chain -- VERY IMPORTANT
	this.originalListener.onStartRequest(request, context);
    },
    onDataAvailable: function(request, context, inputStream, offset, count)
    {
       var binaryInputStream = CCIN(&quot;@mozilla.org/binaryinputstream;1&quot;,
                                 &quot;nsIBinaryInputStream&quot;);
        binaryInputStream.setInputStream(inputStream);

        var storageStream = CCIN(&quot;@mozilla.org/storagestream;1&quot;,
                                 &quot;nsIStorageStream&quot;);
        //8192 is the segment size in bytes, count is the maximum size of the stream in bytes
        storageStream.init(8192, count, null); 

	var binaryOutputStream = CCIN(&quot;@mozilla.org/binaryoutputstream;1&quot;,
                                 &quot;nsIBinaryOutputStream&quot;);
        binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));

        // Copy received data as they come.
        var data = binaryInputStream.readBytes(count);

        this.receivedData.push(data);

        binaryOutputStream.writeBytes(data, count);
        this.buffer.push({request:request, context:context, inputStream:storageStream.newInputStream(0), offset:offset, count:count});
    },

onStopRequest: function(request, context, statusCode)
    {
	try
	{
                //QueryInterface into HttpChannel to access originalURI and requestMethod properties
		request.QueryInterface(Ci.nsIHttpChannel);

                //this is specific to the PirateQuesting Add-on, but is left here as an example of how to modify behaviour based on the requested URL
		if (request.originalURI
                    &amp;&amp; piratequesting.baseURL == request.originalURI.prePath
                    &amp;&amp; request.originalURI.path.indexOf(&quot;/index.php?ajax=&quot;) == 0)
		{

			var data = null;
			if (request.requestMethod.toLowerCase() == &quot;post&quot;)
			{
				var postText = this.readPostTextFromRequest(request, context);
				if (postText)
					data = ((String)(postText)).parseQuery();

			}

                        //Combine the response into a single string
			var responseSource = this.receivedData.join(&#039;&#039;);

			//fix leading spaces bug
			//(FM occasionally adds spaces to the beginning of their ajax responses...
                        //which breaks the XML)
			responseSource = responseSource.replace(/^\s+(\S[\s\S]+)/, &quot;$1&quot;);

                        //gets the date from the response headers on the request.
                        //For PirateQuesting this was preferred over the date on the user&#039;s machine
			var date = Date.parse(request.getResponseHeader(&quot;Date&quot;));

                        //Again a PQ specific function call, but left as an example.
                        //This just passes a string URL, the text of the response,
                        //the date, and the data in the POST request (if applicable)
			piratequesting.ProcessRawResponse(request.originalURI.spec,
                                               responseSource,
                                               date,
                                               data);
		}

		//Now that we:re done with the data for our part, we can pass it on.
		var buffItem;
		for (var i=0, len=this.buffer.length;i&lt;len;i++) {
                       buffItem = this.buffer[i];
		        this.originalListener.onDataAvailable(buffItem.request,
                                          buffItem.context,
                                          buffItem.inputStream,
                                          buffItem.offset,
                                          buffItem.count);
		}

	}
	catch (e)
	{
		//standard function to dump a formatted version of the error to console
		dumpError(e);
	}
	//Pass it on down the chain
	this.originalListener.onStopRequest(request,
                                         context,
                                         statusCode);
    },
.
.
.
(etc)
&lt;/code&gt;&lt;/pre&gt;

note the use of a buffer array to store, in order, every onDataAvaliable call so that we can sort of replay them in the onStopRequest. Please note that I haven&#039;t tested this, but I would expect it to work. We:re basically just holding it back and letting it all go at once, this way. That said, depending on the situation, this could result in highly unexpected behaviour for the end user. most people are used to seeing pages come in gradually rather than all at once.

EDIT: Fixed Type (inputSteam -&gt; inputStream)</description>
		<content:encoded><![CDATA[<p>Divya, One option, I suppose, would be to not pass it on to the next listener in the chain at the end of onDataAvailable. Then, in the onStopRequest, pass all of the accumulated data to the next listener in the onDataAvailable chain. The only trick is that all of the parameters have to be preserved as the other listeners may rely on them.</p>
<p>For example:</p>
<pre><code class="javascript">
TracingListener.prototype =
{
    originalListener: null,
    receivedData: null,
    buffer: null,

    onStartRequest: function(request, context) {
    	this.receivedData = []; //initialize the array
    	this.buffer = []; //initialize the array

	//Pass on the onStartRequest call to the next listener in the chain -- VERY IMPORTANT
	this.originalListener.onStartRequest(request, context);
    },
    onDataAvailable: function(request, context, inputStream, offset, count)
    {
       var binaryInputStream = CCIN("@mozilla.org/binaryinputstream;1",
                                 "nsIBinaryInputStream");
        binaryInputStream.setInputStream(inputStream);

        var storageStream = CCIN("@mozilla.org/storagestream;1",
                                 "nsIStorageStream");
        //8192 is the segment size in bytes, count is the maximum size of the stream in bytes
        storageStream.init(8192, count, null); 

	var binaryOutputStream = CCIN("@mozilla.org/binaryoutputstream;1",
                                 "nsIBinaryOutputStream");
        binaryOutputStream.setOutputStream(storageStream.getOutputStream(0));

        // Copy received data as they come.
        var data = binaryInputStream.readBytes(count);

        this.receivedData.push(data);

        binaryOutputStream.writeBytes(data, count);
        this.buffer.push({request:request, context:context, inputStream:storageStream.newInputStream(0), offset:offset, count:count});
    },

onStopRequest: function(request, context, statusCode)
    {
	try
	{
                //QueryInterface into HttpChannel to access originalURI and requestMethod properties
		request.QueryInterface(Ci.nsIHttpChannel);

                //this is specific to the PirateQuesting Add-on, but is left here as an example of how to modify behaviour based on the requested URL
		if (request.originalURI
                    &#038;&#038; piratequesting.baseURL == request.originalURI.prePath
                    &#038;&#038; request.originalURI.path.indexOf("/index.php?ajax=") == 0)
		{

			var data = null;
			if (request.requestMethod.toLowerCase() == "post")
			{
				var postText = this.readPostTextFromRequest(request, context);
				if (postText)
					data = ((String)(postText)).parseQuery();

			}

                        //Combine the response into a single string
			var responseSource = this.receivedData.join('');

			//fix leading spaces bug
			//(FM occasionally adds spaces to the beginning of their ajax responses...
                        //which breaks the XML)
			responseSource = responseSource.replace(/^\s+(\S[\s\S]+)/, "$1");

                        //gets the date from the response headers on the request.
                        //For PirateQuesting this was preferred over the date on the user's machine
			var date = Date.parse(request.getResponseHeader("Date"));

                        //Again a PQ specific function call, but left as an example.
                        //This just passes a string URL, the text of the response,
                        //the date, and the data in the POST request (if applicable)
			piratequesting.ProcessRawResponse(request.originalURI.spec,
                                               responseSource,
                                               date,
                                               data);
		}

		//Now that we:re done with the data for our part, we can pass it on.
		var buffItem;
		for (var i=0, len=this.buffer.length;i&lt;len;i++) {
                       buffItem = this.buffer[i];
		        this.originalListener.onDataAvailable(buffItem.request,
                                          buffItem.context,
                                          buffItem.inputStream,
                                          buffItem.offset,
                                          buffItem.count);
		}

	}
	catch (e)
	{
		//standard function to dump a formatted version of the error to console
		dumpError(e);
	}
	//Pass it on down the chain
	this.originalListener.onStopRequest(request,
                                         context,
                                         statusCode);
    },
.
.
.
(etc)
</code></pre>
<p>note the use of a buffer array to store, in order, every onDataAvaliable call so that we can sort of replay them in the onStopRequest. Please note that I haven&#8217;t tested this, but I would expect it to work. We:re basically just holding it back and letting it all go at once, this way. That said, depending on the situation, this could result in highly unexpected behaviour for the end user. most people are used to seeing pages come in gradually rather than all at once.</p>
<p>EDIT: Fixed Type (inputSteam -&gt; inputStream)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Divya</title>
		<link>http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/comment-page-1/#comment-1535</link>
		<dc:creator>Divya</dc:creator>
		<pubDate>Tue, 29 Mar 2011 14:43:07 +0000</pubDate>
		<guid isPermaLink="false">http://ashita.org/?p=307#comment-1535</guid>
		<description>Likes!! :)
I have a question. I am trying to show the response in a dialog, before loading it in the browser.
But if i do this in onStopRequest its too late.. parts of the response have already reached the browser.. and if i do this in onDataAvailable its too early, coz parts of the response may have not yet been recieved..
What approach should i take?</description>
		<content:encoded><![CDATA[<p>Likes!! :)<br />
I have a question. I am trying to show the response in a dialog, before loading it in the browser.<br />
But if i do this in onStopRequest its too late.. parts of the response have already reached the browser.. and if i do this in onDataAvailable its too early, coz parts of the response may have not yet been recieved..<br />
What approach should i take?</p>
]]></content:encoded>
	</item>
</channel>
</rss>

