Skip to content

Commit

Permalink
Implement that text/javascript and text/css are optional in HTML5
Browse files Browse the repository at this point in the history
  • Loading branch information
BalusC committed Apr 3, 2021
1 parent 7bd9c83 commit 805a7df
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import java.util.regex.Pattern;
import java.util.zip.GZIPOutputStream;

import com.sun.faces.renderkit.html_basic.StylesheetRenderer;
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.MessageUtils;
import com.sun.faces.util.Util;
Expand Down Expand Up @@ -82,7 +83,7 @@ public abstract class ResourceHelper {
*/
private static final String COMPRESSED_CONTENT_FILENAME = "compressed-content";

private static final String[] EL_CONTENT_TYPES = { "text/css", };
private static final String[] EL_CONTENT_TYPES = { StylesheetRenderer.DEFAULT_CONTENT_TYPE, };

static {
Arrays.sort(EL_CONTENT_TYPES);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import com.sun.faces.RIConstants;
import com.sun.faces.application.ApplicationAssociate;
import com.sun.faces.context.flash.ELFlash;
import com.sun.faces.renderkit.html_basic.ScriptRenderer;
import com.sun.faces.renderkit.html_basic.StylesheetRenderer;
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.MessageUtils;
import com.sun.faces.util.TypedCollections;
Expand Down Expand Up @@ -128,8 +130,8 @@ public ExternalContextImpl(ServletContext sc, ServletRequest request, ServletRes
distributable = ContextParamUtils.getValue(servletContext, ContextParam.EnableDistributable, Boolean.class);

fallbackContentTypeMap = new HashMap<>(3, 1.0f);
fallbackContentTypeMap.put("js", "text/javascript");
fallbackContentTypeMap.put("css", "text/css");
fallbackContentTypeMap.put("js", ScriptRenderer.DEFAULT_CONTENT_TYPE);
fallbackContentTypeMap.put("css", StylesheetRenderer.DEFAULT_CONTENT_TYPE);
fallbackContentTypeMap.put("properties", "text/plain");

}
Expand Down Expand Up @@ -1027,7 +1029,7 @@ public Flash getFlash() {
}
return flash;
}

@Override
public void release() {
servletContext = null;
Expand Down
9 changes: 7 additions & 2 deletions impl/src/main/java/com/sun/faces/facelets/tag/ui/UIDebug.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

import com.sun.faces.facelets.util.DevTools;
import com.sun.faces.facelets.util.FastWriter;
import com.sun.faces.renderkit.RenderKitUtils;
import com.sun.faces.renderkit.html_basic.ScriptRenderer;

import jakarta.faces.component.UIComponentBase;
import jakarta.faces.context.FacesContext;
Expand Down Expand Up @@ -102,8 +104,11 @@ public void encodeBegin(FacesContext facesContext) throws IOException {
writer.startElement("span", this);
writer.writeAttribute("id", getClientId(facesContext), "id");
writer.startElement("script", this);
writer.writeAttribute("language", "javascript", "language");
writer.writeAttribute("type", "text/javascript", "type");

if (!RenderKitUtils.isOutputHtml5Doctype(facesContext)) {
writer.writeAttribute("type", ScriptRenderer.DEFAULT_CONTENT_TYPE, "type");
}

writer.writeText(sb.toString(), this, null);
writer.endElement("script");
writer.endElement("span");
Expand Down
39 changes: 39 additions & 0 deletions impl/src/main/java/com/sun/faces/renderkit/RenderKitUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.logging.Logger;

import com.sun.faces.RIConstants;
import com.sun.faces.config.FaceletsConfiguration;
import com.sun.faces.config.WebConfiguration;
import com.sun.faces.el.ELUtils;
import com.sun.faces.facelets.util.DevTools;
Expand Down Expand Up @@ -141,6 +142,12 @@ public class RenderKitUtils {
*/
private static final String ATTRIBUTES_THAT_ARE_SET_KEY = UIComponentBase.class.getName() + ".attributesThatAreSet";

/**
* UIViewRoot attribute key of a boolean value which remembers whether the view will be rendered with a HTML5 doctype.
*/
private static final String VIEW_ROOT_ATTRIBUTES_DOCTYPE_KEY = RenderKitUtils.class.getName() + ".isOutputHtml5Doctype";


protected static final Logger LOGGER = FacesLogger.RENDERKIT.getLogger();

/**
Expand Down Expand Up @@ -1267,6 +1274,38 @@ public static String getParameterName(FacesContext context, String name) {
return Util.getNamingContainerPrefix(context) + name;
}

/**
* 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;
}

Map<String, Object> attributes = viewRoot.getAttributes();
Boolean outputHtml5Doctype = (Boolean) attributes.get(VIEW_ROOT_ATTRIBUTES_DOCTYPE_KEY);

if (outputHtml5Doctype != null) {
return outputHtml5Doctype;
}

String doctype = Util.getDOCTYPEFromFacesContextAttributes(context);

if (doctype == null) {
WebConfiguration webConfig = WebConfiguration.getInstance(context.getExternalContext());
FaceletsConfiguration faceletsConfig = webConfig.getFaceletsConfiguration();
return faceletsConfig.isOutputHtml5Doctype(viewRoot.getViewId());
}

outputHtml5Doctype = "<!DOCTYPE html>".equals(doctype.trim());
attributes.put(VIEW_ROOT_ATTRIBUTES_DOCTYPE_KEY, outputHtml5Doctype);
return outputHtml5Doctype;
}

// --------------------------------------------------------- Private Methods

// Appends a script to a faces.util.chain() call
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ public void encodeBegin(FacesContext context, UIComponent component) throws IOEx
writer.startElement("span", commandScript);
writer.writeAttribute("id", clientId, "id");
writer.startElement("script", commandScript);
writer.writeAttribute("type", "text/javascript", "type");

if (!RenderKitUtils.isOutputHtml5Doctype(context)) {
writer.writeAttribute("type", ScriptRenderer.DEFAULT_CONTENT_TYPE, "type");
}

RenderKitUtils.renderFunction(context, component, getBehaviorParameters(commandScript), clientId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

import java.io.IOException;

import com.sun.faces.config.FaceletsConfiguration;
import com.sun.faces.config.WebConfiguration;
import com.sun.faces.renderkit.Attribute;
import com.sun.faces.renderkit.AttributeManager;
import com.sun.faces.renderkit.RenderKitUtils;
Expand Down Expand Up @@ -51,9 +49,8 @@ public void encodeBegin(FacesContext context, UIComponent component) throws IOEx
ResponseWriter writer = context.getResponseWriter();
writer.startElement("head", component);
RenderKitUtils.renderPassThruAttributes(context, writer, component, HEAD_ATTRIBUTES);
WebConfiguration webConfig = WebConfiguration.getInstance(context.getExternalContext());
FaceletsConfiguration faceletsConfig = webConfig.getFaceletsConfiguration();
if (faceletsConfig.isOutputHtml5Doctype(context.getViewRoot().getViewId())) {

if (RenderKitUtils.isOutputHtml5Doctype(context)) {
String clientId = component.getClientId(context);
writer.writeAttribute("id", clientId, "clientId");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@

import java.io.IOException;

import com.sun.faces.renderkit.RenderKitUtils;

import jakarta.faces.component.UIComponent;
import jakarta.faces.context.FacesContext;
import jakarta.faces.context.ResponseWriter;

/**
Expand All @@ -28,10 +31,15 @@
*/
public class ScriptRenderer extends ScriptStyleBaseRenderer {

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

@Override
protected void startInlineElement(ResponseWriter writer, UIComponent component) throws IOException {
protected void startInlineElement(FacesContext context, ResponseWriter writer, UIComponent component) throws IOException {
writer.startElement("script", component);
writer.writeAttribute("type", "text/javascript", "type");

if (!RenderKitUtils.isOutputHtml5Doctype(context)) {
writer.writeAttribute("type", DEFAULT_CONTENT_TYPE, "type");
}
}

@Override
Expand All @@ -40,8 +48,8 @@ protected void endInlineElement(ResponseWriter writer, UIComponent component) th
}

@Override
protected void startExternalElement(ResponseWriter writer, UIComponent component) throws IOException {
startInlineElement(writer, component);
protected void startExternalElement(FacesContext context, ResponseWriter writer, UIComponent component) throws IOException {
startInlineElement(context, writer, component);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public final void encodeChildren(FacesContext context, UIComponent component) th

if (renderChildren) {
ResponseWriter writer = context.getResponseWriter();
startInlineElement(writer, component);
startInlineElement(context, writer, component);
super.encodeChildren(context, component);
endInlineElement(writer, component);
}
Expand Down Expand Up @@ -192,7 +192,7 @@ public void encodeEnd(FacesContext context, UIComponent component) throws IOExce
String resourceUrl = "RES_NOT_FOUND";

ResponseWriter writer = context.getResponseWriter();
startExternalElement(writer, component);
startExternalElement(context, writer, component);

WebConfiguration webConfig = WebConfiguration.getInstance();

Expand Down Expand Up @@ -264,7 +264,7 @@ private static UIComponent findComponentIgnoringNamingContainers(UIComponent bas
* Allow the subclass to customize the start inline element content.
* </p>
*/
protected abstract void startInlineElement(ResponseWriter writer, UIComponent component) throws IOException;
protected abstract void startInlineElement(FacesContext context, ResponseWriter writer, UIComponent component) throws IOException;

/**
* <p>
Expand All @@ -278,7 +278,7 @@ private static UIComponent findComponentIgnoringNamingContainers(UIComponent bas
* Allow the subclass to customize the start external element content.
* </p>
*/
protected abstract void startExternalElement(ResponseWriter writer, UIComponent component) throws IOException;
protected abstract void startExternalElement(FacesContext context, ResponseWriter writer, UIComponent component) throws IOException;

/**
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@

import java.io.IOException;

import com.sun.faces.renderkit.RenderKitUtils;

import jakarta.faces.component.UIComponent;
import jakarta.faces.context.FacesContext;
import jakarta.faces.context.ResponseWriter;

/**
Expand All @@ -28,10 +31,18 @@
*/
public class StylesheetRenderer extends ScriptStyleBaseRenderer {

public static final String DEFAULT_CONTENT_TYPE = "text/css";

@Override
protected void startInlineElement(ResponseWriter writer, UIComponent component) throws IOException {
protected void startInlineElement(FacesContext context, ResponseWriter writer, UIComponent component) throws IOException {
writer.startElement("style", component);
writer.writeAttribute("type", "text/css", "type");
writeTypeAttributeIfNecessary(context, writer);
}

private void writeTypeAttributeIfNecessary(FacesContext context, ResponseWriter writer) throws IOException {
if (!RenderKitUtils.isOutputHtml5Doctype(context)) {
writer.writeAttribute("type", DEFAULT_CONTENT_TYPE, "type");
}
}

@Override
Expand All @@ -40,10 +51,10 @@ protected void endInlineElement(ResponseWriter writer, UIComponent component) th
}

@Override
protected void startExternalElement(ResponseWriter writer, UIComponent component) throws IOException {
protected void startExternalElement(FacesContext context, ResponseWriter writer, UIComponent component) throws IOException {
writer.startElement("link", component);
writer.writeAttribute("type", "text/css", "type");
writer.writeAttribute("rel", "stylesheet", "rel");
writeTypeAttributeIfNecessary(context, writer);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -584,13 +584,10 @@ if (!((faces && faces.specversion && faces.specversion >= 23000 ) &&
while (!!initialnodes && initialnodes.length > 0) {
var scriptStr = [];
scriptStr = initialnodes.shift().match(findscript);
// check the type - skip if it not javascript type
var type = [];
type = scriptStr[1].match(findtype);
if ( !!type && type[1]) {
if (type[1] !== "text/javascript") {
continue;
}
// check the type - skip if specified but not text/javascript
var type = scriptStr[1].match(findtype);
if (!!type && type[1] !== "text/javascript") {
continue;
}
scripts.push(scriptStr);
}
Expand Down Expand Up @@ -714,9 +711,9 @@ if (!((faces && faces.specversion && faces.specversion >= 23000 ) &&
var initialnodes = str.match(findlinks);
while (!!initialnodes && initialnodes.length > 0) {
var linkStr = initialnodes.shift().match(findlink);
// check the type - skip if it not css type
// check the type - skip if specified but not text/css
var type = linkStr[1].match(findtype);
if (!type || type[1] !== "text/css") {
if (!!type && type[1] !== "text/css") {
continue;
}
var href = linkStr[1].match(findhref);
Expand All @@ -727,8 +724,8 @@ if (!((faces && faces.specversion && faces.specversion >= 23000 ) &&

for (var i = 0; i < loadedLinks.length; i++) {
var linkNode = loadedLinks[i];

if (linkNode.getAttribute("type") === "text/css") {
var linkNodeType = linkNode.getAttribute("type");
if (!linkNodeType || linkNodeType === "text/css") {
var url = linkNode.getAttribute("href");

if (url) {
Expand Down

0 comments on commit 805a7df

Please sign in to comment.