Reputation: 7318
I'm writing a Chrome extension (a fact that shouldn't(?) matter in this case).
I'm adding an iframe dynamically when the user selects text, as such:
var myframe = '<div id="modal-from-dom" class="modal hide fade" style="width: 673px;">' +
'<div class="modal-body">' +
'<iframe id="iFrameID" style="border: 0px;" src="http://www.example.com/" height="240px" width="638px"></iframe>' +
'</div>' +
'</div>';
$('body').append(myframe);
I then keep searching for the iFrame until an non-empty object is return. Then I try to access the contentWindow
property which ends up being undefined (though other properties such as src
are fine):
$('#iFrameID').prop('contentWindow'); // undefined
Thanks in advance for any ideas you may come up with.
P.S.: The end goal is to get the size of an element inside the iframe so I can resize the iframe host appropriately using postMessage
.
Upvotes: 2
Views: 6068
Reputation: 11810
This is a known issue with Chrome extensions.
iFrames' contentWindow
and contentDocument
attributes are undefined
. window.frames
is also empty. The result is that you can't use postMessage
to communicate down into an iFrame.
See http://code.google.com/p/chromium/issues/detail?id=20773
You can work around this by using a content script that matches the src
of the iframe to gain access to the frame's window
, enabling you to use the postMessage
API to communicate with it.
Here is an example that takes all chrome messages and fires them as message events on in the iframe:
chrome.extension.onMessage.addListener = function(request, sender, sendResponse){
// Pass on some messages context for local execution
window.postMessage(request, "*");
}
Upvotes: 2
Reputation: 25367
I would recommend making an ajax GET for the url to display, taking the html response, adding a script tag that will use postMessage with your parent frame (your extension code), and then set the src of the iframe to data url of the base64 encoded data. It's easier to read some code:
var iFrameID = $(document.getElementById('iFrameID')); //This is very efficient.
$.get('http://www.example.com', function(response) {
postMessager = '<script>'+
'window.postMessage ... '+
reference https://developer.mozilla.org/en/DOM/window.postMessage here
'</script>'
iFrameID.src = 'data:text/html;base64,' + utf8_to_b64(postMessager + response));
});
Where
function utf8_to_b64( str ) {
return window.btoa(unescape(encodeURIComponent( str )));
}
function b64_to_utf8( str ) {
return decodeURIComponent(escape(window.atob( str )));
}
In your extension code, you'll also want postMessage code of course. I know this isn't the most complete information and code, but I hope it points you in a solid direction. Be wary about inserting innerHTML into an iframe with no src attribute, as not javascript will run. And if you're looking to iframe any regular page on the internet, I've got some stuff drumming along to do this that you could message me about.
Upvotes: 0