Wszystkie opublikowane do tej pory odpowiedzi zawierają właściwe rozwiązania, jednak żadna z nich nie była w stanie poprawnie wyjaśnić przyczyny leżącej u podstaw konkretnego problemu.
Facelets to technologia widoku oparta na języku XML, która wykorzystuje XHTML + XML do generowania danych wyjściowych HTML. XML ma pięć znaków specjalnych, które są specjalnie traktowane przez parser XML:
< początek tagu.
> koniec tagu.
" początek i koniec wartości atrybutu.
' alternatywny początek i koniec wartości atrybutu.
&początek podmiotu (który kończy się ;).
W przypadku &których nie następuje #(np  ,  itp), parser XML jest niejawnie szuka jednej z pięciu predefiniowanych nazw jednostki lt , gt, amp, quoti apos, lub dowolny ręcznie zdefiniowana nazwa podmiotu . Jednak w twoim konkretnym przypadku byłeś używany &jako operator JavaScript, a nie jako jednostka XML. To całkowicie wyjaśnia błąd analizy XML, który otrzymałeś:
Nazwa jednostki musi znajdować się bezpośrednio po znaku „&” w odniesieniu do jednostki
Zasadniczo piszesz kod JavaScript w niewłaściwym miejscu, w dokumencie XML zamiast w pliku JS, więc powinieneś odpowiednio uciekać przed wszystkimi znakami specjalnymi XML. &Musi być uciekł jak &.
Tak więc w twoim konkretnym przypadku
if (Modernizr.canvas && Modernizr.localstorage &&
musi stać się
if (Modernizr.canvas && Modernizr.localstorage &&
aby był zgodny z XML.
Jednak to sprawia, że kod JavaScript jest trudniejszy do odczytania i utrzymania. Jak stwierdzono w doskonałym dokumencie Mozilla Developer Network Writing JavaScript for XHTML , kod JavaScript należy umieścić w bloku danych znakowych (CDATA). Zatem w kategoriach JSF byłoby to:
<h:outputScript>
<![CDATA[
// ...
]]>
</h:outputScript>
Parser XML zinterpretuje zawartość bloku jako dane znakowe „zwykłe”, a nie jako XML, a zatem interpretuje znaki specjalne XML „tak jak jest”.
Ale znacznie lepiej jest po prostu umieścić kod JS we własnym pliku JS, który dołączasz za pomocą <script src>lub w terminologii JSF, pliku <h:outputScript>.
<h:outputScript name="onload.js" target="body" />
(zwróć uwagę na target="body"; w ten sposób JSF automatycznie wyrenderuje plik <script>na samym końcu <body>, niezależnie od tego, gdzie <h:outputScript>się znajduje, uzyskując tym samym efekt, co z window.onloadi $(document).ready(); więc nie musisz już ich używać w tym skrypcie)
W ten sposób nie musisz martwić się o znaki specjalne XML w swoim kodzie JS. Jako dodatkowy bonus, daje to możliwość, aby przeglądarka buforowała plik JS, tak aby całkowity rozmiar odpowiedzi był mniejszy.
Zobacz też: