You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ta...@apache.org on 2021/04/06 12:44:58 UTC

[myfaces] branch master updated: MYFACES-4393: Render type='text/javscript` only on HTML4

This is an automated email from the ASF dual-hosted git repository.

tandraschko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces.git


The following commit(s) were added to refs/heads/master by this push:
     new 54b4e3c  MYFACES-4393: Render type='text/javscript` only on HTML4
     new dbf80fb  Merge pull request #198 from melloware/MYFACES-4393
54b4e3c is described below

commit 54b4e3c24e599931dfcd5d49280a142fd024dd63
Author: melloware <me...@gmail.com>
AuthorDate: Tue Apr 6 08:36:05 2021 -0400

    MYFACES-4393: Render type='text/javscript` only on HTML4
---
 .../main/java/jakarta/faces/component/Doctype.java | 100 +++++++++---------
 .../myfaces/push/WebsocketComponentRenderer.java   |   4 +-
 .../renderkit/html/HtmlCommandScriptRenderer.java  |   2 +-
 .../myfaces/renderkit/html/HtmlScriptRenderer.java |   7 +-
 .../apache/myfaces/renderkit/html/util/HTML.java   |   2 -
 .../renderkit/html/util/HtmlRendererUtils.java     |  39 +++++++
 .../myfaces/renderkit/html/util/ResourceUtils.java |   4 +-
 .../apache/myfaces/view/facelets/DoctypeImpl.java  | 116 ++++++++++-----------
 8 files changed, 155 insertions(+), 119 deletions(-)

diff --git a/api/src/main/java/jakarta/faces/component/Doctype.java b/api/src/main/java/jakarta/faces/component/Doctype.java
index 8494185..16e77eb 100644
--- a/api/src/main/java/jakarta/faces/component/Doctype.java
+++ b/api/src/main/java/jakarta/faces/component/Doctype.java
@@ -1,50 +1,50 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 jakarta.faces.component;
-
-/**
- * <p class="changed_added_4_0">
- * <strong>Doctype</strong> is an interface that must be implemented by any {@link UIComponent} that represents a document type declaration.
- * </p>
- *
- * @since 4.0
- */
-public interface Doctype {
-
-    /**
-     * Returns the name of the first element in the document, never <code>null</code>.
-     * For example, <code>"html"</code>.
-     * @return The name of the first element in the document, never <code>null</code>.
-     */
-    String getRootElement();
-
-    /**
-     * Returns the public identifier of the document, or <code>null</code> if there is none.
-     * For example, <code>"-//W3C//DTD XHTML 1.1//EN"</code>.
-     * @return The public identifier of the document, or <code>null</code> if there is none.
-     */
-    String getPublic();
-
-    /**
-     * Returns the system identifier of the document, or <code>null</code> if there is none.
-     * For example, <code>"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"</code>.
-     * @return The system identifier of the document, or <code>null</code> if there is none.
-     */
-    String getSystem();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 jakarta.faces.component;
+
+/**
+ * <p class="changed_added_4_0">
+ * <strong>Doctype</strong> is an interface that must be implemented by any {@link UIComponent} that represents a document type declaration.
+ * </p>
+ *
+ * @since 4.0
+ */
+public interface Doctype {
+
+    /**
+     * Returns the name of the first element in the document, never <code>null</code>.
+     * For example, <code>"html"</code>.
+     * @return The name of the first element in the document, never <code>null</code>.
+     */
+    String getRootElement();
+
+    /**
+     * Returns the public identifier of the document, or <code>null</code> if there is none.
+     * For example, <code>"-//W3C//DTD XHTML 1.1//EN"</code>.
+     * @return The public identifier of the document, or <code>null</code> if there is none.
+     */
+    String getPublic();
+
+    /**
+     * Returns the system identifier of the document, or <code>null</code> if there is none.
+     * For example, <code>"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"</code>.
+     * @return The system identifier of the document, or <code>null</code> if there is none.
+     */
+    String getSystem();
+}
diff --git a/impl/src/main/java/org/apache/myfaces/push/WebsocketComponentRenderer.java b/impl/src/main/java/org/apache/myfaces/push/WebsocketComponentRenderer.java
index fa2889f..9dff476 100644
--- a/impl/src/main/java/org/apache/myfaces/push/WebsocketComponentRenderer.java
+++ b/impl/src/main/java/org/apache/myfaces/push/WebsocketComponentRenderer.java
@@ -44,6 +44,7 @@ import org.apache.myfaces.push.cdi.WebsocketSessionBean;
 import org.apache.myfaces.push.cdi.WebsocketViewBean;
 import org.apache.myfaces.renderkit.html.util.ClientBehaviorRendererUtils;
 import org.apache.myfaces.renderkit.html.util.HTML;
+import org.apache.myfaces.renderkit.html.util.HtmlRendererUtils;
 import org.apache.myfaces.renderkit.html.util.ResourceUtils;
 
 @JSFRenderer(renderKitId = "HTML_BASIC",
@@ -183,9 +184,8 @@ public class WebsocketComponentRenderer extends Renderer implements ComponentSys
 
             appTokenBean.registerWebsocketSession(channelToken, metadata);
         }
-
         writer.startElement(HTML.SCRIPT_ELEM, component);
-        writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
+        HtmlRendererUtils.renderScriptType(facesContext, writer);
 
         StringBuilder sb = new StringBuilder(50);
         sb.append("jsf.push.init(");
diff --git a/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlCommandScriptRenderer.java b/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlCommandScriptRenderer.java
index be048ba..6f9d03d 100644
--- a/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlCommandScriptRenderer.java
+++ b/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlCommandScriptRenderer.java
@@ -62,7 +62,7 @@ public class HtmlCommandScriptRenderer extends HtmlRenderer
         writer.startElement(HTML.SPAN_ELEM, component);
         writer.writeAttribute(HTML.ID_ATTR, component.getClientId(context), null);
         writer.startElement(HTML.SCRIPT_ELEM, component);
-        writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
+        HtmlRendererUtils.renderScriptType(context, writer);
         
         JavascriptContext script = new JavascriptContext();
         
diff --git a/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlScriptRenderer.java b/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlScriptRenderer.java
index eabf83e..9231463 100644
--- a/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlScriptRenderer.java
+++ b/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlScriptRenderer.java
@@ -38,6 +38,7 @@ import jakarta.faces.render.Renderer;
 import jakarta.faces.view.Location;
 
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
+import org.apache.myfaces.renderkit.html.util.HtmlRendererUtils;
 import org.apache.myfaces.renderkit.html.util.JSFAttr;
 import org.apache.myfaces.renderkit.RendererUtils;
 import org.apache.myfaces.renderkit.html.util.HTML;
@@ -144,7 +145,7 @@ public class HtmlScriptRenderer extends Renderer implements ComponentSystemEvent
                 // </script>
                 ResponseWriter writer = facesContext.getResponseWriter();
                 writer.startElement(HTML.SCRIPT_ELEM, component);
-                writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
+                HtmlRendererUtils.renderScriptType(facesContext, writer);
                 RendererUtils.renderChildren(facesContext, component);
                 writer.endElement(HTML.SCRIPT_ELEM);
             }
