first chunk of interfaces that are valid via dart analyzer
This commit is contained in:

committed by
Tobias Bosch

parent
29c20f7a50
commit
8afa421d75
12
modules/core/src/angular.js
vendored
Normal file
12
modules/core/src/angular.js
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Define public API for Angular here
|
||||
*/
|
||||
export * from './annotations/directive';
|
||||
export * from './annotations/component';
|
||||
export * from './annotations/template_config';
|
||||
|
||||
export * from './compiler/compiler';
|
||||
export * from './compiler/template_loader';
|
||||
|
||||
export * from './view/proto_view';
|
||||
export * from './view/view';
|
65
modules/core/src/annotations/component.js
Normal file
65
modules/core/src/annotations/component.js
Normal file
@ -0,0 +1,65 @@
|
||||
import {Directive} from './directive';
|
||||
|
||||
export class Component extends Directive {
|
||||
@CONST constructor({
|
||||
selector,
|
||||
template,
|
||||
elementServices,
|
||||
componentServices,
|
||||
implementsTypes
|
||||
}:{
|
||||
selector:String,
|
||||
template:TemplateConfig,
|
||||
lightDomServices:DomServicesFunction,
|
||||
shadowDomServices:DomServicesFunction,
|
||||
componentServices:ComponentServicesFunction,
|
||||
implementsTypes:Array<Type>
|
||||
})
|
||||
{
|
||||
// super({selector, lightDomServices, implementsTypes});
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
/*
|
||||
import 'package:angular/core.dart' as core;
|
||||
|
||||
|
||||
@Component(
|
||||
selector: 'example',
|
||||
template: const TemplateConfig(
|
||||
url: 'example.dart',
|
||||
uses: const [core.CONFIG],
|
||||
directives: const [CompA],
|
||||
formatters: const [Stringify]
|
||||
),
|
||||
componentServices: Example.componentServices,
|
||||
elementServices: Example.elementServices,
|
||||
implementsTypes: const [App]
|
||||
)
|
||||
class Example implements App {
|
||||
static componentServices(Module m) {
|
||||
m.bind();
|
||||
}
|
||||
static elementServices(ElementModule m) {
|
||||
m.bind();
|
||||
}
|
||||
}
|
||||
|
||||
class CompA {}
|
||||
|
||||
@Formatter()
|
||||
class Stringify {}
|
||||
|
||||
<CompA>
|
||||
LightDOM:
|
||||
</CompA>
|
||||
|
||||
CompA ShadowDOM:
|
||||
<div>
|
||||
<CompB></CompB>
|
||||
</div>
|
||||
|
||||
CompB SHadowDOM:
|
||||
<div></div>
|
||||
*/
|
19
modules/core/src/annotations/directive.js
Normal file
19
modules/core/src/annotations/directive.js
Normal file
@ -0,0 +1,19 @@
|
||||
import {Type} from 'facade/lang';
|
||||
import {ElementServicesFunction} from './facade';
|
||||
|
||||
@ABSTRACT
|
||||
export class Directive {
|
||||
@CONST constructor({
|
||||
selector,
|
||||
lightDomServices,
|
||||
implementsTypes
|
||||
}:{
|
||||
selector:String,
|
||||
lightDomServices:ElementServicesFunction,
|
||||
implementsTypes:Array<Type>
|
||||
})
|
||||
{
|
||||
this.lightDomServices = lightDomServices;
|
||||
this.selector = selector;
|
||||
}
|
||||
}
|
5
modules/core/src/annotations/facade.dart
Normal file
5
modules/core/src/annotations/facade.dart
Normal file
@ -0,0 +1,5 @@
|
||||
import 'package:di/di.dart' show Module;
|
||||
import '../view/element_module.dart' show ElementModule;
|
||||
|
||||
typedef DomServicesFunction(ElementModule m);
|
||||
typedef ComponentServicesFunction(Module m);
|
2
modules/core/src/annotations/facade.es6
Normal file
2
modules/core/src/annotations/facade.es6
Normal file
@ -0,0 +1,2 @@
|
||||
export var DomServicesFunction = Function;
|
||||
export var ComponentServicesFunction = Function;
|
16
modules/core/src/annotations/template_config.js
Normal file
16
modules/core/src/annotations/template_config.js
Normal file
@ -0,0 +1,16 @@
|
||||
import {Type, List} from 'facade/lang';
|
||||
|
||||
export class TemplateConfig {
|
||||
@CONST constructor({
|
||||
url,
|
||||
directives,
|
||||
formatters,
|
||||
source
|
||||
}: {
|
||||
url: String,
|
||||
directives: List<Type>,
|
||||
formatters: List<Type>,
|
||||
source: List<TemplateConfig>
|
||||
})
|
||||
{}
|
||||
}
|
@ -1,7 +1,15 @@
|
||||
import {Future} from '../facade';
|
||||
import {ProtoView} from './proto_view';
|
||||
import {Future} from 'facade/lang';
|
||||
import {Element} from 'facade/dom';
|
||||
import {ProtoView} from '../view/proto_view';
|
||||
import {TemplateLoader} from './template_loader';
|
||||
|
||||
export class Compiler {
|
||||
|
||||
@FIELD('final _templateLoader:TemplateLoader')
|
||||
constructor(templateLoader:TemplateLoader) {
|
||||
this._templateLoader = templateLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Why future?
|
||||
* - compilation will load templates. Instantiating views before templates are loaded will
|
||||
@ -10,7 +18,9 @@ export class Compiler {
|
||||
* - don't know about injector in deserialization
|
||||
* - compile does not need the injector, only the ViewFactory does
|
||||
*/
|
||||
@of(ProtoView) compile(element:TemplateElement):Future {
|
||||
compile(component:Type, element:Element/* = null*/):Future<ProtoView> {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
11
modules/core/src/compiler/template_loader.js
Normal file
11
modules/core/src/compiler/template_loader.js
Normal file
@ -0,0 +1,11 @@
|
||||
import {Future} from 'facade/lang';
|
||||
import {Document} from 'facade/dom';
|
||||
|
||||
export class TemplateLoader {
|
||||
|
||||
constructor() {}
|
||||
|
||||
load(url:String):Future<Document> {
|
||||
return null;
|
||||
}
|
||||
}
|
11
modules/core/src/life_cycle/life_cycle.js
Normal file
11
modules/core/src/life_cycle/life_cycle.js
Normal file
@ -0,0 +1,11 @@
|
||||
export class LifeCycle {
|
||||
|
||||
@FIELD('final _changeDetection:ChangeDetection')
|
||||
@FIELD('final _onChangeDispatcher:OnChangeDispatcher')
|
||||
constructor() {}
|
||||
|
||||
digest() {
|
||||
_changeDetection.detectChanges();
|
||||
_onChangeDispatcher.done();
|
||||
}
|
||||
}
|
13
modules/core/src/view/element_injector_target.js
Normal file
13
modules/core/src/view/element_injector_target.js
Normal file
@ -0,0 +1,13 @@
|
||||
export class ElementInjectorTarget {
|
||||
@FIELD('final _elementInjectorIndex:int')
|
||||
@FIELD('final _directiveIndex:int')
|
||||
@FIELD('final _setterName:String')
|
||||
@FIELD('final _setter:SetterFn')
|
||||
constructor() {}
|
||||
|
||||
invoke(record:Record, elementInjectors:List<ElementInjector>) {
|
||||
var elementInjector:ElementInjector = elementInjectors[this._elementInjectorIndex];
|
||||
var directive = elementInjectors.getByIndex(this._directiveIndex);
|
||||
this._setter(directive, record.currentValue);
|
||||
}
|
||||
}
|
1
modules/core/src/view/element_module.js
Normal file
1
modules/core/src/view/element_module.js
Normal file
@ -0,0 +1 @@
|
||||
export class ElementModule {}
|
19
modules/core/src/view/on_change_dispatcher.js
Normal file
19
modules/core/src/view/on_change_dispatcher.js
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
//TODO(tbosch): I don't like to have done be called from a different place than notify
|
||||
// notify is called by change detection, but done is called by our wrapper on detect changes.
|
||||
export class OnChangeDispatcher {
|
||||
|
||||
@FIELD('_lastView:View')
|
||||
@FIELD('_lastTarget:ElementInjectorTarget')
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
notify(view:View, eTarget:ElementInjectorTarget) {
|
||||
|
||||
}
|
||||
|
||||
done() {
|
||||
|
||||
}
|
||||
}
|
27
modules/core/src/view/proto_element_injector.js
Normal file
27
modules/core/src/view/proto_element_injector.js
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
|
||||
/**
|
||||
|
||||
Difference beteween di.Injector and ElementInjector
|
||||
|
||||
di.Injector (di.Module):
|
||||
- imperative based (can create child injectors imperativly)
|
||||
- Lazy loading of code
|
||||
- Component/App Level services which are usually not DOM Related.
|
||||
|
||||
|
||||
ElementInjector (ElementModule):
|
||||
- ProtoBased (Injector structure fixed at compile time)
|
||||
- understands @Ancestor, @Parent, @Child, @Descendent
|
||||
- Fast
|
||||
- Query mechanism for children
|
||||
- 1:1 to DOM structure.
|
||||
*/
|
||||
|
||||
export class ProtoElementInjector {
|
||||
@FIELD('final _parent:ProtoElementInjector')
|
||||
/// Temporory instance while instantiating
|
||||
@FIELD('_instance:ElementInjector')
|
||||
constructor() {}
|
||||
}
|
||||
|
10
modules/core/src/view/proto_view.js
Normal file
10
modules/core/src/view/proto_view.js
Normal file
@ -0,0 +1,10 @@
|
||||
import {Module} from 'di/di';
|
||||
import {TemplateElement} from 'facade/dom';
|
||||
|
||||
export class ProtoView {
|
||||
@FIELD('final _template:TemplateElement')
|
||||
@FIELD('final _module:Module')
|
||||
@FIELD('final _protoElementInjectors:List<ProtoElementInjector>')
|
||||
@FIELD('final _protoWatchGroup:ProtoWatchGroup')
|
||||
@CONST constructor() { }
|
||||
}
|
34
modules/core/src/view/view.js
Normal file
34
modules/core/src/view/view.js
Normal file
@ -0,0 +1,34 @@
|
||||
import {Node, DocumentFragment} from 'facade/dom';
|
||||
import {ListWrapper wraps List} from 'facade/collection';
|
||||
import {Record} from 'change_detection/record';
|
||||
|
||||
@IMPLEMENTS(WatchGroupDispatcher)
|
||||
export class View {
|
||||
@FIELD('final _fragment:DocumentFragment')
|
||||
/// This list matches the _nodes list. It is sparse, since only Elements have ElementInjector
|
||||
@FIELD('final _rootElementInjectors:List<ElementInjector>')
|
||||
@FIELD('final _elementInjectors:List<ElementInjector>')
|
||||
@FIELD('final _textNodes:List<Text>')
|
||||
@FIELD('final _watchGroup:WatchGroup')
|
||||
/// When the view is part of render tree, the DocumentFragment is empty, which is why we need
|
||||
/// to keep track of the nodes.
|
||||
@FIELD('final _nodes:List<Node>')
|
||||
constructor(fragment:DocumentFragment) {
|
||||
this._fragment = fragment;
|
||||
this._nodes = ListWrapper.clone(fragment.childNodes);
|
||||
}
|
||||
|
||||
notify(record:Record, target) {
|
||||
/*
|
||||
// dispatch to element injector or text nodes based on context
|
||||
if (Number.is(target)) {
|
||||
// we know it refferst to _textNodes.
|
||||
} else {
|
||||
// we know that it is ElementInjectorTarge
|
||||
var eTarget:ElementInjectorTarget = target;
|
||||
onChangeDispatcher.notify(this, eTarget);
|
||||
eTarget.invoke(record, _elementInjectors);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user