Hi Andy,
Thanks for reading through my long email and for the comments! :-)
Sorry I wasn't able to follow up on this last week...
sure, took me a while as well ;)
In the initial non-generic/Ajax-specific design we did have
assumptions
based on the component type - ie. <f:ajax> only supported "action"
events for command components and "valueChange" events for
editableValueHolders. This was awful - and one of the main reasons why
we decided to move forward with the generic Behavior solution.
With the current solution, the component identifies the set of supported
events as well as the default event via the ClientBehaviorHolder
interface. This allows ClientBehavior implementations (such as
AjaxBehavior) to avoid making assumptions based on the component type,
which is important for interoperability - ie. this allows us to write
ClientBehavior implementations which are not specific to a known set of
components - but can work with arbitrary components from different
component providers (eg. RichFaces, IceFaces, Trinidad, ADF Faces, etc...).
ok, of course - sorry for my ignorance about this API. I saw it - but
I didn't draw the right conclusions. With this, I fully agree with
you.
As you point out, however, the component renderer does not currently
know whether a ClientBehavior or ClientBehaviors attached to such events
are capable of producing fallback content. So, if we want to support
fallback content rendering in a generic way, we could add two new
methods to ClientBehavior:
1. public boolean isFallbackAvailable()
2. public void renderFallback(BehaviorContext)
I am ok with this now as well.
If it is too late to get something like this in for 2.0 - ie. if we
cannot add these two methods to ClientBehavior, then we can still solve
this problem in 2.1 by introducing a FallbackClientBehavior interface.
This means that renderers will need to do an "instanceof
FallbackClientBehavior" test when trying to determine whether fallback
content is available, but this seems reasonable to me.
better if we had it in 2.0 of course.
> in this case, we would really need to provide something in the
spec
> which checks if javascript is enabled. Can we really still do this for
> 2.0?
>
I know that the 2.0 spec has been handed off to the JCP - not sure how
much leeway we have to add new APIs at this point. Were you thinking of
new methods on FacesContext? Perhaps something like:
- public boolean isClientScriptingDisabled()
- public void setClientScriptingDisabled()
This might be useful even if we did not provide any automatic detection
for the disabled scripting case, since it would at least provide a
standard way for server-side code (components/renderers/behaviors) to
easily determine whether to script-free content is required.
I do think it is possible to do everything that we discussed here in
2.1. If it is too late to support this in 2.0, perhaps we should add
"disabled JavaScript support" to our 2.1 feature list - not just for
ClientBehavior/AjaxBehavior - but for the more general
<h:commandButton>/<h:commandLink> case as well.
>
> ok, now this is not so extremely easy. What we do in cs-JSF is we have
> a noscript tag - in this noscript tag, we render content which
> displays a modal dialog, telling the user that javascript is disabled
> and that he is forwarded to a javascript-free version of the page.
>
Just curious - how do you do the forward?
the user has to explicitly say "ok" in the dialog - there is nothing
automatic of course if JavaScript is disabled.
> I don't see how we can easily do the same in the spec - what
we could
> do is we could provide some information in the faces-messages section
> of the page including a link. This information would only be rendered
> in a noscript environment and - on clicking the link - would forward
> the user to the script-free version of the page.
>
Yeah - seems like something along these lines would work. Thanks for
suggesting this solution!
We could consider encapsulating this in a "noscript" component that
renders the appropriate content.
Right. If we provide standard APIs for tracking the disabled
scripting
state (eg. FacesContext is/setClientScriptingDisabled()), then we could
simply leave it up to the app developer to figure out when to call
setClientScriptingDisabled(true), at least for the moment. Of course,
it would be good to provide a standard mechanism for automatically
detecting the disabled scripting scenario, though I imagine this would
need to wait until 2.1.
yes, probably - but the API methods might make sense to be added right
now, if we also have the fallback-methods on the behaviours in place.
We could then say that an implementation _may_ support a
JavaScript-free fallback and JavaScript detection, and for the next
version, we could change this to _must_.
Two additional comments by Imre Osswald (via private mail, he reads
the mailing-list, but can of course not post):
- 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.
- instead of rendering a faces-message allowing the user to switch to
the javascript-free version, we could always render the first page
javascript-free, and render a javascript-block which redirects to the
javascript-version (however, this would need an additional
page-rendering in 98+% of the cases for a new session). Also a very
interesting suggestion, but I personally believe we should optimize
for the javascript-enabled case, and not for the non-javascript case.
regards,
Martin