jsr344-experts@javaserverfaces-spec-public.java.net

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

From: Imre Oßwald <ioss_at_pmx.jevelopers.com>
Date: Tue, 22 May 2012 17:34:28 +0200

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