users@javaserverfaces-spec-public.java.net

[jsr344-experts mirror] [jsr344-experts] Re: [1111-PassThruElements] DISCUSSION

From: Blake Sullivan <blake.sullivan_at_oracle.com>
Date: Fri, 08 Jun 2012 18:09:13 -0700

Hey Andy,

I agree that if JSF is going to address ease of use for HTML developers
we should make things work as naturally as possible for them while
making areas where we have conflicts (id handling) obvious as well.

While I was thinking about cases where we could perform the mapping
based on a single element and its attributes, and I think that mapping
complicated html table structures might be too far, we need to at least
address <option> and <select>.

Regarding :

>> 4) Should we support an explicit jsfc value for "use the default
>> component/renderer combinations). (yes c:jsfc="auto" or some such)
>
> I guess this is in the case where no other c: attribute is specified?
Yes. I was thinking of both the cases where we had no c: attribute and
c:jsfc="auto" seemed OK, but also some of cases where the developer has
a bare <div> or <span> and as a result, I was afraid that we wouldn't
always associate the page author's desired behavior. Now, given that I
was proposing that the Renderer take no real part in the rendering for
these HTML cases, it isn't clear what specifying a component would
really buy the page author (since it isn't clear how the Renderer would
have anything to decode either). I would fall back to "when in doubt,
don't add the feature" until we had some real use cases. Therefore, I
would start out without any jsfc attribute support.

I think that the question of how much the Renderers take part in
encoding is an area that we really need to think about. I agree that at
the very least, we likely want to be able to attach the ClientBehaviors
to the html content, as you showed in this example:

> <button jsf="h:commandButton">
> <f:ajax event="action" render="foo bar" execute="foo bar"/>
> </button>
I also see that a Renderer (though maybe not our run-of-the-mill
CommandButtonRenderer) needs to be involved for this example:

> <a href="#" c:action="#{el.to.action}">

In order to generate the client-side logic to fire this action through
PPR channel.

-- Blake Sullivan

