From 310fd066e91f454b990372ffa30e803cc8120975 Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 12:56:40 +0100 Subject: unslug zh-cn: move --- .../add-ons/webextensions/api/clipboard/index.html | 36 ++ .../api/clipboard/setimagedata/index.html | 79 ++++ .../webextensions/api/contextmenus/index.html | 191 -------- .../api/devtools.inspectedwindow/index.html | 72 --- .../api/devtools/inspectedwindow/index.html | 72 +++ .../add-ons/webextensions/api/menus/index.html | 191 ++++++++ .../webextensions/api/tabs/query/index.html | 179 ++++++++ .../api/tabs/\346\237\245\350\257\242/index.html" | 179 -------- .../index.html" | 36 -- .../setimagedata/index.html" | 79 ---- .../build_a_cross_browser_extension/index.html | 275 ++++++++++++ .../implement_a_settings_page/index.html | 203 +++++++++ .../manifest.json/homepage_url/index.html | 42 ++ .../index.html" | 42 -- .../packaging_and_installation/index.html | 83 ---- .../porting_from_google_chrome/index.html | 22 - .../publishing_your_webextension/index.html | 98 ----- .../user_interface/sidebars/index.html | 53 +++ .../index.html" | 53 --- .../add-ons/webextensions/walkthrough/index.html | 488 --------------------- .../your_second_webextension/index.html | 488 +++++++++++++++++++++ .../index.html" | 203 --------- .../index.html" | 275 ------------ .../index.html" | 163 ------- .../releases/19/site_compatibility/index.html | 144 ++++++ .../releases/21/site_compatibility/index.html | 145 ++++++ .../releases/23/site_compatibility/index.html | 92 ++++ .../releases/24/site_compatibility/index.html | 22 + .../releases/3/updating_extensions/index.html | 217 +++++++++ files/zh-cn/mozilla/mozilla_persona/index.html | 155 ------- 30 files changed, 2238 insertions(+), 2139 deletions(-) create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/contextmenus/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/devtools.inspectedwindow/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/api/tabs/\346\237\245\350\257\242/index.html" delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/index.html" delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/setimagedata/index.html" create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/manifest.json/\344\270\273\351\241\265\345\234\260\345\235\200/index.html" delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/packaging_and_installation/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/porting_from_google_chrome/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/publishing_your_webextension/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/user_interface/\344\276\247\350\276\271\346\240\217/index.html" delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/walkthrough/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/\345\256\236\347\216\260\344\270\200\344\270\252\350\256\276\347\275\256\351\241\265\351\235\242/index.html" delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/\346\236\204\345\273\272\344\270\200\344\270\252\350\267\250\346\265\217\350\247\210\345\231\250\347\232\204\346\211\251\345\261\225\346\217\222\344\273\266/index.html" delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/\347\224\250\346\210\267\347\225\214\351\235\242\345\205\203\347\264\240/index.html" create mode 100644 files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html create mode 100644 files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html create mode 100644 files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html create mode 100644 files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html create mode 100644 files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html delete mode 100644 files/zh-cn/mozilla/mozilla_persona/index.html (limited to 'files/zh-cn/mozilla') diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html new file mode 100644 index 0000000000..5fecb4334f --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html @@ -0,0 +1,36 @@ +--- +title: clipboard +slug: Mozilla/Add-ons/WebExtensions/API/剪切板 +tags: + - 剪切板 + - 扩展 + - 附加组件 +translation_of: Mozilla/Add-ons/WebExtensions/API/clipboard +--- +
{{AddonSidebar}}
+ +

WebExtention 的 clipboard API 增加了一个将图像复制到剪贴板的函数。目前,这个 API 仅支持复制图像,但我们期望它未来支持复制文本和 HTML(译者注:原文如此,可能是指被支持复制富内容之后的标准剪贴板 API 取代)。

+ +

这个  WebExtension API 之所以存在,主要是因为标准的 Web 剪贴板 API Clipboard API 不支持将图像写入剪贴板。一旦标准剪贴板 API 对非文本剪贴板内容的支持进入通用状态,则此 API 可能会被弃用。

+ +

Reading from the clipboard is not supported by this API, because the clipboard can already be read using the standard web platform APIs. See Interacting with the clipboard.

+ +

This API is based on Chrome's clipboard API, but that API is only available for Chrome apps, not extensions.

+ +

To use this API you need the "clipboardWrite" extension permission.

+ +

函数

+ +
+
{{WebExtAPIRef("clipboard.setImageData()")}}
+
复制图像到剪切板。
+
+ +

浏览器兼容性

+ +

{{Compat("webextensions.api.clipboard")}} {{WebExtExamples("h2")}}

+ +
说明 + +

 此 API 基于 Chromium 的 chrome.clipboard API.

+
diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html new file mode 100644 index 0000000000..3cdaf45b08 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html @@ -0,0 +1,79 @@ +--- +title: clipboard.setImageData() +slug: Mozilla/Add-ons/WebExtensions/API/剪切板/setImageData +tags: + - API + - Clipboard + - 剪贴板 + - 参考 + - 拓展 + - 方法 +translation_of: Mozilla/Add-ons/WebExtensions/API/clipboard/setImageData +--- +
{{AddonSidebar()}}
+ +

将图像复制到剪贴板。在将图像写入剪贴板之前,会对图像进行重新编码。如果图像无效,则不会修改剪贴板。

+ +

图像被作为包含经过编码的图像的 ArrayBuffer 提供。支持 JPEG 和 PNG 格式。

+ +

基于 Chrome 的 clipboard.setImageData() API,但存在一些差异:

+ + + +

这是一个返回 Promise 的异步函数。

+ +

语法

+ +
browser.clipboard.setImageData(imageData, imageType)
+
+ +

参数

+ +
+
imageData
+
An ArrayBuffer containing the encoded image data to copy to the clipboard.
+
imageType
+
A {{domxref("DOMString")}} indicating the type of image contained in imageData: "png" or "jpeg".
+
+ +

返回值

+ +

A Promise that will be resolved with no arguments if the operation succeeded, or rejected if there was an error (for example, because the data did not represent a valid image).

+ +

浏览器兼容性

+ + + +

{{Compat("webextensions.api.clipboard.setImageData", 10)}}

+ +

示例

+ +

Copy a remote image:

+ +
// requires:
+// * the host permission for "https://cdn.mdn.mozilla.net/*"
+// * the API permission "clipboardWrite"
+
+fetch('https://cdn.mdn.mozilla.net/static/img/favicon144.png')
+.then(response => response.arrayBuffer())
+.then(buffer => browser.clipboard.setImageData(buffer, 'png'));
+ +

Copy an image that was bundled with the extension:

+ +
// requires the API permission "clipboardWrite"
+
+fetch(browser.runtime.getURL('image.png'))
+.then(response => response.arrayBuffer())
+.then(buffer => browser.clipboard.setImageData(buffer, 'png'));
+ +

{{WebExtExamples}}

+ +
说明 + +

 此 API 基于 Chromium 的 chrome.clipboard API.

+
diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/contextmenus/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/contextmenus/index.html deleted file mode 100644 index ffcb6ce7b7..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/api/contextmenus/index.html +++ /dev/null @@ -1,191 +0,0 @@ ---- -title: contextMenus -slug: Mozilla/Add-ons/WebExtensions/API/contextMenus -tags: - - API - - WebExtensions - - contextMenus -translation_of: Mozilla/Add-ons/WebExtensions/API/menus ---- -
{{AddonSidebar}}
- -
在浏览器菜单中添加条目。
- -
- -
此API基于Chrome的“contextMenus”API构建,该API可让Chrome扩展程序将项目添加到浏览器的上下文菜单中。 browser.menus API为Chrome的API添加了一些功能,特别是可以将项目添加到浏览器的“工具”菜单以及上下文菜单中。
- -
- -
在Firefox 55之前,这个API最初也被命名为contextMenus,并且这个名字被保留为别名,所以你可以使用contextMenus编写在Firefox和其他浏览器中工作的代码。
- -
- -
你需要拥有“menus”(或别名" contextMenus ")权限来使用此API。
- -

创建菜单项

- -

使用 {{WebExtAPIRef("menus.create()")}}方法创建一个菜单项。你需要传递一个包含条目选项的对象,它包括条目的id,类型,和需要显示出来的文本值。

- -

绑定一个监听器到{{WebExtAPIRef("contextMenus.onClicked")}}事件来监听你菜单项目的点击事件。此监听器会传递一个{{WebExtAPIRef("contextMenus.OnClickData")}},它包含该事件的详细信息。

- -

你可以根据在调用create()时所传递的参数中使用不同的type值来创建四种不同类型的菜单:

- - - -

如果您创建了多个上下文菜单项目或多个工具菜单项目,则这些项目将被放置在子菜单中。 子菜单的父项将标有扩展名。 例如,下面是一个名为“Menu Demo”的扩展,添加了两个上下文菜单项:

- -

- -

图标

- -

如果你使用 "icons" manifest key 为你的扩展指定一个图标,你的菜单项的旁边就会显示一个指定的图标。浏览器会尝试在普通分辨率下使用16 x 16像素的图标,在高分辨率下使用32 x 32像素的图标:

- -

你可以通过调用 {{WebExtAPIRef("menus.create()")}} 时指定icons选项来给子菜单项设置图标。

- -

- -

例子

- -

下面是一个包含四个项目的菜单,他们分别是:一个普通选项,两个周围有分割线的单选,和一个复选框。单选框使用了自定义图标。

- -

- -

你可以使用以下代码创建一个这样的子菜单:

- -
browser.menus.create({
-  id: "remove-me",
-  title: browser.i18n.getMessage("menuItemRemoveMe"),
-  contexts: ["all"]
-}, onCreated);
-
-browser.menus.create({
-  id: "separator-1",
-  type: "separator",
-  contexts: ["all"]
-}, onCreated);
-
-browser.menus.create({
-  id: "greenify",
-  type: "radio",
-  title: browser.i18n.getMessage("menuItemGreenify"),
-  contexts: ["all"],
-  checked: true,
-  icons: {
-    "16": "icons/paint-green-16.png",
-    "32": "icons/paint-green-32.png"
-  }
-}, onCreated);
-
-browser.menus.create({
-  id: "bluify",
-  type: "radio",
-  title: browser.i18n.getMessage("menuItemBluify"),
-  contexts: ["all"],
-  checked: false,
-  icons: {
-    "16": "icons/paint-blue-16.png",
-    "32": "icons/paint-blue-32.png"
-  }
-}, onCreated);
-
-browser.menus.create({
-  id: "separator-2",
-  type: "separator",
-  contexts: ["all"]
-}, onCreated);
-
-var checkedState = true;
-
-browser.menus.create({
-  id: "check-uncheck",
-  type: "checkbox",
-  title: browser.i18n.getMessage("menuItemUncheckMe"),
-  contexts: ["all"],
-  checked: checkedState
-}, onCreated);
- -

类型

- -
-
{{WebExtAPIRef("contextMenus.ContextType")}}
-
菜单里可以出现的不同内容。可能的值有:"all", "audio", "browser_action", "editable", "frame", "image", "link", "page", "page_action", "password", "selection", "tab", "video".
-
{{WebExtAPIRef("contextMenus.ItemType")}}
-
菜单项的类别有: "normal", "checkbox", "radio", "separator".
-
{{WebExtAPIRef("contextMenus.OnClickData")}}
-
当菜单项被点击时发送的信息。
-
- -

属性

- -
-
{{WebExtAPIRef("contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT")}}
-
可以被添加进上下文菜单项的顶级扩展项的最大值,其ContextType可以是"browser_action" 或者 "page_action".
-
- -

函数

- -
-
{{WebExtAPIRef("contextMenus.create()")}}
-
创建一个新的上下文菜单项目。
-
{{WebExtAPIRef("contextMenus.update()")}}
-
更新一个已经创建了的上下文菜单项目。
-
{{WebExtAPIRef("contextMenus.remove()")}}
-
删除一个上下文菜单项目。
-
{{WebExtAPIRef("contextMenus.removeAll()")}}
-
移除该插件创建的所有上下文菜单项目。
-
- -

事件

- -
-
{{WebExtAPIRef("contextMenus.onClicked")}}
-
当一个上下文菜单项被点击时触发。
-
- -

浏览器兼容性

- -

{{ Compat("webextensions.api.menus", 1, "true") }}

- -

{{WebExtExamples("h2")}}

- -
致谢 - -

此API基于Chromium的 chrome.contextMenus API. 此文档来自于Chromium代码中的context_menus.json

-
- - diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/devtools.inspectedwindow/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/devtools.inspectedwindow/index.html deleted file mode 100644 index d59f29ffde..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/api/devtools.inspectedwindow/index.html +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: devtools.inspectedWindow -slug: Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow -translation_of: Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow ---- -
{{AddonSidebar}}
- -
-

This page describes the WebExtensions devtools APIs as they exist in Firefox 54. Although the APIs are based on the Chrome devtools APIs, there are still many features that are not yet implemented in Firefox, and therefore are not documented here. To see which features are currently missing please see Limitations of the devtools APIs.

-
- -

The devtools.inspectedWindow API lets a devtools extension interact with the window that the developer tools are attached to.

- -

Like all the devtools APIs, this API is only available to code running in the document defined in the devtools_page manifest.json key, or in other devtools documents created by the extension (such as the document hosted by a panel the extension created). See Extending the developer tools for more.

- -

Properties

- -
-
devtools.inspectedWindow.tabId
-
The ID of the window that the developer tools are attached to.
-
- -

Functions

- -
-
devtools.inspectedWindow.eval()
-
Evaluate some JavaScript in the target window.
-
devtools.inspectedWindow.reload()
-
Reload the target window's document.
-
- -

Browser compatibility

- -

{{Compat("webextensions.api.devtools.inspectedWindow")}}{{WebExtExamples("h2")}}

- -
Acknowledgements - -

This API is based on Chromium's chrome.devtools.inspectedWindow API.

- -

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

-
- - diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html new file mode 100644 index 0000000000..d59f29ffde --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html @@ -0,0 +1,72 @@ +--- +title: devtools.inspectedWindow +slug: Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow +translation_of: Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow +--- +
{{AddonSidebar}}
+ +
+

This page describes the WebExtensions devtools APIs as they exist in Firefox 54. Although the APIs are based on the Chrome devtools APIs, there are still many features that are not yet implemented in Firefox, and therefore are not documented here. To see which features are currently missing please see Limitations of the devtools APIs.

+
+ +

The devtools.inspectedWindow API lets a devtools extension interact with the window that the developer tools are attached to.

+ +

Like all the devtools APIs, this API is only available to code running in the document defined in the devtools_page manifest.json key, or in other devtools documents created by the extension (such as the document hosted by a panel the extension created). See Extending the developer tools for more.

+ +

Properties

+ +
+
devtools.inspectedWindow.tabId
+
The ID of the window that the developer tools are attached to.
+
+ +

Functions

+ +
+
devtools.inspectedWindow.eval()
+
Evaluate some JavaScript in the target window.
+
devtools.inspectedWindow.reload()
+
Reload the target window's document.
+
+ +

Browser compatibility

+ +

{{Compat("webextensions.api.devtools.inspectedWindow")}}{{WebExtExamples("h2")}}

+ +
Acknowledgements + +

This API is based on Chromium's chrome.devtools.inspectedWindow API.

+ +

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

+
+ + diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html new file mode 100644 index 0000000000..ffcb6ce7b7 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html @@ -0,0 +1,191 @@ +--- +title: contextMenus +slug: Mozilla/Add-ons/WebExtensions/API/contextMenus +tags: + - API + - WebExtensions + - contextMenus +translation_of: Mozilla/Add-ons/WebExtensions/API/menus +--- +
{{AddonSidebar}}
+ +
在浏览器菜单中添加条目。
+ +
+ +
此API基于Chrome的“contextMenus”API构建,该API可让Chrome扩展程序将项目添加到浏览器的上下文菜单中。 browser.menus API为Chrome的API添加了一些功能,特别是可以将项目添加到浏览器的“工具”菜单以及上下文菜单中。
+ +
+ +
在Firefox 55之前,这个API最初也被命名为contextMenus,并且这个名字被保留为别名,所以你可以使用contextMenus编写在Firefox和其他浏览器中工作的代码。
+ +
+ +
你需要拥有“menus”(或别名" contextMenus ")权限来使用此API。
+ +

创建菜单项

+ +

使用 {{WebExtAPIRef("menus.create()")}}方法创建一个菜单项。你需要传递一个包含条目选项的对象,它包括条目的id,类型,和需要显示出来的文本值。

+ +

绑定一个监听器到{{WebExtAPIRef("contextMenus.onClicked")}}事件来监听你菜单项目的点击事件。此监听器会传递一个{{WebExtAPIRef("contextMenus.OnClickData")}},它包含该事件的详细信息。

+ +

你可以根据在调用create()时所传递的参数中使用不同的type值来创建四种不同类型的菜单:

+ + + +

如果您创建了多个上下文菜单项目或多个工具菜单项目,则这些项目将被放置在子菜单中。 子菜单的父项将标有扩展名。 例如,下面是一个名为“Menu Demo”的扩展,添加了两个上下文菜单项:

+ +

+ +

图标

+ +

如果你使用 "icons" manifest key 为你的扩展指定一个图标,你的菜单项的旁边就会显示一个指定的图标。浏览器会尝试在普通分辨率下使用16 x 16像素的图标,在高分辨率下使用32 x 32像素的图标:

