Giter Site home page Giter Site logo

Comments (5)

tandraschko avatar tandraschko commented on August 24, 2024 1

untested, would be great if someone can test and make a PR for it

from primefaces.

tandraschko avatar tandraschko commented on August 24, 2024

https://github.com/apache/myfaces/blob/1b8695232fdf601cad043e45be570da89a4e65b3/impl/src/main/java/org/apache/myfaces/renderkit/html/util/HtmlRendererUtils.java#L1773

we could support by reflection

from primefaces.

tandraschko avatar tandraschko commented on August 24, 2024

i would change HTML5_COMPLIANCE to type String and do the following:

/*
 * The MIT License
 *
 * Copyright (c) 2009-2024 PrimeTek Informatics
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.primefaces.renderkit;

import org.primefaces.context.PrimeApplicationContext;
import org.primefaces.util.HTML;

import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;

public class RendererUtils {

    private static final Logger LOGGER = Logger.getLogger(RendererUtils.class.getName());

    private static Method METHOD_VIEW_ROOT_GET_DOCTYPE = null;
    private static Method METHOD_DOCTYPE_GET_ROOT_ELEMENT = null;
    private static Method METHOD_DOCTYPE_GET_PUBLIC = null;
    private static Method METHOD_DOCTYPE_GET_SYSTEM = null;

    public static final String SCRIPT_TYPE = "text/javascript";

    private RendererUtils() {
        // Hide constructor
    }

    public static void encodeCheckbox(FacesContext context, boolean checked) throws IOException {
        encodeCheckbox(context, checked, false, false, null);
    }

    public static void encodeCheckbox(FacesContext context, boolean checked, boolean partialSelected, boolean disabled, String styleClass) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        String icon;
        String boxClass = disabled ? HTML.CHECKBOX_BOX_CLASS + " ui-state-disabled" : HTML.CHECKBOX_BOX_CLASS;
        boxClass += checked ? " ui-state-active" : "";
        String containerClass = (styleClass == null) ? HTML.CHECKBOX_CLASS : HTML.CHECKBOX_CLASS + " " + styleClass;

        if (checked) {
            icon = HTML.CHECKBOX_CHECKED_ICON_CLASS;
        }
        else if (partialSelected) {
            icon = HTML.CHECKBOX_PARTIAL_CHECKED_ICON_CLASS;
        }
        else {
            icon = HTML.CHECKBOX_UNCHECKED_ICON_CLASS;
        }

        writer.startElement("div", null);
        writer.writeAttribute("class", containerClass, null);

        writer.startElement("div", null);
        writer.writeAttribute("class", boxClass, null);

        writer.startElement("span", null);
        writer.writeAttribute("class", icon, null);
        writer.endElement("span");

        writer.endElement("div");

        writer.endElement("div");
    }

    /**
     * Duplicate code from OmniFaces project under apache license:
     * <a href="https://github.com/omnifaces/omnifaces/blob/master/license.txt">https://github.com/omnifaces/omnifaces/blob/master/license.txt</a>
     *
     * Returns the {@link RenderKit} associated with the "current" view ID or view handler.
     * <p>
     * The current view ID is the view ID that's set for the view root that's associated with the current faces context.
     * Or if there is none, then the current view handler will be assumed, which is the view handler that's associated
     * with the requested view.
     *
     * @return The {@link RenderKit} associated with the "current" view ID or view handler.
     * @throws NullPointerException When faces context is unavailable.
     * @see <a href="https://github.com/omnifaces/omnifaces">Omnifaces</a>
     */
    public static RenderKit getRenderKit(FacesContext context) {
        String renderKitId = null;
        UIViewRoot view = context.getViewRoot();

        if (view != null) {
            renderKitId = view.getRenderKitId();
        }

        if (renderKitId == null) {
            Application application = context.getApplication();
            ViewHandler viewHandler = application.getViewHandler();

            if (viewHandler != null) {
                renderKitId = viewHandler.calculateRenderKitId(context);
            }

            if (renderKitId == null) {
                renderKitId = application.getDefaultRenderKitId();

                if (renderKitId == null) {
                    renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
                }
            }
        }

        return ((RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY)).getRenderKit(context, renderKitId);
    }

    /**
     * HTML5 Doctype does not require the script type on JavaScript files.
     *
     * @param context the FacesContext
     * @throws IOException if any error occurs
     */
    public static void encodeScriptTypeIfNecessary(FacesContext context) throws IOException {
        if (isOutputHtml5Doctype(context)) {
            return;
        }
        ResponseWriter writer = context.getResponseWriter();
        writer.writeAttribute("type", SCRIPT_TYPE, null);
    }

    /**
     * Returns <code>true</code> if the view root associated with the given {@link FacesContext}
     * will be rendered with a HTML5 doctype.
     *
     * @param context Involved faces context.
     * @return <code>true</code> if the view root associated with the given faces context
     *      will be rendered with a HTML5 doctype.
     */
    public static boolean isOutputHtml5Doctype(FacesContext context) {
        PrimeApplicationContext applicationContext = PrimeApplicationContext.getCurrentInstance(context);
        if ("true".equals(applicationContext.getConfig().getHtml5Compliance())) {
            return true;
        }

        if ("auto".equals(applicationContext.getConfig().getHtml5Compliance())) {
            UIViewRoot viewRoot = context.getViewRoot();
            if (viewRoot == null) {
                return false;
            }

            if (!PrimeApplicationContext.getCurrentInstance(context).getEnvironment().isAtLeastJsf40()) {
                return false;
            }

            try {
                if (METHOD_VIEW_ROOT_GET_DOCTYPE == null) {
                    METHOD_VIEW_ROOT_GET_DOCTYPE = viewRoot.getClass().getMethod("getDoctype");
                }
                Object doctype = METHOD_VIEW_ROOT_GET_DOCTYPE.invoke(viewRoot);
                if (doctype == null) {
                    return false;
                }

                if (METHOD_DOCTYPE_GET_SYSTEM == null) {
                    METHOD_DOCTYPE_GET_ROOT_ELEMENT = doctype.getClass().getMethod("getRootElement");
                    METHOD_DOCTYPE_GET_PUBLIC = doctype.getClass().getMethod("getPublic");
                    METHOD_DOCTYPE_GET_SYSTEM = doctype.getClass().getMethod("getSystem");
                }

                String rootElement = (String) METHOD_DOCTYPE_GET_ROOT_ELEMENT.invoke(doctype);
                String publicVal = (String) METHOD_DOCTYPE_GET_PUBLIC.invoke(doctype);
                String system = (String) METHOD_DOCTYPE_GET_SYSTEM.invoke(doctype);

                return "html".equalsIgnoreCase(rootElement)
                        && publicVal == null
                        && system == null;
            }
            catch (Exception e) {
                LOGGER.log(Level.SEVERE, "Could not detect Doctype of current view!", e);
            }
        }

        return false;
    }
}


