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

Commit c60e936

Browse files
jbdeboertravis@travis-ci.org
authored andcommitted
feat(compiler): useShadowDom option
Closes #367 Closes #936
1 parent 26ad880 commit c60e936

File tree

6 files changed

+96
-8
lines changed

6 files changed

+96
-8
lines changed

lib/core/annotation_src.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,13 @@ class Component extends Directive {
308308
@deprecated
309309
final String publishAs;
310310

311+
/**
312+
* If set to true, this component will always use shadow DOM.
313+
* If set to false, this component will never use shadow DOM.
314+
* If unset, the compiler's default construction strategy will be used
315+
*/
316+
final bool useShadowDom;
317+
311318
const Component({
312319
this.template,
313320
this.templateUrl,
@@ -320,7 +327,8 @@ class Component extends Directive {
320327
selector,
321328
visibility,
322329
exportExpressions,
323-
exportExpressionAttrs})
330+
exportExpressionAttrs,
331+
this.useShadowDom})
324332
: _cssUrls = cssUrl,
325333
_applyAuthorStyles = applyAuthorStyles,
326334
_resetStyleInheritance = resetStyleInheritance,
@@ -349,7 +357,8 @@ class Component extends Directive {
349357
selector: selector,
350358
visibility: visibility,
351359
exportExpressions: exportExpressions,
352-
exportExpressionAttrs: exportExpressionAttrs);
360+
exportExpressionAttrs: exportExpressionAttrs,
361+
useShadowDom: useShadowDom);
353362
}
354363

