Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

161
Vistas
Guaranteeing at most 1 chrome extension popup page open at a time

On my chrome extension, I have a popup page and a background script.

As default, when I click on the extension's icon in two different windows, a popup will open in both windows. I want to limit the amount of popups opened by the extension to be at most one at a time.

Here's how the full scenario that I'm trying to create:

  1. At first no pop up is activated.
  2. Window A opened a popup.
  3. Window B opened a popup, in which case, Window A's popup will close.
  4. Window C is created, go to 2, but this time Window A<-Window B and Window B<-Window C
  5. If in any time The only popup that is open was closed, return to 1.

I know that a popup windows was created because I have a simple port connection that is invoked on the popup startup. Thus, the background is in theory aware of all popup windows that are created, namely, that is the code that I run in the popup to connect:

const port = chrome.runtime.connect({ name: 'popup-communications' });

I attempted to solve the problem in 3 ways, all of them failed.

Attempt 1 Hold the last popup that was connected. If a new one appears, close the old one before you save the new one. Use chrome.extension.getViews to get the new port. I imagined this would work, but rapid clicks on the extension icon (to invoke browserAction) makes this popUp state confused.

let popUp;
chrome.runtime.onConnect.addListener(function connect(port) {
  if (port.name === 'popup-communications') {
    // attempt 1
    if (popUp) {
      popUp?.close?.();
      popUp = null;
      console.log('removed old pop up');
    }
    [popUp] = chrome.extension.getViews({
      type: 'popup',
    });
});

Attempt 2 Close all popups that received from chrome.extension.getView, but the last one. The problem with this approach is that the chrome.extension.getView does not guarantee any order.

let popUp;
chrome.runtime.onConnect.addListener(function connect(port) {
  if (port.name === 'popup-communications') {
    // attempt 2
    const popUps = chrome.extension.getViews({
      type: 'popup',
    });
    console.log(popUps);
    for (let i = 0; i < popUps.length - 1; i++) {
      popUps[i].close();
    }
});

I also experimented with chrome.browserAction.disable and chrome.browserAction.enable. This solution maintains indeed maintains 1 popup at all time, but I want it the popup to be available whenever I click on the extension icon, and this will not happen with this approach (instead I will need to find the relevant window with this popup)

Is there a way to achieve what I'm trying to do here?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

I was able to achieve this behavior in the following way.

background.js

The background listens to connecting popups.

When a popup connects, it will broadcast a message to all open popups to close. Note this message is not sent over the port since the port connection does not broadcast.

There should exist a way to optimize, since at most one other popup can be open, but I will leave that for another time and prefer not to create global variables.

chrome.runtime.onConnect.addListener(function connect(port) {
    if (port.name === 'popup-communications') {

        port.onMessage.addListener(function (msg) {
            if (msg.here) {
                const activeTabId = msg.here;

                // broadcast close request
                chrome.runtime.sendMessage({closeUnmatched: activeTabId});
            }
        });
    }
});

popup.js

  1. Perform a lookup of its tab id.

  2. Add a message listener to know when to close. If the message to close does not match current tab id, popup will close. window.close() is sufficient to close a popup.

  3. "announce" to background that popup is ready by sending the tab Id over the port.

async function getCurrentTab() {
    let queryOptions = {active: true, currentWindow: true};
    let [tab] = await chrome.tabs.query(queryOptions);
    return tab;
}

function addListener(myTabId) {
    chrome.runtime.onMessage.addListener(function (msg) {
        if (msg.closeUnmatched && msg.closeUnmatched !== myTabId) {
            window.close();
        }
    });
}

(async function constructor() {
    const port = chrome.runtime.connect({name: 'popup-communications'});

    // whoami lookup
    const {id: myTabId} = await getCurrentTab();

    // add handler to self-close
    addListener(myTabId);

    // tell background I'm here
    port.postMessage({here: myTabId});

    // do whatever with port..
}());

I assume steps 1-3 can be done faster than user switching tabs/windows to activate another popup. The port connection was complicating things, but I left it in the answer, since you may have a use case for it.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda