Dynamic resource dependency loading

Community Driven Extensions Project
tandraschko
PrimeFaces Core Developer
Posts: 3979
Joined: 03 Dec 2010, 14:11
Location: Bavaria, DE
Contact:

27 Jan 2016, 20:37

Updating h:head via id or @(head) is working now:
https://github.com/primefaces/primefaces/issues/1074
https://github.com/primefaces/primefaces/issues/1075

Also, FYI, if you use MyFaces, your required functionality is also built in via:
org.apache.myfaces.STRICT_JSF_2_REFRESH_TARGET_AJAX
Thomas Andraschko

PrimeFaces | PrimeFaces Extensions

Apache Member | OpenWebBeans, DeltaSpike, MyFaces, BVal, TomEE

Sponsor me: https://github.com/sponsors/tandraschko
Blog: http://tandraschko.blogspot.de/
Twitter: https://twitter.com/TAndraschko

User avatar
mrswadge
Posts: 36
Joined: 10 Sep 2012, 11:11

27 Jan 2016, 22:17

Cool, fast work. Thanks! :)
PrimeFaces 6.0 | Mojarra 2.0.11 | WebLogic 10.3.6

User avatar
mrswadge
Posts: 36
Joined: 10 Sep 2012, 11:11

27 Jan 2016, 23:01

I've not tried the RequestContext#update route yet, but I seem to have a working solution. This is what I did.

This is all within my extension, so no hacking about in other projects.

faces-config.xml

Code: Select all

	<lifecycle>
		<phase-listener>com.otbo.faces.render.ResourceComponentModificationListener</phase-listener>
	</lifecycle>
New class: com.otbo.faces.render.ResourceComponentModificationListener - The purpose of this class is to get a list of the existing resource components that are stored when the view is restored. This then creates a set of the resource components and stores that on the request as an attribute which can be used later on during component rendering.

Code: Select all

package com.otbo.faces.render;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.faces.component.UIComponent;
import javax.faces.component.UIOutput;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

public class ResourceComponentModificationListener implements PhaseListener {

	private static final long serialVersionUID = -52626426246421L;

	private final PhaseId phaseId = PhaseId.ANY_PHASE;

	@Override
	public void beforePhase( PhaseEvent event ) {
		// NOP
	}

	@Override
	public void afterPhase( PhaseEvent event ) {
		// creates a list of the previously loaded component resources.
		if ( PhaseId.RESTORE_VIEW == event.getPhaseId() ) {
			storeInitialState( event.getFacesContext() );
		}
	}

	private void storeInitialState( FacesContext facesContext ) {
		Map<String, Object> requestMap = facesContext.getExternalContext().getRequestMap();

		UIViewRoot viewRoot = facesContext.getViewRoot();
		if ( viewRoot != null ) {
			List<UIComponent> componentResources = viewRoot.getComponentResources( facesContext, "head" );

			// populate a set of unique resources so we know what is loaded already.
			Set<String> loadedResources = new HashSet<String>();
			for ( UIComponent c : componentResources ) {
				if ( c instanceof UIOutput ) {
					String library = (String) c.getAttributes().get( "library" );
					String name = (String) c.getAttributes().get( "name" );
					if ( library != null && name != null ) {
						loadedResources.add( ResourceComponentModificationRenderer.getInstance().getResourceComponentKey( library, name ) );
					}
				}
			}

			requestMap.put( ResourceComponentModificationRenderer.COMPONENT_RESOURCE_SET, loadedResources );
		}
	}

	@Override
	public PhaseId getPhaseId() {
		return phaseId;
	}
}
New class: com.otbo.faces.render.ResourceComponentModificationRenderer - This class has a method renderAdditionalResourceComponents(UIComponent, ResponseWriter) which should be invoked before the initialisation of the component is rendered. This effectively performs a diff between the list of resource components registered at the end of the restore view phase and then creates javascript to place any missing resource components into the header dynamically.

Code: Select all

package com.otbo.faces.render;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.faces.FacesException;
import javax.faces.application.Resource;
import javax.faces.component.UIComponent;
import javax.faces.component.UIOutput;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

import org.apache.commons.lang3.StringEscapeUtils;

public class ResourceComponentModificationRenderer {

	public static final String COMPONENT_RESOURCE_SET = ResourceComponentModificationRenderer.class.getSimpleName() + "_ComponentResourceSet";

	private static final ResourceComponentModificationRenderer instance = new ResourceComponentModificationRenderer();

	private ResourceComponentModificationRenderer() {
	}

	public static ResourceComponentModificationRenderer getInstance() {
		return instance;
	}

	public void renderAdditionalResourceComponents( UIComponent component, ResponseWriter writer ) throws IOException {
		String clientId = component.getClientId();
		writer.startElement( "script", null );
		writer.writeAttribute( "id", clientId + "_s_load", null );
		writer.writeAttribute( "type", "text/javascript", null );

		FacesContext facesContext = FacesContext.getCurrentInstance();
		UIViewRoot viewRoot = facesContext.getViewRoot();
		if ( viewRoot != null ) {
			List<UIComponent> componentResources = viewRoot.getComponentResources( facesContext, "head" );

			Map<String, Object> requestMap = facesContext.getExternalContext().getRequestMap();
			Set<String> loaded = (Set<String>) requestMap.get( COMPONENT_RESOURCE_SET );

			for ( UIComponent c : componentResources ) {
				if ( c instanceof UIOutput ) {
					String library = (String) c.getAttributes().get( "library" );
					String name = (String) c.getAttributes().get( "name" );

					if ( library != null && name != null ) {
						// only load this file if it hasn't already been transmitted to the client.
						String key = getResourceComponentKey( library, name );
						if ( !loaded.contains( key ) ) {
							Resource resource = facesContext.getApplication().getResourceHandler().createResource( name, library );
							String js = "(function(){var c=\"cache\";var v=$.ajaxSetup()[c];$.ajaxSetup()[c]=true;try{$('head').append('%s');}finally{$.ajaxSetup()[c]=v;}}());";
							if ( isStylesheet( c ) ) {
								String styleInclude = StringEscapeUtils.escapeEcmaScript( String.format( "<link type=\"text/css\" rel=\"stylesheet\" href=\"%s\" />", resource.getRequestPath() ) );
								writer.write( String.format( js, styleInclude ) );
								loaded.add( key );
							} else if ( isScript( c ) ) {
								String scriptInclude = StringEscapeUtils.escapeEcmaScript( String.format( "<script type=\"text/javascript\" src=\"%s\"></script>", resource.getRequestPath() ) );
								writer.write( String.format( js, scriptInclude ) );
								loaded.add( key );
							} else {
								throw new FacesException( "Unknown component resource type." );
							}
						}
					}
				}
			}
		}
		writer.endElement( "script" );
	}

	public String getResourceComponentKey( String library, String name ) {
		return library + ":" + name;
	}

	public boolean isScript( UIComponent component ) {
		return "javax.faces.resource.Script".equals( component.getRendererType() );
	}

	public boolean isStylesheet( UIComponent component ) {
		return "javax.faces.resource.Stylesheet".equals( component.getRendererType() );
	}
}
Finally, to hook up these pieces. The component renderer needs to invoke the method ResourceComponentModificationRenderer.getInstance().renderAdditionalResourceComponents( component, writer ); which does all the leg work.

Code: Select all

	@Override
	public void encodeEnd( FacesContext context, UIComponent component ) throws IOException {
		this.encodeMarkup( context, (DateEntry) component );
		this.encodeScript( context, (DateEntry) component );
	}

	private void encodeScript( FacesContext context, DateEntry component ) throws IOException {
		ResponseWriter writer = context.getResponseWriter();

		// ADDED BELOW //
		// detect for required changes to the list of javascript & css includes.
		ResourceComponentModificationRenderer.getInstance().renderAdditionalResourceComponents( component, writer );
		// ADDED ABOVE //
		
		String clientId = component.getClientId();
		String widgetVar = component.resolveWidgetVar();

		WidgetBuilder wb = getWidgetBuilder( context );
		wb.initWithDomReady( "DateEntry", widgetVar, clientId, "dateentry" );
		
		encodeClientBehaviors( context, component );

		wb.finish();
	}
It seems concise and fairly light-weight, so I'm currently happy with the way it's behaving. It only ever includes the scripts/css if it is not already there.

