content script to panel communication

411 views
Skip to first unread message

Raymond Camden

unread,
Jan 10, 2013, 2:13:34 PM1/10/13
to chromium-...@chromium.org
I'm having a heck of a time trying to get code in my content script to talk to my panel. From my content script I can do this:

chrome.extension.sendMessage({greeting: "hello"}, function(response) {
 console.log(response.farewell);
});

and I can pick it up in a background script no problem.

chrome.extension.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.greeting == "hello") sendResponse({farewell: JSON.stringify(sender)});
});

But I need my message to be picked up in my devtools JS. That way I can speak to the panel I've added to dev tools. How can I do that?

John J Barton

unread,
Jan 10, 2013, 2:40:26 PM1/10/13
to Raymond Camden, Chromium-extensions
You're half way there ;-).  You have to proxy the messages through the background process.  Maybe my code will offer some hints:

That said, I pretty much gave up on content scripts for devtools work. In addition to this silly proxy business, theses solutions don't work for mobile aka remote debugging. I've devolved to using evaluate to send from devtools to page and specially marked console log messages to send from page to devtools.

HTH,
jjb  

Raymond Camden

unread,
Jan 10, 2013, 2:58:58 PM1/10/13
to Chromium-extensions
I'm afraid that is a bit much to chew on. Any chance you could give me an idea where specifically in ChannelPlate.js I should be looking?

Some context - not that I think it will help, but just to let you know what I'm doing.

I've got a simple script that looks for schema (basically items marked up with itemscope/item prop). My idea was to add a simple panel to the dev tools that would render all these items. This way you could see a 'data view' of these things from a HTML page.

content script picks up the stuff perfect, but I just can't get the darn data over to devtools.js where I'd be able to update the panel DOM with the results.
--
===========================================================================
Raymond Camden, Adobe Developer Evangelist

Email : raymon...@gmail.com
Blog : www.raymondcamden.com
Twitter: cfjedimaster

John J Barton

unread,
Jan 10, 2013, 3:08:55 PM1/10/13
to Raymond Camden, Chromium-extensions
On Thu, Jan 10, 2013 at 11:58 AM, Raymond Camden <raymon...@gmail.com> wrote:
I'm afraid that is a bit much to chew on. Any chance you could give me an idea where specifically in ChannelPlate.js I should be looking?

ChromeDevtoolsProxy
 

Some context - not that I think it will help, but just to let you know what I'm doing.

I've got a simple script that looks for schema (basically items marked up with itemscope/item prop). My idea was to add a simple panel to the dev tools that would render all these items. This way you could see a 'data view' of these things from a HTML page.

content script picks up the stuff perfect, but I just can't get the darn data over to devtools.js where I'd be able to update the panel DOM with the results.

I think inspectedWindow.eval() might be a good solution for you:
(looks like that doc is wrong unfortunately, the function takes a second argument callback(value) )

Something like this in your devtools panel code:
function getSchema() {
  // from your content script
}
chrome.devtools.inspectedWindow.eval(getSchema + '()', function(schema) {
  // data view code
});
 
jjb



On Thu, Jan 10, 2013 at 1:40 PM, John J Barton <johnj...@johnjbarton.com> wrote:



On Thu, Jan 10, 2013 at 11:13 AM, Raymond Camden <raymon...@gmail.com> wrote:
I'm having a heck of a time trying to get code in my content script to talk to my panel. From my content script I can do this:

chrome.extension.sendMessage({greeting: "hello"}, function(response) {
 console.log(response.farewell);
});

and I can pick it up in a background script no problem.

chrome.extension.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.greeting == "hello") sendResponse({farewell: JSON.stringify(sender)});
});

But I need my message to be picked up in my devtools JS. That way I can speak to the panel I've added to dev tools. How can I do that?

You're half way there ;-).  You have to proxy the messages through the background process.  Maybe my code will offer some hints:

That said, I pretty much gave up on content scripts for devtools work. In addition to this silly proxy business, theses solutions don't work for mobile aka remote debugging. I've devolved to using evaluate to send from devtools to page and specially marked console log messages to send from page to devtools.

HTH,
jjb  



--
===========================================================================
Raymond Camden, Adobe Developer Evangelist

Email : raymon...@gmail.com
Blog : www.raymondcamden.com
Twitter: cfjedimaster

--
You received this message because you are subscribed to the Google Groups "Chromium-extensions" group.
To post to this group, send email to chromium-...@chromium.org.
To unsubscribe from this group, send email to chromium-extens...@chromium.org.
For more options, visit this group at http://groups.google.com/a/chromium.org/group/chromium-extensions/?hl=en.

