編程學(xué)習(xí)網(wǎng) > WEB開發(fā) > 瀏覽器兼容 > 創(chuàng)建您自己的瀏覽器擴(kuò)展,第二部分: 將您的觸角延伸至 Firefox
2014
11-11

創(chuàng)建您自己的瀏覽器擴(kuò)展,第二部分: 將您的觸角延伸至 Firefox

每個(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)頁面

67db7e3dbc898cbcfa2f33248effab92

您也可以使用 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

be61df50ca9e15d1c053a2be18a939c4

構(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)

8765c2788e66aca9ce35626af41af3b61

當(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. 重定向登錄頁面

ccdcd0f148ccb61c3f590fdffeb37cca

在 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í)用程序

5d1ac67582c45fea9ba35d70f1a93256

分發(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

6b731fbf2d0561850d560738f69f9bd7

遵照這里的上傳指令。

尋找答案

您的 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í)資料

Python編程學(xué)習(xí)

查 看2022高級(jí)編程視頻教程免費(fèi)獲取