多虧貢獻者回報,總算找到某 Firefox 套件為啥在 Mac 沒反應了——就是作者沒注意到 browser.preferences.instantApply 這個設定啦(其實抄程式的時候有看過,但是不解其意就順理成章地忽略了……)

instantApply 中文意思是「立即套用」,在 Windows 預設是 False(不會立即套用):
選項視窗會出現「確定」和「取消」按鈕,等使用者按了「確定」後設定才會生效。

instantApply 為 false

另一方面在 Linux 和 Mac,這個選項預設是 True
選項視窗不會出現確定/取消,而是出現「關閉」按鈕。使用者一旦更改選項(比方勾了某個框框),該選項便當場生效。

instantApply 為 true

問題是,如果套件只知道等使用者按「確定」才動作,那在 instantApply 有效而沒有確定鈕的情形下,套件就跟冷凍魚一樣不會動了。

出錯的是這種寫法:在 prefwindow 的 ondialogaccept(按確定/接受)事件發生時進入處理動作,結果 instantApply 啟用時,按關閉按鈕觸發的是 ondialogcancel(取消)而非 ondialogaccept 事件,導致視窗關了,套件卻什麼也沒做。

解決方式

  • 如果是單純開、關、修改對應到 prefs 的選項,那聰明的 Firefox 會自己搞定,不需特別照顧。
  • 如果要做的動作比較複雜,可以用 document.documentElement.instantApply 來取得 instantApply 到底有開沒開,有的話,再捕捉選項改變的時機,另行處理。
  • 如果做不到前一個辦法(捕捉改變時機再處理),還是可以退一步在 ondialogcancel 裡面做原本 ondialogaccept 要做的事。只是這麼一來就不是真的 instantApply 了。

實際在 Noise 套件中,因為改設定的處理比較囉唆,會存 RDF 和一些有的沒的,所以目前決定不做真正的 instantApply,而是在改變選項時,顯示一個「關閉後才會套用」的提示:

沒有提供 instantApply,就給個提示訊息吧

這個方式我覺得很好,可以接受。

參考:About:config entries - MozillaZine Knowledge Base 下的 browser. preferences. instantApply 項目