From 11b2f2f3ef5a23e0ba446560ed443a2567818018 Mon Sep 17 00:00:00 2001 From: uiolee <22849383+uiolee@users.noreply.github.com> Date: Sat, 8 Jul 2023 16:48:06 +0800 Subject: [PATCH 1/5] update Native_manifests --- .../webextensions/native_manifests/index.md | 215 ++++++++++-------- 1 file changed, 122 insertions(+), 93 deletions(-) diff --git a/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md b/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md index 788ce1fe848b4c..e1b3b36c86d8d3 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md +++ b/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md @@ -12,32 +12,30 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests - + - + - + @@ -70,31 +68,30 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests 时传入的名称保持一致。

- 在 OS X 和 Linux 中,它必须和清单文件的文件名保持一致(除.json - 文件扩展名外)。 + 在 MacOS 和 Linux 中,它还必须和清单文件的文件名保持一致(除 .json 文件扩展名外)。 +

+

在Windows上,它必须与你创建的注册表键的名称相匹配,该注册表键包含本地信息传递清单的位置。

-

在 Windows 中,它必须和你创建的包含原生应用清单路径的注册表一致。

- 它必须符合正则表达式 - "^\w+(\.\w+)*$"。这意味着它只能包含小写字母、数字、下划线和 - . ,并且不允许开头或结束是 . ,并且 - . 后面不能是 . 。 + 它必须符合正则表达式 "^\w+(\.\w+)*$"。 + 这意味着它只能包含大小写字母、数字、下划线和 . 。 + 开头或结束不能是是 . ,并且 . 后面不能是 .

- + @@ -102,10 +99,10 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests @@ -116,21 +113,21 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests

Add-on ID 组成的数组。每个值代表允许 ID 为该值的 extension 与这个原生应用通信。

-
-

- 这意味着你可能需要在你 extension 的 manifest.json 中包含 - applications - 字段,并为 extension 设置一个显示的 ID,哪怕是在开发时 -

-
+

+ 请注意这意味着你可能需要在你 extension 的 manifest.json 文件中包含 + browser_specific_settings + 字段,并在开发过程中设置一个明确的 ID。 +

