feat(forms): add easy way to switch between forms modules (#9202)
This commit is contained in:
parent
fe01e2efb7
commit
22916bb5d1
1
build.sh
1
build.sh
|
@ -44,6 +44,7 @@ for PACKAGE in \
|
|||
core \
|
||||
compiler \
|
||||
common \
|
||||
forms \
|
||||
platform-browser \
|
||||
platform-browser-dynamic \
|
||||
platform-server \
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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];
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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');
|
|
@ -0,0 +1 @@
|
|||
export 'index.dart';
|
|
@ -0,0 +1 @@
|
|||
export * from './src/forms';
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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 }),
|
||||
]
|
||||
}
|
|
@ -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';
|
||||
|
||||
|
|
@ -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';
|
||||
|
|
@ -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';
|
|
@ -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';
|
||||
|
|
@ -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';
|
||||
|
|
@ -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';
|
||||
|
|
@ -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';
|
||||
|
|
@ -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';
|
|
@ -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';
|
||||
|
|
@ -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';
|
||||
|
|
@ -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';
|
|
@ -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';
|
||||
|
|
@ -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';
|
||||
|
|
@ -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';
|
||||
|
|
@ -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';
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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 ''; }
|
||||
}
|
|
@ -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 []);
|
||||
}
|
||||
}
|
|
@ -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'];
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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); }
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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');
|
||||
}
|
|
@ -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');
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
import {global} from './lang';
|
||||
|
||||
export var Math = global.Math;
|
||||
export var NaN: any /** TODO #???? */ = typeof NaN;
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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>(); }
|
||||
}
|
|
@ -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';
|
||||
|
||||
|
|
@ -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
|
||||
];
|
||||
}
|
|
@ -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';
|
|
@ -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';
|
||||
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
|
@ -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 {
|
|
@ -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; }
|
File diff suppressed because it is too large
Load Diff
|
@ -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*/ {}) {
|
|
@ -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 {}
|
|
@ -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; }
|
|
@ -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) {
|
|
@ -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"
|
||||
]
|
||||
}
|
|
@ -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"
|
||||
]
|
||||
}
|
|
@ -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}
|
||||
];
|
||||
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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.*',
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue