HTML Literal in JavaScript
==========================
Examples:
function addUserBox(userlist, username, icon) {
var section = @
{username}
;
if (icon)
section.append(@);
userlist.append(section);
}
function addCheckbox(name, label, checked, enabled) {
return @;
}
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 = @;