@@ -229,9 +230,7 @@ public class HtmlScriptRenderer extends Renderer implements ComponentSystemEvent
             ResourceUtils.markScriptAsRendered(facesContext, resource.getLibraryName(), resource.getResourceName());
             ResponseWriter writer = facesContext.getResponseWriter();
             writer.startElement(HTML.SCRIPT_ELEM, component);
-            // We can't render the content type, because usually it returns "application/x-javascript"
-            // and this is not compatible with IE. We should force render "text/javascript".
-            writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
+            HtmlRendererUtils.renderScriptType(facesContext, writer);
             String path = resource.getRequestPath();
             if (additionalQueryParams != null)
             {
diff --git a/impl/src/main/java/org/apache/myfaces/renderkit/html/util/HTML.java b/impl/src/main/java/org/apache/myfaces/renderkit/html/util/HTML.java
index 552e0f5..1e6b144 100644
--- a/impl/src/main/java/org/apache/myfaces/renderkit/html/util/HTML.java
+++ b/impl/src/main/java/org/apache/myfaces/renderkit/html/util/HTML.java
@@ -607,8 +607,6 @@ public interface HTML
     String SCRIPT_TYPE_ATTR = "type";
     String SCRIPT_TYPE_TEXT_JAVASCRIPT = "text/javascript";
     String STYLE_TYPE_TEXT_CSS = "text/css";
-    String SCRIPT_LANGUAGE_ATTR = "language";
-    String SCRIPT_LANGUAGE_JAVASCRIPT = "JavaScript";
     String SCRIPT_ELEM_DEFER_ATTR = "defer";
     String LINK_ELEM = "link";
     String STYLESHEET_VALUE = "stylesheet";
diff --git a/impl/src/main/java/org/apache/myfaces/renderkit/html/util/HtmlRendererUtils.java b/impl/src/main/java/org/apache/myfaces/renderkit/html/util/HtmlRendererUtils.java
index 48ac993..26192b6 100644
--- a/impl/src/main/java/org/apache/myfaces/renderkit/html/util/HtmlRendererUtils.java
+++ b/impl/src/main/java/org/apache/myfaces/renderkit/html/util/HtmlRendererUtils.java
@@ -31,6 +31,7 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import jakarta.faces.FacesException;
+import jakarta.faces.component.Doctype;
 import jakarta.faces.component.EditableValueHolder;
 import jakarta.faces.component.UIComponent;
 import jakarta.faces.component.UIForm;
@@ -1926,4 +1927,42 @@ public final class HtmlRendererUtils
         // render the component
         messages.encodeAll(facesContext);
     }