"auto" is default then, needs to be changed in the docs

from primefaces.

tandraschko avatar tandraschko commented on August 24, 2024
/*
 * The MIT License
 *
 * Copyright (c) 2009-2024 PrimeTek Informatics
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.primefaces.config;

import java.util.Map;
import java.util.Objects;
import javax.faces.component.UIInput;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;

import org.primefaces.util.Constants;
import org.primefaces.util.LangUtils;

/**
 * Container for all config parameters.
 */
public class PrimeConfiguration {

    // context params
    private final boolean validateEmptyFields;
    private final boolean partialSubmitEnabled;
    private final boolean resetValuesEnabled;
    private final boolean interpretEmptyStringAsNull;
    private final String theme;
    private final boolean primeIconsEnabled;
    private final boolean clientSideLocalizationEnabled;
    private final boolean clientSideValidationEnabled;
    private final boolean transformMetadataEnabled;
    private final boolean legacyWidgetNamespace;
    private final boolean interpolateClientSideValidationMessages;
    private final boolean earlyPostParamEvaluation;
    private final boolean moveScriptsToBottom;
    private final boolean moveScriptsToBottomDeferred;
    private final String html5Compliance;
    private boolean csp;
    private boolean policyProvided;
    private String cspPolicy;
    private String cspReportOnlyPolicy;
    private String[] exceptionTypesToIgnoreInLogging;
    private final String multiViewStateStore;
    private final boolean markInputAsInvalidOnErrorMsg;

    // internal config
    private final boolean stringConverterAvailable;

    private final boolean beanValidationEnabled;

    // web.xml
    private final Map<String, String> errorPages;

    private boolean cookiesSecure;
    private String cookiesSameSite;