What do you think? Can you see any holes?
PrimeFaces 6.0 | Mojarra 2.0.11 | WebLogic 10.3.6

tandraschko
PrimeFaces Core Developer
Posts: 3979
Joined: 03 Dec 2010, 14:11
Location: Bavaria, DE
Contact:

27 Jan 2016, 23:19

Should work fine and you can also remove the "dateentry" parameter.

I will check if we can find a better way to do this via <eval>.
Currently your code will also be executed for the initial request && non-ajax requests.
As it's only required for ajax requests, i think it's the best way to place this e.g. in PrimePartialResponseWriter.
Thomas Andraschko

PrimeFaces | PrimeFaces Extensions

Apache Member | OpenWebBeans, DeltaSpike, MyFaces, BVal, TomEE

Sponsor me: https://github.com/sponsors/tandraschko
Blog: http://tandraschko.blogspot.de/
Twitter: https://twitter.com/TAndraschko

tandraschko
PrimeFaces Core Developer
Posts: 3979
Joined: 03 Dec 2010, 14:11
Location: Bavaria, DE
Contact:

28 Jan 2016, 00:12

Could you please try if the correct resources are printed via js console?
It's based on your idea, just a little bit different.
You still need to register the phaselistener.
The code is based on trunk.

Code: Select all

