2
votes

I have written a NPAPI plugin that implements all the logic required and now I am writing an extension that is expected to use the functionality provided in the plugin. This architecture provides me an opportunity to write the same C++ code for both Mozilla Firefox and Google Chrome.

In Chrome I instantiate the object that is defined in the plugin by writing an <embed ...> construction to the separate document that is owned by my extension (it is provided automagically to my Chrome plugin). That just works. In C++ code I perform all the works required in the constructor of my plugin object.

I can't easily adapt my solution to use it in Firefox because the extension is not backed by any separate document and my extension doesn't have permissions to write to any of already rendered documents.

My main question in the most common form is how can I use the functionality provided by the plugin many times and passing an arguments list to my native function on user clicks the button or selects my entry in the drop-down menu (i.e. the method with arguments should be invoked after the specific event, not just at arbitrary time)?

"Supplementary" questions are:

How can I instantiate a plugin in Mozilla Firefox? Where can I get a document that will be "interpreted" by FF and such that the extension will be able to write to it?

2

2 Answers

1
votes

I don't know how to do that myself, but here is an open source firefox extension that does it: https://github.com/kylehuff/webpg-firefox

0
votes

Your Firefox extension needs to make use of a "browser overlay". There are many types of overlays, for various parts of the browser, and they are loaded (overlay'ed) within the specified document, as defined in the chrome.manifest file.

For example, the following applies an overlay to the "browser.xul" file (which is the main browser window)

overlay     chrome://browser/content/browser.xul            content/firefoxOverlay.xul

Now, within that overlay file you can load your plugin object and call the methods provided by the plugin.

Here is an example XUL file which does nothing more than load the NPAPI plugin of the content-type "application/x-example-plugin", and assign the plugin object to the variable "myPlugin"

<script type="text/javascript">
    myPlugin = document.getElementById("myPlugin");
</script>
<?xml version="1.0" encoding="UTF-8"?>
<overlay id="myOverlay" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    <script type="text/javascript">
        myPlugin = document.getElementById("myPlugin");
        alert(myPlugin.someFunction());
    </scrpit>
    <window id="main-window">
        <vbox collapsed="true">
            <html:object id="myPlugin" type="application/x-example-plugin" height="1" width="1" style="visibility:hidden;"></html:object>
        </vbox>
    </window>
</overlay>

Some important things to note

  1. The "xmlns:html=..." declaration is critical, because the plugin object is being loaded in an html:object, and that declaration tells the XUL parser how to render the object.
  2. The id of the window ("main-window") is important, because that is how the XUL parser will overlay the item (within the "main" window)
  3. The object id ("myPlugin", in this example) is how you will reference the plugin object in via the JavaScript later.
  4. Because we are not showing content with our plugin, merely calling public methods provided by it, it is important to make the CSS visibility has "hidden", and the size to 1x1 pixels. Without doing this, you could end up with large blank spaces rendered in the browser UI. Additionally, it is important to use the CSS "visibility" property, not the "display" property. If you set the display property to "none", you will have issues with your plugin actually being initialized within the overlay.
  5. In your extension install.rdf file, you must specify the "unpack" property as "true", i.e.: <em:unpack>true</em:unpack>

Once your overlay is loaded within the context of the browser XUL, and your plugin initialized within the main browser window, you can reference your plugin from within the scope of the main window by the variable you have assigned it to ("myPlugin" in this example).

I will not go into depth here on how to obtain the context of the main window (see the links below), but you once you have a reference you can invoke the exposed methods from within content scripts, sidebars, toolbars, etc.

Reference links -