每個(gè)瀏覽器都有其自己的支持者、批評(píng)者、優(yōu)勢(shì)和劣勢(shì)。它們的共同點(diǎn)是人們將越來越多的時(shí)間花費(fèi)于其中。本系列文章將介紹如何為 Chrome、Firefox 和 Safari 構(gòu)建相同的基礎(chǔ)擴(kuò)展。您將了解到擴(kuò)展每個(gè)瀏覽器是什么樣子,執(zhí)行這些常見任務(wù)是困難還是簡(jiǎn)單,以及如何發(fā)布您的擴(kuò)展。在本文中,您將構(gòu)建一個(gè) Firefox 擴(kuò)展。
Gawkblocker 擴(kuò)展
回憶一下,Gawkblocker 支持您(以及其他用戶)屏蔽某些您不喜歡訪問的域,比如耗時(shí)的博客。Gawkblocker 有以下組件:
- 一個(gè)彈出窗口(顯示您將要屏蔽的域)
- 一個(gè)可見的瀏覽器圖標(biāo)(擴(kuò)展的入口點(diǎn))
- 一個(gè)選項(xiàng)頁面(配置您想要屏蔽以及想要訪問的域)
在 Chrome 中,Gawkblocker 擴(kuò)展將向每個(gè)選項(xiàng)卡或窗口添加一個(gè)監(jiān)聽程序,并與黑名單進(jìn)行匹配,這會(huì)將屏蔽的 URL 重定向到一個(gè)本地頁面?,F(xiàn)在,您將學(xué)習(xí) Gawkblocker 擴(kuò)展在 Firefox 中如何變化。
Gawkblocker 以特定的方式擴(kuò)展至瀏覽器,進(jìn)行一些將在其他擴(kuò)展中進(jìn)行的特定工作。正如?第 1 部分?所述,您需要回答以下這些問題:
- 在瀏覽器 UI 中擁有一席之地有多難?
- 持久化瀏覽器會(huì)話間的數(shù)據(jù)涉及到什么?
- 不同擴(kuò)展部分彼此如何通信?
- 您對(duì)用戶數(shù)據(jù)的研究有多深入?
完成 Firefox 的 Gawkblocker 構(gòu)建流程后就可以回答這些問題。
開始之前
附件就是擴(kuò)展
Firefox 擴(kuò)展被稱為附件。Chrome、Safari 和 Internet Explorer 都使用擴(kuò)展?這一術(shù)語。本系列在提及 Firefox 附件時(shí)將交替使用這兩個(gè)術(shù)語。
對(duì)于本文,您需要下載和安裝 Firefox V12 或更高版本(參閱?參考資料)。(本文示例也是基于 Firefox V12)您也需要一些可以編輯 HTML、CSS 和 JavaScript 的工具。如果您有使用 Firefox 或者 Firefox 附件的經(jīng)驗(yàn)將會(huì)很有幫助。如果沒有這方面的經(jīng)驗(yàn),那么請(qǐng)瀏覽 Mozilla Add-ons 頁面上提供的擴(kuò)展(參閱?參考資料)。試用一下本文提供的幾個(gè)上下文擴(kuò)展。
您的參考文檔是 Mozilla Add-on SDK 開發(fā)人員指南(參閱?參考資料)。您可使用 Add-on Builder( 一個(gè)基于 Web 的工具,用于構(gòu)建 Firefox 擴(kuò)展)完成大多數(shù)工作。Add-on Builder 是 Jetpack(一個(gè) Firefox 項(xiàng)目)的一部分。Jetpack 的目的是使僅使用 HTML、CSS 和 JavaScript 編寫擴(kuò)展變得更為容易(正如您為 Chrome 擴(kuò)展所做的一樣)。也可使用?其他方法?來構(gòu)建 Firefox 擴(kuò)展。
從?下載?部分獲取完整源代碼。
Firefox 擴(kuò)展剖析
其他方法
除了本文展示的流程之外,也可以選擇其他方法來為 Firefox 構(gòu)建擴(kuò)展。您可以下載 SDK 文件,Add-on Builder 可直接從 Developer Hub(參閱?參考資料)獲取該文件。下載 SDK 文件,以便您可以在構(gòu)建附件時(shí)選擇使用 IDE。
您也可以構(gòu)建一個(gè)傳統(tǒng)的(或經(jīng)典的?或 XUL)擴(kuò)展。以這種方法構(gòu)建擴(kuò)展存在缺陷:安裝擴(kuò)展需要重啟,編寫擴(kuò)展的過程較為復(fù)雜。但好處是您可以修改瀏覽器,這是使用 Add-on Builder 或 SDK 所不能實(shí)現(xiàn)的功能。例如,除了 Add-on 欄之外,也可以使用 XUL 將擴(kuò)展圖標(biāo)放置到位。您可以在 Mozilla Development Network 上閱讀有關(guān) XUL 擴(kuò)展的更多信息(參閱?參考資料)。
使用 Add-on Builder 構(gòu)建的 Firefox 擴(kuò)展可使用 CommonJS 約定導(dǎo)入所需的庫。擴(kuò)展中可以包括 HTML、CSS 和 JavaScript 文件的任意組合,但都是以 main.js 文件開始。
main.js 文件是 Firefox 擴(kuò)展的核心。該文件告訴 Firefox 導(dǎo)入哪個(gè)模塊,以及在何處執(zhí)行擴(kuò)展的初始化任務(wù)?;仡?第 1 部分?中的 Chrome 擴(kuò)展。main.js 類似于 background.html 頁面。main.js 在后臺(tái)運(yùn)行,與 Firefox 沒有直接交互,而且在啟動(dòng)過程中僅運(yùn)行一次。
也可以將大量頁面顯示在 Firefox 擴(kuò)展的?panel
?中??梢詫⑦@類頁面作為一個(gè)彈出和選項(xiàng)窗口的組合頁面,如圖 1 所示:
圖 1. 彈出/選項(xiàng)頁面
您也可以使用 Firefox 中的內(nèi)容腳本,與在 Chrome 中使用的方法基本相同。內(nèi)容腳本是可以添加到 Web 頁面進(jìn)行交互的 JavaScript 文件。在 Firefox 中,內(nèi)容腳本可在頁面上下文中有效地運(yùn)行。但是訪問 DOM 或從 DOM 中獲取都可以進(jìn)行代理以防止出現(xiàn)安全問題。內(nèi)容腳本可使用?port
與其他擴(kuò)展進(jìn)行通信。
對(duì)于 Gawkblocker,您可以使用:
- 一個(gè) main.js 文件
- 一個(gè)包含核心功能(大多數(shù)都是從 Chorme 擴(kuò)展中移植過來)的 JavaScript 文件
- 一個(gè)彈出/選項(xiàng)窗口的組合頁面
- 一個(gè)或兩個(gè)圖標(biāo)
Firefox 實(shí)現(xiàn)比 Chrome 略微簡(jiǎn)單點(diǎn),但是用戶體驗(yàn)效果實(shí)際上是一樣的。您可以從我的 Add-on Builder 配置文件(參閱?參考資料)中下載一個(gè)正在運(yùn)行的 Gawkblocker 文件來查看活動(dòng)的擴(kuò)展,和我在此處介紹的其他部分一樣。
使用 Add-on Builder
要使用 Add-on Builder,根據(jù)圖 2 所示以及在 https://builder.addons.mozilla.org/ 中提供的信息,必須完成注冊(cè)過程。然后,可以登錄到 Add-on Builder 創(chuàng)建自己的附件。
圖 2. Add-on Builder
構(gòu)建 Add-on Builder 界面的完整過程不在本文的討論范圍之內(nèi),但是在文件結(jié)構(gòu)中有兩點(diǎn)需要注意。Lib 目錄是使用?require
?導(dǎo)入庫時(shí) Firefox 所要查找的目錄。您可以將 Gawkblocker 的核心 JavaScript 類放在該目錄下。Data 目錄是存放圖像、HTML、CSS 和擴(kuò)展可能提供的其他資產(chǎn)的位置。
當(dāng)構(gòu)建一個(gè)附件并對(duì)其進(jìn)行測(cè)試時(shí),可能會(huì)提示您安裝 Add-on Builder 幫助程序。該幫助程序可在開發(fā)過程中卸載和安裝附件。
更新 Gawkblocker 核心類
在?第 1 部分?中,已經(jīng)為 Gawkblocker 編寫了一個(gè)看上去合理的可移植核心類文件。現(xiàn)在,如果在 Firefox 擴(kuò)展中使用,您就會(huì)發(fā)現(xiàn)這個(gè)類文件實(shí)際上非常方便。
事實(shí)證明,您必須進(jìn)行一些重要改變:
- 使用 Firefox?
simple-storage
?擴(kuò)展 API 代替?localStorage
- 將?
GB
?對(duì)象添加到?exports
在?第 1 部分?的類文件中,定義了一個(gè) Storage Manager 對(duì)象(名為?SM
)— 一個(gè)?localStorage
?包裝程序 — 來處理會(huì)話間的數(shù)據(jù)持久化。該代碼在 Firefox 擴(kuò)展內(nèi)不能運(yùn)行。相反,F(xiàn)irefox 提供一個(gè)名為?simple-storage
?的 API,為您實(shí)現(xiàn)數(shù)據(jù)持久化。您可以輕松地更新?第 1 部分?中的 Storage Manager 對(duì)象,如清單 1 所示:
清單 1. 更新?SM
?對(duì)象
var SM = (function () { var SS = require("simple-storage"); var my = {}; my.get = function (key) { return SS.storage[key]; } ... return my; }());
GB
?對(duì)象不需要改變,但是您必須依照 CommonJS 約定將其添加到?exports
?。清單 2 的最后一行處理該任務(wù):
清單 2. 將?GB
?對(duì)象添加到?exports
var GB = (function (SM) { var my = {}; my.blockTheseSites = { "gawker.com" : "Gawker Media", "io9.com" : "SciFi Blog", "gizmodo.com" : "Gadget Blog", ... } ... }(SM)); exports.GB = GB;
由于變化微乎其微,所以您可以輕松地將它們合并到?GB
?對(duì)象,使其在 Firefox 或 Chrome 中均可運(yùn)行(我將其留給您,可根據(jù)自己項(xiàng)目的需要進(jìn)行實(shí)現(xiàn)。)
將文件重名為 GB.js,然后上傳到 Lib 目錄。這樣您就可以看到在 main.js 中如何使用該對(duì)象了。
Gawkblocker 中的 main.js 文件
在 Chrome 中,使用后臺(tái)頁面文件檢查 URL,查看是否屏蔽。在 Firefox 中,在 main.js 文件中進(jìn)行這一項(xiàng)檢查。在 main.js 進(jìn)行任何操作之前,必須使用一系列?require
?語句導(dǎo)入計(jì)劃使用的模塊和 API,如清單 3 所示:
清單 3.?require
?語句
var data = require("self").data, tabs = require("tabs"), GB = require("GB").GB, popupPanel = require("panel").Panel({ height: 500, contentURL: data.url("popup.html") });
清單 3?中的語句依次告訴 main.js 為您提供:
- 一個(gè)可用于訪問 Data 目錄的對(duì)象
- 一個(gè)處理選項(xiàng)卡的對(duì)象
- 從主類導(dǎo)出的?
GB
?對(duì)象 - 一個(gè)保存彈出窗口的?
popupPanel
?對(duì)象,該代碼也可創(chuàng)建彈出窗口。
此外,由于創(chuàng)建的彈出窗口也可作為選項(xiàng)頁面,因而必須構(gòu)建一些監(jiān)聽程序。在 Chrome 中,您可以利用后臺(tái)頁面并告訴它您想要做什么。在 Firefox 中,可以將消息發(fā)送到 main.js 文件來實(shí)現(xiàn)同樣的目的。例如,清單 4 展示了一個(gè)將默認(rèn)登錄頁面設(shè)置為用戶選擇屏蔽網(wǎng)站的監(jiān)聽程序:
清單 4. 將默認(rèn)登錄頁面設(shè)置為用戶選擇屏蔽網(wǎng)站的監(jiān)聽程序
popupPanel.port.on("watchthis", function () { GB.setWatchThisInstead(http://www.youtube.com/watch?v=N-uyWAe0NhQ); console.log("watchthis"); });
在我們討論彈出頁面時(shí),也可以過一會(huì)將消息傳遞到該端口。
在 main.js 文件中,Gawkblocker 也可以訪問選項(xiàng)卡以查看用戶想要屏蔽哪個(gè) URL(如果有的話)。清單 5 顯示偵聽選項(xiàng)卡以進(jìn)行更新的代碼:
清單 5. 偵聽選項(xiàng)卡進(jìn)行更新
tabs.on("ready", function checkForBlock(tab) { for (site in GB.getBlockedSites()) { if (tab.url.match(site)) { tab.url = GB.getWatchThisInstead(); } } });
功能和性能類似于您在 Chrome 中所進(jìn)行的操作,API 的使用也類似于 Chrome(調(diào)用一個(gè)方法,傳遞一個(gè)回調(diào)函數(shù))
最后,將這個(gè)小徽章添加到瀏覽器右下角,創(chuàng)建一個(gè)?Widget
,如清單 6 所示:
清單 6. 創(chuàng)建一個(gè)?Widget
require("widget").Widget({ id: "GBBrowserAction", label: "Gawkblocker", contentURL: data.url("images/GB-19.png"), panel: popupPanel });
當(dāng) main.js 文件一切就緒后,就可以深入研究彈出頁面的變化。
彈出頁面
在 Chrome 擴(kuò)展中,彈出頁面僅僅是一個(gè)屏蔽域列表。現(xiàn)在正是對(duì)該設(shè)計(jì)進(jìn)行迭代的良好時(shí)機(jī)。對(duì)于 Firefox 擴(kuò)展,將功能從選項(xiàng)頁面遷移到彈出頁面。然后將一個(gè)單擊處理程序添加到彈出頁面中顯示的標(biāo)題上,該頁面將選項(xiàng)?div
?和域列表互換。該選項(xiàng)允許用戶站點(diǎn)訪問屏蔽列表,并為屏蔽站點(diǎn)提供重定向地址。圖 3 顯示了 Gawkblocker 彈出頁面中的選項(xiàng):
圖 3. Gawkblocker 彈出頁面中的選項(xiàng)
當(dāng)您在?清單 4?中建立一個(gè)端口時(shí),記得偵聽 main.js 中的?watchthis
。在清單 7 中,您可以使用?addon.port.emit
?從彈出頁面發(fā)送消息:
清單 7. 使用?addon.port.emit
?從彈出頁面發(fā)送消息
$("#watchthis").click(function () { addon.port.emit("watchthis"); $("#status").text("YOU'RE GOOD MATE. "); });
您也可以通過使用?port
?偵聽該列表,以便從 main.js 中獲取屏蔽站點(diǎn)列表。在 main.js 中,當(dāng)彈出頁面告訴您一切準(zhǔn)備就緒時(shí)就發(fā)送該列表,如清單 8 所示:
清單 8. 當(dāng)彈出頁面告訴您一切準(zhǔn)備就緒時(shí)就發(fā)送列表
popupPanel.port.on("pop", function () { popupPanel.port.emit("blocklist", GB.getBlockedSites()); ... });
在彈出對(duì)象中,可以偵聽和修改頁面,如清單 9 所示:
清單 9. 偵聽和修改頁面
addon.port.on("blocklist", function (blocklist) { $("#blockedlist").children().remove(); $.each(blocklist, function (index, value) { $("#blockedlist").append("<div class='siterow' title='"+value+"'> <div class='sitename'>"+index+"</div><span class='sitedesc'> : "+value+"</span></div>"); showBlockList(blocklist); }); });
彈出頁面請(qǐng)求 main.js 獲取屏蔽站點(diǎn)列表。然后通過該列表進(jìn)行迭代并附加屏蔽站點(diǎn)細(xì)節(jié)來在彈出窗口中顯示?div
。
重定向登錄頁面
在 Chrome 中,可將重定向發(fā)送至部分?jǐn)U展中的登錄頁面。Firefox 不會(huì)這樣做,而是直接將它們發(fā)送到源頁面(您在登錄頁面嵌入的 YouTube URL:“Hey You! Don’t Watch That! Watch This!” ) 。
可以在 main.js 中設(shè)置重定向初始條件,如清單 10 所示:
清單 10. 設(shè)置初始條件
if (!GB.getWatchThisInstead()) { GB.setWatchThisInstead("http://www.youtube.com/watch?v=N-uyWAe0NhQ"); }
圖 4 顯示了重定向登錄頁面:
圖 4. 重定向登錄頁面
在 Add-on Builder 中進(jìn)行測(cè)試
當(dāng)使用 Add-on Builder 時(shí),F(xiàn)irefox 會(huì)使得測(cè)試擴(kuò)展變得較為容易。您會(huì)得到一個(gè)錯(cuò)誤控制臺(tái)、一個(gè)測(cè)試按鈕和一個(gè) Add-on Builder 幫助程序,每次保存時(shí)這個(gè)幫助程序就會(huì)重新加載擴(kuò)展。圖 5 展示了正在運(yùn)行的 Add-on Builder 幫助程序:
圖 5. Add-on Builder 實(shí)用程序
分發(fā)您的擴(kuò)展
擴(kuò)展準(zhǔn)備就緒后,有幾種方法可供選擇來進(jìn)行分發(fā)。如果您在配置文件中將 Add-on 標(biāo)記為公開,就可以為潛在用戶發(fā)送一個(gè)鏈接,這樣他們就可以從鏈接安裝 Add-on。您也可以通過下載的方式分發(fā)一個(gè)打包的擴(kuò)展,或者將擴(kuò)展上傳到 addons.mozilla.org。
分發(fā)一個(gè)打包的擴(kuò)展
要分發(fā)一個(gè)打包的擴(kuò)展,從 Add-on Builder 下載。單擊 Download 圖標(biāo),獲取任何人都可以安裝的 XPI 文件。您也可以通過您希望的方式(郵件、托管、安裝程序以及其他方法)分發(fā)。但是您需要負(fù)責(zé)處理更新和托管。
上傳到 addons.mozilla.org
將一個(gè)擴(kuò)展上傳到 addons.mozilla.org 的過程與分發(fā)您自己的擴(kuò)展相比涉及的技術(shù)較少,但是您需要經(jīng)過一個(gè)審核流程和一些其他障礙。要完成這一過程,在配置文件中單擊緊挨著擴(kuò)展的?upload to AMO?鏈接,如圖 6 所示:
圖 6. 上傳到 AMO
遵照這里的上傳指令。
尋找答案
您的 Firefox 附件已經(jīng)完成了,現(xiàn)在應(yīng)該看看如何給出問題的答案,與 Chrome 中的答案相比:
- 在瀏覽器 UI 中擁有一席之地有多難?
- 如果想要在瀏覽器底部的 Add-on Bar 中進(jìn)行持久化,那么與 Chrome 中的難度相差無幾??梢酝ㄟ^在 main.js 中創(chuàng)建?
Widget
?來實(shí)現(xiàn)。 - 持久化瀏覽器會(huì)話間的數(shù)據(jù)涉及到什么?
- 使用特定于 Firefox 的?
simple-storage
?API。如果想要讓一個(gè) Storage Manager 類在 Chrome 和 Firefox 中運(yùn)行,那么需要實(shí)施一些特性檢測(cè) - 不同的擴(kuò)展部分彼此如何通信?
- 使用?
port
?創(chuàng)建這類通信并建立監(jiān)聽程序和發(fā)送程序。 - 您對(duì)用戶數(shù)據(jù)的研究有多深入?
- 用戶沒有顯式權(quán)限,所以您至少仍然可以訪問用戶訪問的每個(gè) URL。這非常重要。
結(jié)束語
擴(kuò)展僅僅只是在 Firefox 附件中進(jìn)行操作的開始。距離測(cè)試 Add-on Builder 可給予您的極限還很遠(yuǎn)。如果想要深入研究,這里可提供更多信息。在 Add-on Builder、Add-on SDK 和更為復(fù)雜的 XUL 擴(kuò)展之間,您可通過多種方法將觸角延伸至 Firefox 。
敬請(qǐng)期待本系列第 3 部分,其中您可以將 Gawkblocker 移植到 Safari 瀏覽器中。
注:本文轉(zhuǎn)自伯樂在線。
掃碼二維碼 獲取免費(fèi)視頻學(xué)習(xí)資料
- 本文固定鏈接: http://www.wangchenghua.com/post/1731/
- 轉(zhuǎn)載請(qǐng)注明:轉(zhuǎn)載必須在正文中標(biāo)注并保留原文鏈接
- 掃碼: 掃上方二維碼獲取免費(fèi)視頻資料