use apply and call on WebExtension API functions

Hi,
I am converting a chrome extension to safari web extension.
In my test in Safari 14 beta 4. (14610.1.26), it seems the web extension api can't use the apply or call method.
For example:
In Chrome, we can use
Code Block javascript
chrome.tabs.query.apply(null, [{}, function(tabs){
console.log(1, tabs);
}]);

But in Safari, this will not work, we can only use
Code Block javascript
browser.tabs.query({}, function(tabs){
console.log(1, tabs)
});

It would be very helpful if in Safari we can use apply and call method for WebExtension APIs

Thank you very much

Answered by Frameworks Engineer in 630955022
Both of these cases are because the API functions require a proper this object when called. This is currently a requirement in Safari and different from Chrome.

For the first case you can do:
Code Block
browser.tabs.query.apply(browser.tabs, [{}, function(tabs){
console.log(1, tabs);
}]);

Or in the second case:
Code Block
apiTest(browser.tabs.query.bind(browser.tabs));

Here is some more info on bind() and this object.
Another interesting finding is, seems we can not pass the API as a parameter
Code Block javascript
function apiTest(method){
method({}, function(result) {
console.log('Result', result);
});
}
apiTest(browser.tabs.query);

This works in Chrome, but not working in Safari




Accepted Answer
Both of these cases are because the API functions require a proper this object when called. This is currently a requirement in Safari and different from Chrome.

For the first case you can do:
Code Block
browser.tabs.query.apply(browser.tabs, [{}, function(tabs){
console.log(1, tabs);
}]);

Or in the second case:
Code Block
apiTest(browser.tabs.query.bind(browser.tabs));

Here is some more info on bind() and this object.
Thanks timothy, it works!
use apply and call on WebExtension API functions
 
 
Q