firefox插件开发和调试
目錄(?)[+]
原文:http://huandu.me/2010/02/11/595/
Firefox插件(plugins)開發實用指南
Firefox插件可實現強大功能,但其中麻煩事情不少。寫這個實用指南首先是為了方便自己記憶,免得以后再次栽倒一些坑里面,如果能幫助其他人,則是更好。這個指南不是為了手把手教讀者開發插件,而是作為一個FAQ,解決各種詭異問題。
Firefox擁有眾多的擴展(Extension),開發擴展也非常容易,不過有一些事情還是無法用擴展解決,需要訪問操作系統的底層功能,這就需要寫插件(plugins)。例如flash就是一個插件而不是擴展。
Mozilla提供了一系列的教程和文檔,雖然很不詳盡,眾多重要的API語焉不詳,但至少是一個好的開始。
最需要閱讀的是plugins API和使用入門。這是一個相當長的文檔,如果看完所有的內容會花費大量的時間而且還會很暈,這里列一些重點供參考。
- plugins基礎概念
- 寫第一個插件(只需要關注Writing Plug-ins這一節所談到的內容)
- 獲得一份firefox的源碼,比如firefox 3.6。plugins的例子可以在源碼里找到(modules/plugin/sdk/samples),如果出了問題還可以自己編譯一個debug版的firefox來調試。
- 了解瀏覽器能提供什么功能
- 制作插件的安裝程序,推薦用擴展的方式安裝插件,有無數的好處
完成以上這些內容以后差不多就已經可以實現自己的插件了,一般而言,參照著例子來做開發不會有什么問題,只是有不少細節需要留意。
Firefox plugins開發的眾多奇怪的約定(假設plugins已經被正確安裝)
有些約定非常奇怪,不要問我為什么,天曉得開發firefox的牛人們怎么想的。
在Windows下,plugins必須滿足以下條件才能被firefox檢測到:
- 插件的名字必須是np*.dll,也就是必須以np開頭,.dll結尾
- 插件dll資源的語言必須為LANG_ENGLISH,code page必須為1252。在rc文件里是這么寫的:
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
- 插件dll的VERSION_INFO里面必須包含以下值:
VALUE "MIMEType", "application/x-your-mimetype"
這個MIME就是<object>標簽引用插件的唯一憑證。
在Linux下,plugins必須滿足以下條件才能被檢測到:
- 插件的名字必須是lib*plugin.so,即以lib開頭,plugin.so結尾
- 插件必須實現NP_GetMIMEDescription和NP_GetPluginVersion,并返回合適MIME字符串。注意,這個字符串并不是普通的MIME,是有特殊規則的,詳見前面這個鏈接的內容。
- 插件so不要靜態鏈接gtk、opensll、pthread、z等系統庫,這會在不同linux平臺上因為符號表的問題遇到各種運行時錯誤
特別需要說明的是,NP_GetPluginVersion、NP_GetEntryPoints等關鍵函數沒有任何官方文檔介紹它們,只能根據例子來猜,反正沒事就別改它們的實現,copy例子中的代碼就好。
firefox插件開發注意事項
寫firefox插件的一個基本習慣是,經常編譯代碼并運行它,保證你的插件還能工作。只要firefox無法加載dll/so,或者加載出現任何錯誤,都會悄無聲息的忽略這個插件。時常關注一下about:plugins,看看插件是不是還在這個列表里。
firefox插件從窗口模式上可分為windowless和windowed兩種。其中,windowless模式的文檔較多較全,是firefox比較推薦的模式,坑比較少,這里就不多說了。windowed模式則相反,需要好好說說。
無論在Windows還是Linux上,windowed的插件都擁有獨立于瀏覽器頁面的窗口。firefox會通過插件的NPP_SetWindow來告訴插件當前窗口的情況。
關于windowed插件有兩個詭異問題需要注意:
- Windows平臺下,插件窗口默認會響應WM_CTLCOLOREDIT、WM_CTLCOLORLISTBOX、WM_CTLCOLORBTN、WM_CTLCOLORSTATIC消息,并設置一個默認的背景色。這本來沒問題,但在Windows XP下,這個顏色居然永遠是黑色,而不是默認系統背景色(通常是白色)。最好subclass這個窗口并且攔截這些消息,不要讓firefox去處理它們。對于插件來說,firefox處理這些消息只是幫倒忙而已。至于firefox還幫了哪些倒忙,可以去源碼widget/src/windows/nsWindows.cpp的nsWindow::ProcessMessage()去圍觀。
- Linux平臺下,NPP_SetWindow傳入的NPWindow指針中雖然有一個ws_info成員,這個成員里面也確實有一個display變量指向X Window的Display結構,但絕對不要真正使用它,否則可能會導致firefox直接退出,據說這可能是firefox的一個bug。
測試firefox插件小技巧,測試方面的高手可以無視
測試插件前建議先在firefox里面創建一個新的profile(帳號)。這樣可以創造一個最干凈的開發環境,避免被其他擴展/插件干擾。
默認的profile名叫default,在命令行里輸入firefox -p default就可以使用這個profile。如果只是輸入firefox -p,會彈出一個對話框用于選擇profile。這個命令在Windows和Linux下都可使用。
無論是哪個平臺,調試插件的方法都很類似。
Windows下可以用VC以調試方式啟動firefox,載入插件時調試器會自動載入對應的符號,捕捉發生的異常或者設斷點都很方便。
Linux下直接用gdb就好,細節應該不用多說。有一點需要注意,系統默認安裝的firefox命令(默認放在/usr/bin/firefox)是一個shell腳本,真正的可執行文件名字需要打開這個腳本自行查找。
實現firefox插件的基本功能
firefox為插件提供的接口十分原始,很多功能默認沒有實現,下面提供了一些思路和方法。
- 讓插件接受焦點:默認情況下,<object>標簽不能獲得焦點,必須指定tabindex。
- 在插件中使用tab鍵跳到下一個element:沒有好辦法,必須自己手動將焦點還給瀏覽器窗口(Linux下不必如此),然后自己用NPN_*系列函數找到應該獲得focus的DOM element,然后調用這個element的focus()方法。
- 隱藏和顯示插件:直接設置<object>標簽的style.display = “none”即可,但這里有個嚴重的副作用,firefox會調用插件的NS_PluginShutdown,銷毀這個插件。如果不期望造成這種效果,要么別用這種方式隱藏插件,要么把插件狀態保存在js里,再次顯示的時候把狀態設回去。
- 觸發DOM事件:firefox沒有提供任何便利的方法觸發DOM事件,要在插件中做到這點,必須自己模擬js觸發DOM事件的過程。例如,對于HTML事件,假設self是DOM element,js會這么做。
evt = document.createEvent("KeyboardEvent");
evt.initKeyEvent(
"blur", // in DOMString typeArg,
false, // in boolean canBubbleArg,
false); // in boolean cancelableArg,
self.dispatchEvent(evt);
對應的C代碼就是
暫時先寫到這里,如果還有什么疑難雜癥,歡迎評論,我繼續添加。
如何對于plugin進行調試。
如firefox安裝路徑如下: C:\Program Files\Mozilla Firefox1)在配置屬性/調試/命令, 設置為你的firefo.exe路徑:
C:\Program Files\Mozilla Firefox\firefox.exe
2)在配置屬性/常規/輸出目錄, 設置為:
C:\Program Files\Mozilla Firefox\plugins
3) 在配置屬性/生成事件/生成后事件/命令行, 設置為
copy "$(OutDir)\$(ProjectName).dll" "C:\Program Files\Mozilla Firefox\plugins\$(ProjectName).dll"
< 2和3任選其一 >
運行, 打開測試的htm, 就可以調試?
樓上的方法現在應該行不通了。
我的環境是firefox 5, VS2008,斷點進不去,但是可以肯定調用的是我自己的插件。
目前我發現的調試插件dll的解決方法如下:
按照上述設置(也可以做成xpi安裝后,安裝目錄在appdata下一個文件夾內,將插件放到那里,只要firefox能找到插件正常調用就好了)后,正常F5進入調試狀態,再attach到進程:plugin_container上,斷點就可以進入調試了。
總結
以上是生活随笔為你收集整理的firefox插件开发和调试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多彩泡泡屏保特效(JAVA版)
- 下一篇: python counter怎么用_Co