Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome Extension - ContextMenu listener not working after few minutes

I'm trying to create a Chrome Extension which can dynamically create ContextMenu based on storage info. Each created menu has its owned key and will do some actions then send message to Content.js to show info box on page if it is clicked.

The menu will be updated if user select some options in Options page. The Options.js will send out a message to background.js, background.js update the storage then refresh menu.

The menu behavior works fine after extension was loaded. But no longer work after few minutes. If I open a console of service worker then it can stay longer, but it eventually no response when i click menu button. Further more, if i trigger the menu updating from Option page, the button back to live. But still failed after few minutes.

I made some research and found out seems background.js will be terminated very soon after it was loaded. So i doubt that cause this issue. But how com the added menu listener not working after that? The listener should already be added, isn't it?

Background.js


function eventListener(message, sender, sendResponse) {
  if (message.event === "updateMenu") {
    updateMenu();
    sendResponse({ result: "update menu completed" });
  } 
}

function updateMenu() {
  chrome.storage.local.get("currencyMappings", function (result) {
    prepareContextMenuBySetting(result.currencyMappings);
  });
}

function prepareContextMenuBySetting(mappings) {
  chrome.contextMenus.removeAll();
  chrome.contextMenus.create(
    { id: "rootMenu", title: "%s", contexts: ["selection"] },
    function () {
      if (chrome.extension.lastError) {
        console.log("Got expected error: " + chrome.extension.lastError.message);
      }
    });
  mappings.forEach(map => {
    currencies = map.split("|");
    chrome.contextMenus.create(
      { id: `${currencies[0]}to${currencies[1]}`, title: `${currencies[0]} => ${currencies[1]}`, type: "normal", parentId: "rootMenu", contexts: ["selection"] });
  })

  chrome.contextMenus.onClicked.addListener(
    (info, tab) => {
      let rate = null;
      rateKey = info.menuItemId.split("to");
      makeExchange(rateKey, info)
    }
  );

}


Update: Log will display when the function is working. But there was no any log in console when the button action is not working. Event both Server Worker and page console.

like image 953
Tzu Hao Chung Avatar asked Nov 01 '25 21:11

Tzu Hao Chung


1 Answers

I figure out the possible reason. According to https://developer.chrome.com/docs/extensions/mv2/background_pages/#listeners adding listener in listener function may not working.

The root cause is that the backgound.js will be terminated in short time. Only keep the root listener. After backgound.js is terminated, the listener in my menu button not working anymore.

Further more, the background.js actually back to live if the root listener get called. Ex.

chrome.runtime.onMessage.addListener(eventListener);

i added a console.log() at the top of background.js and monitor the console. After the Service Worker display unavailable, which means the backgroud.js is shut down, then I fire a message to background.js. The console.log() will be triggerd.

The solution of my issue is moving adding listener of menu to root level.

chrome.contextMenus.onClicked.addListener(
  (info, tab) => {
    console.log("item clicked");
    let rateKey = info.menuItemId.split("to");
    makeExchange(rateKey, info)
  }
);

Then once background.js is wake up, the button listener will be set.

like image 121
Tzu Hao Chung Avatar answered Nov 04 '25 11:11

Tzu Hao Chung