Sunday, January 18, 2009

Using an IFRAME to force a doctype

There have been times when I wanted to create a JavaScript widget that I could embed into any web page. One problem I ran into was that I would develop my widget in a standards mode page, but then it would not work when embedded on a page in quirksmode.

"Who still uses quirksmode?" you might ask. Well, for legacy reasons, iGoogle gadgets do. I thought that OpenSocial fixed that, but item 6 of the spec says otherwise, though the discussion group suggests a distasteful workaround.

Either way, this whole doctype thing is a problem. On a web page, the document has a doctype property, but it's read-only, so trying to edit that is a dead-end. Originally, I tried manipulating the content of an iframe with src="about:blank" which I thought would be clean because it had no content, but no content means no doctype, so it is also stuck in quirksmode.

One option that does work is to have an empty html page with the strict doctype on the same domain as your JavaScript widget. That way, your widget can write its content into a local iframe using the empty html page as its source. The drawbacks to that approach are: (1) it complicates the API of your widget because it requires the consumer of your API to make a server-side change and bake the URL into calls to your API; and (2) you have to add some extra logic to listen for the iframe to load before you can write to it, so it forces your API to become asynchronous rather than synchronous.

The best solution I've seen so far is to dynamically create an iframe with no src attribute and to use document.write() to insert the content of the iframe or to set the src attribute to javascript:parent.functionThatReturnsTheDesiredContentAsHtml(). This test page demonstrates both techniques.

One thing that is particularly advantageous with this technique is that if your widget requires its own stylesheet, it can load it in the iframe instead of the top-level page where your CSS class names run the risk of conflicting with the CSS class names used in the host page. So even if you know that your widget is going to be used in a standards-compliant page, you may want to use this technique to create a "fresh namespace" for your CSS.

The only disadvantage that I've found with iframeing over inlining is with managing overlays that need to appear outside the iframe. In the test page, there is a green box that appears over the iframes and the main page. For it to be visible, it needs to be an element of the top-level page, which (1) may be in quirksmode and (2) will not honor the CSS rules defined in your iframe. That means that you may have to design your popup so that it works in both rendering modes and uses inline styles (exactly what we were trying to avoid with our universally-embeddable JavaScript widget!).

Also, the JavaScript code that manages such an overlay needs to be wary of its use of the document variable as it is important to use it in the correct context (iframe vs. host page). It is best to create different getters for the two documents and to use those exclusively, avoiding direct access to document altogether.

Overall, I am still pretty happy with this solution, though one thing that occurred to me is that this is a little frightening with respect to phishing in that a malicious web page could easily display an iframe to foreign content (that is familiar to you) and then display its own login box or credit card form on top of it to lure you to enter your information. I mentioned this to Mihai, and he said this is somewhat of a known issue, citing this example at zombieurl.com (warning: page contains sound). I guess that goes to show that you can never be safe from zombies, not even on the Internet.

10 comments:

  1. I appreciate, cause I found exactly what I was looking for. You have ended my four day long hunt! God Bless you man. Have a great day. Bye

    사설토토
    카지노사이트
    파워볼
    온라인카지노

    ReplyDelete
  2. I’m really enjoying the design and layout of your blog. I once again find myself spending way to much time both reading and commenting. But so what, it was still worth it!
    토토
    스포츠토토
    토토사이트
    먹튀검증

    ReplyDelete
  3. Thank you for the good writeup. It in truth was a amusement account it. Look complicated to far brought agreeable from you! However, how can we be in contact?

    사설토토
    바카라사이트
    파워볼사이트
    온라인바카라

    ReplyDelete
  4. Nice Information are there in it! Thank you for some information. You give me some idea's. Keep posting.

    야한동영상
    대딸방
    타이마사지
    안마
    바카라사이트

    ReplyDelete
  5. You absolutely come with really good articles and reviews. Regards for sharing with us your blog. 먹튀검증디비

    ReplyDelete
  6. If some one desires expert view on the topic of running a blog then i propose him/her to visit this weblog, Keep up the pleasant job. 바카라사이트

    ReplyDelete
  7. Interesting post. I Have Been wondering about this issue, so thanks for posting. Pretty cool post. It ‘s really very nice and Useful post. 스포츠중계

    ReplyDelete
  8. After reading this post, we can improve our writing skills and abilities. Here, we can find an informative post. Thanks for your post. 파워볼사이트

    ReplyDelete
  9. Thanks For sharing this Superb article. it is valuable For me Great Work. I ought to be compose greater remark on this incredible point. 먹튀검증

    ReplyDelete
  10. I've been looking for photos and articles on this topic over the past few days due to a school assignment, bitcoincasino and I'm really happy to find a post with the material I was looking for! I bookmark and will come often! Thanks :D

    ReplyDelete