vineri, 24 aprilie 2015

[OmniFaces utilities (2.0)] Set the given script/stylesheet resource as rendered


[OmniFaces utilities] The setScriptResourceRendered() method set the given script resource as rendered.
[OmniFaces utilities] The setStylesheetResourceRendered() method set the given stylesheet resource as rendered.

Method (for script):

Method (for stylesheet):

Usage:

When we need to add any component (resource instance) as a resource in the view, we can use UIViewRoot#addComponentResource(). By any component (resource instance) we understand a resource instance which is rendered by a resource Renderer, as described in the Standard HTML RenderKit. For example, if you move a <script> component at the end of the <body>, you will probably do this:

UIViewRoot view = context.getViewRoot();
view.addComponentResource(context, script_component, "body");

Further, you may need to mark this resource as rendered. You have to instruct JSF that the script resource is already rendered, otherwise JSF will force the auto-inclusion/rendering of the script resource. As BalusC points out, "in case of Mojarra and MyFaces, a context attribute with key of name+library and a value of true has to be set in order to disable auto-inclusion of the resource". Well, in Mojarra you can easy see these words in code lines in com.sun.faces.renderkit.html_basic.ScriptRenderer class, in encodeEnd() method (similar we have for stylesheets resources in StylesheetRenderer). The relevant part is listed below:

@Override
public void encodeEnd(FacesContext context, UIComponent component)
                                                        throws IOException {
 ...
 Map<Object, Object> contextMap = context.getAttributes();
 ...
 String name = (String) attributes.get("name");
 String library = (String) attributes.get("library");
 String key = name + library;
 ...
 // Ensure this script/stylesheet is not rendered more than once per request
 if (contextMap.containsKey(key)) {
     return;
 }
 contextMap.put(key, Boolean.TRUE);
 ...
}

Since there's no standard JSF API for doing this, OmniFaces accomplished this task (for scripts) via Hacks#setScriptResourceRendered():

FacesContext context = ...;
Hacks.setScriptResourceRendered(context, new ResourceIdentifier(script_component));

And, for stylesheets via Hacks#setStylesheetResourceRendered():


FacesContext context = ...;
Hacks.setStylesheetResourceRendered(context, new ResourceIdentifier(stylesheet_component));

Note The OmniFaces org.omnifaces.resourcehandler.ResourceIdentifier is a convenience class to represent a resource identifier (maps resource name and library).
Note OmniFaces uses this method in DeferredScript and CombinedResourceHandler.

Niciun comentariu:

Trimiteți un comentariu