11import { isPresent , isBlank , normalizeBool , CONST_EXPR } from 'angular2/src/facade/lang' ;
22
3- // TODO: fill this!
4- export const NAMED_ENTITIES : { [ key : string ] : string } = < any > CONST_EXPR ( { 'amp' : '&' } ) ;
3+ // see http://www.w3.org/TR/html51/syntax.html#named-character-references
4+ // see https://html.spec.whatwg.org/multipage/entities.json
5+ // This list is not exhaustive to keep the compiler footprint low.
6+ // The `{` / `ƫ` syntax should be used when the named character reference does not exist.
7+ export const NAMED_ENTITIES = CONST_EXPR ( {
8+ 'lt' : '<' ,
9+ 'gt' : '>' ,
10+ 'nbsp' : '\u00A0' ,
11+ 'amp' : '&' ,
12+ 'Aacute' : '\u00C1' ,
13+ 'Acirc' : '\u00C2' ,
14+ 'Agrave' : '\u00C0' ,
15+ 'Atilde' : '\u00C3' ,
16+ 'Auml' : '\u00C4' ,
17+ 'Ccedil' : '\u00C7' ,
18+ 'Eacute' : '\u00C9' ,
19+ 'Ecirc' : '\u00CA' ,
20+ 'Egrave' : '\u00C8' ,
21+ 'Euml' : '\u00CB' ,
22+ 'Iacute' : '\u00CD' ,
23+ 'Icirc' : '\u00CE' ,
24+ 'Igrave' : '\u00CC' ,
25+ 'Iuml' : '\u00CF' ,
26+ 'Oacute' : '\u00D3' ,
27+ 'Ocirc' : '\u00D4' ,
28+ 'Ograve' : '\u00D2' ,
29+ 'Otilde' : '\u00D5' ,
30+ 'Ouml' : '\u00D6' ,
31+ 'Uacute' : '\u00DA' ,
32+ 'Ucirc' : '\u00DB' ,
33+ 'Ugrave' : '\u00D9' ,
34+ 'Uuml' : '\u00DC' ,
35+ 'aacute' : '\u00E1' ,
36+ 'acirc' : '\u00E2' ,
37+ 'agrave' : '\u00E0' ,
38+ 'atilde' : '\u00E3' ,
39+ 'auml' : '\u00E4' ,
40+ 'ccedil' : '\u00E7' ,
41+ 'eacute' : '\u00E9' ,
42+ 'ecirc' : '\u00EA' ,
43+ 'egrave' : '\u00E8' ,
44+ 'euml' : '\u00EB' ,
45+ 'iacute' : '\u00ED' ,
46+ 'icirc' : '\u00EE' ,
47+ 'igrave' : '\u00EC' ,
48+ 'iuml' : '\u00EF' ,
49+ 'oacute' : '\u00F3' ,
50+ 'ocirc' : '\u00F4' ,
51+ 'ograve' : '\u00F2' ,
52+ 'otilde' : '\u00F5' ,
53+ 'ouml' : '\u00F6' ,
54+ 'uacute' : '\u00FA' ,
55+ 'ucirc' : '\u00FB' ,
56+ 'ugrave' : '\u00F9' ,
57+ 'uuml' : '\u00FC' ,
58+ } ) ;
559
660export enum HtmlTagContentType {
761 RAW_TEXT ,
@@ -11,54 +65,72 @@ export enum HtmlTagContentType {
1165
1266export class HtmlTagDefinition {
1367 private closedByChildren : { [ key : string ] : boolean } = { } ;
14- public closedByParent : boolean ;
68+ public closedByParent : boolean = false ;
1569 public requiredParent : string ;
1670 public implicitNamespacePrefix : string ;
1771 public contentType : HtmlTagContentType ;
1872
1973 constructor ( { closedByChildren, requiredParent, implicitNamespacePrefix, contentType} : {
20- closedByChildren ?: string [ ] ,
74+ closedByChildren ?: string ,
2175 requiredParent ?: string ,
2276 implicitNamespacePrefix ?: string ,
2377 contentType ?: HtmlTagContentType
2478 } = { } ) {
25- if ( isPresent ( closedByChildren ) ) {
26- closedByChildren . forEach ( tagName => this . closedByChildren [ tagName ] = true ) ;
79+ if ( isPresent ( closedByChildren ) && closedByChildren . length > 0 ) {
80+ closedByChildren . split ( ',' ) . forEach ( tagName => this . closedByChildren [ tagName . trim ( ) ] = true ) ;
81+ this . closedByParent = true ;
2782 }
28- this . closedByParent = isPresent ( closedByChildren ) && closedByChildren . length > 0 ;
2983 this . requiredParent = requiredParent ;
3084 this . implicitNamespacePrefix = implicitNamespacePrefix ;
3185 this . contentType = isPresent ( contentType ) ? contentType : HtmlTagContentType . PARSABLE_DATA ;
3286 }
3387
34- requireExtraParent ( currentParent : string ) {
88+ requireExtraParent ( currentParent : string ) : boolean {
3589 return isPresent ( this . requiredParent ) &&
36- ( isBlank ( currentParent ) || this . requiredParent != currentParent . toLocaleLowerCase ( ) ) ;
90+ ( isBlank ( currentParent ) || this . requiredParent != currentParent . toLowerCase ( ) ) ;
3791 }
3892
39- isClosedByChild ( name : string ) {
93+ isClosedByChild ( name : string ) : boolean {
4094 return normalizeBool ( this . closedByChildren [ '*' ] ) ||
4195 normalizeBool ( this . closedByChildren [ name . toLowerCase ( ) ] ) ;
4296 }
4397}
4498
45- // TODO: Fill this table using
46- // https://github.com/greim/html-tokenizer/blob/master/parser.js
47- // and http://www.w3.org/TR/html51/syntax.html#optional-tags
99+ // see http://www.w3.org/TR/html51/syntax.html#optional-tags
100+ // This implementation does not fully conform to the HTML5 spec.
48101var TAG_DEFINITIONS : { [ key : string ] : HtmlTagDefinition } = {
49- 'link' : new HtmlTagDefinition ( { closedByChildren : [ '*' ] } ) ,
50- 'ng-content' : new HtmlTagDefinition ( { closedByChildren : [ '*' ] } ) ,
51- 'img' : new HtmlTagDefinition ( { closedByChildren : [ '*' ] } ) ,
52- 'input' : new HtmlTagDefinition ( { closedByChildren : [ '*' ] } ) ,
53- 'p' : new HtmlTagDefinition ( { closedByChildren : [ 'p' ] } ) ,
54- 'tr' : new HtmlTagDefinition ( { closedByChildren : [ 'tr' ] , requiredParent : 'tbody' } ) ,
55- 'col' : new HtmlTagDefinition ( { closedByChildren : [ 'col' ] , requiredParent : 'colgroup' } ) ,
102+ 'link' : new HtmlTagDefinition ( { closedByChildren : '*' } ) ,
103+ 'ng-content' : new HtmlTagDefinition ( { closedByChildren : '*' } ) ,
104+ 'img' : new HtmlTagDefinition ( { closedByChildren : '*' } ) ,
105+ 'input' : new HtmlTagDefinition ( { closedByChildren : '*' } ) ,
106+ 'hr' : new HtmlTagDefinition ( { closedByChildren : '*' } ) ,
107+ 'br' : new HtmlTagDefinition ( { closedByChildren : '*' } ) ,
108+ 'wbr' : new HtmlTagDefinition ( { closedByChildren : '*' } ) ,
109+ 'p' : new HtmlTagDefinition ( {
110+ closedByChildren :
111+ 'address,article,aside,blockquote,div,dl,fieldset,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,main,nav,ol,p,pre,section,table,ul'
112+ } ) ,
113+ 'thead' : new HtmlTagDefinition ( { closedByChildren : 'tbody,tfoot' } ) ,
114+ 'tbody' : new HtmlTagDefinition ( { closedByChildren : 'tbody,tfoot' } ) ,
115+ 'tfoot' : new HtmlTagDefinition ( { closedByChildren : 'tbody' } ) ,
116+ 'tr' : new HtmlTagDefinition ( { closedByChildren : 'tr' , requiredParent : 'tbody' } ) ,
117+ 'td' : new HtmlTagDefinition ( { closedByChildren : 'td,th' } ) ,
118+ 'th' : new HtmlTagDefinition ( { closedByChildren : 'td,th' } ) ,
119+ 'col' : new HtmlTagDefinition ( { closedByChildren : 'col' , requiredParent : 'colgroup' } ) ,
56120 'svg' : new HtmlTagDefinition ( { implicitNamespacePrefix : 'svg' } ) ,
57121 'math' : new HtmlTagDefinition ( { implicitNamespacePrefix : 'math' } ) ,
122+ 'li' : new HtmlTagDefinition ( { closedByChildren : 'li' } ) ,
123+ 'dt' : new HtmlTagDefinition ( { closedByChildren : 'dt,dd' } ) ,
124+ 'dd' : new HtmlTagDefinition ( { closedByChildren : 'dt,dd' } ) ,
125+ 'rb' : new HtmlTagDefinition ( { closedByChildren : 'rb,rt,rtc,rp' } ) ,
126+ 'rt' : new HtmlTagDefinition ( { closedByChildren : 'rb,rt,rtc,rp' } ) ,
127+ 'rtc' : new HtmlTagDefinition ( { closedByChildren : 'rb,rtc,rp' } ) ,
128+ 'rp' : new HtmlTagDefinition ( { closedByChildren : 'rb,rt,rtc,rp' } ) ,
129+ 'optgroup' : new HtmlTagDefinition ( { closedByChildren : 'optgroup' } ) ,
58130 'style' : new HtmlTagDefinition ( { contentType : HtmlTagContentType . RAW_TEXT } ) ,
59131 'script' : new HtmlTagDefinition ( { contentType : HtmlTagContentType . RAW_TEXT } ) ,
60132 'title' : new HtmlTagDefinition ( { contentType : HtmlTagContentType . ESCAPABLE_RAW_TEXT } ) ,
61- 'textarea' : new HtmlTagDefinition ( { contentType : HtmlTagContentType . ESCAPABLE_RAW_TEXT } )
133+ 'textarea' : new HtmlTagDefinition ( { contentType : HtmlTagContentType . ESCAPABLE_RAW_TEXT } ) ,
62134} ;
63135
64136var DEFAULT_TAG_DEFINITION = new HtmlTagDefinition ( ) ;
0 commit comments