Firefox 3.5 扩展更新

本文为试图更新扩展以使其在 Firefox 3.5 中正常工作的扩展开发人员提供有用的信息。

更新基础

本节介绍了每次更新扩展以适应新版本的 Firefox 时需要执行的基本操作。

测试你的扩展

首先编辑你的扩展的 install.rdf 文件,将 maxVersion 更新为 3.5b4(如果你在 Firefox 3.5 beta 4 上测试),并增加你的扩展的 version

然后创建一个新的 Firefox 配置文件,以避免测试影响你的常用配置文件。导航到包含 Firefox 的目录,然后执行以下命令

bash
firefox -createProfile testBeta4

在 Mac 上,你需要一直导航到 Firefox 应用程序包

bash
cd /Applications/Firefox.app/Contents/MacOS/
firefox -createProfile testBeta4

通过在命令行中执行以下命令,使用新的配置文件启动 Firefox

bash
firefox -P testBeta4

彻底测试你的扩展。我们建议你将以下首选项设置为 true,以便在出现任何 JavaScript 警告或异常时得到提醒

  • javascript.options.strict
  • javascript.options.showInConsole

更新你的扩展

如果你在测试过程中遇到任何问题,请更新你的代码以修复这些问题。本文包含一些可能需要进行修改的内容的实用信息。

完成这些操作后,尝试再次使用你的扩展,这次使用你的常规配置文件。这将有助于确保与任何现有的保存数据兼容。

在 addons.mozilla.org 上更新你的扩展

最后,是时候发布你更新后的扩展了。如果你的扩展不需要任何代码更改,你可以登录 AMO 仪表板并在那里更新兼容性版本。否则,你需要将新版本上传到 AMO。

有关更多信息,请参阅 向 AMO 提交附加组件

访问 Places 数据库

在 Firefox 3.5 之前,直接使用 Storage API 访问 Places 数据库需要一些技巧

js
var places = Components.classes["@mozilla.org/file/directory_service;1"]
  .getService(Components.interfaces.nsIProperties)
  .get("ProfD", Components.interfaces.nsIFile);
places.append("places.sqlite");
var db = Components.classes["@mozilla.org/storage/service;1"]
  .getService(Components.interfaces.mozIStorageService)
  .openDatabase(places);

这将手动构建指向 places.sqlite 数据库文件的路径,然后打开该文件以供 Storage 访问。

Firefox 3.5 添加了一项专门的服务,提供了一种方便的方式来访问 Places 数据库;上述技术在 Firefox 3.5 或更高版本中无法使用。

js
var db = Components.classes[
  "@mozilla.org/browser/nav-history-service;1"
].getService(Components.interfaces.nsPIPlacesDatabase).DBConnection;

搜索文本框

textbox 类型的 timed 已被弃用;你应该使用 search

在 Firefox 3 中,你可能使用了

xml
<textbox type="timed" timeout="1000" oncommand="alert(this.value);"/>

在 Firefox 3.5 中,你应该将其更改为

xml
<textbox type="search" timeout="1000" oncommand="alert(this.value);"/>

JSON

JSON.jsm JavaScript 模块在 Firefox 3.5 中被弃用,转而支持原生 JSON 对象支持。有关详细信息,请参阅 在 Firefox 中使用 JSON,以及关于 JSON 的文章,以更全面地了解 JSON 以及如何在不同版本的 Firefox 中使用它。

为了确保与 Firefox 3 和 Firefox 3.5 的兼容性,你可以执行以下操作

js
if (typeof JSON === "undefined") {
  Components.utils.import("resource://gre/modules/JSON.jsm");
  JSON.parse = JSON.fromString;
  JSON.stringify = JSON.toString;
}

这通过在 JSON 未被原生支持时导入 JSON.jsm JavaScript 模块,然后将该模块提供的 方法映射到原生 JSON 使用的方法来实现,从而使相同的调用能够正常工作。

你也可以通过直接使用 nsIJSON 接口来绕过这个问题。

上下文菜单的更改

为了支持 Gecko 1.9.1 中添加的新音频和视频功能,nsContextMenu 类已将 imageURL getter 重命名为 mediaURL;但是,imageURL 于 2009 年 6 月 9 日重新添加。

Chrome 注册的更改

