【FF】firefox附加组件扩展插件开发综述

有一些东西想通过火狐扩展来实现;因为觉得可以省一些事。于是借此机会了解了firefox开发的整个体系。正如所想的,不仅可以开发开发基于火狐的扩展,同时也可以开发一个类似火狐的独立应用程序。

了解火狐技术体系的过程是个断断续续的过程;也同样经历过一个百川汇海的过程。

一. 几个术语

最开始的时候,总是面对着火狐的一些术语似是而非;最后梳理清楚,然后一切恍然大悟。

  • 插件plugin
  • 附加组件addon
    • 主题theme
    • 语言包language pack
    • 扩展extension
      • 传统扩展traditional extensions
      • 自引导扩展bootstrapped extensions
      • add-on sdk扩展(曾用名Jetpack,自引导扩展的一种)

1. 插件和扩展的区别

官方的插件和扩展的区别是这样解释的:

 

Extensions are small add-ons that add new functionality to your Mozilla program.

Plugins are programs that allow websites to provide content to you and have it appear in your browser. 扩展是能够给Mozilla增加一些新功能的附加软件,插件是允许网站向你提供内容并在浏览器中显示的程序).

通俗的讲,“扩展”是基于Firefox本身增加的一些实用功能,

而“插件”则是在Firefox之外独立编写的程序,用于显示网页中的特定内容如Flash、视频和Java 等.

不过初看时总是看不懂;后来了解了什么是插件和扩展的例子才明白其二者是大大的区别的,不过还是无法用文字来描述。不知道以下的解释能否行得通:

浏览器基本的功能是用来显示html网页的。网页的内容自身是可扩展的,这部分要显示就是通过内容的插件;浏览器对网页除了显示外,再做一些额外的事,那就是功能的扩展。

举例来说,基本的网页是没有flash的,那么显示flash内容,就要通过插件了。而对于网页,除了显示外,再附加额外的截图等功能,就是通过扩展了。

从底层来看,插件就是html内容中的<object>和<embed>标签;扩展与内容无关,只与浏览器有关。

算了,不解释了,越说越迷糊。

2.  附加组件第三者插足

有了扩展和插件,其他的一切都好理解。可是官方的很多文档都出来一个附加组件。这个插足的第三者,又是一个什么概念呢?不弄明白,总有一天碰到别人都不好打招呼,不怕认错人也怕叫做人。

官网上的某处,说附加组件包括插件、各种扩展、主题和语言包;这样看来,附加组件应该是全称。但是在火狐的“附加组件管理”中,附加组件一项只能搜索扩展和主题,不能搜索插件;所以还是采用上面的划分。

好了,不在名词之称上继续纠缠。我们的最终目的其实还是只要区分扩展和插件即可。

二. firefox的技术体系

如何开发插件、扩展;如何开发独立的类Firefox应用程序?这是我们的目标。要实现此目标,必须要了解相关的火狐可以提供哪些,在哪里提供。

firefox附加组件扩展插件开发综述 - Mr.7 - Mr.7

总的来说,基于上面的技术体系,可以按图索骥找相关的线索。

火狐要解决的问题主要是一个基础三个扩展:

  • 一个基础:客户端网页内容和js的处理
  • 扩展1-可扩展的网页内容:也就是如何方便插件的编写扩展
  • 扩展2-可扩展的浏览器界面:也就是如何方便扩展的编写
  • 扩展3-可扩展的浏览器功能:也就是如何方便第三方库的引入

解决上述问题,firefox真是抽象又细化,揉碎又提炼,获取了不同的收成。

1. 显示渲染消息层的收获----XUL

在解决基础和扩展1的问题时,都涉及到显示问题。

网页内容需要渲染显示,firefox的界面也需要渲染显示。基本的显示,控件,布局。html的控件有按钮、文本框;应用程序的界面控件有菜单、状态栏。html好像少点布局控件,但是第三方js和css界面库提供了很多;而应用程序的界面绝对少不了布局组件。网页可以通过js来进行消息扩展,应用程序的消息响应难道会少得了?

总之这就是一码事。将渲染显示层公共提出来,既用来显示网页,也用来显示界面;js既可以响应网页消息,也可以用来响应界面的消息。这就是XUL。

2. 功能扩展的收获-XPCOM

