IFRAME scenarios (Standard Compliant IFRAMEs and the OBJECT thing)

Sunday, October 8 2006

A long journey in search of the neat code, where all IFRAMEs are standard and all OBJECTS are just the real thing. That is: how to embed iframe content in a web page while not using a iframe element.

Intro

As the author of a web site devoted to contemporary street art (Contemporary Street Art) I wanted to embed a calendar to show details on event related to graffiti, public art, and contemporary art exhibitions or meetings but disliked the blog built-in feature. I'm using Drupal and I didn't liked any of the available module featuring this functionality.

Also I wanted to keep a unique interface, that is one and only one calendar application, to manage both my private schedule and the public ones. Since I was a happy Google Calendar user, elections ended with a hunanimous consent that Google Calendar would have been the application of choice.

Now Google Calendar offer the chance to both render your calendar, or more than one, public. The only thing you have to do is to spread around the URL of the calendar you want to share, available both as a XML feed and a HTML page, or to export a ICAL file.

But Google Calendar also offer an online configuration tool to embed your selected calendar to your web site or blog of choice. By selecting a few useful settings, the tool generates the HTML code you'll need to insert the calendar in your page. It renders exactly as it looks in your personal Google Calendar page. The problem is: the thing they want you to insert is an IFRAME object.

If you are a standard purist, you want to keep your code neat and standard compliant and if you are really core you probably replace all your Google Maps link & special character with a & character entity reference as I'm doing (and still I missed some as you may find out by checking ContemporaryStreetArt.com against the W3C HTML validator). IFRAME has some problem validating against XHTML 1.0 Strict, it actually validates only against XHTML 1.0 Transitional.

Ok that was the long useless intro to the point of this post, how to actually embed an IFRAME object while keeping your standard habits safe.

How to starts here

First of all, I must say this method, which I don't know if already proposed by someone else or not, has been made possible thanks to Elizabeth Castro's Bye Bye Embed article on A List Apart web site. The above is a solution to embed flash/quicktime/windows media movies in web pages, without using the non-standard tag <embed>.

The solution proposed in the List Apart article, to embed a flash YouTube video or Google Video is to use the following code:

<object type="application/x-shockwave-flash" data="VIDEO URL" width="400" height="326" id="VideoPlayback">
 <param name="movie" value="VIDEO URL" />
 <param name="allowScriptAcess" value="sameDomain" />
 <param name="quality" value="best" />
 <param name="bgcolor" value="#FFFFFF" />
 <param name="scale" value="noScale" />
 <param name="salign" value="TL" />
 <param name="FlashVars" value="playerMode=embedded" />
</object>

In the above code the VIDEO URL is the address of the video, while the type attribute is the declaration for the content type (MIME Media type). Width and height attributes refer to the object size, all the others <param> entities refer to the object's peculiarities. Remember tha id must be unique, that is if you need to embed various objects (videos, flash, and as you'll see in a few lines, an IFRAME) each one of them must have a unique id. If you need to apply a common style to every object, use a attribute instead so you may have the same occurence for all of them. Also you need to have at hand the object content type definition to apply to the above code.

Content types

As seen above, to insert a YouTube or Google Video, as both are a Flash movies, you have to define the content type (MIME Media type), also you have to use the attribute name set to movie with value set to the object's URI for the entity param:

<object type="application/x-shockwave-flash" value="http://yourSiteName/folderName/FlashObjectName.swf" >
<param name="movie" value="http://yourSiteName/folderName/FlashObjectName.swf" />
(...)
</object>

If you need to embed a Windows Media Video, you have to change the content type value, and use src as value for the attribute name of the param entity:

<object type="video/x-ms-wmv" data="http://yourSiteName/folderName/MovieName.wmv" width="320" height="260">
<param name="src" value="http://yourSiteName/folderName/MovieName.wmv" />
(...)
</object>

More on: The Content-Type Header Field.

Show me your (Class) ID

To add different types of content, like a Quicktime movie, you need do declare for Internet Explorer use, the classid for the relevant ActiveX plugin to be initialized. This is a numerical code in the form of 02BF25D5-8C17-4B23-BC80-D3488ABDDC6B, the grammar for calling this is the following:

<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" width="WIDTHinPIXELS" height="HEIGHTinPIXELS">
(...)
</object>

IFRAME this!

