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

[jsr372-experts] Re: [jsr372-experts mirror] Re: Re: Re: Re: Re: Re: [JAVASERVERFACES_SPEC_PUBLIC-1423] Dynamic resource loading in ajax requests

From: Bauke Scholtz <balusc_at_gmail.com>
Date: Tue, 26 Jul 2016 10:11:08 +0200

Leo,

Please see the updated API proposal in
https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1423?focusedCommentId=392837


Is it clear that way?

Cheers, B

On Tue, Jul 26, 2016 at 8:16 AM, Leonardo Uribe <leonardo.uribe_at_irian.at>
wrote:

> Hi
>
> Use something like javax.faces.Resource sounds good. After all, what
> really matters is the scripts are loaded before perform the ajax operation
> and for stylesheet is the same (no matter where the stylesheet are loaded,
> preferred under <head> tag).
>
> regards,
>
> Leonardo Uribe
>
> 2016-07-26 0:12 GMT-05:00 Bauke Scholtz <balusc_at_gmail.com>:
>
>> Hi,
>>
>> Thank you for your thoughts. Definitely valid. I will take those into
>> account.
>>
>> How about javax.faces.Resource instead of javax.faces.ViewHead?
>>
>> Cheers, B
>>
>> On Tue, Jul 26, 2016, 02:31 Leonardo Uribe <leonardo.uribe_at_irian.at>
>> wrote:
>>
>>> Hi
>>>
>>> BS>> 1. No substantial changes in API/impl are necessary in order to
>>> discover
>>> BS>> newly added component resources provided that they are all added
>>> via
>>> BS>> UIViewRoot#addComponentResource().
>>>
>>> Yes, it looks good. Good idea to use UIViewRoot#processEvent() and
>>> PostRestoreStateEvent.
>>>
>>> The only thing to notice is the simplification done for a component
>>> resource
>>> in order to be added. I resume it in this sentence:
>>>
>>> "... If a component resource has "name" and optionally "library"
>>> property set
>>> and does not have children and
>>> ResourceHandler#getRendererTypeForResourceName(
>>> String resourceName) and getRendererType() is equals to
>>> 'javax.faces.resource.Script' ..."
>>>
>>> What I mean is the way how the simplification is done must be explicit
>>> in the
>>> spec. That also means the full algorithm must be somewhere in the
>>> javadoc or
>>> in the spec pdf, maybe adding some lines in JSF 2.3 section 13 Ajax
>>> Integration.
>>>
>>> I would like a general solution to the problem, but I think a
>>> simplification
>>> for only .js resources is also valid.
>>>
>>> BS>> 2. I would like to (re)use the currently unsupported <update
>>> BS>> id="javax.faces.ViewHead"> in jsf.js to perform adding of new
>>> component
>>> BS>> resources.
>>>
>>> Unfortunately here there is a problem. This has been already specified
>>> in the
>>> javascript documentation of jsf.ajax.response(request, context);
>>>
>>> "... If an <update> element is found in the response with the identifier
>>> javax.faces.ViewRoot:
>>>
>>> <update id="javax.faces.ViewRoot">
>>> <![CDATA[...]]>
>>> </update>
>>>
>>> Update the entire DOM replacing the appropriate head and/or body sections
>>> with the content from the response. ..."
>>>
>>> The hack done in MyFaces works because this part was specified, so I do
>>> not
>>> think it is a good idea to change that meaning. Instead, one way to fix
>>> the problem is adding the necessary methods to PartialResponseWriter, as
>>> suggested before. It is not pretty (update facelet-partialresponse .xsd,
>>> fix PartialResponseWriter, update section 13 ...), but I have not found
>>> another way to fix it yet.
>>>
>>> regards,
>>>
>>> Leonardo Uribe
>>>
>>>
>>> 2016-07-22 11:30 GMT-05:00 Bauke Scholtz <balusc_at_gmail.com>:
>>>
>>>> Hi,
>>>>
>>>> I posted a comment on
>>>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1423 with my
>>>> new findings and thoughts.
>>>>
>>>> In a nutshell:
>>>>
>>>> 1. No substantial changes in API/impl are necessary in order to
>>>> discover newly added component resources provided that they are all added
>>>> via UIViewRoot#addComponentResource().
>>>> 2. I would like to (re)use the currently unsupported <update
>>>> id="javax.faces.ViewHead"> in jsf.js to perform adding of new component
>>>> resources.
>>>>
>>>> Cheers, B
>>>>
>>>>
>>>> On Mon, Jul 4, 2016 at 8:06 PM, Leonardo Uribe <leonardo.uribe_at_irian.at
>>>> > wrote:
>>>>
>>>>> Hi
>>>>>
>>>>> BS>> As to "render target", isn't PartialViewContext#getRenderIds()
>>>>> sufficient
>>>>> BS>> for the task? This returns a mutable collection of client IDs
>>>>> which need
>>>>> BS>> to be updated on current partial request.
>>>>>
>>>>> I have been thinking about this for some time to see what's missing
>>>>> from the
>>>>> spec perspective, and the answer is no, getRenderIds() is not enough
>>>>> to do
>>>>> the job (in my personal opinion).
>>>>>
>>>>> The reason is getRenderIds() relies on the fact that it should be a
>>>>> html tag
>>>>> with an id rendered on the client markup that can be updated. If there
>>>>> is
>>>>> no html tag with id set, an ajax update will not work. Please note
>>>>> getRenderIds() works for most cases, but for <head> and <body> tags,
>>>>> both
>>>>> does not allow an id to be set. It is true that there is a solution
>>>>> updating
>>>>> the whole content, but the central point is there is a better solution
>>>>> that
>>>>> could be done with the changes proposed previously in this thread.
>>>>>
>>>>> In summary, the current algorithm for ajax has these weaknesses (sorry
>>>>> if
>>>>> you found this too repetitive):
>>>>>
>>>>> 1. Resource components added as part of a partial update requires to
>>>>> add some html markup inside a <head> or <body> tag, and both tags does
>>>>> not have
>>>>> an id set, and the current API doesn't help to do it without replace
>>>>> the whole tag.
>>>>> 2. If a new component is added, there is no html tag we can use to
>>>>> update it.
>>>>>
>>>>> The first case we have already discussed.
>>>>>
>>>>> The second one is more theoretical but goes far beyond what we have
>>>>> discussed.
>>>>> Anyway, just for clarity sake I'm going to describe it fully and give
>>>>> a
>>>>> possible solution.
>>>>>
>>>>> Think about this fragment:
>>>>>
>>>>> <h:panelGroup id="content" layout="block">
>>>>> <c:if test="#{bean.chooseSomething}">
>>>>> <h:outputScript name="script2.js"/>
>>>>> </c:if>
>>>>> <h:commandButton value="Update" actionListener="#{bean.check}">
>>>>> <f:ajax />
>>>>> </h:commandButton>
>>>>> </h:panelGroup>
>>>>>
>>>>> Now imagine that when an ajax request is triggered, the code inside
>>>>> bean.check() changes chooseSomething from false to true. The lifecycle
>>>>> looks
>>>>> like this:
>>>>>
>>>>> - Lifecycle Execute (....) invoke bean.check, change chooseSomething
>>>>> to true.
>>>>> - Call to vdl.buildView() refresh the whole component tree =>
>>>>> h:outputScript
>>>>> added and PostAddToViewEvent is triggered.
>>>>> - f:ajax requires h:commandButton to be rendered, so a partial update
>>>>> over the
>>>>> commandButton is activated.
>>>>>
>>>>> What's wrong with this? A new component (h:outputScript) was added on a
>>>>> partial request. But the component never had the chance to update
>>>>> itself, so
>>>>> the script was never updated. Ok, you can replace f:ajax with:
>>>>>
>>>>> <f:ajax render="content"/>
>>>>>
>>>>> Problem solved, but is all that really necessary? What if
>>>>> chooseSomething does
>>>>> not change? why update the content in that case?.
>>>>>
>>>>> Please note every component addition triggers a PostAddToViewEvent. It
>>>>> is
>>>>> possible to use that event to detect the change. Since the component
>>>>> is a new
>>>>> one, there is no id on the client side, but probably an ancestor could
>>>>> have an
>>>>> id set. The problem is the current algorithm does not have a standard
>>>>> way to
>>>>> check whether it has an id set on the client or not.
>>>>>
>>>>> But if a method like UIComponent.isClientIdRendered(...) exist, we
>>>>> could create
>>>>> an algorithm that recursively find the parent that needs to be
>>>>> rendered and
>>>>> include it into the current ajax request adding it to getRenderIds().
>>>>> In that
>>>>> sense, the algorithm could automatically find that "content" needs to
>>>>> be
>>>>> updated and activate the render automatically.
>>>>>
>>>>>
>>>>> Going back to the main topic, getRenderIds() relies on a logic that
>>>>> for each
>>>>> id there is an html markup counterpart. setRenderTargetComponent(...)
>>>>> and getTargetComponentsToRender(...) are different because the
>>>>> intention here
>>>>> is to say "... this (resource) component needs to be added for this
>>>>> target,
>>>>> the way how you want to update the client is up to you ...".
>>>>>
>>>>> regards,
>>>>>
>>>>> Leonardo
>>>>>
>>>>> 2016-07-01 13:01 GMT-05:00 Neil Griffin <neil.griffin_at_portletfaces.org
>>>>> >:
>>>>>
>>>>>> Kyle Stiemann will also be commenting on the following issue in JIRA:
>>>>>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1423
>>>>>>
>>>>>> Again, please click on the "watch" link in JIRA if you are
>>>>>> interested. Thanks.
>>>>>>
>>>>>> > On Jun 27, 2016, at 7:12 AM, Bauke Scholtz <balusc_at_gmail.com>
>>>>>> wrote:
>>>>>> >
>>>>>> > As to "render target", isn't PartialViewContext#getRenderIds()
>>>>>> sufficient for the task? This returns a mutable collection of client IDs
>>>>>> which need to be updated on current partial request.
>>>>>> >
>>>>>> > Cheers, B
>>>>>> >
>>>>>> >
>>>>>> > On Mon, Jun 27, 2016 at 11:56 AM, Leonardo Uribe <
>>>>>> leonardo.uribe_at_irian.at> wrote:
>>>>>> > Hi
>>>>>> >
>>>>>> > 2016-06-24 10:35 GMT+02:00 Bauke Scholtz <balusc_at_gmail.com>:
>>>>>> > encodePartial() looks OK.
>>>>>> >
>>>>>> > I only don't understand how RequestViewContext, setRenderTarget()
>>>>>> and getComponentsToRender() are useful as compared to
>>>>>> UIViewRoot#addComponentResource()/getComponentResources().
>>>>>> >
>>>>>> >
>>>>>> > I haven't found good names for those ones but I'll explain the
>>>>>> intention of them.
>>>>>> >
>>>>>> > setRenderTarget(...) is used to indicate a component inside a
>>>>>> specified target needs to be updated on the client in the current partial
>>>>>> request. In comparison, addComponentResource(...) is used to add the
>>>>>> component to the tree.
>>>>>> >
>>>>>> > I know both methods look similar but they are not the same. The
>>>>>> reason is addComponentResource(...) is used to affect the component tree,
>>>>>> so it will be called each time the component tree is build (initial state,
>>>>>> delta, ...), and setRenderTarget(...) is used as a flag to indicate how the
>>>>>> current partial request must be rendered. Add a resource could cause the
>>>>>> flag to be activated, but not every call to addComponentResource(...) cause
>>>>>> the flag to be activated.
>>>>>> >
>>>>>> > Maybe a better name could be setRenderTargetComponent(...)
>>>>>> >
>>>>>> > getComponentsToRender(...) returns the list of the components bound
>>>>>> to an specific target that needs to be rendered on the current ajax
>>>>>> request. in comparison UIViewRoot.getComponentResources(...) return all
>>>>>> components bound to an specific target in the view.
>>>>>> >
>>>>>> > Maybe a better name could be getTargetComponentsToRender(...)
>>>>>> >
>>>>>> > These two methods are in fact more bound to UIViewRoot than to
>>>>>> FacesContext, but the data they manage is "transient", which means the data
>>>>>> is discarded at the end of the request.
>>>>>> >
>>>>>> > I also don't understand "You can't use an eval block because the
>>>>>> encoding does not work correctly". Which encoding exactly is problematic?
>>>>>> (there's at least character encoding, html encoding and javascript encoding
>>>>>> involved). Why couldn't that part be fixed instead?
>>>>>> >
>>>>>> >
>>>>>> > If you have a block like this:
>>>>>> >
>>>>>> > <h:outputScript target="head">
>>>>>> > script2 = function(){
>>>>>> > alert("script2");
>>>>>> > }
>>>>>> > </h:outputScript>
>>>>>> >
>>>>>> > you could try to do in code something like this:
>>>>>> >
>>>>>> > prwriter.startEval(....);
>>>>>> > renderChildren(...);
>>>>>> > prwriter.endEval();
>>>>>> >
>>>>>> > I tried but it doesn't work because you need to encode it properly,
>>>>>> but since there is a ResponseWriter outside of your control, you can't
>>>>>> encapsulate the script without do some nasty hacks over
>>>>>> ResponseWriter/PartialResponseWriter.
>>>>>> >
>>>>>> > In this case eval(...) does not work, so we need to attach the node
>>>>>> (well, if we want to fix this use case, which I think we should).
>>>>>> >
>>>>>> > regards,
>>>>>> >
>>>>>> > Leonardo Uribe
>>>>>> >
>>>>>> > Cheers, B
>>>>>> >
>>>>>> > On Thu, Jun 23, 2016 at 2:45 PM, Leonardo Uribe <
>>>>>> leonardo.uribe_at_irian.at> wrote:
>>>>>> > Hi
>>>>>> >
>>>>>> > Since there is already a solution almost completed in MyFaces
>>>>>> (which an small sample
>>>>>> > done some time ago) I did a prototype to see how it works and try
>>>>>> to find other details
>>>>>> > that could give us a better idea about what to do.
>>>>>> >
>>>>>> > From spec perspective the relevant changes are:
>>>>>> >
>>>>>> > UIComponent: Add the following methods:
>>>>>> >
>>>>>> > public void encodePartial(FacesContext context) throws IOException
>>>>>> >
>>>>>> > Default implementation call startUpdate(), encodeAll(), endUpdate();
>>>>>> >
>>>>>> > UIComponentBase: Add the following methods:
>>>>>> >
>>>>>> > public void encodePartial(FacesContext context) throws IOException
>>>>>> >
>>>>>> > Default implementation if renderer found call
>>>>>> Renderer.encodePartial, otherwise call
>>>>>> > super.encodePartial(...)
>>>>>> >
>>>>>> > Renderer: Add the following methods:
>>>>>> >
>>>>>> > public void encodePartial(FacesContext context, UIComponent
>>>>>> component)
>>>>>> > throws IOException
>>>>>> >
>>>>>> > Default implementation call startUpdate(), encodeAll(), endUpdate();
>>>>>> >
>>>>>> > RequestViewContext: (it could be located in FacesContext)
>>>>>> >
>>>>>> > public void setRenderTarget(String target, boolean value,
>>>>>> > UIComponent component)
>>>>>> >
>>>>>> > public List<UIComponent> getComponentsToRender(String target);
>>>>>> > (it has an internal set to avoid duplicates, find a better name)
>>>>>> >
>>>>>> >
>>>>>> > The remaining tasks are implement encodePartial(...) for
>>>>>> h:outputScript,
>>>>>> > h:outputStylesheet, and update the implementation in
>>>>>> PartialViewContext to call
>>>>>> > encodePartial.
>>>>>> >
>>>>>> > This is a fragment of the generated response when the change
>>>>>> > is activated:
>>>>>> >
>>>>>> > <partial-response id="j_id__v_0"><changes><eval>
>>>>>> > <![CDATA[myfaces._impl.core._Runtime.loadScript(
>>>>>> > "/client-window-example/javax.faces.resource/script1.js.jsf", null,
>>>>>> null,
>>>>>> > "UTF-8", false);]]></eval><update id="content"><![CDATA[ ...
>>>>>> >
>>>>>> > The main page look like this:
>>>>>> >
>>>>>> > <h:commandLink id="page1" value="Page 1"
>>>>>> actionListener="#{ajaxContentBean.setPage1}">
>>>>>> > <f:ajax render=":content"/>
>>>>>> > </h:commandLink>
>>>>>> > ...
>>>>>> > <h:panelGroup id="content" layout="block">
>>>>>> > <ui:include src="#{ajaxContentBean.page}.xhtml" />
>>>>>> > </h:panelGroup>
>>>>>> >
>>>>>> > And the included page has something like this:
>>>>>> >
>>>>>> > <h:outputScript name="script1.js" target="head"/>
>>>>>> > <h:commandButton type="button" value="MSG" onclick="script1()"/>
>>>>>> >
>>>>>> > It works well for scripts but try to update something like this:
>>>>>> >
>>>>>> > <h:outputScript target="head">
>>>>>> > script2 = function(){
>>>>>> > alert("script2");
>>>>>> > }
>>>>>> > </h:outputScript>
>>>>>> >
>>>>>> > or this:
>>>>>> >
>>>>>> > <h:outputStylesheet name="style3.css"/> (target="head" is implicit)
>>>>>> >
>>>>>> > is the real problem. You can't use an eval block because the
>>>>>> encoding does not work
>>>>>> > correctly, so you really need to insert the DOM node. But the
>>>>>> current API in
>>>>>> > PartialResponseWriter is useless because head tag does not have an
>>>>>> id or name where you
>>>>>> > can grab.
>>>>>> >
>>>>>> > Ok, we can try to "make cheat" a little in this part and try:
>>>>>> >
>>>>>> > prwriter.startInsertAfter("javax.faces.ViewHead");
>>>>>> >
>>>>>> > but strictly speaking this should insert the html markup after
>>>>>> </head>, but we want
>>>>>> > the code inside. I just modified the js code to include it inside
>>>>>> in this case, but for
>>>>>> > a real implementation it is required to add some methods to
>>>>>> PartialResponseWriter like:
>>>>>> >
>>>>>> > public void startInsertFirst(String targetId) throws IOException
>>>>>> > public void startInsertLast(String targetId) throws IOException
>>>>>> >
>>>>>> > (find a better name, or maybe startInsertInsideAfter?, look in
>>>>>> another framework how
>>>>>> > they name this?)
>>>>>> >
>>>>>> > There is also another problem: How do you know you need to insert
>>>>>> the node instead of
>>>>>> > update it? The only clue is the node is processed specially in
>>>>>> PartialViewContext like
>>>>>> > this:
>>>>>> >
>>>>>> > List<UIComponent> componentsToRender =
>>>>>> rvc.getComponentsToRender("head");
>>>>>> >
>>>>>> > for (UIComponent resource: componentsToRender)
>>>>>> > {
>>>>>> > resource.encodePartial(_facesContext);
>>>>>> > }
>>>>>> >
>>>>>> > So, we need some flag or context attribute or something to indicate
>>>>>> we are attempting
>>>>>> > to include something new on the tree. Something like
>>>>>> JAVAX_FACES_INSERT_PARTIAL for
>>>>>> > example and something like JAVAX_FACES_UPDATE_TARGET, so the
>>>>>> Renderer in encodePartial
>>>>>> > can decide how to update the view.
>>>>>> >
>>>>>> > The partial response markup looks like this:
>>>>>> >
>>>>>> > <changes><insert><after id="javax.faces.ViewHead"><![CDATA[
>>>>>> > <script type="text/javascript">
>>>>>> > script2 = function(){
>>>>>> > alert("script2");
>>>>>> > }
>>>>>> > </script>]]></after></insert>
>>>>>> >
>>>>>> > It should be better
>>>>>> >
>>>>>> > <changes><insert><last id="javax.faces.ViewHead"><![CDATA[<script
>>>>>> type="text/javascript">
>>>>>> > script2 = function(){
>>>>>> > alert("script2");
>>>>>> > }
>>>>>> > </script>]]></last></insert>
>>>>>> >
>>>>>> > And that's it the proposal from MyFaces side. I think it is
>>>>>> flexible enough to allow the
>>>>>> > algorithm using "two lists comparison", but also enough to allow
>>>>>> the implementation
>>>>>> > inside MyFaces.
>>>>>> >
>>>>>> >
>>>>>> > But note the issue proposed here:
>>>>>> >
>>>>>> > JAVASERVERFACES_SPEC_PUBLIC-1404 Add
>>>>>> UIViewRoot#getRenderedComponentResources()
>>>>>> >
>>>>>> > is still valid. But I'll send the comments related to that one in
>>>>>> other email.
>>>>>> >
>>>>>> >
>>>>>> > Suggestions are welcomed.
>>>>>> >
>>>>>> > regards,
>>>>>> >
>>>>>> > Leonardo Uribe
>>>>>> >
>>>>>> >
>>>>>> >
>>>>>> > 2016-06-22 9:19 GMT+02:00 Cagatay Civici <cagatay.civici_at_gmail.com
>>>>>> >:
>>>>>> > Sure, actually Thomas Andraschko, the reporter of
>>>>>> JAVASERVERFACES_SPEC_PUBLIC-1423 has implemented it in PF, I’ve asked him
>>>>>> for details and his response briefly is;
>>>>>> >> Have a look at:
>>>>>> >> org.primefaces.application.resource.DynamicResourcesPhaseListener
>>>>>> - it collects the initial resources on the ajax request
>>>>>> >> org.primefaces.context.PrimePartialResponseWriter - ln 278; gets
>>>>>> the resources again, creates a diff of the initial and new resources,
>>>>>> render some JS to load the resources dynamically
>>>>>> > Regards,
>>>>>> >
>>>>>> > Cagatay Civici
>>>>>> > PrimeFaces Lead
>>>>>> > PrimeTek Informatics
>>>>>> > On Wednesday 22 June 2016 at 10:02, Bauke Scholtz wrote:
>>>>>> >
>>>>>> >> Cagatay, can you point out it in the PrimeFaces codebase? Then I
>>>>>> will look at similarities and differences and if necessary optimize the
>>>>>> standard solution based on that.
>>>>>> >>
>>>>>> >> Cheers, B
>>>>>> >>
>>>>>> >>
>>>>>> >> On Wed, Jun 22, 2016, 08:43 Cagatay Civici <
>>>>>> cagatay.civici_at_gmail.com> wrote:
>>>>>> >>> We also have a custom solution to this in PrimeFaces as it is a
>>>>>> very common case. A standard solution would be preferred for sure.
>>>>>> >>>
>>>>>> >>> Regards,
>>>>>> >>>
>>>>>> >>> Cagatay Civici
>>>>>> >>> PrimeFaces Lead
>>>>>> >>> PrimeTek Informatics
>>>>>> >>> On Tuesday 21 June 2016 at 22:34, Bauke Scholtz wrote:
>>>>>> >>>
>>>>>> >>>> Coming to it, a new encodeAjax() method in UIComponent and
>>>>>> Renderer (I'd rather call it encodePartial(), in line with the existing
>>>>>> API) is a great suggestion which could indeed solve this problem and has
>>>>>> potential for solving/optimizing ajax based problems in a much more
>>>>>> flexible way. This is indeed a small and easy change in the API (and impl).
>>>>>> >>>>
>>>>>> >>>> +1 from me.
>>>>>> >>>>
>>>>>> >>>> Cheers, B
>>>>>> >>>>
>>>>>> >>>>
>>>>>> >>>>
>>>>>> >>>>
>>>>>> >>>> On Tue, Jun 21, 2016 at 5:22 PM, Bauke Scholtz <balusc_at_gmail.com>
>>>>>> wrote:
>>>>>> >>>>> As to writer.startEval(), as per
>>>>>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1412 I've
>>>>>> added a PartialViewContext#getEvalScripts() for JSF 2.3. This could be used.
>>>>>> >>>>>
>>>>>> >>>>> I will think about encodeAjax() and reply later.
>>>>>> >>>>>
>>>>>> >>>>> Cheers, B
>>>>>> >>>>>
>>>>>> >>>>> On Tue, Jun 21, 2016 at 4:01 PM, Leonardo Uribe <
>>>>>> leonardo.uribe_at_irian.at> wrote:
>>>>>> >>>>>> Hi
>>>>>> >>>>>>
>>>>>> >>>>>> I just wanted to repost a comment from MyFaces issue tracker
>>>>>> in 2012 about the issue being discussed now:
>>>>>> >>>>>>
>>>>>> >>>>>>
>>>>>> >>>>>> Luciano Deiru:
>>>>>> >>>>>>
>>>>>> >>>>>> Thanks for the reply.
>>>>>> >>>>>>
>>>>>> >>>>>> I don't think it's going to be possible for me to migrate my
>>>>>> app to JSF2 without a
>>>>>> >>>>>> complete re-write of the frontend. I did a little more digging
>>>>>> to see if richfaces was
>>>>>> >>>>>> the issue and i can across this section of the richfaces 4.2.2
>>>>>> development guide...
>>>>>> >>>>>> ...
>>>>>> >>>>>>
>>>>>> >>>>>> "JSF 2 does not allow resources such as JavaScript or
>>>>>> Cascading Style Sheets (CSS) to
>>>>>> >>>>>> be added if the element requiring the resource is not
>>>>>> initially present in the JSF
>>>>>> >>>>>> tree. As such, components added to the tree via Ajax must
>>>>>> have any required resources
>>>>>> >>>>>> already loaded. In RichFaces, any components added to the JSF
>>>>>> tree should have
>>>>>> >>>>>> components with corresponding resources included on the main
>>>>>> page initially. To
>>>>>> >>>>>> facilitate this, components can use the rendered="false"
>>>>>> setting to not be
>>>>>> >>>>>> rendered on the page."
>>>>>> >>>>>> ...
>>>>>> >>>>>>
>>>>>> >>>>>> So the only workaround would be to add every possible
>>>>>> richfaces and primefaces component
>>>>>> >>>>>> to the login page so it loads the JS and css. That's a bit
>>>>>> depressing because you
>>>>>> >>>>>> can't create a "pure ajax"/dynamic application in JSF2 even
>>>>>> tho i was possible in JSF1.
>>>>>> >>>>>> It seems like a widely used approach and there are a lot of
>>>>>> forum posts about the
>>>>>> >>>>>> issue but no one is ever able to get it working without
>>>>>> including the hidden components.
>>>>>> >>>>>>
>>>>>> >>>>>>
>>>>>> >>>>>> regards,
>>>>>> >>>>>>
>>>>>> >>>>>> Leonardo Uribe
>>>>>> >>>>>>
>>>>>> >>>>>> 2016-06-21 15:55 GMT+02:00 Leonardo Uribe <
>>>>>> leonardo.uribe_at_irian.at>:
>>>>>> >>>>>>> Hi
>>>>>> >>>>>>>
>>>>>> >>>>>>> I see.
>>>>>> >>>>>>>
>>>>>> >>>>>>> BS>> Also, to avoid duplicates and/or unnecessary
>>>>>> re-rendering, all so far rendered
>>>>>> >>>>>>> BS>> resources must be remembered in JSF state. AFAIC this is
>>>>>> currently not the case.
>>>>>> >>>>>>>
>>>>>> >>>>>>> Well, this is information related to the view that is
>>>>>> implicit there, but you want to
>>>>>> >>>>>>> avoid to put it in the state.
>>>>>> >>>>>>>
>>>>>> >>>>>>> That's the reason why I like the way it is working in
>>>>>> MyFaces, because we just keep
>>>>>> >>>>>>> track of the change, rather than store that information in
>>>>>> the state.
>>>>>> >>>>>>>
>>>>>> >>>>>>> Write the script directly into the <eval> is possible, but
>>>>>> right now from spec
>>>>>> >>>>>>> perspective there are not the necessary "building blocks"
>>>>>> available.
>>>>>> >>>>>>>
>>>>>> >>>>>>> Both h:outputScript and h:outputStylesheet are components
>>>>>> that are supposed to be
>>>>>> >>>>>>> rendered as resources, but both components have Renderer
>>>>>> instances, which are
>>>>>> >>>>>>> the classes who finally decide how they should be rendered.
>>>>>> Even if you have a list,
>>>>>> >>>>>>> this list could include javascript/css or whatever and the
>>>>>> resources could be rendered
>>>>>> >>>>>>> in different ways.
>>>>>> >>>>>>>
>>>>>> >>>>>>> For example an h:outputScript could have children that could
>>>>>> be js code. Or a
>>>>>> >>>>>>> h:outputStylesheet could have a "media" property set.
>>>>>> >>>>>>>
>>>>>> >>>>>>> So if we want a "general" solution to the problem, which
>>>>>> includes script, stylesheets
>>>>>> >>>>>>> or whatever, it is necessary to know the component instance
>>>>>> that needs to be added
>>>>>> >>>>>>> or updated, and then ask the component how it should be
>>>>>> rendered.
>>>>>> >>>>>>>
>>>>>> >>>>>>> The problem from the "building blocks" perspective, is there
>>>>>> is no way the component
>>>>>> >>>>>>> can know the current request is an ajax update.
>>>>>> encodeAll(...) just means encode
>>>>>> >>>>>>> everything and don't ask questions.
>>>>>> >>>>>>>
>>>>>> >>>>>>> I would like to have a method in UIComponent/Renderer called
>>>>>> encodeAjax(...) for the
>>>>>> >>>>>>> component, which by default start and end an <update> section
>>>>>> and call by default
>>>>>> >>>>>>> to encodeAll(...). Something like this
>>>>>> >>>>>>>
>>>>>> >>>>>>> public void encodeAjax(FacesContext _facesContext,
>>>>>> PartialResponseWriter writer) {
>>>>>> >>>>>>> try
>>>>>> >>>>>>> {
>>>>>> >>>>>>> writer.startUpdate(target.getClientId(_facesContext));
>>>>>> >>>>>>> target.encodeAll(_facesContext);
>>>>>> >>>>>>> }
>>>>>> >>>>>>> finally
>>>>>> >>>>>>> {
>>>>>> >>>>>>> writer.endUpdate();
>>>>>> >>>>>>> }
>>>>>> >>>>>>> }
>>>>>> >>>>>>>
>>>>>> >>>>>>> This part is done in PartialViewContext implementation, but
>>>>>> if we can move it here
>>>>>> >>>>>>> we could ask the component in a gentle way how it should be
>>>>>> rendered. Then, from
>>>>>> >>>>>>> this location we could override the method and call
>>>>>> writer.startEval(...), which is
>>>>>> >>>>>>> something is not possible in this moment, because there is no
>>>>>> way right now to
>>>>>> >>>>>>> customize this step for each component.
>>>>>> >>>>>>>
>>>>>> >>>>>>> In this way, you could add an script to load the stylesheet
>>>>>> and then use the eval
>>>>>> >>>>>>> to include it in the response.
>>>>>> >>>>>>>
>>>>>> >>>>>>> I have already mention this improvement in this mail some
>>>>>> time ago:
>>>>>> >>>>>>>
>>>>>> >>>>>>>
>>>>>> https://java.net/projects/javaserverfaces-spec-public/lists/jsr372-experts/archive/2015-04/message/41
>>>>>> >>>>>>>
>>>>>> >>>>>>> It looks we have yet another use case where this could be
>>>>>> useful.
>>>>>> >>>>>>>
>>>>>> >>>>>>> regards,
>>>>>> >>>>>>>
>>>>>> >>>>>>> Leonardo Uribe
>>>>>> >>>>>>>
>>>>>> >>>>>>>
>>>>>> >>>>>>> 2016-06-21 14:51 GMT+02:00 Bauke Scholtz <balusc_at_gmail.com>:
>>>>>> >>>>>>>> Hi,
>>>>>> >>>>>>>>
>>>>>> >>>>>>>> OmniFaces has 3 solutions to dynamically include a (script)
>>>>>> resource:
>>>>>> >>>>>>>>
>>>>>> >>>>>>>> 1: Ajax#load() (just write script straight to <eval>)
>>>>>> >>>>>>>> 2: Components#addScriptResourceToHead()
>>>>>> >>>>>>>> 3: Components#addScriptResourceToBody()
>>>>>> >>>>>>>>
>>>>>> >>>>>>>> Which one to use depends on the moment (which isn't yet
>>>>>> refactored into a single utility method, this is TBD). When the request is
>>>>>> an ajax request with partial rendering (i.e. ajax with NO @all), then use
>>>>>> #1. Else when the current phase is NOT render response, or the view is in
>>>>>> BUILDING state, then use #2. Else use #3.
>>>>>> >>>>>>>>
>>>>>> >>>>>>>> This is implemented for the unload script associated with
>>>>>> OmniFaces @ViewScoped and this works quite well.
>>>>>> >>>>>>>>
>>>>>> >>>>>>>> Also, to avoid duplicates and/or unnecessary re-rendering,
>>>>>> all so far rendered resources must be remembered in JSF state. AFAIC this
>>>>>> is currently not the case.
>>>>>> >>>>>>>>
>>>>>> >>>>>>>> Cheers, B
>>>>>> >>>>>>>>
>>>>>> >>>>>>>>
>>>>>> >>>>>>>> On Tue, Jun 21, 2016 at 2:37 PM, Leonardo Uribe <
>>>>>> leonardo.uribe_at_irian.at> wrote:
>>>>>> >>>>>>>>> Hi
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> I have seen this issue has been opened in the spec issue
>>>>>> tracker
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>>
>>>>>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1423
>>>>>> >>>>>>>>> Dynamic resource loading in ajax requests
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> I would like to contribute with some thoughts about the
>>>>>> topic, since in MyFaces there
>>>>>> >>>>>>>>> is a solution that is not perfect (if PartialViewContext is
>>>>>> overriden, the code will
>>>>>> >>>>>>>>> not work, so some third party libraries will not be able to
>>>>>> use it), but it helps to
>>>>>> >>>>>>>>> identify the missing points in the spec, and specify it
>>>>>> faster.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> This issue could be also relevant for portlets.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> The issue has been reported long time ago in:
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> - https://issues.apache.org/jira/browse/MYFACES-3106
>>>>>> >>>>>>>>> Resources not loaded when using a dynamic ui:inlclude and
>>>>>> rendered via ajax
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> - https://issues.apache.org/jira/browse/MYFACES-3367
>>>>>> >>>>>>>>> Detect when to update head or body target when content has
>>>>>> been updated dynamically
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> - https://issues.apache.org/jira/browse/MYFACES-3659
>>>>>> >>>>>>>>> Conditional include of scripts and stylesheets
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> The first thing to understand the problem is identify the
>>>>>> possible use cases we have:
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> - c:if, ui:include src="#{...}" or facelet tag that
>>>>>> dynamically update the tree.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> For example:
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> ...
>>>>>> >>>>>>>>> <f:ajax event="onclick" render="box"/>
>>>>>> >>>>>>>>> ...
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> <div jsf:id="box">
>>>>>> >>>>>>>>> <c:if test="#{...}">
>>>>>> >>>>>>>>> <h:outputScript target="head" library="js"
>>>>>> name="help.js" />
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> ...
>>>>>> >>>>>>>>> </c:if>
>>>>>> >>>>>>>>> </div>
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> Here we have a case when the components inside the c:if
>>>>>> requires some javascript file,
>>>>>> >>>>>>>>> but the update comes from an ajax request. The algorithm
>>>>>> just somehow put the
>>>>>> >>>>>>>>> h:outputScript on the head of the document, but the ajax
>>>>>> does not trigger the head
>>>>>> >>>>>>>>> refresh, so the component was added to the tree, but the
>>>>>> javascript file was not loaded
>>>>>> >>>>>>>>> and we finally have a broken panel.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> There are variants of the same example with
>>>>>> h:outputStylesheet, or ui:include but the
>>>>>> >>>>>>>>> reason is the same.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> - Dynamic but the resource is added by a
>>>>>> @ResourceDependency annotation.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> This is similar to the previous case, but the component is
>>>>>> added indirectly when
>>>>>> >>>>>>>>> Application.createComponent(...) is executed.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> The important thing to keep in mind is there are 3 possible
>>>>>> targets: "head", "body" and
>>>>>> >>>>>>>>> "form". But the only thing we can do with the current spec
>>>>>> is just force a full update
>>>>>> >>>>>>>>> of each of these targets.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> So, in MyFaces there is a web config param called
>>>>>> >>>>>>>>> org.apache.myfaces.STRICT_JSF_2_REFRESH_TARGET_AJAX that
>>>>>> when it is activated, and
>>>>>> >>>>>>>>> the previous situation happens, it just enable a flag so
>>>>>> the target is updated with
>>>>>> >>>>>>>>> the ajax request. If the "head" needs to be updated, the
>>>>>> whole "head" and the updated
>>>>>> >>>>>>>>> content is sent and so on.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> The processing is done on process partial render time,
>>>>>> after the ajax request is
>>>>>> >>>>>>>>> rendered but before write the state token. Please note if
>>>>>> the target is rendered before
>>>>>> >>>>>>>>> this code, the algorithm should be able to detect the
>>>>>> condition and do not duplicate
>>>>>> >>>>>>>>> the response.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> The solution is not perfect because it force render the
>>>>>> whole target, when we only
>>>>>> >>>>>>>>> need to render the html fragment of the added component
>>>>>> (script/stylesheet/
>>>>>> >>>>>>>>> other js code). But there is no way to do it with the
>>>>>> current API, because <head>
>>>>>> >>>>>>>>> or <body> could not have an id and without id, you can't
>>>>>> insert. PartialResponseWriter
>>>>>> >>>>>>>>> contains these methods:
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> startInsertBefore(String targetId)
>>>>>> >>>>>>>>> startInsertAfter(String targetId)
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> But note these two are useless, because what we need is
>>>>>> insert "inside" at the beginning
>>>>>> >>>>>>>>> or the end.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> For example:
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> <head>
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> <script .../>
>>>>>> >>>>>>>>> </head>
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> <body>
>>>>>> >>>>>>>>> <script .../>
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> </body>
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> Please note there are some cases where the jsf third party
>>>>>> library (for example
>>>>>> >>>>>>>>> primefaces) provides its own rules to to render the script
>>>>>> at first, middle or last. But
>>>>>> >>>>>>>>> in this case it doesn't matter those rules, because what we
>>>>>> really need is that the
>>>>>> >>>>>>>>> resource is added.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> The code that activates the flags to render head, body or
>>>>>> form target is on
>>>>>> >>>>>>>>> h:outputScript and h:outputStylesheet, specifically in the
>>>>>> listener attached to
>>>>>> >>>>>>>>> PostAddToViewEvent. This is the best place, because here is
>>>>>> the place where
>>>>>> >>>>>>>>> UIViewRoot.addComponentResource is done.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> I think what's really important in this problem is provide
>>>>>> the API where you can notify
>>>>>> >>>>>>>>> that the resource needs to be added. In MyFaces there is:
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> class RequestViewContext {
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> public boolean isRenderTarget(String target);
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> public void setRenderTarget(String target, boolean
>>>>>> value);
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> }
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> Which could evolve to something more complex, including the
>>>>>> UIComponent instance and
>>>>>> >>>>>>>>> so on.
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> I don't really like to do a list comparison, because it can
>>>>>> introduce an unnecessary
>>>>>> >>>>>>>>> performance overhead. I would like an API that could have
>>>>>> some methods to register the
>>>>>> >>>>>>>>> component for updated on the target and others to get the
>>>>>> changes and do the necessary
>>>>>> >>>>>>>>> calculation in PartialViewContext.processPartial(...)
>>>>>> (render response).
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> regards,
>>>>>> >>>>>>>>>
>>>>>> >>>>>>>>> Leonardo Uribe
>>>>>> >>>>>>>>
>>>>>> >>>>>>>
>>>>>> >>>>>>
>>>>>> >>>>>
>>>>>> >>>>
>>>>>> >>>
>>>>>> >
>>>>>> >
>>>>>> >
>>>>>> >
>>>>>> >
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>