Toutes les réponses publiées jusqu'à présent donnent les bonnes solutions, mais aucune réponse n'a été en mesure d'expliquer correctement la cause sous-jacente du problème concret.
Facelets est une technologie d'affichage basée sur XML qui utilise XHTML + XML pour générer une sortie HTML. XML a cinq caractères spéciaux qui bénéficient d'un traitement spécial par l'analyseur XML:
<
le début d'une balise.
>
la fin d'une balise.
"
le début et la fin d'une valeur d'attribut.
'
le début et la fin alternatifs d'une valeur d'attribut.
&
le début d'une entité (qui se termine par ;
).
En cas de &
non suivie par #
(par exemple  
,  
etc.), l'analyseur XML est à la recherche implicitement pour l' un des cinq noms d'entités prédéfinies lt
, gt
, amp
, quot
et apos
, ou tout nom d'entité définie manuellement . Cependant, dans votre cas particulier, vous utilisiez &
comme opérateur JavaScript et non comme entité XML. Cela explique totalement l'erreur d'analyse XML que vous avez obtenue:
Le nom de l'entité doit immédiatement suivre le «&» dans la référence de l'entité
En substance, vous écrivez du code JavaScript au mauvais endroit, un document XML au lieu d'un fichier JS, vous devriez donc échapper tous les caractères spéciaux XML en conséquence. Le &
doit être échappé comme &
.
Donc, dans votre cas particulier, le
if (Modernizr.canvas && Modernizr.localstorage &&
doit devenir
if (Modernizr.canvas && Modernizr.localstorage &&
pour le rendre XML valide.
Cependant, cela rend le code JavaScript plus difficile à lire et à maintenir. Comme indiqué dans l'excellent document Writing JavaScript for XHTML de Mozilla Developer Network , vous devriez placer le code JavaScript dans un bloc de données de caractères (CDATA). Ainsi, en termes JSF, ce serait:
<h:outputScript>
<![CDATA[
// ...
]]>
</h:outputScript>
L'analyseur XML interprètera le contenu du bloc comme des données de caractère "plain vanilla" et non comme XML et interprètera donc les caractères spéciaux XML "tels quels".
Mais, mieux vaut simplement mettre le code JS dans son propre fichier JS que vous incluez par <script src>
, ou en termes JSF, le fichier <h:outputScript>
.
<h:outputScript name="onload.js" target="body" />
(notez le target="body"
; de cette façon JSF rendra automatiquement le <script>
à la toute fin de <body>
, quel que <h:outputScript>
soit son emplacement, obtenant ainsi le même effet qu'avec window.onload
et $(document).ready()
; vous n'avez donc plus besoin de les utiliser dans ce script)
De cette façon, vous n'avez pas à vous soucier des caractères spéciaux XML dans votre code JS. En prime, cela vous donne la possibilité de laisser le navigateur mettre en cache le fichier JS afin que la taille totale de la réponse soit plus petite.
Voir également: