Waiting for Caja to be ready

As you have seen before, you use the caja object to tame host objects for sharing with guest code. However, the taming facilities of the caja object are not immediately available. In our previous examples of host code, we have used the following pattern:

caja.initialize({ /* ... */ });
caja.load(aDiv, aUriPolicy, function(frame) {
  // 'caja' object is ready for taming here
});

taking advantage of the fact that Caja does not invoke the callback passed to load until the caja object is ready. Sometimes, this will not be enough; you may want to do some shared setup outside a specific load call. Here, we show you an example of how to do that.

Create guest code

Assume you define some guest JavaScript as follows (also available here):

<html>
  <head></head>
  <body>
    <input type="button" id="theButton" value="Say hello">
    <script type="text/javascript">
      document.getElementById('theButton').onclick = function() {
        sayHello();
      };     
    </script>
  </body>
</html>

Create host page

Now create a host page that wishes to load two instances of this guest, giving the same tamed API (also available here):

<html>
  <head>
    <title>Caja host page</title>
    <script type="text/javascript"
            src="//caja.appspot.com/caja.js">
    </script>
  </head>

  <body>
    <h1>Caja host page</h1>
    <div id="guest0" style="height: 200px;"></div>
    <div id="guest1" style="height: 200px;"></div>
    <script type="text/javascript">
      caja.initialize({
        cajaServer: 'https://caja.appspot.com/',
        debug: true
      });

      function alertGreeting() { alert('Hello world'); };
      var tamedAlertGreeting;

      caja.whenReady(function() {  // (1)
        caja.markFunction(alertGreeting);
        tamedAlertGreeting = caja.tame(alertGreeting);
      });

      function loadGuest(divId) {
        caja.load(document.getElementById(divId), undefined, function(frame) {  // (2)
          frame.code('https://developers.google.com/caja/demos/whenreadycallback/guest.html',
                     'text/html')
               .api({ sayHello: tamedAlertGreeting })
               .run();
        });
      }

      loadGuest('guest0');
      loadGuest('guest1');
    </script>
  </body>
</html>

Caja will call the argument of whenReady at (1) before it honors any pending requests to load as in (2). This example uses that fact to make sure tamedAlertGreeting is available for both guests when the callbacks of load are invoked. The resulting page looks like the following:

Run it yourself

Review

  • You learned to register callbacks that defer until caja is ready to be used.

Next steps