Firefox扩展版Hello World + 构建火狐插件官方样例npruntime步骤

来源:互联网 发布:优化设计 英文 编辑:程序博客网 时间:2024/04/29 13:45

今天尝试开发一个Firefox的扩展,把自己开发过程记录下来,以备不时之需,同时也为初学者提供一个参考。我是根据Mozilla官方教程开发的,有兴趣的朋友可以自己去看看:https://developer.mozilla.org/en/Building_an_Extension。

按照一般的教程,第一个程序都是使用最简单的Hello World,现在我们就制作一个Firefox的Hello World扩展。

开发Firefox插件并没有看上去的那样复杂,仅仅使用XML和JavaScript就可以完成。当然,这个意思是Firefox插件开发使用的技术是XML和JavaScript,要做出一个完善的插件涉及到很多方面。但是对于我们的Hello World就不需要那么多东西啦!

写在前面的话:

Firefox 插件/扩展开发的众多奇怪的约定(假设插件/扩展已经被正确安装)
有些约定非常奇怪,不要问我为什么,天晓得指定firefox插件/扩展的牛人们怎么想的。
①在Windows下,plugins必须满足以下条件才能被firefox检测到:
      1. 插件的名字必须是np*.dll,也就是必须以np开头,.dll结尾。
      2. 插件dll资源的语言必须为LANG_ENGLISH,code_page必须为1252(在.rc文件里定义的)
           LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
           #pragma code_page(1252)
      3. 插件dll的VERSION_INFO里面必须包含以下值:
       VALUE "MIMEType", "application/x-your-mimetype"
       这个MIME就是<object>或者<embed>标签引用插件的唯一凭证。


   ②在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例子中的代码就好。

1. 准备目录结构

首先在硬盘上建立一个目录,名为extension。这个名字是随意取的。然后在里面建立chrome文件夹,再在chrome里面建立content文件夹。注意这两个文件夹的名字都是固定的,不能随意改动。然后在extension里面新建两个文本文件,并且取名为chrome.manifest和install.rdf。这样,就建立起如下的目录结构:

extension

   |--install.rdf

   |--chrome.manifest

   |--chrome

       |--content

          ***.xul

   |--plugins

       ***.dll

2. 编写install.rdf

用文本编辑器打开install.rdf文件,输入以下内容:

<?xml version="1.0"?> 

<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 

         xmlns:em="http://www.mozilla.org/2004/em-rdf#"> 

    <Description about="urn:mozilla:install-manifest"> 

        <!-- 指出扩展的ID。该ID应该是一个Email格式的字符串,或者是一个GUID。注意,使用Email的作用是保证该ID的唯一性,并不要求这个Email地址是有效的。必填--> 

        <em:id>sample@example.net</em:id> 

        <!-- 指出插件的版本号。必填 --> 

        <em:version>1.0</em:version> 

        <!-- 在这里的值必须是2。该标签说明该应用的Firefox扩展,而不是其他XUL应用程序。Firefox插件的代码是2,如果是Firefox主题则会是4。必填 --> 

        <em:type>2</em:type> 

        <!-- 安装扩展的目标应用程序以及最高版本和最低版本。必填 --> 

        <em:targetApplication> 

            <Description> 

                <!-- Firefox的ID,这个值不能改变。必填--> 

                <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> 

  <!-- 指明能使用该扩展的Firefox最低版本。这里是指1.5。必填 --> 

                <em:minVersion>1.5</em:minVersion> 

  <!-- 指明能使用该扩展的Firefox最高版本。这里是指4.0.x。结合minVersion,即是说本扩展只适用于1.5和4.0.x之间的版本。必填--> 

                <em:maxVersion>4.0.*</em:maxVersion> 

            </Description> 

        </em:targetApplication> 

        <!-- 扩展的元数据。 --> 

        <!-- 扩展名字。必填 --> 

        <em:name>sample</em:name> 

        <!-- 扩展的描述。这里的描述将出现在Firefox的工具-附加组件的描述栏。选填 --> 

        <em:description>A test extension</em:description> 

        <!-- 扩展作者。选填 --> 

        <em:creator>afei</em:creator> 

        <!-- 扩展主页的URL。选填 --> 

        <em:homepageURL>http://www.huawei.com/</em:homepageURL> 

    </Description>             

