背景
DartでChrome拡張機能を作るときにはchromeパッケージを使うと思いますが
sendMessageAPI周りが正しく動かないのであきらめてdart:jsパッケージを使って手動で解決する方法です。
正しく動かないコード
content.dart
main() async {
var res = await chrome.runtime.sendMessage('soy source');
print(res);
}
background.dart
main() async* {
await for (var msgEvent in chrome.runtime.onMessage) {
print(msgEvent.message);
msgEvent.sendResponse('hello' + msgEvent.message);
}
}
Uncaught Error: Could not establish connection. Receiving end does not exist.(...)というエラーが出ます。
動くコード
context["chrome"]からメッセージング用のAPIを取り出して使います。
Content Script -> Background -> Content Script
content2.dart
void main() {
context['chrome']['runtime'].callMethod('sendMessage',
[ "soy source", (result) => print(result)]);//二秒後に "hello tab: xxx name:soy source" と表示されます。
}
background2.dart
void main() {
var jsObject = context['chrome']['runtime']['onMessage'];
(jsObject is JsObject ? jsObject : new JsObject.fromBrowserObject(jsObject))
.callMethod('addListener', [onMessage]);
}
bool onMessage(request, sender,JsFunction response) {
var tabID = new JsObject.fromBrowserObject(sender)["tab"]["id"];
new Timer(new Duration(seconds: 2), () {
response.apply(["hello tab: $tabID name:$request"]);
});
return true; //trueにしないと非同期でレスポンスを返せません。
}
Background -> Content Script -> Background
content3.dart
void main(){
var jsObject = context['chrome']['runtime']['onMessage'];
(jsObject is JsObject ? jsObject : new JsObject.fromBrowserObject(jsObject))
.callMethod('addListener', [onMessage]);
}
void onMessage(request, sender,JsFunction sendResponse) {
print("request $request");
sendResponse.apply(["hey $request"]);
}
background3.dart
void main() {
new Timer(new Duration(seconds: 5),(){ //拡張機能をリロードしてから五秒以内にContent Scriptが挿入されているページをリロードしないとうまく動きません。
context['chrome']['tabs'].callMethod(
'sendMessage', [ 376, "マヨネーズ",(result) => print(result)]); //"hey マヨネーズ"と表示されます
});
}