Now here we are with that IFRAME thing I was talking about paragraphes ago, the following is the code I used to embed an IFRAME object, without using the Iframe entity.

<object type="text/html" data="http://www.google.com/calendar/linksWith&Things" style=" width="480" height="730">
</object>

Remember to change all & special characters with &amp; to pass validation.

The above code works just fine, in Mozilla based browser (as Firefox), Opera, and in Internet Esplorer. Well, sort of. Actually, it just works fine in my local Internet Explorer (version 7.0.5700.6), NOT when I put this thing online. Why this is happening? That's a great question. I spent quite a few hours in frustration reading around technical papers and documentations and blog posts on the internet about the object and its IE implementation. Still, no clue. Does it work on previous IE versions (the IE 6 being probably the browser with a major user base out there)? I have no direct clue (I'm trying to have both the Microsoft browser at the same time with the help of a sandbox scenario) but my guess it's it doesn't work on IE 6, or earlier. Even if without any proved evidence, I think this has to do with the dealing of that classid, the fact I'm not stating any for the Iframe it's preventing the object to be displayed by IE as it is (un)recognized as a not a secure/declared ActiveX plugin. Thus IE gives no access, another guess, to prevent security's exploits.

I share with you some of the resources I looked at, because I know how frustrating is the search refining process, in case you are interested in this topic.

A small diversion

In the last of the links above, Mark Pilgrim (the guy behind diveintomark.org) says:

(...) img has been removed from XHTML 2.0, in favor of OBJECT, and I’m wondering if there’s a smooth migration path. The question of the day is: Can we start using object now to replace img?

If you have a look at W3C.org draft specifications for XHTML 2, the section about the Image Module is someway foggy about the topic:

The img element is a holder for embedding attributes such as src. Since these attributes may be applied to any element, the img element is not strictly necessary, but is included to ease the transition to XHTML2.

But it stress a behaviour that should have been taken in more consideration even in XHTML 1, that is the smooth downgrade of unsupported/unavailable content sources:

Like the object element, this element's content is only presented if the referenced resource is unavailable.

In the following example, the W3C text appears only if the W3C image logo is not available, or the file format is not supported by the UA:

<img src="W3C.png">W3C</img>

Which reminds me of a classic List Apart's article: Facts and Opinion About Fahrner Image Replacement, and all related discussions:

Some more link for the future

The following refer to the proposed embedding and object module implemantation in XHML 2:

The real thing in action

Still I didn't find any solutions to see my Google Calendar embedded in both Mozilla and IE engines. I hard-tricky-coded for a day, mixing and scratching XHTML salsas (1.0 mild flavored and 2.0 sticty xmlized taste) with no success. No param or name spice to rescue my code.

My only chanche's being to implement a nested object scenario embedding an image source to provide IE (i.e its users) with alternate content.

So, finally (you are probably thinking), the following is the implementation of the code to embed the Google Calendar in a web page without using the iframe, if you are using a standard savvy browser you'll see the calendar thing, if not you'll probably see the text: Alternate Content goes here. As an example I'll work with the embedding of this very blog feed via the Google Reader, as it looks like the Google Calendar beahvior tends to freeze (something to do with the concurrent calls from the same URL?). After the real thing you'll find the code, together with all the relevant notes:

Example 1

Alternate Content goes here

Code for Example 1

Please note, text wraps are preceeded by >>>

<object type="application/xhtml+xml" data="http://www.google.com/reader/view/feed/http%3A >>>
%2F%2Fexploded.awcr.org%2Frss.xml">
 <object><p>Alternate Content goes here</p></object>
</object>

As you may see the result is ok as long as you see the calendar object if using Firefox or Opera, and you see a Alternate Content goes here if you are using Internet Explorer.

The only issue's being the reduced high and width of the embedded object and thus the presence of the vertical and horizontal scroll bar. In the case of the calendar link, which is made by following a wizard that generates a custom html code, dimensions are specified in the same url ((...)google.com&height=600) but fails to be recognized by the browser. The solution here is to force dimensions, the height and width if you have to, by putting it as attributes of object. Here I'm only adjust the height not to break too much my blog layout:

Example 2

Alternate Content goes here

Code for Example 2
<object type="application/xhtml+xml" data="http://www.google.com/reader/view/feed/http%3A >>>
%2F%2Fexploded.awcr.org%2Frss.xml" height="700" width="450">
 <object><p>Alternate Content goes here</p></object>