无论是插件还是扩展,都可能需要调用第三方的库。强有力的扩展,总是免不了调用一些已有的功能。python倘若不能调用C,那他就要像JAVA那样辛辛苦苦的提供全套解决方案。firefox如果全部功能都要自己实现,那永远赶不上兵强马壮的ie。所以,如何调用第三方的功能,还要支持跨平台的解决方案呢?

Windows上有微软的COM组件,但这用到微软的注册表;linux上没有注册表之说。firefox的解决方案就是XPCOM。不需要注册表的com。一切都很像,所以也就没有看起原理,只看了如何使用。

3. 可扩展的收获-XulRunner

Firefox最后的设计太过精致了。这么好的设计,这么好的扩展,这么好的可选的基础组件,只用来开发一个firefox太过可惜了。所以,还顺带做了其它几个类似的软件,例如Thunderbird。不过,独乐乐不如众乐乐。所以就有了给第三方的独立应用程序开发sdk或者简单的独立平台XulRunner。基于XulRunner可以以类似扩展的方式定制功能,但是独立于firefox而运行。

三. firefox插件的开发

firefox是无穷尽可扩展的,不过可扩展不是firefox一家的专利。现在甚至可以这么说,可扩展性是软件的基本要求。如果软件不具备可扩展性,都不好意思跟别人打招呼。

插件是火狐可扩展性的一个体现。不过,正如前面所说,插件其实是基于内容的。基于内容的插件,不仅火狐需要,IE也需要,chrome也需要,safari也需要。那么,插件也应该支持这些所有的浏览器。

这就是现在经常要解决的两个问题:纵向单个需要扩展;但是横向这个扩展又必须满足所有一切。浏览器的插件解决方案,最好的还是看FireBreath。他的插件可以满足上述要求。

1. 基于html标准的插件生命周期

浏览器调用插件,是通过插件关联的对象。浏览器遇到插件的对象有两种方式:

  • 独立式:此时是打开特定后缀名的文件
  • 嵌入式:此时是网页中有特定mimetype类型的object标签

所以,一个插件,必须在内部声明自己关注的mimetype或者后缀。

此外,插件通常具备的功能:

  • 可与Windows交互:该如何响应消息,如何显示自己
  • 可与当前网页交互:该如何获取插件所在网页的信息
  • 可与js交互:更多的是插件提供的方法如何共js在脚本中方便调用

运行期间,每个内容都会对应一个插件的实例。具体可以参见http://www.firebreath.org/display/documentation/Plugin+Lifecycle

程序实现中要看看以下特点如何体现。

2. FireBreath 插件的程序结构

从这里下载http://www.firebreath.org/display/documentation/Download,注意分别下载源代码和FireBreath-boost。看这里来进行编译http://www.firebreath.org/display/documentation/Building+on+Windows。重点研究{$FireBreath}\examples\FBTestPlugin。编译调试查看源代码是最好的了解方法:

  • prep2008.cmd examples生成vs2008的解决方案;
  • 调试时通过附加进程进行。注意ie的进程就是iexplorer.exe;但是火狐4以上对应的进程不是firefox.exe,而是plugin-container.exe;
  • 调试时,用浏览器打开{$FireBreath}\examples\FBTestPlugin\test.html,即可看到效果。

分析源代码,发现插件的执行流程:

类型调用流程 作用
 API FB::FactoryBase getFactoryInstance() 必须有的API
 Class FB::FactoryBase 
 Class::Function FB::FactoryBase:createPlugin(mimetype) 
 Class FB::PluginCore 消息(鼠标显示)
 Class::Function FB::PluginCore:createJSAPI() 
 Class FB::JSAPIPtr JS交互

  

