Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 7a3ad21

Browse files
committed
fix(block): loading css with Http
Closes #66
1 parent ce6e8e7 commit 7a3ad21

File tree

4 files changed

+55
-31
lines changed

4 files changed

+55
-31
lines changed

lib/block.dart

+29-11
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ class Block implements ElementWrapper {
106106
if (ref.directive.isComponent) {
107107
//nodeModule.factory(type, new ComponentFactory(node, ref.directive), visibility: visibility);
108108
// TODO(misko): there should be no need to wrap function like this.
109-
nodeModule.factory(type, (Injector injector, Compiler compiler, Scope scope, Parser parser, BlockCache $blockCache, UrlRewriter urlRewriter) =>
110-
(new _ComponentFactory(node, ref.directive))(injector, compiler, scope, parser, $blockCache, urlRewriter),
109+
nodeModule.factory(type, (Injector injector, Compiler compiler, Scope scope, Parser parser, BlockCache $blockCache, Http http, TemplateCache templateCache) =>
110+
(new _ComponentFactory(node, ref.directive))(injector, compiler, scope, parser, $blockCache, http, templateCache),
111111
visibility: visibility);
112112
} else {
113113
nodeModule.type(type, type, visibility: visibility);
@@ -272,7 +272,8 @@ class _ComponentFactory {
272272
_ComponentFactory(this.element, this.directive);
273273

274274
dynamic call(Injector injector, Compiler compiler, Scope scope,
275-
Parser parser, BlockCache $blockCache, UrlRewriter urlRewriter) {
275+
Parser parser, BlockCache $blockCache, Http $http,
276+
TemplateCache $templateCache) {
276277
this.compiler = compiler;
277278
shadowDom = element.createShadowRoot();
278279
shadowDom.applyAuthorStyles =
@@ -282,19 +283,36 @@ class _ComponentFactory {
282283

283284
shadowScope = scope.$new(true);
284285
createAttributeMapping(scope, shadowScope, parser);
286+
287+
// TODO(pavelgj): fetching CSS with Http is mainly an attempt to
288+
// work around an unfiled Chrome bug when reloading same CSS breaks
289+
// styles all over the page. We shouldn't be doing browsers work,
290+
// so change back to using @import once Chrome bug is fixed or a
291+
// better work around is found.
292+
async.Future<String> cssFuture;
285293
if (directive.$cssUrl != null) {
286-
shadowDom.innerHtml = '<style>@import "${urlRewriter(directive.$cssUrl)}"</style>';
294+
cssFuture = $http.getString(directive.$cssUrl, cache: $templateCache);
295+
} else {
296+
cssFuture = new async.Future.value(null);
287297
}
288-
TemplateLoader templateLoader;
298+
var blockFuture;
289299
if (directive.$template != null) {
290-
var blockFuture = new async.Future.value().then((_) =>
291-
attachBlockToShadowDom($blockCache.fromHtml(directive.$template)));
292-
templateLoader = new TemplateLoader(blockFuture);
300+
blockFuture =
301+
new async.Future.value($blockCache.fromHtml(directive.$template));
293302
} else if (directive.$templateUrl != null) {
294-
var blockFuture = $blockCache.fromUrl(directive.$templateUrl)
295-
.then((BlockFactory blockFactory) => attachBlockToShadowDom(blockFactory));
296-
templateLoader = new TemplateLoader(blockFuture);
303+
blockFuture = $blockCache.fromUrl(directive.$templateUrl);
297304
}
305+
TemplateLoader templateLoader = new TemplateLoader(
306+
cssFuture.then((String css) {
307+
if (css != null) {
308+
shadowDom.innerHtml = '<style>$css</style>';
309+
}
310+
if (blockFuture != null) {
311+
return blockFuture.then((BlockFactory blockFactory) =>
312+
attachBlockToShadowDom(blockFactory));
313+
}
314+
return shadowDom;
315+
}));
298316
var controller =
299317
createShadowInjector(injector, templateLoader).get(directive.type);
300318
if (directive.$publishAs != null) {

test/compiler_spec.dart

+5-5
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ main() {
235235
Block block = blockFactory(injector, element);
236236
$rootScope.$digest();
237237

238-
nextTurn();
238+
nextTurn(true);
239239
expect(element.textWithShadow()).toEqual('OUTTER-_1:INNER_2(OUTTER-_1)');
240240
})));
241241

@@ -246,15 +246,15 @@ main() {
246246

247247
$compile(element)(injector, element);
248248

249-
nextTurn();
249+
nextTurn(true);
250250
expect(renderedText(element)).toEqual('inside poof');
251251
})));
252252

253253
it('should behave nicely if a mapped attribute is missing', async(inject(() {
254254
var element = $('<parent-expression></parent-expression>');
255255
$compile(element)(injector, element);
256256

257-
nextTurn();
257+
nextTurn(true);
258258
expect(renderedText(element)).toEqual('inside ');
259259
})));
260260

@@ -263,7 +263,7 @@ main() {
263263
var element = $('<parent-expression fromParent=val></parent-expression>');
264264
$compile(element)(injector, element);
265265

266-
nextTurn();
266+
nextTurn(true);
267267
expect(renderedText(element)).toEqual('inside ');
268268
})));
269269

@@ -316,7 +316,7 @@ main() {
316316
$compile(element)(injector, element);
317317
$rootScope.$apply();
318318

319-
nextTurn();
319+
nextTurn(true);
320320
expect(element.textWithShadow()).toEqual('WORKED');
321321
})));
322322