@@ -148,7 +145,7 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests } ``` -清单表示:它允许 ID 为 ping_pong\@example.org 的 extension 通过传入 ping_pong 给 {{WebExtAPIRef("runtime")}} 与自己连接。原生应用自身在 /path/to/native-messaging/app/ping_pong.py 中。 +这允许 ID 为 `ping_pong@example.org` 的 extension 通过 `ping_pong` 的名字传入给相关 {{WebExtAPIRef("runtime")}} API 函数进行连接。原生应用自身在 `/path/to/native-messaging/app/ping_pong.py` 中。 ## 存储管理清单 @@ -168,36 +165,36 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests - + - + @@ -208,22 +205,22 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests ```json { - "name": "favourite-colour-examples@mozilla.org", + "name": "favourite-color-examples@mozilla.org", "description": "ignored", "type": "storage", "data": { - "colour": "management thinks it should be blue!" + "color": "management thinks it should be blue!" } } ``` -在给出的清单文件中,ID 为 favourite-colour-examples\@mozilla.org 的 extension 有权限使用清单中的 data 字段中的数据,代码如下: +在给出的清单文件中,ID 为 `favourite-color-examples@mozilla.org` 的 extension 有权限使用清单中的 data 字段中的数据,代码如下: ```js -var storageItem = browser.storage.managed.get('colour'); +let storageItem = browser.storage.managed.get('color'); storageItem.then((res) => { - console.log(`Managed colour is: ${res.colour}`); + console.log(`Managed color is: ${res.color}`); }); ``` @@ -247,15 +244,15 @@ PKCS #11 清单中包含单个 JSON 对象,对象具有如下属性:

PKCS #11 模块的名字。

它必须和你使用 pkcs11 API 时的名字一致。

- 在 OS X 和 Linux - 中,它必须和清单文件的文件名保持一致(除文件扩展名外) + 在 MacOS 和 Linux 中,它必须和清单文件的文件名保持一致(除文件扩展名外) +

+

在 Windows 中,它必须与你创建的注册表键的名称相匹配,该注册表键包含本地 ·manifest· 的位置

-

在 Windows 中,它必须和你创建的包含原生应用清单路径的注册表一致。

它必须符合正则表达式 - "^\w+(\.\w+)*$"。这意味着它只能包含小写字母、数字、下划线和 - . ,并且不允许开头或结束是 . ,并且 - . 后面不能是 . 。 + "^\w+(\.\w+)*$"。 + 这意味着它只能包含小写字母、数字、下划线和 . 。 + 开头或结束不能是是 . ,并且 . 后面不能是 .

@@ -263,7 +260,7 @@ PKCS #11 清单中包含单个 JSON 对象,对象具有如下属性: @@ -284,7 +281,7 @@ PKCS #11 清单中包含单个 JSON 对象,对象具有如下属性: - + @@ -293,19 +290,21 @@ PKCS #11 清单中包含单个 JSON 对象,对象具有如下属性:

Add-on ID 组成的数组。每个值代表允许 ID 为该值的 extension 与这个模块通信。

-
+

- 这意味着你可能需要在你 extension 的 manifest.json 中包含 - applicationsmanifest.json 文件中包含 + browser_specific_settings - 字段,并为 extension 设置一个显示的 ID,哪怕是在开发时 + 字段,并在开发过程中设置一个明确的 ID。

@@ -325,7 +324,7 @@ PKCS #11 清单中包含单个 JSON 对象,对象具有如下属性: } ``` -给出的这个 JSON 清单,保存为 my_module.json,ID 为 my-extension\@mozilla.org 的 extension 就能够使用类似于如下代码安装 /path/to/libpkcs11testmodule.dylib 安全模块: +给出的这个 JSON 清单,保存为 my_module.json,ID 为 `my-extension@mozilla.org` 的 extension 就能够使用类似于如下代码安装 /path/to/libpkcs11testmodule.dylib 安全模块: ```js browser.pkcs11.installModule("my_module"); @@ -333,19 +332,23 @@ browser.pkcs11.installModule("my_module"); ## 清单路径 -在 Linux 和 Mac OS X 中,你需要将清单文件存在特定的位置。在 Windows 中,你需要创建一个注册表来指向清单文件。 +在 Linux 和 macOS 中,你需要将清单文件存在特定的位置。在 Windows 中,你需要创建一个注册表键来指向清单文件。 -所有类型的清单的详细规则都是相同的,除了倒数第二个的 type 字段表示了清单的类型。下面的例子展示了三种不同类型的清单。在例子中,\ 代表清单中的 name 字段值。 +所有类型的清单的详细规则都是相同的,除了倒数第二个的 type 字段表示了清单的类型。下面的例子展示了三种不同类型的清单。在例子中, `` 代表清单中的 `name` 字段值。 ### Windows 如果想要全局可见,使用下面的路径创建注册表: -```plain +``` HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\NativeMessagingHosts\ +``` +``` HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\ManagedStorage\ +``` +``` HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\PKCS11Modules\ ``` @@ -353,39 +356,53 @@ HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\PKCS11Modules\ ![为原生应用通信清单建立的注册表](native-message-regkey-exaple.png) -> **备注:** 对于原生应用清单,即使原生应用是 32 位的,也不能在 [Wow6432Node](https://en.wikipedia.org/wiki/WoW64#Registry_and_file_system) 下创建注册表。浏览器将总会在 native 视图下寻找注册表的,而不是 32 位放在环境。确保注册表的创建在原生视图中,你可以键入 KEY_WOW64_64KEY 或 KEY_WOW64_32KEY 到 RegCreateKeyEx。请参考:[Accessing an Alternate Registry View]() +> **警告:** 从 Firefox 64 开始,将首先检查 32 位注册表视图 [Wow6432Node](https://zh.wikipedia.org/wiki/WoW64#Registry_and_file_system) 的键,然后是 "native" 注册表视图。请使用适合你的应用程序的那一个。 +> +> **对 于Firefox 63 和更早的版本:** 这个键不应该在 [Wow6432Node](https://zh.wikipedia.org/wiki/WoW64#Registry_and_file_system) 下创建,即使应用程序是 32 位的。以前版本的浏览器总是在注册表的 "native" 视图下寻找该键,而不是在 32 位模拟视图下寻找。为了确保在 "native" 视图中创建键,你可以在 `RegCreateKeyEx` 中传递 `KEY_WOW64_64KEY` 或 `KEY_WOW64_32KEY` 标志。参见[访问备用注册表视图](https://docs.microsoft.com/windows/win32/winprog64/accessing-an-alternate-registry-view)。 如果想要用户级别的可见,使用下面的路径创建注册表: -```plain +``` HKEY_CURRENT_USER\SOFTWARE\Mozilla\NativeMessagingHosts\ +``` +``` HKEY_CURRENT_USER\SOFTWARE\Mozilla\ManagedStorage\ +``` +``` HKEY_CURRENT_USER\SOFTWARE\Mozilla\PKCS11Modules\ ``` 注册表应该有单个默认值,值里存放“到清单文件的路径”。 -### Mac OS X +### macOS 如果想要全局可见,将清单文件存放在: -```plain +``` /Library/Application Support/Mozilla/NativeMessagingHosts/.json +``` +``` /Library/Application Support/Mozilla/ManagedStorage/.json +``` +``` /Library/Application Support/Mozilla/PKCS11Modules/.json ``` 如果想要用户级别的可见,将清单文件存放在: -```plain +``` ~/Library/Application Support/Mozilla/NativeMessagingHosts/.json +``` +``` ~/Library/Application Support/Mozilla/ManagedStorage/.json +``` +``` ~/Library/Application Support/Mozilla/PKCS11Modules/.json ``` @@ -393,30 +410,42 @@ HKEY_CURRENT_USER\SOFTWARE\Mozilla\PKCS11Modules\ 如果想要全局可见,将清单文件存放在: -```plain +``` /usr/lib/mozilla/native-messaging-hosts/.json +``` +``` /usr/lib/mozilla/managed-storage/.json +``` +``` /usr/lib/mozilla/pkcs11-modules/.json ``` 或者: -```plain -/usr/lib64/mozilla/native-messaging-hosts/.json +``` + /usr/lib64/mozilla/native-messaging-hosts/.json +``` -/usr/lib64/mozilla/managed-storage/.json +``` + /usr/lib64/mozilla/managed-storage/.json +``` -/usr/lib64/mozilla/pkcs11-modules/.json +``` + /usr/lib64/mozilla/pkcs11-modules/.json ``` 如果想要用户级别的可见,将清单文件存放在: -```plain +``` ~/.mozilla/native-messaging-hosts/.json +``` +``` ~/.mozilla/managed-storage/.json +``` +``` ~/.mozilla/pkcs11-modules/.json ``` From b0df91fbe80278e55f9a8f4edfff645d66cae0e7 Mon Sep 17 00:00:00 2001 From: uiolee <22849383+uiolee@users.noreply.github.com> Date: Sat, 8 Jul 2023 17:14:12 +0800 Subject: [PATCH 2/5] update prerequisites --- .../mozilla/add-ons/webextensions/prerequisites/index.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/files/zh-cn/mozilla/add-ons/webextensions/prerequisites/index.md b/files/zh-cn/mozilla/add-ons/webextensions/prerequisites/index.md index 0f7765f1cedba4..60d31c39456058 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/prerequisites/index.md +++ b/files/zh-cn/mozilla/add-ons/webextensions/prerequisites/index.md @@ -3,11 +3,6 @@ title: 前提条件 slug: Mozilla/Add-ons/WebExtensions/Prerequisites --- -要使用 WebExtension API 进行开发,你需要进行一些最基本的设置。 +{{AddonSidebar}} -- 下载、安装和启动 [Firefox Developer Edition](https://www.mozilla.org/en-US/firefox/developer/) 或者 [Firefox Nightly](https://nightly.mozilla.org/)。如果想要使用最近的更新,请使用 Nightly 版本。 -- 调整 Firefox 是否允许你安装未签名附加组件的首选项。需注意,该首选项仅在 Firefox Developer Edition 和 Firefox Nightly 中可用。 - - - 在 Firefox 的地址栏中输入 `about:config` - - 在搜索框中输入 `xpinstall.signatures.required` - - 双击该首选项,或者右击并选择“切换”,将其设置为 `false`。 +你所需要的是 Firefox 45 或更高版本。从查看[你的第一个扩展](/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension)开始。 From 7de6b040ade9bc9e442c8a95aa73662b75592dd0 Mon Sep 17 00:00:00 2001 From: uiolee <22849383+uiolee@users.noreply.github.com> Date: Sun, 9 Jul 2023 19:27:14 +0800 Subject: [PATCH 3/5] update --- .../webextensions/native_manifests/index.md | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md b/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md index e1b3b36c86d8d3..b2e9cd19801887 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md +++ b/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md @@ -16,10 +16,8 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests 原生应用通信清单
@@ -70,12 +68,12 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests

在 MacOS 和 Linux 中,它还必须和清单文件的文件名保持一致(除 .json 文件扩展名外)。

-

在Windows上,它必须与你创建的注册表键的名称相匹配,该注册表键包含本地信息传递清单的位置。 +

在 Windows 上,它必须与你创建的注册表键的名称相匹配,该注册表键包含本地信息传递清单的位置。

- 它必须符合正则表达式 "^\w+(\.\w+)*$"。 - 这意味着它只能包含大小写字母、数字、下划线和 . 。 - 开头或结束不能是是 . ,并且 . 后面不能是 . 。 + 它必须符合正则表达式 + "^\w+(\.\w+)*$"。这意味着它只能包含大小写字母、数字、下划线和 + . 。开头或结束不能是是 . ,并且 . 后面不能是 .

@@ -90,8 +88,8 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests @@ -101,8 +99,8 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests @@ -246,13 +244,12 @@ PKCS #11 清单中包含单个 JSON 对象,对象具有如下属性:

在 MacOS 和 Linux 中,它必须和清单文件的文件名保持一致(除文件扩展名外)

-

在 Windows 中,它必须与你创建的注册表键的名称相匹配,该注册表键包含本地 ·manifest· 的位置 +

在 Windows 中,它必须与你创建的注册表键的名称相匹配,该注册表键包含本地·manifest·的位置

它必须符合正则表达式 - "^\w+(\.\w+)*$"。 - 这意味着它只能包含小写字母、数字、下划线和 . 。 - 开头或结束不能是是 . ,并且 . 后面不能是 . 。 + "^\w+(\.\w+)*$"。这意味着它只能包含小写字母、数字、下划线和 + . 。开头或结束不能是是 . ,并且 . 后面不能是 .

From 4d6bc1ab73eb6027c4ea6b48ade74fb42fad4948 Mon Sep 17 00:00:00 2001 From: Uiolee <22849383+uiolee@users.noreply.github.com> Date: Sun, 9 Jul 2023 19:31:08 +0800 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: A1lo --- .../mozilla/add-ons/webextensions/native_manifests/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md b/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md index e1b3b36c86d8d3..d87548c24e4804 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md +++ b/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md @@ -90,8 +90,8 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests From 08a2094f98c2b7075c75b72d3e96d4b34b6106ed Mon Sep 17 00:00:00 2001 From: allo Date: Sun, 9 Jul 2023 23:16:48 +0800 Subject: [PATCH 5/5] minor fixes --- .../webextensions/native_manifests/index.md | 137 +++++++++--------- .../native-message-regkey-exaple.png | Bin 10426 -> 0 bytes 2 files changed, 65 insertions(+), 72 deletions(-) delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/native_manifests/native-message-regkey-exaple.png diff --git a/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md b/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md index 36804d16eb5207..4ffe4f4f4186fb 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md +++ b/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/index.md @@ -5,7 +5,7 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests {{AddonSidebar}} -原生应用清单是一个符合特定规则的 JSON 文件,它应该使用与 extension 不同的安装方式存放在用户的计算机上。举个例子,原生应用清单是由设备管理员或者通过原生应用安装器提供的。 +原生应用清单是一个符合特定规则的 JSON 文件,它应该使用与扩展不同的安装方式存放在用户的计算机上。举个例子,原生应用清单是由设备管理员或者通过原生应用安装器提供的。 有三种不同的原生应用清单: @@ -13,33 +13,32 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests - +
原生应用通信清单 -

- 定义关于与本地应用通信的功能:哪一个 extension 可以与本机的原生应用交换信息。 -

+ 原生应用通信清单 +
+ 开启一个叫 + 原生通信 的功能:使 extension 可以与本机的原生应用交换信息。
存储管理清单 -

- 定义一些 extension 可以用 - {{WebExtAPIRef("storage.managed")}} 读取的只读数据。 -

+ 存储管理清单 +
+ 定义一些 extension 可以用 + {{WebExtAPIRef("storage.managed")}} API 读取的只读数据。
PKCS #11 清单PKCS #11 清单 -

- 定义了 extension 使用 {{WebExtAPIRef("pkcs11")}} API 去枚举 - PKCS #11 安全模型 并在 Firefox 安装它们。 -

+ 定义了 extension 使用 {{WebExtAPIRef("pkcs11")}} API 去枚举 + PKCS #11 安全模型 并在 Firefox 安装它们。
description String

关于这个原生应用的描述。

关于这个原生应用的描述。
path String -

到原生应用的路径。

+

原生应用的路径。

- 在 Windows 中,这可以是一个相对路径。在 OS X 和 Linux - 中,必须是绝对路径。 + 在 Windows 中,这可以是一个相对路径(相对于 manifest )。 + 在 MacOS 和 Linux中,必须是绝对路径。

type String -

定义 extension 和原生应用的连接方法。

+

描述 extension 和原生应用的连接方法。

- 目前只支持一种值,那就是 - stdio。该值表示应用使用标准输入(stdin)来接受消息,用标准输出(stdout)来发送消息。 + 目前只支持一种值,那就是 "stdio"。 + 该值表示应用使用标准输入(stdin)来接受消息,用标准输出(stdout)来发送消息。

String

- 一个 extension 的 ID,表示这个 extension - 可以读取这个仓库。 -

-

- 给出这个 ID 需要你的 extension 的 manifest.json 文件包含 - applicationsbrowser_specific_settings - 字段。 + 字段确定的 ID 一致。

description String

人类可读的描述,Firefox 会忽略它。

人类可读的描述,Firefox 会忽略它
type String

该值只能是storage

+

该值只能是 "storage".

+
data Object

- 一个 JSON 对象,其中可以包含任何合法的 JSON - 值(string、number、boolean、array、object),他们将成为browser.storage.managed可访问的数据。 + 一个 JSON 对象,其中可以包含任何合法的 JSON 值,包括 + string、number、boolean、array、object),他们将成为 browser.storage.managed 存储区域中的数据。

