更新 Firefox 3.5 擴充套件

本文為試圖更新其擴充套件以在 Firefox 3.5 中正常工作的擴充套件開發者提供了有用的資訊。

更新基礎知識

本節涵蓋了您在更新擴充套件以適應新版 Firefox 時需要做的基礎工作。

測試您的擴充套件

首先編輯擴充套件的 install.rdf 檔案,將 maxVersion 更新為 3.5b4(如果您在 Firefox 3.5 Beta 4 上進行測試),並增加擴充套件的 version

然後建立一個新的 Firefox 配置檔案,這樣您的測試就不會危及您的常規配置檔案。導航到包含 Firefox 的目錄,然後輸入命令:

bash
firefox -createProfile testBeta4

在 Mac 上,您需要一路導航到 Firefox 應用程式包內。

bash
cd /Applications/Firefox.app/Contents/MacOS/
firefox -createProfile testBeta4

透過在命令列中輸入此命令,使用新配置檔案啟動 Firefox:

bash
firefox -P testBeta4

全面測試您的擴充套件。建議您將以下首選項設定為 true,以便在出現任何 JavaScript 警告或異常時收到通知:

  • javascript.options.strict
  • javascript.options.showInConsole

更新您的擴充套件

如果在測試過程中遇到任何問題,請更新您的程式碼以解決這些問題。本文包含有關可能需要一些工作才能完成的內容的有用資訊。

完成之後,請嘗試再次使用您的擴充套件,這次使用您的常規配置檔案。這將有助於確保與任何現有的儲存資料相容。

在 addons.mozilla.org 上更新您的擴充套件

最後,是時候釋出您更新後的擴充套件了。如果您的擴充套件不需要任何程式碼更改,您可以登入 AMO 儀表板並在那裡更新相容性版本。否則,您需要將新版本上傳到 AMO。

有關更多資訊,請參閱 提交外掛到 AMO

訪問 Places 資料庫

在 Firefox 3.5 之前,直接使用 Storage API 訪問 Places 資料庫需要一些技巧。

js
var places = Components.classes["@mozilla.org/file/directory_service;1"]
  .getService(Components.interfaces.nsIProperties)
  .get("ProfD", Components.interfaces.nsIFile);
places.append("places.sqlite");
var db = Components.classes["@mozilla.org/storage/service;1"]
  .getService(Components.interfaces.mozIStorageService)
  .openDatabase(places);

這會手動構建一個通往 places.sqlite 資料庫檔案的路徑,然後開啟檔案以供 Storage 訪問。

Firefox 3.5 添加了一個專用服務,它提供了一種方便的方式來訪問 Places 資料庫;上述技術在 Firefox 3.5 或更高版本中不再有效。

js
var db = Components.classes[
  "@mozilla.org/browser/nav-history-service;1"
].getService(Components.interfaces.nsPIPlacesDatabase).DBConnection;

搜尋文字框

timed 型別的 textbox 已棄用;您應該改用 search

在 Firefox 3 中,您可能使用過

xml
<textbox type="timed" timeout="1000" oncommand="alert(this.value);"/>

在 Firefox 3.5 中,您應該將其更改為

xml
<textbox type="search" timeout="1000" oncommand="alert(this.value);"/>

JSON

JSON.jsm JavaScript 模組在 Firefox 3.5 中已被移除,轉而支援原生的 JSON 物件。有關詳細資訊,請參閱關於 JSON 的文章,其中概述了 JSON 以及如何在不同版本的 Firefox 中使用它。

為了確保與 Firefox 3 和 Firefox 3.5 的相容性,您可以這樣做:

js
if (typeof JSON === "undefined") {
  Components.utils.import("resource://gre/modules/JSON.jsm");
  JSON.parse = JSON.fromString;
  JSON.stringify = JSON.toString;
}

這透過匯入 JSON.jsm JavaScript 模組(如果 JSON 不支援原生)來實現,然後將該模組提供的方法對映到原生 JSON 使用的方法,以便相同的呼叫都能正常工作。

您也可以透過直接使用 nsIJSON 介面來繞過此問題。

上下文選單更改

為了支援 Gecko 1.9.1 中新增的新音訊和影片功能,nsContextMenu 類已將 imageURL getter 重新命名為 mediaURL;但是,imageURL 已於 2009 年 6 月 9 日重新新增。

Chrome 註冊更改

