Messaging inside Chrome Extension in ClojureScript -
i'm trying write chrome extension basic communication between content script , background page.
in javascript register listeners in both content , background pages, example in background page:
chrome.browseraction.onclicked.addlistener(function(tab) { // send message active tab chrome.tabs.query({active: true, currentwindow: true}, function(tabs) { var activetab = tabs[0]; chrome.tabs.sendmessage(activetab.id, {"message": "clicked_browser_action"}); }); });
(taken this tutorial).
another example works in javascript:
// content.js chrome.runtime.sendmessage({screenshot: true}, function(response) { console.log("response: " + response); }); // background.js chrome.runtime.onmessage.addlistener( function(request, sender, sendresponse) { alert('message received!'); console.log("request: " + request); if (request.screenshot) { // } });
how can translate above code clojurescript?
my first attempt create project based on lein-chrome-extension template , use khroma's runtime/connect
methods rely on core-async. don't proper communication between content.cljs
, background.cljs
scripts. in content.cljs
have:
(defn init [] (go (let [bg (runtime/connect)] (console/log "content script test") (while true (>! bg :lol-i-am-a-content-script) (console/log "background said: " (<! bg))))))
and in background.cljs
:
(defn on-connect-listener [] (console/log "on-connect-listener") (go-loop [channel (runtime/on-connect)] (let [content (<! channel)] (console/log "content script said: " (<! content)) (>! content :fml-i-am-the-background-script) (recur channel))))
(defn init [] (on-connect-listener))
in chrome console "background said: fml-i-am-the-background-script" messages, therefore messages sent background content page, not vice versa (i have expected "content script said: lol-i-am-a-content-script" well).
most making obvious mistake(s) here. can please help?
thanks!
two weeks ago started working on chrome extension in clojurescript. started using khroma , had no problem in using library achieve two-way communication between background page , content script (or background page , popup button page). can confirm library works. unfortunately, don't see obvious mistake in code examples here.
as side note: didn't how khorma "abused" code.async channels implement duplex communication. khroma gives channel-like object upon connection. putting message on send message , taking message wait receive message. easy? not core.async channel contract. in core.async putting , taking operates on the same queue , can done by anyone (producer or consumer). khroma turned "channel" has 2 queues inside. 1 sending , 1 receiving. if put on channel, cannot take (for example). confusing me @ first. , think confuses well, code hard read:
(let [content (<! channel)] (console/log "content script said: " (<! content)) (>! content :fml-i-am-the-background-script))
the problem >! never blocks (in khroma case putting means sending , non-blocking function call , has nothing channel). <! can "block" if there no message available on channel.
so decided write own library replace khroma. not fix minor design flaw, because wanted auto-generate library chromium sources, covers apis automatically.
the library called chromex , have released simple chrome extension sample project along documentation: https://github.com/binaryage/chromex-sample
the code background page looks this: https://github.com/binaryage/chromex-sample#background-page
note wrap runtime.port
core.async-like channel, don't pretend two-way communication. can take! channel receive message (channel wrapper implements core-async/readport protocol). post message have use separate post-message!
protocol method.
Comments
Post a Comment