description String -

关于该模块的描述。

+

模块的描述。

它将被用在浏览器界面中为模块设置一个友好的名字(比如,在 Firefox 的“安全设备”对话框中) @@ -274,9 +271,9 @@ PKCS #11 清单中包含单个 JSON 对象,对象具有如下属性:

path String -

到模块的路径。

+

模块的路径。

- 在 Windows 中,这可以是一个相对路径。在 OS X 和 Linux + 在 Windows 中,这可以是一个相对于 manifest 的路径。在 MacOS 和 Linux 中,必须是绝对路径。

type String该值只能是pkcs11。This must be "pkcs11".该值只能是 pkcs11
allowed_extensions - 开启一个叫 - 原生通信 的功能:使 extension 可以与本机的原生应用交换信息。 + 开启一个叫原生通信的功能:使 + extension 可以与本机的原生应用交换信息。

原生应用的路径。

- 在 Windows 中,这可以是一个相对路径(相对于 manifest )。 - 在 MacOS 和 Linux中,必须是绝对路径。 + 在 Windows 中,这可以是一个相对路径(相对于 manifest )。在 MacOS 和 + Linux 中,必须是绝对路径。

描述 extension 和原生应用的连接方法。

- 目前只支持一种值,那就是 "stdio"。 - 该值表示应用使用标准输入(stdin)来接受消息,用标准输出(stdout)来发送消息。 + 目前只支持一种值,那就是 + "stdio"。该值表示应用使用标准输入(stdin)来接受消息,用标准输出(stdout)来发送消息。

