Skip to content
This repository has been archived by the owner on Dec 27, 2023. It is now read-only.

Iframe Resizing

nikhil ponnuru edited this page Feb 9, 2016 · 3 revisions

After the iframe is injected into the host page, it won't have the proper height and the same origin policy prevents the host page from sensing the height of iframe contents. To support the dynamic modification of iframe heights, all injected iframes should support the following functionality. All of this functionality will eventually be supported via content scripts, but there are issues with some platforms. Until we solve all issues with content scripts, the injected pages must implement these functions.

Host Page

Interaction with the host page is handled completely by a content script (the script injected into the iframe page by the extension).

Resizing the iframe via content script

The content script handles resizing of an iframe by checking a posted message for a string containing an iframe name and the height of the referenced iframe, for example "iframeName,200" represents a message from an iframe named "iframeName" with contents 200 pixels vertically. The current implementation of the function can be found in privly.js, but as of this writing it is:

    //check the format of the message
if (typeof(message.origin) !== "string" ||
    typeof(message.data) !== "string" ||
    message.data.indexOf(',') < 1) {
  return;
}

//Get the element by name.
var data = message.data.split(",");
var iframe = document.getElementsByName(data[0])[0];
if (iframe === undefined) {
  return;
}

// Only resize iframes eligible for resize.
// All iframes eligible for resize have a custom attribute,
// data-privly-accept-resize, set to true.
var acceptresize = iframe.getAttribute("data-privly-accept-resize");
if (acceptresize !== "true") {
  return;
}

var sourceURL = iframe.getAttribute("src");
var originDomain = message.origin;
if ( typeof sourceURL !== "string") return;
sourceURL = sourceURL.replace("http://", "https://");
originDomain = originDomain.replace("http://", "https://");

//make sure the message comes from the expected domain
if (sourceURL.indexOf(originDomain) === 0)
{
  iframe.style.height = data[1]+'px';
}
},

The script has several integrity checks for the posted message. First, the script will only resize iframe if it has a custom attribute, "acceptresize", set to "true". Second, it ensures that the origin of the message matches the domain of the indicated iframe element.

Injected Page or Content Script

The following functionality will be defined within the iframe injected into the host page. It could be defined by the host page directly, or use the functionality defined by the content script. The goal is to put all this functionality into the content script, but some platforms have security restrictions which make it better supported by the injected page.

Defining the iframe's Height

The contents of the iframe will have a height sampled by the first successful strategy:

  1. The height of a div element wrapping all the body contents of the page. The id of the div element should be "privlyHeightWrapper", var newHeight = document.getElementById("privlyHeightWrapper").offsetHeight;
  2. Deprecated The height of a div element wrapping all the body contents of the page. The id of the div element should be "wrapper."
  3. Pages not defining the privlyHeightWrapper will return the maximum of several elements as defined below. This is intended to be a cross-platform method of finding the height of a document.

Code example:

var D = document;
if(D.body){
  var newHeight = Math.max(
          document.body.scrollHeight, 
          document.documentElement.scrollHeight, 
          document.body.offsetHeight, 
          document.documentElement.offsetHeight, 
          document.body.clientHeight, 
          document.documentElement.clientHeight
      );
}

Posting Resize Message

Resize messages to the parent document contain "name,height", where name is the name of the iframe and height is the height of the document as established above. Note that parent.postMessage does not work from a content script in Google Chrome.

parent.postMessage(window.name+","+height,"*");

Dispatching the resize event

An "event" may be necessary on some platforms as a replacement for the postMessage approach.

var evt = document.createEvent("Events");  
evt.initEvent("IframeResizeEvent", true, false);
var element = document.createElement("privElement");
element.setAttribute("height", height);  
element.setAttribute("frameName", frameName);  
document.documentElement.appendChild(element);    
element.dispatchEvent(evt);

Triggering the Message and Event

The postMessage and Event will be sent after each of these events:

  • Page load
  • After the host page changes the width of the iframe container. Note: this requires the host page to message the iframe's application, which should answer back with the current height
  • When the injected application wants to update its height
Clone this wiki locally