Getting the right tools 获得适合的工具
There are 3 tools that we think are essential for effective add-on development (or any kind of development, really): a source code editor, a source control system, and a build system.
为了方便add-one开发我觉得至少需要3个基本的工具(对于任何种类的开发也是这样):一个源代码编辑器、一个源代码管理系统和一个构建系统。
In regards to code editing, there's no official Mozilla IDE. On the other hand, extensions use the same (or similar) languages that are used for web development, so most text editors and IDEs are up to the task. Most XUL tools and plugins you'll find online are merely templates that generate the folder structure for the project, and that's not much help.
至于代码编辑并没有Mozilla官方的IDE。从另一个角度来讲扩展使用与web开发相同(或相似)的语言,所以大部分文本编辑器和IDE都可以胜任。大多数你能在网上找到的XUL工具和插件都是用于生成工程目录结构的并且没什么大帮助。
We recommend Komodo Edit. It's free, open source, and cross-platform. It's based on the Mozilla XULRunner platform, so it has support for some of the particularities in Firefox extension development. Komodo Edit has automatic completion for XUL tags and attributes, and it supports Mozilla's CSS extensions (CSS values and properties beginning with "-moz"). It has an add-on system similar to the one in Firefox, and there are some Komodo extensions that provide additional help in extension development. That is more than what you can get with most other editors, so we recommend you to give it a try. All of our examples are handled with Komodo Edit, so if you see a .kpf or .komodoproject file in an example you download, this is a Komodo project file.
我们建议使用Komodo编辑器。它是免费开源软件并且跨平台。它是基于Mozilla XULRunner平台的,所以它支持大部分Firefox扩展开发的特性。Komodo编辑器具有XUL标签和属性的自动完成功能,并且支持Mozilla的CSS扩展(以“-moz”开头的CSS值和属性)。它也有一个类似于Firefox的add-on系统,并且也有一些Komodo扩展以辅助扩展开发。这些是你能够从这个编辑器中得到的比其它编辑更多的,所以建议你试一试。所有我们的例子都是用Komodo编辑器创建的,所以当你在下载的例子中看到.kpf或.komodoproject文件时,那么这个就是一个Komodo工程文件。
We recommend Git and GitHub for source control, but any decent software configuration management system will do.
我们建议为源代码管理选用Git和GitHub,不过任何一种软件配置管理系统也都行。
To package XPI files, we use make. We chose make because this is the same system used by Mozilla to build Firefox, and it is available for all operating systems. make is a default tool in most UNIX-based systems. It can be installed on Mac OS X as part of the XCode Tools package, and on Windows with cygwin. In cygwin installations you'll have to explicitly check the make and zip utilities from the long list of packages to download and install.
打包XPI文件我们使用make。使用make的原因是与Mozilla构建Firefox时的方式相同,并且这种方式对于所有操作系统都是有效的。在大部分基于UNIX的系统中make是默认工具。在Mac OS X系统中make是跟随XCode工具包一同被安装的,在Windows上使用cygwin。在cygwin的安装程序中你需要在一个较长的包列表中明确指定make和zip实用工具的下载与安装。
Also make sure that make is in the executable system path. After setting up make, you should be able to open a command line window, run "make -ver", and get the installed version of make as output.
你还需要确定make命令的路径已经追加到了系统可执行目录环境变量中。设置完make后你可以打开一个命令行窗口,执行“make -ver”命令来查看make的版本信息。
We recommend you set up make in your system, since our examples come with all the necessary files to build and install the resulting XPI using this tool. It will save you some packaging time. Or you can create an equivalent system using batch, Ant or whatever you prefer. Ultimately you can just compress the contents of the src directory using any zip or archive tool and get a similar result.
我们建议你在你的系统上配置make,因为我们的例子包含了所有构建所必须的文件并且使用make来安装所产生的XPI。它会为你节省一些打包的时候。或者你可以通过批处理创建一个等同的系统,Ant或任何你喜欢的。最终你可以使用任何zip或归档工具来压缩src目录中的内容来得到相同的结果。
Build system 构建系统
Let's start by downloading the project used to build the second version of Hello World, from the exercise in the last section.
让我们从下载用于创建第二个版本HelloWorld的工程开始。
Unzip the file anywhere you want. Inside the HelloWorld2 directory, you'll see two directories: bin and src. The bin directory should be empty. This is where all the resulting build files will be created, and where you'll find the extension XPI file once you get it to build.
unzip文件到任何你指定的位置。在HelloWorld2目录中你会看到两个子目录:bin和src。bin目录应该是空的,此目录是所有构建产生的文件被创建的位置,并且你会在这里找到构建所得到的扩展XPI文件。
Open the project file (HelloWorld2.komodoproject) from the src directory in Komodo Edit. In the Projects tab you should be able to see the directory structure inside the src directory. This structure should be familiar, as it is almost identical to the unpacked XPI from the previous section.
在Komodo编辑器中打开src目录中的工程文件(HelloWorld2.komodoproject)。在工程标签窗口中你应该能够看到src目录中的目录结构。这个结构看上去应该会很熟悉,因为它前一节所解压缩的XPI文件内容的目录结构几乎相同。
The only notable additions is a file named Makefile under src. This is the file that make uses to build the XPI. You should take some time to read it and understand it, or at least identify the parts that you should change to get a project of your own going. This GNU Make Manual is a very good reference to get to know make and Makefiles.
在src目录中有一个名为Makefile的文件,make使用这个文件来构建XPI。你应该花一些时间去读一下它的内容并做到能够理解,或者是至少你应该能标识出那些可被修改以适用你自己工程的部分。对于了解make和Makefile,GNU make手册是一个不错的选择。
In most cases you'll only need to change the first lines in Makefile. These define the extension name, the extension id (as specified in install.rdf) and the name of the profile directory where the extension will be installed during development and testing. More about this further ahead.
大多数情况下你仅需要变更Makefile文件的前几行。这些行的内容定义了扩展的名字、ID(和install.ref中的一样)和profile目录(在开发和测试中将会被安装到的地方)的名字。更多相关内容后续章节会介绍。
Let's try and build the XPI from the command line first. Open the command line program in your system and navigate to the src directory in your project. Run the following command:
首先让我们试着在命令行中构建XPI。在你的系统中打开命令行程序并定位到你的工程的src目录中。执行以下命令:
make
That's it. If everything went well, you should see an output similar to this:
仅此而以。如果一切都正常的话,你应该会看到类似下面的输出:
Creating XPI file. adding: install.rdf (deflated 50%) adding: chrome.manifest (deflated 50%) adding: content/browserOverlay.js (deflated 42%) adding: content/browserOverlay.xul (deflated 69%) adding: skin/browserOverlay.css (stored 0%) adding: locale/en-US/browserOverlay.dtd (deflated 52%) adding: locale/en-US/browserOverlay.properties (stored 0%) Creating XPI file. Done! Build finished successfully.
If you inspect the bin directory, you should see the xulschoolhello2.xpi file.
如果你检查一下bin目录,你应该会看到xulschoolhello2.xpi文件。
If you run make again, you'll only see the last line of the build process. That is because make can tell that the file in the bin directory is up to date, and nothing needs to be done. Making changes on source files will make make run the necessary steps to build the XPI again.
如果你再次执行make,那么你仅会看到构建过程的最后一行输出。这是因为make能够告知bin目录中的文件是否有更新,如果没有更新就什么也不做。对源代码文件的修改会导致make执行必要的步骤并再次构建XPI。
You can clean up the bin directory by just running the following command (again, from the src directory):
你可以清空bin目录,仅需要执行以下命令(同样是在src目录下执行):
make clean
You can also run these commands from Komodo. Click on Tools > Run Command.... In the "Run" textbox you should type this:
你同样也能够在Komodo中执行此命令。单击Tool菜单的Run Command...,在Run文本框中输入以下内容:
bash -c "make"
Or replace "make" with "make clean" for the clean command. The "bash -c" part forces Komodo to use bash, which for some reason can't be set properly as the default command shell. It isn't necessary to add this, but it's better so that it is consistent with the make command we'll see next.
或者将“make”替换成“make clean”用于清空操作。“bash -C”意思是让Komodo使用bash,由于某些原因无法将其设置成默认的Shell。这一点并不是必须的,但最好是这样做以便能够与我们以后使用make所得到的结果相一致。
In the "Start in" textbox you should choose %p (directory path of active project). If you don't see this textbox, click on the "More" button. You also have the option to save the command, by clicking on the "Add to Toolbox" checkbox. To see the Toolbox, click on View > Tabs > Toolbox, from the main menu. With that, you should now have a very easy way to build your XPI, by just double clicking on the created commands.
在“Start In”文件框中你可以选择%p(当前活动工程的目录路径)。如果你没有看到这个文本框,你可以单击“More”按钮。你还可以选择保存这个命令,通过单击“Add To Toolbox”复选框。看一下工具箱,单击主要菜单View > Tabs > Toolbox。这样你现在就有了一个非常方便的方法来构建你的XPI,仅仅需要在工具箱中双击所创建的命令。
We can make it even better. Once you're testing and debugging your code, you'll find that constantly building and installing an XPI can be very tedious. This is the reason why we introduced "make install". This only works if your extension is already installed in a Firefox profile. Just like in the provided project, you need the add-on id and profile location set in the file Makefile. We use this information to locate the installation path of the extension and overwrite the installed files. If Firefox is open at the time you run "make install", you'll have to restart it in order to see the changes. It's still better than installing the XPI all over again.
我们可以让事情变得更好些。当你测试或调试代码时,你会不断地构建和安装XPI,这是一项很乏味的过程。这也就是为什么我们介绍“make install”的原因。你只有将扩展安装到了Firefox profile中它才会工作。就像我们提供的工程那样,你需要将add-on的ID和profile位置设置到Makefile文件中。我们使用这些信息去定位扩展的安装路径然后覆盖掉已安装的文件。如果Firefox在你“make install”的时候正打开着,你需要重新启动它以便看到修改结果。这仍然比经过所有步骤来安装XPI好得多。
In order to set the profile location to the right value, you should read the support article on profiles, at the Mozilla Support site. We'll also delve deeper in this topic later on in this section.
为了给profile位置设置一个适当的值,你应该阅读profile相关的文章。关于此内容在本节后面的主题中我们会进一步深入研究。
To make "make install" work on non-Windows systems, you need an extra step. The install process requires using an environment variable called OSTYPE, which is not exported. Long story short, if you want to run it from a command line, you need to run:
为了让“make install”可以在非Windows的系统中工作你需要一些额外的步骤。安装过程需要使用一个叫OSTYPE的环境变量,默认情况下此环境变量并没有被export。长话短说,如果你想从命令行执行你需要如下操作:
export OSTYPE; make install
And in the command in Komodo, you should enter the following:
在Komodo中执行此命令你应该像下面这样做:
bash -c "export OSTYPE; make install"
The export command won't work correctly unless you use "bash -c".
export命令只有在你使用了“bash -c”的前提下才会工作。
Building IDL files 构建IDL文件
Some extensions require developing XPCOM components to add certain advanced functions. There's a section dedicated to XPCOM in this tutorial, but we'll briefly discuss the impact it has on building the extension. You can skip this section and keep it present as a reference in case you do need to use XPCOM in your project.
某些扩展需要开发XPCOM组件以增加某些高级功能。本教程的这一部分是专门针对XPCOM的,但我们只是简要讨论一下在构建扩展时的XPCOM的影响。你可以跳过本节并且在你的项目需要使用XPCOM的时候再回来参考一下。
XPCOM interfaces are defined using IDL files. These are text files that define the attributes and methods in one or more interfaces. These IDL files are compiled into binary form and included in the extension as XPT files.
XPCOM接口使用IDL文件来定义。它是一些定义了属性和方法在一个或更多接口的文本文件。这些IDL文件被编译成二进制格式并被包含进扩展中(如,XPT文件)。
To compile an IDL file to XPT, you need a command line tool called xpidl. This tool is included in the Mozilla Gecko SDK. If you need to compile IDLs, go to the SDK page and download a compiled version for your system. Also note any prerequisites you may need. If your system is not listed in the supported builds, you'll have to build the SDK yourself from the Mozilla source. Good luck with that.
为将IDL文件编译成XPT文件,你需要需要一个叫xpidl的命令行工具。这个工具是包含在Mozilla Gecko SDK中的。如果你要编译IDL文件,那么到SDK页面然后下载适合你系统的编译版本。另外需要注意的是你可以需要一些先觉条件。如果你的系统没有被列在支持一览中的话,你需要使用Mozilla源代码自行构建SDK。好运!
You should also set up your environment so that xpidl.exe (or just xpidl on other systems) is in the default executable path, and also add a variable called GECKO_SDK, that points to your SDK build:
你还应该将xpidl.exe加到系统PATH变量中,并需要加一个叫GECKO_SDK的环境变量指向SDK的目录:
export GECKO_SDK=/path/to/your/sdk
Our build system should pick it up from there. To make it work in Komodo in Unix-based systems, we add the command to the .bash_login file in the home directory, and we modify the commands to this:
我们的构建系统需要从那个位置中调用。在基于Unix系统中为了让它能够在Komodo中工作,需要将命令行追加到home目录中的.bash_login文件中,我们可以按照以下内容进行修改:
bash -c ". ~/.bash_login; make"
An example project with XPCOM components is included in the XPCOM section. There is also a mention about building C++ XPCOM, which is something much more complicated.
在XPCOM章节中有一个使用XPCOM组件的例子。同时还提到了一些更复杂的关于使用C++构建XPCOM内容。
Signing extensions 为扩展签名
In order to provide additional security for your users, you can choose to add a signature to your extension. The signature verifies that you are the author of this extension, and it can only be done if you have a valid certificate provided by a trusted Certificate Authority.
为了给你的用户提供额外的安全性,你可以选择为你的扩展加签名。签名验证你才是这个扩展的作者,并只能通过一个可被信任的证书颁发机构才能得到一个有效的证书。
The only noticeable difference for the user is that the XPI installation dialog will say that the extension was created by you, making the dialog a little easier to trust. It's not common to sign extensions because most users will trust the official add-ons site (AMO) rather than rely on extension signatures. On the other hand, it is standard practice for big companies to sign their extensions.
对于用户来讲扩展有没有证书仅有的明显不同是,XPI的安装对话框会说扩展是由你创建的,通过对话框体现一些简单的信任信息。通常不签名扩展是因为大部分用户会信任官方提供下载的add-on胜过扩展的签名。但从另一角度讲大公司的标准做法还是会去签名他们的扩展。
You'll need to download some libraries in order to be able to sign your extension. Follow the instructions, and add something like the following to your Makefile:
你需要下载一些库以便能够签名你的扩展。按照以下步骤向你的Makefile中追加以下一些内容:
# The directory where the signature sources are located. signature_dir := signature # The signing key /certificate file. signature_extra_files := $(build_dir)/META-INF/manifest.mf \ $(build_dir)/META-INF/zigbert.sf # The signing key /certificate file. signature_rsa_file = $(build_dir)/META-INF/zigbert.rsa# The signing key /certificate file. signature_files := $(signature_extra_files) \ $(signature_rsa_file) $(signature_files): $(build_dir) $(xpi_built) @signtool -d $(signature_dir) -k $(cert_name) \ -p $(cert_password) $(build_dir)
Keep in mind that your password should not be in your Makefiles, and you must be very careful with the certificate information. Ideally this should be handled by a single person, and only done near the end of the release process. You should also have a different make command, such as make signed in order to distinguish the signed and unsigned development builds.
要牢记你的证书密码不应该出现在Makefile文件中,并且你还要非常小心证书的信息。理想情况是由一个专人来处理这项工作,并且仅在发布扩展工作的尾声来完成签名工作。你还应该编写不同的make命令以区别签名的和未签名的构建过程。
Firefox profile management Firefox的profile管理
It is good development practice to keep your test environment separate from everything else. You don't want unstable extensions to break your everyday Firefox profile, risking data loss. It's much better to have a different "version" of Firefox for testing. This is what Firefox profiles are for.
一个好的开发习惯是隔离你的测试环境。你不希望不稳定的扩展搞乱你日常使用的Firefox profile,并且冒着丢失数据的风险。所以最好是有一个不同版本的Firefox用于测试。这也是Firefox profile的用意之所在。
You can learn about setting up multiple Firefox profiles in the Mozilla Support article Managing Profiles. You can have as many profiles as you like. You can also mix them with multiple Firefox installations. For instance, you may want to test your extension in Firefox 3.5 and Firefox 3.6, or test it in a localized version of Firefox. You can install as many Firefox versions as you want, and mix profiles and versions.
你可以从Mozilla的支持文档“管理Profiles”中学习如何设置多个Firefox profile。你想有几个profile都行。你还可以通过多个Firefox安装版本使用它们。例如你可以想在Firefox 3.5和3.6或是本地化版本的Firefox中测试你的扩展。你可以安装许多版本的Firefox然后混用profile。
On Windows and Linux it's easy to create shortcuts for every profile you create, using the commands mentioned in the support article.
在Windows和Linux系统中可以很容易地为每个profile创建快捷方式,使用支持文档中所提到的命令即可。
For Mac OS X developers, there is also a way to set up "shortcuts". You can do this by opening the Automator application, choosing Run Shell Script and then entering the profile-loading script in the textbox:
/Applications/Firefox.app/Contents/MacOS/firefox-bin -no-remote -p MyProfile > /dev/null &
You can change "/dev/null" to a file location, in case you want to see dump output from Firefox, or other extensions. The last & prevents Automator from waiting for your Firefox session to finish. Save this as an Application, not a Workflow. And you probably want to have these on your Desktop or Dock, for easy access.
There are also some configuration changes you should make in your testing profiles, so that you get detailed error information in case something fails. The Firefox Error Console (Tools > Error Console) normally displays JavaScript errors that occur on web pages, but with some tweaking you can get error information from your extension. Read this piece on Development preferences.
Developer extensions
There's a wide variety of Firefox extensions that aid web development and add-on development. A good place to look for them is the Mozilla Add-ons site, and there's also a good development extension list here. You should also take some time to play around with the Web Developer tools that are included in Firefox. Some of them can be very useful for add-on development and overlap with the add-ons listed. In this section we'll cover a few that we have found to be very useful.
DOM Inspector
The DOM Inspector used to be part of Firefox as an installer option, but since Firefox 3 it has been separated as another add-on you can add and remove. It's a very useful inspection tool that lets you look into the DOM of HTML and XUL documents, as well as applied CSS rules and associated JavaScript objects. Introduction to DOM Inspector is a good guide on how to get started using it.
The DOM inspector is particularly useful in finding out how to overlay a window, and how to replace default CSS style rules. You can see the names of the files involved, which gives you a good starting point when looking into the Mozilla source. You can even change styles, attributes and execute Javascript code in it, although that's not completely reliable.
JavaScript Debugger
The name says it all. The Venkman JavaScript Debugger is a great way to trace execution of your JavaScript code.
To debug extension and browser code, right-click on the Loaded Scripts panel and uncheck Exclude Browser Files. The list of loaded scripts will grow long to include all of the scripts in Firefox. Having our file naming conventions prove very useful in this case. You can set breakpoints, step in and out of methods, and even get profiling information from Javascript execution. You can inspect variables, keep track of watch expressions, and evaluate arbitrary JS at any point in execution.
This extension has seen little maintenance in quite some time, so it is very buggy. It is specially unreliable when debugging code in Javascript XPCOM and XBL files. Nevertheless, it is a valuable tool when trying to figure out why a certain function is misbehaving.
Tamper Data
Tamper Data intercepts HTTP requests and their responses. It allows you to cancel them and even replace payload data before it is sent. There are several similar extensions, such as Live HTTP Headers, but Tamper Data is the one that we use the most. We'll cover more on HTTP debugging later on.
Firebug
The Firebug extension includes pretty much all tools mentioned so far, but it's mostly focused on web development. The Chromebug extension helps in making Firebug more useful for extension development, but it may still not be powerful enough to replace all of the previously mentioned add-ons.
On the other hand, Firebug has a very friendly, integrated user interface, and sees much more development that its counterparts. It's definitely worth a try.
Leak Monitor
Memory leaks have always been a big criticism drawn against Firefox. Mozilla has proven with time that they take memory usage seriously, improving performance on several critical areas and removing all kinds of memory leaks.
However, extensions are also capable of causing memory leaks. If you want your extension to be included in the Mozilla Add-ons site, you better not have any memory leaks. Using XPCOM in JavaScript has some guidelines you should follow to avoid them. One of the most common errors developers make is to register a JS event listener or observer, and never removing it. The simple practice of always including removal code for everything you add makes a big difference.
To make sure your extension doesn't leak, you should use the Leak Monitor extension when testing it. Always test opening and closing windows. Leaks usually surface when doing this.
Exercise
- Set up a new Firefox profile for XUL School. Make sure you can open and close your XUL School Firefox without having to close the instance of Firefox you use to browse normally. Make any modifications you want to the XUL School project, run make install and restart Firefox to see the extension work with your changes.
- Install DOM Inspector. Use it to locate the menu you created. Hint: You can search for an element by id. Inspect the CSS rules Firefox applies to it by default. Look at the final, computed style for the menu items. Browse around the rest of the Firefox DOM, and try to figure out what the nodes correspond to in the Firefox UI.
- Install the Firebug extension. Open the Firebug window and go to an AJAX-heavy page such as Gmail or Facebook. Open and enable the Net tab. Try to identify what is going on with some of the requests being sent.
Now that you know how to quickly monitor your project and test changes, we'll learn how to add new UI elements to Firefox, through overlays and new windows.
This tutorial was kindly donated to Mozilla by Appcoast.