Hi,
Am 27.03.2014 um 12:45 schrieb Leonardo Uribe <lu4242_at_gmail.com>:
> 2. Use jsf:binding in Mojarra does not work, but it is not in the
> documentation of jsf:element. But the same is true for id attribute and
> these attributes comes from UIComponentBase. This is a bug in Mojarra and
> should be fixed.
binding indeed doesn’t work. I think, PassThroughElementComponentHandler should work more like ComponentTagHandlerDelegateImpl. Did you already file a bug?
id works, though it is not documented.
We should add id, rendered, transient and binding to the documentation.
> 3. I have explained to Frank that in some cases http://xmlns.jcp.org/jsf
> put attributes into normal component attribute map but sometimes it is
> required to use the passthrough attribute map. "id", "binding", "rendered"
> and "transient" should not be put on passthrough attribute map, but other
> attributes should.
If you use the jsf namespace on the attributes correctly, you can easily control, into which map the attribute is put. We should not try to implement some magic which fixes user mistakes. No attribute makes it ever into both maps (see com.sun.faces.facelets.tag.DefaultTagDecorator.ElementConverter#convertTagAttribute).
> In conclusion we have these 3 cases:
>
> 1. Attributes with jsf namespace that should be put on passthrough
> attribute map.
>
> <div jsf:style="noprint">
> Hello World!
> </div>
This doesn’t make sense. Why don’t you simply use <div style="noprint“>…? But your example works in Mojarra, because PassthroughElement handles style and styleClass (which is not documented and so it shouldn’t work).
> 2. Attributes with jsf namespace that should be put on normal attribute map.
>
> <div jsf:binding="#{boxBean.box1}">
> Hello World!
> </div>
See above, this should be fixed. But I still want to stay with the behavior, that EVERY jsf:xxx attribute will be put on the normal attribute map.
> <input jsf:id="input" type="text" jsf:value="#{someBean.someValue}“/>
This works.
> 3. Attributes without any namespace that could overlap attributes in the
> normal component map that requires special treatement.
>
> <div jsf:binding="#{boxBean.box1}" onclick="alert('hello')">
> <f:ajax event="click" render="renderMe"/>
> Hello World!
> </div>
There is a clear rule for overlapping: passtrough attributes take precedence. I like that simple rule without any exceptions.
> What should we do? What's the ideal behavior?
>
> - First of all we need to recognize that in this case attributes marked with
> empty namespace and with jsf namespace behave the same. The only special
> property it has jsf namespace is that its presence in an attribute makes the
> tag susceptible to be converted.
>
> - If the attribute is declared by the component class, it should be added to
> the component attribute map.
>
> - If the attribute is declared by the component class, it should NOT be added
> to the passthrough attribute map.
>
> - If the attribute is NOT declared by the component class, it should be put
> on the passthrough attribute map.
>
> How can we detect if a component class has a property defined? there is no
> standard way to do that, but each JSF implementation has the code deep inside
> UIComponentBase implementation, specifically in the normal component
> attribute map. But that suppose a problem, because in the moment the default
> TagDecorator is active, there is not a component class yet. But the trick
> can be done with a new Rule, but it will not be easy.
This is impossible, because users are free to put whatever they want into both attributes maps. The implementation can’t decide, if the attribute in the attribute map should be there or it is just a mistake.
From my point of view, we have a really simple rule, saying that every jsf: attribute will be on the component attributes map and any other is on the passthrough attributes map.
> This strategy has the big advantage that the attributes are not duplicated, so
> the state size is not doubled.
As said before, attributes are not doubled (i can’t find it in the implementation).
> The objective is avoid changes in the spec if
> possible, so let's see what we can do.
I’ll answer your other mail with the proposed changes a bit later (hopefully this week).
Ciao Frank
>
> regards
>
> Leonardo
>
> 2014-03-25 2:12 GMT+01:00 Edward Burns <edward.burns_at_oracle.com>:
>>>>>>> On Mon, 24 Mar 2014 13:39:21 +0100, Leonardo Uribe <lu4242_at_gmail.com> said:
>>
>> LU> But the user has reported another more troublesome combination:
>>
>> LU> <li jsf:class="toclevel-1 tocsection-2"/>
>>
>> LU> According to the spec it should not work. The javadoc of
>> LU> javax.faces.view.facelets.TagDecorator
>> LU> says this (already mentioned before):
>>
>> LU> "... If the current attribute's namespace is http://xmlns.jcp.org/jsf,
>> LU> convertedTagAttribute's qualified name must be the current attribute's local
>> LU> name and convertedTagAttribute's namespace must be the empty string. This
>> LU> will have the effect of setting the current attribute as a proper property
>> LU> on the UIComponent instance represented by this markup. ..."
>>
>> LU> If the intention of jsf namespace is put the attribute into the
>> LU> attribute map, why that syntax should work, unless the attribute has
>> LU> been explicitly declared on jsf:element component.
>>
>> I haven't checked the code, but I expect the reason it works is due to
>> the old attribute/property transparency. First it looks for a
>> "setClass" method on the UIComponent instance. Failing to find it, it
>> calls UIComponent.getAttributes().put("class", "toclevel-1 tocsection-2").
>>
>> LU> I tried also this
>> LU> combination:
>>
>> LU> <div jsf:style="noprint">
>> LU> Hello World!
>> LU> </div>
>>
>> LU> It works again, but it shouldn't.
>>
>> Again, I expect this causes UIComponent.getAttributes().put("style",
>> "noprint").
>>
>> LU> But it is clear why it is an obvious combination. The same javadoc
>> LU> of TagDecorator detects any attribute with the namespace "jsf" and
>> LU> if it is found the tag is binded to a jsf:element component. The
>> LU> related line says this:
>>
>> LU> "... If one or more of the attributes of the tag argument are in the
>> LU> http://xmlns.jcp.org/jsf namespace, obtain a reference to decoratedTag as
>> LU> described in the following steps and iterate through the list of TagDecorator
>> LU> instances as described in the preceding step ..."
>>
>> Yes, that text is the catch-all that allows the whole passthru elements
>> feature to work.
>>
>> LU> In practice, it seems an attribute using "jsf" namespace should be
>> LU> added in both normal attribute map and passthrough attribute map. I
>> LU> can't detect any problem at the moment, because the logic in the
>> LU> default ResponseWriter keeps track of the rendered attributes, and
>> LU> as long as no logical attributes are copied, things will be
>> LU> fine. Here there is an example of the problem:
>>
>> LU> <div jsf:binding="#{boxBean.box1}">
>> LU> Hello World!
>> LU> </div>
>>
>> LU> In Mojarra this attribute is just ignored, so it doesn't work, but
>> LU> in MyFaces it works, but if the attributes are copied in both maps,
>> LU> this one will be a problem. So the algorithm should duplicate the
>> LU> attributes that are not reserved like "id", "binding", "rendered" or
>> LU> "transient".
>>
>> I would have to step through this in a debugger to authoritatively
>> comment on what the spec intent is here, and therefore to clearly define
>> what "in MyFaces it works" means in this case.
>>
>> LU> There are a couple of attributes that are implementation specific,
>> LU> but since they are not declared in the markup, they do not have the
>> LU> chance to be copied or overriden.
>>
>> I'd like to avoid having to do this.
>>
>> LU> It is curious this syntax does not work:
>>
>> LU> <div pt:style="noprint">
>> LU> Hello World!
>> LU> </div>
>>
>> LU> The tag is not converted into a jsf:element, so the compiler sees it as
>> LU> html markup.
>>
>> I would need to see to that namespace the pt: attribute prefix is
>> bound. If it is the xmlns.jcp.org pass through attribute namespace,
>> then it should work and that is a bug.
>>
>> LU> I do not see any other choice than force the copy to the passthrough
>> LU> attribute map of all attributes declared with jsf namespace. But I have
>> LU> to warn about a side effect over the state. If the attributes are copied
>> LU> twice, that means the state of that component is effectively doubled.
>> LU> If PSS is properly implemented, it will not have a significant effect
>> LU> over the state, because most of the time that part is not part of the
>> LU> "delta" state of the component.
>>
>> I must understand why the copy is necessary.
>>
>> Ed
>>
>> --
>> | edward.burns_at_oracle.com | office: +1 407 458 0017
>> | 0 Work Days Til JavaLand 2014
>> | 30 Work Days til JAX 2014
>