直接用javascript写复杂的firefox extension简直是个梦魇,而且performance也会有很多问题,还有一堆限制(同源…),而用C/C++写XPCOM又太大材小用,很不适合于prototype开发。
于是想找找直接用python来写logic的firefox extension,于是就找到了pyxpcomext
其实它也是基于PyXPCOM的,参见说明:
Why do this?
- It gives the power of Python to Mozilla extension developers
- Easy to setup multi-threaded tasks
- Rapidly build cross platform extensions, no compilation issues!
- Great base of core library functionality
- Not limited to JavaScript
- Provides a Python GUI toolkit to build applications (XULRunner)
- The Python extension is download and installed into a Mozilla application as a regular extension
- Upon starting of the application, the extension is registered, and loads the internal dynamic linked libraries (python, pyxpcom and pydom)
- Additional extension directories are then checked to see if there are any extensions using pyxpcom that need to be registered (and appropriately registers them)
- The internal Python path (sys.path) is updated to reflect any "pylib" directories found in the installed extensions
OK,本着庖丁解牛的精神,这里给出一个step by step的python extension
必备
首先要做firefox extension,当然得有firefox咯(废话,这里使用ff 3.6),要做xpi当然也得有zip工具了,linux下这不是问题,win上可以去找UnxTools,或者也可以使用ff的Extension Developer。
至于像FireBug,Explore Chrome,Javascript Debugger等等,就看你的心情咯~~~
其次,既然要PyXPCOM,装pyxpcomext先,这个是平台相关的,win/lnx会有不同的xpi:
http://pyxpcomext.mozdev.org/downloads.html
还有,既然俺们好歹也算是个XPCOM,总得搞个XulRunner-SDK/Gecko-SDK玩玩啊,其实主要我们也只是用它帮我们compile一下idl~~~
动工
如果有firefox extension开发经验,到这一步已经很简单了~~~
首先先做个简单的框架,把下面几个文件按部就班找个sample抄一下:
然后定义IDL(components/pyIDemo.idl)chrome.manifest
install.rdf
content/
overlay.xul
overlay.js
components/
写python的实现(components/pyDemo.py)#include "nsISupports.idl"
#include "nsIVariant.idl"
[scriptable, uuid(2B3D3376-3312-4a2d-8A1E-C93AAFBC8EF7)]
interface pyIDemo: nsISupports {
// attributes, constants, methods, ...
nsIVariant doPythonCmd(in wstring code);
};
这个python就太简单不过了,只是在输入的wstring上在加个Hello把它返回~~~import os
import sys
import time
import traceback
from cStringIO import StringIO
from xpcom import components, ServerException, nsError
from xpcom.server import WrapObject
class pyDemo:
_com_interfaces_ = [components.interfaces.pyIDemo]
_reg_clsid_ = "{ED590407-D31B-4076-8D3C-3AFA999960A8}"
_reg_contractid_ = "@zouf.trendmicro.com.cn/pyDemo;1"
_reg_desc_ = "Python Plugin Demo"
pyshellGlobals = {
# Give away some free items...
"os": os,
"sys": sys,
"time": time,
# And xpcom accessors.
"components": components,
"Components": components
}
def __init__(self):
pass
def doPythonCmd(self, code):
# Ensure the code ends with an empty newline
try:
try:
result = code + 'Hello'
try:
# See if the result can be turned into an xpcom object
return WrapObject(result, components.interfaces.nsIVariant)
except ValueError:
# else, we'll just return a string representation
return repr(result)
except SyntaxError:
return self._exec_code_and_get_output(code)
except Exception, e:
# Format the exception, removing the exec/eval sections.
exc_tb = traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)
return "".join(exc_tb[:1] + exc_tb[3:])
好,实质内容都有了,下一步就是让javascript做个中转器,帮UI来调用python了,这个我们把它放在overlay.js里:
OK,基本上到这一步你的coding工作就完成了,当然实际上在这一步你会花费数百倍的精力去写你的python logic~~~function do_cmd() {
_pySvc = Components.classes["@zouf.trendmicro.com.cn/pyDemo;1"].
getService(Components.interfaces.pyIDemo);
alert(_pySvc.doPythonCmd('abc'));
}
下一步就是收尾,打包,一下的简单批处理可以帮忙(build.cmd)
它干的活也很干净,只是编译IDL,zip打包,出XPI,大功告成~~~@echo off
SET XUL_PATH=D:\projects\xulrunner-sdk
SET PATH=%XUL_PATH%\bin;%PATH%
xpidl -I %XUL_PATH%\idl -I components -o components/pyIDemo -m typelib components/pyIDemo.idl
zip pydemo.xpi install.rdf chrome.manifest pydemo.jar -r components -r content -r locale
最后把出来的xpi拖到你的ff里试试吧,看看能不能出结果?
#END#
没有评论:
发表评论