Как я могу получить JSF 2.0 для включения JS как «application / javascript» вместо «text / javascript» - PullRequest
6 голосов
/ 13 июля 2011

В нашем приложении JSF 2.0 на работе мы включаем несколько файлов javascript через <h:outputscript>.

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

Полученный html ссылается на них как 'text / javascript'.

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

Согласно этот вопрос , "text / javascript" устарел, более того, htmlunit довольно многословно жалуется на тип. Конечно, все работает просто отлично, и я мог бы отключить ведение журнала htmlunit, но я бы предпочел, чтобы JSF генерировал правильный тип.

Есть ли способ переопределить тип, выбранный <h:outputscript>?

1 Ответ

6 голосов
/ 13 июля 2011

Это жестко закодировано в стандартном рендере <h:outputScript>. Предполагая, что вы используете Мохарру, это com.sun.faces.renderkit.html_basic.ScriptRenderer. Согласно источнику, атрибут type был установлен в методе startElement. Вы можете просто переопределить это:

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");
    }

}

Или, если вы хотите предоставить конечному пользователю возможность указать сам атрибут type и значение по умолчанию application/javascript, если оно не указано:

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");
    }

}

Чтобы запустить его, зарегистрируйте его в 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>

Кстати, есть и приятная аннотация @FacesRenderer, которая должна работать следующим образом

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

    // ...
}

Однако, когда он уже определен стандартным рендерером (ScriptRenderer!), Пользовательский не сможет переопределить его на @FacesRenderer. См. Также выпуск 1748 .

...