I have content script based Chrome extension. I initiate the sign in process through a popup window in the content script.
I open a popup window using the below code and then wait till its closed.
However, I get an 'undefined' from window.open
method. Does anybody know why this happens?
loginwin
is undefined
in below code although the popup window opens up fine with the specified login_url
. The code below is called from my content script.
var loginWin = window.open(login_url, 'LoginWindow', "width=655,height=490");
console.log(loginWin);
// Check every 100 ms if the popup is closed.
var finishedInterval = setInterval(function() {
console.log('checking if loginWin closed');
if (loginWin.closed) {
clearInterval(finishedInterval);
console.log('popup is now closed');
Backbone.history.navigate('index', true);
}
}, 1000);
Note: This answer is obsolete.
window.open()
in a Chrome extension always returns eithernull
(when the popup is blocked) or awindow
object. The information below only applies to very old (2012) versions of Chrome.
Content scripts do not have any access to a page's global window
object. For content scripts, the following applies:
window
variable does not refer to the page's global object. Instead, it refers to a new context, a "layer" over the page. The page's DOM is fully accessible. #execution-environment
Given a document consisting of <iframe id="frameName" src="http://domain/"></iframe>
:
frames[0]
and frames['frameName']
, (normally referring to the the frame's containing global window
object) is undefined
.var iframe = document.getElementById('frameName');
iframe.contentDocument
returns a document
object of the containing frame, because content scripts have access to the DOM of a page. This property is null
when the Same origin policy applies.iframe.contentDocument.defaultView
(refers to the window
object associated with the document) is undefined.iframe.contentWindow
is undefined.As you can see, window.open()
does not return a Window
instance (neither does window.opener
, and so forth).
Inject the code in the page, so that it runs in the context of the page. Note: Only use this method if the page you're operating on can be trusted. To communicate between the injected script and the content script, you could use:
var login_url = 'http://example.com/';
var event_name = 'robwuniq' + Math.random().toString(16); // Unique name
document.addEventListener(event_name, function localName() {
document.removeEventListener(event_name, localName); // Clean-up
// Your logic:
Backbone.history.navigate('index', true);
});
// Method 2b: Inject code which runs in the context of the page
var actualCode = '(' + function(login_url, event_name) {
var loginWin = window.open(login_url, 'LoginWindow', "width=655,height=490");
console.log(loginWin);
// Check every 100 ms if the popup is closed.
var finishedInterval = setInterval(function() {
console.log('checking if loginWin closed');
if (loginWin.closed) {
clearInterval(finishedInterval);
console.log('popup is now closed');
// Notify content script
var event = document.createEvent('Events');
event.initEvent(event_name, false, false);
document.dispatchEvent(event);
}
}, 1000);
} + ')(' + JSON.stringify(login_url+'') + ', "' + event_name + '")';
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);
Launch the window from the background page using window.open()
. This returns a window
object which has a reliable closed
property. See the next bullet point for more details on the communication flow.
chrome.windows.create
to open a window. In the callback, assign an chrome.tabs.onRemoved
and/or chrome.tabs.onUpdated
event. When these event listeners are triggered, they should remove themselves, and notify the original caller (content script) using the sendResponse
function of chrome.extension.onMessage
. In my case, Chrome was blocking the popup and the user had to unblock by clicking the "blocked popup" icon in the upper-right corner of the window. (They can also enable/disable exceptions under "Content settings..." in Chrome settings.)
I would suggest adding some code after window.open() so that the user knows what to do. For example:
if (!loginWin)
alert("You must first unblock popups and try again for this to work!");
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