I’m developing a chrome extension and bumped into a big problem.
I’m using content scripts to inject my javascript code on a web site. The web site has an iframe.
I can change the source code of the iframe but don’t seem to get any access to the iframe’s contentWindow property. I need it to insert text at the current carret position.
So basically this code works perfectly in the context of the page:
$("#iframe1").contentWindow.document.execCommand("InsertHTML", false, 'test text');
But when I try it to run in the context of my chrome extension I get this error:
TypeError: Cannot read property 'document' of undefined
What’s strange is that I can access the html of the iframe. So this code works perfectly from the chrome extension:
$("#iframe1").contents().find('div').html('test')
I tried putting “all_frames”: true in the manifest file but no luck 🙁
To understand why your code does not work, I include a fragment of my previous answer:
Solution for same-origin frames
In your case, either of the following will work:
Generic solution
The generic solution is using
"all_frames": truein the manifest file, and use something like this:This demo is for educational purposes only, do not use this demo in a real extension. Why? Because it uses
postMessageto pass messages around. These events can also be generated by the client, which causes a security leak (XSS: arbitrary HTML injection).The alternative to
postMessageis Chrome’s message API. For a demo, see this answer. You won’t be able to compare thewindowobjects though. What you can do is to rely thewindow.nameproperty. Thewindow.nameproperty is automatically set to the value of the iframe’snameattribute (just once, when the iframe is loaded).