-
Notifications
You must be signed in to change notification settings - Fork 9
Iframe Resizing
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.
Interaction with the host page is handled completely by a content script (the script injected into the iframe page by the extension).
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.
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.
The contents of the iframe will have a height sampled by the first successful strategy:
- 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;
- Deprecated The height of a div element wrapping all the body contents of the page. The id of the div element should be "wrapper."
- 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
);
}
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,"*");
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);
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
Foundation Home
Repository List
Development Mailing List
Testing Mailing List
Announcement Mailing List
Central Wiki
Submit a Bug
IRC
Download Extension
These documents are under active development and discussion.
Credit: This Google Summer of Code content is licensed under the CC Attribution-Noncommercial-Share Alike 3.0 Unported license furnished by the Sahana Software Foundation.