20120321

開發自己的 Firefox add-on 附加元件(三) Widget 模組

Morzilla 官方有提供 Add-on SDK,其中包含了 API。我們利用已寫好的 API 模組,可以快速的建構出基本功能。
本篇將介紹 Widget 模組。並以 Add-on builder來製作、解說範例。

Widget 是顯示在 Firefox 附加元件列(add-on bar,可用 Ctrl+/ 來開啟或關閉)的內容,可能是一個小icon、或是複雜的網頁內容;可以讓其被點擊時展開panel、或是自訂一個 click handler 來指定被點擊時所做的動作(例如在瀏覽器中開啟一個新分頁)。

建立與內容
widget 可以包含圖像或網頁內容。網頁內容可以用content 屬性以 sting 直接顯示,或者用contentURL屬性,透過URL來指向想顯示的內容。

建立widget時,widget會自動加到附加元件列中,我們可以設定widget 的寬度(width 屬性),但widget的高度為了符合附加元件列的高度,所以是固定的。若widget的內容是一個圖片,它將會被自動調整成16*16大小。

以下的範例是widget包含一個圖片:
require("widget").Widget({
  id: "mozilla-icon",
  label: "My Mozilla Widget",
  contentURL: "http://www.mozilla.org/favicon.ico"
});

注意:上段程式碼需寫在Add-on builder介面中 main.js檔案裡,且位置為:
(若不清楚如何開始使用Add-on builder,請參考這篇文章)
exports.main = function() {
//程式碼加在這裡
//以下若未特別註明則皆為如此
};

程式碼輸入完畢後,按下 Test按鈕,應該會看到如下畫面



滑鼠游標移到圖示上,會顯示我們定義在 label 屬性中的文字 "My Mozilla Widget"。

contentURL 也可以指向放置在add-on專案中的檔案。
首先我們建立一個簡單的 HTML 檔案,命名為"myHTML.html",內容如下

I'm the content of HTML file.

然後在Add-on builder左側的 data目錄下加入這個HTML 檔案



可以直接指向本機 myHTML.html的路徑來上傳我們剛才預先寫好的檔案(有可能發生error403而無法上傳,若發生則建議採取以下方法),或者在data目錄下新增一個空白檔案。新增空白檔案時指定的名稱需打上副檔名 (.html),否則系統預設的檔案格式是 .js,附檔名在檔案建立之後也可以修改。



若使用直接在Add-on builder內新增空白HTML檔案的方法,則在檔案新增完之後,將其開啟,並輸入前述 myHTML.html檔內的程式碼。

接著,在main.js中輸入以下程式碼
exports.main = function() {

var data = require("self").data;
 
require("widget").Widget({
  id: "my-widget",
  label: "My Widget",
  width:200,//設定widget的寬度以顯示完整內容
  contentURL: data.url("myHTML.html")
});

};
line3我們載入了 self 模組(將會在之後的文章中詳細說明),並在line9使用了 self 模組的 data.url方法來連結資料夾(此處為data 資料夾)中的檔案(myHTML.html)。
按下Test按鈕,顯示結果如下:



也可以用content 屬性,直接定義widget 顯示內容
require("widget").Widget({
  id: "hello-display",
  label: "My Hello Widget",
  content: "Hello!",
  width: 50
});



scripting widget content
為了要和widget的內容互動,我們必須載入另外獨立的script檔案到panel中。在SDK中我們將這些檔案稱作 content scripts,因為這些檔案是專門用來與網頁內容作互動。

雖然 content scripts 可以存取widget的內容,但不能使用SDK's APIs。所以建置一個完整的解決方案通常需要在content script 和 main add-on code之間傳送訊息。
  • You can specify one or more content scripts to load into the widget using the contentScript or contentScriptFile options to the Widget() constructor.
  • You can communicate with the script using either the postMessage() API or (preferably, usually) the port API.

Widget的面板(Panel)
可以提供Panel 給Widget 建構子,如此一來當使用者點擊widget就會自動顯示panel。
data = require("self").data
 
var clockPanel = require("panel").Panel({
  width:215,
  height:160,
  contentURL: data.url("clock.html")
});
 
require("widget").Widget({
  id: "open-clock-btn",
  label: "Clock",
  contentURL: data.url("History.png"),
  panel: clockPanel
});
目前這是唯一可以增加panel給Widget的方法。

我們必須在widget的建構子中設定panel,如果是在widget建構之後才指定panel,則panel仍可顯示,但不會被標記在widget的位置,也就是不會在widget的上方顯示:
data = require("self").data
 
var clockPanel = require("panel").Panel({
  width:215,
  height:160,
  contentURL: data.url("clock.html")
});
 
var widget = require("widget").Widget({
  id: "open-clock-btn",
  label: "Clock",
  contentURL: data.url("History.png")
});
 
widget.panel = clockPanel;
 
// Will not be anchored
widget.panel.show();
如果把panel.show() 寫在widget的onClick function中,panel也無法被標記在widget的位置:
data = require("self").data
 
var clockPanel = require("panel").Panel({
  width:215,
  height:160,
  contentURL:data.url("myHTML.html")
});
 
var widget=require("widget").Widget({
  id: "open-clock-btn",
  label: "Clock",
  contentURL: data.url("favicon.ico"),
  panel: clockPanel,
  onClick:function(){
      this.panel.show();
  }
});

了解更多Widget類別的詳細建構子、方法、屬性、事件,請參考這裡

沒有留言:

張貼留言