I know that waiting for an asynchronous method is stupid, one should use callbacks instead. But what if an third party API forces you to be synchronous?
I'm developing a Chrome Extension that will prevent the user from visiting websites that's already open in another tab. I basically need to cancel requests based on the urls in open tabs. I want to use chrome.webRequest.onBeforeRequest
like this:
function onBeforeRequest(details) {
var websiteAlreadyOpenInOtherTab;
// Here i want to set `websiteAlreadyOpenInOtherTab` by using the `chrome.tabs`
// API. It's asynchronous though and that's my problem. I cant return a value
// from an asynchronous method call.
if (websiteAlreadyOpenInOtherTab) {
return { cancel: true };
}
}
chrome.webRequest.onBeforeRequest.addListener(
onBeforeRequest,
{ urls: ['<all_urls>'], types: ['main_frame'] },
['blocking']);
Hopefully you see my dilemma in the code above. I need to return an object based on the result of asynchronous method calls. Is it possible to achieve this?
Maybe you can solve the problem by keeping track of the tab URLs?:
chrome.tabs.query
chrome.tabs.onUpdated
and chrome.tabs.onRemoved
and add/remove/update the URLs when they change.Some kind of code example based on the documentation:
var tabUrlHandler = (function() {
// All opened urls
var urls = {},
queryTabsCallback = function(allTabs) {
allTabs && allTabs.forEach(function(tab) {
urls[tab.id] = tab.url;
});
},
updateTabCallback = function(tabId, changeinfo, tab) {
urls[tabId] = tab.url;
},
removeTabCallback = function(tabId, removeinfo) {
delete urls[tabId];
};
// init
chrome.tabs.query({ active: true }, queryTabsCallback);
chrome.tabs.onUpdated.addListener(updateTabCallback);
chrome.tabs.onRemoved.addListener(removeTabCallback);
return {
contains: function(url) {
for (var urlId in urls) {
if (urls[urlId] == url) {
return true;
}
}
return false;
}
};
}());
Now you should be able to ask the tabUrlHandler
directly in your onBeforeRequestMethod
:
function onBeforeRequest(details) {
var websiteAlreadyOpenInOtherTab = tabUrlHandler.contains(details.url);
if (websiteAlreadyOpenInOtherTab) {
return { cancel: true };
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With