Messaging between content script and popup script in Chrome extension - javascript

I'm trying to create a popup chrome extension that shows information about the DOM in the current page, which seems to require messaging. I've been able to send messages to the background, but I need the data to be specific to the current page, as the background is identical to all popups/pages.
In popup.js, I send a message when the DOM is loaded (should trigger when popup is clicked?)
document.addEventListener('DOMContentLoaded', function() {
chrome.runtime.sendMessage({method: "getTableData"}, function response() {
});
});
I also have a listener in the contentscript.js (and background.js for testing)
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if(request.method == "getTableData") {
console.log("table request found!");
}
});
Then, when I activate the popup, the background console outputs table request found!, while
the console for the current page doesn't.
Thanks.

You need to use chrome.tabs.sendMessage instead of chrome.runtime.sendMessage to send a message to a content script.

Related

Make Chrome extension javascript document apply to open webpage, not popup [duplicate]

This question already has answers here:
How to access the webpage DOM/HTML from an extension popup or background script?
(2 answers)
Closed 2 years ago.
I'm writing a chrome extension in which i need to click on a item on the webpage. The item can be found with document.getElementsByClassName("className")[0].click() but if I run this in the popup, it searches for the item in the popup menu instead. How can I make it return and click the item in the webpage?
You should make a content script and use that to perform the click. Content scripts are loaded in the context of the HTML page, as opposed to the extension popup.
You can message between your content script and your main extension code by using the messaging API.
Your extension code could send a message to the content script like this:
// Query the active tab in the current window (there will only be one)
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
// Send a message to that tab (found as tabs[0]),
chrome.tabs.sendMessage(tabs[0].id, {message: "perform_click"}, function(response) {
console.log("Click performed.");
});
});
And your content script could handle the request like this:
// Listen for events from the background script (main part of the extension)
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// This function will be called in the content script to handle messages received from the main extension code.
// If the extension is requesting a click, we do that here
if (request.message == "perform_click") {
document.getElementsByClassName("className")[0].click()
}
});

Chrome Extension Error Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist

I have a tab change listener in background script which which will send a message to the content script to preform a set of actions in content script.
My code in background script is
window.chrome.tabs.onActivated.addListener((activeInfo) => {
window.chrome.tabs.sendMessage(activeInfo.tabId, { type: 'getLibraries' }, (data) => {
// do some thing
});
});
content script is
window.chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
switch (message.type) {
case 'getLibraries':
// do something
break;
default:
console.error('Unrecognised message: ', message);
}
});
This is working fine in most cases. When I add the extension to my browser and switch to a previously opened tab, the content script wont be present there as the plugin was not present while loading the tab. At this time the background scrip tries to send message on tab change. Since there is no content script chrome will throw the following error
Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist
I need a tab change detection in background script which will send a message to the content script without causing the above error. Is there any way to detect if the content script has loaded from background script?

Chrome extension window onload jquery

How am I going to write something when user clicks extension icon and loads the window?
I've already tried
window.onload = function() {
console.log("das");
}
and ]
$(document).ready(function(){
console.log('document is ready');
});
but still there isn't any log?
Maybe it's not the best idea but you can use chrome.tabs.sendMessage and chrome.runtime.onMessage.addListener to communicate between contentscript.js and popup.js
contentscript.js is running directly in page scope so you can easily detect when page is ready. After that you can send a message chrome.tabs.sendMessage(tabs.id, {action: 'pageReady'});. In popup.js you are listening to:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.action === 'pageReady') {
// Do what you want to do on page ready
}
});
It should works good for you. You can also send response to the caller:
contentscript.js send information to the popup.js that page is ready.
popup.js do what you want to do (show table).
popup.js send information to the contentscript.js that table is added.
EDIT
I'm not sure about my solution because I found information that:
The popup, while being an extension page, is not a background page. It
is only accessible when it is open
I don't know if it is possible to listen on events in popup. You need to check it.

Can't shoot a response every time extension button is clicked

So I'm just trying to get a response every time the extension button is clicked. So like with AdBlock how this comes down
But instead I'm just trying to do a console.log() every time the button is clicked without any visible popups.
I've tried this so far
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
switch (request.directive) {
case "popup-click":
// execute the content script
chrome.tabs.executeScript(null, { // defaults to the current tab
file: "real.js", // script to inject into page and run in sandbox
allFrames: true // This injects script into iframes in the page and doesn't work before 4.0.266.0.
});
sendResponse({}); // sending back empty response to sender
break;
default:
// helps debug when request directive doesn't match
alert("Unmatched request of '" + request + "' from script to background.js from " + sender);
}
}
);
Then my real.js
console.log("Yo");
But sadly I only get a Yo when it launches. Any ideas?
If you don't have a popup (nothing shows when you click the button), then there is an event that will fire when the button is clicked:
chrome.browserAction.onClicked
Fired when a browser action icon is clicked. This event will not fire if the browser action has a popup.
To use:
// In your background script
chrome.browserAction.onClicked.addListener( function() {
// Do stuff
});
If, however, you do have a popup, then, as the docs mention, this event will not fire. Then your code is more appropriate: you just need to send a message from the popup and catch it in the background script whenever it is opened. See a full example in this answer.

Executing script on a precise tab in Google Chrome extension

I want to execute a script on a precise tab of my browser. This script will give back a value.
I don't know what I have to use. The Doc says that contentScript are called on every loading of a new page. I just want to execute the script once the user clicked on a button in my popup.html.
In your contentScript file add listener like this:
chrome.extension.onMessage.addListener(function(msg, sender, sendResponse) {
//do job
sendResponse(...);
});
And in your popup.html on click event:
chrome.tabs.sendMessage(tabid, "message", function responseCallback(response) {
//...
});
more info http://developer.chrome.com/extensions/tabs.html#method-sendMessage

Categories