0

I am developing a firefox extension that retrieves data from the webpage in the current tab. I am loading a script into the webpage when the user clicks on the overlay toolbar button which does some processing and gets information from the web page. I want to display that information in a popup window.

I am using the following api to load the script:

var loader = Components.classes[ "@mozilla.org/moz/jssubscript-loader;1" ].getService( Components.interfaces.mozIJSSubScriptLoader );
loader.loadSubScript("chrome://dynamonote/content/contentscript.js");

I need to send the object created in contentscript.js and display it in popup.html which is displayed when user clicks on the toolbar icon.

I am receiving the gBrowser is not defined error when I execute the code. The details of the code I am using is given below:

In the onCommand of the overlay, I am calling the following function:

var Popup = {
    showPopup: function() {
        window.open("chrome://dynamonote/content/popup.html", "dynamonote", "chrome");
    }
};

This shows a popup window. In the init function of popup.html which is called when the page loads, I am executing the following code:

        function loadContentScript() {
            Components.utils.reportError("loadContentScript() called");
            gBrowser.selectedBrowser.messageManager.loadFrameScript("chrome://dynamonote/content/contentscript.js", true);
            gBrowser.selectedBrowser.messageManager.addMessageListener("foomessage", onMessage);
            Components.utils.reportError("loadContentScript() executed");
        }

The following code is executed in the contentscript.js file:

(function() {
    Components.utils.reportError("-- content script -- ");
    var doc = content.document;

    //Do something here

    var data = {
        "time": new Date().toLocaleString()
    };
    Components.utils.reportError("-- content script -- found something");
        sendSyncMessage("foomessage", onMessage(data));
})();

Please help me out with this.

Vivek
  • 680
  • 1
  • 12
  • 24
  • Sounds like you are trying to force concepts from Chrome extensions into a classic Firefox extension, something that is far from trivial. If that's where you are coming from, the [Add-on SDK](https://addons.mozilla.org/en-US/developers/builder) might be a better choice. In particular, the packages [page-mod](https://addons.mozilla.org/en-US/developers/docs/sdk/1.6/packages/addon-kit/page-mod.html) and [widget](https://addons.mozilla.org/en-US/developers/docs/sdk/1.6/packages/addon-kit/widget.html). Either way, you seem to be mistaken about what `mozIJSSubScriptLoader` does. – Wladimir Palant Apr 19 '12 at 19:20
  • Yes. I wanted to use the chrome code in firefox as well. Could you suggest a better way to do this? I cannot use the sdk apis because they dont allow me to add a toolbar button in the navigation bar like xul. Also could you tell me the difference between loadSubscript of firefox and executescript of chrome? – Vivek Apr 19 '12 at 19:43
  • There is a reason why the SDK does that - extensions aren't supposed to waste space in the navigation bar any more. But, see http://stackoverflow.com/a/9622212/785541. – Wladimir Palant Apr 19 '12 at 19:47
  • Is there an alternate way if I want to follow the XUL way? If I need to change the current design, could you please tell me how I could approach this problem? – Vivek Apr 19 '12 at 19:54

1 Answers1

1

If you want content scripts in a classic Firefox extension then mozIJSSubScriptLoader is the wrong tool - the "content script" will keep advanced privileges and likely cause security issues. You could use the message manager instead (ignore the talk about process separation, it is irrelevant for the desktop Firefox). So to load your script into the currently selected tab you would use the following code:

gBrowser.selectedBrowser.messageManager
        .loadFrameScript("chrome://dynamonote/content/contentscript.js", true);
gBrowser.selectedBrowser.messageManager.addMessageListener("foomessage", onMessage);

function onMessage(obj)
{
  alert("Received object from content script: " + obj.toSource());
}

Note that you should remove that message listener when it isn't needed any more. And to send a message back the content script would use code like this:

sendAsyncMessage("foomessage", obj);
Wladimir Palant
  • 56,865
  • 12
  • 98
  • 126
  • I tried out the solution but I am receiving the gBrowser is not defined error. I have updated my question with some more information. Also tried window.messageManager but that did not work either. – Vivek Apr 20 '12 at 06:44
  • @quad_damage: `gBrowser` is a global variable defined in the context of the browser window. If you script is running in a different window then you need to get the browser window first. In your case it is probably as simple as `parent.gBrowser` (the script is running inside a frame in the browser window). – Wladimir Palant Apr 20 '12 at 11:25
  • Sorry, I am getting the same error message "parent.gBrowser is undefined". I am loading the script from popup.html file. Popup.html is loaded when the user clicks on the toolbar icon. How can I access the gBrowser object from popup.html? I am using the following api to open the popup: `window.open("chrome://dynamonote/content/popup.html", "dynamonote", "chrome");` Is this the right way to do it? – Vivek Apr 20 '12 at 13:33
  • @quad_damage: Heh... As I said, if "the script is running inside a frame". For a dialog window it will be `window.opener.gBrowser`. – Wladimir Palant Apr 20 '12 at 14:51
  • Thank you Wladimir :) I had some confusions regarding the scope of the objects and their access. I was able to bring it to a working state with your suggestions. Is there a good tutorial which explains the concepts related to Firefox add-on development which I can refer to? – Vivek Apr 22 '12 at 18:09