(I have already read this and it didn't work, and I've done a lot of searching and experimentation to no avail.)
I am writing a Chrome extension (BigConsole) with the goal of building a better Console tab for the Chrome developer tools. This means I would like to execute user-input code in the context of the page with access to the DOM and other variables on the page. To do this, the communication is structured as follows:
devtools
creates a panel
where the user writes codepanel
, the panel
sends a message to a background
script with the codebackground
script receives the message/code from panel
and passes it on to the content
script which is injected into the pagecontent
script receives the message/code from the background
script and injects a script
element into the page which then runs the codescript
on the page is then posted back to the content
script with window.postMessagecontent
script listens for the message/result from the page and passes it on to the background
scriptbackground
script receives the message/result from the content
script and passes it on to the panel
panel
receives the message/result from the background
script and inserts it into the log of resultsWhew.
Right now, when the user tries to run the code, nothing happens. I put a bunch of console.log()
s into the code but nothing appears in the console. My main question is, what have I done wrong here with the message passing that results in nothing happening? Alternatively, I would love to be told that I am making this way too complicated and there is a better way of doing things. Simplified code below...
panel.js:
window.onload = function() {
var port = chrome.runtime.connect({name: "Eval in context"});
// Add the eval'd response to the console when the background page sends it back
port.onMessage.addListener(function (msg) {
addToConsole(msg, false);
});
document.getElementById('run').addEventListener('click', function() {
var s = document.getElementById('console').value;
try {
// Ask the background page to ask the content script to inject a script
// into the DOM that can finally eval `s` in the right context.
port.postMessage(s);
// Outputting `s` to the log in the panel works here,
// but console.log() does nothing, and I can't observe any
// results of port.postMessage
}
catch(e) {}
});
};
background.js:
chrome.runtime.onConnect.addListener(function (port) {
// Listen for message from the panel and pass it on to the content
port.onMessage.addListener(function (message) {
// Request a tab for sending needed information
chrome.tabs.query({'active': true,'currentWindow': true}, function (tabs) {
// Send message to content script
if (tab) {
chrome.tabs.sendMessage(tabs[0].id, message);
}
});
});
// Post back to Devtools from content
chrome.runtime.onMessage.addListener(function (message, sender) {
port.postMessage(message);
});
});
content.js:
// Listen for the content to eval from the panel via the background page
chrome.runtime.onMessage.addListener(function (message, sender) {
executeScriptInPageContext(message);
});
function executeScriptInPageContext(m) { alert(m); }
Chrome has documentation on sending messages from webpages to chrome extensions. You add an “externally_connectable” object to your manifest. This will specify which webpages you want to allow to communicate with your extension (in this case, localhost, since I was developing on my machine).
In addition to sending messages between different components in your extension, you can use the messaging API to communicate with other extensions.
They've set the default shortcut to Ctrl+D . Activating this command will perform a click on the page (or browser) action, opening the popup or whatever the action is configured to do.
Background Script - Provides persistence and handles background events. Content Script - Scripts that run in isolation in the context of the web page. Injected Script - Scripts that are programmatically injected into the web page.
As pointed out by Alex, here's a typo in your code which prevents it from working.
Drop your current code and use chrome.devtools.inspectedWindow.eval
to directly run the code and parse the results. This simplifies your complicated logic to:
PS. There is a way to manipulate the existing console, but I recommend against using it, unless it's for personal use. Two different ways to do this are shown in this answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With