原生应用的路径。

- 在 Windows 中,这可以是一个相对路径(相对于 manifest )。 - 在 MacOS 和 Linux中,必须是绝对路径。 + 在 Windows 中,这可以是一个相对路径(相对于 manifest)。在 MacOS 和 Linux + 中,必须是绝对路径。

- 原生应用通信清单 + 原生应用通信清单 - 开启一个叫原生通信的功能:使 - extension 可以与本机的原生应用交换信息。 + 启用原生通信特性:使扩展可以与本机的原生应用通信。
- 存储管理清单 + 存储管理清单 - 定义一些 extension 可以用 + 定义一些扩展可以用 {{WebExtAPIRef("storage.managed")}} API 读取的只读数据。
PKCS #11 清单PKCS #11 清单 - 定义了 extension 使用 {{WebExtAPIRef("pkcs11")}} API 去枚举 - PKCS #11 安全模型 并在 Firefox 安装它们。 + 定义了扩展使用 {{WebExtAPIRef("pkcs11")}} API 去枚举 + PKCS #11 安全模型,并在 Firefox 安装它们。
-对于所有的原生应用清单,你需要做一些工作以便于浏览器可以找到它们。这些规则在 [清单路径](#清单路径) 章节。 +对于所有的原生应用清单,你需要做一些工作以便于浏览器可以找到它们。这些规则在[清单路径](#清单路径)章节。 ## 原生应用通信清单 @@ -48,19 +47,19 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests - - - + + + - + - + - + - + - +
NameTypeDescription名称类型描述
nameString字符串 -

原生应用的名字

+

原生应用的名字。

- 它必须与 extension 调用 + 它必须与扩展调用 {{WebExtAPIRef("runtime.connectNative()")}} 和 {{WebExtAPIRef("runtime.sendNativeMessage()")}} 时传入的名称保持一致。 @@ -72,32 +71,31 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests

它必须符合正则表达式 - "^\w+(\.\w+)*$"。这意味着它只能包含大小写字母、数字、下划线和 - . 。开头或结束不能是是 . ,并且 . 后面不能是 . 。 + "^\w+(\.\w+)*$"。这意味着它只能包含大小写字母、数字、下划线和点。开头或结尾不能是是点,并且点后面不能再跟一个点。

descriptionString字符串 关于这个原生应用的描述。
pathString字符串

原生应用的路径。

- 在 Windows 中,这可以是一个相对路径(相对于 manifest)。在 MacOS 和 Linux + 在 Windows 中,这可以是一个相对路径(相对于清单)。在 MacOS 和 Linux 中,必须是绝对路径。

typeString字符串 -

描述 extension 和原生应用的连接方法。

+

描述扩展和原生应用的连接方法。

目前只支持一种值,那就是 "stdio"。该值表示应用使用标准输入(stdin)来接受消息,用标准输出(stdout)来发送消息。 @@ -106,18 +104,17 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests

allowed_extensionsArray of String字符串数组

- 由 - Add-on ID附加组件 ID - 组成的数组。每个值代表允许 ID 为该值的 extension 与这个原生应用通信。 + 组成的数组。每个值代表允许 ID 为该值的扩展与这个原生应用通信。

- 请注意这意味着你可能需要在你 extension 的 manifest.json 文件中包含 + 请注意这意味着你可能需要在你扩展的 manifest.json 文件中包含

-举个例子,这是 ping_pong 原生应用的原生应用通信清单: +举个例子,这是 `ping_pong` 原生应用的清单: ```json { @@ -143,7 +140,7 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests } ``` -这允许 ID 为 `ping_pong@example.org` 的 extension 通过 `ping_pong` 的名字传入给相关 {{WebExtAPIRef("runtime")}} API 函数进行连接。原生应用自身在 `/path/to/native-messaging/app/ping_pong.py` 中。 +这允许 ID 为 `ping_pong@example.org` 的扩展通过 `ping_pong` 的名字传入给相关 {{WebExtAPIRef("runtime")}} API 函数进行连接。原生应用自身在 `/path/to/native-messaging/app/ping_pong.py` 中。 ## 存储管理清单 @@ -152,18 +149,18 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests - - - + + + - + - + - + - + @@ -213,7 +209,7 @@ slug: Mozilla/Add-ons/WebExtensions/Native_manifests } ``` -在给出的清单文件中,ID 为 `favourite-color-examples@mozilla.org` 的 extension 有权限使用清单中的 data 字段中的数据,代码如下: +根据给出的 JSON 清单,`favourite-color-examples@mozilla.org` 扩展可以像这样访问数据: ```js let storageItem = browser.storage.managed.get('color'); @@ -229,33 +225,32 @@ PKCS #11 清单中包含单个 JSON 对象,对象具有如下属性:
NameTypeDescription名称类型描述
nameString字符串

- 可以访问此存储的扩展的 ID,与你在 extension 中 + 可以访问此存储的扩展的 ID,与你在扩展中

descriptionString字符串 人类可读的描述,Firefox 会忽略它
typeString字符串 -

该值只能是 "storage".

+

该值只能是 "storage"

dataObject对象

- 一个 JSON 对象,其中可以包含任何合法的 JSON 值,包括 - string、number、boolean、array、object),他们将成为 browser.storage.managed 存储区域中的数据。 + 一个 JSON 对象,其中可以包含任何合法的 JSON 值,包括字符串、数字、布尔值、数组、对象,它们将成为 browser.storage.managed 存储区域中的数据。

