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

Commit ea1f7a2

Browse files
committed
feat(directives): $cssUrl
1 parent 472b6c6 commit ea1f7a2

File tree

7 files changed

+84
-8
lines changed

7 files changed

+84
-8
lines changed

demo/web/book.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
h2 { color: red }

demo/web/main.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class BookComponent {
6161
BookComponent(BookController this.controller);
6262

6363
static String $templateUrl = 'book.html';
64+
static String $cssUrl = 'book.css';
6465

6566
attach(Scope scope) {
6667
controller.attach(scope);

lib/block.dart

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,21 +344,23 @@ class ComponentWrapper {
344344
Parser parser;
345345
Block shadowBlock;
346346

347-
348347
ComponentWrapper(this.directiveRef, this.controller, this.elementRoot, this.parser, $compiler, $http) {
349348
var directive = directiveRef.directive;
350349
var shadowRoot = elementRoot.createShadowRoot();
351350

351+
var styleData = '';
352+
if (directive.$cssUrl != null) {
353+
styleData = '<style>@import "${directive.$cssUrl}"</style>';
354+
}
355+
352356
_appendAndCompileTemplate(data) {
353-
shadowRoot.innerHtml = data;
357+
shadowRoot.innerHtml = styleData + data;
354358
shadowBlock = $compiler(shadowRoot.nodes)(shadowRoot.nodes);
355359
}
356360
// There is support here for directives having both $template and
357361
// $templateUrl. This could be a clever way to add a 'LOADING'
358362
// message.
359-
if (directive.$template != null) {
360-
_appendAndCompileTemplate(directive.$template);
361-
}
363+
_appendAndCompileTemplate(directive.$template != null ? directive.$template : '');
362364

363365
if (directive.$templateUrl != null) {
364366
$http.getString(directive.$templateUrl).then((data) {

lib/directive.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class Directive {
1313
Type $controllerType;
1414
String $template;
1515
String $templateUrl;
16+
String $cssUrl;
1617
Map<String, String> $map;
1718

1819
bool isComponent = false;
@@ -43,6 +44,7 @@ class Directive {
4344
$transclude = reflectStaticField(type, '\$transclude');
4445
$template = reflectStaticField(type, '\$template');
4546
$templateUrl = reflectStaticField(type, '\$templateUrl');
47+
$cssUrl = reflectStaticField(type, '\$cssUrl');
4648
$priority = reflectStaticField(type, '\$priority');
4749
$map = reflectStaticField(type, '\$map');
4850
if ($priority == null) {

test/_http.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ class MockHttp extends Http {
1313
gets[url] = content;
1414
}
1515

16-
flush() => Future.wait(futures);
16+
flush() => gets.length == 0 ? Future.wait(futures) :
17+
throw "Expected GETs not called $gets";
1718

1819
Future<String> getString(String url, {bool withCredentials, void onProgress(ProgressEvent e)}) {
1920
if (!gets.containsKey(url)) throw "Unexpected URL $url";

test/_http_spec.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,12 @@ main() {
2020
http.getString('unknown');
2121
}).toThrow('Unexpected URL unknown');
2222
});
23+
24+
it('should barf on hanging requests', () {
25+
http.expectGET('request', 'response');
26+
expect(() {
27+
http.flush();
28+
}).toThrow('Expected GETs not called {request: response}');
29+
});
2330
});
2431
}

test/templateurl_spec.dart

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,37 @@ class SimpleUrlComponent {
1616
attach(Scope scope) {}
1717
}
1818

19+
class HtmlAndCssComponent {
20+
static String $templateUrl = 'simple.html';
21+
static String $cssUrl = 'simple.css';
22+
attach(Scope scope) {}
23+
}
24+
25+
class InlineWithCssComponent {
26+
static String $template = '<div>inline!</div>';
27+
static String $cssUrl = 'simple.css';
28+
attach(Scope scope) {}
29+
}
30+
31+
class OnlyCssComponent {
32+
static String $cssUrl = 'simple.css';
33+
attach(Scope scope) {}
34+
}
35+
1936
main() {
20-
describe('templateUrl', () {
37+
describe('async template loading', () {
2138
beforeEach(module((module) {
2239
var mockHttp = new MockHttp();
2340
module.value(MockHttp, mockHttp);
2441
module.value(Http, mockHttp);
2542
module.directive(LogAttrDirective);
2643
module.directive(SimpleUrlComponent);
44+
module.directive(HtmlAndCssComponent);
45+
module.directive(OnlyCssComponent);
46+
module.directive(InlineWithCssComponent);
2747
}));
2848

29-
it('should replace element with template from url', inject((MockHttp $http, Compiler $compile, Scope $rootScope, Log log) {
49+
it('should replace element with template from url', inject((MockHttp $http, Compiler $compile, Scope $rootScope, Log log) {
3050
$http.expectGET('simple.html', '<div log="SIMPLE">Simple!</div>');
3151

3252
var element = $('<div><simple-url log>ignore</replace><div>');
@@ -37,7 +57,49 @@ main() {
3757
// Note: There is no ordering. It is who ever comes off the wire first!
3858
expect(log.result()).toEqual('LOG; SIMPLE');
3959
}));
60+
}));
61+
62+
it('should load a CSS file into a style', inject((MockHttp $http, Compiler $compile, Scope $rootScope, Log log) {
63+
$http.expectGET('simple.html', '<div log="SIMPLE">Simple!</div>');
64+
65+
var element = $('<div><html-and-css log>ignore</html-and-css><div>');
66+
$compile(element)(element)..attach($rootScope);
67+
68+
$http.flush().then(expectAsync1((data) {
69+
expect(renderedText(element)).toEqual('@import "simple.css"Simple!');
70+
expect(element[0].nodes[0].shadowRoot.innerHtml).toEqual(
71+
'<style>@import "simple.css"</style><div log="SIMPLE">Simple!</div>'
72+
);
73+
// Note: There is no ordering. It is who ever comes off the wire first!
74+
expect(log.result()).toEqual('LOG; SIMPLE');
75+
}));
76+
}));
77+
78+
it('should load a CSS file with a \$template', inject((Compiler $compile, Scope $rootScope) {
79+
var element = $('<div><inline-with-css log>ignore</inline-with-css><div>');
80+
$compile(element)(element)..attach($rootScope);
81+
expect(renderedText(element)).toEqual('@import "simple.css"inline!');
82+
}));
83+
84+
it('should load a CSS with no template', inject((Compiler $compile, Scope $rootScope) {
85+
var element = $('<div><only-css log>ignore</only-css><div>');
86+
$compile(element)(element)..attach($rootScope);
4087

88+
expect(renderedText(element)).toEqual('@import "simple.css"');
89+
}));
90+
91+
it('should load the CSS before the template is loaded', inject((MockHttp $http, Compiler $compile, Scope $rootScope) {
92+
$http.expectGET('simple.html', '<div>Simple!</div>');
93+
94+
var element = $('<html-and-css>ignore</html-and-css>');
95+
$compile(element)(element)..attach($rootScope);
96+
97+
// The HTML is not loaded yet, but the CSS @import should be in the DOM.
98+
expect(renderedText(element)).toEqual('@import "simple.css"');
99+
100+
$http.flush().then(expectAsync1((data) {
101+
expect(renderedText(element)).toEqual('@import "simple.css"Simple!');
102+
}));
41103
}));
42104
});
43105
}

0 commit comments

Comments
 (0)