Hey Jeremy -
Thanks for the comments and for the link to the article on graceful
degradation/progressive enhancement - that was an excellent read!
I agree with comments that others have already made on this thread, in
particular:
- There is value in both approaches.
- One approach may be preferred over another based on the target user base.
- The choice of behavior should be an implementation detail of the
render kit.
- The spec should not preclude either approach.
Having said that, I do believe that there is value in providing the APIs
that we have discussed in this thread. While these APIs may be more
useful for folks who are implementing graceful degradation solutions, I
don't believe they interfere with progressive enhancement in any way, so
this still seems like a worthy addition to me.
Actually, the ClientBehavior fallback APIs may be useful for progressive
enhancement-based renderers. In the graceful degradation case, an
input/select renderer that wants to enable ClientBehavior-provided
fallback content would:
- Check to see whether JavaScript is disabled
(FacesContext.isClientScriptingDisabled())
- If so, check to see whether fallback content is available
(ClientBehavior.isFallbackAvailable())
- If available, ask the ClientBehavior to render its fallback content
(ClientBehavior.renderFallback())
The progressive enhancement approach would look something like:
- Don't bother checking to see whether JavaScript is disabled.
- Always check to see whether fallback content is available.
- If available, always ask the ClientBehavior to render its fallback
content.
The end result is that in the progressive enhancement version of the
renderer, we always get the "Refresh" button (maybe f:ajax needs to
allow for an instance-specific name for the fallback button). Actually,
if the renderer wanted to clean up the UI in the case where JavaScript
is disabled, it could also render a script that hides the fallback
content on the client. (Though not sure whether this is considered good
form or not.)
Andy
Jeremy Grelle wrote On 4/13/2009 6:39 PM ET:
Sorry to be so late in chiming in here, but I thought I'd add my
two
cents since this is something we do think about quite a bit in the
Spring web tier as you guys have already alluded.
At a high level, you are talking about two fundamentally different
approaches: graceful degradation vs. progressive enhancement. I'll
avoid getting into too long of a theoretical diatribe on the relative
value of the two approaches and just refer to one of my preferred
sources for further explanation:
http://accessites.org/site/2007/02/graceful-degradation-progressive-enhan...
We take the progressive enhancement approach in Spring Faces and we
also generally advocate its use to the whole of the Spring community
whether using JSF or not. One of the main reasons we favor
progressive enhancement vs. graceful degradation is because it is
rather difficult to conclusively determine ahead of time whether
JavaScript is enabled or not, and even if you are able to do so
successfully, it still does not guarantee that the JavaScript
environment will be available and in a certain state throughout the
whole of the client-side interaction. Browsers in general (including
IE) have improved in this regard, but IE6 for example (which is still,
sadly, in fairly wide use) is particularly bad at recovering in the
case of a JavaScript error on the page, and the other browsers still
are not in any way fool-proof in this regard. In some cases, it's
really not the fault of the browsers, but of poorly behaving
components that don't respect the open nature of the JavaScript sandbox.
If you render all of the components on a page in such a way that they
assume the JavaScript environment is available and in a certain state,
and the script of one of the components higher up on the page fails
badly or perhaps just misbehaves in some way that causes those
assumptions to break, you are likely to end up with your users cursing
you for putting a broken UI in front of them. Alternatively, if you
render a fully functional DOM and add rich behavior progressively
(which may include mutating the foundation in some way, as we do with
the Spring Faces commandLink), even if something breaks your script,
you are much more likely to be left with components that still
function in the face of unexpected failures. Now, achieving the right
balance of CSS, HTML, and scripts such that the transition is not
jarring to the user (as Dan cited below) can be difficult, but it can
be done. We intentionally did not implement a smoother transition in
the Spring Faces demo app because we wanted it to be clear what is
happening when describing the progressive enhancement techniques to
our community.
Now is progressive enhancement the right approach for every single
application? Not necessarily. For many internal intranet
applications, which I think right now are still the sweet spot for
JSF, an approach that assumes more about the user's environment is
perfectly acceptable. But I for one am more interested in expanding
the possibilities of JSF being used to create public facing
applications that reach the widest possible audience of users. To do
that, IMHO, a functional HTML foundation should not be a fallback, but
rather the default.
I am generally not in favor of baking either approach directly into
the JSF APIs (though note that when using progressive enhancement,
there is usually no need to do so in the first place). I would love
to see a progressive enhancement approach taken in the basic default
components (most notably commandLink), but I'm not sure that
necessarily belongs in the spec either as it is more of an
implementation detail.
Thanks,
Jeremy
On Apr 13, 2009, at 2:22 AM, Dan Allen wrote:
>
>
> - potentially, every command-link could be rendered as an <input
> type="submit">, and then some additional javascript is rendered which
> makes this look and act like a link: a very interesting suggestion,
> cause it would mean we would not need any javascript detection at all!
> However, I do see some backwards compatibility issues.
>
> I don't want to interrupt a good discussion, so just take note of my
> comment here. Styling buttons is not always reliable. Some browsers
> ignore styles completely, so generally I won't recommend this
> approach. Spring Faces renders a button first and then swaps in a
> link if JavaScript is available (by using JavaScript). I was
> impressed by the idea, but a non-technical user noticed the "flash"
> it creates in some browsers that don't execute DOM manipulation fast
> enough. Therefore, I like the idea of deciding up front of a browser
> is going to support JavaScript or not and then choose the most
> optimal rendering from then on out (i.e., render normally once it's
> determined that JavaScript is enabled rather than using these hacks
> on every request).
>
> -Dan
>
> --
> Dan Allen
> Senior Software Engineer, Red Hat | Author of Seam in Action
>
>
http://mojavelinux.com
>
http://mojavelinux.com/seaminaction
>
http://in.relation.to/Bloggers/Dan
>
> NOTE: While I make a strong effort to keep up with my email on a daily
> basis, personal or other work matters can sometimes keep me away
> from my email. If you contact me, but don't hear back for more than a
> week,
> it is very likely that I am excessively backlogged or the message was
> caught in the spam filters. Please don't hesitate to resend a
> message if
> you feel that it did not reach my attention.