</RDF>

install.rdf文件是供具有扩展管理功能的XUL应用程序使用的,XUL应用程序可以使用该文件识别正在安装的扩展的信息。install.rdf文件具有下面的格式:

<?xml version="1.0"?> 

<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 

         xmlns:em="http://www.mozilla.org/2004/em-rdf#"> 

    <Description about="urn:mozilla:install-manifest"> 

        <!-- properties --> 

    </Description> 

</RDF>

上面的install.rdf的注释很多,实际应用中就不需要那么多注释了。

3. 编写XUL文件

Firefox的界面使用XUL和JavaScript进行描述。XUL即XML User Interface Language,是Mozilla开发的一种使用XML进行用户界面描述的语言。XUL只用来定义用户界面,其组件的功能由JavaScript进行定义。

Firefox的整个界面都使用XUL进行定义。可以在%FIREFOX_INSTALL_DIR%/chrome/browser.jar里面找到content/browser/browser.xul文件。(说明一下,jar文件可以用WinRAR或其他一些压缩工具解压缩,这是一个使用zip算法压缩的压缩包)在这个XUL文件中有这么一段:

<statusbar id="status-bar"> 

<!-- ... <statusbarpanel> ... --> 

</statusbar>

这里的这个<statusbar id="status-bar">称为Overlay。所谓Overlay,就是在运行一个XUL文档的时候可以附加其他的XUL文件的方式。就是说,原来有一个XUL是a.xul,里面有一个Overlay定义为overlay-point,如果我们可以在另一个b.xul中对这个Overlay进行追加,在执行a.xul的时候可以自动的把b.xul的内容附加到overlay-point并运行出来。如下的代码所示:

<?xml version="1.0"?> 

<overlay id="sample"    

                 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 

<statusbar id="status-bar"> 

    <statusbarpanel id="my-panel" label="Hello World"    /> 

</statusbar> 

</overlay>

刚刚说了,<statusbar id="status-bar">就是一个Overlay,那么在我们的插件的XUL文档就是基于这个Overlay进行扩展。在这里,我们在statusbar上面定义了一个statusbarpanel,它的id是my-panel,label是Hello, World。这段代码比较清晰,就是在原有的statusbar上追加一个statusbarpanel,这个statusbarpanel显示Hello, World。

明白了这段代码之后,我们把这个文件定义成sample.xul,保存在chrome/content下面。可以看到这个文件夹结构和Firefox自有的那个结构是一致的。

在写完了XUL文件之后,我们要定义其chrome.manifest。XUL文档需要通过chrome://协议进行请求。chrome://类似http://协议,只不过是用来请求XUL文档的。在Firefox的地址栏中输入chrome://browser/content/browser.xul,看看有什么反应,就会知道XUL文档的作用了。

这个URL包括四部分:

1) chrome:// - 即协议名,就像http://一样;

2) browser/ - 包名,即插件的包的ID;

3) content/ - 请求内容的类型;

4) browser.xul - 请求的文件名。

所以,chrome://foo/skin/bar.png就是请求一个在foo包下面的skin里面的bar.png文件。

4. 编写chrome.manifest

在chrome.manifest中添加下面一句:

content         sample        chrome/content/

这里指明,请求类型时content,包名是sample,位置是相对于chrome.manifest文件的chrome/content/。注意,这里的最后面一个/是不能缺少的!

然后需要告诉Firefox我们的扩展Overlay,在chrome.manifest里面再添加一句:

overlay chrome://browser/content/browser.xul chrome://sample/content/sample.xul

