将新的 WebExtensions WebIDL 文件接入 mozilla-central

dom/bindings/Bindings.conf 中添加新条目

新的 WebIDL 绑定应作为 dom/bindings/Bindings.conf 中的新条目添加。新条目应按字母顺序添加,并放在此配置文件中已列出的其他 WebExtensions API 绑定附近(查找 ExtensionBrowser webidl 定义以及与 WebExtensions API 相关的其他现有 WebIDL 绑定)

# WebExtension API
...
'ExtensionRuntime': {
  'headerFile': 'mozilla/extensions/ExtensionRuntime.h',
  'nativeType': 'mozilla::extensions::ExtensionRuntime',
},

警告

如果 dom/bindings/Bindings.conf 中的条目未按字母顺序排列,或者引用的 headerFile 尚未存在,则 mach build 将失败。

dom/webidl/moz.build 中添加新条目

新的 .webidl 文件也必须在“dom/webidl/moz.build”中列出,它应该添加到

  • 现有的 WEBIDL_FILES 条目组中,这些条目专门用于 WebExtensions API 绑定

  • 或在 PREPROCESSED_WEBIDL_FILES 条目组中,这些条目专门用于 WebExtensions API 绑定,**如果生成的 `.webidl` 包括预处理宏**(例如,当 API 的一部分在所有构建中都不可用时,例如仅在桌面构建中可用的 API 子集)。

# WebExtensions API.
WEBIDL_FILES += [
  ...
  "ExtensionRuntime.webidl",
  ...
]

PREPROCESSED_WEBIDL_FILES += [
  ...
]

警告

用于列出 WebExtensions API .webidl 文件的 PREPROCESSED_WERBIDL_FILES 组可能尚不存在(当添加第一个预处理的 .webidl 时,将在现有的 WEBIDL_FILES 之后添加一个)。

toolkit/components/extensions/webidl-api/moz.build 中添加新条目

WebExtensions API 绑定的新 C++ 文件需要添加到 toolkit/components/extensions/webidl-api/moz.build 中以使其成为构建的一部分,新的 .cpp 文件必须添加到 UNIFIED_SOURCES 组中,其他 WebIDL 绑定也列在其中。类似地,新的 .h 对应文件必须添加到 EXPORTS.mozilla.extensions 中(这确保头文件将被放置到之前在 dom/bindings/Bindings.conf 中设置的路径中)

# WebExtensions API namespaces.
UNIFIED_SOURCES += [
  ...
  "ExtensionRuntime.cpp",
  ...
]

EXPORTS.mozilla.extensions += [
  ...
  "ExtensionRuntime.h",
  ...
]

将新的 API 接入 dom/webidl/ExtensionBrowser.webidl

要使新的 WebIDL 绑定成为 browser 全局的一部分,必须向 dom/webidl/ExtensionBrowser.webidl 添加一个新属性

// `browser.runtime` API namespace.
[Replaceable, SameObject, BinaryName="GetExtensionRuntime",
 Func="mozilla::extensions::ExtensionRuntime::IsAllowed"]
readonly attribute ExtensionRuntime runtime;

注意

chrome 被定义为 browser 全局的别名,因此通过将新属性添加到 ExtensionBrowser` 中, 相同的 属性 也将 ``chrome 全局中可用。与基于“特权 JS”的 WebExtensions API 不同,chromebrowser API 完全相同,并且如果未传递回调,则异步方法将返回 Promise(类似于支持 WebExtensions API 的 Safari 版本)。

添加到 ExtensionBrowser.webidl 中的附加属性将需要对 ExtensionBrowser C++ 类进行一些添加,如 toolkit/components/extensions/webidl-api/ExtensionBrowser.h 中所定义

  • 新对应**公共方法**的定义(按照惯例命名为 GetExtensionMyNamespace

  • 一个 RefPtr 作为新的**私有数据成员命名**(按照惯例命名为 mExtensionMyNamespace

...
namespace extensions {

...
class ExtensionRuntime;
...

class ExtensionBrowser final : ... {
  ...
  RefPtr<ExtensionRuntime> mExtensionRuntime;
  ...

  public:
    ...
    ExtensionRuntime* GetExtensionRuntime();
}
...

然后在其 toolkit/components/extensions/webidl-api/ExtensionBrowser.cpp 对应文件中

  • 新公共方法的实现

  • NS_IMPL_CYCLE_COLLECTION_UNLINKNS_IMPL_CYCLE_COLLECTION_TRAVERSE 宏中添加新的私有成员数据 RefPtr

...
#include "mozilla/extensions/ExtensionRuntime.h"
...
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ExtensionBrowser)
  ...
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mExtensionRuntime)
  ...
NS_IMPL_CYCLE_COLLECTION_UNLINK_END

NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ExtensionBrowser)
  ...
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExtensionRuntime)
  ...
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
...

ExtensionRuntime* ExtensionBrowser::GetExtensionRuntime() {
  if (!mExtensionRuntime) {
    mExtensionRuntime = new ExtensionRuntime(mGlobal, this);
  }

  return mExtensionRuntime
}

警告

忘记将新的 RefPtr 添加到循环收集遍历和取消链接宏中不会导致构建错误,但会导致泄漏。

确保不要忘记仔细检查这些宏,尤其是在某些测试由于检测到的关闭泄漏而失败时。