On 6/8/12 4:23 PM, Andy Schwartz wrote:
> Changing the subject line to:
>
>> [1111-PassThruElements] DISCUSSION
>
> Since this seems to be more in line with that thread
>
> On 6/8/12 2:25 PM, Blake Sullivan wrote:
>> I think that the jsfc and passThru attribute discussions suggest two
>> different use cases:
>> 1) Annotating/overriding the output of the rendering of normal JSF
>> components (the passThru attribute case)
>> 2) Associating JSF components with HTML markup (the current jsfc case)
>>
>> For the second of these, I question what jsfc is bringing to the table
>
> Before jumping into Blake's comments, I wanted to go back to something
> that Ed mentioned earlier:
>
>> The jsfc feature crept in when we adopted Facelets, but it was never
>> given the true attention it deserved because not all EG members liked
>> it.
>
> Pretty sure I must have been one of the EG members who expressed
> doubts about this feature. My dislike for jsfc is not because I am
> opposed to the idea of facilitating HTML-centric page authoring, but
> because I don't actually think that jsfc helps nearly as much as it
> should. jsfc gives the impression that JSF/Facelets supports an
> HTML-centric authoring model. However, this model falls on its face
> way too quickly.
>
> Let's look at a simple example...
>
> Say a web designer codes the following bit of HTML:
>
> <input class="business-input" type="email">
>
> And also defines some styles for the ".business-input" CSS selector.
>
> The content looks great, yay!
>
> Time to hand off to the JSF app developer.
>
> The app developer wants to minimize the amount of changes to the page
> content and cleverly decides to use jsfc:
>
> <input class="business-input" type="email" value="#{el.to.value}
> jsfc="h:inputText">
>
> Yay! That was so easy!
>
> Oh, wait... you actually wanted the honor those style class and type
> attributes?
>
> Really?!?
>
> Because I was thinking that we would just stash those attributes away
> in the UIComponent's attribute map, never to be seen again.
>
> Sigh.
>
> As we look to enhance (or replace?) jsfc, I hope that we can keep this
> simple, yet fundamental, limitation in mind.
>
>
>> if we simply say that the presence of a component attribute implies
>> the presence of a component:
>> <div class="comp-div" data-foo="bar" c:rendered="#{el.to.rendered}">
>> If a page author wants to use template markup with the odd component,
>> this seems sufficient.
>
> One thing that that would be nice about using the presence of
> "component" (c: namespaced) attributes to drive component creation is
> that allows us to break away from the existing jsfc attribute handling
> contract (rather than break this).
>
>
>> The only slightly wonky bit has to do with ids, since the renderer
>> wants to own the id in order to apply the naming container rules.
>> For example, this could lead to trouble:
>>
>> <div*id="myDiv"* class="comp-div" data-foo="bar" c:rendered="#{el.to.rendered}">
>> For clarity reasons, I would propose that in cases where a component
>> is associated with the markup, we disallow id and suggest c:id instead:
>> <div*c:id="myDiv"* class="comp-div" data-foo="bar" c:rendered="#{el.to.rendered}">
>
> Ids are definitely weird. I do like the idea that this:
>
> <div c:id="foo">
>
> Would be the minimally sufficient content to force a <div> pass
> through element/component to be created. Nice.
>
>
>> Of course, if we aren't using jsfc, there is the question of how
>> associate the component (and renderer) with the markup.
>
> Right.
>
>
>> We could just require the use of JSFc and be done with it, but if
>> our goal is to make things as simple as possible for page authors,
>> why would we? It would seem preferable to use the markup to
>> associate the component for the page author by default.
>
> Yep. I would love to see something as simple as:
>
> <button c:action="#{el.to.action}>
>
> For creating a "command" button, without the page author being forced
> to explicitly declare jsfc="h:commandButton".
>
> Though this means that we need to design a mapping mechanism that the
> Facelets compiler could use to translate from arbitrary markup
> elements/attributes to corresponding JSF components/attributes. This
> mechanism would need to be configurable in such a way that the above
> <button> content could be re-mapped from h:commandButton to an
> equivalent 3rd party button component.
>
>
>> If the page author wants a different component, she can use the
>> jsfc attribute (which maybe should be c:jsfc to do so).
>>
>> That actually leads to four more questions (with my opinions)
>> 1) Should the Renderer actually be rendering anything (other than the
>> clientId) (probably not--the page author already specified her markup)
>
> I wonder whether there are cases where the Renderer is going to want
> to enhance the markup. For example, it would be nice if we had some
> way to translate:
>
> <a href="#" c:action="#{el.to.action}">
>
> Into a "command" link, but that would require rendering some
> JavaScript code to do the submit.
>
>> 2) Should the non-component attributes be present on the component
>> instance (as passThru attributes?) (yes)
>
> Yep, this is key. Though wondering whether there are cases where we
> would want to allow mappings from HTML attributes to component
> attributes to be performed at Facelets compilation time.
>
>> 3) If we are already associating the html markup with the components,
>> should we work harder to map the HTML attributes to component
>> attributes (yes)
>
> Oh. Yeah. Guess that was my reaction to #2. :-)
>
>> 4) Should we support an explicit jsfc value for "use the default
>> component/renderer combinations). (yes c:jsfc="auto" or some such)
>
> I guess this is in the case where no other c: attribute is specified?
>
>> Here is an example of component mapping:
>>
>> <input c:id="name" type=text" value="#{myBean.name}"
>> disabled="disabled"/>
>>
>> I think that a page author might reasonably expect that the markup
>> would have an associated inputText conponent with a valueExpression
>> that writes back into the managed bean and sets the disabled
>> attribute to true.
>
> Yep.
>
>> This does potentially cause problems if we are sticking the pass
>> through attributes into the the pass thru map on the component--we
>> don't want the same attribute in two different places. I would say
>> that only the "type" attribute ends up in the passThru map in this
>> case. The downside of this is that it is probably not clear which
>> attributes should end up in the passThru map vs. being consumed.
>> This can also cause backwards compatibility problems if we add a
>> component attribute at a later point in time and would like to map it
>> from HTML.... That blows. I change my mind--I would say that all
>> non-explicit component attributes populate the passThru map but the
>> attributes are not bidirectional with the component attributes.
>
> Need to think about this some more.
>
> If we are hoping to tackle this area, we probably need to start by
> trying to identify the range of use cases that we hope to cover.
> Simple div/input/button cases are one thing. What about more complex
> components - eg. tables, or components that have no equivalent in HTML
> land? How far do we hope to take this?
>
> BTW, another way to remove complexity from the page content would be
> to make it easier to move component configuration to Java code.
> Thinking particularly about being able to move verbose JSF markup like:
>
> <button jsf="h:commandButton">
> <f:ajax event="action" render="foo bar" execute="foo bar"/>
> </button>
>
> Out of the page.
>
> Sure, this is possible with component bindings:
>
> <button jsfc="h:commandButton" binding="#{el.to.component}">
>
> However, JSF's component binding mechanism is too complex/too easy to
> get wrong. I'm thinking that there is some way that we could do this
> that:
>
> - Would not require the use of EL expressions.
> - Would automatically ensure that dynamically configured components do
> not end up in an inappropriate scope (eg. no session scope UIComponents)
>
> Also thinking that more fluent Java APIs for UIComponents, Converters,
> Validaters, Behaviors would go a long way to simplifying this.
>
> Andy
>
>>
>> -- Blake Sullivan
>>
>
>