firefoxのWeb Extensionsのtabs APIのtips


Web Extensitons でfirefoxのアドオンを作って、詰まった諸々をメモ

https://github.com/thrakt/load-nexttab-firefox
https://github.com/thrakt/hatenabookmark-show-count-firefox

tabsはbackgroundでしか動かない

permissionsでtabsを追加しても、backgroundで動かしているスクリプト配下でしかbrowser.tabsは見えない。

未読タブを識別する方法はないっぽい

firefoxは開いたタブをセッションとして保存でき、再起動時に同じタブを開いた状態で再開できる。しかし、再開時は開いていないタブは未読み込み状態になる。これを識別する方法が見つからなかった。

一度開いたタブはcompleteになってしまう。作ったアドオンでは、グローバル変数に実際に読み込んだタブを記録してなんとかしましたが、どうだろう……。

tabs.onCreatedは起動時に全タブで呼ばれる

tabs.onCreatedはタブの作成時に発行されるイベントですが、起動時に全タブで呼ばれます。起動時は呼ばなくていいんだけど、起動後に新しいタブを追加した時は呼びたい、みたいな時に困る。

DOMのloadイベント的な、ブラウザの起動処理が終わった後に呼ばれる物が欲しかったんだけどないっぽい。runtime.onStartupで行けるかと思ったら、本当に起動時に呼ばれてしまうので意味がない。

挙動を見たところ、次の順で呼ばれる。

  • runtime.onStartup
  • tabs.onCreated 全タブ
  • tabs.onActivated

tabs.onActivatedはタブ移動時に毎回呼ばれますが、起動時にも1度呼ばれます。なので、tabs.onActivatedで一回だけイベントリスナへの追加をすれば先述の挙動は作れる。これでとりあえず解決。

tabs.onActivatedは読み込み前に呼ばれる

tabs.onActivatedはタブの読み込み完了前に呼ばれます。タブ作成時のtab.urlabout:blankなので、ここに依存する処理を書くと困る。

タブの作成時の動きとして、

  1. tab.urlabout:blankで、tab.statuscomplete
  2. tab.urlが開くURLになり、tab.statusloading
  3. 読み込み完了後、tab.statuscompleteになる

となる。なので、tabs.onUpdatedで呼ばれるようにして、読み込み完了後に処理するようにする。

browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  if (tab.status === 'complete' && tab.url.startsWith('http')) {
    // something to do
  }
});

という感じ。