浏览器会维护一个mimetype和插件的列表;一个插件可以有多个mimetype。但是通常一个mimetype只会对应一个插件。在网页中,当遇到一个mimetype时,会找到对应的plugin,然后创建并交将控制权交给插件对象。

  • 如何创建插件对象呢?每个插件必须要有固定的API,同时必须要有个工厂对象FB::FactoryBase。这是固定的约定。
  • 一个插件是一个dll,但是该dll内部其实可以有多个逻辑插件。通过FB::PluginCorePtr createPlugin(const std::string& mimetype)来实现mimetype逻辑和插件的对应。
  • 每个插件需要考虑消息与windows进行交互,也就是鼠标和显示等各种信息;这正是FB::PluginCorePtr的拿手好戏。该类为了模拟Windows的消息分派机制,也采用宏实现。所以有宏,还是常见的消息名,看上去就像Windows Style了。
  • 特别注意的是,这里终于看到了我一直想看的ondraw,原来HDC是这么获取的。有了HDC,那么后面可以遐想的故事就多了。不过还有一点疑惑,有了HDC,常见的Windows显示都出来了;但是那些Windows的显示风格会和HTML的渲染风格完全不一样,插件在此会和背景和谐吗?不过猜想,HTML的渲染也应该是HDC开始的,只不过做了很多很多的封装。如何将HTML渲染DC获取,或者插件中也使用XUL元素,进而实现组合定制控件,该如何实现呢?这一步继续下去,其实就是如何基于XUL来做自绘制控件......
  • 插件还必须和JS交互。这是通过virtual FB::JSAPIPtr FB::PluginCore:createJSAPI();来实现。PluginCore和JSAPI各司其职,前者负责消息;后者负责给js提供方法。其实二者完全可以集合在一个类中,也就是双重继承。此时只需要createJSAPI时返回this即可。但是最佳的模式,还是将二者分开。
  • 插件毕竟是在html中,如何获取html呢?交给它就行PluginCore::m_host->getDomWindow。
    总的来说,强烈建议从头到尾顺序看看官网http://www.firebreath.org/display/documentation/FireBreath+Home

3. Firefox 插件的位置

firefox的插件在什么地方呢?firebreath只是推荐的最优插件开发方法,还有很多种开发方法。而插件的安装地方也有很多。firefox如何知道plugin都安装了何处呢?看如下参考:https://developer.mozilla.org/en-US/docs/Gecko_Plugin_API_Reference/Plug-in_Basics#How_Plug-ins_Are_Used。对应windows来说,如下:

  • 系统环境变量MOZ_PLUGIN_PATH对应目录
  • 当前用户{$cur_user}\Application Data\Mozilla\Firefox\plugins
  • 应用程序的plugin目录。一些应用程序可以自带火狐扩展,此时,只要将插件放在所在plugin目录即可
  • {$firefox}\plugins目录

也建议看看firefox plugin的相关信息https://developer.mozilla.org/en-US/docs/Gecko_Plugin_API_Reference

四. firefox扩展的开发

扩展的内容也很庞大。该如何下手呢?

扩展应该具备的功能,实际上和插件一样:

  • 可以调用第三方库来增强功能
  • 可以增强firefox自身对网页显示的功能
  • 此外还有一条,扩展有自身的一套包格式

具备这三种特点,扩展也经过了三代的发展,发展的轨迹由功能最强到开发最简单。这条历史就像COM的发展史一样,由技术派走向了大众派。

1. 扩展的包结构

以下是一个传统扩展的逻辑包结构,或者目录结构。详细的信息参考https://developer.mozilla.org/zh-CN/docs/XUL_School-840092-dup/Getting_Started_with_Firefox_Extensions

xulschoolhello1

  • chrome.manifest(扩展的包结构和扩展方法描述)
  • install.rdf(扩展的名称等配置信息)
  • content (扩展的界面和脚本消息)
    • browserOverlay.xul
    • browserOverlay.js
  • skin (可选,扩展的外观配置)
    • browserOverlay.css
  • locale(可选,扩展的语言配置)
    • en-US
      • browserOverlay.dtd
      • browserOverlay.properties

注意,包是扩展的逻辑结构,实际目录是物理结构。逻辑上,个扩展个配置个目录

此外,了解一个扩展,最主要的方法就是查看chrome.manifest。因为这是查看扩展的结构,以及扩展的自定义方法的大纲视图。通常,类似如下:

 

