first chunk of interfaces that are valid via dart analyzer
This commit is contained in:
parent
29c20f7a50
commit
8afa421d75
16
gulpfile.js
16
gulpfile.js
|
@ -58,9 +58,10 @@ var sourceTypeConfigs = {
|
|||
compiler: function() {
|
||||
return traceur(js2dartOptions, true);
|
||||
},
|
||||
transpileSrc: ['modules/**/*.es6d'],
|
||||
transpileSrc: ['modules/**/*.js'],
|
||||
htmlSrc: ['modules/*/src/**/*.html'],
|
||||
copySrc: ['modules/**/*.dart'],
|
||||
// TODO: execute pub get after a yaml changed and was copied over to 'build' folder
|
||||
copySrc: ['modules/**/*.dart', 'modules/**/*.yaml'],
|
||||
outputDir: 'build/dart',
|
||||
outputExt: 'dart',
|
||||
mimeType: 'application/dart'
|
||||
|
@ -69,9 +70,9 @@ var sourceTypeConfigs = {
|
|||
compiler: function() {
|
||||
return traceur(js2es5Options, true);
|
||||
},
|
||||
transpileSrc: ['modules/**/*.es*'],
|
||||
transpileSrc: ['modules/**/*.js', 'modules/**/*.es6'],
|
||||
htmlSrc: ['modules/*/src/**/*.html'],
|
||||
copySrc: ['modules/**/*.js'],
|
||||
copySrc: ['modules/**/*.es5'],
|
||||
outputDir: 'build/js',
|
||||
outputExt: 'js'
|
||||
}
|
||||
|
@ -82,18 +83,25 @@ gulp.task('modules/clean', function() {
|
|||
.pipe(clean());
|
||||
});
|
||||
|
||||
function renameSrcToLib(file) {
|
||||
file.dirname = file.dirname.replace(/\bsrc\b/, 'lib');
|
||||
}
|
||||
|
||||
function createModuleTask(sourceTypeConfig, isWatch) {
|
||||
var start = isWatch ? watch : gulp.src.bind(gulp);
|
||||
return function(done) {
|
||||
var transpile = start(sourceTypeConfig.transpileSrc)
|
||||
.pipe(rename({extname: '.'+sourceTypeConfig.outputExt}))
|
||||
.pipe(rename(renameSrcToLib))
|
||||
.pipe(sourceTypeConfig.compiler())
|
||||
.pipe(gulp.dest(sourceTypeConfig.outputDir));
|
||||
var copy = start(sourceTypeConfig.copySrc)
|
||||
.pipe(rename(renameSrcToLib))
|
||||
.pipe(gulp.dest(sourceTypeConfig.outputDir));
|
||||
// TODO: provide the list of files to the template
|
||||
// automatically!
|
||||
var html = start(sourceTypeConfig.htmlSrc)
|
||||
.pipe(rename(renameSrcToLib))
|
||||
.pipe(ejs({
|
||||
type: sourceTypeConfig.outputExt
|
||||
}))
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
name: change_detection
|
||||
environment:
|
||||
sdk: '>=1.4.0'
|
||||
dependencies:
|
||||
dev_dependencies:
|
||||
unittest: '>=0.10.1 <0.12.0'
|
|
@ -0,0 +1,5 @@
|
|||
export class ChangeDetection {
|
||||
|
||||
detectChanges():int {}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export class ProtoRecord {
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
export class ProtoWatchGroup {
|
||||
watch(
|
||||
expression:String,
|
||||
context:dynamic,
|
||||
{isCollection})
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@Component(
|
||||
bind: {
|
||||
'title': 'title',
|
||||
'name': 'name'
|
||||
}
|
||||
)
|
||||
class MyComponent implements ChangeListener {
|
||||
String name;
|
||||
String title;
|
||||
|
||||
onChange(List<Record> changes) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
|
@ -0,0 +1,3 @@
|
|||
export class Record {
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export class WatchGroup {
|
||||
@FIELD('final dispatcher:WatchGroupDispatcher')
|
||||
constructor() {}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
export class WatchGroupDispatcher {
|
||||
notify(record:Record, context) {}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
name: core
|
||||
environment:
|
||||
sdk: '>=1.4.0'
|
||||
dependencies:
|
||||
change_detection:
|
||||
path: ../change_detection
|
||||
di:
|
||||
path: ../di
|
||||
facade:
|
||||
path: ../facade
|
||||
dev_dependencies:
|
||||
unittest: '>=0.10.1 <0.12.0'
|
|
@ -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';
|
|
@ -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>
|
||||
*/
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
|
@ -0,0 +1,2 @@
|
|||
export var DomServicesFunction = Function;
|
||||
export var ComponentServicesFunction = Function;
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
export class LifeCycle {
|
||||
|
||||
@FIELD('final _changeDetection:ChangeDetection')
|
||||
@FIELD('final _onChangeDispatcher:OnChangeDispatcher')
|
||||
constructor() {}
|
||||
|
||||
digest() {
|
||||
_changeDetection.detectChanges();
|
||||
_onChangeDispatcher.done();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export class ElementModule {}
|
|
@ -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() {
|
||||
|
||||
}
|
||||
}
|
|
@ -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() {}
|
||||
}
|
||||
|
|
@ -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() { }
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import {describe, id} from 'spec/spec';
|
||||
|
||||
function main() {
|
||||
describe('compiler', () => {
|
||||
it('should hello', () => {
|
||||
print('I am working');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
name: di
|
||||
environment:
|
||||
sdk: '>=1.4.0'
|
||||
dependencies:
|
||||
dev_dependencies:
|
||||
unittest: '>=0.10.1 <0.12.0'
|
|
@ -0,0 +1 @@
|
|||
export * from './module';
|
|
@ -0,0 +1,24 @@
|
|||
import {Type} from 'facade/lang';
|
||||
import {Map, MapWrapper wraps Map} from 'facade/collection';
|
||||
|
||||
/// becouse we need to know when toValue was not set.
|
||||
/// (it could be that toValue is set to null or undefined in js)
|
||||
var _UNDEFINED = {}
|
||||
|
||||
export class Module {
|
||||
|
||||
@FIELD('final bindings:Map<Key, Binding>')
|
||||
constructor(){
|
||||
this.bindings = new MapWrapper();
|
||||
}
|
||||
|
||||
bind(type:Type,
|
||||
{toValue=_UNDEFINED, toFactory, toImplementation, inject, toInstanceOf, withAnnotation}/*:
|
||||
{toFactory:Function, toImplementation: Type, inject: Array, toInstanceOf:Type}*/) {}
|
||||
|
||||
bindByKey(key:Key,
|
||||
{toValue=_UNDEFINED, toFactory, toImplementation, inject, toInstanceOf}/*:
|
||||
{toFactory:Function, toImplementation: Type, inject: Array, toInstanceOf:Type}*/) {}
|
||||
|
||||
install(module:Module) {}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
name: examples
|
||||
environment:
|
||||
sdk: '>=1.4.0'
|
||||
dependencies:
|
||||
dev_dependencies:
|
||||
unittest: '>=0.10.1 <0.12.0'
|
|
@ -1,5 +1,6 @@
|
|||
import {DOM} from './dom';
|
||||
export class App {
|
||||
@field('input:Element')
|
||||
constructor() {
|
||||
this.input = null;
|
||||
this.list = null;
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* This is a special facade used to bootstrap JS automatically.
|
||||
* (In contrast to door wheere the user needs to explicitly call into angular.)
|
||||
* This file is appened to AngularJS and needs to be written in ES5.
|
||||
*/
|
||||
(function(window, document) {
|
||||
document.addEventListener('DOMContentLoaded', bootstrap, false);
|
||||
function bootstrap() {
|
||||
// TODO(misko): load application factory from the module system.
|
||||
applicationFactory().run();
|
||||
}
|
||||
})(window, document);
|
|
@ -0,0 +1,6 @@
|
|||
name: facade
|
||||
environment:
|
||||
sdk: '>=1.4.0'
|
||||
dependencies:
|
||||
dev_dependencies:
|
||||
unittest: '>=0.10.1 <0.12.0'
|
|
@ -0,0 +1,20 @@
|
|||
library facade.collection;
|
||||
|
||||
import 'dart:collection' show HashMap;
|
||||
export 'dart:collection' show Map;
|
||||
export 'dart:core' show List;
|
||||
|
||||
class MapWrapper {
|
||||
static HashMap create() => new HashMap();
|
||||
static get(m, k) => m[k];
|
||||
static void set(m, k, v){ m[k] = v; }
|
||||
static contains(m, k) => m.containsKey(k);
|
||||
}
|
||||
|
||||
class ListWrapper {
|
||||
static List clone(List l) => new List.from(l);
|
||||
static List create() => new List();
|
||||
static get(m, k) => m[k];
|
||||
static void set(m, k, v) { m[k] = v; }
|
||||
static contains(m, k) => m.containsKey(k);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
export var List = window.Array;
|
||||
export var Map = window.Map;
|
||||
export class MapWrapper {
|
||||
static create():HashMap { return new HashMap(); }
|
||||
static get(m, k) { return m[k]; }
|
||||
static set(m, k, v) { m[k] = v; }
|
||||
static contains(m, k) { return m.containsKey(k); }
|
||||
}
|
||||
|
||||
|
||||
export class ListWrapper {
|
||||
static create():List { return new List(); }
|
||||
static get(m, k) { return m[k]; }
|
||||
static set(m, k, v) { m[k] = v; }
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
library dom;
|
||||
library angular.core.facade.dom;
|
||||
|
||||
import 'dart:html';
|
||||
|
||||
export 'dart:html' show DocumentFragment, Node, Element, TemplateElement;
|
||||
|
||||
class DOM {
|
||||
static query(selector) {
|
||||
return document.query(selector);
|
|
@ -1,3 +1,8 @@
|
|||
export var DocumentFragment = window.DocumentFragment;
|
||||
export var Node = window.Node;
|
||||
export var Element = window.HTMLElement;
|
||||
export var TemplateElement = window.HTMLTemplateElement;
|
||||
|
||||
export class DOM {
|
||||
static query(selector) {
|
||||
return document.querySelector(selector);
|
|
@ -0,0 +1,4 @@
|
|||
library angular.core.facade.async;
|
||||
|
||||
export 'dart:async' show Future;
|
||||
export 'dart:core' show Type;
|
|
@ -0,0 +1,2 @@
|
|||
export var Future = Promise;
|
||||
export var Type = Function;
|
|
@ -0,0 +1,13 @@
|
|||
import 'dart:core' as core;
|
||||
import 'dart:collection';
|
||||
|
||||
class Map {
|
||||
|
||||
new() => null;
|
||||
|
||||
ping() => core.print('map');
|
||||
}
|
||||
|
||||
main() {
|
||||
new Map().ping();
|
||||
}
|
|
@ -1 +1 @@
|
|||
Subproject commit 9fc0b738664c75ac16c44f190322b4b7ca95a1ea
|
||||
Subproject commit 971ffb32b88bcad5eab5877ecbde2995e30c96c1
|
Loading…
Reference in New Issue