users@javaserverfaces-spec-public.java.net

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

From: Frank Caputo <frank_at_frankcaputo.de>
Date: Tue, 22 May 2012 22:39:39 +0200

Hi EG,

I had similar thoughts about HTML5.

HTML5 is DTD-less and supposed to change quickly. To allow this agility, we should have 2 things:

1) render through unknown attributes
2) have a generic dynamic element

Explanation:

1) All attributes not handled by a component should be simply rendered out as they are. Eg. h:inputText doesn't know the attribute placeholder.

<h:inputText value="#{foo.bar}" placeholder="foo"/> would be rendered as <input type="text" value="" placeholder="foo"/>

This way new attributes in HTML5 are no longer a problem (this would also be fine for all those data-xxx attributes ;-))

If the value of an unknown attribute is null or "", don't render it.

Maybe we could override attributes. Eg. h:inputText doesn't have the attribute type, but the renderer renders it.

<h:inputText value="#{foo.bar}" type="email"/> would be rendered as <input type="email" value=""/> because the unknown attribute overrides it.

The type attribute is just a hint for the client (eg. to change the keyboard layout) while it doesn't change anything on the server.

UIComponentBase should provide a Map of all unknown attributes to the renderer.


2) A UIComponent which could represent any HTML tag would be very helpful, eg. if one wants to render anything else but a div or span conditionally or have it in the render list of a partial response. We should add this functionality to h:panelGroup. We could either deprecate the layout attribute and add a new one for the tag name or enhance it to simply hold the tag name.

<h:panelGroup layout="ul" type="disc" id="foo"/> would be rendered as <ul type="disc" id="foo"></ul> if we would also have 1).

We could also enhance the facelet parser to let us have tags like <ul type="disc" id="foo" jsfc="h:panelGroup"></ul> which handles jsfc="h:panelGroup" specially and converts it to <h:panelGroup layout="ul" type="disc" id="foo"/> using the tag name for the attribute layout.


I think, that both features provide pretty much HTML5 functionality, because most of them are client side. The only one making my head aching is the form attribute of the input elements (http://www.html5rocks.com/en/tutorials/forms/html5forms/#toc-inputs-attributes-attributes).

Another benefit is the ability to support browser specific tags and attributes which makes sense in intranet applications.

It would also increase the acceptance for HTML developers, who are often unhappy with not letting them do what they want when they must use JSF.


Frank

On 22.05.2012, at 17:34, Imre Oßwald <ioss_at_pmx.jevelopers.com> wrote:

> Hi
>
> Why limit this to "data" attributes?
>
> I suggest we add a more general <f:attributes> or <f:attribute values="…"> (I prefer the extra one), which should be able to set any attribute-value(s) on its parent tag.
> Apart from being in line with <f:attribute> and more "HTML5-changes-safe"/HTML-agnostic by not limiting it to 'data-*', it could be a nice addition for the authoring of composite-components.
>
> We might also want to consider not only to be able to set arbitrary attributes on components, but also to just render them, as I am not sure we "always" want to be late when new attributes are added to HTML5 (as for: role, aria-*, contenteditable, etc..., on* [I counted 50+ onxxx event handler attributes the last time I visited the HTML5 specs])
>
> <f:attributes value(s?)="#{el.to.map}" /> would set the attributes defined by the keys of the map with the values of the map on the parent component.
> <f:attributes name="data" value="#{el.to.map}" /> would be like the proposed <f:dataAttributes value="#{el.to.map}" />
>
> If used with json, it should be possible to also add the "value" as the content of the tag, as it is much easier to write json outside of an attribute (especially if we write 'true' json, where the property names have to be quoted or if one wants to have json as the attribute value (to avoid escaping-hell a bit))
> so instead of: <f:attributes values="{'data': {'toggle':true, 'duration': #{my.animationSettings.toggleDuration}, 'object':'{\"one\":\"A\",\"two\":\"B\",\"three\":\"C\"}' }, 'role': 'banner'}" /> allow for:
>
> <f:attributes>
> {
> 'data': {
> 'toggle': true,
> 'duration': #{my.animationSettings.toggleDuration}
> 'object': '{"one":"A", "two": "B", "three": "C"}'
> },
> 'role': 'banner',
> }
> </f:attributes>
>
> For composite-components we would gain the possibility to copy (all) attributes used on the component into the components of the composite (and even give us a way to "correctly" support unset attributes ;) ).
> Even if, we don't add some sort of "filter", using an EL one could filter the #{cc.attrs} map.
> This should probably get some counterpart in the interface section:
>
> <cc:interface>
> <cc:attributes var="attrsJS" name/select/filter="on(.*)"/>
> <cc:attributes var="attrsData" name/select/filter="data-(.*)"/>
> <!-- or -->
> <cc:attributes name/select/filter="data-(.*)" targets="T2"/>
> </cc:interface>
>
> <cc:implementation>
> <h:someTag title="not using cc:attributes 'filter'">
> <f:attributes value="#{my:mapselect(cc.attrs, 'aria-*')}"/>
> <h:someTag ......>
> <f:attributes value="#{attrsJS}"/>
> </h:someTag>
> <h:someTag2 id="T2"…….>
> <f:attributes value="#{attrsData}"/>
> </h:someTag2>
> </cc:implementation>
>
>
>>>
>>> Would we support multiple <f:dataAttributes> tags for a single
>>> component? For example, in this case:
>>>
>>> <f:dataAttributes value="#{foo.bonusDataAttrs}">
>>> <f:dataAttributes value="#{bar.morebonusDataAttrs}">
>>>
>>> Do we merge the maps? Last one wins? Unsupported?
>>
>> merge
>
> +1 for merge (Last one wins)
>
>>> If we go with two tags:
>>>
>>> <f:dataAttributes value="#{foo.bonusDataAttrs}">
>>> <f:dataAttribute name="foo" value="bar"/>
>>>
>>> I would think that we would spec this such that <f:dataAttribute> would
>>> win over the equivalent value in the EL-bound map.
>>
>> I would throw an exception if both are there (just like in Facelets:
>> you can't specify the same attribute twice, right?)
> (I guess with f:attribute you can?)
>
> -1 if we merge (see above) this should be considered merging
>
>
> Regards,
> Imre
>