diff --git a/lib/block.dart b/lib/block.dart index b70c1b4dc..c2960e1e5 100644 --- a/lib/block.dart +++ b/lib/block.dart @@ -106,8 +106,8 @@ class Block implements ElementWrapper { if (ref.directive.isComponent) { //nodeModule.factory(type, new ComponentFactory(node, ref.directive), visibility: visibility); // TODO(misko): there should be no need to wrap function like this. - nodeModule.factory(type, (Injector injector, Compiler compiler, Scope scope, Parser parser, BlockCache $blockCache, UrlRewriter urlRewriter) => - (new _ComponentFactory(node, ref.directive))(injector, compiler, scope, parser, $blockCache, urlRewriter), + nodeModule.factory(type, (Injector injector, Compiler compiler, Scope scope, Parser parser, BlockCache $blockCache, Http http, TemplateCache templateCache) => + (new _ComponentFactory(node, ref.directive))(injector, compiler, scope, parser, $blockCache, http, templateCache), visibility: visibility); } else { nodeModule.type(type, type, visibility: visibility); @@ -272,7 +272,8 @@ class _ComponentFactory { _ComponentFactory(this.element, this.directive); dynamic call(Injector injector, Compiler compiler, Scope scope, - Parser parser, BlockCache $blockCache, UrlRewriter urlRewriter) { + Parser parser, BlockCache $blockCache, Http $http, + TemplateCache $templateCache) { this.compiler = compiler; shadowDom = element.createShadowRoot(); shadowDom.applyAuthorStyles = @@ -282,19 +283,36 @@ class _ComponentFactory { shadowScope = scope.$new(true); createAttributeMapping(scope, shadowScope, parser); + + // TODO(pavelgj): fetching CSS with Http is mainly an attempt to + // work around an unfiled Chrome bug when reloading same CSS breaks + // styles all over the page. We shouldn't be doing browsers work, + // so change back to using @import once Chrome bug is fixed or a + // better work around is found. + async.Future cssFuture; if (directive.$cssUrl != null) { - shadowDom.innerHtml = ''; + cssFuture = $http.getString(directive.$cssUrl, cache: $templateCache); + } else { + cssFuture = new async.Future.value(null); } - TemplateLoader templateLoader; + var blockFuture; if (directive.$template != null) { - var blockFuture = new async.Future.value().then((_) => - attachBlockToShadowDom($blockCache.fromHtml(directive.$template))); - templateLoader = new TemplateLoader(blockFuture); + blockFuture = + new async.Future.value($blockCache.fromHtml(directive.$template)); } else if (directive.$templateUrl != null) { - var blockFuture = $blockCache.fromUrl(directive.$templateUrl) - .then((BlockFactory blockFactory) => attachBlockToShadowDom(blockFactory)); - templateLoader = new TemplateLoader(blockFuture); + blockFuture = $blockCache.fromUrl(directive.$templateUrl); } + TemplateLoader templateLoader = new TemplateLoader( + cssFuture.then((String css) { + if (css != null) { + shadowDom.innerHtml = ''; + } + if (blockFuture != null) { + return blockFuture.then((BlockFactory blockFactory) => + attachBlockToShadowDom(blockFactory)); + } + return shadowDom; + })); var controller = createShadowInjector(injector, templateLoader).get(directive.type); if (directive.$publishAs != null) { diff --git a/test/compiler_spec.dart b/test/compiler_spec.dart index e110987ac..d30f336a9 100644 --- a/test/compiler_spec.dart +++ b/test/compiler_spec.dart @@ -235,7 +235,7 @@ main() { Block block = blockFactory(injector, element); $rootScope.$digest(); - nextTurn(); + nextTurn(true); expect(element.textWithShadow()).toEqual('OUTTER-_1:INNER_2(OUTTER-_1)'); }))); @@ -246,7 +246,7 @@ main() { $compile(element)(injector, element); - nextTurn(); + nextTurn(true); expect(renderedText(element)).toEqual('inside poof'); }))); @@ -254,7 +254,7 @@ main() { var element = $(''); $compile(element)(injector, element); - nextTurn(); + nextTurn(true); expect(renderedText(element)).toEqual('inside '); }))); @@ -263,7 +263,7 @@ main() { var element = $(''); $compile(element)(injector, element); - nextTurn(); + nextTurn(true); expect(renderedText(element)).toEqual('inside '); }))); @@ -316,7 +316,7 @@ main() { $compile(element)(injector, element); $rootScope.$apply(); - nextTurn(); + nextTurn(true); expect(element.textWithShadow()).toEqual('WORKED'); }))); diff --git a/test/shadow_root_options_spec.dart b/test/shadow_root_options_spec.dart index 741eb2d9b..f763e0251 100644 --- a/test/shadow_root_options_spec.dart +++ b/test/shadow_root_options_spec.dart @@ -58,7 +58,7 @@ main() { element.forEach((elt) { document.body.append(elt); }); // we need the computed style. $compile(element)(injector, element); - nextTurn(); + nextTurn(true); expect(element[1].shadowRoot.query('div').getComputedStyle().border).toContain('3px solid'); // ""0px none"" is the default style. expect(element[2].shadowRoot.query('div').getComputedStyle().border).toContain('0px none'); @@ -72,7 +72,7 @@ main() { element.forEach((elt) { document.body.append(elt); }); // we need the computed style. $compile(element)(injector, element); - nextTurn(); + nextTurn(true); expect(element[1].shadowRoot.query('div').getComputedStyle().fontSize).toEqual('16px'); expect(element[2].shadowRoot.query('div').getComputedStyle().fontSize).toEqual('20px'); }))); diff --git a/test/templateurl_spec.dart b/test/templateurl_spec.dart index 54d88d047..3f2080103 100644 --- a/test/templateurl_spec.dart +++ b/test/templateurl_spec.dart @@ -44,6 +44,7 @@ main() { it('should use the UrlRewriter for both HTML and CSS URLs', inject((Http $http, Compiler $compile, Scope $rootScope, Log log, Injector injector) { backend.expectGET('PREFIX:simple.html', '
Simple!
'); + backend.expectGET('PREFIX:simple.css', '.hello{}'); var element = $('
ignore
'); $compile(element)(injector, element); @@ -51,9 +52,9 @@ main() { backend.flush(); backend.assertAllGetsCalled(); - expect(renderedText(element)).toEqual('@import "PREFIX:simple.css"Simple!'); + expect(renderedText(element)).toEqual('.hello{}Simple!'); expect(element[0].nodes[0].shadowRoot.innerHtml).toEqual( - '
Simple!
' + '
Simple!
' ); })); }); @@ -103,6 +104,7 @@ main() { it('should load a CSS file into a style', async(inject((MockHttp $http, Compiler $compile, Scope $rootScope, Log log, Injector injector) { $http.expectGET('simple.html', '
Simple!
'); + $http.expectGET('simple.css', '.hello{}'); var element = $('
ignore
'); $compile(element)(injector, element); @@ -110,40 +112,44 @@ main() { $http.flush(); nextTurn(true); - expect(renderedText(element)).toEqual('@import "simple.css"Simple!'); + expect(renderedText(element)).toEqual('.hello{}Simple!'); expect(element[0].nodes[0].shadowRoot.innerHtml).toEqual( - '
Simple!
' + '
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', async(inject((Compiler $compile, Scope $rootScope, Injector injector) { + it('should load a CSS file with a \$template', async(inject((MockHttp $http, Compiler $compile, Scope $rootScope, Injector injector) { var element = $('
ignore
'); + $http.expectGET('simple.css', '.hello{}'); $compile(element)(injector, element); nextTurn(true); - expect(renderedText(element)).toEqual('@import "simple.css"inline!'); + expect(renderedText(element)).toEqual('.hello{}inline!'); }))); - it('should load a CSS with no template', inject((Compiler $compile, Scope $rootScope, Injector injector) { + it('should load a CSS with no template', async(inject((MockHttp $http, Compiler $compile, Scope $rootScope, Injector injector) { var element = $('
ignore
'); + $http.expectGET('simple.css', '.hello{}'); $compile(element)(injector, element); - expect(renderedText(element)).toEqual('@import "simple.css"'); - })); + nextTurn(true); + expect(renderedText(element)).toEqual('.hello{}'); + }))); it('should load the CSS before the template is loaded', async(inject((MockHttp $http, Compiler $compile, Scope $rootScope, Injector injector) { $http.expectGET('simple.html', '
Simple!
'); + $http.expectGET('simple.css', '.hello{}'); var element = $('ignore'); $compile(element)(injector, element); - // The HTML is not loaded yet, but the CSS @import should be in the DOM. - expect(renderedText(element)).toEqual('@import "simple.css"'); + nextTurn(); + expect(renderedText(element)).toEqual('.hello{}'); - nextTurn(true); - expect(renderedText(element)).toEqual('@import "simple.css"Simple!'); + nextTurn(); + expect(renderedText(element)).toEqual('.hello{}Simple!'); }))); }); }