+ +

你可以通过调用 {{WebExtAPIRef("menus.create()")}} 时指定icons选项来给子菜单项设置图标。

+ +

+ +

例子

+ +

下面是一个包含四个项目的菜单,他们分别是:一个普通选项,两个周围有分割线的单选,和一个复选框。单选框使用了自定义图标。

+ +

+ +

你可以使用以下代码创建一个这样的子菜单:

+ +
browser.menus.create({
+  id: "remove-me",
+  title: browser.i18n.getMessage("menuItemRemoveMe"),
+  contexts: ["all"]
+}, onCreated);
+
+browser.menus.create({
+  id: "separator-1",
+  type: "separator",
+  contexts: ["all"]
+}, onCreated);
+
+browser.menus.create({
+  id: "greenify",
+  type: "radio",
+  title: browser.i18n.getMessage("menuItemGreenify"),
+  contexts: ["all"],
+  checked: true,
+  icons: {
+    "16": "icons/paint-green-16.png",
+    "32": "icons/paint-green-32.png"
+  }
+}, onCreated);
+
+browser.menus.create({
+  id: "bluify",
+  type: "radio",
+  title: browser.i18n.getMessage("menuItemBluify"),
+  contexts: ["all"],
+  checked: false,
+  icons: {
+    "16": "icons/paint-blue-16.png",
+    "32": "icons/paint-blue-32.png"
+  }
+}, onCreated);
+
+browser.menus.create({
+  id: "separator-2",
+  type: "separator",
+  contexts: ["all"]
+}, onCreated);
+
+var checkedState = true;
+
+browser.menus.create({
+  id: "check-uncheck",
+  type: "checkbox",
+  title: browser.i18n.getMessage("menuItemUncheckMe"),
+  contexts: ["all"],
+  checked: checkedState
+}, onCreated);
+ +

类型

+ +
+
{{WebExtAPIRef("contextMenus.ContextType")}}
+
菜单里可以出现的不同内容。可能的值有:"all", "audio", "browser_action", "editable", "frame", "image", "link", "page", "page_action", "password", "selection", "tab", "video".
+
{{WebExtAPIRef("contextMenus.ItemType")}}
+
菜单项的类别有: "normal", "checkbox", "radio", "separator".
+
{{WebExtAPIRef("contextMenus.OnClickData")}}
+
当菜单项被点击时发送的信息。
+
+ +

属性

+ +
+
{{WebExtAPIRef("contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT")}}
+
可以被添加进上下文菜单项的顶级扩展项的最大值,其ContextType可以是"browser_action" 或者 "page_action".
+
+ +

函数

+ +
+
{{WebExtAPIRef("contextMenus.create()")}}
+
创建一个新的上下文菜单项目。
+
{{WebExtAPIRef("contextMenus.update()")}}
+
更新一个已经创建了的上下文菜单项目。
+
{{WebExtAPIRef("contextMenus.remove()")}}
+
删除一个上下文菜单项目。
+
{{WebExtAPIRef("contextMenus.removeAll()")}}
+
移除该插件创建的所有上下文菜单项目。
+
+ +

事件

+ +
+
{{WebExtAPIRef("contextMenus.onClicked")}}
+
当一个上下文菜单项被点击时触发。
+
+ +

浏览器兼容性

+ +

{{ Compat("webextensions.api.menus", 1, "true") }}

+ +

{{WebExtExamples("h2")}}

+ +
致谢 + +

此API基于Chromium的 chrome.contextMenus API. 此文档来自于Chromium代码中的context_menus.json

+
+ + diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html new file mode 100644 index 0000000000..9afe6e80a8 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html @@ -0,0 +1,179 @@ +--- +title: 选项卡. 查询 () +slug: Mozilla/Add-ons/WebExtensions/API/tabs/查询 +translation_of: Mozilla/Add-ons/WebExtensions/API/tabs/query +--- +
[阿登侧边栏()]
+ +

获取具有指定属性的所有选项卡,如果未指定任何属性,则获取所有选项卡。

+ +

这是返回 的异步函数。Promise

+ +

语法

+ +
let querying = browser.tabs.query(queryObj)
+
+ +

参数

+ +
+
queryObj
+
+

object.函数将仅获取其属性与此处包含的属性匹配的选项卡。query()

+ +

请参阅 \WebExtAPIRef("选项卡")。Tab")=文档以了解有关这些属性的详细信息。

