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

fix(block): loading css with Http #67

Merged
merged 1 commit into from
Aug 5, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 29 additions & 11 deletions lib/block.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 =
Expand All @@ -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<String> cssFuture;
if (directive.$cssUrl != null) {
shadowDom.innerHtml = '<style>@import "${urlRewriter(directive.$cssUrl)}"</style>';
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 = '<style>$css</style>';
}
if (blockFuture != null) {
return blockFuture.then((BlockFactory blockFactory) =>
attachBlockToShadowDom(blockFactory));
}
return shadowDom;
}));
var controller =
createShadowInjector(injector, templateLoader).get(directive.type);
if (directive.$publishAs != null) {
Expand Down
10 changes: 5 additions & 5 deletions test/compiler_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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)');
})));

Expand All @@ -246,15 +246,15 @@ main() {

$compile(element)(injector, element);

nextTurn();
nextTurn(true);
expect(renderedText(element)).toEqual('inside poof');
})));

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

nextTurn();
nextTurn(true);
expect(renderedText(element)).toEqual('inside ');
})));

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

nextTurn();
nextTurn(true);
expect(renderedText(element)).toEqual('inside ');
})));

Expand Down Expand Up @@ -316,7 +316,7 @@ main() {
$compile(element)(injector, element);
$rootScope.$apply();

nextTurn();
nextTurn(true);
expect(element.textWithShadow()).toEqual('WORKED');
})));

Expand Down
4 changes: 2 additions & 2 deletions test/shadow_root_options_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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');
})));
Expand Down
32 changes: 19 additions & 13 deletions test/templateurl_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,17 @@ 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', '<div log="SIMPLE">Simple!</div>');
backend.expectGET('PREFIX:simple.css', '.hello{}');

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

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(
'<style>@import "PREFIX:simple.css"</style><div log="SIMPLE">Simple!</div>'
'<style>.hello{}</style><div log="SIMPLE">Simple!</div>'
);
}));
});
Expand Down Expand Up @@ -103,47 +104,52 @@ 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', '<div log="SIMPLE">Simple!</div>');
$http.expectGET('simple.css', '.hello{}');

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

$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(
'<style>@import "simple.css"</style><div log="SIMPLE">Simple!</div>'
'<style>.hello{}</style><div log="SIMPLE">Simple!</div>'
);
// 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 = $('<div><inline-with-css log>ignore</inline-with-css><div>');
$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 = $('<div><only-css log>ignore</only-css><div>');
$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', '<div>Simple!</div>');
$http.expectGET('simple.css', '.hello{}');

var element = $('<html-and-css>ignore</html-and-css>');
$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!');
})));
});
}