Firefox 3.5 修復了一個可能允許使用遠端 chrome 的安全漏洞。這將影響任何在其 chrome.manifest 檔案中包含引用網站、資料或資源 URL 的資源的外掛。有關詳細資訊,請參閱 Firefox 3.5 的安全更改

從請求中獲取載入上下文

以前,可以透過查詢各種 docShell API 從請求中獲取載入上下文。特別是,使用 notificationCallbacks.getInterface(nsIDOMWindow) 來獲取與載入關聯的視窗物件是一種常見做法。雖然舊方法在某些情況下可能有效,但不再推薦使用(詳情)。

正確且可靠的方法是使用 nsILoadContext(請參閱 介面定義)。

從 JavaScript,您可以這樣做:

js
var loadContext;
try {
  loadContext = aRequest
    .QueryInterface(Components.interfaces.nsIChannel) // aRequest is equivalent to aSubject from observe
    .notificationCallbacks.getInterface(Components.interfaces.nsILoadContext);
} catch (ex) {
  try {
    loadContext = aRequest.loadGroup.notificationCallbacks.getInterface(
      Components.interfaces.nsILoadContext,
    );
  } catch (ex) {
    loadContext = null;
  }
}
// you can now use |loadContext.associatedWindow| to get the Window object

另一個 JavaScript 示例,如果上述方法不起作用:

js
// SOURCE: http://stackoverflow.com/questions/10719606/is-it-possible-to-know-the-target-domwindow-for-an-httprequest

function getWindowForRequest(request) {
  if (request instanceof Components.interfaces.nsIRequest) {
    try {
      if (request.notificationCallbacks) {
        return request.notificationCallbacks.getInterface(
          Components.interfaces.nsILoadContext,
        ).associatedWindow;
      }
    } catch (e) {}
    try {
      if (request.loadGroup && request.loadGroup.notificationCallbacks) {
        return request.loadGroup.notificationCallbacks.getInterface(
          Components.interfaces.nsILoadContext,
        ).associatedWindow;
      }
    } catch (e) {}
  }
  return null;
}

從 C++,您可以這樣做:

cpp
nsCOMPtr<nsILoadContext> loadContext;
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
NS_QueryNotificationCallbacks(channel, loadContext);

可自定義工具欄

在 Firefox 3.5 中,可自定義工具欄的行為已發生更改,現在 <xul:toolbar/> 繫結會從其關聯的 <xul:toolbarpalette/> 中移除工具欄項並將其新增到工具欄,而不是克隆它們並複製到工具欄。這意味著調色盤現在只會包含不在工具欄上的項,而不再像以前那樣包含無論是否顯示在工具欄上的所有可自定義元素。這可能會給那些依賴於能夠從 <xul:toolbarpalette/> 中檢索所有可自定義工具欄項,或嘗試動態將項插入調色盤以在工具欄自定義期間使其可用的外掛帶來麻煩。有關更多資訊,請參閱 Firefox bug 407725WebKit bug 467045

XPCNativeWrapper

從 Firefox 3.5 開始,您不能再在使用了 XPCNativeWrapper 自動化的 chrome 包中使用 data: 繫結。這解決了潛在的安全問題。

XUL 文件現在會進行 XPCNativeWrapper 處理,因此您現在需要使用 getAttribute() 方法來獲取屬性值,而不是直接讀取它們。

如果您的擴充套件使用了 xpcnativewrappers=no(這種情況不應該發生,因為它不安全),那麼從 Firefox 3.5 開始,該擴充套件的 XBL 將不會應用於使用 XPCNativeWrapper 自動化的文件。

新的相關功能

監聽所有標籤頁上的事件

Firefox 3.5 引入了對新增和移除偵聽所有標籤頁的進度監聽器的支援。有關詳細資訊,請參閱 監聽所有標籤頁上的事件

面向主題開發者

  • 請參閱 Firefox 3.5 中的主題更改
  • 訪問 MozillaZine 論壇 FF3.1 的主題更改,以獲取 3.0 和 3.1 之間影響主題開發者的所有更改的概覽/列表。這包括新的 CSS 功能(如 nth-child、-moz-box-shadow 等)、現有小部件的更改、整體 UI 改進以及新的 FF3.1 功能(音訊/影片支援、隱私瀏覽、擴充套件的會話恢復、盒狀/視窗/文字陰影)。