355364
/**

lib/core_dom/element_binder.dart

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@ class TemplateElementBinder extends ElementBinder {
1414
return _directiveCache = [template];
1515
}
1616

17-
TemplateElementBinder(_perf, _expando, _parser, _componentFactory, this.template, this.templateBinder,
17+
TemplateElementBinder(perf, expando, parser, componentFactory,
18+
transcludingComponentFactory, shadowDomComponentFactory,
19+
this.template, this.templateBinder,
1820
onEvents, bindAttrs, childMode)
19-
: super(_perf, _expando, _parser, _componentFactory, null, null, onEvents, bindAttrs, childMode);
21+
: super(perf, expando, parser, componentFactory,
22+
transcludingComponentFactory, shadowDomComponentFactory,
23+
null, null, onEvents, bindAttrs, childMode);
2024

2125
String toString() => "[TemplateElementBinder template:$template]";
2226

@@ -41,7 +45,11 @@ class ElementBinder {
4145
final Profiler _perf;
4246
final Expando _expando;
4347
final Parser _parser;
48+
49+
// The default component factory
4450
final ComponentFactory _componentFactory;
51+
final TranscludingComponentFactory _transcludingComponentFactory;
52+
final ShadowDomComponentFactory _shadowDomComponentFactory;
4553
final Map onEvents;
4654
final Map bindAttrs;
4755

@@ -53,7 +61,11 @@ class ElementBinder {
5361
// Can be either COMPILE_CHILDREN or IGNORE_CHILDREN
5462
final String childMode;
5563

56-
ElementBinder(this._perf, this._expando, this._parser, this._componentFactory, this.component, this.decorators,
64+
ElementBinder(this._perf, this._expando, this._parser,
65+
this._componentFactory,
66+
this._transcludingComponentFactory,
67+
this._shadowDomComponentFactory,
68+
this.component, this.decorators,
5769
this.onEvents, this.bindAttrs, this.childMode);
5870

5971
final bool hasTemplate = false;
@@ -215,7 +227,16 @@ class ElementBinder {
215227
}
216228
nodesAttrsDirectives.add(ref);
217229
} else if (ref.annotation is Component) {
218-
nodeModule.factory(ref.type, _componentFactory.call(node, ref), visibility: visibility);
230+
var factory;
231+
var annotation = ref.annotation as Component;
232+
if (annotation.useShadowDom == true) {
233+
factory = _shadowDomComponentFactory;
234+
} else if (annotation.useShadowDom == false) {
235+
factory = _transcludingComponentFactory;
236+
} else {
237+
factory = _componentFactory;
238+
}
239+
nodeModule.factory(ref.type, factory.call(node, ref), visibility: visibility);
219240
} else {
220241
nodeModule.type(ref.type, visibility: visibility);
221242
}

lib/core_dom/element_binder_builder.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,22 @@ class ElementBinderFactory {
66
final Profiler _perf;
77
final Expando _expando;
88
final ComponentFactory _componentFactory;
9+
final TranscludingComponentFactory _transcludingComponentFactory;
10+
final ShadowDomComponentFactory _shadowDomComponentFactory;
911

10-
ElementBinderFactory(this._parser, this._perf, this._expando, this._componentFactory);
12+
ElementBinderFactory(this._parser, this._perf, this._expando, this._componentFactory,
13+
this._transcludingComponentFactory, this._shadowDomComponentFactory);
1114

1215
// TODO: Optimize this to re-use a builder.
1316
ElementBinderBuilder builder() => new ElementBinderBuilder(this);
1417

1518
ElementBinder binder(ElementBinderBuilder b) =>
1619
new ElementBinder(_perf, _expando, _parser, _componentFactory,
20+
_transcludingComponentFactory, _shadowDomComponentFactory,
1721
b.component, b.decorators, b.onEvents, b.bindAttrs, b.childMode);
1822
TemplateElementBinder templateBinder(ElementBinderBuilder b, ElementBinder transclude) =>
1923
new TemplateElementBinder(_perf, _expando, _parser, _componentFactory,
24+
_transcludingComponentFactory, _shadowDomComponentFactory,
2025
b.template, transclude, b.onEvents, b.bindAttrs, b.childMode);
2126
}
2227

lib/core_dom/module_internal.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class CoreDomModule extends Module {
5757
type(Compiler, implementedBy: TaggingCompiler);
5858

5959
type(ComponentFactory, implementedBy: ShadowDomComponentFactory);
60+
type(ShadowDomComponentFactory);
61+
type(TranscludingComponentFactory);
6062
type(Content);
6163
value(ContentPort, null);
6264

test/core/annotation_src_spec.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ void main() => describe('annotations', () {
4545
selector: '',
4646
visibility: Directive.LOCAL_VISIBILITY,
4747
exportExpressions: [],
48-
exportExpressionAttrs: []
48+
exportExpressionAttrs: [],
49+
useShadowDom: true
4950
);
5051

5152
// Check that no fields are null

test/core_dom/compiler_spec.dart

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,35 @@ void main() {
618618
}).toThrow('Unknown selector format \'buttonbar button\' for InvalidSelector');
619619
});
620620
});
621+
622+
describe('useShadowDom option', () {
623+
beforeEachModule((Module m) {
624+
m.type(ShadowyComponent);
625+
m.type(ShadowlessComponent);
626+
});
627+
628+
it('should create shadowy components', async((Logger log) {
629+
_.compile('<shadowy></shadowy>');
630+
expect(log).toEqual(['shadowy']);
631+
expect(_.rootElement.shadowRoot).toBeNotNull();
632+
}));
633+
634+
it('should create shadowless components', async((Logger log) {
635+
_.compile('<shadowless></shadowless>');
636+
expect(log).toEqual(['shadowless']);
637+
expect(_.rootElement.shadowRoot).toBeNull();
638+
}));
639+
640+
it('should create other components with the default strategy', async((ComponentFactory factory) {
641+
_.compile('<simple></simple>');
642+
if (factory is TranscludingComponentFactory) {
643+
expect(_.rootElement.shadowRoot).toBeNull();
644+
} else {
645+
expect(factory is ShadowDomComponentFactory).toBeTruthy();
646+
expect(_.rootElement.shadowRoot).toBeNotNull();
647+
}
648+
}));
649+
});
621650
});
622651

623652

@@ -807,6 +836,27 @@ class SimpleComponent {
807836
}
808837
}
809838

839+
@Component(
840+
selector: 'shadowy',
841+
template: r'With shadow DOM',
842+
useShadowDom: true
843+
)
844+
class ShadowyComponent {
845+
ShadowyComponent(Logger log) {
846+
log('shadowy');
847+
}
848+
}
849+
850+
@Component(
851+
selector: 'shadowless',
852+
template: r'Without shadow DOM',
853+
useShadowDom: false
854+
)
855+
class ShadowlessComponent {
856+
ShadowlessComponent(Logger log) {
857+
log('shadowless');
858+
}
859+
}
810860

811861
@Component(
812862
selector: 'sometimes',

0 commit comments

Comments
 (0)