Todas as respostas postadas até agora fornecem as soluções corretas, mas nenhuma resposta foi capaz de explicar adequadamente a causa subjacente do problema concreto.
Facelets é uma tecnologia de visualização baseada em XML que usa XHTML + XML para gerar saída HTML. XML possui cinco caracteres especiais que têm tratamento especial pelo analisador XML:
<
o início de uma tag.
>
o fim de uma tag.
"
o início e o fim de um valor de atributo.
'
o início e o fim alternativos de um valor de atributo.
&
o início de uma entidade (que termina com ;
).
Em caso de &
que não é seguido por #
(por exemplo  
,  
, etc), o analisador XML é implicitamente à procura de um dos cinco nomes de entidades predefinidas lt
, gt
, amp
, quot
e apos
, ou qualquer nome de entidade definida manualmente . No entanto, em seu caso específico, você estava usando &
como um operador JavaScript, não como uma entidade XML. Isso explica totalmente o erro de análise de XML que você obteve:
O nome da entidade deve seguir imediatamente o '&' na referência da entidade
Em essência, você está escrevendo código JavaScript no lugar errado, um documento XML em vez de um arquivo JS, então você deve escapar todos os caracteres especiais XML de acordo. O &
deve ser escapado como &
.
Então, em seu caso particular, o
if (Modernizr.canvas && Modernizr.localstorage &&
deve se tornar
if (Modernizr.canvas && Modernizr.localstorage &&
para torná-lo válido para XML.
No entanto, isso torna o código JavaScript mais difícil de ler e manter. Conforme declarado no excelente documento do Mozilla Developer Network, Writing JavaScript for XHTML , você deve colocar o código JavaScript em um bloco de dados de caracteres (CDATA). Assim, em termos de JSF, isso seria:
<h:outputScript>
<![CDATA[
// ...
]]>
</h:outputScript>
O analisador XML interpretará o conteúdo do bloco como dados de caractere "plain vanilla" e não como XML e, portanto, interpretará os caracteres especiais XML "no estado em que se encontram".
Mas, muito melhor é apenas colocar o código JS em seu próprio arquivo JS que você inclui por <script src>
, ou em termos JSF, o <h:outputScript>
.
<h:outputScript name="onload.js" target="body" />
(observe o target="body"
; desta forma, o JSF renderizará automaticamente o <script>
no final de <body>
, independentemente de onde <h:outputScript>
ele esteja localizado, obtendo assim o mesmo efeito que com window.onload
e $(document).ready()
; portanto, você não precisa mais usá-los nesse script)
Dessa forma, você não precisa se preocupar com caracteres especiais XML em seu código JS. Como um bônus adicional, isso dá a oportunidade de permitir que o navegador armazene em cache o arquivo JS para que o tamanho total da resposta seja menor.
Veja também: