以下的截圖畫面顯示的 panel的內容是由目前所開啟的瀏覽器分頁的清單所組成:
Panel 適合用在顯示臨時的介面給使用者,比modal dialog更方便讓使用者忽略或關閉,因為只要使用者和該應用程式介面以外的部分互動,panel就會隱藏。
Panel的內容會在其被建立的同時、panel顯示(show)之前載入,且在panel被隱藏時仍會進行內容載入的動作,因此可以做到將panel維持在背景而更新其內容為下次顯示所需。
我們可以藉由監聽(listen)panel的show 和hide 事件,來使 add-on 接收panel顯示或隱藏的通知。
Panel 的內容
Panel的內容被指定為HTML,藉由panel 的建構子中contentURL屬性來指定HTML檔案的URL並載入。
可以載入遠端的URL:
var panel = require("panel").Panel({ width: 180, height: 180, contentURL: "https://en.wikipedia.org/w/index.php?title=Jetpackuseformat=mobile" }); panel.show();
另外,也可以載入封裝在我們的add-on中的HTML檔,這通常是建立dialog的方式。
若要載入封裝在add-on中的HTML,我們要將HTML放在add-on的data目錄下,並用self模組的 data.url() 方法,如下:
var panel = require("panel").Panel({ contentURL: require("self").data.url("myFile.html") }); panel.show();
Scripting Panel Content
我們不能從main add-on 程式直接存取panel的內容,而必須載入script到panel中。在SDK中,這種scripts稱為"content scripts",因為content scripts是專門用來處理web content。
content scripts 可以存取他們所附加上的內容,但他們不能使用SDK's APIs。
因此實作一個完整的解決方案通常代表,我們必須在content script 和 the main add-on code之間傳送訊息。
- 我們可以透過Panel()建構子中的contentScript或contentScriptFile,以指定一個或多個content scripts來載入到一個panel中。
- 我們可以藉由postMessage() API 或 (較常用的) the port API來和script溝通。
var myScript = "window.addEventListener('click', function(event) {" + " var t = event.target;" + " if (t.nodeName == 'A')" + " self.port.emit('click-link', t.toString());" + "}, false);" var panel = require("panel").Panel({ contentURL: "http://www.bbc.co.uk/mobile/index.html", contentScript: myScript }); panel.port.on("click-link", function(url) { console.log(url); }); panel.show();這個例子使用了contentScript來以string提供 script。通常情況下,使用contentScriptFile來用URL來指向存放在add-on中的data資料夾裡的script 檔案會比較好,因為這樣程式較為簡潔易懂,也較易debug。
程式碼中第 13 行的 Console 用法請見這裡。
取得使用者輸入
下面的 add-on 加入一個 widget ,當其被點擊時會顯示panel。panel中只包含一個 textarea 元件:當使用者按下return key,textarea 裡的內容就會被傳送給main add-on code。
這個 add-on 包含三個檔案:
- main.js: the main add-on code, that creates the widget and panel
- get-text.js: the content script that interacts with the panel content
- text-entry.html: the panel content itself, specified as HTML
my-addon/
-data/
--get-text.js
--text-entry.html
-lib/
--main.js
"main.js":
var data = require("self").data; // Create a panel whose content is defined in "text-entry.html". // Attach a content script called "get-text.js". var text_entry = require("panel").Panel({ width: 212, height: 200, contentURL: data.url("text-entry.html"), contentScriptFile: data.url("get-text.js") }); // Send the content script a message called "show" when // the panel is shown. text_entry.on("show", function() { text_entry.port.emit("show"); }); // Listen for messages called "text-entered" coming from // the content script. The message payload is the text the user // entered. // In this implementation we'll just log the text to the console. text_entry.port.on("text-entered", function (text) { console.log(text); text_entry.hide(); }); // Create a widget, and attach the panel to it, so the panel is // shown when the user clicks the widget. require("widget").Widget({ label: "Text entry", id: "text-entry", contentURL: "http://www.mozilla.org/favicon.ico", panel: text_entry });content script "get-text.js":
self.port.on("show", function (arg) { var textArea = document.getElementById('edit-box'); textArea.focus(); // When the user hits return, send a message to main.js. // The message payload is the contents of the edit box. textArea.onkeyup = function(event) { if (event.keyCode == 13) { // Remove the newline. text = textArea.value.replace(/(\r\n|\n|\r)/gm,""); self.port.emit("text-entered", text); textArea.value = ''; } }; });最後,"text-entry.html"定義textaream元件:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <style type="text/css" media="all"> textarea { margin: 10px; } </style> </head> <body> <textarea rows="10" cols="20" id="edit-box"></textarea> </body> </html>
設定被信任的panel內容(trusted panel content)的樣式
像先前所說的,我們可以將HTML打包到add-on的data目錄底下,然後用這個HTML檔案來定義panel的內容。
我們稱這樣的檔案叫作"trusted" content,因為跟從外部來源載入add-on的內容不同,add-on的作者很清楚的知道這個trusted content是在做什麼的。和trusted content互動,我們不必使用content scripts:可以直接將script include到HTML檔案中來使用。
當我們使用data目錄下的HTML檔案來表示panel的內容時,我們可以使用CSS來設定樣式。
可以直接將CSS寫在HTML檔案中,或在HTML中參考data目錄下的CSS檔案。
若未指定樣式,則panel的預設顯示樣式會依作業系統而異:
由於這些預設的樣式,設計自己的樣式時要注意,例如在OS X環境下,如果將background-color設為白色,卻沒有設定color的話,panel的文字會看不見(因為背景色和字體顏色皆為白)。
了解更多Panel類別的詳細建構子、方法、屬性、事件,請參考這裡。
沒有留言:
張貼留言