拡張間連携とEvent Driven JavaScript
click this and start slide
自己紹介
- Taberareloo
- LDRFullFeed
- ChromeFullFeed
れんけい!!
Chromeの拡張は連携ができる!!
Chrome拡張間連携
拡張間で連携できるAPIがある
受信側
chrome.extension.onConnectExternal chrome.extension.onRequestExternal
送信側
chrome.extension.sendRequest chrome.extension.connect
Background間の連携
background page同士で連携ができる. => 夢が広がる
用意しなくてもmigemoできる.
Key用EventListenerをいくつも引っ掛けるのは無駄
問題点
backgroundだけ?
content script間の連携
content script領域はそれぞれ別に分かれていて,
(IsolatedWorld参照)
Greasemonkeyのようにwindowが共有されてない
できるかなって 拡張連携
じゃあできないの?
できます.
Event Driven JS
Eventを使えばいける!
もともとEvent Drivenなやり方はcontentWindowがないChrome Extensionにおいて使われてきた.
独自のEventを定義して, Event の Dispatchを使って拡張同士がcontent script領域でやりとり
content scriptでのcontentWindow
content scriptからcontentWindowが消えた…
- javascript: urlによる実行
- script要素をpageにappend
結果を受け取りたかったらどうするの…
=> Event
MessageEvent
MessageEventを使えば, JSONにシリアライズ可能なデータをやり取り出来る
例によってnanto_viさんのblogを
送信側
ChromeFullFeedから抜粋
page上で実行されるscript(content scriptじゃなくて, script要素で作ったもの)
// event作成 var ev = document.createEvent('MessageEvent'); // text dataを載せて ev.initMessageEvent('LDRFullFeed.load', true, false, text, location.protocol+"//"+location.host, "", window); // container(DOM Element)からdispatch container.dispatchEvent(ev);
MessageEventとstructured clone
ちなみに, Chrome 5からはMessageEventのdataに文字列以外(JSのObjectなど)が自動でcloneされて入るようになり, JSON.stringifyとJSON.parseの手間がなくなる. (structured clone)
受信側
window.addEventListener('LDRFullFeed.load', function(ev){ // eventを受け取り // JSON.parse(ev.data)してobjectに変換 // containerからdispatchしておくと, // ev.targetから対象のDOM Elementも送り付けられる fullfeed(JSON.parse(ev.data), ev.target); }, false);
注意
eventのpropertyは, 通常のもの以外content script領域に入ったら見ることができません.
// event作成 var ev = document.createEvent('Event'); // text dataを載せて ev.initEvent('LDRFullFeed.load', true, false); // propertyに入れて ev.text = text document.body.dispatchEvent(ev);
この時のev.textはcontent scriptからじゃ見れない.
そのためにMessageEventをつかう.
Content Script上での連携
これを拡張間連携で使う
例: ChromeKeyConfig
ChromeKeyConfigにあらかじめbackground pageから呼び出して欲しいeventを登録する.
これのおかげでChromeKeyConfig上にTaberarelooのメニューがでてる.
実例(Taberareloo)
var CHROME_GESTURES = 'jpkfjicglakibpenojifdiepckckakgk'; var CHROME_KEYCONFIG = 'okneonigbfnolfkmfgjmaeniipdjkgkl'; var REGISTER = { 'CHROME_GESTURES' : false, 'CHROME_KEYCONFIG': false }; var action = { group:'Taberareloo', actions:[ {name:'Taberareloo.link'}, {name:'Taberareloo.quote'}, {name:'Taberareloo.general'} ] }; chrome.extension.sendRequest(CHROME_GESTURES, action, function(res){ REGISTER['CHROME_GESTURES'] = true; }); chrome.extension.sendRequest(CHROME_KEYCONFIG, action, function(res){ REGISTER['CHROME_KEYCONFIG'] = true; });
Content Scriptでは
先程登録したEventをlistenする.
window.addEventListener('Taberareloo.link', TBRL.link, false); window.addEventListener('Taberareloo.quote', TBRL.quote, false); window.addEventListener('Taberareloo.general', TBRL.general, false);
このEventがChromeKeyConfigから登録されたキーが入力されるとdispatchされるので, あとはそれをこちら側で処理すればいい.
MessageEventなので, ev.dataには向こうから情報をこちらに送ってくることができる!!
まとめ
- ChromeはIsolatedWorldで区切られた拡張の中で連携できる
- クリーンな連携. 拡張同士のバッティングが起きにくい
- sendRequestでbackground同士で拡張間連携ができる
- IsolatedWorldで区切られているので, メッセージベースの非同期な連携
- 同じ機能を持った拡張なんていくつもいらない
- 協調行動
- MessageEventを使ってEvent DrivenなJS
- content scriptとcontentWindow (GM風に言うとunsafeWindow)を行き来できる
- 拡張間で非同期な連携ができる
終わり
ありがとうございました
-
krtx liked this
-
innervisions reblogged this from otsune
-
lagash reblogged this from syanaash
-
syanaash reblogged this from otsune
-
stardance reblogged this from otsune
-
stardance liked this
-
ukar reblogged this from otsune
-
nashi-kyo reblogged this from otsune
-
otsune reblogged this from utatane-constellation
-
8th713 liked this
-
laclefyoshi reblogged this from utatane-constellation
-
syoichi liked this
-
utatane-constellation posted this