My Chrome extension uses message passing to retrieve various values from the extension's built in localstorage area on the background page.
The thing I love about chrome message passing, is it lets you include a callback function inside the sendMessage call, like so:
chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
console.log(response.farewell);
});
and the corresponding message receiving code would look like the following (example code from the Chrome extensions documentation):
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting == "hello")
sendResponse({farewell: "goodbye"});
});
I'm trying to convert my extension to the Safari extension format, but I can't figure out how to map the Chrome sendMessage / onMessage functions to Safari's
safari.self.tab.dispatchMessage(name, data)
message handling functions
Is it even possible to include callback functions in Safari's dispatchMessage function call? If not, how should I work around this limitation?
In environments that only provide a one-way message passing system, you can always implement "message-with-callback" yourself, by associating an unique ID with every message, and storing the callbacks in a dictionary that maps these IDs to the callbacks.
At the end of this answer, I've copy-pasted the Safari-specific storage module from the source code of my cross-browser Lyrics Here extension, which provides the following API:
config.getItem(key, callback)
config.setItem(key, value, callback)
config.removeItem(key, callback)
config.clear(callback)
The callback of
getItem
contains the value associated with the key (if found). The other callbacks receive a boolean that tells whether the operation succeeded or not.The source code is annotated and contains snippets to handle a few edge-cases. Feel free to shoot a few questions at me if there's anything unclear.
config-safari.js (AMD)
Fragment of global.html: