Unsurprisingly, Internet Explorer 8 broke yet another feature of the web. This time, the folks at Redmond broke how Internet Explorer passes the flashvars parameter into Flash. Typically, when placing a Flash object on an HTML page, you use the following syntax:
<object id="flv" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="692" height="516" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" align="middle"> <param name="allowScriptAccess" value="sameDomain" /> <param name="allowFullScreen" value="true" /> <param name="quality" value="high" /> <param name="bgcolor" value="#424242" /> <param name="FlashVars" value="name=value" /> <param name="wmode" value="transparent" /> <embed type="application/x-shockwave-flash" width="692" height="516" src="http://www.example.com/mysample.swf" name="flv" allowfullscreen="true" allowscriptaccess="sameDomain" wmode="transparent" bgcolor="#424242" quality="high" flashvars="name=value" pluginspage="http://www.macromedia.com/go/getflashplayer" align="middle"></embed> <param name="movie" value="http://www.example.com/mysample.swf" /> </object>
The OBJECT tag is used by Internet Explorer and the EMBED tag is used by everyone else (Firefox, Safari, etc.). Although the flashvars paramter is not formally described in the HTML 4.0.1 spec1, this code worked fine with IE 6 and IE 7. Unfortunately, IE 8 does not pass flashvars into the Flash Player. The only work around is to pass the flashvars parameter as part of the movie name parameter, as shown below:
<object id="flv" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="692" height="516" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" align="middle"> <param name="allowScriptAccess" value="sameDomain" /> <param name="allowFullScreen" value="true" /> <param name="quality" value="high" /> <param name="bgcolor" value="#424242" /> <param name="FlashVars" value="name=value" /> <param name="wmode" value="transparent" /> <embed type="application/x-shockwave-flash" width="692" height="516" src="http://www.example.com/mysample.swf" name="flv" allowfullscreen="true" allowscriptaccess="sameDomain" wmode="transparent" bgcolor="#424242" quality="high" flashvars="name=value" pluginspage="http://www.macromedia.com/go/getflashplayer" align="middle"></embed> <param name="movie" value="http://www.example.com/mysample.swf?name=value" /> </object>
Notes:
While working on a recent project in GWT, I needed to embed a full HTML document inside an IFRAME. And I didn't want to specify a remote URL for the IFRAME - I actually wanted to shove the HTML content directly into the IFRAME.
Initially I thought it was trivial: create an IFrameElement and call setInnerHTML.
IFrameElement iframe = Document.get().createIFrameElement(); iframe.setInnerHTML(htmlContent);
Unfortunately, that doesn't work. It doesn't cause any errors, but it doesn't actually fill in the iframe. Instead, you have to use native javascript to write into the document object for the iframe:
private final native void fillIframe(IFrameElement iframe, String content) /*-{ var doc = iframe.document; if(iframe.contentDocument) doc = iframe.contentDocument; // For NS6 else if(iframe.contentWindow) doc = iframe.contentWindow.document; // For IE5.5 and IE6 // Put the content in the iframe doc.open(); doc.writeln(content); doc.close(); }-*/;
Voila! However, one of the side effects is that the iframe doesn't include any CSS unless your embedded HTML references a stylesheet. If you want to manually add a reference to a specific stylesheet, you can do that through native javascript as well:
private final native void addHeadElement(IFrameElement iframe, String cssUrl) /*-{ setTimeout(function() { var body; if ( iframe.contentDocument ) { // FF iframe.contentDocument.designMode= "On"; iframe.contentDocument.execCommand('styleWithCSS',false,'false'); body= iframe.contentDocument.body; } else if ( iframe.contentWindow ) { // IE body = iframe.contentWindow.document.body; } if (body == null) { return; } body.className = "custom-body-classname"; var head = body.previousSibling; if(head == null) { head = iframe.contentWindow.document.createElement("head"); iframe.contentWindow.document.childNodes[0].insertBefore(head, body); } var fileref = iframe.contentWindow.document.createElement("link"); fileref.setAttribute("rel", "stylesheet"); fileref.setAttribute("type", "text/css"); fileref.setAttribute("href", cssUrl); head.appendChild(fileref); }, 50); }-*/;}
There's still one more problem. You can't use either of native methods until the IFRAME element has been attached to the DOM. The easiest way around this is to add the IFRAME element to a panel and over the onLoad() method for the panel:
final IFrameElement iframe = Document.get().createIFrameElement(); FlowPanel innerBox = new FlowPanel() { @Override protected void onLoad() { super.onLoad(); // Fill the IFrame with the content html fillIframe(iframe, contentHtml); // Add a HEAD element to the IFrame with the appropriate CSS addHeadElement(iframe, cssUrl); } }; innerBox.getElement().appendChild(iframe);
I got the idea and the important code from an article titled Inject HTML into an IFrame from Software As She's Developed.
In an earlier post, I described a class to handle redirects in Struts and passing parameters along. That technique is not necessary; as of Struts 1.2.7, you can use the ActionRedirect class instead.
Here's a basic example from inside the execute method in an Action.
OnJava has an interesting article on generic approach to handling exceptions within a J2EE framework. The basic idea involves creating a generic base class for exceptions and a basic handler for all requests that includes dispatcher to pass the request along to the appropriate method.
One of the huge pains about writing AJAX applications is handling logging and debugging. Many Java developers use log4j, so something similar would be immensely beneficial. Of course, there is a SourceForge project called log4ajax that attempts to solve this very problem.
Recent comments
13 weeks 3 days ago