- - - + + + - + - + - - + + - +
NameTypeDescription名称类别描述
nameString字符串

PKCS #11 模块的名字。

它必须和你使用 pkcs11 API 时的名字一致。

- 在 MacOS 和 Linux 中,它必须和清单文件的文件名保持一致(除文件扩展名外) + 在 MacOS 和 Linux 中,它必须和清单文件的文件名保持一致(除文件扩展名外)。

-

在 Windows 中,它必须与你创建的注册表键的名称相匹配,该注册表键包含本地·manifest·的位置 +

在 Windows 中,它必须与你创建的注册表键的名称相匹配,该注册表键包含了清单的文件位置。

它必须符合正则表达式 - "^\w+(\.\w+)*$"。这意味着它只能包含小写字母、数字、下划线和 - . 。开头或结束不能是是 . ,并且 . 后面不能是 . 。 + "^\w+(\.\w+)*$"。这意味着它只能包含小写字母、数字、下划线和点。开头或结尾不能是点,并且点后面不能再跟一个点。

descriptionString字符串

模块的描述。

@@ -270,19 +265,19 @@ PKCS #11 清单中包含单个 JSON 对象,对象具有如下属性:

模块的路径。

- 在 Windows 中,这可以是一个相对于 manifest 的路径。在 MacOS 和 Linux + 在 Windows 中,这可以是一个相对于清单的路径。在 MacOS 和 Linux 中,必须是绝对路径。