    public PrimeConfiguration(FacesContext context, PrimeEnvironment environment) {
        ExternalContext externalContext = context.getExternalContext();

        stringConverterAvailable = null != context.getApplication().createConverter(String.class);

        errorPages = WebXmlParser.getErrorPages(context);

        validateEmptyFields = resolveValidateEmptyFields(context, environment);


        // parse context params
        String value = externalContext.getInitParameter(Constants.ContextParams.INTERPRET_EMPTY_STRING_AS_NULL);
        interpretEmptyStringAsNull = Boolean.parseBoolean(value);

        value = externalContext.getInitParameter(Constants.ContextParams.SUBMIT);
        partialSubmitEnabled = "partial".equalsIgnoreCase(value);

        value = externalContext.getInitParameter(Constants.ContextParams.RESET_VALUES);
        resetValuesEnabled = Boolean.parseBoolean(value);

        value = externalContext.getInitParameter(Constants.ContextParams.CSV);
        clientSideValidationEnabled = Boolean.parseBoolean(value);

        theme = externalContext.getInitParameter(Constants.ContextParams.THEME);

        value = externalContext.getInitParameter(Constants.ContextParams.PRIME_ICONS);
        primeIconsEnabled = Boolean.parseBoolean(Objects.toString(value, "true"));

        value = externalContext.getInitParameter(Constants.ContextParams.TRANSFORM_METADATA);
        transformMetadataEnabled = Boolean.parseBoolean(value);

        value = externalContext.getInitParameter(Constants.ContextParams.LEGACY_WIDGET_NAMESPACE);
        legacyWidgetNamespace = Boolean.parseBoolean(value);

        value = externalContext.getInitParameter(Constants.ContextParams.BEAN_VALIDATION_DISABLED);
        beanValidationEnabled = environment.isBeanValidationAvailable() && !Boolean.parseBoolean(value);

        value = externalContext.getInitParameter(Constants.ContextParams.INTERPOLATE_CLIENT_SIDE_VALIDATION_MESSAGES);
        interpolateClientSideValidationMessages = Boolean.parseBoolean(value);

        value = externalContext.getInitParameter(Constants.ContextParams.EARLY_POST_PARAM_EVALUATION);
        earlyPostParamEvaluation = Boolean.parseBoolean(value);

        value = externalContext.getInitParameter(Constants.ContextParams.CLIENT_SIDE_LOCALISATION);
        clientSideLocalizationEnabled = Boolean.parseBoolean(Objects.toString(value, "true"));

        value = Objects.toString(externalContext.getInitParameter(Constants.ContextParams.MOVE_SCRIPTS_TO_BOTTOM));
        switch (value) {
            case "true":
                moveScriptsToBottom = Boolean.TRUE;
                moveScriptsToBottomDeferred = Boolean.FALSE;
                break;
            case "defer":
                moveScriptsToBottom = Boolean.TRUE;
                moveScriptsToBottomDeferred = Boolean.TRUE;
                break;
            default:
                moveScriptsToBottom = Boolean.FALSE;
                moveScriptsToBottomDeferred = Boolean.FALSE;
                break;
        }

        value = externalContext.getInitParameter(Constants.ContextParams.HTML5_COMPLIANCE);
        html5Compliance = LangUtils.isBlank(value) ? "auto" : value;

        value = Objects.toString(externalContext.getInitParameter(Constants.ContextParams.CSP));
        switch (value) {
            case "true":
                csp = Boolean.TRUE;
                cspPolicy = externalContext.getInitParameter(Constants.ContextParams.CSP_POLICY);
                break;
            case "reportOnly":
                csp = Boolean.TRUE;
                cspReportOnlyPolicy = externalContext.getInitParameter(Constants.ContextParams.CSP_REPORT_ONLY_POLICY);
                break;
            case "policyProvided":
                csp = Boolean.TRUE;
                policyProvided = Boolean.TRUE;
                break;
            default:
                csp = Boolean.FALSE;
                break;
        }

        value = externalContext.getInitParameter(Constants.ContextParams.EXCEPTION_TYPES_TO_IGNORE_IN_LOGGING);
        if (LangUtils.isBlank(value)) {
            exceptionTypesToIgnoreInLogging = new String[0];
        }
        else {
            exceptionTypesToIgnoreInLogging = value.split(",");
        }

        multiViewStateStore = externalContext.getInitParameter(Constants.ContextParams.MULTI_VIEW_STATE_STORE);

        value = externalContext.getInitParameter(Constants.ContextParams.MARK_INPUT_AS_INVALID_ON_ERROR_MSG);
        markInputAsInvalidOnErrorMsg = Boolean.parseBoolean(value);

        if (environment.isAtLeastJsf40()) {
            value = externalContext.getInitParameter(Constants.ContextParams.COOKIES_SAME_SITE);
            cookiesSameSite = (value == null) ? "Strict" : value;
        }

        cookiesSecure = true;
        if (externalContext.getContext() instanceof ServletContext) {
            ServletContext se = (ServletContext) externalContext.getContext();
            if (se.getSessionCookieConfig() != null) {
                cookiesSecure = se.getSessionCookieConfig().isSecure();
            }
        }
    }

