This page describes how to build and use XULRunner with the Python extension on Windows and while generally useful it is written based on experiences with accessibility projects. See also XULRunner. Or, if you are interested in working with XULRunner with Python on Linux, see Mark Lise's Post
With the Python extensions enabled XULRunner provides python script access to the DOM and XPCOM in addition to the usual Java Script. This gives access to Python features and modules and builds on Mark Hammond's pyXPCOM work from Active State. XPCOM components can also be created in Python.
Currently (Mar 07) Python is not enabled by default so a custom build of Mozilla is needed. This page provides instructions in the hope of eliminating much trial and error. You should also read the the developer documentation on source code and building as wells as PyXPCOM
XULRunner with Python promises to be a good platform for accessibility projects and both Jambu Alternative Input and the IAccessible2 test tool are using it. Of particular interested is access to MSAA and IAccessible2 via the Python comtypes package.
Development Machine Setup
First a word of warning that ZoneAlarm has exhibited memory leaks that cause build machines to crash with rather spurious errors. You may want to uninstall it if you suspect this to be a problem. You will also want to disable any virus scanner resident monitoring as that will slow builds.
Ensure the PC is running XP with all the latest Service Packs and patches applied.
Microsoft C++ compiler is required and whilst the current free version is Visual Studio 8 Express (MSVC8) you will almost certainly want to use Visual Studio .NET 2003 (MSVC71) which is not longer officially available. The issue is that XULRunner must be built with the same version of C as Python and with Python 2.5 that is MSVC71. Both must use the same version of the C runtime library MSVCRT?.DLL or crashes will ensue. The alternative is to build Python with MSVC8 as well asMozilla, but that may be problematic. It might also be possible to use the Open Source MinGW compiler with the correct MSVC run time but that is apparently not recommended. Apply any Service Packs and for MSVC71 SP 1 is available. The matching platform SDK is also needed and for MSVC71 that is .NET Framework SDK 1.1.
The latest Mozilla Build system is easy to use. Install the included Python distro using python25\python-2.5.msi. It doesn't need to be installed for the build but will be useful later when installing Python packages which look for entries in the Windows' registry.
Building
The batch file start-msvc71.bat is used to launch the build console (MSys from the MinGw project ). If you plan to checkout often into empty folders you could modify it to set the CVSROOT environment variable.
set CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
Having created a mozilla project directory (e.g. C:\projects\mozilla or /c/projects/mozilla in msys) create the following .mozconfig file. Note this is complete and does not require the checkout of any other project specific .mozconfig files as sometimes shown. It effectively specifies a release build that is not particularly suitable for debugging XULRunner itself. It uses the trunk (or latest) code in CVS so may be unstable.
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/../obj-xulrunner mk_add_options MOZ_CO_PROJECT=xulrunner ac_add_options --enable-application=xulrunner ac_add_options --enable-extensions=python,default ac_add_options --disable-javaxpcom ac_add_options --disable-activex ac_add_options --disable-activex-scripting ac_add_options --disable-tests ac_add_options --enable-optimize
To check out all the required source code and build it the first time with no local client.mk file, execute
cd /c/projects cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co mozilla/client.mk cd mozilla make -f client.mk
For subsequent updates from CVS followed by a build, use
cd /c/projects/mozilla make -f client.mk
which will also checkout client.mk itself
For build only, without checkouts, use
make -f client.mk build
and see client.mk for other options.
The built XULRunner can then be found as c:\projects\obj-xulrunner\dist\bin\xulrunner.exe.
Using Python in XUL applications
Add the following to your prefs.js during development
pref("browser.dom.window.dump.enabled", true); pref("javascript.options.showInConsole", true); pref("javascript.options.strict", true); pref("nglayout.debug.disable_xul_cache", true); pref("nglayout.debug.disable_xul_fastload", true);
HTML <script> tags specify that Python is used with type="application/x-python" attribute. DOM scripting is pretty much as with Java Script. For example
def onLoad(): btnTest = document.getElementById("btnTest") btnTest.addEventListener('command', onTest, False) def onTest(): window.alert('Button activated') window.addEventListener('load', onLoad, False)
One possible gotcha is that the default python path used to find modules that are imported explicitly includes the xulrunner executable directory and the directory that is current when XULRunner launches. However it does not include any path related to the XUL application being run. Some work around will need to be found.
Unhandled exceptions are displayed in the JavaScript Error Console which can be opened using xulrunner -jsconsole. One solution is to put try .... except: print_exc() round any event handler to print tracebacks to stdout and use a python console to catch that output. The JSconsole can also be open and used from code, for example (in Javascript)
function openJavaScriptConsole() { var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] .getService(Components.interfaces.nsIWindowWatcher); wwatch.openWindow(null, "chrome://global/content/console.xul", "_blank", "chrome,dialog=no,all", null); } // dump to the js console (xulrunner -jsconsole) function jsdump(str) { Components.classes['@mozilla.org/consoleservice;1'] .getService(Components.interfaces.nsIConsoleService) .logStringMessage(str); } function jserror(str) { Components.utils.reportError(str); }
A final tip is to use task manager to check for a zombie xulrunner process after a crash. A zombie will keep old code open and cause confusion when you make changes and run xulrunner again.
Deploying
Python must be installed on the target machine. Perhaps eventually a XULRunner with a minimal Python installation can be generated with something like py2exe or pyInstaller. Untill then simply deploy the dist\bin folder and the XUL application. Don't copy any .pyo files that exist for python modules in the application or errors will occur on the target machine.
It is possible to test for python in a batch file using something like
rem Check Python 2.5 installed reg query "HKLM\SOFTWARE\Python\PythonCore\2.5" > nul 2>&1 || reg query "HKCU\SOFTWARE\Python\PythonCore\2.5" > nul 2>&1 if errorlevel 1 ( echo Python 2.5 was not found. Please install it. echo Exiting... pause exit /b 1 ) start "XULRunner with Python" "%moz_bin%\xulrunner.exe" -app application.ini %opts% exit /b 0
See XULRunner:Deploying_XULRunner_1.8 for general information.
Sample
A sample XULRunner application with these Python features is available. This includes the pyXPCOM tests and a basic Python console from Alex Badea