Python Component Sample

Last modified

XPConnect allows JavaScript to transparantly access and manipulate XPCOM objects;

Big Deal, I hear you say! But it also works for Python!!!

This sample demonstrates accessing a XPCOM object through XPConnect. The JavaScript executed when this page loads creates an instance of the Python object by using the `Components` object, then accesses it through the nsISample interface by calling `QueryInterface`:

    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
    var sample = Components.classes["component://mozilla/sample/sample-world"].createInstance();
    sample = sample.QueryInterface(Components.interfaces.nsISample);

The buttons on the form are connected to JavaScript event handlers which call the methods defined in Python

Compiling the idl

The XPIDL compiler (xpidl on Unix, xpidl.exe on Windows, and a CodeWarrior plugin on Mac) is compiled at build time (except on Mac) thus you will have to build mozilla in order to test this out. If you have already built mozilla then the compiler will be located at `mozilla\dist\WIN32_D.OBJ\bin\xpidl.exe`.

Once you have the XPIDL compiler enter the following command at your prompt:
`D:\whereever\xpcom\test\test_component>d:\mozilla\dist\WIN32_D.OBJ\bin\xpidl -I d:\mozilla\dist\idl -m typelib py_test_component.idl`. You must then copy the generated .xpt file to the mozilla component directory.

The `-I d:\mozilla\dist\idl` points the compiler to the folder containing the other idl files, needed because nsISample.idl inherits from nsISupports.idl. The `-m typelib` instruction tells the compiler to build the .XPT typelib file..

For more information on compilation see the xpidl compiler page.

Running the sample

NOTE: This doesn't work for me - I get an access denied error using XPConnect!

Using Mozilla, load this file. Pay attention to the console when clicking "write".

JavaScript and form source:

    <script>
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
    var sample = Components.classes["component://Python.TestComponent"].createInstance();
    sample = sample.QueryInterface(Components.interfaces.nsIPythonTestInterface);
    dump("sample = " + sample + "\n");

    function get()
    {
      var field = document.getElementById('Value');
      field.value = sample.str_value;
    }

    function set()
    {
      var field = document.getElementById('Value');
      sample.str_value = field.value;
    }

    function poke()
    {
      var field = document.getElementById('Value');
      sample.poke(field.value);
    }

    function write()
    {
      sample.writeValue("here is what I'm writing: ");
    }
    </script>

    <form name="form">
    <input type="button" value="Get" onclick="get();">
    <input type="button" value="Set" onclick="set();">
    <input type="button" value="Poke" onclick="poke();">
    <input type="text" id="Value">
    <input type="button" value="Write" onclick="write();">
    <form>