How To Make Page To Interact With Background Page? - google-chrome-extension

My Chrome extension has a background page that execute script on current tab.
The script change elements on current tab by adding code to existing elements to call function 'myFunction' defined at background page when 'onClick' events occur.
The problem is that exception is thrown that 'myFunction' is not defined on current tab.
what is the best way to enable this interaction? to enable current page to go to function defined on background page?
Thanks in advance!

The background page is executed in an independent context, and thus its functions can't be directly executed in the currently opened tab.
What you need is a content script executed on all the tabs, that then communicates with the background page, using the message passing mechanism.
Without more information, it's difficult to help you more.

As mentioned in the first answer, "Without more information, it's difficult to help you more.", but for your second question it sounds like what you need is a reference to the function defined in your background page. This can be achieved with the getBackgroundPage function. The code looks like this;
var bgPage = chrome.extension.getBackgroundPage();
bgPage.myFunction();

Related

Use a content script to create an element on the page that is invisible to the page

I have a content script in a Chrome extension. I'd like to inject an element into the page, but I need to do so in such a way that the page is unaware of the injected element at all, i.e. it needs to be completely invisible to the page and only visible within the content script context. The page should not be able to locate the element (even with getElementByID), receive events related to it, or anything.
Is such a thing possible? How would I go about doing that? If it's not, what is the closest thing I can do?
If Shadow DOM as mentioned by #Xan doesn't work for you:
The next best thing would depend a lot on what you are trying to do.
A browser action might suit your needs as you could put the data/buttons/etc. you want to display there and the page would not be able to get to it. You could still run a content script to get the data needed from the page.

Open and pass data to a popup (new tab) from content script

I'm writing a chrome extension and have a question.
My extension has some .html page in it, let it be 'popup.html'. I inject a content script into some page and this script opens a 'popup.html' in a new tab with something like 'var p = window.open(chrome.extension.getURL('/popup.html'), "popup")', which works perfectly. Next, I need to pass some data to this window and I can't figure how to do it in a simple way.
For some reason I can't call child window's function from a content script with
var p = window.open(chrome.extension.getURL('/popup.html'), "popup");
p.foo(data);
In the console I see Uncaught TypeError: Cannot call method 'foo' of undefined message.
I can't pass data in a query string, because the data is simply too big.
Is there an elegant and simple way to pass data to such kind of window? I thought about messaging, but how do I effectively get tab ID of a newly opened window w/out using a background page?
Thanks a lot in advance.
UPD:
I tried to inverse the logic and get a data from parent window with 'window.opener.foo()' but in a newly opened tab window.opener returns null.
Ok, I found two solutions to my problem.
1) Add a background page, which opens a popup with chrome.tabs.create(). Then send a message from a content script to a background page, which re-sends it to a corresponding tab via chrome.tabs.sendMessage(). It looks a little ugly, but works.
2) A better one, w/out background page. Extension (popup) page creates a listener for long-lived connection. Then content script sends a message to this connection. A problem here is that a listener is not created right after the page is opened, so there should be a mechanism for a content script to wait until popup is loaded. It can be a simple setTimeout or a notification from popup via same long-lived connection.
If anyone has a better solution I'd gladly check it out as well.

Chrome extensions: is it possible to call a function in the options page from the background page?

How do I call a function in the options page from the background page?
For example, in the options page, you can call:
chrome.extension.getBackgroundPage().updateIcon("someDifferentIcon.png");
thereby communicating with the background page from the options page. How do you communicate with the options page from the background page?
One possible difficulty is that the options page is not always open (unlike the background), so that may explain why its not built-in (like above). My question is, is it possible to do?
A simple approach to implement your idea is using "chrome.extension.sendRequest" API. For example:
options.js:
chrome.extension.sendRequest({id:"updateIcon", filename:"foo.png"});
background.js:
chrome.extension.onRequest.addListener(funciton(request) {
if (request && (request.id == "updateIcon"))
updateIcon(chrome.extension.geURL(request.filename));
});
If the options page is already open, you can use chrome.extension.getViews({type:"tab"}) to get a hold of its window object and then call functions on it (you'll need to iterate over the returned views and pick the one with the URL that is the URL of your options page). If it's not open yet, you can use the tabs API to open a tab that points to it first, and then use chrome.extension.getViews.

Can Popup page use DOM elements created in Background Page

Actually, I want to store some data in background page and the popup page just show that part of data say Data as a div element created in background page document.createElement("div"). Here, the background page will register some listeners to the tab update and change the Data elements accordingly. What the popup will do is to get that Data and appendit use the document.appendChild(Data).
(The purpose I intend is this will cause the popup changes immediately while the tab updage is triggered.)
However, the elements are shown as usual, what I am facing very headache is I have registered the onclick for the div object in backgroundpage as onclick="chrome.extension.getBackgroundPage().somefunc()". However, the first time, all the click will triger the right behavior but after the popup loses foucs and get focus again, all the click won't work.
I try to put something like change the onclick="somefunc()" and leave the func within the script of popup page. And there I want to log whether it is called by console.log("clicked"). Here, something unbelievable happens, the function is succefully trigerred BUT the console is null here, I cannot even call chrome.extension.getBackgroundPage() as well.
Here are a list of questions, maybe very hard to express for me...
1. Whether I can reuse the DOM element from the background page to the popup page directly by appendChild(chrome.extension.getBackgroundPage().getElementById()?
2.Will the onclick event registered in the background page still work in the popup pages?
3. What's the problem with the problem I am encountering? I have tried many ways to find out the reason but all in vain at last...
Best Regards,
If you need any more information, please let me know.
(PS: I am wonderning if it is called something like the event propogation, however, I am not an expert in this two pages communicating...)

How to control over browser back button

I want a confirmation window on click of a browser back button. If I press yes then the previous page will get load ortherwise I will remain in the same page?
Any suggestion is highly appreciated.. But please be on track.. my question is straight forward
thx in advance..
Why do you want to do that?
You can prevent them from leaving the page by using Javascript, but if you can't use that, it's not possible to do anything about it.
Generally you should use the unload event in the body (in jQuery for instance, just add
jQuery(window).unload(function(evt){
if(!confirm('Do you really want to leave')){
evt.preventDefault();
}});
Prototype have something similar, and for pure Javascript, I guess that it still depends on the browser you're using, but window.unload = function(evt){return false;} might work.
Don't remember the correct syntax for it though.
but I do not know if you can limit that for only the back or if it will trigger for all the unloads (like clicking on a link, closing the browser etc.)
If you want to stop them because they might have unsaved data in a form, then that is ok. If you want to stop them from going back for another reason than that, I think you should rethink why.
Generally if using the back button can cause issues you already have bigger problems.
What you probably want to do is check that you do things like this:
Use POST for all requests that alter data
Use nonce's (unique ID's) to enure forms don't get submitted twice
I use noscript for this very reason. I insist on having control of my browser not the site that I am visiting. I only allow scripts for certain sites. For any site that disables my back button,I don't allow it to run scripts.

Resources