aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/mozilla/add-ons/webextensions/your_second_webextension/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/zh-tw/mozilla/add-ons/webextensions/your_second_webextension/index.html')
-rw-r--r--files/zh-tw/mozilla/add-ons/webextensions/your_second_webextension/index.html368
1 files changed, 368 insertions, 0 deletions
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>