Skip to content

Commit b861a9f

Browse files
jbdeboerchirayuk
authored andcommitted
feat(ng-base-css): useNgBaseCss Component annotation field.
Introduces a useNgBaseCss field in the ```@Component``` annotation. It defaults to true, but when set to false, the component will not load any base CSS files. For components that do not rely on base CSS, loading a global CSS file can be a significant performance issue. Best practices say that large global CSS files are an anti-pattern for shadow DOM based apps. ng-base-css allows apps to use this anti-pattern to support legacy app design. The useNgBaseCss field allows app developers to transition to per-component styles and reap the performance benefits immediately.
1 parent 706f9e9 commit b861a9f

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

lib/core/annotation_src.dart

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,11 @@ class Component extends Directive {
316316
*/
317317
final bool useShadowDom;
318318

319+
/**
320+
* Defaults to true, but if set to false any NgBaseCss stylesheets will be ignored.
321+
*/
322+
final bool useNgBaseCss;
323+
319324
const Component({
320325
this.template,
321326
this.templateUrl,
@@ -329,7 +334,8 @@ class Component extends Directive {
329334
visibility,
330335
exportExpressions,
331336
exportExpressionAttrs,
332-
this.useShadowDom})
337+
this.useShadowDom,
338+
this.useNgBaseCss: true})
333339
: _cssUrls = cssUrl,
334340
_applyAuthorStyles = applyAuthorStyles,
335341
_resetStyleInheritance = resetStyleInheritance,
@@ -359,7 +365,8 @@ class Component extends Directive {
359365
visibility: visibility,
360366
exportExpressions: exportExpressions,
361367
exportExpressionAttrs: exportExpressionAttrs,
362-
useShadowDom: useShadowDom);
368+
useShadowDom: useShadowDom,
369+
useNgBaseCss: useNgBaseCss);
363370
}
364371

365372
/**

lib/core_dom/shadow_dom_component_factory.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class ShadowDomComponentFactory implements ComponentFactory {
4343
Http http = injector.getByKey(_HTTP_KEY);
4444
TemplateCache templateCache = injector.getByKey(_TEMPLATE_CACHE_KEY);
4545
DirectiveMap directives = injector.getByKey(_DIRECTIVE_MAP_KEY);
46-
NgBaseCss baseCss = injector.getByKey(_NG_BASE_CSS_KEY);
46+
NgBaseCss baseCss = component.useNgBaseCss ? injector.getByKey(_NG_BASE_CSS_KEY) : null;
4747
// This is a bit of a hack since we are returning different type then we are.
4848
var componentFactory = new _ComponentFactory(node,
4949
ref.typeKey,
@@ -105,7 +105,9 @@ class _ComponentFactory implements Function {
105105
// so change back to using @import once Chrome bug is fixed or a
106106
// better work around is found.
107107
Iterable<async.Future<dom.StyleElement>> cssFutures;
108-
var cssUrls = []..addAll(_baseCss.urls)..addAll(component.cssUrls);
108+
var cssUrls = _baseCss != null ?
109+
([]..addAll(_baseCss.urls)..addAll(component.cssUrls)) :
110+
component.cssUrls;
109111
var tag = element.tagName.toLowerCase();
110112
if (cssUrls.isNotEmpty) {
111113
cssFutures = cssUrls.map((cssUrl) => _styleElementCache.putIfAbsent(

test/directive/ng_base_css_spec.dart

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,19 @@ import '../_specs.dart';
88
cssUrl: 'simple.css')
99
class _HtmlAndCssComponent {}
1010

11+
@Component(
12+
selector: 'no-base-css',
13+
templateUrl: 'simple.html',
14+
cssUrl: 'simple.css',
15+
useNgBaseCss: false)
16+
class _NoBaseCssComponent {}
17+
18+
1119
main() => describe('NgBaseCss', () {
1220
beforeEachModule((Module module) {
1321
module
14-
..bind(_HtmlAndCssComponent);
22+
..bind(_HtmlAndCssComponent)
23+
..bind(_NoBaseCssComponent);
1524
});
1625

1726
it('should load css urls from ng-base-css', async((TestBed _, MockHttpBackend backend) {
@@ -50,6 +59,23 @@ main() => describe('NgBaseCss', () {
5059
);
5160
}));
5261

62+
it('should respect useNgBaseCss', async((TestBed _, MockHttpBackend backend) {
63+
backend
64+
..expectGET('simple.css').respond(200, '.simple{}')
65+
..expectGET('simple.html').respond(200, '<div>Simple!</div>');
66+
67+
var element = e('<div ng-base-css="base.css"><no-base-css>ignore</no-base-css></div>');
68+
_.compile(element);
69+
70+
microLeap();
71+
backend.flush();
72+
microLeap();
73+
74+
expect(element.children[0].shadowRoot).toHaveHtml(
75+
'<style>.simple{}</style><div>Simple!</div>'
76+
);
77+
}));
78+
5379
describe('from injector', () {
5480
beforeEachModule((Module module) {
5581
module.bind(NgBaseCss, toValue: new NgBaseCss()..urls = ['injected.css']);
@@ -72,5 +98,22 @@ main() => describe('NgBaseCss', () {
7298
'<style>.injected{}</style><style>.simple{}</style><div>Simple!</div>'
7399
);
74100
}));
101+
102+
it('should respect useNgBaseCss', async((TestBed _, MockHttpBackend backend) {
103+
backend
104+
..expectGET('simple.css').respond(200, '.simple{}')
105+
..expectGET('simple.html').respond(200, '<div>Simple!</div>');
106+
107+
var element = e('<div><no-base-css>ignore</no-base-css></div>');
108+
_.compile(element);
109+
110+
microLeap();
111+
backend.flush();
112+
microLeap();
113+
114+
expect(element.children[0].shadowRoot).toHaveHtml(
115+
'<style>.simple{}</style><div>Simple!</div>'
116+
);
117+
}));
75118
});
76119
});

0 commit comments

Comments
 (0)