All answers posted so far are giving the right solutions, however no one answer was able to properly explain the underlying cause of the concrete problem.
Facelets is a XML based view technology which uses XHTML+XML to generate HTML output. XML has five special characters which has special treatment by the XML parser:
<
the start of a tag.>
the end of a tag."
the start and end of an attribute value.'
the alternative start and end of an attribute value.&
the start of an entity (which ends with;
).
In case of &
which is not followed by #
(e.g.  
,  
, etc), the XML parser is implicitly looking for one of the five predefined entity names lt
, gt
, amp
, quot
and apos
, or any manually defined entity name. However, in your particular case, you was using &
as a JavaScript operator, not as an XML entity. This totally explains the XML parsing error you got:
The entity name must immediately follow the ‘&’ in the entity reference
In essence, you’re writing JavaScript code in the wrong place, a XML document instead of a JS file, so you should be escaping all XML special characters accordingly. The &
must be escaped as &
.
So, in your particular case, the
if (Modernizr.canvas && Modernizr.localstorage &&
must become
if (Modernizr.canvas && Modernizr.localstorage &&
to make it XML-valid.
However, this makes the JavaScript code harder to read and maintain. In case when you want to continue using &
instead of &
in JavaScript code in a XML document, then you should be placing the JavaScript code in a character data (CDATA) block. Thus, in JSF terms, that would be:
<h:outputScript> <![CDATA[ // ... ]]> </h:outputScript>
The XML parser will interpret the block’s contents as “plain vanilla” character data and not as XML and hence interpret the XML special characters “as-is”.
But, much better is to just put the JS code in its own JS file which you include by <script src>
, or in JSF terms, the <h:outputScript>
.
<h:outputScript name="onload.js" target="body" />
(note the target="body"
; this way JSF will automatically render the <script>
at the very end of <body>
, regardless of where <h:outputScript>
itself is located, hereby achieving the same effect as with window.onload
and $(document).ready()
; so you don’t need to use those anymore in that script)
This way you don’t need to worry about XML-special characters in your JS code. As an additional bonus, this gives you the opportunity to let the browser cache the JS file so that total response size is smaller.