views:

51

answers:

2

I'm working on a safari extension and I was wondering if there is a way to do synchronous message passing in a safari extension.

I want to send a message from my injected javascript to the global page have the injected javascript wait until a result is returned. Having to split my code into another function that receives a message from the global page just seems overly complicated.

+1  A: 

You can use the "special" canLoad message. Technically, it's intended to send a message and return a value related to whether an element on the page can load, but it's really just a synchronous message that's answered by the global HTML page the same way as any other. You'd just look for the message named 'canLoad' instead of passing a custom message name:

// injected script
var myVar = safari.self.tab.canLoad( event );

// global HTML file
<!DOCTYPE html>

<script type="text/javascript" charset="utf-8">
  safari.application.addEventListener( 'message', listen, true );

  function listen( msgEvent ) {
    switch( msgEvent.name ) {
      case 'canLoad':
        msgEvent.message = 'My return value';
        break;
    }
  }
</script>

You can read more about the canLoad message in the development guide.

Rob Wilkerson
I remember reading about the canLoad function but the problem is that the first argument must be a beforeLoad event object. Since my code isn't triggered by a beforeLoad event, I wont be able to use that.
Clever Error
The synchronous canLoad event is only triggered when the browser is trying to load content. It has to be synchronous other it would not be possible to prevent any part of a load from occurring. Every other form of communication is asynchronous.
olliej
A: 

There was someone else who asked the same question on the Safari developer forum. In short, you can't. (Besides, in my humble opinion, the canLoad function is purely stupid.)

You may, however, use closures to make it as painless as possible.

zneak