如何编写 Cloud9 JavaScript IDE 的功能扩展
上周末我们在JSConf.eu发布了Cloud9 IDE,同时发布了对应的GitHub项目。在4天时间里该项目得到340个人的关注和将近50个fork。Cloud9的口号是由"由Javascripters 为Javascripters创建的IED",这口号有点递归,它意味着你可以hack这个ide使它变得更强大。Cloud9项目开始之初就尤其注意考虑这点了;Cloud9中的每一个功能点都是一个扩展(extension)。在IED启动的时候我们用优秀的 requireJS 库加载所有的扩展。前端UI使用 ajax.org platform (apf),apf 使我们轻松地模块化Cloud9的用户界面。下面开始详细介绍怎样为Cloud9编写扩展。
一个扩展的生命周期是从它作为requireJS的模块开始的。我将简述requireJS的基本语法,想深入了解requireJS请参考这个文档。一个扩展会依赖其他的扩展和一些核心模块。我们将编写一个给编辑器中选定的JSON代码进行格式化的扩展。该扩展依赖核心模块:core/ide, core/ext, core/util 和编辑器管理扩展:ext/editors/editors.让我们称该扩展为formatjson,然后将其置于ext文件夹下。
require.def("ext/formatjson/formatjson",
["core/ide",
"core/ext",
"core/util",
"ext/editors/editors",
"text!ext/formatjson/formatjson.xml"],
function(ide, ext, util, editors, markup) {
return ext.register("ext/formatjson/formatjson", {
//Object definition
});
}
);
require.def 第一个参数标识扩展的名字,第二参数中 ide,ext ,util和 editors 代表传入该扩展依赖的对象引用,formatjson扩展的第五个依赖是加载为一个文本的xml文件。 ‘text!’ 语法告诉 requireJS 不要将参数引入的文件解析为 javascript,仅将其中的内容作为文本返回即可。所有依赖加载完毕后将调用第三个参数代表的回调函数,在回调函数中将我们的扩展注册到扩展管理器中,让我们看看扩展文件的结构。
{ name : "JSON Formatter", dev : "Your Name Here", alone : true, type : ext.GENERAL, markup : markup, hook : function(){}, init : function(){}, enable : function(){}, disable : function(){}, destroy : function(){} }
属性和方法详解:
属性
属性名 | 是否必须 | 描述 |
---|---|---|
name | 必须 | 扩展的名字,供管理器中显示 |
dev | 可选 | 开发者名字,供扩展管理器中显示,主要是表彰开发者的荣誉 |
alone | 可选 | Boolean值,标识该扩展是个独立的扩展还是某个扩展的子扩展 |
type | 可选 | 扩展类型,现在只支持 ext.GENERAL和ext.EDITOR,这个属性极有可能在未来版本中弃用 |
markup | 可选 | String,该扩展的UI定义的标记文本 |
visible | 可选 | Boolean值标识该扩展在加载时是否可见,该属性仅对 Panel 扩展有效 |
方法
方法名 | 必须 | 描述 |
---|---|---|
hook | 可选 | 在扩展注册时调用该方法,允许你延迟该扩展的初始化。 例如你可以添加一个菜单项来初始化该扩展。 初始化的时候, markup 参数的值被解析然后调用 init方法。如果没有定义hook方法,则扩展注册时会立即初始化。当你指定hook后,就要自己全权负责扩展的初始化。扩展的初始化是由调用ext.initExtension(_self);完成的,其中 _self 是.Panel 扩展一个个引用。对于panel hook函数 通常只有一单单的一个声明:panels.register(this); |
init | 必须 | 初始化时解析完UI markup标记字符串后 调用该函数。使所有markup中引入的该扩展的元素可用,并可以对应到其正确的位置。在扩展管理器中启动该扩展时也会调用该函数。 对editor 型扩展,第一个参数是tab page元素,指示该扩展可以用之填充到自己的UI.Panel 对panel ,第一个参数应该给this.panel传一个在Cloud9 UI的panel元素 (通常是window元素)。 |
enable | 必须 | 前端启用该扩展时调用。这个函数是通过在前端菜单中点击某个panel扩展时被立即调用的(例如点击完某个菜单项后显现勾勾的这个动作)。不要与在扩展管理器中的启用和禁用扩展混淆,启禁扩展调用的是 destroy和init方法 |
disable | 必须 | 前端停用扩展时调用。这个函数是通过在前端菜单中点击隐藏panel扩展时被立即调用的(例如点击完某个菜单项后勾勾不显示的这个动作)。不要与在扩展管理器中的启用和禁用扩展混淆,启禁扩展调用的是 destroy和init方法 |
destroy | 必须 | 注销扩展时调用。注销时清除引入的UI元素,事件处理器,和其他状态等。在扩展管理器中禁用扩展时调用。 |