为 Firefox 3 更新扩展

本文提供的信息将有助于希望更新其扩展以使其在 Firefox 3 下正常工作的开发者。

在继续之前,我们可以提供一个有用的提示:如果您的扩展唯一需要的更改是提高其安装清单中的 maxVersion 字段,并且您将扩展托管在 addons.mozilla.org 上,那么您实际上不需要上传新版本的扩展!使用 AMO 上的开发者控制面板调整 maxVersion。这样可以避免您的扩展被重新审查。

步骤 1:更新安装清单

第一步——也是大多数扩展唯一需要的步骤——是更新 安装清单 文件 install.rdf,以表明与 Firefox 3 兼容。

找到指示 Firefox 最大兼容版本的行(对于 Firefox 2,可能如下所示)

xml
<em:maxVersion>2.0.*</em:maxVersion>

将其更改为指示与 Firefox 3 兼容

xml
<em:maxVersion>3.0.*</em:maxVersion>

然后重新安装您的扩展。

请注意,Firefox 3 取消了版本号中的额外“.0”,因此您只需使用 3.0.*,而不是 3.0.0.*

已经(并将继续)存在一些 API 更改,这些更改可能会破坏某些扩展。我们仍在努力编制这些更改的完整列表。

注意:如果您的扩展仍然使用 Install.js 脚本而不是 安装清单,您现在需要过渡到安装清单。Firefox 3 不再支持 XPI 文件中的 install.js 脚本。

在安装清单中添加本地化

Firefox 3 支持安装清单中的新属性来指定本地化描述。旧方法仍然有效,但新方法允许 Firefox 即使在禁用附加组件且等待安装时也能获取本地化。有关更多详细信息,请参阅 本地化扩展描述

步骤 2:确保您提供安全的更新

如果您自己托管附加组件,而不是在像 addons.mozilla.org 这样的安全附加组件托管提供商上,那么您必须提供一种安全的方法来更新您的附加组件。这将涉及将您的更新托管在 SSL 网站上,或者使用加密密钥签署更新信息。有关更多信息,请阅读 保护更新

步骤 3:处理更改的 API

一些 API 发生了重大变化。其中最显著的,可能会影响大量扩展的,是

DOM

来自外部文档的节点在插入当前文档之前应使用 document.importNode() 克隆(或使用 document.adoptNode() 采用)。有关 Node.ownerDocument 问题的更多信息,请参阅 W3C DOM FAQ

Firefox 目前不强制执行此规则(在 Firefox 3 的开发过程中曾强制执行一段时间,但由于强制执行此规则导致太多站点中断)。我们鼓励 Web 开发者修复他们的代码以遵循此规则,以提高未来的兼容性。

书签和历史

如果您的扩展以任何方式访问书签或历史数据,它将需要进行大量工作才能与 Firefox 3 兼容。访问此信息的旧 API 已被新的 Places 架构取代。有关更新现有扩展以使用 Places API 的详细信息,请参阅 Places 迁移指南

下载管理器

由于从 RDF 数据存储过渡到使用 Storage API,下载管理器 API 略有变化。这应该是一个相当容易的过渡。此外,用于监控下载进度的 API 已更改为支持多个下载管理器监听器。有关更多信息,请参阅 nsIDownloadManagernsIDownloadProgressListener监控下载

密码管理器

如果您的扩展使用密码管理器访问用户登录信息,则需要更新以使用新的登录管理器 API。

  • 文章 使用 nsILoginManager 包含示例,包括演示如何编写您的扩展以同时使用密码管理器和登录管理器,以便它可以在 Firefox 3 和早期版本中使用。
  • nsILoginInfo
  • nsILoginManager

如果您想在扩展中提供自己的密码存储实现,您还可以覆盖内置的密码管理器存储。有关详细信息,请参阅 创建登录管理器存储模块

弹窗(菜单、上下文菜单、工具提示和面板)

XUL 弹窗系统在 Firefox 3 中进行了大量修改。弹窗系统包括主菜单、上下文菜单和弹窗面板。已创建 使用弹窗 指南,详细说明了该系统的工作原理。需要注意的是,popup.showPopup 已弃用,取而代之的是新的 popup.openPopuppopup.openPopupAtScreen

自动完成

nsIAutoCompleteController 接口的 handleEnter() 方法已更改为接受一个参数,该参数指示文本是选自自动完成弹窗,还是用户在输入文本后按 Enter 键。

