Compare commits
50 Commits
2.0.0-beta
...
2.0.0-beta
Author | SHA1 | Date | |
---|---|---|---|
185c679563 | |||
b3f4e05b57 | |||
abd1e6e680 | |||
f1f5b45361 | |||
50548fb565 | |||
8f47aa3530 | |||
df7885c9f5 | |||
0f10624b08 | |||
6f1ef33e32 | |||
231773ea76 | |||
e725542703 | |||
2337469753 | |||
55122cd57a | |||
7e0f02f96e | |||
e7ad03cba6 | |||
74be3d3fde | |||
a15ca23469 | |||
de77700da0 | |||
e73fee7156 | |||
72ab35bceb | |||
0f22dce036 | |||
c6036435f0 | |||
d86be245b8 | |||
a26053d3ff | |||
24d5b665e1 | |||
aa98fad338 | |||
9cb6dbbbab | |||
e21718faa9 | |||
b0f7d59e64 | |||
b86829f492 | |||
22929a1671 | |||
86c40f8474 | |||
16b521794c | |||
2a70f4e4c7 | |||
2f31c4c1c5 | |||
1435763383 | |||
05238df89b | |||
772d60d9fe | |||
24086bf0bb | |||
9b0e10e9a7 | |||
995a9e0cf8 | |||
b55f1764b5 | |||
5e9daed2e8 | |||
aa8c5aa2e2 | |||
f2c7946cca | |||
da1fcfd820 | |||
dbeff6f548 | |||
26e60d658a | |||
c2ceb7fba4 | |||
4bfe49cd42 |
103
CHANGELOG.md
103
CHANGELOG.md
@ -1,3 +1,60 @@
|
||||
<a name="2.0.0-beta.5"></a>
|
||||
# 2.0.0-beta.5 (2016-02-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular1-router:** add missing wrapper methods ([55122cd](https://github.com/angular/angular/commit/55122cd)), closes [#6763](https://github.com/angular/angular/issues/6763) [#6861](https://github.com/angular/angular/issues/6861) [#6861](https://github.com/angular/angular/issues/6861)
|
||||
* **angular1-router:** add support for using the component helper ([d86be24](https://github.com/angular/angular/commit/d86be24)), closes [angular/angular.js#13860](https://github.com/angular/angular.js/issues/13860) [#6076](https://github.com/angular/angular/issues/6076) [#5278](https://github.com/angular/angular/issues/5278)
|
||||
* **async:** handle synchronous initial value in async pipe ([26e60d6](https://github.com/angular/angular/commit/26e60d6)), closes [#5996](https://github.com/angular/angular/issues/5996)
|
||||
* **build:** don't try to copy .d.ts files into the npm distro ([16b5217](https://github.com/angular/angular/commit/16b5217)), closes [#6921](https://github.com/angular/angular/issues/6921)
|
||||
* **compiler:** fix interpolation regexp ([9b0e10e](https://github.com/angular/angular/commit/9b0e10e)), closes [#6056](https://github.com/angular/angular/issues/6056)
|
||||
* **compiler:** use event names for matching directives ([231773e](https://github.com/angular/angular/commit/231773e)), closes [#6870](https://github.com/angular/angular/issues/6870)
|
||||
* **core:** add detail to dehydrated detector exception ([e7ad03c](https://github.com/angular/angular/commit/e7ad03c)), closes [#6939](https://github.com/angular/angular/issues/6939)
|
||||
* **core:** mute mode printing in console in prod mode ([74be3d3](https://github.com/angular/angular/commit/74be3d3)), closes [#6873](https://github.com/angular/angular/issues/6873)
|
||||
* **di:** throw if a token uses more than 20 dependencies. ([de77700](https://github.com/angular/angular/commit/de77700)), closes [#6690](https://github.com/angular/angular/issues/6690) [#6869](https://github.com/angular/angular/issues/6869)
|
||||
* **forms:** add RadioButtonValueAccessor to the list of default value accessors ([8f47aa3](https://github.com/angular/angular/commit/8f47aa3))
|
||||
* **forms:** add support for radio buttons ([e725542](https://github.com/angular/angular/commit/e725542)), closes [#6877](https://github.com/angular/angular/issues/6877)
|
||||
* **forms:** use strict runtimeType checks instead of instanceof ([50548fb](https://github.com/angular/angular/commit/50548fb)), closes [#6981](https://github.com/angular/angular/issues/6981)
|
||||
* **Headers:** serializable toJSON ([b55f176](https://github.com/angular/angular/commit/b55f176)), closes [#6073](https://github.com/angular/angular/issues/6073) [#6714](https://github.com/angular/angular/issues/6714)
|
||||
* **ngFor:** update view locals if identity changes ([0f10624](https://github.com/angular/angular/commit/0f10624)), closes [#6923](https://github.com/angular/angular/issues/6923)
|
||||
* **router:** Added route data to normalized async route ([df7885c](https://github.com/angular/angular/commit/df7885c)), closes [#6802](https://github.com/angular/angular/issues/6802)
|
||||
* **router:** don't prepend `/` unnecessarily to Location paths ([c603643](https://github.com/angular/angular/commit/c603643)), closes [#6729](https://github.com/angular/angular/issues/6729) [#5502](https://github.com/angular/angular/issues/5502)
|
||||
* **router:** fix incorrect url param value coercion of 1 to true ([995a9e0](https://github.com/angular/angular/commit/995a9e0)), closes [#5346](https://github.com/angular/angular/issues/5346) [#6286](https://github.com/angular/angular/issues/6286)
|
||||
* **router:** fix url path for star segment in path recognizer ([6f1ef33](https://github.com/angular/angular/commit/6f1ef33)), closes [#6976](https://github.com/angular/angular/issues/6976)
|
||||
* **router:** fixed the location wrapper for angular1 ([e73fee7](https://github.com/angular/angular/commit/e73fee7)), closes [#6943](https://github.com/angular/angular/issues/6943)
|
||||
* **typings:** Don't expose typing dependencies to users. ([2a70f4e](https://github.com/angular/angular/commit/2a70f4e)), closes [#5973](https://github.com/angular/angular/issues/5973) [#5807](https://github.com/angular/angular/issues/5807) [#6266](https://github.com/angular/angular/issues/6266) [#5242](https://github.com/angular/angular/issues/5242) [#6817](https://github.com/angular/angular/issues/6817) [#6267](https://github.com/angular/angular/issues/6267)
|
||||
* **upgrade:** fix infinite $rootScope.$digest() ([7e0f02f](https://github.com/angular/angular/commit/7e0f02f)), closes [#6385](https://github.com/angular/angular/issues/6385) [#6386](https://github.com/angular/angular/issues/6386)
|
||||
* **Validators:** fix Validators.required marking number zero as invalid ([c2ceb7f](https://github.com/angular/angular/commit/c2ceb7f)), closes [#6617](https://github.com/angular/angular/issues/6617)
|
||||
* **WebWorkers:** Fix flaky WebWorker test ([da1fcfd](https://github.com/angular/angular/commit/da1fcfd)), closes [#6851](https://github.com/angular/angular/issues/6851)
|
||||
|
||||
### Features
|
||||
|
||||
* **angular1_router:** allow component to bind to router ([0f22dce](https://github.com/angular/angular/commit/0f22dce))
|
||||
* **typings:** install es6-shim typings to a location users can reference. ([f1f5b45](https://github.com/angular/angular/commit/f1f5b45))
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
Transitive typings are no longer included in the distribution.
|
||||
|
||||
If you use `--target=es5`, you will need to add a line somewhere in your
|
||||
application (for example, at the top of the `.ts` file where you call `bootstrap`):
|
||||
```
|
||||
///<reference path="node_modules/angular2/typings/browser.d.ts"/>
|
||||
```
|
||||
(Note that if your file is not in the same directory as `node_modules`, you'll
|
||||
need to add one or more `../` to the start of that path.)
|
||||
|
||||
If you have unit tests, you need to install typings in your project using
|
||||
http://github.com/typings/typings
|
||||
And install typings such as `jasmine`, `angular-protractor`, or `selenium-webdriver`
|
||||
to satisfy the type-checker.
|
||||
|
||||
<a name="2.0.0-beta.4"></a>
|
||||
# 2.0.0-beta.4 (2016-02-10)
|
||||
|
||||
This release was incorrect; replaced with beta.5.
|
||||
|
||||
<a name="2.0.0-beta.3"></a>
|
||||
# 2.0.0-beta.3 (2016-02-03)
|
||||
|
||||
@ -27,6 +84,52 @@
|
||||
|
||||
* **dart/transform:** Only process deferred libs when necessary ([f56df65](https://github.com/angular/angular/commit/f56df65)), closes [#6745](https://github.com/angular/angular/issues/6745)
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
This is a breaking change for unit tests. The API for the DebugElement
|
||||
has changed. Now, there is a DebugElement or DebugNode for every node
|
||||
in the DOM, not only nodes with an ElementRef. `componentViewChildren` is
|
||||
removed, and `childNodes` is a list of ElementNodes corresponding to every
|
||||
child in the DOM. `query` no longer takes a scope parameter, since
|
||||
the entire rendered DOM is included in the `childNodes`.
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
componentFixture.debugElement.componentViewChildren[0];
|
||||
```
|
||||
|
||||
After
|
||||
```
|
||||
// Depending on the DOM structure of your component, the
|
||||
// index may have changed or the first component child
|
||||
// may be a sub-child.
|
||||
componentFixture.debugElement.children[0];
|
||||
```
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
debugElement.query(By.css('div'), Scope.all());
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
debugElement.query(By.css('div'));
|
||||
```
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
componentFixture.debugElement.elementRef;
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
componentFixture.elementRef;
|
||||
```
|
||||
|
||||
<a name="2.0.0-beta.2"></a>
|
||||
# 2.0.0-beta.2 (2016-01-28)
|
||||
|
@ -981,15 +981,16 @@ gulp.task('!pre.test.typings.layoutNodeModule', ['build.js.cjs'], function() {
|
||||
.pipe(gulp.dest(path.join(tmpdir, 'node_modules')));
|
||||
});
|
||||
gulp.task('!pre.test.typings.copyTypingsSpec', function() {
|
||||
return gulp.src(['typing_spec/*.ts'], {base: 'typing_spec'}).pipe(gulp.dest(path.join(tmpdir)));
|
||||
return gulp.src(['typing_spec/*.ts'], {base: 'typing_spec'}).pipe(gulp.dest(tmpdir));
|
||||
});
|
||||
|
||||
gulp.task('test.typings',
|
||||
['!pre.test.typings.layoutNodeModule', '!pre.test.typings.copyTypingsSpec'], function() {
|
||||
var tsc = require('gulp-typescript');
|
||||
|
||||
return gulp.src([tmpdir + '/**'])
|
||||
return gulp.src([tmpdir + '/*.ts'])
|
||||
.pipe(tsc({
|
||||
target: 'ES5',
|
||||
target: 'ES6',
|
||||
module: 'commonjs',
|
||||
experimentalDecorators: true,
|
||||
noImplicitAny: true,
|
||||
|
@ -173,6 +173,10 @@ var StringMapWrapper = {
|
||||
|
||||
var List = Array;
|
||||
var ListWrapper = {
|
||||
toJSON: function(l) {
|
||||
return JSON.stringify(l);
|
||||
},
|
||||
|
||||
clear: function (l) {
|
||||
l.length = 0;
|
||||
},
|
||||
@ -247,6 +251,10 @@ var ListWrapper = {
|
||||
};
|
||||
|
||||
var StringWrapper = {
|
||||
charCodeAt: function(s, i) {
|
||||
return s.charCodeAt(i);
|
||||
},
|
||||
|
||||
equals: function (s1, s2) {
|
||||
return s1 === s2;
|
||||
},
|
||||
@ -303,8 +311,8 @@ Location.prototype.subscribe = function () {
|
||||
//TODO: implement
|
||||
};
|
||||
Location.prototype.path = function () {
|
||||
return $location.path();
|
||||
return $location.url();
|
||||
};
|
||||
Location.prototype.go = function (url) {
|
||||
return $location.path(url);
|
||||
Location.prototype.go = function (path, query) {
|
||||
return $location.url(path + query);
|
||||
};
|
||||
|
@ -57,7 +57,7 @@ function routerFactory($q, $location, $$directiveIntrospector, $browser, $rootSc
|
||||
});
|
||||
|
||||
var router = new RootRouter(registry, location, $routerRootComponent);
|
||||
$rootScope.$watch(function () { return $location.path(); }, function (path) {
|
||||
$rootScope.$watch(function () { return $location.url(); }, function (path) {
|
||||
if (router.lastNavigationAttempt !== path) {
|
||||
router.navigateByUrl(path);
|
||||
}
|
||||
|
@ -155,10 +155,12 @@ function ngOutletDirective($animate, $q: ng.IQService, $router) {
|
||||
}
|
||||
|
||||
this.controller.$$routeParams = instruction.params;
|
||||
this.controller.$$template = '<div ' + dashCase(componentName) + '></div>';
|
||||
this.controller.$$template =
|
||||
'<' + dashCase(componentName) + ' router="$$router"></' + dashCase(componentName) + '>';
|
||||
this.controller.$$router = this.router.childRouter(instruction.componentType);
|
||||
|
||||
let newScope = scope.$new();
|
||||
newScope.$$router = this.controller.$$router;
|
||||
|
||||
let clone = $transclude(newScope, clone => {
|
||||
$animate.enter(clone, null, this.currentElement || element);
|
||||
|
2
modules/angular1_router/src/ng_route_shim.js
vendored
2
modules/angular1_router/src/ng_route_shim.js
vendored
@ -1,4 +1,4 @@
|
||||
/** @license Copyright 2014-2015 Google, Inc. http://github.com/angular/angular/LICENSE */
|
||||
/** @license Copyright 2014-2016 Google, Inc. http://github.com/angular/angular/LICENSE */
|
||||
(function () {
|
||||
|
||||
'use strict';
|
||||
|
@ -21,17 +21,29 @@ describe('navigation', function () {
|
||||
$router = _$router_;
|
||||
});
|
||||
|
||||
registerComponent('userCmp', {
|
||||
registerDirective('userCmp', {
|
||||
template: '<div>hello {{userCmp.$routeParams.name}}</div>'
|
||||
});
|
||||
registerComponent('oneCmp', {
|
||||
registerDirective('oneCmp', {
|
||||
template: '<div>{{oneCmp.number}}</div>',
|
||||
controller: function () {this.number = 'one'}
|
||||
});
|
||||
registerComponent('twoCmp', {
|
||||
registerDirective('twoCmp', {
|
||||
template: '<div>{{twoCmp.number}}</div>',
|
||||
controller: function () {this.number = 'two'}
|
||||
});
|
||||
registerComponent('threeCmp', {
|
||||
template: '<div>{{$ctrl.number}}</div>',
|
||||
controller: function () {this.number = 'three'}
|
||||
});
|
||||
registerComponent('getParams', {
|
||||
template: '<div>{{$ctrl.params.x}}</div>',
|
||||
controller: function () {
|
||||
this.$routerOnActivate = function(next) {
|
||||
this.params = next.params;
|
||||
};
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
it('should work in a simple case', function () {
|
||||
@ -47,6 +59,21 @@ describe('navigation', function () {
|
||||
expect(elt.text()).toBe('one');
|
||||
});
|
||||
|
||||
|
||||
it('should work with components created by the `mod.component()` helper', function () {
|
||||
compile('<ng-outlet></ng-outlet>');
|
||||
|
||||
$router.config([
|
||||
{ path: '/', component: 'threeCmp' }
|
||||
]);
|
||||
|
||||
$router.navigateByUrl('/');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.text()).toBe('three');
|
||||
});
|
||||
|
||||
|
||||
it('should navigate between components with different parameters', function () {
|
||||
$router.config([
|
||||
{ path: '/user/:name', component: 'userCmp' }
|
||||
@ -68,7 +95,7 @@ describe('navigation', function () {
|
||||
function ParentController() {
|
||||
instanceCount += 1;
|
||||
}
|
||||
registerComponent('parentCmp', {
|
||||
registerDirective('parentCmp', {
|
||||
template: 'parent { <ng-outlet></ng-outlet> }',
|
||||
$routeConfig: [
|
||||
{ path: '/user/:name', component: 'userCmp' }
|
||||
@ -94,7 +121,7 @@ describe('navigation', function () {
|
||||
|
||||
|
||||
it('should work with nested outlets', function () {
|
||||
registerComponent('childCmp', {
|
||||
registerDirective('childCmp', {
|
||||
template: '<div>inner { <div ng-outlet></div> }</div>',
|
||||
$routeConfig: [
|
||||
{ path: '/b', component: 'oneCmp' }
|
||||
@ -112,9 +139,29 @@ describe('navigation', function () {
|
||||
expect(elt.text()).toBe('outer { inner { one } }');
|
||||
});
|
||||
|
||||
it('should work when parent route has empty path', inject(function ($location) {
|
||||
registerComponent('childCmp', {
|
||||
template: '<div>inner { <div ng-outlet></div> }</div>',
|
||||
$routeConfig: [
|
||||
{ path: '/b', component: 'oneCmp' }
|
||||
]
|
||||
});
|
||||
|
||||
$router.config([
|
||||
{ path: '/...', component: 'childCmp' }
|
||||
]);
|
||||
compile('<div>outer { <div ng-outlet></div> }</div>');
|
||||
|
||||
$router.navigateByUrl('/b');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.text()).toBe('outer { inner { one } }');
|
||||
expect($location.path()).toBe('/b');
|
||||
}));
|
||||
|
||||
|
||||
it('should work with recursive nested outlets', function () {
|
||||
registerComponent('recurCmp', {
|
||||
registerDirective('recurCmp', {
|
||||
template: '<div>recur { <div ng-outlet></div> }</div>',
|
||||
$routeConfig: [
|
||||
{ path: '/recur', component: 'recurCmp' },
|
||||
@ -147,6 +194,21 @@ describe('navigation', function () {
|
||||
}));
|
||||
|
||||
|
||||
it('should pass through query terms to the location', inject(function ($location) {
|
||||
$router.config([
|
||||
{ path: '/user', component: 'userCmp' }
|
||||
]);
|
||||
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$router.navigateByUrl('/user?x=y');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect($location.path()).toBe('/user');
|
||||
expect($location.search()).toEqual({ x: 'y'});
|
||||
}));
|
||||
|
||||
|
||||
it('should change location to the canonical route', inject(function ($location) {
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
@ -163,7 +225,7 @@ describe('navigation', function () {
|
||||
|
||||
|
||||
it('should change location to the canonical route with nested components', inject(function ($location) {
|
||||
registerComponent('childRouter', {
|
||||
registerDirective('childRouter', {
|
||||
template: '<div>inner { <div ng-outlet></div> }</div>',
|
||||
$routeConfig: [
|
||||
{ path: '/new-child', component: 'oneCmp', name: 'NewChild'},
|
||||
@ -206,9 +268,22 @@ describe('navigation', function () {
|
||||
}));
|
||||
|
||||
|
||||
it('should navigate when the location query changes', inject(function ($location) {
|
||||
$router.config([
|
||||
{ path: '/get/params', component: 'getParams' }
|
||||
]);
|
||||
compile('<div ng-outlet></div>');
|
||||
|
||||
$location.url('/get/params?x=y');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(elt.text()).toBe('y');
|
||||
}));
|
||||
|
||||
|
||||
it('should expose a "navigating" property on $router', inject(function ($q) {
|
||||
var defer;
|
||||
registerComponent('pendingActivate', {
|
||||
registerDirective('pendingActivate', {
|
||||
$canActivate: function () {
|
||||
defer = $q.defer();
|
||||
return defer.promise;
|
||||
@ -227,36 +302,54 @@ describe('navigation', function () {
|
||||
expect($router.navigating).toBe(false);
|
||||
}));
|
||||
|
||||
function registerComponent(name, options) {
|
||||
var controller = options.controller || function () {};
|
||||
|
||||
['$routerOnActivate', '$routerOnDeactivate', '$routerOnReuse', '$routerCanReuse', '$routerCanDeactivate'].forEach(function (hookName) {
|
||||
if (options[hookName]) {
|
||||
controller.prototype[hookName] = options[hookName];
|
||||
}
|
||||
});
|
||||
|
||||
function registerDirective(name, options) {
|
||||
function factory() {
|
||||
return {
|
||||
template: options.template || '',
|
||||
controllerAs: name,
|
||||
controller: controller
|
||||
controller: getController(options)
|
||||
};
|
||||
}
|
||||
|
||||
if (options.$canActivate) {
|
||||
factory.$canActivate = options.$canActivate;
|
||||
}
|
||||
if (options.$routeConfig) {
|
||||
factory.$routeConfig = options.$routeConfig;
|
||||
}
|
||||
|
||||
applyStaticProperties(factory, options);
|
||||
$compileProvider.directive(name, factory);
|
||||
}
|
||||
|
||||
function registerComponent(name, options) {
|
||||
|
||||
var definition = {
|
||||
template: options.template || '',
|
||||
controller: getController(options),
|
||||
}
|
||||
applyStaticProperties(definition, options);
|
||||
$compileProvider.component(name, definition);
|
||||
}
|
||||
|
||||
function compile(template) {
|
||||
elt = $compile('<div>' + template + '</div>')($rootScope);
|
||||
$rootScope.$digest();
|
||||
return elt;
|
||||
}
|
||||
|
||||
function getController(options) {
|
||||
var controller = options.controller || function () {};
|
||||
[
|
||||
'$routerOnActivate', '$routerOnDeactivate',
|
||||
'$routerOnReuse', '$routerCanReuse',
|
||||
'$routerCanDeactivate'
|
||||
].forEach(function (hookName) {
|
||||
if (options[hookName]) {
|
||||
controller.prototype[hookName] = options[hookName];
|
||||
}
|
||||
});
|
||||
return controller;
|
||||
}
|
||||
|
||||
function applyStaticProperties(target, options) {
|
||||
['$canActivate', '$routeConfig'].forEach(function(property) {
|
||||
if (options[property]) {
|
||||
target[property] = options[property];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -44,36 +44,105 @@ describe('router', function () {
|
||||
expect(elt.text()).toBe('Home');
|
||||
}));
|
||||
|
||||
function registerComponent(name, options) {
|
||||
var controller = options.controller || function () {};
|
||||
it('should bind the component to the current router', inject(function($location) {
|
||||
var router;
|
||||
registerComponent('homeCmp', {
|
||||
bindings: { router: '=' },
|
||||
controller: function($scope, $element) {
|
||||
this.$routerOnActivate = function() {
|
||||
router = this.router;
|
||||
};
|
||||
},
|
||||
template: 'Home'
|
||||
});
|
||||
|
||||
['$onActivate', '$onDeactivate', '$onReuse', '$canReuse', '$canDeactivate'].forEach(function (hookName) {
|
||||
if (options[hookName]) {
|
||||
controller.prototype[hookName] = options[hookName];
|
||||
registerComponent('app', {
|
||||
template: '<div ng-outlet></div>',
|
||||
$routeConfig: [
|
||||
{ path: '/', component: 'homeCmp' }
|
||||
]
|
||||
});
|
||||
|
||||
compile('<app></app>');
|
||||
|
||||
$location.path('/');
|
||||
$rootScope.$digest();
|
||||
var homeElement = elt.find('home-cmp');
|
||||
expect(homeElement.text()).toBe('Home');
|
||||
expect(homeElement.isolateScope().$ctrl.router).toBeDefined();
|
||||
expect(router).toBeDefined();
|
||||
}));
|
||||
|
||||
it('should work when an async route is provided route data', inject(function($location, $q) {
|
||||
registerDirective('homeCmp', {
|
||||
template: 'Home ({{homeCmp.isAdmin}})',
|
||||
$routerOnActivate: function(next, prev) {
|
||||
this.isAdmin = next.routeData.data.isAdmin;
|
||||
}
|
||||
});
|
||||
|
||||
registerDirective('app', {
|
||||
template: '<div ng-outlet></div>',
|
||||
$routeConfig: [
|
||||
{ path: '/', loader: function() { return $q.when('homeCmp'); }, data: { isAdmin: true } }
|
||||
]
|
||||
});
|
||||
|
||||
compile('<app></app>');
|
||||
|
||||
$location.path('/');
|
||||
$rootScope.$digest();
|
||||
expect(elt.text()).toBe('Home (true)');
|
||||
}));
|
||||
|
||||
function registerDirective(name, options) {
|
||||
function factory() {
|
||||
return {
|
||||
template: options.template || '',
|
||||
controllerAs: name,
|
||||
controller: controller
|
||||
controller: getController(options)
|
||||
};
|
||||
}
|
||||
|
||||
if (options.$canActivate) {
|
||||
factory.$canActivate = options.$canActivate;
|
||||
}
|
||||
if (options.$routeConfig) {
|
||||
factory.$routeConfig = options.$routeConfig;
|
||||
}
|
||||
|
||||
applyStaticProperties(factory, options);
|
||||
$compileProvider.directive(name, factory);
|
||||
}
|
||||
|
||||
function registerComponent(name, options) {
|
||||
|
||||
var definition = {
|
||||
bindings: options.bindings,
|
||||
template: options.template || '',
|
||||
controller: getController(options),
|
||||
}
|
||||
applyStaticProperties(definition, options);
|
||||
$compileProvider.component(name, definition);
|
||||
}
|
||||
|
||||
function compile(template) {
|
||||
elt = $compile('<div>' + template + '</div>')($rootScope);
|
||||
$rootScope.$digest();
|
||||
return elt;
|
||||
}
|
||||
|
||||
function getController(options) {
|
||||
var controller = options.controller || function () {};
|
||||
[
|
||||
'$routerOnActivate', '$routerOnDeactivate',
|
||||
'$routerOnReuse', '$routerCanReuse',
|
||||
'$routerCanDeactivate'
|
||||
].forEach(function (hookName) {
|
||||
if (options[hookName]) {
|
||||
controller.prototype[hookName] = options[hookName];
|
||||
}
|
||||
});
|
||||
return controller;
|
||||
}
|
||||
|
||||
function applyStaticProperties(target, options) {
|
||||
['$canActivate', '$routeConfig'].forEach(function(property) {
|
||||
if (options[property]) {
|
||||
target[property] = options[property];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1,12 +1,12 @@
|
||||
{
|
||||
"version": "v4",
|
||||
"repo": "angular/DefinitelyTyped",
|
||||
"repo": "DefinitelyTyped/DefinitelyTyped",
|
||||
"ref": "master",
|
||||
"path": "typings",
|
||||
"bundle": "typings/tsd.d.ts",
|
||||
"installed": {
|
||||
"angularjs/angular.d.ts": {
|
||||
"commit": "746b9a892629060bc853e792afff536e0ec4655e"
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ Bootstrapping
|
||||
@cheatsheetIndex 0
|
||||
@description
|
||||
{@target ts}`import {bootstrap} from 'angular2/platform/browser';`{@endtarget}
|
||||
{@target js}Available from the `ng.platform.browser` namespace.{@endtarget}
|
||||
{@target js}Available from the `ng.platform.browser` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/bootstrap.dart';`{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
|
@ -4,7 +4,7 @@ Built-in directives
|
||||
@description
|
||||
{@target ts}`import {NgIf, ...} from 'angular2/common';`{@endtarget}
|
||||
{@target js}Available from the `ng.common` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/common.dart';`{@endtarget}
|
||||
{@target dart}Available using `platform_directives` in pubspec{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
syntax:
|
||||
|
@ -4,7 +4,7 @@ Class decorators
|
||||
@description
|
||||
{@target ts}`import {Directive, ...} from 'angular2/core';`{@endtarget}
|
||||
{@target js}Available from the `ng.core` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/core.dart';`{@endtarget}
|
||||
{@target dart}`import 'package:angular2/angular2.dart';`{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
syntax(ts):
|
||||
|
@ -4,7 +4,7 @@ Dependency injection configuration
|
||||
@description
|
||||
{@target ts}`import {provide} from 'angular2/core';`{@endtarget}
|
||||
{@target js}Available from the `ng.core` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/core.dart';`{@endtarget}
|
||||
{@target dart}`import 'package:angular2/angular2.dart';`{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
syntax(ts dart):
|
||||
|
@ -4,7 +4,7 @@ Class field decorators for directives and components
|
||||
@description
|
||||
{@target ts}`import {Input, ...} from 'angular2/core';`{@endtarget}
|
||||
{@target js}Available from the `ng.core` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/core.dart';`{@endtarget}
|
||||
{@target dart}`import 'package:angular2/angular2.dart';`{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
syntax(ts dart):
|
||||
|
@ -4,7 +4,7 @@ Forms
|
||||
@description
|
||||
{@target ts}`import {FORM_DIRECTIVES} from 'angular2/common';`{@endtarget}
|
||||
{@target js}Available from `ng.common.FORM_DIRECTIVES`{@endtarget}
|
||||
{@target dart}`import 'package:angular2/common.dart';`{@endtarget}
|
||||
{@target dart}Available using `platform_directives` in pubspec{@endtarget}
|
||||
|
||||
@cheatsheetItem
|
||||
syntax:
|
||||
|
@ -4,7 +4,7 @@ Routing and navigation
|
||||
@description
|
||||
{@target ts}`import {RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, ...} from 'angular2/router';`{@endtarget}
|
||||
{@target js}Available from the `ng.router` namespace{@endtarget}
|
||||
{@target dart}`import 'package:angular2/router.dart';`{@endtarget}
|
||||
{@target dart}`import 'package:angular2/angular2.dart';`{@endtarget}
|
||||
|
||||
|
||||
@cheatsheetItem
|
||||
|
@ -456,7 +456,7 @@ Where
|
||||
* `local` is a local identifier for local variables.
|
||||
* `internal` is an internal variable which the directive exports for binding.
|
||||
* `key` is an attribute name usually only used to trigger a specific directive.
|
||||
* `keyExpression` is an property name to which the expression will be bound to.
|
||||
* `keyExpression` is a property name to which the expression will be bound to.
|
||||
* `varExport` allows exporting of directive internal state as variables for further binding. If no `internal` name
|
||||
is specified, the exporting is to an implicit variable.
|
||||
* `microsyntax` allows you to build a simple microsyntax which can still clearly identify which expressions bind to
|
||||
|
@ -141,7 +141,8 @@ export {URLSearchParams} from './src/http/url_search_params';
|
||||
* // Send a response to the request
|
||||
* connection.mockRespond(response);
|
||||
* });
|
||||
* });
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* http.get('people.json').observer({
|
||||
* next: res => {
|
||||
@ -156,7 +157,8 @@ export const HTTP_PROVIDERS: any[] = [
|
||||
// issue: https://github.com/angular/angular/issues/3183
|
||||
provide(Http,
|
||||
{
|
||||
useFactory: (xhrBackend, requestOptions) => new Http(xhrBackend, requestOptions),
|
||||
useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
|
||||
new Http(xhrBackend, requestOptions),
|
||||
deps: [XHRBackend, RequestOptions]
|
||||
}),
|
||||
BrowserXhr,
|
||||
@ -268,7 +270,8 @@ export const HTTP_BINDINGS = HTTP_PROVIDERS;
|
||||
* // Send a response to the request
|
||||
* connection.mockRespond(response);
|
||||
* });
|
||||
* });
|
||||
* }
|
||||
* });
|
||||
|
||||
* jsonp.get('people.json').observer({
|
||||
* next: res => {
|
||||
@ -283,7 +286,8 @@ export const JSONP_PROVIDERS: any[] = [
|
||||
// issue: https://github.com/angular/angular/issues/3183
|
||||
provide(Jsonp,
|
||||
{
|
||||
useFactory: (jsonpBackend, requestOptions) => new Jsonp(jsonpBackend, requestOptions),
|
||||
useFactory: (jsonpBackend: JSONPBackend, requestOptions: RequestOptions) =>
|
||||
new Jsonp(jsonpBackend, requestOptions),
|
||||
deps: [JSONPBackend, RequestOptions]
|
||||
}),
|
||||
BrowserJsonp,
|
||||
|
36
modules/angular2/manual_typings/globals-es6.d.ts
vendored
36
modules/angular2/manual_typings/globals-es6.d.ts
vendored
@ -1,36 +0,0 @@
|
||||
/**
|
||||
* Declarations angular depends on for compilation to ES6.
|
||||
* This file is also used to propagate our transitive typings
|
||||
* to users.
|
||||
*/
|
||||
|
||||
/// <reference path="../typings/zone/zone.d.ts"/>
|
||||
/// <reference path="../typings/hammerjs/hammerjs.d.ts"/>
|
||||
|
||||
// TODO: ideally the node.d.ts reference should be scoped only for files that need and not to all
|
||||
// the code including client code
|
||||
/// <reference path="../typings/node/node.d.ts" />
|
||||
|
||||
declare var assert: any;
|
||||
|
||||
|
||||
interface BrowserNodeGlobal {
|
||||
Object: typeof Object;
|
||||
Array: typeof Array;
|
||||
Map: typeof Map;
|
||||
Set: typeof Set;
|
||||
Date: typeof Date;
|
||||
RegExp: typeof RegExp;
|
||||
JSON: typeof JSON;
|
||||
Math: typeof Math;
|
||||
assert(condition: any): void;
|
||||
Reflect: any;
|
||||
zone: Zone;
|
||||
getAngularTestability: Function;
|
||||
getAllAngularTestabilities: Function;
|
||||
frameworkStabilizers: Array<Function>;
|
||||
setTimeout: Function;
|
||||
clearTimeout: Function;
|
||||
setInterval: Function;
|
||||
clearInterval: Function;
|
||||
}
|
55
modules/angular2/manual_typings/globals.d.ts
vendored
55
modules/angular2/manual_typings/globals.d.ts
vendored
@ -1,7 +1,52 @@
|
||||
/**
|
||||
* Declarations angular depends on for compilation to ES6.
|
||||
* This file is also used to propagate our transitive typings
|
||||
* to users.
|
||||
* Subset of es6-shim typings.
|
||||
* Angular should not require use of ES6 runtime but some API usages are already present.
|
||||
* See https://github.com/angular/angular/issues/5242
|
||||
* TODO(alexeagle): remove methods below which may not be present in targeted browser
|
||||
*/
|
||||
/// <reference path="../typings/es6-shim/es6-shim.d.ts"/>
|
||||
/// <reference path="./globals-es6.d.ts"/>
|
||||
|
||||
declare type PromiseConstructor = typeof Promise;
|
||||
|
||||
interface String {
|
||||
/**
|
||||
* Returns true if the sequence of elements of searchString converted to a String is the
|
||||
* same as the corresponding elements of this object (converted to a String) starting at
|
||||
* position. Otherwise returns false.
|
||||
*/
|
||||
startsWith(searchString: string, position?: number): boolean;
|
||||
|
||||
/**
|
||||
* Returns true if the sequence of elements of searchString converted to a String is the
|
||||
* same as the corresponding elements of this object (converted to a String) starting at
|
||||
* endPosition – length(this). Otherwise returns false.
|
||||
*/
|
||||
endsWith(searchString: string, endPosition?: number): boolean;
|
||||
}
|
||||
interface Array<T> {
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found, find
|
||||
* immediately returns that element value. Otherwise, find returns undefined.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: T, index: number, obj: Array<T>) => boolean, thisArg?: any): T;
|
||||
/**
|
||||
* Returns the this object after filling the section identified by start and end with value
|
||||
* @param value value to fill array section with
|
||||
* @param start index to start filling the array at. If start is negative, it is treated as
|
||||
* length+start where length is the length of the array.
|
||||
* @param end index to stop filling the array at. If end is negative, it is treated as
|
||||
* length+end.
|
||||
*/
|
||||
fill(value: T, start?: number, end?: number): T[];
|
||||
}
|
||||
interface NumberConstructor {
|
||||
/**
|
||||
* Returns true if the value passed is an integer, false otherwise.
|
||||
* @param number A numeric value.
|
||||
*/
|
||||
isInteger(number: number): boolean;
|
||||
}
|
||||
|
@ -8,6 +8,12 @@
|
||||
"license": "<%= packageJson.license %>",
|
||||
"repository": <%= JSON.stringify(packageJson.repository) %>,
|
||||
"devDependencies": <%= JSON.stringify(packageJson.defaultDevDependencies) %>,
|
||||
"dependencies": {
|
||||
"typings": "0.6.6"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "typings install --ambient --name es6-promise github:DefinitelyTyped/DefinitelyTyped/es6-promise/es6-promise.d.ts#830e8ebd9ef137d039d5c7ede24a421f08595f83; typings install --ambient --name es6-collections github:DefinitelyTyped/DefinitelyTyped/es6-collections/es6-collections.d.ts#9f97e2a2bc1f502550c9b4fcaad1c48df5521d37"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"es6-promise": "<%= packageJson.dependencies['es6-promise'] %>",
|
||||
"es6-shim": "<%= packageJson.dependencies['es6-shim'] %>",
|
||||
|
@ -117,6 +117,11 @@ export class NgFor implements DoCheck {
|
||||
var viewRef = <EmbeddedViewRef>this._viewContainer.get(i);
|
||||
viewRef.setLocal('last', i === ilen - 1);
|
||||
}
|
||||
|
||||
changes.forEachIdentityChange((record) => {
|
||||
var viewRef = <EmbeddedViewRef>this._viewContainer.get(record.currentIndex);
|
||||
viewRef.setLocal('\$implicit', record.item);
|
||||
});
|
||||
}
|
||||
|
||||
private _perViewChange(view, record) {
|
||||
|
@ -31,7 +31,7 @@ export {
|
||||
NgSelectOption,
|
||||
SelectControlValueAccessor
|
||||
} from './forms/directives/select_control_value_accessor';
|
||||
export {FORM_DIRECTIVES} from './forms/directives';
|
||||
export {FORM_DIRECTIVES, RadioButtonState} from './forms/directives';
|
||||
export {NG_VALIDATORS, NG_ASYNC_VALIDATORS, Validators} from './forms/validators';
|
||||
export {
|
||||
RequiredValidator,
|
||||
@ -39,4 +39,25 @@ export {
|
||||
MaxLengthValidator,
|
||||
Validator
|
||||
} from './forms/directives/validators';
|
||||
export {FormBuilder, FORM_PROVIDERS, FORM_BINDINGS} from './forms/form_builder';
|
||||
export {FormBuilder} from './forms/form_builder';
|
||||
import {FormBuilder} from './forms/form_builder';
|
||||
import {RadioControlRegistry} from './forms/directives/radio_control_value_accessor';
|
||||
import {Type, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
/**
|
||||
* Shorthand set of providers used for building Angular forms.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```typescript
|
||||
* bootstrap(MyApp, [FORM_PROVIDERS]);
|
||||
* ```
|
||||
*/
|
||||
export const FORM_PROVIDERS: Type[] = CONST_EXPR([FormBuilder, RadioControlRegistry]);
|
||||
|
||||
/**
|
||||
* See {@link FORM_PROVIDERS} instead.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export const FORM_BINDINGS = FORM_PROVIDERS;
|
||||
|
@ -8,6 +8,7 @@ import {NgForm} from './directives/ng_form';
|
||||
import {DefaultValueAccessor} from './directives/default_value_accessor';
|
||||
import {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
||||
import {NumberValueAccessor} from './directives/number_value_accessor';
|
||||
import {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
||||
import {NgControlStatus} from './directives/ng_control_status';
|
||||
import {
|
||||
SelectControlValueAccessor,
|
||||
@ -23,6 +24,10 @@ export {NgFormModel} from './directives/ng_form_model';
|
||||
export {NgForm} from './directives/ng_form';
|
||||
export {DefaultValueAccessor} from './directives/default_value_accessor';
|
||||
export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
||||
export {
|
||||
RadioControlValueAccessor,
|
||||
RadioButtonState
|
||||
} from './directives/radio_control_value_accessor';
|
||||
export {NumberValueAccessor} from './directives/number_value_accessor';
|
||||
export {NgControlStatus} from './directives/ng_control_status';
|
||||
export {
|
||||
@ -63,6 +68,7 @@ export const FORM_DIRECTIVES: Type[] = CONST_EXPR([
|
||||
NumberValueAccessor,
|
||||
CheckboxControlValueAccessor,
|
||||
SelectControlValueAccessor,
|
||||
RadioControlValueAccessor,
|
||||
NgControlStatus,
|
||||
|
||||
RequiredValidator,
|
||||
|
@ -18,7 +18,7 @@ const CHECKBOX_VALUE_ACCESSOR = CONST_EXPR(new Provider(
|
||||
selector:
|
||||
'input[type=checkbox][ngControl],input[type=checkbox][ngFormControl],input[type=checkbox][ngModel]',
|
||||
host: {'(change)': 'onChange($event.target.checked)', '(blur)': 'onTouched()'},
|
||||
bindings: [CHECKBOX_VALUE_ACCESSOR]
|
||||
providers: [CHECKBOX_VALUE_ACCESSOR]
|
||||
})
|
||||
export class CheckboxControlValueAccessor implements ControlValueAccessor {
|
||||
onChange = (_) => {};
|
||||
|
@ -0,0 +1,126 @@
|
||||
import {
|
||||
Directive,
|
||||
ElementRef,
|
||||
Renderer,
|
||||
Self,
|
||||
forwardRef,
|
||||
Provider,
|
||||
Attribute,
|
||||
Input,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
Injector,
|
||||
Injectable
|
||||
} from 'angular2/core';
|
||||
import {
|
||||
NG_VALUE_ACCESSOR,
|
||||
ControlValueAccessor
|
||||
} from 'angular2/src/common/forms/directives/control_value_accessor';
|
||||
import {NgControl} from 'angular2/src/common/forms/directives/ng_control';
|
||||
import {CONST_EXPR, looseIdentical, isPresent} from 'angular2/src/facade/lang';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
const RADIO_VALUE_ACCESSOR = CONST_EXPR(new Provider(
|
||||
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => RadioControlValueAccessor), multi: true}));
|
||||
|
||||
|
||||
/**
|
||||
* Internal class used by Angular to uncheck radio buttons with the matching name.
|
||||
*/
|
||||
@Injectable()
|
||||
export class RadioControlRegistry {
|
||||
private _accessors: any[] = [];
|
||||
|
||||
add(control: NgControl, accessor: RadioControlValueAccessor) {
|
||||
this._accessors.push([control, accessor]);
|
||||
}
|
||||
|
||||
remove(accessor: RadioControlValueAccessor) {
|
||||
var indexToRemove = -1;
|
||||
for (var i = 0; i < this._accessors.length; ++i) {
|
||||
if (this._accessors[i][1] === accessor) {
|
||||
indexToRemove = i;
|
||||
}
|
||||
}
|
||||
ListWrapper.removeAt(this._accessors, indexToRemove);
|
||||
}
|
||||
|
||||
select(accessor: RadioControlValueAccessor) {
|
||||
this._accessors.forEach((c) => {
|
||||
if (c[0].control.root === accessor._control.control.root && c[1] !== accessor) {
|
||||
c[1].fireUncheck();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The value provided by the forms API for radio buttons.
|
||||
*/
|
||||
export class RadioButtonState {
|
||||
constructor(public checked: boolean, public value: string) {}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The accessor for writing a radio control value and listening to changes that is used by the
|
||||
* {@link NgModel}, {@link NgFormControl}, and {@link NgControlName} directives.
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* @Component({
|
||||
* template: `
|
||||
* <input type="radio" name="food" [(ngModel)]="foodChicken">
|
||||
* <input type="radio" name="food" [(ngModel)]="foodFish">
|
||||
* `
|
||||
* })
|
||||
* class FoodCmp {
|
||||
* foodChicken = new RadioButtonState(true, "chicken");
|
||||
* foodFish = new RadioButtonState(false, "fish");
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
@Directive({
|
||||
selector:
|
||||
'input[type=radio][ngControl],input[type=radio][ngFormControl],input[type=radio][ngModel]',
|
||||
host: {'(change)': 'onChange()', '(blur)': 'onTouched()'},
|
||||
providers: [RADIO_VALUE_ACCESSOR]
|
||||
})
|
||||
export class RadioControlValueAccessor implements ControlValueAccessor,
|
||||
OnDestroy, OnInit {
|
||||
_state: RadioButtonState;
|
||||
_control: NgControl;
|
||||
@Input() name: string;
|
||||
_fn: Function;
|
||||
onChange = () => {};
|
||||
onTouched = () => {};
|
||||
|
||||
constructor(private _renderer: Renderer, private _elementRef: ElementRef,
|
||||
private _registry: RadioControlRegistry, private _injector: Injector) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this._control = this._injector.get(NgControl);
|
||||
this._registry.add(this._control, this);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void { this._registry.remove(this); }
|
||||
|
||||
writeValue(value: any): void {
|
||||
this._state = value;
|
||||
if (isPresent(value) && value.checked) {
|
||||
this._renderer.setElementProperty(this._elementRef.nativeElement, 'checked', true);
|
||||
}
|
||||
}
|
||||
|
||||
registerOnChange(fn: (_: any) => {}): void {
|
||||
this._fn = fn;
|
||||
this.onChange = () => {
|
||||
fn(new RadioButtonState(true, this._state.value));
|
||||
this._registry.select(this);
|
||||
};
|
||||
}
|
||||
|
||||
fireUncheck(): void { this._fn(new RadioButtonState(false, this._state.value)); }
|
||||
|
||||
registerOnTouched(fn: () => {}): void { this.onTouched = fn; }
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {isBlank, isPresent, looseIdentical} from 'angular2/src/facade/lang';
|
||||
import {isBlank, isPresent, looseIdentical, hasConstructor} from 'angular2/src/facade/lang';
|
||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||
|
||||
import {ControlContainer} from './control_container';
|
||||
@ -13,6 +13,7 @@ import {DefaultValueAccessor} from './default_value_accessor';
|
||||
import {NumberValueAccessor} from './number_value_accessor';
|
||||
import {CheckboxControlValueAccessor} from './checkbox_value_accessor';
|
||||
import {SelectControlValueAccessor} from './select_control_value_accessor';
|
||||
import {RadioControlValueAccessor} from './radio_control_value_accessor';
|
||||
import {normalizeValidator} from './normalize_validator';
|
||||
|
||||
|
||||
@ -81,11 +82,13 @@ export function selectValueAccessor(dir: NgControl,
|
||||
var builtinAccessor;
|
||||
var customAccessor;
|
||||
valueAccessors.forEach(v => {
|
||||
if (v instanceof DefaultValueAccessor) {
|
||||
if (hasConstructor(v, DefaultValueAccessor)) {
|
||||
defaultAccessor = v;
|
||||
|
||||
} else if (v instanceof CheckboxControlValueAccessor || v instanceof NumberValueAccessor ||
|
||||
v instanceof SelectControlValueAccessor) {
|
||||
} else if (hasConstructor(v, CheckboxControlValueAccessor) ||
|
||||
hasConstructor(v, NumberValueAccessor) ||
|
||||
hasConstructor(v, SelectControlValueAccessor) ||
|
||||
hasConstructor(v, RadioControlValueAccessor)) {
|
||||
if (isPresent(builtinAccessor))
|
||||
_throwError(dir, "More than one built-in value accessor matches");
|
||||
builtinAccessor = v;
|
||||
|
@ -105,22 +105,4 @@ export class FormBuilder {
|
||||
return this.control(controlConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand set of providers used for building Angular forms.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```typescript
|
||||
* bootstrap(MyApp, [FORM_PROVIDERS]);
|
||||
* ```
|
||||
*/
|
||||
export const FORM_PROVIDERS: Type[] = CONST_EXPR([FormBuilder]);
|
||||
|
||||
/**
|
||||
* See {@link FORM_PROVIDERS} instead.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export const FORM_BINDINGS = FORM_PROVIDERS;
|
||||
}
|
@ -208,6 +208,16 @@ export abstract class AbstractControl {
|
||||
return isPresent(this.getError(errorCode, path));
|
||||
}
|
||||
|
||||
get root(): AbstractControl {
|
||||
let x: AbstractControl = this;
|
||||
|
||||
while (isPresent(x._parent)) {
|
||||
x = x._parent;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_updateControlsErrors(): void {
|
||||
this._status = this._calculateStatus();
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {isBlank, isPresent, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {isBlank, isPresent, CONST_EXPR, isString} from 'angular2/src/facade/lang';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/promise';
|
||||
import {ObservableWrapper} from 'angular2/src/facade/async';
|
||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
@ -44,7 +44,9 @@ export class Validators {
|
||||
* Validator that requires controls to have a non-empty value.
|
||||
*/
|
||||
static required(control: modelModule.Control): {[key: string]: boolean} {
|
||||
return isBlank(control.value) || control.value == "" ? {"required": true} : null;
|
||||
return isBlank(control.value) || (isString(control.value) && control.value == "") ?
|
||||
{"required": true} :
|
||||
null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,6 +81,7 @@ export class AsyncPipe implements PipeTransform, OnDestroy {
|
||||
if (isPresent(obj)) {
|
||||
this._subscribe(obj);
|
||||
}
|
||||
this._latestReturnedValue = this._latestValue;
|
||||
return this._latestValue;
|
||||
}
|
||||
|
||||
|
@ -433,8 +433,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
var parts = splitAtColon(name, [null, name]);
|
||||
var target = parts[0];
|
||||
var eventName = parts[1];
|
||||
targetEvents.push(new BoundEventAst(eventName, target,
|
||||
this._parseAction(expression, sourceSpan), sourceSpan));
|
||||
var ast = this._parseAction(expression, sourceSpan);
|
||||
targetMatchableAttrs.push([name, ast.source]);
|
||||
targetEvents.push(new BoundEventAst(eventName, target, ast, sourceSpan));
|
||||
// Don't detect directives for event names for now,
|
||||
// so don't add the event name to the matchableAttrs
|
||||
}
|
||||
|
@ -456,11 +456,10 @@ export class ApplicationRef_ extends ApplicationRef {
|
||||
});
|
||||
return completer.promise.then(_ => {
|
||||
let c = this._injector.get(Console);
|
||||
let modeDescription =
|
||||
assertionsEnabled() ?
|
||||
"in the development mode. Call enableProdMode() to enable the production mode." :
|
||||
"in the production mode. Call enableDevMode() to enable the development mode.";
|
||||
c.log(`Angular 2 is running ${modeDescription}`);
|
||||
if (assertionsEnabled()) {
|
||||
c.log(
|
||||
"Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.");
|
||||
}
|
||||
return _;
|
||||
});
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
|
||||
handleEvent(eventName: string, elIndex: number, event: any): boolean {
|
||||
if (!this.hydrated()) {
|
||||
this.throwDehydratedError();
|
||||
this.throwDehydratedError(`${this.id} -> ${eventName}`);
|
||||
}
|
||||
try {
|
||||
var locals = new Map<string, any>();
|
||||
@ -130,7 +130,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
// facilitate error reporting.
|
||||
detectChangesInRecords(throwOnChange: boolean): void {
|
||||
if (!this.hydrated()) {
|
||||
this.throwDehydratedError();
|
||||
this.throwDehydratedError(this.id);
|
||||
}
|
||||
try {
|
||||
this.detectChangesInRecordsInternal(throwOnChange);
|
||||
@ -362,7 +362,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
oldValue, newValue, null);
|
||||
}
|
||||
|
||||
throwDehydratedError(): void { throw new DehydratedException(); }
|
||||
throwDehydratedError(detail: string): void { throw new DehydratedException(detail); }
|
||||
|
||||
private _currentBinding(): BindingTarget {
|
||||
return this.bindingTargets[this.propertyBindingIndex];
|
||||
|
@ -40,6 +40,9 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
private _movesTail: CollectionChangeRecord = null;
|
||||
private _removalsHead: CollectionChangeRecord = null;
|
||||
private _removalsTail: CollectionChangeRecord = null;
|
||||
// Keeps track of records where custom track by is the same, but item identity has changed
|
||||
private _identityChangesHead: CollectionChangeRecord = null;
|
||||
private _identityChangesTail: CollectionChangeRecord = null;
|
||||
|
||||
constructor(private _trackByFn?: TrackByFn) {
|
||||
this._trackByFn = isPresent(this._trackByFn) ? this._trackByFn : trackByIdentity;
|
||||
@ -84,6 +87,13 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
}
|
||||
}
|
||||
|
||||
forEachIdentityChange(fn: Function) {
|
||||
var record: CollectionChangeRecord;
|
||||
for (record = this._identityChangesHead; record !== null; record = record._nextIdentityChange) {
|
||||
fn(record);
|
||||
}
|
||||
}
|
||||
|
||||
diff(collection: any): DefaultIterableDiffer {
|
||||
if (isBlank(collection)) collection = [];
|
||||
if (!isListLikeIterable(collection)) {
|
||||
@ -123,7 +133,7 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
// TODO(misko): can we limit this to duplicates only?
|
||||
record = this._verifyReinsertion(record, item, itemTrackBy, index);
|
||||
}
|
||||
record.item = item;
|
||||
if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item);
|
||||
}
|
||||
|
||||
record = record._next;
|
||||
@ -135,9 +145,12 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
|
||||
record = this._mismatch(record, item, itemTrackBy, index);
|
||||
mayBeDirty = true;
|
||||
} else if (mayBeDirty) {
|
||||
// TODO(misko): can we limit this to duplicates only?
|
||||
record = this._verifyReinsertion(record, item, itemTrackBy, index);
|
||||
} else {
|
||||
if (mayBeDirty) {
|
||||
// TODO(misko): can we limit this to duplicates only?
|
||||
record = this._verifyReinsertion(record, item, itemTrackBy, index);
|
||||
}
|
||||
if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item);
|
||||
}
|
||||
record = record._next;
|
||||
index++;
|
||||
@ -150,9 +163,12 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
return this.isDirty;
|
||||
}
|
||||
|
||||
// CollectionChanges is considered dirty if it has any additions, moves or removals.
|
||||
/* CollectionChanges is considered dirty if it has any additions, moves, removals, or identity
|
||||
* changes.
|
||||
*/
|
||||
get isDirty(): boolean {
|
||||
return this._additionsHead !== null || this._movesHead !== null || this._removalsHead !== null;
|
||||
return this._additionsHead !== null || this._movesHead !== null ||
|
||||
this._removalsHead !== null || this._identityChangesHead !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,6 +199,7 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
}
|
||||
this._movesHead = this._movesTail = null;
|
||||
this._removalsHead = this._removalsTail = null;
|
||||
this._identityChangesHead = this._identityChangesTail = null;
|
||||
|
||||
// todo(vicb) when assert gets supported
|
||||
// assert(!this.isDirty);
|
||||
@ -216,12 +233,18 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
record = this._linkedRecords === null ? null : this._linkedRecords.get(itemTrackBy, index);
|
||||
if (record !== null) {
|
||||
// We have seen this before, we need to move it forward in the collection.
|
||||
// But first we need to check if identity changed, so we can update in view if necessary
|
||||
if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item);
|
||||
|
||||
this._moveAfter(record, previousRecord, index);
|
||||
} else {
|
||||
// Never seen it, check evicted list.
|
||||
record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy);
|
||||
if (record !== null) {
|
||||
// It is an item which we have evicted earlier: reinsert it back into the list.
|
||||
// But first we need to check if identity changed, so we can update in view if necessary
|
||||
if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item);
|
||||
|
||||
this._reinsertAfter(record, previousRecord, index);
|
||||
} else {
|
||||
// It is a new item: add it.
|
||||
@ -269,7 +292,6 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
record.currentIndex = index;
|
||||
this._addToMoves(record, index);
|
||||
}
|
||||
record.item = item;
|
||||
return record;
|
||||
}
|
||||
|
||||
@ -469,6 +491,18 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
return record;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_addIdentityChange(record: CollectionChangeRecord, item: any) {
|
||||
record.item = item;
|
||||
if (this._identityChangesTail === null) {
|
||||
this._identityChangesTail = this._identityChangesHead = record;
|
||||
} else {
|
||||
this._identityChangesTail = this._identityChangesTail._nextIdentityChange = record;
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
toString(): string {
|
||||
var list = [];
|
||||
this.forEachItem((record) => list.push(record));
|
||||
@ -485,9 +519,13 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
var removals = [];
|
||||
this.forEachRemovedItem((record) => removals.push(record));
|
||||
|
||||
var identityChanges = [];
|
||||
this.forEachIdentityChange((record) => identityChanges.push(record));
|
||||
|
||||
return "collection: " + list.join(', ') + "\n" + "previous: " + previous.join(', ') + "\n" +
|
||||
"additions: " + additions.join(', ') + "\n" + "moves: " + moves.join(', ') + "\n" +
|
||||
"removals: " + removals.join(', ') + "\n";
|
||||
"removals: " + removals.join(', ') + "\n" + "identityChanges: " +
|
||||
identityChanges.join(', ') + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -513,6 +551,9 @@ export class CollectionChangeRecord {
|
||||
_nextAdded: CollectionChangeRecord = null;
|
||||
/** @internal */
|
||||
_nextMoved: CollectionChangeRecord = null;
|
||||
/** @internal */
|
||||
_nextIdentityChange: CollectionChangeRecord = null;
|
||||
|
||||
|
||||
constructor(public item: any, public trackById: any) {}
|
||||
|
||||
|
@ -91,7 +91,7 @@ export class ChangeDetectionError extends WrappedException {
|
||||
* This is an internal Angular error.
|
||||
*/
|
||||
export class DehydratedException extends BaseException {
|
||||
constructor() { super('Attempt to use a dehydrated detector.'); }
|
||||
constructor(details: string) { super(`Attempt to use a dehydrated detector: ${details}`); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -248,15 +248,12 @@ class _Scanner {
|
||||
}
|
||||
|
||||
scanCharacter(start: number, code: number): Token {
|
||||
assert(this.peek == code);
|
||||
this.advance();
|
||||
return newCharacterToken(start, code);
|
||||
}
|
||||
|
||||
|
||||
scanOperator(start: number, str: string): Token {
|
||||
assert(this.peek == StringWrapper.charCodeAt(str, 0));
|
||||
assert(SetWrapper.has(OPERATORS, str));
|
||||
this.advance();
|
||||
return newOperatorToken(start, str);
|
||||
}
|
||||
@ -274,7 +271,6 @@ class _Scanner {
|
||||
*/
|
||||
scanComplexOperator(start: number, one: string, twoCode: number, two: string, threeCode?: number,
|
||||
three?: string): Token {
|
||||
assert(this.peek == StringWrapper.charCodeAt(one, 0));
|
||||
this.advance();
|
||||
var str: string = one;
|
||||
if (this.peek == twoCode) {
|
||||
@ -285,12 +281,10 @@ class _Scanner {
|
||||
this.advance();
|
||||
str += three;
|
||||
}
|
||||
assert(SetWrapper.has(OPERATORS, str));
|
||||
return newOperatorToken(start, str);
|
||||
}
|
||||
|
||||
scanIdentifier(): Token {
|
||||
assert(isIdentifierStart(this.peek));
|
||||
var start: number = this.index;
|
||||
this.advance();
|
||||
while (isIdentifierPart(this.peek)) this.advance();
|
||||
@ -303,7 +297,6 @@ class _Scanner {
|
||||
}
|
||||
|
||||
scanNumber(start: number): Token {
|
||||
assert(isDigit(this.peek));
|
||||
var simple: boolean = (this.index === start);
|
||||
this.advance(); // Skip initial digit.
|
||||
while (true) {
|
||||
@ -329,7 +322,6 @@ class _Scanner {
|
||||
}
|
||||
|
||||
scanString(): Token {
|
||||
assert(this.peek == $SQ || this.peek == $DQ);
|
||||
var start: number = this.index;
|
||||
var quote: number = this.peek;
|
||||
this.advance(); // Skip initial quote.
|
||||
|
@ -49,7 +49,7 @@ import {
|
||||
|
||||
var _implicitReceiver = new ImplicitReceiver();
|
||||
// TODO(tbosch): Cannot make this const/final right now because of the transpiler...
|
||||
var INTERPOLATION_REGEXP = /\{\{(.*?)\}\}/g;
|
||||
var INTERPOLATION_REGEXP = /\{\{([\s\S]*?)\}\}/g;
|
||||
|
||||
class ParseException extends BaseException {
|
||||
constructor(message: string, input: string, errLocation: string, ctxLocation?: any) {
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
OutOfBoundsError
|
||||
} from './exceptions';
|
||||
import {FunctionWrapper, Type, isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
import {Key} from './key';
|
||||
import {SelfMetadata, HostMetadata, SkipSelfMetadata} from './metadata';
|
||||
|
||||
@ -874,6 +875,9 @@ export class Injector {
|
||||
obj = factory(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16,
|
||||
d17, d18, d19);
|
||||
break;
|
||||
default:
|
||||
throw new BaseException(
|
||||
`Cannot instantiate '${provider.key.displayName}' because it has more than 20 dependencies`);
|
||||
}
|
||||
} catch (e) {
|
||||
throw new InstantiationError(this, e, e.stack, provider.key);
|
||||
|
@ -9,7 +9,7 @@ import {CONST} from 'angular2/src/facade/lang';
|
||||
* var t = new OpaqueToken("value");
|
||||
*
|
||||
* var injector = Injector.resolveAndCreate([
|
||||
* provide(t, {useValue: "providedValue"})
|
||||
* provide(t, {useValue: "bindingValue"})
|
||||
* ]);
|
||||
*
|
||||
* expect(injector.get(t)).toEqual("bindingValue");
|
||||
|
@ -1166,7 +1166,7 @@ export var ViewChild: ViewChildFactory = makePropDecorator(ViewChildMetadata);
|
||||
* shown: boolean;
|
||||
*
|
||||
* constructor(private @Query(Item) items:QueryList<Item>) {
|
||||
* items.onChange(() => console.log(items.length));
|
||||
* items.changes.subscribe(() => console.log(items.length));
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
|
@ -254,7 +254,7 @@ export class ContentChildMetadata extends QueryMetadata {
|
||||
* shown: boolean;
|
||||
*
|
||||
* constructor(private @Query(Item) items:QueryList<Item>) {
|
||||
* items.onChange(() => console.log(items.length));
|
||||
* items.changes.subscribe(() => console.log(items.length));
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
|
@ -1071,8 +1071,8 @@ export class OutputMetadata {
|
||||
* @Directive({selector: '[ngModel]'})
|
||||
* class NgModelStatus {
|
||||
* constructor(public control:NgModel) {}
|
||||
* @HostBinding('[class.valid]') get valid { return this.control.valid; }
|
||||
* @HostBinding('[class.invalid]') get invalid { return this.control.invalid; }
|
||||
* @HostBinding('class.valid') get valid { return this.control.valid; }
|
||||
* @HostBinding('class.invalid') get invalid { return this.control.invalid; }
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
|
@ -83,7 +83,7 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_zipTypesAndAnnotaions(paramTypes, paramAnnotations): any[][] {
|
||||
_zipTypesAndAnnotations(paramTypes, paramAnnotations): any[][] {
|
||||
var result;
|
||||
|
||||
if (typeof paramTypes === 'undefined') {
|
||||
@ -119,7 +119,7 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||
var paramAnnotations = this._reflect.getMetadata('parameters', typeOrFunc);
|
||||
var paramTypes = this._reflect.getMetadata('design:paramtypes', typeOrFunc);
|
||||
if (isPresent(paramTypes) || isPresent(paramAnnotations)) {
|
||||
return this._zipTypesAndAnnotaions(paramTypes, paramAnnotations);
|
||||
return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
|
||||
}
|
||||
}
|
||||
// The array has to be filled with `undefined` because holes would be skipped by `some`
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {normalizeBlank, isPresent, global} from 'angular2/src/facade/lang';
|
||||
import {normalizeBlank, isPresent, global, ZoneLike} from 'angular2/src/facade/lang';
|
||||
import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
|
||||
import {wtfLeave, wtfCreateScope, WtfScopeFn} from '../profile/profile';
|
||||
|
||||
export interface NgZoneZone extends Zone {
|
||||
export interface NgZoneZone extends ZoneLike {
|
||||
/** @internal */
|
||||
_innerZone: boolean;
|
||||
}
|
||||
@ -348,8 +348,9 @@ export class NgZone {
|
||||
var errorHandling;
|
||||
|
||||
if (enableLongStackTrace) {
|
||||
errorHandling = StringMapWrapper.merge(
|
||||
Zone.longStackTraceZone, {onError: function(e) { ngZone._notifyOnError(this, e); }});
|
||||
errorHandling =
|
||||
StringMapWrapper.merge(global.Zone.longStackTraceZone,
|
||||
{onError: function(e) { ngZone._notifyOnError(this, e); }});
|
||||
} else {
|
||||
errorHandling = {onError: function(e) { ngZone._notifyOnError(this, e); }};
|
||||
}
|
||||
|
@ -15,20 +15,16 @@ import {toPromise} from 'rxjs/operator/toPromise';
|
||||
export {Observable} from 'rxjs/Observable';
|
||||
export {Subject} from 'rxjs/Subject';
|
||||
|
||||
export namespace NodeJS {
|
||||
export interface Timer {}
|
||||
}
|
||||
|
||||
export class TimerWrapper {
|
||||
static setTimeout(fn: (...args: any[]) => void, millis: number): NodeJS.Timer {
|
||||
static setTimeout(fn: (...args: any[]) => void, millis: number): number {
|
||||
return global.setTimeout(fn, millis);
|
||||
}
|
||||
static clearTimeout(id: NodeJS.Timer): void { global.clearTimeout(id); }
|
||||
static clearTimeout(id: number): void { global.clearTimeout(id); }
|
||||
|
||||
static setInterval(fn: (...args: any[]) => void, millis: number): NodeJS.Timer {
|
||||
static setInterval(fn: (...args: any[]) => void, millis: number): number {
|
||||
return global.setInterval(fn, millis);
|
||||
}
|
||||
static clearInterval(id: NodeJS.Timer): void { global.clearInterval(id); }
|
||||
static clearInterval(id: number): void { global.clearInterval(id); }
|
||||
}
|
||||
|
||||
export class ObservableWrapper {
|
||||
@ -161,4 +157,4 @@ export class EventEmitter<T> extends Subject<T> {
|
||||
|
||||
return super.subscribe(schedulerFn, errorFn, completeFn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -353,3 +353,7 @@ 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;
|
||||
}
|
||||
|
@ -1,3 +1,36 @@
|
||||
// Zones are TC-39 standards-track so users could choose a different implementation
|
||||
// Rather than import {Zone} from 'zone.js' we define an interface
|
||||
// so that any library that structurally matches may be used with Angular 2.
|
||||
export interface ZoneLike {
|
||||
fork(locals?: any): ZoneLike;
|
||||
run(fn: any, applyTo?: any, applyWith?: any): any;
|
||||
}
|
||||
export interface ZoneLikeConstructor {
|
||||
longStackTraceZone: { [key: string]: any; };
|
||||
}
|
||||
|
||||
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;
|
||||
zone: ZoneLike;
|
||||
Zone: ZoneLikeConstructor;
|
||||
getAngularTestability: Function;
|
||||
getAllAngularTestabilities: Function;
|
||||
frameworkStabilizers: Array<Function>;
|
||||
setTimeout: Function;
|
||||
clearTimeout: Function;
|
||||
setInterval: Function;
|
||||
clearInterval: Function;
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): Load WorkerGlobalScope from lib.webworker.d.ts file #3492
|
||||
declare var WorkerGlobalScope;
|
||||
var globalScope: BrowserNodeGlobal;
|
||||
@ -10,7 +43,7 @@ if (typeof window === 'undefined') {
|
||||
}
|
||||
} else {
|
||||
globalScope = <any>window;
|
||||
};
|
||||
}
|
||||
|
||||
export const IS_DART = false;
|
||||
|
||||
@ -430,4 +463,8 @@ export function evalExpression(sourceUrl: string, expr: string, declarations: st
|
||||
|
||||
export function isPrimitive(obj: any): boolean {
|
||||
return !isJsObject(obj);
|
||||
}
|
||||
|
||||
export function hasConstructor(value: Object, type: Type): boolean {
|
||||
return value.constructor === type;
|
||||
}
|
@ -3,11 +3,11 @@ import {global} from 'angular2/src/facade/lang';
|
||||
|
||||
let _nextRequestId = 0;
|
||||
export const JSONP_HOME = '__ng_jsonp__';
|
||||
var _jsonpConnections = null;
|
||||
var _jsonpConnections: {[key: string]: any} = null;
|
||||
|
||||
function _getJsonpConnections(): {[key: string]: any} {
|
||||
if (_jsonpConnections === null) {
|
||||
_jsonpConnections = global[JSONP_HOME] = {};
|
||||
_jsonpConnections = (<{[key: string]: any}>global)[JSONP_HOME] = {};
|
||||
}
|
||||
return _jsonpConnections;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import {BrowserJsonp} from './browser_jsonp';
|
||||
import {makeTypeError} from 'angular2/src/facade/exceptions';
|
||||
import {StringWrapper, isPresent} from 'angular2/src/facade/lang';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import {Observer} from 'rxjs/Observer';
|
||||
|
||||
const JSONP_ERR_NO_CALLBACK = 'JSONP injected script did not invoke callback.';
|
||||
const JSONP_ERR_WRONG_METHOD = 'JSONP requests must use GET request method.';
|
||||
@ -51,7 +52,7 @@ export class JSONPConnection_ extends JSONPConnection {
|
||||
throw makeTypeError(JSONP_ERR_WRONG_METHOD);
|
||||
}
|
||||
this.request = req;
|
||||
this.response = new Observable(responseObserver => {
|
||||
this.response = new Observable((responseObserver: Observer<Response>) => {
|
||||
|
||||
this.readyState = ReadyState.Loading;
|
||||
let id = this._id = _dom.nextRequestID();
|
||||
@ -70,7 +71,7 @@ export class JSONPConnection_ extends JSONPConnection {
|
||||
|
||||
let script = this._script = _dom.build(url);
|
||||
|
||||
let onLoad = event => {
|
||||
let onLoad = (event: Event) => {
|
||||
if (this.readyState === ReadyState.Cancelled) return;
|
||||
this.readyState = ReadyState.Done;
|
||||
_dom.cleanup(script);
|
||||
@ -93,7 +94,7 @@ export class JSONPConnection_ extends JSONPConnection {
|
||||
responseObserver.complete();
|
||||
};
|
||||
|
||||
let onError = error => {
|
||||
let onError = (error: Error) => {
|
||||
if (this.readyState === ReadyState.Cancelled) return;
|
||||
this.readyState = ReadyState.Done;
|
||||
_dom.cleanup(script);
|
||||
|
@ -32,7 +32,7 @@ export class MockConnection implements Connection {
|
||||
* {@link EventEmitter} of {@link Response}. Can be subscribed to in order to be notified when a
|
||||
* response is available.
|
||||
*/
|
||||
response: any; // Subject<Response>
|
||||
response: ReplaySubject<Response>;
|
||||
|
||||
constructor(req: Request) {
|
||||
this.response = take.call(new ReplaySubject(1), 1);
|
||||
@ -131,7 +131,8 @@ export class MockBackend implements ConnectionBackend {
|
||||
* ### Example
|
||||
*
|
||||
* ```
|
||||
* import {MockBackend, Http, BaseRequestOptions} from 'angular2/http';
|
||||
* import {Http, BaseRequestOptions} from 'angular2/http';
|
||||
* import {MockBackend} from 'angular2/http/testing';
|
||||
* import {Injector} from 'angular2/core';
|
||||
*
|
||||
* it('should get a response', () => {
|
||||
@ -139,7 +140,7 @@ export class MockBackend implements ConnectionBackend {
|
||||
* var text; //this will be set from mock response
|
||||
* var injector = Injector.resolveAndCreate([
|
||||
* MockBackend,
|
||||
* provide(Http, {useFactory: (backend, options) {
|
||||
* provide(Http, {useFactory: (backend, options) => {
|
||||
* return new Http(backend, options);
|
||||
* }, deps: [MockBackend, BaseRequestOptions]}]);
|
||||
* var backend = injector.get(MockBackend);
|
||||
@ -176,7 +177,8 @@ export class MockBackend implements ConnectionBackend {
|
||||
constructor() {
|
||||
this.connectionsArray = [];
|
||||
this.connections = new Subject();
|
||||
this.connections.subscribe(connection => this.connectionsArray.push(connection));
|
||||
this.connections.subscribe((connection: MockConnection) =>
|
||||
this.connectionsArray.push(connection));
|
||||
this.pendingConnections = new Subject();
|
||||
}
|
||||
|
||||
@ -187,7 +189,7 @@ export class MockBackend implements ConnectionBackend {
|
||||
*/
|
||||
verifyNoPendingRequests() {
|
||||
let pending = 0;
|
||||
this.pendingConnections.subscribe(c => pending++);
|
||||
this.pendingConnections.subscribe((c: MockConnection) => pending++);
|
||||
if (pending > 0) throw new BaseException(`${pending} pending connections to be resolved`);
|
||||
}
|
||||
|
||||
@ -197,7 +199,7 @@ export class MockBackend implements ConnectionBackend {
|
||||
*
|
||||
* This method only exists in the mock implementation, not in real Backends.
|
||||
*/
|
||||
resolveAllConnections() { this.connections.subscribe(c => c.readyState = 4); }
|
||||
resolveAllConnections() { this.connections.subscribe((c: MockConnection) => c.readyState = 4); }
|
||||
|
||||
/**
|
||||
* Creates a new {@link MockConnection}. This is equivalent to calling `new
|
||||
@ -205,7 +207,7 @@ export class MockBackend implements ConnectionBackend {
|
||||
* emitter of this `MockBackend` instance. This method will usually only be used by tests
|
||||
* against the framework itself, not by end-users.
|
||||
*/
|
||||
createConnection(req: Request): Connection {
|
||||
createConnection(req: Request): MockConnection {
|
||||
if (!isPresent(req) || !(req instanceof Request)) {
|
||||
throw new BaseException(`createConnection requires an instance of Request, got ${req}`);
|
||||
}
|
||||
|
@ -8,7 +8,9 @@ import {Injectable} from 'angular2/core';
|
||||
import {BrowserXhr} from './browser_xhr';
|
||||
import {isPresent} from 'angular2/src/facade/lang';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import {Observer} from 'rxjs/Observer';
|
||||
import {isSuccess, getResponseURL} from '../http_utils';
|
||||
|
||||
/**
|
||||
* Creates connections using `XMLHttpRequest`. Given a fully-qualified
|
||||
* request, an `XHRConnection` will immediately create an `XMLHttpRequest` object and send the
|
||||
@ -27,7 +29,7 @@ export class XHRConnection implements Connection {
|
||||
readyState: ReadyState;
|
||||
constructor(req: Request, browserXHR: BrowserXhr, baseResponseOptions?: ResponseOptions) {
|
||||
this.request = req;
|
||||
this.response = new Observable(responseObserver => {
|
||||
this.response = new Observable((responseObserver: Observer<Response>) => {
|
||||
let _xhr: XMLHttpRequest = browserXHR.build();
|
||||
_xhr.open(RequestMethod[req.method].toUpperCase(), req.url);
|
||||
// load event handler
|
||||
@ -64,7 +66,7 @@ export class XHRConnection implements Connection {
|
||||
responseObserver.error(response);
|
||||
};
|
||||
// error event handler
|
||||
let onError = (err) => {
|
||||
let onError = (err: any) => {
|
||||
var responseOptions = new ResponseOptions({body: err, type: ResponseType.Error});
|
||||
if (isPresent(baseResponseOptions)) {
|
||||
responseOptions = baseResponseOptions.merge(responseOptions);
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||
import {
|
||||
isListLikeIterable,
|
||||
iterateListLike,
|
||||
Map,
|
||||
MapWrapper,
|
||||
StringMapWrapper,
|
||||
@ -57,8 +58,9 @@ export class Headers {
|
||||
}
|
||||
|
||||
// headers instanceof StringMap
|
||||
StringMapWrapper.forEach(
|
||||
headers, (v, k) => { this._headersMap.set(k, isListLikeIterable(v) ? v : [v]); });
|
||||
StringMapWrapper.forEach(headers, (v: any, k: string) => {
|
||||
this._headersMap.set(k, isListLikeIterable(v) ? v : [v]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,13 +112,13 @@ export class Headers {
|
||||
* Sets or overrides header value for given name.
|
||||
*/
|
||||
set(header: string, value: string | string[]): void {
|
||||
var list = [];
|
||||
var list: string[] = [];
|
||||
|
||||
if (isListLikeIterable(value)) {
|
||||
var pushValue = (<string[]>value).join(',');
|
||||
list.push(pushValue);
|
||||
} else {
|
||||
list.push(value);
|
||||
list.push(<string>value);
|
||||
}
|
||||
|
||||
this._headersMap.set(header, list);
|
||||
@ -130,7 +132,17 @@ export class Headers {
|
||||
/**
|
||||
* Returns string of all headers.
|
||||
*/
|
||||
toJSON(): string { return Json.stringify(this.values()); }
|
||||
toJSON(): {[key: string]: any} {
|
||||
let serializableHeaders = {};
|
||||
this._headersMap.forEach((values: string[], name: string) => {
|
||||
let list = [];
|
||||
|
||||
iterateListLike(values, val => list = ListWrapper.concat(list, val.split(',')));
|
||||
|
||||
serializableHeaders[name] = list;
|
||||
});
|
||||
return serializableHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of header values for a given name.
|
||||
|
@ -12,7 +12,8 @@ function httpRequest(backend: ConnectionBackend, request: Request): Observable<R
|
||||
return backend.createConnection(request).response;
|
||||
}
|
||||
|
||||
function mergeOptions(defaultOpts, providedOpts, method, url): RequestOptions {
|
||||
function mergeOptions(defaultOpts: BaseRequestOptions, providedOpts: RequestOptionsArgs,
|
||||
method: RequestMethod, url: string): RequestOptions {
|
||||
var newOptions = defaultOpts;
|
||||
if (isPresent(providedOpts)) {
|
||||
// Hack so Dart can used named parameters
|
||||
@ -104,7 +105,7 @@ export class Http {
|
||||
if (isString(url)) {
|
||||
responseObservable = httpRequest(
|
||||
this._backend,
|
||||
new Request(mergeOptions(this._defaultOptions, options, RequestMethod.Get, url)));
|
||||
new Request(mergeOptions(this._defaultOptions, options, RequestMethod.Get, <string>url)));
|
||||
} else if (url instanceof Request) {
|
||||
responseObservable = httpRequest(this._backend, url);
|
||||
} else {
|
||||
@ -183,7 +184,8 @@ export class Jsonp extends Http {
|
||||
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
|
||||
var responseObservable: any;
|
||||
if (isString(url)) {
|
||||
url = new Request(mergeOptions(this._defaultOptions, options, RequestMethod.Get, url));
|
||||
url =
|
||||
new Request(mergeOptions(this._defaultOptions, options, RequestMethod.Get, <string>url));
|
||||
}
|
||||
if (url instanceof Request) {
|
||||
if (url.method !== RequestMethod.Get) {
|
||||
|
@ -3,16 +3,18 @@ import {RequestMethod} from './enums';
|
||||
import {makeTypeError} from 'angular2/src/facade/exceptions';
|
||||
import {Response} from './static_response';
|
||||
|
||||
export function normalizeMethodName(method): RequestMethod {
|
||||
export function normalizeMethodName(method: string | RequestMethod): RequestMethod {
|
||||
if (isString(method)) {
|
||||
var originalMethod = method;
|
||||
method = method.replace(/(\w)(\w*)/g, (g0, g1, g2) => g1.toUpperCase() + g2.toLowerCase());
|
||||
method = RequestMethod[method];
|
||||
method = (<string>method)
|
||||
.replace(/(\w)(\w*)/g, (g0: string, g1: string, g2: string) =>
|
||||
g1.toUpperCase() + g2.toLowerCase());
|
||||
method = <number>(<{[key: string]: any}>RequestMethod)[method];
|
||||
if (typeof method !== 'number')
|
||||
throw makeTypeError(
|
||||
`Invalid request method. The method "${originalMethod}" is not supported.`);
|
||||
}
|
||||
return method;
|
||||
return <RequestMethod>method;
|
||||
}
|
||||
|
||||
export const isSuccess = (status: number): boolean => (status >= 200 && status < 300);
|
||||
|
@ -92,7 +92,7 @@ export class Response {
|
||||
* Attempts to return body as parsed `JSON` object, or raises an exception.
|
||||
*/
|
||||
json(): any {
|
||||
var jsonResponse;
|
||||
var jsonResponse: string | Object;
|
||||
if (isJsObject(this._body)) {
|
||||
jsonResponse = this._body;
|
||||
} else if (isString(this._body)) {
|
||||
|
@ -121,7 +121,7 @@ export class URLSearchParams {
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
var paramsList = [];
|
||||
var paramsList: string[] = [];
|
||||
this.paramsMap.forEach((values, k) => { values.forEach(v => paramsList.push(k + '=' + v)); });
|
||||
return paramsList.join('&');
|
||||
}
|
||||
|
@ -69,11 +69,11 @@ export class MockDirectiveResolver extends DirectiveResolver {
|
||||
this.viewProviderOverrides.set(type, viewBindings);
|
||||
}
|
||||
|
||||
setProvidersOverride(type: Type, bindings: any[]): void {
|
||||
this._providerOverrides.set(type, bindings);
|
||||
setProvidersOverride(type: Type, providers: any[]): void {
|
||||
this._providerOverrides.set(type, providers);
|
||||
}
|
||||
|
||||
setViewProvidersOverride(type: Type, viewBindings: any[]): void {
|
||||
this.viewProviderOverrides.set(type, viewBindings);
|
||||
setViewProvidersOverride(type: Type, viewProviders: any[]): void {
|
||||
this.viewProviderOverrides.set(type, viewProviders);
|
||||
}
|
||||
}
|
||||
|
@ -14,11 +14,12 @@ import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||
* ```
|
||||
* import {Component} from 'angular2/core';
|
||||
* import {bootstrap} from 'angular2/platform/browser';
|
||||
* import {Router, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, RouteConfig} from 'angular2/router';
|
||||
* import {Router, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, RouteConfig, RouteParams} from
|
||||
* 'angular2/router';
|
||||
*
|
||||
* @Component({directives: [ROUTER_DIRECTIVES]})
|
||||
* @RouteConfig([
|
||||
* {path: '/user/:id', component: UserCmp, as: 'UserCmp'},
|
||||
* {path: '/user/:id', component: UserCmp, name: 'UserCmp'},
|
||||
* ])
|
||||
* class AppCmp {}
|
||||
*
|
||||
@ -47,14 +48,14 @@ export class RouteParams {
|
||||
* ### Example
|
||||
*
|
||||
* ```
|
||||
* import {Component, View} from 'angular2/core';
|
||||
* import {Component} from 'angular2/core';
|
||||
* import {bootstrap} from 'angular2/platform/browser';
|
||||
* import {Router, ROUTER_DIRECTIVES, routerBindings, RouteConfig} from 'angular2/router';
|
||||
* import {Router, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, RouteConfig, RouteData} from
|
||||
* 'angular2/router';
|
||||
*
|
||||
* @Component({...})
|
||||
* @View({directives: [ROUTER_DIRECTIVES]})
|
||||
* @Component({directives: [ROUTER_DIRECTIVES]})
|
||||
* @RouteConfig([
|
||||
* {path: '/user/:id', component: UserCmp, as: 'UserCmp', data: {isAdmin: true}},
|
||||
* {path: '/user/:id', component: UserCmp, name: 'UserCmp', data: {isAdmin: true}},
|
||||
* ])
|
||||
* class AppCmp {}
|
||||
*
|
||||
@ -67,7 +68,7 @@ export class RouteParams {
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* bootstrap(AppCmp, routerBindings(AppCmp));
|
||||
* bootstrap(AppCmp, ROUTER_PROVIDERS);
|
||||
* ```
|
||||
*/
|
||||
export class RouteData {
|
||||
|
@ -5,7 +5,7 @@ import {UrlChangeListener} from './platform_location';
|
||||
/**
|
||||
* `LocationStrategy` is responsible for representing and reading route state
|
||||
* from the browser's URL. Angular provides two strategies:
|
||||
* {@link HashLocationStrategy} (default) and {@link PathLocationStrategy}.
|
||||
* {@link HashLocationStrategy} and {@link PathLocationStrategy} (default).
|
||||
*
|
||||
* This is used under the hood of the {@link Location} service.
|
||||
*
|
||||
@ -54,7 +54,6 @@ export abstract class LocationStrategy {
|
||||
*
|
||||
* bootstrap(AppCmp, [
|
||||
* ROUTER_PROVIDERS,
|
||||
* PathLocationStrategy,
|
||||
* provide(APP_BASE_HREF, {useValue: '/my/app'})
|
||||
* ]);
|
||||
* ```
|
||||
|
@ -208,15 +208,16 @@ export class PathRecognizer {
|
||||
}
|
||||
|
||||
if (isPresent(currentSegment)) {
|
||||
captured.push(currentSegment.path);
|
||||
|
||||
// the star segment consumes all of the remaining URL, including matrix params
|
||||
if (segment instanceof StarSegment) {
|
||||
positionalParams[segment.name] = currentSegment.toString();
|
||||
captured.push(currentSegment.toString());
|
||||
nextSegment = null;
|
||||
break;
|
||||
}
|
||||
|
||||
captured.push(currentSegment.path);
|
||||
|
||||
if (segment instanceof DynamicSegment) {
|
||||
positionalParams[segment.name] = currentSegment.path;
|
||||
} else if (!segment.match(currentSegment.path)) {
|
||||
|
@ -26,10 +26,10 @@ export class RouteConfig {
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* import {RouteConfig} from 'angular2/router';
|
||||
* import {RouteConfig, Route} from 'angular2/router';
|
||||
*
|
||||
* @RouteConfig([
|
||||
* {path: '/home', component: HomeCmp, name: 'HomeCmp' }
|
||||
* new Route({path: '/home', component: HomeCmp, name: 'HomeCmp' })
|
||||
* ])
|
||||
* class MyApp {}
|
||||
* ```
|
||||
@ -110,10 +110,11 @@ export class AuxRoute implements RouteDefinition {
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* import {RouteConfig} from 'angular2/router';
|
||||
* import {RouteConfig, AsyncRoute} from 'angular2/router';
|
||||
*
|
||||
* @RouteConfig([
|
||||
* {path: '/home', loader: () => Promise.resolve(MyLoadedCmp), name: 'MyLoadedCmp'}
|
||||
* new AsyncRoute({path: '/home', loader: () => Promise.resolve(MyLoadedCmp), name:
|
||||
* 'MyLoadedCmp'})
|
||||
* ])
|
||||
* class MyApp {}
|
||||
* ```
|
||||
@ -150,11 +151,11 @@ export class AsyncRoute implements RouteDefinition {
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* import {RouteConfig} from 'angular2/router';
|
||||
* import {RouteConfig, Route, Redirect} from 'angular2/router';
|
||||
*
|
||||
* @RouteConfig([
|
||||
* {path: '/', redirectTo: ['/Home'] },
|
||||
* {path: '/home', component: HomeCmp, name: 'Home'}
|
||||
* new Redirect({path: '/', redirectTo: ['/Home'] }),
|
||||
* new Route({path: '/home', component: HomeCmp, name: 'Home'})
|
||||
* ])
|
||||
* class MyApp {}
|
||||
* ```
|
||||
|
@ -44,6 +44,7 @@ export function normalizeRouteConfig(config: RouteDefinition,
|
||||
path: config.path,
|
||||
loader: wrappedLoader,
|
||||
name: config.name,
|
||||
data: config.data,
|
||||
useAsDefault: config.useAsDefault
|
||||
});
|
||||
}
|
||||
@ -66,6 +67,7 @@ export function normalizeRouteConfig(config: RouteDefinition,
|
||||
path: config.path,
|
||||
loader: componentDefinitionObject.loader,
|
||||
name: config.name,
|
||||
data: config.data,
|
||||
useAsDefault: config.useAsDefault
|
||||
});
|
||||
} else {
|
||||
|
@ -438,7 +438,7 @@ export class RootRouter extends Router {
|
||||
}
|
||||
var emitPath = instruction.toUrlPath();
|
||||
var emitQuery = instruction.toUrlQuery();
|
||||
if (emitPath.length > 0) {
|
||||
if (emitPath.length > 0 && emitPath[0] != '/') {
|
||||
emitPath = '/' + emitPath;
|
||||
}
|
||||
|
||||
@ -465,7 +465,7 @@ export class RootRouter extends Router {
|
||||
commit(instruction: Instruction, _skipLocationChange: boolean = false): Promise<any> {
|
||||
var emitPath = instruction.toUrlPath();
|
||||
var emitQuery = instruction.toUrlQuery();
|
||||
if (emitPath.length > 0) {
|
||||
if (emitPath.length > 0 && emitPath[0] != '/') {
|
||||
emitPath = '/' + emitPath;
|
||||
}
|
||||
var promise = super.commit(instruction);
|
||||
|
@ -206,7 +206,7 @@ export function serializeParams(paramMap: {[key: string]: any}): string[] {
|
||||
var params = [];
|
||||
if (isPresent(paramMap)) {
|
||||
StringMapWrapper.forEach(paramMap, (value, key) => {
|
||||
if (value == true) {
|
||||
if (value === true) {
|
||||
params.push(key);
|
||||
} else {
|
||||
params.push(key + '=' + value);
|
||||
|
@ -84,7 +84,7 @@ export interface NgMatchers extends jasmine.Matchers {
|
||||
not: NgMatchers;
|
||||
}
|
||||
|
||||
var _global: jasmine.GlobalPolluter = <any>(typeof window === 'undefined' ? global : window);
|
||||
var _global = <any>(typeof window === 'undefined' ? global : window);
|
||||
|
||||
/**
|
||||
* Jasmine matching function with Angular matchers mixed in.
|
||||
|
@ -18,7 +18,7 @@ export {inject, injectAsync} from './test_injector';
|
||||
|
||||
export {expect, NgMatchers} from './matchers';
|
||||
|
||||
var _global: jasmine.GlobalPolluter = <any>(typeof window === 'undefined' ? global : window);
|
||||
var _global = <any>(typeof window === 'undefined' ? global : window);
|
||||
|
||||
/**
|
||||
* Run a function (with an optional asynchronous callback) after each test case.
|
||||
|
@ -14,7 +14,7 @@ export {expect, NgMatchers} from './matchers';
|
||||
|
||||
export var proxy: ClassDecorator = (t) => t;
|
||||
|
||||
var _global: jasmine.GlobalPolluter = <any>(typeof window === 'undefined' ? global : window);
|
||||
var _global = <any>(typeof window === 'undefined' ? global : window);
|
||||
|
||||
export var afterEach: Function = _global.afterEach;
|
||||
|
||||
|
@ -339,7 +339,7 @@ export class UpgradeAdapter {
|
||||
(injector: angular.IInjectorService, rootScope: angular.IRootScopeService) => {
|
||||
ng1Injector = injector;
|
||||
ObservableWrapper.subscribe(ngZone.onTurnDone,
|
||||
(_) => { ngZone.run(() => rootScope.$apply()); });
|
||||
(_) => ngZone.runOutsideAngular(() => rootScope.$apply()));
|
||||
ng1compilePromise =
|
||||
UpgradeNg1ComponentAdapterBuilder.resolve(this.downgradedComponents, injector);
|
||||
}
|
||||
|
@ -361,30 +361,64 @@ export function main() {
|
||||
});
|
||||
}));
|
||||
|
||||
it('should use custom track by if function is provided',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
var template =
|
||||
`<template ngFor #item [ngForOf]="items" [ngForTrackBy]="customTrackBy" #i="index">
|
||||
describe('track by', function() {
|
||||
it('should not replace tracked items',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
var template =
|
||||
`<template ngFor #item [ngForOf]="items" [ngForTrackBy]="customTrackBy" #i="index">
|
||||
<p>{{items[i]}}</p>
|
||||
</template>`;
|
||||
tcb.overrideTemplate(TestComponent, template)
|
||||
.createAsync(TestComponent)
|
||||
.then((fixture) => {
|
||||
var buildItemList =
|
||||
() => {
|
||||
fixture.debugElement.componentInstance.items = [{'id': 'a'}];
|
||||
fixture.detectChanges();
|
||||
return fixture.debugElement.queryAll(By.css('p'))[0];
|
||||
}
|
||||
|
||||
var firstP = buildItemList();
|
||||
var finalP = buildItemList();
|
||||
expect(finalP.nativeElement).toBe(firstP.nativeElement);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
tcb.overrideTemplate(TestComponent, template)
|
||||
.createAsync(TestComponent)
|
||||
.then((fixture) => {
|
||||
var buildItemList =
|
||||
() => {
|
||||
fixture.debugElement.componentInstance.items = [{'id': 'a'}];
|
||||
fixture.detectChanges();
|
||||
return fixture.debugElement.queryAll(By.css('p'))[0];
|
||||
}
|
||||
|
||||
var firstP = buildItemList();
|
||||
var finalP = buildItemList();
|
||||
expect(finalP.nativeElement).toBe(firstP.nativeElement);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
it('should update implicit local variable on view',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
var template =
|
||||
`<div><template ngFor #item [ngForOf]="items" [ngForTrackBy]="customTrackBy">{{item['color']}}</template></div>`;
|
||||
tcb.overrideTemplate(TestComponent, template)
|
||||
.createAsync(TestComponent)
|
||||
.then((fixture) => {
|
||||
fixture.debugElement.componentInstance.items = [{'id': 'a', 'color': 'blue'}];
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('blue');
|
||||
fixture.debugElement.componentInstance.items = [{'id': 'a', 'color': 'red'}];
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('red');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
it('should move items around and keep them updated ',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
var template =
|
||||
`<div><template ngFor #item [ngForOf]="items" [ngForTrackBy]="customTrackBy">{{item['color']}}</template></div>`;
|
||||
tcb.overrideTemplate(TestComponent, template)
|
||||
.createAsync(TestComponent)
|
||||
.then((fixture) => {
|
||||
fixture.debugElement.componentInstance.items =
|
||||
[{'id': 'a', 'color': 'blue'}, {'id': 'b', 'color': 'yellow'}];
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('blueyellow');
|
||||
fixture.debugElement.componentInstance.items =
|
||||
[{'id': 'b', 'color': 'orange'}, {'id': 'a', 'color': 'red'}];
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('orangered');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
dispatchEvent,
|
||||
fakeAsync,
|
||||
tick,
|
||||
flushMicrotasks,
|
||||
expect,
|
||||
it,
|
||||
inject,
|
||||
@ -31,7 +32,8 @@ import {
|
||||
NgFor,
|
||||
NgForm,
|
||||
Validators,
|
||||
Validator
|
||||
Validator,
|
||||
RadioButtonState
|
||||
} from 'angular2/common';
|
||||
import {Provider, forwardRef, Input} from 'angular2/core';
|
||||
import {By} from 'angular2/platform/browser';
|
||||
@ -328,6 +330,33 @@ export function main() {
|
||||
});
|
||||
}));
|
||||
|
||||
it("should support <type=radio>",
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
var t = `<form [ngFormModel]="form">
|
||||
<input type="radio" ngControl="foodChicken" name="food">
|
||||
<input type="radio" ngControl="foodFish" name="food">
|
||||
</form>`;
|
||||
|
||||
tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((fixture) => {
|
||||
fixture.debugElement.componentInstance.form = new ControlGroup({
|
||||
"foodChicken": new Control(new RadioButtonState(false, 'chicken')),
|
||||
"foodFish": new Control(new RadioButtonState(true, 'fish'))
|
||||
});
|
||||
fixture.detectChanges();
|
||||
|
||||
var input = fixture.debugElement.query(By.css("input"));
|
||||
expect(input.nativeElement.checked).toEqual(false);
|
||||
|
||||
dispatchEvent(input.nativeElement, "change");
|
||||
fixture.detectChanges();
|
||||
|
||||
let value = fixture.debugElement.componentInstance.form.value;
|
||||
expect(value['foodChicken'].checked).toEqual(true);
|
||||
expect(value['foodFish'].checked).toEqual(false);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it("should support <select>",
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
var t = `<div [ngFormModel]="form">
|
||||
@ -812,9 +841,50 @@ export function main() {
|
||||
|
||||
expect(fixture.debugElement.componentInstance.name).toEqual("updatedValue");
|
||||
})));
|
||||
});
|
||||
|
||||
|
||||
it("should support <type=radio>",
|
||||
inject([TestComponentBuilder], fakeAsync((tcb: TestComponentBuilder) => {
|
||||
var t = `<form>
|
||||
<input type="radio" name="food" ngControl="chicken" [(ngModel)]="data['chicken1']">
|
||||
<input type="radio" name="food" ngControl="fish" [(ngModel)]="data['fish1']">
|
||||
</form>
|
||||
|
||||
<form>
|
||||
<input type="radio" name="food" ngControl="chicken" [(ngModel)]="data['chicken2']">
|
||||
<input type="radio" name="food" ngControl="fish" [(ngModel)]="data['fish2']">
|
||||
</form>`;
|
||||
|
||||
var fixture: ComponentFixture;
|
||||
tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((f) => { fixture = f; });
|
||||
tick();
|
||||
|
||||
fixture.debugElement.componentInstance.data = {
|
||||
'chicken1': new RadioButtonState(false, 'chicken'),
|
||||
'fish1': new RadioButtonState(true, 'fish'),
|
||||
|
||||
'chicken2': new RadioButtonState(false, 'chicken'),
|
||||
'fish2': new RadioButtonState(true, 'fish')
|
||||
};
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
var input = fixture.debugElement.query(By.css("input"));
|
||||
expect(input.nativeElement.checked).toEqual(false);
|
||||
|
||||
dispatchEvent(input.nativeElement, "change");
|
||||
tick();
|
||||
|
||||
let data = fixture.debugElement.componentInstance.data;
|
||||
|
||||
expect(data['chicken1']).toEqual(new RadioButtonState(true, 'chicken'));
|
||||
expect(data['fish1']).toEqual(new RadioButtonState(false, 'fish'));
|
||||
|
||||
expect(data['chicken2']).toEqual(new RadioButtonState(false, 'chicken'));
|
||||
expect(data['fish2']).toEqual(new RadioButtonState(true, 'fish'));
|
||||
})));
|
||||
});
|
||||
|
||||
describe("setting status classes", () => {
|
||||
it("should work with single fields",
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
@ -35,6 +35,9 @@ export function main() {
|
||||
|
||||
it("should not error on a non-empty string",
|
||||
() => { expect(Validators.required(new Control("not empty"))).toEqual(null); });
|
||||
|
||||
it("should accept zero as valid",
|
||||
() => { expect(Validators.required(new Control(0))).toEqual(null); });
|
||||
});
|
||||
|
||||
describe("minLength", () => {
|
||||
|
@ -327,6 +327,15 @@ export function main() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should locate directives in event bindings', () => {
|
||||
var dirA = CompileDirectiveMetadata.create(
|
||||
{selector: '[a]', type: new CompileTypeMetadata({name: 'DirB'})});
|
||||
|
||||
expect(humanizeTplAst(parse('<div (a)="b">', [dirA])))
|
||||
.toEqual(
|
||||
[[ElementAst, 'div'], [BoundEventAst, 'a', null, 'b'], [DirectiveAst, dirA]]);
|
||||
});
|
||||
|
||||
it('should parse directive host properties', () => {
|
||||
var dirA = CompileDirectiveMetadata.create({
|
||||
selector: 'div',
|
||||
|
@ -25,6 +25,12 @@ class ItemWithId {
|
||||
toString() { return `{id: ${this.id}}` }
|
||||
}
|
||||
|
||||
class ComplexItem {
|
||||
constructor(private id: string, private color: string) {}
|
||||
|
||||
toString() { return `{id: ${this.id}, color: ${this.color}}` }
|
||||
}
|
||||
|
||||
// todo(vicb): UnmodifiableListView / frozen object when implemented
|
||||
export function main() {
|
||||
describe('iterable differ', function() {
|
||||
@ -342,8 +348,12 @@ export function main() {
|
||||
|
||||
beforeEach(() => { differ = new DefaultIterableDiffer(trackByItemId); });
|
||||
|
||||
it('should not treat maps as new with track by function', () => {
|
||||
it('should treat the collection as dirty if identity changes', () => {
|
||||
differ.diff(buildItemList(['a']));
|
||||
expect(differ.diff(buildItemList(['a']))).toBe(differ);
|
||||
});
|
||||
|
||||
it('should treat seen records as identity changes, not additions', () => {
|
||||
let l = buildItemList(['a', 'b', 'c']);
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
@ -357,11 +367,26 @@ export function main() {
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: [`{id: a}`, `{id: b}`, `{id: c}`],
|
||||
identityChanges: [`{id: a}`, `{id: b}`, `{id: c}`],
|
||||
previous: [`{id: a}`, `{id: b}`, `{id: c}`]
|
||||
}));
|
||||
});
|
||||
|
||||
it('should track moves normally with track by function', () => {
|
||||
it('should have updated properties in identity change collection', () => {
|
||||
let l = [new ComplexItem('a', 'blue'), new ComplexItem('b', 'yellow')];
|
||||
differ.check(l);
|
||||
|
||||
l = [new ComplexItem('a', 'orange'), new ComplexItem('b', 'red')];
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: [`{id: a, color: orange}`, `{id: b, color: red}`],
|
||||
identityChanges: [`{id: a, color: orange}`, `{id: b, color: red}`],
|
||||
previous: [`{id: a, color: orange}`, `{id: b, color: red}`]
|
||||
}));
|
||||
});
|
||||
|
||||
it('should track moves normally', () => {
|
||||
let l = buildItemList(['a', 'b', 'c']);
|
||||
differ.check(l);
|
||||
|
||||
@ -370,13 +395,14 @@ export function main() {
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['{id: b}[1->0]', '{id: a}[0->1]', '{id: c}'],
|
||||
identityChanges: ['{id: b}[1->0]', '{id: a}[0->1]', '{id: c}'],
|
||||
previous: ['{id: a}[0->1]', '{id: b}[1->0]', '{id: c}'],
|
||||
moves: ['{id: b}[1->0]', '{id: a}[0->1]']
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
it('should track duplicate reinsertion normally with track by function', () => {
|
||||
it('should track duplicate reinsertion normally', () => {
|
||||
let l = buildItemList(['a', 'a']);
|
||||
differ.check(l);
|
||||
|
||||
@ -385,6 +411,7 @@ export function main() {
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['{id: b}[null->0]', '{id: a}[0->1]', '{id: a}[1->2]'],
|
||||
identityChanges: ['{id: a}[0->1]', '{id: a}[1->2]'],
|
||||
previous: ['{id: a}[0->1]', '{id: a}[1->2]'],
|
||||
moves: ['{id: a}[0->1]', '{id: a}[1->2]'],
|
||||
additions: ['{id: b}[null->0]']
|
||||
@ -392,7 +419,7 @@ export function main() {
|
||||
|
||||
});
|
||||
|
||||
it('should track removals normally with track by function', () => {
|
||||
it('should track removals normally', () => {
|
||||
let l = buildItemList(['a', 'b', 'c']);
|
||||
differ.check(l);
|
||||
|
||||
|
@ -421,6 +421,10 @@ export function main() {
|
||||
|
||||
it('should parse conditional expression',
|
||||
() => { checkInterpolation('{{ a < b ? a : b }}'); });
|
||||
|
||||
it('should parse expression with newline characters', () => {
|
||||
checkInterpolation(`{{ 'foo' +\n 'bar' +\r 'baz' }}`, `{{ "foo" + "bar" + "baz" }}`);
|
||||
});
|
||||
});
|
||||
|
||||
describe("parseSimpleBinding", () => {
|
||||
|
@ -1,11 +1,12 @@
|
||||
import {isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
export function iterableChangesAsString({collection = CONST_EXPR([]), previous = CONST_EXPR([]),
|
||||
additions = CONST_EXPR([]), moves = CONST_EXPR([]),
|
||||
removals = CONST_EXPR([])}) {
|
||||
export function iterableChangesAsString(
|
||||
{collection = CONST_EXPR([]), previous = CONST_EXPR([]), additions = CONST_EXPR([]),
|
||||
moves = CONST_EXPR([]), removals = CONST_EXPR([]), identityChanges = CONST_EXPR([])}) {
|
||||
return "collection: " + collection.join(', ') + "\n" + "previous: " + previous.join(', ') + "\n" +
|
||||
"additions: " + additions.join(', ') + "\n" + "moves: " + moves.join(', ') + "\n" +
|
||||
"removals: " + removals.join(', ') + "\n";
|
||||
"removals: " + removals.join(', ') + "\n" + "identityChanges: " +
|
||||
identityChanges.join(', ') + "\n";
|
||||
}
|
||||
|
||||
export function kvChangesAsString(
|
||||
|
@ -189,6 +189,49 @@ export function main() {
|
||||
expect(car.engine).toBeAnInstanceOf(Engine);
|
||||
});
|
||||
|
||||
it('should throw when using a factory with more than 20 dependencies', () => {
|
||||
function factoryWithTooManyArgs() { return new Car(null); }
|
||||
|
||||
var injector = createInjector([
|
||||
Engine,
|
||||
provide(Car,
|
||||
{
|
||||
useFactory: factoryWithTooManyArgs,
|
||||
deps: [
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine,
|
||||
Engine
|
||||
]
|
||||
})
|
||||
]);
|
||||
|
||||
try {
|
||||
injector.get(Car);
|
||||
throw "Must throw";
|
||||
} catch (e) {
|
||||
expect(e.message)
|
||||
.toContain(`Cannot instantiate 'Car' because it has more than 20 dependencies`);
|
||||
}
|
||||
});
|
||||
|
||||
it('should supporting provider to null', () => {
|
||||
var injector = createInjector([provide(Engine, {useValue: null})]);
|
||||
var engine = injector.get(Engine);
|
||||
|
@ -448,6 +448,21 @@ function declareTests() {
|
||||
});
|
||||
}));
|
||||
|
||||
it('should support directives where a selector matches event binding',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(
|
||||
MyComp,
|
||||
new ViewMetadata(
|
||||
{template: '<p (customEvent)="doNothing()"></p>', directives: [EventDir]}))
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var tc = fixture.debugElement.children[0];
|
||||
expect(tc.inject(EventDir)).not.toBe(null);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should read directives metadata from their binding token',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new ViewMetadata({
|
||||
@ -2133,6 +2148,13 @@ class IdDir {
|
||||
id: string;
|
||||
}
|
||||
|
||||
@Directive({selector: '[customEvent]'})
|
||||
@Injectable()
|
||||
class EventDir {
|
||||
@Output() customEvent = new EventEmitter();
|
||||
doSomething() {}
|
||||
}
|
||||
|
||||
@Directive({selector: '[static]'})
|
||||
@Injectable()
|
||||
class NeedsAttribute {
|
||||
|
@ -4,9 +4,13 @@ import {
|
||||
RegExpWrapper,
|
||||
RegExpMatcherWrapper,
|
||||
StringWrapper,
|
||||
CONST_EXPR
|
||||
CONST_EXPR,
|
||||
hasConstructor
|
||||
} from 'angular2/src/facade/lang';
|
||||
|
||||
class MySuperclass {}
|
||||
class MySubclass extends MySuperclass {}
|
||||
|
||||
export function main() {
|
||||
describe('RegExp', () => {
|
||||
it('should expose the index for each match', () => {
|
||||
@ -119,5 +123,13 @@ export function main() {
|
||||
expect(StringWrapper.stripRight(null, "S")).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasConstructor', () => {
|
||||
it("should be true when the type matches",
|
||||
() => { expect(hasConstructor(new MySuperclass(), MySuperclass)).toEqual(true); });
|
||||
|
||||
it("should be false for subtypes",
|
||||
() => { expect(hasConstructor(new MySubclass(), MySuperclass)).toEqual(false); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -29,8 +29,8 @@ import {RequestOptions, BaseRequestOptions} from 'angular2/src/http/base_request
|
||||
import {BaseResponseOptions, ResponseOptions} from 'angular2/src/http/base_response_options';
|
||||
import {ResponseType, ReadyState, RequestMethod} from 'angular2/src/http/enums';
|
||||
|
||||
var addEventListenerSpy;
|
||||
var existingScripts = [];
|
||||
var addEventListenerSpy: any;
|
||||
var existingScripts: MockBrowserJsonp[] = [];
|
||||
var unused: Response;
|
||||
|
||||
class MockBrowserJsonp extends BrowserJsonp {
|
||||
@ -67,8 +67,8 @@ class MockBrowserJsonp extends BrowserJsonp {
|
||||
|
||||
export function main() {
|
||||
describe('JSONPBackend', () => {
|
||||
let backend;
|
||||
let sampleRequest;
|
||||
let backend: JSONPBackend_;
|
||||
let sampleRequest: Request;
|
||||
|
||||
beforeEach(() => {
|
||||
let injector = Injector.resolveAndCreate([
|
||||
@ -84,7 +84,7 @@ export function main() {
|
||||
afterEach(() => { existingScripts = []; });
|
||||
|
||||
it('should create a connection', () => {
|
||||
var instance;
|
||||
var instance: JSONPConnection;
|
||||
expect(() => instance = backend.createConnection(sampleRequest)).not.toThrow();
|
||||
expect(instance).toBeAnInstanceOf(JSONPConnection);
|
||||
});
|
||||
@ -92,7 +92,7 @@ export function main() {
|
||||
|
||||
describe('JSONPConnection', () => {
|
||||
it('should use the injected BaseResponseOptions to create the response',
|
||||
inject([AsyncTestCompleter], async => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let connection = new JSONPConnection_(sampleRequest, new MockBrowserJsonp(),
|
||||
new ResponseOptions({type: ResponseType.Error}));
|
||||
connection.response.subscribe(res => {
|
||||
@ -103,7 +103,8 @@ export function main() {
|
||||
existingScripts[0].dispatchEvent('load');
|
||||
}));
|
||||
|
||||
it('should ignore load/callback when disposed', inject([AsyncTestCompleter], async => {
|
||||
it('should ignore load/callback when disposed',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var connection = new JSONPConnection_(sampleRequest, new MockBrowserJsonp());
|
||||
let spy = new SpyObject();
|
||||
let loadSpy = spy.spy('load');
|
||||
@ -126,7 +127,7 @@ export function main() {
|
||||
}));
|
||||
|
||||
it('should report error if loaded without invoking callback',
|
||||
inject([AsyncTestCompleter], async => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let connection = new JSONPConnection_(sampleRequest, new MockBrowserJsonp());
|
||||
connection.response.subscribe(
|
||||
res => {
|
||||
@ -141,7 +142,8 @@ export function main() {
|
||||
existingScripts[0].dispatchEvent('load');
|
||||
}));
|
||||
|
||||
it('should report error if script contains error', inject([AsyncTestCompleter], async => {
|
||||
it('should report error if script contains error',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let connection = new JSONPConnection_(sampleRequest, new MockBrowserJsonp());
|
||||
|
||||
connection.response.subscribe(
|
||||
@ -169,7 +171,8 @@ export function main() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should respond with data passed to callback', inject([AsyncTestCompleter], async => {
|
||||
it('should respond with data passed to callback',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let connection = new JSONPConnection_(sampleRequest, new MockBrowserJsonp());
|
||||
|
||||
connection.response.subscribe(res => {
|
||||
|
@ -22,16 +22,16 @@ import {Map} from 'angular2/src/facade/collection';
|
||||
import {RequestOptions, BaseRequestOptions} from 'angular2/src/http/base_request_options';
|
||||
import {BaseResponseOptions, ResponseOptions} from 'angular2/src/http/base_response_options';
|
||||
import {ResponseType} from 'angular2/src/http/enums';
|
||||
import {ReplaySubject} from 'rxjs/subject/ReplaySubject';
|
||||
|
||||
export function main() {
|
||||
describe('MockBackend', () => {
|
||||
|
||||
var backend;
|
||||
var sampleRequest1;
|
||||
var sampleResponse1;
|
||||
var sampleRequest2;
|
||||
var sampleResponse2;
|
||||
var connection;
|
||||
var backend: MockBackend;
|
||||
var sampleRequest1: Request;
|
||||
var sampleResponse1: Response;
|
||||
var sampleRequest2: Request;
|
||||
var sampleResponse2: Response;
|
||||
|
||||
beforeEach(() => {
|
||||
var injector = Injector.resolveAndCreate(
|
||||
@ -50,47 +50,50 @@ export function main() {
|
||||
() => {expect(backend.createConnection(sampleRequest1)).toBeAnInstanceOf(MockConnection)});
|
||||
|
||||
it('should create a new connection and allow subscription', () => {
|
||||
let connection = backend.createConnection(sampleRequest1);
|
||||
let connection: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection.response.subscribe(() => {});
|
||||
});
|
||||
|
||||
it('should allow responding after subscription', inject([AsyncTestCompleter], async => {
|
||||
let connection = backend.createConnection(sampleRequest1);
|
||||
connection.response.subscribe((res) => { async.done(); });
|
||||
it('should allow responding after subscription',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let connection: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection.response.subscribe(() => { async.done(); });
|
||||
connection.mockRespond(sampleResponse1);
|
||||
}));
|
||||
|
||||
it('should allow subscribing after responding', inject([AsyncTestCompleter], async => {
|
||||
let connection = backend.createConnection(sampleRequest1);
|
||||
it('should allow subscribing after responding',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let connection: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection.mockRespond(sampleResponse1);
|
||||
connection.response.subscribe((res) => { async.done(); });
|
||||
connection.response.subscribe(() => { async.done(); });
|
||||
}));
|
||||
|
||||
it('should allow responding after subscription with an error',
|
||||
inject([AsyncTestCompleter], async => {
|
||||
let connection = backend.createConnection(sampleRequest1);
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let connection: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection.response.subscribe(null, () => { async.done(); });
|
||||
connection.mockError(new Error('nope'));
|
||||
}));
|
||||
|
||||
it('should not throw when there are no unresolved requests',
|
||||
inject([AsyncTestCompleter], async => {
|
||||
let connection = backend.createConnection(sampleRequest1);
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let connection: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection.response.subscribe(() => { async.done(); });
|
||||
connection.mockRespond(sampleResponse1);
|
||||
backend.verifyNoPendingRequests();
|
||||
}));
|
||||
|
||||
xit('should throw when there are unresolved requests', inject([AsyncTestCompleter], async => {
|
||||
let connection = backend.createConnection(sampleRequest1);
|
||||
xit('should throw when there are unresolved requests',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let connection: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection.response.subscribe(() => { async.done(); });
|
||||
backend.verifyNoPendingRequests();
|
||||
}));
|
||||
|
||||
it('should work when requests are resolved out of order',
|
||||
inject([AsyncTestCompleter], async => {
|
||||
let connection1 = backend.createConnection(sampleRequest1);
|
||||
let connection2 = backend.createConnection(sampleRequest1);
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let connection1: MockConnection = backend.createConnection(sampleRequest1);
|
||||
let connection2: MockConnection = backend.createConnection(sampleRequest1);
|
||||
connection1.response.subscribe(() => { async.done(); });
|
||||
connection2.response.subscribe(() => {});
|
||||
connection2.mockRespond(sampleResponse1);
|
||||
@ -98,10 +101,12 @@ export function main() {
|
||||
backend.verifyNoPendingRequests();
|
||||
}));
|
||||
|
||||
xit('should allow double subscribing', inject([AsyncTestCompleter], async => {
|
||||
let responses = [sampleResponse1, sampleResponse2];
|
||||
backend.connections.subscribe(c => c.mockRespond(responses.shift()));
|
||||
let responseObservable = backend.createConnection(sampleRequest1).response;
|
||||
xit('should allow double subscribing',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
let responses: Response[] = [sampleResponse1, sampleResponse2];
|
||||
backend.connections.subscribe((c: MockConnection) => c.mockRespond(responses.shift()));
|
||||
let responseObservable: ReplaySubject<Response> =
|
||||
backend.createConnection(sampleRequest1).response;
|
||||
responseObservable.subscribe(res => expect(res.text()).toBe('response1'));
|
||||
responseObservable.subscribe(res => expect(res.text()).toBe('response2'), null,
|
||||
async.done);
|
||||
|
@ -23,12 +23,12 @@ import {RequestOptions, BaseRequestOptions} from 'angular2/src/http/base_request
|
||||
import {BaseResponseOptions, ResponseOptions} from 'angular2/src/http/base_response_options';
|
||||
import {ResponseType} from 'angular2/src/http/enums';
|
||||
|
||||
var abortSpy;
|
||||
var sendSpy;
|
||||
var openSpy;
|
||||
var setRequestHeaderSpy;
|
||||
var addEventListenerSpy;
|
||||
var existingXHRs = [];
|
||||
var abortSpy: any;
|
||||
var sendSpy: any;
|
||||
var openSpy: any;
|
||||
var setRequestHeaderSpy: any;
|
||||
var addEventListenerSpy: any;
|
||||
var existingXHRs: MockBrowserXHR[] = [];
|
||||
var unused: Response;
|
||||
|
||||
class MockBrowserXHR extends BrowserXhr {
|
||||
@ -51,19 +51,21 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
this.setRequestHeader = setRequestHeaderSpy = spy.spy('setRequestHeader');
|
||||
}
|
||||
|
||||
setStatusCode(status) { this.status = status; }
|
||||
setStatusCode(status: number) { this.status = status; }
|
||||
|
||||
setResponse(value) { this.response = value; }
|
||||
setResponse(value: string) { this.response = value; }
|
||||
|
||||
setResponseText(value) { this.responseText = value; }
|
||||
setResponseText(value: string) { this.responseText = value; }
|
||||
|
||||
setResponseURL(value) { this.responseURL = value; }
|
||||
setResponseURL(value: string) { this.responseURL = value; }
|
||||
|
||||
setResponseHeaders(value) { this.responseHeaders = value; }
|
||||
setResponseHeaders(value: string) { this.responseHeaders = value; }
|
||||
|
||||
getAllResponseHeaders() { return this.responseHeaders || ''; }
|
||||
|
||||
getResponseHeader(key) { return Headers.fromResponseHeaderString(this.responseHeaders).get(key); }
|
||||
getResponseHeader(key: string) {
|
||||
return Headers.fromResponseHeaderString(this.responseHeaders).get(key);
|
||||
}
|
||||
|
||||
addEventListener(type: string, cb: Function) { this.callbacks.set(type, cb); }
|
||||
|
||||
@ -80,8 +82,8 @@ class MockBrowserXHR extends BrowserXhr {
|
||||
|
||||
export function main() {
|
||||
describe('XHRBackend', () => {
|
||||
var backend;
|
||||
var sampleRequest;
|
||||
var backend: XHRBackend;
|
||||
var sampleRequest: Request;
|
||||
|
||||
beforeEach(() => {
|
||||
var injector = Injector.resolveAndCreate([
|
||||
@ -102,10 +104,10 @@ export function main() {
|
||||
|
||||
describe('XHRConnection', () => {
|
||||
it('should use the injected BaseResponseOptions to create the response',
|
||||
inject([AsyncTestCompleter], async => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({type: ResponseType.Error}));
|
||||
connection.response.subscribe(res => {
|
||||
connection.response.subscribe((res: Response) => {
|
||||
expect(res.type).toBe(ResponseType.Error);
|
||||
async.done();
|
||||
});
|
||||
@ -113,11 +115,12 @@ export function main() {
|
||||
existingXHRs[0].dispatchEvent('load');
|
||||
}));
|
||||
|
||||
it('should complete a request', inject([AsyncTestCompleter], async => {
|
||||
it('should complete a request', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({type: ResponseType.Error}));
|
||||
connection.response.subscribe(res => { expect(res.type).toBe(ResponseType.Error); },
|
||||
null, () => { async.done(); });
|
||||
connection.response.subscribe((res: Response) => {
|
||||
expect(res.type).toBe(ResponseType.Error);
|
||||
}, null, () => { async.done(); });
|
||||
existingXHRs[0].setStatusCode(200);
|
||||
existingXHRs[0].dispatchEvent('load');
|
||||
}));
|
||||
@ -129,10 +132,11 @@ export function main() {
|
||||
expect(abortSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should create an error Response on error', inject([AsyncTestCompleter], async => {
|
||||
it('should create an error Response on error',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({type: ResponseType.Error}));
|
||||
connection.response.subscribe(null, res => {
|
||||
connection.response.subscribe(null, (res: Response) => {
|
||||
expect(res.type).toBe(ResponseType.Error);
|
||||
async.done();
|
||||
});
|
||||
@ -170,13 +174,14 @@ export function main() {
|
||||
expect(setRequestHeaderSpy).toHaveBeenCalledWith('X-Multi', 'a,b');
|
||||
});
|
||||
|
||||
it('should return the correct status code', inject([AsyncTestCompleter], async => {
|
||||
it('should return the correct status code',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var statusCode = 418;
|
||||
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({status: statusCode}));
|
||||
|
||||
connection.response.subscribe(
|
||||
res => {
|
||||
(res: Response) => {
|
||||
|
||||
},
|
||||
errRes => {
|
||||
@ -188,7 +193,8 @@ export function main() {
|
||||
existingXHRs[0].dispatchEvent('load');
|
||||
}));
|
||||
|
||||
it('should call next and complete on 200 codes', inject([AsyncTestCompleter], async => {
|
||||
it('should call next and complete on 200 codes',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var nextCalled = false;
|
||||
var errorCalled = false;
|
||||
var statusCode = 200;
|
||||
@ -196,7 +202,7 @@ export function main() {
|
||||
new ResponseOptions({status: statusCode}));
|
||||
|
||||
connection.response.subscribe(
|
||||
res => {
|
||||
(res: Response) => {
|
||||
nextCalled = true;
|
||||
expect(res.status).toBe(statusCode);
|
||||
},
|
||||
@ -210,14 +216,15 @@ export function main() {
|
||||
existingXHRs[0].dispatchEvent('load');
|
||||
}));
|
||||
|
||||
it('should call error and not complete on 300+ codes', inject([AsyncTestCompleter], async => {
|
||||
it('should call error and not complete on 300+ codes',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var nextCalled = false;
|
||||
var errorCalled = false;
|
||||
var statusCode = 301;
|
||||
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({status: statusCode}));
|
||||
|
||||
connection.response.subscribe(res => { nextCalled = true; }, errRes => {
|
||||
connection.response.subscribe((res: Response) => { nextCalled = true; }, errRes => {
|
||||
expect(errRes.status).toBe(statusCode);
|
||||
expect(nextCalled).toBe(false);
|
||||
async.done();
|
||||
@ -226,13 +233,14 @@ export function main() {
|
||||
existingXHRs[0].setStatusCode(statusCode);
|
||||
existingXHRs[0].dispatchEvent('load');
|
||||
}));
|
||||
it('should normalize IE\'s 1223 status code into 204', inject([AsyncTestCompleter], async => {
|
||||
it('should normalize IE\'s 1223 status code into 204',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var statusCode = 1223;
|
||||
var normalizedCode = 204;
|
||||
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({status: statusCode}));
|
||||
|
||||
connection.response.subscribe(res => {
|
||||
connection.response.subscribe((res: Response) => {
|
||||
expect(res.status).toBe(normalizedCode);
|
||||
async.done();
|
||||
});
|
||||
@ -241,7 +249,8 @@ export function main() {
|
||||
existingXHRs[0].dispatchEvent('load');
|
||||
}));
|
||||
|
||||
it('should normalize responseText and response', inject([AsyncTestCompleter], async => {
|
||||
it('should normalize responseText and response',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var responseBody = 'Doge';
|
||||
|
||||
var connection1 =
|
||||
@ -250,7 +259,7 @@ export function main() {
|
||||
var connection2 =
|
||||
new XHRConnection(sampleRequest, new MockBrowserXHR(), new ResponseOptions());
|
||||
|
||||
connection1.response.subscribe(res => {
|
||||
connection1.response.subscribe((res: Response) => {
|
||||
expect(res.text()).toBe(responseBody);
|
||||
|
||||
connection2.response.subscribe(ress => {
|
||||
@ -267,7 +276,7 @@ export function main() {
|
||||
}));
|
||||
|
||||
it('should parse response headers and add them to the response',
|
||||
inject([AsyncTestCompleter], async => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var statusCode = 200;
|
||||
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({status: statusCode}));
|
||||
@ -278,7 +287,7 @@ export function main() {
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive`
|
||||
|
||||
connection.response.subscribe(res => {
|
||||
connection.response.subscribe((res: Response) => {
|
||||
expect(res.headers.get('Date')).toEqual('Fri, 20 Nov 2015 01:45:26 GMT');
|
||||
expect(res.headers.get('Content-Type')).toEqual('application/json; charset=utf-8');
|
||||
expect(res.headers.get('Transfer-Encoding')).toEqual('chunked');
|
||||
@ -291,12 +300,13 @@ export function main() {
|
||||
existingXHRs[0].dispatchEvent('load');
|
||||
}));
|
||||
|
||||
it('should add the responseURL to the response', inject([AsyncTestCompleter], async => {
|
||||
it('should add the responseURL to the response',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var statusCode = 200;
|
||||
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({status: statusCode}));
|
||||
|
||||
connection.response.subscribe(res => {
|
||||
connection.response.subscribe((res: Response) => {
|
||||
expect(res.url).toEqual('http://google.com');
|
||||
async.done();
|
||||
});
|
||||
@ -307,14 +317,14 @@ export function main() {
|
||||
}));
|
||||
|
||||
it('should add use the X-Request-URL in CORS situations',
|
||||
inject([AsyncTestCompleter], async => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var statusCode = 200;
|
||||
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
|
||||
new ResponseOptions({status: statusCode}));
|
||||
var responseHeaders = `X-Request-URL: http://somedomain.com
|
||||
Foo: Bar`
|
||||
|
||||
connection.response.subscribe(res => {
|
||||
connection.response.subscribe((res: Response) => {
|
||||
expect(res.url).toEqual('http://somedomain.com');
|
||||
async.done();
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {Headers} from 'angular2/src/http/headers';
|
||||
import {Json} from 'angular2/src/facade/lang';
|
||||
import {Map, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
@ -62,6 +63,42 @@ export function main() {
|
||||
expect(/bar, ?baz/g.test(headers.getAll('foo')[0])).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('.toJSON()', () => {
|
||||
let headers = null;
|
||||
let inputArr = null;
|
||||
let obj = null;
|
||||
|
||||
beforeEach(() => {
|
||||
headers = new Headers();
|
||||
inputArr = ['application/jeisen', 'application/jason', 'application/patrickjs'];
|
||||
obj = {'Accept': inputArr};
|
||||
headers.set('Accept', inputArr);
|
||||
});
|
||||
|
||||
|
||||
it('should be serializable with toJSON', () => {
|
||||
let stringifed = Json.stringify(obj);
|
||||
let serializedHeaders = Json.stringify(headers);
|
||||
expect(serializedHeaders).toEqual(stringifed);
|
||||
});
|
||||
|
||||
|
||||
it('should be able to parse serialized header', () => {
|
||||
let stringifed = Json.stringify(obj);
|
||||
let serializedHeaders = Json.stringify(headers);
|
||||
expect(Json.parse(serializedHeaders)).toEqual(Json.parse(stringifed));
|
||||
});
|
||||
|
||||
|
||||
it('should be able to recreate serializedHeaders', () => {
|
||||
let serializedHeaders = Json.stringify(headers);
|
||||
let parsedHeaders = Json.parse(serializedHeaders);
|
||||
let recreatedHeaders = new Headers(parsedHeaders);
|
||||
expect(Json.stringify(parsedHeaders)).toEqual(Json.stringify(recreatedHeaders));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.fromResponseHeaderString()', () => {
|
||||
|
@ -42,7 +42,7 @@ export function main() {
|
||||
var jsonp: Jsonp;
|
||||
|
||||
it('should allow using jsonpInjectables and httpInjectables in same injector',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
parentInjector = Injector.resolveAndCreate([
|
||||
provide(XHRBackend, {useClass: MockBackend}),
|
||||
provide(JSONPBackend, {useClass: MockBackend})
|
||||
@ -91,7 +91,7 @@ export function main() {
|
||||
var http: Http;
|
||||
var injector: Injector;
|
||||
var backend: MockBackend;
|
||||
var baseResponse;
|
||||
var baseResponse: Response;
|
||||
var jsonp: Jsonp;
|
||||
beforeEach(() => {
|
||||
injector = Injector.resolveAndCreate([
|
||||
@ -129,19 +129,19 @@ export function main() {
|
||||
|
||||
|
||||
it('should accept a fully-qualified request as its only parameter',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
backend.connections.subscribe(c => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.url).toBe('https://google.com');
|
||||
c.mockRespond(new Response(new ResponseOptions({body: 'Thank you'})));
|
||||
async.done();
|
||||
});
|
||||
http.request(new Request(new RequestOptions({url: 'https://google.com'})))
|
||||
.subscribe((res) => {});
|
||||
.subscribe((res: Response) => {});
|
||||
}));
|
||||
|
||||
it('should accept a fully-qualified request as its only parameter',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
backend.connections.subscribe(c => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.url).toBe('https://google.com');
|
||||
expect(c.request.method).toBe(RequestMethod.Post);
|
||||
c.mockRespond(new Response(new ResponseOptions({body: 'Thank you'})));
|
||||
@ -149,64 +149,64 @@ export function main() {
|
||||
});
|
||||
http.request(new Request(new RequestOptions(
|
||||
{url: 'https://google.com', method: RequestMethod.Post})))
|
||||
.subscribe((res) => {});
|
||||
.subscribe((res: Response) => {});
|
||||
}));
|
||||
|
||||
|
||||
it('should perform a get request for given url if only passed a string',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
backend.connections.subscribe(c => c.mockRespond(baseResponse));
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));
|
||||
http.request('http://basic.connection')
|
||||
.subscribe(res => {
|
||||
.subscribe((res: Response) => {
|
||||
expect(res.text()).toBe('base response');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should perform a post request for given url if options include a method',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
backend.connections.subscribe(c => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.method).toEqual(RequestMethod.Post);
|
||||
c.mockRespond(baseResponse);
|
||||
});
|
||||
let requestOptions = new RequestOptions({method: RequestMethod.Post});
|
||||
http.request('http://basic.connection', requestOptions)
|
||||
.subscribe(res => {
|
||||
.subscribe((res: Response) => {
|
||||
expect(res.text()).toBe('base response');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should perform a post request for given url if options include a method',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
backend.connections.subscribe(c => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.method).toEqual(RequestMethod.Post);
|
||||
c.mockRespond(baseResponse);
|
||||
});
|
||||
let requestOptions = {method: RequestMethod.Post};
|
||||
http.request('http://basic.connection', requestOptions)
|
||||
.subscribe(res => {
|
||||
.subscribe((res: Response) => {
|
||||
expect(res.text()).toBe('base response');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should perform a get request and complete the response',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
backend.connections.subscribe(c => c.mockRespond(baseResponse));
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));
|
||||
http.request('http://basic.connection')
|
||||
.subscribe(res => { expect(res.text()).toBe('base response'); }, null,
|
||||
.subscribe((res: Response) => { expect(res.text()).toBe('base response'); }, null,
|
||||
() => { async.done(); });
|
||||
}));
|
||||
|
||||
it('should perform multiple get requests and complete the responses',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
backend.connections.subscribe(c => c.mockRespond(baseResponse));
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));
|
||||
|
||||
http.request('http://basic.connection')
|
||||
.subscribe(res => { expect(res.text()).toBe('base response'); });
|
||||
.subscribe((res: Response) => { expect(res.text()).toBe('base response'); });
|
||||
http.request('http://basic.connection')
|
||||
.subscribe(res => { expect(res.text()).toBe('base response'); }, null,
|
||||
.subscribe((res: Response) => { expect(res.text()).toBe('base response'); }, null,
|
||||
() => { async.done(); });
|
||||
}));
|
||||
|
||||
@ -219,149 +219,160 @@ export function main() {
|
||||
|
||||
|
||||
describe('.get()', () => {
|
||||
it('should perform a get request for given url', inject([AsyncTestCompleter], async => {
|
||||
backend.connections.subscribe(c => {
|
||||
it('should perform a get request for given url',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.method).toBe(RequestMethod.Get);
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.get(url).subscribe(res => {});
|
||||
http.get(url).subscribe((res: Response) => {});
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe('.post()', () => {
|
||||
it('should perform a post request for given url', inject([AsyncTestCompleter], async => {
|
||||
backend.connections.subscribe(c => {
|
||||
it('should perform a post request for given url',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.method).toBe(RequestMethod.Post);
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.post(url, 'post me').subscribe(res => {});
|
||||
http.post(url, 'post me').subscribe((res: Response) => {});
|
||||
}));
|
||||
|
||||
|
||||
it('should attach the provided body to the request', inject([AsyncTestCompleter], async => {
|
||||
it('should attach the provided body to the request',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var body = 'this is my post body';
|
||||
backend.connections.subscribe(c => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.text()).toBe(body);
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.post(url, body).subscribe(res => {});
|
||||
http.post(url, body).subscribe((res: Response) => {});
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe('.put()', () => {
|
||||
it('should perform a put request for given url', inject([AsyncTestCompleter], async => {
|
||||
backend.connections.subscribe(c => {
|
||||
it('should perform a put request for given url',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.method).toBe(RequestMethod.Put);
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.put(url, 'put me').subscribe(res => {});
|
||||
http.put(url, 'put me').subscribe((res: Response) => {});
|
||||
}));
|
||||
|
||||
it('should attach the provided body to the request', inject([AsyncTestCompleter], async => {
|
||||
it('should attach the provided body to the request',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var body = 'this is my put body';
|
||||
backend.connections.subscribe(c => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.text()).toBe(body);
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.put(url, body).subscribe(res => {});
|
||||
http.put(url, body).subscribe((res: Response) => {});
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe('.delete()', () => {
|
||||
it('should perform a delete request for given url', inject([AsyncTestCompleter], async => {
|
||||
backend.connections.subscribe(c => {
|
||||
it('should perform a delete request for given url',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.method).toBe(RequestMethod.Delete);
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.delete(url).subscribe(res => {});
|
||||
http.delete(url).subscribe((res: Response) => {});
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe('.patch()', () => {
|
||||
it('should perform a patch request for given url', inject([AsyncTestCompleter], async => {
|
||||
backend.connections.subscribe(c => {
|
||||
it('should perform a patch request for given url',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.method).toBe(RequestMethod.Patch);
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.patch(url, 'this is my patch body').subscribe(res => {});
|
||||
http.patch(url, 'this is my patch body').subscribe((res: Response) => {});
|
||||
}));
|
||||
|
||||
it('should attach the provided body to the request', inject([AsyncTestCompleter], async => {
|
||||
it('should attach the provided body to the request',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var body = 'this is my patch body';
|
||||
backend.connections.subscribe(c => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.text()).toBe(body);
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.patch(url, body).subscribe(res => {});
|
||||
http.patch(url, body).subscribe((res: Response) => {});
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe('.head()', () => {
|
||||
it('should perform a head request for given url', inject([AsyncTestCompleter], async => {
|
||||
backend.connections.subscribe(c => {
|
||||
it('should perform a head request for given url',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.method).toBe(RequestMethod.Head);
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.head(url).subscribe(res => {});
|
||||
http.head(url).subscribe((res: Response) => {});
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe('searchParams', () => {
|
||||
it('should append search params to url', inject([AsyncTestCompleter], async => {
|
||||
it('should append search params to url',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var params = new URLSearchParams();
|
||||
params.append('q', 'puppies');
|
||||
backend.connections.subscribe(c => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.url).toEqual('https://www.google.com?q=puppies');
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.get('https://www.google.com', new RequestOptions({search: params}))
|
||||
.subscribe(res => {});
|
||||
.subscribe((res: Response) => {});
|
||||
}));
|
||||
|
||||
|
||||
it('should append string search params to url', inject([AsyncTestCompleter], async => {
|
||||
backend.connections.subscribe(c => {
|
||||
it('should append string search params to url',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.url).toEqual('https://www.google.com?q=piggies');
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.get('https://www.google.com', new RequestOptions({search: 'q=piggies'}))
|
||||
.subscribe(res => {});
|
||||
.subscribe((res: Response) => {});
|
||||
}));
|
||||
|
||||
|
||||
it('should produce valid url when url already contains a query',
|
||||
inject([AsyncTestCompleter], async => {
|
||||
backend.connections.subscribe(c => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.url).toEqual('https://www.google.com?q=angular&as_eq=1.x');
|
||||
backend.resolveAllConnections();
|
||||
async.done();
|
||||
});
|
||||
http.get('https://www.google.com?q=angular', new RequestOptions({search: 'as_eq=1.x'}))
|
||||
.subscribe(res => {});
|
||||
.subscribe((res: Response) => {});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('string method names', () => {
|
||||
it('should allow case insensitive strings for method names', () => {
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
backend.connections.subscribe(c => {
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
backend.connections.subscribe((c: MockConnection) => {
|
||||
expect(c.request.method)
|
||||
.toBe(RequestMethod.Post)
|
||||
c.mockRespond(new Response(new ResponseOptions({body: 'Thank you'})));
|
||||
@ -369,7 +380,7 @@ export function main() {
|
||||
});
|
||||
http.request(
|
||||
new Request(new RequestOptions({url: 'https://google.com', method: 'PosT'})))
|
||||
.subscribe((res) => {});
|
||||
.subscribe((res: Response) => {});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -51,6 +51,7 @@ var NG_COMMON = [
|
||||
'AbstractControl.validator',
|
||||
'AbstractControl.validator=',
|
||||
'AbstractControl.value',
|
||||
'AbstractControl.root',
|
||||
'AbstractControl.valueChanges',
|
||||
'AbstractControlDirective',
|
||||
'AbstractControlDirective.control',
|
||||
@ -102,6 +103,7 @@ var NG_COMMON = [
|
||||
'Control.validator',
|
||||
'Control.validator=',
|
||||
'Control.value',
|
||||
'Control.root',
|
||||
'Control.valueChanges',
|
||||
'ControlArray',
|
||||
'ControlArray.asyncValidator',
|
||||
@ -134,6 +136,7 @@ var NG_COMMON = [
|
||||
'ControlArray.validator',
|
||||
'ControlArray.validator=',
|
||||
'ControlArray.value',
|
||||
'ControlArray.root',
|
||||
'ControlArray.valueChanges',
|
||||
'ControlContainer',
|
||||
'ControlContainer.control',
|
||||
@ -179,6 +182,7 @@ var NG_COMMON = [
|
||||
'ControlGroup.validator',
|
||||
'ControlGroup.validator=',
|
||||
'ControlGroup.value',
|
||||
'ControlGroup.root',
|
||||
'ControlGroup.valueChanges',
|
||||
'ControlValueAccessor:dart',
|
||||
'CurrencyPipe',
|
||||
@ -415,6 +419,7 @@ var NG_COMMON = [
|
||||
'ObservableListDiff.forEachMovedItem():dart',
|
||||
'ObservableListDiff.forEachPreviousItem():dart',
|
||||
'ObservableListDiff.forEachRemovedItem():dart',
|
||||
'ObservableListDiff.forEachIdentityChange():dart',
|
||||
'ObservableListDiff.isDirty:dart',
|
||||
'ObservableListDiff.length:dart',
|
||||
'ObservableListDiff.onDestroy():dart',
|
||||
@ -447,7 +452,12 @@ var NG_COMMON = [
|
||||
'Validators#maxLength()',
|
||||
'Validators#minLength()',
|
||||
'Validators#nullValidator()',
|
||||
'Validators#required()'
|
||||
'Validators#required()',
|
||||
'RadioButtonState',
|
||||
'RadioButtonState.checked',
|
||||
'RadioButtonState.checked=',
|
||||
'RadioButtonState.value',
|
||||
'RadioButtonState.value='
|
||||
];
|
||||
|
||||
var NG_COMPILER = [
|
||||
|
@ -105,6 +105,20 @@ export function main() {
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate to child routes when the root component has an empty path',
|
||||
inject([AsyncTestCompleter, Location], (async, location) => {
|
||||
compile(tcb, 'outer { <router-outlet></router-outlet> }')
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([new Route({path: '/...', component: ParentCmp})]))
|
||||
.then((_) => rtr.navigateByUrl('/b'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('outer { inner { hello } }');
|
||||
expect(location.urlChanges).toEqual(['/b']);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should navigate to child routes of async routes', inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, 'outer { <router-outlet></router-outlet> }')
|
||||
.then((rtc) => {fixture = rtc})
|
||||
|
@ -90,5 +90,14 @@ export function main() {
|
||||
expect(match['allParams']).toEqual({'c': '3'});
|
||||
});
|
||||
});
|
||||
|
||||
describe('wildcard segment', () => {
|
||||
it('should return a url path which matches the original url path', () => {
|
||||
var rec = new PathRecognizer('/wild/*everything');
|
||||
var url = parser.parse('/wild/super;variable=value/anotherPartAfterSlash');
|
||||
var match = rec.recognize(url);
|
||||
expect(match['urlPath']).toEqual('wild/super;variable=value/anotherPartAfterSlash');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -220,6 +220,15 @@ export function main() {
|
||||
expect(path).toEqual('hi/how/are/you?name=brad');
|
||||
});
|
||||
|
||||
it('should preserve the number 1 as a query string value', () => {
|
||||
router.config(
|
||||
[new Route({path: '/hi/how/are/you', component: DummyComponent, name: 'GreetingUrl'})]);
|
||||
|
||||
var instruction = router.generate(['/GreetingUrl', {'name': 1}]);
|
||||
var path = stringifyInstruction(instruction);
|
||||
expect(path).toEqual('hi/how/are/you?name=1');
|
||||
});
|
||||
|
||||
it('should serialize parameters that are not part of the route definition as query string params',
|
||||
() => {
|
||||
router.config([
|
||||
|
@ -1,30 +1,33 @@
|
||||
{
|
||||
"version": "v4",
|
||||
"repo": "angular/DefinitelyTyped",
|
||||
"repo": "DefinitelyTyped/DefinitelyTyped",
|
||||
"ref": "master",
|
||||
"path": "typings",
|
||||
"bundle": "typings/tsd.d.ts",
|
||||
"installed": {
|
||||
"es6-shim/es6-shim.d.ts": {
|
||||
"commit": "4b36b94d5910aa8a4d20bdcd5bd1f9ae6ad18d3c"
|
||||
"es6-promise/es6-promise.d.ts": {
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
},
|
||||
"es6-collections/es6-collections.d.ts": {
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
},
|
||||
"hammerjs/hammerjs.d.ts": {
|
||||
"commit": "22c44d95912a07f81c103a694330b15b92f7cb40"
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
},
|
||||
"jasmine/jasmine.d.ts": {
|
||||
"commit": "4b36b94d5910aa8a4d20bdcd5bd1f9ae6ad18d3c"
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
},
|
||||
"node/node.d.ts": {
|
||||
"commit": "51738fdf1643d269067861b405e87503b7479236"
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
},
|
||||
"selenium-webdriver/selenium-webdriver.d.ts": {
|
||||
"commit": "be0b6b394f77a59e192ad7cfec18078706e44db5"
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
},
|
||||
"zone/zone.d.ts": {
|
||||
"commit": "31e7317c9a0793857109236ef7c7f223305a8aa9"
|
||||
"zone.js/zone.js.d.ts": {
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
},
|
||||
"angular-protractor/angular-protractor.d.ts": {
|
||||
"commit": "4207593c012565a7ea800ed861ffbe5011e7a501"
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,8 @@ describe('md-progress-linear', function() {
|
||||
var incrementButton = element(by.id('increment'));
|
||||
var decrementButton = element(by.id('decrement'));
|
||||
|
||||
var initialValue = progressBar.getAttribute('aria-valuenow');
|
||||
// Really a Promise<string> but can be coerced to a number after resolving
|
||||
var initialValue: any = progressBar.getAttribute('aria-valuenow');
|
||||
|
||||
incrementButton.click();
|
||||
expect(progressBar.getAttribute('aria-valuenow')).toBeGreaterThan(initialValue);
|
||||
|
@ -23,9 +23,10 @@ describe('WebWorkers Kitchen Sink', function() {
|
||||
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
|
||||
browser.ignoreSynchronization = true;
|
||||
browser.get(URL);
|
||||
let changeButtonSelector = 'hello-app .changeButton';
|
||||
|
||||
browser.wait(protractor.until.elementLocated(by.css(selector)), 15000);
|
||||
element(by.css("hello-app .changeButton")).click();
|
||||
browser.wait(protractor.until.elementLocated(by.css(changeButtonSelector)), 15000);
|
||||
element(by.css(changeButtonSelector)).click();
|
||||
var elem = element(by.css(selector));
|
||||
browser.wait(protractor.until.elementTextIs(elem, "howdy world!"), 5000);
|
||||
expect(elem.getText()).toEqual("howdy world!");
|
||||
|
@ -46,13 +46,13 @@
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"angular": {
|
||||
"version": "1.4.8"
|
||||
"version": "1.5.0"
|
||||
},
|
||||
"angular-animate": {
|
||||
"version": "1.4.8"
|
||||
"version": "1.5.0"
|
||||
},
|
||||
"angular-mocks": {
|
||||
"version": "1.4.8"
|
||||
"version": "1.5.0"
|
||||
},
|
||||
"ansi": {
|
||||
"version": "0.3.0"
|
||||
@ -5345,7 +5345,7 @@
|
||||
}
|
||||
},
|
||||
"ts2dart": {
|
||||
"version": "0.7.19",
|
||||
"version": "0.7.22",
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.4.4"
|
||||
@ -5824,9 +5824,9 @@
|
||||
}
|
||||
},
|
||||
"zone.js": {
|
||||
"version": "0.5.11"
|
||||
"version": "0.5.13"
|
||||
}
|
||||
},
|
||||
"name": "angular-srcs",
|
||||
"version": "2.0.0-beta.1"
|
||||
"version": "2.0.0-beta.3"
|
||||
}
|
||||
|
40
npm-shrinkwrap.json
generated
40
npm-shrinkwrap.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "angular-srcs",
|
||||
"version": "2.0.0-beta.1",
|
||||
"version": "2.0.0-beta.3",
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.0.7",
|
||||
@ -74,19 +74,19 @@
|
||||
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz"
|
||||
},
|
||||
"angular": {
|
||||
"version": "1.4.8",
|
||||
"from": "angular@>=1.4.7 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/angular/-/angular-1.4.8.tgz"
|
||||
"version": "1.5.0",
|
||||
"from": "angular@1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/angular/-/angular-1.5.0.tgz"
|
||||
},
|
||||
"angular-animate": {
|
||||
"version": "1.4.8",
|
||||
"from": "angular-animate@>=1.4.7 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.4.8.tgz"
|
||||
"version": "1.5.0",
|
||||
"from": "angular-animate@1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.5.0.tgz"
|
||||
},
|
||||
"angular-mocks": {
|
||||
"version": "1.4.8",
|
||||
"from": "angular-mocks@>=1.4.7 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/angular-mocks/-/angular-mocks-1.4.8.tgz"
|
||||
"version": "1.5.0",
|
||||
"from": "angular-mocks@1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/angular-mocks/-/angular-mocks-1.5.0.tgz"
|
||||
},
|
||||
"ansi": {
|
||||
"version": "0.3.0",
|
||||
@ -8518,30 +8518,30 @@
|
||||
}
|
||||
},
|
||||
"ts2dart": {
|
||||
"version": "0.7.19",
|
||||
"from": "ts2dart@>=0.7.18 <0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/ts2dart/-/ts2dart-0.7.19.tgz",
|
||||
"version": "0.7.22",
|
||||
"from": "https://registry.npmjs.org/ts2dart/-/ts2dart-0.7.22.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ts2dart/-/ts2dart-0.7.22.tgz",
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.4.4",
|
||||
"from": "source-map@>=0.4.2 <0.5.0",
|
||||
"from": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz"
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.3.3",
|
||||
"from": "source-map-support@>=0.3.1 <0.4.0",
|
||||
"from": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.3.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.3.3.tgz",
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.1.32",
|
||||
"from": "source-map@0.1.32",
|
||||
"from": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "1.7.3",
|
||||
"from": "typescript@1.7.3",
|
||||
"from": "https://registry.npmjs.org/typescript/-/typescript-1.7.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-1.7.3.tgz"
|
||||
}
|
||||
}
|
||||
@ -9291,9 +9291,9 @@
|
||||
}
|
||||
},
|
||||
"zone.js": {
|
||||
"version": "0.5.11",
|
||||
"from": "zone.js@0.5.11",
|
||||
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.5.11.tgz"
|
||||
"version": "0.5.13",
|
||||
"from": "https://registry.npmjs.org/zone.js/-/zone.js-0.5.13.tgz",
|
||||
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.5.13.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
14
package.json
14
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "angular-srcs",
|
||||
"version": "2.0.0-beta.3",
|
||||
"version": "2.0.0-beta.5",
|
||||
"branchPattern": "2.0.*",
|
||||
"description": "Angular 2 - a web framework for modern web apps",
|
||||
"homepage": "https://github.com/angular/angular",
|
||||
@ -35,13 +35,13 @@
|
||||
"es6-promise": "^3.0.2",
|
||||
"es6-shim": "^0.33.3",
|
||||
"reflect-metadata": "0.1.2",
|
||||
"rxjs": "5.0.0-beta.0",
|
||||
"zone.js": "0.5.11"
|
||||
"rxjs": "^5.0.0-beta.2",
|
||||
"zone.js": "^0.5.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"angular": "^1.4.7",
|
||||
"angular-animate": "^1.4.7",
|
||||
"angular-mocks": "^1.4.7",
|
||||
"angular": "^1.5.0",
|
||||
"angular-animate": "^1.5.0",
|
||||
"angular-mocks": "^1.5.0",
|
||||
"base64-js": "^0.0.8",
|
||||
"bower": "^1.3.12",
|
||||
"broccoli": "^0.16.9",
|
||||
@ -111,7 +111,7 @@
|
||||
"systemjs": "0.18.10",
|
||||
"systemjs-builder": "^0.10.3",
|
||||
"through2": "^0.6.5",
|
||||
"ts2dart": "^0.7.19",
|
||||
"ts2dart": "^0.7.22",
|
||||
"ts-api-guardian": "0.0.2",
|
||||
"tsd": "^0.6.5-beta",
|
||||
"tslint": "^3.2.1",
|
||||
|
@ -15,7 +15,6 @@ cd $ROOT_DIR
|
||||
|
||||
NPM_DIR=$ROOT_DIR/dist/npm
|
||||
FILES='!(test|e2e_test|docs)'
|
||||
DTS_FILES='*.d.ts'
|
||||
|
||||
PUBLISH_DIR=$NPM_DIR/$NAME
|
||||
rm -fr $PUBLISH_DIR
|
||||
@ -29,14 +28,9 @@ mkdir -p $PUBLISH_DIR/ts
|
||||
cp -r $ROOT_DIR/modules/$NAME/$FILES $PUBLISH_DIR/ts
|
||||
|
||||
if [ $NAME = "angular2" ]; then
|
||||
# Publish bundles and typings
|
||||
mkdir -p $PUBLISH_DIR/bundles/typings/es6-shim
|
||||
mkdir -p $PUBLISH_DIR/bundles/typings/jasmine
|
||||
# Copy Bundles
|
||||
mkdir -p $PUBLISH_DIR/bundles
|
||||
cp -r $ROOT_DIR/dist/js/bundle/$FILES $PUBLISH_DIR/bundles
|
||||
# Copy Typings
|
||||
cp -r $ROOT_DIR/modules/angular2/typings/es6-shim/$DTS_FILES $PUBLISH_DIR/bundles/typings/es6-shim
|
||||
cp -r $ROOT_DIR/modules/angular2/typings/jasmine/$DTS_FILES $PUBLISH_DIR/bundles/typings/jasmine
|
||||
fi
|
||||
|
||||
if [ $NAME = "benchpress" ]; then
|
||||
|
@ -171,6 +171,14 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
||||
patterns: [{match: /\$SCRIPTS\$/, replacement: jsReplace('SCRIPTS')}]
|
||||
});
|
||||
|
||||
let ambientTypings = [
|
||||
'angular2/typings/hammerjs/hammerjs.d.ts',
|
||||
'angular2/typings/node/node.d.ts',
|
||||
'angular2/manual_typings/globals.d.ts',
|
||||
'angular2/typings/es6-collections/es6-collections.d.ts',
|
||||
'angular2/typings/es6-promise/es6-promise.d.ts'
|
||||
];
|
||||
|
||||
// Use TypeScript to transpile the *.ts files to ES5
|
||||
var es5Tree = compileWithTypescript(es5ModulesTree, {
|
||||
declaration: false,
|
||||
@ -180,7 +188,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
||||
moduleResolution: 'classic',
|
||||
noEmitOnError: !noTypeChecks,
|
||||
rootDir: './',
|
||||
rootFilePaths: ['angular2/manual_typings/globals.d.ts'],
|
||||
rootFilePaths: ambientTypings,
|
||||
inlineSourceMap: sourceMaps,
|
||||
inlineSources: sourceMaps,
|
||||
target: 'es5'
|
||||
@ -311,7 +319,11 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
||||
experimentalDecorators: true,
|
||||
noEmitOnError: false,
|
||||
rootDir: './',
|
||||
rootFilePaths: ['angular2/manual_typings/globals-es6.d.ts'],
|
||||
rootFilePaths: [
|
||||
'angular2/typings/zone.js/zone.js.d.ts',
|
||||
'angular2/typings/hammerjs/hammerjs.d.ts',
|
||||
'angular2/typings/node/node.d.ts',
|
||||
],
|
||||
inlineSourceMap: sourceMaps,
|
||||
inlineSources: sourceMaps,
|
||||
target: 'es6'
|
||||
|
@ -32,9 +32,16 @@ module.exports = function makeNodeTree(projects, destinationPath) {
|
||||
]
|
||||
});
|
||||
|
||||
let ambientTypings = [
|
||||
'angular2/typings/hammerjs/hammerjs.d.ts',
|
||||
'angular2/typings/node/node.d.ts',
|
||||
'angular2/manual_typings/globals.d.ts',
|
||||
'angular2/typings/es6-collections/es6-collections.d.ts',
|
||||
'angular2/typings/es6-promise/es6-promise.d.ts'
|
||||
];
|
||||
|
||||
// Compile the sources and generate the @internal .d.ts
|
||||
let compiledSrcTreeWithInternals =
|
||||
compileTree(srcTree, true, ['angular2/manual_typings/globals.d.ts']);
|
||||
let compiledSrcTreeWithInternals = compileTree(srcTree, true, ambientTypings);
|
||||
|
||||
var testTree = new Funnel('modules', {
|
||||
include: [
|
||||
@ -85,11 +92,10 @@ module.exports = function makeNodeTree(projects, destinationPath) {
|
||||
|
||||
testTree = mergeTrees([testTree, srcPrivateDeclarations]);
|
||||
|
||||
let compiledTestTree = compileTree(testTree, false, [
|
||||
let compiledTestTree = compileTree(testTree, false, ambientTypings.concat([
|
||||
'angular2/typings/jasmine/jasmine.d.ts',
|
||||
'angular2/typings/angular-protractor/angular-protractor.d.ts',
|
||||
'angular2/manual_typings/globals.d.ts'
|
||||
]);
|
||||
]));
|
||||
|
||||
// Merge the compiled sources and tests
|
||||
let compiledSrcTree =
|
||||
@ -112,12 +118,7 @@ module.exports = function makeNodeTree(projects, destinationPath) {
|
||||
var srcPkgJsons = extractPkgJsons(srcTree, BASE_PACKAGE_JSON);
|
||||
var testPkgJsons = extractPkgJsons(testTree, BASE_PACKAGE_JSON);
|
||||
|
||||
var typingsTree = new Funnel(
|
||||
'modules',
|
||||
{include: ['angular2/typings/**/*.d.ts', 'angular2/manual_typings/*.d.ts'], destDir: '/'});
|
||||
|
||||
var nodeTree =
|
||||
mergeTrees([compiledTree, srcDocs, testDocs, srcPkgJsons, testPkgJsons, typingsTree]);
|
||||
var nodeTree = mergeTrees([compiledTree, srcDocs, testDocs, srcPkgJsons, testPkgJsons]);
|
||||
|
||||
// Transform all tests to make them runnable in node
|
||||
nodeTree = replace(nodeTree, {
|
||||
@ -139,22 +140,6 @@ module.exports = function makeNodeTree(projects, destinationPath) {
|
||||
nodeTree = replace(
|
||||
nodeTree, {files: ['**/*.js'], patterns: [{match: /^/, replacement: () => `'use strict';`}]});
|
||||
|
||||
// Add a line to the end of our top-level .d.ts file.
|
||||
// This HACK for transitive typings is a workaround for
|
||||
// https://github.com/Microsoft/TypeScript/issues/5097
|
||||
//
|
||||
// This allows users to get our top-level dependencies like zone.d.ts
|
||||
// to appear when they compile against angular2.
|
||||
//
|
||||
// This carries the risk that the user brings their own copy of that file
|
||||
// (or any other symbols exported here) and they will get a compiler error
|
||||
// because of the duplicate definitions.
|
||||
// TODO(alexeagle): remove this when typescript releases a fix
|
||||
nodeTree = replace(nodeTree, {
|
||||
files: ['angular2/core.d.ts'],
|
||||
patterns: [{match: /$/, replacement: 'import "./manual_typings/globals-es6.d.ts";\r\n'}]
|
||||
});
|
||||
|
||||
return destCopy(nodeTree, destinationPath);
|
||||
};
|
||||
|
||||
|
@ -566,6 +566,7 @@ const COMMON = [
|
||||
'AbstractControl.updateValueAndValidity({onlySelf,emitEvent}:{onlySelf?:boolean, emitEvent?:boolean}):void',
|
||||
'AbstractControl.valid:boolean',
|
||||
'AbstractControl.value:any',
|
||||
'AbstractControl.root:AbstractControl',
|
||||
'AbstractControl.valueChanges:Observable<any>',
|
||||
'AbstractControlDirective',
|
||||
'AbstractControlDirective.control:AbstractControl',
|
||||
@ -794,6 +795,8 @@ const COMMON = [
|
||||
'Validators.minLength(minLength:number):Function',
|
||||
'Validators.nullValidator(c:any):{[key:string]:boolean}',
|
||||
'Validators.required(control:Control):{[key:string]:boolean}',
|
||||
'RadioButtonState',
|
||||
'RadioButtonState.constructor(checked:boolean, value:string)',
|
||||
'const COMMON_DIRECTIVES:Type[][]',
|
||||
'const COMMON_PIPES:any',
|
||||
'const CORE_DIRECTIVES:Type[]',
|
||||
|
@ -1,21 +1,21 @@
|
||||
{
|
||||
"version": "v4",
|
||||
"repo": "angular/DefinitelyTyped",
|
||||
"repo": "DefinitelyTyped/DefinitelyTyped",
|
||||
"ref": "master",
|
||||
"path": "typings",
|
||||
"bundle": "typings/tsd.d.ts",
|
||||
"installed": {
|
||||
"fs-extra/fs-extra.d.ts": {
|
||||
"commit": "fa52db59121913b35e9641a0f73ccc3ffba58840"
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
},
|
||||
"node/node.d.ts": {
|
||||
"commit": "285e6b692a5898ccc1dc19475187429deafb69d7"
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
},
|
||||
"es6-promise/es6-promise.d.ts": {
|
||||
"commit": "d5f92f93bdb49f332fa662ff1d0cc8700f02e4dc"
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
},
|
||||
"jasmine/jasmine.d.ts": {
|
||||
"commit": "5996649b8eecebbd6dd2e25a6a254de1b169a65c"
|
||||
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user