</object>

Now, the following is the solution I intended to use for my Contemporary Street Art page, if you use a standard compliant browser you'll see the embedded feed, if using IE you'll be awarded the image AND the text link (the explanation for this beahviour comes after the code).

Example 3

Alternate Content goes here

Code for Example 3
<object type="application/xhtml+xml" data="http://www.google.com/reader/view/feed/http%3A >>>
%2F%2Fexploded.awcr.org%2Frss.xml" height="700" width="450">
 <object contentype="image/gif">
  <a target="_blank" href="http://www.google.com/calendar/render? >>>
cid=538g4829c1hgdmrbp0i01fgfoo%40 >>>
group.calendar.google.com">
   <img src="http://www.google.com/calendar/images/ext/gc_button1_en.gif" border=0>
 </a></object>
  <object contentype="text/html">
   <p>Alternate Content goes here</p>
  </object>
</object>

Note: The contentype attribute is the same as the type one, the only difference is this is not recognized by Mozilla but it is only by IE. Revision: Looks like the above code has the following behaviour in IE:

  • The text string Alternate Content goes here is displayed
  • A IE alert pops up: To help protect your security, Internet Explorer has restricted this webpage from running scripts or ActiveX controls that could access your computer. Click here for options...

If you select to allow blocked content the following Windows alert box pops up:

Alert box

Then, even if you select to OK, allow the content, the only available content shown is the image and the text string. And both of them, that is the deeper object is shown even if the previous one succeed to render the proposed content. Also this only works if there's any external unrecognized/unrendered object, in the example above this is represented by the Google Reader feed. If the image and the text option are given alone, IE does not render them even if they both are recognized (and rendered as previously seen) content objects.

This is NOT happy AND ending

After all that, maybe I lost a bit of the big picture, maybe I made some silly mistake. If this is not the case, then I'm afraid there still are huge improvements to make in both web standard and the adoptance of those standards by UAs. My post focus on a Windows XP computer web browser point of view, I really don't have any remote idea of how this page may be rendered on a mobile device, on a Safari on a Mac OSX, or on a whatever running no-matter-what.

It was just an effort to find a solution, I hope it may be of help. Comments are appreciated.

xHTML-Compliant iFrames using jQuery

Method for creating xHTML-strict compliant iFrames I've looked for the same solution for ages, and finally wrote this to solve. It's pretty slick, hope it helps! Cheers

combine a conditional and object as well as browser specific css

The only solution to the issue I have found is to provide an iframe to IE only then put in an object under the conditional. I then use browser specific CSS to set the object to display none for IE. It validates to XHTML strict and IE users do not see the security message. I just do not know what to do for users without JavaScript.
<!--[if IE]>
    <iframe src="data.html" frameborder="0" scrolling="no" 
    marginheight="0" marginwidth="0" topmargin="0" leftmargin="0" 
    allowtransparency="true" width="182" height="51">
        <script type="text/javascript">
            document.write("test");
        </script>
        <noscript>
            <a href="data.html" target="_blank">
                <img src="data.gif" alt="" />
            </a>
        </noscript>
    </iframe>
<![endif]-->

<object data="data.html" type="text/javascript" class="objecthide">
    <script type="text/javascript">
        document.write("test");
    </script>
    <noscript>
        <div>
            <a href="data.html">
                <img src="data.gif" alt="" />
            </a>
        </div>
    </noscript>
</object>

Neat solution

Thanks a lot Sherri for your comment, and for this nice hack. Now it's a matter of resolving the non-javascript browsers issue...

Post new comment

The content of this field is kept private and will not be shown publicly.

Journal of Contemporary Street Art

The Journal of Contemporary Street Art is printed on demand with lulu (lulu.com) and it mix street art photography with toponomy research.

Buy the Journal of Contemporary Street Art - JoCSA00

Support independent publishing: buy this book on Lulu - Buy the Journal of Contemporary Street Art (JoCSA00)

Subscribe to the feed!

What is this RSS thing? For help on subscribing and more options, or to subscribe to a particular category, please have a look at: RSS feed how to.

My del.icio.us tags

Aggregate Me!

My Google shared stuff

browse my shared stuff on Google

My friendfeed page

me on friendfeed.

Support Civil Liberties and Human Rights

Support EFF and Amnesty International, visit their web sites and find out how you can help.

Beijing 2008