开发者

How can I get JSF 2.0 to include JS as 'application/javascript' instead of 'text/javascript'

In our JSF 2.0 application at work, we include several javascript files via <h:outputscript>.

<h:outputScript library="javascript" name="DoStuff.js"/>

The resulting html references them as 'text/javascript'.

<script type="text/javascript" src="/mycontext/javax.faces.resource/DoStuff.js.jsf?ln=javascript"></script>

According to this question, "text/javascript" is obsolete, what's more, htmlunit complains about the type rather verbosely. O开发者_开发百科f course, everything works just fine and I could shut off htmlunit's logging, but I'd rather have JSF generate the correct type.

Is there a way to override the type chosen by <h:outputscript>?


This is hardcoded in the default renderer of the <h:outputScript>. Assuming that you're using Mojarra, it's the com.sun.faces.renderkit.html_basic.ScriptRenderer. According to the source, the type attribute is been set in the startElement method. You could just override it:

public class ExtendedScriptRenderer extends ScriptRenderer {

    @Override
    protected void startElement(ResponseWriter writer, UIComponent component) throws IOException {
        writer.startElement("script", component);
        writer.writeAttribute("type", "application/javascript", "type");
    }

}

Or if you want to provide the enduser the possibility to specify the type attribute itself and default to application/javascript when unspecified:

public class ExtendedScriptRenderer extends ScriptRenderer {

    @Override
    protected void startElement(ResponseWriter writer, UIComponent component) throws IOException {
        writer.startElement("script", component);
        String type = (String) component.getAttributes().get("type");
        if (type == null) type = "application/javascript";
        writer.writeAttribute("type", type, "type");
    }

}

To get it to run, register it as follows in faces-config.xml:

<render-kit>
    <renderer>
        <component-family>javax.faces.Output</component-family>
        <renderer-type>javax.faces.resource.Script</renderer-type>
        <renderer-class>com.example.ExtendedScriptRenderer</renderer-class>
    </renderer>
</render-kit>

There's by the way also the nice @FacesRenderer annotation which should work as follows

@FacesRenderer(componentFamily="javax.faces.Output", rendererType="javax.faces.resource.Script")
public class ExtendedScriptRenderer extends ScriptRenderer {

    // ...
}

However, when it's already been definied by a standard renderer (the ScriptRenderer!), then the custom one will fail to override it by a @FacesRenderer. See also issue 1748.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