diff --git a/lib/block.dart b/lib/block.dart index 983bcc640..e78a5f7f2 100644 --- a/lib/block.dart +++ b/lib/block.dart @@ -344,21 +344,23 @@ class ComponentWrapper { Parser parser; Block shadowBlock; - ComponentWrapper(this.directiveRef, this.controller, this.elementRoot, this.parser, $compiler, $http) { var directive = directiveRef.directive; var shadowRoot = elementRoot.createShadowRoot(); + var styleData = ''; + if (directive.$cssUrl != null) { + styleData = ''; + } + _appendAndCompileTemplate(data) { - shadowRoot.innerHtml = data; + shadowRoot.innerHtml = styleData + data shadowBlock = $compiler(shadowRoot.nodes)(shadowRoot.nodes); } // There is support here for directives having both $template and // $templateUrl. This could be a clever way to add a 'LOADING' // message. - if (directive.$template != null) { - _appendAndCompileTemplate(directive.$template); - } + _appendAndCompileTemplate(directive.$template != null ? directive.$template : ''); if (directive.$templateUrl != null) { $http.getString(directive.$templateUrl).then((data) { diff --git a/lib/directive.dart b/lib/directive.dart index 4a2d8a7d7..b2fd09b25 100644 --- a/lib/directive.dart +++ b/lib/directive.dart @@ -13,6 +13,7 @@ class Directive { Type $controllerType; String $template; String $templateUrl; + String $cssUrl; Map $map; bool isComponent = false; @@ -43,6 +44,7 @@ class Directive { $transclude = reflectStaticField(type, '\$transclude'); $template = reflectStaticField(type, '\$template'); $templateUrl = reflectStaticField(type, '\$templateUrl'); + $cssUrl = reflectStaticField(type, '\$cssUrl'); $priority = reflectStaticField(type, '\$priority'); $map = reflectStaticField(type, '\$map'); if ($priority == null) { diff --git a/test/_http.dart b/test/_http.dart index e18c72535..159884ba6 100644 --- a/test/_http.dart +++ b/test/_http.dart @@ -13,7 +13,8 @@ class MockHttp extends Http { gets[url] = content; } - flush() => Future.wait(futures); + flush() => gets.length == 0 ? Future.wait(futures) : + throw "Expected GETs not called $gets"; Future getString(String url, {bool withCredentials, void onProgress(ProgressEvent e)}) { if (!gets.containsKey(url)) throw "Unexpected URL $url"; diff --git a/test/_http_spec.dart b/test/_http_spec.dart index e9b13e86f..e545bb9b2 100644 --- a/test/_http_spec.dart +++ b/test/_http_spec.dart @@ -20,5 +20,12 @@ main() { http.getString('unknown'); }).toThrow('Unexpected URL unknown'); }); + + it('should barf on hanging requests', () { + http.expectGET('request', 'response'); + expect(() { + http.flush(); + }).toThrow('Expected GETs not called {request: response}'); + }); }); } diff --git a/test/templateurl_spec.dart b/test/templateurl_spec.dart index 74755186c..a3a761d05 100644 --- a/test/templateurl_spec.dart +++ b/test/templateurl_spec.dart @@ -16,17 +16,37 @@ class SimpleUrlComponent { attach(Scope scope) {} } +class HtmlAndCssComponent { + static String $templateUrl = 'simple.html'; + static String $cssUrl = 'simple.css'; + attach(Scope scope) {} +} + +class InlineWithCssComponent { + static String $template = '
inline!
'; + static String $cssUrl = 'simple.css'; + attach(Scope scope) {} +} + +class OnlyCssComponent { + static String $cssUrl = 'simple.css'; + attach(Scope scope) {} +} + main() { - describe('templateUrl', () { + describe('async template loading', () { beforeEach(module((module) { var mockHttp = new MockHttp(); module.value(MockHttp, mockHttp); module.value(Http, mockHttp); module.directive(LogAttrDirective); module.directive(SimpleUrlComponent); + module.directive(HtmlAndCssComponent); + module.directive(OnlyCssComponent); + module.directive(InlineWithCssComponent); })); - it('should replace element with template from url', inject((MockHttp $http, Compiler $compile, Scope $rootScope, Log log) { + it('should replace element with template from url', inject((MockHttp $http, Compiler $compile, Scope $rootScope, Log log) { $http.expectGET('simple.html', '
Simple!
'); var element = $('
ignore
'); @@ -37,7 +57,35 @@ main() { // Note: There is no ordering. It is who ever comes off the wire first! expect(log.result()).toEqual('LOG; SIMPLE'); })); + })); + + it('should load a CSS file into a style', inject((MockHttp $http, Compiler $compile, Scope $rootScope, Log log) { + $http.expectGET('simple.html', '
Simple!
'); + + var element = $('
ignore
'); + $compile(element)(element)..attach($rootScope); + + $http.flush().then(expectAsync1((data) { + expect(renderedText(element)).toEqual('@import "simple.css"Simple!'); + expect(element[0].nodes[0].shadowRoot.innerHtml).toEqual( + '
Simple!
' + ); + // Note: There is no ordering. It is who ever comes off the wire first! + expect(log.result()).toEqual('LOG; SIMPLE'); + })); + })); + + it('should load a CSS file with a \$template', inject((Compiler $compile, Scope $rootScope) { + var element = $('
ignore
'); + $compile(element)(element)..attach($rootScope); + expect(renderedText(element)).toEqual('@import "simple.css"inline!'); + })); + + it('should load a CSS with no template', inject((Compiler $compile, Scope $rootScope) { + var element = $('
ignore
'); + $compile(element)(element)..attach($rootScope); + expect(renderedText(element)).toEqual('@import "simple.css"'); })); }); }