typeString该值只能是 pkcs11字符串该值只能是 "pkcs11"
allowed_extensionsArray of String字符串数组

由 @@ -290,11 +285,11 @@ PKCS #11 清单中包含单个 JSON 对象,对象具有如下属性: href="https://extensionworkshop.com/documentation/develop/extensions-and-the-add-on-id/" >Add-on ID - 组成的数组。每个值代表允许 ID 为该值的 extension 与这个模块通信。 + 组成的数组。每个值代表允许 ID 为该值的扩展与这个模块通信。

- 请注意这意味着你可能需要在你 extension 的 manifest.json 文件中包含 + 备注:这意味着你可能需要在你扩展的 manifest.json 文件中包含 ` 代表清单中的 `name` 字段值。 +所有类型的清单的详细规则都是相同的,除了倒数第二个的 type 字段表示了清单的类型。下面的例子展示了三种不同类型的清单。在例子中,`` 代表清单中的 `name` 字段值。 ### Windows @@ -349,15 +344,13 @@ HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\ManagedStorage\ HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\PKCS11Modules\ ``` -注册表应该有单个默认值,值里存放“到清单文件的路径”。比如为原生应用通信清单建立的注册表差不多是这样: - -![为原生应用通信清单建立的注册表](native-message-regkey-exaple.png) +注册表应该有单个默认值,值里存放到清单文件的路径。 -> **警告:** 从 Firefox 64 开始,将首先检查 32 位注册表视图 [Wow6432Node](https://zh.wikipedia.org/wiki/WoW64#Registry_and_file_system) 的键,然后是 "native" 注册表视图。请使用适合你的应用程序的那一个。 +> **警告:** 从 Firefox 64 开始,将首先检查 32 位注册表视图 [Wow6432Node](https://zh.wikipedia.org/wiki/WoW64#Registry_and_file_system) 的键,然后是“native”注册表视图。请使用适合你的应用程序的那一个。 > -> **对 于Firefox 63 和更早的版本:** 这个键不应该在 [Wow6432Node](https://zh.wikipedia.org/wiki/WoW64#Registry_and_file_system) 下创建,即使应用程序是 32 位的。以前版本的浏览器总是在注册表的 "native" 视图下寻找该键,而不是在 32 位模拟视图下寻找。为了确保在 "native" 视图中创建键,你可以在 `RegCreateKeyEx` 中传递 `KEY_WOW64_64KEY` 或 `KEY_WOW64_32KEY` 标志。参见[访问备用注册表视图](https://docs.microsoft.com/windows/win32/winprog64/accessing-an-alternate-registry-view)。 +> **对于 Firefox 63 和更早的版本**:这个键不应该在 [Wow6432Node](https://zh.wikipedia.org/wiki/WoW64#Registry_and_file_system) 下创建,即使应用程序是 32 位的。以前版本的浏览器总是在注册表的“native”视图下寻找该键,而不是在 32 位模拟视图下寻找。为了确保在“native”视图中创建键,你可以在 `RegCreateKeyEx` 中传递 `KEY_WOW64_64KEY` 或 `KEY_WOW64_32KEY` 标志。参见[访问备用注册表视图](https://docs.microsoft.com/windows/win32/winprog64/accessing-an-alternate-registry-view)。 -如果想要用户级别的可见,使用下面的路径创建注册表: +如果想要用户级别可见,使用下面的路径创建注册表: ``` HKEY_CURRENT_USER\SOFTWARE\Mozilla\NativeMessagingHosts\ @@ -371,7 +364,7 @@ HKEY_CURRENT_USER\SOFTWARE\Mozilla\ManagedStorage\ HKEY_CURRENT_USER\SOFTWARE\Mozilla\PKCS11Modules\ ``` -注册表应该有单个默认值,值里存放“到清单文件的路径”。 +注册表应该有单个默认值,为到清单文件的路径。 ### macOS @@ -389,7 +382,7 @@ HKEY_CURRENT_USER\SOFTWARE\Mozilla\PKCS11Modules\ /Library/Application Support/Mozilla/PKCS11Modules/.json ``` -如果想要用户级别的可见,将清单文件存放在: +如果想要用户级别可见,将清单文件存放在: ``` ~/Library/Application Support/Mozilla/NativeMessagingHosts/.json @@ -422,18 +415,18 @@ HKEY_CURRENT_USER\SOFTWARE\Mozilla\PKCS11Modules\ 或者: ``` - /usr/lib64/mozilla/native-messaging-hosts/.json +/usr/lib64/mozilla/native-messaging-hosts/.json ``` ``` - /usr/lib64/mozilla/managed-storage/.json +/usr/lib64/mozilla/managed-storage/.json ``` ``` - /usr/lib64/mozilla/pkcs11-modules/.json +/usr/lib64/mozilla/pkcs11-modules/.json ``` -如果想要用户级别的可见,将清单文件存放在: +如果想要用户级别可见,将清单文件存放在: ``` ~/.mozilla/native-messaging-hosts/.json diff --git a/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/native-message-regkey-exaple.png b/files/zh-cn/mozilla/add-ons/webextensions/native_manifests/native-message-regkey-exaple.png deleted file mode 100644 index 44858b05a776934708ab18b0446f051245b3e0f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10426 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