Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Communication between firefox extension and page javascript

I am developing a web-based javascript/html application with a sister firefox-extension.

The application's page-javascript performs a few XHR calls immediately after page-load, in order to bring in and display all the content that the page requires.

Is there a way, without polling the DOM, that my extension can know that the page's initialisation procedures are complete?

like image 836
Cheekysoft Avatar asked Aug 20 '09 10:08

Cheekysoft


2 Answers

Interesting question indeed..

I've just found out through this post on MozillaZine's forum an easy way to accomplish this. The technique basically consists in defining a custom DOM element within the web page, filling it with some arbitrary attributes, and then using it as the target of a custom event. The event can than be captured and used to pass values from the webpage to the extension.

Web page (assumes jquery is available)

<script type="text/javascript">
    $(document).ready(function(){

    $.get("http://mywebsite.net/ajax.php",function(data){
         //[...]process data

        //define a custom element and append it to the document

         var element = document.createElement("MyExtensionDataElement");
         element.setAttribute("application_state", "ready");
         document.documentElement.appendChild(element);

         //create a custom event and dispatch it 
         // using the custom element as its target

         var ev = document.createEvent("Events");
         ev.initEvent("MyExtensionEvent", true, false);
         element.dispatchEvent(ev);
    });             
  });
</script>

Chrome code:

function myListener(e) {
   alert("data:" + e.target.getAttribute("application_state"));
}

function on_specialpage_load(event) {
  if (event.originalTarget instanceof HTMLDocument && 
      event.originalTarget.location.href == "http://mywebsite.net/myspecialpage.html") {

    var doc=event.originalTarget;
    doc.addEventListener("MyExtensionEvent", myListener, false, true);
  }
}
gBrowser.addEventListener("DOMContentLoaded",on_specialpage_load,false);

Notice that doc.addEventListener has a fourth parameter, indicating that it will accept events coming from untrusted code. However you can add this event listener selectively, so that only trusted pages from your site will be able to pass values to the extension.

like image 178
Andrea Fiore Avatar answered Sep 19 '22 03:09

Andrea Fiore


You could hook into the XMLHttpRequest object from your extension and monitor the requests, similar to what this GreaseMonkey script does (description). Add a wrapper to onreadystatechange in the same way he's added a wrapper to open which notifies the extension when complete. Probably also want some code which makes sure you're only doing this when visiting your own page.

Firebug does similar stuff for its Net panel, the codebase for that is a bit more intimidating though :) I also had a look at the Firebug Lite watchXHR function, but that code is a bit too cunning for me, if you can work it out let me know.

like image 28
robertc Avatar answered Sep 23 '22 03:09

robertc