Firefox 3.5 修复了一个安全漏洞,该漏洞使得使用远程 chrome 成为可能。这将影响任何在其 chrome.manifest 文件中包含引用网站、数据或资源 URL 的资源的附加组件。有关详细信息,请参阅 Firefox 3.5 中的安全更改

从请求中获取加载上下文

以前,可以通过查询各种 docShell API 从请求中获取加载上下文。特别是,使用 notificationCallbacks.getInterface(nsIDOMWindow) 获取与加载相关的窗口对象是一种常见的做法。虽然旧方法在某些情况下可能仍然有效,但不建议再使用它 (详细信息)。

正确可靠的方法是使用 nsILoadContext(请参阅 接口定义)。

从 JavaScript 中,你可以像这样操作

js
var loadContext;
try {
  loadContext = aRequest
    .QueryInterface(Components.interfaces.nsIChannel) // aRequest is equivalent to aSubject from observe
    .notificationCallbacks.getInterface(Components.interfaces.nsILoadContext);
} catch (ex) {
  try {
    loadContext = aRequest.loadGroup.notificationCallbacks.getInterface(
      Components.interfaces.nsILoadContext,
    );
  } catch (ex) {
    loadContext = null;
  }
}
// you can now use |loadContext.associatedWindow| to get the Window object

如果上述方法不起作用,则另一个 JavaScript 示例

js
// SOURCE: http://stackoverflow.com/questions/10719606/is-it-possible-to-know-the-target-domwindow-for-an-httprequest

function getWindowForRequest(request) {
  if (request instanceof Components.interfaces.nsIRequest) {
    try {
      if (request.notificationCallbacks) {
        return request.notificationCallbacks.getInterface(
          Components.interfaces.nsILoadContext,
        ).associatedWindow;
      }
    } catch (e) {}
    try {
      if (request.loadGroup && request.loadGroup.notificationCallbacks) {
        return request.loadGroup.notificationCallbacks.getInterface(
          Components.interfaces.nsILoadContext,
        ).associatedWindow;
      }
    } catch (e) {}
  }
  return null;
}

从 C++ 中,你可以像这样操作

cpp
nsCOMPtr<nsILoadContext> loadContext;
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
NS_QueryNotificationCallbacks(channel, loadContext);

可定制的工具栏

在 Firefox 3.5 中,可定制工具栏的行为已更改,使得 <xul:toolbar/> 绑定现在会从其关联的 <xul:toolbarpalette/> 中删除工具栏项目,并将它们添加到工具栏,而不是克隆它们并将它们复制到工具栏。这意味着该调色板现在只包含工具栏中不存在的项目,而不是以前包含所有可定制元素,无论它们是否显示在工具栏上。这可能会给依赖于能够从 <xul:toolbarpalette/> 中检索所有可定制工具栏项目或尝试动态将项目插入调色板以使其在工具栏定制期间可用的附加组件造成麻烦。有关更多信息,请参阅 Firefox 错误 407725Webkit 错误 467045

XPCNativeWrapper

从 Firefox 3.5 开始,你不能再在获得 XPCNativeWrapper 自动化的 chrome 包中使用 data: 绑定。这解决了潜在的安全问题。

XUL 文档现在获得了 XPCNativeWrapper 处理,因此你现在需要使用 getAttribute() 方法来获取属性值,而不是直接读取它们。

如果你的扩展正在使用 xpcnativewrappers=no(它不应该这样做,因为它不安全),那么从 Firefox 3.5 开始,来自该扩展的 XBL 不会应用于使用 XPCNativeWrapper 自动化的文档。

感兴趣的新功能

监听所有标签上的事件

Firefox 3.5 引入了对添加和删除监听所有标签的进度监听器的支持。有关详细信息,请参阅 监听所有标签上的事件

面向主题开发人员

  • 请查看 Firefox 3.1 中的主题更改
  • 访问 Mozillazine 论坛 FF3.1 的主题更改,以获取对影响主题开发人员的 3.0 和 3.1 之间的所有更改的概述/列表。这涉及新的 CSS 功能(如 nth-child、-moz-box-shadow 等)、对现有小部件的更改、整体 UI 改进以及新的 FF3.1 功能(音频/视频支持、私人浏览、扩展会话恢复、框/窗口/文本阴影)。