1

I have a chrome extension which is currently consists of a background page and a popup page. There are some initialization happens when the popup is opened. I am using DOM event

doc.addEventListener('DOMContentLoaded', function() { ... }

And the behaviour is correct. The issue is when closing the popup. Since chrome popup does not throw unload event I am using what was suggested here. Here is my code

popup.js

bgPage = chrome.extension.getBackgroundPage();
bgPageManager = bgPage.manager(); // This is the exposed api from bg page
bgPageManager.init(chrome.runtime.connect({
    name: 'P1'
}));

Here connecting to the runtime and sending the port to background page so that it can listen to onDisconnect event.

Background.js

function init(port) {
    port.onDisconnect.addListener(function() {
        // Clean up happens here
        stateManager.unregister();
    });
}

This works as well.

But the issue is, this onDisconnect getting fired when the popup is getting opened, not when it is getting closed

The documentation for onDisconnect event is

An object which allows the addition and removal of listeners for a Chrome event.

Which is not every helpful ;)

So is there anything wrong I am doing, or any way when I can detect the popup close?

Community
  • 1
  • 1
years_of_no_light
  • 938
  • 1
  • 10
  • 24
  • Not enough code here to see a coherent picture. What's `bgPageManager`? What's listening to `onConnect`? – Xan Mar 06 '16 at 09:50
  • @Xan: added description about `bgPageManager`. And there is no `onConnect` for `Port`. You can check it here https://developer.chrome.com/extensions/runtime#type-Port – years_of_no_light Mar 06 '16 at 10:06

1 Answers1

2

Unless there's something listening to chrome.runtime.onConnect in the popup page (from your comment, doesn't seem so), chrome.runtime.connect() will return a Port that immediately closes (as no-one was willing to listen).

You're definitely making it more difficult than it should be with involving getBackgroundPage though. The popup can initiate the port itself. All you need to do is:

// popup code
var bgPort = chrome.runtime.connect({name: "P1"});

// background code
var popupPort;
chrome.runtime.onConnect.addListener(function(port) {
  if(port.name == "P1") {
    popupPort = port;
    popupPort.onDisconnect.addListener(function() {
      /* Clean up happens here */
    });
  }
});

In case you want to preserve what you already have, the minimal code to put into the popup is this:

var bgPort;
chrome.runtime.onConnect.addListener(function(port) {
  if(port.name == "P1") {
    bgPort = port;
  }
});

Note that in all cases you need to keep a reference to the Port object on both sides. If the garbage collector collects it, the port will be disconnected.

Finally, a port name is optional; if it's the only port you use, you can drop the code that sets/checks the name.

Xan
  • 74,770
  • 16
  • 179
  • 206
  • I see what you mean now. I did not get the idea that `onConnect` and `onDisconnect` are thrown on two different objects. Now it makes sense. Thank you. I need `getBackgroundPage` since my popup page uses few APIs which are in backgroundPage and are required to hold state across the lifetime. – years_of_no_light Mar 06 '16 at 10:22
  • 1
    I always dislike `getBackgroundPage` for very tight code coupling. Using messaging/`chrome.storage` allows for more flexibility. – Xan Mar 06 '16 at 10:24