<?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>Ashita.org &#187; XPCOM</title>
	<atom:link href="http://www.ashita.org/tag/xpcom/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ashita.org</link>
	<description></description>
	<lastBuildDate>Thu, 22 Apr 2010 17:21:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Implementing an XPCOM Firefox Interface and Creating Observers</title>
		<link>http://www.ashita.org/implementing-an-xpcom-firefox-interface-and-creating-observers/</link>
		<comments>http://www.ashita.org/implementing-an-xpcom-firefox-interface-and-creating-observers/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 19:05:25 +0000</pubDate>
		<dc:creator>Jonathan Fingland</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Firefox Extension]]></category>
		<category><![CDATA[XPCOM]]></category>

		<guid isPermaLink="false">http://ashita.org/?p=314</guid>
		<description><![CDATA[There are lots of cases when it is desirable to implement one of the XPCOM interfaces in use by Firefox, or other mozilla-based browsers. There are three cases where PirateQuesting does so, but once you see the concept, it should be easy to adapt to your situation.


You must have a QueryInterface to enjoy this ride
First [...]]]></description>
			<content:encoded><![CDATA[<p>There are lots of cases when it is desirable to implement one of the XPCOM interfaces in use by Firefox, or other mozilla-based browsers. There are three cases where PirateQuesting does so, but once you see the concept, it should be easy to adapt to your situation.</p>
<ul class='structure'>
<li>
<h3>You must have a QueryInterface to enjoy this ride</h3>
<p>First off, all XPCOM interfaces in Firefox inherit from <a href="https://developer.mozilla.org/en/nsISupports"><code>nsISupports</code></a> (Also see details on oxymoronical.com <a href="http://www.oxymoronical.com/experiments/apidocs/platform/1.9.2a1pre/interface/nsISupports">here</a>). Only one method is scriptable and part of XPCOM &#8212; <a href="https://developer.mozilla.org/en/NsISupports/QueryInterface"><code>QueryInterface</code></a> &#8212; and it <em>must</em> be present in all implementations of XPCOM interfaces. </p>
<pre><code class='javascript'>
//"implements" nsISupports
var InterfaceImplementation = function() {
  QueryInterface: function (aIID) {
      if (aIID.equals(Components.interfaces.nsISupports))
      {
         return this;
      }
      throw Components.results.NS_NOINTERFACE;
  }
}
</code></pre>
<p>The above is an example of the very minimum required to support any interface. <code>QueryInterface</code> requires a first parameter which is an aIID from <code>Components.interfaces.*</code>. There is also a second, optional, parameter, but as I have never come across this in use, it&#8217;s not worth pursuing here.
</li>
<li>
<h3>Now what?</h3>
<p>A very common (and useful) use of XPCOM interface implementation is creating your own observers, for example:</p>
<pre><code class='javascript'>
var myObserver = {

  observe: function(request, aTopic, aData){
    if (aTopic == "http-on-examine-response")
    {
      //response has come back, now what?
    }
    else if (aTopic == "http-on-modify-request")
    {
      //opportunity to modify headers on request
    }
  },

  QueryInterface: function(aIID){
     if (aIID.equals(Components.interfaces.nsIObserver) ||
         aIID.equals(Components.interfaces.nsISupports))
    {
      return this;
    }
    throw Components.results.NS_NOINTERFACE;
  },
};
</code></pre>
<p>The <a href="http://www.oxymoronical.com/experiments/apidocs/interface/nsIObserverService">nsIObserver</a> interface is fairly simple as it only adds one new method. As you can see now, though, <code>QueryInterface</code> now checks for both <code>nsIObserver</code> and <code>nsISupports</code>. Remember: any interface you implement must have a <code>QueryInterface</code> supporting all interfaces in the inheritance chain.
</li>
<li>
<h3>Observer registration</h3>
<p>If you then wanted to register your observer, it&#8217;s as easy as:</p>
<pre><code class='javascript'>
var observerService = Components.classes["@mozilla.org/observer-service;1"]
                               .getService(Components.interfaces.nsIObserverService);

observerService.addObserver(myObserver,"http-on-examine-response", false);
observerService.addObserver(myObserver,"http-on-modify-request", false);
</code></pre>
<p>Then to unregister, you do:</p>
<pre><code class='javascript'>
observerService.removeObserver(myObserver, "http-on-examine-response");
observerService.removeObserver(myObserver, "http-on-modify-request");
</code></pre>
<p>When I have a chance, I&#8217;ll add a more complete example of using observers to watch http requests, but in the meantime check out the list of <a href="https://developer.mozilla.org/en/Observer_Notifications">Observer Notifications</a> at MDC.
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.ashita.org/implementing-an-xpcom-firefox-interface-and-creating-observers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
