代码共享 -- Javascript code modules
一个Javascript code module是被放置在经过注册位置的简单js代码。 通过Components.utils.import() or Components.utils["import"]()方法来实现module的引用。
它允许在插件内部,将其它域的js对象放置在当前对象的域中使用。
看一个例子:
const EXPORTED_SYMBOLS = ['sayHello'];
function sayHello(){ return ‘Hello World’; } |
除了有一个固定的const EXPORTED_SYMBOLS 数组之外,和普通的js文件没什么区别。
第一句表示:将sayHello变量export到引用它的对象的域中。
可以来验证一下:
①、将HelloWorld插件做一些修改:
增加了一个core.js,增加了一个codeModules.js内容分别如下:
Components.utils.import('resource://module/codeModules.js'); window.addEventListener('load', function() { gBrowser.addEventListener('DOMContentLoaded', function(e) { alert(sayHello()); }, false); }, false); |
const EXPORTED_SYMBOLS = ['sayHello'];
function sayHello(){ return 'hello world'; } |
②、因为我们已经将content注册过了,所以接下来注册modules,修改chrome.manifest
resource module chrome/modules/ |
③、将core.js引入到页面,修改
<script type="application/javascript" src="chrome://sample/content/core.js"></script> |
这样一来,打开任意一个页面,都会调用core.js里面的方法。
接下来看看core.js文件,一开始就通过:Components.utils.import('resource://module/codeModules.js');
引入了一个插件内的文件,然后就可以在core.js里面调用这个文件的方法了,当然前提是这个文件已经将这个方法给export了,如果要export多个方法,可以修改EXPORTED_SYMBOLS数组,添加一个新的变量即可。
运行结果,打开任意的页面,可以弹出:
这样就可以引申出一个设计架构,在插件开发的时候,个人觉得还是比较实用的:
可以设计一个类似于如下的Module,命名为util.js:
const EXPORTED_SYMBOLS = ['Util'];
var Util = { __noSuchMethod__ : function(aName, aArguments) { try { Components.utils.import('resource://module/utils/' + aName + '.js', Util); return Util[aName].apply(Util, aArguments); } catch (e) { throw new Error('Could not import util ' + aName + ':\n' + e); } } } |
这个Module有一个Util对象,它覆盖了 __noSuchMethod__这个方法,这个方法是FF暴露出来的接口,如何在某个对象上调用一个不存在的方法,在FF浏览器中,就会执行__noSuchMethod__方法,如果这个对象覆盖了这个方法,那么就会按照覆盖的方法执行。这样一来就可以把这个对象当做工具来使用了,如果调用它不存在的方法,它就会去引入以这个方法名为名字的资源文件,然后通过apply调用这个方法。
__noSuchMethod__的详细介绍,请参考:http://irving-wei.iteye.com/blog/1994948
如何使用这个Module?
在module目录下创建一个新的目录,命名为utils,将codeModules.js拖入其中,改名为sayHello.js。新的目录结构如下图:
接下来就可以修改core.js
Components.utils.import('resource://module/util.js'); window.addEventListener('load', function() { gBrowser.addEventListener('DOMContentLoaded', function(e) { alert(Util.sayHello()); }, false); }, false); |
Build,安装插件,运行。
只要在util目录下添加以需要暴露的方法命名的a.js文件,就可以通过Util工具类在任意引入util.js的文件中调用a方法了,非常方便。
这个设计来源自GraseMonkey的源码分析。
<!--EndFragment-->