+
+    /**
+     * Returns <code>true</code> if the view root associated with the given faces context 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) {
+        UIViewRoot viewRoot = context.getViewRoot();
+
+        if (viewRoot == null) {
+            return false;
+        }
+
+        Doctype doctype = viewRoot.getDoctype();
+
+        if (doctype == null) {
+            return false;
+        }
+
+        return "html".equalsIgnoreCase(doctype.getRootElement())
+                && doctype.getPublic() == null
+                && doctype.getSystem() == null;
+    }
+
+    /**
+     * If HTML5 doctype do not render the "type='text/javascript`" attribute as its not necessary.
+     *
+     * @param context Involved faces context.
+     * @param writer Involved response writer.
+     * @throws IOException if any error occurs writing the response.
+     */
+    public static void renderScriptType(FacesContext context, ResponseWriter writer) throws IOException
+    {
+        if (!HtmlRendererUtils.isOutputHtml5Doctype(context))
+        {
+            writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
+        }
+    }
 }
diff --git a/impl/src/main/java/org/apache/myfaces/renderkit/html/util/ResourceUtils.java b/impl/src/main/java/org/apache/myfaces/renderkit/html/util/ResourceUtils.java
index af271a4..bb94d2b 100644
--- a/impl/src/main/java/org/apache/myfaces/renderkit/html/util/ResourceUtils.java
+++ b/impl/src/main/java/org/apache/myfaces/renderkit/html/util/ResourceUtils.java
@@ -82,7 +82,7 @@ public class ResourceUtils
                     resourceName, libraryName);
             markScriptAsRendered(facesContext, libraryName, resourceName);
             writer.startElement(HTML.SCRIPT_ELEM, null);
-            writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT , null);
+            HtmlRendererUtils.renderScriptType(facesContext, writer);
             writer.writeURIAttribute(HTML.SRC_ATTR, resource.getRequestPath(), null);
             writer.endElement(HTML.SCRIPT_ELEM);
         }
@@ -120,7 +120,7 @@ public class ResourceUtils
         markScriptAsRendered(facesContext, ResourceHandler.JSF_SCRIPT_LIBRARY_NAME,
                 ResourceHandler.JSF_SCRIPT_RESOURCE_NAME);
         writer.startElement(HTML.SCRIPT_ELEM, null);
-        writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
+        HtmlRendererUtils.renderScriptType(facesContext, writer);
         writer.writeURIAttribute(HTML.SRC_ATTR, resource.getRequestPath(), null);
         writer.endElement(HTML.SCRIPT_ELEM);
 
diff --git a/impl/src/main/java/org/apache/myfaces/view/facelets/DoctypeImpl.java b/impl/src/main/java/org/apache/myfaces/view/facelets/DoctypeImpl.java
index db4357b..d880a3d 100644
--- a/impl/src/main/java/org/apache/myfaces/view/facelets/DoctypeImpl.java
+++ b/impl/src/main/java/org/apache/myfaces/view/facelets/DoctypeImpl.java
@@ -1,58 +1,58 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.myfaces.view.facelets;
-
-import jakarta.faces.component.Doctype;
-import java.io.Serializable;
-
-public class DoctypeImpl implements Serializable, Doctype
-{
-    private String rootElement;
-    private String publicId;
-    private String system;
-
-    public DoctypeImpl()
-    {
-    }
-
-    public DoctypeImpl(String rootElement, String publicId, String system)
-    {
-        this.rootElement = rootElement;
-        this.publicId = publicId;
-        this.system = system;
-    }
-
-    @Override
-    public String getRootElement()
-    {
-        return rootElement;
-    }
-
-    @Override
-    public String getPublic()
-    {
-        return publicId;
-    }
-
-    @Override
-    public String getSystem()
-    {
-        return system;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.myfaces.view.facelets;
+
+import jakarta.faces.component.Doctype;
+import java.io.Serializable;
+
+public class DoctypeImpl implements Serializable, Doctype
+{
+    private String rootElement;
+    private String publicId;
+    private String system;
+
+    public DoctypeImpl()
+    {
+    }
+
+    public DoctypeImpl(String rootElement, String publicId, String system)
+    {
+        this.rootElement = rootElement;
+        this.publicId = publicId;
+        this.system = system;
+    }
+
+    @Override
+    public String getRootElement()
+    {
+        return rootElement;
+    }
+
+    @Override
+    public String getPublic()
+    {
+        return publicId;
+    }
+
+    @Override
+    public String getSystem()
+    {
+        return system;
+    }
+}