users@javaserverfaces-spec-public.java.net

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

From: Andy Schwartz <andy.schwartz_at_oracle.com>
Date: Thu, 24 May 2012 09:33:05 -0400

Woops, one minor correction:

> This minimally allows EL-binding to a Map<String>.

Map<String, Object>.

(The value needs to be Object rather than String since this map could
contain ValueExpressions.)

Andy

On 5/24/12 9:27 AM, Andy Schwartz wrote:
> Gang -
>
> Been thinking through our options for "pass-through" elements.
>
> Frank's original description/proposal:
>
>> 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).
>
> I like the idea, though an h:panelGroup-specific solution seems awkward.
>
> Frank also suggested this tweak:
>>
>> 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.
>
> Which would make this more convenient for web designers (or anyone who
> prefers to code in HTML).
>
> I still have concerns about the panelGroup-specific nature of this
> approach. Also, this assumes that we would change the behavior for
> unknown attributes to always pass through. As discussed earlier, this
> will be problematic for applications which rely on the existing
> behavior for unknown attributes (ie. added to the component's
> attribute map, but not passed through).
>
> Phil proposed an interesting refinement:
>
>> Could the idea of pass-though attributes also apply to components? Using the h:panelGroup to render a different output seems a little odd to me, but perhaps a specific prefix could be used for dynamic components, so:
>>
>> <h:panelGroup layout="ul" type="disc" id="foo"/>
>>
>> becomes:
>>
>> <d:ul type="disc" id="foo"/>
>>
>
> This is cool in that it is not specific to h:panelGroup. It also does
> not suffer from backwards compatibility issues, since we're off in a
> new namespace.
>
> The one downside is that this requires the use of a namespace. My
> guess is that a web designer is going to prefer something closer to:
>
>> <ul type="disc" id="foo" jsfc="h:panelGroup">
>
> Than:
>
>> <d:ul type="disc" id="foo"/>
>
> Yet another approach:
>
>> Another option would be to add a single generic component which
>> allows the element name to be specified as an attribute, eg:
>>
>> <h:element name="ul">
>
> The idea here is that <h:element> tag/component would be spec'ed such
> that all attributes (other than the attribute that specifies the
> element name) are passed through.
>
> The obvious downside is that folks who want to code HTML elements
> aren't going to want to be forced to use h:element any time a JSF
> component is required.
>
> Looking back at the above proposals, it seems that we want a solution
> that:
>
> 1. Allows web designers/HTML coders to author content using HTML
> elements - ie. no special namespace or element names.
> 2. Allows attributes to be passed through, preferably with no
> namespace requirement.
> 3. Provides some way to indicate that a JSF component needs to be
> created.
>
> This got me to thinking about possibly combining approaches.
>
> I think the ideal solution would be something like:
>
>> <ul type="disc" id="foo" jsfc="h:element">
>
> Where we would spec that the element name would be implicitly set as
> the h:element's element name attribute. (This is special behavior
> that doesn't currently exist for any jsfc usage.)
>
> I would be tempted to simplify further - eg. I would love it if we
> could use something closer to HTML's minimized boolean attribute form, eg:
>
>> <ul type="disc" id="foo" jsfc>
>
> Though:
>
> - This isn't a boolean attribute. And...
> - XML doesn't support this form.
>
> So that's out.
>
> Another option might be to introduce a magic jsfc value, eg:
>
>> <ul type="disc" id="foo" jsfc="true">
>
> Which automatically results in the creation of an "h:element"
> component with the element name properly configured and all attributes
> copied over/passed-through.
>
> Some form of this should be fairly simple to add to the
> spec/implement. And as Frank pointed out, is relevant to JSF 2.2's
> HTML5 goals since:
>
>
>> It has actually something to do with HTML5 because, if we had this generic element, we would also have all new HTML5 elements, which have only client side impact.
>
> Thoughts?
>
> Getting back to data-* and generic attribute pass through...
>
> For this case I actually prefer Phil's suggestion of using a namepsace
> prefix:
>
>> Anything prefixed with the 'd:' schema gets created as a dynamic pass-though component. Perhaps a prefix should also be used for unknown attributes to allow tooling some hints that breaking the facelet schema in this case is permitted.
>
> As I think that it is important to avoid blurring the lines between
> traditional attributes (that are stored in the component's attribute
> map but not passed through) and pass-through attributes for our
> existing component tags.
>
> This would require that we introduce a new namespace, eg:
>
>> xmlns:p="http://java.sun.com/jsf/passthru"
>
> And then use this on component tags that render content, eg:
>
>> <h:commandButton action="#{hr.giveAndyAPayRaise}" p:data-foo="bar"
>> p:some-non-data-pass-thru-attr="foobar"/>
>
> With seems like we've got the best of both worlds:
>
> - In cases where web designers just want to drop down to HTML, they
> can happily do this (and use jsfc="true").
> - In cases where JSF developers need to tack on some bonus attributes,
> they can happily do this in a clear/explicit and fairly concise way.
> (Or, well... let's just say it's more concise than f:dataAttribute.)
>
> Additionally, to address Paul's use case (arbitrary # of possibly
> dynamically determined bonus attributes), we could add one new
> non-namespaced attribute:
>
>> <h:commandButton passThruAttributes="#{foo.bonusAttrs}"/>
>
> This minimally allows EL-binding to a Map<String>.
>
> I think we'll need to argue more about whether we should:
>
> - Support JSON as a literal (inline) representation. And/or...
> - Support JSON as an accepted type in the EL-binding case.
>
> Though I kind of think that these questions are larger than the pass
> through attribute case. (For example, if we add JSON support for
> "passThruAttributes", should dataTable's value attribute provide
> similar support?)
>
> In any case, if we start by adding:
>
> - jsfc="true" (or jsfc="h:element") for pass-through elements
> - p:foo="bar" for pass-through attributes on existing (rendering)
> component tags.
> - passThruAttributes="#{foo.mapOfPassThroughAttributes}"
>
> We'll have come a long way towards improving our HTML5 story for JSF 2.2.
>
> Andy
>
> On 5/23/12 4:27 PM, Frank Caputo wrote:
>> On 23.05.2012, at 15:53, Andy Schwartz <andy.schwartz_at_oracle.com> wrote:
>>
>>
>>> On 5/22/12 11:11 PM, Phil Webb wrote:
>>>
>>>> Could the idea of pass-though attributes also apply to components? Using the h:panelGroup to render a different output seems a little odd to me, but perhaps a specific prefix could be used for dynamic components, so:
>>>>
>>>> <h:panelGroup layout="ul" type="disc" id="foo"/>
>>>>
>>>> becomes:
>>>>
>>>> <d:ui type="disc" id="foo"/>
>>>>
>>>> Anything prefixed with the 'd:' schema gets created as a dynamic pass-though component.
>>>>
>>> Interesting. Just to be sure... the "<d:ui>" in your example was meant to be "<d:ul>", right?
>>>
>>> Another option would be to add a single generic component which allows the element name to be specified as an attribute, eg:
>>>
>>> <h:element name="ul">
>>>
>>
>> This would also be ok for me.
>>
>>
>>> Not quite as nifty as your namespace-based approach I suppose, though I prefer either of these over mucking with <h:panelGroup>.
>>>
>>> (I agree with Brian that this looks like it should be tackled as a separate issue.)
>>>
>>
>> It has definitely nothing to do with the attributes but would be only a little enhancement without the render through attributes.
>>
>> It has actually something to do with HTML5 because, if we had this generic element, we would also have all new HTML5 elements, which have only client side impact.
>>
>>
>>>> Perhaps a prefix should also be used for unknown attributes to allow tooling some hints that breaking the facelet schema in this case is permitted.
>>>>
>>>> If pass-though attributes do become part of the spec they should probably be opt-in. There may be existing code currently using additional attributes for their own ends. I believe that UIComponent.getValueExpression() can be used to get any attribute, so some developers may have attributes in their XHTML that they use currently but they absolutely do not want exposed to the browser.
>>>>
>>>>
>>> Yep. I have the same concern. Currently Facelets dumps unspecified attributes into the UIComponent's attributes map. Existing apps are using this for their own purposes and would be negatively impacted if we simply started passing all of these through to the client.
>>>
>>> I like your namespaced attribute recommendation.
>>>
>>> I really like the idea of tackling the problem generically, rather than limiting the focus to the data-* attributes.
>>>
>>> I also like Frank's suggestion that we allow this to be used to override attributes that are rendered by the Renderer:
>>>
>>>
>>>> <h:inputText value="#{foo.bar}" type="email"/> would be rendered as <input type="email" value=""/> because the unknown attribute overrides it.
>>>>
>>> Though we'll want to find a way to hide this complexity from Renderer implementations - ie. ideally Renderers would not need to explicitly check for the presence of an attribute override every time an attribute is written to the ResponseWriter. I think that this means that we'll want this complexity to live in the ResponseWriter. It's possible that doing so will have some implications for the specification.
>>>
>>
>> +1, that way, I added support for placeholder and data-xxx attributes in my last project.
>>
>>
>>> One case that does not seem to be covered by the pass-through attribute approach is the original case that Paul raised - ie. the ability to specify an arbitrary # of possibly dynamically determined bonus attributes. If we want to tackle this case, seems like we would still be stuck with adding some Map<String, Object>-based attribute, eg:
>>>
>>> <h:panelGroup passThruAttributes="#{foo.bonusAttrs}"/>
>>>
>>
>> +1, my proposal was just to ease life of HTML developers, who don't want to put their attributes into a backing bean, because often they don't have the skills to do so. And the more complex the clients get the more specialized the frontend developers will be and the less they know Java.
>>
>>
>> Cheers,
>> Frank
>>
>>
>>> Andy
>>>
>>>
>>>
>>
>>
>