test/shadow_root_options_spec.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ main() {
5858
element.forEach((elt) { document.body.append(elt); }); // we need the computed style.
5959
$compile(element)(injector, element);
6060

61-
nextTurn();
61+
nextTurn(true);
6262
expect(element[1].shadowRoot.query('div').getComputedStyle().border).toContain('3px solid');
6363
// ""0px none"" is the default style.
6464
expect(element[2].shadowRoot.query('div').getComputedStyle().border).toContain('0px none');
@@ -72,7 +72,7 @@ main() {
7272
element.forEach((elt) { document.body.append(elt); }); // we need the computed style.
7373
$compile(element)(injector, element);
7474

75-
nextTurn();
75+
nextTurn(true);
7676
expect(element[1].shadowRoot.query('div').getComputedStyle().fontSize).toEqual('16px');
7777
expect(element[2].shadowRoot.query('div').getComputedStyle().fontSize).toEqual('20px');
7878
})));

test/templateurl_spec.dart

+19-13
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,17 @@ main() {
4444
it('should use the UrlRewriter for both HTML and CSS URLs', inject((Http $http, Compiler $compile, Scope $rootScope, Log log, Injector injector) {
4545

4646
backend.expectGET('PREFIX:simple.html', '<div log="SIMPLE">Simple!</div>');
47+
backend.expectGET('PREFIX:simple.css', '.hello{}');
4748

4849
var element = $('<div><html-and-css log>ignore</html-and-css><div>');
4950
$compile(element)(injector, element);
5051

5152
backend.flush();
5253
backend.assertAllGetsCalled();
5354

54-
expect(renderedText(element)).toEqual('@import "PREFIX:simple.css"Simple!');
55+
expect(renderedText(element)).toEqual('.hello{}Simple!');
5556
expect(element[0].nodes[0].shadowRoot.innerHtml).toEqual(
56-
'<style>@import "PREFIX:simple.css"</style><div log="SIMPLE">Simple!</div>'
57+
'<style>.hello{}</style><div log="SIMPLE">Simple!</div>'
5758
);
5859
}));
5960
});
@@ -103,47 +104,52 @@ main() {
103104

104105
it('should load a CSS file into a style', async(inject((MockHttp $http, Compiler $compile, Scope $rootScope, Log log, Injector injector) {
105106
$http.expectGET('simple.html', '<div log="SIMPLE">Simple!</div>');
107+
$http.expectGET('simple.css', '.hello{}');
106108

107109
var element = $('<div><html-and-css log>ignore</html-and-css><div>');
108110
$compile(element)(injector, element);
109111

110112
$http.flush();
111113
nextTurn(true);
112114

113-
expect(renderedText(element)).toEqual('@import "simple.css"Simple!');
115+
expect(renderedText(element)).toEqual('.hello{}Simple!');
114116
expect(element[0].nodes[0].shadowRoot.innerHtml).toEqual(
115-
'<style>@import "simple.css"</style><div log="SIMPLE">Simple!</div>'
117+
'<style>.hello{}</style><div log="SIMPLE">Simple!</div>'
116118
);
117119
// Note: There is no ordering. It is who ever comes off the wire first!
118120
expect(log.result()).toEqual('LOG; SIMPLE');
119121
})));
120122

121-
it('should load a CSS file with a \$template', async(inject((Compiler $compile, Scope $rootScope, Injector injector) {
123+
it('should load a CSS file with a \$template', async(inject((MockHttp $http, Compiler $compile, Scope $rootScope, Injector injector) {
122124
var element = $('<div><inline-with-css log>ignore</inline-with-css><div>');
125+
$http.expectGET('simple.css', '.hello{}');
123126
$compile(element)(injector, element);
124127

125128
nextTurn(true);
126-
expect(renderedText(element)).toEqual('@import "simple.css"inline!');
129+
expect(renderedText(element)).toEqual('.hello{}inline!');
127130
})));
128131

129-
it('should load a CSS with no template', inject((Compiler $compile, Scope $rootScope, Injector injector) {
132+
it('should load a CSS with no template', async(inject((MockHttp $http, Compiler $compile, Scope $rootScope, Injector injector) {
130133
var element = $('<div><only-css log>ignore</only-css><div>');
134+
$http.expectGET('simple.css', '.hello{}');
131135
$compile(element)(injector, element);
132136

133-
expect(renderedText(element)).toEqual('@import "simple.css"');
134-
}));
137+
nextTurn(true);
138+
expect(renderedText(element)).toEqual('.hello{}');
139+
})));
135140

136141
it('should load the CSS before the template is loaded', async(inject((MockHttp $http, Compiler $compile, Scope $rootScope, Injector injector) {
137142
$http.expectGET('simple.html', '<div>Simple!</div>');
143+
$http.expectGET('simple.css', '.hello{}');
138144

139145
var element = $('<html-and-css>ignore</html-and-css>');
140146
$compile(element)(injector, element);
141147

142-
// The HTML is not loaded yet, but the CSS @import should be in the DOM.
143-
expect(renderedText(element)).toEqual('@import "simple.css"');
148+
nextTurn();
149+
expect(renderedText(element)).toEqual('.hello{}');
144150

145-
nextTurn(true);
146-
expect(renderedText(element)).toEqual('@import "simple.css"Simple!');
151+
nextTurn();
152+
expect(renderedText(element)).toEqual('.hello{}Simple!');
147153
})));
148154
});
149155
}

0 commit comments

Comments
 (0)