How to communicate between frame and Edge Extension content script? - javascript

I am developing an Edge extension, I need to send a message from frame document(not the top document, top document works fine) to content script.
As following:
`contentscript.js
window.addEventListener("message", function(event) {
console.log("window top message...event:");
console.log(event);
});`
Send a message from the frame document, with:
window.top.postMessage("Hi, I am from frame", "*").
In the console panel, I can see window top message...event: and then the browser reload the page. It seems the message was blocked.
The extension can be got from github.
steps to reproduce:
Load the extension, open Google, open console panel, switch to Frame, and type
window.top.postMessage("Hi, I am from frame", "*").
Could anybody help?

If you have a background page, and your contentscript.js has access to browser. object, the cheap'n'easy way might be to bounce message to extension and back like so:
contentscript.js
browser.runtime.sendMessage({name: 'bounce', payload: {name: hello}});
background.js
browser.runtime.onMessage.addListener(function (request, sender) {
if (request.name === 'bounce') {
browser.tabs.sendMessage(sender.tab.id, request.payload);
}
});
and just listen for {name: hello} on your contentscript. All frames, including top should get this message.

Related

Chrome Extension tab and contextmenu trouble

I am trying to sendMessage from my contextmenu.js file to my content.js file anytime the user right clicks on any website on chrome.
This will include sites
- that are on the current tab and is active
- that are popups and is inactive
- that are popups and is active
- on another window and is inactive
- on another window and is active
My code looks like this:
//contextmenu.js
chrome.contextMenus.onClicked.addListener((clickData, tab) => {
chrome.tabs.sendMessage(tab.id, {text: 'rightClicked'}, (response) => {
console.log(response)
})
})
//content.js
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg.text === 'rightClicked') {
sendResponse('performing operation')
}
})
I'm getting the error message:
"Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist."
Assuming contextmenu.js is declared in "background" section and content.js in "content_scripts" section of manifest.json, the posted code is fine, but extensions have many moving parts so the problem is elsewhere. The error message means there was no content script running at the time the message was sent, which could happen in these cases:
the page was still loading - to fix this add "run_at": "document_start" in manifest.json's content_scripts section, more info.
the extension was recently installed or updated or reloaded but the tab wasn't reloaded, see content script re-injection after upgrade or install or switch to programmatic injection instead of declaring content_scripts section in manifest.json, more info.
you clicked inside an iframe but you didn't allow the content script to run inside iframes - add "all_frames": true in manifest.json's content_scripts section, more info and specify frameId in sendMessage like this:
chrome.contextMenus.onClicked.addListener((clickData, tab) => {
const {frameId} = clickData;
chrome.tabs.sendMessage(tab.id, {text: 'rightClicked'}, {frameId}, response => {
console.log(response)
});
});
the page can't run content scripts at all (e.g. a chrome:// page or another extension) - can't be fixed in general but for a personal use you can start Chrome with --extensions-on-chrome-urls command line switch and add chrome://*/* pattern to the content_scripts section's matches list.
the page URL is blacklisted - check chrome://policy for the presence of runtime_blocked_hosts and contact your admin
I figured it out.
There is nothing wrong with my code. I was just not matching the right URLs, because I was testing the onClick on a blank page which has no URL or chrome://extension itself. The code works on a any website.
//manifest.json
"content_scripts": [
{
"matches": ["<all_urls>"]
...
}

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?

Opening file Dialog with context menu

I am working to create a Web Extension for both google chrome and Firefox.
Ultimately my goal is to open a file dialogue when I click on the context menu item added by my extension. However, there are two major problems when trying to do this.
The file dialogue must be opened by user action that activates an input element with type=file.
Context menu events are added and called from the background script of the extension.
Is there a silver bullet solution I am missing?
Failed Solutions
Background input element: Input elements will not function when used in the background script.
Message Passing (works on Chrome but not Firefox): Sending a message from the background to the content script keeps its user triggered status on chrome, but loses it in Firefox.
For those interested: this is the code that works in Chrome but not Firefox.
Background.js:
chrome.contextMenus.create({
title: "Clickme",
contexts:["image"], // ContextType
onclick: function(){sendMsg("openDialog")} // Called when clicked in menu
});
Content.js:
var fInput= document.createElement("input"); //hidden input to open filedialog
fInput.setAttribute("type", "file"); //opens files
fInput.setAttribute("id", "fileopeninput"); ////only useful for inspector debugging
///TAKE MESSAGE FROM Background
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if(request.msg === "openDialog"){
fInput.click(); //triggers open file dialogue
}
});

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.

Messaging between content script and popup script in Chrome extension

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.

Categories