Compare commits
2 Commits
2.0.0-beta
...
2.0.0-beta
Author | SHA1 | Date | |
---|---|---|---|
4945e73588 | |||
8a00a863ac |
@ -36,13 +36,12 @@ env:
|
||||
matrix:
|
||||
# Order: a slower build first, so that we don't occupy an idle travis worker waiting for others to complete.
|
||||
- MODE=dart DART_CHANNEL=stable DART_VERSION=$DART_STABLE_VERSION
|
||||
# Disable dart dev build, which is timing out after 2h. #6823
|
||||
# - MODE=dart DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=dart DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=saucelabs_required DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=browserstack_required DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=saucelabs_optional DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=browserstack_optional DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=dart_ddc DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=dart_experimental DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=js DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=router DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
|
||||
- MODE=build_only DART_CHANNEL=stable DART_VERSION=$DART_STABLE_VERSION
|
||||
@ -53,6 +52,7 @@ matrix:
|
||||
allow_failures:
|
||||
- env: "MODE=saucelabs_optional DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
|
||||
- env: "MODE=browserstack_optional DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
|
||||
- env: "MODE=dart_experimental DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
|
||||
# TODO(alxhub): remove when dartdoc #1039 is in dev channel
|
||||
- env: "MODE=dart DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
|
||||
|
||||
|
48
CHANGELOG.md
48
CHANGELOG.md
@ -1,33 +1,3 @@
|
||||
<a name="2.0.0-beta.3"></a>
|
||||
# 2.0.0-beta.3 (2016-02-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bundle:** add angular2/platform/testing/browser to SystemJS testing bundle ([ae7d2ab](https://github.com/angular/angular/commit/ae7d2ab))
|
||||
* **circle:** pre-dependencies `npm install npm` ([36a0e04](https://github.com/angular/angular/commit/36a0e04)), closes [#6777](https://github.com/angular/angular/issues/6777)
|
||||
* **dart/transform:** Handle edge cases in ReflectionRemover ([3e9b532](https://github.com/angular/angular/commit/3e9b532)), closes [#6749](https://github.com/angular/angular/issues/6749)
|
||||
* **docs:** `rxjs/add/operators/map` -> `rxjs/add/operator/map` (no 's'). ([2a302aa](https://github.com/angular/angular/commit/2a302aa))
|
||||
* **karma:** fix running karma via gulp ([27daeaf](https://github.com/angular/angular/commit/27daeaf))
|
||||
* **query:** don’t cross component boundaries ([c6adbf6](https://github.com/angular/angular/commit/c6adbf6)), closes [#6759](https://github.com/angular/angular/issues/6759)
|
||||
* **query:** update view queries that query directives in embedded views ([1f7a41c](https://github.com/angular/angular/commit/1f7a41c)), closes [#6747](https://github.com/angular/angular/issues/6747)
|
||||
* **WebWorkers:** Add support for transitionend events. ([c2a38c0](https://github.com/angular/angular/commit/c2a38c0)), closes [#6649](https://github.com/angular/angular/issues/6649)
|
||||
* **zone:** correct incorrect calls to zone ([3211938](https://github.com/angular/angular/commit/3211938))
|
||||
|
||||
### Features
|
||||
|
||||
* **change_detection:** allow all legal programs in the dev mode ([42231f5](https://github.com/angular/angular/commit/42231f5))
|
||||
* **dart/transform:** Generate all code into <file>.template.dart ([8c36aa8](https://github.com/angular/angular/commit/8c36aa8))
|
||||
* **debug:** replace DebugElement with new Debug DOM ([e1bf3d3](https://github.com/angular/angular/commit/e1bf3d3))
|
||||
* **ngFor:** add custom trackBy function support ([cee2318](https://github.com/angular/angular/commit/cee2318)), closes [#6779](https://github.com/angular/angular/issues/6779)
|
||||
* **upgrade:** support bindToController with binding definitions ([99e6500](https://github.com/angular/angular/commit/99e6500)), closes [#4784](https://github.com/angular/angular/issues/4784)
|
||||
* **WebWorker:** Add Router Support for WebWorker Apps ([8bea667](https://github.com/angular/angular/commit/8bea667)), closes [#3563](https://github.com/angular/angular/issues/3563)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **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)
|
||||
|
||||
|
||||
<a name="2.0.0-beta.2"></a>
|
||||
# 2.0.0-beta.2 (2016-01-28)
|
||||
|
||||
@ -60,10 +30,13 @@
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* there's a chance of breakage as router's Instruction constructor
|
||||
signature changed.
|
||||
|
||||
* `Renderer.listen` now has to return a function that
|
||||
removes the event listener.
|
||||
|
||||
* TemplateRef.elementRef is now read-only.
|
||||
* remove TemplateRef.elementRef setter
|
||||
|
||||
* Tests are now required to use `setBaseTestProviders`
|
||||
to set up. Assuming your tests are run on a browser, setup would change
|
||||
@ -86,6 +59,7 @@ setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS,
|
||||
TEST_BROWSER_APPLICATION_PROVIDERS);
|
||||
```
|
||||
|
||||
* This is very unlikely to be breaking, but I'm still marking just in case. The only change to the user should be that dev mode is driven by Dart's checked mode, like it was in the past.
|
||||
|
||||
<a name="2.0.0-beta.1"></a>
|
||||
# 2.0.0-beta.1 catamorphic-involution (2016-01-08)
|
||||
@ -132,7 +106,6 @@ setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS,
|
||||
take a native element instead of an ElementRef
|
||||
* `Renderer` interface now operates on plain native nodes,
|
||||
instead of `RenderElementRef`s or `RenderViewRef`s
|
||||
|
||||
<a name="2.0.0-beta.0"></a>
|
||||
# 2.0.0-beta.0 somnambulant-inauguration (2015-12-15)
|
||||
|
||||
@ -154,7 +127,10 @@ setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS,
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Previously, Angular would run in dev prod mode by default, and you could enable the dev mode by calling enableDevMode. Now, Angular runs in the dev mode by default, and you can enable the prod mode by calling enableProdMode.
|
||||
* Before
|
||||
Previously Angular would run in dev prod mode by default, and you could enable the dev mode by calling enableDevMode.
|
||||
After
|
||||
Now, Angular runs in the dev mode by default, and you can enable the prod mode by calling enableProdMode.
|
||||
|
||||
|
||||
|
||||
@ -231,11 +207,11 @@ bundle. `ngUpgrade` has a dedicated `upgrade.js` bundle now.
|
||||
|
||||
* `Observable` are no more re-exported from `angular2/core`
|
||||
|
||||
Before
|
||||
Before
|
||||
```
|
||||
import {Observable} from 'angular2/core'
|
||||
```
|
||||
After
|
||||
After
|
||||
```
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
```
|
||||
@ -456,7 +432,7 @@ import * as core from 'angular2/core';
|
||||
* Operators and Observables from RxJS (e.g. .map(), .toArray(), .toPromise(), etc ) now need to be explicitly imported (once per operator in your app)
|
||||
```
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import 'rxjs/add/operator/map';
|
||||
import 'rxjs/add/operators/map';
|
||||
import 'rxjs/add/observable/interval';
|
||||
|
||||
Observable.interval(1000).subscribe(...);
|
||||
|
14
DEVELOPER.md
14
DEVELOPER.md
@ -9,7 +9,7 @@ JS and Dart versions. It also explains the basic mechanics of using `git`, `node
|
||||
* [Installing NPM Modules and Dart Packages](#installing-npm-modules-and-dart-packages)
|
||||
* [Build commands](#build-commands)
|
||||
* [Running Tests Locally](#running-tests-locally)
|
||||
* [Code Style](#code-style)
|
||||
* [Formatting](#clang-format)
|
||||
* [Project Information](#project-information)
|
||||
* [CI using Travis](#ci-using-travis)
|
||||
* [Transforming Dart code](#transforming-dart-code)
|
||||
@ -227,9 +227,7 @@ Angular specific command line options when running protractor:
|
||||
Angular specific command line options when running protractor (e.g. force gc, ...):
|
||||
`$(npm bin)/protractor protractor-{js|dart2js}-conf.js --ng-help`
|
||||
|
||||
## Code Style
|
||||
|
||||
### Formatting with <a name="clang-format">clang-format</a>
|
||||
## Formatting with <a name="clang-format">clang-format</a>
|
||||
|
||||
We use [clang-format](http://clang.llvm.org/docs/ClangFormat.html) to automatically enforce code
|
||||
style for our TypeScript code. This allows us to focus our code reviews more on the content, and
|
||||
@ -275,14 +273,6 @@ to some whitespace difference.
|
||||
* `clang-format` integrations are also available for many popular editors (`vim`, `emacs`,
|
||||
`Sublime Text`, etc.).
|
||||
|
||||
### Linting
|
||||
|
||||
We use [tslint](https://github.com/palantir/tslint) for linting. See linting rules in [gulpfile](gulpfile.js). To lint, run
|
||||
|
||||
```shell
|
||||
$ gulp lint
|
||||
```
|
||||
|
||||
## Generating the API documentation
|
||||
|
||||
The following gulp task will generate the API docs in the `dist/angular.io/partials/api/angular2`:
|
||||
|
15
circle.yml
15
circle.yml
@ -1,21 +1,6 @@
|
||||
machine:
|
||||
node:
|
||||
version: 5.4.1
|
||||
|
||||
dependencies:
|
||||
pre:
|
||||
- npm install -g npm
|
||||
override:
|
||||
- npm install:
|
||||
environment:
|
||||
# Token for tsd to increase github rate limit
|
||||
# See https://github.com/DefinitelyTyped/tsd#tsdrc
|
||||
# This is not hidden using https://circleci.com/docs/fork-pr-builds#details
|
||||
# because those are not visible for pull requests, and those should also be reliable.
|
||||
# This SSO token belongs to github account angular-github-ratelimit-token which has no access
|
||||
# (password is in Valentine)
|
||||
TSD_GITHUB_TOKEN: ef474500309daea53d5991b3079159a29520a40b
|
||||
|
||||
test:
|
||||
override:
|
||||
- npm run build
|
||||
|
14
gulpfile.js
14
gulpfile.js
@ -155,7 +155,7 @@ var HTTP_BUNDLE_CONTENT = 'angular2/http - rxjs/* - ' + ANGULAR2_BUNDLE_CONFIG.j
|
||||
var ROUTER_BUNDLE_CONTENT = 'angular2/router + angular2/router/router_link_dsl - rxjs/* - ' +
|
||||
ANGULAR2_BUNDLE_CONFIG.join(' - ');
|
||||
var TESTING_BUNDLE_CONTENT =
|
||||
'angular2/testing + angular2/http/testing + angular2/router/testing + angular2/platform/testing/browser - rxjs/* - ' +
|
||||
'angular2/testing + angular2/http/testing + angular2/router/testing - rxjs/* - ' +
|
||||
ANGULAR2_BUNDLE_CONFIG.join(' - ');
|
||||
var UPGRADE_BUNDLE_CONTENT = 'angular2/upgrade - rxjs/* - ' + ANGULAR2_BUNDLE_CONFIG.join(' - ');
|
||||
|
||||
@ -463,7 +463,7 @@ function runKarma(configFile, done) {
|
||||
|
||||
gulp.task('test.js', function(done) {
|
||||
runSequence('test.unit.tools/ci', 'test.transpiler.unittest', 'test.unit.js/ci',
|
||||
'test.unit.cjs/ci', 'test.typings', 'check-public-api', sequenceComplete(done));
|
||||
'test.unit.cjs/ci', 'test.typings', sequenceComplete(done));
|
||||
});
|
||||
|
||||
gulp.task('test.dart', function(done) {
|
||||
@ -627,11 +627,7 @@ gulp.task('!test.unit.router/karma-run', function(done) {
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('buildRouter.dev', function() {
|
||||
var modulesSrcDir = __dirname + '/modules';
|
||||
var distDir = __dirname + '/dist';
|
||||
buildRouter(modulesSrcDir, distDir);
|
||||
});
|
||||
gulp.task('buildRouter.dev', function() { buildRouter(); });
|
||||
|
||||
gulp.task('test.unit.dart', function(done) {
|
||||
printModulesWarning();
|
||||
@ -830,7 +826,7 @@ gulp.task('test.unit.js/ci', function(done) {
|
||||
reporters: ['dots'],
|
||||
browsers: browserConf.browsersToRun
|
||||
},
|
||||
function(err) { done(); })
|
||||
done)
|
||||
.start();
|
||||
});
|
||||
|
||||
@ -870,8 +866,6 @@ gulp.task('test.unit.cjs/ci', function(done) {
|
||||
runJasmineTests(['dist/js/cjs/{angular2,benchpress}/test/**/*_spec.js'], done);
|
||||
});
|
||||
|
||||
gulp.task('check-public-api',
|
||||
function(done) { runJasmineTests(['dist/tools/public_api_guard/**/*_spec.js'], done); });
|
||||
|
||||
gulp.task('test.unit.cjs', ['build/clean.js', 'build.tools'], function(neverDone) {
|
||||
var watch = require('./tools/build/watch');
|
||||
|
50
modules/angular1_router/build.js
vendored
50
modules/angular1_router/build.js
vendored
@ -21,25 +21,18 @@ var files = [
|
||||
|
||||
var PRELUDE = '(function(){\n';
|
||||
var POSTLUDE = '\n}());\n';
|
||||
var FACADES = fs.readFileSync(__dirname + '/lib/facades.es5', 'utf8');
|
||||
var DIRECTIVES = fs.readFileSync(__dirname + '/src/ng_outlet.ts', 'utf8');
|
||||
var moduleTemplate = fs.readFileSync(__dirname + '/src/module_template.js', 'utf8');
|
||||
|
||||
function main(modulesDirectory) {
|
||||
var angular1RouterModuleDirectory = modulesDirectory + '/angular1_router';
|
||||
|
||||
var facades = fs.readFileSync(
|
||||
angular1RouterModuleDirectory + '/lib/facades.es5', 'utf8');
|
||||
var directives = fs.readFileSync(
|
||||
angular1RouterModuleDirectory + '/src/ng_outlet.ts', 'utf8');
|
||||
var moduleTemplate = fs.readFileSync(
|
||||
angular1RouterModuleDirectory + '/src/module_template.js', 'utf8');
|
||||
|
||||
var dir = modulesDirectory + '/angular2/src/router/';
|
||||
function main() {
|
||||
var dir = __dirname + '/../angular2/src/router/';
|
||||
var sharedCode = files.reduce(function (prev, file) {
|
||||
return prev + transform(fs.readFileSync(dir + file, 'utf8'));
|
||||
}, '');
|
||||
|
||||
var out = moduleTemplate.replace('//{{FACADES}}', facades)
|
||||
.replace('//{{SHARED_CODE}}', sharedCode);
|
||||
return PRELUDE + transform(directives) + out + POSTLUDE;
|
||||
var out = moduleTemplate.replace('//{{FACADES}}', FACADES).replace('//{{SHARED_CODE}}', sharedCode);
|
||||
return PRELUDE + transform(DIRECTIVES) + out + POSTLUDE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -69,29 +62,10 @@ function isFacadeModule(modulePath) {
|
||||
modulePath === 'angular2/src/core/reflection/reflection';
|
||||
}
|
||||
|
||||
module.exports = function(modulesDirectory, outputDirectory) {
|
||||
if (!fs.existsSync(outputDirectory)) {
|
||||
fs.mkdirSync(outputDirectory);
|
||||
module.exports = function () {
|
||||
var dist = __dirname + '/../../dist';
|
||||
if (!fs.existsSync(dist)) {
|
||||
fs.mkdirSync(dist);
|
||||
}
|
||||
fs.writeFileSync(
|
||||
outputDirectory + '/angular_1_router.js', main(modulesDirectory));
|
||||
fs.writeFileSync(dist + '/angular_1_router.js', main());
|
||||
};
|
||||
|
||||
// CLI entry point
|
||||
if (require.main === module) {
|
||||
try {
|
||||
var args = process.argv;
|
||||
args.shift(); // node
|
||||
args.shift(); // scriptfile.js
|
||||
if (args.length < 2) {
|
||||
console.log("usage: $0 outFile path/to/modules");
|
||||
process.exit(1);
|
||||
}
|
||||
var outfile = args.shift();
|
||||
var directory = args.shift();
|
||||
fs.writeFileSync(outfile, main(directory));
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,9 @@ export './src/core/application_tokens.dart' show APP_ID,
|
||||
export './src/core/zone.dart';
|
||||
export './src/core/render.dart';
|
||||
export './src/core/linker.dart';
|
||||
export './src/core/debug/debug_node.dart' show DebugElement,
|
||||
DebugNode,
|
||||
export './src/core/debug/debug_element.dart' show DebugElement,
|
||||
Scope,
|
||||
inspectElement,
|
||||
asNativeElements;
|
||||
export './src/core/testability/testability.dart';
|
||||
export './src/core/change_detection.dart';
|
||||
|
@ -20,7 +20,12 @@ export {
|
||||
export * from './src/core/zone';
|
||||
export * from './src/core/render';
|
||||
export * from './src/core/linker';
|
||||
export {DebugElement, DebugNode, asNativeElements} from './src/core/debug/debug_node';
|
||||
export {
|
||||
DebugElement,
|
||||
Scope,
|
||||
inspectElement,
|
||||
asNativeElements
|
||||
} from './src/core/debug/debug_element';
|
||||
export * from './src/core/testability/testability';
|
||||
export * from './src/core/change_detection';
|
||||
export * from './src/core/platform_directives_and_pipes';
|
||||
|
@ -32,7 +32,7 @@ filename | list of barrels | dev/prod | minified?
|
||||
`angular2-all.umd.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade`| prod | no
|
||||
`angular2-all.umd.min.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade` | prod | yes
|
||||
`angular2-all.umd.dev.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade` | dev | no
|
||||
`angular2-all-testing.umd.dev.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade`, `angular2/testing`, `angular2/http/testing`, `angular2/router/testing`, `angular2/platform/testing/browser` | dev | no
|
||||
`angular2-all-testing.umd.dev.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade`, `angular2/testing`, `angular2/http/testing`, `angular2/router/testing` | dev | no
|
||||
|
||||
**Warning**: bundles in the `UMD` format are _not_ "additive". A single application should use only one bundle from the above list.
|
||||
|
||||
@ -55,7 +55,7 @@ filename | list of barrels | dev/prod | minified?
|
||||
`upgrade.js` | `angular2/upgrade` | prod | no
|
||||
`upgrade.min.js` | `angular2/upgrade` | prod | yes
|
||||
`upgrade.dev.js` | `angular2/upgrade` | dev | no
|
||||
`testing.dev.js` | `angular2/testing`, `angular2/http/testing`, `angular2/router/testing`, `angular2/platform/testing/browser` | dev | no
|
||||
`testing.dev.js` | `angular2/testing`, `angular2/http/testing`, `angular2/router/testing` | dev | no
|
||||
|
||||
**Note**: bundles in the `System.register` format are "additive" - it is quite common to include several bundles in one application.
|
||||
For example people using Angular 2 with `http` and `router` would include: `angular2.js`, `http.js` and `router.js`.
|
||||
|
@ -10,16 +10,16 @@ Routing and navigation
|
||||
@cheatsheetItem
|
||||
syntax(ts):
|
||||
`@RouteConfig([
|
||||
{ path: '/:myParam', component: MyComponent, name: 'MyCmp' },
|
||||
{ path: '/staticPath', component: ..., name: ...},
|
||||
{ path: '/*wildCardParam', component: ..., name: ...}
|
||||
{ path: '/:myParam', component: MyComponent, as: 'MyCmp' },
|
||||
{ path: '/staticPath', component: ..., as: ...},
|
||||
{ path: '/*wildCardParam', component: ..., as: ...}
|
||||
])
|
||||
class MyComponent() {}`|`@RouteConfig`
|
||||
syntax(js):
|
||||
`var MyComponent = ng.router.RouteConfig([
|
||||
{ path: '/:myParam', component: MyComponent, name: 'MyCmp' },
|
||||
{ path: '/staticPath', component: ..., name: ...},
|
||||
{ path: '/*wildCardParam', component: ..., name: ...}
|
||||
{ path: '/:myParam', component: MyComponent, as: 'MyCmp' },
|
||||
{ path: '/staticPath', component: ..., as: ...},
|
||||
{ path: '/*wildCardParam', component: ..., as: ...}
|
||||
]).Class({
|
||||
constructor: function() {}
|
||||
});`|`ng.router.RouteConfig`
|
||||
|
@ -1,8 +1,16 @@
|
||||
import {DebugElement} from 'angular2/core';
|
||||
import {DebugElement, Scope} from 'angular2/core';
|
||||
|
||||
var debugElement: DebugElement;
|
||||
var predicate;
|
||||
|
||||
// #docregion scope_all
|
||||
debugElement.query(predicate);
|
||||
debugElement.query(predicate, Scope.all);
|
||||
// #enddocregion
|
||||
|
||||
// #docregion scope_light
|
||||
debugElement.query(predicate, Scope.light);
|
||||
// #enddocregion
|
||||
|
||||
// #docregion scope_view
|
||||
debugElement.query(predicate, Scope.view);
|
||||
// #enddocregion
|
||||
|
@ -1,17 +1,17 @@
|
||||
import {By} from 'angular2/platform/browser';
|
||||
import {DebugElement} from 'angular2/core';
|
||||
import {DebugElement, Scope} from 'angular2/core';
|
||||
|
||||
var debugElement: DebugElement;
|
||||
class MyDirective {}
|
||||
|
||||
// #docregion by_all
|
||||
debugElement.query(By.all());
|
||||
debugElement.query(By.all(), Scope.all);
|
||||
// #enddocregion
|
||||
|
||||
// #docregion by_css
|
||||
debugElement.query(By.css('[attribute]'));
|
||||
debugElement.query(By.css('[attribute]'), Scope.all);
|
||||
// #enddocregion
|
||||
|
||||
// #docregion by_directive
|
||||
debugElement.query(By.directive(MyDirective));
|
||||
debugElement.query(By.directive(MyDirective), Scope.all);
|
||||
// #enddocregion
|
||||
|
@ -1,8 +1,8 @@
|
||||
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
||||
export {
|
||||
BROWSER_PROVIDERS,
|
||||
ELEMENT_PROBE_BINDINGS,
|
||||
ELEMENT_PROBE_PROVIDERS,
|
||||
ELEMENT_PROBE_PROVIDERS_PROD_MODE,
|
||||
inspectNativeElement,
|
||||
BrowserDomAdapter,
|
||||
By,
|
||||
|
@ -1,8 +1,8 @@
|
||||
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
||||
export {
|
||||
BROWSER_PROVIDERS,
|
||||
ELEMENT_PROBE_BINDINGS,
|
||||
ELEMENT_PROBE_PROVIDERS,
|
||||
ELEMENT_PROBE_PROVIDERS_PROD_MODE,
|
||||
inspectNativeElement,
|
||||
BrowserDomAdapter,
|
||||
By,
|
||||
|
@ -12,4 +12,4 @@ export {
|
||||
EventManagerPlugin
|
||||
} from 'angular2/src/platform/dom/events/event_manager';
|
||||
export * from 'angular2/src/platform/dom/debug/by';
|
||||
export * from 'angular2/src/platform/dom/debug/ng_probe';
|
||||
export * from 'angular2/src/platform/dom/debug/debug_element_view_listener';
|
@ -12,5 +12,3 @@ export 'package:angular2/src/web_workers/shared/service_message_broker.dart'
|
||||
show ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory;
|
||||
export 'package:angular2/src/web_workers/shared/serializer.dart' show PRIMITIVE;
|
||||
export 'package:angular2/src/web_workers/shared/message_bus.dart';
|
||||
export 'package:angular2/src/web_workers/worker/router_providers.dart'
|
||||
show WORKER_APP_ROUTER;
|
||||
|
@ -8,13 +8,12 @@ export {
|
||||
ClientMessageBrokerFactory,
|
||||
FnArg,
|
||||
UiArguments
|
||||
} from 'angular2/src/web_workers/shared/client_message_broker';
|
||||
} from '../src/web_workers/shared/client_message_broker';
|
||||
export {
|
||||
ReceivedMessage,
|
||||
ServiceMessageBroker,
|
||||
ServiceMessageBrokerFactory
|
||||
} from 'angular2/src/web_workers/shared/service_message_broker';
|
||||
export {PRIMITIVE} from 'angular2/src/web_workers/shared/serializer';
|
||||
export * from 'angular2/src/web_workers/shared/message_bus';
|
||||
} from '../src/web_workers/shared/service_message_broker';
|
||||
export {PRIMITIVE} from '../src/web_workers/shared/serializer';
|
||||
export * from '../src/web_workers/shared/message_bus';
|
||||
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
||||
export {WORKER_APP_ROUTER} from 'angular2/src/web_workers/worker/router_providers';
|
||||
|
@ -18,9 +18,7 @@ export '../src/web_workers/shared/service_message_broker.dart'
|
||||
|
||||
export '../src/web_workers/shared/serializer.dart' show PRIMITIVE;
|
||||
export '../src/web_workers/shared/message_bus.dart';
|
||||
export '../src/web_workers/ui/router_providers.dart' show WORKER_RENDER_ROUTER;
|
||||
|
||||
import 'package:angular2/src/platform/worker_render_common.dart';
|
||||
|
||||
const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION_COMMON;
|
||||
|
||||
|
@ -24,4 +24,3 @@ import {WORKER_RENDER_APPLICATION} from 'angular2/src/platform/worker_render';
|
||||
* @deprecated Use WORKER_RENDER_APPLICATION
|
||||
*/
|
||||
export const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION;
|
||||
export {WORKER_RENDER_ROUTER} from 'angular2/src/web_workers/ui/router_providers';
|
||||
|
@ -20,12 +20,18 @@ export {OnActivate, OnDeactivate, OnReuse, CanDeactivate, CanReuse} from './src/
|
||||
export {CanActivate} from './src/router/lifecycle_annotations';
|
||||
export {Instruction, ComponentInstruction} from './src/router/instruction';
|
||||
export {OpaqueToken} from 'angular2/core';
|
||||
export {ROUTER_PROVIDERS_COMMON} from 'angular2/src/router/router_providers_common';
|
||||
export {ROUTER_PROVIDERS, ROUTER_BINDINGS} from 'angular2/src/router/router_providers';
|
||||
|
||||
import {PlatformLocation} from './src/router/platform_location';
|
||||
import {LocationStrategy} from './src/router/location_strategy';
|
||||
import {PathLocationStrategy} from './src/router/path_location_strategy';
|
||||
import {Router, RootRouter} from './src/router/router';
|
||||
import {RouterOutlet} from './src/router/router_outlet';
|
||||
import {RouterLink} from './src/router/router_link';
|
||||
import {RouteRegistry, ROUTER_PRIMARY_COMPONENT} from './src/router/route_registry';
|
||||
import {Location} from './src/router/location';
|
||||
import {ApplicationRef, provide, OpaqueToken, Provider} from 'angular2/core';
|
||||
import {CONST_EXPR} from './src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
|
||||
/**
|
||||
* A list of directives. To use the router directives like {@link RouterOutlet} and
|
||||
@ -50,3 +56,63 @@ import {CONST_EXPR} from './src/facade/lang';
|
||||
* ```
|
||||
*/
|
||||
export const ROUTER_DIRECTIVES: any[] = CONST_EXPR([RouterOutlet, RouterLink]);
|
||||
|
||||
/**
|
||||
* A list of {@link Provider}s. To use the router, you must add this to your application.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/iRUP8B5OUbxCWQ3AcIDm))
|
||||
*
|
||||
* ```
|
||||
* import {Component} from 'angular2/core';
|
||||
* import {
|
||||
* ROUTER_DIRECTIVES,
|
||||
* ROUTER_PROVIDERS,
|
||||
* RouteConfig
|
||||
* } from 'angular2/router';
|
||||
*
|
||||
* @Component({directives: [ROUTER_DIRECTIVES]})
|
||||
* @RouteConfig([
|
||||
* {...},
|
||||
* ])
|
||||
* class AppCmp {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* bootstrap(AppCmp, [ROUTER_PROVIDERS]);
|
||||
* ```
|
||||
*/
|
||||
export const ROUTER_PROVIDERS: any[] = CONST_EXPR([
|
||||
RouteRegistry,
|
||||
CONST_EXPR(new Provider(LocationStrategy, {useClass: PathLocationStrategy})),
|
||||
PlatformLocation,
|
||||
Location,
|
||||
CONST_EXPR(new Provider(
|
||||
Router,
|
||||
{
|
||||
useFactory: routerFactory,
|
||||
deps: CONST_EXPR([RouteRegistry, Location, ROUTER_PRIMARY_COMPONENT, ApplicationRef])
|
||||
})),
|
||||
CONST_EXPR(new Provider(
|
||||
ROUTER_PRIMARY_COMPONENT,
|
||||
{useFactory: routerPrimaryComponentFactory, deps: CONST_EXPR([ApplicationRef])}))
|
||||
]);
|
||||
|
||||
/**
|
||||
* Use {@link ROUTER_PROVIDERS} instead.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export const ROUTER_BINDINGS = ROUTER_PROVIDERS;
|
||||
|
||||
function routerFactory(registry, location, primaryComponent, appRef) {
|
||||
var rootRouter = new RootRouter(registry, location, primaryComponent);
|
||||
appRef.registerDisposeListener(() => rootRouter.dispose());
|
||||
return rootRouter;
|
||||
}
|
||||
|
||||
function routerPrimaryComponentFactory(app) {
|
||||
if (app.componentTypes.length == 0) {
|
||||
throw new BaseException("Bootstrap at least one component before injecting Router.");
|
||||
}
|
||||
return app.componentTypes[0];
|
||||
}
|
||||
|
@ -6,8 +6,7 @@ import {
|
||||
IterableDiffers,
|
||||
ViewContainerRef,
|
||||
TemplateRef,
|
||||
EmbeddedViewRef,
|
||||
TrackByFn
|
||||
EmbeddedViewRef
|
||||
} from 'angular2/core';
|
||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||
|
||||
@ -60,11 +59,10 @@ import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||
* See a [live demo](http://plnkr.co/edit/KVuXxDp0qinGDyo307QW?p=preview) for a more detailed
|
||||
* example.
|
||||
*/
|
||||
@Directive({selector: '[ngFor][ngForOf]', inputs: ['ngForTrackBy', 'ngForOf', 'ngForTemplate']})
|
||||
@Directive({selector: '[ngFor][ngForOf]', inputs: ['ngForOf', 'ngForTemplate']})
|
||||
export class NgFor implements DoCheck {
|
||||
/** @internal */
|
||||
_ngForOf: any;
|
||||
_ngForTrackBy: TrackByFn;
|
||||
private _differ: IterableDiffer;
|
||||
|
||||
constructor(private _viewContainer: ViewContainerRef, private _templateRef: TemplateRef,
|
||||
@ -73,7 +71,7 @@ export class NgFor implements DoCheck {
|
||||
set ngForOf(value: any) {
|
||||
this._ngForOf = value;
|
||||
if (isBlank(this._differ) && isPresent(value)) {
|
||||
this._differ = this._iterableDiffers.find(value).create(this._cdr, this._ngForTrackBy);
|
||||
this._differ = this._iterableDiffers.find(value).create(this._cdr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,8 +81,6 @@ export class NgFor implements DoCheck {
|
||||
}
|
||||
}
|
||||
|
||||
set ngForTrackBy(value: TrackByFn) { this._ngForTrackBy = value; }
|
||||
|
||||
ngDoCheck() {
|
||||
if (isPresent(this._differ)) {
|
||||
var changes = this._differ.diff(this._ngForOf);
|
||||
|
@ -57,7 +57,7 @@ class ObservableListDiff extends DefaultIterableDiffer {
|
||||
class ObservableListDiffFactory implements IterableDifferFactory {
|
||||
const ObservableListDiffFactory();
|
||||
bool supports(obj) => obj is ObservableList;
|
||||
IterableDiffer create(ChangeDetectorRef cdRef, [Function trackByFn]) {
|
||||
IterableDiffer create(ChangeDetectorRef cdRef) {
|
||||
return new ObservableListDiff(cdRef);
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_
|
||||
import {AppViewManager} from './linker/view_manager';
|
||||
import {AppViewManager_} from "./linker/view_manager";
|
||||
import {ViewResolver} from './linker/view_resolver';
|
||||
import {AppViewListener} from './linker/view_listener';
|
||||
import {DirectiveResolver} from './linker/directive_resolver';
|
||||
import {PipeResolver} from './linker/pipe_resolver';
|
||||
import {Compiler} from './linker/compiler';
|
||||
@ -31,6 +32,7 @@ export const APPLICATION_COMMON_PROVIDERS: Array<Type | Provider | any[]> = CONS
|
||||
APP_ID_RANDOM_PROVIDER,
|
||||
ResolvedMetadataCache,
|
||||
new Provider(AppViewManager, {useClass: AppViewManager_}),
|
||||
AppViewListener,
|
||||
ViewResolver,
|
||||
new Provider(IterableDiffers, {useValue: defaultIterableDiffers}),
|
||||
new Provider(KeyValueDiffers, {useValue: defaultKeyValueDiffers}),
|
||||
|
@ -20,6 +20,5 @@ export {
|
||||
IterableDifferFactory,
|
||||
KeyValueDiffers,
|
||||
KeyValueDiffer,
|
||||
KeyValueDifferFactory,
|
||||
TrackByFn
|
||||
KeyValueDifferFactory
|
||||
} from './change_detection/change_detection';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {IterableDiffers, IterableDifferFactory, TrackByFn} from './differs/iterable_differs';
|
||||
import {IterableDiffers, IterableDifferFactory} from './differs/iterable_differs';
|
||||
import {DefaultIterableDifferFactory} from './differs/default_iterable_differ';
|
||||
import {KeyValueDiffers, KeyValueDifferFactory} from './differs/keyvalue_differs';
|
||||
import {DefaultKeyValueDifferFactory} from './differs/default_keyvalue_differ';
|
||||
@ -37,12 +37,7 @@ export {BindingRecord, BindingTarget} from './binding_record';
|
||||
export {DirectiveIndex, DirectiveRecord} from './directive_record';
|
||||
export {DynamicChangeDetector} from './dynamic_change_detector';
|
||||
export {ChangeDetectorRef} from './change_detector_ref';
|
||||
export {
|
||||
IterableDiffers,
|
||||
IterableDiffer,
|
||||
IterableDifferFactory,
|
||||
TrackByFn
|
||||
} from './differs/iterable_differs';
|
||||
export {IterableDiffers, IterableDiffer, IterableDifferFactory} from './differs/iterable_differs';
|
||||
export {KeyValueDiffers, KeyValueDiffer, KeyValueDifferFactory} from './differs/keyvalue_differs';
|
||||
export {PipeTransform} from './pipe_transform';
|
||||
export {WrappedValue, SimpleChange} from './change_detection_util';
|
||||
|
@ -350,7 +350,6 @@ export class ChangeDetectorJITGenerator {
|
||||
var condition = `!${pipe}.pure || (${contexOrArgCheck.join(" || ")})`;
|
||||
|
||||
var check = `
|
||||
${this._genThrowOnChangeCheck(oldValue, newValue)}
|
||||
if (${this.changeDetectionUtilVarName}.looseNotIdentical(${oldValue}, ${newValue})) {
|
||||
${newValue} = ${this.changeDetectionUtilVarName}.unwrapValue(${newValue})
|
||||
${this._genChangeMarker(r)}
|
||||
@ -378,7 +377,6 @@ export class ChangeDetectorJITGenerator {
|
||||
`;
|
||||
|
||||
var check = `
|
||||
${this._genThrowOnChangeCheck(oldValue, newValue)}
|
||||
if (${this.changeDetectionUtilVarName}.looseNotIdentical(${oldValue}, ${newValue})) {
|
||||
${this._genChangeMarker(r)}
|
||||
${this._genUpdateDirectiveOrElement(r)}
|
||||
@ -411,6 +409,7 @@ export class ChangeDetectorJITGenerator {
|
||||
if (!r.lastInBinding) return "";
|
||||
|
||||
var newValue = this._names.getLocalName(r.selfIndex);
|
||||
var oldValue = this._names.getFieldName(r.selfIndex);
|
||||
var notifyDebug = this.genConfig.logBindingUpdate ? `this.logBindingUpdate(${newValue});` : "";
|
||||
|
||||
var br = r.bindingRecord;
|
||||
@ -418,12 +417,14 @@ export class ChangeDetectorJITGenerator {
|
||||
var directiveProperty =
|
||||
`${this._names.getDirectiveName(br.directiveRecord.directiveIndex)}.${br.target.name}`;
|
||||
return `
|
||||
${this._genThrowOnChangeCheck(oldValue, newValue)}
|
||||
${directiveProperty} = ${newValue};
|
||||
${notifyDebug}
|
||||
${IS_CHANGED_LOCAL} = true;
|
||||
`;
|
||||
} else {
|
||||
return `
|
||||
${this._genThrowOnChangeCheck(oldValue, newValue)}
|
||||
this.notifyDispatcher(${newValue});
|
||||
${notifyDebug}
|
||||
`;
|
||||
@ -434,7 +435,7 @@ export class ChangeDetectorJITGenerator {
|
||||
_genThrowOnChangeCheck(oldValue: string, newValue: string): string {
|
||||
if (assertionsEnabled()) {
|
||||
return `
|
||||
if (throwOnChange && !${this.changeDetectionUtilVarName}.devModeEqual(${oldValue}, ${newValue})) {
|
||||
if(throwOnChange) {
|
||||
this.throwOnChangeError(${oldValue}, ${newValue});
|
||||
}
|
||||
`;
|
||||
|
@ -4,17 +4,10 @@ import {
|
||||
isBlank,
|
||||
Type,
|
||||
StringWrapper,
|
||||
looseIdentical,
|
||||
isPrimitive
|
||||
looseIdentical
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
import {
|
||||
ListWrapper,
|
||||
MapWrapper,
|
||||
StringMapWrapper,
|
||||
isListLikeIterable,
|
||||
areIterablesEqual
|
||||
} from 'angular2/src/facade/collection';
|
||||
import {ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {ProtoRecord} from './proto_record';
|
||||
import {ChangeDetectionStrategy, isDefaultChangeDetectionStrategy} from './constants';
|
||||
import {implementsOnDestroy} from './pipe_lifecycle_reflector';
|
||||
@ -221,17 +214,4 @@ export class ChangeDetectionUtil {
|
||||
}
|
||||
|
||||
static looseNotIdentical(a: any, b: any): boolean { return !looseIdentical(a, b); }
|
||||
|
||||
static devModeEqual(a: any, b: any): boolean {
|
||||
if (isListLikeIterable(a) && isListLikeIterable(b)) {
|
||||
return areIterablesEqual(a, b, ChangeDetectionUtil.devModeEqual);
|
||||
|
||||
} else if (!isListLikeIterable(a) && !isPrimitive(a) && !isListLikeIterable(b) &&
|
||||
!isPrimitive(b)) {
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return looseIdentical(a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
import {CONST} from 'angular2/src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
import {isListLikeIterable, iterateListLike, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {
|
||||
isListLikeIterable,
|
||||
iterateListLike,
|
||||
ListWrapper,
|
||||
MapWrapper
|
||||
} from 'angular2/src/facade/collection';
|
||||
|
||||
import {
|
||||
isBlank,
|
||||
@ -12,21 +17,17 @@ import {
|
||||
} from 'angular2/src/facade/lang';
|
||||
|
||||
import {ChangeDetectorRef} from '../change_detector_ref';
|
||||
import {IterableDiffer, IterableDifferFactory, TrackByFn} from '../differs/iterable_differs';
|
||||
import {IterableDiffer, IterableDifferFactory} from '../differs/iterable_differs';
|
||||
|
||||
@CONST()
|
||||
export class DefaultIterableDifferFactory implements IterableDifferFactory {
|
||||
supports(obj: Object): boolean { return isListLikeIterable(obj); }
|
||||
create(cdRef: ChangeDetectorRef, trackByFn?: TrackByFn): DefaultIterableDiffer {
|
||||
return new DefaultIterableDiffer(trackByFn);
|
||||
}
|
||||
create(cdRef: ChangeDetectorRef): DefaultIterableDiffer { return new DefaultIterableDiffer(); }
|
||||
}
|
||||
|
||||
var trackByIdentity = (index: number, item: any) => item;
|
||||
|
||||
export class DefaultIterableDiffer implements IterableDiffer {
|
||||
private _length: number = null;
|
||||
private _collection = null;
|
||||
private _length: number = null;
|
||||
// Keeps track of the used records at any point in time (during & across `_check()` calls)
|
||||
private _linkedRecords: _DuplicateMap = null;
|
||||
// Keeps track of the removed records at any point in time during `_check()` calls.
|
||||
@ -41,10 +42,6 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
private _removalsHead: CollectionChangeRecord = null;
|
||||
private _removalsTail: CollectionChangeRecord = null;
|
||||
|
||||
constructor(private _trackByFn?: TrackByFn) {
|
||||
this._trackByFn = isPresent(this._trackByFn) ? this._trackByFn : trackByIdentity;
|
||||
}
|
||||
|
||||
get collection() { return this._collection; }
|
||||
|
||||
get length(): number { return this._length; }
|
||||
@ -107,37 +104,31 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
var mayBeDirty: boolean = false;
|
||||
var index: number;
|
||||
var item;
|
||||
var itemTrackBy;
|
||||
|
||||
if (isArray(collection)) {
|
||||
var list = collection;
|
||||
this._length = collection.length;
|
||||
|
||||
for (index = 0; index < this._length; index++) {
|
||||
item = list[index];
|
||||
itemTrackBy = this._trackByFn(index, item);
|
||||
if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
|
||||
record = this._mismatch(record, item, itemTrackBy, index);
|
||||
if (record === null || !looseIdentical(record.item, item)) {
|
||||
record = this._mismatch(record, item, index);
|
||||
mayBeDirty = true;
|
||||
} else {
|
||||
if (mayBeDirty) {
|
||||
// TODO(misko): can we limit this to duplicates only?
|
||||
record = this._verifyReinsertion(record, item, itemTrackBy, index);
|
||||
}
|
||||
record.item = item;
|
||||
} else if (mayBeDirty) {
|
||||
// TODO(misko): can we limit this to duplicates only?
|
||||
record = this._verifyReinsertion(record, item, index);
|
||||
}
|
||||
|
||||
record = record._next;
|
||||
}
|
||||
} else {
|
||||
index = 0;
|
||||
iterateListLike(collection, (item) => {
|
||||
itemTrackBy = this._trackByFn(index, item);
|
||||
if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
|
||||
record = this._mismatch(record, item, itemTrackBy, index);
|
||||
if (record === null || !looseIdentical(record.item, item)) {
|
||||
record = this._mismatch(record, item, index);
|
||||
mayBeDirty = true;
|
||||
} else if (mayBeDirty) {
|
||||
// TODO(misko): can we limit this to duplicates only?
|
||||
record = this._verifyReinsertion(record, item, itemTrackBy, index);
|
||||
record = this._verifyReinsertion(record, item, index);
|
||||
}
|
||||
record = record._next;
|
||||
index++;
|
||||
@ -199,8 +190,7 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
_mismatch(record: CollectionChangeRecord, item: any, itemTrackBy: any,
|
||||
index: number): CollectionChangeRecord {
|
||||
_mismatch(record: CollectionChangeRecord, item, index: number): CollectionChangeRecord {
|
||||
// The previous record after which we will append the current one.
|
||||
var previousRecord: CollectionChangeRecord;
|
||||
|
||||
@ -213,20 +203,19 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
}
|
||||
|
||||
// Attempt to see if we have seen the item before.
|
||||
record = this._linkedRecords === null ? null : this._linkedRecords.get(itemTrackBy, index);
|
||||
record = this._linkedRecords === null ? null : this._linkedRecords.get(item, index);
|
||||
if (record !== null) {
|
||||
// We have seen this before, we need to move it forward in the collection.
|
||||
this._moveAfter(record, previousRecord, index);
|
||||
} else {
|
||||
// Never seen it, check evicted list.
|
||||
record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy);
|
||||
record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(item);
|
||||
if (record !== null) {
|
||||
// It is an item which we have evicted earlier: reinsert it back into the list.
|
||||
this._reinsertAfter(record, previousRecord, index);
|
||||
} else {
|
||||
// It is a new item: add it.
|
||||
record =
|
||||
this._addAfter(new CollectionChangeRecord(item, itemTrackBy), previousRecord, index);
|
||||
record = this._addAfter(new CollectionChangeRecord(item), previousRecord, index);
|
||||
}
|
||||
}
|
||||
return record;
|
||||
@ -259,17 +248,15 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
_verifyReinsertion(record: CollectionChangeRecord, item: any, itemTrackBy: any,
|
||||
index: number): CollectionChangeRecord {
|
||||
_verifyReinsertion(record: CollectionChangeRecord, item, index: number): CollectionChangeRecord {
|
||||
var reinsertRecord: CollectionChangeRecord =
|
||||
this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy);
|
||||
this._unlinkedRecords === null ? null : this._unlinkedRecords.get(item);
|
||||
if (reinsertRecord !== null) {
|
||||
record = this._reinsertAfter(reinsertRecord, record._prev, index);
|
||||
} else if (record.currentIndex != index) {
|
||||
record.currentIndex = index;
|
||||
this._addToMoves(record, index);
|
||||
}
|
||||
record.item = item;
|
||||
return record;
|
||||
}
|
||||
|
||||
@ -470,20 +457,31 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
var record: CollectionChangeRecord;
|
||||
|
||||
var list = [];
|
||||
this.forEachItem((record) => list.push(record));
|
||||
for (record = this._itHead; record !== null; record = record._next) {
|
||||
list.push(record);
|
||||
}
|
||||
|
||||
var previous = [];
|
||||
this.forEachPreviousItem((record) => previous.push(record));
|
||||
for (record = this._previousItHead; record !== null; record = record._nextPrevious) {
|
||||
previous.push(record);
|
||||
}
|
||||
|
||||
var additions = [];
|
||||
this.forEachAddedItem((record) => additions.push(record));
|
||||
|
||||
for (record = this._additionsHead; record !== null; record = record._nextAdded) {
|
||||
additions.push(record);
|
||||
}
|
||||
var moves = [];
|
||||
this.forEachMovedItem((record) => moves.push(record));
|
||||
for (record = this._movesHead; record !== null; record = record._nextMoved) {
|
||||
moves.push(record);
|
||||
}
|
||||
|
||||
var removals = [];
|
||||
this.forEachRemovedItem((record) => removals.push(record));
|
||||
for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
|
||||
removals.push(record);
|
||||
}
|
||||
|
||||
return "collection: " + list.join(', ') + "\n" + "previous: " + previous.join(', ') + "\n" +
|
||||
"additions: " + additions.join(', ') + "\n" + "moves: " + moves.join(', ') + "\n" +
|
||||
@ -514,7 +512,7 @@ export class CollectionChangeRecord {
|
||||
/** @internal */
|
||||
_nextMoved: CollectionChangeRecord = null;
|
||||
|
||||
constructor(public item: any, public trackById: any) {}
|
||||
constructor(public item: any) {}
|
||||
|
||||
toString(): string {
|
||||
return this.previousIndex === this.currentIndex ?
|
||||
@ -552,13 +550,13 @@ class _DuplicateItemRecordList {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a CollectionChangeRecord having CollectionChangeRecord.trackById == trackById and
|
||||
// Returns a CollectionChangeRecord having CollectionChangeRecord.item == item and
|
||||
// CollectionChangeRecord.currentIndex >= afterIndex
|
||||
get(trackById: any, afterIndex: number): CollectionChangeRecord {
|
||||
get(item: any, afterIndex: number): CollectionChangeRecord {
|
||||
var record: CollectionChangeRecord;
|
||||
for (record = this._head; record !== null; record = record._nextDup) {
|
||||
if ((afterIndex === null || afterIndex < record.currentIndex) &&
|
||||
looseIdentical(record.trackById, trackById)) {
|
||||
looseIdentical(record.item, item)) {
|
||||
return record;
|
||||
}
|
||||
}
|
||||
@ -601,7 +599,7 @@ class _DuplicateMap {
|
||||
|
||||
put(record: CollectionChangeRecord) {
|
||||
// todo(vicb) handle corner cases
|
||||
var key = getMapKey(record.trackById);
|
||||
var key = getMapKey(record.item);
|
||||
|
||||
var duplicates = this.map.get(key);
|
||||
if (!isPresent(duplicates)) {
|
||||
@ -612,17 +610,17 @@ class _DuplicateMap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the `value` using key. Because the CollectionChangeRecord value may be one which we
|
||||
* Retrieve the `value` using key. Because the CollectionChangeRecord value maybe one which we
|
||||
* have already iterated over, we use the afterIndex to pretend it is not there.
|
||||
*
|
||||
* Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
|
||||
* have any more `a`s needs to return the last `a` not the first or second.
|
||||
*/
|
||||
get(trackById: any, afterIndex: number = null): CollectionChangeRecord {
|
||||
var key = getMapKey(trackById);
|
||||
get(value: any, afterIndex: number = null): CollectionChangeRecord {
|
||||
var key = getMapKey(value);
|
||||
|
||||
var recordList = this.map.get(key);
|
||||
return isBlank(recordList) ? null : recordList.get(trackById, afterIndex);
|
||||
return isBlank(recordList) ? null : recordList.get(value, afterIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -631,7 +629,7 @@ class _DuplicateMap {
|
||||
* The list of duplicates also is removed from the map if it gets empty.
|
||||
*/
|
||||
remove(record: CollectionChangeRecord): CollectionChangeRecord {
|
||||
var key = getMapKey(record.trackById);
|
||||
var key = getMapKey(record.item);
|
||||
// todo(vicb)
|
||||
// assert(this.map.containsKey(key));
|
||||
var recordList: _DuplicateItemRecordList = this.map.get(key);
|
||||
|
@ -13,19 +13,12 @@ export interface IterableDiffer {
|
||||
onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* An optional function passed into {@link NgFor} that defines how to track
|
||||
* items in an iterable (e.g. by index or id)
|
||||
*/
|
||||
export interface TrackByFn { (index: number, item: any): any; }
|
||||
|
||||
|
||||
/**
|
||||
* Provides a factory for {@link IterableDiffer}.
|
||||
*/
|
||||
export interface IterableDifferFactory {
|
||||
supports(objects: any): boolean;
|
||||
create(cdRef: ChangeDetectorRef, trackByFn?: TrackByFn): IterableDiffer;
|
||||
create(cdRef: ChangeDetectorRef): IterableDiffer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -304,10 +304,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
||||
|
||||
if (proto.shouldBeChecked()) {
|
||||
var prevValue = this._readSelf(proto, values);
|
||||
var detectedChange = throwOnChange ?
|
||||
!ChangeDetectionUtil.devModeEqual(prevValue, currValue) :
|
||||
ChangeDetectionUtil.looseNotIdentical(prevValue, currValue);
|
||||
if (detectedChange) {
|
||||
if (ChangeDetectionUtil.looseNotIdentical(prevValue, currValue)) {
|
||||
if (proto.lastInBinding) {
|
||||
var change = ChangeDetectionUtil.simpleChange(prevValue, currValue);
|
||||
if (throwOnChange) this.throwOnChangeError(prevValue, currValue);
|
||||
@ -408,10 +405,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
||||
|
||||
if (proto.shouldBeChecked()) {
|
||||
var prevValue = this._readSelf(proto, values);
|
||||
var detectedChange = throwOnChange ?
|
||||
!ChangeDetectionUtil.devModeEqual(prevValue, currValue) :
|
||||
ChangeDetectionUtil.looseNotIdentical(prevValue, currValue);
|
||||
if (detectedChange) {
|
||||
if (ChangeDetectionUtil.looseNotIdentical(prevValue, currValue)) {
|
||||
currValue = ChangeDetectionUtil.unwrapValue(currValue);
|
||||
|
||||
if (proto.lastInBinding) {
|
||||
|
248
modules/angular2/src/core/debug/debug_element.ts
Normal file
248
modules/angular2/src/core/debug/debug_element.ts
Normal file
@ -0,0 +1,248 @@
|
||||
import {Type, isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||
import {ListWrapper, MapWrapper, Predicate} from 'angular2/src/facade/collection';
|
||||
import {unimplemented} from 'angular2/src/facade/exceptions';
|
||||
|
||||
import {AppElement} from 'angular2/src/core/linker/element';
|
||||
import {AppView} from 'angular2/src/core/linker/view';
|
||||
import {ElementRef, ElementRef_} from 'angular2/src/core/linker/element_ref';
|
||||
|
||||
/**
|
||||
* A DebugElement contains information from the Angular compiler about an
|
||||
* element and provides access to the corresponding ElementInjector and
|
||||
* underlying DOM Element, as well as a way to query for children.
|
||||
*
|
||||
* A DebugElement can be obtained from a {@link ComponentFixture} or from an
|
||||
* {@link ElementRef} via {@link inspectElement}.
|
||||
*/
|
||||
export abstract class DebugElement {
|
||||
/**
|
||||
* Return the instance of the component associated with this element, if any.
|
||||
*/
|
||||
get componentInstance(): any { return unimplemented(); };
|
||||
|
||||
/**
|
||||
* Return the native HTML element for this DebugElement.
|
||||
*/
|
||||
get nativeElement(): any { return unimplemented(); };
|
||||
|
||||
/**
|
||||
* Return an Angular {@link ElementRef} for this element.
|
||||
*/
|
||||
get elementRef(): ElementRef { return unimplemented(); };
|
||||
|
||||
/**
|
||||
* Get the directive active for this element with the given index, if any.
|
||||
*/
|
||||
abstract getDirectiveInstance(directiveIndex: number): any;
|
||||
|
||||
/**
|
||||
* Get child DebugElements from within the Light DOM.
|
||||
*
|
||||
* @return {DebugElement[]}
|
||||
*/
|
||||
get children(): DebugElement[] { return unimplemented(); };
|
||||
|
||||
/**
|
||||
* Get the root DebugElement children of a component. Returns an empty
|
||||
* list if the current DebugElement is not a component root.
|
||||
*
|
||||
* @return {DebugElement[]}
|
||||
*/
|
||||
get componentViewChildren(): DebugElement[] { return unimplemented(); };
|
||||
|
||||
/**
|
||||
* Simulate an event from this element as if the user had caused
|
||||
* this event to fire from the page.
|
||||
*/
|
||||
abstract triggerEventHandler(eventName: string, eventObj: Event): void;
|
||||
|
||||
/**
|
||||
* Check whether the element has a directive with the given type.
|
||||
*/
|
||||
abstract hasDirective(type: Type): boolean;
|
||||
|
||||
/**
|
||||
* Inject the given type from the element injector.
|
||||
*/
|
||||
abstract inject(type: Type): any;
|
||||
|
||||
|
||||
/**
|
||||
* Read a local variable from the element (e.g. one defined with `#variable`).
|
||||
*/
|
||||
abstract getLocal(name: string): any;
|
||||
|
||||
/**
|
||||
* Return the first descendant TestElement matching the given predicate
|
||||
* and scope.
|
||||
*
|
||||
* @param {Function: boolean} predicate
|
||||
* @param {Scope} scope
|
||||
*
|
||||
* @return {DebugElement}
|
||||
*/
|
||||
query(predicate: Predicate<DebugElement>, scope: Function = Scope.all): DebugElement {
|
||||
var results = this.queryAll(predicate, scope);
|
||||
return results.length > 0 ? results[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return descendant TestElememts matching the given predicate
|
||||
* and scope.
|
||||
*
|
||||
* @param {Function: boolean} predicate
|
||||
* @param {Scope} scope
|
||||
*
|
||||
* @return {DebugElement[]}
|
||||
*/
|
||||
queryAll(predicate: Predicate<DebugElement>, scope: Function = Scope.all): DebugElement[] {
|
||||
var elementsInScope: any[] = scope(this);
|
||||
|
||||
return elementsInScope.filter(predicate);
|
||||
}
|
||||
}
|
||||
|
||||
export class DebugElement_ extends DebugElement {
|
||||
constructor(private _appElement: AppElement) { super(); }
|
||||
|
||||
get componentInstance(): any {
|
||||
if (!isPresent(this._appElement)) {
|
||||
return null;
|
||||
}
|
||||
return this._appElement.getComponent();
|
||||
}
|
||||
|
||||
get nativeElement(): any { return this.elementRef.nativeElement; }
|
||||
|
||||
get elementRef(): ElementRef { return this._appElement.ref; }
|
||||
|
||||
getDirectiveInstance(directiveIndex: number): any {
|
||||
return this._appElement.getDirectiveAtIndex(directiveIndex);
|
||||
}
|
||||
|
||||
get children(): DebugElement[] {
|
||||
return this._getChildElements(this._appElement.parentView, this._appElement);
|
||||
}
|
||||
|
||||
get componentViewChildren(): DebugElement[] {
|
||||
if (!isPresent(this._appElement.componentView)) {
|
||||
// The current element is not a component.
|
||||
return [];
|
||||
}
|
||||
|
||||
return this._getChildElements(this._appElement.componentView, null);
|
||||
}
|
||||
|
||||
triggerEventHandler(eventName: string, eventObj: Event): void {
|
||||
this._appElement.parentView.triggerEventHandlers(eventName, eventObj,
|
||||
this._appElement.proto.index);
|
||||
}
|
||||
|
||||
hasDirective(type: Type): boolean {
|
||||
if (!isPresent(this._appElement)) {
|
||||
return false;
|
||||
}
|
||||
return this._appElement.hasDirective(type);
|
||||
}
|
||||
|
||||
inject(type: Type): any {
|
||||
if (!isPresent(this._appElement)) {
|
||||
return null;
|
||||
}
|
||||
return this._appElement.get(type);
|
||||
}
|
||||
|
||||
getLocal(name: string): any { return this._appElement.parentView.locals.get(name); }
|
||||
|
||||
/** @internal */
|
||||
_getChildElements(view: AppView, parentAppElement: AppElement): DebugElement[] {
|
||||
var els = [];
|
||||
for (var i = 0; i < view.appElements.length; ++i) {
|
||||
var appEl = view.appElements[i];
|
||||
if (appEl.parent == parentAppElement) {
|
||||
els.push(new DebugElement_(appEl));
|
||||
|
||||
var views = appEl.nestedViews;
|
||||
if (isPresent(views)) {
|
||||
views.forEach(
|
||||
(nextView) => { els = els.concat(this._getChildElements(nextView, null)); });
|
||||
}
|
||||
}
|
||||
}
|
||||
return els;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link DebugElement} for an {@link ElementRef}.
|
||||
*
|
||||
* @param {ElementRef}: elementRef
|
||||
* @return {DebugElement}
|
||||
*/
|
||||
export function inspectElement(elementRef: ElementRef): DebugElement {
|
||||
return new DebugElement_((<ElementRef_>elementRef).internalElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps an array of {@link DebugElement}s to an array of native DOM elements.
|
||||
*/
|
||||
export function asNativeElements(arr: DebugElement[]): any[] {
|
||||
return arr.map((debugEl) => debugEl.nativeElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set of scope functions used with {@link DebugElement}'s query functionality.
|
||||
*/
|
||||
export class Scope {
|
||||
/**
|
||||
* Scope queries to both the light dom and view of an element and its
|
||||
* children.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example core/debug/ts/debug_element/debug_element.ts region='scope_all'}
|
||||
*/
|
||||
static all(debugElement: DebugElement): DebugElement[] {
|
||||
var scope = [];
|
||||
scope.push(debugElement);
|
||||
|
||||
debugElement.children.forEach(child => scope = scope.concat(Scope.all(child)));
|
||||
|
||||
debugElement.componentViewChildren.forEach(child => scope = scope.concat(Scope.all(child)));
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope queries to the light dom of an element and its children.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example core/debug/ts/debug_element/debug_element.ts region='scope_light'}
|
||||
*/
|
||||
static light(debugElement: DebugElement): DebugElement[] {
|
||||
var scope = [];
|
||||
debugElement.children.forEach(child => {
|
||||
scope.push(child);
|
||||
scope = scope.concat(Scope.light(child));
|
||||
});
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope queries to the view of an element of its children.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example core/debug/ts/debug_element/debug_element.ts region='scope_view'}
|
||||
*/
|
||||
static view(debugElement: DebugElement): DebugElement[] {
|
||||
var scope = [];
|
||||
|
||||
debugElement.componentViewChildren.forEach(child => {
|
||||
scope.push(child);
|
||||
scope = scope.concat(Scope.light(child));
|
||||
});
|
||||
return scope;
|
||||
}
|
||||
}
|
@ -1,171 +0,0 @@
|
||||
import {isPresent} from 'angular2/src/facade/lang';
|
||||
import {Predicate} from 'angular2/src/facade/collection';
|
||||
import {Injector} from 'angular2/src/core/di';
|
||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {RenderDebugInfo} from 'angular2/src/core/render/api';
|
||||
|
||||
export class EventListener { constructor(public name: string, public callback: Function){}; }
|
||||
|
||||
export class DebugNode {
|
||||
nativeNode: any;
|
||||
listeners: EventListener[];
|
||||
parent: DebugElement;
|
||||
providerTokens: any[];
|
||||
locals: Map<string, any>;
|
||||
injector: Injector;
|
||||
componentInstance: any;
|
||||
|
||||
constructor(nativeNode: any, parent: DebugNode) {
|
||||
this.nativeNode = nativeNode;
|
||||
if (isPresent(parent) && parent instanceof DebugElement) {
|
||||
parent.addChild(this);
|
||||
} else {
|
||||
this.parent = null;
|
||||
}
|
||||
this.listeners = [];
|
||||
this.providerTokens = [];
|
||||
}
|
||||
|
||||
setDebugInfo(info: RenderDebugInfo) {
|
||||
this.injector = info.injector;
|
||||
this.providerTokens = info.providerTokens;
|
||||
this.locals = info.locals;
|
||||
this.componentInstance = info.component;
|
||||
}
|
||||
|
||||
inject(token: any): any { return this.injector.get(token); }
|
||||
|
||||
getLocal(name: string): any { return this.locals.get(name); }
|
||||
}
|
||||
|
||||
export class DebugElement extends DebugNode {
|
||||
name: string;
|
||||
properties: Map<string, any>;
|
||||
attributes: Map<string, any>;
|
||||
childNodes: DebugNode[];
|
||||
nativeElement: any;
|
||||
|
||||
constructor(nativeNode: any, parent: any) {
|
||||
super(nativeNode, parent);
|
||||
this.properties = new Map<string, any>();
|
||||
this.attributes = new Map<string, any>();
|
||||
this.childNodes = [];
|
||||
this.nativeElement = nativeNode;
|
||||
}
|
||||
|
||||
addChild(child: DebugNode) {
|
||||
if (isPresent(child)) {
|
||||
this.childNodes.push(child);
|
||||
child.parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
removeChild(child: DebugNode) {
|
||||
var childIndex = this.childNodes.indexOf(child);
|
||||
if (childIndex !== -1) {
|
||||
child.parent = null;
|
||||
this.childNodes.splice(childIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
insertChildrenAfter(child: DebugNode, newChildren: DebugNode[]) {
|
||||
var siblingIndex = this.childNodes.indexOf(child);
|
||||
if (siblingIndex !== -1) {
|
||||
var previousChildren = this.childNodes.slice(0, siblingIndex + 1);
|
||||
var nextChildren = this.childNodes.slice(siblingIndex + 1);
|
||||
this.childNodes =
|
||||
ListWrapper.concat(ListWrapper.concat(previousChildren, newChildren), nextChildren);
|
||||
for (var i = 0; i < newChildren.length; ++i) {
|
||||
var newChild = newChildren[i];
|
||||
if (isPresent(newChild.parent)) {
|
||||
newChild.parent.removeChild(newChild);
|
||||
}
|
||||
newChild.parent = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query(predicate: Predicate<DebugElement>): DebugElement {
|
||||
var results = this.queryAll(predicate);
|
||||
return results.length > 0 ? results[0] : null;
|
||||
}
|
||||
|
||||
queryAll(predicate: Predicate<DebugElement>): DebugElement[] {
|
||||
var matches = [];
|
||||
_queryElementChildren(this, predicate, matches);
|
||||
return matches;
|
||||
}
|
||||
|
||||
queryAllNodes(predicate: Predicate<DebugNode>): DebugNode[] {
|
||||
var matches = [];
|
||||
_queryNodeChildren(this, predicate, matches);
|
||||
return matches;
|
||||
}
|
||||
|
||||
get children(): DebugElement[] {
|
||||
var children = [];
|
||||
this.childNodes.forEach((node) => {
|
||||
if (node instanceof DebugElement) {
|
||||
children.push(node);
|
||||
}
|
||||
});
|
||||
return children;
|
||||
}
|
||||
|
||||
triggerEventHandler(eventName: string, eventObj: Event) {
|
||||
this.listeners.forEach((listener) => {
|
||||
if (listener.name == eventName) {
|
||||
listener.callback(eventObj);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function asNativeElements(debugEls: DebugElement[]): any {
|
||||
return debugEls.map((el) => el.nativeElement);
|
||||
}
|
||||
|
||||
function _queryElementChildren(element: DebugElement, predicate: Predicate<DebugElement>,
|
||||
matches: DebugElement[]) {
|
||||
element.childNodes.forEach(node => {
|
||||
if (node instanceof DebugElement) {
|
||||
if (predicate(node)) {
|
||||
matches.push(node);
|
||||
}
|
||||
_queryElementChildren(node, predicate, matches);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _queryNodeChildren(parentNode: DebugNode, predicate: Predicate<DebugNode>,
|
||||
matches: DebugNode[]) {
|
||||
if (parentNode instanceof DebugElement) {
|
||||
parentNode.childNodes.forEach(node => {
|
||||
if (predicate(node)) {
|
||||
matches.push(node);
|
||||
}
|
||||
if (node instanceof DebugElement) {
|
||||
_queryNodeChildren(node, predicate, matches);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Need to keep the nodes in a global Map so that multiple angular apps are supported.
|
||||
var _nativeNodeToDebugNode = new Map<any, DebugNode>();
|
||||
|
||||
export function getDebugNode(nativeNode: any): DebugNode {
|
||||
return _nativeNodeToDebugNode.get(nativeNode);
|
||||
}
|
||||
|
||||
export function getAllDebugNodes(): DebugNode[] {
|
||||
return MapWrapper.values(_nativeNodeToDebugNode);
|
||||
}
|
||||
|
||||
export function indexDebugNode(node: DebugNode) {
|
||||
_nativeNodeToDebugNode.set(node.nativeNode, node);
|
||||
}
|
||||
|
||||
export function removeDebugNodeFromIndex(node: DebugNode) {
|
||||
_nativeNodeToDebugNode.delete(node.nativeNode);
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
import {isPresent} from 'angular2/src/facade/lang';
|
||||
import {
|
||||
Renderer,
|
||||
RootRenderer,
|
||||
RenderComponentType,
|
||||
RenderDebugInfo
|
||||
} from 'angular2/src/core/render/api';
|
||||
import {
|
||||
DebugNode,
|
||||
DebugElement,
|
||||
EventListener,
|
||||
getDebugNode,
|
||||
indexDebugNode,
|
||||
removeDebugNodeFromIndex
|
||||
} from 'angular2/src/core/debug/debug_node';
|
||||
|
||||
export class DebugDomRootRenderer implements RootRenderer {
|
||||
constructor(private _delegate: RootRenderer) {}
|
||||
|
||||
renderComponent(componentProto: RenderComponentType): Renderer {
|
||||
return new DebugDomRenderer(this, this._delegate.renderComponent(componentProto));
|
||||
}
|
||||
}
|
||||
|
||||
export class DebugDomRenderer implements Renderer {
|
||||
constructor(private _rootRenderer: DebugDomRootRenderer, private _delegate: Renderer) {}
|
||||
|
||||
renderComponent(componentType: RenderComponentType): Renderer {
|
||||
return this._rootRenderer.renderComponent(componentType);
|
||||
}
|
||||
|
||||
selectRootElement(selector: string): any {
|
||||
var nativeEl = this._delegate.selectRootElement(selector);
|
||||
var debugEl = new DebugElement(nativeEl, null);
|
||||
indexDebugNode(debugEl);
|
||||
return nativeEl;
|
||||
}
|
||||
|
||||
createElement(parentElement: any, name: string): any {
|
||||
var nativeEl = this._delegate.createElement(parentElement, name);
|
||||
var debugEl = new DebugElement(nativeEl, getDebugNode(parentElement));
|
||||
debugEl.name = name;
|
||||
indexDebugNode(debugEl);
|
||||
return nativeEl;
|
||||
}
|
||||
|
||||
createViewRoot(hostElement: any): any { return this._delegate.createViewRoot(hostElement); }
|
||||
|
||||
createTemplateAnchor(parentElement: any): any {
|
||||
var comment = this._delegate.createTemplateAnchor(parentElement);
|
||||
var debugEl = new DebugNode(comment, getDebugNode(parentElement));
|
||||
indexDebugNode(debugEl);
|
||||
return comment;
|
||||
}
|
||||
|
||||
createText(parentElement: any, value: string): any {
|
||||
var text = this._delegate.createText(parentElement, value);
|
||||
var debugEl = new DebugNode(text, getDebugNode(parentElement));
|
||||
indexDebugNode(debugEl);
|
||||
return text;
|
||||
}
|
||||
|
||||
projectNodes(parentElement: any, nodes: any[]) {
|
||||
var debugParent = getDebugNode(parentElement);
|
||||
if (isPresent(debugParent) && debugParent instanceof DebugElement) {
|
||||
nodes.forEach((node) => { debugParent.addChild(getDebugNode(node)); });
|
||||
}
|
||||
return this._delegate.projectNodes(parentElement, nodes);
|
||||
}
|
||||
|
||||
attachViewAfter(node: any, viewRootNodes: any[]) {
|
||||
var debugNode = getDebugNode(node);
|
||||
if (isPresent(debugNode)) {
|
||||
var debugParent = debugNode.parent;
|
||||
if (viewRootNodes.length > 0 && isPresent(debugParent)) {
|
||||
var debugViewRootNodes = [];
|
||||
viewRootNodes.forEach((rootNode) => debugViewRootNodes.push(getDebugNode(rootNode)));
|
||||
debugParent.insertChildrenAfter(debugNode, debugViewRootNodes);
|
||||
}
|
||||
}
|
||||
return this._delegate.attachViewAfter(node, viewRootNodes);
|
||||
}
|
||||
|
||||
detachView(viewRootNodes: any[]) {
|
||||
viewRootNodes.forEach((node) => {
|
||||
var debugNode = getDebugNode(node);
|
||||
if (isPresent(debugNode) && isPresent(debugNode.parent)) {
|
||||
debugNode.parent.removeChild(debugNode);
|
||||
}
|
||||
});
|
||||
return this._delegate.detachView(viewRootNodes);
|
||||
}
|
||||
|
||||
destroyView(hostElement: any, viewAllNodes: any[]) {
|
||||
viewAllNodes.forEach((node) => { removeDebugNodeFromIndex(getDebugNode(node)); });
|
||||
return this._delegate.destroyView(hostElement, viewAllNodes);
|
||||
}
|
||||
|
||||
listen(renderElement: any, name: string, callback: Function) {
|
||||
var debugEl = getDebugNode(renderElement);
|
||||
if (isPresent(debugEl)) {
|
||||
debugEl.listeners.push(new EventListener(name, callback));
|
||||
}
|
||||
return this._delegate.listen(renderElement, name, callback);
|
||||
}
|
||||
|
||||
listenGlobal(target: string, name: string, callback: Function): Function {
|
||||
return this._delegate.listenGlobal(target, name, callback);
|
||||
}
|
||||
|
||||
setElementProperty(renderElement: any, propertyName: string, propertyValue: any) {
|
||||
var debugEl = getDebugNode(renderElement);
|
||||
if (isPresent(debugEl) && debugEl instanceof DebugElement) {
|
||||
debugEl.properties.set(propertyName, propertyValue);
|
||||
}
|
||||
return this._delegate.setElementProperty(renderElement, propertyName, propertyValue);
|
||||
}
|
||||
|
||||
setElementAttribute(renderElement: any, attributeName: string, attributeValue: string) {
|
||||
var debugEl = getDebugNode(renderElement);
|
||||
if (isPresent(debugEl) && debugEl instanceof DebugElement) {
|
||||
debugEl.attributes.set(attributeName, attributeValue);
|
||||
}
|
||||
return this._delegate.setElementAttribute(renderElement, attributeName, attributeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used only in debug mode to serialize property changes to comment nodes,
|
||||
* such as <template> placeholders.
|
||||
*/
|
||||
setBindingDebugInfo(renderElement: any, propertyName: string, propertyValue: string) {
|
||||
return this._delegate.setBindingDebugInfo(renderElement, propertyName, propertyValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used only in development mode to set information needed by the DebugNode for this element.
|
||||
*/
|
||||
setElementDebugInfo(renderElement: any, info: RenderDebugInfo) {
|
||||
var debugEl = getDebugNode(renderElement);
|
||||
debugEl.setDebugInfo(info);
|
||||
return this._delegate.setElementDebugInfo(renderElement, info);
|
||||
}
|
||||
|
||||
setElementClass(renderElement: any, className: string, isAdd: boolean) {
|
||||
return this._delegate.setElementClass(renderElement, className, isAdd);
|
||||
}
|
||||
|
||||
setElementStyle(renderElement: any, styleName: string, styleValue: string) {
|
||||
return this._delegate.setElementStyle(renderElement, styleName, styleValue);
|
||||
}
|
||||
|
||||
invokeElementMethod(renderElement: any, methodName: string, args: any[]) {
|
||||
return this._delegate.invokeElementMethod(renderElement, methodName, args);
|
||||
}
|
||||
|
||||
setText(renderNode: any, text: string) { return this._delegate.setText(renderNode, text); }
|
||||
}
|
@ -463,11 +463,7 @@ export class AppElement implements DependencyProvider, ElementRef, AfterViewChec
|
||||
var inj: AppElement = this;
|
||||
while (isPresent(inj)) {
|
||||
inj._setQueriesAsDirty();
|
||||
if (isBlank(inj.parent) && inj.parentView.proto.type === ViewType.EMBEDDED) {
|
||||
inj = inj.parentView.containerAppElement;
|
||||
} else {
|
||||
inj = inj.parent;
|
||||
}
|
||||
inj = inj.parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ import {
|
||||
CONST_EXPR
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||
import {Renderer, RootRenderer, RenderDebugInfo} from 'angular2/src/core/render/api';
|
||||
import {Renderer, RootRenderer} from 'angular2/src/core/render/api';
|
||||
import {ViewRef_, HostViewFactoryRef} from './view_ref';
|
||||
import {ProtoPipes} from 'angular2/src/core/pipes/pipes';
|
||||
import {camelCaseToDashCase} from 'angular2/src/core/render/util';
|
||||
@ -119,12 +119,6 @@ export class AppView implements ChangeDispatcher {
|
||||
(templateName, _) => { localsMap.set(templateName, null); });
|
||||
for (var i = 0; i < appElements.length; i++) {
|
||||
var appEl = appElements[i];
|
||||
var providerTokens = [];
|
||||
if (isPresent(appEl.proto.protoInjector)) {
|
||||
for (var j = 0; j < appEl.proto.protoInjector.numberOfProviders; j++) {
|
||||
providerTokens.push(appEl.proto.protoInjector.getProviderAtIndex(j).key.token);
|
||||
}
|
||||
}
|
||||
StringMapWrapper.forEach(appEl.proto.directiveVariableBindings, (directiveIndex, name) => {
|
||||
if (isBlank(directiveIndex)) {
|
||||
localsMap.set(name, appEl.nativeElement);
|
||||
@ -132,9 +126,6 @@ export class AppView implements ChangeDispatcher {
|
||||
localsMap.set(name, appEl.getDirectiveAtIndex(directiveIndex));
|
||||
}
|
||||
});
|
||||
this.renderer.setElementDebugInfo(
|
||||
appEl.nativeElement, new RenderDebugInfo(appEl.getInjector(), appEl.getComponent(),
|
||||
providerTokens, localsMap));
|
||||
}
|
||||
var parentLocals = null;
|
||||
if (this.proto.type !== ViewType.COMPONENT) {
|
||||
|
11
modules/angular2/src/core/linker/view_listener.ts
Normal file
11
modules/angular2/src/core/linker/view_listener.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import {Injectable} from 'angular2/src/core/di';
|
||||
import * as viewModule from './view';
|
||||
|
||||
/**
|
||||
* Listener for view creation / destruction.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AppViewListener {
|
||||
onViewCreated(view: viewModule.AppView) {}
|
||||
onViewDestroyed(view: viewModule.AppView) {}
|
||||
}
|
@ -22,6 +22,7 @@ import {
|
||||
} from './view_ref';
|
||||
import {ViewContainerRef} from './view_container_ref';
|
||||
import {TemplateRef, TemplateRef_} from './template_ref';
|
||||
import {AppViewListener} from './view_listener';
|
||||
import {RootRenderer, RenderComponentType} from 'angular2/src/core/render/api';
|
||||
import {wtfCreateScope, wtfLeave, WtfScopeFn} from '../profile/profile';
|
||||
import {APP_ID} from 'angular2/src/core/application_tokens';
|
||||
@ -184,7 +185,10 @@ export abstract class AppViewManager {
|
||||
export class AppViewManager_ extends AppViewManager {
|
||||
private _nextCompTypeId: number = 0;
|
||||
|
||||
constructor(private _renderer: RootRenderer, @Inject(APP_ID) private _appId: string) { super(); }
|
||||
constructor(private _renderer: RootRenderer, private _viewListener: AppViewListener,
|
||||
@Inject(APP_ID) private _appId: string) {
|
||||
super();
|
||||
}
|
||||
|
||||
getViewContainer(location: ElementRef): ViewContainerRef {
|
||||
return (<ElementRef_>location).internalElement.getViewContainerRef();
|
||||
@ -312,10 +316,10 @@ export class AppViewManager_ extends AppViewManager {
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
onViewCreated(view: AppView) {}
|
||||
onViewCreated(view: AppView) { this._viewListener.onViewCreated(view); }
|
||||
|
||||
/** @internal */
|
||||
onViewDestroyed(view: AppView) {}
|
||||
onViewDestroyed(view: AppView) { this._viewListener.onViewDestroyed(view); }
|
||||
|
||||
/** @internal */
|
||||
createRenderComponentType(encapsulation: ViewEncapsulation,
|
||||
|
@ -1268,7 +1268,7 @@ export var Input: InputFactory = makePropDecorator(InputMetadata);
|
||||
* @Component({
|
||||
* selector: 'app',
|
||||
* template: `
|
||||
* <interval-dir (everySecond)="everySecond()" (everyFiveSeconds)="everyFiveSeconds()">
|
||||
* <interval-dir (every-second)="everySecond()" (every-five-seconds)="everyFiveSeconds()">
|
||||
* </interval-dir>
|
||||
* `,
|
||||
* directives: [IntervalDir]
|
||||
|
@ -504,7 +504,7 @@ export class DirectiveMetadata extends InjectableMetadata {
|
||||
* @Component({
|
||||
* selector: 'app',
|
||||
* template: `
|
||||
* <interval-dir (everySecond)="everySecond()" (everyFiveSeconds)="everyFiveSeconds()">
|
||||
* <interval-dir (every-second)="everySecond()" (every-five-seconds)="everyFiveSeconds()">
|
||||
* </interval-dir>
|
||||
* `,
|
||||
* directives: [IntervalDir]
|
||||
@ -1035,7 +1035,7 @@ export class InputMetadata {
|
||||
* @Component({
|
||||
* selector: 'app',
|
||||
* template: `
|
||||
* <interval-dir (everySecond)="everySecond()" (everyFiveSeconds)="everyFiveSeconds()">
|
||||
* <interval-dir (every-second)="everySecond()" (every-five-seconds)="everyFiveSeconds()">
|
||||
* </interval-dir>
|
||||
* `,
|
||||
* directives: [IntervalDir]
|
||||
|
@ -1,16 +1,10 @@
|
||||
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
|
||||
import {Injector} from 'angular2/src/core/di/injector';
|
||||
|
||||
export class RenderComponentType {
|
||||
constructor(public id: string, public encapsulation: ViewEncapsulation,
|
||||
public styles: Array<string | any[]>) {}
|
||||
}
|
||||
|
||||
export class RenderDebugInfo {
|
||||
constructor(public injector: Injector, public component: any, public providerTokens: any[],
|
||||
public locals: Map<string, any>) {}
|
||||
}
|
||||
|
||||
export interface ParentRenderer { renderComponent(componentType: RenderComponentType): Renderer; }
|
||||
|
||||
export abstract class Renderer implements ParentRenderer {
|
||||
@ -48,8 +42,6 @@ export abstract class Renderer implements ParentRenderer {
|
||||
*/
|
||||
abstract setBindingDebugInfo(renderElement: any, propertyName: string, propertyValue: string);
|
||||
|
||||
abstract setElementDebugInfo(renderElement: any, info: RenderDebugInfo);
|
||||
|
||||
abstract setElementClass(renderElement: any, className: string, isAdd: boolean);
|
||||
|
||||
abstract setElementStyle(renderElement: any, styleName: string, styleValue: string);
|
||||
|
@ -422,14 +422,14 @@ export class NgZone {
|
||||
fn();
|
||||
ListWrapper.remove(ngZone._pendingTimeouts, id);
|
||||
};
|
||||
id = parentSetTimeout.call(this, cb, delay, args);
|
||||
id = parentSetTimeout(cb, delay, args);
|
||||
ngZone._pendingTimeouts.push(id);
|
||||
return id;
|
||||
};
|
||||
},
|
||||
'$clearTimeout': function(parentClearTimeout) {
|
||||
return function(id: number) {
|
||||
parentClearTimeout.call(this, id);
|
||||
parentClearTimeout(id);
|
||||
ListWrapper.remove(ngZone._pendingTimeouts, id);
|
||||
};
|
||||
},
|
||||
|
@ -225,19 +225,6 @@ class ListWrapper {
|
||||
|
||||
bool isListLikeIterable(obj) => obj is Iterable;
|
||||
|
||||
bool areIterablesEqual(Iterable a, Iterable b, Function comparator) {
|
||||
var iterator1 = a.iterator;
|
||||
var iterator2 = b.iterator;
|
||||
|
||||
while (true) {
|
||||
var done1 = !iterator1.moveNext();
|
||||
var done2 = !iterator2.moveNext();
|
||||
if (done1 && done2) return true;
|
||||
if (done1 || done2) return false;
|
||||
if (!comparator(iterator2.current, iterator2.current)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
void iterateListLike(iter, fn(item)) {
|
||||
assert(iter is Iterable);
|
||||
for (var item in iter) {
|
||||
|
@ -274,19 +274,6 @@ export function isListLikeIterable(obj: any): boolean {
|
||||
getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
|
||||
}
|
||||
|
||||
export function areIterablesEqual(a: any, b: any, comparator: Function): boolean {
|
||||
var iterator1 = a[getSymbolIterator()]();
|
||||
var iterator2 = b[getSymbolIterator()]();
|
||||
|
||||
while (true) {
|
||||
let item1 = iterator1.next();
|
||||
let item2 = iterator2.next();
|
||||
if (item1.done && item2.done) return true;
|
||||
if (item1.done || item2.done) return false;
|
||||
if (!comparator(item1.value, item2.value)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function iterateListLike(obj: any, fn: Function) {
|
||||
if (isArray(obj)) {
|
||||
for (var i = 0; i < obj.length; i++) {
|
||||
|
@ -345,8 +345,6 @@ class DateWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
bool isPrimitive(Object obj) => obj is num || obj is bool || obj == null || obj is String;
|
||||
|
||||
// needed to match the exports from lang.js
|
||||
var global = null;
|
||||
|
||||
|
@ -427,7 +427,3 @@ export function evalExpression(sourceUrl: string, expr: string, declarations: st
|
||||
}
|
||||
return new Function(...fnArgNames.concat(fnBody))(...fnArgValues);
|
||||
}
|
||||
|
||||
export function isPrimitive(obj: any): boolean {
|
||||
return !isJsObject(obj);
|
||||
}
|
@ -98,15 +98,15 @@ export class MockConnection implements Connection {
|
||||
* ### Example
|
||||
*
|
||||
* ```
|
||||
* import {BaseRequestOptions, Http} from 'angular2/http';
|
||||
* import {DefaultOptions, Http} from 'angular2/http';
|
||||
* import {MockBackend} from 'angular2/http/testing';
|
||||
* it('should get some data', inject([AsyncTestCompleter], (async) => {
|
||||
* var connection;
|
||||
* var injector = Injector.resolveAndCreate([
|
||||
* MockBackend,
|
||||
* provide(Http, {useFactory: (backend, options) => {
|
||||
* return new Http(backend, options);
|
||||
* }, deps: [MockBackend, BaseRequestOptions]})]);
|
||||
* provide(Http, {useFactory: (backend, defaultOptions) => {
|
||||
* return new Http(backend, defaultOptions)
|
||||
* }, deps: [MockBackend, DefaultOptions]})]);
|
||||
* var http = injector.get(Http);
|
||||
* var backend = injector.get(MockBackend);
|
||||
* //Assign any newly-created connection to local variable
|
||||
|
@ -30,12 +30,12 @@ import {BrowserDomAdapter} from './browser/browser_adapter';
|
||||
import {BrowserGetTestability} from 'angular2/src/platform/browser/testability';
|
||||
import {wtfInit} from 'angular2/src/core/profile/wtf_init';
|
||||
import {EventManager, EVENT_MANAGER_PLUGINS} from "angular2/src/platform/dom/events/event_manager";
|
||||
import {ELEMENT_PROBE_PROVIDERS} from 'angular2/platform/common_dom';
|
||||
export {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
||||
export {Title} from 'angular2/src/platform/browser/title';
|
||||
export {
|
||||
DebugElementViewListener,
|
||||
ELEMENT_PROBE_PROVIDERS,
|
||||
ELEMENT_PROBE_PROVIDERS_PROD_MODE,
|
||||
ELEMENT_PROBE_BINDINGS,
|
||||
inspectNativeElement,
|
||||
By
|
||||
} from 'angular2/platform/common_dom';
|
||||
@ -84,8 +84,7 @@ export const BROWSER_APP_COMMON_PROVIDERS: Array<any /*Type | Provider | any[]*/
|
||||
Testability,
|
||||
BrowserDetails,
|
||||
AnimationBuilder,
|
||||
EventManager,
|
||||
ELEMENT_PROBE_PROVIDERS
|
||||
EventManager
|
||||
]);
|
||||
|
||||
export function initDomAdapter() {
|
||||
|
@ -39,6 +39,6 @@ export class By {
|
||||
* {@example platform/dom/debug/ts/by/by.ts region='by_directive'}
|
||||
*/
|
||||
static directive(type: Type): Predicate<DebugElement> {
|
||||
return (debugElement) => { return debugElement.providerTokens.indexOf(type) !== -1; };
|
||||
return (debugElement) => { return debugElement.hasDirective(type); };
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
import {CONST_EXPR, isPresent, NumberWrapper, StringWrapper} from 'angular2/src/facade/lang';
|
||||
import {MapWrapper, Map, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {Injectable, provide, Provider} from 'angular2/src/core/di';
|
||||
import {AppViewListener} from 'angular2/src/core/linker/view_listener';
|
||||
import {AppView} from 'angular2/src/core/linker/view';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {DebugElement, DebugElement_} from 'angular2/src/core/debug/debug_element';
|
||||
|
||||
const NG_ID_PROPERTY = 'ngid';
|
||||
const INSPECT_GLOBAL_NAME = 'ng.probe';
|
||||
|
||||
const NG_ID_SEPARATOR = '#';
|
||||
|
||||
// Need to keep the views in a global Map so that multiple angular apps are supported
|
||||
var _allIdsByView = new Map<AppView, number>();
|
||||
var _allViewsById = new Map<number, AppView>();
|
||||
|
||||
var _nextId = 0;
|
||||
|
||||
function _setElementId(element, indices: number[]) {
|
||||
if (isPresent(element) && DOM.isElementNode(element)) {
|
||||
DOM.setData(element, NG_ID_PROPERTY, indices.join(NG_ID_SEPARATOR));
|
||||
}
|
||||
}
|
||||
|
||||
function _getElementId(element): number[] {
|
||||
var elId = DOM.getData(element, NG_ID_PROPERTY);
|
||||
if (isPresent(elId)) {
|
||||
return elId.split(NG_ID_SEPARATOR).map(partStr => NumberWrapper.parseInt(partStr, 10));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link DebugElement} for the given native DOM element, or
|
||||
* null if the given native element does not have an Angular view associated
|
||||
* with it.
|
||||
*/
|
||||
export function inspectNativeElement(element): DebugElement {
|
||||
var elId = _getElementId(element);
|
||||
if (isPresent(elId)) {
|
||||
var view = _allViewsById.get(elId[0]);
|
||||
if (isPresent(view)) {
|
||||
return new DebugElement_(view.appElements[elId[1]]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class DebugElementViewListener implements AppViewListener {
|
||||
constructor() { DOM.setGlobalVar(INSPECT_GLOBAL_NAME, inspectNativeElement); }
|
||||
|
||||
onViewCreated(view: AppView) {
|
||||
var viewId = _nextId++;
|
||||
_allViewsById.set(viewId, view);
|
||||
_allIdsByView.set(view, viewId);
|
||||
for (var i = 0; i < view.appElements.length; i++) {
|
||||
var el = view.appElements[i];
|
||||
_setElementId(el.nativeElement, [viewId, i]);
|
||||
}
|
||||
}
|
||||
|
||||
onViewDestroyed(view: AppView) {
|
||||
var viewId = _allIdsByView.get(view);
|
||||
_allIdsByView.delete(view);
|
||||
_allViewsById.delete(viewId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Providers which support debugging Angular applications (e.g. via `ng.probe`).
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example platform/dom/debug/ts/debug_element_view_listener/providers.ts region='providers'}
|
||||
*/
|
||||
export const ELEMENT_PROBE_PROVIDERS: any[] = CONST_EXPR([
|
||||
DebugElementViewListener,
|
||||
CONST_EXPR(new Provider(AppViewListener, {useExisting: DebugElementViewListener})),
|
||||
]);
|
||||
|
||||
/**
|
||||
* Use {@link ELEMENT_PROBE_PROVIDERS}.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export const ELEMENT_PROBE_BINDINGS = ELEMENT_PROBE_PROVIDERS;
|
@ -1,42 +0,0 @@
|
||||
import {CONST_EXPR, assertionsEnabled, isPresent} from 'angular2/src/facade/lang';
|
||||
import {Injectable, provide, Provider} from 'angular2/src/core/di';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {DebugNode, getDebugNode} from 'angular2/src/core/debug/debug_node';
|
||||
import {DomRootRenderer} from 'angular2/src/platform/dom/dom_renderer';
|
||||
import {RootRenderer} from 'angular2/core';
|
||||
import {DebugDomRootRenderer} from 'angular2/src/core/debug/debug_renderer';
|
||||
|
||||
|
||||
const INSPECT_GLOBAL_NAME = 'ng.probe';
|
||||
|
||||
/**
|
||||
* Returns a {@link DebugElement} for the given native DOM element, or
|
||||
* null if the given native element does not have an Angular view associated
|
||||
* with it.
|
||||
*/
|
||||
export function inspectNativeElement(element): DebugNode {
|
||||
return getDebugNode(element);
|
||||
}
|
||||
|
||||
function _createConditionalRootRenderer(rootRenderer) {
|
||||
if (assertionsEnabled()) {
|
||||
return _createRootRenderer(rootRenderer);
|
||||
}
|
||||
return rootRenderer;
|
||||
}
|
||||
|
||||
function _createRootRenderer(rootRenderer) {
|
||||
DOM.setGlobalVar(INSPECT_GLOBAL_NAME, inspectNativeElement);
|
||||
return new DebugDomRootRenderer(rootRenderer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Providers which support debugging Angular applications (e.g. via `ng.probe`).
|
||||
*/
|
||||
export const ELEMENT_PROBE_PROVIDERS: any[] = CONST_EXPR([
|
||||
new Provider(RootRenderer,
|
||||
{useFactory: _createConditionalRootRenderer, deps: [DomRootRenderer]})
|
||||
]);
|
||||
|
||||
export const ELEMENT_PROBE_PROVIDERS_PROD_MODE: any[] = CONST_EXPR(
|
||||
[new Provider(RootRenderer, {useFactory: _createRootRenderer, deps: [DomRootRenderer]})]);
|
@ -14,12 +14,7 @@ import {
|
||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||
import {DomSharedStylesHost} from './shared_styles_host';
|
||||
|
||||
import {
|
||||
Renderer,
|
||||
RootRenderer,
|
||||
RenderComponentType,
|
||||
RenderDebugInfo
|
||||
} from 'angular2/src/core/render/api';
|
||||
import {Renderer, RootRenderer, RenderComponentType} from 'angular2/core';
|
||||
|
||||
import {EventManager} from './events/event_manager';
|
||||
|
||||
@ -206,8 +201,6 @@ export class DomRenderer implements Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
setElementDebugInfo(renderElement: any, info: RenderDebugInfo) {}
|
||||
|
||||
setElementClass(renderElement: any, className: string, isAdd: boolean): void {
|
||||
if (isAdd) {
|
||||
DOM.addClass(renderElement, className);
|
||||
|
@ -36,7 +36,6 @@ import {BrowserDomAdapter} from './browser/browser_adapter';
|
||||
import {wtfInit} from 'angular2/src/core/profile/wtf_init';
|
||||
import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer';
|
||||
import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl';
|
||||
import {BrowserPlatformLocation} from 'angular2/src/router/browser_platform_location';
|
||||
import {
|
||||
ServiceMessageBrokerFactory,
|
||||
ServiceMessageBrokerFactory_
|
||||
@ -60,13 +59,6 @@ export const WORKER_RENDER_PLATFORM: Array<any /*Type | Provider | any[]*/> = CO
|
||||
new Provider(PLATFORM_INITIALIZER, {useValue: initWebWorkerRenderPlatform, multi: true})
|
||||
]);
|
||||
|
||||
/**
|
||||
* A list of {@link Provider}s. To use the router in a Worker enabled application you must
|
||||
* include these providers when setting up the render thread.
|
||||
*/
|
||||
export const WORKER_RENDER_ROUTER: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([BrowserPlatformLocation]);
|
||||
|
||||
export const WORKER_RENDER_APPLICATION_COMMON: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
|
||||
APPLICATION_COMMON_PROVIDERS,
|
||||
WORKER_RENDER_MESSAGING_PROVIDERS,
|
||||
|
@ -1,58 +0,0 @@
|
||||
import {Injectable} from 'angular2/core';
|
||||
import {History, Location} from 'angular2/src/facade/browser';
|
||||
import {UrlChangeListener} from './platform_location';
|
||||
import {PlatformLocation} from './platform_location';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
|
||||
/**
|
||||
* `PlatformLocation` encapsulates all of the direct calls to platform APIs.
|
||||
* This class should not be used directly by an application developer. Instead, use
|
||||
* {@link Location}.
|
||||
*/
|
||||
@Injectable()
|
||||
export class BrowserPlatformLocation extends PlatformLocation {
|
||||
private _location: Location;
|
||||
private _history: History;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._init();
|
||||
}
|
||||
|
||||
// This is moved to its own method so that `MockPlatformLocationStrategy` can overwrite it
|
||||
/** @internal */
|
||||
_init() {
|
||||
this._location = DOM.getLocation();
|
||||
this._history = DOM.getHistory();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
get location(): Location { return this._location; }
|
||||
|
||||
getBaseHrefFromDOM(): string { return DOM.getBaseHref(); }
|
||||
|
||||
onPopState(fn: UrlChangeListener): void {
|
||||
DOM.getGlobalEventTarget('window').addEventListener('popstate', fn, false);
|
||||
}
|
||||
|
||||
onHashChange(fn: UrlChangeListener): void {
|
||||
DOM.getGlobalEventTarget('window').addEventListener('hashchange', fn, false);
|
||||
}
|
||||
|
||||
get pathname(): string { return this._location.pathname; }
|
||||
get search(): string { return this._location.search; }
|
||||
get hash(): string { return this._location.hash; }
|
||||
set pathname(newPath: string) { this._location.pathname = newPath; }
|
||||
|
||||
pushState(state: any, title: string, url: string): void {
|
||||
this._history.pushState(state, title, url);
|
||||
}
|
||||
|
||||
replaceState(state: any, title: string, url: string): void {
|
||||
this._history.replaceState(state, title, url);
|
||||
}
|
||||
|
||||
forward(): void { this._history.forward(); }
|
||||
|
||||
back(): void { this._history.back(); }
|
||||
}
|
@ -5,7 +5,7 @@ import {
|
||||
APP_BASE_HREF,
|
||||
normalizeQueryParams
|
||||
} from './location_strategy';
|
||||
import {UrlChangeListener} from './platform_location';
|
||||
import {EventListener} from 'angular2/src/facade/browser';
|
||||
import {isPresent} from 'angular2/src/facade/lang';
|
||||
import {PlatformLocation} from './platform_location';
|
||||
|
||||
@ -58,7 +58,7 @@ export class HashLocationStrategy extends LocationStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
onPopState(fn: UrlChangeListener): void {
|
||||
onPopState(fn: EventListener): void {
|
||||
this._platformLocation.onPopState(fn);
|
||||
this._platformLocation.onHashChange(fn);
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ export class RedirectInstruction extends ResolvedInstruction {
|
||||
* `ComponentInstructions` is a public API. Instances of `ComponentInstruction` are passed
|
||||
* to route lifecycle hooks, like {@link CanActivate}.
|
||||
*
|
||||
* `ComponentInstruction`s are [hash consed](https://en.wikipedia.org/wiki/Hash_consing). You should
|
||||
* `ComponentInstruction`s are [https://en.wikipedia.org/wiki/Hash_consing](hash consed). You should
|
||||
* never construct one yourself with "new." Instead, rely on {@link Router/RouteRecognizer} to
|
||||
* construct `ComponentInstruction`s.
|
||||
*
|
||||
|
@ -1,6 +1,5 @@
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {OpaqueToken} from 'angular2/core';
|
||||
import {UrlChangeListener} from './platform_location';
|
||||
|
||||
/**
|
||||
* `LocationStrategy` is responsible for representing and reading route state
|
||||
@ -25,7 +24,7 @@ export abstract class LocationStrategy {
|
||||
abstract replaceState(state: any, title: string, url: string, queryParams: string): void;
|
||||
abstract forward(): void;
|
||||
abstract back(): void;
|
||||
abstract onPopState(fn: UrlChangeListener): void;
|
||||
abstract onPopState(fn: (_: any) => any): void;
|
||||
abstract getBaseHref(): string;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {Injectable, Inject, Optional} from 'angular2/core';
|
||||
import {EventListener, History, Location} from 'angular2/src/facade/browser';
|
||||
import {isBlank} from 'angular2/src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
import {
|
||||
@ -7,7 +8,7 @@ import {
|
||||
normalizeQueryParams,
|
||||
joinWithSlash
|
||||
} from './location_strategy';
|
||||
import {PlatformLocation, UrlChangeListener} from './platform_location';
|
||||
import {PlatformLocation} from './platform_location';
|
||||
|
||||
/**
|
||||
* `PathLocationStrategy` is a {@link LocationStrategy} used to configure the
|
||||
@ -74,7 +75,7 @@ export class PathLocationStrategy extends LocationStrategy {
|
||||
this._baseHref = href;
|
||||
}
|
||||
|
||||
onPopState(fn: UrlChangeListener): void {
|
||||
onPopState(fn: EventListener): void {
|
||||
this._platformLocation.onPopState(fn);
|
||||
this._platformLocation.onHashChange(fn);
|
||||
}
|
||||
|
@ -1,48 +1,50 @@
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {Injectable} from 'angular2/core';
|
||||
import {EventListener, History, Location} from 'angular2/src/facade/browser';
|
||||
|
||||
/**
|
||||
* `PlatformLocation` encapsulates all of the direct calls to platform APIs.
|
||||
* This class should not be used directly by an application developer. Instead, use
|
||||
* {@link Location}.
|
||||
*
|
||||
* `PlatformLocation` encapsulates all calls to DOM apis, which allows the Router to be platform
|
||||
* agnostic.
|
||||
* This means that we can have different implementation of `PlatformLocation` for the different
|
||||
* platforms
|
||||
* that angular supports. For example, the default `PlatformLocation` is {@link
|
||||
* BrowserPlatformLocation},
|
||||
* however when you run your app in a WebWorker you use {@link WebWorkerPlatformLocation}.
|
||||
*
|
||||
* The `PlatformLocation` class is used directly by all implementations of {@link LocationStrategy}
|
||||
* when
|
||||
* they need to interact with the DOM apis like pushState, popState, etc...
|
||||
*
|
||||
* {@link LocationStrategy} in turn is used by the {@link Location} service which is used directly
|
||||
* by
|
||||
* the {@link Router} in order to navigate between routes. Since all interactions between {@link
|
||||
* Router} /
|
||||
* {@link Location} / {@link LocationStrategy} and DOM apis flow through the `PlatformLocation`
|
||||
* class
|
||||
* they are all platform independent.
|
||||
*/
|
||||
export abstract class PlatformLocation {
|
||||
abstract getBaseHrefFromDOM(): string;
|
||||
abstract onPopState(fn: UrlChangeListener): void;
|
||||
abstract onHashChange(fn: UrlChangeListener): void;
|
||||
@Injectable()
|
||||
export class PlatformLocation {
|
||||
private _location: Location;
|
||||
private _history: History;
|
||||
|
||||
pathname: string;
|
||||
search: string;
|
||||
hash: string;
|
||||
constructor() { this._init(); }
|
||||
|
||||
abstract replaceState(state: any, title: string, url: string): void;
|
||||
// This is moved to its own method so that `MockPlatformLocationStrategy` can overwrite it
|
||||
/** @internal */
|
||||
_init() {
|
||||
this._location = DOM.getLocation();
|
||||
this._history = DOM.getHistory();
|
||||
}
|
||||
|
||||
abstract pushState(state: any, title: string, url: string): void;
|
||||
getBaseHrefFromDOM(): string { return DOM.getBaseHref(); }
|
||||
|
||||
abstract forward(): void;
|
||||
onPopState(fn: EventListener): void {
|
||||
DOM.getGlobalEventTarget('window').addEventListener('popstate', fn, false);
|
||||
}
|
||||
|
||||
abstract back(): void;
|
||||
onHashChange(fn: EventListener): void {
|
||||
DOM.getGlobalEventTarget('window').addEventListener('hashchange', fn, false);
|
||||
}
|
||||
|
||||
get pathname(): string { return this._location.pathname; }
|
||||
get search(): string { return this._location.search; }
|
||||
get hash(): string { return this._location.hash; }
|
||||
set pathname(newPath: string) { this._location.pathname = newPath; }
|
||||
|
||||
pushState(state: any, title: string, url: string): void {
|
||||
this._history.pushState(state, title, url);
|
||||
}
|
||||
|
||||
replaceState(state: any, title: string, url: string): void {
|
||||
this._history.replaceState(state, title, url);
|
||||
}
|
||||
|
||||
forward(): void { this._history.forward(); }
|
||||
|
||||
back(): void { this._history.back(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* A serializable version of the event from onPopState or onHashChange
|
||||
*/
|
||||
export interface UrlChangeEvent { type: string; }
|
||||
|
||||
export interface UrlChangeListener { (e: UrlChangeEvent): any; }
|
||||
|
@ -1,42 +0,0 @@
|
||||
// import {ROUTER_PROVIDERS_COMMON} from './router_providers_common';
|
||||
import {ROUTER_PROVIDERS_COMMON} from 'angular2/router';
|
||||
import {Provider} from 'angular2/core';
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {BrowserPlatformLocation} from './browser_platform_location';
|
||||
import {PlatformLocation} from './platform_location';
|
||||
|
||||
/**
|
||||
* A list of {@link Provider}s. To use the router, you must add this to your application.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/iRUP8B5OUbxCWQ3AcIDm))
|
||||
*
|
||||
* ```
|
||||
* import {Component} from 'angular2/core';
|
||||
* import {
|
||||
* ROUTER_DIRECTIVES,
|
||||
* ROUTER_PROVIDERS,
|
||||
* RouteConfig
|
||||
* } from 'angular2/router';
|
||||
*
|
||||
* @Component({directives: [ROUTER_DIRECTIVES]})
|
||||
* @RouteConfig([
|
||||
* {...},
|
||||
* ])
|
||||
* class AppCmp {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* bootstrap(AppCmp, [ROUTER_PROVIDERS]);
|
||||
* ```
|
||||
*/
|
||||
export const ROUTER_PROVIDERS: any[] = CONST_EXPR([
|
||||
ROUTER_PROVIDERS_COMMON,
|
||||
CONST_EXPR(new Provider(PlatformLocation, {useClass: BrowserPlatformLocation})),
|
||||
]);
|
||||
|
||||
/**
|
||||
* Use {@link ROUTER_PROVIDERS} instead.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export const ROUTER_BINDINGS = ROUTER_PROVIDERS;
|
@ -1,40 +0,0 @@
|
||||
import {LocationStrategy} from 'angular2/src/router/location_strategy';
|
||||
import {PathLocationStrategy} from 'angular2/src/router/path_location_strategy';
|
||||
import {Router, RootRouter} from 'angular2/src/router/router';
|
||||
import {RouteRegistry, ROUTER_PRIMARY_COMPONENT} from 'angular2/src/router/route_registry';
|
||||
import {Location} from 'angular2/src/router/location';
|
||||
import {CONST_EXPR, Type} from 'angular2/src/facade/lang';
|
||||
import {ApplicationRef, OpaqueToken, Provider} from 'angular2/core';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
|
||||
/**
|
||||
* The Platform agnostic ROUTER PROVIDERS
|
||||
*/
|
||||
export const ROUTER_PROVIDERS_COMMON: any[] = CONST_EXPR([
|
||||
RouteRegistry,
|
||||
CONST_EXPR(new Provider(LocationStrategy, {useClass: PathLocationStrategy})),
|
||||
Location,
|
||||
CONST_EXPR(new Provider(
|
||||
Router,
|
||||
{
|
||||
useFactory: routerFactory,
|
||||
deps: CONST_EXPR([RouteRegistry, Location, ROUTER_PRIMARY_COMPONENT, ApplicationRef])
|
||||
})),
|
||||
CONST_EXPR(new Provider(
|
||||
ROUTER_PRIMARY_COMPONENT,
|
||||
{useFactory: routerPrimaryComponentFactory, deps: CONST_EXPR([ApplicationRef])}))
|
||||
]);
|
||||
|
||||
function routerFactory(registry: RouteRegistry, location: Location, primaryComponent: Type,
|
||||
appRef: ApplicationRef): RootRouter {
|
||||
var rootRouter = new RootRouter(registry, location, primaryComponent);
|
||||
appRef.registerDisposeListener(() => rootRouter.dispose());
|
||||
return rootRouter;
|
||||
}
|
||||
|
||||
function routerPrimaryComponentFactory(app: ApplicationRef): Type {
|
||||
if (app.componentTypes.length == 0) {
|
||||
throw new BaseException("Bootstrap at least one component before injecting Router.");
|
||||
}
|
||||
return app.componentTypes[0];
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import {
|
||||
ComponentRef,
|
||||
DebugElement,
|
||||
DirectiveResolver,
|
||||
DynamicComponentLoader,
|
||||
Injector,
|
||||
Injectable,
|
||||
ViewMetadata,
|
||||
ElementRef,
|
||||
EmbeddedViewRef,
|
||||
ViewResolver,
|
||||
provide
|
||||
@ -23,7 +23,7 @@ import {el} from './utils';
|
||||
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
|
||||
import {DebugNode, DebugElement, getDebugNode} from 'angular2/src/core/debug/debug_node';
|
||||
import {DebugElement_} from 'angular2/src/core/debug/debug_element';
|
||||
|
||||
|
||||
/**
|
||||
@ -45,11 +45,6 @@ export abstract class ComponentFixture {
|
||||
*/
|
||||
nativeElement: any;
|
||||
|
||||
/**
|
||||
* The ElementRef for the element at the root of the component.
|
||||
*/
|
||||
elementRef: ElementRef;
|
||||
|
||||
/**
|
||||
* Trigger a change detection cycle for the component.
|
||||
*/
|
||||
@ -71,9 +66,7 @@ export class ComponentFixture_ extends ComponentFixture {
|
||||
constructor(componentRef: ComponentRef) {
|
||||
super();
|
||||
this._componentParentView = (<ViewRef_>componentRef.hostView).internalView;
|
||||
this.elementRef = this._componentParentView.appElements[0].ref;
|
||||
this.debugElement = <DebugElement>getDebugNode(
|
||||
this._componentParentView.rootNodesOrAppElements[0].nativeElement);
|
||||
this.debugElement = new DebugElement_(this._componentParentView.appElements[0]);
|
||||
this.componentInstance = this.debugElement.componentInstance;
|
||||
this.nativeElement = this.debugElement.nativeElement;
|
||||
this._componentRef = componentRef;
|
||||
|
@ -78,18 +78,11 @@ export class UpgradeNg1ComponentAdapterBuilder {
|
||||
}
|
||||
|
||||
extractBindings() {
|
||||
var btcIsObject = typeof this.directive.bindToController === 'object';
|
||||
if (btcIsObject && Object.keys(this.directive.scope).length) {
|
||||
throw new Error(
|
||||
`Binding definitions on scope and controller at the same time are not supported.`);
|
||||
}
|
||||
|
||||
var context = (btcIsObject) ? this.directive.bindToController : this.directive.scope;
|
||||
|
||||
if (typeof context == 'object') {
|
||||
for (var name in context) {
|
||||
if ((<any>context).hasOwnProperty(name)) {
|
||||
var localName = context[name];
|
||||
var scope = this.directive.scope;
|
||||
if (typeof scope == 'object') {
|
||||
for (var name in scope) {
|
||||
if ((<any>scope).hasOwnProperty(name)) {
|
||||
var localName = scope[name];
|
||||
var type = localName.charAt(0);
|
||||
localName = localName.substr(1) || name;
|
||||
var outputName = 'output_' + name;
|
||||
@ -116,7 +109,7 @@ export class UpgradeNg1ComponentAdapterBuilder {
|
||||
this.propertyMap[outputName] = localName;
|
||||
break;
|
||||
default:
|
||||
var json = JSON.stringify(context);
|
||||
var json = JSON.stringify(scope);
|
||||
throw new Error(
|
||||
`Unexpected mapping '${type}' in '${json}' in '${this.name}' directive.`);
|
||||
}
|
||||
|
@ -4,5 +4,4 @@
|
||||
*/
|
||||
export const RENDERER_CHANNEL = "ng-Renderer";
|
||||
export const XHR_CHANNEL = "ng-XHR";
|
||||
export const EVENT_CHANNEL = "ng-Events";
|
||||
export const ROUTER_CHANNEL = "ng-Router";
|
||||
export const EVENT_CHANNEL = "ng-events";
|
||||
|
@ -1,7 +0,0 @@
|
||||
// This file contains interface versions of browser types that can be serialized to Plain Old
|
||||
// JavaScript Objects
|
||||
export class LocationType {
|
||||
constructor(public href: string, public protocol: string, public host: string,
|
||||
public hostname: string, public port: string, public pathname: string,
|
||||
public search: string, public hash: string, public origin: string) {}
|
||||
}
|
@ -6,7 +6,6 @@ import {RenderComponentType} from "angular2/src/core/render/api";
|
||||
import {Injectable} from "angular2/src/core/di";
|
||||
import {RenderStore} from 'angular2/src/web_workers/shared/render_store';
|
||||
import {ViewEncapsulation, VIEW_ENCAPSULATION_VALUES} from 'angular2/src/core/metadata/view';
|
||||
import {LocationType} from './serialized_types';
|
||||
|
||||
// PRIMITIVE is any type that does not need to be serialized (string, number, boolean)
|
||||
// We set it to String so that it is considered a Type.
|
||||
@ -32,8 +31,6 @@ export class Serializer {
|
||||
return this._serializeRenderComponentType(obj);
|
||||
} else if (type === ViewEncapsulation) {
|
||||
return serializeEnum(obj);
|
||||
} else if (type === LocationType) {
|
||||
return this._serializeLocation(obj);
|
||||
} else {
|
||||
throw new BaseException("No serializer for " + type.toString());
|
||||
}
|
||||
@ -58,8 +55,6 @@ export class Serializer {
|
||||
return this._deserializeRenderComponentType(map);
|
||||
} else if (type === ViewEncapsulation) {
|
||||
return VIEW_ENCAPSULATION_VALUES[map];
|
||||
} else if (type === LocationType) {
|
||||
return this._deserializeLocation(map);
|
||||
} else {
|
||||
throw new BaseException("No deserializer for " + type.toString());
|
||||
}
|
||||
@ -95,25 +90,6 @@ export class Serializer {
|
||||
}
|
||||
}
|
||||
|
||||
private _serializeLocation(loc: LocationType): Object {
|
||||
return {
|
||||
'href': loc.href,
|
||||
'protocol': loc.protocol,
|
||||
'host': loc.host,
|
||||
'hostname': loc.hostname,
|
||||
'port': loc.port,
|
||||
'pathname': loc.pathname,
|
||||
'search': loc.search,
|
||||
'hash': loc.hash,
|
||||
'origin': loc.origin
|
||||
};
|
||||
}
|
||||
|
||||
private _deserializeLocation(loc: {[key: string]: any}): LocationType {
|
||||
return new LocationType(loc['href'], loc['protocol'], loc['host'], loc['hostname'], loc['port'],
|
||||
loc['pathname'], loc['search'], loc['hash'], loc['origin']);
|
||||
}
|
||||
|
||||
private _serializeRenderComponentType(obj: RenderComponentType): Object {
|
||||
return {
|
||||
'id': obj.id,
|
||||
@ -130,4 +106,4 @@ export class Serializer {
|
||||
}
|
||||
|
||||
|
||||
export class RenderStoreObject {}
|
||||
export class RenderStoreObject {}
|
@ -50,13 +50,11 @@ export class ServiceMessageBroker_ extends ServiceMessageBroker {
|
||||
ObservableWrapper.subscribe(source, (message) => this._handleMessage(message));
|
||||
}
|
||||
|
||||
registerMethod(methodName: string, signature: Type[], method: (..._: any[]) => Promise<any>| void,
|
||||
returnType?: Type): void {
|
||||
registerMethod(methodName: string, signature: Type[], method: Function, returnType?: Type): void {
|
||||
this._methods.set(methodName, (message: ReceivedMessage) => {
|
||||
var serializedArgs = message.args;
|
||||
let numArgs = signature === null ? 0 : signature.length;
|
||||
var deserializedArgs: any[] = ListWrapper.createFixedSize(numArgs);
|
||||
for (var i = 0; i < numArgs; i++) {
|
||||
var deserializedArgs: any[] = ListWrapper.createFixedSize(signature.length);
|
||||
for (var i = 0; i < signature.length; i++) {
|
||||
var serializedArg = serializedArgs[i];
|
||||
deserializedArgs[i] = this._serializer.deserialize(serializedArg, signature[i]);
|
||||
}
|
||||
|
@ -3,8 +3,7 @@ import {
|
||||
serializeMouseEvent,
|
||||
serializeKeyboardEvent,
|
||||
serializeGenericEvent,
|
||||
serializeEventWithTarget,
|
||||
serializeTransitionEvent
|
||||
serializeEventWithTarget
|
||||
} from 'angular2/src/web_workers/ui/event_serializer';
|
||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
@ -90,9 +89,6 @@ export class EventDispatcher {
|
||||
case "waiting":
|
||||
serializedEvent = serializeGenericEvent(event);
|
||||
break;
|
||||
case "transitionend":
|
||||
serializedEvent = serializeTransitionEvent(event);
|
||||
break;
|
||||
default:
|
||||
throw new BaseException(eventName + " not supported on WebWorkers");
|
||||
}
|
||||
|
@ -86,14 +86,6 @@ Map<String, dynamic> serializeKeyboardEvent(dynamic e) {
|
||||
return serialized;
|
||||
}
|
||||
|
||||
Map<String, dynamic> serializeTransitionEvent(dynamic e) {
|
||||
var serialized = serializeGenericEvent(e);
|
||||
serialized['propertyName'] = e.propertyName;
|
||||
serialized['elapsedTime'] = e.elapsedTime;
|
||||
serialized['pseudoElement'] = e.pseudoElement;
|
||||
return addTarget(e, serialized);
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): #3374. See above.
|
||||
Map<String, dynamic> addTarget(
|
||||
dynamic e, Map<String, dynamic> serializedEvent) {
|
||||
|
@ -32,8 +32,6 @@ const KEYBOARD_EVENT_PROPERTIES = [
|
||||
'which'
|
||||
];
|
||||
|
||||
const TRANSITION_EVENT_PROPERTIES = ['propertyName', 'elapsedTime', 'pseudoElement'];
|
||||
|
||||
const EVENT_PROPERTIES = ['type', 'bubbles', 'cancelable'];
|
||||
|
||||
const NODES_WITH_VALUE =
|
||||
@ -59,11 +57,6 @@ export function serializeKeyboardEvent(e: KeyboardEvent): {[key: string]: any} {
|
||||
return addTarget(e, serializedEvent);
|
||||
}
|
||||
|
||||
export function serializeTransitionEvent(e: TransitionEvent): {[key: string]: any} {
|
||||
var serializedEvent = serializeEvent(e, TRANSITION_EVENT_PROPERTIES);
|
||||
return addTarget(e, serializedEvent);
|
||||
}
|
||||
|
||||
// TODO(jteplitz602): #3374. See above.
|
||||
function addTarget(e: Event, serializedEvent: {[key: string]: any}): {[key: string]: any} {
|
||||
if (NODES_WITH_VALUE.has((<HTMLElement>e.target).tagName.toLowerCase())) {
|
||||
|
@ -1,54 +0,0 @@
|
||||
import {BrowserPlatformLocation} from 'angular2/src/router/browser_platform_location';
|
||||
import {Injectable} from 'angular2/src/core/di';
|
||||
import {ROUTER_CHANNEL} from 'angular2/src/web_workers/shared/messaging_api';
|
||||
import {
|
||||
ServiceMessageBrokerFactory,
|
||||
ServiceMessageBroker
|
||||
} from 'angular2/src/web_workers/shared/service_message_broker';
|
||||
import {PRIMITIVE, Serializer} from 'angular2/src/web_workers/shared/serializer';
|
||||
import {bind} from './bind';
|
||||
import {LocationType} from 'angular2/src/web_workers/shared/serialized_types';
|
||||
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
|
||||
import {Promise, EventEmitter, ObservableWrapper, PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {UrlChangeListener} from 'angular2/src/router/platform_location';
|
||||
|
||||
@Injectable()
|
||||
export class MessageBasedPlatformLocation {
|
||||
private _channelSink: EventEmitter<Object>;
|
||||
private _broker: ServiceMessageBroker;
|
||||
|
||||
constructor(private _brokerFactory: ServiceMessageBrokerFactory,
|
||||
private _platformLocation: BrowserPlatformLocation, bus: MessageBus,
|
||||
private _serializer: Serializer) {
|
||||
this._platformLocation.onPopState(<UrlChangeListener>bind(this._sendUrlChangeEvent, this));
|
||||
this._platformLocation.onHashChange(<UrlChangeListener>bind(this._sendUrlChangeEvent, this));
|
||||
this._broker = this._brokerFactory.createMessageBroker(ROUTER_CHANNEL);
|
||||
this._channelSink = bus.to(ROUTER_CHANNEL);
|
||||
}
|
||||
|
||||
start(): void {
|
||||
this._broker.registerMethod("getLocation", null, bind(this._getLocation, this), LocationType);
|
||||
this._broker.registerMethod("setPathname", [PRIMITIVE], bind(this._setPathname, this));
|
||||
this._broker.registerMethod("pushState", [PRIMITIVE, PRIMITIVE, PRIMITIVE],
|
||||
bind(this._platformLocation.pushState, this._platformLocation));
|
||||
this._broker.registerMethod("replaceState", [PRIMITIVE, PRIMITIVE, PRIMITIVE],
|
||||
bind(this._platformLocation.replaceState, this._platformLocation));
|
||||
this._broker.registerMethod("forward", null,
|
||||
bind(this._platformLocation.forward, this._platformLocation));
|
||||
this._broker.registerMethod("back", null,
|
||||
bind(this._platformLocation.back, this._platformLocation));
|
||||
}
|
||||
|
||||
private _getLocation(): Promise<Location> {
|
||||
return PromiseWrapper.resolve(this._platformLocation.location);
|
||||
}
|
||||
|
||||
|
||||
private _sendUrlChangeEvent(e: Event): void {
|
||||
let loc = this._serializer.serialize(this._platformLocation.location, LocationType);
|
||||
let serializedEvent = {'type': e.type};
|
||||
ObservableWrapper.callEmit(this._channelSink, {'event': serializedEvent, 'location': loc});
|
||||
}
|
||||
|
||||
private _setPathname(pathname: string): void { this._platformLocation.pathname = pathname; }
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import {MessageBasedPlatformLocation} from './platform_location';
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {BrowserPlatformLocation} from 'angular2/src/router/browser_platform_location';
|
||||
import {APP_INITIALIZER, Provider, Injector, NgZone} from 'angular2/core';
|
||||
|
||||
export const WORKER_RENDER_ROUTER = CONST_EXPR([
|
||||
MessageBasedPlatformLocation,
|
||||
BrowserPlatformLocation,
|
||||
CONST_EXPR(
|
||||
new Provider(APP_INITIALIZER,
|
||||
{useFactory: initRouterListeners, multi: true, deps: CONST_EXPR([Injector])}))
|
||||
]);
|
||||
|
||||
function initRouterListeners(injector: Injector): () => void {
|
||||
return () => {
|
||||
let zone = injector.get(NgZone);
|
||||
|
||||
zone.run(() => injector.get(MessageBasedPlatformLocation).start());
|
||||
};
|
||||
}
|
@ -31,10 +31,6 @@ class GenericEvent {
|
||||
Point get page => _getPoint('page');
|
||||
Point get screen => _getPoint('screen');
|
||||
|
||||
String get propertyName => properties['propertyName'];
|
||||
num get elapsedTime => properties['elapsedTime'];
|
||||
String get pseudoElement => properties['pseudoElement'];
|
||||
|
||||
EventTarget get target {
|
||||
if (_target != null) {
|
||||
return _target;
|
||||
|
@ -1,136 +0,0 @@
|
||||
import {Injectable} from 'angular2/src/core/di';
|
||||
import {
|
||||
PlatformLocation,
|
||||
UrlChangeEvent,
|
||||
UrlChangeListener
|
||||
} from 'angular2/src/router/platform_location';
|
||||
import {
|
||||
FnArg,
|
||||
UiArguments,
|
||||
ClientMessageBroker,
|
||||
ClientMessageBrokerFactory
|
||||
} from 'angular2/src/web_workers/shared/client_message_broker';
|
||||
import {ROUTER_CHANNEL} from 'angular2/src/web_workers/shared/messaging_api';
|
||||
import {LocationType} from 'angular2/src/web_workers/shared/serialized_types';
|
||||
import {Promise, PromiseWrapper, EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
import {PRIMITIVE, Serializer} from 'angular2/src/web_workers/shared/serializer';
|
||||
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
|
||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {StringWrapper} from 'angular2/src/facade/lang';
|
||||
import {deserializeGenericEvent} from './event_deserializer';
|
||||
|
||||
@Injectable()
|
||||
export class WebWorkerPlatformLocation extends PlatformLocation {
|
||||
private _broker: ClientMessageBroker;
|
||||
private _popStateListeners: Array<Function> = [];
|
||||
private _hashChangeListeners: Array<Function> = [];
|
||||
private _location: LocationType = null;
|
||||
private _channelSource: EventEmitter<Object>;
|
||||
|
||||
constructor(brokerFactory: ClientMessageBrokerFactory, bus: MessageBus,
|
||||
private _serializer: Serializer) {
|
||||
super();
|
||||
this._broker = brokerFactory.createMessageBroker(ROUTER_CHANNEL);
|
||||
|
||||
this._channelSource = bus.from(ROUTER_CHANNEL);
|
||||
ObservableWrapper.subscribe(this._channelSource, (msg: {[key: string]: any}) => {
|
||||
var listeners: Array<Function> = null;
|
||||
if (StringMapWrapper.contains(msg, 'event')) {
|
||||
let type: string = msg['event']['type'];
|
||||
if (StringWrapper.equals(type, "popstate")) {
|
||||
listeners = this._popStateListeners;
|
||||
} else if (StringWrapper.equals(type, "hashchange")) {
|
||||
listeners = this._hashChangeListeners;
|
||||
}
|
||||
|
||||
if (listeners !== null) {
|
||||
let e = deserializeGenericEvent(msg['event']);
|
||||
// There was a popState or hashChange event, so the location object thas been updated
|
||||
this._location = this._serializer.deserialize(msg['location'], LocationType);
|
||||
listeners.forEach((fn: Function) => fn(e));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** @internal **/
|
||||
init(): Promise<boolean> {
|
||||
var args: UiArguments = new UiArguments("getLocation");
|
||||
|
||||
var locationPromise: Promise<LocationType> = this._broker.runOnService(args, LocationType);
|
||||
return PromiseWrapper.then(locationPromise, (val: LocationType): boolean => {
|
||||
this._location = val;
|
||||
return true;
|
||||
}, (err): boolean => { throw new BaseException(err); });
|
||||
}
|
||||
|
||||
getBaseHrefFromDOM(): string {
|
||||
throw new BaseException(
|
||||
"Attempt to get base href from DOM from WebWorker. You must either provide a value for the APP_BASE_HREF token through DI or use the hash location strategy.");
|
||||
}
|
||||
|
||||
onPopState(fn: UrlChangeListener): void { this._popStateListeners.push(fn); }
|
||||
|
||||
onHashChange(fn: UrlChangeListener): void { this._hashChangeListeners.push(fn); }
|
||||
|
||||
get pathname(): string {
|
||||
if (this._location === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this._location.pathname;
|
||||
}
|
||||
|
||||
get search(): string {
|
||||
if (this._location === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this._location.search;
|
||||
}
|
||||
|
||||
get hash(): string {
|
||||
if (this._location === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this._location.hash;
|
||||
}
|
||||
|
||||
set pathname(newPath: string) {
|
||||
if (this._location === null) {
|
||||
throw new BaseException("Attempt to set pathname before value is obtained from UI");
|
||||
}
|
||||
|
||||
this._location.pathname = newPath;
|
||||
|
||||
var fnArgs = [new FnArg(newPath, PRIMITIVE)];
|
||||
var args = new UiArguments("setPathname", fnArgs);
|
||||
this._broker.runOnService(args, null);
|
||||
}
|
||||
|
||||
pushState(state: any, title: string, url: string): void {
|
||||
var fnArgs =
|
||||
[new FnArg(state, PRIMITIVE), new FnArg(title, PRIMITIVE), new FnArg(url, PRIMITIVE)];
|
||||
var args = new UiArguments("pushState", fnArgs);
|
||||
this._broker.runOnService(args, null);
|
||||
}
|
||||
|
||||
replaceState(state: any, title: string, url: string): void {
|
||||
var fnArgs =
|
||||
[new FnArg(state, PRIMITIVE), new FnArg(title, PRIMITIVE), new FnArg(url, PRIMITIVE)];
|
||||
var args = new UiArguments("replaceState", fnArgs);
|
||||
this._broker.runOnService(args, null);
|
||||
}
|
||||
|
||||
forward(): void {
|
||||
var args = new UiArguments("forward");
|
||||
this._broker.runOnService(args, null);
|
||||
}
|
||||
|
||||
back(): void {
|
||||
var args = new UiArguments("back");
|
||||
this._broker.runOnService(args, null);
|
||||
}
|
||||
}
|
@ -1,9 +1,4 @@
|
||||
import {
|
||||
Renderer,
|
||||
RootRenderer,
|
||||
RenderComponentType,
|
||||
RenderDebugInfo
|
||||
} from 'angular2/src/core/render/api';
|
||||
import {Renderer, RootRenderer, RenderComponentType} from 'angular2/src/core/render/api';
|
||||
import {
|
||||
ClientMessageBroker,
|
||||
ClientMessageBrokerFactory,
|
||||
@ -191,8 +186,6 @@ export class WebWorkerRenderer implements Renderer, RenderStoreObject {
|
||||
]);
|
||||
}
|
||||
|
||||
setElementDebugInfo(renderElement: any, info: RenderDebugInfo) {}
|
||||
|
||||
setElementClass(renderElement: any, className: string, isAdd: boolean) {
|
||||
this._runOnService('setElementClass', [
|
||||
new FnArg(renderElement, RenderStoreObject),
|
||||
|
@ -1,21 +0,0 @@
|
||||
import {ApplicationRef, Provider, NgZone, APP_INITIALIZER} from 'angular2/core';
|
||||
import {PlatformLocation} from 'angular2/src/router/platform_location';
|
||||
import {WebWorkerPlatformLocation} from './platform_location';
|
||||
import {ROUTER_PROVIDERS_COMMON} from 'angular2/src/router/router_providers_common';
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
|
||||
export var WORKER_APP_ROUTER = [
|
||||
ROUTER_PROVIDERS_COMMON,
|
||||
new Provider(PlatformLocation, {useClass: WebWorkerPlatformLocation}),
|
||||
new Provider(APP_INITIALIZER,
|
||||
{
|
||||
useFactory: (platformLocation: WebWorkerPlatformLocation, zone: NgZone) => () =>
|
||||
initRouter(platformLocation, zone),
|
||||
multi: true,
|
||||
deps: [PlatformLocation, NgZone]
|
||||
})
|
||||
];
|
||||
|
||||
function initRouter(platformLocation: WebWorkerPlatformLocation, zone: NgZone): Promise<boolean> {
|
||||
return zone.run(() => { return platformLocation.init(); });
|
||||
}
|
@ -19,9 +19,10 @@ import {Component, View, provide} from 'angular2/core';
|
||||
import {NgFor} from 'angular2/common';
|
||||
import {NgClass} from 'angular2/src/common/directives/ng_class';
|
||||
|
||||
function detectChangesAndCheck(fixture: ComponentFixture, classes: string) {
|
||||
function detectChangesAndCheck(fixture: ComponentFixture, classes: string, elIndex: number = 0) {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.children[0].nativeElement.className).toEqual(classes);
|
||||
expect(fixture.debugElement.componentViewChildren[elIndex].nativeElement.className)
|
||||
.toEqual(classes);
|
||||
}
|
||||
|
||||
export function main() {
|
||||
@ -38,7 +39,7 @@ export function main() {
|
||||
fixture.detectChanges();
|
||||
fixture.debugElement.componentInstance.items = [['1']];
|
||||
|
||||
detectChangesAndCheck(fixture, '1');
|
||||
detectChangesAndCheck(fixture, '1', 1);
|
||||
|
||||
async.done();
|
||||
});
|
||||
|
@ -16,7 +16,7 @@ import {
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {Component, View, TemplateRef, ContentChild} from 'angular2/core';
|
||||
import {NgFor} from 'angular2/src/common/directives/ng_for';
|
||||
import {By} from 'angular2/platform/common_dom';
|
||||
|
||||
|
||||
export function main() {
|
||||
describe('ngFor', () => {
|
||||
@ -318,7 +318,7 @@ export function main() {
|
||||
'<test-cmp><li template="#item #i=index">{{i}}: {{item}};</li></test-cmp>')
|
||||
.createAsync(ComponentUsingTestComponent)
|
||||
.then((fixture) => {
|
||||
var testComponent = fixture.debugElement.children[0];
|
||||
var testComponent = fixture.debugElement.componentViewChildren[0];
|
||||
testComponent.componentInstance.items = ['a', 'b', 'c'];
|
||||
fixture.detectChanges();
|
||||
expect(testComponent.nativeElement).toHaveText('0: a;1: b;2: c;');
|
||||
@ -334,7 +334,7 @@ export function main() {
|
||||
.overrideTemplate(ComponentUsingTestComponent, '<test-cmp></test-cmp>')
|
||||
.createAsync(ComponentUsingTestComponent)
|
||||
.then((fixture) => {
|
||||
var testComponent = fixture.debugElement.children[0];
|
||||
var testComponent = fixture.debugElement.componentViewChildren[0];
|
||||
testComponent.componentInstance.items = ['a', 'b', 'c'];
|
||||
fixture.detectChanges();
|
||||
expect(testComponent.nativeElement).toHaveText('0: a;1: b;2: c;');
|
||||
@ -352,7 +352,7 @@ export function main() {
|
||||
'<test-cmp><li template="#item #i=index">{{i}}: {{item}};</li></test-cmp>')
|
||||
.createAsync(ComponentUsingTestComponent)
|
||||
.then((fixture) => {
|
||||
var testComponent = fixture.debugElement.children[0];
|
||||
var testComponent = fixture.debugElement.componentViewChildren[0];
|
||||
testComponent.componentInstance.items = ['a', 'b', 'c'];
|
||||
fixture.detectChanges();
|
||||
expect(testComponent.nativeElement).toHaveText('0: a;1: b;2: c;');
|
||||
@ -360,31 +360,6 @@ export function main() {
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
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">
|
||||
<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();
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@ -398,7 +373,6 @@ class TestComponent {
|
||||
@ContentChild(TemplateRef) contentTpl: TemplateRef;
|
||||
items: any;
|
||||
constructor() { this.items = [1, 2]; }
|
||||
customTrackBy(index: number, item: any): string { return item['id']; }
|
||||
}
|
||||
|
||||
@Component({selector: 'outer-cmp'})
|
||||
|
@ -32,7 +32,8 @@ export function main() {
|
||||
.createAsync(TestComponent)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'max-width'))
|
||||
.toEqual('40px');
|
||||
|
||||
async.done();
|
||||
@ -50,13 +51,15 @@ export function main() {
|
||||
|
||||
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'max-width'))
|
||||
.toEqual('40px');
|
||||
|
||||
expr = fixture.debugElement.componentInstance.expr;
|
||||
expr['max-width'] = '30%';
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'max-width'))
|
||||
.toEqual('30%');
|
||||
|
||||
async.done();
|
||||
@ -72,12 +75,14 @@ export function main() {
|
||||
.then((fixture) => {
|
||||
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'max-width'))
|
||||
.toEqual('40px');
|
||||
|
||||
StringMapWrapper.delete(fixture.debugElement.componentInstance.expr, 'max-width');
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'max-width'))
|
||||
.toEqual('');
|
||||
|
||||
async.done();
|
||||
@ -93,16 +98,20 @@ export function main() {
|
||||
.then((fixture) => {
|
||||
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'max-width'))
|
||||
.toEqual('40px');
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'font-size'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'font-size'))
|
||||
.toEqual('12px');
|
||||
|
||||
StringMapWrapper.delete(fixture.debugElement.componentInstance.expr, 'max-width');
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'max-width'))
|
||||
.toEqual('');
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'font-size'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'font-size'))
|
||||
.toEqual('12px');
|
||||
|
||||
async.done();
|
||||
@ -118,17 +127,21 @@ export function main() {
|
||||
.then((fixture) => {
|
||||
fixture.debugElement.componentInstance.expr = {'max-width': '40px'};
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'max-width'))
|
||||
.toEqual('40px');
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'font-size'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'font-size'))
|
||||
.toEqual('12px');
|
||||
|
||||
StringMapWrapper.delete(fixture.debugElement.componentInstance.expr, 'max-width');
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'font-size'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'font-size'))
|
||||
.toEqual('12px');
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'max-width'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'max-width'))
|
||||
.toEqual('');
|
||||
|
||||
async.done();
|
||||
|
@ -673,7 +673,7 @@ export function main() {
|
||||
fixture.debugElement.componentInstance.name = null;
|
||||
fixture.detectChanges();
|
||||
|
||||
var form = fixture.debugElement.children[0].inject(NgForm);
|
||||
var form = fixture.debugElement.componentViewChildren[0].inject(NgForm);
|
||||
expect(form.controls['user']).not.toBeDefined();
|
||||
|
||||
tick();
|
||||
@ -708,7 +708,7 @@ export function main() {
|
||||
fixture.debugElement.componentInstance.name = null;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.debugElement.children[0].providerTokens.length).toEqual(0);
|
||||
expect(fixture.debugElement.componentViewChildren.length).toEqual(0);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
@ -728,7 +728,7 @@ export function main() {
|
||||
fixture.debugElement.componentInstance.name = 'show';
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
var form = fixture.debugElement.children[0].inject(NgForm);
|
||||
var form = fixture.debugElement.componentViewChildren[0].inject(NgForm);
|
||||
|
||||
|
||||
expect(form.controls['login']).toBeDefined();
|
||||
@ -756,7 +756,7 @@ export function main() {
|
||||
fixture.debugElement.componentInstance.name = 'show';
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
var form = fixture.debugElement.children[0].inject(NgForm);
|
||||
var form = fixture.debugElement.componentViewChildren[0].inject(NgForm);
|
||||
|
||||
expect(form.controls['user']).toBeDefined();
|
||||
|
||||
|
@ -887,13 +887,6 @@ export function main() {
|
||||
'Expression [\'"]a in location[\'"] has changed after it was checked'));
|
||||
});
|
||||
|
||||
it('should not throw when two arrays are structurally the same', () => {
|
||||
var val = _createChangeDetector('a', new TestDataWithGetter(() => ['value']));
|
||||
val.changeDetector.detectChanges();
|
||||
|
||||
expect(() => { val.changeDetector.checkNoChanges(); }).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not break the next run', () => {
|
||||
var val = _createChangeDetector('a', new TestData('value'));
|
||||
expect(() => val.changeDetector.checkNoChanges())
|
||||
@ -1604,12 +1597,6 @@ class TestData {
|
||||
constructor(public a: any) {}
|
||||
}
|
||||
|
||||
class TestDataWithGetter {
|
||||
constructor(private fn: Function) {}
|
||||
|
||||
get a() { return this.fn(); }
|
||||
}
|
||||
|
||||
class TestDispatcher implements ChangeDispatcher {
|
||||
log: string[];
|
||||
debugLog: string[];
|
||||
|
@ -1,60 +0,0 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach
|
||||
} from 'angular2/testing_internal';
|
||||
|
||||
import {ChangeDetectionUtil} from 'angular2/src/core/change_detection/change_detection_util';
|
||||
|
||||
export function main() {
|
||||
describe("ChangeDetectionUtil", () => {
|
||||
describe("devModeEqual", () => {
|
||||
it("should do the deep comparison of iterables", () => {
|
||||
expect(ChangeDetectionUtil.devModeEqual([['one']], [['one']])).toBe(true);
|
||||
expect(ChangeDetectionUtil.devModeEqual(['one'], ['one', 'two'])).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual(['one', 'two'], ['one'])).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual(['one'], 'one')).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual(['one'], new Object())).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual('one', ['one'])).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual(new Object(), ['one'])).toBe(false);
|
||||
});
|
||||
|
||||
it("should compare primitive numbers", () => {
|
||||
expect(ChangeDetectionUtil.devModeEqual(1, 1)).toBe(true);
|
||||
expect(ChangeDetectionUtil.devModeEqual(1, 2)).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual(new Object(), 2)).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual(1, new Object())).toBe(false);
|
||||
});
|
||||
|
||||
it("should compare primitive strings", () => {
|
||||
expect(ChangeDetectionUtil.devModeEqual('one', 'one')).toBe(true);
|
||||
expect(ChangeDetectionUtil.devModeEqual('one', 'two')).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual(new Object(), 'one')).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual('one', new Object())).toBe(false);
|
||||
});
|
||||
|
||||
it("should compare primitive booleans", () => {
|
||||
expect(ChangeDetectionUtil.devModeEqual(true, true)).toBe(true);
|
||||
expect(ChangeDetectionUtil.devModeEqual(true, false)).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual(new Object(), true)).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual(true, new Object())).toBe(false);
|
||||
});
|
||||
|
||||
it("should compare null", () => {
|
||||
expect(ChangeDetectionUtil.devModeEqual(null, null)).toBe(true);
|
||||
expect(ChangeDetectionUtil.devModeEqual(null, 1)).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual(new Object(), null)).toBe(false);
|
||||
expect(ChangeDetectionUtil.devModeEqual(null, new Object())).toBe(false);
|
||||
});
|
||||
|
||||
it("should return true for other objects", () => {
|
||||
expect(ChangeDetectionUtil.devModeEqual(new Object(), new Object())).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
@ -14,17 +14,11 @@ import {
|
||||
} from 'angular2/src/core/change_detection/differs/default_iterable_differ';
|
||||
|
||||
import {NumberWrapper} from 'angular2/src/facade/lang';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {TestIterable} from '../../../core/change_detection/iterable';
|
||||
import {iterableChangesAsString} from '../../../core/change_detection/util';
|
||||
|
||||
class ItemWithId {
|
||||
constructor(private id: string) {}
|
||||
|
||||
toString() { return `{id: ${this.id}}` }
|
||||
}
|
||||
|
||||
// todo(vicb): UnmodifiableListView / frozen object when implemented
|
||||
export function main() {
|
||||
describe('iterable differ', function() {
|
||||
@ -260,7 +254,6 @@ export function main() {
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
it('should support duplicates', () => {
|
||||
let l = ['a', 'a', 'a', 'b', 'b'];
|
||||
differ.check(l);
|
||||
@ -331,80 +324,5 @@ export function main() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('trackBy function', function() {
|
||||
var differ;
|
||||
|
||||
var trackByItemId = (index: number, item: any): any => item.id;
|
||||
|
||||
var buildItemList =
|
||||
(list: string[]) => { return list.map((val) => {return new ItemWithId(val)}) };
|
||||
|
||||
beforeEach(() => { differ = new DefaultIterableDiffer(trackByItemId); });
|
||||
|
||||
it('should not treat maps as new with track by function', () => {
|
||||
|
||||
let l = buildItemList(['a', 'b', 'c']);
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: [`{id: a}[null->0]`, `{id: b}[null->1]`, `{id: c}[null->2]`],
|
||||
additions: [`{id: a}[null->0]`, `{id: b}[null->1]`, `{id: c}[null->2]`]
|
||||
}));
|
||||
|
||||
l = buildItemList(['a', 'b', 'c']);
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: [`{id: a}`, `{id: b}`, `{id: c}`],
|
||||
previous: [`{id: a}`, `{id: b}`, `{id: c}`]
|
||||
}));
|
||||
});
|
||||
|
||||
it('should track moves normally with track by function', () => {
|
||||
let l = buildItemList(['a', 'b', 'c']);
|
||||
differ.check(l);
|
||||
|
||||
l = buildItemList(['b', 'a', 'c']);
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['{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', () => {
|
||||
let l = buildItemList(['a', 'a']);
|
||||
differ.check(l);
|
||||
|
||||
l = buildItemList(['b', 'a', 'a']);
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['{id: b}[null->0]', '{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]']
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
it('should track removals normally with track by function', () => {
|
||||
let l = buildItemList(['a', 'b', 'c']);
|
||||
differ.check(l);
|
||||
|
||||
ListWrapper.removeAt(l, 2);
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['{id: a}', '{id: b}'],
|
||||
previous: ['{id: a}', '{id: b}', '{id: c}[2->null]'],
|
||||
removals: ['{id: c}[2->null]']
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
294
modules/angular2/test/core/debug/debug_element_spec.ts
Normal file
294
modules/angular2/test/core/debug/debug_element_spec.ts
Normal file
@ -0,0 +1,294 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
xdescribe,
|
||||
describe,
|
||||
dispatchEvent,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
beforeEachProviders,
|
||||
it,
|
||||
xit,
|
||||
TestComponentBuilder
|
||||
} from 'angular2/testing_internal';
|
||||
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
|
||||
import {PromiseWrapper, EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||
|
||||
import {Injectable} from 'angular2/core';
|
||||
import {NgFor, NgIf} from 'angular2/common';
|
||||
import {Scope} from 'angular2/core';
|
||||
import {By} from 'angular2/platform/common_dom';
|
||||
|
||||
import {
|
||||
Directive,
|
||||
Component,
|
||||
View,
|
||||
} from 'angular2/src/core/metadata';
|
||||
|
||||
@Injectable()
|
||||
class Logger {
|
||||
log: string[];
|
||||
|
||||
constructor() { this.log = []; }
|
||||
|
||||
add(thing: string) { this.log.push(thing); }
|
||||
}
|
||||
|
||||
@Directive({selector: '[message]', inputs: ['message']})
|
||||
@Injectable()
|
||||
class MessageDir {
|
||||
logger: Logger;
|
||||
|
||||
constructor(logger: Logger) { this.logger = logger; }
|
||||
|
||||
set message(newMessage) { this.logger.add(newMessage); }
|
||||
}
|
||||
|
||||
@Component({selector: 'child-comp'})
|
||||
@View({
|
||||
template: `<div class="child" message="child">
|
||||
<span class="childnested" message="nestedchild">Child</span>
|
||||
</div>
|
||||
<span class="child" [innerHtml]="childBinding"></span>`,
|
||||
directives: [MessageDir],
|
||||
})
|
||||
@Injectable()
|
||||
class ChildComp {
|
||||
childBinding: string;
|
||||
|
||||
constructor() { this.childBinding = 'Original'; }
|
||||
}
|
||||
|
||||
@Component({selector: 'cond-content-comp', viewProviders: [Logger]})
|
||||
@View({
|
||||
template: `<div class="child" message="child" *ngIf="false"><ng-content></ng-content></div>`,
|
||||
directives: [NgIf, MessageDir],
|
||||
})
|
||||
@Injectable()
|
||||
class ConditionalContentComp {
|
||||
}
|
||||
|
||||
@Component({selector: 'parent-comp', viewProviders: [Logger]})
|
||||
@View({
|
||||
template: `<div class="parent" message="parent">
|
||||
<span class="parentnested" message="nestedparent">Parent</span>
|
||||
</div>
|
||||
<span class="parent" [innerHtml]="parentBinding"></span>
|
||||
<child-comp class="child-comp-class"></child-comp>
|
||||
<cond-content-comp class="cond-content-comp-class"></cond-content-comp>`,
|
||||
directives: [ChildComp, MessageDir, ConditionalContentComp],
|
||||
})
|
||||
@Injectable()
|
||||
class ParentComp {
|
||||
parentBinding: string;
|
||||
constructor() { this.parentBinding = 'OriginalParent'; }
|
||||
}
|
||||
|
||||
@Directive({selector: 'custom-emitter', outputs: ['myevent']})
|
||||
@Injectable()
|
||||
class CustomEmitter {
|
||||
myevent: EventEmitter<any>;
|
||||
|
||||
constructor() { this.myevent = new EventEmitter(); }
|
||||
}
|
||||
|
||||
@Component({selector: 'events-comp'})
|
||||
@View({
|
||||
template: `<button (click)="handleClick()"></button>
|
||||
<custom-emitter (myevent)="handleCustom()"></custom-emitter>`,
|
||||
directives: [CustomEmitter],
|
||||
})
|
||||
@Injectable()
|
||||
class EventsComp {
|
||||
clicked: boolean;
|
||||
customed: boolean;
|
||||
|
||||
constructor() {
|
||||
this.clicked = false;
|
||||
this.customed = false;
|
||||
}
|
||||
|
||||
handleClick() { this.clicked = true; }
|
||||
|
||||
handleCustom() { this.customed = true; }
|
||||
}
|
||||
|
||||
@Component({selector: 'using-for', viewProviders: [Logger]})
|
||||
@View({
|
||||
template: `<span *ngFor="#thing of stuff" [innerHtml]="thing"></span>
|
||||
<ul message="list">
|
||||
<li *ngFor="#item of stuff" [innerHtml]="item"></li>
|
||||
</ul>`,
|
||||
directives: [NgFor, MessageDir],
|
||||
})
|
||||
@Injectable()
|
||||
class UsingFor {
|
||||
stuff: string[];
|
||||
|
||||
constructor() { this.stuff = ['one', 'two', 'three']; }
|
||||
}
|
||||
|
||||
export function main() {
|
||||
describe('debug element', function() {
|
||||
|
||||
it('should list component child elements',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(ParentComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
|
||||
var childEls = componentFixture.debugElement.children;
|
||||
// The root is a lone component, and has no children in the light dom.
|
||||
expect(childEls.length).toEqual(0);
|
||||
|
||||
var rootCompChildren = componentFixture.debugElement.componentViewChildren;
|
||||
// The root component has 4 elements in its shadow view.
|
||||
expect(rootCompChildren.length).toEqual(4);
|
||||
expect(DOM.hasClass(rootCompChildren[0].nativeElement, 'parent')).toBe(true);
|
||||
expect(DOM.hasClass(rootCompChildren[1].nativeElement, 'parent')).toBe(true);
|
||||
expect(DOM.hasClass(rootCompChildren[2].nativeElement, 'child-comp-class'))
|
||||
.toBe(true);
|
||||
expect(DOM.hasClass(rootCompChildren[3].nativeElement, 'cond-content-comp-class'))
|
||||
.toBe(true);
|
||||
|
||||
var nested = rootCompChildren[0].children;
|
||||
expect(nested.length).toEqual(1);
|
||||
expect(DOM.hasClass(nested[0].nativeElement, 'parentnested')).toBe(true);
|
||||
|
||||
var childComponent = rootCompChildren[2];
|
||||
expect(childComponent.children.length).toEqual(0);
|
||||
|
||||
var childCompChildren = childComponent.componentViewChildren;
|
||||
expect(childCompChildren.length).toEqual(2);
|
||||
expect(DOM.hasClass(childCompChildren[0].nativeElement, 'child')).toBe(true);
|
||||
expect(DOM.hasClass(childCompChildren[1].nativeElement, 'child')).toBe(true);
|
||||
|
||||
var childNested = childCompChildren[0].children;
|
||||
expect(childNested.length).toEqual(1);
|
||||
expect(DOM.hasClass(childNested[0].nativeElement, 'childnested')).toBe(true);
|
||||
|
||||
var conditionalContentComp = rootCompChildren[3];
|
||||
expect(conditionalContentComp.children.length).toEqual(0);
|
||||
|
||||
expect(conditionalContentComp.componentViewChildren.length).toEqual(1);
|
||||
var ngIfWithProjectedNgContent = conditionalContentComp.componentViewChildren[0];
|
||||
expect(ngIfWithProjectedNgContent.children.length).toBe(0);
|
||||
expect(ngIfWithProjectedNgContent.componentViewChildren.length).toBe(0);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should list child elements within viewports',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(UsingFor).then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
|
||||
var childEls = componentFixture.debugElement.componentViewChildren;
|
||||
// TODO should this count include the <template> element?
|
||||
expect(childEls.length).toEqual(5);
|
||||
|
||||
var list = childEls[4];
|
||||
expect(list.children.length).toEqual(4);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should query child elements',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(ParentComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
|
||||
var childTestEls = componentFixture.debugElement.queryAll(By.directive(MessageDir));
|
||||
|
||||
expect(childTestEls.length).toBe(4);
|
||||
expect(DOM.hasClass(childTestEls[0].nativeElement, 'parent')).toBe(true);
|
||||
expect(DOM.hasClass(childTestEls[1].nativeElement, 'parentnested')).toBe(true);
|
||||
expect(DOM.hasClass(childTestEls[2].nativeElement, 'child')).toBe(true);
|
||||
expect(DOM.hasClass(childTestEls[3].nativeElement, 'childnested')).toBe(true);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should query child elements in the light DOM',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(ParentComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
|
||||
var parentEl = componentFixture.debugElement.componentViewChildren[0];
|
||||
|
||||
var childTestEls = parentEl.queryAll(By.directive(MessageDir), Scope.light);
|
||||
|
||||
expect(childTestEls.length).toBe(1);
|
||||
expect(DOM.hasClass(childTestEls[0].nativeElement, 'parentnested')).toBe(true);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should query child elements in the current component view DOM',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(ParentComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
|
||||
var childTestEls =
|
||||
componentFixture.debugElement.queryAll(By.directive(MessageDir), Scope.view);
|
||||
|
||||
expect(childTestEls.length).toBe(2);
|
||||
expect(DOM.hasClass(childTestEls[0].nativeElement, 'parent')).toBe(true);
|
||||
expect(DOM.hasClass(childTestEls[1].nativeElement, 'parentnested')).toBe(true);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow injecting from the element injector',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(ParentComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
|
||||
expect(componentFixture.debugElement.componentViewChildren[0].inject(Logger).log)
|
||||
.toEqual(['parent', 'nestedparent', 'child', 'nestedchild']);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should trigger event handlers',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(EventsComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
|
||||
expect(componentFixture.debugElement.componentInstance.clicked).toBe(false);
|
||||
expect(componentFixture.debugElement.componentInstance.customed).toBe(false);
|
||||
|
||||
componentFixture.debugElement.componentViewChildren[0].triggerEventHandler(
|
||||
'click', <Event>{});
|
||||
expect(componentFixture.debugElement.componentInstance.clicked).toBe(true);
|
||||
|
||||
componentFixture.debugElement.componentViewChildren[1].triggerEventHandler(
|
||||
'myevent', <Event>{});
|
||||
expect(componentFixture.debugElement.componentInstance.customed).toBe(true);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
@ -1,392 +0,0 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
xdescribe,
|
||||
describe,
|
||||
dispatchEvent,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
beforeEachProviders,
|
||||
it,
|
||||
xit,
|
||||
TestComponentBuilder
|
||||
} from 'angular2/testing_internal';
|
||||
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
|
||||
import {PromiseWrapper, EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||
|
||||
import {Injectable} from 'angular2/core';
|
||||
import {NgFor, NgIf} from 'angular2/common';
|
||||
import {By} from 'angular2/platform/common_dom';
|
||||
|
||||
import {Directive, Component, View, Input} from 'angular2/src/core/metadata';
|
||||
|
||||
@Injectable()
|
||||
class Logger {
|
||||
log: string[];
|
||||
|
||||
constructor() { this.log = []; }
|
||||
|
||||
add(thing: string) { this.log.push(thing); }
|
||||
}
|
||||
|
||||
@Directive({selector: '[message]', inputs: ['message']})
|
||||
@Injectable()
|
||||
class MessageDir {
|
||||
logger: Logger;
|
||||
|
||||
constructor(logger: Logger) { this.logger = logger; }
|
||||
|
||||
set message(newMessage) { this.logger.add(newMessage); }
|
||||
}
|
||||
|
||||
@Component({selector: 'child-comp'})
|
||||
@View({
|
||||
template: `<div class="child" message="child">
|
||||
<span class="childnested" message="nestedchild">Child</span>
|
||||
</div>
|
||||
<span class="child" [innerHtml]="childBinding"></span>`,
|
||||
directives: [MessageDir],
|
||||
})
|
||||
@Injectable()
|
||||
class ChildComp {
|
||||
childBinding: string;
|
||||
|
||||
constructor() { this.childBinding = 'Original'; }
|
||||
}
|
||||
|
||||
@Component({selector: 'parent-comp', viewProviders: [Logger]})
|
||||
@View({
|
||||
template: `<div class="parent" message="parent">
|
||||
<span class="parentnested" message="nestedparent">Parent</span>
|
||||
</div>
|
||||
<span class="parent" [innerHtml]="parentBinding"></span>
|
||||
<child-comp class="child-comp-class"></child-comp>`,
|
||||
directives: [ChildComp, MessageDir],
|
||||
})
|
||||
@Injectable()
|
||||
class ParentComp {
|
||||
parentBinding: string;
|
||||
constructor() { this.parentBinding = 'OriginalParent'; }
|
||||
}
|
||||
|
||||
@Directive({selector: 'custom-emitter', outputs: ['myevent']})
|
||||
@Injectable()
|
||||
class CustomEmitter {
|
||||
myevent: EventEmitter<any>;
|
||||
|
||||
constructor() { this.myevent = new EventEmitter(); }
|
||||
}
|
||||
|
||||
@Component({selector: 'events-comp'})
|
||||
@View({
|
||||
template: `<button (click)="handleClick()"></button>
|
||||
<custom-emitter (myevent)="handleCustom()"></custom-emitter>`,
|
||||
directives: [CustomEmitter],
|
||||
})
|
||||
@Injectable()
|
||||
class EventsComp {
|
||||
clicked: boolean;
|
||||
customed: boolean;
|
||||
|
||||
constructor() {
|
||||
this.clicked = false;
|
||||
this.customed = false;
|
||||
}
|
||||
|
||||
handleClick() { this.clicked = true; }
|
||||
|
||||
handleCustom() { this.customed = true; }
|
||||
}
|
||||
|
||||
@Component({selector: 'cond-content-comp', viewProviders: [Logger]})
|
||||
@View({
|
||||
template: `<div class="child" message="child" *ngIf="myBool"><ng-content></ng-content></div>`,
|
||||
directives: [NgIf, MessageDir],
|
||||
})
|
||||
@Injectable()
|
||||
class ConditionalContentComp {
|
||||
myBool: boolean = false;
|
||||
}
|
||||
|
||||
@Component({selector: 'conditional-parent-comp', viewProviders: [Logger]})
|
||||
@View({
|
||||
template: `<span class="parent" [innerHtml]="parentBinding"></span>
|
||||
<cond-content-comp class="cond-content-comp-class">
|
||||
<span class="from-parent"></span>
|
||||
</cond-content-comp>`,
|
||||
directives: [ConditionalContentComp],
|
||||
})
|
||||
@Injectable()
|
||||
class ConditionalParentComp {
|
||||
parentBinding: string;
|
||||
constructor() { this.parentBinding = 'OriginalParent'; }
|
||||
}
|
||||
|
||||
@Component({selector: 'using-for', viewProviders: [Logger]})
|
||||
@View({
|
||||
template: `<span *ngFor="#thing of stuff" [innerHtml]="thing"></span>
|
||||
<ul message="list">
|
||||
<li *ngFor="#item of stuff" [innerHtml]="item"></li>
|
||||
</ul>`,
|
||||
directives: [NgFor, MessageDir],
|
||||
})
|
||||
@Injectable()
|
||||
class UsingFor {
|
||||
stuff: string[];
|
||||
constructor() { this.stuff = ['one', 'two', 'three']; }
|
||||
}
|
||||
|
||||
@Directive({selector: '[mydir]', exportAs: 'mydir'})
|
||||
class MyDir {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'locals-comp',
|
||||
template: `
|
||||
<div mydir #alice="mydir"></div>
|
||||
`,
|
||||
directives: [MyDir]
|
||||
})
|
||||
class LocalsComp {
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'bank-account',
|
||||
template: `
|
||||
Bank Name: {{bank}}
|
||||
Account Id: {{id}}
|
||||
`
|
||||
})
|
||||
class BankAccount {
|
||||
@Input() bank: string;
|
||||
@Input('account') id: string;
|
||||
|
||||
normalizedBankName: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'test-app',
|
||||
template: `
|
||||
<bank-account bank="RBC" account="4747"></bank-account>
|
||||
`,
|
||||
directives: [BankAccount]
|
||||
})
|
||||
class TestApp {
|
||||
}
|
||||
|
||||
export function main() {
|
||||
describe('debug element', function() {
|
||||
it('should list all child nodes',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.createAsync(ParentComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
// The root component has 3 elements and 2 text node children.
|
||||
expect(fixture.debugElement.childNodes.length).toEqual(5);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should list all component child elements',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(ParentComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
var childEls = fixture.debugElement.children;
|
||||
|
||||
// The root component has 3 elements in its view.
|
||||
expect(childEls.length).toEqual(3);
|
||||
expect(DOM.hasClass(childEls[0].nativeElement, 'parent')).toBe(true);
|
||||
expect(DOM.hasClass(childEls[1].nativeElement, 'parent')).toBe(true);
|
||||
expect(DOM.hasClass(childEls[2].nativeElement, 'child-comp-class')).toBe(true);
|
||||
|
||||
var nested = childEls[0].children;
|
||||
expect(nested.length).toEqual(1);
|
||||
expect(DOM.hasClass(nested[0].nativeElement, 'parentnested')).toBe(true);
|
||||
|
||||
var childComponent = childEls[2];
|
||||
|
||||
var childCompChildren = childComponent.children;
|
||||
expect(childCompChildren.length).toEqual(2);
|
||||
expect(DOM.hasClass(childCompChildren[0].nativeElement, 'child')).toBe(true);
|
||||
expect(DOM.hasClass(childCompChildren[1].nativeElement, 'child')).toBe(true);
|
||||
|
||||
var childNested = childCompChildren[0].children;
|
||||
expect(childNested.length).toEqual(1);
|
||||
expect(DOM.hasClass(childNested[0].nativeElement, 'childnested')).toBe(true);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should list conditional component child elements',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.createAsync(ConditionalParentComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
var childEls = fixture.debugElement.children;
|
||||
|
||||
// The root component has 2 elements in its view.
|
||||
expect(childEls.length).toEqual(2);
|
||||
expect(DOM.hasClass(childEls[0].nativeElement, 'parent')).toBe(true);
|
||||
expect(DOM.hasClass(childEls[1].nativeElement, 'cond-content-comp-class'))
|
||||
.toBe(true);
|
||||
|
||||
var conditionalContentComp = childEls[1];
|
||||
|
||||
expect(conditionalContentComp.children.length).toEqual(0);
|
||||
|
||||
conditionalContentComp.componentInstance.myBool = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(conditionalContentComp.children.length).toEqual(1);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should list child elements within viewports',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.createAsync(UsingFor).then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
var childEls = fixture.debugElement.children;
|
||||
expect(childEls.length).toEqual(4);
|
||||
|
||||
// The 4th child is the <ul>
|
||||
var list = childEls[3];
|
||||
|
||||
expect(list.children.length).toEqual(3);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should list element attributes',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.createAsync(TestApp).then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
var bankElem = fixture.debugElement.children[0];
|
||||
|
||||
expect(bankElem.attributes.get('bank')).toEqual('RBC');
|
||||
expect(bankElem.attributes.get('account')).toEqual('4747');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should query child elements by css',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.createAsync(ParentComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
var childTestEls = fixture.debugElement.queryAll(By.css('child-comp'));
|
||||
|
||||
expect(childTestEls.length).toBe(1);
|
||||
expect(DOM.hasClass(childTestEls[0].nativeElement, 'child-comp-class')).toBe(true);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should query child elements by directive',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.createAsync(ParentComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
var childTestEls = fixture.debugElement.queryAll(By.directive(MessageDir));
|
||||
|
||||
expect(childTestEls.length).toBe(4);
|
||||
expect(DOM.hasClass(childTestEls[0].nativeElement, 'parent')).toBe(true);
|
||||
expect(DOM.hasClass(childTestEls[1].nativeElement, 'parentnested')).toBe(true);
|
||||
expect(DOM.hasClass(childTestEls[2].nativeElement, 'child')).toBe(true);
|
||||
expect(DOM.hasClass(childTestEls[3].nativeElement, 'childnested')).toBe(true);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should list providerTokens',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(ParentComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.debugElement.providerTokens).toContain(Logger);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should list locals',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.createAsync(LocalsComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.debugElement.children[0].getLocal('alice')).toBeAnInstanceOf(MyDir);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow injecting from the element injector',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(ParentComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.debugElement.children[0].inject(Logger).log)
|
||||
.toEqual(['parent', 'nestedparent', 'child', 'nestedchild']);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should list event listeners',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(EventsComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.debugElement.children[0].listeners.length).toEqual(1);
|
||||
expect(fixture.debugElement.children[1].listeners.length).toEqual(1);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
it('should trigger event handlers',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
|
||||
tcb.createAsync(EventsComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.debugElement.componentInstance.clicked).toBe(false);
|
||||
expect(fixture.debugElement.componentInstance.customed).toBe(false);
|
||||
|
||||
fixture.debugElement.children[0].triggerEventHandler('click', <Event>{});
|
||||
expect(fixture.debugElement.componentInstance.clicked).toBe(true);
|
||||
|
||||
fixture.debugElement.children[1].triggerEventHandler('myevent', <Event>{});
|
||||
expect(fixture.debugElement.componentInstance.customed).toBe(true);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
@ -32,7 +32,8 @@ export function main() {
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.createAsync(App).then((tc) => {
|
||||
tc.detectChanges();
|
||||
expect(asNativeElements(tc.debugElement.children)).toHaveText('frame(lock)');
|
||||
expect(asNativeElements(tc.debugElement.componentViewChildren))
|
||||
.toHaveText('frame(lock)');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
@ -17,11 +17,12 @@ import {
|
||||
} from 'angular2/testing_internal';
|
||||
|
||||
import {OnDestroy} from 'angular2/core';
|
||||
import {Injector} from 'angular2/core';
|
||||
import {Injector, inspectElement} from 'angular2/core';
|
||||
import {NgIf} from 'angular2/common';
|
||||
import {By} from 'angular2/platform/common_dom';
|
||||
import {Component, View, ViewMetadata} from 'angular2/src/core/metadata';
|
||||
import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader';
|
||||
import {ElementRef, ElementRef_} from 'angular2/src/core/linker/element_ref';
|
||||
import {ElementRef} from 'angular2/src/core/linker/element_ref';
|
||||
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {ComponentFixture_} from "angular2/src/testing/test_component_builder";
|
||||
@ -33,80 +34,6 @@ export function main() {
|
||||
describe('DynamicComponentLoader', function() {
|
||||
describe("loading into a location", () => {
|
||||
it('should work',
|
||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||
(loader, tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(
|
||||
MyComp,
|
||||
new ViewMetadata(
|
||||
{template: '<location #loc></location>', directives: [Location]}))
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
loader.loadIntoLocation(DynamicallyLoaded, tc.elementRef, 'loc')
|
||||
.then(ref => {
|
||||
expect(tc.debugElement.nativeElement)
|
||||
.toHaveText("Location;DynamicallyLoaded;");
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should return a disposable component ref',
|
||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||
(loader, tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(
|
||||
MyComp,
|
||||
new ViewMetadata(
|
||||
{template: '<location #loc></location>', directives: [Location]}))
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
|
||||
loader.loadIntoLocation(DynamicallyLoaded, tc.elementRef, 'loc')
|
||||
.then(ref => {
|
||||
ref.dispose();
|
||||
expect(tc.debugElement.nativeElement).toHaveText("Location;");
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow to dispose even if the location has been removed',
|
||||
inject(
|
||||
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||
(loader, tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new ViewMetadata({
|
||||
template: '<child-cmp *ngIf="ctxBoolProp"></child-cmp>',
|
||||
directives: [NgIf, ChildComp]
|
||||
}))
|
||||
.overrideView(
|
||||
ChildComp,
|
||||
new ViewMetadata(
|
||||
{template: '<location #loc></location>', directives: [Location]}))
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
tc.debugElement.componentInstance.ctxBoolProp = true;
|
||||
tc.detectChanges();
|
||||
var childCompEl = (<ElementRef_>tc.elementRef).internalElement;
|
||||
// TODO(juliemr): This is hideous, see if there's a better way to handle
|
||||
// child element refs now.
|
||||
var childElementRef =
|
||||
childCompEl.componentView.appElements[0].nestedViews[0].appElements[0].ref;
|
||||
loader.loadIntoLocation(DynamicallyLoaded, childElementRef, 'loc')
|
||||
.then(ref => {
|
||||
expect(tc.debugElement.nativeElement)
|
||||
.toHaveText("Location;DynamicallyLoaded;");
|
||||
|
||||
tc.debugElement.componentInstance.ctxBoolProp = false;
|
||||
tc.detectChanges();
|
||||
expect(tc.debugElement.nativeElement).toHaveText("");
|
||||
|
||||
ref.dispose();
|
||||
expect(tc.debugElement.nativeElement).toHaveText("");
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should update host properties',
|
||||
inject(
|
||||
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||
(loader, tcb: TestComponentBuilder, async) => {
|
||||
@ -115,20 +42,91 @@ export function main() {
|
||||
{template: '<location #loc></location>', directives: [Location]}))
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
loader.loadIntoLocation(DynamicallyLoadedWithHostProps, tc.elementRef, 'loc')
|
||||
|
||||
loader.loadIntoLocation(DynamicallyLoaded, tc.debugElement.elementRef, 'loc')
|
||||
.then(ref => {
|
||||
ref.instance.id = "new value";
|
||||
|
||||
tc.detectChanges();
|
||||
|
||||
var newlyInsertedElement =
|
||||
DOM.childNodes(tc.debugElement.nativeElement)[1];
|
||||
expect((<HTMLElement>newlyInsertedElement).id).toEqual("new value");
|
||||
expect(tc.debugElement.nativeElement)
|
||||
.toHaveText("Location;DynamicallyLoaded;");
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should return a disposable component ref',
|
||||
inject(
|
||||
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||
(loader, tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(
|
||||
MyComp, new ViewMetadata(
|
||||
{template: '<location #loc></location>', directives: [Location]}))
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
|
||||
loader.loadIntoLocation(DynamicallyLoaded, tc.debugElement.elementRef, 'loc')
|
||||
.then(ref => {
|
||||
ref.dispose();
|
||||
expect(tc.debugElement.nativeElement).toHaveText("Location;");
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow to dispose even if the location has been removed',
|
||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||
(loader, tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new ViewMetadata({
|
||||
template: '<child-cmp *ngIf="ctxBoolProp"></child-cmp>',
|
||||
directives: [NgIf, ChildComp]
|
||||
}))
|
||||
.overrideView(
|
||||
ChildComp,
|
||||
new ViewMetadata(
|
||||
{template: '<location #loc></location>', directives: [Location]}))
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
tc.debugElement.componentInstance.ctxBoolProp = true;
|
||||
tc.detectChanges();
|
||||
var childCompEl = tc.debugElement.query(By.css('child-cmp'));
|
||||
loader.loadIntoLocation(DynamicallyLoaded, childCompEl.elementRef, 'loc')
|
||||
.then(ref => {
|
||||
expect(tc.debugElement.nativeElement)
|
||||
.toHaveText("Location;DynamicallyLoaded;");
|
||||
|
||||
tc.debugElement.componentInstance.ctxBoolProp = false;
|
||||
tc.detectChanges();
|
||||
expect(tc.debugElement.nativeElement).toHaveText("");
|
||||
|
||||
ref.dispose();
|
||||
expect(tc.debugElement.nativeElement).toHaveText("");
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should update host properties',
|
||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||
(loader, tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(
|
||||
MyComp,
|
||||
new ViewMetadata(
|
||||
{template: '<location #loc></location>', directives: [Location]}))
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
loader.loadIntoLocation(DynamicallyLoadedWithHostProps,
|
||||
tc.debugElement.elementRef, 'loc')
|
||||
.then(ref => {
|
||||
ref.instance.id = "new value";
|
||||
|
||||
tc.detectChanges();
|
||||
|
||||
var newlyInsertedElement =
|
||||
DOM.childNodes(tc.debugElement.nativeElement)[1];
|
||||
expect((<HTMLElement>newlyInsertedElement).id).toEqual("new value");
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should leave the view tree in a consistent state if hydration fails',
|
||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||
(loader, tcb: TestComponentBuilder, async) => {
|
||||
@ -141,8 +139,8 @@ export function main() {
|
||||
tc.debugElement
|
||||
|
||||
PromiseWrapper.catchError(
|
||||
loader.loadIntoLocation(DynamicallyLoadedThrows, tc.elementRef,
|
||||
'loc'),
|
||||
loader.loadIntoLocation(DynamicallyLoadedThrows,
|
||||
tc.debugElement.elementRef, 'loc'),
|
||||
error => {
|
||||
expect(error.message).toContain("ThrownInConstructor");
|
||||
expect(() => tc.detectChanges()).not.toThrow();
|
||||
@ -161,7 +159,8 @@ export function main() {
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
expect(() => loader.loadIntoLocation(DynamicallyLoadedWithHostProps,
|
||||
tc.elementRef, 'someUnknownVariable'))
|
||||
tc.debugElement.elementRef,
|
||||
'someUnknownVariable'))
|
||||
.toThrowError('Could not find variable someUnknownVariable');
|
||||
async.done();
|
||||
});
|
||||
@ -174,8 +173,9 @@ export function main() {
|
||||
new ViewMetadata({template: '<div #loc></div>', directives: []}))
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
loader.loadIntoLocation(DynamicallyLoadedWithNgContent, tc.elementRef,
|
||||
'loc', null, [[DOM.createTextNode('hello')]])
|
||||
loader.loadIntoLocation(DynamicallyLoadedWithNgContent,
|
||||
tc.debugElement.elementRef, 'loc', null,
|
||||
[[DOM.createTextNode('hello')]])
|
||||
.then(ref => {
|
||||
tc.detectChanges();
|
||||
expect(tc.nativeElement).toHaveText('dynamic(hello)');
|
||||
@ -193,8 +193,8 @@ export function main() {
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
PromiseWrapper.catchError(
|
||||
loader.loadIntoLocation(DynamicallyLoadedWithNgContent, tc.elementRef,
|
||||
'loc', null, []),
|
||||
loader.loadIntoLocation(DynamicallyLoadedWithNgContent,
|
||||
tc.debugElement.elementRef, 'loc', null, []),
|
||||
(e) => {
|
||||
expect(e.message).toContain(
|
||||
`The component ${stringify(DynamicallyLoadedWithNgContent)} has 1 <ng-content> elements, but only 0 slots were provided`);
|
||||
@ -215,7 +215,7 @@ export function main() {
|
||||
}))
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
loader.loadNextToLocation(DynamicallyLoaded, tc.elementRef)
|
||||
loader.loadNextToLocation(DynamicallyLoaded, tc.debugElement.elementRef)
|
||||
.then(ref => {
|
||||
expect(tc.debugElement.nativeElement).toHaveText("Location;");
|
||||
expect(DOM.nextSibling(tc.debugElement.nativeElement))
|
||||
@ -227,38 +227,38 @@ export function main() {
|
||||
}));
|
||||
|
||||
it('should return a disposable component ref',
|
||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||
(loader, tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new ViewMetadata({
|
||||
template: '<div><location #loc></location></div>',
|
||||
directives: [Location]
|
||||
}))
|
||||
.
|
||||
inject(
|
||||
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||
(loader, tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new ViewMetadata({
|
||||
template: '<div><location #loc></location></div>',
|
||||
directives: [Location]
|
||||
}))
|
||||
.
|
||||
|
||||
createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
loader.loadNextToLocation(DynamicallyLoaded, tc.elementRef)
|
||||
.then(ref => {
|
||||
loader.loadNextToLocation(DynamicallyLoaded2, tc.elementRef)
|
||||
.then(ref2 => {
|
||||
var firstSibling =
|
||||
DOM.nextSibling(tc.debugElement.nativeElement);
|
||||
var secondSibling = DOM.nextSibling(firstSibling);
|
||||
expect(tc.debugElement.nativeElement).toHaveText("Location;");
|
||||
expect(firstSibling).toHaveText("DynamicallyLoaded;");
|
||||
expect(secondSibling).toHaveText("DynamicallyLoaded2;");
|
||||
createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
loader.loadNextToLocation(DynamicallyLoaded, tc.debugElement.elementRef)
|
||||
.then(ref => {
|
||||
loader.loadNextToLocation(DynamicallyLoaded2, tc.debugElement.elementRef)
|
||||
.then(ref2 => {
|
||||
var firstSibling = DOM.nextSibling(tc.debugElement.nativeElement);
|
||||
var secondSibling = DOM.nextSibling(firstSibling);
|
||||
expect(tc.debugElement.nativeElement).toHaveText("Location;");
|
||||
expect(firstSibling).toHaveText("DynamicallyLoaded;");
|
||||
expect(secondSibling).toHaveText("DynamicallyLoaded2;");
|
||||
|
||||
ref2.dispose();
|
||||
ref2.dispose();
|
||||
|
||||
firstSibling = DOM.nextSibling(tc.debugElement.nativeElement);
|
||||
secondSibling = DOM.nextSibling(firstSibling);
|
||||
expect(secondSibling).toBeNull();
|
||||
firstSibling = DOM.nextSibling(tc.debugElement.nativeElement);
|
||||
secondSibling = DOM.nextSibling(firstSibling);
|
||||
expect(secondSibling).toBeNull();
|
||||
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}));
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should update host properties',
|
||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||
@ -271,7 +271,8 @@ export function main() {
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
|
||||
loader.loadNextToLocation(DynamicallyLoadedWithHostProps, tc.elementRef)
|
||||
loader.loadNextToLocation(DynamicallyLoadedWithHostProps,
|
||||
tc.debugElement.elementRef)
|
||||
.then(ref => {
|
||||
ref.instance.id = "new value";
|
||||
|
||||
@ -292,8 +293,9 @@ export function main() {
|
||||
tcb.overrideView(MyComp, new ViewMetadata({template: '', directives: [Location]}))
|
||||
.createAsync(MyComp)
|
||||
.then((tc) => {
|
||||
loader.loadNextToLocation(DynamicallyLoadedWithNgContent, tc.elementRef,
|
||||
null, [[DOM.createTextNode('hello')]])
|
||||
loader.loadNextToLocation(DynamicallyLoadedWithNgContent,
|
||||
tc.debugElement.elementRef, null,
|
||||
[[DOM.createTextNode('hello')]])
|
||||
.then(ref => {
|
||||
tc.detectChanges();
|
||||
var newlyInsertedElement =
|
||||
|
@ -3,7 +3,7 @@ library angular2.test.di.integration_dart_spec;
|
||||
|
||||
import 'package:angular2/angular2.dart';
|
||||
import 'package:angular2/core.dart';
|
||||
import 'package:angular2/src/core/debug/debug_node.dart';
|
||||
import 'package:angular2/src/core/debug/debug_element.dart';
|
||||
import 'package:angular2/testing_internal.dart';
|
||||
import 'package:observe/observe.dart';
|
||||
import 'package:angular2/src/core/change_detection/differs/default_iterable_differ.dart';
|
||||
@ -56,7 +56,7 @@ main() {
|
||||
.createAsync(Dummy)
|
||||
.then((tc) {
|
||||
tc.detectChanges();
|
||||
expect(asNativeElements(tc.debugElement.children))
|
||||
expect(asNativeElements(tc.debugElement.componentViewChildren))
|
||||
.toHaveText('[Hello, World]');
|
||||
async.done();
|
||||
});
|
||||
@ -112,7 +112,7 @@ main() {
|
||||
.createAsync(Dummy)
|
||||
.then((tc) {
|
||||
tc.detectChanges();
|
||||
expect(asNativeElements(tc.debugElement.children))
|
||||
expect(asNativeElements(tc.debugElement.componentViewChildren))
|
||||
.toHaveText('prop:foo-prop;map:foo-map');
|
||||
async.done();
|
||||
});
|
||||
@ -149,7 +149,7 @@ main() {
|
||||
.createAsync(Dummy)
|
||||
.then((tc) {
|
||||
tc.detectChanges();
|
||||
var cmp = tc.debugElement.children[0]
|
||||
var cmp = tc.debugElement.componentViewChildren[0]
|
||||
.inject(OnChangeComponent);
|
||||
expect(cmp.prop).toEqual('hello');
|
||||
expect(cmp.changes.containsKey('prop')).toEqual(true);
|
||||
@ -178,7 +178,7 @@ main() {
|
||||
tc.detectChanges();
|
||||
|
||||
expect(log.result()).toEqual("check");
|
||||
expect(asNativeElements(tc.debugElement.children))
|
||||
expect(asNativeElements(tc.debugElement.componentViewChildren))
|
||||
.toHaveText('12');
|
||||
|
||||
tc.detectChanges();
|
||||
@ -194,7 +194,7 @@ main() {
|
||||
|
||||
// we changed the list => a check
|
||||
expect(log.result()).toEqual("check; check");
|
||||
expect(asNativeElements(tc.debugElement.children))
|
||||
expect(asNativeElements(tc.debugElement.componentViewChildren))
|
||||
.toHaveText('123');
|
||||
|
||||
// we replaced the list => a check
|
||||
@ -204,7 +204,7 @@ main() {
|
||||
tc.detectChanges();
|
||||
|
||||
expect(log.result()).toEqual("check; check; check");
|
||||
expect(asNativeElements(tc.debugElement.children))
|
||||
expect(asNativeElements(tc.debugElement.componentViewChildren))
|
||||
.toHaveText('567');
|
||||
});
|
||||
})));
|
||||
|
@ -160,7 +160,8 @@ function declareTests() {
|
||||
fixture.debugElement.componentInstance.ctxProp = 'Hello World!';
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.debugElement.children[0].nativeElement.id).toEqual('Hello World!');
|
||||
expect(fixture.debugElement.componentViewChildren[0].nativeElement.id)
|
||||
.toEqual('Hello World!');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
@ -175,13 +176,15 @@ function declareTests() {
|
||||
fixture.debugElement.componentInstance.ctxProp = 'Initial aria label';
|
||||
fixture.detectChanges();
|
||||
expect(
|
||||
DOM.getAttribute(fixture.debugElement.children[0].nativeElement, 'aria-label'))
|
||||
DOM.getAttribute(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'aria-label'))
|
||||
.toEqual('Initial aria label');
|
||||
|
||||
fixture.debugElement.componentInstance.ctxProp = 'Changed aria label';
|
||||
fixture.detectChanges();
|
||||
expect(
|
||||
DOM.getAttribute(fixture.debugElement.children[0].nativeElement, 'aria-label'))
|
||||
DOM.getAttribute(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'aria-label'))
|
||||
.toEqual('Changed aria label');
|
||||
|
||||
async.done();
|
||||
@ -198,12 +201,14 @@ function declareTests() {
|
||||
|
||||
fixture.debugElement.componentInstance.ctxProp = 'bar';
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getAttribute(fixture.debugElement.children[0].nativeElement, 'foo'))
|
||||
expect(DOM.getAttribute(
|
||||
fixture.debugElement.componentViewChildren[0].nativeElement, 'foo'))
|
||||
.toEqual('bar');
|
||||
|
||||
fixture.debugElement.componentInstance.ctxProp = null;
|
||||
fixture.detectChanges();
|
||||
expect(DOM.hasAttribute(fixture.debugElement.children[0].nativeElement, 'foo'))
|
||||
expect(DOM.hasAttribute(
|
||||
fixture.debugElement.componentViewChildren[0].nativeElement, 'foo'))
|
||||
.toBeFalsy();
|
||||
|
||||
async.done();
|
||||
@ -220,12 +225,14 @@ function declareTests() {
|
||||
|
||||
fixture.debugElement.componentInstance.ctxProp = '10';
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'height'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'height'))
|
||||
.toEqual('10px');
|
||||
|
||||
fixture.debugElement.componentInstance.ctxProp = null;
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getStyle(fixture.debugElement.children[0].nativeElement, 'height'))
|
||||
expect(DOM.getStyle(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'height'))
|
||||
.toEqual('');
|
||||
|
||||
async.done();
|
||||
@ -241,11 +248,13 @@ function declareTests() {
|
||||
.then((fixture) => {
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.children[0].nativeElement.tabIndex).toEqual(0);
|
||||
expect(fixture.debugElement.componentViewChildren[0].nativeElement.tabIndex)
|
||||
.toEqual(0);
|
||||
|
||||
fixture.debugElement.componentInstance.ctxNumProp = 5;
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.children[0].nativeElement.tabIndex).toEqual(5);
|
||||
expect(fixture.debugElement.componentViewChildren[0].nativeElement.tabIndex)
|
||||
.toEqual(5);
|
||||
|
||||
async.done();
|
||||
});
|
||||
@ -260,11 +269,13 @@ function declareTests() {
|
||||
.then((fixture) => {
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.children[0].nativeElement.readOnly).toBeFalsy();
|
||||
expect(fixture.debugElement.componentViewChildren[0].nativeElement.readOnly)
|
||||
.toBeFalsy();
|
||||
|
||||
fixture.debugElement.componentInstance.ctxBoolProp = true;
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.children[0].nativeElement.readOnly).toBeTruthy();
|
||||
expect(fixture.debugElement.componentViewChildren[0].nativeElement.readOnly)
|
||||
.toBeTruthy();
|
||||
|
||||
async.done();
|
||||
});
|
||||
@ -280,12 +291,14 @@ function declareTests() {
|
||||
|
||||
fixture.debugElement.componentInstance.ctxProp = 'Some <span>HTML</span>';
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getInnerHTML(fixture.debugElement.children[0].nativeElement))
|
||||
expect(
|
||||
DOM.getInnerHTML(fixture.debugElement.componentViewChildren[0].nativeElement))
|
||||
.toEqual('Some <span>HTML</span>');
|
||||
|
||||
fixture.debugElement.componentInstance.ctxProp = 'Some other <div>HTML</div>';
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getInnerHTML(fixture.debugElement.children[0].nativeElement))
|
||||
expect(
|
||||
DOM.getInnerHTML(fixture.debugElement.componentViewChildren[0].nativeElement))
|
||||
.toEqual('Some other <div>HTML</div>');
|
||||
|
||||
async.done();
|
||||
@ -300,7 +313,7 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var nativeEl = fixture.debugElement.children[0].nativeElement;
|
||||
var nativeEl = fixture.debugElement.componentViewChildren[0].nativeElement;
|
||||
fixture.debugElement.componentInstance.ctxProp = 'foo bar';
|
||||
fixture.detectChanges();
|
||||
|
||||
@ -327,12 +340,13 @@ function declareTests() {
|
||||
fixture.debugElement.componentInstance.ctxProp = 'Hello World!';
|
||||
fixture.detectChanges();
|
||||
|
||||
var containerSpan = fixture.debugElement.children[0];
|
||||
|
||||
expect(containerSpan.children[0].inject(MyDir).dirProp).toEqual('Hello World!');
|
||||
expect(containerSpan.children[1].inject(MyDir).dirProp).toEqual('Hi there!');
|
||||
expect(containerSpan.children[2].inject(MyDir).dirProp).toEqual('Hi there!');
|
||||
expect(containerSpan.children[3].inject(MyDir).dirProp)
|
||||
expect(fixture.debugElement.componentViewChildren[0].inject(MyDir).dirProp)
|
||||
.toEqual('Hello World!');
|
||||
expect(fixture.debugElement.componentViewChildren[1].inject(MyDir).dirProp)
|
||||
.toEqual('Hi there!');
|
||||
expect(fixture.debugElement.componentViewChildren[2].inject(MyDir).dirProp)
|
||||
.toEqual('Hi there!');
|
||||
expect(fixture.debugElement.componentViewChildren[3].inject(MyDir).dirProp)
|
||||
.toEqual('One more Hello World!');
|
||||
async.done();
|
||||
});
|
||||
@ -354,7 +368,7 @@ function declareTests() {
|
||||
fixture.debugElement.componentInstance.ctxProp = 'a';
|
||||
fixture.detectChanges();
|
||||
|
||||
var dir = fixture.debugElement.children[0].getLocal('dir');
|
||||
var dir = fixture.debugElement.componentViewChildren[0].getLocal('dir');
|
||||
expect(dir.dirProp).toEqual('aa');
|
||||
async.done();
|
||||
});
|
||||
@ -391,7 +405,7 @@ function declareTests() {
|
||||
fixture.debugElement.componentInstance.ctxProp = 'Hello World!';
|
||||
fixture.detectChanges();
|
||||
|
||||
var tc = fixture.debugElement.children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[0];
|
||||
|
||||
expect(tc.inject(MyDir).dirProp).toEqual('Hello World!');
|
||||
expect(tc.inject(ChildComp).dirProp).toEqual(null);
|
||||
@ -433,7 +447,7 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var tc = fixture.debugElement.children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[0];
|
||||
var idDir = tc.inject(IdDir);
|
||||
|
||||
fixture.debugElement.componentInstance.ctxProp = 'some_id';
|
||||
@ -549,7 +563,7 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
expect(fixture.debugElement.children[0].children[0].getLocal('alice'))
|
||||
expect(fixture.debugElement.componentViewChildren[0].getLocal('alice'))
|
||||
.toBeAnInstanceOf(ChildComp);
|
||||
|
||||
async.done();
|
||||
@ -565,7 +579,7 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
expect(fixture.debugElement.children[0].children[0].getLocal('localdir'))
|
||||
expect(fixture.debugElement.componentViewChildren[0].getLocal('localdir'))
|
||||
.toBeAnInstanceOf(ExportDir);
|
||||
|
||||
async.done();
|
||||
@ -606,31 +620,34 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var childCmp = fixture.debugElement.children[0].children[0];
|
||||
|
||||
expect(childCmp.getLocal('alice')).toBeAnInstanceOf(ChildComp);
|
||||
expect(childCmp.getLocal('bob')).toBeAnInstanceOf(ChildComp);
|
||||
expect(childCmp.getLocal('alice')).not.toBe(childCmp.getLocal('bob'));
|
||||
expect(fixture.debugElement.componentViewChildren[0].getLocal('alice'))
|
||||
.toBeAnInstanceOf(ChildComp);
|
||||
expect(fixture.debugElement.componentViewChildren[0].getLocal('bob'))
|
||||
.toBeAnInstanceOf(ChildComp);
|
||||
expect(fixture.debugElement.componentViewChildren[0].getLocal('alice'))
|
||||
.not.toBe(
|
||||
fixture.debugElement.componentViewChildren[0].getLocal('bob'));
|
||||
|
||||
async.done();
|
||||
})}));
|
||||
|
||||
it('should assign the component instance to a var- with shorthand syntax',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter],
|
||||
(tcb: TestComponentBuilder,
|
||||
async) => {tcb.overrideView(MyComp, new ViewMetadata({
|
||||
template: '<child-cmp #alice></child-cmp>',
|
||||
directives: [ChildComp]
|
||||
}))
|
||||
(tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new ViewMetadata({
|
||||
template: '<child-cmp #alice></child-cmp>',
|
||||
directives: [ChildComp]
|
||||
}))
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
|
||||
expect(fixture.debugElement.children[0].getLocal('alice'))
|
||||
.toBeAnInstanceOf(ChildComp);
|
||||
expect(fixture.debugElement.componentViewChildren[0].getLocal('alice'))
|
||||
.toBeAnInstanceOf(ChildComp);
|
||||
|
||||
async.done();
|
||||
})}));
|
||||
async.done();
|
||||
})}));
|
||||
|
||||
it('should assign the element instance to a user-defined variable',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter],
|
||||
@ -643,7 +660,7 @@ function declareTests() {
|
||||
.then((fixture) => {
|
||||
|
||||
var value =
|
||||
fixture.debugElement.children[0].children[0].getLocal('alice');
|
||||
fixture.debugElement.componentViewChildren[0].getLocal('alice');
|
||||
expect(value).not.toBe(null);
|
||||
expect(value.tagName.toLowerCase()).toEqual('div');
|
||||
|
||||
@ -660,7 +677,7 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
expect(fixture.debugElement.children[0].children[0].getLocal('superAlice'))
|
||||
expect(fixture.debugElement.componentViewChildren[0].getLocal('superAlice'))
|
||||
.toBeAnInstanceOf(ChildComp);
|
||||
|
||||
async.done();
|
||||
@ -702,7 +719,7 @@ function declareTests() {
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
|
||||
var cmp = fixture.debugElement.children[0].getLocal('cmp');
|
||||
var cmp = fixture.debugElement.componentViewChildren[0].getLocal('cmp');
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(1);
|
||||
@ -728,7 +745,7 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var cmp = fixture.debugElement.children[0].getLocal('cmp');
|
||||
var cmp = fixture.debugElement.componentViewChildren[0].getLocal('cmp');
|
||||
|
||||
fixture.debugElement.componentInstance.ctxProp = "one";
|
||||
fixture.detectChanges();
|
||||
@ -754,7 +771,7 @@ function declareTests() {
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
|
||||
var cmp = fixture.debugElement.children[0].getLocal('cmp');
|
||||
var cmp = fixture.debugElement.componentViewChildren[0].getLocal('cmp');
|
||||
|
||||
fixture.debugElement.componentInstance.ctxProp = "one";
|
||||
fixture.detectChanges();
|
||||
@ -780,7 +797,7 @@ function declareTests() {
|
||||
tcb.createAsync(MyComp).then(root => { fixture = root; });
|
||||
tick();
|
||||
|
||||
var cmp = fixture.debugElement.children[0].getLocal('cmp');
|
||||
var cmp = fixture.debugElement.componentViewChildren[0].getLocal('cmp');
|
||||
fixture.detectChanges();
|
||||
expect(cmp.numberOfChecks).toEqual(1);
|
||||
|
||||
@ -813,7 +830,8 @@ function declareTests() {
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
|
||||
var childComponent = fixture.debugElement.children[0].getLocal('child');
|
||||
var childComponent =
|
||||
fixture.debugElement.componentViewChildren[0].getLocal('child');
|
||||
expect(childComponent.myHost).toBeAnInstanceOf(SomeDirective);
|
||||
|
||||
async.done();
|
||||
@ -835,7 +853,7 @@ function declareTests() {
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
var tc = fixture.debugElement.children[0].children[0].children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[0].children[1];
|
||||
|
||||
var childComponent = tc.getLocal('child');
|
||||
expect(childComponent.myHost).toBeAnInstanceOf(SomeDirective);
|
||||
@ -854,7 +872,7 @@ function declareTests() {
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
|
||||
var tc = fixture.debugElement.children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[0];
|
||||
var emitter = tc.inject(DirectiveEmittingEvent);
|
||||
var listener = tc.inject(DirectiveListeningEvent);
|
||||
|
||||
@ -889,10 +907,9 @@ function declareTests() {
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
|
||||
var tc = fixture.debugElement.childNodes[0];
|
||||
|
||||
var tc = fixture.debugElement.componentViewChildren[0];
|
||||
var emitter = tc.inject(DirectiveEmittingEvent);
|
||||
var myComp = fixture.debugElement.inject(MyComp);
|
||||
var myComp = tc.inject(MyComp);
|
||||
var listener = tc.inject(DirectiveListeningEvent);
|
||||
|
||||
myComp.ctxProp = '';
|
||||
@ -917,7 +934,7 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var tc = fixture.debugElement.children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[0];
|
||||
var dir = tc.inject(DirectiveWithTwoWayBinding);
|
||||
|
||||
fixture.debugElement.componentInstance.ctxProp = 'one';
|
||||
@ -944,7 +961,7 @@ function declareTests() {
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
|
||||
var tc = fixture.debugElement.children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[0];
|
||||
var listener = tc.inject(DirectiveListeningDomEvent);
|
||||
|
||||
dispatchEvent(tc.nativeElement, 'domEvent');
|
||||
@ -971,7 +988,7 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var tc = fixture.debugElement.children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[0];
|
||||
var listener = tc.inject(DirectiveListeningDomEvent);
|
||||
dispatchEvent(DOM.getGlobalEventTarget("window"), 'domEvent');
|
||||
expect(listener.eventTypes).toEqual(['window_domEvent']);
|
||||
@ -1000,7 +1017,8 @@ function declareTests() {
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(DOM.getAttribute(fixture.debugElement.children[0].nativeElement, "role"))
|
||||
expect(DOM.getAttribute(
|
||||
fixture.debugElement.componentViewChildren[0].nativeElement, "role"))
|
||||
.toEqual("button");
|
||||
|
||||
async.done();
|
||||
@ -1016,7 +1034,7 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var tc = fixture.debugElement.children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[0];
|
||||
var updateHost = tc.inject(DirectiveUpdatingHostProperties);
|
||||
|
||||
updateHost.id = "newId";
|
||||
@ -1048,15 +1066,17 @@ function declareTests() {
|
||||
.then((fixture) => {
|
||||
var dispatchedEvent = DOM.createMouseEvent('click');
|
||||
var dispatchedEvent2 = DOM.createMouseEvent('click');
|
||||
DOM.dispatchEvent(fixture.debugElement.children[0].nativeElement,
|
||||
DOM.dispatchEvent(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
dispatchedEvent);
|
||||
DOM.dispatchEvent(fixture.debugElement.children[1].nativeElement,
|
||||
DOM.dispatchEvent(fixture.debugElement.componentViewChildren[1].nativeElement,
|
||||
dispatchedEvent2);
|
||||
expect(DOM.isPrevented(dispatchedEvent)).toBe(true);
|
||||
expect(DOM.isPrevented(dispatchedEvent2)).toBe(false);
|
||||
expect(DOM.getChecked(fixture.debugElement.children[0].nativeElement))
|
||||
expect(
|
||||
DOM.getChecked(fixture.debugElement.componentViewChildren[0].nativeElement))
|
||||
.toBeFalsy();
|
||||
expect(DOM.getChecked(fixture.debugElement.children[1].nativeElement))
|
||||
expect(
|
||||
DOM.getChecked(fixture.debugElement.componentViewChildren[1].nativeElement))
|
||||
.toBeTruthy();
|
||||
async.done();
|
||||
});
|
||||
@ -1078,7 +1098,7 @@ function declareTests() {
|
||||
fixture.debugElement.componentInstance.ctxBoolProp = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
var tc = fixture.debugElement.children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[1];
|
||||
|
||||
var listener = tc.inject(DirectiveListeningDomEvent);
|
||||
var listenerother = tc.inject(DirectiveListeningDomEventOther);
|
||||
@ -1116,11 +1136,11 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var tc = fixture.debugElement.children[0].children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[0];
|
||||
var dynamicVp = tc.inject(DynamicViewport);
|
||||
dynamicVp.done.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.children[0].children[1].nativeElement)
|
||||
expect(fixture.debugElement.componentViewChildren[1].nativeElement)
|
||||
.toHaveText('dynamic greet');
|
||||
async.done();
|
||||
});
|
||||
@ -1137,7 +1157,7 @@ function declareTests() {
|
||||
{template: '<input static type="text" title>', directives: [NeedsAttribute]}))
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var tc = fixture.debugElement.children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[0];
|
||||
var needsAttribute = tc.inject(NeedsAttribute);
|
||||
expect(needsAttribute.typeAttribute).toEqual('text');
|
||||
expect(needsAttribute.staticAttribute).toEqual('');
|
||||
@ -1163,7 +1183,7 @@ function declareTests() {
|
||||
}))
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var comp = fixture.debugElement.children[0].getLocal("consuming");
|
||||
var comp = fixture.debugElement.componentViewChildren[0].getLocal("consuming");
|
||||
expect(comp.injectable).toBeAnInstanceOf(InjectableService);
|
||||
|
||||
async.done();
|
||||
@ -1181,7 +1201,7 @@ function declareTests() {
|
||||
}))
|
||||
.createAsync(DirectiveProvidingInjectableInView)
|
||||
.then((fixture) => {
|
||||
var comp = fixture.debugElement.children[0].getLocal("consuming");
|
||||
var comp = fixture.debugElement.componentViewChildren[0].getLocal("consuming");
|
||||
expect(comp.injectable).toBeAnInstanceOf(InjectableService);
|
||||
|
||||
async.done();
|
||||
@ -1211,7 +1231,7 @@ function declareTests() {
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var comp = fixture.debugElement.children[0].getLocal("dir");
|
||||
var comp = fixture.debugElement.componentViewChildren[0].getLocal("dir");
|
||||
expect(comp.directive.injectable).toBeAnInstanceOf(InjectableService);
|
||||
|
||||
async.done();
|
||||
@ -1237,7 +1257,7 @@ function declareTests() {
|
||||
}))
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var gpComp = fixture.debugElement.children[0];
|
||||
var gpComp = fixture.debugElement.componentViewChildren[0];
|
||||
var parentComp = gpComp.children[0];
|
||||
var childComp = parentComp.children[0];
|
||||
|
||||
@ -1269,7 +1289,8 @@ function declareTests() {
|
||||
}))
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
var providing = fixture.debugElement.children[0].getLocal("providing");
|
||||
var providing =
|
||||
fixture.debugElement.componentViewChildren[0].getLocal("providing");
|
||||
expect(providing.created).toBe(false);
|
||||
|
||||
fixture.debugElement.componentInstance.ctxBoolProp = true;
|
||||
@ -1414,7 +1435,7 @@ function declareTests() {
|
||||
tcb.createAsync(MyComp).then(root => { fixture = root; });
|
||||
tick();
|
||||
|
||||
var tc = fixture.debugElement.children[0];
|
||||
var tc = fixture.debugElement.componentViewChildren[0];
|
||||
tc.inject(DirectiveEmittingEvent).fireEvent("boom");
|
||||
|
||||
try {
|
||||
@ -1729,7 +1750,8 @@ function declareTests() {
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
var dir = fixture.debugElement.children[0].inject(DirectiveWithPropDecorators);
|
||||
var dir = fixture.debugElement.componentViewChildren[0].inject(
|
||||
DirectiveWithPropDecorators);
|
||||
expect(dir.dirProp).toEqual("aaa");
|
||||
async.done();
|
||||
});
|
||||
@ -1744,11 +1766,13 @@ function declareTests() {
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
var dir = fixture.debugElement.children[0].inject(DirectiveWithPropDecorators);
|
||||
var dir = fixture.debugElement.componentViewChildren[0].inject(
|
||||
DirectiveWithPropDecorators);
|
||||
dir.myAttr = "aaa";
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(DOM.getOuterHTML(fixture.debugElement.children[0].nativeElement))
|
||||
expect(
|
||||
DOM.getOuterHTML(fixture.debugElement.componentViewChildren[0].nativeElement))
|
||||
.toContain('my-attr="aaa"');
|
||||
async.done();
|
||||
});
|
||||
@ -1767,8 +1791,8 @@ function declareTests() {
|
||||
tcb.createAsync(MyComp).then(root => { fixture = root; });
|
||||
tick();
|
||||
|
||||
var emitter =
|
||||
fixture.debugElement.children[0].inject(DirectiveWithPropDecorators);
|
||||
var emitter = fixture.debugElement.componentViewChildren[0].inject(
|
||||
DirectiveWithPropDecorators);
|
||||
emitter.fireEvent('fired !');
|
||||
|
||||
tick();
|
||||
@ -1778,23 +1802,24 @@ function declareTests() {
|
||||
|
||||
|
||||
it('should support host listener decorators',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder,
|
||||
async) => {
|
||||
tcb.overrideView(MyComp, new ViewMetadata({
|
||||
template: '<with-prop-decorators></with-prop-decorators>',
|
||||
directives: [DirectiveWithPropDecorators]
|
||||
}))
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
var dir = fixture.debugElement.children[0].inject(DirectiveWithPropDecorators);
|
||||
var native = fixture.debugElement.children[0].nativeElement;
|
||||
DOM.dispatchEvent(native, DOM.createMouseEvent('click'));
|
||||
inject([TestComponentBuilder, AsyncTestCompleter],
|
||||
(tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new ViewMetadata({
|
||||
template: '<with-prop-decorators></with-prop-decorators>',
|
||||
directives: [DirectiveWithPropDecorators]
|
||||
}))
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
var dir = fixture.debugElement.componentViewChildren[0].inject(
|
||||
DirectiveWithPropDecorators);
|
||||
var native = fixture.debugElement.componentViewChildren[0].nativeElement;
|
||||
DOM.dispatchEvent(native, DOM.createMouseEvent('click'));
|
||||
|
||||
expect(dir.target).toBe(native);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
expect(dir.target).toBe(native);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
it('should support defining views in the component decorator',
|
||||
@ -1806,7 +1831,7 @@ function declareTests() {
|
||||
.createAsync(MyComp)
|
||||
.then((fixture) => {
|
||||
fixture.detectChanges();
|
||||
var native = fixture.debugElement.children[0].nativeElement;
|
||||
var native = fixture.debugElement.componentViewChildren[0].nativeElement;
|
||||
expect(native).toHaveText("No View Decorator: 123");
|
||||
async.done();
|
||||
});
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
} from 'angular2/testing_internal';
|
||||
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {AppViewListener} from 'angular2/src/core/linker/view_listener';
|
||||
|
||||
import {
|
||||
bind,
|
||||
@ -33,15 +34,17 @@ import {
|
||||
View,
|
||||
ViewContainerRef,
|
||||
ViewEncapsulation,
|
||||
ViewMetadata
|
||||
ViewMetadata,
|
||||
Scope
|
||||
} from 'angular2/core';
|
||||
import {
|
||||
By,
|
||||
} from 'angular2/platform/common_dom';
|
||||
import {getAllDebugNodes} from 'angular2/src/core/debug/debug_node';
|
||||
|
||||
export function main() {
|
||||
describe('projection', () => {
|
||||
beforeEachProviders(() => [provide(AppViewListener, {useClass: AppViewListener})]);
|
||||
|
||||
it('should support simple components',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MainComp, new ViewMetadata({
|
||||
@ -196,8 +199,7 @@ export function main() {
|
||||
.then((main) => {
|
||||
|
||||
var viewportDirectives =
|
||||
main.debugElement.children[0]
|
||||
.childNodes.filter(By.directive(ManualViewportDirective))
|
||||
main.debugElement.queryAll(By.directive(ManualViewportDirective))
|
||||
.map(de => de.inject(ManualViewportDirective));
|
||||
|
||||
expect(main.debugElement.nativeElement).toHaveText('(, B)');
|
||||
@ -242,8 +244,8 @@ export function main() {
|
||||
.then((main) => {
|
||||
|
||||
var viewportDirective =
|
||||
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].inject(
|
||||
ManualViewportDirective);
|
||||
main.debugElement.query(By.directive(ManualViewportDirective))
|
||||
.inject(ManualViewportDirective);
|
||||
|
||||
expect(main.debugElement.nativeElement).toHaveText('OUTER(INNER(INNERINNER(,BC)))');
|
||||
viewportDirective.show();
|
||||
@ -267,8 +269,8 @@ export function main() {
|
||||
.then((main) => {
|
||||
|
||||
var viewportDirective =
|
||||
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].inject(
|
||||
ManualViewportDirective);
|
||||
main.debugElement.query(By.directive(ManualViewportDirective))
|
||||
.inject(ManualViewportDirective);
|
||||
|
||||
expect(main.debugElement.nativeElement).toHaveText('(, BC)');
|
||||
|
||||
@ -334,20 +336,12 @@ export function main() {
|
||||
}))
|
||||
.createAsync(MainComp)
|
||||
.then((main) => {
|
||||
var sourceDirective;
|
||||
|
||||
// We can't use the child nodes to get a hold of this because it's not in the dom at
|
||||
// all.
|
||||
getAllDebugNodes().forEach((debug) => {
|
||||
if (debug.providerTokens.indexOf(ManualViewportDirective) !== -1) {
|
||||
sourceDirective = debug.inject(ManualViewportDirective);
|
||||
}
|
||||
});
|
||||
|
||||
var sourceDirective: ManualViewportDirective =
|
||||
main.debugElement.query(By.directive(ManualViewportDirective))
|
||||
.inject(ManualViewportDirective);
|
||||
var projectDirective: ProjectDirective =
|
||||
main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].inject(
|
||||
ProjectDirective);
|
||||
|
||||
main.debugElement.query(By.directive(ProjectDirective)).inject(ProjectDirective);
|
||||
expect(main.debugElement.nativeElement).toHaveText('START()END');
|
||||
|
||||
projectDirective.show(sourceDirective.templateRef);
|
||||
@ -367,11 +361,10 @@ export function main() {
|
||||
.then((main) => {
|
||||
|
||||
var sourceDirective: ManualViewportDirective =
|
||||
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].inject(
|
||||
ManualViewportDirective);
|
||||
main.debugElement.query(By.directive(ManualViewportDirective))
|
||||
.inject(ManualViewportDirective);
|
||||
var projectDirective: ProjectDirective =
|
||||
main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].inject(
|
||||
ProjectDirective);
|
||||
main.debugElement.query(By.directive(ProjectDirective)).inject(ProjectDirective);
|
||||
expect(main.debugElement.nativeElement).toHaveText('SIMPLE()START()END');
|
||||
|
||||
projectDirective.show(sourceDirective.templateRef);
|
||||
@ -396,11 +389,10 @@ export function main() {
|
||||
.then((main) => {
|
||||
|
||||
var sourceDirective: ManualViewportDirective =
|
||||
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].inject(
|
||||
ManualViewportDirective);
|
||||
main.debugElement.query(By.directive(ManualViewportDirective))
|
||||
.inject(ManualViewportDirective);
|
||||
var projectDirective: ProjectDirective =
|
||||
main.debugElement.queryAllNodes(By.directive(ProjectDirective))[0].inject(
|
||||
ProjectDirective);
|
||||
main.debugElement.query(By.directive(ProjectDirective)).inject(ProjectDirective);
|
||||
expect(main.debugElement.nativeElement).toHaveText('(, B)START()END');
|
||||
|
||||
projectDirective.show(sourceDirective.templateRef);
|
||||
@ -427,8 +419,8 @@ export function main() {
|
||||
|
||||
main.detectChanges();
|
||||
var manualDirective: ManualViewportDirective =
|
||||
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0].inject(
|
||||
ManualViewportDirective);
|
||||
main.debugElement.query(By.directive(ManualViewportDirective))
|
||||
.inject(ManualViewportDirective);
|
||||
expect(main.debugElement.nativeElement).toHaveText('TREE(0:)');
|
||||
manualDirective.show();
|
||||
main.detectChanges();
|
||||
@ -488,12 +480,12 @@ export function main() {
|
||||
expect(main.debugElement.nativeElement).toHaveText('MAIN()');
|
||||
|
||||
var viewportElement =
|
||||
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[0];
|
||||
main.debugElement.componentViewChildren[0].componentViewChildren[0];
|
||||
viewportElement.inject(ManualViewportDirective).show();
|
||||
expect(main.debugElement.nativeElement).toHaveText('MAIN(FIRST())');
|
||||
|
||||
viewportElement =
|
||||
main.debugElement.queryAllNodes(By.directive(ManualViewportDirective))[1];
|
||||
main.debugElement.componentViewChildren[0].componentViewChildren[1];
|
||||
viewportElement.inject(ManualViewportDirective).show();
|
||||
expect(main.debugElement.nativeElement).toHaveText('MAIN(FIRST(SECOND(a)))');
|
||||
|
||||
@ -548,24 +540,21 @@ export function main() {
|
||||
.then((main) => {
|
||||
var conditionalComp =
|
||||
main.debugElement.query(By.directive(ConditionalContentComponent));
|
||||
|
||||
var viewViewportDir =
|
||||
conditionalComp.queryAllNodes(By.directive(ManualViewportDirective))[0].inject(
|
||||
ManualViewportDirective);
|
||||
|
||||
expect(main.debugElement.nativeElement).toHaveText('(, D)');
|
||||
expect(main.debugElement.nativeElement).toHaveText('(, D)');
|
||||
|
||||
viewViewportDir.show();
|
||||
|
||||
expect(main.debugElement.nativeElement).toHaveText('(AC, D)');
|
||||
conditionalComp.query(By.directive(ManualViewportDirective), Scope.view)
|
||||
.inject(ManualViewportDirective);
|
||||
|
||||
var contentViewportDir =
|
||||
conditionalComp.queryAllNodes(By.directive(ManualViewportDirective))[1].inject(
|
||||
ManualViewportDirective);
|
||||
conditionalComp.query(By.directive(ManualViewportDirective), Scope.light)
|
||||
.inject(ManualViewportDirective);
|
||||
|
||||
expect(main.debugElement.nativeElement).toHaveText('(, D)');
|
||||
expect(main.debugElement.nativeElement).toHaveText('(, D)');
|
||||
// first show content viewport, then the view viewport,
|
||||
// i.e. projection needs to take create of already
|
||||
// created views
|
||||
contentViewportDir.show();
|
||||
|
||||
viewViewportDir.show();
|
||||
expect(main.debugElement.nativeElement).toHaveText('(ABC, D)');
|
||||
|
||||
// hide view viewport, and test that it also hides
|
||||
|
@ -53,7 +53,8 @@ export function main() {
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
|
||||
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|');
|
||||
expect(asNativeElements(view.debugElement.componentViewChildren))
|
||||
.toHaveText('2|3|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
@ -69,7 +70,7 @@ export function main() {
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
|
||||
var q = view.debugElement.children[0].getLocal('q');
|
||||
var q = view.debugElement.componentViewChildren[0].getLocal('q');
|
||||
|
||||
view.detectChanges();
|
||||
|
||||
@ -91,7 +92,7 @@ export function main() {
|
||||
view.debugElement.componentInstance.shouldShow = true;
|
||||
view.detectChanges();
|
||||
|
||||
var q = view.debugElement.children[0].getLocal('q');
|
||||
var q = view.debugElement.componentViewChildren[0].getLocal('q');
|
||||
|
||||
expect(q.log).toEqual([["setter", "foo"], ["init", "foo"], ["check", "foo"]]);
|
||||
|
||||
@ -120,36 +121,7 @@ export function main() {
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
var q = view.debugElement.children[0].getLocal('q');
|
||||
|
||||
expect(q.log).toEqual([["setter", "foo"], ["init", "foo"], ["check", "foo"]]);
|
||||
|
||||
q.shouldShow = false;
|
||||
view.detectChanges();
|
||||
|
||||
expect(q.log).toEqual([
|
||||
["setter", "foo"],
|
||||
["init", "foo"],
|
||||
["check", "foo"],
|
||||
["setter", null],
|
||||
["check", null]
|
||||
]);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should contain the first view child accross embedded views',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
var template = '<needs-view-child #q></needs-view-child>';
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.overrideTemplate(
|
||||
NeedsViewChild,
|
||||
'<div *ngIf="true"><div *ngIf="shouldShow" text="foo"></div></div>')
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
var q = view.debugElement.children[0].getLocal('q');
|
||||
var q = view.debugElement.componentViewChildren[0].getLocal('q');
|
||||
|
||||
expect(q.log).toEqual([["setter", "foo"], ["init", "foo"], ["check", "foo"]]);
|
||||
|
||||
@ -180,7 +152,8 @@ export function main() {
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|4|');
|
||||
expect(asNativeElements(view.debugElement.componentViewChildren))
|
||||
.toHaveText('2|3|4|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
@ -196,7 +169,8 @@ export function main() {
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|');
|
||||
expect(asNativeElements(view.debugElement.componentViewChildren))
|
||||
.toHaveText('2|3|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
@ -214,11 +188,12 @@ export function main() {
|
||||
.then((view) => {
|
||||
|
||||
view.detectChanges();
|
||||
expect(asNativeElements(view.debugElement.children)).toHaveText('2|');
|
||||
expect(asNativeElements(view.debugElement.componentViewChildren)).toHaveText('2|');
|
||||
|
||||
view.debugElement.componentInstance.shouldShow = true;
|
||||
view.detectChanges();
|
||||
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3|');
|
||||
expect(asNativeElements(view.debugElement.componentViewChildren))
|
||||
.toHaveText('2|3|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
@ -254,11 +229,13 @@ export function main() {
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
|
||||
expect(asNativeElements(view.debugElement.children)).toHaveText('2|1d|2d|3d|');
|
||||
expect(asNativeElements(view.debugElement.componentViewChildren))
|
||||
.toHaveText('2|1d|2d|3d|');
|
||||
|
||||
view.debugElement.componentInstance.list = ['3d', '2d'];
|
||||
view.detectChanges();
|
||||
expect(asNativeElements(view.debugElement.children)).toHaveText('2|3d|2d|');
|
||||
expect(asNativeElements(view.debugElement.componentViewChildren))
|
||||
.toHaveText('2|3d|2d|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
@ -273,7 +250,8 @@ export function main() {
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
var needsTpl: NeedsTpl = view.debugElement.children[0].inject(NeedsTpl);
|
||||
var needsTpl: NeedsTpl =
|
||||
view.debugElement.componentViewChildren[0].inject(NeedsTpl);
|
||||
|
||||
expect(needsTpl.vc.createEmbeddedView(needsTpl.query.first).hasLocal('light'))
|
||||
.toBe(true);
|
||||
@ -297,7 +275,7 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q = view.debugElement.children[0].getLocal("q");
|
||||
var q = view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
view.detectChanges();
|
||||
|
||||
ObservableWrapper.subscribe(q.query.changes, (_) => {
|
||||
@ -322,8 +300,8 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q1 = view.debugElement.children[0].getLocal("q1");
|
||||
var q2 = view.debugElement.children[0].getLocal("q2");
|
||||
var q1 = view.debugElement.componentViewChildren[0].getLocal("q1");
|
||||
var q2 = view.debugElement.componentViewChildren[0].getLocal("q2");
|
||||
|
||||
var firedQ2 = false;
|
||||
|
||||
@ -347,8 +325,7 @@ export function main() {
|
||||
view.debugElement.componentInstance.shouldShow = true;
|
||||
view.detectChanges();
|
||||
|
||||
var q: NeedsQuery = view.debugElement.children[0].getLocal('q');
|
||||
|
||||
var q: NeedsQuery = view.debugElement.componentViewChildren[1].getLocal('q');
|
||||
expect(q.query.length).toEqual(1);
|
||||
|
||||
view.debugElement.componentInstance.shouldShow = false;
|
||||
@ -357,7 +334,7 @@ export function main() {
|
||||
view.debugElement.componentInstance.shouldShow = true;
|
||||
view.detectChanges();
|
||||
|
||||
var q2: NeedsQuery = view.debugElement.children[0].getLocal('q');
|
||||
var q2: NeedsQuery = view.debugElement.componentViewChildren[1].getLocal('q');
|
||||
|
||||
expect(q2.query.length).toEqual(1);
|
||||
|
||||
@ -376,7 +353,7 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q = view.debugElement.children[0].getLocal("q");
|
||||
var q = view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
|
||||
view.debugElement.componentInstance.list = ['1d', '2d'];
|
||||
|
||||
@ -399,7 +376,7 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q = view.debugElement.children[0].getLocal("q");
|
||||
var q = view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
view.detectChanges();
|
||||
|
||||
expect(q.query.first.text).toEqual("one");
|
||||
@ -418,7 +395,7 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q = view.debugElement.children[0].getLocal("q");
|
||||
var q = view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
|
||||
view.debugElement.componentInstance.list = ['1d', '2d'];
|
||||
|
||||
@ -445,7 +422,7 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q = view.debugElement.children[0].getLocal("q");
|
||||
var q = view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
|
||||
view.debugElement.componentInstance.list = ['1d', '2d'];
|
||||
|
||||
@ -469,7 +446,8 @@ export function main() {
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
|
||||
expect(asNativeElements(view.debugElement.children)).toHaveText('hello|world|');
|
||||
expect(asNativeElements(view.debugElement.componentViewChildren))
|
||||
.toHaveText('hello|world|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
@ -482,7 +460,8 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q: NeedsViewQueryByLabel = view.debugElement.children[0].getLocal("q");
|
||||
var q: NeedsViewQueryByLabel =
|
||||
view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
view.detectChanges();
|
||||
|
||||
expect(q.query.first.nativeElement).toHaveText("text");
|
||||
@ -500,7 +479,7 @@ export function main() {
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
|
||||
var q = view.debugElement.children[0].getLocal('q');
|
||||
var q = view.debugElement.componentViewChildren[0].getLocal('q');
|
||||
|
||||
view.detectChanges();
|
||||
|
||||
@ -521,7 +500,7 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q: NeedsViewQuery = view.debugElement.children[0].getLocal("q");
|
||||
var q: NeedsViewQuery = view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
|
||||
view.detectChanges();
|
||||
|
||||
@ -538,7 +517,7 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q: NeedsViewQuery = view.debugElement.children[0].getLocal("q");
|
||||
var q: NeedsViewQuery = view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
|
||||
view.detectChanges();
|
||||
|
||||
@ -555,7 +534,7 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q: NeedsViewQueryIf = view.debugElement.children[0].getLocal("q");
|
||||
var q: NeedsViewQueryIf = view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
|
||||
view.detectChanges();
|
||||
|
||||
@ -578,7 +557,8 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q: NeedsViewQueryNestedIf = view.debugElement.children[0].getLocal("q");
|
||||
var q: NeedsViewQueryNestedIf =
|
||||
view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
|
||||
view.detectChanges();
|
||||
|
||||
@ -603,7 +583,8 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q: NeedsViewQueryOrder = view.debugElement.children[0].getLocal("q");
|
||||
var q: NeedsViewQueryOrder =
|
||||
view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
|
||||
view.detectChanges();
|
||||
|
||||
@ -626,7 +607,8 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q: NeedsViewQueryOrderWithParent = view.debugElement.children[0].getLocal("q");
|
||||
var q: NeedsViewQueryOrderWithParent =
|
||||
view.debugElement.componentViewChildren[0].getLocal("q");
|
||||
|
||||
view.detectChanges();
|
||||
|
||||
@ -649,7 +631,8 @@ export function main() {
|
||||
tcb.overrideTemplate(MyComp, template)
|
||||
.createAsync(MyComp)
|
||||
.then((view) => {
|
||||
var q: NeedsViewQueryOrder = view.debugElement.children[0].getLocal('q');
|
||||
var q: NeedsViewQueryOrder =
|
||||
view.debugElement.componentViewChildren[0].getLocal('q');
|
||||
|
||||
// no significance to 50, just a reasonably large cycle.
|
||||
for (var i = 0; i < 50; i++) {
|
||||
@ -673,7 +656,7 @@ export function main() {
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
|
||||
var q = view.debugElement.children[0].getLocal('q');
|
||||
var q = view.debugElement.componentViewChildren[0].getLocal('q');
|
||||
expect(q.query1).toBeDefined();
|
||||
expect(q.query2).toBeDefined();
|
||||
expect(q.query3).toBeDefined();
|
||||
@ -758,6 +741,7 @@ class NeedsViewChild implements AfterViewInit,
|
||||
ngAfterViewChecked() { this.log.push(["check", isPresent(this.child) ? this.child.text : null]); }
|
||||
}
|
||||
|
||||
|
||||
@Directive({selector: '[dir]'})
|
||||
@Injectable()
|
||||
class InertDirective {
|
||||
|
@ -8,6 +8,7 @@ import 'package:angular2/src/core/linker/directive_resolver.dart';
|
||||
import 'package:angular2/src/core/linker/view.dart';
|
||||
import 'package:angular2/src/core/linker/element_ref.dart';
|
||||
import 'package:angular2/src/core/linker/view_manager.dart';
|
||||
import 'package:angular2/src/core/linker/view_listener.dart';
|
||||
import 'package:angular2/src/platform/dom/dom_adapter.dart';
|
||||
import 'package:angular2/testing_internal.dart';
|
||||
|
||||
@ -51,5 +52,8 @@ class SpyRenderer extends SpyObject implements Renderer {}
|
||||
@proxy
|
||||
class SpyRootRenderer extends SpyObject implements RootRenderer {}
|
||||
|
||||
@proxy
|
||||
class SpyAppViewListener extends SpyObject implements AppViewListener {}
|
||||
|
||||
@proxy
|
||||
class SpyDomAdapter extends SpyObject implements DomAdapter {}
|
||||
|
@ -11,6 +11,7 @@ import {DirectiveResolver} from 'angular2/src/core/linker/directive_resolver';
|
||||
import {AppView, AppProtoView, HostViewFactory} from 'angular2/src/core/linker/view';
|
||||
import {ElementRef} from 'angular2/src/core/linker/element_ref';
|
||||
import {AppViewManager_} from 'angular2/src/core/linker/view_manager';
|
||||
import {AppViewListener} from 'angular2/src/core/linker/view_listener';
|
||||
import {DomAdapter} from 'angular2/src/platform/dom/dom_adapter';
|
||||
|
||||
import {SpyObject, proxy} from 'angular2/testing_internal';
|
||||
@ -70,7 +71,6 @@ export class SpyRenderer extends SpyObject {
|
||||
this.spy('setElementProperty');
|
||||
this.spy('setElementAttribute');
|
||||
this.spy('setBindingDebugInfo');
|
||||
this.spy('setElementDebugInfo');
|
||||
this.spy('setElementClass');
|
||||
this.spy('setElementStyle');
|
||||
this.spy('invokeElementMethod');
|
||||
@ -88,6 +88,10 @@ export class SpyRootRenderer extends SpyObject {
|
||||
}
|
||||
}
|
||||
|
||||
export class SpyAppViewListener extends SpyObject {
|
||||
constructor() { super(AppViewListener); }
|
||||
}
|
||||
|
||||
export class SpyDomAdapter extends SpyObject {
|
||||
constructor() { super(DomAdapter); }
|
||||
}
|
||||
|
@ -0,0 +1,71 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
xdescribe,
|
||||
describe,
|
||||
dispatchEvent,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
beforeEachProviders,
|
||||
it,
|
||||
xit,
|
||||
TestComponentBuilder,
|
||||
} from 'angular2/testing_internal';
|
||||
import {global} from 'angular2/src/facade/lang';
|
||||
import {provide, Component, Directive, Injectable, View} from 'angular2/core';
|
||||
import {inspectNativeElement} from 'angular2/platform/browser';
|
||||
import {IS_DART} from 'angular2/src/facade/lang';
|
||||
|
||||
@Component({selector: 'my-comp'})
|
||||
@View({directives: []})
|
||||
@Injectable()
|
||||
class MyComp {
|
||||
ctxProp: string;
|
||||
}
|
||||
|
||||
export function main() {
|
||||
describe('element probe', function() {
|
||||
it('should return a TestElement from a dom element',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideTemplate(MyComp, '<div some-dir></div>')
|
||||
.createAsync(MyComp)
|
||||
.then((componentFixture) => {
|
||||
expect(inspectNativeElement(componentFixture.debugElement.nativeElement)
|
||||
.componentInstance)
|
||||
.toBeAnInstanceOf(MyComp);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should clean up whent the view is destroyed',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideTemplate(MyComp, '')
|
||||
.createAsync(MyComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.destroy();
|
||||
expect(inspectNativeElement(componentFixture.debugElement.nativeElement)).toBe(null);
|
||||
|
||||
async.done();
|
||||
});
|
||||
|
||||
}));
|
||||
|
||||
if (!IS_DART) {
|
||||
it('should provide a global function to inspect elements',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideTemplate(MyComp, '')
|
||||
.createAsync(MyComp)
|
||||
.then((componentFixture) => {
|
||||
expect(global['ng']['probe'](componentFixture.debugElement.nativeElement)
|
||||
.componentInstance)
|
||||
.toBeAnInstanceOf(MyComp);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}), 1000);
|
||||
}
|
||||
});
|
||||
}
|
@ -290,7 +290,6 @@ var NG_COMMON = [
|
||||
'NgFor.ngDoCheck()',
|
||||
'NgFor.ngForOf=',
|
||||
'NgFor.ngForTemplate=',
|
||||
'NgFor.ngForTrackBy=',
|
||||
'NgForm',
|
||||
'NgForm.addControl()',
|
||||
'NgForm.addControlGroup()',
|
||||
@ -889,60 +888,21 @@ var NG_CORE = [
|
||||
'CyclicDependencyError.message=',
|
||||
'CyclicDependencyError.stackTrace',
|
||||
'PLATFORM_PIPES:js',
|
||||
'DebugNode',
|
||||
'DebugNode.getLocal()',
|
||||
'DebugNode.inject()',
|
||||
'DebugNode.setDebugInfo()',
|
||||
'DebugNode.componentInstance',
|
||||
'DebugNode.componentInstance=',
|
||||
'DebugNode.injector',
|
||||
'DebugNode.injector=',
|
||||
'DebugNode.listeners',
|
||||
'DebugNode.listeners=',
|
||||
'DebugNode.locals',
|
||||
'DebugNode.locals=',
|
||||
'DebugNode.nativeNode',
|
||||
'DebugNode.nativeNode=',
|
||||
'DebugNode.parent',
|
||||
'DebugNode.parent=',
|
||||
'DebugNode.providerTokens',
|
||||
'DebugNode.providerTokens=',
|
||||
'DebugElement',
|
||||
'DebugElement.children',
|
||||
'DebugElement.attributes',
|
||||
'DebugElement.attributes=',
|
||||
'DebugElement.properties',
|
||||
'DebugElement.properties=',
|
||||
'DebugElement.childNodes',
|
||||
'DebugElement.childNodes=',
|
||||
'DebugElement.injector',
|
||||
'DebugElement.injector=',
|
||||
'DebugElement.listeners',
|
||||
'DebugElement.listeners=',
|
||||
'DebugElement.locals',
|
||||
'DebugElement.locals=',
|
||||
'DebugElement.name',
|
||||
'DebugElement.name=',
|
||||
'DebugElement.parent',
|
||||
'DebugElement.parent=',
|
||||
'DebugElement.componentInstance',
|
||||
'DebugElement.componentInstance=',
|
||||
'DebugElement.componentViewChildren',
|
||||
'DebugElement.elementRef',
|
||||
/*
|
||||
Abstract methods
|
||||
'DebugElement.getDirectiveInstance()',
|
||||
'DebugElement.getLocal()',
|
||||
'DebugElement.providerTokens',
|
||||
'DebugElement.providerTokens=',
|
||||
'DebugElement.hasDirective()',
|
||||
'DebugElement.inject()',
|
||||
'DebugElement.nativeNode',
|
||||
'DebugElement.nativeNode=',
|
||||
*/
|
||||
'DebugElement.nativeElement',
|
||||
'DebugElement.nativeElement=',
|
||||
'DebugElement.query()',
|
||||
'DebugElement.queryAll()',
|
||||
'DebugElement.queryAllNodes()',
|
||||
'DebugElement.triggerEventHandler()',
|
||||
'DebugElement.setDebugInfo()',
|
||||
'DebugElement.addChild()',
|
||||
'DebugElement.removeChild()',
|
||||
'DebugElement.insertChildrenAfter()',
|
||||
'Dependency#fromKey()',
|
||||
'Dependency',
|
||||
'Dependency.key',
|
||||
@ -1248,6 +1208,10 @@ var NG_CORE = [
|
||||
'ResolvedFactory.dependencies=',
|
||||
'ResolvedFactory.factory',
|
||||
'ResolvedFactory.factory=',
|
||||
'Scope#all()',
|
||||
'Scope#light()',
|
||||
'Scope#view()',
|
||||
'Scope', // TODO(misko): rename?
|
||||
'Self',
|
||||
'SelfMetadata',
|
||||
'SkipSelf',
|
||||
@ -1390,6 +1354,7 @@ var NG_CORE = [
|
||||
'provide()',
|
||||
'createNgZone()',
|
||||
'forwardRef():js',
|
||||
'inspectElement()',
|
||||
'platform():js',
|
||||
'resolveForwardRef():js',
|
||||
'PLATFORM_COMMON_PROVIDERS',
|
||||
@ -1635,8 +1600,8 @@ var NG_PLATFORM_BROWSER = [
|
||||
'By#directive():js',
|
||||
'By:js',
|
||||
'DOCUMENT',
|
||||
'ELEMENT_PROBE_BINDINGS:js',
|
||||
'ELEMENT_PROBE_PROVIDERS:js',
|
||||
'ELEMENT_PROBE_PROVIDERS_PROD_MODE:js',
|
||||
'Title.getTitle():js',
|
||||
'Title.setTitle():js',
|
||||
'Title:js',
|
||||
|
@ -12,9 +12,6 @@ import {
|
||||
xit,
|
||||
} from 'angular2/testing_internal';
|
||||
|
||||
|
||||
import {By} from 'angular2/platform/common_dom';
|
||||
|
||||
import {specs, compile, TEST_ROUTER_PROVIDERS, clickOnElement, getHref} from '../util';
|
||||
|
||||
import {Router, AsyncRoute, Route, Location} from 'angular2/router';
|
||||
@ -36,7 +33,7 @@ import {
|
||||
} from './fixture_components';
|
||||
|
||||
function getLinkElement(rtc: ComponentFixture) {
|
||||
return rtc.debugElement.query(By.css('a')).nativeElement;
|
||||
return rtc.debugElement.componentViewChildren[0].nativeElement;
|
||||
}
|
||||
|
||||
function asyncRoutesWithoutChildrenWithRouteData() {
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
xit
|
||||
} from 'angular2/testing_internal';
|
||||
|
||||
import {By} from 'angular2/platform/common_dom';
|
||||
import {provide, Component, Injector, Inject} from 'angular2/core';
|
||||
|
||||
import {Router, ROUTER_DIRECTIVES, RouteParams, RouteData, Location} from 'angular2/router';
|
||||
@ -25,7 +24,7 @@ import {specs, compile, TEST_ROUTER_PROVIDERS, clickOnElement, getHref} from '..
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
|
||||
function getLinkElement(rtc: ComponentFixture, linkIndex: number = 0) {
|
||||
return rtc.debugElement.queryAll(By.css('a'))[linkIndex].nativeElement;
|
||||
return rtc.debugElement.componentViewChildren[linkIndex].nativeElement;
|
||||
}
|
||||
|
||||
function auxRoutes() {
|
||||
|
@ -14,14 +14,13 @@ import {
|
||||
|
||||
import {specs, compile, TEST_ROUTER_PROVIDERS, clickOnElement, getHref} from '../util';
|
||||
|
||||
import {By} from 'angular2/platform/common_dom';
|
||||
import {Router, Route, Location} from 'angular2/router';
|
||||
|
||||
import {HelloCmp, UserCmp, TeamCmp, ParentCmp, ParentWithDefaultCmp} from './fixture_components';
|
||||
|
||||
|
||||
function getLinkElement(rtc: ComponentFixture) {
|
||||
return rtc.debugElement.query(By.css('a')).nativeElement;
|
||||
return rtc.debugElement.componentViewChildren[0].nativeElement;
|
||||
}
|
||||
|
||||
function syncRoutesWithoutChildrenWithoutParams() {
|
||||
|
@ -17,7 +17,6 @@ import {
|
||||
SpyObject
|
||||
} from 'angular2/testing_internal';
|
||||
|
||||
import {By} from 'angular2/platform/common_dom';
|
||||
import {NumberWrapper} from 'angular2/src/facade/lang';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
@ -112,7 +111,9 @@ export function main() {
|
||||
fixture.debugElement.componentInstance.name = 'brian';
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('brian');
|
||||
expect(getHref(fixture)).toEqual('/user/brian');
|
||||
expect(DOM.getAttribute(fixture.debugElement.componentViewChildren[0].nativeElement,
|
||||
'href'))
|
||||
.toEqual('/user/brian');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
@ -126,7 +127,11 @@ export function main() {
|
||||
.then((_) => router.navigateByUrl('/page/1'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(fixture)).toEqual('/page/2');
|
||||
expect(DOM.getAttribute(fixture.debugElement.componentViewChildren[1]
|
||||
.componentViewChildren[0]
|
||||
.nativeElement,
|
||||
'href'))
|
||||
.toEqual('/page/2');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
@ -141,7 +146,11 @@ export function main() {
|
||||
.then((_) => router.navigateByUrl('/page/1'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(fixture)).toEqual('/page/2');
|
||||
expect(DOM.getAttribute(fixture.debugElement.componentViewChildren[1]
|
||||
.componentViewChildren[0]
|
||||
.nativeElement,
|
||||
'href'))
|
||||
.toEqual('/page/2');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
@ -155,7 +164,11 @@ export function main() {
|
||||
.then((_) => router.navigateByUrl('/book/1984/page/1'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(fixture)).toEqual('/book/1984/page/100');
|
||||
expect(DOM.getAttribute(fixture.debugElement.componentViewChildren[1]
|
||||
.componentViewChildren[0]
|
||||
.nativeElement,
|
||||
'href'))
|
||||
.toEqual('/book/1984/page/100');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
@ -189,7 +202,11 @@ export function main() {
|
||||
.then((_) => router.navigateByUrl('/child-with-grandchild/grandchild'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(fixture)).toEqual('/child-with-grandchild/grandchild');
|
||||
expect(DOM.getAttribute(fixture.debugElement.componentViewChildren[1]
|
||||
.componentViewChildren[0]
|
||||
.nativeElement,
|
||||
'href'))
|
||||
.toEqual('/child-with-grandchild/grandchild');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
@ -202,17 +219,15 @@ export function main() {
|
||||
.then((_) => router.navigateByUrl('/book/1984/page/1'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
// TODO(juliemr): This should be one By.css('book-cmp a') query, but the parse5
|
||||
// adapter
|
||||
// can't handle css child selectors.
|
||||
expect(DOM.getAttribute(fixture.debugElement.query(By.css('book-cmp'))
|
||||
.query(By.css('a'))
|
||||
expect(DOM.getAttribute(fixture.debugElement.componentViewChildren[1]
|
||||
.componentViewChildren[0]
|
||||
.nativeElement,
|
||||
'href'))
|
||||
.toEqual('/book/1984/page/100');
|
||||
|
||||
expect(DOM.getAttribute(fixture.debugElement.query(By.css('page-cmp'))
|
||||
.query(By.css('a'))
|
||||
expect(DOM.getAttribute(fixture.debugElement.componentViewChildren[1]
|
||||
.componentViewChildren[2]
|
||||
.componentViewChildren[0]
|
||||
.nativeElement,
|
||||
'href'))
|
||||
.toEqual('/book/1984/page/2');
|
||||
@ -226,7 +241,11 @@ export function main() {
|
||||
.then((_) => router.navigateByUrl('/'))
|
||||
.then((_) => {
|
||||
fixture.detectChanges();
|
||||
expect(getHref(fixture)).toEqual('/(aside)');
|
||||
expect(DOM.getAttribute(fixture.debugElement.componentViewChildren[1]
|
||||
.componentViewChildren[0]
|
||||
.nativeElement,
|
||||
'href'))
|
||||
.toEqual('/(aside)');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
@ -316,7 +335,9 @@ export function main() {
|
||||
fixture.debugElement.componentInstance.name = 'brian';
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement).toHaveText('brian');
|
||||
expect(getHref(fixture)).toEqual('/user/brian');
|
||||
expect(DOM.getAttribute(
|
||||
fixture.debugElement.componentViewChildren[0].nativeElement, 'href'))
|
||||
.toEqual('/user/brian');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
@ -326,7 +347,7 @@ export function main() {
|
||||
describe('when clicked', () => {
|
||||
|
||||
var clickOnElement = function(view) {
|
||||
var anchorEl = fixture.debugElement.query(By.css('a')).nativeElement;
|
||||
var anchorEl = fixture.debugElement.componentViewChildren[0].nativeElement;
|
||||
var dispatchedEvent = DOM.createMouseEvent('click');
|
||||
DOM.dispatchEvent(anchorEl, dispatchedEvent);
|
||||
return dispatchedEvent;
|
||||
@ -377,7 +398,7 @@ export function main() {
|
||||
}
|
||||
|
||||
function getHref(tc: ComponentFixture) {
|
||||
return DOM.getAttribute(tc.debugElement.query(By.css('a')).nativeElement, 'href');
|
||||
return DOM.getAttribute(tc.debugElement.componentViewChildren[0].nativeElement, 'href');
|
||||
}
|
||||
|
||||
@Component({selector: 'my-comp'})
|
||||
|
@ -325,7 +325,7 @@ export function main() {
|
||||
done();
|
||||
});
|
||||
restoreJasmineIt();
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
describe('using beforeEachProviders', () => {
|
||||
beforeEachProviders(() => [bind(FancyService).toValue(new FancyService())]);
|
||||
|
@ -417,35 +417,6 @@ export function main() {
|
||||
});
|
||||
}));
|
||||
|
||||
it('should support bindToController with bindings', inject([AsyncTestCompleter], (async) => {
|
||||
var adapter = new UpgradeAdapter();
|
||||
var ng1Module = angular.module('ng1', []);
|
||||
|
||||
var ng1 = function() {
|
||||
return {
|
||||
scope: {},
|
||||
bindToController: {title: '@'},
|
||||
template: '{{ctl.title}}',
|
||||
controllerAs: 'ctl',
|
||||
controller: Class({constructor: function() {}})
|
||||
};
|
||||
};
|
||||
ng1Module.directive('ng1', ng1);
|
||||
var Ng2 = Component({
|
||||
selector: 'ng2',
|
||||
template: '<ng1 title="WORKS"></ng1>',
|
||||
directives: [adapter.upgradeNg1Component('ng1')]
|
||||
}).Class({constructor: function() {}});
|
||||
ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2));
|
||||
var element = html(`<div><ng2></ng2></div>`);
|
||||
adapter.bootstrap(element, ['ng1'])
|
||||
.ready((ref) => {
|
||||
expect(multiTrim(document.body.textContent)).toEqual('WORKS');
|
||||
ref.dispose();
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should support single require in linking fn', inject([AsyncTestCompleter], (async) => {
|
||||
var adapter = new UpgradeAdapter();
|
||||
var ng1Module = angular.module('ng1', []);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user