Reputation: 2014
I'm working on a chrome extension that has a login popup window. So the idea is for the extension to work it would require user to login so that it could interact with our API and get/post data.
So I override the browserAction
to check if the user is logged in or not then if it is not it should show a login popup. My problem is when I click again the extension icon it reopens the same login popup window. How do I prevent that to happen and only one instance of login window should appear if it is open?
background.js
// omitted some codes for brevity
chrome.browserAction.onClicked.addListener(function () {
// omitted some codes for brevity
chrome.windows.create({
'url': 'login.html',
'type': 'popup',
'width': width,
'height': height,
'left': (screen.width/2) - (width/2),
'top': (screen.height/2) - (height/2),
'focused': true
});
});
Upvotes: 0
Views: 2368
Reputation: 33296
There are multiple ways that you can do this.
chrome.tabs.query()
to detect window is openYou could check for the existence of your popup window by calling chrome.tabs.query()
:
var popupUrl = chrome.runtime.getURL('/login.html');
chrome.tabs.query({url:popupUrl},function(tabs){
if(tabs.length > -1){
//The popup exists
}
});
In order for the above to work, you have to declare the tabs
permission.
However, chrome.tabs.query()
will not detect the popup window during the time between the call to chrome.windows.create()
and when the window actually opens. Based on testing, this time is long enough for the user to click the browser action button multiple times, opening multiple popup windows.
Given the drawbacks of using chrome.tabs.query()
to detect the window, my preference is to use a global variable to hold the current state of the popup window. In the code below, the variable popupWindowId
can have three general states:
false
: Window is not opentrue
: Window is in the process of being openedtypeof popupWindowId === 'number'
: Popup window is open. The number is the window ID.If the user clicked the browser action button, then the user wants the popup. While, we don't want to open a new popup, we do want to provide the user with what they want. Thus, if the popup is already open, then the popup window is focused. This will bring it to the top, showing it to the user. A full implementation should also check that the popup window is within the visible bounds of the screen. If it is not visible, then it should be moved to be visible. This later functionality is not implemented here.
To detect when the popup window is closed, a chrome.windows.onRemoved
listener is used.
I also like to provide feedback to the user of what is going on, so the title of the popup is changed to "Popup window is already open. Click to focus popup." while the popup is open. When the window is closed, the title is changed back to "Open popup window".
background.js:
var windowNotOpenTitle = 'Open popup window';
var windowIsOpenTitle = 'Popup window is already open. Click to focus popup.';
var popupWindowId = false; //popupWindowId can be true, false, or the popup's window Id.
chrome.browserAction.onClicked.addListener(function () {
let width= 400;
let height= 300;
if(popupWindowId === false){
popupWindowId = true; //Prevent user pressing pressing the button multiple times.
chrome.browserAction.setTitle({title:windowIsOpenTitle});
chrome.windows.create({
'url': 'login.html',
'type': 'popup',
'width': width,
'height': height,
'left': (screen.width/2) - (width/2),
'top': (screen.height/2) - (height/2),
'focused': true
},function(win){
popupWindowId = win.id;
});
return;
}else if(typeof popupWindowId === 'number'){
//The window is open, and the user clicked the button.
// Focus the window.
chrome.windows.update(popupWindowId,{focused:true});
}
});
chrome.windows.onRemoved.addListener(function (winId){
if(popupWindowId === winId){
//chrome.browserAction.enable();
chrome.browserAction.setTitle({title:windowNotOpenTitle});
popupWindowId = false;
}
});
Upvotes: 5