Iframe messaging

Introduction

When widgets are rendered within an Iframe, you need to handle communication between this iframe and your main page. Main example is 'resizeHeight'. If your widget need to grow up or to shrink itself, it sends a 'resizeHeight' message to your page, and you need to handle it correctly to resize your iframe.

Cross-domain iframe communication was not an easy task until recent postMessage method (http://developer.mozilla.org/en/docs/DOM:window.postMessage), and unfortunately, it's not currently implemented in all browsers. For all non enabled postMessage browsers, we use a special trick, using an html proxy, this is transparent for you, you don't need to know how the message is getting to your page.

Browserhas postMessage?
Internet Explorer 6no
Internet Explorer 7no
Internet Explorer 8byes
Firefox 2no
Firefox 3yes
Safari 2no
Safari 3no
Webkityes
Opera >= 9.50yes

Setting up your page

You first need to include IFrameMessaging.js, which provide a class to handle messages coming from widgets.

<script type="text/javascript" src="http://www.netvibes.com/js/UWA/Utils/IFrameMessaging.js"></script>

Then, you have to define the function used to manage all messages coming from the widget. In this case, this is a basic code, only handling resizing message:

msgHandler = function(message) {
  var id = message.id;
  switch (message.action) {
    case 'resizeHeight':
      var frame = document.getElementById('frame_' + id);
      if (frame) {
        frame.setAttribute('height', message.value);
      }
      break;
  }
};

Finally, instantiate IFrameMessaging class. You MUST name your iFrameMessaging object UWA.MessageHandler, because the iFrame messaging system will call it explicitely with this name. then you have to pass your message handler and, not mandatory but advisable, to set 'trustedOrigin' parameter to the domain where your Exposition server is.

UWA.MessageHandler = new UWA.iFrameMessaging;
UWA.MessageHandler.init({
    'eventHandler': msgHandler,
    'trustedOrigin' : 'nvmodules.netvibes.com'
});

This is finished for Javascript part.

In your page body, add your iframe. Please note you have to provide a html proxy file([ABSOLUTE_PATH_TO_YOUR_HTML_PROXY]) to enable iframe messaging for non postMessage enabled browser (we'll see that in next point HTML proxy

<iframe id="frame_123458" scrolling="no" frameborder="0" height="100" width="400"  src="http://nvmodules.netvibes.com/widget/frame/?uwaUrl=http%3A%2F%2Fwww.netvibes.com%2Fapi%2Fuwa%2Fexamples%2Falexa.html&id=123458&ifproxyUrl=[ABSOLUTE_PATH_TO_YOUR_HTML_PROXY]&alexaSite0=netvibes.com&alexaSite1=nytimes.com">

here is the full sample page :

<html>
<head>

<script type="text/javascript" src="http://www.netvibes.com/js/UWA/Utils/IFrameMessaging.js"></script>


<script type="text/javascript">

msgHandler = function(message) {
  var id = message.id;
  switch (message.action) {
      
    case 'resizeHeight':
      var frame = document.getElementById('frame_' + id);
      if (frame) {
        frame.setAttribute('height', message.value);
      }
      break;
  }
};


UWA.MessageHandler = new UWA.iFrameMessaging;
UWA.MessageHandler.init({
    'eventHandler': msgHandler,
    'trustedOrigin' : 'nvmodules.netvibes.com'
});

</script>
</head>
<body>
<iframe id="frame_123458" scrolling="no" frameborder="0" height="100" width="400"  src="http://nvmodules.netvibes.com/widget/frame/?uwaUrl=http%3A%2F%2Fwww.netvibes.com%2Fapi%2Fuwa%2Fexamples%2Falexa.html&id=123458&ifproxyUrl=[ABSOLUTE_PATH_TO_YOUR_HTML_PROXY]&alexaSite0=netvibes.com&alexaSite1=nytimes.com">
</iframe>
</body>

HTML proxy

This file should be present anywhere in your domain, and passed as a parameter in your iframe to handle non postMessage enabled browsers. This exemple links ifproxy.js from Netvibes domain but you can host it by yourself:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="http://www.netvibes.com/js/UWA/Utils/ifproxy.js"></script>
<title>UWA Container Proxy</title>
</head>
<body>
</body>
</html>