生活随笔
收集整理的這篇文章主要介紹了
如何编写 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文件夾下。
01 require.def("ext/formatjson/formatjson",
05 ?????"ext/editors/editors",
06 ?????"text!ext/formatjson/formatjson.xml"],
07 ????function(ide, ext, util, editors, markup) {
09 return ext.register("ext/formatjson/formatjson", {
10 ????????//Object definition
jingxing05 翻譯于 昨天(12:55) 0人頂
頂?翻譯的不錯哦!
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 擴展有效
jingxing05 翻譯于 昨天(13:25) 0人頂
頂?翻譯的不錯哦!
方法 方法名 必須 描述 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元素,事件處理器,和其他狀態等。在擴展管理器中禁用擴展時調用。
jingxing05 翻譯于 昨天(14:41) 0人頂
頂?翻譯的不錯哦!
實現 Format JSON擴展 好,現在我們已經有了基本概念,讓我們開始真正來實現 format json擴展。首先完成我們需要屬性和方法。我將添加一nodes數組,其中包含該擴展所需的所有UI元素。我們用hook方法來創建一個菜單來初始化 formatjson擴展,并顯示一個格式化窗口接受用戶輸入的縮進值。代碼如下:
{name : "JSON Formatter",dev : "Ajax.org",alone : true,type : ext.GENERAL,markup : markup,nodes : [],hook : function(){var _self = this;this.nodes.push(mnuEdit.appendChild(new apf.item({caption : "Format JSON",onclick : function(){ext.initExtension(_self);_self.winFormat.show();}})));},init : function(amlNode){this.winFormat = winFormat;},enable : function(){this.nodes.each(function(item){item.enable();});},disable : function(){this.nodes.each(function(item){item.disable();});},destroy : function(){this.nodes.each(function(item){item.destroy(true, true);});this.nodes = [];this.winFormat.destroy(true, true);}
} 在hook方法中創建一個菜單依附到mnuEdit。mnuEdit是對編輯器菜單的全局引用。現在我們的UI元素的名字掛靠在全局命名空間下(可能會在將來的版本中變更)。Cloud9中可用的UI元素表如下,并指定了哪些擴展添加了這個元素。
NameExtensionPurpose mnuFile 頂部菜單欄的 File 菜單 mnuEdit 頂部菜單欄的 Edit 菜單 mnuView 頂部菜單欄的 View菜單 mnuEditors view菜單的 editors mnuModes Window菜單的布局菜單 mnuPanels ext/panels/panels 頂部菜單欄的windows菜單 vbMain 布局的主vbox tbMain 主菜單欄 barMenu 菜單 barTools 主菜單欄的第一欄 sbMain 底部的狀態欄 mnuFile mnuFile winDbgConsole ext/console/console 控制臺面板 tabConsole ext/console/console 控制臺窗口的tab元素 winFilesViewer ext/tree/tree 樹面板 trFiles ext/tree/tree 樹面板中的樹元素
jingxing05 翻譯于 昨天(15:07) 0人頂
頂?翻譯的不錯哦!
還有更多建好的元素。可以在各自的擴展或通過DOM/XPath操作找到他們。例如在工具欄和狀態欄之間有一個hbox包含3個vbox元素。 <a:hbox><a:vbox /><a:vbox /><a:vbox />
</a:hbox> 可以用XPath選擇器來訪問元素:
vbMain.selectSingleNode("a:hbox/a:vbox[2]"); 這條查詢將定位到hbox中的第二個vbox。這個vbox含有了打開的文件tab和控制臺面板。然后你可以像我們在formatjson擴展中對菜單的處理方法一樣將你想要的元素添加到該vbox。
jingxing05 翻譯于 昨天(15:15) 0人頂
頂?翻譯的不錯哦!
MarkupUI 標記 然后format json 擴展會彈出個窗口給用戶來設置縮進的空格數。我們用aml標記語法來創建這個窗口。我將aml代碼放到名為formatjson.xml的xml文件中,并在最外層添加了一個擴展所需的根元素:a:application,看起來像這樣:
<a:application xmlns:a="http://ajax.org/2005/aml"><!-- Your UI markup here -->
</a:application> UI標記可以包含html和 AML元素。我們使用AML的一個下拉列表spinner和兩個按鈕來描述對json格式化的窗口。
<a:windowid = "winFormat"title = "Format JSON"center = "true"modal = "false"buttons = "close"kbclose = "true"width = "200"><a:vbox><a:hbox padding="5" edge="10"><a:label width="100">Indentation</a:label><a:spinner id="spIndent" flex="1" min="1" max="20" /></a:hbox><a:divider /><a:hbox pack="end" padding="5" edge="10 10 5 10"><a:button default="2" caption="Format" onclick = "require('ext/formatjson/formatjson').format(spIndent.value);"/><a:button οnclick="winFormat.hide()">Done</a:button></a:hbox></a:vbox>
</a:window> 格式化按鈕綁定了onclick事件來調用我們擴展的format方法,它傳入了spinner的值。這就是我們在擴展中需要實現的方法,讓我們動手吧。
jingxing05 翻譯于 昨天(15:34) 0人頂
頂?翻譯的不錯哦!
自定義函數 格式化函數有一個參數,來指定json中縮進的空格數。首先獲取當前選擇的代碼,如果選中的代碼為有效的json,則對其格式化,更新到當前選中的代碼,否則給用戶一個錯誤提示。
我們需要加載另一個依賴來完成該功能,就是ace編輯器的Range模塊。于是我在頂部將ace/Range添加到依賴列表中,然后調用參數"Range"。格式化函數看起來如下(我給每個部分添加了注解)。
{...format : function(indent){//獲取當前編輯器var editor = editors.currentEditor;//從當前編輯器獲取選中的對象var sel = editor.getSelection();//獲取當前的文檔對象引用var doc = editor.getDocument();//獲取當前選中對象的range對象var range = sel.getRange();//從range對象獲取選中的文本var value = doc.getTextRange(range);//嘗試將選中的文本轉換為JSON,并格式化 //然后再回轉為文本字符串,如果出現錯誤則給用戶顯示錯誤.try{value = JSON.stringify(JSON.parse(value), null, indent);}catch(e){util.alert("Invalid JSON", "The selection contains an invalid or incomplete JSON string","Please correct the JSON and try again");return;}//如果格式化成功則用格式化后值替換掉range對象var end = doc.replace(range, value);//用格式化的值更新當前選中的部分 sel.setSelectionRange(Range.fromPoints(range.start, end));
},...
} 我們的擴展現在可以使用了,但讓我們再添加點東西。
jingxing05 翻譯于 昨天(17:27) 0人頂
頂?翻譯的不錯哦!
Key快捷鍵綁定 我希望使用快捷鍵來使用這個擴展,window使用: Ctrl-Shift-J,mac用Command-Shift-J。Cloud9中用戶可以自行配置快捷鍵。要實現上述功能,還需幾個步驟。首先在 ext/keybindings_default文件中為我們的擴展新添windows和mac的默認鍵綁定部分。
..."ext" : {..."formatjson" : {"format" : "Ctrl-Shift-J" // Or "Command-Shift-J" for the mac file},...
}... 然后必須要讓快捷鍵管理器知道該擴展對什么快捷鍵響應和顯示什么UI元素。添加名為hotkeys和hotitems的hash表:
hotkeys : {"format":1},hotitems : {}, 現在你有兩種途徑為鍵綁定添加處理器了。直接的方式是在擴展中添加響應方法,方法的名稱與hotkeys中指定的名稱相同即可,此處就是“format”。因為我們的json格式化擴展有一個菜單來顯示快捷鍵,我更喜歡將響應方法連接到菜單的onclick事件上,這樣當我按下快捷鍵時這個方法被執行。而且當我使用快捷鍵時這個菜單按鈕應該點亮。可以在hotitems哈希表中添加菜單項來達到目的:
this.hotitems["format"] = [this.nodes[0]]; 現在我們可以在Tools菜單下的Extendtion Manage中來激活該擴展了,可以觀看下面這段視頻來看看,如何在3分鐘內完成這個擴展。( 視頻下載)
jingxing05 翻譯于 昨天(18:04) 0人頂
頂?翻譯的不錯哦!
其他資源 When you need help with creating an extension 在你開發擴展需要幫助的時候請到Cloud9的?Google Group?。可以向github的issue跟蹤issue tracker of GitHub提交任何你發現的問題。Cloud9的所有開發者在Twitter上十分活躍。在擴展Cloud9的路上祝你好運。我都等不及要看你會擴展出什么了。 ?我們非常樂意將你酷斃了的擴展添加為Cloud9的子模塊,或者在Github上提交pull request。
玩得開心 !
總結
以上是生活随笔 為你收集整理的如何编写 Cloud9 JavaScript IDE 的功能扩展 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。