这句是告诉Firefox,需要在chrome://browser/content/browser.xul加载的时候将chrome://sample/content/sample.xul扩展进来。

5. 测试

至此,已经完成了这个Hello World的扩展。下面简单测试一下。

使用压缩工具将extension文件夹压缩成zip文件(不能是其他压缩格式),注意有些工具会将本文件夹加入压缩包,这里要求压缩包解开之后应该是extension下面的两个文件和一个文件夹,而不是extension文件夹。然后将后缀名改为xpi。然后打开Firefox,将这个xpi拖到窗口中,Firefox将提示安装扩展,按照一般的过程安装之后,重启Firefox有时候在安装扩展时会有找不到安装脚本的错误,就是因为在压缩时根下面没有install.rdf那一层导致的。

当我们在重启Firefox之后,右下角出现Hello, Word字样时,说明我们的扩展已经安装成功了!


附:https://developer.mozilla.org/en-US/docs/Compiling_The_npruntime_Sample_Plugin_in_Visual_Studio

DLL构建BUILD过程:

Build One Project :

①  Create a new project in Visual Studio for Visualc++|Win32|Win32 Project, then check DLL in the wizard.
     If a wizard gives you a checkbox to create an empty project, then check it. Otherwise you'll delete files later.
     Again note that the resulting DLL filename must start with "np", so either call your project like this or rename the file later
     Delete the .cpp and .h and ReadMe files from the project and disk (if you did not create an empty project)
②.Copy the npruntime sample plugin source code into the dir of the new VS project and add the files to the project using the VS GUI

    (.cpp files to "Source Files", .h files to "Header Files", .rc file to "Resource Files"). Samples can be obtained from:   

    https://developer.mozilla.org/en/Plugins/Samples_and_Test_Cases
Configurate The Environment :

① Get the NPAPI SDK.(http://ftp.mozilla.org/pub/mozilla.org/xulrunner/releases/),Add the NPAPI SDK include path (example : D:\xulrunner-sdk\sdk\include) to Project Properties|(all configurations)|C++|General|Additional Include Directories. Note: If your project is still empty, the C++ tree might not be visible. So, add some files first.
②.Add the following preprocessor definitions to Project Properties|(all configurations)|C++|Preprocessor|Preprocessor Definitions: WIN32;_WINDOWS;XP_WIN32;XP_WIN;_X86_;NPSIMPLE_EXPORTS
③.Disable precompiled headers using Project Properties|(all configurations)|C++|Precompiled headers|Create/Use precompiled header. They may be already disabled.
④.Define the function exports by adding the .def filename (e.g. nprt.def) to Project Properties|(all configurations)|Linker|Input|Module Definition File. It could be either the full path or the path relative to the project directory.
Optional Operation :

Optional: Open the above .def file and change "NPRT" to the filename of your dll as VS sees it (without "np", if you decided to rename later)
Optional: Edit the .rc file and and the top of npp_gate.cpp for the description, mimetype, file extension etc. to reflect your plugin

Generate Plugins And Test it :

①. Remove the function NPP_GetJavaClass from npp_gate.cpp
②. Build the project .
③. Rename the resulting DLL so that the filename starts with "np" and ends with ".dll" (or "32.dll"? 8.3?) and copy it in Mozilla's "plugins" folder
④. Start Mozilla and open about:plugins to verify the plugin is detected .
⑤. Open the file "test.html" and begin testing. Make sure the mimetypes of your html embed tags match the mimetype specified in your nprt.rc file and the top of your npp_gate.cpp file

Version Issues:
If VC++ compiler throws you error C2664 on 'DrawText' function call, you may replace it by 'DrawTextA'. In fact, all win32 API functions dealing with character strings can be added an 'A' to the end to avoid unicode cast errors.
Visual C++ 2008 Express don't support C99 standard about int32_t, uint32_t. You have to add #include "nptypes.h" in top of plugin.h file.
Feel free to append here your issues fixes if the above guide helped you.


原创粉丝点击