代码共享 -- 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-->