@@ -9,34 +9,22 @@ import {
99 serializeEnum ,
1010 CONST_EXPR
1111} from 'angular2/src/facade/lang' ;
12- import { DOM } from 'angular2/src/core/dom/dom_adapter' ;
12+
1313import { ListWrapper } from 'angular2/src/facade/collection' ;
1414
1515import { HtmlAst , HtmlAttrAst , HtmlTextAst , HtmlElementAst } from './html_ast' ;
1616
17- import { escapeDoubleQuoteString } from './util' ;
1817import { Injectable } from 'angular2/src/core/di' ;
1918import { HtmlToken , HtmlTokenType , tokenizeHtml } from './html_lexer' ;
2019import { ParseError , ParseLocation , ParseSourceSpan } from './parse_util' ;
2120import { HtmlTagDefinition , getHtmlTagDefinition } from './html_tags' ;
2221
23- // TODO: remove this, just provide a plain error message!
24- export enum HtmlTreeErrorType {
25- UnexpectedClosingTag
26- }
27-
28- const HTML_ERROR_TYPE_MSGS = CONST_EXPR ( [ 'Unexpected closing tag' ] ) ;
29-
30-
3122export class HtmlTreeError extends ParseError {
32- static create ( type : HtmlTreeErrorType , elementName : string ,
33- location : ParseLocation ) : HtmlTreeError {
34- return new HtmlTreeError ( type , HTML_ERROR_TYPE_MSGS [ serializeEnum ( type ) ] , elementName ,
35- location ) ;
23+ static create ( elementName : string , location : ParseLocation , msg : string ) : HtmlTreeError {
24+ return new HtmlTreeError ( elementName , location , msg ) ;
3625 }
3726
38- constructor ( public type : HtmlTreeErrorType , msg : string , public elementName : string ,
39- location : ParseLocation ) {
27+ constructor ( public elementName : string , location : ParseLocation , msg : string ) {
4028 super ( location , msg ) ;
4129 }
4230}
@@ -55,11 +43,8 @@ export class HtmlParser {
5543 }
5644}
5745
58- var NS_PREFIX_RE = / ^ @ [ ^ : ] + / g;
59-
6046class TreeBuilder {
6147 private index : number = - 1 ;
62- private length : number ;
6348 private peek : HtmlToken ;
6449
6550 private rootNodes : HtmlAst [ ] = [ ] ;
@@ -129,7 +114,7 @@ class TreeBuilder {
129114 while ( this . peek . type === HtmlTokenType . ATTR_NAME ) {
130115 attrs . push ( this . _consumeAttr ( this . _advance ( ) ) ) ;
131116 }
132- var fullName = elementName ( prefix , name , this . _getParentElement ( ) ) ;
117+ var fullName = getElementFullName ( prefix , name , this . _getParentElement ( ) ) ;
133118 var voidElement = false ;
134119 // Note: There could have been a tokenizer error
135120 // so that we don't get a token for the end tag...
@@ -150,15 +135,12 @@ class TreeBuilder {
150135 }
151136
152137 private _pushElement ( el : HtmlElementAst ) {
153- var stackIndex = this . elementStack . length - 1 ;
154- while ( stackIndex >= 0 ) {
155- var parentEl = this . elementStack [ stackIndex ] ;
156- if ( ! getHtmlTagDefinition ( parentEl . name ) . isClosedByChild ( el . name ) ) {
157- break ;
138+ if ( this . elementStack . length > 0 ) {
139+ var parentEl = ListWrapper . last ( this . elementStack ) ;
140+ if ( getHtmlTagDefinition ( parentEl . name ) . isClosedByChild ( el . name ) ) {
141+ this . elementStack . pop ( ) ;
158142 }
159- stackIndex -- ;
160143 }
161- this . elementStack . splice ( stackIndex , this . elementStack . length - 1 - stackIndex ) ;
162144
163145 var tagDef = getHtmlTagDefinition ( el . name ) ;
164146 var parentEl = this . _getParentElement ( ) ;
@@ -175,35 +157,29 @@ class TreeBuilder {
175157
176158 private _consumeEndTag ( endTagToken : HtmlToken ) {
177159 var fullName =
178- elementName ( endTagToken . parts [ 0 ] , endTagToken . parts [ 1 ] , this . _getParentElement ( ) ) ;
160+ getElementFullName ( endTagToken . parts [ 0 ] , endTagToken . parts [ 1 ] , this . _getParentElement ( ) ) ;
179161 if ( ! this . _popElement ( fullName ) ) {
180- this . errors . push ( HtmlTreeError . create ( HtmlTreeErrorType . UnexpectedClosingTag , fullName ,
181- endTagToken . sourceSpan . start ) ) ;
162+ this . errors . push ( HtmlTreeError . create ( fullName , endTagToken . sourceSpan . start ,
163+ `Unexpected closing tag " ${ endTagToken . parts [ 1 ] } "` ) ) ;
182164 }
183165 }
184166
185167 private _popElement ( fullName : string ) : boolean {
186- var stackIndex = this . elementStack . length - 1 ;
187- var hasError = false ;
188- while ( stackIndex >= 0 ) {
168+ for ( let stackIndex = this . elementStack . length - 1 ; stackIndex >= 0 ; stackIndex -- ) {
189169 var el = this . elementStack [ stackIndex ] ;
190- if ( el . name == fullName ) {
191- break ;
170+ if ( el . name . toLowerCase ( ) == fullName . toLowerCase ( ) ) {
171+ ListWrapper . splice ( this . elementStack , stackIndex , this . elementStack . length - stackIndex ) ;
172+ return true ;
192173 }
193174 if ( ! getHtmlTagDefinition ( el . name ) . closedByParent ) {
194- hasError = true ;
195- break ;
175+ return false ;
196176 }
197- stackIndex -- ;
198- }
199- if ( ! hasError ) {
200- this . elementStack . splice ( stackIndex , this . elementStack . length - stackIndex ) ;
201177 }
202- return ! hasError ;
178+ return false ;
203179 }
204180
205181 private _consumeAttr ( attrName : HtmlToken ) : HtmlAttrAst {
206- var fullName = elementName ( attrName . parts [ 0 ] , attrName . parts [ 1 ] , null ) ;
182+ var fullName = mergeNsAndName ( attrName . parts [ 0 ] , attrName . parts [ 1 ] ) ;
207183 var end = attrName . sourceSpan . end ;
208184 var value = '' ;
209185 if ( this . peek . type === HtmlTokenType . ATTR_VALUE ) {
@@ -228,20 +204,24 @@ class TreeBuilder {
228204 }
229205}
230206
231- function elementName ( prefix : string , localName : string , parentElement : HtmlElementAst ) {
207+ function mergeNsAndName ( prefix : string , localName : string ) : string {
208+ return isPresent ( prefix ) ? `@${ prefix } :${ localName } ` : localName ;
209+ }
210+
211+ function getElementFullName ( prefix : string , localName : string ,
212+ parentElement : HtmlElementAst ) : string {
232213 if ( isBlank ( prefix ) ) {
233214 prefix = getHtmlTagDefinition ( localName ) . implicitNamespacePrefix ;
215+ if ( isBlank ( prefix ) && isPresent ( parentElement ) ) {
216+ prefix = namespacePrefix ( parentElement . name ) ;
217+ }
234218 }
235- if ( isBlank ( prefix ) && isPresent ( parentElement ) ) {
236- prefix = namespacePrefix ( parentElement . name ) ;
237- }
238- if ( isPresent ( prefix ) ) {
239- return `@${ prefix } :${ localName } ` ;
240- } else {
241- return localName ;
242- }
219+
220+ return mergeNsAndName ( prefix , localName ) ;
243221}
244222
223+ var NS_PREFIX_RE = / ^ @ ( [ ^ : ] + ) / g;
224+
245225function namespacePrefix ( elementName : string ) : string {
246226 var match = RegExpWrapper . firstMatch ( NS_PREFIX_RE , elementName ) ;
247227 return isBlank ( match ) ? null : match [ 1 ] ;
0 commit comments