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

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

From: Blake Sullivan <blake.sullivan_at_oracle.com>
Date: Mon, 11 Jun 2012 09:45:47 -0700

Frank,

[Blake wrote]
> 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.
>
[Frank wrote]
> In this example href in the passtrough map must not override the href
> of the renderer. I propose the following behavior:
>

I'm not sure that I agree with this statement for several reasons:

1) I think it would be confusing to have two different behaviors
2) How does the page author know which form to use? Is she supposed to
try the normal attribute form first and then try the other if that
doesn't work? What happens if the Renderer changes its implementation
in the future?
3) In this particular case, why mustn't the page author's href override
the Renderer's use of href? Or to put this differently, why does the
(presumably) HtmlCommandLinkRenderer need to own the href in this case?
We can attach our Javascript without owning href.

One part that might not be clear (OK, it isn't clear at all :) ) is that
when I originally wrote "(though maybe not our run-of-the-mill
CommandButtonRenderer)," I meant that for these HTML cases, we might
want to have special Renderers that attempt to modify the page-author's
specified HTML as little as possible. I believe that we really have to
trust the page author in this case. In cases where there is clear
conflict, like the id attribute, I think that we need to be very clear
at design-time what the problem is.

-- Blake Sullivan

On 6/10/12 7:48 AM, Frank Caputo wrote:
> Hi Blake and Andy,
>
> Am 09.06.2012 um 03:09 schrieb Blake Sullivan:
>
>> 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.
>
> In this example href in the passtrough map must not override the href
> of the renderer. I propose the following behavior:
>
> Having a c:xxx attribute turns all other attributes into passthrough
> attributes which never override attributes automatically rendered by
> the renderer. If we want to override attributes we must use
> f:passThroughAttribute. Saying this, we must be able to flag
> passthrough attributes to override or not. E.g:
>
> <f:passThroughAttribute name="href" value="#" override="true"/>
>
> I propose override is false by default.
>
> IMO it is OK to have not the smallest syntax, if the developer want's
> to change default behavior. This might be more robust.
>
>
> Cheers,
> Frank
>
>>
>> -- 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
>>>>
>>>
>>>
>>
>
> -
>
> Frank Caputo
> Johann-Mohr-Weg 24d
> 22763 Hamburg
>
> Mobil +49 177 61 61 81 3
> E-Mail info_at_frankcaputo.de <mailto:info_at_frankcaputo.de>
>