;逻辑包结构 content myapp jar:chrome/myapp.jar!/content/ locale    myapp    zh-CN        jar:chrome/myapp.jar!/locale/zh-CN/ skin    myapp    classic/1.0    jar:chrome/myapp.jar!/skin/ ;界面 overlay chrome://browser/content/browser.xul chrome://myapp/content/ui.xul overlay chrome://myapp/content/main.xul chrome://myapp/content/left.xul overlay chrome://myapp/content/main.xul chrome://myapp/content/right.xul overlay chrome://myapp/content/main.xul chrome://myapp/content/overlay/tab1.xul overlay chrome://myapp/content/main.xul chrome://myapp/content/overlay/tab2.xul ;自定义接口,供js调用 interfaces components/iTest1.xpt interfaces components/iTest2.xpt ;自定义接口的实现对象 binary-component components/myapp_XPCOM.dll

一个扩展可以使一个xpi文件;或者是一个目录。

上面的声明,充分体现了包的逻辑结构,也展示了实际目录既可以是物理目录,也可以是压缩目录(jar)。xpt后缀是自定义接口编译后的二进制文件;接口的实现对应着动态库(dll 或 so)。

  • 通常,传统的扩展包括的包结构和自定义方法声明;这些是所有的扩展开发都具备的。
  • 传统的扩展安装后要重启火狐;这一点好像不是什么致命的问题,但是在实际过程中安装插件就想立刻使用。此时重启,可能打断用户的上下文场景,是叔可忍,婶不可忍。这点是分家后的chrome引以为戒,也是firefox不得不改的。
  • 此外,传统的扩展,采用XUL作为界面层。XUL相比于html,提供了更多的界面元素,特别是布局元素。但是引入一个新的语言,学习成本太高;这个是firefox开发希望酌情改进,降低难度的。

2. 扩展的开发模式转变

以上,说了火狐要改进的亮点:避免安装后重启,避免学习XUL。

自引导扩展bootstrapped extensions解决了前面一个问题;add-on SDK同时也解决了第二个问题。

自引导扩展参见“https://developer.mozilla.org/zh-CN/docs/Extensions/%E5%BC%95%E5%AF%BC%E5%9E%8B%E6%89%A9%E5%B1%95”。

3. 最推荐的扩展开发方法:add-on SDK

add-on SDK扩展,也叫做jetpack,安装后不需要重启就可以使用;同时,主要使用JS+HTML+CSS来实现界面效果。详细的说明请看:“https://addons.mozilla.org/en-US/developers/docs/sdk/latest/”。

先安装(https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/tutorials/installation.html),再试用,通过例子学习。

安装过后,通过cfx init来创建基本的目录结构,同时可以打包cfx xpi和运行cfx run。

重点关注的是在add-on SDK下,是否也可以使用XPCOM。发现果然可以。功能组件还是按照老方法来创建,但是功能组件的调用,在SDK下更方便。

五. 开发独立的类firefox程序

火狐的扩展实际上是一个指定目录结构的包,火狐自身实际上也是一个指定目录结构的包。只要是指定目录结构的包,它可以独立运行(例如火狐自己),或者运行在火狐中(例如扩展)。独立运行的不一定只是火狐自己,任何一个这样的包都可以独立运行,成为一个独立的应用程序。此时,就是XULRunner出场了。

看一个例子可以明白:https://developer.mozilla.org/en-US/docs/Getting_started_with_XULRunner。不过该例子下载后好像不能运行,可能是格式太老原因。下面这个例子就可以直接运行:http://download.csdn.net/detail/problc/3370885。虽然简单,但是hello world是一切的开始。

如何运行了。下载XULRunner,最好将该目录添加到系统环境变量中。然后XulRunner.exe Application.ini即可。例如,xulrunner.exe "D:\Mozilla Firefox\application.ini"就可运行起火狐。

如果没有xulrunner,但是有firefox,想验证下应用程序的效果,可以用firefox来启动,例如:"D:\Mozilla Firefox\firefox.exe" -app "G:\MyProject\FF\myappa\application.ini"。

XULrunner程序的一切效果都如扩展,可以使用XUL,可以使用XPCOM,可以使用JS。这么看来,这天生就是一个支持JS脚本,且具备浏览器渲染的程序。目前很多directui,以及通过内嵌浏览器利用网页做界面的程序,实质上都可以下岗了。

不过,为什么360杀毒软件越做越漂亮,好像利用XUL难以达到效果。不过,这实际上是因为自定义效果的原因。但是总体来说,XUL内部已经具备开发一切界面效果的潜力,只要去挖掘。

相关的资料可以参考:https://developer.mozilla.org/zh-CN/docs/XULRunner

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值