I ran into a problem recently where a completely valid XHTML 1.0 transitional site was rendered incompliant by the addition of <cfmenu>. It seems that <cfmenu> causes compliance to fail in two ways:
First, it adds JavaScript to the “OnMouseOver” and “OnMouseOut” attributes of its menu items. To be compliant, it should be adding them to the “onmouseover” and “onmouseout” attributes. There’s an easy fix to this. Inspired by Ben Nadel’s post on altering the output of the writeToBrowser feature of <cfimage> I just used <cfsavecontent> to capture the menu, and then alter it, as listed below:
<cfsavecontent
variable=“menuContent”>
<cfmenu
name=“menu”
type=“vertical”>
<cfmenuitem
name=“home”
href=“index.cfm”
display=“Home”/>
</cfmenu>
</cfsavecontent>
<!— These calls help bring page to XHTML compliance. —>
<cfset menuContent = Replace(menuContent, “OnMouseOver”, “onmouseover”, “ALL”) />
<cfset menuContent = Replace(menuContent, “OnMouseOut”, “onmouseout”, “ALL”) />
<cfoutput>#menuContent#</cfoutput>
But that doesn’t hit the other problem, which is that any of the Ajax capable tags seem to add the following bit of code to the top of a page:
_cf_loadingtexthtml=”<div align=’center’><img src=’/CFIDE/scripts/ajax/resources/cf/images/loading.gif’/>”
This screws up compliance on two fronts:
- The div created in that code isn’t closed.
- The img created in that code doesn’t have a alt tag.
Now the interesting thing here is that isn’t actually a div that’s created, it’s only JavaScript that will at some point create those elements. I think technically the compliance test is falsely marking this as a violation. But try explaining that to a client who demands compliance without understanding the theory behind it.
Anyway, I can’t find a single way around this. Using the OnRequest method of application.cfc was my best bet. I figured I would use to call <cfsavecontent> and replace the offending code like I did above. Unfortunately, this spot of code is directly written to the buffer when <cfmenu> gets called.
I also tried a few getPageContext() functions, but to no avail. I’ll be stuck trying to explain this to the client. In the meantime, I filed a bug report with Adobe.