Open bigbonsai opened 6 years ago
@BalusC / @arjantijms Could you have a look at it? It seems quite annoying for users.
It may be related to the dynamic resource loading feature. In the PF HeadRenderer, we get all resources and call #encodeAllon them, to render the script/style tag. This worked fire in every Mojarra and MyFaces version but it seems that Mojarra 2.3 doesn't render the tags when you are in ajax request with update=@all. The weird thing is that viewRoot#getComponentResources delivers all correct resources but #encodeAll does nothing.
@BalusC I'm upgrading my app to Wildfly 15 (Mojarra 2.3.5.SP2 + Primefaces 6.2 + Omnifaces 3.2). A minimal diference to Omnifaces ShowCase is Mojarra 2.3.5.SP1 (Wildfly 13).
I'm using FullAjaxExceptionHandler and getting mentioned error when handling ajax exceptions. Could this be related?
core.js.xhtml?ln=primefaces&v=6.2:3 Uncaught TypeError: Cannot read property 'error' of null
at Object.<anonymous> (core.js.xhtml?ln=primefaces&v=6.2:3)
at i (jquery.js.xhtml?ln=primefaces&v=6.2:2)
at Object.fireWith [as resolveWith] (jquery.js.xhtml?ln=primefaces&v=6.2:2)
at A (jquery.js.xhtml?ln=primefaces&v=6.2:4)
at XMLHttpRequest.<anonymous> (jquery.js.xhtml?ln=primefaces&v=6.2:4)
VM2128:1 Uncaught TypeError: Cannot read property 'cw' of null
at <anonymous>:1:12
at p (jquery.js.xhtml?ln=primefaces&v=6.2:2)
at Ja (jquery.js.xhtml?ln=primefaces&v=6.2:3)
at r.fn.init.append (jquery.js.xhtml?ln=primefaces&v=6.2:3)
at r.fn.init.<anonymous> (jquery.js.xhtml?ln=primefaces&v=6.2:3)
at T (jquery.js.xhtml?ln=primefaces&v=6.2:3)
at r.fn.init.html (jquery.js.xhtml?ln=primefaces&v=6.2:3)
at Object.updateBody (core.js.xhtml?ln=primefaces&v=6.2:3)
at Object.updateElement (core.js.xhtml?ln=primefaces&v=6.2:3)
at Object.doUpdate (core.js.xhtml?ln=primefaces&v=6.2:3)
VM2125:1 Uncaught TypeError: Cannot read property 'locales' of null
at <anonymous>:1:12
at p (jquery.js.xhtml?ln=primefaces&v=6.2:2)
at Function.globalEval (jquery.js.xhtml?ln=primefaces&v=6.2:2)
at text script (jquery.js.xhtml?ln=primefaces&v=6.2:4)
at Qb (jquery.js.xhtml?ln=primefaces&v=6.2:4)
at A (jquery.js.xhtml?ln=primefaces&v=6.2:4)
at XMLHttpRequest.<anonymous> (jquery.js.xhtml?ln=primefaces&v=6.2:4)
at Object.send (jquery.js.xhtml?ln=primefaces&v=6.2:4)
at Function.ajax (jquery.js.xhtml?ln=primefaces&v=6.2:4)
at Function.r._evalUrl (jquery.js.xhtml?ln=primefaces&v=6.2:4)
should be the same bug, yes
As @tandraschko said, Mojarra is not rendering all the resources during an ajax request with update=\@ALL.
@BalusC
One possible hack (in OmniFaces) so that the FullAjaxExceptionHandler works again:
Edit the method Hacks.removeResourceDependencyState
(used by FullAjaxExceptionHandler), clearing JSF's processed resource dependencies:
context.getAttributes().keySet().remove(javax.faces.application.ResourceHandler.RESOURCE_IDENTIFIER);
The snippet above makes JSF render all resources again. I don't know if it affects other funcionalities, as I've only tested the exception handled by FullAjaxExceptionHandler.
@tandraschko
Additionally, dealing with this issue, I've observed that PrimeFaces updates the <head>
tag differently from the Mojarra and MyFaces way of doing it when it comes to updating elements in an ajax response (javascript).
PrimeFaces replaces the <head>
:
$('head').html(content.substring(headStartIndex, content.lastIndexOf("</head>")));
This act of "replacing" the head tag brings some weird behaviors as the browser removes the styles and replaces them with new ones (the user perceives a "flicker" sometimes).
Mojarra do not allow replacement of the head tag, stating that
javax.faces.ViewHead not supported - browsers cannot reliably replace the head's contents. (https://github.com/javaserverfaces/mojarra/blob/master/impl/src/main/js/jsf.js)
When it comes to update ViewRoot, it replaces the <body>
tag and executes the same code triggered by a change in javax.faces.Resource
, appending new scripts and styles to the head (but not replacing it).
Myfaces seems to proceed this way either:
we cannot replace the head, almost no browser allows this, some of them throw errors others simply ignore it or replace it and destroy the dom that way! (https://github.com/apache/myfaces/blob/master/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxResponse.js)
Myfaces' _replaceHead
function bears the following comment:
replaces a current head theoretically, pratically only the scripts are evaled anew since nothing else can be changed.
Omniface's FullAjaxExceptionHandler showcase works because the demo was created using a Mojarra component (<h:commandButton...
with <f:ajax...
).
Mojarra do not replace the head tag, and everything works as normal (despite the fact that the partial-response should contain all the resources).
Link to omnifaces' showcase: http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler
The problem becomes apparent if the demo is created with PrimeFaces (<p:commandButton ajax="true" ...
), because PrimeFaces replaces the head element.
Since the head provided by the partial-response is incomplete, the view is rendered in a broken way (often missing critical javascript and styles).
One work around could be to change PrimeFaces' functions PrimeFaces.ajax.Utils.updateHead
and PrimeFaces.ajax.Utils.updateElement
(in core.js) to behave the way Mojarra and MyFaces do. Is there any known issue with that?
Below is a javascript hack that attempts to ilustrate that.
I, personally, think that update=@all should also replace the whole head content. update=@all is used to replace the whole view (including title e.g.). The flickering is expected as the head content is replaced - also @all should only be used for special cases like FullAjaxExceptionHandler.
Maybe the PF behavior is not perfect, but the JSF behavior also is not perfect. We replace the content since years now in PrimeFaces and we didn't had any issues in modern browsers.
But back to the actual issue: I think Mojarra should behave like all older Mojarra versions and MyFaces: it should render the resource, when someone tries to manually render the resource component via UIComponent#encodeAll. This makes it more flexible for third-party-libs and compatible with older versions.
It doesn't mean that the JSF impl have to render the resources in their HeadRenderer on AJAX requests, they can skip it. But they should also allow it to render if some would like to:
This is our code:
for (UIComponent resource : viewRoot.getComponentResources(context, "head")) { resource.encodeAll(context); }
Stackoverflow
Seems like the component resources are available (see PrimeFaces HeadRenderer) in the postback but somehow they are not rendered in the response inside the head tag.
NOTE: this will only happen with update=@all as otherwise the head-tag won't be replaced.
Discoverd with PrimeFaces 6.2 on Mojarra 3.3.2.
After pressing this button, this stacktraces shows the problem.