aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/mozilla/add-ons/webextensions
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:43:23 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:43:23 -0500
commit218934fa2ed1c702a6d3923d2aa2cc6b43c48684 (patch)
treea9ef8ac1e1b8fe4207b6d64d3841bfb8990b6fd0 /files/zh-tw/mozilla/add-ons/webextensions
parent074785cea106179cb3305637055ab0a009ca74f2 (diff)
downloadtranslated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.gz
translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.bz2
translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.zip
initial commit
Diffstat (limited to 'files/zh-tw/mozilla/add-ons/webextensions')
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/anatomy_of_a_webextension/index.html139
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/api/cookies/cookiestore/index.html80
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/api/cookies/index.html163
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/api/cookies/onchanged/index.html118
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/api/cookies/onchangedcause/index.html82
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/api/index.html53
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/api/storage/index.html103
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/api/storage/local/index.html84
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/api/storage/storagearea/get/index.html122
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/api/storage/storagearea/index.html85
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/content_scripts/index.html444
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/index.html115
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/internationalization/index.html400
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/manifest.json/author/index.html44
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/manifest.json/background/index.html93
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/manifest.json/browser_specific_settings/index.html88
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html46
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/manifest.json/index.html113
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/manifest.json/options_ui/index.html110
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/user_interface/browser_action/index.html50
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/user_interface/context_menu_items/index.html54
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/user_interface/devtools_panels/index.html66
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/user_interface/index.html94
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/user_interface/sidebars/index.html55
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/what_are_webextensions/index.html26
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/your_first_webextension/index.html150
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/your_second_webextension/index.html368
27 files changed, 3345 insertions, 0 deletions
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/anatomy_of_a_webextension/index.html b/files/zh-tw/mozilla/add-ons/webextensions/anatomy_of_a_webextension/index.html
new file mode 100644
index 0000000000..505642ac10
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/anatomy_of_a_webextension/index.html
@@ -0,0 +1,139 @@
+---
+title: Anatomy of an extension
+slug: Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension
+translation_of: Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension
+---
+<div>{{AddonSidebar}}</div>
+
+<p>附加元件是一群檔案的集合,基於發布及安裝的目的而包裝成一個檔案。在這個章節,我們將快速地瀏覽這些可能會放在附加元件中的檔案。</p>
+
+<h2 id="manifest.json">manifest.json</h2>
+
+<p>這是每個附加元件中,唯一一個必要放置的檔案。它包含了附加元件的名稱、版本、及需要的權限等資訊,同時也提供了附加元件中其他檔案的路徑指標。</p>
+
+<p>這份manifest也可以包含幾項其他種類檔案的指標路徑:</p>
+
+<ul>
+ <li><a href="/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts">Background pages</a>: 實作長時間執行的邏輯。</li>
+ <li>附加元件的圖示及任何定義的按鈕。</li>
+ <li><a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Sidebars_popups_options_pages">Sidebars, popups, and options pages</a>: 提供各種使用者介面元件的 HTML 文件。</li>
+ <li><a href="/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Content_scripts">Content scripts</a>: 包含於你附加元件中的 JavaScript。你將會利用它注入到網頁中。</li>
+</ul>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13669/webextension-anatomy.png" style="display: block; height: 581px; margin-left: auto; margin-right: auto; width: 600px;"></p>
+
+<p>參考 <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a> 參考頁取得全部的明細。</p>
+
+<p>除了那些參考自manifest之外,附加元件可以包含額外支援的檔案作為 <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Extension_pages">Extension pages</a> 。</p>
+
+<h2 id="Background_scripts_後台腳本">Background scripts 後台腳本</h2>
+
+<p>擴展套件通常需要保持長期狀態或長時間執行操作,而生命週期不依賴於任何特定網頁或瀏覽器視窗。這是後台腳本的用途。</p>
+
+<p>後台腳本會在擴充套件讀取時立即執行且會持續執行直到擴充套件被禁用或是解除安裝。你可以在腳本裡使用任何WebExtension APIs, 只要你已經申請了必要的權限。</p>
+
+<h3 id="Specifying_background_scripts_載入後台腳本">Specifying background scripts 載入後台腳本</h3>
+
+<p>你可以在"manifest.json"裡使用<code>background</code>關鍵字用來包含後台腳本。</p>
+
+<pre class="brush: json">// manifest.json
+
+"background": {
+ "scripts": ["background-script.js"]
+}</pre>
+
+<p>你可以同時載入後台腳本,而他們會運行於相同的環境中,就像是在一個網頁中同時載入一樣。</p>
+
+<p>然而,你也可以先載入一個後台頁面,然後在後台頁面中載入腳本。這樣的做法能為後台腳本提供 ES 6 模組的支援,算是一个優點。</p>
+
+<p style="margin-bottom: 0em;"><strong>manifest.json</strong></p>
+
+<pre class="brush: json line-numbers language-json"><code class="language-json"><span class="comment token">// manifest.json</span>
+
+<span class="key token">"background":</span> <span class="punctuation token">{</span>
+ <span class="key token">"page":</span> <span class="string token">"background-page.html"</span>
+<span class="punctuation token">}</span></code></pre>
+
+<p style="margin-bottom: 0em;"><strong>background-page.html</strong></p>
+
+<pre class="brush: html line-numbers language-html"><code class="language-html"><span class="doctype token">&lt;!DOCTYPE html&gt;</span>
+<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>html</span> <span class="attr-name token">lang</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"zh-tw</span><span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>head</span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>meta</span> <span class="attr-name token">charset</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>utf-8<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>script</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>module<span class="punctuation token">"</span></span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>background-script.js<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>script</span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>head</span><span class="punctuation token">&gt;</span></span>
+<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>html</span><span class="punctuation token">&gt;</span></span></code></pre>
+
+<h3 id="Background_script_environment_後台腳本環境">Background script environment 後台腳本環境</h3>
+
+<h4 id="DOM_APIs">DOM APIs</h4>
+
+<p>後台腳本運行在一個特殊的網頁中,我們稱之為後台頁面(background pages) 。這個頁面會給予他們一個全域的變數<a href="/zh-TW/docs/Web/API/Window">window</a>,並且<span class="tlid-translation translation"><span title="">提供腳本使用所有的標準DOM API。</span></span></p>
+
+<h4 id="WebExtension_APIs">WebExtension APIs</h4>
+
+<p>只要你請求了必要的<a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">權限</a>後,後台腳本可以使用任何的<a href="/en-US/Add-ons/WebExtensions/API">WebExtension APIs</a> 。</p>
+
+<h4 id="Cross-origin_access_跨域請求">Cross-origin access 跨域請求</h4>
+
+<p>當後台腳本擁有<a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">host permissions </a>時,便能像任何主機發送 XHR 請求。</p>
+
+<h4 id="Web_content_網頁內容">Web content 網頁內容</h4>
+
+<p>後台腳本沒辦法直接的存取前端的網頁。然而,你可以載入 <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">content scripts</a> 到前端網頁後,<a href="/en-US/Add-ons/WebExtensions/Content_scripts#Communicating_with_background_scripts">透過message-passing API 來與 content scripts 進行通訊</a> 。</p>
+
+<h4 id="Content_security_policy_內容安全策略">Content security policy 內容安全策略</h4>
+
+<p>依據内容安全策略(Content Security Policy),後台腳本不能執行一些可能有危險的操作,例如使用 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval">eval()</a></code>。 詳情请参考<a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy">内容安全策略</a>。</p>
+
+<h2 id="Sidebars_popups_options_pages側邊欄、彈出視窗、選項頁面">Sidebars, popups, options pages側邊欄、彈出視窗、選項頁面</h2>
+
+<p>Your extension can include various user interface components whose content is defined using an HTML document:</p>
+
+<ul>
+ <li>a <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars">sidebar</a> is a pane that is displayed at the left-hand side of the browser window, next to the web page</li>
+ <li>a <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups">popup</a> is a dialog that you can display when the user clicks on a <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_action">toolbar button</a> or <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Page_actions">address bar button</a></li>
+ <li>an <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Options_pages">options page</a> is a page that's shown when the user accesses your add-on's preferences in the browser's native add-ons manager.</li>
+</ul>
+
+<p>For each of these components, you create an HTML file and point to it using a specific property in <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a>. The HTML file can include CSS and JavaScript files, just like a normal web page.</p>
+
+<p>All of these are a type of <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Extension_pages">Extension pages</a>, and unlike a normal web page, your JavaScript can use all the same privileged WebExtension APIs as your background script. They can even directly access variables in the background page using {{WebExtAPIRef("runtime.getBackgroundPage()")}}.</p>
+
+<h2 id="Extension_pages擴充頁面">Extension pages擴充頁面</h2>
+
+<p>You can also include HTML documents in your extension which are not attached to some predefined user interface component. Unlike the documents you might provide for sidebars, popups, or options pages, these don't have an entry in manifest.json. However, they do also get access to all the same privileged WebExtension APIs as your background script.</p>
+
+<p>You'd typically load a page like this using {{WebExtAPIRef("windows.create()")}} or {{WebExtAPIRef("tabs.create()")}}.</p>
+
+<p>See <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Extension_pages">Extension pages</a> to learn more.</p>
+
+<h2 id="Content_scripts">Content scripts</h2>
+
+<p>Use content scripts to access and manipulate web pages. Content scripts are loaded into web pages and run in the context of that particular page.</p>
+
+<p>Content scripts are extension-provided scripts which run in the context of a web page; this differs from scripts which are loaded by the page itself, including those which are provided in {{HTMLElement("script")}} elements within the page.</p>
+
+<p>Content scripts can see and manipulate the page's DOM, just like normal scripts loaded by the page.</p>
+
+<p>Unlike normal page scripts, they can:</p>
+
+<ul>
+ <li>Make cross-domain XHR requests.</li>
+ <li>Use a small subset of the <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API">WebExtension APIs</a>.</li>
+ <li>Exchange messages with their background scripts and can in this way indirectly access all the WebExtension APIs.</li>
+</ul>
+
+<p>Content scripts cannot directly access normal page scripts but can exchange messages with them using the standard <code><a href="/en-US/docs/Web/API/Window/postMessage">window.postMessage()</a></code> API.</p>
+
+<p>Usually, when we talk about content scripts, we are referring to JavaScript, but you can inject CSS into web pages using the same mechanism.</p>
+
+<p>See the <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">content scripts</a> article to learn more.</p>
+
+<h2 id="Web_accessible_resources_網頁無障礙資源">Web accessible resources 網頁無障礙資源</h2>
+
+<p>Web accessible resources are resources such as images, HTML, CSS, and JavaScript that you include in the extension and want to make accessible to content scripts and page scripts. Resources which are made web-accessible can be referenced by page scripts and content scripts using a special URI scheme.</p>
+
+<p>For example, if a content script wants to insert some images into web pages, you could include them in the extension and make them web accessible. Then the content script could create and append <code><a href="/en-US/docs/Web/HTML/Element/img">img</a></code> tags which reference the images via the <code>src</code> attribute.</p>
+
+<p>To learn more, see the documentation for the <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/web_accessible_resources">web_accessible_resources</a> manifest.json key.</p>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/cookiestore/index.html b/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/cookiestore/index.html
new file mode 100644
index 0000000000..b8ab73dc3f
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/cookiestore/index.html
@@ -0,0 +1,80 @@
+---
+title: cookies.CookieStore
+slug: Mozilla/Add-ons/WebExtensions/API/cookies/CookieStore
+translation_of: Mozilla/Add-ons/WebExtensions/API/cookies/CookieStore
+---
+<div>{{AddonSidebar()}}</div>
+
+<p>{{WebExtAPIRef("cookies")}} API 的 <code>CookieStore</code> 型別代表瀏覽器中的 cookie 存放空間。</p>
+
+<p>不同瀏覽模式(browsing mode)的視窗,有不同的 cookie 存放空間:例如隱私/隱身模式的視窗,會使用來自非隱私/隱身模式視窗的個別 cookie 存放空間。</p>
+
+<h2 id="型別">型別</h2>
+
+<p>此型別的值都是物件,並包含以下屬性:</p>
+
+<dl class="reference-values">
+ <dt><code>id</code></dt>
+ <dd><code>string</code>,代表 cookie 存放空間內的唯一識別號(identifier)。</dd>
+ <dt><code>tabIds</code></dt>
+ <dd><code>integers</code> 的 <code>array</code>,識別所有分享此 cookie 存放空間的瀏覽頁籤。</dd>
+</dl>
+
+<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
+
+<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
+
+<p>{{Compat("webextensions.api.cookies.CookieStore")}}</p>
+
+<h2 id="示例">示例</h2>
+
+<p>在以下程式碼片段內,{{WebExtAPIRef("cookies.getAllCookieStores()")}} 用來查找瀏覽器內,所有目前能用 cookie 存放空間,並列出每個 cookie 存放空間的 ID、還有分享此 cookie 存放空間的頁籤。</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">logStores</span><span class="punctuation token">(</span>cookieStores<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ <span class="keyword token">for</span><span class="punctuation token">(</span>store <span class="keyword token">of</span> cookieStores<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="template-string token"><span class="string token">`Cookie store: </span><span class="interpolation token"><span class="interpolation-punctuation punctuation token">${</span>store<span class="punctuation token">.</span>id<span class="interpolation-punctuation punctuation token">}</span></span><span class="string token">\n Tab IDs: </span><span class="interpolation token"><span class="interpolation-punctuation punctuation token">${</span>store<span class="punctuation token">.</span>tabIds<span class="interpolation-punctuation punctuation token">}</span></span><span class="string token">`</span></span><span class="punctuation token">)</span><span class="punctuation token">;</span>
+ <span class="punctuation token">}</span>
+<span class="punctuation token">}</span>
+
+<span class="keyword token">var</span> getting <span class="operator token">=</span> browser<span class="punctuation token">.</span>cookies<span class="punctuation token">.</span><span class="function token">getAllCookieStores</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
+getting<span class="punctuation token">.</span><span class="function token">then</span><span class="punctuation token">(</span>logStores<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre>
+
+<p>{{WebExtExamples}}</p>
+
+<div class="note"><strong>致謝</strong>
+
+<p>此 API 基於 Chromium 的 <a href="https://developer.chrome.com/extensions/cookies"><code>chrome.cookies</code></a> API 而來,文件改作自 Chromium 程式碼裡的 <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json"><code>cookies.json</code></a>。</p>
+
+<p>Microsoft Edge 的相容資訊來自微軟公司,原文以創用 CC 姓名標示 3.0 美國版條款授權大眾使用。</p>
+</div>
+
+<div class="hidden">
+<pre>// Copyright 2015 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</pre>
+</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/index.html b/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/index.html
new file mode 100644
index 0000000000..34da08932c
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/index.html
@@ -0,0 +1,163 @@
+---
+title: cookies
+slug: Mozilla/Add-ons/WebExtensions/API/cookies
+tags:
+ - API
+ - Add-ons
+ - Cookies
+ - Extensions
+ - Interface
+ - Non-standard
+ - Reference
+ - WebExtensions
+ - 介面
+ - 參考文件
+ - 擴充套件
+ - 附加元件
+ - 非標準
+translation_of: Mozilla/Add-ons/WebExtensions/API/cookies
+---
+<div>{{AddonSidebar}}</div>
+
+<div>讓擴充套件可以取得、設定 cookies 資訊,並監控其變動。</div>
+
+<div> </div>
+
+<p>使用此 API 前,必須先在 <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json </a>檔案中加入「cookies」這項 <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">API 權限宣告</a>,也必須以 <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#Host_permissions">host 權限宣告</a>將要存取 Cookies 的網站列入。參見 <a href="/en-US/Add-ons/WebExtensions/API/cookies#Permissions">Cookie 權限</a>一節。</p>
+
+<h2 id="型別">型別</h2>
+
+<dl>
+ <dt>{{WebExtAPIRef("cookies.Cookie")}}</dt>
+ <dd>代表一個 HTTP cookie 的相關資訊。</dd>
+ <dt>{{WebExtAPIRef("cookies.CookieStore")}}</dt>
+ <dd>代表瀏覽器中的 cookie 存放空間。</dd>
+ <dt>{{WebExtAPIRef("cookies.OnChangedCause")}}</dt>
+ <dd>代表觸發 cookie 資料變動的原因。</dd>
+</dl>
+
+<h2 id="方法">方法</h2>
+
+<dl>
+ <dt>{{WebExtAPIRef("cookies.get()")}}</dt>
+ <dd>取回單一 cookie 的相關資訊。</dd>
+ <dt>{{WebExtAPIRef("cookies.getAll()")}}</dt>
+ <dd>取回符合設定條件的所有 cookies 資訊。</dd>
+ <dt>{{WebExtAPIRef("cookies.set()")}}</dt>
+ <dd>為 cookie 設定資料。如果目前已有相同的 cookies,則會覆寫原本的 cookie 資料。</dd>
+ <dt>{{WebExtAPIRef("cookies.remove()")}}</dt>
+ <dd>刪除某特定名稱的 cookie。</dd>
+ <dt>{{WebExtAPIRef("cookies.getAllCookieStores()")}}</dt>
+ <dd>列出目前所有的 cookie 存放空間。</dd>
+</dl>
+
+<h2 id="事件處理程序">事件處理程序</h2>
+
+<dl>
+ <dt>{{WebExtAPIRef("cookies.onChanged")}}</dt>
+ <dd>當 cookie 設定或刪除時觸發。</dd>
+</dl>
+
+<h2 id="權限">權限</h2>
+
+<p>使用此 API 前,擴充套件應於 manifest.json 設定檔中指明需要「cookies」<a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">API 權限</a>,亦須以 <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#Host_permissions">host 權限宣告</a>指明需要存取 cookies 的網站清單。此後,符合 host 權限宣告的 URL 所能讀寫的任何 cookies,該擴充套件即可讀取。比方說:</p>
+
+<dl>
+ <dt><code>http://*.example.com/</code></dt>
+ <dd>
+ <p>若套件有這樣的 host 權限宣告,即可:</p>
+
+ <ul>
+ <li>讀取 <code>www.example.com</code> 任何路徑下的非安全 cookie。</li>
+ <li>寫入 <code>www.example.com</code> 任何路徑下的安全或非安全 cookie。</li>
+ </ul>
+
+ <p>但<em>不能</em>:</p>
+
+ <ul>
+ <li>讀取 <code>www.example.com</code> 下的安全 cookie。</li>
+ </ul>
+ </dd>
+ <dt><code>http://www.example.com/</code></dt>
+ <dd>
+ <p>若套件有這樣的 host 權限宣告,即可:</p>
+
+ <ul>
+ <li>讀取 <code>www.example.com</code> 任何路徑下的非安全 cookie。</li>
+ <li>讀取 <code>.example.com</code> 任何路徑下的非安全 cookie。</li>
+ <li>寫入 <code>www.example.com</code> 任何路徑下的安全或非安全 cookie。</li>
+ <li>寫入 <code>.example.com</code> 任何路徑下的安全或非安全 cookie。</li>
+ </ul>
+
+ <p>但<em>不能</em>:</p>
+
+ <ul>
+ <li>寫入 <code>foo.example.com</code> 的 cookie。</li>
+ <li>寫入 <code>foo.www.example.com</code> 的 cookie。</li>
+ </ul>
+ </dd>
+ <dt><code>*://*.example.com/</code></dt>
+ <dd>
+ <p>若套件有這樣的 host 權限宣告,即可:</p>
+
+ <ul>
+ <li>讀、寫 <code>www.example.com</code> 任何路徑下的安全或非安全 cookie。</li>
+ </ul>
+ </dd>
+</dl>
+
+<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
+
+<p>{{Compat("webextensions.api.cookies")}}</p>
+
+<div class="hidden note">
+<p>The "Chrome incompatibilities" section is included from <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities"> https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities</a> using the <a href="/en-US/docs/Template:WebExtChromeCompat">WebExtChromeCompat</a> macro.</p>
+
+<p>If you need to update this content, edit <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities">https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities</a>, then shift-refresh this page to see your changes.</p>
+
+<p>譯者按:該文件會持續更新,不建議翻譯。</p>
+</div>
+
+<h3 id="Edge_不相容資訊">Edge 不相容資訊</h3>
+
+<p>Edge 不支援 promises,請使用回呼(callback)函式處理。</p>
+
+<p> {{WebExtExamples("h2")}}</p>
+
+<div class="note"><strong>致謝</strong>
+
+<p>此 API 基於 Chromium 的 <a href="https://developer.chrome.com/extensions/cookies"><code>chrome.cookies</code></a> API 而來,文件改作自 Chromium 程式碼裡的 <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json"><code>cookies.json</code></a>。</p>
+
+<p>Microsoft Edge 的相容資訊來自微軟公司,原文以創用 CC 姓名標示 3.0 美國版條款授權大眾使用。</p>
+</div>
+
+<div class="hidden">
+<pre>// Copyright 2015 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</pre>
+</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/onchanged/index.html b/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/onchanged/index.html
new file mode 100644
index 0000000000..7558105bcc
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/onchanged/index.html
@@ -0,0 +1,118 @@
+---
+title: cookies.onChanged
+slug: Mozilla/Add-ons/WebExtensions/API/cookies/onChanged
+translation_of: Mozilla/Add-ons/WebExtensions/API/cookies/onChanged
+---
+<div>{{AddonSidebar()}}</div>
+
+<p>{{WebExtAPIRef("cookies")}} API 的 <code>onChanged</code> 事件會在 cookie 設定或刪除時觸發。</p>
+
+<p>請注意,更新 cookie 的屬性要透過以下兩個步驟實做:</p>
+
+<ol>
+ <li>首先,要更新的 cookie 會先被刪掉,並產生一個 <code>overwrite</code> 的 {{WebExtAPIRef("cookies.OnChangedCause")}} 提醒。</li>
+ <li>接著,帶著更新數值的新 cookie 會被寫進去,並產生第二個 <code>explicit</code> 的 {{WebExtAPIRef("cookies.OnChangedCause")}} 提醒。</li>
+</ol>
+
+<h2 id="語法">語法</h2>
+
+<pre class="syntaxbox brush:js">browser.cookies.onChanged.addListener(listener)
+browser.cookies.onChanged.removeListener(listener)
+browser.cookies.onChanged.hasListener(listener)
+</pre>
+
+<p>此 API 也能以 <code>browser.cookies.onChanged.*</code> 運行。</p>
+
+<p>此事件有以下函式:</p>
+
+<dl>
+ <dt><code>addListener(callback)</code></dt>
+ <dd>給此事件添加監聽器(listener)。</dd>
+ <dt><code>removeListener(listener)</code></dt>
+ <dd>停止監聽此事件。<code>listener</code> 參數是要移除的監聽器。</dd>
+ <dt><code>hasListener(listener)</code></dt>
+ <dd>檢查此事件的 <code>listener</code> 是否被監聽了。若有監聽,回傳 <code>true</code>,否則回傳 <code>false</code>。</dd>
+</dl>
+
+<h2 id="addListener_語法">addListener 語法</h2>
+
+<h3 id="參數">參數</h3>
+
+<dl>
+ <dt><code>callback</code></dt>
+ <dd>
+ <p>能被呼叫的 callback 函式會在此事件發生的時候觸發。函式會 passed 以下參數:</p>
+
+ <dl class="reference-values">
+ <dt><code>changeInfo</code></dt>
+ <dd>一個含有觸發事件資訊的 <code>object</code>。它有兩個屬性:</dd>
+ <dd>
+ <dl class="reference-values">
+ <dt><code>removed</code></dt>
+ <dd>一個 <code>boolean</code>。如果 cookie 被刪除則為 <code>true</code>,否則為 <code>false</code>。</dd>
+ <dt><code>cookie</code></dt>
+ <dd>一個 {{WebExtAPIRef('cookies.Cookie')}} 物件。含有被設定、或被刪除的 cookie 資訊。</dd>
+ <dt><code>cause</code></dt>
+ <dd>一個 {{WebExtAPIRef('cookies.OnChangedCause')}} 數值。含有 cookie被改變的潛在原因。</dd>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+</dl>
+
+<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
+
+<p class="hidden">本相容性表格由結構化資料產生。若要貢獻資料,請參考 <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> 並給一個 pull request。</p>
+
+<p>{{Compat("webextensions.api.cookies.onChanged")}}</p>
+
+<h2 id="示例">示例</h2>
+
+<p>本範例監聽 <code>onChanged</code> 事件並紀錄由 <code>changeInfo</code> 參數傳來的資訊:</p>
+
+<pre class="brush: js line-numbers language-js">browser.cookies.onChanged.addListener(function(changeInfo) {
+  console.log('Cookie changed: ' +
+              '\n * Cookie: ' + JSON.stringify(changeInfo.cookie) +
+              '\n * Cause: ' + changeInfo.cause +
+              '\n * Removed: ' + changeInfo.removed);
+});</pre>
+
+<p>{{WebExtExamples}}</p>
+
+<div class="note"><strong>致謝</strong>
+
+<p>此 API 基於 Chromium 的 <a href="https://developer.chrome.com/extensions/cookies"><code>chrome.cookies</code></a> API 而來,文件改作自 Chromium 程式碼裡的 <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json"><code>cookies.json</code></a>。</p>
+
+<p>Microsoft Edge 的相容資訊來自微軟公司,原文以創用 CC 姓名標示 3.0 美國版條款授權大眾使用。</p>
+</div>
+
+<div class="hidden">
+<pre>// Copyright 2015 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</pre>
+</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/onchangedcause/index.html b/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/onchangedcause/index.html
new file mode 100644
index 0000000000..592aaf7d6d
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/api/cookies/onchangedcause/index.html
@@ -0,0 +1,82 @@
+---
+title: cookies.OnChangedCause
+slug: Mozilla/Add-ons/WebExtensions/API/cookies/OnChangedCause
+translation_of: Mozilla/Add-ons/WebExtensions/API/cookies/OnChangedCause
+---
+<div>{{AddonSidebar()}}</div>
+
+<p>{{WebExtAPIRef("cookies")}} API 的 <code>OnChangedCause</code> 型別,代表觸發 cookie 資料變動的原因。</p>
+
+<h2 id="型別">型別</h2>
+
+<p>此型別的所有值都是字串(string)。可用值包括:</p>
+
+<dl>
+ <dt><code>evicted</code></dt>
+ <dd>由於垃圾回收(garbage collection)而被刪除的 cookie。</dd>
+ <dt><code>expired</code></dt>
+ <dd>由於過期而被刪除的 cookie。</dd>
+ <dt><code>explicit</code></dt>
+ <dd>透過顯式呼叫(explicit call){{WebExtAPIRef("cookies.remove()")}} 而被插入或刪除的 cookie。</dd>
+ <dt><code>expired_overwrite</code></dt>
+ <dd>被已過期(already-expired expiration date)cookie 所覆寫的 cookie。</dd>
+ <dt><code>overwrite</code></dt>
+ <dd>A call to {{WebExtAPIRef("cookies.set()")}} overwrote this cookie with a different one.</dd>
+</dl>
+
+<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
+
+<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
+
+<p>{{Compat("webextensions.api.cookies.OnChangedCause")}}</p>
+
+<h2 id="示例">示例</h2>
+
+<p>你可以在 cookie 變更的時候監聽被通知的 {{WebExtAPIRef("cookies.onChanged")}} 事件。此監聽器 passed 含有 <code>cause</code> 屬性,值為 <code>OnChangeCaused</code> 字串的 <code>changeInfo</code> 物件:</p>
+
+<pre class="brush: js">browser.cookies.onChanged.addListener(function(changeInfo) {
+  console.log('Cookie changed: ' +
+              '\n * Cookie: ' + JSON.stringify(changeInfo.cookie) +
+              '\n * Cause: ' + changeInfo.cause +
+              '\n * Removed: ' + changeInfo.removed);
+});</pre>
+
+<p>{{WebExtExamples}}</p>
+
+<div class="note"><strong>致謝</strong>
+
+<p>此 API 基於 Chromium 的 <a href="https://developer.chrome.com/extensions/cookies"><code>chrome.cookies</code></a> API 而來,文件改作自 Chromium 程式碼裡的 <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json"><code>cookies.json</code></a>。</p>
+
+<p>Microsoft Edge 的相容資訊來自微軟公司,原文以創用 CC 姓名標示 3.0 美國版條款授權大眾使用。</p>
+</div>
+
+<div class="hidden">
+<pre>// Copyright 2015 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</pre>
+</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/api/index.html b/files/zh-tw/mozilla/add-ons/webextensions/api/index.html
new file mode 100644
index 0000000000..955086de10
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/api/index.html
@@ -0,0 +1,53 @@
+---
+title: JavaScript APIs
+slug: Mozilla/Add-ons/WebExtensions/API
+tags:
+ - NeedsTranslation
+ - TopicStub
+ - WebExtensions
+translation_of: Mozilla/Add-ons/WebExtensions/API
+---
+<div>{{AddonSidebar}}</div>
+
+<div>
+<p>JavaScript APIs for WebExtensions can be used inside the extension's <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts">background scripts</a> and in any other documents bundled with the extension, including <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_action">browser action</a> or <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Page_actions">page action</a> popups, <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Sidebars">sidebars</a>, <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Options_pages">options pages</a>, or <a href="/en-US/Add-ons/WebExtensions/manifest.json/chrome_url_overrides">new tab pages</a>. A few of these APIs can also be accessed by an extension's <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Content_scripts">content scripts</a> (see the <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts#WebExtension_APIs">list in the content script guide</a>).</p>
+
+<p>To use the more powerful APIs you need to <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json/permissions">request permission</a> in your extension's manifest.json.</p>
+
+<p>You can access the APIs using the <code>browser</code> namespace:</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">logTabs</span><span class="punctuation token">(</span>tabs<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>tabs<span class="punctuation token">)</span><span class="punctuation token">;</span>
+<span class="punctuation token">}</span>
+
+browser<span class="punctuation token">.</span>tabs<span class="punctuation token">.</span><span class="function token">query</span><span class="punctuation token">(</span><span class="punctuation token">{</span>currentWindow<span class="punctuation token">:</span> <span class="keyword token">true</span><span class="punctuation token">}</span><span class="punctuation token">,</span> logTabs<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre>
+</div>
+
+<div>
+<p>Many of the APIs are asynchronous, returning a <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code>:</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">logCookie</span><span class="punctuation token">(</span>c<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>c<span class="punctuation token">)</span><span class="punctuation token">;</span>
+<span class="punctuation token">}</span>
+
+<span class="keyword token">function</span> <span class="function token">logError</span><span class="punctuation token">(</span>e<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ console<span class="punctuation token">.</span><span class="function token">error</span><span class="punctuation token">(</span>e<span class="punctuation token">)</span><span class="punctuation token">;</span>
+<span class="punctuation token">}</span>
+
+<span class="keyword token">var</span> setCookie <span class="operator token">=</span> browser<span class="punctuation token">.</span>cookies<span class="punctuation token">.</span><span class="keyword token">set</span><span class="punctuation token">(</span>
+ <span class="punctuation token">{</span>url<span class="punctuation token">:</span> <span class="string token">"https://developer.mozilla.org/"</span><span class="punctuation token">}</span>
+<span class="punctuation token">)</span><span class="punctuation token">;</span>
+setCookie<span class="punctuation token">.</span><span class="function token">then</span><span class="punctuation token">(</span>logCookie<span class="punctuation token">,</span> logError<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre>
+</div>
+
+<div>
+<p>Note that this is different from Google Chrome's extension system, which uses the <code>chrome</code> namespace instead of <code>browser</code>, and which uses callbacks instead of promises for asynchronous functions. As a porting aid, the Firefox implementation of WebExtensions APIs supports <code>chrome</code> and callbacks as well as <code>browser</code> and promises. Mozilla has also written a polyfill which enables code that uses <code>browser</code> and promises to work unchanged in Chrome: <a class="external external-icon" href="https://github.com/mozilla/webextension-polyfill">https://github.com/mozilla/webextension-polyfill</a>.</p>
+
+<p>Firefox also implements these APIs under the <code>chrome</code> namespace using callbacks. This allows code written for Chrome to run largely unchanged in Firefox for the APIs documented here.</p>
+
+<p>Microsoft Edge uses the <code>browser</code> namespace, but doesn't yet support promise-based asynchronous APIs. In Edge, for the time being, asynchronous APIs must use callbacks.</p>
+
+<p>Not all browsers support all the APIs: for the details, see <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_support_for_JavaScript_APIs">Browser support for JavaScript APIs</a>.</p>
+</div>
+
+<div>{{SubpagesWithSummaries}}</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/api/storage/index.html b/files/zh-tw/mozilla/add-ons/webextensions/api/storage/index.html
new file mode 100644
index 0000000000..8e1d68894d
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/api/storage/index.html
@@ -0,0 +1,103 @@
+---
+title: storage
+slug: Mozilla/Add-ons/WebExtensions/API/storage
+tags:
+ - API
+ - 擴充套件
+translation_of: Mozilla/Add-ons/WebExtensions/API/storage
+---
+<div>
+<div>{{AddonSidebar}}</div>
+
+<p>讓套件可以存讀資料以及監聽儲存項目的更動。</p>
+
+<p>儲存系統基於 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API">Web Storage API</a>,有一些不同,包括:</p>
+
+<ul>
+ <li>非同步</li>
+ <li>值的作用域在套件而不是某個特定的網域(後端的所有腳本與內容腳本都可用同樣的鍵值)。</li>
+ <li>儲存的值可以是任何的 JSON-ifiable 值而並非只能是 <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code>。這包括了: <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">陣列</a></code>、<code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">物件</a></code>。但只有在內容可以被以JSON表示的時候,這表示不包含DOM節點。你不需要特地把值轉爲JSON <code>Strings</code>來儲存它們,它們在內部就是以JSON來表示的。</li>
+ <li>同一個API呼叫中可以設置或取得複數鍵值。</li>
+</ul>
+
+<p>要使用這個 API 你必須在 <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a> 裡面加入 "storage" 的<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">權限</a>。</p>
+
+<p>每個套件都有自己的儲存空間,它們可以被切分爲不同種類的儲存。</p>
+
+<p>雖然這個 API 與{{domxref("Window.localStorage")}}很相似,建議你不要在套件裡使用 <code>Window.localStorage</code> 儲存套件相關資料。Firefox 在用戶由於隱私問題清除歷史記錄與資料時會清除 localStorage API 儲存的資料,而 <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/local">storage.local</a></code> API 儲存的則會留著。</p>
+
+<div class="note">儲存空間不會被加密,所以你不應該把它們用來儲存用戶的機密資料。</div>
+
+<h2 id="型別">型別</h2>
+
+<dl>
+ <dt>{{WebExtAPIRef("storage.StorageArea")}}</dt>
+ <dd>表示儲存空間的物件。</dd>
+ <dt>{{WebExtAPIRef("storage.StorageChange")}}</dt>
+ <dd>表示儲存空間變化的物件。</dd>
+</dl>
+
+<h2 id="屬性">屬性</h2>
+
+<p><code>storage</code> 有三個屬性,各自表示不同種類的儲存空間。</p>
+
+<dl>
+ <dt>{{WebExtAPIRef("storage.sync")}}</dt>
+ <dd>表示 <code>sync</code> 儲存空間。<code>sync</code> 儲存空間裡的項目會被瀏覽器同步,所以可以跨裝置在所有已登入瀏覽器實例裡面使用。</dd>
+ <dt>{{WebExtAPIRef("storage.local")}}</dt>
+ <dd>表示 <code>local</code> 儲存空間。<code>local</code> 儲存空間裡的項目會被侷限在安裝套件的機器上。</dd>
+ <dt>{{WebExtAPIRef("storage.managed")}}</dt>
+ <dd>表示 <code>managed</code> 儲存空間。<code>managed</code> 儲存空間的項目由網域管理者設置而且對套件唯讀,修改這項會導致錯誤。</dd>
+</dl>
+
+<h2 id="事件">事件</h2>
+
+<dl>
+ <dt>{{WebExtAPIRef("storage.onChanged")}}</dt>
+ <dd>當儲存空間裡的一個或更多項目被修改時觸發。</dd>
+</dl>
+
+<h2 id="瀏覽器兼容性">瀏覽器兼容性</h2>
+</div>
+
+<p>{{Compat("webextensions.api.storage")}}</p>
+
+<p>{{WebExtExamples("h2")}}</p>
+
+<div class="note"><strong>Acknowledgements</strong>
+
+<p>This API is based on Chromium's <a href="https://developer.chrome.com/extensions/storage"><code>chrome.storage</code></a> API. This documentation is derived from <a href="https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json"><code>storage.json</code></a> in the Chromium code.</p>
+
+<p>Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.</p>
+</div>
+
+<div class="hidden">
+<pre>// Copyright 2015 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</pre>
+</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/api/storage/local/index.html b/files/zh-tw/mozilla/add-ons/webextensions/api/storage/local/index.html
new file mode 100644
index 0000000000..3cdc3ab140
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/api/storage/local/index.html
@@ -0,0 +1,84 @@
+---
+title: storage.local
+slug: Mozilla/Add-ons/WebExtensions/API/storage/local
+translation_of: Mozilla/Add-ons/WebExtensions/API/storage/local
+---
+<div>{{AddonSidebar()}}</div>
+
+<p>代表 <code>local</code> 儲存空間。通常 <code>local</code> 裡面的東西,會放在套件安裝的地方。</p>
+
+<p>瀏覽器可能會限制套件本地可儲存的資料數量:</p>
+
+<ul>
+ <li>Chrome 限制套件內用到此 API 資料的上限為 5MB,除非有 <a href="/zh-TW/Add-ons/WebExtensions/manifest.json/permissions#Unlimited_storage">unlimitedStorage</a> 權限。</li>
+ <li>56 版以後的 Firefox 將能要求 unlimitedStorage 權限。目前 Firefox 還沒有限制套件內的資料上限,但這功能會在未來引入:因此,如果可能會儲存大容量的資料,最好要實做 unlimitedStorage 的請求。</li>
+</ul>
+
+<p>如果套件被移除、相關的儲存資料也會一併移除。</p>
+
+<p>在 Firefox 內,你可以透過 about:config 內設定 keepUuidOnUninstall 與 keepStorageOnUninstall 為 <code>true</code> 以避免瀏覽器在移除套件時,一併移除相關的儲存資料。這個功能是為了方便開發者除錯,套件本身無法改變這個設定。</p>
+
+<p>雖然這 API 與 {{domxref("Window.localStorage")}} 相似,但不建議在套件內使用 <code>Window.localStorage</code>。在某些情況下,用戶會出於隱私上的理由,要求 Firefox 清理瀏覽紀錄與資料,這其中就包含使用 localStorage API 的資料。另一方面,storage.local API 的資料,在這種情況下會予以保留。</p>
+
+<h2 id="方法">方法</h2>
+
+<p><code>local</code> 物件實做了定義於 {{WebExtAPIRef("storage.StorageArea")}} 類別的方法:</p>
+
+<dl>
+ <dt>{{WebExtAPIRef("storage.StorageArea.get()")}}</dt>
+ <dd>取得一個或多個源自儲存空間的項目。</dd>
+ <dt>{{WebExtAPIRef("storage.StorageArea.getBytesInUse()")}}</dt>
+ <dd>取得儲存空間內,一個或多個已為項目所使用的容量。單位為 byte。</dd>
+ <dt>{{WebExtAPIRef("storage.StorageArea.set()")}}</dt>
+ <dd>Stores one or more items in the storage area. If the item already exists, its value will be updated. When you set a value, the {{WebExtAPIRef("storage.onChanged")}} event will fire.</dd>
+ <dt>{{WebExtAPIRef("storage.StorageArea.remove()")}}</dt>
+ <dd>刪除一個或多個儲存空間內的項目。</dd>
+ <dt>{{WebExtAPIRef("storage.StorageArea.clear()")}}</dt>
+ <dd>刪除所有儲存空間內的項目。</dd>
+</dl>
+
+<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
+
+<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
+
+<p>{{Compat("webextensions.api.storage.local")}}</p>
+
+<p>{{WebExtExamples}}</p>
+
+<div class="note"><strong>致謝</strong>
+
+<p>This API is based on Chromium's <a href="https://developer.chrome.com/extensions/storage#property-local"><code>chrome.storage</code></a> API. This documentation is derived from <a href="https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json"><code>storage.json</code></a> in the Chromium code.</p>
+
+<p>Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.</p>
+</div>
+
+<div class="hidden">
+<pre>// Copyright 2015 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</pre>
+</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/api/storage/storagearea/get/index.html b/files/zh-tw/mozilla/add-ons/webextensions/api/storage/storagearea/get/index.html
new file mode 100644
index 0000000000..744cc6ed8b
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/api/storage/storagearea/get/index.html
@@ -0,0 +1,122 @@
+---
+title: StorageArea.get()
+slug: Mozilla/Add-ons/WebExtensions/API/storage/StorageArea/get
+translation_of: Mozilla/Add-ons/WebExtensions/API/storage/StorageArea/get
+---
+<div>{{AddonSidebar()}}</div>
+
+<p>從儲存空間內檢查一個或多個單元(item)。</p>
+
+<p>這個非同步函式會回傳 <code><a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code>。</p>
+
+<h2 id="語法">語法</h2>
+
+<pre class="syntaxbox">let gettingItem = browser.storage.&lt;storageType&gt;.get(
+ keys // null, string, object or array of strings
+)
+</pre>
+
+<p><code>&lt;storageType&gt;</code> 會是以下可覆寫的儲存類型之一:{{WebExtAPIRef("storage.sync")}} 或 {{WebExtAPIRef("storage.local")}}。</p>
+
+<h3 id="參數">參數</h3>
+
+<dl>
+ <dt><code>keys</code></dt>
+ <dd>用來識別要檢查單元的 key(單個為字串;多個為陣列、或指定預設值的物件)。如果把這裡留空(空字串、空陣列、空物件都可以),就會取得空物件。如果是 <code>null</code> 或 undefined,則會取得所有儲存的內容。</dd>
+</dl>
+
+<h3 id="回傳值">回傳值</h3>
+
+<p><code><a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code> that will be fulfilled with a <code>results</code> object containing every object in <code>keys</code> that was found in the storage area. If the operation failed, the promise will be rejected with an error message.</p>
+
+<div class="warning">
+<p>When used within a content script in Firefox versions prior to 52, the Promise returned by <code>browser.storage.local.get()</code> is fulfilled with an Array containing one Object. The Object in the Array contains the <code>keys</code> found in the storage area, as described above. The Promise is correctly fulfilled with an Object when used in the background context (background scripts, popups, options pages, etc.). When this API is used as <code>chrome.storage.local.get()</code>, it correctly passes an Object to the callback function.</p>
+</div>
+
+<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
+
+<p>{{Compat("webextensions.api.storage.StorageArea.get")}}</p>
+
+<h2 id="示例">示例</h2>
+
+<p>假設儲存空間有以下單元:</p>
+
+<pre class="brush: js">// 兩個單元:「kitten」與「monster」
+browser.storage.local.set({
+ kitten: {name:"Mog", eats:"mice"},
+ monster: {name:"Kraken", eats:"people"}
+});</pre>
+
+<p>Define success and failure handlers for the promise:</p>
+
+<pre class="brush: js">function onGot(item) {
+ console.log(item);
+}
+
+function onError(error) {
+ console.log(`Error: ${error}`);
+}</pre>
+
+<p>With no <code>keys</code> argument, retrieve everything:</p>
+
+<pre class="brush: js">let gettingItem = browser.storage.local.get();
+gettingItem.then(onGot, onError);
+
+// -&gt; Object { kitten: Object, monster: Object }</pre>
+
+<p>With an empty keys argument, return nothing:</p>
+
+<pre class="brush: js">// with an empty array, retrieve nothing
+let gettingItem = browser.storage.local.get([]);
+gettingItem.then(onGot, onError);
+
+// -&gt; Object { }</pre>
+
+<p>With the name of an object, retrieve the match:</p>
+
+<pre class="brush: js">let gettingItem = browser.storage.local.get("kitten");
+gettingItem.then(onGot, onError);
+
+// -&gt; Object { kitten: Object }</pre>
+
+<p>With an array of object names, retrieve all matches:</p>
+
+<pre class="brush: js">let gettingItem = browser.storage.local.get(["kitten", "monster", "grapefruit"]);
+gettingItem.then(onGot, onError);
+
+// -&gt; Object { kitten: Object, monster: Object } </pre>
+
+<p>With an object with object names as keys and the default value as value:</p>
+
+<pre class="brush: js">let gettingItem = browser.storage.local.get({
+ kitten: "no kitten",
+ monster: "no monster",
+ grapefruit: {
+ name: "Grape Fruit",
+ eats: "Water"
+ }
+});
+
+// -&gt; Object { kitten: Object, monster: Object, grapefruit: Object }
+</pre>
+
+<p>{{WebExtExamples}}</p>
+
+<h3 id="Chrome_示例">Chrome 示例</h3>
+
+<pre class="brush: js">chrome.storage.local.get("kitten", function(items){
+ console.log(items.kitten); // -&gt; {name:"Mog", eats:"mice"}
+});</pre>
+
+<p class="brush: js">Or with an arrow function</p>
+
+<pre class="brush: js">chrome.storage.local.get("kitten", items=&gt;{
+ console.log(items.kitten); // -&gt; {name:"Mog", eats:"mice"}
+});</pre>
+
+<div class="note"><strong>致謝</strong>
+
+<p>This API is based on Chromium's <a href="https://developer.chrome.com/extensions/storage"><code>chrome.storage</code></a> API. This documentation is derived from <a href="https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json"><code>storage.json</code></a> in the Chromium code.</p>
+
+<p>Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.</p>
+</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/api/storage/storagearea/index.html b/files/zh-tw/mozilla/add-ons/webextensions/api/storage/storagearea/index.html
new file mode 100644
index 0000000000..088e8b5a79
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/api/storage/storagearea/index.html
@@ -0,0 +1,85 @@
+---
+title: storage.StorageArea
+slug: Mozilla/Add-ons/WebExtensions/API/storage/StorageArea
+tags:
+ - API
+ - Add-ons
+ - Extensions
+ - NeedsTranslation
+ - Non-standard
+ - Reference
+ - Storage
+ - StorageArea
+ - TopicStub
+ - Type
+ - WebExtensions
+translation_of: Mozilla/Add-ons/WebExtensions/API/storage/StorageArea
+---
+<div>{{AddonSidebar()}}</div>
+
+<p>StorageArea is an object representing a storage area.</p>
+
+<h2 id="Type">Type</h2>
+
+<p>Values of this type are objects.</p>
+
+<h2 id="Methods">Methods</h2>
+
+<dl>
+ <dt>{{WebExtAPIRef("storage.StorageArea.get()")}}</dt>
+ <dd>Retrieves one or more items from the storage area.</dd>
+ <dt>{{WebExtAPIRef("storage.StorageArea.getBytesInUse()")}}</dt>
+ <dd>Gets the amount of storage space (in bytes) used one or more items being stored in the storage area.</dd>
+ <dt>{{WebExtAPIRef("storage.StorageArea.set()")}}</dt>
+ <dd>Stores one or more items in the storage area. If an item already exists, its value will be updated.</dd>
+ <dt>{{WebExtAPIRef("storage.StorageArea.remove()")}}</dt>
+ <dd>Removes one or more items from the storage area.</dd>
+ <dt>{{WebExtAPIRef("storage.StorageArea.clear()")}}</dt>
+ <dd>Removes all items from the storage area.</dd>
+</dl>
+
+<h2 id="Browser_compatibility">Browser compatibility</h2>
+
+<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
+
+<p>{{Compat("webextensions.api.storage.StorageArea")}}</p>
+
+<p>{{WebExtExamples}}</p>
+
+<div class="note"><strong>Acknowledgements</strong>
+
+<p>This API is based on Chromium's <a href="https://developer.chrome.com/extensions/storage#type-StorageArea"><code>chrome.storage</code></a> API. This documentation is derived from <a href="https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/storage.json"><code>storage.json</code></a> in the Chromium code.</p>
+
+<p>Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.</p>
+</div>
+
+<div class="hidden">
+<pre>// Copyright 2015 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</pre>
+</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/content_scripts/index.html b/files/zh-tw/mozilla/add-ons/webextensions/content_scripts/index.html
new file mode 100644
index 0000000000..e767b3ef89
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/content_scripts/index.html
@@ -0,0 +1,444 @@
+---
+title: 內容腳本
+slug: Mozilla/Add-ons/WebExtensions/Content_scripts
+tags:
+ - 擴充套件
+translation_of: Mozilla/Add-ons/WebExtensions/Content_scripts
+---
+<div>{{AddonSidebar}}</div>
+
+<div>內容腳本(content script)是擴充套件的一部分,它會在在特定的網頁執行(與之相對的則是同樣屬於套件</div>
+
+<div>的後端腳本(background scripts)或者網站本身的腳本,像是那些那些透過 {{HTMLElement("script")}} 標籤讀取的內</div>
+
+<div>容)</div>
+
+<div> </div>
+
+<p><a href="/en-US/Add-ons/WebExtensions/Background_scripts">後端腳本</a>可以使用所有的 <a href="/en-US/Add-ons/WebExtensions/API">擴充套件JavaScript APIs</a>,但它們無法直接使用網頁中的內容。所以如果你的套件必須要透過 content scripts 才能使用它們。</p>
+
+<p>就像一般網頁裡的 scripts 一樣,content scripts 可以透過 standard DOM APIs 存取並修改頁面內容。</p>
+
+<p>Content scripts 只能使用can only access <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts#WebExtension_APIs">一小部分的擴充套件APIs</a>,但它們可以透過一個訊息系統<a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts#Communicating_with_background_scripts">來與後端腳本溝通</a>,從而間接地使用擴充套件APIs。</p>
+
+<div class="note">
+<p>留意到 content scripts 目前會在 addons.mozilla.org 和 testpilot.firefox.com 中被阻擋。如果你嘗試在這些網域下的頁面注入一段 content script 會失敗並且在日誌裡記下一個 <a href="/en-US/docs/Web/HTTP/CSP">CSP</a> 錯誤。</p>
+</div>
+
+<div class="note">
+<p>由於錯誤 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1408996">1408996</a>,透過 <code>var foo</code> or <code>window.foo = "bar"</code> 加入 content script 的 global 作用域的值可能會消失。</p>
+</div>
+
+<h2 id="讀入內容腳本">讀入內容腳本</h2>
+
+<p>你可以透過下列三種方式將內容腳本讀入頁面:</p>
+
+<ol>
+ <li><strong>在安裝時讀入至符合URL模式的頁面:</strong>透過你的 manifest.json 中的 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts">content_scripts</a></code> 鍵,你可以要求瀏覽器在每次讀取URL<a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Match_patterns">符合給定模式</a>的頁面時讀入內容腳本。</li>
+ <li><strong>在執行時讀入至符合URL模式的頁面:</strong>透過 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts">content_scripts</a></code> API,你可以要求瀏覽器在每次讀取URL<a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Match_patterns">符合給定模式</a>的頁面時讀入內容腳本。這就像第一種方法,不同的是你可以在執行時增加或移除內容腳本。</li>
+ <li><strong>在執行時讀入至特定的頁籤:透過</strong> <code><a href="/en-US/Add-ons/WebExtensions/API/Tabs/executeScript">tabs.executeScript()</a></code> API,你可以在任何時候將內容腳本讀入特定的頁籤:舉例來說可以在使用者點擊<a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_action">工具列按鈕</a>時給予回應。</li>
+</ol>
+
+<p>每個套件的每個架構裡都只有一個全局作用域,所以一個內容腳本的變數可以直接被其他內容腳本使用,不管那個內容腳本是怎麼被讀入的。</p>
+
+<p>透過方法(1)和方法(2)你只能把內容腳本讀入至URL可以用<a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns">匹配模式</a>來呈現的頁面中。而透過方法3可以把腳本讀入與套件打包在一起的頁面之中,但是你不能在像是 "about:debugging" 或 "about:addons" 這類特別的瀏覽器頁面讀入腳本。</p>
+
+<h2 id="內容腳本環境">內容腳本環境</h2>
+
+<h3 id="使用_DOM">使用 DOM</h3>
+
+<p>內容腳本可以像一般頁面的腳本一樣使用並修改頁面的DOM。它們也可以偵測到所有頁面script 對 DOM 做的更動。</p>
+
+<p>然而,內容腳本看到的是「乾淨的DOM」。這表示:</p>
+
+<ul>
+ <li>內容腳本看不見頁面腳本的 Javascript 變數</li>
+ <li>如果頁面腳本修改了原有DOM的屬性,內容腳本會看見原來的屬性而非被修改過的。</li>
+</ul>
+
+<p>在 Gecko 裡,這種行爲稱爲 <a href="/en-US/docs/Xray_vision">X光視野</a>。</p>
+
+<p>舉例來說,有這樣一個網頁:</p>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta http-equiv="content-type" content="text/html; charset=utf-8" /&gt;
+ &lt;/head&gt;
+
+ &lt;body&gt;
+ &lt;script src="page-scripts/page-script.js"&gt;&lt;/script&gt;
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+
+<p>"page-script.js" 做了這件事:</p>
+
+<pre class="brush: js">// page-script.js
+
+// 替DOM新增一個元素
+var p = document.createElement("p");
+p.textContent = "This paragraph was added by a page script.";
+p.setAttribute("id", "page-script-para");
+document.body.appendChild(p);
+
+// 替 window 定義一個新的屬性
+window.foo = "This global variable was added by a page script";
+
+// 重新定義內建的 window.confirm 函數
+window.confirm = function() {
+ alert("The page script has also redefined 'confirm'");
+}</pre>
+
+<p>接著、一個套件把 content script 插入頁面:</p>
+
+<pre class="brush: js">// content-script.js
+
+// 可以使用與修改DOM
+var pageScriptPara = document.getElementById("page-script-para");
+pageScriptPara.style.backgroundColor = "blue";
+
+// 看不見 page-script 增加的屬性
+console.log(window.foo); // undefined
+
+// 看見的是原有的形式
+window.confirm("Are you sure?"); // 呼叫原本的 window.confirm()</pre>
+
+<p>反過來也是一樣,頁面腳本無法看到內容腳本增加的 Javascript 屬性。</p>
+
+<p>這表示我們可以預期內容腳本依賴著DOM屬性,不需要擔心它的變數與頁面腳本中所定義的變數衝突。</p>
+
+<p>這實際的影響就是內容腳本無法使用所有頁面腳本讀入的函式庫。所以,舉例來說,如果頁面包含了 JQuery,內容腳本將無法看到它。</p>
+
+<p>如果內容腳本真的想要使用 javascript 函式庫,那麼函式庫本身必須要與要使用它的內容腳本一同插入:</p>
+
+<pre class="brush: json">"content_scripts": [
+ {
+ "matches": ["*://*.mozilla.org/*"],
+ "js": ["jquery.js", "content-script.js"]
+ }
+]</pre>
+
+<p>注意到 Firefox 提供了一些API來使用被頁面腳本產生的 Javascript 物件以及對頁面腳本公開自己的 Javascript 物件。詳閱<a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts">與頁面腳本共用物件</a>。</p>
+
+<h3 id="擴充套件APIs">擴充套件APIs</h3>
+
+<p>除標準DOM APIs之外,內容腳本可以使用下列 擴充套件APIs:</p>
+
+<p>來自 <code><a href="/en-US/Add-ons/WebExtensions/API/extension">extension</a></code>:</p>
+
+<ul>
+ <li><code><a href="/en-US/Add-ons/WebExtensions/API/extension#getURL()">getURL()</a></code></li>
+ <li><code><a href="/en-US/Add-ons/WebExtensions/API/extension#inIncognitoContext">inIncognitoContext</a></code></li>
+</ul>
+
+<p>來自 <code><a href="/en-US/Add-ons/WebExtensions/API/runtime">runtime</a></code>:</p>
+
+<ul>
+ <li><code><a href="/en-US/Add-ons/WebExtensions/API/runtime#connect()">connect()</a></code></li>
+ <li><code><a href="/en-US/Add-ons/WebExtensions/API/runtime#getManifest()">getManifest()</a></code></li>
+ <li><code><a href="/en-US/Add-ons/WebExtensions/API/runtime#getURL()">getURL()</a></code></li>
+ <li><code><a href="/en-US/Add-ons/WebExtensions/API/runtime#onConnect">onConnect</a></code></li>
+ <li><code><a href="/en-US/Add-ons/WebExtensions/API/runtime#onMessage">onMessage</a></code></li>
+ <li><code><a href="/en-US/Add-ons/WebExtensions/API/runtime#sendMessage()">sendMessage()</a></code></li>
+</ul>
+
+<p>來自 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n">i18n</a></code>:</p>
+
+<ul>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/getMessage">getMessage()</a></code></li>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/getAcceptLanguages">getAcceptLanguages()</a></code></li>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/getUILanguage">getUILanguage()</a></code></li>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/detectLanguage">detectLanguage()</a></code></li>
+</ul>
+
+<p>來自 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage">storage</a></code> 的全部。</p>
+
+<h3 id="XHR_與_Fetch">XHR 與 Fetch</h3>
+
+<p>內容腳本可以透過一般的 <code><a href="/en-US/docs/Web/API/XMLHttpRequest">window.XMLHttpRequest</a></code> 與 <code><a href="/en-US/docs/Web/API/Fetch_API">window.fetch()</a></code> APIs 來發出請求。</p>
+
+<p>內容腳本跟套件的其他部分擁有相同的跨網域權限: 所以如果套件在 manifest.json 中透過 <code><a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json/permissions">permissions</a></code> 鍵要求了某一網域的使用,那麼它的內容腳本也能使用同樣的網域。</p>
+
+<p>這是透過公開更多內容腳本中授權的XHR以及fetch實例來達成的。這件事情會導致標頭中不會設置 <code><a href="/en-US/docs/Web/HTTP/Headers/Origin">Origin</a></code> 與 <code><a href="/en-US/docs/Web/HTTP/Headers/Referer">Referer</a></code>的副作用,就像頁面請求自己一樣,一般會避免請求將跨來源泄露出去。從58版本號以後套件要傳送一些彷彿是頁面內容自己傳送的請求時可以改用 <code>content.XMLHttpRequest</code> 與 <code>content.fetch()</code>。對跨瀏覽器套件來說,這些事情的存在必須要能被做特徵檢測。</p>
+
+<h2 id="與後端腳本溝通">與後端腳本溝通</h2>
+
+<p>雖然內容腳本不能直接使用大部分的 擴充套件APIs,但是透過使用訊息APIs與後端腳本溝通,它們能夠間接地使用與後端腳本一樣的 APIs。</p>
+
+<p>後端腳本與內容腳本的溝通模式有兩種: 你可以傳送選擇性夾帶回應的一次性訊息,也可以在兩者之間建立一個長存的連線來交換訊息。</p>
+
+<h3 id="一次性訊息">一次性訊息</h3>
+
+<p>要傳送選擇性夾帶回應的一次性訊息,你可以使用下列APIs:</p>
+
+<table class="fullwidth-table standard-table">
+ <thead>
+ <tr>
+ <th scope="row"> </th>
+ <th scope="col">在內容腳本處</th>
+ <th scope="col">在後端腳本處</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th scope="row">傳訊息</th>
+ <td><code><a href="/en-US/Add-ons/WebExtensions/API/runtime/sendMessage">browser.runtime.sendMessage()</a></code></td>
+ <td><code><a href="/en-US/Add-ons/WebExtensions/API/Tabs/sendMessage">browser.tabs.sendMessage()</a></code></td>
+ </tr>
+ <tr>
+ <th scope="row">收訊息</th>
+ <td><code><a href="/en-US/Add-ons/WebExtensions/API/runtime/onMessage">browser.runtime.onMessage</a></code></td>
+ <td><code><a href="/en-US/Add-ons/WebExtensions/API/runtime/onMessage">browser.runtime.onMessage</a></code></td>
+ </tr>
+ </tbody>
+</table>
+
+<p>舉例來說,有個監聽著頁面點擊事件的內容腳本。如果點擊對象是連結,它會傳送目標的URL給後端腳本:</p>
+
+<pre class="brush: js">// content-script.js
+
+window.addEventListener("click", notifyExtension);
+
+function notifyExtension(e) {
+ if (e.target.tagName != "A") {
+ return;
+ }
+ browser.runtime.sendMessage({"url": e.target.href});
+}</pre>
+
+<p>後端腳本監聽這些訊息並且透過 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications">notifications</a></code> API 顯示通知:</p>
+
+<pre class="brush: js">// background-script.js
+
+browser.runtime.onMessage.addListener(notify);
+
+function notify(message) {
+ browser.notifications.create({
+ "type": "basic",
+ "iconUrl": browser.extension.getURL("link.png"),
+ "title": "你點了個按鈕喲!",
+ "message": message.url
+ });
+}
+</pre>
+
+<p>這個範例來自 GitHub上的 <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n </a>,稍微經過修改。</p>
+
+<h3 id="基於連線的訊息">基於連線的訊息</h3>
+
+<p>當你在後端腳本與內容腳本間交換大量訊息時,使用一次性連線顯得沒效率。所以另一個替代方案是是在兩者間建立一個長存的連線,透過這個連線交換訊息。</p>
+
+<p>兩邊都有一個 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/Port">runtime.Port</a></code> 物件可以用來交換訊息。</p>
+
+<p>建立連線你需要:</p>
+
+<ul>
+ <li>一邊透過 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onConnect">runtime.onConnect</a></code> 監聽連線</li>
+ <li>另一邊呼叫 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/connect">tabs.connect()</a></code> (對內容腳本建立連線時)或 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/connect">runtime.connect()</a></code> (對後端腳本建立連線時)。這會回傳一個 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/Port">runtime.Port</a></code> 物件。</li>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onConnect">runtime.onConnect</a></code> 監聽器傳送自己的 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/Port">runtime.Port</a></code> 物件。</li>
+</ul>
+
+<p>當兩邊都有端口後,可以透過 <code>runtime.Port.postMessage()</code> 來傳送訊息,用 <code>runtime.Port.onMessage</code> 接收訊息。</p>
+
+<p>舉例來說,當這讀取完成,這個內容腳本會:</p>
+
+<ul>
+ <li>連線至後端腳本,並將 <code>Port</code> 儲存在一個 <code>myPort</code> 變數</li>
+ <li>監聽並記錄 <code>myPort</code> 的訊息</li>
+ <li>當使用者點擊文件時,透過 <code>myPort</code> 傳送訊息給後端腳本</li>
+</ul>
+
+<pre class="brush: js">// content-script.js
+
+var myPort = browser.runtime.connect({name:"port-from-cs"});
+myPort.postMessage({greeting: "內容腳本傳喜訊"});
+
+myPort.onMessage.addListener(function(m) {
+ console.log("內容腳本收到來自後端腳本的訊息: ");
+ console.log(m.greeting);
+});
+
+document.body.addEventListener("click", function() {
+ myPort.postMessage({greeting: "它們點了網頁!"});
+});</pre>
+
+<p>同樣地,後端腳本會:</p>
+
+<ul>
+ <li>監聽來自內容腳本的連線請求</li>
+ <li>當它收到連線請求:
+ <ul>
+ <li>將端口儲存在 <code>portFromCS 這個變數</code></li>
+ <li>透過端口傳送訊息給內容腳本</li>
+ <li>開始監聽並記錄端口上的訊息</li>
+ </ul>
+ </li>
+ <li>當使用者點擊套件的工具列按鈕時,透過 <code>portFromCS</code> 傳送訊息給內容腳本</li>
+</ul>
+
+<pre class="brush: js">// background-script.js
+
+var portFromCS;
+
+function connected(p) {
+ portFromCS = p;
+ portFromCS.postMessage({greeting: "嘿!內容腳本!"});
+ portFromCS.onMessage.addListener(function(m) {
+ console.log("後端腳本收到來自內容腳本的訊息:")
+ console.log(m.greeting);
+ });
+}
+
+browser.runtime.onConnect.addListener(connected);
+
+browser.browserAction.onClicked.addListener(function() {
+ portFromCS.postMessage({greeting: "它們按了按鈕!"});
+});
+</pre>
+
+<h4 id="複數內容腳本">複數內容腳本</h4>
+
+<p>如果你有多個內容腳本同時在溝通,你可能會想把這些連線儲存在陣列裡面。</p>
+
+<p> </p>
+
+<ul>
+</ul>
+
+<pre class="brush: js">// background-script.js
+
+var ports = []
+
+function connected(p) {
+ ports[p.sender.tab.id]    = p
+ //...
+}
+
+browser.runtime.onConnect.addListener(connected)
+
+browser.browserAction.onClicked.addListener(function() {
+ ports.forEach(p =&gt; {
+        p.postMessage({greeting: "它們按了按鈕!"})
+    })
+});</pre>
+
+<p> </p>
+
+<ul>
+</ul>
+
+<h2 id="與網頁溝通">與網頁溝通</h2>
+
+<p>雖說內容腳本預設不能存取頁面腳本產生的物件,但它們可以透過DOM <code><a href="/en-US/docs/Web/API/Window/postMessage">window.postMessage</a></code> 和 <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">window.addEventListener</a></code> APIs與頁面腳本溝通。</p>
+
+<p>例如:</p>
+
+<pre class="brush: js">// page-script.js
+
+var messenger = document.getElementById("from-page-script");
+
+messenger.addEventListener("click", messageContentScript);
+
+function messageContentScript() {
+ window.postMessage({
+ direction: "from-page-script",
+ message: "Message from the page"
+ }, "*");</pre>
+
+<pre class="brush: js">// content-script.js
+
+window.addEventListener("message", function(event) {
+ if (event.source == window &amp;&amp;
+ event.data &amp;&amp;
+ event.data.direction == "from-page-script") {
+ alert("內容腳本收到訊息: \"" + event.data.message + "\"");
+ }
+});</pre>
+
+<p>完全版的範例請<a href="https://mdn.github.io/webextensions-examples/content-script-page-script-messaging.html">查看GitHub上的示範頁面</a>並按照教學做。</p>
+
+<div class="warning">
+<p>注意到當你透過這個方式跟不被信任的內容腳本互動時要非常小心。套件有很強的權限,惡意網頁可以輕易地騙出這些權限。</p>
+
+<p>舉個簡單的例子,假設一接收訊息的內容腳本長這樣:</p>
+
+<pre class="brush: js">// content-script.js
+
+window.addEventListener("message", function(event) {
+ if (event.source == window &amp;&amp;
+ event.data.direction &amp;&amp;
+ event.data.direction == "from-page-script") {
+ eval(event.data.message);
+ }
+});</pre>
+
+<p>如此一來頁面腳本可以使用包含內容腳本全部權限的程式碼。</p>
+</div>
+
+<h2 id="在內容腳本中使用_eval()">在內容腳本中使用 eval()</h2>
+
+<p>在 Chrome 裡, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval">eval()</a></code> 只會在內容腳本而不會在頁面腳本裡執行。</p>
+
+<p>在 Firefox 裡:</p>
+
+<ul>
+ <li>如果你呼叫 <code>eval()</code>,它會在內容腳本中執行</li>
+ <li>如果你呼叫 <code>window.eval()</code>,它會在頁面腳本中執行</li>
+</ul>
+
+<p>例如,試想有一個內容腳本長這樣:</p>
+
+<pre class="brush: js">// content-script.js
+
+window.eval('window.x = 1;');
+eval('window.y = 2');
+
+console.log(`In content script, window.x: ${window.x}`);
+console.log(`In content script, window.y: ${window.y}`);
+
+window.postMessage({
+ message: "check"
+}, "*");</pre>
+
+<p>這段程式碼透過 <code>window.eval()</code> 和 <code>eval()</code> 建立了些變數 x 和 y 、記錄下它們的值並且傳訊息給頁面。</p>
+
+<p>接收訊息這邊,頁面腳本記錄下一樣的值:</p>
+
+<pre class="brush: js">window.addEventListener("message", function(event) {
+ if (event.source === window &amp;&amp; event.data &amp;&amp; event.data.message === "check") {
+ console.log(`In page script, window.x: ${window.x}`);
+ console.log(`In page script, window.y: ${window.y}`);
+ }
+});</pre>
+
+<p>在 Chrome 裡,這會產出這樣的結果:</p>
+
+<pre>In content script, window.x: 1
+In content script, window.y: 2
+In page script, window.x: undefined
+In page script, window.y: undefined</pre>
+
+<p>而在 Firefox 裡會產生這些:</p>
+
+<pre>In content script, window.x: undefined
+In content script, window.y: 2
+In page script, window.x: 1
+In page script, window.y: undefined</pre>
+
+<p>這些也適用於 <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout()</a></code>、 <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a></code>、與 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function">Function()</a></code>。</p>
+
+<p>當在頁面執行程式碼時一定要小一萬個心,頁面的環境有可能被惡意的網頁所控制,它們可以重新定義與你互動的物件來作出一些出乎意料的行爲:</p>
+
+<pre class="brush: js">// page.js 重新定義 console.log
+
+var original = console.log;
+
+console.log = function() {
+  original(true);
+}
+</pre>
+
+<pre class="brush: js">// content-script.js 呼叫被重新定義的版本
+
+window.eval('console.log(false)');
+</pre>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/index.html b/files/zh-tw/mozilla/add-ons/webextensions/index.html
new file mode 100644
index 0000000000..bf6499baac
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/index.html
@@ -0,0 +1,115 @@
+---
+title: 瀏覽器擴充功能
+slug: Mozilla/Add-ons/WebExtensions
+tags:
+ - NeedsTranslation
+ - TopicStub
+translation_of: Mozilla/Add-ons/WebExtensions
+---
+<div>{{AddonSidebar}}</div>
+
+<p>擴充功能(extension)可以擴展和修改瀏覽器的功能。Firefox 的擴充功能是使用 WebExtension API 建立而成,這是一個開發跨瀏覽器擴充功能的系統。這個系統的大部分相容於 Google Chrome 和 Opera 的 <a class="external-icon external" href="https://developer.chrome.com/extensions">擴充功能 API</a> 與 <a href="https://browserext.github.io/browserext/">W3C Draft Community Group</a>。這些瀏覽器的擴充功能在大多數的情況下,只需要<a href="https://developer.mozilla.org/zh-TW/Add-ons/WebExtensions/Porting_from_Google_Chrome">一點改變</a>就可以在 Firefox 或 <a href="https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/extensions/">Microsoft Edge</a> 中執行。這個 API 也和<a href="https://developer.mozilla.org/zh-TW/Firefox/Multiprocess_Firefox">多處理程序的 Firefox</a> 完全相容。</p>
+
+<p>如果你有任何新點子、問題,或是需要使用 WebExtension API 來移植舊的擴充功能,你可以在 <a href="https://mail.mozilla.org/listinfo/dev-addons">dev-addons 郵件群組</a>或 <a href="https://wiki.mozilla.org/IRC">IRC</a> 上的 <a href="irc://irc.mozilla.org/extdev">#extdev</a> 找到我們。</p>
+
+<div class="row topicpage-table">
+<div class="section">
+<h2 id="開始入門">開始入門</h2>
+
+<ul>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/What_are_WebExtensions">何謂擴充功能?</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Your_first_WebExtension">你的第一個 WebExtension</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Your_second_WebExtension">你的第二個 WebExtension</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Anatomy_of_a_WebExtension">解析 WebExtension</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Examples">WebExtension 範例</a></li>
+</ul>
+
+<h2 id="如何……">如何……</h2>
+
+<ul>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Intercept_HTTP_requests">監看 HTTP 請求</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Modify_a_web_page">修改網頁</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar">在工作列增加按鈕</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Implement_a_settings_page">建立設定頁面</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard">和剪貼簿互動</a></li>
+</ul>
+
+<h2 id="使用者介面">使用者介面</h2>
+
+<ul>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface">介紹</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_action">工具列按鈕</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups">有彈出框的工具列按鈕</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Page_actions">網址列按鈕</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups">有彈出框的網址列按鈕</a><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Page_actions">網址列按鈕</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars">側邊欄</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items">右鍵選單</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Options_pages">設定頁面</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Bundled_web_pages">附加頁面</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Notifications">通知</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/Omnibox">網址列建議</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels">開發者工具面板</a></li>
+</ul>
+
+<h2 id="概念">概念</h2>
+
+<ul>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/API">JavaScript API 總覽</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Content_scripts">內容腳本</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Match_patterns">觸發條件</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Working_with_files">檔案控制</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Internationalization">國際化</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy">資訊安全聲明</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Native_messaging">原生溝通方式</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Using_the_devtools_APIs">使用開發工具 APIs</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/User_experience_best_practices">UX 範例</a></li>
+</ul>
+
+<h2 id="移植">移植</h2>
+
+<ul>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Porting_from_Google_Chrome">移植 Google Chrome 的擴充功能</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Porting_a_legacy_Firefox_add-on">移植舊的 Firefox 附加元件</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Embedded_WebExtensions">嵌入式 WebExtensions</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Comparison_with_the_Add-on_SDK">與附加元件 SDK 比較</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Comparison_with_XUL_XPCOM_extensions">與 XUL/XPCOM 比較</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities">Chrome 衝突表</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Differences_between_desktop_and_Android">桌面版與 Android 版的差異</a></li>
+</ul>
+
+<h2 id="Firefox_工作流程">Firefox 工作流程</h2>
+
+<ul>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/User_experience_best_practices">UX</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Temporary_Installation_in_Firefox">安裝</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Debugging">除錯</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Developing_WebExtensions_for_Firefox_for_Android">在 Firefox for Android 上開發</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Getting_started_with_web-ext">開始使用 web-ext</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/web-ext_command_reference">web-ext 指令參考</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/WebExtensions_and_the_Add-on_ID">WebExtensions 和附加元件 ID</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Publishing_your_WebExtension">發布你的 WebExtension</a></li>
+</ul>
+</div>
+
+<div class="section">
+<h2 id="參考資料">參考資料</h2>
+
+<h4 id="JavaScript_APIs">JavaScript APIs</h4>
+
+<ul>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/API">JavaScript API 總覽</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Browser_support_for_JavaScript_APIs">JavaScript APIs 在各種瀏覽器的相容表</a></li>
+</ul>
+
+<div class="twocolumns">{{ ListSubpages ("/zh-TW/Add-ons/WebExtensions/API") }}</div>
+
+<h4 id="Manifest_keys">Manifest keys</h4>
+
+<ul>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json 總覽</a></li>
+ <li><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Browser_compatibility_for_manifest.json">manifest.json 在各種瀏覽器的相容表</a></li>
+</ul>
+
+<div class="twocolumns">{{ ListSubpages ("/zh-TW/Add-ons/WebExtensions/manifest.json") }}</div>
+</div>
+</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/internationalization/index.html b/files/zh-tw/mozilla/add-ons/webextensions/internationalization/index.html
new file mode 100644
index 0000000000..7c521177a3
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/internationalization/index.html
@@ -0,0 +1,400 @@
+---
+title: Internationalization
+slug: Mozilla/Add-ons/WebExtensions/Internationalization
+translation_of: Mozilla/Add-ons/WebExtensions/Internationalization
+---
+<div>{{AddonSidebar}}</div>
+
+<p><a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions">WebExtension</a> API 有個相當方便、能用於國際化的模組:<a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/API/i18n">i18n</a>。我們將在這篇文章內探索本功能,並提供實際做動的範例。專供 extensions 組建所使用的 i18n 系統 API,用法與坊間諸如 <a href="http://i18njs.com/">i18n.js</a> 的函式庫相似。</p>
+
+<div class="note">
+<p>本例所使用的套件:<a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a> 能在 GitHub 找到。看各章節時,請配著原始碼觀看。</p>
+</div>
+
+<h2 id="剖析國際化的套件">剖析國際化的套件</h2>
+
+<p>國際化套件能包含與其他套件相同的功能:<a href="/zh-TW/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts">background scripts</a>、<a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">content scripts</a>……等。但它也擁有一些能允許在語言間切換的部份。目錄樹大概是這樣:</p>
+
+<ul class="directory-tree">
+ <li>extension-root-directory/
+ <ul>
+ <li>_locales
+ <ul>
+ <li>en
+ <ul>
+ <li>messages.json
+ <ul>
+ <li>English messages (strings)</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>de
+ <ul>
+ <li>messages.json
+ <ul>
+ <li>German messages (strings)</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>etc.</li>
+ </ul>
+ </li>
+ <li>manifest.json
+ <ul>
+ <li>locale-dependent metadata</li>
+ </ul>
+ </li>
+ <li>myJavascript.js
+ <ul>
+ <li>JavaScript for retrieving browser locale, locale-specific messages, etc.</li>
+ </ul>
+ </li>
+ <li>myStyles.css
+ <ul>
+ <li>locale-dependent CSS</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+</ul>
+
+<p>我們將逐一探索各大新特性:章節的每個部份,都是要國際化套件時,所需遵循的步驟。</p>
+
+<h2 id="在__locales_提供本地化的字串">在 _locales 提供本地化的字串</h2>
+
+<div class="pull-aside">
+<div class="moreinfo">You can look up language subtags using the <em>Find</em> tool on the <a href="http://r12a.github.io/apps/subtags/">Language subtag lookup page</a>. Note that you need to search for the English name of the language.</div>
+</div>
+
+<p>Every i18n system requires the provision of strings translated into all the different locales you want to support. In extensions, these are contained within a directory called <code>_locales</code>, placed inside the extension root. Each individual locale has its strings (referred to as messages) contained within a file called <code>messages.json</code>, which is placed inside a subdirectory of <code>_locales</code>, named using the language subtag for that locale's language.</p>
+
+<p>Note that if the subtag includes a basic language plus a regional variant, then the language and variant are conventionally separated using a hyphen: for example, "en-US". However, in the directories under <code>_locales</code>, <strong>the separator must be an underscore</strong>: "en_US".</p>
+
+<p>So <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n/_locales">for example, in our sample app</a> we have directories for "en" (English), "de" (German), "nl" (Dutch), and "ja" (Japanese). Each one of these has a <code>messages.json</code> file inside it.</p>
+
+<p>Let's now look at the structure of one of these files (<a href="https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/_locales/en/messages.json">_locales/en/messages.json</a>):</p>
+
+<pre class="brush: json">{
+ "extensionName": {
+ "message": "Notify link clicks i18n",
+ "description": "Name of the extension."
+ },
+
+ "extensionDescription": {
+ "message": "Shows a notification when the user clicks on links.",
+ "description": "Description of the extension."
+ },
+
+ "notificationTitle": {
+ "message": "Click notification",
+ "description": "Title of the click notification."
+ },
+
+ "notificationContent": {
+ "message": "You clicked $URL$.",
+ "description": "Tells the user which link they clicked.",
+ "placeholders": {
+      "url" : {
+        "content" : "$1",
+        "example" : "https://developer.mozilla.org"
+      }
+    }
+ }
+}</pre>
+
+<p>This file is standard JSON — each one of its members is an object with a name, which contains a <code>message</code> and a <code>description</code>. All of these items are strings; <code>$URL$</code> is a placeholder, which is replaced with a substring at the time the <code>notificationContent</code> member is called by the extension. You'll learn how to do this in the {{anch("Retrieving message strings from JavaScript")}} section.</p>
+
+<div class="note">
+<p><strong>Note</strong>: You can find much more information about the contents of <code>messages.json</code> files in our <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/Locale-Specific_Message_reference">Locale-Specific Message reference</a>.</p>
+</div>
+
+<h2 id="Internationalizing_manifest.json">Internationalizing manifest.json</h2>
+
+<p>There are a couple of different tasks to carry out to internationalize your manifest.json.</p>
+
+<h3 id="Retrieving_localized_strings_in_manifests">Retrieving localized strings in manifests</h3>
+
+<p>Your <a href="https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/manifest.json">manifest.json</a> includes strings that are displayed to the user, such as the extension's name and description. If you internationalize these strings and put the appropriate translations of them in messages.json, then the correct translation of the string will be displayed to the user, based on the current locale, like so.</p>
+
+<p>To internationalize strings, specify them like this:</p>
+
+<pre class="brush: json">"name": "__MSG_extensionName__",
+"description": "__MSG_extensionDescription__",</pre>
+
+<p>Here, we are retrieving message strings dependant on the browser's locale, rather than just including static strings.</p>
+
+<p>To call a message string like this, you need to specify it like this:</p>
+
+<ol>
+ <li>Two underscores, followed by</li>
+ <li>The string "MSG", followed by</li>
+ <li>One underscore, followed by</li>
+ <li>The name of the message you want to call as defined in <code>messages.json</code>, followed by</li>
+ <li>Two underscores</li>
+</ol>
+
+<pre><strong>__MSG_</strong> + <em>messageName</em> + <strong>__</strong></pre>
+
+<h3 id="Specifying_a_default_locale">Specifying a default locale</h3>
+
+<p>Another field you should specify in your manifest.json is <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/default_locale">default_locale</a>:</p>
+
+<pre class="brush: json">"default_locale": "en"</pre>
+
+<p>This specifies a default locale to use if the extension doesn't include a localized string for the browser's current locale. Any message strings that are not available in the browser locale are taken from the default locale instead. There are some more details to be aware of in terms of how the browser selects strings — see {{anch("Localized string selection")}}.</p>
+
+<h2 id="Locale-dependent_CSS">Locale-dependent CSS</h2>
+
+<p>Note that you can also retrieve localized strings from CSS files in the extension. For example, you might want to construct a locale-dependent CSS rule, like this:</p>
+
+<pre class="brush: css">header {
+ background-image: url(../images/__MSG_extensionName__/header.png);
+}</pre>
+
+<p>This is useful, although you might be better off handling such a situation using {{anch("Predefined messages")}}.</p>
+
+<h2 id="Retrieving_message_strings_from_JavaScript">Retrieving message strings from JavaScript</h2>
+
+<p>So, you've got your message strings set up, and your manifest. Now you just need to start calling your message strings from JavaScript so your extension can talk the right language as much as possible. The actual <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n">i18n API</a> is pretty simple, containing just four main methods:</p>
+
+<ul>
+ <li>You'll probably use {{WebExtAPIRef("i18n.getMessage()")}} most often — this is the method you use to retrieve a specific language string, as mentioned above. We'll see specific usage examples of this below.</li>
+ <li>The {{WebExtAPIRef("i18n.getAcceptLanguages()")}} and {{WebExtAPIRef("i18n.getUILanguage()")}} methods could be used if you needed to customize the UI depending on the locale — perhaps you might want to show preferences specific to the users' preferred languages higher up in a prefs list, or display cultural information relevant only to a certain language, or format displayed dates appropriately according to the browser locale.</li>
+ <li>The {{WebExtAPIRef("i18n.detectLanguage()")}} method could be used to detect the language of user-submitted content, and format it appropriately.</li>
+</ul>
+
+<p>In our <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a> example, the<a href="https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/background-script.js"> background script</a> contains the following lines:</p>
+
+<pre class="brush: js">var title = browser.i18n.getMessage("notificationTitle");
+var content = browser.i18n.getMessage("notificationContent", message.url);</pre>
+
+<p>The first one just retrieves the <code>notificationTitle message</code> field from the available <code>messages.json</code> file most appropriate for the browser's current locale. The second one is similar, but it is being passed a URL as a second parameter. What gives? This is how you specify the content to replace the <code>$URL$</code> placeholder we see in the <code>notificationContent message</code> field:</p>
+
+<pre class="brush: json">"notificationContent": {
+ "message": "You clicked $URL$.",
+ "description": "Tells the user which link they clicked.",
+ "placeholders": {
+ "url" : {
+ "content" : "$1",
+ "example" : "https://developer.mozilla.org"
+ }
+ }
+}
+</pre>
+
+<p>The <code>"placeholders"</code> member defines all the placeholders, and where they are retrieved from. The <code>"url"</code> placeholder specifies that its content is taken from $1, which is the first value given inside the second parameter of <code>getMessage()</code>. Since the placeholder is called <code>"url"</code>, we use <code>$URL$</code> to call it inside the actual message string (so for <code>"name"</code> you'd use <code>$NAME$</code>, etc.) If you have multiple placeholders, you can provide them inside an array that is given to {{WebExtAPIRef("i18n.getMessage()")}} as the second parameter — <code>[a, b, c]</code> will be available as <code>$1</code>, <code>$2</code>, and <code>$3</code>, and so on, inside <code>messages.json</code>.</p>
+
+<p>Let's run through an example: the original <code>notificationContent</code> message string in the <code>en/messages.json</code> file is</p>
+
+<pre>You clicked $URL$.</pre>
+
+<p>Let's say the link clicked on points to <code>https://developer.mozilla.org</code>. After the {{WebExtAPIRef("i18n.getMessage()")}} call, the contents of the second parameter are made available in messages.json as <code>$1</code>, which replaces the <code>$URL$</code> placeholder as defined in the <code>"url"</code> placeholder. So the final message string is</p>
+
+<pre>You clicked https://developer.mozilla.org.</pre>
+
+<h3 id="Direct_placeholder_usage">Direct placeholder usage</h3>
+
+<p>It is possible to insert your variables (<code>$1</code>, <code>$2</code>, <code>$3</code>, etc.) directly into the message strings, for example we could rewrite the above <code>"notificationContent"</code> member like this:</p>
+
+<pre class="brush: json">"notificationContent": {
+ "message": "You clicked $1.",
+ "description": "Tells the user which link they clicked."
+}</pre>
+
+<p>This may seem quicker and less complex, but the other way (using <code>"placeholders"</code>) is seen as best practice. This is because having the placeholder name (e.g. <code>"url"</code>) and example helps you to remember what the placeholder is for — a week after you write your code, you'll probably forget what <code>$1</code>–<code>$8</code> refer to, but you'll be more likely to know what your placeholder names refer to.</p>
+
+<h3 id="Hardcoded_substitution">Hardcoded substitution</h3>
+
+<p>It is also possible to include hardcoded strings in placeholders, so that the same value is used every time, instead of getting the value from a variable in your code. For example:</p>
+
+<pre class="brush: json">"mdn_banner": {
+ "message": "For more information on web technologies, go to $MDN$.",
+ "description": "Tell the user about MDN",
+ "placeholders": {
+ "mdn": {
+ "content": "https://developer.mozilla.org/"
+ }
+ }
+}</pre>
+
+<p>In this case we are just hardcoding the placeholder content, rather than getting it from a variable value like <code>$1</code>. This can sometimes be useful when your message file is very complex, and you want to split up different values to make the strings more readable in the file, plus then these values could be accessed programmatically.</p>
+
+<p>In addition, you can use such substitutions to specify parts of the string that you don't want to be translated, such as person or business names.</p>
+
+<h2 id="Localized_string_selection">Localized string selection</h2>
+
+<p>Locales can be specified using only a language code, like <code>fr</code> or <code>en</code>, or they may be further qualified with a region code, like <code>en_US</code> or <code>en_GB</code>, which describes a regional variant of the same basic language. When you ask the i18n system for a string, it will select a string using the following algorithm:</p>
+
+<ol>
+ <li>if there is a <code>messages.json</code> file for the exact current locale, and it contains the string, return it.</li>
+ <li>Otherwise, if the current locale is qualified with a region (e.g. <code>en_US</code>) and there is a <code>messages.json</code> file for the regionless version of that locale (e.g. <code>en</code>), and that file contains the string, return it.</li>
+ <li>Otherwise, if there is a <code>messages.json</code> file for the <code>default_locale</code> defined in the <code>manifest.json</code>, and it contains the string, return it.</li>
+ <li>Otherwise return an empty string.</li>
+</ol>
+
+<p>Take the following example:</p>
+
+<ul class="directory-tree">
+ <li>extension-root-directory/
+ <ul>
+ <li>_locales
+ <ul>
+ <li>en_GB
+ <ul>
+ <li>messages.json
+ <ul>
+ <li><code>{ "colorLocalised": { "message": "colour", "description": "Color." }, ... }</code></li>
+ </ul>
+ </li>
+ </ul>
+ en
+
+ <ul>
+ <li>messages.json
+ <ul>
+ <li><code>{ "colorLocalised": { "message": "color", "description": "Color." }, ... }</code></li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>fr
+ <ul>
+ <li>messages.json
+ <ul>
+ <li><code>{ "colorLocalised": { "message": "<span lang="fr">couleur</span>", "description": "Color." }, ...}</code></li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+</ul>
+
+<p>Suppose the <code>default_locale</code> is set to <code>fr</code>, and the browser's current locale is <code>en_GB</code>:</p>
+
+<ul>
+ <li>If the extension calls <code>getMessage("colorLocalised")</code>, it will return "colour".</li>
+ <li>If "colorLocalised" were not present in <code>en_GB</code>, then <code>getMessage("colorLocalised")</code>, would return "color", not "couleur".</li>
+</ul>
+
+<h2 id="Predefined_messages">Predefined messages</h2>
+
+<p>The i18n module provides us with some predefined messages, which we can call in the same way as we saw earlier in {{anch("Calling message strings from manifests and extension CSS")}}. For example:</p>
+
+<pre>__MSG_extensionName__</pre>
+
+<p>Predefined messages use exactly the same syntax, except with <code>@@</code> before the message name, for example</p>
+
+<pre>__MSG_@@ui_locale__</pre>
+
+<p>The following table shows the different available predefined messages:</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Message name</th>
+ <th scope="col">Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>@@extension_id</code></td>
+ <td>
+ <p>The extension's internally-generated UUID. You might use this string to construct URLs for resources inside the extension. Even unlocalized extensions can use this message.</p>
+
+ <p>You can't use this message in a manifest file.</p>
+
+ <p>Also note that this ID is <em>not</em> the add-on ID returned by {{WebExtAPIRef("runtime.id")}}, and that can be set using the <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/applications">applications</a> key in manifest.json. It's the generated UUID that appears in the add-on's URL. This means that you can't use this value as the <code>extensionId</code> parameter to {{WebExtAPIRef("runtime.sendMessage()")}}, and can't use it to check against the <code>id</code> property of a {{WebExtAPIRef("runtime.MessageSender")}} object.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>@@ui_locale</code></td>
+ <td>The current locale; you might use this string to construct locale-specific URLs.</td>
+ </tr>
+ <tr>
+ <td><code>@@bidi_dir</code></td>
+ <td>The text direction for the current locale, either "ltr" for left-to-right languages such as English or "rtl" for right-to-left languages such as Arabic.</td>
+ </tr>
+ <tr>
+ <td><code>@@bidi_reversed_dir</code></td>
+ <td>If the <code>@@bidi_dir</code> is "ltr", then this is "rtl"; otherwise, it's "ltr".</td>
+ </tr>
+ <tr>
+ <td><code>@@bidi_start_edge</code></td>
+ <td>If the <code>@@bidi_dir</code> is "ltr", then this is "left"; otherwise, it's "right".</td>
+ </tr>
+ <tr>
+ <td><code>@@bidi_end_edge</code></td>
+ <td>If the <code>@@bidi_dir</code> is "ltr", then this is "right"; otherwise, it's "left".</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Going back to our earlier example, it would make more sense to write it like this:</p>
+
+<pre class="brush: css">header {
+ background-image: url(../images/__MSG_@@ui_locale__/header.png);
+}</pre>
+
+<p>Now we can just store our local specific images in directories that match the different locales we are supporting — en, de, etc. — which makes a lot more sense.</p>
+
+<p>Let's look at an example of using <code>@@bidi_*</code> messages in a CSS file:</p>
+
+<pre class="brush: css">body {
+ direction: __MSG_@@bidi_dir__;
+}
+
+div#header {
+ margin-bottom: 1.05em;
+ overflow: hidden;
+ padding-bottom: 1.5em;
+ padding-__MSG_@@bidi_start_edge__: 0;
+ padding-__MSG_@@bidi_end_edge__: 1.5em;
+ position: relative;
+}</pre>
+
+<p>For left-to-right languages such as English, the CSS declarations involving the predefined messages above would translate to the following final code lines:</p>
+
+<pre class="brush: css">direction: ltr;
+padding-left: 0;
+padding-right: 1.5em;
+</pre>
+
+<p>For a right-to-left language like Arabic, you'd get:</p>
+
+<pre class="brush: css">direction: rtl;
+padding-right: 0;
+padding-left: 1.5em;</pre>
+
+<h2 id="Testing_out_your_extension">Testing out your extension</h2>
+
+<p>Starting in Firefox 45, you can install extensions temporarily from disk — see <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Packaging_and_installation#Loading_from_disk">Loading from disk</a>. Do this, and then try testing out our <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a> extension. Go to one of your favourite websites and click a link to see if a notification appears reporting the URL of the clicked link.</p>
+
+<p>Next, change Firefox's locale to one supported in the extension that you want to test.</p>
+
+<ol>
+ <li>Open "about:config" in Firefox, and search for the <code>general.useragent.locale</code> preference.</li>
+ <li>Double click on the preference (or press Return/Enter) to select it, enter the language code for the locale you want to test, then click "OK" (or press Return/Enter). For example in our example extension, "en" (English), "de" (German), "nl" (Dutch), and "ja" (Japanese) are supported.</li>
+ <li>Search for <code>intl.locale.matchOS</code> and double click the preference so that it is set to <code>false</code>.</li>
+ <li>Restart your browser to complete the change.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note</strong>: This works to change the browser's locale, even if you haven't got the <a href="https://addons.mozilla.org/en-US/firefox/language-tools/">language pack</a> installed for that language. You'll just get the browser UI in your default language if this is the case.</p>
+</div>
+
+<ol>
+</ol>
+
+<p>Load the extension temporarily from disk again, then test your new locale:</p>
+
+<ul>
+ <li>Visit "about:addons" again — you should now see the extension listed, with its icon, plus name and description in the chosen language.</li>
+ <li>Test your extension again. In our example, you'd go to another website and click a link, to see if the notification now appears in the chosen language.</li>
+</ul>
+
+<p>{{EmbedYouTube("R7--fp5pPGg")}}</p>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/author/index.html b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/author/index.html
new file mode 100644
index 0000000000..a99d8438e8
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/author/index.html
@@ -0,0 +1,44 @@
+---
+title: 作者
+slug: Mozilla/Add-ons/WebExtensions/manifest.json/author
+translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/author
+---
+<div>
+<div>{{AddonSidebar}}</div>
+
+<table class="fullwidth-table standard-table">
+ <tbody>
+ <tr>
+ <th scope="row" style="width: 30%;">型別</th>
+ <td><code>String</code></td>
+ </tr>
+ <tr>
+ <th scope="row">強制</th>
+ <td>No</td>
+ </tr>
+ <tr>
+ <th scope="row">範例</th>
+ <td>
+ <pre class="brush: json no-line-numbers language-json">
+<code class="language-json"><span class="key token">"author":</span> <span class="string token">"cool puppy"</span></code></pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<p>套件作者,用來顯示在瀏覽器的用戶介面中。如果有提供 <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json/developer">developer</a> 鍵而且裡面包含 "name" 屬性,那會覆蓋author鍵。不能指定多個作者。</p>
+
+<p>這是一個<a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Internationalization#Internationalizing_manifest.json">可侷限的屬性</a>。</p>
+</div>
+
+<p> </p>
+
+<h2 id="範例">範例</h2>
+
+<pre class="brush: json no-line-numbers language-json"><code class="language-json"><span class="key token">"author":</span> <span class="string token">"cool puppy"</span></code></pre>
+
+<h2 id="瀏覽器兼容">瀏覽器兼容</h2>
+
+<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
+
+<p>{{Compat("webextensions.manifest.author")}}</p>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/background/index.html b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/background/index.html
new file mode 100644
index 0000000000..d02b6eb600
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/background/index.html
@@ -0,0 +1,93 @@
+---
+title: background
+slug: Mozilla/Add-ons/WebExtensions/manifest.json/background
+tags:
+ - 擴充套件
+translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/background
+---
+<div>
+<div>{{AddonSidebar}}</div>
+
+<table class="fullwidth-table standard-table">
+ <tbody>
+ <tr>
+ <th scope="row" style="width: 30%;">型別</th>
+ <td><code>Object</code></td>
+ </tr>
+ <tr>
+ <th scope="row">強制</th>
+ <td>No</td>
+ </tr>
+ <tr>
+ <th scope="row">範例</th>
+ <td>
+ <pre class="brush: json no-line-numbers language-json">
+<code class="language-json"><span class="key token">"background":</span> <span class="punctuation token">{</span>
+ <span class="key token">"scripts":</span> <span class="punctuation token">[</span><span class="string token">"background.js"</span><span class="punctuation token">]</span>
+<span class="punctuation token">}</span></code></pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<p>用 <code>background</code> 鍵來引入一個或多個後端腳本,還有一個選擇性的套件後端頁面。</p>
+
+<p>後端腳本是用來放置一些需要維護長期狀態或是進行長期操作的程式碼,它麼的生命週期跟任何網頁或瀏覽器視窗是獨立的。</p>
+
+<p>後端腳本會在套件一被讀取就被讀入,一直到套件被禁用或移除才會卸載。只要你有請求對應的<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">權限</a>你可以在這個腳本裡使用任何擴充套件 APIs。</p>
+
+<p>更多細節,查看<a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_pages">套件解析</a>的"後端頁面"章節。</p>
+
+<p><code>background</code> 鍵是一個物件,可能包含下列二屬性其中之一,兩者都是選擇性的:</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>"scripts"</code></td>
+ <td>
+ <p>一個字串組成的陣列,每個都是 JavaScript 原始碼的路徑。路徑是 manifest.json 檔案自身的相對路徑。這些是會被套件讀取的後端腳本。</p>
+
+ <p>腳本共用全局 <code>window</code>。</p>
+
+ <p>腳本根據陣列裡的順序讀入。</p>
+
+ <p><strong>註:Firefox 版本50以前有一個錯誤</strong> 當 Firefox 除錯器開啓時,腳本並不總是按照陣列裡的順序讀入。要解決這個錯誤,你可以用 <code>"page"</code> 屬性並且在頁面中透過 <code>&lt;script&gt;</code> 標籤讀入後端腳本。這個錯誤在 Firefox 50 被修正,從那開始腳本總是會依照陣列中的順序讀入。</p>
+
+ <div class="note">
+ <p><strong>註:</strong> 如果你想要用<code>&lt;script&gt;標籤</code>從遠端取得一個腳本(例如 <code>&lt;script src = "https://code.jquery.com/jquery-1.7.1.min.js"&gt;</code>),你必須要修改套件 manifest.json 中的 <code>content_security_policy</code> 鍵。</p>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td><code>"page"</code></td>
+ <td>
+ <p>如果你指定 <code>"scripts"</code>,那麼爲了讓你的腳本執行一個空白頁面會被建立。</p>
+
+ <p>如果頁面中需要某些內容,你可以用 <code>"page"</code> 選項定義自己的頁面。</p>
+
+ <p>如果你用了這個屬性,你就不能透過 <code>"scripts"</code> 來指定後端腳本。但是你可以像一般的網頁一樣在頁面中引入你自己的腳本。</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="範例">範例</h2>
+
+<pre class="brush: json no-line-numbers language-json"><code class="language-json"> <span class="key token">"background":</span> <span class="punctuation token">{</span>
+ <span class="key token">"scripts":</span> <span class="punctuation token">[</span><span class="string token">"jquery.js"</span><span class="punctuation token">,</span> <span class="string token">"my-background.js"</span><span class="punctuation token">]</span>
+ <span class="punctuation token">}</span></code></pre>
+
+<p>讀取兩個後端腳本。</p>
+
+<pre class="brush: json line-numbers language-json"><code class="language-json"><span class="key token">"background":</span> <span class="punctuation token">{</span>
+ <span class="key token">"page":</span> <span class="string token">"my-background.html"</span>
+ <span class="punctuation token">}</span></code></pre>
+
+<p>讀取一個自訂的後端頁面。</p>
+
+<h2 id="瀏覽器兼容">瀏覽器兼容</h2>
+</div>
+
+<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
+
+<p>{{Compat("webextensions.manifest.background", 10)}}</p>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/browser_specific_settings/index.html b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/browser_specific_settings/index.html
new file mode 100644
index 0000000000..7a96adfecc
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/browser_specific_settings/index.html
@@ -0,0 +1,88 @@
+---
+title: applications
+slug: Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings
+tags:
+ - 擴充套件
+translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings
+---
+<div>
+<div>{{AddonSidebar}}</div>
+
+<table class="fullwidth-table standard-table">
+ <tbody>
+ <tr>
+ <th scope="row" style="width: 30%;">型別</th>
+ <td><code>Object</code></td>
+ </tr>
+ <tr>
+ <th scope="row">強制</th>
+ <td>通常是不強制(請看<a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/WebExtensions_and_the_Add-on_ID#When_do_you_need_an_add-on_ID">你什麼時候會需要 Add-on ID?</a>)。在 Firefox 48(桌面)前以及Android版Firefox 是強制的。</td>
+ </tr>
+ <tr>
+ <th scope="row">範例</th>
+ <td>
+ <pre class="brush: json no-line-numbers language-json">
+<code class="language-json"><span class="key token">"applications":</span> <span class="punctuation token">{</span>
+ <span class="key token">"gecko":</span> <span class="punctuation token">{</span>
+ <span class="key token">"id":</span> <span class="string token">"addon@example.com"</span><span class="punctuation token">,</span>
+ <span class="key token">"strict_min_version":</span> <span class="string token">"42.0"</span>
+ <span class="punctuation token">}</span>
+<span class="punctuation token">}</span></code></pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="敘述">敘述</h2>
+
+<p><code>applications</code> 鍵包含了詳細描述特定應用的鍵。</p>
+
+<p>目前這只包含了一個鍵,<code>gecko</code>,它包含4個string參數:</p>
+
+<ul>
+ <li><code>id</code> 是套件ID。Firefox 48 以後爲選擇性,48前爲強制。需要什麼來指定 add-on ID 請查看<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/WebExtensions_and_the_Add-on_ID">套件與 Add-on ID</a>。</li>
+ <li><code>strict_min_version</code>:支持的最舊Gecko版本。在這個欄位版本號包含 "*" 是不合法的。預設是 "42a1"。</li>
+ <li><code>strict_max_version</code>: 支持的最新Gecko版本。如果套件安裝的 Firefox 版本超過這個版本號則套件會被禁用或不被允許安裝。預設爲 "*",表示禁用最新支持版本檢查。</li>
+ <li><code>update_url</code> 是<a href="https://developer.mozilla.org/en-US/Add-ons/Updates">套件更新 manifest</a>。備:連結必須以 "https" 開頭。這個鍵用來自己管理套件更新(不透過套件管理器)。</li>
+</ul>
+
+<p>查看<a href="https://addons.mozilla.org/en-US/firefox/pages/appversions/">可用Gecko版本</a>。</p>
+
+<h3 class="highlight-spanned" id="套件ID格式"><span class="highlight-span">套件ID格式</span></h3>
+
+<p>套件ID格式必須是下列其中一種:</p>
+
+<ul>
+ <li><a href="https://en.wikipedia.org/wiki/Universally_unique_identifier" title="Generating_GUIDs">GUID</a></li>
+ <li>寫得像信箱地址的字串:<code class="plain">extensionname@example.org</code></li>
+</ul>
+
+<p>後者比較容易產生與操作。小心,在這裡使用真實信箱地址可能會引來垃圾信件。</p>
+
+<p>例如:</p>
+
+<pre class="brush:json;auto-links:false no-line-numbers language-json"><code class="language-json"><span class="key token">"id":</span> <span class="string token">"extensionname@example.org"</span><span class="punctuation token">,</span>
+
+<span class="key token">"id":</span> <span class="string token">"{daf44bf7-a45e-4450-979c-91cf07434c3d}"</span></code></pre>
+
+<p> </p>
+
+<h2 id="範例">範例</h2>
+
+<p>包含所有可用鍵的範例。註:大多數套件會忽略 <code>strict_max_version</code> 和 <code>update_url</code>。</p>
+
+<pre class="brush: json no-line-numbers language-json"><code class="language-json"><span class="key token">"applications":</span> <span class="punctuation token">{</span>
+ <span class="key token">"gecko":</span> <span class="punctuation token">{</span>
+ <span class="key token">"id":</span> <span class="string token">"addon@example.com"</span><span class="punctuation token">,</span>
+ <span class="key token">"strict_min_version":</span> <span class="string token">"42.0"</span><span class="punctuation token">,</span>
+ <span class="key token">"strict_max_version":</span> <span class="string token">"50.*"</span><span class="punctuation token">,</span>
+ <span class="key token">"update_url":</span> <span class="string token">"https://example.com/updates.json"</span>
+ <span class="punctuation token">}</span>
+<span class="punctuation token">}</span></code></pre>
+
+<h2 id="瀏覽器兼容">瀏覽器兼容</h2>
+</div>
+
+<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
+
+<p>{{Compat("webextensions.manifest.browser_specific_settings")}}</p>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html
new file mode 100644
index 0000000000..4a9b065496
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html
@@ -0,0 +1,46 @@
+---
+title: homepage_url
+slug: Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url
+tags:
+ - 擴充套件
+translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url
+---
+<div>
+<div>{{AddonSidebar}}</div>
+
+<table class="fullwidth-table standard-table">
+ <tbody>
+ <tr>
+ <th scope="row" style="width: 30%;">型別</th>
+ <td><code>String</code></td>
+ </tr>
+ <tr>
+ <th scope="row">強制</th>
+ <td>No</td>
+ </tr>
+ <tr>
+ <th scope="row">範例</th>
+ <td>
+ <pre class="brush: json no-line-numbers language-json">
+<code class="language-json"><span class="key token">"homepage_url":</span> <span class="string token">"https://example.org/my-addon"</span></code></pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<p>套件首頁的URL。</p>
+
+<p>如果有 <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json/developer">developer</a> 鍵且它包含 "url" 屬性,這會覆蓋 homepage_url 鍵。</p>
+
+<p>這是一個<a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Internationalization#Internationalizing_manifest.json">可侷限的屬性</a>。</p>
+
+<h2 id="範例">範例</h2>
+
+<pre class="brush: json no-line-numbers language-json"><code class="language-json"><span class="key token">"homepage_url":</span> <span class="string token">"https://github.com/mdn/webextensions-examples/tree/master/beastify"</span></code></pre>
+
+<h2 id="瀏覽器兼容性">瀏覽器兼容性</h2>
+</div>
+
+<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
+
+<p>{{Compat("webextensions.manifest.homepage_url")}}</p>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/index.html b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/index.html
new file mode 100644
index 0000000000..23eda6a41c
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/index.html
@@ -0,0 +1,113 @@
+---
+title: manifest.json
+slug: Mozilla/Add-ons/WebExtensions/manifest.json
+tags:
+ - Add-ons
+ - Extensions
+ - NeedsTranslation
+ - TopicStub
+ - WebExtensions
+translation_of: Mozilla/Add-ons/WebExtensions/manifest.json
+---
+<div>{{AddonSidebar}}</div>
+
+<p>manifest.json 是所有採用 WebExtension API 的擴充功能中、唯一一個必須包含的檔案。</p>
+
+<p>你可透過 manifest.json 為擴充功能指定名稱(name)、版本(version)這類的基本元資料(metadata),也可指定擴充功能的一些相關功能,例如像是背景腳本(background scripts)、內容腳本(content scripts)、瀏覽器動作(browser actions)等等。</p>
+
+<p>這是個採用 <a href="/en-US/docs/Glossary/JSON">JSON</a> 格式的檔案,但有個例外:它可接受含有 "<code>//</code>" 這種格式的註解文字。</p>
+
+<p>manifest.json 可採用的鍵值如下所列:</p>
+
+<div class="twocolumns">{{ ListSubpages ("/en-US/Add-ons/WebExtensions/manifest.json") }}</div>
+
+<div class="twocolumns"> </div>
+
+<p><code>"manifest_version"</code>、<code>"version"</code> 和 <code>"name"</code> 是一定要設定的鍵值。另外,如果有設定 "_locales" directory ,就一定要設定 <code>"default_locale"</code> ,否則就是這兩個鍵值都不做設定。 Google Chrome, 並不支援 <code>"applications"</code> ,但針對 Firefox 48 之前及 Android 的版本,則必須設置這個鍵值。</p>
+
+<p>你可透過擴充功能中的 JavaScript,藉由 {{WebExtAPIRef("runtime.getManifest()")}} 這個函式來存取擴充功能裡的 manifest :</p>
+
+<pre class="brush: js">browser.runtime.getManifest().version;</pre>
+
+<h2 id="範例">範例</h2>
+
+<p>以下程式碼顯示的是一般 manifest 鍵值的基本語法。請注意,這個範例並不是讓你用來直接複製貼上的,你必須根據所開發的擴充功能,填入相應的鍵值、關於擴充功能的完整範例,請參見 <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Examples">擴充功能範例</a>。</p>
+
+<pre class="brush: json">{
+ "applications": {
+ "gecko": {
+ "id": "addon@example.com",
+ "strict_min_version": "42.0"
+ }
+ },
+
+ "background": {
+ "scripts": ["jquery.js", "my-background.js"],
+ "page": "my-background.html"
+ },
+
+ "browser_action": {
+ "default_icon": {
+ "19": "button/geo-19.png",
+ "38": "button/geo-38.png"
+ },
+ "default_title": "Whereami?",
+ "default_popup": "popup/geo.html"
+ },
+
+ "commands": {
+ "toggle-feature": {
+  "suggested_key": {
+    "default": "Ctrl+Shift+Y",
+    "linux": "Ctrl+Shift+U"
+  },
+     "description": "Send a 'toggle-feature' event"
+ }
+ },
+
+ "content_security_policy": "script-src 'self' https://example.com; object-src 'self'",
+
+ "content_scripts": [
+ {
+ "exclude_matches": ["*://developer.mozilla.org/*"],
+ "matches": ["*://*.mozilla.org/*"],
+ "js": ["borderify.js"]
+ }
+ ],
+
+ "default_locale": "en",
+
+ "description": "...",
+
+ "icons": {
+ "48": "icon.png",
+ "96": "icon@2x.png"
+ },
+
+ "manifest_version": 2,
+
+ "name": "...",
+
+ "page_action": {
+ "default_icon": {
+ "19": "button/geo-19.png",
+ "38": "button/geo-38.png"
+ },
+ "default_title": "Whereami?",
+ "default_popup": "popup/geo.html"
+ },
+
+ "permissions": ["webNavigation"],
+
+ "version": "0.1",
+
+ "web_accessible_resources": ["images/my-image.png"]
+}</pre>
+
+<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
+
+<p>若想對所有的 manifest 鍵值及其子健有個完整的概念,可參見 <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_compatibility_for_manifest.json">完整 manifest.json 瀏覽器相容表</a>。</p>
+
+<div class="hidden">此頁面的相容表是根據結構化資料所生成的。如果你想對該資料做出貢獻,可直接 check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> 並以 pull request 的方式回饋給我們。</div>
+
+<p>{{Compat("webextensions.manifest")}}</p>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/options_ui/index.html b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/options_ui/index.html
new file mode 100644
index 0000000000..7a376817f1
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/manifest.json/options_ui/index.html
@@ -0,0 +1,110 @@
+---
+title: options_ui
+slug: Mozilla/Add-ons/WebExtensions/manifest.json/options_ui
+tags:
+ - 擴充套件
+translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/options_ui
+---
+<div>
+<div>{{AddonSidebar}}</div>
+
+<table class="fullwidth-table standard-table">
+ <tbody>
+ <tr>
+ <th scope="row" style="width: 30%;">型別</th>
+ <td><code>Object</code></td>
+ </tr>
+ <tr>
+ <th scope="row">強制</th>
+ <td>No</td>
+ </tr>
+ <tr>
+ <th scope="row">範例</th>
+ <td>
+ <pre class="brush: json no-line-numbers language-json">
+<code class="language-json"><span class="key token">"options_ui":</span> <span class="punctuation token">{</span>
+ <span class="key token">"page":</span> <span class="string token">"options/options.html"</span>
+<span class="punctuation token">}</span></code></pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<p>用 <code>options_ui</code> 鍵來定義套件的<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Options_pages">選項頁面</a>。</p>
+
+<p>選項頁面包含了套件的設定。用戶可以從套件管理員進入這個畫面,而你可以用{{WebExtAPIRef("runtime.openOptionsPage()")}}打開它。</p>
+
+<p>指定 <code>options_ui</code> 爲一個與套件打包在一起的HTML檔案路徑。就像一般的網頁一樣,HTML檔案可包含CSS與JavaScript檔案。跟普通頁面不同的是,它可以使用所有被<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">授權</a>的<a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API">套件APIs</a>。 不過,它執行的作用域不同於你的後端腳本。</p>
+
+<p>如果你想在<strong>選項頁面</strong>與<strong>後端腳本</strong>的JavaScript裡<strong>共用</strong>資料或函數,你可以透過用{{WebExtAPIRef("extension.getBackgroundPage()")}}與後端腳本的 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window">Window</a> 關聯、用{{WebExtAPIRef("extension.getViews()")}}與任何套件內腳本的{{domxref("Window")}}關聯來實現。你也可以透過 <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage">runtime.sendMessage()</a></code>、 <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage">runtime.onMessage</a></code>,跟(或)<code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/connect">runtime.connect()</a></code>在選項頁面與後端的頁面的JavaScript之間溝通。<br>
+ 後者(或是<code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/Port">runtime.Port</a></code>)也可以用來在<a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Background_scripts">後端腳本</a>與<strong><a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts">內容腳本</a></strong>之間共用選項。</p>
+
+<p>一般要儲存選項頁面的選項變動時,你要可能會用 <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage">storage API</a>、<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/sync">storage.sync</a>(如果你想要在所有用戶登入的瀏覽器實例之間同步設定的話),或者透過 <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/local">storage.local</a> (如果設定是針對目前身份或機器)。而如果你希望你的<a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Background_scripts">後端腳本</a>(或<a href="https://developer.mozilla.org/en-US/docs/">內容腳本</a>)監聽該變化,你可以加上 <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/onChanged">storage.onChanged</a> 監聽器。</p>
+
+<h2 id="語法">語法</h2>
+
+<p><code>options_ui</code> 鍵是一個包含了下列內容的物件:</p>
+
+<table class="fullwidth-table standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Name</th>
+ <th scope="col">Type</th>
+ <th scope="col">Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_styles">browser_style</a></code></td>
+ <td><code>Boolean</code></td>
+ <td>
+ <p>可選,預設爲 <code>true</code>。</p>
+
+ <p>用這個來替你的頁面引入一個樣式表,使你的頁面與瀏覽器UI以及其他用 <code>browser_style</code> 的套件看起來一致。雖然它預設是<code>true</code>還是建議你加入這個屬性。</p>
+
+ <p>在 Firefox 裡,樣式表可以在 chrome://browser/content/extension.css 或 chrome://browser/content/extension-mac.css(OS X)查看。設定尺寸的時候注意到這個樣式表目前會做這個設定<code>box-sizing: border-box</code> (查看 <a href="https://developer.mozilla.org/docs/Web/CSS/box-sizing">box-sizing</a>)。</p>
+
+ <p><a class="external external-icon" href="https://firefoxux.github.io/StyleGuide/#/controls">Firefox風格指南</a>寫到一些你可以應用到彈出視窗裡面的元素上來變成特定樣式的class。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>open_in_tab</code></td>
+ <td><code>Boolean</code></td>
+ <td>
+ <p>可選,預設爲 <code>false</code>。</p>
+
+ <p>如果設爲 <code>true</code>,選項頁面會在普通的瀏覽器頁籤開啓而不是整合在瀏覽器的套件管理員裡。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>page</code></td>
+ <td><code>String</code></td>
+ <td>
+ <p>強制。</p>
+
+ <p>包含選項頁面細項的HTML檔案路徑。</p>
+
+ <p>這個路徑是 manifest.json 的相對路徑。</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="範例">範例</h2>
+
+<pre class="brush: json no-line-numbers language-json"><code class="language-json"> <span class="key token">"options_ui":</span> <span class="punctuation token">{</span>
+ <span class="key token">"page":</span> <span class="string token">"options/options.html"</span>
+ <span class="punctuation token">}</span></code></pre>
+
+<h2 id="瀏覽器兼容性">瀏覽器兼容性</h2>
+</div>
+
+
+
+<p>{{Compat("webextensions.manifest.options_ui")}}</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_styles">Browser styles</a></li>
+</ul>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/user_interface/browser_action/index.html b/files/zh-tw/mozilla/add-ons/webextensions/user_interface/browser_action/index.html
new file mode 100644
index 0000000000..afdf61f340
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/user_interface/browser_action/index.html
@@ -0,0 +1,50 @@
+---
+title: 工具列按鈕
+slug: Mozilla/Add-ons/WebExtensions/user_interface/Browser_action
+tags:
+ - 擴充套件
+translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Browser_action
+---
+<div>{{AddonSidebar}}</div>
+
+<p>根據<a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction">工具列按鈕</a>,這個用戶介面是一個加到瀏覽器工具列的按鈕。用戶透過點擊按鈕來與你的套件互動。<br>
+ <img alt="" src="https://mdn.mozillademos.org/files/15751/browser-action.png" style="display: block; height: 182px; margin-left: auto; margin-right: auto; width: 350px;"></p>
+
+<p>工具列按鈕與網址列按鈕非常相似。關於差別以及何時該使用的指引,詳閱<a href="/en-US/Add-ons/WebExtensions/user_interface/Page_actions#Page_actions_and_browser_actions">工具列按鈕。</a></p>
+
+<h2 id="詳細指定工具列按鈕">詳細指定工具列按鈕</h2>
+
+<p>透過在 manifest.json 中使用 <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action">browser_action</a></code> 鍵來定義工具列按鈕的屬性:</p>
+
+<pre class="brush: json line-numbers language-json"><code class="language-json"><span class="key token">"browser_action":</span> <span class="punctuation token">{</span>
+ <span class="key token">"default_icon":</span> <span class="punctuation token">{</span>
+ <span class="key token">"19":</span> <span class="string token">"button/geo-19.png"</span><span class="punctuation token">,</span>
+ <span class="key token">"38":</span> <span class="string token">"button/geo-38.png"</span>
+ <span class="punctuation token">}</span><span class="punctuation token">,</span>
+ <span class="key token">"default_title":</span> <span class="string token">"我在哪?"</span>
+<span class="punctuation token">}</span></code></pre>
+
+<p>唯一一個強制的鍵只有 <code>default_icon</code>。</p>
+
+<p>指定工具列按鈕的方式有兩種: 有<a href="/en-US/Add-ons/WebExtensions/Popups">彈出視窗</a>跟沒有<a href="/en-US/Add-ons/WebExtensions/Popups">彈出視窗</a>。如果你不指定彈出視窗,當用戶點擊按鈕事件會被傳送到套件,而套件透過 <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/BrowserAction/onClicked" title="Fired when a browser action icon is clicked. This event will not fire if the browser action has a popup."><code>browserAction.onClicked</code></a> 監聽:</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js">browser<span class="punctuation token">.</span>browserAction<span class="punctuation token">.</span>onClicked<span class="punctuation token">.</span><span class="function token">addListener</span><span class="punctuation token">(</span>handleClick<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre>
+
+<p>如果你指定彈出視窗,點擊事件不會被傳送,取而代之當用戶點擊按鈕時彈出視窗會被展開。用戶可以跟彈出視窗互動且當用戶點擊了彈出視窗外側它會自動關閉。更多建立與管理彈出視窗的細節請查看<a href="/en-US/Add-ons/WebExtensions/Popups">彈出視窗</a>文章。</p>
+
+<p>註: 你的套件只能有一個工具列按鈕。</p>
+
+<p>你可以透過 <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction">browserAction</a></code> API 程式化地更改任何工具列按鈕的屬性。</p>
+
+<h2 id="圖示">圖示</h2>
+
+<p>更多關於建立工具列按鈕使用的圖示,請查看文件<a class="grey-90 no-underline hover-no-underline" href="https://design.firefox.com/photon/index.html">光子設計系統</a>裡的<a href="https://design.firefox.com/photon/visuals/iconography.html">圖示學</a>。</p>
+
+<h2 id="範例">範例</h2>
+
+<p>GitHub上的<a href="https://github.com/mdn/webextensions-examples">擴充套件範例</a>程式庫包含兩個建立工具列按鈕的範例:</p>
+
+<ul>
+ <li><a href="https://github.com/mdn/webextensions-examples/blob/master/bookmark-it/">bookmark-it</a> 使用不含彈出視窗的工具列按鈕。</li>
+ <li><a href="https://github.com/mdn/webextensions-examples/tree/master/beastify">beastify</a> 使用包含彈出視窗的工具列按鈕。</li>
+</ul>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/user_interface/context_menu_items/index.html b/files/zh-tw/mozilla/add-ons/webextensions/user_interface/context_menu_items/index.html
new file mode 100644
index 0000000000..949ec58b74
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/user_interface/context_menu_items/index.html
@@ -0,0 +1,54 @@
+---
+title: 快捷選單項
+slug: Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items
+tags:
+ - 擴充套件
+translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items
+---
+<div>{{AddonSidebar}}</div>
+
+<div>
+<p>這個用戶介面添加一個或多個項目到瀏覽器的快捷選單。這是用戶在網頁上點擊右鍵時出現的選單。頁籤也可以透過 <a href="/en-US/Add-ons/WebExtensions/API/menus">browser.menus API</a> 使用快捷選單。</p>
+
+<p><img alt="Example of content menu items added by a WebExtension, from the context-menu-demo example" src="https://mdn.mozillademos.org/files/15756/context_menu_example.png" style="display: block; height: 382px; margin-left: auto; margin-right: auto; width: 350px;"></p>
+
+<p>你可以用這個介面來顯示一些跟特定瀏覽器或網頁內容相關的功能。舉例來說,當用戶在圖片上按右鍵時提供圖片編輯器的功能或者在反白內容上按右鍵時提供儲存頁面內容的功能。你可以對選單添加普通的選單項目、核取方塊、單選按鈕組以及分隔線。選單項目透過{{WebExtAPIRef("contextMenus.create")}}添加後透過它會顯示在所有瀏覽器頁籤,但是你可以透過{{WebExtAPIRef("contextMenus.remove")}}來移除它。</p>
+
+<h2 id="指定快捷選單項目">指定快捷選單項目</h2>
+
+<p>透過{{WebExtAPIRef("contextMenus")}} API可以程式化地管理快捷選單項目。然而,你必須請求 <code>contextMenus</code> 的權限才能使用這些API的好處。</p>
+
+<pre class="brush: json">"permissions": ["contextMenus"]</pre>
+
+<p>現在你可以在你套件的後端腳本處添加(修改/刪除)選單項目。建立一個選單項目你要指定 id,標題以及它應該隸屬於哪個選單:</p>
+
+<pre class="brush: js">browser.contextMenus.create({
+ id: "log-selection",
+ title: browser.i18n.getMessage("contextMenuItemSelectionLogger"),
+ contexts: ["selection"]
+}, onCreated);</pre>
+
+<p>接著你的套件會監聽選單項目的點擊。送出有關項目點擊、點擊環境以及發生點擊頁籤的資訊可以用來使用恰當的套件功能。</p>
+
+<pre class="brush: js">browser.contextMenus.onClicked.addListener(function(info, tab) {
+ switch (info.menuItemId) {
+ case "log-selection":
+ console.log(info.selectionText);
+ break;
+ ...
+ }
+})</pre>
+
+<h2 id="圖示">圖示</h2>
+
+<p>更多關於建立快捷選單圖示的細節請查看文件<a class="grey-90 no-underline hover-no-underline" href="https://design.firefox.com/photon/index.html">光子設計系統</a>的<a href="https://design.firefox.com/photon/visuals/iconography.html">圖示學</a>。</p>
+
+<h2 id="範例">範例</h2>
+
+<p>GitHub上的<a class="external external-icon" href="https://github.com/mdn/webextensions-examples">webextensions-examples</a> 程式庫包含了兩個建立快捷選單的範例:</p>
+
+<ul>
+ <li><a href="https://github.com/mdn/webextensions-examples/tree/master/menu-demo">menu-demo</a> 替瀏覽器的快捷選單添加幾個項目。</li>
+ <li><a href="https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types">context-menu-copy-link-with-types</a> 替連結添加一個快捷選單項,以純文字或rich HTML的形式複製連結的UR。</li>
+</ul>
+</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/user_interface/devtools_panels/index.html b/files/zh-tw/mozilla/add-ons/webextensions/user_interface/devtools_panels/index.html
new file mode 100644
index 0000000000..fddea1b0e0
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/user_interface/devtools_panels/index.html
@@ -0,0 +1,66 @@
+---
+title: 開發工具面板
+slug: Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels
+tags:
+ - 初學者
+ - 擴充套件
+ - 教學
+ - 用戶介面
+translation_of: Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels
+---
+<div>{{AddonSidebar}}</div>
+
+<div class="note">
+<p>Firefox 54 以後可以使用這個功能。</p>
+</div>
+
+<p>當套件提供開發者使用的工具時,可以以一個瀏覽器開發工具的新面板的形式在開發者工具裡添加一個UI。</p>
+
+<p><img alt='Simple example showing the addition of "My panel" to the Developer Tools tabs.' src="https://mdn.mozillademos.org/files/15746/developer_panel_tab.png" style="display: block; height: 112px; margin-left: auto; margin-right: auto; width: 350px;"></p>
+
+<h2 id="指定開發工具面板">指定開發工具面板</h2>
+
+<p>開發工具面板可以透過 <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools.panels">devtools.panels</a></code> API 添加,因此這必須在特別的開發工具頁面執行。</p>
+
+<p>透過在套件的 <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a> 添加 <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/devtools_page">devtools_page</a></code> 鍵並提供HTML檔案來添加開發工具頁面:</p>
+
+<pre class="brush: json line-numbers language-json"><code class="language-json"><span class="key token">"devtools_page":</span> <span class="string token">"devtools-page.html"</span></code></pre>
+
+<p>在開發工具頁面,呼叫腳本會添加開發工具面板:</p>
+
+<pre class="brush: html">&lt;body&gt;
+  &lt;script src="devtools.js"&gt;&lt;/script&gt;
+&lt;/body&gt;</pre>
+
+<p>在腳本裡,藉由指定面板標題、圖示、HTML檔案來建立開發工具:</p>
+
+<pre class="brush: js">function handleShown() {
+ console.log("panel is being shown");
+}
+
+function handleHidden() {
+ console.log("panel is being hidden");
+}
+
+browser.devtools.panels.create(
+ "My Panel", // title
+ "icons/star.png", // icon
+ "devtools/panel/panel.html" // content
+).then((newPanel) =&gt; {
+ newPanel.onShown.addListener(handleShown);
+ newPanel.onHidden.addListener(handleHidden);
+});</pre>
+
+<p>套件現在可以在檢測器視窗透過 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow/eval"><code>devtools</code>.inspectedWindow.eval()</a></code> 或透過後端腳本傳送訊息來插入內容腳本兩種方式執行。你可以在<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Extending_the_developer_tools">擴充開發者工具</a>找到更多相關訊息。</p>
+
+<h2 id="開發面板設計">開發面板設計</h2>
+
+<p>更多關於如何設計符合 Firefox 風格的開發者面板,請查看文件<a class="grey-90 no-underline hover-no-underline" href="https://design.firefox.com/photon/index.html">光子設計系統</a>。</p>
+
+<h2 id="圖示">圖示</h2>
+
+<p>更多關於建立開發者工具面板圖示的細節,請查看文件<a class="grey-90 no-underline hover-no-underline" href="https://design.firefox.com/photon/index.html">光子設計系統</a>的<a href="https://design.firefox.com/photon/visuals/iconography.html">圖示學</a>。</p>
+
+<h2 id="範例">範例</h2>
+
+<p>GitHub上的 <a href="https://github.com/mdn/webextensions-examples">webextensions-examples</a> 程式庫包含了建立開發工具面板的 <a href="https://github.com/mdn/webextensions-examples/blob/master/devtools-panels/">devtools-panels</a> 範例。</p>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/user_interface/index.html b/files/zh-tw/mozilla/add-ons/webextensions/user_interface/index.html
new file mode 100644
index 0000000000..5c8e40bcdd
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/user_interface/index.html
@@ -0,0 +1,94 @@
+---
+title: 用戶介面
+slug: Mozilla/Add-ons/WebExtensions/user_interface
+tags:
+ - 擴充套件
+ - 用戶介面
+translation_of: Mozilla/Add-ons/WebExtensions/user_interface
+---
+<div>{{AddonSidebar}}</div>
+
+<p>套件APIs 提供了幾種介面來完成對用戶的功能。下方是那些介面的概述,每種用戶介面都有更詳細的資訊可以查閱。</p>
+
+<div class="note">
+<p>爲了使用這些UI元件在套件裡提供優秀的用戶體驗,建議閱讀<a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/User_experience_best_practices">用戶體驗最佳實踐</a>文章。</p>
+</div>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">
+ <p>可用介面</p>
+ </th>
+ <th scope="col">敘述</th>
+ <th scope="col" style="width: 350px;">範例</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><a href="/Add-ons/WebExtensions/user_interface/Browser_action">工具列按鈕</a></td>
+ <td>一個瀏覽器工具列上的按鈕,被點擊時會送出事件給套件。預設的情況下在所有頁籤都能看到此按鈕。</td>
+ <td><img alt="Example showing a toolbar button (browser action)." src="https://mdn.mozillademos.org/files/15751/browser-action.png" style="height: 364px; width: 700px;"></td>
+ </tr>
+ <tr>
+ <td>附帶<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups">彈出視窗</a>的工具列按鈕</td>
+ <td>一個按鈕上的彈出視窗,當按鈕被點擊時展開。彈出視窗被一個HTML文件來定義。</td>
+ <td><img alt="Example of the pop-up on a toolbar button" src="https://mdn.mozillademos.org/files/15753/popup-shadow.png" style="height: 624px; width: 700px;"></td>
+ </tr>
+ <tr>
+ <td><a href="/Add-ons/WebExtensions/user_interface/Page_actions">網址列按鈕</a></td>
+ <td>一個網址列上的按鈕,點擊時傳送事件給套件。預設的情況下,在所有的頁籤中此按鈕都會被隱藏。</td>
+ <td><img alt="Example showing an address bar button (page action) " src="https://mdn.mozillademos.org/files/15745/address_bar_button.png" style="height: 348px; width: 700px;"></td>
+ </tr>
+ <tr>
+ <td>附帶<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups">彈出視窗</a>的網址列按鈕</td>
+ <td>網址列按鈕上的一個按鈕,當按鈕被點擊時展開,彈出視窗被一個HTML文件來定義。</td>
+ <td><img alt="Example of a popup on the address bar button" src="https://mdn.mozillademos.org/files/15747/page_action_popup.png" style="height: 524px; width: 700px;"></td>
+ </tr>
+ <tr>
+ <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items">快捷選單</a></td>
+ <td>在一個或多個瀏覽器快捷選單中的選單項目、核取方塊、選項按鈕。另外,選單可以透過增加分隔線來組成。當選單項目被點擊時傳送一個事件給套件。</td>
+ <td><img alt="Example of content menu items added by a WebExtension, from the context-menu-demo example" src="https://mdn.mozillademos.org/files/15756/context_menu_example.png" style="height: 942px; width: 864px;"></td>
+ </tr>
+ <tr>
+ <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars">側邊欄</a></td>
+ <td>
+ <p dir="ltr">一個顯示在網頁旁邊的HTML文件,每頁可以顯示獨立的內容。側邊欄會在用戶安裝套件時打開,然後根據用戶對側邊欄的可視選項開關。側邊欄裡的用戶互動由它的HTML文件來控制。</p>
+ </td>
+ <td><img alt="Example of a sidebar" src="https://mdn.mozillademos.org/files/15755/bookmarks-sidebar.png" style="height: 846px; width: 700px;"></td>
+ </tr>
+ <tr>
+ <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Options_pages">選項頁面</a></td>
+ <td>一個使你可以定義用戶能修改的偏好設定的頁面。用戶可以透過瀏覽器的套件管理畫面進到這裡。</td>
+ <td><img alt="Example showing the options page content added in the favorite colors example." src="https://mdn.mozillademos.org/files/15748/options_page.png"></td>
+ </tr>
+ <tr>
+ <td><a href="/Add-ons/WebExtensions/user_interface/Extension_pages">套件頁面</a></td>
+ <td>透過套件裡的網頁來在視窗或頁籤內提供表單、幫助訊息或任何需要的內容。</td>
+ <td><img alt="Example of a simple bundled page displayed as a detached panel." src="https://mdn.mozillademos.org/files/15752/bundled_page_as_panel_small.png" style="height: 432px; width: 700px;"></td>
+ </tr>
+ <tr>
+ <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Notifications">通知</a></td>
+ <td>透過作業系統的機制顯示的短暫的通知。當用戶點擊通知或通知關閉時(不論自動關閉或用戶手動關閉)時傳送事件給套件。</td>
+ <td><img alt="Example of an extension triggered system notification" src="https://mdn.mozillademos.org/files/15754/notify-shadowed.png" style="height: 294px; width: 780px;"></td>
+ </tr>
+ <tr>
+ <td><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Omnibox">網址列建議</a></td>
+ <td>當用戶輸入關鍵字時提供自訂的網址列建議。</td>
+ <td><img alt="Example showing the result of the firefox_code_search WebExtension's customization of the address bar suggestions." src="https://mdn.mozillademos.org/files/15749/omnibox_example_small.png" style="height: 464px; width: 700px;"></td>
+ </tr>
+ <tr>
+ <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels">開發者工具面板</a></td>
+ <td>一個包含相關HTML文件的頁籤顯示在瀏覽器的開發者工具裡。</td>
+ <td><img alt="Example showing the result of the firefox_code_search WebExtension's customization of the address bar suggestions." src="https://mdn.mozillademos.org/files/15746/developer_panel_tab.png" style="height: 224px; width: 700px;"></td>
+ </tr>
+ </tbody>
+</table>
+
+<p>下面是一些關於建立這些用戶介面的詳細教學:</p>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar">在工具列加入一個按鈕</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Implement_a_settings_page">建立設定頁面</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Extending_the_developer_tools">擴充開發者工具</a></li>
+</ul>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/user_interface/sidebars/index.html b/files/zh-tw/mozilla/add-ons/webextensions/user_interface/sidebars/index.html
new file mode 100644
index 0000000000..923cd9d14f
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/user_interface/sidebars/index.html
@@ -0,0 +1,55 @@
+---
+title: 側邊欄
+slug: Mozilla/Add-ons/WebExtensions/user_interface/Sidebars
+tags:
+ - 擴充套件
+translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Sidebars
+---
+<div>{{AddonSidebar}}</div>
+
+<div>
+<p>側邊欄是一個顯示在瀏覽器視窗上、網頁旁邊的面板。瀏覽器提供能讓用戶看見目前可用的側邊欄並且擇一顯示的UI。例如,Firefox 有一個 "檢視 &gt; 側邊欄" 的選單。一次只能有一個側邊欄顯示,而那個側邊欄會顯示在所有的頁籤以及瀏覽器視窗。</p>
+
+<p>瀏覽器可能包含了一些內建的側邊欄。例如,Firefox 包含了一個可以跟書籤互動的側邊欄:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/15755/bookmarks-sidebar.png" style="display: block; height: 423px; margin-left: auto; margin-right: auto; width: 350px;">在 manifest.json 裡用 <code>sidebar_action</code> 鍵可以替瀏覽器添加側邊欄。它會被列在內建的側邊欄旁邊,而用戶可以透過與內建側邊欄一模一樣的機制來打開它。</p>
+
+<p>就像工具列按鈕一樣,你藉由HTML文件指定側邊欄的內容。當用戶打開側邊欄,側邊欄的文件會被讀取到每個開著的瀏覽器視窗。每個視窗都各自獲取文件的實例,當新的視窗被開啓,他們也會獲取自己的側邊欄實例。</p>
+
+<p>你可以用{{WebExtAPIRef("sidebarAction.setPanel()")}}函數設置某個頁籤專屬的文件。側邊欄會透過{{WebExtAPIRef("windows.getCurrent()")}} API找出它隸屬的視窗 :</p>
+
+<pre class="brush: js">// sidebar.js
+browser.windows.getCurrent({populate: true}).then((windowInfo) =&gt; {
+ myWindowId = windowInfo.id;
+});</pre>
+
+<p>如果側邊欄要在不同的視窗顯示不同內容這會很有用。範例請看 <a href="https://github.com/mdn/webextensions-examples/tree/master/annotate-page">"annotate-page" 範例</a>。</p>
+
+<p>側邊欄文件與後端腳本以及彈出視窗享有一樣的權限。他們可以透過{{WebExtAPIRef("runtime.getBackgroundPage()")}}直接讀取後端頁面(只要側邊欄隸屬於隱私模式的視窗),並且可以透過一些 messaging APIs 與內容腳本或原生應用互動,像是{{WebExtAPIRef("tabs.sendMessage()")}}與{{WebExtAPIRef("runtime.sendNativeMessage()")}}。</p>
+
+<p>側邊欄文件會在瀏覽器視窗關閉或用戶關閉側邊欄時被卸載。這代表不像後端腳本,側邊欄文件並不總是保持讀入的狀態。但是不像工具列按鈕,他們可以在用戶與網頁互動時保持讀入。</p>
+
+<p>當定義著側邊欄的套件被首次安裝時,側邊欄2會自動開啓。這是爲了幫助用戶瞭解這個套件包含了一個側邊欄。註:套件無法程式化地開啓側邊欄,側邊欄只能由用戶開啓。</p>
+
+<h2 id="指定側邊欄">指定側邊欄</h2>
+
+<p>要指定側邊欄,在 manifest.json 裡透過 <code><a href="/en-US/Add-ons/WebExtensions/manifest.json/sidebar_action">sidebar_action</a></code> 鍵定義文件、標題以及圖示:</p>
+
+<pre class="brush: json">"sidebar_action": {
+ "default_title": "My sidebar",
+ "default_panel": "sidebar.html",
+ "default_icon": "sidebar_icon.png"
+}</pre>
+
+<p>你可以透過{{WebExtAPIRef("sidebarAction")}} API程式化地更改標題、面板以及圖示。</p>
+
+<p>標題與圖示會在任一個瀏覽器提供的UI中顯示,像是 Firefox 裡的 "檢視 &gt; 側邊欄" 選單。</p>
+
+<h2 id="側邊欄設計">側邊欄設計</h2>
+
+<p>更多如何設計符合 Firefox 風格的側邊欄網頁細節,請查看文件<a class="grey-90 no-underline hover-no-underline" href="https://design.firefox.com/photon/index.html">光子設計系統</a>。</p>
+
+<h2 id="範例">範例</h2>
+
+<p>GitHub上的 <a href="https://github.com/mdn/webextensions-examples">webextensions-examples</a> 程式庫包含了建立側邊欄的 <a href="https://github.com/mdn/webextensions-examples/tree/master/annotate-page">annotate-page</a> 範例。</p>
+</div>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/what_are_webextensions/index.html b/files/zh-tw/mozilla/add-ons/webextensions/what_are_webextensions/index.html
new file mode 100644
index 0000000000..6494e50a5f
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/what_are_webextensions/index.html
@@ -0,0 +1,26 @@
+---
+title: 何謂附加元件?
+slug: Mozilla/Add-ons/WebExtensions/What_are_WebExtensions
+translation_of: Mozilla/Add-ons/WebExtensions/What_are_WebExtensions
+---
+<div>{{AddonSidebar}}</div>
+
+<div> </div>
+
+<p>附加元件(Add-ons)擴展並修改了瀏覽器的功能。他們使用標準的網路技術──JavaScript、HTML、以及 CSS、還有一些專用的 JavaScript API──寫成。除此之外,附加元件可以給瀏覽器添加新功能、或是改變特定網站的外觀或內容。</p>
+
+<p>Firefox的附加元件開發基於能跨瀏覽器的 WebExtensions APIs ,在很大的程度上相容於和 Google Chrome 與 Opera 瀏覽器所支持的 <a class="external external-icon" href="https://developer.chrome.com/extensions">extension API</a>  。大多數情況下,針對這些瀏覽器所撰寫的 Extension <a href="https://developer.mozilla.org/zh-TW/Add-ons/WebExtensions/Porting_from_Google_Chrome">只要些許修改</a>就能在 Firefox 或是 Microsoft Edge 執行,也與 <a href="https://developer.mozilla.org/zh-TW/Firefox/Multiprocess_Firefox">multiprocess Firefox</a> 完全相容。</p>
+
+<p>在過去,你可以使用三種系統開發 Firefox 附加元件: <a href="/zh-TW/Add-ons/Overlay_Extensions">XUL/XPCOM overlays</a>、<a href="/zh-TW/docs/Mozilla/Add-ons/Bootstrapped_extensions">bootstrapped extensions</a>、或是 <a href="/zh-TW/docs/Mozilla/Add-ons/SDK">Add-on SDK</a>。但2017年11月底之後,WebExtensions 將成為唯一開發 Firefox 附加元件的方式,而其他方式會被廢棄。</p>
+
+<p>如果你有任何想法或問題,甚至是需要協助轉換舊附加元件到新系統,你可以在 <a class="external external-icon" href="https://mail.mozilla.org/listinfo/dev-addons">dev-addons mailing list</a> 或 <a class="external external-icon" href="https://wiki.mozilla.org/IRC">IRC</a> 的 <a href="irc://irc.mozilla.org/webextensions">#webextensions</a> 找到我們。</p>
+
+<p> </p>
+
+<h2 id="接下來呢?">接下來呢?</h2>
+
+<ul>
+ <li>一些附加元件的範例,請參看 <a href="https://github.com/mdn/webextensions-examples">Example WebExtensions</a>。</li>
+ <li>學習附加元件的結構,請參看 <a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension">解析 WebExtension</a>.</li>
+ <li>一個簡單的附加元件開發流程,請參看 <a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension">你的第一個 WebExtension</a>。</li>
+</ul>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/your_first_webextension/index.html b/files/zh-tw/mozilla/add-ons/webextensions/your_first_webextension/index.html
new file mode 100644
index 0000000000..7e4f37423e
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/your_first_webextension/index.html
@@ -0,0 +1,150 @@
+---
+title: 你的第一個 WebExtension
+slug: Mozilla/Add-ons/WebExtensions/Your_first_WebExtension
+translation_of: Mozilla/Add-ons/WebExtensions/Your_first_WebExtension
+---
+<div>{{AddonSidebar}}</div>
+
+<p>我們會在這篇文章詳細講解 Firefox 的 WebExtension 的製作。這支附加元件會在 "mozilla.org" 網域底下的所有網頁,增加紅色外框。</p>
+
+<p>範例的原始碼也放在 GitHub 喔:<a href="https://github.com/mdn/webextensions-examples/tree/master/borderify">https://github.com/mdn/webextensions-examples/tree/master/borderify</a>。</p>
+
+<p>首先勒,你需要 Firefox 45.0 或以上的版本。</p>
+
+<h2 id="撰寫_WebExtension">撰寫 WebExtension</h2>
+
+<p>新增一個資料夾,然後進到裡面:</p>
+
+<pre class="brush: bash">mkdir borderify
+cd borderify</pre>
+
+<h3 id="manifest.json">manifest.json</h3>
+
+<p>現在新增一個檔案 "manifest.json",直接放在 "borderify" 目錄底下就行,然後把下面的程式碼塞進去:</p>
+
+<pre class="brush: json">{
+
+ "manifest_version": 2,
+ "name": "Borderify",
+ "version": "1.0",
+
+ "description": "Adds a red border to all webpages matching mozilla.org.",
+
+ "icons": {
+ "48": "icons/border-48.png"
+ },
+
+ "content_scripts": [
+ {
+ "matches": ["*://*.mozilla.org/*"],
+ "js": ["borderify.js"]
+ }
+ ]
+
+}</pre>
+
+<ul>
+ <li>最前面的三個 key:<code><a href="/zh-TW/Add-ons/WebExtensions/manifest.json/manifest_version">manifest_version</a></code>、<code><a href="/zh-TW/Add-ons/WebExtensions/manifest.json/name">name</a></code>、<code><a href="/zh-TW/Add-ons/WebExtensions/manifest.json/version">version</a></code> 必須寫進去,它包含了附加元件的基本詮釋資料(metadata)。</li>
+ <li><code><a href="/zh-TW/Add-ons/WebExtensions/manifest.json/description">description</a></code> 是可選、但最好要有:它會在附加元件管理員內標示。</li>
+ <li><code><a href="/zh-TW/Add-ons/WebExtensions/manifest.json/icons">icons</a></code> 也是可選、但最好要有:它允許附加元件指定圖示、也會在附加元件的管理員顯示。</li>
+</ul>
+
+<p>這裡最有趣的 key 是 <code><a href="/zh-TW/Add-ons/WebExtensions/manifest.json/content_scripts">content_scripts</a></code>:它告訴 Firefox 說:符合特定型態的 URL 會載入網頁的腳本。在此我們告訴 Firefox 說:所有由 "mozilla.org" 或其子域名服務的 HTTP 或 HTTPS 頁面,都要載入 "borderify.js"。</p>
+
+<ul>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Content_scripts">深入理解 content script</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Match_patterns">深入理解 about match pattern</a></li>
+</ul>
+
+<div class="warning">
+<p><a href="/zh-TW/Add-ons/WebExtensions/WebExtensions_and_the_Add-on_ID#When_do_you_need_an_Add-on_ID">某些情況下,你需要給附加元件指定 ID</a>。如果需要指定附加元件 ID,請在 <code>manifest.json</code> 引入 <code><a href="/zh-TW/Add-ons/WebExtensions/manifest.json/applications">applications</a></code> key,並設定 <code>gecko.id</code> 屬性:</p>
+
+<pre class="brush: json">"applications": {
+ "gecko": {
+ "id": "borderify@example.com"
+ }
+}</pre>
+</div>
+
+<h3 id="iconsborder-48.png">icons/border-48.png</h3>
+
+<p>附加元件要有一個圖標。它會在附加元件管理員的附加元件清單旁邊列出來。我們的 manifest.json 已經說好了,要在 "icons/border-48.png" 那邊會有個圖標。</p>
+
+<p>在 "borderify" 目錄下直接建立 "icons" 目錄,並儲存一個叫 "border-48.png" 的圖標檔。你可以用<a href="https://github.com/mdn/webextensions-examples/blob/master/borderify/icons/border-48.png">範例的這張圖標</a>,它是從 Google Material Design 圖標集抓下來的,並使用<a href="https://creativecommons.org/licenses/by-sa/3.0/deed.zh_TW">創用 CC:姓名標示-相同方式分享</a>授權。</p>
+
+<p>如果你要用自己的圖標,它應該是 48x48 像素。你也可以針對高解析度提供 96x96 像素的圖標,這樣的話它在 manifest.json 會被指定為 <code>icons</code> 物件內的 <code>96</code> property:</p>
+
+<pre class="brush: json">"icons": {
+ "48": "icons/border-48.png",
+ "96": "icons/border-96.png"
+}</pre>
+
+<p>要不然,你也能提供 SVG 檔,它就會等比縮放。</p>
+
+<ul>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/manifest.json/icons">深入理解指定圖標。</a></li>
+</ul>
+
+<h3 id="borderify.js">borderify.js</h3>
+
+<p>最後,新增一個檔案叫 "borderify.js",直接放在 "borderify" 目錄底下即可,然後一樣把下面的 code 塞進去:</p>
+
+<pre class="brush: js">document.body.style.border = "5px solid red";</pre>
+
+<p>一旦網址符合 manifest.json 中 content_scripts 所設定的模式,這段 script 就會載入,並且就像該頁自己讀入的程式碼一樣、能夠直接存取該頁上的東西。</p>
+
+<ul>
+ <li><a href="/en-US/Add-ons/WebExtensions/Content_scripts">深入了解 content scripts.</a></li>
+</ul>
+
+<h2 id="測試看看">測試看看</h2>
+
+<p>首先,仔細檢查這些檔案是否在正確的位置:</p>
+
+<pre>borderify/
+ icons/
+ border-48.png
+ borderify.js
+ manifest.json</pre>
+
+<h3 id="安裝">安裝</h3>
+
+<p>在 Firefox 打開 about:debugging,點選 Load Temporary Add-on 然後選擇你的 manifest.json 檔案:</p>
+
+<p>{{EmbedYouTube("cer9EUKegG4")}}</p>
+
+<p>現在這個附加元件就要安裝起來,但它要在你重新啟動 Firefox 後才開始。</p>
+
+<p>又或者,你可以從命令列利用 <a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Getting_started_with_web-ext">web-ext</a> 工具執行 WebExtension。</p>
+
+<h3 id="測試">測試</h3>
+
+<p>現在去看一下 mozilla.org 還有它下面的所有網頁。你應該會看到有個紅色外框圍繞著網頁。</p>
+
+<p>{{EmbedYouTube("rxBQl2Z9IBQ")}}</p>
+
+<div class="note">
+<p>不過,別把這招用在 addons.mozilla.org 上,該網域目前會阻擋 content scripts。</p>
+</div>
+
+<p>再做點小實驗吧。改一下腳本讓外框顏色改變,或是做其他更動。接著存檔,並按下 about:debugging 的 Reload 鍵重啟附加元件。現在你能看到更動了:</p>
+
+<p>{{EmbedYouTube("NuajE60jfGY")}}</p>
+
+<ul>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Temporary_Installation_in_Firefox">多了解一點附加元件的載入</a></li>
+</ul>
+
+<h2 id="打包並發送">打包並發送</h2>
+
+<p>想讓別人用你的附加元件,就要把元件遞交給 Mozilla 簽署之。想獲得更多資訊,請參見 <a href="/zh-TW/docs/Mozilla/Add-ons/WebExtensions/Publishing_your_WebExtension">發布你的 WebExtension</a>。</p>
+
+<h2 id="接下來咧?">接下來咧?</h2>
+
+<p>現在你針對 Firefox 的 WebExtension 開發有點子的話,來看看:</p>
+
+<ul>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Anatomy_of_a_WebExtension">reading more about the anatomy of WebExtensions</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/Your_second_WebExtension">再寫個更進階的 WebExtension</a></li>
+ <li><a href="/zh-TW/Add-ons/WebExtensions/API">了解 WebExtensions 所提供的 JavaScript API</a></li>
+</ul>
diff --git a/files/zh-tw/mozilla/add-ons/webextensions/your_second_webextension/index.html b/files/zh-tw/mozilla/add-ons/webextensions/your_second_webextension/index.html
new file mode 100644
index 0000000000..403eff4aa7
--- /dev/null
+++ b/files/zh-tw/mozilla/add-ons/webextensions/your_second_webextension/index.html
@@ -0,0 +1,368 @@
+---
+title: 你的第二個 WebExtension
+slug: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension
+translation_of: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension
+---
+<p>{{AddonSidebar}}</p>
+
+<p>假如你已經讀過了 <a href="https://developer.mozilla.org/zh-TW/Add-ons/WebExtensions/Your_first_WebExtension">你的第一個 WebExtension</a>,你也已經知道該如何寫一個 extension(外掛),在這篇文章中我們將會教你寫一個稍微複雜一點的 extension,來 demo 一些 API 的使用。</p>
+
+<p>在這個 extension 中,將會新增一個按鈕到 Firefox 的工具列上,當使用者按下按鈕後,將會顯示一個彈出視窗 (pop-up) 並可選擇一個動物。當使用者選擇了一個動物後,將會在當前的網頁中顯示使用者所選的動物圖片。</p>
+
+<p>為了實作這個,我們將需要:</p>
+
+<ul>
+ <li><strong>定義一個 <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_action">browser action</a> 給新增於 Firefox 工具列的按鈕。</strong><br>
+ 這個按鈕,我們將提供以下功能:
+ <ul>
+ <li>按鈕的 icon,命名為 "beasts-32.png"</li>
+ <li>當按下按鈕時顯示一個彈出視窗 (pop-up),這個 pop-up將會包含  HTML, CSS 和 JavaScript。</li>
+ </ul>
+ </li>
+ <li><strong>定義一個 extension 用的 icon,</strong> 命名為 "beasts-48.png". 此 icon 將會顯示於 Add-ons Manager.</li>
+ <li><strong>寫一個內容腳本 "beastify.js" ,該檔案會被當前網頁讀取。</strong><br>
+ 讓網頁顯示所選的動物圖片的程式碼會寫在這裡。</li>
+ <li><strong>打包所需要的動物圖片,此圖片是用來顯示按下按鈕後顯示於網頁上的。</strong><br>
+ 為了讓網頁可以取用圖片,我們將會讓這些圖片變成可讓 "網頁存取的資源"。</li>
+</ul>
+
+<p>下面是這次 extension 的流程圖:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13671/Untitled-1.png" style="display: block; height: 1200px; margin-left: auto; margin-right: auto; width: 860px;"></p>
+
+<p>這個一個簡單的 extension,但是會教你許多基本的 WebExtensions API 的概念:</p>
+
+<ul>
+ <li>新增一個按鈕到工具列</li>
+ <li>利用 HTML, CSS 和 JavaScript 去定義一個 pop-up</li>
+ <li>讀取內容腳本到網頁</li>
+ <li>內容腳本與整個 extension 間的溝通</li>
+ <li>打包 extension 所需的資源,讓網頁可以存取</li>
+</ul>
+
+<p>也可以在 GitHub 上找到範例的原始碼: <a href="https://github.com/mdn/webextensions-examples/tree/master/beastify">https://github.com/mdn/webextensions-examples/tree/master/beastify</a></p>
+
+<p>實作這個 extension 前,請先確認你的 Firefox 有 45.0 或更新的版本。</p>
+
+<h2 id="實作_extension">實作 extension</h2>
+
+<p>新增一個資料夾,然後進去:</p>
+
+<pre class="brush: bash notranslate">mkdir beastify
+cd beastify</pre>
+
+<h3 id="manifest.json">manifest.json</h3>
+
+<p>在資料夾 "beastify" 下新增一個檔案,並命名為 "manifest.json",然後撰寫以下程式碼。</p>
+
+<pre class="brush: json notranslate">{
+
+ "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"
+ ]
+
+}
+</pre>
+
+<ul>
+ <li>最前面的三個 key:<code><a href="https://developer.mozilla.org/zh-TW/Add-ons/WebExtensions/manifest.json/manifest_version">manifest_version</a></code>、<code><a href="https://developer.mozilla.org/zh-TW/Add-ons/WebExtensions/manifest.json/name">name</a></code>、<code><a href="https://developer.mozilla.org/zh-TW/Add-ons/WebExtensions/manifest.json/version">version</a></code> 必須寫進去,它包含了附加元件的基本詮釋資料(metadata)。</li>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/description">description</a></code> 和 <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url">homepage_url</a></code> 為非必要但建議加上:主要在說明該 extension。</li>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/icons">icons</a></code> 為非必要但建議加上:它允許附加元件指定圖示、也會在附加元件的管理員顯示</li>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">permissions</a></code> 列出了該 extension 所需要的權限。這邊我們只會要求 <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#activeTab_permission"><code>activeTab</code> permission</a> 。</li>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action">browser_action</a></code> 定義工具列的按鈕,在這邊我們將會提供三種 key:
+ <ul>
+ <li><code>default_icon</code> 為必要的:告訴 button 該使用的 icon 為何</li>
+ <li><code>default_title</code>為非必要的:該 value 會顯示在 button 的 tip 裡</li>
+ <li><code>default_popup</code> 如果想要顯示 pop-up,此為必要的 key:此教學中有使用到 pop-up 故為必要的,並將 HTML 檔案指給他。</li>
+ </ul>
+ </li>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/web_accessible_resources">web_accessible_resources</a></code> 列出所有希望讓網頁可以存取的檔案。</li>
+</ul>
+
+<p>所有的路徑都會關連到 manifest.json 。</p>
+
+<h3 id="The_icon">The icon</h3>
+
+<p>一個 extension 應該要有一個 icon。icon 將會顯示在 Add-ons Manager 的 extension 列表中。(在 Firefox 網址列輸入 "about:addons" 開啟 Add-ons Manager)。</p>
+
+<p>在 beastify 下建立一個名為 "icons" 的資料夾,並準備一個命名為 "beasts-48.png" 的 icon並存在 "beastify/icons" 的資料夾中(可以使用我們的<a href="https://github.com/mdn/webextensions-examples/blob/master/beastify/icons/beasts-48.png">範例圖檔</a>,圖檔來源:<a href="https://www.iconfinder.com/iconsets/free-retina-icon-set">Free Retina Icon Set</a>,遵照<a href="http://www.aha-soft.com/free-icons/free-retina-icon-set/">使用條款</a>來使用)。並在 manifest.json 裡告訴他要使用 "icons/beasts-48.png" 路徑下的 icon。</p>
+
+<p>如果你想要使用自己的 icon,icon 大小必須是  48x48 pixels,另外也可使用 96x96 pixel 來支援較高解析度的顯示。</p>
+
+<pre class="brush: json line-numbers language-json notranslate"><code class="language-json"><span class="key token">"icons":</span> <span class="punctuation token">{</span>
+ <span class="key token">"48":</span> <span class="string token">"icons/beasts-48.png"</span><span class="punctuation token">,</span>
+ <span class="key token">"96":</span> <span class="string token">"icons/beasts-96.png"</span>
+<span class="punctuation token">}</span></code></pre>
+
+<h3 id="工具列按鈕The_toolbar_button">工具列按鈕(The toolbar button)</h3>
+
+<p>工具列按鈕也需要一個 icon,在 manifest.json 裡 "browser_action" 物件中的 "default_icon" 中告訴他要使用 "icons/beasts-32.png" 路徑下的 icon。。</p>
+
+<p>準備一個命名為 "beasts-32.png" 的 icon,並存在 "beastify/icons" 資料夾中(你可以使用<a href="https://github.com/mdn/webextensions-examples/blob/master/beastify/icons/beasts-32.png">範例圖檔</a>,圖檔來源:<a href="http://www.iconbeast.com/free">IconBeast Lite icon set</a>,遵守<a href="http://www.iconbeast.com/faq/">使用條款</a>來使用)。 </p>
+
+<p>假設你不使用 pop-up,當按下按鈕的時候就會觸發事件。假如使用 pop-up ,當按下按鈕時並不會觸發事件,取而代之會打開 pop-up。不過這邊我們想要用 pop-up,所以接來下會教你如何新增他。</p>
+
+<h3 id="The_popup">The popup</h3>
+
+<p>pop-up 的方法主要是讓使用者可以選擇三個動物中的其中一個。</p>
+
+<p>在 beastify 下 新增一個名為 "popup" 的資料夾,該資料夾中會包含以下三個檔案:</p>
+
+<ul>
+ <li><strong><code>choose_beast.html</code></strong> 定義 pop-up 的顯示的內容文字</li>
+ <li><strong><code>choose_beast.css</code></strong> 定義 html 裡的 styles </li>
+ <li><strong><code>choose_beast.js</code></strong> 當使用者選擇動物後實行的腳本內容</li>
+</ul>
+
+<pre class="brush: bash line-numbers language-bash notranslate"><code class="language-bash">mkdir popup
+cd popup
+touch choose_beast.html choose_beast.css choose_beast.js</code></pre>
+
+<h4 id="choose_beast.html">choose_beast.html</h4>
+
+<p>HTML 內容長得像這樣:</p>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;link rel="stylesheet" href="choose_beast.css"/&gt;
+ &lt;/head&gt;
+
+&lt;body&gt;
+ &lt;div id="popup-content"&gt;
+ &lt;div class="button beast"&gt;Frog&lt;/div&gt;
+ &lt;div class="button beast"&gt;Turtle&lt;/div&gt;
+ &lt;div class="button beast"&gt;Snake&lt;/div&gt;
+ &lt;div class="button reset"&gt;Reset&lt;/div&gt;
+ &lt;/div&gt;
+ &lt;div id="error-content" class="hidden"&gt;
+ &lt;p&gt;Can't beastify this web page.&lt;/p&gt;&lt;p&gt;Try a different page.&lt;/p&gt;
+ &lt;/div&gt;
+ &lt;script src="choose_beast.js"&gt;&lt;/script&gt;
+&lt;/body&gt;
+
+&lt;/html&gt;</pre>
+
+<p>我們在 ID 為 <code>"popup-content"</code>  的 <code><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div">&lt;div&gt;</a></code>  元件裡建立了一個包含每種動物選項的元件。當載入 popup 發生問題時,用另外一個 ID 為 <code>"error-content"</code> 且類別定義為 <code>"hidden"</code> 的 <code><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div">&lt;div&gt;</a></code>  元件來處理。</p>
+
+<p>值得注意的是我們在這個檔案裡引用了 CSS 與 JS 檔案,就如同一般網頁。</p>
+
+<h4 id="choose_beast.css">choose_beast.css</h4>
+
+<p>CSS 定義了 pop-up 的大小,並確保三個選項有填滿整個 pop-up,並給他們幾個基本的 style:</p>
+
+<pre class="brush: css notranslate">html, body {
+ width: 100px;
+}
+
+.button {
+ margin: 3% auto;
+ padding: 4px;
+ text-align: center;
+ font-size: 1.5em;
+ cursor: pointer;
+}
+
+.beast:hover {
+ background-color: #CFF2F2;
+}
+
+.beast {
+ background-color: #E5F2F2;
+}
+
+.clear {
+ background-color: #FBFBC9;
+}
+
+.clear:hover {
+ background-color: #EAEAC9;
+}
+</pre>
+
+<h4 id="choose_beast.js">choose_beast.js</h4>
+
+<p>在 pop-up 的 JavaScript 中,我們監控著 click 事件。當按下其中一個選項後,將會讀取 js 檔到當前的瀏覽器分頁(active_tab)中,當內容腳本被讀取後,將會發送一個訊息告訴他該選擇哪一張圖片。</p>
+
+<pre class="brush: js notranslate">/*
+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");
+ }
+}
+
+/*
+Listen for clicks in the popup.
+
+If the click is on one of the beasts:
+ Inject the "beastify.js" content script in the active tab.
+
+ Then get the active tab and send "beastify.js" a message
+ containing the URL to the chosen beast's image.
+
+If it's on a button which contains class "clear":
+ Reload the page.
+ Close the popup. This is needed, as the content script malfunctions after page reloads.
+*/
+
+document.addEventListener("click", (e) =&gt; {
+ if (e.target.classList.contains("beast")) {
+ var chosenBeast = e.target.textContent;
+ var chosenBeastURL = beastNameToURL(chosenBeast);
+
+ browser.tabs.executeScript(null, {
+ file: "/content_scripts/beastify.js"
+ });
+
+ var gettingActiveTab = browser.tabs.query({active: true, currentWindow: true});
+ gettingActiveTab.then((tabs) =&gt; {
+ browser.tabs.sendMessage(tabs[0].id, {beastURL: chosenBeastURL});
+ });
+ }
+ else if (e.target.classList.contains("clear")) {
+ browser.tabs.reload();
+ window.close();
+ }
+});
+</pre>
+
+<p>這邊使用了三個 WebExtensions API 的方法:</p>
+
+<ul>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/executeScript">browser.tabs.executeScript</a></code> 讀取內容腳本 "content_scripts/beastify.js" 到當前的瀏覽器分頁裡面</li>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/query">browser.tabs.query</a></code> 取得當前的瀏覽器分頁</li>
+ <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/sendMessage">browser.tabs.sendMessage</a></code> 送訊息到當前的瀏覽器分頁中正在執行的內容腳本裡(beastify.js)。訊息包含了所選的動物的 URL</li>
+</ul>
+
+<h3 id="內容腳本The_content_script">內容腳本(The content script)</h3>
+
+<p>在 beastify 下建立一個名為 "content_scripts" 的資料夾,並新增一個命名為 "beastify.js" 的檔案,檔案裡的內容:</p>
+
+<pre class="brush: js notranslate">/*
+beastify():
+* removes every node in the document.body,
+* then inserts the chosen beast
+* then removes itself as a listener
+*/
+function beastify(request, sender, sendResponse) {
+ removeEverything();
+ insertBeast(request.beastURL);
+ browser.runtime.onMessage.removeListener(beastify);
+}
+
+/*
+Remove every node under document.body
+*/
+function removeEverything() {
+ while (document.body.firstChild) {
+ document.body.firstChild.remove();
+ }
+}
+
+/*
+Given a URL to a beast image, create and style an IMG node pointing to
+that image, then insert the node into the document.
+*/
+function insertBeast(beastURL) {
+ var beastImage = document.createElement("img");
+ beastImage.setAttribute("src", beastURL);
+ beastImage.setAttribute("style", "width: 100vw");
+ beastImage.setAttribute("style", "height: 100vh");
+ document.body.appendChild(beastImage);
+}
+
+/*
+Assign beastify() as a listener for messages from the extension.
+*/
+browser.runtime.onMessage.addListener(beastify);
+</pre>
+
+<p>內容腳本中新增了一個 listener ,使其從 extension 可傳送訊息。(具體來說是從 "choose_beast.js" 這邊) ,在 listener 中做了:</p>
+
+<ul>
+ <li>removeEverything():移除 <code>document.body</code> 中所有的 element ()</li>
+ <li>insertBeast(beastURL):新增一個 <code>&lt;img&gt;</code> element 並告訴它圖片的 URL,並插入到文件中</li>
+ <li>removeListener(beastify):刪除訊息 listener</li>
+</ul>
+
+<h3 id="The_beasts">The beasts</h3>
+
+<p>最後,我們需要將動物的照片放進來</p>
+
+<p>新增一個名為 "beasts" 的資料夾,並把三張動物的圖片放進此資料夾中,請取相對應的檔名。可以使用<a href="https://github.com/mdn/webextensions-examples/tree/master/beastify/beasts">範例圖片</a> ,或從這邊下載:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/11459/frog.jpg" style="display: inline-block; height: 200px; margin: 20px; width: 200px;"><img alt="" src="https://mdn.mozillademos.org/files/11461/snake.jpg" style="display: inline-block; height: 200px; margin: 20px; width: 200px;"><img alt="" src="https://mdn.mozillademos.org/files/11463/turtle.jpg" style="display: inline-block; height: 200px; margin: 20px; width: 200px;"></p>
+
+<h2 id="Testing_it_out">Testing it out</h2>
+
+<p>首先,請再三的確認檔案有放到相對應的資料夾中:</p>
+
+<pre class="notranslate">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</pre>
+
+<p>開啟 Firefox 45.0,並安裝本地的 extensive 到瀏覽器裡。</p>
+
+<p>在 Firefox 網址列輸入 "about:debugging" ,點選 "Load Temporary Add-on",然後選擇你的 "manifest.json" 檔案。然後應該就會看到 extensive 的 icon 出現在工具列上了:</p>
+
+<p>{{EmbedYouTube("sAM78GU4P34")}}</p>
+
+<p>打開一個網頁,點選 icon,選擇一個動物的名字,將會看到網頁內容被動物的圖片取代了:</p>
+
+<p>{{EmbedYouTube("YMQXyAQSiE8")}}</p>
+
+<h2 id="透過命令行佈署">透過命令行佈署</h2>
+
+<p>你可以利用<a href="/en-US/Add-ons/WebExtensions/Getting_started_with_web-ext">web-ext</a>自動化暫時載入。<br>
+ 試試看:</p>
+
+<pre class="brush: bash notranslate">cd beastify
+web-ext run</pre>