Raymond Camden

unread,
Jan 10, 2013, 3:24:46 PM1/10/13
to Chromium-extensions
Hmpth, should this be valid from within a devtools JS page? I don't get an error running it, but my callback (which afaik is supposed to have a result ob and a isError boolean) gets undefined values back.

Raymond Camden

unread,
Jan 10, 2013, 3:28:34 PM1/10/13
to Chromium-extensions
Ok, I think I saw the issue - my evaluation wasn't returning anything. This is what I have now:

chrome.devtools.inspectedWindow.eval('document.evaluate("/html/body//*[@itemscope]", document, null, XPathResult.ANY_TYPE, null)', function(ob,isErr) {

Which gives me:

Object has too long reference chain(must not be longer than 1000)

John J Barton

unread,
Jan 10, 2013, 3:31:54 PM1/10/13
to Raymond Camden, Chromium-extensions
You're close now, just return something that can be converted to JSON. Do more analysis in the page;  don't send back any DOMish.

jjb

Raymond Camden

unread,
Jan 10, 2013, 3:34:06 PM1/10/13
to John J Barton, Chromium-extensions
Hmm. Am I allowed to call a function defined in JS instead of replicating the content of the function? When I tried to eval 'hasItems' or 'hasItems()' (a utility func that returns true or false), I get an undefined object and the error flag is true.

Or should I convert the entire logic of my content script into a string I can eval with the result as you said?

John J Barton

unread,
Jan 10, 2013, 4:35:36 PM1/10/13
to Raymond Camden, Chromium-extensions
On Thu, Jan 10, 2013 at 12:34 PM, Raymond Camden <raymon...@gmail.com> wrote:
Hmm. Am I allowed to call a function defined in JS instead of replicating the content of the function? When I tried to eval 'hasItems' or 'hasItems()' (a utility func that returns true or false), I get an undefined object and the error flag is true.

Or should I convert the entire logic of my content script into a string I can eval with the result as you said?

Yes, wrap your entire content script in a function and, rather than send the result over the message channel, return it instead. Then convert that function to a string for the eval().

Raymond Camden

unread,
Jan 10, 2013, 4:44:38 PM1/10/13
to John J Barton, Chromium-extensions
Hmm. So assuming my content script is something like this now.

function hasgood() { return 1; }
function getgood() { return [1,2,3]};

With the intent being, the extension runs hasgood and if true, then getgood, and I want that result in my panel.

Your saying to wrap the content script itself in a function... did you mean...

(function() {
hasgood = function  { return 1; }
getgood = function { return [1,2,3]};
})()

Or am I misreading you? Doing this and trying to eval("hasgood()") did not work. Sorry for being dense here.


John J Barton

unread,
Jan 10, 2013, 5:08:24 PM1/10/13
to Raymond Camden, Chromium-extensions
On Thu, Jan 10, 2013 at 1:44 PM, Raymond Camden <raymon...@gmail.com> wrote:
Hmm. So assuming my content script is something like this now.

function hasgood() { return 1; }
function getgood() { return [1,2,3]};

With the intent being, the extension runs hasgood and if true, then getgood, and I want that result in my panel.

Something like
  function beGood() {
    function hasgood() { return 1; }
    function getgood() { return [1,2,3]};
   
    if (hasgood()) return getgood();
    else return "no good";
  }
  chrome.devtoolsInspectedWindow.eval("(" + beGood + "());", function(value) { console.log("Am I good?", value); });
 

Your saying to wrap the content script itself in a function... did you mean...

(function() {
hasgood = function  { return 1; }
getgood = function { return [1,2,3]};
})()
The (...)() will call the function in your devtools environment, but you want the call in the page environment. 

Or am I misreading you? Doing this and trying to eval("hasgood()") did not work. Sorry for being dense here.

Assuming that you meant chrome.devtools.inspectedWindow.eval(), then expression "hasgood()" will be executed in the page, but you didn't define hasgood, it's still in devtools.  The construct 
   "(" + beGood + "());"
causes beGood to be converted to a string and wrapped in (...)() then sent to the page to be evaled, thus beGood() is called

BTW you can try this out in the devtools console using eval().

Raymond Camden

unread,
Jan 10, 2013, 5:18:24 PM1/10/13
to John J Barton, Chromium-extensions
You sir - kick ass. Not only did it make sense - it worked. I've now got all my logic in devtools.js - I can remove my content script altogether - and start working on the logic.

My God - why was this so incredibly difficult and why are there *no* examples of Panel communication stuff in the docs? 
Reply all
Reply to author
Forward
0 new messages