Chromium拡張始まったな

id:Constellation さんのナイスなスクリプトによって、Mac でも拡張が作れるようになって、(自分の中で) 俄然盛り上がってきた。

というわけで、色々試行錯誤中だけど、ノウハウ共有のために書いておく。

URL指定

id:swdyh さんにコメントで教えてもらった。

manifest.json の matches はかなり面倒。ワイルドカードだと思っているとハマる。

本当に全部のページに適用したい時は、

"matches" : ["http://*/*", "https://*/*", "file:///*"]

だけでは不完全で、

"matches" : ["http://*/*", "https://*/*", "file:///*", "file://*/*", "chrome://*/*"]

と書かないといけない。(file://localhost/ と file:/// は同じものだけど、マッチングパターン的には違うものと見做される)

"chrome-extension://*/*" も入れたかったけど、なぜか invalid values とか言われるので無理っぽい。

拡張とページ、あるいは拡張間で任意のオブジェクトを受け渡しする

各拡張はそれぞれ別の window オブジェクトを持っているので、ある拡張で

window.foo = 'hoge';

とかやったとしても、ページや他の拡張からは見えない。

しかし、イベントオブジェクトは共有するらしい。


id:os0x さんの記事↓を参考に、ある拡張ではイベントを投げるだけの関数を定義して、window オブジェクトを投げてみる。

function dispatch_event(type,opt){
  var ev = document.createEvent('Event');
  ev.initEvent(type, true, true);
  if (opt)
    for (var k in opt)
      if (!ev[k])
  ev[k] = opt[k];
  document.dispatchEvent(ev);
}

window.onclick = function(){
  dispatch_event('foo',{foo:window});
}

別の拡張やページのスクリプトで、このようにすると、ちゃんと拡張の window オブジェクトが取れる。

window.addEventListener('foo',function(e){
  alert(e.foo);  //=> [object global]
},false)

他にも、

alert(e.foo === window);  //=> false
alert(e.foo.document === window.document);  //=> true

という具合になる。document は共有、window は分離。わかりやすい。


document は共有なので、document オブジェクトに追加したプロパティは、ページ側からも他の拡張からもアクセスできる。

というわけで

今後は keyconfig を本格的に作ろうかな。