Skip to content

Commit da9d041

Browse files
committed
feat(view): add support for components that use shadow dom emulation
1 parent df4ac0d commit da9d041

27 files changed

Lines changed: 188 additions & 89 deletions

modules/benchmarks/src/compiler/compiler_benchmark.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {DOM, document} from 'facade/dom';
22
import {isBlank, Type} from 'facade/lang';
33
import {MapWrapper} from 'facade/collection';
4-
import {AnnotatedType} from 'core/compiler/annotated_type';
4+
import {DirectiveMetadata} from 'core/compiler/directive_metadata';
55

66
import {Parser} from 'change_detection/parser/parser';
77
import {Lexer} from 'change_detection/parser/lexer';
@@ -81,7 +81,7 @@ export function main() {
8181
var reader = new DirectiveMetadataReader();
8282
var cache = new CompilerCache();
8383
var compiler = new Compiler(null, reader, new Parser(new Lexer()), cache);
84-
var annotatedComponent = reader.annotatedType(BenchmarkComponent);
84+
var annotatedComponent = reader.read(BenchmarkComponent);
8585

8686
var templateNoBindings = loadTemplate('templateNoBindings', COUNT);
8787
var templateWithBindings = loadTemplate('templateWithBindings', COUNT);

modules/core/src/annotations/annotations.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {ABSTRACT, CONST, normalizeBlank} from 'facade/lang';
22
import {List} from 'facade/collection';
33
import {TemplateConfig} from './template_config';
4+
import {ShadowDomStrategy} from '../compiler/shadow_dom';
45

56

67
@ABSTRACT()
@@ -35,6 +36,7 @@ export class Component extends Directive {
3536
lightDomServices:any; //List;
3637
shadowDomServices:any; //List;
3738
componentServices:any; //List;
39+
shadowDom:any; //ShadowDomStrategy;
3840

3941
@CONST()
4042
constructor({
@@ -44,15 +46,17 @@ export class Component extends Directive {
4446
lightDomServices,
4547
shadowDomServices,
4648
componentServices,
47-
implementsTypes
49+
implementsTypes,
50+
shadowDom
4851
}:{
4952
selector:String,
5053
bind:Object,
5154
template:TemplateConfig,
5255
lightDomServices:List,
5356
shadowDomServices:List,
5457
componentServices:List,
55-
implementsTypes:List
58+
implementsTypes:List,
59+
shadowDom:ShadowDomStrategy
5660
}={})
5761
{
5862
super({
@@ -65,6 +69,7 @@ export class Component extends Directive {
6569
this.lightDomServices = lightDomServices;
6670
this.shadowDomServices = shadowDomServices;
6771
this.componentServices = componentServices;
72+
this.shadowDom = shadowDom;
6873
}
6974
}
7075

modules/core/src/application.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {ChangeDetector} from 'change_detection/change_detector';
1010
import {RecordRange} from 'change_detection/record_range';
1111
import {TemplateLoader} from './compiler/template_loader';
1212
import {DirectiveMetadataReader} from './compiler/directive_metadata_reader';
13-
import {AnnotatedType} from './compiler/annotated_type';
13+
import {DirectiveMetadata} from './compiler/directive_metadata';
1414
import {List, ListWrapper} from 'facade/collection';
1515
import {PromiseWrapper} from 'facade/async';
1616
import {VmTurnZone} from 'core/zone/vm_turn_zone';
@@ -36,7 +36,7 @@ export function documentDependentBindings(appComponentType) {
3636
// TODO(rado): inspect annotation here and warn if there are bindings,
3737
// lightDomServices, and other component annotations that are skipped
3838
// for bootstrapping components.
39-
return reader.annotatedType(appComponentType);
39+
return reader.read(appComponentType);
4040
}, [DirectiveMetadataReader]),
4141

4242
bind(appElementToken).toFactory((appComponentAnnotatedType, appDocument) => {

modules/core/src/compiler/compiler.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {CompilePipeline} from './pipeline/compile_pipeline';
1111
import {CompileElement} from './pipeline/compile_element';
1212
import {createDefaultSteps} from './pipeline/default_steps';
1313
import {TemplateLoader} from './template_loader';
14-
import {AnnotatedType} from './annotated_type';
14+
import {DirectiveMetadata} from './directive_metadata';
1515
import {Component} from '../annotations/annotations';
1616

1717
/**
@@ -59,12 +59,12 @@ export class Compiler {
5959
this._compilerCache = cache;
6060
}
6161

62-
createSteps(component:AnnotatedType):List<CompileStep> {
62+
createSteps(component:DirectiveMetadata):List<CompileStep> {
6363
var annotation: Component = component.annotation;
6464
var directives = annotation.template.directives;
6565
var annotatedDirectives = ListWrapper.create();
6666
for (var i=0; i<directives.length; i++) {
67-
ListWrapper.push(annotatedDirectives, this._reader.annotatedType(directives[i]));
67+
ListWrapper.push(annotatedDirectives, this._reader.read(directives[i]));
6868
}
6969
return createDefaultSteps(this._parser, component, annotatedDirectives);
7070
}
@@ -75,12 +75,12 @@ export class Compiler {
7575
// transitively via the _templateLoader and store them in templateCache
7676

7777
return PromiseWrapper.resolve(this.compileAllLoaded(
78-
templateCache, this._reader.annotatedType(component), templateRoot)
78+
templateCache, this._reader.read(component), templateRoot)
7979
);
8080
}
8181

8282
// public so that we can compile in sync in performance tests.
83-
compileAllLoaded(templateCache, component:AnnotatedType, templateRoot:Element = null):ProtoView {
83+
compileAllLoaded(templateCache, component:DirectiveMetadata, templateRoot:Element = null):ProtoView {
8484
var rootProtoView = this._compilerCache.get(component.type);
8585
if (isPresent(rootProtoView)) {
8686
return rootProtoView;
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
import {Type, FIELD} from 'facade/lang';
22
import {Directive} from '../annotations/annotations'
3+
import {ShadowDomStrategy} from './shadow_dom';
34

45
/**
56
* Combination of a type with the Directive annotation
67
*/
7-
export class AnnotatedType {
8+
export class DirectiveMetadata {
89
type:Type;
910
annotation:Directive;
10-
constructor(type:Type, annotation:Directive) {
11+
shadowDomStrategy:ShadowDomStrategy;
12+
13+
constructor(type:Type, annotation:Directive, shadowDomStrategy:ShadowDomStrategy) {
1114
this.annotation = annotation;
1215
this.type = type;
16+
this.shadowDomStrategy = shadowDomStrategy;
1317
}
1418
}
Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
import {Type, isPresent, BaseException, stringify} from 'facade/lang';
2-
import {Directive} from '../annotations/annotations';
3-
import {AnnotatedType} from './annotated_type';
2+
import {Directive, Component} from '../annotations/annotations';
3+
import {DirectiveMetadata} from './directive_metadata';
44
import {reflector} from 'reflection/reflection';
5+
import {ShadowDom, ShadowDomStrategy, ShadowDomNative} from './shadow_dom';
56

6-
/**
7-
* Interface representing a way of extracting [Directive] annotations from
8-
* [Type]. This interface has three native implementations:
9-
*
10-
* 1) JavaScript native implementation
11-
* 2) Dart reflective implementation
12-
* 3) Dart transformer generated implementation
13-
*/
147
export class DirectiveMetadataReader {
15-
annotatedType(type:Type):AnnotatedType {
8+
read(type:Type):DirectiveMetadata {
169
var annotations = reflector.annotations(type);
1710
if (isPresent(annotations)) {
1811
for (var i=0; i<annotations.length; i++) {
1912
var annotation = annotations[i];
13+
14+
if (annotation instanceof Component) {
15+
return new DirectiveMetadata(type, annotation, this.parseShadowDomStrategy(annotation));
16+
}
17+
2018
if (annotation instanceof Directive) {
21-
return new AnnotatedType(type, annotation);
19+
return new DirectiveMetadata(type, annotation, null);
2220
}
2321
}
2422
}
2523
throw new BaseException(`No Directive annotation found on ${stringify(type)}`);
2624
}
25+
26+
parseShadowDomStrategy(annotation:Component):ShadowDomStrategy{
27+
return isPresent(annotation.shadowDom) ? annotation.shadowDom : ShadowDomNative;
28+
}
2729
}

modules/core/src/compiler/element_binder.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import {ProtoElementInjector} from './element_injector';
22
import {FIELD} from 'facade/lang';
33
import {MapWrapper} from 'facade/collection';
4-
import {AnnotatedType} from './annotated_type';
4+
import {DirectiveMetadata} from './directive_metadata';
55
import {List, Map} from 'facade/collection';
66
import {ProtoView} from './view';
77

88
export class ElementBinder {
99
protoElementInjector:ProtoElementInjector;
10-
componentDirective:AnnotatedType;
11-
templateDirective:AnnotatedType;
10+
componentDirective:DirectiveMetadata;
11+
templateDirective:DirectiveMetadata;
1212
textNodeIndices:List<int>;
1313
hasElementPropertyBindings:boolean;
1414
nestedProtoView: ProtoView;
1515
events:Map;
1616
constructor(
17-
protoElementInjector: ProtoElementInjector, componentDirective:AnnotatedType, templateDirective:AnnotatedType) {
17+
protoElementInjector: ProtoElementInjector, componentDirective:DirectiveMetadata, templateDirective:DirectiveMetadata) {
1818
this.protoElementInjector = protoElementInjector;
1919
this.componentDirective = componentDirective;
2020
this.templateDirective = templateDirective;

modules/core/src/compiler/pipeline/compile_element.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {List, Map, ListWrapper, MapWrapper} from 'facade/collection';
22
import {Element, DOM} from 'facade/dom';
33
import {int, isBlank, isPresent} from 'facade/lang';
4-
import {AnnotatedType} from '../annotated_type';
4+
import {DirectiveMetadata} from '../directive_metadata';
55
import {Decorator} from '../../annotations/annotations';
66
import {Component} from '../../annotations/annotations';
77
import {Template} from '../../annotations/annotations';
@@ -24,9 +24,9 @@ export class CompileElement {
2424
propertyBindings:Map;
2525
eventBindings:Map;
2626
variableBindings:Map;
27-
decoratorDirectives:List<AnnotatedType>;
28-
templateDirective:AnnotatedType;
29-
componentDirective:AnnotatedType;
27+
decoratorDirectives:List<DirectiveMetadata>;
28+
templateDirective:DirectiveMetadata;
29+
componentDirective:DirectiveMetadata;
3030
isViewRoot:boolean;
3131
hasBindings:boolean;
3232
inheritedProtoView:ProtoView;
@@ -110,7 +110,7 @@ export class CompileElement {
110110
MapWrapper.set(this.eventBindings, eventName, expression);
111111
}
112112

113-
addDirective(directive:AnnotatedType) {
113+
addDirective(directive:DirectiveMetadata) {
114114
var annotation = directive.annotation;
115115
if (annotation instanceof Decorator) {
116116
if (isBlank(this.decoratorDirectives)) {

modules/core/src/compiler/pipeline/compile_pipeline.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {Element, Node, DOM} from 'facade/dom';
44
import {CompileElement} from './compile_element';
55
import {CompileControl} from './compile_control';
66
import {CompileStep} from './compile_step';
7-
import {AnnotatedType} from '../annotated_type';
7+
import {DirectiveMetadata} from '../directive_metadata';
88

99
/**
1010
* CompilePipeline for executing CompileSteps recursively for

modules/core/src/compiler/pipeline/compile_step.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {CompileElement} from './compile_element';
22
import {CompileControl} from './compile_control';
3-
import {AnnotatedType} from '../annotated_type';
3+
import {DirectiveMetadata} from '../directive_metadata';
44

55
/**
66
* One part of the compile process.

0 commit comments

Comments
 (0)