I have little trouble with asynchronous functions. The asynchronous function in getImageSizeByUrl() could be handled by using $.Deferred().
function getImageSizeByUrl(url) {
var deferredReady = $.Deferred();
var tmpImg = new Image();
tmpImg.src = url;
// asynchronous function
$(tmpImg).on('load',function(){
getImageSizeByUrlWidth = tmpImg.width;
getImageSizeByUrlHeight = tmpImg.height;
deferredReady.resolve();
});
return deferredReady.promise();
}
But now I have two other problems. In the lower function, the function $.when itself is asynchronous. So it only wraps the problem. So the function chrome.webRequest.onBeforeRequest.addListener() is done, without waiting for the return of getImageSizeByUrl(). How in this tricky case it is possible to get a synchronous behaviour?
My second problem is the nested return value in the lower function. return {redirectUrl: "https://www.google.de/images/srpr/logo11w.png"}; and return {} should be the return for the parent function function(info).
(Background: The lower listener function of a chrome extension checks every image before loading. The listener needs a return value for redirecting or allowing the image loading. But the listener function doesn't wait for the result of the upper function getImageSizeByUrl and returns an empty value.)
// listener for image loading
chrome.webRequest.onBeforeRequest.addListener(
function(info) {
console.log("test1");
$.when(
getImageSizeByUrl(info.url)
).done(
function() {
// for example: if image has to big height or width, load alternative image
if(getImageSizeByUrlHeight > 200 || getImageSizeByUrlWidth > 200) {
// load alternative image
console.log("test3");
return {redirectUrl: "https://www.google.de/images/srpr/logo11w.png"};
} else {
// image is not big. allow loading
console.log("test3");
return {};
}
}
);
console.log("test3");
},
{
urls: [
"<all_urls>",
],
types: ["image"]
},
["blocking"]
);
Hope someone is able to help me/give me some hints. :)
Best regards
You might find it more useful to write a constructor that returns a "promisified Image", ie an instance of
window.Image
with a custom.setSrc()
method that returns a promise.Something like this (untested) should do it :
Now you can call the returned Image's
.setSrc(...)
method instead of.src = '...'
Your
....addListener()
handler might look something like this :An advantage of doing it this way is that the returned Image is reusable. A second call to
.setSrc()
would operate on the same instance of Image, but would return a new promise.Note: I've not tried to penetrate the
chrome.webRequest.onBeforeRequest.addListener()
wrapper the other parameters passed to it. After a casual glance at the documentation, this looks like it might be the wrong approach. Therefore this answer may well offer only a partial solution.