My favorites | Sign in
Project Logo
                
Search
for
Updated Oct 27, 2008 by mikeal.rogers
Labels: Featured
UsingJSBridge  
A guide to using jsbridge

Introduction

jsbridge is intended to be a standard way of communicating with a Mozilla javascript environment. This includes JavaScript < - > Python object translations and a callback mechanism for Python responses to custom events fired in the javascript environment.

The Shell

jsbridge by default using mozrunner to start Firefox and configure it for the bridge.

You can use the jsbridge script to start Firefox the bridge and drop in to an interactive shell. If you have ipython installed it will use ipython's shell instead of the default Python shell, this is recommended on non-Windows platforms.

$ jsbridge --launch
Started  ['/Applications/Firefox.app/Contents/MacOS/firefox-bin', '-profile', 
'/var/folders/fj/fjSM4KgKEXCWylssQ3jcBU+++TI/-Tmp-/tmpZcrIck.mozrunner', '-repl', '24242', '-jsconsole']

In [1]: 

When launching a mozilla application the application's stdout is redirected to your local Python's stdout.

In the interactive shell you have an object in the local space called bridge, this object is a representation of the focused window in the mozilla application at the time the bridge is started.

All objects in all namespace in this window will be lazy loaded when you try and access them or in the interactive interpreter when you try to use tab completion or call dir() on an object:

In [1]: bridge.<tab>
Display all 486 possibilities? (y or n)

You can set JavaScript attributes and call JavaScript functions from Python.

In [1]: bridge.title = 'asdf'

In [2]: bridge.focus()

You can also get new bridge objects using a couple built in helper functions.

In [2]: mostRecentBrowserWindow = jsbridge.getBrowserWindow()

In [3]: preferencesWindow = jsbridge.getPreferencesWindow()

Running jsbridge from your code

import jsbridge

def dostuff(): pass

if __name__ == "__main__":
    moz = jsbridge.start(start_firefox=True)
    dostuff()
    try:
        moz.wait()
    except KeyboardInterrupt:
        moz.stop()

This is the simplest case. It starts Firefox with the bridge attached and waits for either Firefox to quit or a keyboard interrupt.

Now we'll add some actual code to dostuff().

def dostuff():
    from jsbridge import network
    my_module = JSObject(network.bridge, "Components.utils.import('resource://myextension/modules/myModule.js)")
    my_module.runMyJS()

This illustrates how you can call code defined in an extension's resource from Python.

Using the jsbridge event system

jsbridge has an incredibly powerful event system. On the JavaScript side, you can fire your own events from your Mozilla extension or application code. Those events are then JSON serialized and sent over a backchannel to Python. On the Python side you can add listeners for those events and trigger your own related Python code.

Here is a very simple example.

JavaScript (most likely to be placed in your extension code)

var events = {}; Components.utils.import("resource://jsbridge/modules/events.js", events);

var pass = function (obj){
  events.fireEvent("myextension:pass", obj);
}
var fail = function (obj){
  events.fireEvent("myextension:fail", obj);
}
var end = function (){
  events.fireEvent("myextension:end", true);
}

Python Example 1 (global listener)

from jsbridge.events import add_global_listener

results = { "pass": [], "fail": [] }

def global_listener(event_name, obj):
    if event_name == "myextension.pass" or event_name == "myextension.fail":
        results[event_name].append(obj)
    elif event_name == "myextension.end":
        print "Done. Passes = "+str(len(results['pass']))+", Fails = "+str(len(results['fail']))

add_global_listener(global_listener)

Python Example 2 (individual listeners)

from jsbridge.events import add_listener

passes = []
fails = []

add_listener("myextension.pass", lambda obj: passes.append(obj) )
add_listener("myextension.fail", lambda obj: fails.append(obj) )

def done(obj):
    print "Done. Passes = "+str(len(passes))+", Fails = "+str(len(fails))

add_listener("myextension.end", done)

Sign in to add a comment
Hosted by Google Code