    protected boolean resolveValidateEmptyFields(FacesContext context, PrimeEnvironment environment) {
        ExternalContext externalContext = context.getExternalContext();

        String param = externalContext.getInitParameter(UIInput.VALIDATE_EMPTY_FIELDS_PARAM_NAME);

        if (param == null && externalContext.getApplicationMap().containsKey(UIInput.VALIDATE_EMPTY_FIELDS_PARAM_NAME)) {
            Object applicationMapValue = externalContext.getApplicationMap().get(UIInput.VALIDATE_EMPTY_FIELDS_PARAM_NAME);
            if (applicationMapValue instanceof String) {
                param = (String) applicationMapValue;
            }
            else if (applicationMapValue instanceof Boolean) {
                return (Boolean) applicationMapValue;
            }
        }

        if (param == null) {
            // null means the same as auto.
            param = "auto";
        }
        else {
            // The environment variables are case insensitive.
            param = param.toLowerCase();
        }

        return ("auto".equals(param) && environment.isBeanValidationAvailable()) || "true".equals(param);
    }

    public boolean isValidateEmptyFields() {
        return validateEmptyFields;
    }

    public boolean isPartialSubmitEnabled() {
        return partialSubmitEnabled;
    }

    public boolean isResetValuesEnabled() {
        return resetValuesEnabled;
    }

    public boolean isInterpretEmptyStringAsNull() {
        return interpretEmptyStringAsNull;
    }

    public String getTheme() {
        return theme;
    }

    public boolean isPrimeIconsEnabled() {
        return primeIconsEnabled;
    }

    public boolean isClientSideLocalizationEnabled() {
        return clientSideLocalizationEnabled;
    }

    public boolean isClientSideValidationEnabled() {
        return clientSideValidationEnabled;
    }

    public boolean isTransformMetadataEnabled() {
        return transformMetadataEnabled;
    }

    public boolean isLegacyWidgetNamespace() {
        return legacyWidgetNamespace;
    }

    public boolean isInterpolateClientSideValidationMessages() {
        return interpolateClientSideValidationMessages;
    }

    public boolean isEarlyPostParamEvaluation() {
        return earlyPostParamEvaluation;
    }

    public boolean isMoveScriptsToBottom() {
        return moveScriptsToBottom;
    }

    public boolean isMoveScriptsToBottomDeferred() {
        return moveScriptsToBottomDeferred;
    }

    public String getHtml5Compliance() {
        return html5Compliance;
    }

    public boolean isStringConverterAvailable() {
        return stringConverterAvailable;
    }

    public boolean isBeanValidationEnabled() {
        return beanValidationEnabled;
    }

    public Map<String, String> getErrorPages() {
        return errorPages;
    }

    public boolean isCsp() {
        return csp;
    }

    public boolean isPolicyProvided() {
        return policyProvided;
    }

    public String getCspPolicy() {
        return cspPolicy;
    }

    public String getCspReportOnlyPolicy() {
        return cspReportOnlyPolicy;
    }

    public String[] getExceptionTypesToIgnoreInLogging() {
        return exceptionTypesToIgnoreInLogging;
    }

    public String getMultiViewStateStore() {
        return multiViewStateStore;
    }

    public boolean isMarkInputAsInvalidOnErrorMsg() {
        return markInputAsInvalidOnErrorMsg;
    }

    public boolean isCookiesSecure() {
        return cookiesSecure;
    }

    public String getCookiesSameSite() {
        return cookiesSameSite;
    }
}

from primefaces.

melloware avatar melloware commented on August 24, 2024

I can take a look at this.

from primefaces.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.