DOMParser

  • 当实例化 DOMParser 时,它继承了调用代码的主体,以及构造函数来自的窗口的 documentURIbaseURI

  • 如果调用者具有 UniversalXPConnect 权限,它可以将参数传递给 new DOMParser()。如果传递的参数少于三个,则其余参数将默认为 null

    • 第一个参数是要使用的主体;这会覆盖通常继承的默认主体。
    • 第二个参数是要使用的 documentURI
    • 第三个参数是要使用的 baseURI
  • 如果您使用契约初始化 DOMParser,例如通过调用 createInstance(),并且您没有调用 DOMParserinit() 方法,则尝试启动解析操作将自动创建并初始化具有 null 主体以及 documentURIbaseURI 的 null 指针的 DOMParser

停止使用内部字符串 API

内部字符串 API 不再导出;您必须迁移到外部字符串 API。请参阅以下文章以获取有用的信息

已移除的接口

以下接口已从 Gecko 1.9(驱动 Firefox 3)中移除。如果您的扩展使用了其中任何一个,您将需要更新您的代码

  • nsIDOMPaintListener
  • nsIDOMScrollListener
  • nsIDOMMutationListener
  • nsIDOMPageTransitionListener
  • nsICloseAllWindows(参见 Firefox bug 386200

步骤 4:检查相关的 Chrome 更改

Chrome 布局发生了一些变化,可能会影响某些扩展。

新盒子

Chrome 发生了一个小变化,可能需要更改您的代码。添加了一个新的 vbox,名为“browser-bottombox”,它包含浏览器窗口底部的查找栏和状态栏。尽管这不影响显示的出现,但如果您的扩展相对于这些元素覆盖 chrome,则可能会影响您的扩展。

例如,如果您之前在状态栏之前覆盖了一些 chrome,如下所示

xml
<window id="main-window">
  <something insertbefore="status-bar" />
</window>

您现在应该这样覆盖它

xml
<vbox id="browser-bottombox">
  <something insertbefore="status-bar" />
</vbox>

或者使用以下技术使您的覆盖在 Firefox 2 和 Firefox 3 上都有效

xml
<window id="main-window">
  <vbox id="browser-bottombox" insertbefore="status-bar">
    <something insertbefore="status-bar" />
  </vbox>
</window>

更改的盒子

尝试覆盖“appcontent”盒子以在文档内容上浮动 chrome 的扩展将不再显示该内容。您应该更新您的扩展以使用新的 <xul:panel> XUL 元素。如果您希望阻止面板在延迟后自动消失,您可以将 noautohide 属性设置为 true

其他更改

在此处添加您在更新扩展以使其与 Firefox 3 配合使用时必须进行的简单更改。

  • 出于安全原因,不再支持 chrome://browser/base/utilityOverlay.js。如果您之前使用此文件,则应切换到 chrome://browser/content/utilityOverlay.js

  • nsIAboutModule 实现现在需要支持 getURIFlags 方法。请参阅 nsIAboutModule.idl 以获取文档。这会影响提供新 about: URI 的扩展。(Firefox bug 337746

  • <xul:tabbrowser> 元素不再是“toolkit”的一部分(Firefox bug 339964)。这意味着此元素不再可用于 XUL 应用程序和扩展。它继续在主 Firefox 窗口 (browser.xul) 中使用。

  • 需要记录对 nsISupports_proxies 以及可能与线程相关接口的更改。

  • 如果您在 XUL 文件中使用 XML 处理指令,例如 <?xml-stylesheet ?>,请注意 Firefox bug 319654 中所做的更改

    1. XML PI 现在已添加到 XUL 文档的 DOM 中。这意味着 document.firstChild 不再保证是根元素。如果您需要在脚本中获取根文档,请改用 document.documentElement
    2. <?xml-stylesheet ?><?xul-overlay ?> 处理指令在文档序言之外不再有效。
  • 加载网页内容(浏览器页面加载)时不会触发 window.addEventListener("load", myFunc, true)。这是由于 Firefox bug 296639 更改了内部和外部窗口的通信方式。这里的简单修复是使用 gBrowser.addEventListener("load", myFunc, true),它在 Firefox 2 中也有效。

  • content.window.getSelection() 返回一个对象(可以通过 toString() 转换为字符串),这与现已弃用的 content.document.getSelection() 不同,后者返回一个字符串

  • event.preventBubble() 在 Firefox 2 中已弃用,并在 Firefox 3 中已移除。请使用 event.stopPropagation(),它在 Firefox 2 中也有效。

  • 由于修复了 Firefox bug 52209,使用 setTimeout()setTimeout() 启动的计时器现在被模式窗口阻止。您可以改用 nsITimer

  • 如果您的扩展需要允许不受信任的来源(例如,网站)访问扩展的 chrome,则必须使用新的 contentaccessible 标志