11import { Injectable } from 'angular2/di' ;
22import { isBlank , isPresent , BaseException , stringify } from 'angular2/src/facade/lang' ;
3- import { Map , MapWrapper , StringMapWrapper , StringMap } from 'angular2/src/facade/collection' ;
3+ import { Map , MapWrapper , ListWrapper } from 'angular2/src/facade/collection' ;
44import { PromiseWrapper , Promise } from 'angular2/src/facade/async' ;
55import { DOM } from 'angular2/src/dom/dom_adapter' ;
66
@@ -15,35 +15,62 @@ import {UrlResolver} from 'angular2/src/services/url_resolver';
1515 */
1616@Injectable ( )
1717export class TemplateLoader {
18- _htmlCache : StringMap < string , /*element*/ any > = StringMapWrapper . create ( ) ;
18+ _cache : Map < string , Promise < string > > = MapWrapper . create ( ) ;
1919
20- constructor ( public _xhr : XHR , urlResolver : UrlResolver ) { }
20+ constructor ( private _xhr : XHR , urlResolver : UrlResolver ) { }
2121
22- load ( template : ViewDefinition ) : Promise < /*element*/ any > {
23- if ( isPresent ( template . template ) ) {
24- return PromiseWrapper . resolve ( DOM . createTemplate ( template . template ) ) ;
22+ load ( view : ViewDefinition ) : Promise < /*element*/ any > {
23+ let html ;
24+ let fetchedStyles ;
25+
26+ // Load the HTML
27+ if ( isPresent ( view . template ) ) {
28+ html = PromiseWrapper . resolve ( view . template ) ;
29+ } else if ( isPresent ( view . templateAbsUrl ) ) {
30+ html = this . _loadText ( view . templateAbsUrl ) ;
31+ } else {
32+ throw new BaseException ( 'View should have either the templateUrl or template property set' ) ;
33+ }
34+
35+ // Load the styles
36+ if ( isPresent ( view . styleAbsUrls ) && view . styleAbsUrls . length > 0 ) {
37+ fetchedStyles = ListWrapper . map ( view . styleAbsUrls , url => this . _loadText ( url ) ) ;
38+ } else {
39+ fetchedStyles = [ ] ;
2540 }
26- var url = template . absUrl ;
27- if ( isPresent ( url ) ) {
28- var promise = StringMapWrapper . get ( this . _htmlCache , url ) ;
29-
30- if ( isBlank ( promise ) ) {
31- // TODO(vicb): change error when TS gets fixed
32- // https://github.com/angular/angular/issues/2280
33- // throw new BaseException(`Failed to fetch url "${url}"`);
34- promise = PromiseWrapper . then ( this . _xhr . get ( url ) , html => {
35- var template = DOM . createTemplate ( html ) ;
36- return template ;
37- } , _ => PromiseWrapper . reject ( new BaseException ( `Failed to fetch url "${ url } "` ) , null ) ) ;
38-
39- StringMapWrapper . set ( this . _htmlCache , url , promise ) ;
40- }
41-
42- // We need to clone the result as others might change it
43- // (e.g. the compiler).
44- return promise . then ( ( tplElement ) => DOM . clone ( tplElement ) ) ;
41+
42+ // Inline the styles and return a template element
43+ return PromiseWrapper . all ( ListWrapper . concat ( [ html ] , fetchedStyles ) )
44+ . then ( ( res : List < string > ) => {
45+ let html = res [ 0 ] ;
46+ let fetchedStyles = ListWrapper . slice ( res , 1 ) ;
47+
48+ html = _createStyleTags ( view . styles ) + _createStyleTags ( fetchedStyles ) + html ;
49+
50+ return DOM . createTemplate ( html ) ;
51+ } ) ;
52+ }
53+
54+ private _loadText ( url : string ) : Promise < string > {
55+ var response = MapWrapper . get ( this . _cache , url ) ;
56+
57+ if ( isBlank ( response ) ) {
58+ // TODO(vicb): change error when TS gets fixed
59+ // https://github.com/angular/angular/issues/2280
60+ // throw new BaseException(`Failed to fetch url "${url}"`);
61+ response = PromiseWrapper . catchError (
62+ this . _xhr . get ( url ) ,
63+ _ => PromiseWrapper . reject ( new BaseException ( `Failed to fetch url "${ url } "` ) , null ) ) ;
64+
65+ MapWrapper . set ( this . _cache , url , response ) ;
4566 }
4667
47- throw new BaseException ( 'View should have either the url or template property set' ) ;
68+ return response ;
4869 }
4970}
71+
72+ function _createStyleTags ( styles ?: List < string > ) : string {
73+ return isBlank ( styles ) ?
74+ '' :
75+ ListWrapper . map ( styles , css => `<style type='text/css'>${ css } </style>` ) . join ( '' ) ;
76+ }
0 commit comments