7

Here is my problem: I'm developing a Chrome extension for Gmail and needs to apply some changes when the extension is updated.

For example, I want to be sure that the extension will display an alert dialog within Gmail after the extension has been updated. This implies to check whether Gmail is already open in a Chrome window at the time of the update, and if not to create a listener in order to wait for Gmail to be loaded in the future and then to display the alert dialog.

The code below does just that. However, I cannot manage to remove the listener (chrome.tabs.onUpdated.removeListener?) when a new Gmail tab has been discovered.

background.js

 // [...] code before // Reload Tabs where Gmail is active function reloadTab(order) { chrome.windows.getCurrent(function(win) { var cwin = win.id; chrome.tabs.query({windowId: cwin}, function(tabs) { var countGmailTabs = 0; for (var i = 0; i < tabs.length; i++) { var t = tabs[i].url; if (t.match('mail.google.com')) { countGmailTabs += 1; if (order === 'set') { chrome.tabs.reload(tabs[i].id); } else if (order !== 'set') { var GmailTab = tabs[i]; NewGmailURL(order, GmailTab); return; } } } // Gmail not found ! if (countGmailTabs < 1 && order !== 'set') { chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { if ( tab.url.match('mail.google.com') && changeInfo.status === 'loading' ) { NewGmailURL('update', tab); return; // Everything OK, now remove listener. How? } }); } }); }); } // [...] 

Thanks for your help!

For information, the alert dialog is displayed thanks to URL parameters.

// Modify Gmail URL var updated = false; function NewGmailURL(param, ztab) { if (param === 'updated') { urlMyExtension = ztab.url.replace(urlGmail + '?query=update&', urlGmail +'?query=' + param + '&'); } else { urlMyExtension = ztab.url.replace(urlGmail, urlGmail + '?query=' + param + '&'); } if (!done && param !== 'updated') { chrome.tabs.update(ztab.id, { url: urlMyExtension, highlighted: ztab.highlighted }, null); updated = true; } } 

[UPDATED] ANSWER

In case anyone meets the same problem, here is the answer thanks to @ExpertSystem:

// Listen to Tabs URL function myListener(tabId, info, tab) { if (tab.url.match("mail.google.com") && (info.status === "loading")) { NewGmailURL("update", tab); /* Now, let's relieve ourselves from our listener duties */ chrome.tabs.onUpdated.removeListener(myListener); return; } } // Reload Tabs where Gmail is active function reloadTab(order) { chrome.tabs.query({ currentWindow: true }, function(tabs) { var countGmailTabs = 0; for (var i = 0; i < tabs.length; i++) { var t = tabs[i].url; if (t.match('mail.google.com')) { countGmailTabs += 1; if (order === 'set') { chrome.tabs.reload(tabs[i].id); } else if (order !== 'set') { var GmailTab = tabs[i]; NewGmailURL(order, GmailTab); return; } } } // Gmail not found ! if (countGmailTabs < 1 && order !== 'set') { chrome.tabs.onUpdated.addListener(GmailListener); } }); } 

1 Answer 1

16

In order to be able to remove a listener do not implement it as an anonymous function. Implementing it as "named" function, allows you to reference it alter when calling removeListener().
E.g.:

/* Change this: */ chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {...}); /* To this: */ function myListener(tabId, info, tab) { if (tab.url.match("mail.google.com") && (info.status === "loading")) { NewGmailURL("update", tab); /* Now, let's relieve ourselves from our listener duties */ chrome.tabs.onUpdated.removeListener(myListener); return; } }); chrome.tabs.onUpdated.addListener(myListener); 

BTW, (not related to your problem, but) you are making a couple of superflous calls:

You don't need to get the current window and then get its tabs, like this:

chrome.windows.getCurrent(function(win) { var cwin = win.id; chrome.tabs.query({windowId: cwin}, function(tabs) { ... 

You can do it in one call, like this:
(See, also, chrome.windows.getCurrent())

chrome.window.getCurrent({ populate: true }, function(win) { var tabs = win.tabs; ... 

Or even like this:
(See, also, chrome.tabs.query())

chrome.tabs.query({ currentWindow: true }, function(tabs) { ... 
Sign up to request clarification or add additional context in comments.

2 Comments

Always glad to help ! Take a look at my updated answer to save a few method calls ;)
ahah :) Yes, looks better. Thanks a lot, still a bit lost with the Chrome extension API! Really appreciate it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.