users@javaserverfaces-spec-public.java.net

[jsr344-experts mirror] [jsr344-experts] Re: Re: Re: Re: Re: [1089-HTML5-data-*attributes] PROPOSAL

From: Blake Sullivan <blake.sullivan_at_oracle.com>
Date: Tue, 22 May 2012 10:01:42 -0700

I agree with all of this except for the specifics of this part:

    Finally, all comes to several ways to pass data-* attributes and
    merging them before generating the HTML tag. The easy way
    <f:dataAttribute name="..." value="..."/>. The Java way
    <f:dataAttribute value="#{bean.map}"/>. The "jQuery" / "Javascript"
    way <f:dataAttribute value="{json}" />. And with no limit
    <f:dataAttribute value="#{bean.json}" />.

I would prefer not to overload <f:dataAttribute> to specify the entire
Map if no "name" attribute is supplied. Rather, I would prefer that we
add a "dataAttributes" attribute to UIComponents supporting this
feature. Since not all UIComponents render DOM, this feature would not
be available on all UIComponents.

Like all mutable collections, we will want to specify that the Map
passed in is not live.

As for support for simple inline specification of Maps and Arrays, I
believe that should be its own issue. We would want to standardize
whatever behavior we decide upon across any Map, Collection, or List
attributes. That said, I believe we want to consider the following:

1) We want to make sure that we really do want to use JSON syntax for this

2) For performance reasons, we want place the parsing code in the
TagHandler/Tag. This means that

<f:dataAttribute name="myMapKey" value="{json}"/> and <f:dataAttribute
name="myMapKey" value="#{bean.map}"/> are valid, but <f:dataAttribute
name="myMapKey" value="#{bean.json}"/> is not since it would requires
the UIComponent to parse the JSON.

3) We need to consider backwards compatibility, specifically

<f:dataAttribute name="myJsonKey" value="[true]"/>

vs

<f:dataAttribute name="myNonJsonKey" value="[foo]"/>

If the page author meant "[foo]" rather than String[]{foo}, she will be sad.

This should not be a problem for attributes for which the type is known,
since attributes that support Maps and Collections, likely do not
support Strings as well, so there is no ambiguity. This leaves
<f:attribute> and <f:dataAttribute>. We have a few choices there:

a) Ignore the issue
b) Try and parse as JSON and only parse as String if the JSON parse
doesn't succeed
c) Require escaping to indicate the String case
d) Add a type attribute to <f:attribute> and <f:dataAttribute> and
either require that "java.lang.String" (or maybe just "String") or
"json" be used to identify which form we want.

I would go for d) where if the value attribute is surrounded by either
"[]" or "{}" we assume json unless the "type" attribute is specified.
This is theoretically not completely backwards compatible, but is what
most page authors would want. It also nicely addresses issues with
<f:attribute> only supporting Strings. I would actually go further and
state that if the "name" of the <f:attribute> duplicates the name of a
know attribute on its UIComponent, the type is assumed to be the type of
that attribute.

We should also keep in mind that adding this feature will involve some
design time work

-- Blake Sullivan

On 5/22/12 8:11 AM, Andy Schwartz wrote:
> Gang -
>
> Some more thoughts from Paul:
>
>> Hi there,
>>
>> If you go with a new tag like <f:dataAttribute>, I agree you should
>> keep as minimal attributes as possible. Like a "value" one that
>> support anything (String, JSON, Map, EL, ...) and eventually a "name"
>> one to create a pair key/value.
>>
>> About precedence, I think the final purpose is to populate a
>> Map<String, String> where the key is the data-* name and the value is
>> the plain text value that will be put on the generated HTML tag. So
>> if a JSF component has several <f:dataAttribute>, just read them from
>> the first one to the last one and put their values on the Map,
>> overriding existing keys without question. This way, you authorized
>> users to easily do whatever they want.
>>
>> For example, the first <f:dataAttribute> can be using JSON with the
>> default configuration for all data-* attributes. Then, for some
>> particuliar JSF components, you can add some <f:dataAttribute
>> name="..." value="..."> to override some data-* attributes in this
>> case. So it would be a merge with no errors. Quite easy, quite
>> powerfull.
>>
>> About JSON versus Map, I understand because Java rocks :). I think
>> the best way should be to support both, it shouldn't be that hard (I
>> guess...). One strong point for JSON is that you can write it
>> directly in you XHTML page, not sure you can do it with a Map.
>>
>> jQuery UI + EL comes into action for example when you use REST or CDI
>> producers to serve your JSON configuration for jQuery UI widgets so
>> you can retrieve it using EL in your JSF components (the ones that
>> will generate the widgets).
>>
>> Finally, all comes to several ways to pass data-* attributes and
>> merging them before generating the HTML tag. The easy way
>> <f:dataAttribute name="..." value="..."/>. The Java way
>> <f:dataAttribute value="#{bean.map}"/>. The "jQuery" / "Javascript"
>> way <f:dataAttribute value="{json}" />. And with no limit
>> <f:dataAttribute value="#{bean.json}" />.
>>
>> Regards,
>>
>> Paul.
>
>
> Andy
>