+ +
+
active[optional_inline]
+
boolean.选项卡是否在窗口中处于活动状态。
+
audible[optional_inline]
+
boolean.标签是否可听见。
+
autoDiscardable[optional_inline]
+
boolean.当资源不足时,浏览器是否可以自动丢弃选项卡。
+
cookieStoreId[optional_inline]
+
string.使用此仅返回其 Cookie 存储 ID 为 的选项卡。此选项仅在加载项具有权限时才可用cookieStoreId"cookies"
+
currentWindow[optional_inline]
+
boolean.选项卡是否在当前窗口中。
+
discarded[optional_inline]
+
boolean.是否丢弃选项卡。丢弃的选项卡是其内容已从内存中卸载,但仍在选项卡条中可见的选项卡。下次激活时,其内容将重新加载。
+
hidden[optional_inline]
+
boolean.选项卡是否隐藏。
+
highlighted[optional_inline]
+
boolean.选项卡是否突出显示。
+
index[optional_inline]
+
integer.选项卡在其窗口中的位置。
+
muted[optional_inline]
+
boolean.选项卡是否为静音。
+
lastFocusedWindow[optional_inline]
+
boolean.选项卡是否在上一个焦点窗口中。
+
pinned[optional_inline]
+
boolean.选项卡是否固定。
+
status[optional_inline]
+
{WebExtAPIRef('选项卡。TabStatus ')=。选项卡是否已完成加载。
+
title[optional_inline]
+
string.将页面标题与图案匹配。
+
url[optional_inline]
+
string或。将选项卡与一个或多个匹配模式匹配。请注意,片段标识符不匹配。array of string
+
windowId{{optional_inline}}
+
integer. The of the parent window, or {{WebExtAPIRef('windows.WINDOW_ID_CURRENT')}} for the current window.id
+
windowType{{optional_inline}}
+
{{WebExtAPIRef('tabs.WindowType')}}. The type of window the tabs are in.
+
+
+
+ +

Return value

+ +

A that will be fulfilled with an of objects, containing information about each matching tab.Promisearray{{WebExtAPIRef('tabs.Tab')}}

+ +

If any error occurs, the promise will be rejected with an error message.

+ +

Examples

+ +

Get all tabs:

+ +
function logTabs(tabs) {
+  for (let tab of tabs) {
+    // tab.url requires the `tabs` permission
+    console.log(tab.url);
+  }
+}
+
+function onError(error) {
+  console.log(`Error: ${error}`);
+}
+
+let querying = browser.tabs.query({});
+querying.then(logTabs, onError);
+ +

Get all tabs in the current window:

+ +
function logTabs(tabs) {
+  for (let tab of tabs) {
+    // tab.url requires the `tabs` permission
+    console.log(tab.url);
+  }
+}
+
+function onError(error) {
+  console.log(`Error: ${error}`);
+}
+
+let querying = browser.tabs.query({currentWindow: true});
+querying.then(logTabs, onError);
+ +

Get the active tab in the current window:

+ +
function logTabs(tabs) {
+  // tabs[0].url requires the `tabs` permission
+  console.log(tabs[0].url);
+}
+
+function onError(error) {
+  console.log(`Error: ${error}`);
+}
+
+let querying = browser.tabs.query({currentWindow: true, active: true});
+querying.then(logTabs, onError);
+ +

Get tabs for all HTTP and HTTPS URLs under or any of its subdomains:"mozilla.org"

+ +
function logTabs(tabs) {
+  for (let tab of tabs) {
+    // tab.url requires the `tabs` permission
+    console.log(tab.url);
+  }
+}
+
+function onError(error) {
+  console.log(`Error: ${error}`);
+}
+
+let querying = browser.tabs.query({url: "*://*.mozilla.org/*"});
+querying.then(logTabs, onError);
+ +

{{WebExtExamples}}

+ +

Browser compatibility

+ + + +

{{Compat("webextensions.api.tabs.query")}}

+ +
Acknowledgements + +

This API is based on Chromium's chrome.tabs API. This documentation is derived from tabs.json in the Chromium code.

+ +

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

+
+ + diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/\346\237\245\350\257\242/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/\346\237\245\350\257\242/index.html" deleted file mode 100644 index 9afe6e80a8..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/\346\237\245\350\257\242/index.html" +++ /dev/null @@ -1,179 +0,0 @@ ---- -title: 选项卡. 查询 () -slug: Mozilla/Add-ons/WebExtensions/API/tabs/查询 -translation_of: Mozilla/Add-ons/WebExtensions/API/tabs/query ---- -
[阿登侧边栏()]
- -

获取具有指定属性的所有选项卡,如果未指定任何属性,则获取所有选项卡。

- -

这是返回 的异步函数。Promise

- -

语法

- -
let querying = browser.tabs.query(queryObj)
-
- -

参数

- -
-
queryObj
-
-

object.函数将仅获取其属性与此处包含的属性匹配的选项卡。query()

- -

请参阅 \WebExtAPIRef("选项卡")。Tab")=文档以了解有关这些属性的详细信息。

- -
-
active[optional_inline]
-
boolean.选项卡是否在窗口中处于活动状态。
-
audible[optional_inline]
-
boolean.标签是否可听见。
-
autoDiscardable[optional_inline]
-
boolean.当资源不足时,浏览器是否可以自动丢弃选项卡。
-
cookieStoreId[optional_inline]
-
string.使用此仅返回其 Cookie 存储 ID 为 的选项卡。此选项仅在加载项具有权限时才可用cookieStoreId"cookies"
-
currentWindow[optional_inline]
-
boolean.选项卡是否在当前窗口中。
-
discarded[optional_inline]
-
boolean.是否丢弃选项卡。丢弃的选项卡是其内容已从内存中卸载,但仍在选项卡条中可见的选项卡。下次激活时,其内容将重新加载。
-
hidden[optional_inline]
-
boolean.选项卡是否隐藏。
-
highlighted[optional_inline]
-
boolean.选项卡是否突出显示。
-
index[optional_inline]
-
integer.选项卡在其窗口中的位置。
-
muted[optional_inline]
-
boolean.选项卡是否为静音。
-
lastFocusedWindow[optional_inline]
-
boolean.选项卡是否在上一个焦点窗口中。
-
pinned[optional_inline]
-
boolean.选项卡是否固定。
-
status[optional_inline]
-
{WebExtAPIRef('选项卡。TabStatus ')=。选项卡是否已完成加载。
-
title[optional_inline]
-
string.将页面标题与图案匹配。
-
url[optional_inline]
-
string或。将选项卡与一个或多个匹配模式匹配。请注意,片段标识符不匹配。array of string
-
windowId{{optional_inline}}
-
integer. The of the parent window, or {{WebExtAPIRef('windows.WINDOW_ID_CURRENT')}} for the current window.id
-
windowType{{optional_inline}}
-
{{WebExtAPIRef('tabs.WindowType')}}. The type of window the tabs are in.
-
-
-
- -

Return value

- -

A that will be fulfilled with an of objects, containing information about each matching tab.Promisearray{{WebExtAPIRef('tabs.Tab')}}

- -

If any error occurs, the promise will be rejected with an error message.

- -

Examples

- -

Get all tabs:

- -
function logTabs(tabs) {
-  for (let tab of tabs) {
-    // tab.url requires the `tabs` permission
-    console.log(tab.url);
-  }
-}
-
-function onError(error) {
-  console.log(`Error: ${error}`);
-}
-
-let querying = browser.tabs.query({});
-querying.then(logTabs, onError);
- -

Get all tabs in the current window:

- -
function logTabs(tabs) {
-  for (let tab of tabs) {
-    // tab.url requires the `tabs` permission
-    console.log(tab.url);
-  }
-}
-
-function onError(error) {
-  console.log(`Error: ${error}`);
-}
-
-let querying = browser.tabs.query({currentWindow: true});
-querying.then(logTabs, onError);
- -

Get the active tab in the current window:

- -
function logTabs(tabs) {
-  // tabs[0].url requires the `tabs` permission
-  console.log(tabs[0].url);
-}
-
-function onError(error) {
-  console.log(`Error: ${error}`);
-}
-
-let querying = browser.tabs.query({currentWindow: true, active: true});
-querying.then(logTabs, onError);
- -

Get tabs for all HTTP and HTTPS URLs under or any of its subdomains:"mozilla.org"

- -
function logTabs(tabs) {
-  for (let tab of tabs) {
-    // tab.url requires the `tabs` permission
-    console.log(tab.url);
-  }
-}
-
-function onError(error) {
-  console.log(`Error: ${error}`);
-}
-
-let querying = browser.tabs.query({url: "*://*.mozilla.org/*"});
-querying.then(logTabs, onError);
- -

{{WebExtExamples}}

- -

Browser compatibility

- - - -

{{Compat("webextensions.api.tabs.query")}}

- -
Acknowledgements - -

This API is based on Chromium's chrome.tabs API. This documentation is derived from tabs.json in the Chromium code.

- -

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

-
- - diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/index.html" deleted file mode 100644 index 5fecb4334f..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/index.html" +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: clipboard -slug: Mozilla/Add-ons/WebExtensions/API/剪切板 -tags: - - 剪切板 - - 扩展 - - 附加组件 -translation_of: Mozilla/Add-ons/WebExtensions/API/clipboard ---- -
{{AddonSidebar}}
- -

WebExtention 的 clipboard API 增加了一个将图像复制到剪贴板的函数。目前,这个 API 仅支持复制图像,但我们期望它未来支持复制文本和 HTML(译者注:原文如此,可能是指被支持复制富内容之后的标准剪贴板 API 取代)。

- -

这个  WebExtension API 之所以存在,主要是因为标准的 Web 剪贴板 API Clipboard API 不支持将图像写入剪贴板。一旦标准剪贴板 API 对非文本剪贴板内容的支持进入通用状态,则此 API 可能会被弃用。

- -

Reading from the clipboard is not supported by this API, because the clipboard can already be read using the standard web platform APIs. See Interacting with the clipboard.

- -

This API is based on Chrome's clipboard API, but that API is only available for Chrome apps, not extensions.

- -

To use this API you need the "clipboardWrite" extension permission.

- -

函数

- -
-
{{WebExtAPIRef("clipboard.setImageData()")}}
-
复制图像到剪切板。
-
- -

浏览器兼容性

- -

{{Compat("webextensions.api.clipboard")}} {{WebExtExamples("h2")}}

- -
说明 - -

 此 API 基于 Chromium 的 chrome.clipboard API.

-
diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/setimagedata/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/setimagedata/index.html" deleted file mode 100644 index 3cdaf45b08..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/setimagedata/index.html" +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: clipboard.setImageData() -slug: Mozilla/Add-ons/WebExtensions/API/剪切板/setImageData -tags: - - API - - Clipboard - - 剪贴板 - - 参考 - - 拓展 - - 方法 -translation_of: Mozilla/Add-ons/WebExtensions/API/clipboard/setImageData ---- -
{{AddonSidebar()}}
- -

将图像复制到剪贴板。在将图像写入剪贴板之前,会对图像进行重新编码。如果图像无效,则不会修改剪贴板。

- -

图像被作为包含经过编码的图像的 ArrayBuffer 提供。支持 JPEG 和 PNG 格式。

- -

基于 Chrome 的 clipboard.setImageData() API,但存在一些差异:

- - - -

这是一个返回 Promise 的异步函数。

- -

语法

- -
browser.clipboard.setImageData(imageData, imageType)
-
- -

参数

- -
-
imageData
-
An ArrayBuffer containing the encoded image data to copy to the clipboard.
-
imageType
-
A {{domxref("DOMString")}} indicating the type of image contained in imageData: "png" or "jpeg".
-
- -

返回值

- -

A Promise that will be resolved with no arguments if the operation succeeded, or rejected if there was an error (for example, because the data did not represent a valid image).

- -

浏览器兼容性

- - - -

{{Compat("webextensions.api.clipboard.setImageData", 10)}}

- -

示例

- -

Copy a remote image:

- -
// requires:
-// * the host permission for "https://cdn.mdn.mozilla.net/*"
-// * the API permission "clipboardWrite"
-
-fetch('https://cdn.mdn.mozilla.net/static/img/favicon144.png')
-.then(response => response.arrayBuffer())
-.then(buffer => browser.clipboard.setImageData(buffer, 'png'));
- -

Copy an image that was bundled with the extension:

- -
// requires the API permission "clipboardWrite"
-
-fetch(browser.runtime.getURL('image.png'))
-.then(response => response.arrayBuffer())
-.then(buffer => browser.clipboard.setImageData(buffer, 'png'));
- -

{{WebExtExamples}}

- -
说明 - -

 此 API 基于 Chromium 的 chrome.clipboard API.

-
diff --git a/files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html b/files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html new file mode 100644 index 0000000000..6d1a21497c --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html @@ -0,0 +1,275 @@ +--- +title: 构建一个跨浏览器的扩展程序 +slug: Mozilla/Add-ons/WebExtensions/构建一个跨浏览器的扩展插件 +tags: + - Web插件 + - 扩展 + - 指南 + - 插件 +translation_of: Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension +--- +

{{AddonSidebar()}}

+ +

浏览器扩展 API 的引入为浏览器扩展的开发创造了 “一次开发跨浏览器” 的前景。然而,在使用扩展 API 的浏览器中(主要是 Chrome、 Firefox、 Opera 和 Edge) ,API 的实现和覆盖范围都存在差异。除此之外,Safari 使用了它自己的 Safari 扩展脚本系统。

+ +

最大化兼容浏览器扩展意味着至少在两个不同的浏览器上兼容同一个扩展。本文探讨了在创建跨浏览器扩展时所面临的六个主要挑战,并在每种情况下提出了如何应对这些挑战。

+ +

本文不讨论为 Safari 构建浏览器扩展。您可以通过 Safari 扩展共享一些资源,比如图片和 HTML 内容。然而,如果您要进行 JavaScript 部分的编程则需要作为一个单独的开发项目进行,除非您希望创建自己的 polyfill。

+ +

跨平台扩展的开发障碍

+ +

在开发跨平台扩展时,需要注意以下六个方面:

+ + + +

API 命名空间

+ +

在四大主流浏览器中,有两个 API 命名空间正在使用:

+ + + +

Firefox 也支持 Chrome 浏览器的 chrome.* 名称空间,主要用于协助扩展移植。然而,首选应该使用浏览器 browser.* 命名空间。除了被提议的标准外, browser.* 使用 promises ーー一种现代化且简单的处理异步事件机制。

+ +

只有在非常小的扩展中,命名空间才可能是唯一的跨平台问题。因此,如果你遇到了且试图专门解决这个问题的话,可能很少会有帮助。最好的方法是通过异步事件处理来解决这个问题。

+ +

API 异步事件处理

+ +

在四个主要浏览器中,有两种方法可以处理异步事件:

+ + + +

Firefox 还支持 chrome.* 命名空间中的 callbacks 风格的 API,这主要是为了便于从 Chrome 迁移。然而,应该首选使用 promises(以及 browser.* 命名空间),它已被采纳为拟议标准的一部分。它极大地简化了异步事件处理,特别是在需要将事件链接在一起的情况下。

+ +
+

如果你对这两种方法之间的差异不熟悉,可以看一下 了解异步 JavaScript: Callbacks、 Promises 和 Async/Await 或者 MDN 的 Using promises 页面。

+
+ +

浏览器扩展 API 的垫片(Polyfill)

+ +

那么,当 Firefox 是唯一支持它的浏览器时,你如何轻松地使用 promises 呢?解决方案是使用 promises 为 Firefox 编程,并使用浏览器扩展 API 的垫片(Polyfill)
+
+ 这个 polyfill 解决了跨 Firefox、 Chrome 和 Opera 的 API 名称空间和异步事件处理。在撰写本报告时(2018年11月) ,Edge 的支持正在开发中。
+
+ 要使用 polyfill,可以使用 npm 安装到开发环境中,或者直接从 GitHub Relase 页面下载。

+ +

然后,引入 browser-polyfill.js 到:

+ + + +

例如,这个 manifest.json 代码让你的后台脚本可以使用 polyfill:

+ +
{
+ // ...
+ "background": {
+   "scripts": [
+     "browser-polyfill.js",
+     "background.js"
+   ]
+ }
+}
+ +

您的目标是确保在任何其他扩展脚本执行 browser.* API 前执行 polyfill。

+ +
+

关于如何使用模块打包器使用 polyfill 的更多细节和信息,请参阅 GitHub 上的项目自述文件

+
+ +

还有其他的 polyfill 选项,但是在撰写本文时,没有一个提供浏览器扩展 API polyfill 的覆盖范围。所以,如果你没有把 Firefox 作为你的首选,你的选择就是接受 polyfills 的限制,移植到 Firefox 并添加跨浏览器的支持,或者开发你自己的 polyfill。

+ +

API 函数覆盖率

+ +

这四个主要浏览器提供的 API 函数的实现差异可分为三大类:

+ + + +

你可以在 Mozilla Developer Network 浏览器对 JavaScript API 页面的支持上找到4个主要浏览器对扩展 API 的支持细节,以及 Firefox for Android 对扩展 API 的支持细节。浏览器兼容性信息也包含在每个函数及其方法、类型和事件的 Mozilla Developer Network JavaScript APIs 参考页面中。

+ +

处理 API 差异

+ +

解决这些差异的一个简单方法是将扩展中使用的函数限制在没有 API 差异的函数范围内。在实践中,对于大多数扩展,这种方法可能限制性太强。
+
+ 相反,如果 API 之间存在差异,则应该提供替代实现或降级功能。(请记住: 您可能还需要这样考虑同一浏览器的不同版本之间的 API 支持差异。)

+ +

使用运行时检查函数特性的可用性是实现备选或降级功能的推荐方法。执行运行时检查的好处是,如果函数是可用的,您不需要更新和重新分发扩展来使用它。

+ +

下面的代码使您能够执行运行时检查:

+ +
if (typeof <function> === "function") {
+   // safe to use the function
+}
+ +

Manifest 字段

+ +

4个主要浏览器支持的 manifest.json 文件字段的差异大致可分为三类:

+ + + +

浏览器兼容性信息包含在 Mozilla Developer Network manifest.json 页的每个字段中。

+ +

manifest.json 文件在不同浏览器之间的版本号可能有所不同,为每个浏览器创建和编辑一个静态版本号通常是最简单的方法。

+ +

扩展打包

+ +

通过浏览器扩展商店打包和分发扩展相对简单。

+ + + +

有关打包的详细信息,请参阅相应扩展的开发人员门户网站上的指南。

+ +

扩展发布

+ +

这四种主要浏览器都维护有浏览器扩展商店。每个商店还对扩展进行审核,以检查安全漏洞。

+ +

因此,您需要为每个商店分别添加和更新扩展。在某些情况下,您可以使用脚本上传扩展。

+ +

下表总结了每个商店的做法和特点:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

注册费

+
+

上传模块

+
+

发布审核

+
+

开发者账号需要2FA验证

+
+

Firefox

+
+

+
+

web-ext

+
+

全自动,仅需要几秒钟1

+
+

+
+

Chrome

+
+

+
+

+
+

全自动,短于一小时

+
+

+
+

Opera

+
+

+
+

+
+

人工审核,但不需要提供SLA

+
+

+
+

Edge

+
+

+
+

+
+

人工审核,需要72小时2

+
+

+
+ +

1 在发布后会延期进行一次人工审查,如果发现了需要解决的问题,可能导致扩展被暂停。

+ +

2 在撰写本文时,微软只允许发布预先批准的扩展。

+ +

其他考虑

+ +

扩展命名

+ +

Microsoft 要求扩展具有唯一的名称,并通过 Windows Dev Center 为扩展声明一个或多个名称。因此,即使您不打算立即支持 Edge,为微软保留一个扩展名可能是最谨慎的做法。

+ +

版本号指定

+ +

Firefox 和 Chrome 商店要求每个上传的扩展发布包都有一个单独的版本号。这意味着如果在线上遇到问题,就不能恢复到之前的版本号。

+ +

在不同的实现中共享资源

+ +

即使你要支持的平台中包括 Safari,仍然可以在对于不同浏览器的实现中共享许多资源。其中包括:

+ + + +

总结

+ +

在进行跨平台扩展开发时,可以通过对标 Firefox 和使用 WebExtension API Polyfill 来解决扩展 API 之间的根本差异。遵循这种方法,您将在使用与提议的 WebExtension API 标准紧密结合的 API 特性中受益,并使用 promises 来简单的处理异步事件。

+ +

跨平台工作的主要重点可能是处理主要浏览器支持的 API 特性之间的差异。创建你的 manifest.json 文件应该是相对简单的,你可以手动完成。然后,您将需要考虑扩展包中的打包差异,以及提交到每个扩展商店的过程差异。

+ +

您同时可以使用 browser-extension-template 用于快速设置、生成和发布浏览器扩展项目。

+ +

根据本文中的建议,您现在应该能够创建一个在四种主要浏览器上都运行良好的扩展程序,使您能够将扩展功能交付给更多的人。

diff --git a/files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html b/files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html new file mode 100644 index 0000000000..fe8ac2e0a7 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html @@ -0,0 +1,203 @@ +--- +title: 实现一个设置页面 +slug: Mozilla/Add-ons/WebExtensions/实现一个设置页面 +translation_of: Mozilla/Add-ons/WebExtensions/Implement_a_settings_page +--- +
{{AddonSidebar}}
+ +

设置页面可以让用户查看,修改扩展的一些设置。

+ +

对于WebExtensions,设置通常使用 storage API 保存. 实现一个设置页面通常包含以下三步:

+ + + +
+

你也可以使用 runtime.openOptionsPage() 打开该页面。

+
+ +

简单的 WebExtension

+ +

首先,我们写一个向用户访问的所有页面添加一个蓝色边框的扩展。

+ +

创建一个新的文件夹命名为“setting”,然后创建文件“manifest.json”它包含以下内容:

+ +
{
+
+  "manifest_version": 2,
+  "name": "Settings example",
+  "version": "1.0",
+
+  "content_scripts": [
+    {
+      "matches": ["<all_urls>"],
+      "js": ["borderify.js"]
+    }
+  ]
+
+}
+ +

该扩展指示浏览器在用户访问的网站上加载一个名为"borderify.js“的Content Script。

+ +

接下来,在"setting"目录下创建"borderify.js",然后给予他以下内容:

+ +
document.body.style.border = "10px solid blue";
+ +

这只是向网页加入了一一个蓝色边框

+ +

现在 安装该扩展 并测试它——打开任意一个网页:

+ +

{{EmbedYouTube("E-WUhihF8fw")}}

+ +

添加设置页面

+ +

现在让我们创建一个设置页面来允许用户设置边框的颜色。

+ +

首先更新 "manifest.json" 使他拥有如下内容:

+ +
{
+
+  "manifest_version": 2,
+  "name": "Settings example",
+  "version": "1.0",
+
+  "content_scripts": [
+    {
+      "matches": ["<all_urls>"],
+      "js": ["borderify.js"]
+    }
+  ],
+
+  "options_ui": {
+    "page": "options.html"
+  },
+
+  "permissions": ["storage"]
+
+}
+
+ +

我们加入了两个manifest 关键字:

+ + + +

接下来,因为我们承诺提供"options.html",让我们来创建他,在"setting"目录创建一个该文件并具有以下内容:

+ +
<!DOCTYPE html>
+
+<html>
+  <head>
+    <meta charset="utf-8">
+  </head>
+
+  <body>
+
+    <form>
+        <label>Border color<input type="text" id="color" ></label>
+        <button type="submit">Save</button>
+    </form>
+
+    <script src="options.js"></script>
+
+  </body>
+
+</html>
+
+ +

这里定义了一个带有标记文字{{htmlelement("input")}}的 {{htmlelement("form")}} 和一个 提交 {{htmlelement("button")}}. 也包含了一个名为"options.js"的脚本。

+ +

仍然在"settting"目录下创建 "options.js",并给予他以下内容:

+ +
function saveOptions(e) {
+  e.preventDefault();
+  browser.storage.local.set({
+    color: document.querySelector("#color").value
+  });
+}
+
+function restoreOptions() {
+
+  function setCurrentChoice(result) {
+    document.querySelector("#color").value = result.color || "blue";
+  }
+
+  function onError(error) {
+    console.log(`Error: ${error}`);
+  }
+
+  var getting = browser.storage.local.get("color");
+  getting.then(setCurrentChoice, onError);
+}
+
+document.addEventListener("DOMContentLoaded", restoreOptions);
+document.querySelector("form").addEventListener("submit", saveOptions);
+
+ +

它做了两件事:

+ + + +

最后,更新"borderify.js" 来读取边框颜色:

+ +
+

因为 browser.storage.local.get() 在火狐52版本之前的一个漏洞 ,以下代码没法起作用。为了使它生效,onGot()中的 item.color 必须改为 item[0].color。

+
+ +
 function onError(error) {
+  console.log(`Error: ${error}`);
+}
+
+function onGot(item) {
+  var color = "blue";
+  if (item.color) {
+    color = item.color;
+  }
+  document.body.style.border = "10px solid " + color;
+}
+
+var getting = browser.storage.local.get("color");
+getting.then(onGot, onError);
+
+ +

最后,完整的扩展看起来是这样:

+ +
settings/
+    borderify.js
+    manifest.json
+    options.html
+    options.js
+ +

现在:

+ + + +

在火狐中你可以通过访问"about:addons"点击扩展旁边的"Preferences"按钮访问设置页面。

+ +

{{EmbedYouTube("ECt9cbWh1qs")}}

+ +

进一步了解

+ + diff --git a/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html b/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html new file mode 100644 index 0000000000..01749d5ff3 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html @@ -0,0 +1,42 @@ +--- +title: homepage_url +slug: Mozilla/Add-ons/WebExtensions/manifest.json/主页地址 +translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url +--- +
{{AddonSidebar}}
+ + + + + + + + + + + + + + + + +
值类型字符串(String)
强制性非强制
示例 +
+"homepage_url": "https://example.org/my-addon"
+
+ +

该扩展的主页地址。

+ +

如果 developer 键存在且包含“url”属性,它将会覆盖 homepage_url 键。

+ +

这是一个 localizable property.

+ +

示例

+ +
"homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify"
+ +

浏览器兼容性

+ + + +

{{Compat("webextensions.manifest.homepage_url")}}

diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/\344\270\273\351\241\265\345\234\260\345\235\200/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/\344\270\273\351\241\265\345\234\260\345\235\200/index.html" deleted file mode 100644 index 01749d5ff3..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/\344\270\273\351\241\265\345\234\260\345\235\200/index.html" +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: homepage_url -slug: Mozilla/Add-ons/WebExtensions/manifest.json/主页地址 -translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url ---- -
{{AddonSidebar}}
- - - - - - - - - - - - - - - - -
值类型字符串(String)
强制性非强制
示例 -
-"homepage_url": "https://example.org/my-addon"
-
- -

该扩展的主页地址。

- -

如果 developer 键存在且包含“url”属性,它将会覆盖 homepage_url 键。

- -

这是一个 localizable property.

- -

示例

- -
"homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify"
- -

浏览器兼容性

- - - -

{{Compat("webextensions.manifest.homepage_url")}}

diff --git a/files/zh-cn/mozilla/add-ons/webextensions/packaging_and_installation/index.html b/files/zh-cn/mozilla/add-ons/webextensions/packaging_and_installation/index.html deleted file mode 100644 index 654aaea253..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/packaging_and_installation/index.html +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: 打包和安装 -slug: Mozilla/Add-ons/WebExtensions/Packaging_and_installation -translation_of: Mozilla/Add-ons/WebExtensions/Temporary_Installation_in_Firefox -translation_of_original: Mozilla/Add-ons/WebExtensions/Packaging_and_installation ---- -

打包你的扩展

- -

Firefox 扩展应打包为 XPI 文件。它只是一个 ZIP 文件,但采用 .xpi 作为扩展名。

- -

最重要的一点,ZIP 文件必须是扩展文件的 ZIP 打包,不能包含一层根目录。

- -

Windows

- -
    -
  1. 打开你的扩展文件所在的文件夹。
  2. -
  3. 选择所有文件。
  4. -
  5. 右击并选择 发送到 → 压缩(zipped)文件夹。
  6. -
  7. 将得到的文件从 文件名.zip 重命名为 文件名.xpi
  8. -
- -

Screenshot of the Windows Explorer context menu showing Send to compressed (zipped) folder

- -

Mac OS X

- -
    -
  1. 打开你的扩展文件所在的文件夹。
  2. -
  3. 选择所有文件。
  4. -
  5. 右击并选择 压缩 n 项。
  6. -
  7. 将得到的文件从 Archive.zip 重命名为  文件名.xpi
  8. -
- -

Screenshot of the Finder context menu showing the Compress 15 Items option

- -

Linux / Mac OS X 终端

- -
    -
  1. cd path/to/my-extension/
  2. -
  3. zip -r ../my-extension.xpi *
  4. -
- -

安装你的扩展

- -
    -
  1. 导航到 about:addons
  2. -
  3. 拖拽 XPI 到页面上,或者打开齿轮菜单,选择“从文件安装附加组件...”
  4. -
  5. 点击弹出的对话框中的“安装”
  6. -
- -

在 Firefox OS 上安装你的扩展

- -

你可以使用 WebIDE 提供的 USB 或者 Wifi 进行安装

- -

故障排除

- -

下面是几种你可能会遇到的常见问题:

- -

"此附加组件无法安装,因为它未经验证。"

- - - -

"该附加组件无法安装,因为它似乎已损坏。"

- - - -

完全没反应

- - diff --git a/files/zh-cn/mozilla/add-ons/webextensions/porting_from_google_chrome/index.html b/files/zh-cn/mozilla/add-ons/webextensions/porting_from_google_chrome/index.html deleted file mode 100644 index 496abe0bd3..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/porting_from_google_chrome/index.html +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: 从 Google Chrome 移植 -slug: Mozilla/Add-ons/WebExtensions/Porting_from_Google_Chrome -tags: - - WebExtensions -translation_of: Mozilla/Add-ons/WebExtensions/Porting_a_Google_Chrome_extension ---- -
{{AddonSidebar}}
- -

使用 WebExtension API 开发的扩展是专为跨浏览器兼容而设计的:很大程度上,该技术与 Google Chrome 和 Opera 支持的扩展 API 代码直接兼容。为这些浏览器编写的扩展,在大多数情况下,只需少数修改就能在 Firefox 中运行。几乎所有的扩展 API 都支持使用 chrome 命名空间下的回调函数,跟 Chrome 一样。那些仅有的 chrome 命名空间不支持的 API 是故意不与 Chrome 兼容的。这些情况下,API 文档页将明确声明它仅在 browser 命名空间中受支持。从 Chrome 或者 Opera 移植一个扩展的过程大概这样:

- -
    -
  1. 检查你 manifest.json 使用的功能并了解 WebExtension API 对应的 Chrome 不兼容参考表。如果你在使用的功能或者 API 还未被 Firefox 支持,那你可能还不能移植你的扩展。Mozilla 提供了一个服务可助您自动执行此步:https://www.extensiontest.com/
  2. -
  3. 安装你的扩展至 Firefox 并对其进行测试。
  4. -
  5. 如有任何问题,可通过 dev-addons 邮件列表IRC 上的 #webextensions 联系我们。
  6. -
  7. 提交您的附加组件至 AMO 以供签名及分发
  8. -
- -

如果您依赖 Chrome 命令行选项来加载解压的扩展,请参看 Firefox 中进行临时安装的 web-ext 工具以便开发。

- - diff --git a/files/zh-cn/mozilla/add-ons/webextensions/publishing_your_webextension/index.html b/files/zh-cn/mozilla/add-ons/webextensions/publishing_your_webextension/index.html deleted file mode 100644 index e7792b75d4..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/publishing_your_webextension/index.html +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: 发布你的附加组件 -slug: Mozilla/Add-ons/WebExtensions/Publishing_your_WebExtension -tags: - - WebExtensions -translation_of: Mozilla/Add-ons/WebExtensions/Package_your_extension_ ---- -
{{AddonSidebar}}
- -

一般当你完成了基于WebExtension技术的附加组件的代码编写和测试, 你可能会想与其他人分享这成果(不管出于什么目的...). Mozilla旗下有一个网站: addons.mozilla.org (简称AMO), 开发者们可以在这里发布附加组件, 而其他用户可以在这里找到这些附加组件并安装使用, 通过在AMO上发布你的附加组件, 你可以加入到我们的社区里来, 这里有一群用户和创造者, 说不准会发现几个使用你的附加组件的人哦.

- -

你编写的附加组件并不一定需要发布在AMO上, 但是、即使你不打算在AMO上发布你的附加组件, 你也必须提交你的附加组件到AMO上来进行审核以获得签名。因为火狐浏览器会拒绝安装没有AMO签名的附加组件。

- -

所以发布一个附加组件的流程, 可概述为:

- -
    -
  1. 压缩你所创建的附加组件文件
  2. -
  3. AMO上创建一个属于你的账户
  4. -
  5. 上传你的压缩文件到AMO来进行签名和审核, 并选择是否在AMO上进行发布
  6. -
  7. 修复在审核中发现的任何问题
  8. -
  9. 如果你选择不在AMO上发布, 可以恢复已签名的附件组件, 并自行发布
  10. -
- -

当你准备发布附加组件的新版本时, 你可以访问 addons.mozilla.org 的附加组件页来更新它, 并上传新的版本.
- 需要注意的是: 你必须在这个附加组件页进行更新, 否则AMO没法知道你是要更新一个已经存在的附加组件呢, 还是要上传一个全新的附加组件呢.

- -

如果你选择在AMO上发布你的附加组件, 之后火狐浏览器会自动检查更新. 如果你选择自行发布,  你需要在你的manifest.json中手动设置一个applications 唯一标识, 并且需要手动设置update_url属性指向你的update manifest file.

- -
-
-

火狐浏览器把附加组件包的后缀叫做或改为".xpi", 这只是".zip"的一个扩展.

- -

在上传附加组件到AMO的时候, 你不需要把压缩包的后缀改为".XPI".

-
-
- -

1. 使用zip压缩你的附加组件文件

- -

首先你的附加组件文件夹应该包含一个manifest.json和其他一些需要的文件 - javascript文件, icons文件, HTML文件等等. 你需要使用zip把它们压缩成一个文件以便上传到AMO.

- -

注意: 请将你的附加组件目录的的所有文件压缩为zip包,而 不要直接对附加组件根目录进行压缩(见下图所示).

- -

Windows

- -
    -
  1. 打开你的附加组件所在的文件夹.
  2. -
  3. 选中所有文件.
  4. -
  5. 右键并选择发送到 → 压缩到(zipped)文件夹.
  6. -
- -

- -

Mac OS X

- -
    -
  1. 打开你的附加组件所在的文件夹.
  2. -
  3. 选中所有文件.
  4. -
  5. 右键并选择压缩n项.
  6. -
- -

- -

Linux / Mac OS X Terminal

- -
    -
  1. cd path/to/my-addon/
  2. -
  3. zip -r ../my-addon.zip *
  4. -
- -

2. 在AMO上创建一个账户

- -

访问https://addons.mozilla.org/. 如果你已经有一个火狐账户, 你可以直接使用它来登录. 否则, 点击"注册"并按要求创建一个火狐账户.

- -

3. 上传你的zip压缩文件

- -

接下来, 上传压缩后的附加组件到AMO进行签名和审查, 并选择是否发布到AMO, 更多细节, 可查看Submitting to AMO.

- -
-

需要注意的是一旦你上传了你的附加组件(基于WebExtension技术)到AMO, 你不能使用Add-on SDK或过时的XUL/XPCOM技术来更新该附加组件. 如果你切换到了这些技术平台之一, 必须把它做为新的附加组件并重新提交.

- -

总而言之: 像Add-on SDK和XUL/XPCOM等过时的技术体系在不久的将来都将被淘汰, WebExtensions才是唯一.

- -

在上传你的附加组件之前,请再次检查你的zip包内没有包含其他不相关的文件.

-
- -

4. 修复审查中出现的问题

- -

当你上传了附加组件, AMO服务器将运行一些基本的检查并立即通知你有关的一切问题. 这些问题分为2种类型: "错误"和"警告". 如果你有错误, 你必须修复它们并重新提交, 如果只是警告, 你最好也搞定它们(当可以也忽略警告): 然后可以继续提交.

- -

如果自动检查器没有报告任何错误, 该附件组件将进行更为详细的审核(复查). 你同样会收到审查结果并且需要修复所有问题, 然后重新提交.

- -

5. 发布你的附加组件

- -

如果你选择了在AMO上托管你的附加组件, 这意味着发布过程的结束. AMO会对该附加组件进行签名和发布, 之后其他用户就能下载并安装使用了.

- -

如果你选择不在AMO上进行发布, 可以恢复已签名的附加组件, 并自行发布(比如把附件组件的压缩包直接发给别人).

- -

 

diff --git a/files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html b/files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html new file mode 100644 index 0000000000..8d13bfaf2c --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html @@ -0,0 +1,53 @@ +--- +title: 侧边栏 +slug: Mozilla/Add-ons/WebExtensions/user_interface/侧边栏 +translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Sidebars +--- +
{{AddonSidebar}}
+ +
+

A sidebar is a pane that is displayed at the side of the browser window, next to the web page. The browser provides a UI that enables the user to see the currently available sidebars and to select a sidebar to display. For example, Firefox has a "View > Sidebar" menu. Only one sidebar can be shown at a time, and that sidebar will be displayed for all tabs and all browser windows.

+ +

The browser may include a number of built-in sidebars. For example, Firefox includes a sidebar for interacting with bookmarks:

+ +

Using the sidebar_action manifest.json key, an extension can add its own sidebar to the browser. It will be listed alongside the built-in sidebars, and the user will be able to open it using the same mechanism as for the built-in sidebars.

+ +

就像浏览器的弹出页面,侧边栏也是一个HTML文档。当用户打开侧边栏时,HTML文档载入打开的浏览器窗口。每个窗口有一个该文档的实例。打开一个新窗口时,该窗口获得自己的文档实例

+ +

可以使用函数{{WebExtAPIRef("sidebarAction.setPanel()")}}指定侧边栏仅用于指定的某个标签,使用{{WebExtAPIRef("windows.getCurrent()")}} 侧边栏知道自己属于哪一个标签。

+ +
// sidebar.js
+browser.windows.getCurrent({populate: true}).then((windowInfo) => {
+  myWindowId = windowInfo.id;
+});
+ +

不同的窗口使用不同的侧边栏是非常有用的,这是一个实例 ,见"annotate-page" example.

+ +

侧边栏俱有和后台程序以及弹出窗口相同的API权限,在非隐藏模式下,侧边栏使用API {{WebExtAPIRef("runtime.getBackgroundPage()")}} 可以直接访问后台页面,使用 API 如{{WebExtAPIRef("tabs.sendMessage()")}} 与content scripts交互,使用API 如 {{WebExtAPIRef("runtime.sendNativeMessage()")}} 与原生应用交互。

+ +

关闭窗口或关闭侧边栏时,侧边栏文档退出。这意味着和后台页面不同,侧边栏文档不是一直住留,也不像弹出窗口,只要用户与页面交互 ,它就一直存在。

+ +

使用侧边栏的扩展载入时,侧边栏自动打开。这是为了帮助用户知道扩展俱有侧边栏。注意不能通过编程的方式打开侧边栏:侧边栏只能由用户打开。

+ +

声明侧边栏

+ +

声明侧边栏,只需在manifest.json中指 定关键字  sidebar_action    并同时指定title 和 icon:

+ +
"sidebar_action": {
+  "default_title": "My sidebar",
+  "default_panel": "sidebar.html",
+  "default_icon": "sidebar_icon.png"
+}
+ +

使用API {{WebExtAPIRef("sidebarAction")}} ,你可以用编程的方式修改title panel icon。

+ +

浏览器提供的显示侧边栏的UI中,title和icon显示给用户,如Firefox菜单栏的"View > Sidebar"

+ + + +

For details on how to design your sidebar's web page to match the style of Firefox, see the Photon Design System documentation.

+ +

Example

+ +

The webextensions-examples repository on GitHub includes the annotate-page example which implements a sidebar.

+
diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/user_interface/\344\276\247\350\276\271\346\240\217/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/user_interface/\344\276\247\350\276\271\346\240\217/index.html" deleted file mode 100644 index 8d13bfaf2c..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/user_interface/\344\276\247\350\276\271\346\240\217/index.html" +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: 侧边栏 -slug: Mozilla/Add-ons/WebExtensions/user_interface/侧边栏 -translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Sidebars ---- -
{{AddonSidebar}}
- -
-

A sidebar is a pane that is displayed at the side of the browser window, next to the web page. The browser provides a UI that enables the user to see the currently available sidebars and to select a sidebar to display. For example, Firefox has a "View > Sidebar" menu. Only one sidebar can be shown at a time, and that sidebar will be displayed for all tabs and all browser windows.

- -

The browser may include a number of built-in sidebars. For example, Firefox includes a sidebar for interacting with bookmarks:

- -

Using the sidebar_action manifest.json key, an extension can add its own sidebar to the browser. It will be listed alongside the built-in sidebars, and the user will be able to open it using the same mechanism as for the built-in sidebars.

- -

就像浏览器的弹出页面,侧边栏也是一个HTML文档。当用户打开侧边栏时,HTML文档载入打开的浏览器窗口。每个窗口有一个该文档的实例。打开一个新窗口时,该窗口获得自己的文档实例

- -

可以使用函数{{WebExtAPIRef("sidebarAction.setPanel()")}}指定侧边栏仅用于指定的某个标签,使用{{WebExtAPIRef("windows.getCurrent()")}} 侧边栏知道自己属于哪一个标签。

- -
// sidebar.js
-browser.windows.getCurrent({populate: true}).then((windowInfo) => {
-  myWindowId = windowInfo.id;
-});
- -

不同的窗口使用不同的侧边栏是非常有用的,这是一个实例 ,见"annotate-page" example.

- -

侧边栏俱有和后台程序以及弹出窗口相同的API权限,在非隐藏模式下,侧边栏使用API {{WebExtAPIRef("runtime.getBackgroundPage()")}} 可以直接访问后台页面,使用 API 如{{WebExtAPIRef("tabs.sendMessage()")}} 与content scripts交互,使用API 如 {{WebExtAPIRef("runtime.sendNativeMessage()")}} 与原生应用交互。

- -

关闭窗口或关闭侧边栏时,侧边栏文档退出。这意味着和后台页面不同,侧边栏文档不是一直住留,也不像弹出窗口,只要用户与页面交互 ,它就一直存在。

- -

使用侧边栏的扩展载入时,侧边栏自动打开。这是为了帮助用户知道扩展俱有侧边栏。注意不能通过编程的方式打开侧边栏:侧边栏只能由用户打开。

- -

声明侧边栏

- -

声明侧边栏,只需在manifest.json中指 定关键字  sidebar_action    并同时指定title 和 icon:

- -
"sidebar_action": {
-  "default_title": "My sidebar",
-  "default_panel": "sidebar.html",
-  "default_icon": "sidebar_icon.png"
-}
- -

使用API {{WebExtAPIRef("sidebarAction")}} ,你可以用编程的方式修改title panel icon。

- -

浏览器提供的显示侧边栏的UI中,title和icon显示给用户,如Firefox菜单栏的"View > Sidebar"

- - - -

For details on how to design your sidebar's web page to match the style of Firefox, see the Photon Design System documentation.

- -

Example

- -

The webextensions-examples repository on GitHub includes the annotate-page example which implements a sidebar.

-
diff --git a/files/zh-cn/mozilla/add-ons/webextensions/walkthrough/index.html b/files/zh-cn/mozilla/add-ons/webextensions/walkthrough/index.html deleted file mode 100644 index 962e04d404..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/walkthrough/index.html +++ /dev/null @@ -1,488 +0,0 @@ ---- -title: 你的第二个 WebExtension -slug: Mozilla/Add-ons/WebExtensions/Walkthrough -translation_of: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension ---- -

{{AddonSidebar}}

- -

如果你已经阅读了 你的第一个扩展,那么你现在已经知道如何写一个扩展了。在这篇文章,我们将写一个稍微复杂一点点的扩展来为你展示更多的一些API 。

- -

这个扩展会添加一个新按钮到 Firefox 的工具栏。在用户点击该按钮时,我们会显示一个弹出窗(popup)来让他们选择一种动物。在他们选择之后,我们会将当前网页替换为他所选动物的图片。

- -

要实现这点,我们将:

- - - -

你可以想象这样的扩展的整体结构:

- -

- -

这是一个非常简单的扩展,但也展示了 WebExtensions API 的许多基本概念:

- - - -

你可以在 GitHub 找到该扩展的完整的源代码

- -

写这个扩展,你需要45或更高版本的firefox。

- -

编写扩展

- -

创建一个新目录,并切换到该目录:

- -
    -
  1. -
    mkdir beastify
    -cd beastify
    -
  2. -
- -

manifest.json

- -

现在创建一个名为 "manifest.json" 的文件,并对其添加下列内容:

- -
    -
  1. -
    {
    -
    -  "manifest_version": 2,
    -  "name": "Beastify",
    -  "version": "1.0",
    -
    -  "description": "Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#beastify",
    -  "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify",
    -  "icons": {
    -    "48": "icons/beasts-48.png"
    -  },
    -
    -  "permissions": [
    -    "activeTab"
    -  ],
    -
    -  "browser_action": {
    -    "default_icon": "icons/beasts-32.png",
    -    "default_title": "Beastify",
    -    "default_popup": "popup/choose_beast.html"
    -  },
    -
    -  "web_accessible_resources": [
    -    "beasts/frog.jpg",
    -    "beasts/turtle.jpg",
    -    "beasts/snake.jpg"
    -  ]
    -
    -}
    -
  2. -
- - - -

需要注意,所有路径是相对于 manifest.json 。

- -

图标

- -

插件应该有一个图标。这个图标被用于显示在附加组件管理器中(可以通过"about:addons"来访问)。当前插件中manifest.json指定了我们插件的图标位于"icons/beasts-48.png"。

- -

创建“icons”文件夹,并将图标命名为“beasts-48.png”。你可以使用我们例子中的图标,它是从 Aha-Soft’s Free Retina iconset 截取的,使用需要遵循该网站的许可证

- -

如果你使用自己的图标,它的尺寸应该是48×\times48像素的。同时,对于高分辨率的设备,可以提供96×\times96像素的图片。此时,manifest.json应当这样配置:

- -
    -
  1. -
    "icons": {
    -  "48": "icons/beasts-48.png",
    -  "96": "icons/beasts-96.png"
    -}
    -
  2. -
- - - -

工具栏按钮

- -

工具栏按钮也需要一个图标,并且我们的 manifest.json 承诺我们会为该工具栏在 "icons/beasts-32.png" 提供一个图标。

- -

将一个图标命名为为 "beasts-32.png"并保存到"icons"文件夹。你可以使用例子中的图片,它是取自 IconBeast Lite 图标集并按其许可协议授权使用。

- -

如果你没有弹出窗,用户点击的事件会直接分派到你的插件中。如果你制作了弹出窗,用户点击会直接打开这个弹出窗,而不会被分派给插件。本例中我们需要弹出窗,因此我们现在开始写它。

- -

弹出窗

- -

该弹出窗的函数是让用户选择三种动物的其中一种。

- -

在根目录下创建“popup”文件夹,用于存放弹出窗的代码。弹出窗由以下文件组成:

- - - -
mkdir popup
-cd popup
-touch choose_beast.html choose_beast.css choose_beast.js
- -

choose_beast.html

- -

HTML 文件就像这样:

- -
    -
  1. -
    <!DOCTYPE html>
    -
    -<html>
    -  <head>
    -    <meta charset="utf-8">
    -    <link rel="stylesheet" href="choose_beast.css"/>
    -  </head>
    -
    -<body>
    -  <div id="popup-content">
    -    <div class="button beast">Frog</div>
    -    <div class="button beast">Turtle</div>
    -    <div class="button beast">Snake</div>
    -    <div class="button reset">Reset</div>
    -  </div>
    -  <div id="error-content" class="hidden">
    -    <p>Can't beastify this web page.</p><p>Try a different page.</p>
    -  </div>
    -  <script src="choose_beast.js"></script>
    -</body>
    -
    -</html>
    -
  2. -
- -

我们有一个ID为 "popup-content" 的<div>元素包含了每个动物选择。我们还有另外一个<div> 元素,它的ID为 "error-content" ,class为"hidden"。我们将会使用它以防初始化弹窗的时候出问题。

- -

注意我们引入了CSS和JS文件,就像网页一样。

- -

choose_beast.css

- -

CSS 固定了弹出窗的大小,确保3个选择填充满空间,并给了他们基本点样式。同时隐藏了class="hidden"的元素,这意味着我们的"error-content" <div> 将会被默认隐藏:

- -
    -
  1. -
    html, body {
    -  width: 100px;
    -}
    -
    -.hidden {
    -  display: none;
    -}
    -
    -.button {
    -  margin: 3% auto;
    -  padding: 4px;
    -  text-align: center;
    -  font-size: 1.5em;
    -  cursor: pointer;
    -}
    -
    -.beast:hover {
    -  background-color: #CFF2F2;
    -}
    -
    -.beast {
    -  background-color: #E5F2F2;
    -}
    -
    -.reset {
    -  background-color: #FBFBC9;
    -}
    -
    -.reset:hover {
    -  background-color: #EAEA9D;
    -}
    -
  2. -
- -

choose_beast.js

- -

我们在弹出窗的脚本中监听点击事件。 如果用户选择其中一个动物,我们在当前标签页中插入一段内容脚本。一旦内容脚本加载,我们发送一条有关动物选择的信息:

- -
    -
  1. -
    /**
    - * CSS to hide everything on the page,
    - * except for elements that have the "beastify-image" class.
    - */
    -const hidePage = `body > :not(.beastify-image) {
    -                    display: none;
    -                  }`;
    -
    -/**
    - * Listen for clicks on the buttons, and send the appropriate message to
    - * the content script in the page.
    - */
    -function listenForClicks() {
    -  document.addEventListener("click", (e) => {
    -
    -    /**
    -     * Given the name of a beast, get the URL to the corresponding image.
    -     */
    -    function beastNameToURL(beastName) {
    -      switch (beastName) {
    -        case "Frog":
    -          return browser.extension.getURL("beasts/frog.jpg");
    -        case "Snake":
    -          return browser.extension.getURL("beasts/snake.jpg");
    -        case "Turtle":
    -          return browser.extension.getURL("beasts/turtle.jpg");
    -      }
    -    }
    -
    -    /**
    -     * Insert the page-hiding CSS into the active tab,
    -     * then get the beast URL and
    -     * send a "beastify" message to the content script in the active tab.
    -     */
    -    function beastify(tabs) {
    -      browser.tabs.insertCSS({code: hidePage}).then(() => {
    -        let url = beastNameToURL(e.target.textContent);
    -        browser.tabs.sendMessage(tabs[0].id, {
    -          command: "beastify",
    -          beastURL: url
    -        });
    -      });
    -    }
    -
    -    /**
    -     * Remove the page-hiding CSS from the active tab,
    -     * send a "reset" message to the content script in the active tab.
    -     */
    -    function reset(tabs) {
    -      browser.tabs.removeCSS({code: hidePage}).then(() => {
    -        browser.tabs.sendMessage(tabs[0].id, {
    -          command: "reset",
    -        });
    -      });
    -    }
    -
    -    /**
    -     * Just log the error to the console.
    -     */
    -    function reportError(error) {
    -      console.error(`Could not beastify: ${error}`);
    -    }
    -
    -    /**
    -     * Get the active tab,
    -     * then call "beastify()" or "reset()" as appropriate.
    -     */
    -    if (e.target.classList.contains("beast")) {
    -      browser.tabs.query({active: true, currentWindow: true})
    -        .then(beastify)
    -        .catch(reportError);
    -    }
    -    else if (e.target.classList.contains("reset")) {
    -      browser.tabs.query({active: true, currentWindow: true})
    -        .then(reset)
    -        .catch(reportError);
    -    }
    -  });
    -}
    -
    -/**
    - * There was an error executing the script.
    - * Display the popup's error message, and hide the normal UI.
    - */
    -function reportExecuteScriptError(error) {
    -  document.querySelector("#popup-content").classList.add("hidden");
    -  document.querySelector("#error-content").classList.remove("hidden");
    -  console.error(`Failed to execute beastify content script: ${error.message}`);
    -}
    -
    -/**
    - * When the popup loads, inject a content script into the active tab,
    - * and add a click handler.
    - * If we couldn't inject the script, handle the error.
    - */
    -browser.tabs.executeScript({file: "/content_scripts/beastify.js"})
    -.then(listenForClicks)
    -.catch(reportExecuteScriptError);
    -
  2. -
- -

从96行开始。只要弹出窗加载完,popup scrpit 就会使用 browser.tabs.executeScript() API在活跃标签页执行 content script。如果执行 content scrpit成功,content script会在页面中一直保持,直到标签被关闭或者用户导航到其他页面。

- -

browser.tabs.executeScript()调用失败的常见原因是你不能在所有页面执行content scripts。例如,你不能在特权浏览器页面执行,像about:debugging,你也不能在addons.mozilla.org域执行。如果调用失败,reportExecuteScriptError()会隐藏"popup-content" <div>,并展示"error-content" <div>, 然后打印一个错误到控制台

- -

如果成功执行 content script ,我们会调用 listenForClicks()。这个监听了弹窗上的点击事件。

- - - -

beastify() 函数做了三件事:

- - - -

reset() 函数实际上就是撤销 beastify :

- - - -

The content script

- -

在扩展的根目录下创建一个新的文件夹,叫做"content_scripts",然后在里面新建一个新的名为 "beastify.js" 的文件,内容如下:

- -
    -
  1. -
    (function() {
    -  /**
    -   * Check and set a global guard variable.
    -   * If this content script is injected into the same page again,
    -   * it will do nothing next time.
    -   */
    -  if (window.hasRun) {
    -    return;
    -  }
    -  window.hasRun = true;
    -
    -  /**
    -   * Given a URL to a beast image, remove all existing beasts, then
    -   * create and style an IMG node pointing to
    -   * that image, then insert the node into the document.
    -   */
    -  function insertBeast(beastURL) {
    -    removeExistingBeasts();
    -    let beastImage = document.createElement("img");
    -    beastImage.setAttribute("src", beastURL);
    -    beastImage.style.height = "100vh";
    -    beastImage.className = "beastify-image";
    -    document.body.appendChild(beastImage);
    -  }
    -
    -  /**
    -   * Remove every beast from the page.
    -   */
    -  function removeExistingBeasts() {
    -    let existingBeasts = document.querySelectorAll(".beastify-image");
    -    for (let beast of existingBeasts) {
    -      beast.remove();
    -    }
    -  }
    -
    -  /**
    -   * Listen for messages from the background script.
    -   * Call "beastify()" or "reset()".
    -  */
    -  browser.runtime.onMessage.addListener((message) => {
    -    if (message.command === "beastify") {
    -      insertBeast(message.beastURL);
    -    } else if (message.command === "reset") {
    -      removeExistingBeasts();
    -    }
    -  });
    -
    -})();
    -
  2. -
- -

content script做的第一件事是检查全局变量 window.hasRun:如果它被设置了,脚本直接返回,否则设置window.hasRun并继续。原因是每次用户打开弹出窗,弹出窗就会在活跃页面执行一个content script ,所以我们可能会在单个页面运行多个脚本实例。如果是这样的话,我们需要保证只有一个实例在做所有事情。

- -

然后,从第40行开始,content script 监听来自弹出窗的信息,使用browser.runtime.onMessage API。在上面我们看到弹出窗脚本能够发送两种不同的信息:"beastify" and "reset"。

- - - -

动物们

- -

最后,我们要加入包含动物们的图像。

- -

创建"beasts"文件夹,之后将图片放入并命名。你可以从 the GitHub repository,或这里下载图片:

- -

- -

测试

- -

请仔细确认项目目录如下所示:

- -
    -
  1. -
    beastify/
    -
    -    beasts/
    -        frog.jpg
    -        snake.jpg
    -        turtle.jpg
    -
    -    content_scripts/
    -        beastify.js
    -
    -    icons/
    -        beasts-32.png
    -        beasts-48.png
    -
    -    popup/
    -        choose_beast.css
    -        choose_beast.html
    -        choose_beast.js
    -
    -    manifest.json
    -
  2. -
- -

Firefox 45开始,你可以临时从硬盘中安装扩展

- -

在Firefox地址栏中输入:about:debugging,单击“临时载入附加组件”,然后选择你的manifest.json文件。

- -

然后你应该已经看到扩展图标出现在了Firefox的工具条上:

- -

{{EmbedYouTube("sAM78GU4P34")}}

- -

打开一个网页,然后点击图标,选择一个动物,然后观察网页的变化

- -

{{EmbedYouTube("YMQXyAQSiE8")}}

- -

用命令行开发

- -

你可以通过使用 web-ext 工具来将临时安装的工作自动化,试试这个:

- -
    -
  1. -
    cd beastify
    -web-ext run
    -
  2. -
diff --git a/files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html b/files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html new file mode 100644 index 0000000000..962e04d404 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html @@ -0,0 +1,488 @@ +--- +title: 你的第二个 WebExtension +slug: Mozilla/Add-ons/WebExtensions/Walkthrough +translation_of: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension +--- +

{{AddonSidebar}}

+ +

如果你已经阅读了 你的第一个扩展,那么你现在已经知道如何写一个扩展了。在这篇文章,我们将写一个稍微复杂一点点的扩展来为你展示更多的一些API 。

+ +

这个扩展会添加一个新按钮到 Firefox 的工具栏。在用户点击该按钮时,我们会显示一个弹出窗(popup)来让他们选择一种动物。在他们选择之后,我们会将当前网页替换为他所选动物的图片。

+ +

要实现这点,我们将:

+ + + +

你可以想象这样的扩展的整体结构:

+ +

+ +

这是一个非常简单的扩展,但也展示了 WebExtensions API 的许多基本概念:

+ + + +

你可以在 GitHub 找到该扩展的完整的源代码

+ +

写这个扩展,你需要45或更高版本的firefox。

+ +

编写扩展

+ +

创建一个新目录,并切换到该目录:

+ +
    +
  1. +
    mkdir beastify
    +cd beastify
    +
  2. +
+ +

manifest.json

+ +

现在创建一个名为 "manifest.json" 的文件,并对其添加下列内容:

+ +
    +
  1. +
    {
    +
    +  "manifest_version": 2,
    +  "name": "Beastify",
    +  "version": "1.0",
    +
    +  "description": "Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#beastify",
    +  "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify",
    +  "icons": {
    +    "48": "icons/beasts-48.png"
    +  },
    +
    +  "permissions": [
    +    "activeTab"
    +  ],
    +
    +  "browser_action": {
    +    "default_icon": "icons/beasts-32.png",
    +    "default_title": "Beastify",
    +    "default_popup": "popup/choose_beast.html"
    +  },
    +
    +  "web_accessible_resources": [
    +    "beasts/frog.jpg",
    +    "beasts/turtle.jpg",
    +    "beasts/snake.jpg"
    +  ]
    +
    +}
    +
  2. +
+ + + +

需要注意,所有路径是相对于 manifest.json 。

+ +

图标

+ +

插件应该有一个图标。这个图标被用于显示在附加组件管理器中(可以通过"about:addons"来访问)。当前插件中manifest.json指定了我们插件的图标位于"icons/beasts-48.png"。

+ +

创建“icons”文件夹,并将图标命名为“beasts-48.png”。你可以使用我们例子中的图标,它是从 Aha-Soft’s Free Retina iconset 截取的,使用需要遵循该网站的许可证

+ +

如果你使用自己的图标,它的尺寸应该是48×\times48像素的。同时,对于高分辨率的设备,可以提供96×\times96像素的图片。此时,manifest.json应当这样配置:

+ +
    +
  1. +
    "icons": {
    +  "48": "icons/beasts-48.png",
    +  "96": "icons/beasts-96.png"
    +}
    +
  2. +
+ + + +

工具栏按钮

+ +

工具栏按钮也需要一个图标,并且我们的 manifest.json 承诺我们会为该工具栏在 "icons/beasts-32.png" 提供一个图标。

+ +

将一个图标命名为为 "beasts-32.png"并保存到"icons"文件夹。你可以使用例子中的图片,它是取自 IconBeast Lite 图标集并按其许可协议授权使用。

+ +

如果你没有弹出窗,用户点击的事件会直接分派到你的插件中。如果你制作了弹出窗,用户点击会直接打开这个弹出窗,而不会被分派给插件。本例中我们需要弹出窗,因此我们现在开始写它。

+ +

弹出窗

+ +

该弹出窗的函数是让用户选择三种动物的其中一种。

+ +

在根目录下创建“popup”文件夹,用于存放弹出窗的代码。弹出窗由以下文件组成:

+ + + +
mkdir popup
+cd popup
+touch choose_beast.html choose_beast.css choose_beast.js
+ +

choose_beast.html

+ +

HTML 文件就像这样:

+ +
    +
  1. +
    <!DOCTYPE html>
    +
    +<html>
    +  <head>
    +    <meta charset="utf-8">
    +    <link rel="stylesheet" href="choose_beast.css"/>
    +  </head>
    +
    +<body>
    +  <div id="popup-content">
    +    <div class="button beast">Frog</div>
    +    <div class="button beast">Turtle</div>
    +    <div class="button beast">Snake</div>
    +    <div class="button reset">Reset</div>
    +  </div>
    +  <div id="error-content" class="hidden">
    +    <p>Can't beastify this web page.</p><p>Try a different page.</p>
    +  </div>
    +  <script src="choose_beast.js"></script>
    +</body>
    +
    +</html>
    +
  2. +
+ +

我们有一个ID为 "popup-content" 的<div>元素包含了每个动物选择。我们还有另外一个<div> 元素,它的ID为 "error-content" ,class为"hidden"。我们将会使用它以防初始化弹窗的时候出问题。

+ +

注意我们引入了CSS和JS文件,就像网页一样。

+ +

choose_beast.css

+ +

CSS 固定了弹出窗的大小,确保3个选择填充满空间,并给了他们基本点样式。同时隐藏了class="hidden"的元素,这意味着我们的"error-content" <div> 将会被默认隐藏:

+ +
    +
  1. +
    html, body {
    +  width: 100px;
    +}
    +
    +.hidden {
    +  display: none;
    +}
    +
    +.button {
    +  margin: 3% auto;
    +  padding: 4px;
    +  text-align: center;
    +  font-size: 1.5em;
    +  cursor: pointer;
    +}
    +
    +.beast:hover {
    +  background-color: #CFF2F2;
    +}
    +
    +.beast {
    +  background-color: #E5F2F2;
    +}
    +
    +.reset {
    +  background-color: #FBFBC9;
    +}
    +
    +.reset:hover {
    +  background-color: #EAEA9D;
    +}
    +
  2. +
+ +

choose_beast.js

+ +

我们在弹出窗的脚本中监听点击事件。 如果用户选择其中一个动物,我们在当前标签页中插入一段内容脚本。一旦内容脚本加载,我们发送一条有关动物选择的信息:

+ +
    +
  1. +
    /**
    + * CSS to hide everything on the page,
    + * except for elements that have the "beastify-image" class.
    + */
    +const hidePage = `body > :not(.beastify-image) {
    +                    display: none;
    +                  }`;
    +
    +/**
    + * Listen for clicks on the buttons, and send the appropriate message to
    + * the content script in the page.
    + */
    +function listenForClicks() {
    +  document.addEventListener("click", (e) => {
    +
    +    /**
    +     * Given the name of a beast, get the URL to the corresponding image.
    +     */
    +    function beastNameToURL(beastName) {
    +      switch (beastName) {
    +        case "Frog":
    +          return browser.extension.getURL("beasts/frog.jpg");
    +        case "Snake":
    +          return browser.extension.getURL("beasts/snake.jpg");
    +        case "Turtle":
    +          return browser.extension.getURL("beasts/turtle.jpg");
    +      }
    +    }
    +
    +    /**
    +     * Insert the page-hiding CSS into the active tab,
    +     * then get the beast URL and
    +     * send a "beastify" message to the content script in the active tab.
    +     */
    +    function beastify(tabs) {
    +      browser.tabs.insertCSS({code: hidePage}).then(() => {
    +        let url = beastNameToURL(e.target.textContent);
    +        browser.tabs.sendMessage(tabs[0].id, {
    +          command: "beastify",
    +          beastURL: url
    +        });
    +      });
    +    }
    +
    +    /**
    +     * Remove the page-hiding CSS from the active tab,
    +     * send a "reset" message to the content script in the active tab.
    +     */
    +    function reset(tabs) {
    +      browser.tabs.removeCSS({code: hidePage}).then(() => {
    +        browser.tabs.sendMessage(tabs[0].id, {
    +          command: "reset",
    +        });
    +      });
    +    }
    +
    +    /**
    +     * Just log the error to the console.
    +     */
    +    function reportError(error) {
    +      console.error(`Could not beastify: ${error}`);
    +    }
    +
    +    /**
    +     * Get the active tab,
    +     * then call "beastify()" or "reset()" as appropriate.
    +     */
    +    if (e.target.classList.contains("beast")) {
    +      browser.tabs.query({active: true, currentWindow: true})
    +        .then(beastify)
    +        .catch(reportError);
    +    }
    +    else if (e.target.classList.contains("reset")) {
    +      browser.tabs.query({active: true, currentWindow: true})
    +        .then(reset)
    +        .catch(reportError);
    +    }
    +  });
    +}
    +
    +/**
    + * There was an error executing the script.
    + * Display the popup's error message, and hide the normal UI.
    + */
    +function reportExecuteScriptError(error) {
    +  document.querySelector("#popup-content").classList.add("hidden");
    +  document.querySelector("#error-content").classList.remove("hidden");
    +  console.error(`Failed to execute beastify content script: ${error.message}`);
    +}
    +
    +/**
    + * When the popup loads, inject a content script into the active tab,
    + * and add a click handler.
    + * If we couldn't inject the script, handle the error.
    + */
    +browser.tabs.executeScript({file: "/content_scripts/beastify.js"})
    +.then(listenForClicks)
    +.catch(reportExecuteScriptError);
    +
  2. +
+ +

从96行开始。只要弹出窗加载完,popup scrpit 就会使用 browser.tabs.executeScript() API在活跃标签页执行 content script。如果执行 content scrpit成功,content script会在页面中一直保持,直到标签被关闭或者用户导航到其他页面。

+ +

browser.tabs.executeScript()调用失败的常见原因是你不能在所有页面执行content scripts。例如,你不能在特权浏览器页面执行,像about:debugging,你也不能在addons.mozilla.org域执行。如果调用失败,reportExecuteScriptError()会隐藏"popup-content" <div>,并展示"error-content" <div>, 然后打印一个错误到控制台

+ +

如果成功执行 content script ,我们会调用 listenForClicks()。这个监听了弹窗上的点击事件。

+ + + +

beastify() 函数做了三件事:

+ + + +

reset() 函数实际上就是撤销 beastify :

+ + + +

The content script

+ +

在扩展的根目录下创建一个新的文件夹,叫做"content_scripts",然后在里面新建一个新的名为 "beastify.js" 的文件,内容如下:

+ +
    +
  1. +
    (function() {
    +  /**
    +   * Check and set a global guard variable.
    +   * If this content script is injected into the same page again,
    +   * it will do nothing next time.
    +   */
    +  if (window.hasRun) {
    +    return;
    +  }
    +  window.hasRun = true;
    +
    +  /**
    +   * Given a URL to a beast image, remove all existing beasts, then
    +   * create and style an IMG node pointing to
    +   * that image, then insert the node into the document.
    +   */
    +  function insertBeast(beastURL) {
    +    removeExistingBeasts();
    +    let beastImage = document.createElement("img");
    +    beastImage.setAttribute("src", beastURL);
    +    beastImage.style.height = "100vh";
    +    beastImage.className = "beastify-image";
    +    document.body.appendChild(beastImage);
    +  }
    +
    +  /**
    +   * Remove every beast from the page.
    +   */
    +  function removeExistingBeasts() {
    +    let existingBeasts = document.querySelectorAll(".beastify-image");
    +    for (let beast of existingBeasts) {
    +      beast.remove();
    +    }
    +  }
    +
    +  /**
    +   * Listen for messages from the background script.
    +   * Call "beastify()" or "reset()".
    +  */
    +  browser.runtime.onMessage.addListener((message) => {
    +    if (message.command === "beastify") {
    +      insertBeast(message.beastURL);
    +    } else if (message.command === "reset") {
    +      removeExistingBeasts();
    +    }
    +  });
    +
    +})();
    +
  2. +
+ +

content script做的第一件事是检查全局变量 window.hasRun:如果它被设置了,脚本直接返回,否则设置window.hasRun并继续。原因是每次用户打开弹出窗,弹出窗就会在活跃页面执行一个content script ,所以我们可能会在单个页面运行多个脚本实例。如果是这样的话,我们需要保证只有一个实例在做所有事情。

+ +

然后,从第40行开始,content script 监听来自弹出窗的信息,使用browser.runtime.onMessage API。在上面我们看到弹出窗脚本能够发送两种不同的信息:"beastify" and "reset"。

+ + + +

动物们

+ +

最后,我们要加入包含动物们的图像。

+ +

创建"beasts"文件夹,之后将图片放入并命名。你可以从 the GitHub repository,或这里下载图片:

+ +

+ +

测试

+ +

请仔细确认项目目录如下所示:

+ +
    +
  1. +
    beastify/
    +
    +    beasts/
    +        frog.jpg
    +        snake.jpg
    +        turtle.jpg
    +
    +    content_scripts/
    +        beastify.js
    +
    +    icons/
    +        beasts-32.png
    +        beasts-48.png
    +
    +    popup/
    +        choose_beast.css
    +        choose_beast.html
    +        choose_beast.js
    +
    +    manifest.json
    +
  2. +
+ +

Firefox 45开始,你可以临时从硬盘中安装扩展

+ +

在Firefox地址栏中输入:about:debugging,单击“临时载入附加组件”,然后选择你的manifest.json文件。

+ +

然后你应该已经看到扩展图标出现在了Firefox的工具条上:

+ +

{{EmbedYouTube("sAM78GU4P34")}}

+ +

打开一个网页,然后点击图标,选择一个动物,然后观察网页的变化

+ +

{{EmbedYouTube("YMQXyAQSiE8")}}

+ +

用命令行开发

+ +

你可以通过使用 web-ext 工具来将临时安装的工作自动化,试试这个:

+ +
    +
  1. +
    cd beastify
    +web-ext run
    +
  2. +
diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/\345\256\236\347\216\260\344\270\200\344\270\252\350\256\276\347\275\256\351\241\265\351\235\242/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/\345\256\236\347\216\260\344\270\200\344\270\252\350\256\276\347\275\256\351\241\265\351\235\242/index.html" deleted file mode 100644 index fe8ac2e0a7..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/\345\256\236\347\216\260\344\270\200\344\270\252\350\256\276\347\275\256\351\241\265\351\235\242/index.html" +++ /dev/null @@ -1,203 +0,0 @@ ---- -title: 实现一个设置页面 -slug: Mozilla/Add-ons/WebExtensions/实现一个设置页面 -translation_of: Mozilla/Add-ons/WebExtensions/Implement_a_settings_page ---- -
{{AddonSidebar}}
- -

设置页面可以让用户查看,修改扩展的一些设置。

- -

对于WebExtensions,设置通常使用 storage API 保存. 实现一个设置页面通常包含以下三步:

- - - -
-

你也可以使用 runtime.openOptionsPage() 打开该页面。

-
- -

简单的 WebExtension

- -

首先,我们写一个向用户访问的所有页面添加一个蓝色边框的扩展。

- -

创建一个新的文件夹命名为“setting”,然后创建文件“manifest.json”它包含以下内容:

- -
{
-
-  "manifest_version": 2,
-  "name": "Settings example",
-  "version": "1.0",
-
-  "content_scripts": [
-    {
-      "matches": ["<all_urls>"],
-      "js": ["borderify.js"]
-    }
-  ]
-
-}
- -

该扩展指示浏览器在用户访问的网站上加载一个名为"borderify.js“的Content Script。

- -

接下来,在"setting"目录下创建"borderify.js",然后给予他以下内容:

- -
document.body.style.border = "10px solid blue";
- -

这只是向网页加入了一一个蓝色边框

- -

现在 安装该扩展 并测试它——打开任意一个网页:

- -

{{EmbedYouTube("E-WUhihF8fw")}}

- -

添加设置页面

- -

现在让我们创建一个设置页面来允许用户设置边框的颜色。

- -

首先更新 "manifest.json" 使他拥有如下内容:

- -
{
-
-  "manifest_version": 2,
-  "name": "Settings example",
-  "version": "1.0",
-
-  "content_scripts": [
-    {
-      "matches": ["<all_urls>"],
-      "js": ["borderify.js"]
-    }
-  ],
-
-  "options_ui": {
-    "page": "options.html"
-  },
-
-  "permissions": ["storage"]
-
-}
-
- -

我们加入了两个manifest 关键字:

- - - -

接下来,因为我们承诺提供"options.html",让我们来创建他,在"setting"目录创建一个该文件并具有以下内容:

- -
<!DOCTYPE html>
-
-<html>
-  <head>
-    <meta charset="utf-8">
-  </head>
-
-  <body>
-
-    <form>
-        <label>Border color<input type="text" id="color" ></label>
-        <button type="submit">Save</button>
-    </form>
-
-    <script src="options.js"></script>
-
-  </body>
-
-</html>
-
- -

这里定义了一个带有标记文字{{htmlelement("input")}}的 {{htmlelement("form")}} 和一个 提交 {{htmlelement("button")}}. 也包含了一个名为"options.js"的脚本。

- -

仍然在"settting"目录下创建 "options.js",并给予他以下内容:

- -
function saveOptions(e) {
-  e.preventDefault();
-  browser.storage.local.set({
-    color: document.querySelector("#color").value
-  });
-}
-
-function restoreOptions() {
-
-  function setCurrentChoice(result) {
-    document.querySelector("#color").value = result.color || "blue";
-  }
-
-  function onError(error) {
-    console.log(`Error: ${error}`);
-  }
-
-  var getting = browser.storage.local.get("color");
-  getting.then(setCurrentChoice, onError);
-}
-
-document.addEventListener("DOMContentLoaded", restoreOptions);
-document.querySelector("form").addEventListener("submit", saveOptions);
-
- -

它做了两件事:

- - - -

最后,更新"borderify.js" 来读取边框颜色:

- -
-

因为 browser.storage.local.get() 在火狐52版本之前的一个漏洞 ,以下代码没法起作用。为了使它生效,onGot()中的 item.color 必须改为 item[0].color。

-
- -
 function onError(error) {
-  console.log(`Error: ${error}`);
-}
-
-function onGot(item) {
-  var color = "blue";
-  if (item.color) {
-    color = item.color;
-  }
-  document.body.style.border = "10px solid " + color;
-}
-
-var getting = browser.storage.local.get("color");
-getting.then(onGot, onError);
-
- -

最后,完整的扩展看起来是这样:

- -
settings/
-    borderify.js
-    manifest.json
-    options.html
-    options.js
- -

现在:

- - - -

在火狐中你可以通过访问"about:addons"点击扩展旁边的"Preferences"按钮访问设置页面。

- -

{{EmbedYouTube("ECt9cbWh1qs")}}

- -

进一步了解

- - diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/\346\236\204\345\273\272\344\270\200\344\270\252\350\267\250\346\265\217\350\247\210\345\231\250\347\232\204\346\211\251\345\261\225\346\217\222\344\273\266/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/\346\236\204\345\273\272\344\270\200\344\270\252\350\267\250\346\265\217\350\247\210\345\231\250\347\232\204\346\211\251\345\261\225\346\217\222\344\273\266/index.html" deleted file mode 100644 index 6d1a21497c..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/\346\236\204\345\273\272\344\270\200\344\270\252\350\267\250\346\265\217\350\247\210\345\231\250\347\232\204\346\211\251\345\261\225\346\217\222\344\273\266/index.html" +++ /dev/null @@ -1,275 +0,0 @@ ---- -title: 构建一个跨浏览器的扩展程序 -slug: Mozilla/Add-ons/WebExtensions/构建一个跨浏览器的扩展插件 -tags: - - Web插件 - - 扩展 - - 指南 - - 插件 -translation_of: Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension ---- -

{{AddonSidebar()}}

- -

浏览器扩展 API 的引入为浏览器扩展的开发创造了 “一次开发跨浏览器” 的前景。然而,在使用扩展 API 的浏览器中(主要是 Chrome、 Firefox、 Opera 和 Edge) ,API 的实现和覆盖范围都存在差异。除此之外,Safari 使用了它自己的 Safari 扩展脚本系统。

- -

最大化兼容浏览器扩展意味着至少在两个不同的浏览器上兼容同一个扩展。本文探讨了在创建跨浏览器扩展时所面临的六个主要挑战,并在每种情况下提出了如何应对这些挑战。

- -

本文不讨论为 Safari 构建浏览器扩展。您可以通过 Safari 扩展共享一些资源,比如图片和 HTML 内容。然而,如果您要进行 JavaScript 部分的编程则需要作为一个单独的开发项目进行,除非您希望创建自己的 polyfill。

- -

跨平台扩展的开发障碍

- -

在开发跨平台扩展时,需要注意以下六个方面:

- - - -

API 命名空间

- -

在四大主流浏览器中,有两个 API 命名空间正在使用:

- - - -

Firefox 也支持 Chrome 浏览器的 chrome.* 名称空间,主要用于协助扩展移植。然而,首选应该使用浏览器 browser.* 命名空间。除了被提议的标准外, browser.* 使用 promises ーー一种现代化且简单的处理异步事件机制。

- -

只有在非常小的扩展中,命名空间才可能是唯一的跨平台问题。因此,如果你遇到了且试图专门解决这个问题的话,可能很少会有帮助。最好的方法是通过异步事件处理来解决这个问题。

- -

API 异步事件处理

- -

在四个主要浏览器中,有两种方法可以处理异步事件:

- - - -

Firefox 还支持 chrome.* 命名空间中的 callbacks 风格的 API,这主要是为了便于从 Chrome 迁移。然而,应该首选使用 promises(以及 browser.* 命名空间),它已被采纳为拟议标准的一部分。它极大地简化了异步事件处理,特别是在需要将事件链接在一起的情况下。

- -
-

如果你对这两种方法之间的差异不熟悉,可以看一下 了解异步 JavaScript: Callbacks、 Promises 和 Async/Await 或者 MDN 的 Using promises 页面。

-
- -

浏览器扩展 API 的垫片(Polyfill)

- -

那么,当 Firefox 是唯一支持它的浏览器时,你如何轻松地使用 promises 呢?解决方案是使用 promises 为 Firefox 编程,并使用浏览器扩展 API 的垫片(Polyfill)
-
- 这个 polyfill 解决了跨 Firefox、 Chrome 和 Opera 的 API 名称空间和异步事件处理。在撰写本报告时(2018年11月) ,Edge 的支持正在开发中。
-
- 要使用 polyfill,可以使用 npm 安装到开发环境中,或者直接从 GitHub Relase 页面下载。

- -

然后,引入 browser-polyfill.js 到:

- - - -

例如,这个 manifest.json 代码让你的后台脚本可以使用 polyfill:

- -
{
- // ...
- "background": {
-   "scripts": [
-     "browser-polyfill.js",
-     "background.js"
-   ]
- }
-}
- -

您的目标是确保在任何其他扩展脚本执行 browser.* API 前执行 polyfill。

- -
-

关于如何使用模块打包器使用 polyfill 的更多细节和信息,请参阅 GitHub 上的项目自述文件

-
- -

还有其他的 polyfill 选项,但是在撰写本文时,没有一个提供浏览器扩展 API polyfill 的覆盖范围。所以,如果你没有把 Firefox 作为你的首选,你的选择就是接受 polyfills 的限制,移植到 Firefox 并添加跨浏览器的支持,或者开发你自己的 polyfill。

- -

API 函数覆盖率

- -

这四个主要浏览器提供的 API 函数的实现差异可分为三大类:

- - - -

你可以在 Mozilla Developer Network 浏览器对 JavaScript API 页面的支持上找到4个主要浏览器对扩展 API 的支持细节,以及 Firefox for Android 对扩展 API 的支持细节。浏览器兼容性信息也包含在每个函数及其方法、类型和事件的 Mozilla Developer Network JavaScript APIs 参考页面中。

- -

处理 API 差异

- -

解决这些差异的一个简单方法是将扩展中使用的函数限制在没有 API 差异的函数范围内。在实践中,对于大多数扩展,这种方法可能限制性太强。
-
- 相反,如果 API 之间存在差异,则应该提供替代实现或降级功能。(请记住: 您可能还需要这样考虑同一浏览器的不同版本之间的 API 支持差异。)

- -

使用运行时检查函数特性的可用性是实现备选或降级功能的推荐方法。执行运行时检查的好处是,如果函数是可用的,您不需要更新和重新分发扩展来使用它。

- -

下面的代码使您能够执行运行时检查:

- -
if (typeof <function> === "function") {
-   // safe to use the function
-}
- -

Manifest 字段

- -

4个主要浏览器支持的 manifest.json 文件字段的差异大致可分为三类:

- - - -

浏览器兼容性信息包含在 Mozilla Developer Network manifest.json 页的每个字段中。

- -

manifest.json 文件在不同浏览器之间的版本号可能有所不同,为每个浏览器创建和编辑一个静态版本号通常是最简单的方法。

- -

扩展打包

- -

通过浏览器扩展商店打包和分发扩展相对简单。

- - - -

有关打包的详细信息,请参阅相应扩展的开发人员门户网站上的指南。

- -

扩展发布

- -

这四种主要浏览器都维护有浏览器扩展商店。每个商店还对扩展进行审核,以检查安全漏洞。

- -

因此,您需要为每个商店分别添加和更新扩展。在某些情况下,您可以使用脚本上传扩展。

- -

下表总结了每个商店的做法和特点:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

注册费

-
-

上传模块

-
-

发布审核

-
-

开发者账号需要2FA验证

-
-

Firefox

-
-

-
-

web-ext

-
-

全自动,仅需要几秒钟1

-
-

-
-

Chrome

-
-

-
-

-
-

全自动,短于一小时

-
-

-
-

Opera

-
-

-
-

-
-

人工审核,但不需要提供SLA

-
-

-
-

Edge

-
-

-
-

-
-

人工审核,需要72小时2

-
-

-
- -

1 在发布后会延期进行一次人工审查,如果发现了需要解决的问题,可能导致扩展被暂停。

- -

2 在撰写本文时,微软只允许发布预先批准的扩展。

- -

其他考虑

- -

扩展命名

- -

Microsoft 要求扩展具有唯一的名称,并通过 Windows Dev Center 为扩展声明一个或多个名称。因此,即使您不打算立即支持 Edge,为微软保留一个扩展名可能是最谨慎的做法。

- -

版本号指定

- -

Firefox 和 Chrome 商店要求每个上传的扩展发布包都有一个单独的版本号。这意味着如果在线上遇到问题,就不能恢复到之前的版本号。

- -

在不同的实现中共享资源

- -

即使你要支持的平台中包括 Safari,仍然可以在对于不同浏览器的实现中共享许多资源。其中包括:

- - - -

总结

- -

在进行跨平台扩展开发时,可以通过对标 Firefox 和使用 WebExtension API Polyfill 来解决扩展 API 之间的根本差异。遵循这种方法,您将在使用与提议的 WebExtension API 标准紧密结合的 API 特性中受益,并使用 promises 来简单的处理异步事件。

- -

跨平台工作的主要重点可能是处理主要浏览器支持的 API 特性之间的差异。创建你的 manifest.json 文件应该是相对简单的,你可以手动完成。然后,您将需要考虑扩展包中的打包差异,以及提交到每个扩展商店的过程差异。

- -

您同时可以使用 browser-extension-template 用于快速设置、生成和发布浏览器扩展项目。

- -

根据本文中的建议,您现在应该能够创建一个在四种主要浏览器上都运行良好的扩展程序,使您能够将扩展功能交付给更多的人。

diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/\347\224\250\346\210\267\347\225\214\351\235\242\345\205\203\347\264\240/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/\347\224\250\346\210\267\347\225\214\351\235\242\345\205\203\347\264\240/index.html" deleted file mode 100644 index 0aaec74b1f..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/\347\224\250\346\210\267\347\225\214\351\235\242\345\205\203\347\264\240/index.html" +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: 用户界面元素 -slug: Mozilla/Add-ons/WebExtensions/用户界面元素 -translation_of: Mozilla/Add-ons/WebExtensions/user_interface -translation_of_original: Mozilla/Add-ons/WebExtensions/User_interface_components ---- -
{{AddonSidebar}}
- -

该主题概括了所有你能用来创建你扩展的用户界面的组件。

- -

浏览器行为

- -

浏览器行为是一个你能添加至浏览器工具栏的按钮,用户可以点击该按钮来与你的扩展交互。

- -

- -

有两种方式定义一个浏览器行为: 有一个 弹出菜单, 或者没有弹出菜单。

- -

当你没有定义一个弹出菜单时,用户点击按钮会导致一个消息被分发至扩展,而你可以使用 browserAction.onClicked 来监听它:

- -
browser.browserAction.onClicked.addListener(handleClick);
- -

如果你定义了弹出菜单,点击事件就不会被分发取而代之的是弹出菜单会显示出来。用户可以跟弹出菜单交互而当用户点击菜单外的区域时它会自动关闭。

- -

值得注意的是你的扩展只能拥有一个浏览器行为。

- -

定义浏览器行为

- -

你通过使用在manifest.json 文件中使用 browser_action 关键字定义浏览器行为的属性 - 图标, 标题, 弹出菜单 :

- -
"browser_action": {
-  "default_icon": {
-    "19": "button/geo-19.png",
-    "38": "button/geo-38.png"
-  },
-  "default_title": "Whereami?",
-  "default_popup": "popup/geo.html"
-}
- -

唯一必要的关键字是 default_icon.你可以使用 browserAction API 修改任何属性.

- -

例子

- -

在GITHUB上的 webextensions-examples 资源包含了以下使用浏览行为的例子:

- - - -

页面行为

- -

页面行为在很多方面类似于 browser actions , 除了:

- - - -

为了强调页面行为只跟部分页面有联系,他们将其显示在地址栏内而不是工具栏:

- -

- -

不像浏览器行为,页面行为默认是关闭的, 调用 pageAction.show()pageAction.hide() 可以显示或隐藏页面行为。

- -

定义页面行为

- -

通过在manifest.json中使用page_action 关键字来定义页面行为的属性 —— 图标, 标题, 弹出菜单:

- -
"page_action": {
-  "browser_style": true,
-  "default_icon": {
-    "19": "button/geo-19.png",
-    "38": "button/geo-38.png"
-  },
-  "default_title": "Whereami?",
-  "default_popup": "popup/geo.html"
-}
- -

default_icon 是唯一强制要求的关键字. 你可以使用 pageAction API 修改所有的属性或现实或隐藏页面行为。

- -

例子

- -

 chill-out 例子使用了一个页面行为。

- -

弹出菜单

- -

一个弹出菜单是一个绑定至 browser action 或者 page action  的对话框。

- -

- -

当用户点击按钮弹出菜单显示,当用户点击弹出菜单外的任何区域弹出菜单关闭。可以使用  window.close() 来关闭弹出菜单。

- -

你可以使用专门的在manifest.json中使用"_execute_browser_action" 和 "_execute_page_action" 来定义一个快捷键打开浏览器行为或页面行为. 详情请看 commands manifest.json 关键字。不过你不能在你的扩展脚本中通过编程打开弹出菜单 : 他只能通过用户的行为的被打开。

- -

弹出菜单像普通网页一样通过HTML文件被定义,你当然也可以在里面包含CSS 和 javascript文件。 而且不像普通网页, 其包含的javascript可以使用所有的已经通过permissions获取了使用权限的 WebExtension APIs

- -

你可以要求浏览器在你的弹出菜单中包含一个样式表以使其看起来与浏览器UI一致。为了达成这一目的,在你的 browser_actionpage_action  关键字中包含 "browser_style": true

- -

弹出菜单存在一个限制其可以加载资源的源地址的安全机制, 同时不允许类似 eval() 的做法的使用 查看 Content Security Policy 获取更多细节。

- -

你可以使用Add-on Debugger来调试弹出菜单标记和脚本,但是你需要一些技巧来设置让弹出菜单不在自动关闭。 阅读关于调试弹出菜单

- -

弹出菜单尺寸重新计算

- -

弹出菜单自动根据其内容调整尺寸。其适应算法可能因浏览器而不同。

- -

在火狐, 尺寸只再弹出菜单显示前被计算,而且在内容变化后至多进行每秒十次的计算。严格来说, 尺寸受 <body> 元素放置尺寸决定。 一种怪异的说法是, 他由 <html> 决定, Firefox 计算该元素的推荐宽度, 重新调整弹出菜单至其宽度, 然后完成尺寸调整所以这里没有上下滚动。 如果适应用户的屏幕他可能会增长到800X600px的尺寸。 如果用户 移动弹出菜单对应按钮到菜单面板 ,而后弹出菜单会在菜单栏内显示并具有合适的尺寸。

- -

设置页面

- -

设置页面允许你定义你的扩展可以被用户修改的选项。 用户从浏览器扩展管理器中访问设置页面:

- -

{{EmbedYouTube("02oXAcbUv-s")}}

- -

每个浏览器访问该页面的方法存在区别。

- - - -

你可以通过调用 runtime.openOptionsPage() 打开设置页面

- -

设置页面存在一个限制其可以加载资源的源地址的安全机制, 同时不允许类似 eval() 的做法的使用 查看 Content Security Policy 获取更多细节。

- -

定义一个设置页面:

- -

创建一个设置页面有以下流程:

- - - -

例子

- -

 favourite-colour 使用了设置页面。

- -

上下文菜单项

- -

使用 {{WebExtAPIRef("contextMenus")}} API, 你可以按你指定的情况向浏览器上下文菜单添加项目, 比如,你可以只在用户点击图片时显示一项,或者在一个可编辑的元素上,或者被选择的页面的一部份。

- -

指定一个上下文菜单项

- -

您可以使用{{WebExtAPIRef("contextMenus")}} API来 程序化地管理上下文菜单项。

- -

例子

- -

 context-menu-demo 创建了几种不同的上下文菜单项。

- -

通知

- -

使用 {{WebExtAPIRef("notifications")}} API,你通过使用操作系统的通知系统可以创建短时通知:

- -

- -

定义一个通知

- -

使用{{WebExtAPIRef("notifications")}} API 可以程序化地管理通知。

- -

Examples

- -

notify-link-clicks-i18n 创建了通知。

diff --git a/files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html new file mode 100644 index 0000000000..c026e80052 --- /dev/null +++ b/files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html @@ -0,0 +1,144 @@ +--- +title: Site Compatibility for Firefox 19 +slug: Site_Compatibility_for_Firefox_19 +translation_of: Mozilla/Firefox/Releases/19/Site_compatibility +--- +
{{FirefoxSidebar}}

{{ draft() }}

+

Firefox 19 Beta was released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

+

This article only explains the changes that may affect backward compatibility for Websites. For the other new features and changes, please read the following documents:

+ +

This list may be updated until the release of the final version, so please check back later.

+
+

CSS

+
+

flexbox脱前缀

+ +

The CSS3 flexible boxes (flexbox) implementation has been prefixed. From now on, use the related properties and keywords without moz prefix. Note that the flexbox is still disabled by default in Firefox 19. If you'd like to test the feature, open about:config and change the value of layout.css.flexbox.enabled to true.

+
+
+

-moz-initial属性脱前缀

+ +

The -moz-initial keyword has been unprefixed. While -moz-initial will remain in the meantime as an alias of initial, it will be removed at some time, so use the unprefixed keyword instead.

+
+
+

:-moz-placeholder伪类已修改成伪元素::-moz-placeholder

+ +

The :-moz-placeholder pseudo-class that matches form elements with the placeholder attribute has been removed, and the ::-moz-placeholder pseudo-element has been added instead. The implementation of WebKit has been a pseudo-element, and this change is a part of the standardization effort.

+
+
+

CSS动画中带有!important的关键帧规则声明将被忽略

+ +

Following the latest CSS3 animations spec, key frame rule declarations with the !important keyword are now be ignored and parse errors will be returned.

+
+
+

在about:config中添加了一些控制带前缀的CSS属性的有效性的选项

+ +

While this is not a change affecting site compatibility, it's worth mentioning because this has been developed as part of efforts to keep compatibility. Preferences to disable some major prefixed properties have been added: layout.css.prefixes.border-image, layout.css.prefixes.transforms, layout.css.prefixes.transitions and layout.css.prefixes.animations. Web developers can disable those preferences (change the values to false) to test whether style rules are applied as intended even after those prefixed implementations are removed.

+
+
+
+

DOM

+
+

Element.getElementsBy* 现在将返回HTMLCollection对象

+ +

getElementsByTagName, getElementsByTagNameNS以及getElementsByClassName方法返回的元素列表对象的类型从NodeList(遵循DOM3核心规范)变为HTMLCollection(遵循DOM4规范草案).

+
+
+

hasFeature/isSupported方法现在总会返回true

+ +

The document.implementation.hasFeature and Element.isSupported methods have been changed to always return true. The spec has been changed because those APIs were considered useless. However the SVG features are exception; those methods continue to return the support statuses.

+
+
+

createElement(null)不再抛出异常

+ +

Previously the document.createElement method has thrown exception INVALID_CHARACTER_ERR if the argument was null. The method now returns the HTMLUnknownElement object because the argument should be treated as a string and considered to be the same code as document.createElement("null").

+
+
+

document.referrer遵循了最新规范

+ +

When the URL of a nested inline frame (iframe) or a grandchild window is programmatically changed from the parent window, the value of the document.referrer property now points the URL of the parent window where the script is written instead of the child window that refers directly. This is due to a change of the spec and leads to the same behavior as Internet Explorer and Opera. WebKit to follow.

+
+
+

如果修改日期未知,则File.lastModifiedDate属性将返回当前日期

+ +

Following the latest File API spec, the lastModifiedDate property of a File object now returns the current date if the file's last modified date is unknown. Previously it returns null in such case.

+
+
+

Encoding API 遵循了最新规范

+ +

Following a change of the Encoding API spec, the implementation of TextEncoder and TextDecoder has been updated.

+
+
+

移除XForms支持

+ +

The XML Events implementation has been removed. The development of the Mozilla XForms extension that has used the API has been practically discontinued. The XForms accessibility support has also been removed from Firefox 19.

+
+
+
+

JavaScript

+
+

Map.sizeSet.size从方法变成属性

+ +

The size method, that returns the number of key/value pairs saved in a Map object and the number of values saved in a Set object, are changed to be read-only properties.

+
+
+
+

事件处理

+
+

一些事件句柄属性只存在于bodyframeset元素上

+ +

Previously, the onbeforeunload attribute has been recognized even if it has been set on any elements, and the named handler is called when the event is fired. To comply with the spec, it's now ignored when it has been set on elements other than body and frameset. The other attributes treated the same include onafterprint, onbeforeprint, onhashchange, onoffline, ononline, onpagehide, onpageshow, onpopstate, onresize and onunload.

+
+
+
+

文件处理

+
+

不再支持Content-Disposition响应头中的name参数

+ +

The name parameter included in the HTTP Content-Disposition header used for file downloading is now ignored. This parameter is non-standard and supported only by Firefox and Google Chrome. From now, use the standard filename parameter instead.

+
+
+
+

插件

+
+

移除了对Carbon NPAPI的支持

+ +

The Carbon event model and the Quickdraw drawing model, deprecated since Firefox 4, are no longer available. Webmasters should make sure your content works well if it requires any special plug-in. If it doesn't work on Firefox 19, please contact the plug-in vendor.

+
+
diff --git a/files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html new file mode 100644 index 0000000000..cf566f4262 --- /dev/null +++ b/files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html @@ -0,0 +1,145 @@ +--- +title: Firefox 21网站兼容性 +slug: Site_Compatibility_for_Firefox_21 +translation_of: Mozilla/Firefox/Releases/21/Site_compatibility +--- +
{{FirefoxSidebar}}
+

CSS

+
+

-moz-user-select:none的表现变得和-moz-user-select:-moz-none相同,也就是和其他浏览器实现了统一

+ +

Previously, when you set the none keyword to the -moz-user-select property, the text of on the element and sub-elements became unselectable, even if one of those sub-elements had -moz-user-select:text. Starting with Firefox 21, none behaves like -moz-none and other browsers, so selection can be re-enabled on sub-elements using -moz-user-select:text.

+
+
+
+

DOM

+
+

删除了对tablecolslayout属性的支持

+ +

Firefox no longer accepts the cols and layout properties on the table elements. No other browsers support these obscure properties.

+
+
+

scrollWidthscrollHeight不再受overflow:visible的影响

+ +

The scrollWidth and scrollHeight properties might have wrong values when CSS overflow:visible was set on the element. This behavior has been fixed to match the values as if overflow:hidden is set.

+
+
+

window不再接受自定义的索引属性

+ +

Setting indexed expandos (custom properties which have number as the property name) on the window object is no longer allowed. Your code like window[2] = "myString" will be ignored from now on.

+
+
+

window对象上的索引属性变的可枚举

+ +

Previously, iframes in the DOM were not enumerable on the window object. This behavior has been changed to comply with the spec, which means they are now returned with Object.keys(window). This is important to note for things like global leak detection, since appending iframes to the document will modify the enumerable keys on the window object.

+
+
+

XMLHttpRequest.setRequestHeader方法的实现遵循了当前规范

+ +

Previously, if the same headers were repeatedly set with XMLHttpRequest.setRequestHeader, the last-specified value was used. This behavior has been changed to comply with the spec, so those values will be properly combined.

+
+
+

formMethodformEnctype的默认值成为一个空字符串

+ +

The HTML5 spec of the formMethod and formEnctype properties has been updated to have the empty string as default value. Firefox followed the change.

+
+
+

如果传递多条规则,CSSStyleSheet.insertRule方法会报错

+ +

If multiple rules was passed to the CSSStyleSheet.insertRule method, only the first rule was inserted into the stylesheet. Instead, Firefox now throws an exception SYNTAX_ERR like other browsers.

+
+
+

NodeIteratorTreeWalker上删除掉expandEntityReferences属性

+ +

The expandEntityReferences property, which returned a flag indicating whether or not the children of entity reference nodes were visible to the object, has been removed from the NodeIterator and TreeWalker objects, as it never made much sense.

+
+
+

CSSKeyframesRule.insertRule方法被改名为appendRule

+ +

One of the methods of the CSSKeyframesRule interface, insertRule has been renamed to appendRule to match a spec change.

+
+
+

HTMLInputElement.inputmode现在默认被禁用

+ +

HTMLInputElement's inputmode API, which has been implemented since Firefox 17, is now disabled by default because the spec is still unstable. You have to enable the dom.forms.inputmode pref or use the Aurora channel to try out this feature. Note that this API will be renamed inputMode (capitalized M) in Firefox 22.

+
+
+
+

JavaScript

+
+

E4X已经被完全删除

+ +

The support of ECMAScript for XML (E4X), deprecated and disabled since Firefox 17, has finally been dropped. You can no longer use the feature regardless of the hidden preference.

+
+
+

parseInt把以0开头的字符串当成十进制数字解析,而不是以前的八进制

+ +

The parseInt method implementation has been updated to conform to the ECMAScript 5 spec, and it now parses leading-zero strings as decimal, not octal. Therefore, parseInt("042") will return 42 instead of 34. If you'd like to parse strings as octal, specify the radix like parseInt(str, 8).

+
+
+

修正String.localeCompare在无参情况下的表现,以符合ES5规范

+ +

The String.localeCompare method implementation has been updated to conform to the latest ECMAScript 5 spec. If no argument is passed, the method takes the "undefined" string as the argument.

+
+
+
+

SVG

+
+

删除掉那些未实现的SVG特性

+ +

Unimplemented SVG features have been removed instead of just returning the NOT_IMPLEMENTED errors. These features include the viewport and currentView properties of SVGSVGElement.

+
+
+
+

Audio/Video

+
+

mozAudioContext属性脱前缀

+ +

The mozAudioContext implementation has been unprefixed. It's still disabled by default, though. To try out this feature, change the value of the media.webaudio.enabled pref to true.

+
+
+
+

安全

+
+

CSP实现更新到符合最新规范

+ +

Content Security Policy (CSP) 1.0 spec has been implemented. The existing parser will be used when a policy is served via the X-Content-Security-Policy header, and the new parser that follows the 1.0 spec will be used when a policy is served via the officially spec'd Content-Security-Policy header. Consult the latest spec if you'd like to implement CSP on your site. The documents on MDN will be updated sometime soon.

+
+
diff --git a/files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html new file mode 100644 index 0000000000..34f2ab9b60 --- /dev/null +++ b/files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html @@ -0,0 +1,92 @@ +--- +title: Site Compatibility for Firefox 23 +slug: Site_Compatibility_for_Firefox_23 +translation_of: Mozilla/Firefox/Releases/23/Site_compatibility +--- +
{{FirefoxSidebar}}

{{ draft() }}

+

Firefox 23 Aurora (pre-Beta) was released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

+

This article only explains the changes that may affect backward compatibility for Websites. For the other new features and changes, please read the following documents:

+ +

This list may be updated until the release of the final version on , so please check back later.

+
+

CSS

+
+

能产生文字闪烁效果的text-decoration:blink属性值被删除

+ +

Firefox previously supported the Netscape-derived blink effect with the blink keyword for the CSS text-decoration property as well as the HTML blink element and the DOM String.blink method. Starting with Firefox 23, the blink effect no longer works. While text-decoration:blink continues to be supported by the CSS parser and the DOM APIs, the HTML parser has dropped the blink element support, thus the element will be treated as an unknown element. Internet Explorer, Chrome and Safari haven't supported the effect. Opera may also drop the support once it switches to the Blink rendering engine.

+
+
+
+

DOM

+
+

添加到侧边栏的功能被删除

+ +

window.sidebar.addPanel and window.sidebar.addPersistentPanel are no longer supported. These methods were a part of a Netscape-derived API which allowed Web publishers to integrate their contents as sidebar panels of the browser. They were not standardized, rarely used, and not very well supported. No other browsers have implemented these.

+

There is also a plan to remove window.sidebar itself in the future.

+
+
+

requestAnimationFrame脱前缀

+ +

requestAnimationFrame, the unprefixed version of mozRequestAnimationFrame, has been added. This unprefixed method passes a DOMHighResTimeStamp to callbacks. It has microsecond precision and can be compared to performance.now().

+

On the other hand, the prefixed method, which will be removed in the future, continues to pass an epoch-based DOMTimeStamp to callbacks. The passed-in value has millisecond precision and can be compared to mozAnimationStartTime.

+
+
+

跨域文档的contentDocument属性现在返回null

+ +

The contentDocument property on frames now returns null if the caller doesn't subsume the document. This change affects the contentDocument property on the frame, iframe and object elements as well as the getSVGDocument method on the embed, iframe and object elements.

+
+
+

window.defaultStatus被删除

+ +

The window.defaultStatus property is no longer available. Setting this property has had no effect in Firefox because the default preference has disallowed changes to the status text by Web pages. Recently, the Firefox UI dropped support for enabling that pref. Also, this property is not specified in the HTML5 spec. window.status is still available.

+
+
+

不再允许创建AnimationEvent和TransitionEvent

+ +

The support for obsolete document.createEvent("AnimationEvent"), document.createEvent("TransitionEvent"), AnimationEvent.initAnimationEvent, and TransitionEvent.initTransitionEvent has been removed.

+
+
+
+

视频和音频

+
+

Audio Data API被废弃

+ +

The non-standard, experimental Audio Data API is now considered deprecated. The standard Web Audio API can be used instead.

+
+
+

HTMLMediaElement.initialTime被删除

+ +

The HTMLMediaElement.initialTime property is no longer available, due to the removal from the spec.

+
+
+
+

安全和隐私

+
+

在SSL页面(HTTPS)上的非SSL活动内容会被默认阻止

+ +

Firefox 18 introduced preferences to block loading content from non-SSL (http) sites on SSL (https) pages. One of those preferences, security.mixed_content.block_active_content is now enabled by default in order to enhance user security. That means insecure scripts, stylesheets, plug-in contents, inline frames, Web fonts and WebSockets are blocked on secure pages, and a notification is displayed instead. It will not block "display content" like images, videos or audio. See Tanvi Vyas' blog post for details.

+

Mozilla is tracking mixed content issues found on major sites as well as its own properties.

+
+
diff --git a/files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html new file mode 100644 index 0000000000..296e580123 --- /dev/null +++ b/files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html @@ -0,0 +1,22 @@ +--- +title: Firefox 24网站兼容性 +slug: Site_Compatibility_for_Firefox_24 +translation_of: Mozilla/Firefox/Releases/24/Site_compatibility +--- +
{{FirefoxSidebar}}

{{ draft() }}

+

Firefox 24 Aurora (pre-Beta) will be released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

+

This article only explains the changes that may affect backward compatibility for Websites. For the other new features and changes, please read the following documents:

+ +

This list may be updated until the release of the final version on , so please check back later.

+
+

DOM

+
+

releaseEvents,captureEvents,routeEvent等方法被删除

+ +

The releaseEvents, captureEvents, routeEvent, enableExternalCapture and disableExternalCapture methods on the window object have been removed. They were Netscape-derived APIs deprecated since Firefox 3 and the implementation has been no-op (doing nothing). Recently Google Chrome (the Blink rendering engine) also removed the support for those methods. The standard DOM Event methods, including addEventListener and removeEventListener, should be used instead.

+
+
diff --git a/files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html b/files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html new file mode 100644 index 0000000000..96a2e8ec19 --- /dev/null +++ b/files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html @@ -0,0 +1,217 @@ +--- +title: 为Firefox 3升级扩展 +slug: Updating_extensions_for_Firefox_3 +tags: + - Firefox 3 +translation_of: Mozilla/Firefox/Releases/3/Updating_extensions +--- +
+ +

英文原文取自于 http://developer.mozilla.org/en/docs/Extensions 这篇文章将对于那些想把他们的扩展在Firefox 3中正常运行的开发者提供一些有用的信息。

+ +

在进入主题之前,首先要提示一下:如果你的扩展所需要的唯一改变只是安装文件中的maxVersion信息,并且你的扩展所在的主机是addons.mozilla.org,事实上你不需要上传你的新的版本的扩展!只需要在AMO中使用开发者控制面板调整maxVersion。通过这种方式你可以避免你的扩展被再次审核。

+ +

第一步: 升级安装文件

+ +

第一步,当然,对于大多数的扩展也仅需要这一步——更新安装文件install.rdf,声明扩展兼容Firefox 3。

+ +

找到声明兼容的最大版本号的那一行(对于Firefox2,如下):

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

对于Firefox 3,如下:

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

然后重新安装扩展。

+ +

注意,在Firefox3的本版号中没有额外的“.0”,所以请使用“3.0.*”,而非“3.0.0.*”。

+ +
Note: Note that at this point more changes in Firefox 3 are expected. These changes may break some extensions, so you shouldn't release an extension with 3.0.* maxVersion to the users until the Firefox 3 release candidate is out. During the Firefox 3 Beta period, you should use 3.0b5 as your maxVersion.
+ +


+ There have been (and will continue to be) a number of API changes that will likely break some extensions. We're still working on compiling a complete list of these changes.

+ +
Note: If your extension still uses an Install.js script instead of an install manifest, you need to make the transition to an install manifest now. Firefox 3 no longer supports install.js scripts in XPI files.
+ +

Add localizations to the install manifest

+ +

Firefox 3 supports new properties in the install manifest to specify localized descriptions. The old methods still work however the new allow Firefox to pick up the localizations even when the add-on is disabled and pending install. See Localizing extension descriptions for more details.

+ +

Step 2: 确保提供安全的更新

+ +

If you are hosting addons yourself and not on a secure add-on hosting provider like addons.mozilla.org then you must provide a secure method of updating your add-on. This will either involve hosting your updates on an SSL website, or using cryptographic keys to sign the update information. Read Securing Updates for more information.

+ +

Step 3: Deal with changed APIs

+ +

Several APIs have been changed in significant ways. The most significant of these, which will likely affect a large number of extensions, are:

+ +

DOM

+ + +

将外部文档的节点插入当前文档之前,你必须使用 document.importNode() 从外部文档导入源节点,或者使用 document.adoptNode()导入源节点, + 想要了解更多的 Node.ownerDocument 问题,请参考 W3C DOM FAQ.

+ +

即使你不执行导入动作,就执行插入外部文档中的节点.Firefox目前也不会报错(如果严格按标准执行,很多已有的网站都无法正常运行). + 我们鼓励开发者严格按标准修改自己已有的不符合上述标准的代码.

+ +

Bookmarks & History

+ +

If your extension accesses bookmark or history data in any way, it will need substantial work to be compatible with Firefox 3. The old APIs for accessing this information have been replaced by the new Places architecture. See the Places migration guide for details on updating your existing extension to use the Places API.

+ +

Download Manager

+ +

The Download Manager API has changed slightly due to the transition from an RDF data store to using the Storage API. This should be a pretty easy transition to make. In addition, the API for monitoring download progress has changed to support multiple download manager listeners. See nsIDownloadManager, nsIDownloadProgressListener, and Monitoring downloads for more information.

+ +

Password Manager

+ +

If your extension accesses user login information using the Password Manager, it will need to be updated to use the new Login Manager API.

+ + + +

You can also override the built-in password manager storage if you want to provide your own password storage implementation in your extensions. See Creating a Login Manager storage module for details.

+ +

Popups (Menus, Context Menus, Tooltips and Panels)

+ +

The XUL Popup system was heavily modified in Firefox 3. The Popup system includes main menus, context menus and popup panels. A guide to using Popups has been created, detailing how the system works. One thing to note is that popup.showPopup has been deprecated in favor of new popup.openPopup and popup.openPopupAtScreen.

+ +

Autocomplete

+ +

The nsIAutoCompleteController interface's handleEnter() method has been changed to accept an argument that indicates whether the text was selected from the autocomplete popup or by the user pressing enter after typing text.

+ +

DOMParser

+ + + +

Removed interfaces

+ +

The following interfaces were removed from Gecko 1.9, which drives Firefox 3. If your extension makes use of any of these, you'll need to update your code:

+ + + +

Step 4: Check for relevant chrome changes

+ +

There has been a minor change to the chrome that may require changes in your code. A new vbox has been added, called "browser-bottombox", which encloses the find bar and status bar at the bottom of the browser window. Although this doesn't affect the appearance of the display, it may affect your extension if it overlays chrome relative to these elements.

+ +

For example, if you previously overlaid some chrome before the status bar, like this:

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

You should now overlay it like this:

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

Or use the following technique to make your overlay work on both Firefox 2 and Firefox 3:

+ +
<window id="main-window">
+  <vbox id="browser-bottombox" insertbefore="status-bar">
+    <something insertbefore="status-bar" />
+  </vbox>
+</window>
+
+ +
Note: This change is effective for Firefox 3 beta 4 and the pre-beta 4 nightlies.
+ +

其他方面的修改

+ +

Add simple changes you had to make while updating your extension to work with Firefox 3 here.

+ + diff --git a/files/zh-cn/mozilla/mozilla_persona/index.html b/files/zh-cn/mozilla/mozilla_persona/index.html deleted file mode 100644 index 583cb6cb5a..0000000000 --- a/files/zh-cn/mozilla/mozilla_persona/index.html +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: Mozilla Persona -slug: Mozilla/Mozilla_Persona -tags: - - Mozilla - - Persona ---- -
-

保持联系或获取帮助!

-

关注 我们的 blog,加入 我们的邮件列表,或在 IRC 中的 #identity 找到我们。

-
-

Mozilla Persona 是一个用于 web 的完全去中心化且安全的验证系统,基于开放 BrowserID 协议。Mozilla 当前管理一个 Persona 相关的一个可选的、中心化服务的一小组套件。

-

为什么你和你的站点应该使用 Persona?

-
    -
  1. Persona 完全消除了站点特定的密码, 把用户和网站从创建、管理和安全存放密码的责任中解放出来。
  2. -
  3. Persona 易于使用。只需点击两次,一个 Persona 用户可以登入到一个诸如 VoostThe Times Crossword 的新站点,绕开了账户创建相关的摩擦。
  4. -
  5. Persona 易于实现。开发人员在一个下午就可以把 Persona 添加到站点上。
  6. -
  7. 最好的是,不会被锁定。 开发人员获取所有他们用户的验证过的邮件地址,而用户可以在 Persona 上使用任何邮件地址。
  8. -
  9. Persona 基于 BrowserID 协议构建。一旦流行的浏览器供应商实现了 BrowserID,它们不再需要依赖于 Mozilla 来登入。
  10. -
-

继续阅读来开始!

-
- 注意:Persona 在活跃开发中。关注我们的 blog 来了解新特性,或加入我们的邮件列表来提供反馈!
-

在你的站点上使用 Persona

- - - - - - - - - - - -
-

准备开始

-
-
- 为什么使用 Persona?
-
- 了解在你的站点上支持 Persona 的原因和它与其它身份验证系统的区别。
-
- 快速安装
-
- 一份快捷的攻略,展示了如何向你的网站中添加 Persona。
-
-
-

Persona API 参考

-
-
- navigator.id API 参考
-
- navigator.id 对象的参考,web 开发者可以用此来把 Persona 继承到站点中。
-
- 验证 API 参考
-
- 建立在 https://verifier.login.persona.org/verify 上的远程验证 API 的参考。
-
-
-

指导

-
-
- 安全考虑
-
- 确保 Persona 部署安全的实践和技术。
-
- 浏览器兼容性
-
- 准确获知哪些浏览器支持 Persona。
-
- 国际化
-
- 了解 Persona 如何处理不同的语言。
-
-
-

资源

-
-
- 库和插件
-
- 寻找你偏好的编程语言、web 框架、博客或是内容管理系统(CMS)的即插库。
-
- Persona cookbook
-
- Persona 站点的示例源代码。包括 PHP、Node.JS 等等的片段。
-
- 品牌资源
-
- 登入按钮和其它向用户表现 Persona 的图形。
-
-
-

 

- - - - - - - -
-

给身份提供者的信息

-

如果你是一个电子邮件提供商或另一个身份提供服务,翻阅下面的链接来获知如何成为一个 Persona 身份提供者。

-
-
- IdP 概述
-
- Persona 身份提供者的高层视角。
-
- 实现一个 IdP
-
- 成为一个 IdP 的详细技术细节指导。
-
- 开发提示
-
- 开发一个新的身份提供者的一系列开发提示和技巧。
-
- .well-known/browserid
-
- .well-known/browserid 文件的结构和用途概述,这个文件被 IdPs 用于通知它们支持这个协议。
-
-
-

Persona 项目

-
-
- 术语表
-
- BrowserID 和 Persona 定义的术语。
-
- FAQ
-
- 常见问题的回答。
-
- 协议概述
-
- 底层 BrowserID 协议的中等技术概述。
-
- 加密
-
- 一瞥 Persona 和 BrowserID 背后的密码学概念。
-
- 协议规范
-
- 这里是深层技术细节。
-
- Persona 网站
-
- 要让 Persona 运作, 我们在https://login.persona.org 建立了三个服务:一个备用身份提供者、一个可迁移的 {{ domxref("navigator.id") }} API 实现以及一个身份断言验证服务。
-
- Persona 源码
-
- Persona 网站背后的源码托管在 GitHub 的一个仓库上。欢迎提交补丁!
-
-
-

 

-- cgit v1.2.3-54-g00ecf