0

I am making a Chrome extension. Clicking a button in popup.html opens a new window and loads feedback-panel.html.

This works but, on click, I'd like to check if the window is already open and if so focus to it instead of creating a new one.

JavaScript window.open only if the window does not already exist looked promissing but it relies on the open windows being stored as variables on the parent page when the window is opened and checking those before opening a new one. This wont work for me since the parent window (popup.html) will often be closed and reopened itself and I'd lose the variables.

I tried to implement the same idea but store the window variables in with chrome.storage since it lets you store objects. Well, it does let you store objects but it serializes them first so the window variable loses all of it's functions and I end up with

result.feedbackPanel.focus() is not a function

Here is my attempt:

function openFeedbackPanel(){
    chrome.storage.local.get('feedbackPanel', function (result) {
        console.log( result.feedbackPanel); // logs window object sans all functions
        if(result.feedbackPanel && ! result.feedbackPanel.closed){
            try{
                result.feedbackPanel.focus();
            }
            catch(error){
                chrome.storage.local.remove('feedbackPanel', function () {
                });
                createFeedbackPanel();
            }
        }
        else{
            createFeedbackPanel();
        }
    });
}
function createFeedbackPanel(){
    var win =  window.open('feedback-panel.html', 'Feedback', 'width=935, height=675');
    console.log(win); // logs full object as expected 
    chrome.storage.local.set({"feedbackPanel": win});
}



$('#some-button').click(openFeedbackPanel());

So, since this doesnt work:

How can I check if a popup window is already open from a non-parent window (one that did not open the popup)?

Community
  • 1
  • 1
Wesley Smith
  • 19,401
  • 22
  • 85
  • 133

2 Answers2

5

no need to track windows and store them.
if you know your extension ID, the simplest way is to test all tabs url's and see if it's already opened

chrome.tabs.query({}, function(tabs) {
  var doFlag = true;
  for (var i=tabs.length-1; i>=0; i--) {
    if (tabs[i].url === "chrome-extension://EXTENSION_ID/feedback-panel.html") {
      //your popup is alive
      doFlag = false;
      chrome.tabs.update(tabs[i].id, {active: true}); //focus it
      break;
    }
  }
  if (doFlag) { //it didn't found anything, so create it
    window.open('feedback-panel.html', 'Feedback', 'width=935, height=675');
  }
});

and here is already answered how to get extension ID,

Community
  • 1
  • 1
Wolf War
  • 1,503
  • 1
  • 15
  • 28
  • This looks promissing but sadly it doesnt work. When the page isnt open, it opens it but when it is open nothing happens. I set a breakpoint and the code is being called `chrome.tabs.update(tabs[i].id, {active: true});` and I have the correct tab id but the window does not gain focus. Im thinking that this is because the popup itself is still open – Wesley Smith Mar 16 '16 at 04:44
  • @DelightedD0D I tested it on my win10 in Opera browser, and popup gets focused (from background). Maybe it's different platform behavior? – Wolf War Mar 16 '16 at 10:41
  • Hmm, didnt realize you could install chrome extensions in opera, can you test in in actual chrome? Id love to confirm it works so I can focus on the reason mine doesnt – Wesley Smith Mar 16 '16 at 16:54
  • Thats so strange, would it be possible for you to upload the test extension you made somewhere that Id be able to download it? Id like to compare it to what I have in regards to the workflow to try and pinpoint what causes mine to fail. And thanks for your time :) – Wesley Smith Mar 16 '16 at 20:55
  • @DelightedD0D download it, unrarit and install in developer mode... on toolbar button should create test popup or focus on it if it's already created http://bit.ly/1R4iTKb – Wolf War Mar 17 '16 at 00:14
  • 1
    Thanks Wolf, If I take my project down to a skeleton like your example, it does in fact work. There must be something in my code preventing it, now for the fun of tracking that down..... – Wesley Smith Mar 17 '16 at 00:56
  • Quick note, `window.open` really shouldn't be used in Chrome over `chrome.windows`/`chrome.tabs`. There are corner cases where `window.open` fails. – Xan Mar 20 '16 at 00:54
1

You can also use the messaging system. This is an example I use for an extension's options. Call a function like this in the onClick for the button:

    // send message to the option tab to focus it.
    // if not found, create it
    showOptionsTab: function() {
        chrome.runtime.sendMessage({window: 'highlight'}, null, function(response) {
            if (!response) {
                // no one listening
                chrome.tabs.create({url: '../html/options.html'});
            }
        });
    },

And in your window/tab listen for the message like this

// listen for request to make ourselves highlighted
chrome.runtime.onMessage.addListener(t.onMessage);

...

// message: highlight ourselves and tell the sender we are here
t.onMessage = function(request, sender, response) {
    if (request.window === 'highlight') {
        chrome.tabs.getCurrent(function(t) {
            chrome.tabs.update(t.id, {'highlighted': true});
        });
        response(JSON.stringify({message: 'OK'}));
    }
};

One advantage of this method is it does not need the tabs permission.

Michael Updike
  • 644
  • 1
  • 6
  • 13