/*
 * Copyright 2009-2014 PrimeTek.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.primefaces.context;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.faces.FacesException;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.PartialResponseWriter;
import javax.faces.event.AbortProcessingException;
import org.primefaces.application.resource.TestPhaseListener;

import org.primefaces.json.JSONArray;
import org.primefaces.json.JSONException;
import org.primefaces.json.JSONObject;
import org.primefaces.util.ComponentUtils;
import org.primefaces.util.ResourceUtils;

public class PrimePartialResponseWriter extends PartialResponseWriter {

    private static final Map<String, String> CALLBACK_EXTENSION_PARAMS = Collections.unmodifiableMap(new HashMap<String, String>() {
        {
            put("ln", "primefaces");
            put("type", "args");
        }
    });

    private final PartialResponseWriter wrapped;

    public PrimePartialResponseWriter(PartialResponseWriter wrapped) {
        super(wrapped);
        this.wrapped = wrapped;
    }

    public void encodeJSONObject(String paramName, JSONObject jsonObject) throws IOException, JSONException {
        String json = jsonObject.toString();
        json = ComponentUtils.escapeXml(json);

        getWrapped().write("\"");
        getWrapped().write(paramName);
        getWrapped().write("\":");
        getWrapped().write(json);
    }

    public void encodeJSONArray(String paramName, JSONArray jsonArray) throws IOException, JSONException {
        String json = jsonArray.toString();
        json = ComponentUtils.escapeXml(json);

        getWrapped().write("\"");
        getWrapped().write(paramName);
        getWrapped().write("\":");
        getWrapped().write(json);
    }

    public void encodeJSONValue(String paramName, Object paramValue) throws IOException, JSONException {
        String json = new JSONObject().put(paramName, paramValue).toString();
        json = ComponentUtils.escapeXml(json);

        getWrapped().write(json.substring(1, json.length() - 1));
    }

    public void encodeCallbackParams(Map<String, Object> params) throws IOException, JSONException {

        if (params != null && !params.isEmpty()) {

            startExtension(CALLBACK_EXTENSION_PARAMS);
            getWrapped().write("{");

            for (Iterator<String> it = params.keySet().iterator(); it.hasNext();) {
                String paramName = it.next();
                Object paramValue = params.get(paramName);

                if (paramValue instanceof JSONObject) {
                    encodeJSONObject(paramName, (JSONObject) paramValue);
                } else if (paramValue instanceof JSONArray) {
                    encodeJSONArray(paramName, (JSONArray) paramValue);
                } else if (isBean(paramValue)) {
                    encodeJSONObject(paramName, new JSONObject(paramValue));
                } else {
                    encodeJSONValue(paramName, paramValue);
                }

                if (it.hasNext()) {
                    getWrapped().write(",");
                }
            }

            getWrapped().write("}");
            endExtension();
        }
    }

    public void encodeScripts(RequestContext requestContext) throws IOException {
        List<String> scripts = requestContext.getScriptsToExecute();
        if (!scripts.isEmpty()) {
            startEval();

            for (int i = 0; i < scripts.size(); i++) {
                getWrapped().write(scripts.get(i));
                getWrapped().write(';');
            }

            endEval();
        }
    }

    @Override
    public void delete(String targetId) throws IOException {
        wrapped.delete(targetId);
    }

    @Override
    public void endError() throws IOException {
        wrapped.endError();
    }

    @Override
    public void endEval() throws IOException {
        wrapped.endEval();
    }

    @Override
    public void endExtension() throws IOException {
        wrapped.endExtension();
    }

    @Override
    public void endInsert() throws IOException {
        wrapped.endInsert();
    }

    @Override
    public void endUpdate() throws IOException {
        wrapped.endUpdate();
    }

    @Override
    public void redirect(String url) throws IOException {
        wrapped.redirect(url);
    }

    @Override
    public void startDocument() throws IOException {
        wrapped.startDocument();

        RequestContext requestContext = RequestContext.getCurrentInstance();

        if (requestContext != null) {
            try {
                FacesContext context = FacesContext.getCurrentInstance();
                
                // parameter namespacing
                if (context.getViewRoot() instanceof NamingContainer) {
                    Map<String, Object> params = new HashMap<String, Object>();
                    params.put("parameterNamespace", context.getViewRoot().getContainerClientId(context));
                    encodeCallbackParams(params);
                }

                // dynamic resource loading
                HashSet<ResourceUtils.ResourceInfo> loadedResources = (HashSet<ResourceUtils.ResourceInfo>) context.getAttributes().get(TestPhaseListener.KEY);
                List<UIComponent> resources = context.getViewRoot().getComponentResources(context, "head");
                
                if (loadedResources  != null && resources.size() > loadedResources.size()) {
                    startEval();

                    for (UIComponent resource : resources) {
                        ResourceUtils.ResourceInfo resourceInfo = ResourceUtils.newResourceInfo(resource);
                        if (resourceInfo != null) {
                            if (!loadedResources.contains(resourceInfo)) {
                                String resourcePath = ResourceUtils.newResource(resourceInfo, context).getRequestPath();

                                if (ResourceUtils.isStylesheet(resource)) {
                                    getWrapped().write("console.log('css:" + resourcePath + "');");
                                }
                                else if (ResourceUtils.isScript(resource)) {
                                    getWrapped().write("console.log('js:" + resourcePath + "');");
                                }
                                else {
                                    throw new FacesException("Unknown component resource type: " + resource.getRendererType());
                                }
                            }
                        }
                    }

                    endEval();
                }
            } catch (Exception e) {
                throw new AbortProcessingException(e);
            }
        }
    }


    
    @Override
    public void endDocument() throws IOException {
        RequestContext requestContext = RequestContext.getCurrentInstance();

        if (requestContext != null) {
            try {
                FacesContext context = FacesContext.getCurrentInstance();
                if (context.isValidationFailed()) {
                    requestContext.addCallbackParam("validationFailed", true);
                }

                encodeCallbackParams(requestContext.getCallbackParams());
                encodeScripts(requestContext);
            } catch (Exception exception) {
                throw new AbortProcessingException(exception);
            }
        }

        wrapped.endDocument();
    }

    @Override
    public void startError(String errorName) throws IOException {
        wrapped.startError(errorName);
    }

    @Override
    public void startEval() throws IOException {
        wrapped.startEval();
    }

    @Override
    public void startExtension(Map<String, String> attributes) throws IOException {
        wrapped.startExtension(attributes);
    }

    @Override
    public void startInsertAfter(String targetId) throws IOException {
        wrapped.startInsertAfter(targetId);
    }

    @Override
    public void startInsertBefore(String targetId) throws IOException {
        wrapped.startInsertBefore(targetId);
    }

    @Override
    public void startUpdate(String targetId) throws IOException {
        wrapped.startUpdate(targetId);
    }

    @Override
    public void updateAttributes(String targetId, Map<String, String> attributes) throws IOException {
        wrapped.updateAttributes(targetId, attributes);
    }

    private boolean isBean(Object value) {
        if (value == null) {
            return false;
        }

        if (value instanceof Boolean || value instanceof String || value instanceof Number) {
            return false;
        }

        return true;
    }
}

Code: Select all

/*
 * Copyright 2009-2014 PrimeTek.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.primefaces.application.resource;

import java.util.HashSet;
import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import org.primefaces.util.ResourceUtils;

public class TestPhaseListener implements PhaseListener {

    public static final String KEY = "test";
    
    @Override
    public void beforePhase(PhaseEvent event) {

    }

    @Override
    public void afterPhase(PhaseEvent event) {
        FacesContext context = event.getFacesContext();

        if (context.getViewRoot() == null || !facesContext.getPartialViewContext().isAjaxRequest()) {
            return;
        }
            
        HashSet<ResourceUtils.ResourceInfo> loadedResources = new HashSet<ResourceUtils.ResourceInfo>();

        List<UIComponent> resources = context.getViewRoot().getComponentResources(context, "head");
        for (UIComponent resource : resources) {
            ResourceUtils.ResourceInfo resourceInfo = ResourceUtils.newResourceInfo(resource);
            if (resourceInfo != null) {
                loadedResources.add(resourceInfo);
            }
        }

        context.getAttributes().put(KEY, loadedResources);
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

}

Code: Select all

/*
 * Copyright 2014 tandraschko.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.primefaces.util;

import java.io.Serializable;
import javax.faces.FacesException;
import javax.faces.application.Application;
import javax.faces.application.Resource;
import javax.faces.component.UIComponent;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;

public class ResourceUtils {

    public static final String RENDERER_SCRIPT = "javax.faces.resource.Script";
    public static final String RENDERER_STYLESHEET = "javax.faces.resource.Stylesheet";
    
    public static void addComponentResource(FacesContext context, String name, String library, String target) {

        Application application = context.getApplication();

        UIComponent componentResource = application.createComponent(UIOutput.COMPONENT_TYPE);
        componentResource.setRendererType(application.getResourceHandler().getRendererTypeForResourceName(name));
        componentResource.getAttributes().put("name", name);
        componentResource.getAttributes().put("library", library);
        componentResource.getAttributes().put("target", target);

        context.getViewRoot().addComponentResource(context, componentResource, target);
    }

    public static void addComponentResource(FacesContext context, String name, String library) {
        addComponentResource(context, name, library, "head");
    }
    
    public static void addComponentResource(FacesContext context, String name) {
        addComponentResource(context, name, Constants.LIBRARY, "head");
    }
    
    public static boolean isScript(UIComponent component) {
        return RENDERER_SCRIPT.equals(component.getRendererType());
    }

    public static boolean isStylesheet(UIComponent component) {
        return RENDERER_STYLESHEET.equals(component.getRendererType());
    }
    
    public static ResourceInfo newResourceInfo(UIComponent component) {
        
        if (!(component instanceof UIOutput)) {
            return null;
        }
        
        String library = (String) component.getAttributes().get("library");
        String name = (String) component.getAttributes().get("name");
        
        return new ResourceInfo(library, name);
    }
    
    public static Resource newResource(ResourceInfo resourceInfo, FacesContext context) {
        Resource resource = context.getApplication().getResourceHandler().createResource(resourceInfo.getName(), resourceInfo.getLibrary());
        
        if (resource == null) {
            throw new FacesException("Resource '" + resourceInfo.getName() + "' in library '" + resourceInfo.getLibrary() + "' not found!");
        }
        
        return resource;
    }

    public static class ResourceInfo implements Serializable {

        private String library;
        private String name;

        public ResourceInfo(String library, String name) {
            this.library = library;
            this.name = name;
        }

        public String getLibrary() {
            return library;
        }

        public void setLibrary(String library) {
            this.library = library;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public int hashCode() {
            int hash = 7;
            hash = 41 * hash + (this.library != null ? this.library.hashCode() : 0);
            hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0);
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final ResourceInfo other = (ResourceInfo) obj;
            if ((this.library == null) ? (other.library != null) : !this.library.equals(other.library)) {
                return false;
            }
            if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
                return false;
            }
            return true;
        }
    }
}

Thomas Andraschko

PrimeFaces | PrimeFaces Extensions

Apache Member | OpenWebBeans, DeltaSpike, MyFaces, BVal, TomEE

Sponsor me: https://github.com/sponsors/tandraschko
Blog: http://tandraschko.blogspot.de/
Twitter: https://twitter.com/TAndraschko

User avatar
mrswadge
Posts: 36
Joined: 10 Sep 2012, 11:11

28 Jan 2016, 23:08

Hi there,

Good news. I just gave it a try and it worked well. 8-)

I left my code the same and added the listener to my 6.0-snapshot build as default. The eval section of the partial response appeared on top, which I hope would mean that javascript gets executed first. I might go away and test that.

Code: Select all

<?xml version='1.0' encoding='UTF-8'?>
<partial-response><changes><eval><![CDATA[console.log('js:/javax.faces.resource/dateentry/jquery.autotab.js.xhtml?ln=otbofaces&v=20160128205938');console.log('js:/javax.faces.resource/dateentry/jquery.caret.js.xhtml?ln=otbofaces&v=20160128205938');console.log('js:/javax.faces.resource/dateentry/jquery.date-entry.js.xhtml?ln=otbofaces&v=20160128205938');console.log('js:/javax.faces.resource/dateentry/dateentry.js.xhtml?ln=otbofaces&v=20160128205938');console.log('css:/javax.faces.resource/dateentry/dateentry.css.xhtml?ln=otbofaces&v=20160128205938');]]></eval><update id="j_idt9"><![CDATA[
<form id="j_idt9" name="j_idt9" method="post" action="/index2.xhtml" enctype="application/x-www-form-urlencoded">
... etc ...
</form>]]></update><update id="javax.faces.ViewState"><![CDATA[3873173150800564178:-6850984218023427414]]></update></changes></partial-response>
It looks promising.

Cheers,
Stuart
PrimeFaces 6.0 | Mojarra 2.0.11 | WebLogic 10.3.6

tandraschko
PrimeFaces Core Developer
Posts: 3979
Joined: 03 Dec 2010, 14:11
Location: Bavaria, DE
Contact:

28 Jan 2016, 23:20

Good news. I just gave it a try and it worked well. 8-)
Great!
The eval section of the partial response appeared on top, which I hope would mean that javascript gets executed first.
Yep exactly.

So the only thing left is a small JS function to load the resources.

I will discuss with Cagatay first and come back in some days.
Hopefully we can remove our dynamic loading through the WidgetBuilder and add it via this way.

Could you give it a try in both MyFaces (2.0, 2.1, 2.2) and Mojarra (2.0, 2.1, 2.2) if the same resources are printed?
Thomas Andraschko

PrimeFaces | PrimeFaces Extensions

Apache Member | OpenWebBeans, DeltaSpike, MyFaces, BVal, TomEE

Sponsor me: https://github.com/sponsors/tandraschko
Blog: http://tandraschko.blogspot.de/
Twitter: https://twitter.com/TAndraschko

User avatar
mrswadge
Posts: 36
Joined: 10 Sep 2012, 11:11

01 Feb 2016, 00:01

Could you give it a try in both MyFaces (2.0, 2.1, 2.2) and Mojarra (2.0, 2.1, 2.2) if the same resources are printed?
I'll try to get this tested tomorrow :)
PrimeFaces 6.0 | Mojarra 2.0.11 | WebLogic 10.3.6

User avatar
mrswadge
Posts: 36
Joined: 10 Sep 2012, 11:11

01 Feb 2016, 13:59

I got the testing done and found it working as expected on all. Versions tested listed below.
  • - Mojarra
    • - 2.0.11
      - 2.1.9
      - 2.2.9
    - MyFaces
    • - 2.0.23
      - 2.1.17
      - 2.2.9
PrimeFaces 6.0 | Mojarra 2.0.11 | WebLogic 10.3.6

User avatar
mrswadge
Posts: 36
Joined: 10 Sep 2012, 11:11

01 Feb 2016, 18:13

One thing that I do see (in Chrome at least) is a warning when downloading the sources in this way. I don't know if there is a simple workaround for this.
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
PrimeFaces 6.0 | Mojarra 2.0.11 | WebLogic 10.3.6

Post Reply

Return to “Extensions”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 7 guests