users@javaserverfaces-spec-public.java.net

[jsr344-experts mirror] HTML5 friendly markup (fix inconsistencies and documentation review)

From: Edward Burns <edward.burns_at_oracle.com>
Date: Fri, 21 Mar 2014 14:26:23 -0700

>>>>> On Tue, 18 Mar 2014 21:37:58 -0500, Leonardo Uribe <lu4242_at_gmail.com> said:

LU> Hi

LU> Recently in MyFaces Core 2.2.1 it was found some inconsistencies
LU> over the documentation done for HTML5 friendly markup (javadoc of
LU> TagDecorator and JSF 2.2 section 10.1.4). There are basically 2
LU> problems, that I will describe below. I have fixed them in MyFaces
LU> Core 2.2.2.

LU> The first problem is the documentation and the purpose of
LU> <jsf:element ...> tag is not very clear for the reader. In JSF 2.2
LU> section 10.1.4.1 page 10-8 it says something like this:

LU> "...

LU> <meter jsf:id="meter2" min="#{bean.min}" max="#{bean.max}"
LU> value="350">350 degrees</meter>

LU> ...

LU> As in the preceding example, the TagDecorator mechanism is activated
LU> but it is determined that this component should act as a
LU> <jsf:element> component for the purposes of postback processing. The
LU> behavior of the <jsf:element> is normatively specified in the VDLdoc
LU> for that tag. The behavior of the javax.faces.passthrough.Element
LU> renderer is normatively specified in the RenderKitDoc for that
LU> renderer ..."

LU> In the javadoc of TagDecorator it says something like this:

LU> "... If one or more of the attributes of the tag argument are in
LU> the http://xmlns.jcp.org/jsf namespace, obtain a reference to
LU> decoratedTag as described in the following steps and iterate through
LU> the list of TagDecorator instances as described in the preceding
LU> step, but pass decoratedTag to each call to
LU> decorate(javax.faces.view.facelets.Tag).

LU> ...

LU> * If no matching entry is found, let jsf:element be the value of
LU> targetTag ..."

LU> In few words, it is clear that TagDecorator converts something like
LU> <meter ... into <jsf:element pt:elementName="meter" ... . That's ok.
LU> The problem is what happen to their attributes. This is what the
LU> javadoc of TagDecorator says about how to convert the attributes:

LU> "... If the current attribute's namespace is empty or different from
LU> the argument tag's namespace, let the current attribute be
LU> convertedTagAttribute. This will have the effect of setting the
LU> current attribute as an attribute on the attributes map of the
LU> UIComponent instance represented by this markup. ..."

LU> This mean that the tag is translated from this:

LU> <meter jsf:id="meter2" min="#{bean.min}" max="#{bean.max}"
LU> value="350">350 degrees</meter>

LU> to this:

LU> <jsf:element pt:elementName="meter" id="meter2" min="#{bean.min}"
LU> max="#{bean.max}" value="350">350 degrees</jsf:element>

LU> Take a look at what happened to min, max and value
LU> attributes. Applying the rule written in the spec, the attributes
LU> are copied to the component attribute map. According to the spec,
LU> the resulting output will be this:

LU> <meter id="meter2">350 degrees</meter>

LU> Where are the attributes? in the component attribute map like the
LU> spec says. The renderkit javadoc of javax.faces.passthrough.Element
LU> doesn't mention anything about process the attributes in attribute
LU> map. What the user expect is something like this:

LU> <meter id="meter2" min="1" max="400" value="350">350 degrees</meter>

LU> But trying the example with Mojarra 2.2.6 or earlier, it works as
LU> the user expect. How? I did a black box test and it seems the
LU> attributes are copied somehow into the passthrough attribute map, so
LU> once the attributes are not rendered and the tag is closed, they are
LU> rendered as passthrough attributes. It is clear the intention, so I
LU> just fixed it in MyFaces, but the problem is a behavior like that
LU> needs to be documented in TagDecorator.

LU> The solution applied in MyFaces was add the necessary lines in
LU> TagDecorator to duplicate the attribute so now the final component
LU> looks like this:

LU> <jsf:element pt:elementName="meter" id="meter2" min="#{bean.min}"
LU> p:min="#{bean.min}" max="#{bean.max}" p:max="#{bean.max}"
LU> value="350" p:value="350">350 degrees</jsf:element>

LU> It is not the best we can do, since the renderer never changes for
LU> the component and the attributes of jsf:element can be defined it
LU> could be better to set the remaining attributes in the passthrough
LU> attribute map by default, but it will work well in any case and the
LU> overhead is minimal if PSS algorithm is properly implemented.

LU> The second problem is related to the attributes declared for
LU> jsf:element. The taglib javadoc of jsf:element has these
LU> attributes:

LU> * onclick
LU> * ondblclick
LU> * onmousedown
LU> * onmouseup
LU> * onmouseover
LU> * onmousemove
LU> * onmouseout
LU> * onkeypress
LU> * onkeydown
LU> * onkeyup

LU> The same javadoc says something like this too:

LU> "... The component that backs this element must implement
LU> javax.faces.component.behavior.ClientBehaviorHolder and return
LU> "click" from its getDefaultEventName() method. The list of events
LU> returned from its getEventNames() method must include the "on*"
LU> attributes below, ommitting the leading "on". ..."

LU> That's ok. Now try something like this:

LU> <div jsf:id="box1">
LU> <f:ajax render="..." event="click"/>
LU> </div>

LU> It doesn't work in Mojarra 2.2.6 and earlier versions. I think
LU> according to the spec documentation a case like the previous one
LU> should work, but it gets my attention the fact that the list of
LU> attributes that are subject to be target of client behavior are
LU> fixed. Please note the behavior of these attributes are quite
LU> predictable. It should be something that allows you to customize
LU> this part, but at least the following attributes should be there
LU> too:

LU> * onload (supported by <body>, <frame>, <frameset>, <iframe>, <img>,
LU> <input type="image">, <link>, <script>, <style>)
LU> * onunload (supported by <body>, <frameset>)

LU> Theoretically it doesn't matter if all valid names for html event
LU> are part of jsf:element. I have added onload/onunload in MyFaces
LU> 2.2.2, since it is quite easy to do so and it doesn't affect
LU> anything.

LU> regards,

LU> Leonardo Uribe

-- 
| edward.burns_at_oracle.com | office: +1 407 458 0017
|  1 Work Days Til JavaLand 2014
| 31 Work Days til JAX 2014