feat(forms): add easy way to switch between forms modules (#9202)

This commit is contained in:
Kara 2016-06-14 18:23:40 -07:00 committed by Rob Wormald
parent fe01e2efb7
commit 22916bb5d1
75 changed files with 3553 additions and 566 deletions

View File

@ -44,6 +44,7 @@ for PACKAGE in \
core \
compiler \
common \
forms \
platform-browser \
platform-browser-dynamic \
platform-server \

View File

@ -95,6 +95,11 @@ export class NgForm extends ControlContainer implements Form {
@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
super();
console.warn(`
*It looks like you're using the old forms module. This will be opt-in in the next RC, and
will eventually be removed in favor of the new forms module. For more information, see:
https://docs.google.com/document/u/1/d/1RIezQqE4aEhBRmArIAS1mRIZtWFf6JxN_7B4meyWK0Y/pub
`);
this.form = new ControlGroup(
{}, null, composeValidators(validators), composeAsyncValidators(asyncValidators));
}

View File

@ -113,6 +113,11 @@ export class NgFormModel extends ControlContainer implements Form,
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
super();
console.warn(`
*It looks like you're using the old forms module. This will be opt-in in the next RC, and
will eventually be removed in favor of the new forms module. For more information, see:
https://docs.google.com/document/u/1/d/1RIezQqE4aEhBRmArIAS1mRIZtWFf6JxN_7B4meyWK0Y/pub
`);
}
ngOnChanges(changes: SimpleChanges): void {

View File

@ -1,54 +0,0 @@
/**
* @module
* @description
* This module is used for handling user input, by defining and building a {@link FormGroup} that
* consists of
* {@link FormControl} objects, and mapping them onto the DOM. {@link FormControl} objects can then
* be used
* to read information
* from the form DOM elements.
*
* Forms providers are not included in default providers; you must import these providers
* explicitly.
*/
import {Type} from '@angular/core';
import {RadioControlRegistry} from './forms/directives/radio_control_value_accessor';
import {FormBuilder} from './forms/form_builder';
export {FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES, RadioButtonState} from './forms/directives';
export {AbstractControlDirective} from './forms/directives/abstract_control_directive';
export {CheckboxControlValueAccessor} from './forms/directives/checkbox_value_accessor';
export {ControlContainer} from './forms/directives/control_container';
export {ControlValueAccessor, NG_VALUE_ACCESSOR} from './forms/directives/control_value_accessor';
export {DefaultValueAccessor} from './forms/directives/default_value_accessor';
export {Form} from './forms/directives/form_interface';
export {NgControl} from './forms/directives/ng_control';
export {NgControlStatus} from './forms/directives/ng_control_status';
export {NgForm} from './forms/directives/ng_form';
export {NgModel} from './forms/directives/ng_model';
export {NgModelGroup} from './forms/directives/ng_model_group';
export {FormControlDirective} from './forms/directives/reactive_directives/form_control_directive';
export {FormControlName} from './forms/directives/reactive_directives/form_control_name';
export {FormGroupDirective} from './forms/directives/reactive_directives/form_group_directive';
export {FormGroupName} from './forms/directives/reactive_directives/form_group_name';
export {NgSelectOption, SelectControlValueAccessor} from './forms/directives/select_control_value_accessor';
export {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator, Validator} from './forms/directives/validators';
export {FormBuilder} from './forms/form_builder';
export {AbstractControl, FormArray, FormControl, FormGroup} from './forms/model';
export {NG_ASYNC_VALIDATORS, NG_VALIDATORS, Validators} from './forms/validators';
/**
* Shorthand set of providers used for building Angular forms.
*
* ### Example
*
* ```typescript
* bootstrap(MyApp, [FORM_PROVIDERS]);
* ```
*
* @experimental
*/
export const FORM_PROVIDERS: Type[] = /*@ts2dart_const*/[FormBuilder, RadioControlRegistry];

View File

@ -21,6 +21,7 @@ export './src/core/debug/debug_node.dart' show DebugElement,
asNativeElements;
export './src/core/testability/testability.dart';
export './src/core/change_detection.dart';
export './src/core/platform_directives_and_pipes.dart';
export './src/core/platform_common_providers.dart';
export './src/core/application_common_providers.dart';
export './src/core/reflection/reflection.dart';

View File

@ -14,6 +14,7 @@ export * from './src/linker';
export {DebugElement, DebugNode, asNativeElements, getDebugNode} from './src/debug/debug_node';
export * from './src/testability/testability';
export * from './src/change_detection';
export * from './src/platform_directives_and_pipes';
export * from './src/platform_common_providers';
export * from './src/application_common_providers';
export {wtfCreateScope, wtfLeave, wtfStartTimeRange, wtfEndTimeRange, WtfScopeFn} from './src/profile/profile';

View File

@ -0,0 +1,58 @@
import {OpaqueToken} from './di';
/**
A token that can be provided when bootstrapping an application to make an array of directives
* available in every component of the application.
*
* ### Example
*
* ```typescript
* import {PLATFORM_DIRECTIVES} from '@angular/core';
* import {OtherDirective} from './myDirectives';
*
* @Component({
* selector: 'my-component',
* template: `
* <!-- can use other directive even though the component does not list it in `directives` -->
* <other-directive></other-directive>
* `
* })
* export class MyComponent {
* ...
* }
*
* bootstrap(MyComponent, [{provide: PLATFORM_DIRECTIVES, useValue: [OtherDirective],
multi:true}]);
* ```
* @stable
*/
export const PLATFORM_DIRECTIVES: OpaqueToken =
/*@ts2dart_const*/ new OpaqueToken('Platform Directives');
/**
* A token that can be provided when bootstraping an application to make an array of pipes
* available in every component of the application.
*
* ### Example
*
* ```typescript
* import {PLATFORM_PIPES} from '@angular/core';
* import {OtherPipe} from './myPipe';
*
* @Component({
* selector: 'my-component',
* template: `
* {{123 | other-pipe}}
* `
* })
* export class MyComponent {
* ...
* }
*
* bootstrap(MyComponent, [{provide: PLATFORM_PIPES, useValue: [OtherPipe], multi:true}]);
* ```
* @stable
*/
export const PLATFORM_PIPES: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken('Platform Pipes');

View File

@ -0,0 +1 @@
export 'index.dart';

View File

@ -0,0 +1 @@
export * from './src/forms';

View File

@ -0,0 +1,19 @@
{
"name": "@angular/forms",
"version": "0.0.0-PLACEHOLDER",
"description": "",
"main": "index.js",
"jsnext:main": "esm/index.js",
"typings": "index.d.ts",
"author": "angular",
"license": "MIT",
"peerDependencies": {
"@angular/core": "0.0.0-PLACEHOLDER",
"@angular/common": "0.0.0-PLACEHOLDER",
"@angular/compiler": "0.0.0-PLACEHOLDER"
},
"repository": {
"type": "git",
"url": "https://github.com/angular/angular.git"
}
}

View File

@ -0,0 +1,19 @@
export default {
entry: '../../../dist/packages-dist/forms/esm/index.js',
dest: '../../../dist/packages-dist/forms/esm/forms.umd.js',
format: 'umd',
moduleName: 'ng.forms',
globals: {
'@angular/core': 'ng.core',
'@angular/common': 'ng.common',
'@angular/compiler': 'ng.compiler',
'rxjs/Subject': 'Rx',
'rxjs/observable/PromiseObservable': 'Rx', // this is wrong, but this stuff has changed in rxjs b.6 so we need to fix it when we update.
'rxjs/operator/toPromise': 'Rx.Observable.prototype',
'rxjs/Observable': 'Rx'
},
plugins: [
// nodeResolve({ jsnext: true, main: true }),
]
}

View File

@ -1,5 +1,5 @@
import {unimplemented} from '../../facade/exceptions';
import {isPresent} from '../../facade/lang';
import {unimplemented} from '../facade/exceptions';
import {isPresent} from '../facade/lang';
import {AbstractControl} from '../model';

View File

@ -1,6 +1,6 @@
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
import {isBlank} from '../../facade/lang';
import {isBlank} from '../facade/lang';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';

View File

@ -1,4 +1,4 @@
import {unimplemented} from '../../facade/exceptions';
import {unimplemented} from '../facade/exceptions';
import {AbstractControlDirective} from './abstract_control_directive';
import {ControlValueAccessor} from './control_value_accessor';

View File

@ -1,6 +1,6 @@
import {Directive, Self} from '@angular/core';
import {isPresent} from '../../facade/lang';
import {isPresent} from '../facade/lang';
import {NgControl} from './ng_control';

View File

@ -1,8 +1,8 @@
import {Directive, Inject, Optional, Self, forwardRef} from '@angular/core';
import {EventEmitter, ObservableWrapper, PromiseWrapper} from '../../facade/async';
import {ListWrapper} from '../../facade/collection';
import {isPresent} from '../../facade/lang';
import {EventEmitter, ObservableWrapper, PromiseWrapper} from '../facade/async';
import {ListWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang';
import {AbstractControl, FormControl, FormGroup} from '../model';
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';

View File

@ -1,7 +1,7 @@
import {Directive, Host, Inject, Input, OnChanges, OnDestroy, Optional, Output, Self, SimpleChanges, forwardRef} from '@angular/core';
import {EventEmitter, ObservableWrapper} from '../../facade/async';
import {BaseException} from '../../facade/exceptions';
import {EventEmitter, ObservableWrapper} from '../facade/async';
import {BaseException} from '../facade/exceptions';
import {FormControl} from '../model';
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../validators';

View File

@ -1,6 +1,6 @@
import {Directive, ElementRef, Renderer, forwardRef} from '@angular/core';
import {NumberWrapper} from '../../facade/lang';
import {NumberWrapper} from '../facade/lang';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';

View File

@ -1,7 +1,7 @@
import {Directive, ElementRef, Injectable, Injector, Input, OnDestroy, OnInit, Renderer, forwardRef} from '@angular/core';
import {ListWrapper} from '../../facade/collection';
import {isPresent} from '../../facade/lang';
import {ListWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
import {NgControl} from './ng_control';

View File

@ -1,7 +1,7 @@
import {Directive, Inject, Input, OnChanges, Optional, Output, Self, SimpleChanges, forwardRef} from '@angular/core';
import {EventEmitter, ObservableWrapper} from '../../../facade/async';
import {StringMapWrapper} from '../../../facade/collection';
import {EventEmitter, ObservableWrapper} from '../../facade/async';
import {StringMapWrapper} from '../../facade/collection';
import {FormControl} from '../../model';
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../../validators';

View File

@ -1,6 +1,6 @@
import {Directive, Host, Inject, Input, OnChanges, OnDestroy, Optional, Output, Self, SimpleChanges, SkipSelf, forwardRef} from '@angular/core';
import {EventEmitter, ObservableWrapper} from '../../../facade/async';
import {EventEmitter, ObservableWrapper} from '../../facade/async';
import {FormControl} from '../../model';
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../../validators';

View File

@ -1,9 +1,9 @@
import {Directive, Inject, Input, OnChanges, Optional, Output, Self, SimpleChanges, forwardRef} from '@angular/core';
import {EventEmitter, ObservableWrapper} from '../../../facade/async';
import {ListWrapper, StringMapWrapper} from '../../../facade/collection';
import {BaseException} from '../../../facade/exceptions';
import {isBlank} from '../../../facade/lang';
import {EventEmitter, ObservableWrapper} from '../../facade/async';
import {ListWrapper, StringMapWrapper} from '../../facade/collection';
import {BaseException} from '../../facade/exceptions';
import {isBlank} from '../../facade/lang';
import {FormControl, FormGroup} from '../../model';
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS, Validators} from '../../validators';
import {ControlContainer} from '../control_container';

View File

@ -1,7 +1,7 @@
import {Directive, ElementRef, Host, Input, OnDestroy, Optional, Renderer, forwardRef} from '@angular/core';
import {MapWrapper} from '../../facade/collection';
import {StringWrapper, isBlank, isPresent, isPrimitive, looseIdentical} from '../../facade/lang';
import {MapWrapper} from '../facade/collection';
import {StringWrapper, isBlank, isPresent, isPrimitive, looseIdentical} from '../facade/lang';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';

View File

@ -1,7 +1,7 @@
import {Directive, ElementRef, Host, Input, OnDestroy, Optional, Renderer, forwardRef} from '@angular/core';
import {MapWrapper} from '../../facade/collection';
import {StringWrapper, isBlank, isPresent, isPrimitive, isString, looseIdentical} from '../../facade/lang';
import {MapWrapper} from '../facade/collection';
import {StringWrapper, isBlank, isPresent, isPrimitive, isString, looseIdentical} from '../facade/lang';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';

View File

@ -1,6 +1,6 @@
import {ListWrapper, StringMapWrapper} from '../../facade/collection';
import {BaseException} from '../../facade/exceptions';
import {hasConstructor, isBlank, isPresent, looseIdentical} from '../../facade/lang';
import {ListWrapper, StringMapWrapper} from '../facade/collection';
import {BaseException} from '../facade/exceptions';
import {hasConstructor, isBlank, isPresent, looseIdentical} from '../facade/lang';
import {FormControl, FormGroup} from '../model';
import {Validators} from '../validators';

View File

@ -1,6 +1,6 @@
import {Attribute, Directive, forwardRef} from '@angular/core';
import {NumberWrapper} from '../../facade/lang';
import {NumberWrapper} from '../facade/lang';
import {AbstractControl} from '../model';
import {NG_VALIDATORS, Validators} from '../validators';

View File

@ -0,0 +1,132 @@
library angular2.core.facade.async;
import 'dart:async';
export 'dart:async' show Stream, StreamController, StreamSubscription;
export 'promise.dart';
class TimerWrapper {
static Timer setTimeout(fn(), int millis) =>
new Timer(new Duration(milliseconds: millis), fn);
static void clearTimeout(Timer timer) {
timer.cancel();
}
static Timer setInterval(fn(), int millis) {
var interval = new Duration(milliseconds: millis);
return new Timer.periodic(interval, (Timer timer) {
fn();
});
}
static void clearInterval(Timer timer) {
timer.cancel();
}
}
class ObservableWrapper {
static StreamSubscription subscribe/*<T>*/(Stream s, onNext(/*=T*/ value),
[onError, onComplete]) {
return s.listen(onNext,
onError: onError, onDone: onComplete, cancelOnError: true);
}
static bool isObservable(obs) {
return obs is Stream;
}
/**
* Returns whether `emitter` has any subscribers listening to events.
*/
static bool hasSubscribers(EventEmitter emitter) {
return emitter._controller.hasListener;
}
static void dispose(StreamSubscription s) {
s.cancel();
}
@Deprecated('Use callEmit() instead')
static void callNext(EventEmitter emitter, value) {
emitter.add(value);
}
static void callEmit(EventEmitter emitter, value) {
emitter.add(value);
}
static void callError(EventEmitter emitter, error) {
emitter.addError(error);
}
static void callComplete(EventEmitter emitter) {
emitter.close();
}
static Stream fromPromise(Future f) {
return new Stream.fromFuture(f);
}
static Future toPromise(Stream s) {
return s.single;
}
}
class EventEmitter<T> extends Stream<T> {
StreamController<T> _controller;
/// Creates an instance of [EventEmitter], which depending on [isAsync],
/// delivers events synchronously or asynchronously.
EventEmitter([bool isAsync = true]) {
_controller = new StreamController<T>.broadcast(sync: !isAsync);
}
StreamSubscription<T> listen(void onData(T event),
{Function onError, void onDone(), bool cancelOnError}) {
return _controller.stream.listen(onData,
onError: onError, onDone: onDone, cancelOnError: cancelOnError);
}
void add(value) {
_controller.add(value);
}
void emit(value) {
_controller.add(value);
}
void addError(error) {
_controller.addError(error);
}
void close() {
_controller.close();
}
}
//todo(robwormald): maybe fix in ts2dart?
class Subject<T> extends Stream<T> {
StreamController<T> _controller;
Subject([bool isAsync = true]) {
_controller = new StreamController<T>.broadcast(sync: !isAsync);
}
StreamSubscription<T> listen(void onData(T data),
{Function onError, void onDone(), bool cancelOnError}) {
return _controller.stream.listen(onData,
onError: onError, onDone: onDone, cancelOnError: cancelOnError);
}
void add(value) {
_controller.add(value);
}
void addError(error) {
_controller.addError(error);
}
void close() {
_controller.close();
}
}

View File

@ -0,0 +1,169 @@
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';
import {PromiseObservable} from 'rxjs/observable/PromiseObservable';
import {toPromise} from 'rxjs/operator/toPromise';
import {global, noop} from './lang';
export {Observable} from 'rxjs/Observable';
export {Subject} from 'rxjs/Subject';
export {PromiseCompleter, PromiseWrapper} from './promise';
export class TimerWrapper {
static setTimeout(fn: (...args: any[]) => void, millis: number): number {
return global.setTimeout(fn, millis);
}
static clearTimeout(id: number): void { global.clearTimeout(id); }
static setInterval(fn: (...args: any[]) => void, millis: number): number {
return global.setInterval(fn, millis);
}
static clearInterval(id: number): void { global.clearInterval(id); }
}
export class ObservableWrapper {
// TODO(vsavkin): when we use rxnext, try inferring the generic type from the first arg
static subscribe<T>(
emitter: any, onNext: (value: T) => void, onError?: (exception: any) => void,
onComplete: () => void = () => {}): Object {
onError = (typeof onError === 'function') && onError || noop;
onComplete = (typeof onComplete === 'function') && onComplete || noop;
return emitter.subscribe({next: onNext, error: onError, complete: onComplete});
}
static isObservable(obs: any): boolean { return !!obs.subscribe; }
/**
* Returns whether `obs` has any subscribers listening to events.
*/
static hasSubscribers(obs: EventEmitter<any>): boolean { return obs.observers.length > 0; }
static dispose(subscription: any) { subscription.unsubscribe(); }
/**
* @deprecated - use callEmit() instead
*/
static callNext(emitter: EventEmitter<any>, value: any) { emitter.next(value); }
static callEmit(emitter: EventEmitter<any>, value: any) { emitter.emit(value); }
static callError(emitter: EventEmitter<any>, error: any) { emitter.error(error); }
static callComplete(emitter: EventEmitter<any>) { emitter.complete(); }
static fromPromise(promise: Promise<any>): Observable<any> {
return PromiseObservable.create(promise);
}
static toPromise(obj: Observable<any>): Promise<any> { return toPromise.call(obj); }
}
/**
* Use by directives and components to emit custom Events.
*
* ### Examples
*
* In the following example, `Zippy` alternatively emits `open` and `close` events when its
* title gets clicked:
*
* ```
* @Component({
* selector: 'zippy',
* template: `
* <div class="zippy">
* <div (click)="toggle()">Toggle</div>
* <div [hidden]="!visible">
* <ng-content></ng-content>
* </div>
* </div>`})
* export class Zippy {
* visible: boolean = true;
* @Output() open: EventEmitter<any> = new EventEmitter();
* @Output() close: EventEmitter<any> = new EventEmitter();
*
* toggle() {
* this.visible = !this.visible;
* if (this.visible) {
* this.open.emit(null);
* } else {
* this.close.emit(null);
* }
* }
* }
* ```
*
* The events payload can be accessed by the parameter `$event` on the components output event
* handler:
*
* ```
* <zippy (open)="onOpen($event)" (close)="onClose($event)"></zippy>
* ```
*
* Uses Rx.Observable but provides an adapter to make it work as specified here:
* https://github.com/jhusain/observable-spec
*
* Once a reference implementation of the spec is available, switch to it.
* @stable
*/
export class EventEmitter<T> extends Subject<T> {
// TODO: mark this as internal once all the facades are gone
// we can't mark it as internal now because EventEmitter exported via @angular/core would not
// contain this property making it incompatible with all the code that uses EventEmitter via
// facades, which are local to the code and do not have this property stripped.
// tslint:disable-next-line
__isAsync: boolean;
/**
* Creates an instance of [EventEmitter], which depending on [isAsync],
* delivers events synchronously or asynchronously.
*/
constructor(isAsync: boolean = false) {
super();
this.__isAsync = isAsync;
}
emit(value: T) { super.next(value); }
/**
* @deprecated - use .emit(value) instead
*/
next(value: any) { super.next(value); }
subscribe(generatorOrNext?: any, error?: any, complete?: any): any {
let schedulerFn: any /** TODO #9100 */;
let errorFn = (err: any): any /** TODO #9100 */ => null;
let completeFn = (): any /** TODO #9100 */ => null;
if (generatorOrNext && typeof generatorOrNext === 'object') {
schedulerFn = this.__isAsync ? (value: any /** TODO #9100 */) => {
setTimeout(() => generatorOrNext.next(value));
} : (value: any /** TODO #9100 */) => { generatorOrNext.next(value); };
if (generatorOrNext.error) {
errorFn = this.__isAsync ? (err) => { setTimeout(() => generatorOrNext.error(err)); } :
(err) => { generatorOrNext.error(err); };
}
if (generatorOrNext.complete) {
completeFn = this.__isAsync ? () => { setTimeout(() => generatorOrNext.complete()); } :
() => { generatorOrNext.complete(); };
}
} else {
schedulerFn = this.__isAsync ? (value: any /** TODO #9100 */) => {
setTimeout(() => generatorOrNext(value));
} : (value: any /** TODO #9100 */) => { generatorOrNext(value); };
if (error) {
errorFn =
this.__isAsync ? (err) => { setTimeout(() => error(err)); } : (err) => { error(err); };
}
if (complete) {
completeFn =
this.__isAsync ? () => { setTimeout(() => complete()); } : () => { complete(); };
}
}
return super.subscribe(schedulerFn, errorFn, completeFn);
}
}

View File

@ -0,0 +1,17 @@
library angular.core.facade.base_wrapped_exception;
/**
* A base class for the WrappedException that can be used to identify
* a WrappedException from ExceptionHandler without adding circular
* dependency.
*/
class BaseWrappedException extends Error {
BaseWrappedException();
get originalException => null;
get originalStack => null;
String get message => '';
String get wrapperMessage => '';
dynamic get context => null;
}

View File

@ -0,0 +1,15 @@
/**
* A base class for the WrappedException that can be used to identify
* a WrappedException from ExceptionHandler without adding circular
* dependency.
*/
export class BaseWrappedException extends Error {
constructor(message: string) { super(message); }
get wrapperMessage(): string { return ''; }
get wrapperStack(): any { return null; }
get originalException(): any { return null; }
get originalStack(): any { return null; }
get context(): any { return null; }
get message(): string { return ''; }
}

View File

@ -0,0 +1,32 @@
/**
* Dart version of browser APIs. This library depends on 'dart:html' and
* therefore can only run in the browser.
*/
library angular2.src.facade.browser;
import 'dart:js' show context;
import 'dart:html' show Location, window;
export 'dart:html'
show
document,
window,
Element,
Node,
MouseEvent,
KeyboardEvent,
Event,
EventTarget,
History,
Location,
EventListener;
Location get location => window.location;
final _gc = context['gc'];
void gc() {
if (_gc != null) {
_gc.apply(const []);
}
}

View File

@ -0,0 +1,17 @@
/**
* JS version of browser APIs. This library can only run in the browser.
*/
var win = typeof window !== 'undefined' && window || <any>{};
export {win as window};
export var document = win.document;
export var location = win.location;
export var gc = win['gc'] ? () => win['gc']() : (): any /** TODO #9100 */ => null;
export var performance = win['performance'] ? win['performance'] : null;
export const Event = win['Event'];
export const MouseEvent = win['MouseEvent'];
export const KeyboardEvent = win['KeyboardEvent'];
export const EventTarget = win['EventTarget'];
export const History = win['History'];
export const Location = win['Location'];
export const EventListener = win['EventListener'];

View File

@ -0,0 +1,287 @@
library facade.collection;
import 'dart:collection' show IterableBase;
import 'dart:convert' show JsonEncoder;
export 'dart:core' show Iterator, Map, List, Set;
import 'dart:math' show max, min;
var jsonEncoder = new JsonEncoder();
class MapIterator extends Iterator<List> {
final Iterator _iterator;
final Map _map;
MapIterator(Map map)
: _map = map,
_iterator = map.keys.iterator;
bool moveNext() => _iterator.moveNext();
List get current {
return _iterator.current != null
? [_iterator.current, _map[_iterator.current]]
: null;
}
}
class IterableMap extends IterableBase<List> {
final Map _map;
IterableMap(Map map) : _map = map;
Iterator<List> get iterator => new MapIterator(_map);
}
class MapWrapper {
static Map/*<K,V>*/ clone/*<K,V>*/(Map/*<K,V>*/ m) => new Map.from(m);
// in opposite to JS, Dart does not create a new map
static Map/*<K,V>*/ createFromStringMap/*<K,V>*/(Map/*<K,V>*/ m) => m;
// in opposite to JS, Dart does not create a new map
static Map/*<K,V>*/ toStringMap/*<K,V>*/(Map/*<K,V>*/ m) => m;
static Map/*<K,V>*/ createFromPairs/*<K,V>*/(List pairs) => pairs.fold(/*<K,V>*/{}, (m, p) {
m[p[0]] = p[1];
return m;
});
static void clearValues(Map m) {
for (var k in m.keys) {
m[k] = null;
}
}
static Iterable/*<List<dynamic>>*/ iterable/*<K,V>*/(Map/*<K,V>*/ m) => new IterableMap(m);
static List/*<K>*/ keys/*<K,V>*/(Map/*<K,V>*/ m) => m.keys.toList();
static List/*<V>*/ values/*<K,V>*/(Map/*<K,V>*/ m) => m.values.toList();
}
class StringMapWrapper {
static Map/*<String,V>*/ create/*<V>*/() => {};
static bool contains/*<V>*/(Map/*<String,V>*/ map, String key) => map.containsKey(key);
static get/*<V>*/(Map/*<String,V>*/ map, String key) => map[key];
static void set/*<V>*/(Map/*<String,V>*/ map, String key, /*=V*/value) {
map[key] = value;
}
static void delete/*<V>*/(Map/*<String,V>*/ m, String k) {
m.remove(k);
}
static void forEach/*<V>*/(Map/*<String,V>*/ m, fn(/*=V*/ v, String k)) {
m.forEach((k, v) => fn(v, k));
}
static Map/*<String,V>*/ merge/*<V>*/(Map/*<String,V>*/ a, Map/*<String,V>*/ b) {
var m = new Map/*<String,V>*/.from(a);
if (b != null) {
b.forEach((k, v) => m[k] = v);
}
return m;
}
static List<String> keys(Map<String, dynamic> a) {
return a.keys.toList();
}
static List values(Map<String, dynamic> a) {
return a.values.toList();
}
static bool isEmpty(Map m) => m.isEmpty;
static bool equals/*<V>*/(Map/*<String,V>*/ m1, Map/*<String,V>*/ m2) {
if (m1.length != m2.length) {
return false;
}
for (var key in m1.keys) {
if (m1[key] != m2[key]) {
return false;
}
}
return true;
}
}
typedef bool Predicate<T>(T item);
class ListWrapper {
static List/*<T>*/ clone/*<T>*/(Iterable/*<T>*/ l) => new List.from(l);
static List/*<T>*/ createFixedSize/*<T>*/(int size) => new List(size);
static List/*<T>*/ createGrowableSize/*<T>*/(int size) =>
new List.generate(size, (_) => null, growable: true);
static bool contains(List m, k) => m.contains(k);
static int indexOf(List list, value, [int startIndex = 0]) =>
list.indexOf(value, startIndex);
static int lastIndexOf(List list, value, [int startIndex = null]) =>
list.lastIndexOf(value, startIndex == null ? list.length : startIndex);
static void forEachWithIndex/*<T>*/(List/*<T>*/ list, fn(/*=T*/ item, int index)) {
for (var i = 0; i < list.length; ++i) {
fn(list[i], i);
}
}
static /*=T*/ first/*<T>*/(List/*<T>*/ list) => list.isEmpty ? null : list.first;
static /*=T*/ last/*<T>*/(List/*<T>*/ list) => list.isEmpty ? null : list.last;
static List/*<T>*/ reversed/*<T>*/(List/*<T>*/ list) => list.reversed.toList();
static List/*<T>*/ concat/*<T>*/(List/*<T>*/ a, List/*<T>*/ b) {
return new List()
..length = a.length + b.length
..setRange(0, a.length, a)
..setRange(a.length, a.length + b.length, b);
}
static void insert/*<T>*/(List/*<T>*/ l, int index, /*=T*/ value) {
l.insert(index, value);
}
static removeAt(List l, int index) => l.removeAt(index);
static void removeAll/*<T>*/(List/*<T>*/ list, List/*<T>*/ items) {
for (var i = 0; i < items.length; ++i) {
list.remove(items[i]);
}
}
static bool remove/*<T>*/(List/*<T>*/ list, /*=T*/ item) => list.remove(item);
static void clear(List l) {
l.clear();
}
static bool isEmpty(Iterable list) => list.isEmpty;
static void fill/*<T>*/(List/*<T>*/ l, /*=T*/ value, [int start = 0, int end]) {
l.fillRange(_startOffset(l, start), _endOffset(l, end), value);
}
static bool equals/*<T>*/(List/*<T>*/ a, List/*<T>*/ b) {
if (a.length != b.length) return false;
for (var i = 0; i < a.length; ++i) {
if (a[i] != b[i]) return false;
}
return true;
}
static List/*<T>*/ slice/*<T>*/(List/*<T>*/ l, [int from = 0, int to]) {
from = _startOffset(l, from);
to = _endOffset(l, to);
//in JS if from > to an empty array is returned
if (to != null && from > to) {
return [];
}
return l.sublist(from, to);
}
static List/*<T>*/ splice/*<T>*/(List/*<T>*/ l, int from, int length) {
from = _startOffset(l, from);
var to = from + length;
var sub = l.sublist(from, to);
l.removeRange(from, to);
return sub;
}
static void sort/*<T>*/(List/*<T>*/ l, [int compareFn(/*=T*/a, /*=T*/b) = null]) {
if (compareFn == null) {
l.sort();
} else {
l.sort(compareFn);
}
}
static String toJSON(List l) {
return jsonEncoder.convert(l);
}
// JS splice, slice, fill functions can take start < 0 which indicates a position relative to
// the end of the list
static int _startOffset(List l, int start) {
int len = l.length;
return start < 0 ? max(len + start, 0) : min(start, len);
}
// JS splice, slice, fill functions can take end < 0 which indicates a position relative to
// the end of the list
static int _endOffset(List l, int end) {
int len = l.length;
if (end == null) return len;
return end < 0 ? max(len + end, 0) : min(end, len);
}
static maximum(List l, fn(item)) {
if (l.length == 0) {
return null;
}
var solution = null;
var maxValue = double.NEGATIVE_INFINITY;
for (var index = 0; index < l.length; index++) {
var candidate = l[index];
if (candidate == null) {
continue;
}
var candidateValue = fn(candidate);
if (candidateValue > maxValue) {
solution = candidate;
maxValue = candidateValue;
}
}
return solution;
}
static List flatten(List l) {
var target = [];
_flattenArray(l, target);
return target;
}
static addAll(List l, List source) {
l.addAll(source);
}
}
List _flattenArray(List source, List target) {
if (source != null) {
for (var i = 0; i < source.length; i++) {
var item = source[i];
if (item is List) {
_flattenArray(item, target);
} else {
target.add(item);
}
}
}
return target;
}
bool isListLikeIterable(obj) => obj is Iterable;
bool areIterablesEqual/*<T>*/(
Iterable/*<T>*/ a,
Iterable/*<T>*/ b,
bool comparator(/*=T*/a, /*=T*/b))
{
var iterator1 = a.iterator;
var iterator2 = b.iterator;
while (true) {
var done1 = !iterator1.moveNext();
var done2 = !iterator2.moveNext();
if (done1 && done2) return true;
if (done1 || done2) return false;
if (!comparator(iterator1.current, iterator2.current)) return false;
}
}
void iterateListLike/*<T>*/(Iterable/*<T>*/ iter, fn(/*=T*/item)) {
assert(iter is Iterable);
for (var item in iter) {
fn(item);
}
}
class SetWrapper {
static Set/*<T>*/ createFromList/*<T>*/(List/*<T>*/ l) => new Set.from(l);
static bool has/*<T>*/(Set/*<T>*/ s, /*=T*/key) => s.contains(key);
static void delete/*<T>*/(Set/*<T>*/ m, /*=T*/k) {
m.remove(k);
}
}

View File

@ -0,0 +1,352 @@
import {getSymbolIterator, global, isArray, isBlank, isJsObject, isPresent} from './lang';
export var Map = global.Map;
export var Set = global.Set;
// Safari and Internet Explorer do not support the iterable parameter to the
// Map constructor. We work around that by manually adding the items.
var createMapFromPairs: {(pairs: any[]): Map<any, any>} = (function() {
try {
if (new Map(<any>[[1, 2]]).size === 1) {
return function createMapFromPairs(pairs: any[]): Map<any, any> { return new Map(pairs); };
}
} catch (e) {
}
return function createMapAndPopulateFromPairs(pairs: any[]): Map<any, any> {
var map = new Map();
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i];
map.set(pair[0], pair[1]);
}
return map;
};
})();
var createMapFromMap: {(m: Map<any, any>): Map<any, any>} = (function() {
try {
if (new Map(<any>new Map())) {
return function createMapFromMap(m: Map<any, any>): Map<any, any> { return new Map(<any>m); };
}
} catch (e) {
}
return function createMapAndPopulateFromMap(m: Map<any, any>): Map<any, any> {
var map = new Map();
m.forEach((v, k) => { map.set(k, v); });
return map;
};
})();
var _clearValues: {(m: Map<any, any>): void} = (function() {
if ((<any>(new Map()).keys()).next) {
return function _clearValues(m: Map<any, any>) {
var keyIterator = m.keys();
var k: any /** TODO #???? */;
while (!((k = (<any>keyIterator).next()).done)) {
m.set(k.value, null);
}
};
} else {
return function _clearValuesWithForeEach(m: Map<any, any>) {
m.forEach((v, k) => { m.set(k, null); });
};
}
})();
// Safari doesn't implement MapIterator.next(), which is used is Traceur's polyfill of Array.from
// TODO(mlaval): remove the work around once we have a working polyfill of Array.from
var _arrayFromMap: {(m: Map<any, any>, getValues: boolean): any[]} = (function() {
try {
if ((<any>(new Map()).values()).next) {
return function createArrayFromMap(m: Map<any, any>, getValues: boolean): any[] {
return getValues ? (<any>Array).from(m.values()) : (<any>Array).from(m.keys());
};
}
} catch (e) {
}
return function createArrayFromMapWithForeach(m: Map<any, any>, getValues: boolean): any[] {
var res = ListWrapper.createFixedSize(m.size), i = 0;
m.forEach((v, k) => {
res[i] = getValues ? v : k;
i++;
});
return res;
};
})();
export class MapWrapper {
static clone<K, V>(m: Map<K, V>): Map<K, V> { return createMapFromMap(m); }
static createFromStringMap<T>(stringMap: {[key: string]: T}): Map<string, T> {
var result = new Map<string, T>();
for (var prop in stringMap) {
result.set(prop, stringMap[prop]);
}
return result;
}
static toStringMap<T>(m: Map<string, T>): {[key: string]: T} {
var r: {[key: string]: T} = {};
m.forEach((v, k) => r[k] = v);
return r;
}
static createFromPairs(pairs: any[]): Map<any, any> { return createMapFromPairs(pairs); }
static clearValues(m: Map<any, any>) { _clearValues(m); }
static iterable<T>(m: T): T { return m; }
static keys<K>(m: Map<K, any>): K[] { return _arrayFromMap(m, false); }
static values<V>(m: Map<any, V>): V[] { return _arrayFromMap(m, true); }
}
/**
* Wraps Javascript Objects
*/
export class StringMapWrapper {
static create(): {[k: /*any*/ string]: any} {
// Note: We are not using Object.create(null) here due to
// performance!
// http://jsperf.com/ng2-object-create-null
return {};
}
static contains(map: {[key: string]: any}, key: string): boolean {
return map.hasOwnProperty(key);
}
static get<V>(map: {[key: string]: V}, key: string): V {
return map.hasOwnProperty(key) ? map[key] : undefined;
}
static set<V>(map: {[key: string]: V}, key: string, value: V) { map[key] = value; }
static keys(map: {[key: string]: any}): string[] { return Object.keys(map); }
static values<T>(map: {[key: string]: T}): T[] {
return Object.keys(map).reduce((r, a) => {
r.push(map[a]);
return r;
}, []);
}
static isEmpty(map: {[key: string]: any}): boolean {
for (var prop in map) {
return false;
}
return true;
}
static delete (map: {[key: string]: any}, key: string) { delete map[key]; }
static forEach<K, V>(map: {[key: string]: V}, callback: /*(V, K) => void*/ Function) {
for (var prop in map) {
if (map.hasOwnProperty(prop)) {
callback(map[prop], prop);
}
}
}
static merge<V>(m1: {[key: string]: V}, m2: {[key: string]: V}): {[key: string]: V} {
var m: {[key: string]: V} = {};
for (var attr in m1) {
if (m1.hasOwnProperty(attr)) {
m[attr] = m1[attr];
}
}
for (var attr in m2) {
if (m2.hasOwnProperty(attr)) {
m[attr] = m2[attr];
}
}
return m;
}
static equals<V>(m1: {[key: string]: V}, m2: {[key: string]: V}): boolean {
var k1 = Object.keys(m1);
var k2 = Object.keys(m2);
if (k1.length != k2.length) {
return false;
}
var key: any /** TODO #???? */;
for (var i = 0; i < k1.length; i++) {
key = k1[i];
if (m1[key] !== m2[key]) {
return false;
}
}
return true;
}
}
/**
* A boolean-valued function over a value, possibly including context information
* regarding that value's position in an array.
*/
export interface Predicate<T> { (value: T, index?: number, array?: T[]): boolean; }
export class ListWrapper {
// JS has no way to express a statically fixed size list, but dart does so we
// keep both methods.
static createFixedSize(size: number): any[] { return new Array(size); }
static createGrowableSize(size: number): any[] { return new Array(size); }
static clone<T>(array: T[]): T[] { return array.slice(0); }
static forEachWithIndex<T>(array: T[], fn: (t: T, n: number) => void) {
for (var i = 0; i < array.length; i++) {
fn(array[i], i);
}
}
static first<T>(array: T[]): T {
if (!array) return null;
return array[0];
}
static last<T>(array: T[]): T {
if (!array || array.length == 0) return null;
return array[array.length - 1];
}
static indexOf<T>(array: T[], value: T, startIndex: number = 0): number {
return array.indexOf(value, startIndex);
}
static contains<T>(list: T[], el: T): boolean { return list.indexOf(el) !== -1; }
static reversed<T>(array: T[]): T[] {
var a = ListWrapper.clone(array);
return a.reverse();
}
static concat(a: any[], b: any[]): any[] { return a.concat(b); }
static insert<T>(list: T[], index: number, value: T) { list.splice(index, 0, value); }
static removeAt<T>(list: T[], index: number): T {
var res = list[index];
list.splice(index, 1);
return res;
}
static removeAll<T>(list: T[], items: T[]) {
for (var i = 0; i < items.length; ++i) {
var index = list.indexOf(items[i]);
list.splice(index, 1);
}
}
static remove<T>(list: T[], el: T): boolean {
var index = list.indexOf(el);
if (index > -1) {
list.splice(index, 1);
return true;
}
return false;
}
static clear(list: any[]) { list.length = 0; }
static isEmpty(list: any[]): boolean { return list.length == 0; }
static fill(list: any[], value: any, start: number = 0, end: number = null) {
list.fill(value, start, end === null ? list.length : end);
}
static equals(a: any[], b: any[]): boolean {
if (a.length != b.length) return false;
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
}
static slice<T>(l: T[], from: number = 0, to: number = null): T[] {
return l.slice(from, to === null ? undefined : to);
}
static splice<T>(l: T[], from: number, length: number): T[] { return l.splice(from, length); }
static sort<T>(l: T[], compareFn?: (a: T, b: T) => number) {
if (isPresent(compareFn)) {
l.sort(compareFn);
} else {
l.sort();
}
}
static toString<T>(l: T[]): string { return l.toString(); }
static toJSON<T>(l: T[]): string { return JSON.stringify(l); }
static maximum<T>(list: T[], predicate: (t: T) => number): T {
if (list.length == 0) {
return null;
}
var solution: any /** TODO #???? */ = null;
var maxValue = -Infinity;
for (var index = 0; index < list.length; index++) {
var candidate = list[index];
if (isBlank(candidate)) {
continue;
}
var candidateValue = predicate(candidate);
if (candidateValue > maxValue) {
solution = candidate;
maxValue = candidateValue;
}
}
return solution;
}
static flatten<T>(list: Array<T|T[]>): T[] {
var target: any[] /** TODO #???? */ = [];
_flattenArray(list, target);
return target;
}
static addAll<T>(list: Array<T>, source: Array<T>): void {
for (var i = 0; i < source.length; i++) {
list.push(source[i]);
}
}
}
function _flattenArray(source: any[], target: any[]): any[] {
if (isPresent(source)) {
for (var i = 0; i < source.length; i++) {
var item = source[i];
if (isArray(item)) {
_flattenArray(item, target);
} else {
target.push(item);
}
}
}
return target;
}
export function isListLikeIterable(obj: any): boolean {
if (!isJsObject(obj)) return false;
return isArray(obj) ||
(!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
}
export function areIterablesEqual(a: any, b: any, comparator: Function): boolean {
var iterator1 = a[getSymbolIterator()]();
var iterator2 = b[getSymbolIterator()]();
while (true) {
let item1 = iterator1.next();
let item2 = iterator2.next();
if (item1.done && item2.done) return true;
if (item1.done || item2.done) return false;
if (!comparator(item1.value, item2.value)) return false;
}
}
export function iterateListLike(obj: any, fn: Function) {
if (isArray(obj)) {
for (var i = 0; i < obj.length; i++) {
fn(obj[i]);
}
} else {
var iterator = obj[getSymbolIterator()]();
var item: any /** TODO #???? */;
while (!((item = iterator.next()).done)) {
fn(item.value);
}
}
}
// Safari and Internet Explorer do not support the iterable parameter to the
// Set constructor. We work around that by manually adding the items.
var createSetFromList: {(lst: any[]): Set<any>} = (function() {
var test = new Set([1, 2, 3]);
if (test.size === 3) {
return function createSetFromList(lst: any[]): Set<any> { return new Set(lst); };
} else {
return function createSetAndPopulateFromList(lst: any[]): Set<any> {
var res = new Set(lst);
if (res.size !== lst.length) {
for (var i = 0; i < lst.length; i++) {
res.add(lst[i]);
}
}
return res;
};
}
})();
export class SetWrapper {
static createFromList<T>(lst: T[]): Set<T> { return createSetFromList(lst); }
static has<T>(s: Set<T>, key: T): boolean { return s.has(key); }
static delete<K>(m: Set<K>, k: K) { m.delete(k); }
}

View File

@ -0,0 +1,133 @@
import {BaseWrappedException} from './base_wrapped_exception';
import {isListLikeIterable} from './collection';
import {isBlank, isPresent} from './lang';
class _ArrayLogger {
res: any[] = [];
log(s: any): void { this.res.push(s); }
logError(s: any): void { this.res.push(s); }
logGroup(s: any): void { this.res.push(s); }
logGroupEnd(){};
}
/**
* Provides a hook for centralized exception handling.
*
* The default implementation of `ExceptionHandler` prints error messages to the `Console`. To
* intercept error handling,
* write a custom exception handler that replaces this default as appropriate for your app.
*
* ### Example
*
* ```javascript
*
* class MyExceptionHandler implements ExceptionHandler {
* call(error, stackTrace = null, reason = null) {
* // do something with the exception
* }
* }
*
* bootstrap(MyApp, {provide: ExceptionHandler, useClass: MyExceptionHandler}])
*
* ```
* @stable
*/
export class ExceptionHandler {
constructor(private _logger: any, private _rethrowException: boolean = true) {}
static exceptionToString(exception: any, stackTrace: any = null, reason: string = null): string {
var l = new _ArrayLogger();
var e = new ExceptionHandler(l, false);
e.call(exception, stackTrace, reason);
return l.res.join('\n');
}
call(exception: any, stackTrace: any = null, reason: string = null): void {
var originalException = this._findOriginalException(exception);
var originalStack = this._findOriginalStack(exception);
var context = this._findContext(exception);
this._logger.logGroup(`EXCEPTION: ${this._extractMessage(exception)}`);
if (isPresent(stackTrace) && isBlank(originalStack)) {
this._logger.logError('STACKTRACE:');
this._logger.logError(this._longStackTrace(stackTrace));
}
if (isPresent(reason)) {
this._logger.logError(`REASON: ${reason}`);
}
if (isPresent(originalException)) {
this._logger.logError(`ORIGINAL EXCEPTION: ${this._extractMessage(originalException)}`);
}
if (isPresent(originalStack)) {
this._logger.logError('ORIGINAL STACKTRACE:');
this._logger.logError(this._longStackTrace(originalStack));
}
if (isPresent(context)) {
this._logger.logError('ERROR CONTEXT:');
this._logger.logError(context);
}
this._logger.logGroupEnd();
// We rethrow exceptions, so operations like 'bootstrap' will result in an error
// when an exception happens. If we do not rethrow, bootstrap will always succeed.
if (this._rethrowException) throw exception;
}
/** @internal */
_extractMessage(exception: any): string {
return exception instanceof BaseWrappedException ? exception.wrapperMessage :
exception.toString();
}
/** @internal */
_longStackTrace(stackTrace: any): any {
return isListLikeIterable(stackTrace) ? (<any[]>stackTrace).join('\n\n-----async gap-----\n') :
stackTrace.toString();
}
/** @internal */
_findContext(exception: any): any {
try {
if (!(exception instanceof BaseWrappedException)) return null;
return isPresent(exception.context) ? exception.context :
this._findContext(exception.originalException);
} catch (e) {
// exception.context can throw an exception. if it happens, we ignore the context.
return null;
}
}
/** @internal */
_findOriginalException(exception: any): any {
if (!(exception instanceof BaseWrappedException)) return null;
var e = exception.originalException;
while (e instanceof BaseWrappedException && isPresent(e.originalException)) {
e = e.originalException;
}
return e;
}
/** @internal */
_findOriginalStack(exception: any): any {
if (!(exception instanceof BaseWrappedException)) return null;
var e = exception;
var stack = exception.originalStack;
while (e instanceof BaseWrappedException && isPresent(e.originalException)) {
e = e.originalException;
if (e instanceof BaseWrappedException && isPresent(e.originalException)) {
stack = e.originalStack;
}
}
return stack;
}
}

View File

@ -0,0 +1,50 @@
library angular.core.facade.exceptions;
import 'base_wrapped_exception.dart';
import 'exception_handler.dart';
export 'exception_handler.dart';
class BaseException extends Error {
final String _message;
BaseException([this._message]);
String get message => _message;
String toString() {
return this.message;
}
}
class WrappedException extends BaseWrappedException {
final dynamic _context;
final String _wrapperMessage;
final originalException;
final originalStack;
WrappedException(
[this._wrapperMessage,
this.originalException,
this.originalStack,
this._context]);
String get message {
return ExceptionHandler.exceptionToString(this);
}
String toString() {
return this.message;
}
dynamic get context => _context;
String get wrapperMessage => _wrapperMessage;
}
Error makeTypeError([String message = ""]) {
return new BaseException(message);
}
dynamic unimplemented() {
throw new BaseException('unimplemented');
}

View File

@ -0,0 +1,56 @@
import {BaseWrappedException} from './base_wrapped_exception';
import {ExceptionHandler} from './exception_handler';
export {ExceptionHandler} from './exception_handler';
/**
* @stable
*/
export class BaseException extends Error {
public stack: any;
constructor(public message: string = '--') {
super(message);
this.stack = (<any>new Error(message)).stack;
}
toString(): string { return this.message; }
}
/**
* Wraps an exception and provides additional context or information.
* @stable
*/
export class WrappedException extends BaseWrappedException {
private _wrapperStack: any;
constructor(
private _wrapperMessage: string, private _originalException: any /** TODO #9100 */,
private _originalStack?: any /** TODO #9100 */, private _context?: any /** TODO #9100 */) {
super(_wrapperMessage);
this._wrapperStack = (<any>new Error(_wrapperMessage)).stack;
}
get wrapperMessage(): string { return this._wrapperMessage; }
get wrapperStack(): any { return this._wrapperStack; }
get originalException(): any { return this._originalException; }
get originalStack(): any { return this._originalStack; }
get context(): any { return this._context; }
get message(): string { return ExceptionHandler.exceptionToString(this); }
toString(): string { return this.message; }
}
export function makeTypeError(message?: string): Error {
return new TypeError(message);
}
export function unimplemented(): any {
throw new BaseException('unimplemented');
}

View File

@ -0,0 +1,57 @@
library facade.intl;
import 'package:intl/intl.dart';
String _normalizeLocale(String locale) => locale.replaceAll('-', '_');
enum NumberFormatStyle { Decimal, Percent, Currency }
class NumberFormatter {
static String format(num number, String locale, NumberFormatStyle style,
{int minimumIntegerDigits: 1,
int minimumFractionDigits: 0,
int maximumFractionDigits: 3,
String currency,
bool currencyAsSymbol: false}) {
locale = _normalizeLocale(locale);
NumberFormat formatter;
switch (style) {
case NumberFormatStyle.Decimal:
formatter = new NumberFormat.decimalPattern(locale);
break;
case NumberFormatStyle.Percent:
formatter = new NumberFormat.percentPattern(locale);
break;
case NumberFormatStyle.Currency:
if (currencyAsSymbol) {
// See https://github.com/dart-lang/intl/issues/59.
throw new Exception(
'Displaying currency as symbol is not supported.');
}
formatter = new NumberFormat.currencyPattern(locale, currency);
break;
}
formatter.minimumIntegerDigits = minimumIntegerDigits;
formatter.minimumFractionDigits = minimumFractionDigits;
formatter.maximumFractionDigits = maximumFractionDigits;
return formatter.format(number);
}
}
class DateFormatter {
static RegExp _multiPartRegExp = new RegExp(r'^([yMdE]+)([Hjms]+)$');
static String format(DateTime date, String locale, String pattern) {
locale = _normalizeLocale(locale);
var formatter = new DateFormat(null, locale);
var matches = _multiPartRegExp.firstMatch(pattern);
if (matches != null) {
// Support for patterns which have known date and time components.
formatter.addPattern(matches[1]);
formatter.addPattern(matches[2], ', ');
} else {
formatter.addPattern(pattern);
}
return formatter.format(date);
}
}

View File

@ -0,0 +1,207 @@
export enum NumberFormatStyle {
Decimal,
Percent,
Currency
}
export class NumberFormatter {
static format(
num: number, locale: string, style: NumberFormatStyle,
{minimumIntegerDigits = 1, minimumFractionDigits = 0, maximumFractionDigits = 3, currency,
currencyAsSymbol = false}: {
minimumIntegerDigits?: number,
minimumFractionDigits?: number,
maximumFractionDigits?: number,
currency?: string,
currencyAsSymbol?: boolean
} = {}): string {
var intlOptions: Intl.NumberFormatOptions = {
minimumIntegerDigits: minimumIntegerDigits,
minimumFractionDigits: minimumFractionDigits,
maximumFractionDigits: maximumFractionDigits
};
intlOptions.style = NumberFormatStyle[style].toLowerCase();
if (style == NumberFormatStyle.Currency) {
intlOptions.currency = currency;
intlOptions.currencyDisplay = currencyAsSymbol ? 'symbol' : 'code';
}
return new Intl.NumberFormat(locale, intlOptions).format(num);
}
}
var DATE_FORMATS_SPLIT =
/((?:[^yMLdHhmsaZEwGjJ']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|J+|j+|m+|s+|a|Z|G+|w+))(.*)/;
var PATTERN_ALIASES = {
yMMMdjms: datePartGetterFactory(combine([
digitCondition('year', 1),
nameCondition('month', 3),
digitCondition('day', 1),
digitCondition('hour', 1),
digitCondition('minute', 1),
digitCondition('second', 1),
])),
yMdjm: datePartGetterFactory(combine([
digitCondition('year', 1), digitCondition('month', 1), digitCondition('day', 1),
digitCondition('hour', 1), digitCondition('minute', 1)
])),
yMMMMEEEEd: datePartGetterFactory(combine([
digitCondition('year', 1), nameCondition('month', 4), nameCondition('weekday', 4),
digitCondition('day', 1)
])),
yMMMMd: datePartGetterFactory(
combine([digitCondition('year', 1), nameCondition('month', 4), digitCondition('day', 1)])),
yMMMd: datePartGetterFactory(
combine([digitCondition('year', 1), nameCondition('month', 3), digitCondition('day', 1)])),
yMd: datePartGetterFactory(
combine([digitCondition('year', 1), digitCondition('month', 1), digitCondition('day', 1)])),
jms: datePartGetterFactory(combine(
[digitCondition('hour', 1), digitCondition('second', 1), digitCondition('minute', 1)])),
jm: datePartGetterFactory(combine([digitCondition('hour', 1), digitCondition('minute', 1)]))
};
var DATE_FORMATS = {
yyyy: datePartGetterFactory(digitCondition('year', 4)),
yy: datePartGetterFactory(digitCondition('year', 2)),
y: datePartGetterFactory(digitCondition('year', 1)),
MMMM: datePartGetterFactory(nameCondition('month', 4)),
MMM: datePartGetterFactory(nameCondition('month', 3)),
MM: datePartGetterFactory(digitCondition('month', 2)),
M: datePartGetterFactory(digitCondition('month', 1)),
LLLL: datePartGetterFactory(nameCondition('month', 4)),
dd: datePartGetterFactory(digitCondition('day', 2)),
d: datePartGetterFactory(digitCondition('day', 1)),
HH: hourExtracter(datePartGetterFactory(hour12Modify(digitCondition('hour', 2), false))),
H: hourExtracter(datePartGetterFactory(hour12Modify(digitCondition('hour', 1), false))),
hh: hourExtracter(datePartGetterFactory(hour12Modify(digitCondition('hour', 2), true))),
h: hourExtracter(datePartGetterFactory(hour12Modify(digitCondition('hour', 1), true))),
jj: datePartGetterFactory(digitCondition('hour', 2)),
j: datePartGetterFactory(digitCondition('hour', 1)),
mm: datePartGetterFactory(digitCondition('minute', 2)),
m: datePartGetterFactory(digitCondition('minute', 1)),
ss: datePartGetterFactory(digitCondition('second', 2)),
s: datePartGetterFactory(digitCondition('second', 1)),
// while ISO 8601 requires fractions to be prefixed with `.` or `,`
// we can be just safely rely on using `sss` since we currently don't support single or two digit
// fractions
sss: datePartGetterFactory(digitCondition('second', 3)),
EEEE: datePartGetterFactory(nameCondition('weekday', 4)),
EEE: datePartGetterFactory(nameCondition('weekday', 3)),
EE: datePartGetterFactory(nameCondition('weekday', 2)),
E: datePartGetterFactory(nameCondition('weekday', 1)),
a: hourClockExtracter(datePartGetterFactory(hour12Modify(digitCondition('hour', 1), true))),
Z: datePartGetterFactory({timeZoneName: 'long'}),
z: datePartGetterFactory({timeZoneName: 'short'}),
ww: datePartGetterFactory({}), // Week of year, padded (00-53). Week 01 is the week with the
// first Thursday of the year. not support ?
w: datePartGetterFactory({}), // Week of year (0-53). Week 1 is the week with the first Thursday
// of the year not support ?
G: datePartGetterFactory(nameCondition('era', 1)),
GG: datePartGetterFactory(nameCondition('era', 2)),
GGG: datePartGetterFactory(nameCondition('era', 3)),
GGGG: datePartGetterFactory(nameCondition('era', 4))
};
function hourClockExtracter(inner: (date: Date, locale: string) => string): (
date: Date, locale: string) => string {
return function(date: Date, locale: string): string {
var result = inner(date, locale);
return result.split(' ')[1];
};
}
function hourExtracter(inner: (date: Date, locale: string) => string): (
date: Date, locale: string) => string {
return function(date: Date, locale: string): string {
var result = inner(date, locale);
return result.split(' ')[0];
};
}
function hour12Modify(
options: Intl.DateTimeFormatOptions, value: boolean): Intl.DateTimeFormatOptions {
options.hour12 = value;
return options;
}
function digitCondition(prop: string, len: number): Intl.DateTimeFormatOptions {
var result = {};
(result as any /** TODO #9100 */)[prop] = len == 2 ? '2-digit' : 'numeric';
return result;
}
function nameCondition(prop: string, len: number): Intl.DateTimeFormatOptions {
var result = {};
(result as any /** TODO #9100 */)[prop] = len < 4 ? 'short' : 'long';
return result;
}
function combine(options: Intl.DateTimeFormatOptions[]): Intl.DateTimeFormatOptions {
var result = {};
options.forEach(option => { (<any>Object).assign(result, option); });
return result;
}
function datePartGetterFactory(ret: Intl.DateTimeFormatOptions): (date: Date, locale: string) =>
string {
return function(date: Date, locale: string): string {
return new Intl.DateTimeFormat(locale, ret).format(date);
};
}
var datePartsFormatterCache: Map<string, string[]> = new Map<string, string[]>();
function dateFormatter(format: string, date: Date, locale: string): string {
var text = '';
var match: any /** TODO #9100 */;
var fn: any /** TODO #9100 */;
var parts: string[] = [];
if ((PATTERN_ALIASES as any /** TODO #9100 */)[format]) {
return (PATTERN_ALIASES as any /** TODO #9100 */)[format](date, locale);
}
if (datePartsFormatterCache.has(format)) {
parts = datePartsFormatterCache.get(format);
} else {
var matchs = DATE_FORMATS_SPLIT.exec(format);
while (format) {
match = DATE_FORMATS_SPLIT.exec(format);
if (match) {
parts = concat(parts, match, 1);
format = parts.pop();
} else {
parts.push(format);
format = null;
}
}
datePartsFormatterCache.set(format, parts);
}
parts.forEach(part => {
fn = (DATE_FORMATS as any /** TODO #9100 */)[part];
text += fn ? fn(date, locale) :
part === '\'\'' ? '\'' : part.replace(/(^'|'$)/g, '').replace(/''/g, '\'');
});
return text;
}
var slice = [].slice;
function concat(
array1: any /** TODO #9100 */, array2: any /** TODO #9100 */,
index: any /** TODO #9100 */): string[] {
return array1.concat(slice.call(array2, index));
}
export class DateFormatter {
static format(date: Date, locale: string, pattern: string): string {
return dateFormatter(pattern, date, locale);
}
}

View File

@ -0,0 +1,402 @@
library angular.core.facade.lang;
export 'dart:core' show Type, RegExp, print, DateTime, Uri;
import 'dart:math' as math;
import 'dart:convert' as convert;
import 'dart:async' show Future, Zone;
String getTypeNameForDebugging(Object type) => type.toString();
class Math {
static final _random = new math.Random();
static int floor(num n) => n.floor();
static double random() => _random.nextDouble();
static num min(num a, num b) => math.min(a, b);
}
const IS_DART = true;
scheduleMicroTask(Function fn) {
Zone.current.scheduleMicrotask(fn);
}
bool isPresent(Object obj) => obj != null;
bool isBlank(Object obj) => obj == null;
bool isString(Object obj) => obj is String;
bool isFunction(Object obj) => obj is Function;
bool isType(Object obj) => obj is Type;
bool isStringMap(Object obj) => obj is Map;
bool isStrictStringMap(Object obj) => obj is Map;
bool isArray(Object obj) => obj is List;
bool isPromise(Object obj) => obj is Future;
bool isNumber(Object obj) => obj is num;
bool isBoolean(Object obj) => obj is bool;
bool isDate(Object obj) => obj is DateTime;
String stringify(obj) {
final exp = new RegExp(r"from Function '(\w+)'");
final str = obj.toString();
if (exp.firstMatch(str) != null) {
return exp.firstMatch(str).group(1);
} else {
return str;
}
}
int serializeEnum(val) {
return val.index;
}
/**
* Deserializes an enum
* val should be the indexed value of the enum (sa returned from @Link{serializeEnum})
* values should be a map from indexes to values for the enum that you want to deserialize.
*/
dynamic deserializeEnum(num val, Map<num, dynamic> values) {
return values[val];
}
String resolveEnumToken(enumValue, val) {
// turn Enum.Token -> Token
return val.toString().replaceFirst(new RegExp('^.+\\.'),'');
}
class StringWrapper {
static String fromCharCode(int code) {
return new String.fromCharCode(code);
}
static int charCodeAt(String s, int index) {
return s.codeUnitAt(index);
}
static List<String> split(String s, RegExp regExp) {
var parts = <String>[];
var lastEnd = 0;
regExp.allMatches(s).forEach((match) {
parts.add(s.substring(lastEnd, match.start));
lastEnd = match.end;
for (var i = 0; i < match.groupCount; i++) {
parts.add(match.group(i + 1));
}
});
parts.add(s.substring(lastEnd));
return parts;
}
static bool equals(String s, String s2) {
return s == s2;
}
static String stripLeft(String s, String charVal) {
if (isPresent(s) && s.length > 0) {
var pos = 0;
for (var i = 0; i < s.length; i++) {
if (s[i] != charVal) break;
pos++;
}
s = s.substring(pos);
}
return s;
}
static String stripRight(String s, String charVal) {
if (isPresent(s) && s.length > 0) {
var pos = s.length;
for (var i = s.length - 1; i >= 0; i--) {
if (s[i] != charVal) break;
pos--;
}
s = s.substring(0, pos);
}
return s;
}
static String replace(String s, Pattern from, String replace) {
return s.replaceFirst(from, replace);
}
static String replaceAll(String s, RegExp from, String replace) {
return s.replaceAll(from, replace);
}
static String slice(String s, [int start = 0, int end]) {
start = _startOffset(s, start);
end = _endOffset(s, end);
//in JS if start > end an empty string is returned
if (end != null && start > end) {
return "";
}
return s.substring(start, end);
}
static String replaceAllMapped(String s, RegExp from, Function cb) {
return s.replaceAllMapped(from, cb);
}
static bool contains(String s, String substr) {
return s.contains(substr);
}
static int compare(String a, String b) => a.compareTo(b);
// JS slice function can take start < 0 which indicates a position relative to
// the end of the string
static int _startOffset(String s, int start) {
int len = s.length;
return start < 0 ? math.max(len + start, 0) : math.min(start, len);
}
// JS slice function can take end < 0 which indicates a position relative to
// the end of the string
static int _endOffset(String s, int end) {
int len = s.length;
if (end == null) return len;
return end < 0 ? math.max(len + end, 0) : math.min(end, len);
}
}
class StringJoiner {
final List<String> _parts = <String>[];
void add(String part) {
_parts.add(part);
}
String toString() => _parts.join("");
}
class NumberWrapper {
static String toFixed(num n, int fractionDigits) {
return n.toStringAsFixed(fractionDigits);
}
static bool equal(num a, num b) {
return a == b;
}
static int parseIntAutoRadix(String text) {
return int.parse(text);
}
static int parseInt(String text, int radix) {
return int.parse(text, radix: radix);
}
static double parseFloat(String text) {
return double.parse(text);
}
static double get NaN => double.NAN;
static bool isNaN(num value) => value.isNaN;
static bool isInteger(value) => value is int;
}
class RegExpWrapper {
static RegExp create(regExpStr, [String flags = '']) {
bool multiLine = flags.contains('m');
bool caseSensitive = !flags.contains('i');
return new RegExp(regExpStr,
multiLine: multiLine, caseSensitive: caseSensitive);
}
static Match firstMatch(RegExp regExp, String input) {
return regExp.firstMatch(input);
}
static bool test(RegExp regExp, String input) {
return regExp.hasMatch(input);
}
static Iterator<Match> matcher(RegExp regExp, String input) {
return regExp.allMatches(input).iterator;
}
static String replaceAll(RegExp regExp, String input, Function replace) {
final m = RegExpWrapper.matcher(regExp, input);
var res = "";
var prev = 0;
while(m.moveNext()) {
var c = m.current;
res += input.substring(prev, c.start);
res += replace(c);
prev = c.start + c[0].length;
}
res += input.substring(prev);
return res;
}
}
class RegExpMatcherWrapper {
static _JSLikeMatch next(Iterator<Match> matcher) {
if (matcher.moveNext()) {
return new _JSLikeMatch(matcher.current);
}
return null;
}
}
class _JSLikeMatch {
Match _m;
_JSLikeMatch(this._m);
String operator [](index) => _m[index];
int get index => _m.start;
int get length => _m.groupCount + 1;
}
class FunctionWrapper {
static apply(Function fn, posArgs) {
return Function.apply(fn, posArgs);
}
static Function bind(Function fn, dynamic scope) {
return fn;
}
}
const _NAN_KEY = const Object();
// Dart VM implements `identical` as true reference identity. JavaScript does
// not have this. The closest we have in JS is `===`. However, for strings JS
// would actually compare the contents rather than references. `dart2js`
// compiles `identical` to `===` and therefore there is a discrepancy between
// Dart VM and `dart2js`. The implementation of `looseIdentical` attempts to
// bridge the gap between the two while retaining good performance
// characteristics. In JS we use simple `identical`, which compiles to `===`,
// and in Dart VM we emulate the semantics of `===` by special-casing strings.
// Note that the VM check is a compile-time constant. This allows `dart2js` to
// evaluate the conditional during compilation and inline the entire function.
//
// See: dartbug.com/22496, dartbug.com/25270
const _IS_DART_VM = !identical(1.0, 1); // a hack
bool looseIdentical(a, b) => _IS_DART_VM
? _looseIdentical(a, b)
: identical(a, b);
// This function is intentionally separated from `looseIdentical` to keep the
// number of AST nodes low enough for `dart2js` to inline the code.
bool _looseIdentical(a, b) =>
a is String && b is String ? a == b : identical(a, b);
// Dart compare map keys by equality and we can have NaN != NaN
dynamic getMapKey(value) {
if (value is! num) return value;
return value.isNaN ? _NAN_KEY : value;
}
// TODO: remove with https://github.com/angular/angular/issues/3055
dynamic normalizeBlank(obj) => obj;
bool normalizeBool(bool obj) {
return isBlank(obj) ? false : obj;
}
bool isJsObject(o) {
return false;
}
warn(o) {
print(o);
}
// Functions below are noop in Dart. Imperatively controlling dev mode kills
// tree shaking. We should only rely on `assertionsEnabled`.
@Deprecated('Do not use this function. It is for JS only. There is no alternative.')
void lockMode() {}
@Deprecated('Do not use this function. It is for JS only. There is no alternative.')
void enableDevMode() {}
@Deprecated('Do not use this function. It is for JS only. There is no alternative.')
void enableProdMode() {}
/// Use this function to guard debugging code. When Dart is compiled in
/// production mode, the code guarded using this function will be tree
/// shaken away, reducing code size.
///
/// WARNING: DO NOT CHANGE THIS METHOD! This method is designed to have no
/// more AST nodes than the maximum allowed by dart2js to inline it. In
/// addition, the use of `assert` allows the compiler to statically compute
/// the value returned by this function and tree shake conditions guarded by
/// it.
///
/// Example:
///
/// if (assertionsEnabled()) {
/// ...code here is tree shaken away in prod mode...
/// }
bool assertionsEnabled() {
var k = false;
assert((k = true));
return k;
}
// Can't be all uppercase as our transpiler would think it is a special directive...
class Json {
static parse(String s) => convert.JSON.decode(s);
static String stringify(data) {
var encoder = new convert.JsonEncoder.withIndent(" ");
return encoder.convert(data);
}
}
class DateWrapper {
static DateTime create(int year,
[int month = 1,
int day = 1,
int hour = 0,
int minutes = 0,
int seconds = 0,
int milliseconds = 0]) {
return new DateTime(year, month, day, hour, minutes, seconds, milliseconds);
}
static DateTime fromISOString(String str) {
return DateTime.parse(str);
}
static DateTime fromMillis(int ms) {
return new DateTime.fromMillisecondsSinceEpoch(ms, isUtc: true);
}
static int toMillis(DateTime date) {
return date.millisecondsSinceEpoch;
}
static DateTime now() {
return new DateTime.now();
}
static String toJson(DateTime date) {
return date.toUtc().toIso8601String();
}
}
bool isPrimitive(Object obj) => obj is num || obj is bool || obj == null || obj is String;
// needed to match the exports from lang.js
var global = null;
dynamic evalExpression(String sourceUrl, String expr, String declarations, Map<String, String> vars) {
throw "Dart does not support evaluating expression during runtime!";
}
bool hasConstructor(Object value, Type type) {
return value.runtimeType == type;
}
num bitWiseOr(List values) {
var val = values.reduce((num a, num b) => (a as int) | (b as int));
return val as num;
}
num bitWiseAnd(List values) {
var val = values.reduce((num a, num b) => (a as int) & (b as int));
return val as num;
}
String escape(String s) {
return Uri.encodeComponent(s);
}

View File

@ -0,0 +1,502 @@
export interface BrowserNodeGlobal {
Object: typeof Object;
Array: typeof Array;
Map: typeof Map;
Set: typeof Set;
Date: DateConstructor;
RegExp: RegExpConstructor;
JSON: typeof JSON;
Math: any; // typeof Math;
assert(condition: any): void;
Reflect: any;
getAngularTestability: Function;
getAllAngularTestabilities: Function;
getAllAngularRootElements: Function;
frameworkStabilizers: Array<Function>;
setTimeout: Function;
clearTimeout: Function;
setInterval: Function;
clearInterval: Function;
encodeURI: Function;
}
// TODO(jteplitz602): Load WorkerGlobalScope from lib.webworker.d.ts file #3492
declare var WorkerGlobalScope: any /** TODO #9100 */;
// CommonJS / Node have global context exposed as "global" variable.
// We don't want to include the whole node.d.ts this this compilation unit so we'll just fake
// the global "global" var for now.
declare var global: any /** TODO #9100 */;
var globalScope: BrowserNodeGlobal;
if (typeof window === 'undefined') {
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
// TODO: Replace any with WorkerGlobalScope from lib.webworker.d.ts #3492
globalScope = <any>self;
} else {
globalScope = <any>global;
}
} else {
globalScope = <any>window;
}
export function scheduleMicroTask(fn: Function) {
Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
}
export const IS_DART = false;
// Need to declare a new variable for global here since TypeScript
// exports the original value of the symbol.
var _global: BrowserNodeGlobal = globalScope;
export {_global as global};
export var Type = Function;
/**
* Runtime representation a type that a Component or other object is instances of.
*
* An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by
* the `MyCustomComponent` constructor function.
*/
export interface Type extends Function {}
/**
* Runtime representation of a type that is constructable (non-abstract).
*/
export interface ConcreteType extends Type { new (...args: any[] /** TODO #9100 */): any; }
export function getTypeNameForDebugging(type: Type): string {
if (type['name']) {
return type['name'];
}
return typeof type;
}
export var Math = _global.Math;
export var Date = _global.Date;
var _devMode: boolean = true;
var _modeLocked: boolean = false;
export function lockMode() {
_modeLocked = true;
}
/**
* Disable Angular's development mode, which turns off assertions and other
* checks within the framework.
*
* One important assertion this disables verifies that a change detection pass
* does not result in additional changes to any bindings (also known as
* unidirectional data flow).
* @stable
*/
export function enableProdMode() {
if (_modeLocked) {
// Cannot use BaseException as that ends up importing from facade/lang.
throw 'Cannot enable prod mode after platform setup.';
}
_devMode = false;
}
export function assertionsEnabled(): boolean {
return _devMode;
}
// TODO: remove calls to assert in production environment
// Note: Can't just export this and import in in other files
// as `assert` is a reserved keyword in Dart
_global.assert = function assert(condition) {
// TODO: to be fixed properly via #2830, noop for now
};
export function isPresent(obj: any): boolean {
return obj !== undefined && obj !== null;
}
export function isBlank(obj: any): boolean {
return obj === undefined || obj === null;
}
export function isBoolean(obj: any): boolean {
return typeof obj === 'boolean';
}
export function isNumber(obj: any): boolean {
return typeof obj === 'number';
}
export function isString(obj: any): obj is String {
return typeof obj === 'string';
}
export function isFunction(obj: any): boolean {
return typeof obj === 'function';
}
export function isType(obj: any): boolean {
return isFunction(obj);
}
export function isStringMap(obj: any): boolean {
return typeof obj === 'object' && obj !== null;
}
const STRING_MAP_PROTO = Object.getPrototypeOf({});
export function isStrictStringMap(obj: any): boolean {
return isStringMap(obj) && Object.getPrototypeOf(obj) === STRING_MAP_PROTO;
}
export function isPromise(obj: any): boolean {
return obj instanceof (<any>_global).Promise;
}
export function isArray(obj: any): boolean {
return Array.isArray(obj);
}
export function isDate(obj: any): obj is Date {
return obj instanceof Date && !isNaN(obj.valueOf());
}
export function noop() {}
export function stringify(token: any): string {
if (typeof token === 'string') {
return token;
}
if (token === undefined || token === null) {
return '' + token;
}
if (token.name) {
return token.name;
}
if (token.overriddenName) {
return token.overriddenName;
}
var res = token.toString();
var newLineIndex = res.indexOf('\n');
return (newLineIndex === -1) ? res : res.substring(0, newLineIndex);
}
// serialize / deserialize enum exist only for consistency with dart API
// enums in typescript don't need to be serialized
export function serializeEnum(val: any): number {
return val;
}
export function deserializeEnum(val: any, values: Map<number, any>): any {
return val;
}
export function resolveEnumToken(enumValue: any, val: any): string {
return enumValue[val];
}
export class StringWrapper {
static fromCharCode(code: number): string { return String.fromCharCode(code); }
static charCodeAt(s: string, index: number): number { return s.charCodeAt(index); }
static split(s: string, regExp: RegExp): string[] { return s.split(regExp); }
static equals(s: string, s2: string): boolean { return s === s2; }
static stripLeft(s: string, charVal: string): string {
if (s && s.length) {
var pos = 0;
for (var i = 0; i < s.length; i++) {
if (s[i] != charVal) break;
pos++;
}
s = s.substring(pos);
}
return s;
}
static stripRight(s: string, charVal: string): string {
if (s && s.length) {
var pos = s.length;
for (var i = s.length - 1; i >= 0; i--) {
if (s[i] != charVal) break;
pos--;
}
s = s.substring(0, pos);
}
return s;
}
static replace(s: string, from: string, replace: string): string {
return s.replace(from, replace);
}
static replaceAll(s: string, from: RegExp, replace: string): string {
return s.replace(from, replace);
}
static slice<T>(s: string, from: number = 0, to: number = null): string {
return s.slice(from, to === null ? undefined : to);
}
static replaceAllMapped(s: string, from: RegExp, cb: Function): string {
return s.replace(from, function(...matches: any[]) {
// Remove offset & string from the result array
matches.splice(-2, 2);
// The callback receives match, p1, ..., pn
return cb(matches);
});
}
static contains(s: string, substr: string): boolean { return s.indexOf(substr) != -1; }
static compare(a: string, b: string): number {
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
}
}
export class StringJoiner {
constructor(public parts: string[] = []) {}
add(part: string): void { this.parts.push(part); }
toString(): string { return this.parts.join(''); }
}
export class NumberParseError extends Error {
name: string;
constructor(public message: string) { super(); }
toString(): string { return this.message; }
}
export class NumberWrapper {
static toFixed(n: number, fractionDigits: number): string { return n.toFixed(fractionDigits); }
static equal(a: number, b: number): boolean { return a === b; }
static parseIntAutoRadix(text: string): number {
var result: number = parseInt(text);
if (isNaN(result)) {
throw new NumberParseError('Invalid integer literal when parsing ' + text);
}
return result;
}
static parseInt(text: string, radix: number): number {
if (radix == 10) {
if (/^(\-|\+)?[0-9]+$/.test(text)) {
return parseInt(text, radix);
}
} else if (radix == 16) {
if (/^(\-|\+)?[0-9ABCDEFabcdef]+$/.test(text)) {
return parseInt(text, radix);
}
} else {
var result: number = parseInt(text, radix);
if (!isNaN(result)) {
return result;
}
}
throw new NumberParseError(
'Invalid integer literal when parsing ' + text + ' in base ' + radix);
}
// TODO: NaN is a valid literal but is returned by parseFloat to indicate an error.
static parseFloat(text: string): number { return parseFloat(text); }
static get NaN(): number { return NaN; }
static isNaN(value: any): boolean { return isNaN(value); }
static isInteger(value: any): boolean { return Number.isInteger(value); }
}
export var RegExp = _global.RegExp;
export class RegExpWrapper {
static create(regExpStr: string, flags: string = ''): RegExp {
flags = flags.replace(/g/g, '');
return new _global.RegExp(regExpStr, flags + 'g');
}
static firstMatch(regExp: RegExp, input: string): RegExpExecArray {
// Reset multimatch regex state
regExp.lastIndex = 0;
return regExp.exec(input);
}
static test(regExp: RegExp, input: string): boolean {
regExp.lastIndex = 0;
return regExp.test(input);
}
static matcher(regExp: RegExp, input: string): {re: RegExp; input: string} {
// Reset regex state for the case
// someone did not loop over all matches
// last time.
regExp.lastIndex = 0;
return {re: regExp, input: input};
}
static replaceAll(regExp: RegExp, input: string, replace: Function): string {
let c = regExp.exec(input);
let res = '';
regExp.lastIndex = 0;
let prev = 0;
while (c) {
res += input.substring(prev, c.index);
res += replace(c);
prev = c.index + c[0].length;
regExp.lastIndex = prev;
c = regExp.exec(input);
}
res += input.substring(prev);
return res;
}
}
export class RegExpMatcherWrapper {
static next(matcher: {re: RegExp; input: string}): RegExpExecArray {
return matcher.re.exec(matcher.input);
}
}
export class FunctionWrapper {
static apply(fn: Function, posArgs: any): any { return fn.apply(null, posArgs); }
static bind(fn: Function, scope: any): Function { return fn.bind(scope); }
}
// JS has NaN !== NaN
export function looseIdentical(a: any, b: any): boolean {
return a === b || typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b);
}
// JS considers NaN is the same as NaN for map Key (while NaN !== NaN otherwise)
// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
export function getMapKey<T>(value: T): T {
return value;
}
export function normalizeBlank(obj: Object): any {
return isBlank(obj) ? null : obj;
}
export function normalizeBool(obj: boolean): boolean {
return isBlank(obj) ? false : obj;
}
export function isJsObject(o: any): boolean {
return o !== null && (typeof o === 'function' || typeof o === 'object');
}
export function print(obj: Error | Object) {
console.log(obj);
}
export function warn(obj: Error | Object) {
console.warn(obj);
}
// Can't be all uppercase as our transpiler would think it is a special directive...
export class Json {
static parse(s: string): Object { return _global.JSON.parse(s); }
static stringify(data: Object): string {
// Dart doesn't take 3 arguments
return _global.JSON.stringify(data, null, 2);
}
}
export class DateWrapper {
static create(
year: number, month: number = 1, day: number = 1, hour: number = 0, minutes: number = 0,
seconds: number = 0, milliseconds: number = 0): Date {
return new Date(year, month - 1, day, hour, minutes, seconds, milliseconds);
}
static fromISOString(str: string): Date { return new Date(str); }
static fromMillis(ms: number): Date { return new Date(ms); }
static toMillis(date: Date): number { return date.getTime(); }
static now(): Date { return new Date(); }
static toJson(date: Date): string { return date.toJSON(); }
}
export function setValueOnPath(global: any, path: string, value: any) {
var parts = path.split('.');
var obj: any = global;
while (parts.length > 1) {
var name = parts.shift();
if (obj.hasOwnProperty(name) && isPresent(obj[name])) {
obj = obj[name];
} else {
obj = obj[name] = {};
}
}
if (obj === undefined || obj === null) {
obj = {};
}
obj[parts.shift()] = value;
}
// When Symbol.iterator doesn't exist, retrieves the key used in es6-shim
declare var Symbol: any;
var _symbolIterator: any = null;
export function getSymbolIterator(): string|symbol {
if (isBlank(_symbolIterator)) {
if (isPresent((<any>globalScope).Symbol) && isPresent(Symbol.iterator)) {
_symbolIterator = Symbol.iterator;
} else {
// es6-shim specific logic
var keys = Object.getOwnPropertyNames(Map.prototype);
for (var i = 0; i < keys.length; ++i) {
var key = keys[i];
if (key !== 'entries' && key !== 'size' &&
(Map as any).prototype[key] === Map.prototype['entries']) {
_symbolIterator = key;
}
}
}
}
return _symbolIterator;
}
export function evalExpression(
sourceUrl: string, expr: string, declarations: string, vars: {[key: string]: any}): any {
var fnBody = `${declarations}\nreturn ${expr}\n//# sourceURL=${sourceUrl}`;
var fnArgNames: string[] = [];
var fnArgValues: any[] = [];
for (var argName in vars) {
fnArgNames.push(argName);
fnArgValues.push(vars[argName]);
}
return new Function(...fnArgNames.concat(fnBody))(...fnArgValues);
}
export function isPrimitive(obj: any): boolean {
return !isJsObject(obj);
}
export function hasConstructor(value: Object, type: Type): boolean {
return value.constructor === type;
}
export function bitWiseOr(values: number[]): number {
return values.reduce((a, b) => { return a | b; });
}
export function bitWiseAnd(values: number[]): number {
return values.reduce((a, b) => { return a & b; });
}
export function escape(s: string): string {
return _global.encodeURI(s);
}

View File

@ -0,0 +1,24 @@
library angular.core.facade.math;
import 'dart:core' show double, num;
import 'dart:math' as math;
const NaN = double.NAN;
class Math {
static num pow(num x, num exponent) {
return math.pow(x, exponent);
}
static num max(num a, num b) => math.max(a, b);
static num min(num a, num b) => math.min(a, b);
static num floor(num a) => a.floor();
static num ceil(num a) => a.ceil();
static num sqrt(num x) => math.sqrt(x);
static num round(num x) => x.round();
}

View File

@ -0,0 +1,4 @@
import {global} from './lang';
export var Math = global.Math;
export var NaN: any /** TODO #???? */ = typeof NaN;

View File

@ -0,0 +1,58 @@
library angular2.core.facade.promise;
import 'dart:async';
import 'dart:async' as async;
class PromiseWrapper {
static Future/*<T>*/ resolve/*<T>*/(dynamic /*=T*/ obj) => new Future.value(obj);
static Future/*<T>*/ reject/*<T>*/(dynamic /*=T*/ obj, Object stackTrace) => new Future.error(obj,
stackTrace != null ? stackTrace : obj is Error ? (obj as Error).stackTrace : null);
static Future<List/*<T>*/> all/*<T>*/(List<dynamic> promises) {
return Future
.wait(promises.map((p) => p is Future ? p as Future/*<T>*/ : new Future/*<T>*/.value(p)));
}
static Future/*<R>*/ then/*<T, R>*/(Future/*<T>*/ promise, dynamic /*=R*/ success(dynamic /*=T*/ value), [Function onError]) {
if (success == null) return promise.catchError(onError);
return promise.then(success, onError: onError);
}
static Future/*<T>*/ wrap/*<T>*/(dynamic /*=T*/ fn()) {
return new Future(fn);
}
// Note: We can't rename this method to `catch`, as this is not a valid
// method name in Dart.
static Future catchError(Future promise, Function onError) {
return promise.catchError(onError);
}
static void scheduleMicrotask(fn) {
async.scheduleMicrotask(fn);
}
static bool isPromise(obj) {
return obj is Future;
}
static PromiseCompleter/*<T>*/ completer/*<T>*/() =>
new PromiseCompleter();
}
class PromiseCompleter<T> {
final Completer<T> c = new Completer();
Future<T> get promise => c.future;
void resolve(v) {
c.complete(v);
}
void reject(error, stack) {
if (stack == null && error is Error) {
stack = error.stackTrace;
}
c.completeError(error, stack);
}
}

View File

@ -0,0 +1,49 @@
"use strict";
var PromiseCompleter = (function () {
function PromiseCompleter() {
var _this = this;
this.promise = new Promise(function (res, rej) {
_this.resolve = res;
_this.reject = rej;
});
}
return PromiseCompleter;
}());
exports.PromiseCompleter = PromiseCompleter;
var PromiseWrapper = (function () {
function PromiseWrapper() {
}
PromiseWrapper.resolve = function (obj) { return Promise.resolve(obj); };
PromiseWrapper.reject = function (obj, _) { return Promise.reject(obj); };
// Note: We can't rename this method into `catch`, as this is not a valid
// method name in Dart.
PromiseWrapper.catchError = function (promise, onError) {
return promise.catch(onError);
};
PromiseWrapper.all = function (promises) {
if (promises.length == 0)
return Promise.resolve([]);
return Promise.all(promises);
};
PromiseWrapper.then = function (promise, success, rejection) {
return promise.then(success, rejection);
};
PromiseWrapper.wrap = function (computation) {
return new Promise(function (res, rej) {
try {
res(computation());
}
catch (e) {
rej(e);
}
});
};
PromiseWrapper.scheduleMicrotask = function (computation) {
PromiseWrapper.then(PromiseWrapper.resolve(null), computation, function (_) { });
};
PromiseWrapper.isPromise = function (obj) { return obj instanceof Promise; };
PromiseWrapper.completer = function () { return new PromiseCompleter(); };
return PromiseWrapper;
}());
exports.PromiseWrapper = PromiseWrapper;
//# sourceMappingURL=promise.js.map

View File

@ -0,0 +1,55 @@
export class PromiseCompleter<R> {
promise: Promise<R>;
resolve: (value?: R|PromiseLike<R>) => void;
reject: (error?: any, stackTrace?: string) => void;
constructor() {
this.promise = new Promise((res, rej) => {
this.resolve = res;
this.reject = rej;
});
}
}
export class PromiseWrapper {
static resolve<T>(obj: T): Promise<T> { return Promise.resolve(obj); }
static reject(obj: any, _: any): Promise<any> { return Promise.reject(obj); }
// Note: We can't rename this method into `catch`, as this is not a valid
// method name in Dart.
static catchError<T>(promise: Promise<T>, onError: (error: any) => T | PromiseLike<T>):
Promise<T> {
return promise.catch(onError);
}
static all<T>(promises: (T|Promise<T>)[]): Promise<T[]> {
if (promises.length == 0) return Promise.resolve([]);
return Promise.all(promises);
}
static then<T, U>(
promise: Promise<T>, success: (value: T) => U | PromiseLike<U>,
rejection?: (error: any, stack?: any) => U | PromiseLike<U>): Promise<U> {
return promise.then(success, rejection);
}
static wrap<T>(computation: () => T): Promise<T> {
return new Promise((res, rej) => {
try {
res(computation());
} catch (e) {
rej(e);
}
});
}
static scheduleMicrotask(computation: () => any): void {
PromiseWrapper.then(PromiseWrapper.resolve(null), computation, (_) => {});
}
static isPromise(obj: any): boolean { return obj instanceof Promise; }
static completer<T>(): PromiseCompleter<T> { return new PromiseCompleter<T>(); }
}

View File

@ -1,9 +1,8 @@
import {Injectable} from '@angular/core';
import {StringMapWrapper} from '../facade/collection';
import {isArray, isPresent} from '../facade/lang';
import {AsyncValidatorFn, ValidatorFn} from './directives/validators';
import {StringMapWrapper} from './facade/collection';
import {isArray, isPresent} from './facade/lang';
import * as modelModule from './model';

View File

@ -0,0 +1,54 @@
import {COMMON_DIRECTIVES, FORM_DIRECTIVES as OLD_FORM_DIRECTIVES, FORM_PROVIDERS as OLD_FORM_PROVIDERS} from '@angular/common';
import {CompilerConfig} from '@angular/compiler';
import {PLATFORM_DIRECTIVES, PLATFORM_PIPES, Type} from '@angular/core';
import {FORM_DIRECTIVES as NEW_FORM_DIRECTIVES} from './directives';
import {RadioControlRegistry as NewRadioControlRegistry} from './directives/radio_control_value_accessor';
import {ListWrapper} from './facade/collection';
import {FormBuilder as NewFormBuilder} from './form_builder';
/*
* Shorthand set of providers used for building Angular forms.
*
* ### Example
*
* ```typescript
* bootstrap(MyApp, [FORM_PROVIDERS]);
* ```
*
* @experimental
*/
export const FORM_PROVIDERS: Type[] = /*@ts2dart_const*/[NewFormBuilder, NewRadioControlRegistry];
function flatten(platformDirectives: any[]): any[] {
let flattenedDirectives: any[] = [];
platformDirectives.forEach((directives) => {
if (Array.isArray(directives)) {
flattenedDirectives = flattenedDirectives.concat(directives);
} else {
flattenedDirectives.push(directives);
}
});
return flattenedDirectives;
}
export function disableDeprecatedForms(): any[] {
return [{
provide: CompilerConfig,
useFactory: (platformDirectives: any[], platformPipes: any[]) => {
const flattenedDirectives = flatten(platformDirectives);
ListWrapper.remove(flattenedDirectives, OLD_FORM_DIRECTIVES);
return new CompilerConfig({platformDirectives: flattenedDirectives, platformPipes});
},
deps: [PLATFORM_DIRECTIVES, PLATFORM_PIPES]
}];
}
export function provideForms(): any[] {
return [
{provide: PLATFORM_DIRECTIVES, useValue: NEW_FORM_DIRECTIVES, multi: true}, FORM_PROVIDERS
];
}

View File

@ -0,0 +1,37 @@
/**
* @module
* @description
* This module is used for handling user input, by defining and building a {@link FormGroup} that
* consists of
* {@link FormControl} objects, and mapping them onto the DOM. {@link FormControl} objects can then
* be used
* to read information
* from the form DOM elements.
*
* Forms providers are not included in default providers; you must import these providers
* explicitly.
*/
export {FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES, RadioButtonState} from './directives';
export {AbstractControlDirective} from './directives/abstract_control_directive';
export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
export {ControlContainer} from './directives/control_container';
export {ControlValueAccessor, NG_VALUE_ACCESSOR} from './directives/control_value_accessor';
export {DefaultValueAccessor} from './directives/default_value_accessor';
export {Form} from './directives/form_interface';
export {NgControl} from './directives/ng_control';
export {NgControlStatus} from './directives/ng_control_status';
export {NgForm} from './directives/ng_form';
export {NgModel} from './directives/ng_model';
export {NgModelGroup} from './directives/ng_model_group';
export {FormControlDirective} from './directives/reactive_directives/form_control_directive';
export {FormControlName} from './directives/reactive_directives/form_control_name';
export {FormGroupDirective} from './directives/reactive_directives/form_group_directive';
export {FormGroupName} from './directives/reactive_directives/form_group_name';
export {NgSelectOption, SelectControlValueAccessor} from './directives/select_control_value_accessor';
export {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator, Validator} from './directives/validators';
export {FormBuilder} from './form_builder';
export {AbstractControl, FormArray, FormControl, FormGroup} from './model';
export {NG_ASYNC_VALIDATORS, NG_VALIDATORS, Validators} from './validators';
export * from './form_providers';

View File

@ -1,10 +1,9 @@
import {EventEmitter, Observable, ObservableWrapper} from '../facade/async';
import {ListWrapper, StringMapWrapper} from '../facade/collection';
import {isBlank, isPresent, normalizeBool} from '../facade/lang';
import {PromiseWrapper} from '../facade/promise';
import {composeAsyncValidators, composeValidators} from './directives/shared';
import {AsyncValidatorFn, ValidatorFn} from './directives/validators';
import {EventEmitter, Observable, ObservableWrapper} from './facade/async';
import {ListWrapper, StringMapWrapper} from './facade/collection';
import {isBlank, isPresent, normalizeBool} from './facade/lang';
import {PromiseWrapper} from './facade/promise';

View File

@ -1,14 +1,14 @@
import {OpaqueToken} from '@angular/core';
import {ObservableWrapper} from '../facade/async';
import {StringMapWrapper} from '../facade/collection';
import {isBlank, isPresent, isString} from '../facade/lang';
import {PromiseWrapper} from '../facade/promise';
import {AsyncValidatorFn, ValidatorFn} from './directives/validators';
import {ObservableWrapper} from './facade/async';
import {StringMapWrapper} from './facade/collection';
import {isBlank, isPresent, isString} from './facade/lang';
import {PromiseWrapper} from './facade/promise';
import * as modelModule from './model';
/**
* Providers for validators to be used for {@link FormControl}s in a form.
*

View File

@ -2,13 +2,13 @@ import {afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xit
import {fakeAsync, flushMicrotasks, Log, tick,} from '@angular/core/testing';
import {SpyNgControl, SpyValueAccessor} from '../spies';
import {SpyNgControl, SpyValueAccessor} from './spies';
import {FormGroup, FormControl, FormControlName, FormGroupName, NgModelGroup, FormGroupDirective, ControlValueAccessor, Validators, NgForm, NgModel, FormControlDirective, NgControl, DefaultValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, Validator} from '@angular/common/src/forms';
import {FormGroup, FormControl, FormControlName, FormGroupName, NgModelGroup, FormGroupDirective, ControlValueAccessor, Validators, NgForm, NgModel, FormControlDirective, NgControl, DefaultValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, Validator} from '@angular/forms';
import {selectValueAccessor, composeValidators} from '@angular/common/src/forms/directives/shared';
import {TimerWrapper} from '../../src/facade/async';
import {PromiseWrapper} from '../../src/facade/promise';
import {selectValueAccessor, composeValidators} from '@angular/forms/src/directives/shared';
import {TimerWrapper} from '../src/facade/async';
import {PromiseWrapper} from '../src/facade/promise';
import {SimpleChange} from '@angular/core/src/change_detection';
class DummyControlValueAccessor implements ControlValueAccessor {

View File

@ -1,7 +1,7 @@
import {FormBuilder, FormControl} from '@angular/common/src/forms';
import {afterEach, beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing/testing_internal';
import {FormBuilder, FormControl} from '@angular/forms';
import {PromiseWrapper} from '../../src/facade/promise';
import {PromiseWrapper} from '../src/facade/promise';
export function main() {
function syncValidator(_: any /** TODO #9100 */): any /** TODO #9100 */ { return null; }

View File

@ -1,10 +1,10 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, inject,} from '@angular/core/testing/testing_internal';
import {fakeAsync, flushMicrotasks, Log, tick} from '@angular/core/testing';
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
import {FormGroup, FormControl, FormArray, Validators} from '@angular/common/src/forms';
import {IS_DART, isPresent} from '../../src/facade/lang';
import {PromiseWrapper} from '../../src/facade/promise';
import {TimerWrapper, ObservableWrapper, EventEmitter} from '../../src/facade/async';
import {FormGroup, FormControl, FormArray, Validators} from '@angular/forms';
import {IS_DART, isPresent} from '../src/facade/lang';
import {PromiseWrapper} from '../src/facade/promise';
import {TimerWrapper, ObservableWrapper, EventEmitter} from '../src/facade/async';
export function main() {
function asyncValidator(expected: any /** TODO #9100 */, timeouts = /*@ts2dart_const*/ {}) {

View File

@ -0,0 +1,14 @@
library core.spies;
import 'package:angular2/common.dart';
import 'package:angular2/src/core/change_detection/change_detection.dart';
import 'package:angular2/testing_internal.dart';
@proxy
class SpyNgControl extends SpyObject implements NgControl {}
@proxy
class SpyValueAccessor extends SpyObject implements ControlValueAccessor {}
@proxy
class SpyChangeDetectorRef extends SpyObject implements ChangeDetectorRef {}

View File

@ -0,0 +1,13 @@
import {ChangeDetectorRef} from '@angular/core/src/change_detection/change_detector_ref';
import {SpyObject, proxy} from '@angular/core/testing/testing_internal';
export class SpyChangeDetectorRef extends SpyObject {
constructor() {
super(ChangeDetectorRef);
this.spy('markForCheck');
}
}
export class SpyNgControl extends SpyObject {}
export class SpyValueAccessor extends SpyObject { writeValue: any; }

View File

@ -1,9 +1,9 @@
import {AbstractControl, FormControl, Validators} from '@angular/common/src/forms';
import {Log, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
import {afterEach, beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing/testing_internal';
import {AbstractControl, FormControl, Validators} from '@angular/forms';
import {EventEmitter, ObservableWrapper, TimerWrapper} from '../../src/facade/async';
import {PromiseWrapper} from '../../src/facade/promise';
import {EventEmitter, ObservableWrapper, TimerWrapper} from '../src/facade/async';
import {PromiseWrapper} from '../src/facade/promise';
export function main() {
function validator(key: string, error: any) {

View File

@ -0,0 +1,31 @@
{
"angularCompilerOptions": {
"skipTemplateCodegen": true
},
"compilerOptions": {
"baseUrl": ".",
"declaration": true,
"stripInternal": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "es2015",
"moduleResolution": "node",
"outDir": "../../../dist/packages-dist/forms/esm",
"paths": {
"@angular/core": ["../../../dist/packages-dist/core"],
"@angular/core/testing": ["../../../dist/packages-dist/core/testing"],
"@angular/common": ["../../../dist/packages-dist/common"],
"@angular/common/testing": ["../../../dist/packages-dist/common/testing"],
"@angular/compiler": ["../../../dist/packages-dist/compiler"],
"@angular/compiler/testing": ["../../../dist/packages-dist/compiler/testing"]
},
"rootDir": ".",
"sourceMap": true,
"inlineSources": true,
"target": "es2015"
},
"files": [
"index.ts",
"../../../node_modules/zone.js/dist/zone.js.d.ts"
]
}

View File

@ -0,0 +1,32 @@
{
"angularCompilerOptions": {
"skipTemplateCodegen": true
},
"compilerOptions": {
"baseUrl": ".",
"declaration": true,
"stripInternal": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "../../../dist/packages-dist/forms/",
"paths": {
"@angular/core": ["../../../dist/packages-dist/core/"],
"@angular/core/testing": ["../../../dist/packages-dist/core/testing"],
"@angular/common": ["../../../dist/packages-dist/common"],
"@angular/common/testing": ["../../../dist/packages-dist/common/testing"],
"@angular/compiler": ["../../../dist/packages-dist/compiler"],
"@angular/compiler/testing": ["../../../dist/packages-dist/compiler/testing"]
},
"rootDir": ".",
"sourceMap": true,
"inlineSources": true,
"lib": ["es6", "dom"],
"target": "es5"
},
"files": [
"index.ts",
"../../../node_modules/zone.js/dist/zone.js.d.ts"
]
}

View File

@ -1,6 +1,6 @@
import {COMMON_DIRECTIVES, COMMON_PIPES} from '@angular/common';
import {COMPILER_PROVIDERS, CompilerConfig, XHR} from '@angular/compiler';
import {ApplicationRef, ComponentRef, ReflectiveInjector, Type, coreLoadAndBootstrap} from '@angular/core';
import {ApplicationRef, ComponentRef, PLATFORM_DIRECTIVES, PLATFORM_PIPES, ReflectiveInjector, Type, coreLoadAndBootstrap} from '@angular/core';
import {BROWSER_APP_PROVIDERS, WORKER_APP_APPLICATION_PROVIDERS, WORKER_RENDER_APPLICATION_PROVIDERS, WORKER_SCRIPT, browserPlatform, workerAppPlatform, workerRenderPlatform} from '@angular/platform-browser';
import {ReflectionCapabilities, reflector} from './core_private';
@ -11,13 +11,16 @@ import {XHRImpl} from './src/xhr/xhr_impl';
export const BROWSER_APP_COMPILER_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
COMPILER_PROVIDERS,
{
COMPILER_PROVIDERS, {
provide: CompilerConfig,
useValue:
new CompilerConfig({platformDirectives: COMMON_DIRECTIVES, platformPipes: COMMON_PIPES})
useFactory: (platformDirectives: any[], platformPipes: any[]) => {
return new CompilerConfig({platformDirectives, platformPipes});
},
deps: [PLATFORM_DIRECTIVES, PLATFORM_PIPES]
},
{provide: XHR, useClass: XHRImpl},
{provide: PLATFORM_DIRECTIVES, useValue: COMMON_DIRECTIVES, multi: true},
{provide: PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true}
];
@ -125,13 +128,16 @@ export function bootstrapRender(
const WORKER_APP_COMPILER_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
COMPILER_PROVIDERS,
{
COMPILER_PROVIDERS, {
provide: CompilerConfig,
useValue:
new CompilerConfig({platformDirectives: COMMON_DIRECTIVES, platformPipes: COMMON_PIPES})
useFactory: (platformDirectives: any[], platformPipes: any[]) => {
return new CompilerConfig({platformDirectives, platformPipes});
},
deps: [PLATFORM_DIRECTIVES, PLATFORM_PIPES]
},
{provide: XHR, useClass: XHRImpl},
{provide: PLATFORM_DIRECTIVES, useValue: COMMON_DIRECTIVES, multi: true},
{provide: PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true}
];

View File

@ -58,7 +58,6 @@ export const BROWSER_APP_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
Testability, EventManager, ELEMENT_PROBE_PROVIDERS
];
export function browserPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PLATFORM_PROVIDERS));

View File

@ -32,6 +32,10 @@ System.config({
main: 'index.js',
defaultExtension: 'js'
},
'@angular/forms': {
main: 'index.js',
defaultExtension: 'js'
},
// remove after all tests imports are fixed
'@angular/facade': {
main: 'index.js',

View File

@ -42,7 +42,7 @@ var specFiles: any =
'@angular/platform-browser-dynamic/**',
'@angular/core/test/zone/**',
'@angular/core/test/fake_async_spec.*',
'@angular/common/test/forms/**',
'@angular/forms/test/**',
'@angular/common/test/forms-deprecated/**',
'@angular/router/test/route_config/route_config_spec.*',
'@angular/router/test/integration/bootstrap_spec.*',

View File

@ -169,7 +169,9 @@ const CORE = [
'const AUTO_STYLE:any',
'const PACKAGE_ROOT_URL:any',
'const PLATFORM_COMMON_PROVIDERS:Array<any|Type|Provider|any[]>',
'const PLATFORM_DIRECTIVES:OpaqueToken',
'const PLATFORM_INITIALIZER:any',
'const PLATFORM_PIPES:OpaqueToken',
'ContentChildMetadata',
'ContentChildMetadata.constructor(_selector:Type|string, {read=null}:{read?:any}={})',
'ContentChildMetadataFactory',