HTML Literal in JavaScript
==========================

Examples:

   function addUserBox(userlist, username, icon) {
     var section = @<section class="user"><h1>{username}</h1></section>;
     if (icon)
       section.append(@<img src="{icon}" alt=""/>);
     userlist.append(section);
   }

   function addCheckbox(name, label, checked, enabled) {
     return @<label><input type="checkbox" name={name}
              checked?={checked} disabled?={!enabled}/> {label}</label>;
   }


Support:

This new syntax must only be supported in scripts that are CORS
same-origin and in Window (not Worker) contexts. (Otherwise, we risk
leaking XML files and exposing the DOM to workers.) The "@" and "<>"
syntax pieces also help mitigate this risk, since they can't appear at
the start of valid XML files.


Syntax:

   Literal      := ; everything that it accepts today, plus html-literal.

   html-literal := fragment | "@" element
   fragment     := "<>" contents "</>"
   contents     := ( element | element-text | substitution )*;
   element      := ( starttag contents* endtag | emptytag )
   starttag     := "<" elementname [ WhiteSpace attribute ]* ">"
   emptytag     := "<" elementname [ WhiteSpace attribute ]* "/>"
   endtag       := "</" elementname ">"  ; must match elementname of corresponding starttag production
   elementname  := ( "svg:" | "math:" )? IdentifierPart
   attribute    := attribute-s | attribute-b
   attribute-s  := IdentifierPart "=" ( subst-string | substitution )
   attribute-b  := IdentifierPart "?=" ( substitution )
   subst-string :=   "'" ( subst-text-1 | substitution )* "'" 
                   | """ ( subst-text-2 | substitution )* """
   substitution := "{" Expression "}"
   element-text := SourceCharacter but not "<", "{", "\", or LineTerminator
                   | EscapeSequence
                   | LineContinuation
   subst-text-1 := SourceCharacter but not "'", "{", "\", or LineTerminator
                   | EscapeSequence
                   | LineContinuation
   subst-text-2 := SourceCharacter but not """, "{", "\", or LineTerminator
                   | EscapeSequence
                   | LineContinuation


The production "fragment" is evaluated as follows:

   1. let DF be the result of calling document.createDocumentFragment.

   2. call DF.appendChild() once for the result of evaluating each
      production in the "fragment" production's "contents" production
      in source order.

   3. return DF.

The production "element" is evaluated as follows:

   1. let E be the result of calling document.createElementNS with as
      the the first argument the IdentifierPart in the production's
      starttag or emptytag production's "elementname" production, and
      as its second argument the HTML namespace if that "elementname"
      production has only the IdentifierPart component, the SVG
      namespace if that production starts with "svg:", and the MathML
      namespace if that production starts with "math:".

   2. for each attribute production in the element production's
      starttag or emptytag production, evaluate the attribute-s or
      attribute-b child production as follows:

      attribute-s: call E.setAttribute() with the value of the
        attribute production's IdentifierPart production as the first
        argument, and the result of evaluating the attribute
        production's subst-string or substitution production as the
        second argument.

      attribute-b: evaluate the attribute production's substitution
        production, and proceed using the steps for first of the
        following conditions to match the result:

        if the type of the result is undefined, or is an object whose
        value is equal to null, or is a boolean whose value is equal
        to false: do nothing

        if the type of the result is boolean: call E.setAttribute()
          with the value of the attribute production's IdentifierPart
          production as the first argument, and the empty string as
          the second argument.

        otherwise: call E.setAttribute() with the value of the
          attribute production's IdentifierPart production as the
          first argument, and the stringification of the result as the
          second argument.

   3. call DF.appendChild() once for the result of evaluating each
      production in the "element" production's "contents" production
      in source order, if the production has a "contents" production.

The "subst-string" production evaluates to the string formed by
concatenating the result of evaluating each child "subst-text-1",
"subst-text-2", and "substitution" production in sequence.

The productions "element-text", "subst-text-1", and "subst-text-2"
evaluate the same way as the "DoubleStringCharacters" or
"SingleStringCharacters" productions.

The production "substitution" evaluates the same way as its Expression
production.


Possible improvements: use the namespace of the parent element if none
is explicitly given, defaulting to html: if there's no parent. so e.g.:

   var x = @<svg:svg><g><foreignObject><html:p><span/></html:p></foreignObject></g></svg:svg>;
