Oct 12 2009

Getting the source window of a request

Category: Firefox, JavaScriptJonathan Fingland @ 3:35 pm

This post draws heavily on a question and answer on “An observer for URL changes (Firefox extension)” from StackOverflow.

In this post, however, I’m going to focus only on getting the window from which an http request originated.

  • What you need to know

    Yesterday’s post about XHR Listening by a Firefox Addon gives a good basis to work from so I will assume you’ve read over that and understood it (you if haven’t read it, do so now).

  • Organization and code

    In the case on StackOverflow, the logic was all in the observer, not the TracingListener. It also makes a good example of how to get selected data.

    
    
    var myObserver = {
       observe: function(aSubject, aTopic, aData){
              if (aTopic == 'http-on-examine-response')
              {
                    var oHttp = aSubject.QueryInterface(Ci.nsIHttpChannel);
                    var interfaceRequestor =   oHttp.notificationCallbacks
                                                   .QueryInterface(Ci.nsIInterfaceRequestor);
                    aSubject.DOMWindow = interfaceRequestor.getInterface(Ci.nsIDOMWindow);
              }
         }
       },
    
       QueryInterface: function(iid){
          if (!iid.equals(Ci.nsISupports) &&
              !iid.equals(Ci.nsIObserver))
            throw Components.results.NS_ERROR_NO_INTERFACE;
    
          return this;
       }
    }
    
    • How does it work?

      The three lines after our topic check very simply QueryInterface into nsIHttpChannel (like we had to with getting the URI and requestMethod), then the tricky bit is the next two steps: getting the channel’s notificationCallbacks and QueryInterface-ing into an nsIInterfaceRequestor, and then calling getInterface to get an nsIDOMWindow. nsIInterfaceRequestor provides a single method, getInterface, which is very similar to QueryInterface, but not the same (See the nsIInterfaceRequestor docs for more info).

  • Finishing up

    All that’s left is to register the observer

    
    var observerService = Cc["@mozilla.org/observer-service;1"]
        .getService(Ci.nsIObserverService);
    
    observerService.addObserver(myObserver,
        "http-on-examine-response", false);
    

Leave a Reply