Compare commits
78 Commits
2.0.0-beta
...
2.0.0-beta
Author | SHA1 | Date | |
---|---|---|---|
4945e73588 | |||
8a00a863ac | |||
db87baeb98 | |||
c4c43f5a77 | |||
0ae77753f3 | |||
5f0baaac73 | |||
b5b6ece65a | |||
4282297c24 | |||
9c96b8affc | |||
132829e5e2 | |||
4a414420e9 | |||
fb6335ab60 | |||
89bd008445 | |||
caafb41eb5 | |||
31b81a7439 | |||
f7b1973358 | |||
32f01da49a | |||
59684c97b0 | |||
a32a0a3a97 | |||
96f5b0929d | |||
8e6cf7fca8 | |||
fdbe8741c9 | |||
775fb2c340 | |||
b60f594798 | |||
cc49790bdb | |||
a4bc19c530 | |||
f7985dbdb7 | |||
0bdcb5c1e0 | |||
a0d25db4a5 | |||
625474c4e2 | |||
1cd2a6328a | |||
d6bafe4fe3 | |||
6a2ef15355 | |||
a8ca560503 | |||
ad361808ec | |||
c47639f2b1 | |||
ba90a85f7b | |||
d3b569557f | |||
c9090ffa31 | |||
341bf39d23 | |||
3778ac26aa | |||
6cfc6f5bb2 | |||
47a3b4d56b | |||
c72ed991ad | |||
78bfdf78ea | |||
a24ee6add4 | |||
df3074fdfe | |||
f7424d5aeb | |||
a593ffa6f3 | |||
761c6d0df7 | |||
3e65d1458e | |||
a4b5cb8376 | |||
c785a1e474 | |||
3adc472f06 | |||
e7081b8b7c | |||
9b3a548f6f | |||
90b3502bb8 | |||
e19b31db29 | |||
bd015f14e8 | |||
ca7ba12fc6 | |||
ae05ec69c4 | |||
92dc3b91d8 | |||
8bd697b316 | |||
eda4c3eb4c | |||
4d0c2ed1f6 | |||
eda6a5d52a | |||
c1c54ed0f2 | |||
6b73d09ba1 | |||
ac85cbb28a | |||
b0cebdba6b | |||
933a9112da | |||
8c37b7e8f2 | |||
c8e909f8c9 | |||
69ae3634c7 | |||
95248f46a1 | |||
b3c7df1783 | |||
c56679e8e1 | |||
041c599511 |
@ -1,11 +1,11 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- '4.2.1'
|
||||
- '5.4.1'
|
||||
|
||||
branches:
|
||||
except:
|
||||
- g3sync
|
||||
- g3_v2_0
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@ -60,6 +60,7 @@ addons:
|
||||
firefox: "38.0"
|
||||
|
||||
before_install:
|
||||
- npm install -g npm@3.5.3
|
||||
- node tools/analytics/build-analytics start ci job
|
||||
- node tools/analytics/build-analytics start ci before_install
|
||||
- echo ${TSDRC} > .tsdrc
|
||||
@ -77,7 +78,9 @@ install:
|
||||
# Check the size of caches
|
||||
- du -sh ./node_modules || true
|
||||
# Install npm dependecies
|
||||
- npm install
|
||||
# check-node-modules will exit(1) if we don't need to install
|
||||
# we need to manually kick off the postinstall script if check-node-modules exit(0)s
|
||||
- node tools/npm/check-node-modules --purge && npm install || npm run postinstall
|
||||
- node tools/analytics/build-analytics success ci install
|
||||
|
||||
before_script:
|
||||
|
1790
CHANGELOG.md
1790
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@ -180,7 +180,8 @@ Must be one of the following:
|
||||
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
* **perf**: A code change that improves performance
|
||||
* **test**: Adding missing tests or correcting existing tests
|
||||
* **build** Changes that affect the build system, CI configuration or external dependencies (example scopes: gulp, broccoli, npm)
|
||||
* **build**: Changes that affect the build system, CI configuration or external dependencies (example scopes: gulp, broccoli, npm)
|
||||
* **ci**: Any changes to our CI configuration files and scripts (Travis, Circle CI, BrowserStack, SauceLabs)
|
||||
* **chore**: Other changes that don't modify `src` or `test` files
|
||||
|
||||
### Scope
|
||||
|
30
DEVELOPER.md
30
DEVELOPER.md
@ -23,7 +23,16 @@ if you'd like to contribute to Angular.
|
||||
Before you can build and test Angular, you must install and configure the
|
||||
following products on your development machine:
|
||||
|
||||
* [Dart](https://www.dartlang.org) (version ` >=1.12.0 <2.0.0`), specifically the Dart-SDK and
|
||||
* [Git](http://git-scm.com) and/or the **GitHub app** (for [Mac](http://mac.github.com) or
|
||||
[Windows](http://windows.github.com)); [GitHub's Guide to Installing
|
||||
Git](https://help.github.com/articles/set-up-git) is a good source of information.
|
||||
|
||||
* [Node.js](http://nodejs.org), (version `>=5.4.1 <6`) which is used to run a development web server,
|
||||
run tests, and generate distributable files. We also use Node's Package Manager, `npm`
|
||||
(version `>=3.5.3 <4.0`), which comes with Node. Depending on your system, you can install Node either from
|
||||
source or as a pre-packaged bundle.
|
||||
|
||||
* *Optional*: [Dart](https://www.dartlang.org) (version ` >=1.13.2 <2.0.0`), specifically the Dart-SDK and
|
||||
Dartium (a version of [Chromium](http://www.chromium.org) with native support for Dart through
|
||||
the Dart VM). One of the **simplest** ways to get both is to install the **Dart Editor bundle**,
|
||||
which includes the editor, SDK and Dartium. See the [Dart tools](https://www.dartlang.org/tools)
|
||||
@ -33,19 +42,6 @@ following products on your development machine:
|
||||
to the `Path` (e.g. `path-to-dart-sdk-folder\bin`) and a new `DARTIUM_BIN` environment variable must be
|
||||
created, pointing to the executable (e.g. `path-to-dartium-folder\chrome.exe).`
|
||||
|
||||
* [Git](http://git-scm.com) and/or the **GitHub app** (for [Mac](http://mac.github.com) or
|
||||
[Windows](http://windows.github.com)); [GitHub's Guide to Installing
|
||||
Git](https://help.github.com/articles/set-up-git) is a good source of information.
|
||||
|
||||
* [Node.js](http://nodejs.org), (version `>=4.2.1 <5`) which is used to run a development web server,
|
||||
run tests, and generate distributable files. We also use Node's Package Manager, `npm`
|
||||
(version `>=2.14.7 <3.0`), which comes with Node. Depending on your system, you can install Node either from
|
||||
source or as a pre-packaged bundle.
|
||||
|
||||
* [Chrome Canary](https://www.google.com/chrome/browser/canary.html), a version of Chrome with
|
||||
bleeding edge functionality, built especially for developers (and early adopters).
|
||||
|
||||
* [Bower](http://bower.io/).
|
||||
|
||||
|
||||
## Getting the Sources
|
||||
@ -200,15 +196,15 @@ Then, in another terminal:
|
||||
export SAUCE_USERNAME='my_user'; export SAUCE_ACCESS_KEY='my_key';
|
||||
export BROWSER_STACK_USERNAME='my_user'; export BROWSER_STACK_ACCESS_KEY='my_key';
|
||||
```
|
||||
- Then run `gulp test.unit.js.(saucelabs|browserstack) --browsers=option1,option2,..,optionN`
|
||||
- Then run `gulp test.unit.js.(sauce|browserstack) --browsers=option1,option2,..,optionN`
|
||||
The options are any mix of browsers and aliases which are defined in the [browser-providers.conf.js](https://github.com/angular/angular/blob/master/browser-providers.conf.js) file.
|
||||
They are case insensitive, and the `SL_` or `BS_` prefix must not be added for browsers.
|
||||
|
||||
Some examples of commands:
|
||||
```
|
||||
gulp test.unit.js.saucelabs --browsers=Safari8,ie11 //run in Sauce Labs with Safari 8 and IE11
|
||||
gulp test.unit.js.sauce --browsers=Safari8,ie11 //run in Sauce Labs with Safari 8 and IE11
|
||||
gulp test.unit.js.browserstack --browsers=Safari,IE //run in Browser Stack with Safari 7, Safari 8, Safari 9, IE 9, IE 10 and IE 11
|
||||
gulp test.unit.js.saucelabs --browsers=IOS,safari8,android5.1 //run in Sauce Labs with iOS 7, iOS 8, iOs 9, Safari 8 and Android 5.1
|
||||
gulp test.unit.js.sauce --browsers=IOS,safari8,android5.1 //run in Sauce Labs with iOS 7, iOS 8, iOs 9, Safari 8 and Android 5.1
|
||||
```
|
||||
|
||||
### E2E tests
|
||||
|
215
LICENSE
215
LICENSE
@ -1,202 +1,21 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
The MIT License
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
Copyright (c) 2014-2016 Google, Inc. http://angular.io
|
||||
|
||||
1. Definitions.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
6
circle.yml
Normal file
6
circle.yml
Normal file
@ -0,0 +1,6 @@
|
||||
machine:
|
||||
node:
|
||||
version: 5.4.1
|
||||
test:
|
||||
override:
|
||||
- npm run build
|
157
gulpfile.js
157
gulpfile.js
@ -3,10 +3,10 @@
|
||||
// THIS CHECK SHOULD BE THE FIRST THING IN THIS FILE
|
||||
// This is to ensure that we catch env issues before we error while requiring other dependencies.
|
||||
require('./tools/check-environment')(
|
||||
{requiredNpmVersion: '>=2.14.7 <3.0.0', requiredNodeVersion: '>=4.2.1 <5.0.0'});
|
||||
{requiredNpmVersion: '>=3.5.3 <4.0.0', requiredNodeVersion: '>=5.4.1 <6.0.0'});
|
||||
|
||||
|
||||
var del = require('del');
|
||||
var fse = require('fs-extra');
|
||||
var gulp = require('gulp');
|
||||
var gulpPlugins = require('gulp-load-plugins')();
|
||||
var merge = require('merge');
|
||||
@ -42,7 +42,7 @@ if (cliArgs.projects) {
|
||||
|
||||
// --projects=angular2,angular2_material => {angular2: true, angular2_material: true}
|
||||
var allProjects =
|
||||
'angular1_router,angular2,angular2_material,benchmarks,benchmarks_external,benchpress,playground,bundle_deps';
|
||||
'angular1_router,angular2,angular2_material,benchmarks,benchmarks_external,benchpress,playground,payload_tests,bundle_deps';
|
||||
var cliArgsProjects = (cliArgs.projects || allProjects)
|
||||
.split(',')
|
||||
.reduce((map, projectName) => {
|
||||
@ -168,24 +168,36 @@ var BENCHPRESS_BUNDLE_CONFIG = {
|
||||
dest: CONFIG.dest.bundles.benchpress
|
||||
};
|
||||
|
||||
var PAYLOAD_TESTS_CONFIG = {
|
||||
ts: {
|
||||
bundleName: 'app-bundle-deps.min.js',
|
||||
cases: ['hello_world'],
|
||||
dist: function(caseName, packaging) {
|
||||
return path.join(__dirname, CONFIG.dest.js.prod.es5, 'payload_tests', caseName,
|
||||
'ts/' + packaging);
|
||||
},
|
||||
systemjs: {sizeLimits: {'uncompressed': 850 * 1024, 'gzip level=9': 165 * 1024}},
|
||||
webpack: {sizeLimits: {'uncompressed': 550 * 1024, 'gzip level=9': 120 * 1024}}
|
||||
}
|
||||
};
|
||||
|
||||
// ------------
|
||||
// clean
|
||||
|
||||
gulp.task('build/clean.tools', function() { del(path.join('dist', 'tools')); });
|
||||
gulp.task('build/clean.tools', (done) => fse.remove(path.join('dist', 'tools'), done));
|
||||
|
||||
gulp.task('build/clean.js', function(done) { del(CONFIG.dest.js.all, done); });
|
||||
gulp.task('build/clean.js', (done) => fse.remove(CONFIG.dest.js.all, done));
|
||||
|
||||
gulp.task('build/clean.dart', function(done) { del(CONFIG.dest.dart, done); });
|
||||
gulp.task('build/clean.dart', (done) => fse.remove(CONFIG.dest.dart, done));
|
||||
|
||||
gulp.task('build/clean.docs', function(done) { del(CONFIG.dest.docs, done); });
|
||||
gulp.task('build/clean.docs', (done) => fse.remove(CONFIG.dest.docs, done));
|
||||
|
||||
gulp.task('build/clean.docs_angular_io',
|
||||
function(done) { del(CONFIG.dest.docs_angular_io, done); });
|
||||
gulp.task('build/clean.docs_angular_io', (done) => fse.remove(CONFIG.dest.docs_angular_io, done));
|
||||
|
||||
gulp.task('build/clean.bundles', function(done) { del(CONFIG.dest.bundles.all, done); });
|
||||
gulp.task('build/clean.bundles', (done) => fse.remove(CONFIG.dest.bundles.all, done));
|
||||
|
||||
gulp.task('build/clean.bundles.benchpress',
|
||||
function(done) { del(CONFIG.dest.bundles.benchpress, done); });
|
||||
(done) => fse.remove(CONFIG.dest.bundles.benchpress, done));
|
||||
|
||||
// ------------
|
||||
// transpile
|
||||
@ -313,7 +325,9 @@ gulp.task('lint', ['build.tools'], function() {
|
||||
"requireParameterType": true,
|
||||
"requireReturnType": true,
|
||||
"semicolon": true,
|
||||
"variable-name": [true, "ban-keywords"]
|
||||
|
||||
// TODO: find a way to just screen for reserved names
|
||||
"variable-name": false
|
||||
}
|
||||
};
|
||||
return gulp.src(['modules/angular2/src/**/*.ts', '!modules/angular2/src/testing/**'])
|
||||
@ -638,7 +652,7 @@ gulp.task('test.unit.dart', function(done) {
|
||||
// This test will fail if the size of our hello_world app goes beyond one of
|
||||
// these values when compressed at the specified level.
|
||||
// Measure in bytes.
|
||||
var _DART_PAYLOAD_SIZE_LIMITS = {'uncompressed': 320 * 1024, 'gzip level=6': 90 * 1024};
|
||||
var _DART_PAYLOAD_SIZE_LIMITS = {'uncompressed': 320 * 1024, 'gzip level=9': 90 * 1024};
|
||||
gulp.task('test.payload.dart/ci', function(done) {
|
||||
runSequence('build/packages.dart', '!pubget.payload.dart', '!pubbuild.payload.dart',
|
||||
'!checkAndReport.payload.dart', done);
|
||||
@ -658,6 +672,103 @@ gulp.task('!checkAndReport.payload.dart', function() {
|
||||
{failConditions: _DART_PAYLOAD_SIZE_LIMITS, prefix: 'hello_world'});
|
||||
});
|
||||
|
||||
// JS payload size tracking
|
||||
gulp.task('test.payload.js/ci', function(done) {
|
||||
runSequence('build.payload.js', '!checkAndReport.payload.js', sequenceComplete(done));
|
||||
});
|
||||
|
||||
gulp.task('build.payload.js', ['build.js'], function(done) {
|
||||
runSequence('!build.payload.js.webpack', '!build.payload.js.systemjs', sequenceComplete(done));
|
||||
});
|
||||
|
||||
gulp.task('!build.payload.js.webpack', function() {
|
||||
var q = require('q');
|
||||
var webpack = q.denodeify(require('webpack'));
|
||||
|
||||
var ES5_PROD_ROOT = __dirname + '/' + CONFIG.dest.js.prod.es5;
|
||||
|
||||
return q.all(PAYLOAD_TESTS_CONFIG.ts.cases.map(function(caseName) {
|
||||
var CASE_PATH = PAYLOAD_TESTS_CONFIG.ts.dist(caseName, 'webpack');
|
||||
|
||||
return webpack({
|
||||
// bundle app + framework
|
||||
entry: CASE_PATH + '/index.js',
|
||||
output: {path: CASE_PATH, filename: "app-bundle.js"},
|
||||
resolve: {
|
||||
extensions: ['', '.js'],
|
||||
packageAlias: '', // option added to ignore "broken" package.json in our dist folder
|
||||
root: [ES5_PROD_ROOT]
|
||||
}
|
||||
})
|
||||
.then(function() { // pad bundle with mandatory dependencies
|
||||
return new Promise(function(resolve, reject) {
|
||||
gulp.src([
|
||||
'node_modules/zone.js/dist/zone-microtask.js',
|
||||
'node_modules/zone.js/dist/long-stack-trace-zone.js',
|
||||
'node_modules/reflect-metadata/Reflect.js',
|
||||
CASE_PATH + '/app-bundle.js'
|
||||
])
|
||||
.pipe(gulpPlugins.concat(PAYLOAD_TESTS_CONFIG.ts.bundleName))
|
||||
.pipe(gulpPlugins.uglify())
|
||||
.pipe(gulp.dest(CASE_PATH))
|
||||
.on('end', resolve)
|
||||
.on('error', reject);
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
gulp.task('!build.payload.js.systemjs', function() {
|
||||
var bundler = require('./tools/build/bundle');
|
||||
|
||||
return Promise.all(PAYLOAD_TESTS_CONFIG.ts.cases.map(function(caseName) {
|
||||
var CASE_PATH = PAYLOAD_TESTS_CONFIG.ts.dist(caseName, 'systemjs');
|
||||
|
||||
return bundler
|
||||
.bundle(
|
||||
{
|
||||
paths: {'index': CASE_PATH + '/index.js'},
|
||||
meta: {'angular2/core': {build: false}, 'angular2/platform/browser': {build: false}}
|
||||
},
|
||||
'index', CASE_PATH + '/index.register.js', {})
|
||||
.then(function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
gulp.src([
|
||||
'node_modules/systemjs/dist/system.src.js',
|
||||
'dist/js/prod/es5/bundle/angular2-polyfills.js',
|
||||
'dist/js/prod/es5/bundle/angular2.js',
|
||||
'dist/js/prod/es5//rxjs/bundles/Rx.js',
|
||||
CASE_PATH + '/index.register.js',
|
||||
'tools/build/systemjs/payload_tests_import.js'
|
||||
])
|
||||
.pipe(gulpPlugins.concat(PAYLOAD_TESTS_CONFIG.ts.bundleName))
|
||||
.pipe(gulpPlugins.uglify())
|
||||
.pipe(gulp.dest(CASE_PATH))
|
||||
.on('end', resolve)
|
||||
.on('error', reject);
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
gulp.task('!checkAndReport.payload.js', function() {
|
||||
var reportSize = require('./tools/analytics/reportsize');
|
||||
|
||||
function caseSizeStream(caseName, packaging) {
|
||||
return reportSize(PAYLOAD_TESTS_CONFIG.ts.dist(caseName, packaging) + '/' +
|
||||
PAYLOAD_TESTS_CONFIG.ts.bundleName,
|
||||
{
|
||||
failConditions: PAYLOAD_TESTS_CONFIG.ts[packaging].sizeLimits,
|
||||
prefix: caseName + '_' + packaging
|
||||
})
|
||||
}
|
||||
|
||||
return PAYLOAD_TESTS_CONFIG.ts.cases.reduce(function(sizeReportingStreams, caseName) {
|
||||
sizeReportingStreams.add(caseSizeStream(caseName, 'systemjs'));
|
||||
sizeReportingStreams.add(caseSizeStream(caseName, 'webpack'));
|
||||
}, merge2());
|
||||
});
|
||||
|
||||
gulp.task('watch.dart.dev', function(done) {
|
||||
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
|
||||
'!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css',
|
||||
@ -906,16 +1017,12 @@ gulp.task('build/pure-packages.dart/standalone', function() {
|
||||
.pipe(gulp.dest(CONFIG.dest.dart));
|
||||
});
|
||||
|
||||
gulp.task('build/pure-packages.dart/license',
|
||||
function() {
|
||||
return gulp.src(['LICENSE'])
|
||||
.pipe(gulp.dest(path.join(CONFIG.dest.dart, 'angular2_testing')));
|
||||
})
|
||||
gulp.task('build/pure-packages.dart/license', function() {
|
||||
return gulp.src(['LICENSE']).pipe(gulp.dest(path.join(CONFIG.dest.dart, 'angular2_testing')));
|
||||
});
|
||||
|
||||
|
||||
gulp.task('build/pure-packages.dart/angular2', function() {
|
||||
var yaml = require('js-yaml');
|
||||
|
||||
gulp.task('build/pure-packages.dart/angular2', function() {
|
||||
return gulp.src([
|
||||
'modules_dart/transform/**/*',
|
||||
'!modules_dart/transform/**/*.proto',
|
||||
@ -923,7 +1030,7 @@ gulp.task('build/pure-packages.dart/license',
|
||||
'!modules_dart/transform/**/packages{,/**}',
|
||||
])
|
||||
.pipe(gulp.dest(path.join(CONFIG.dest.dart, 'angular2')));
|
||||
});
|
||||
});
|
||||
|
||||
// Builds all Dart packages, but does not compile them
|
||||
gulp.task('build/packages.dart', function(done) {
|
||||
@ -1127,8 +1234,8 @@ gulp.task('!bundle.testing', ['build.js.dev'], function() {
|
||||
{sourceMaps: true});
|
||||
});
|
||||
|
||||
gulp.task('!bundles.js.docs', function() {
|
||||
gulp.src('modules/angular2/docs/bundles/*').pipe(gulp.dest('dist/js/bundle'));
|
||||
gulp.task('!bundles.js.docs', ['clean'], function() {
|
||||
return gulp.src('modules/angular2/docs/bundles/*').pipe(gulp.dest('dist/js/bundle'));
|
||||
});
|
||||
|
||||
gulp.task('!bundles.js.umd', ['build.js.dev'], function() {
|
||||
@ -1276,7 +1383,7 @@ gulp.task('!bundle.copy', function() {
|
||||
|
||||
gulp.task('!bundles.js.checksize', function(done) {
|
||||
var reportSize = require('./tools/analytics/reportsize');
|
||||
return reportSize('dist/js/bundle/**', {printToConsole: ['gzip level=2']});
|
||||
return reportSize('dist/js/bundle/**/*.js', {printToConsole: ['gzip level=2']});
|
||||
});
|
||||
|
||||
gulp.task('bundles.js',
|
||||
|
@ -5,8 +5,7 @@ library angular2;
|
||||
*
|
||||
* This library does not include `bootstrap`. Import `bootstrap.dart` instead.
|
||||
*/
|
||||
export 'package:angular2/core.dart'
|
||||
hide forwardRef, resolveForwardRef, ForwardRefFn;
|
||||
export 'package:angular2/core.dart';
|
||||
export 'package:angular2/common.dart';
|
||||
export 'package:angular2/instrumentation.dart';
|
||||
export 'package:angular2/src/core/angular_entrypoint.dart' show AngularEntrypoint;
|
||||
|
@ -1,5 +1,6 @@
|
||||
library angular2.core;
|
||||
|
||||
export './src/core/angular_entrypoint.dart' show AngularEntrypoint;
|
||||
export './src/core/metadata.dart';
|
||||
export './src/core/util.dart';
|
||||
export 'package:angular2/src/facade/lang.dart' show enableProdMode;
|
||||
|
@ -8,7 +8,7 @@
|
||||
# Modules, barrels and bundles
|
||||
|
||||
Angular2 source code is authored using the ES2015 standardized module format where one module corresponds to exactly one file. Multiple modules (files) can be logically grouped into so-called "barrels".
|
||||
A bundle is a file the contains all the code for one or more barrels.
|
||||
A bundle is a file that contains all the code for one or more barrels.
|
||||
|
||||
Most bundles come in several flavors:
|
||||
* regular and minified (got `.min` in their name);
|
||||
|
@ -2,7 +2,7 @@
|
||||
Bootstrapping
|
||||
@cheatsheetIndex 0
|
||||
@description
|
||||
{@target ts}`import {bootstrap} from 'angular2/angular2';`{@endtarget}
|
||||
{@target ts}`import {bootstrap} from 'angular2/platform/browser';`{@endtarget}
|
||||
{@target js}Available from the `ng.platform.browser` namespace.{@endtarget}
|
||||
{@target dart}`import 'package:angular2/bootstrap.dart';`{@endtarget}
|
||||
|
||||
|
@ -71,7 +71,7 @@ The `*` symbol means that the current element will be turned into an embedded te
|
||||
syntax:
|
||||
`<p>Card No.: {{cardNumber | myCreditCardNumberFormatter}}</p>`|`{{cardNumber | myCreditCardNumberFormatter}}`
|
||||
description:
|
||||
Transforms the current value of expression `cardNumber` via the pipe called `creditCardNumberFormatter`.
|
||||
Transforms the current value of expression `cardNumber` via the pipe called `myCreditCardNumberFormatter`.
|
||||
|
||||
@cheatsheetItem
|
||||
syntax:
|
||||
|
@ -371,14 +371,14 @@ In TypeScript:
|
||||
import {platform, Provider, APP_INITIALIZER, Injector} from 'angular2/core';
|
||||
import {
|
||||
WORKER_RENDER_PLATFORM,
|
||||
WORKER_RENDER_APP_COMMON,
|
||||
WORKER_RENDER_APPLICATION_COMMON,
|
||||
initializeGenericWorkerRenderer,
|
||||
MessageBus
|
||||
} from 'angular2/platform/worker_render';
|
||||
|
||||
var bus = new MyAwesomeMessageBus();
|
||||
platform([WORKER_RENDER_PLATFORM])
|
||||
.application([WORKER_RENDER_APP_COMMON, new Provider(MessageBus, {useValue: bus}),
|
||||
.application([WORKER_RENDER_APPLICATION_COMMON, new Provider(MessageBus, {useValue: bus}),
|
||||
new Provider(APP_INITIALIZER, {
|
||||
useFactory: (injector) => () => initializeGenericWorkerRenderer(injector),
|
||||
deps: [Injector],
|
||||
@ -419,7 +419,7 @@ import 'package:angular2/platform/worker_render.dart';
|
||||
main() {
|
||||
var bus = new MyAwesomeMessageBus();
|
||||
platform([WORKER_RENDER_PLATFORM])
|
||||
.application([WORKER_RENDER_APP_COMMON, new Provider(MessageBus, useValue: bus),
|
||||
.application([WORKER_RENDER_APPLICATION_COMMON, new Provider(MessageBus, useValue: bus),
|
||||
new Provider(APP_INITIALIZER,
|
||||
useFactory: (injector) => () => initializeGenericWorkerRenderer(injector),
|
||||
deps: [Injector],
|
||||
@ -456,9 +456,9 @@ void initAppThread(NgZone zone) {
|
||||
*/
|
||||
}
|
||||
```
|
||||
Notice how we use the `WORKER_RENDER_APP_COMMON` providers instead of the `WORKER_RENDER_APP` providers on the render thread.
|
||||
This is because the `WORKER_RENDER_APP` providers include an application initializer that starts a new WebWorker/Isolate.
|
||||
The `WORKER_RENDER_APP_COMMON` providers make no assumption about where your application code lives.
|
||||
Notice how we use the `WORKER_RENDER_APPLICTION_COMMON` providers instead of the `WORKER_RENDER_APPLICATION` providers on the render thread.
|
||||
This is because the `WORKER_RENDER_APPLICATION` providers include an application initializer that starts a new WebWorker/Isolate.
|
||||
The `WORKER_RENDER_APPLICATION_COMMON` providers make no assumption about where your application code lives.
|
||||
However, we now need to provide our own app initializer. At the very least this initializer needs to call `initializeGenericWorkerRenderer`.
|
||||
|
||||
## MessageBroker
|
||||
|
@ -6,8 +6,6 @@
|
||||
|
||||
/// <reference path="../typings/zone/zone.d.ts"/>
|
||||
/// <reference path="../typings/hammerjs/hammerjs.d.ts"/>
|
||||
/// <reference path="../typings/jasmine/jasmine.d.ts"/>
|
||||
/// <reference path="../typings/angular-protractor/angular-protractor.d.ts"/>
|
||||
|
||||
// TODO: ideally the node.d.ts reference should be scoped only for files that need and not to all
|
||||
// the code including client code
|
||||
@ -30,6 +28,7 @@ interface BrowserNodeGlobal {
|
||||
zone: Zone;
|
||||
getAngularTestability: Function;
|
||||
getAllAngularTestabilities: Function;
|
||||
frameworkStabilizers: Array<Function>;
|
||||
setTimeout: Function;
|
||||
clearTimeout: Function;
|
||||
setInterval: Function;
|
||||
|
21
modules/angular2/platform/testing/browser.ts
Normal file
21
modules/angular2/platform/testing/browser.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import {
|
||||
TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
|
||||
ADDITIONAL_TEST_BROWSER_PROVIDERS
|
||||
} from 'angular2/platform/testing/browser_static';
|
||||
|
||||
import {BROWSER_APP_PROVIDERS} from 'angular2/platform/browser';
|
||||
|
||||
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
/**
|
||||
* Default patform providers for testing.
|
||||
*/
|
||||
export const TEST_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([TEST_BROWSER_STATIC_PLATFORM_PROVIDERS]);
|
||||
|
||||
/**
|
||||
* Default application providers for testing.
|
||||
*/
|
||||
export const TEST_BROWSER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([BROWSER_APP_PROVIDERS, ADDITIONAL_TEST_BROWSER_PROVIDERS]);
|
69
modules/angular2/platform/testing/browser_static.ts
Normal file
69
modules/angular2/platform/testing/browser_static.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import {
|
||||
APP_ID,
|
||||
DirectiveResolver,
|
||||
NgZone,
|
||||
Provider,
|
||||
ViewResolver,
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
PLATFORM_INITIALIZER
|
||||
} from 'angular2/core';
|
||||
import {BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
|
||||
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
|
||||
|
||||
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
||||
import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock';
|
||||
import {MockDirectiveResolver} from 'angular2/src/mock/directive_resolver_mock';
|
||||
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
|
||||
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
|
||||
import {LocationStrategy} from 'angular2/src/router/location_strategy';
|
||||
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
|
||||
|
||||
import {XHRImpl} from "angular2/src/platform/browser/xhr_impl";
|
||||
import {XHR} from 'angular2/compiler';
|
||||
|
||||
import {TestComponentBuilder} from 'angular2/src/testing/test_component_builder';
|
||||
|
||||
import {BrowserDetection} from 'angular2/src/testing/utils';
|
||||
|
||||
import {ELEMENT_PROBE_PROVIDERS} from 'angular2/platform/common_dom';
|
||||
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Log} from 'angular2/src/testing/utils';
|
||||
|
||||
function initBrowserTests() {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
BrowserDetection.setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default patform providers for testing without a compiler.
|
||||
*/
|
||||
export const TEST_BROWSER_STATIC_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
new Provider(PLATFORM_INITIALIZER, {useValue: initBrowserTests, multi: true})
|
||||
]);
|
||||
|
||||
export const ADDITIONAL_TEST_BROWSER_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([
|
||||
new Provider(APP_ID, {useValue: 'a'}),
|
||||
ELEMENT_PROBE_PROVIDERS,
|
||||
new Provider(DirectiveResolver, {useClass: MockDirectiveResolver}),
|
||||
new Provider(ViewResolver, {useClass: MockViewResolver}),
|
||||
Log,
|
||||
TestComponentBuilder,
|
||||
new Provider(NgZone, {useClass: MockNgZone}),
|
||||
new Provider(LocationStrategy, {useClass: MockLocationStrategy}),
|
||||
new Provider(AnimationBuilder, {useClass: MockAnimationBuilder}),
|
||||
]);
|
||||
|
||||
/**
|
||||
* Default application providers for testing without a compiler.
|
||||
*/
|
||||
export const TEST_BROWSER_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([
|
||||
BROWSER_APP_COMMON_PROVIDERS,
|
||||
new Provider(XHR, {useClass: XHRImpl}),
|
||||
ADDITIONAL_TEST_BROWSER_PROVIDERS
|
||||
]);
|
1
modules/angular2/platform/testing/server.dart
Normal file
1
modules/angular2/platform/testing/server.dart
Normal file
@ -0,0 +1 @@
|
||||
// Intentionally blank, the Parse5Adapater bindings for JavaScript don't apply.
|
90
modules/angular2/platform/testing/server.ts
Normal file
90
modules/angular2/platform/testing/server.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import {
|
||||
APP_ID,
|
||||
DirectiveResolver,
|
||||
NgZone,
|
||||
Provider,
|
||||
ViewResolver,
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
PLATFORM_INITIALIZER,
|
||||
APPLICATION_COMMON_PROVIDERS,
|
||||
Renderer
|
||||
} from 'angular2/core';
|
||||
import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter';
|
||||
|
||||
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
||||
import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock';
|
||||
import {MockDirectiveResolver} from 'angular2/src/mock/directive_resolver_mock';
|
||||
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
|
||||
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
|
||||
import {LocationStrategy} from 'angular2/src/router/location_strategy';
|
||||
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
|
||||
|
||||
import {TestComponentBuilder} from 'angular2/src/testing/test_component_builder';
|
||||
import {XHR} from 'angular2/src/compiler/xhr';
|
||||
import {BrowserDetection} from 'angular2/src/testing/utils';
|
||||
|
||||
import {COMPILER_PROVIDERS} from 'angular2/src/compiler/compiler';
|
||||
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {RootRenderer} from 'angular2/src/core/render/api';
|
||||
import {DomRootRenderer, DomRootRenderer_} from 'angular2/src/platform/dom/dom_renderer';
|
||||
import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
|
||||
|
||||
import {
|
||||
EventManager,
|
||||
EVENT_MANAGER_PLUGINS,
|
||||
ELEMENT_PROBE_PROVIDERS
|
||||
} from 'angular2/platform/common_dom';
|
||||
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
|
||||
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Log} from 'angular2/src/testing/utils';
|
||||
|
||||
function initServerTests() {
|
||||
Parse5DomAdapter.makeCurrent();
|
||||
BrowserDetection.setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default patform providers for testing.
|
||||
*/
|
||||
export const TEST_SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
new Provider(PLATFORM_INITIALIZER, {useValue: initServerTests, multi: true})
|
||||
]);
|
||||
|
||||
function appDoc() {
|
||||
try {
|
||||
return DOM.defaultDoc();
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default application providers for testing.
|
||||
*/
|
||||
export const TEST_SERVER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
CONST_EXPR([
|
||||
// TODO(julie): when angular2/platform/server is available, use that instead of making our own
|
||||
// list here.
|
||||
APPLICATION_COMMON_PROVIDERS,
|
||||
COMPILER_PROVIDERS,
|
||||
new Provider(DOCUMENT, {useFactory: appDoc}),
|
||||
new Provider(DomRootRenderer, {useClass: DomRootRenderer_}),
|
||||
new Provider(RootRenderer, {useExisting: DomRootRenderer}),
|
||||
EventManager,
|
||||
new Provider(EVENT_MANAGER_PLUGINS, {useClass: DomEventsPlugin, multi: true}),
|
||||
new Provider(XHR, {useClass: XHR}),
|
||||
new Provider(APP_ID, {useValue: 'a'}),
|
||||
DomSharedStylesHost,
|
||||
ELEMENT_PROBE_PROVIDERS,
|
||||
new Provider(DirectiveResolver, {useClass: MockDirectiveResolver}),
|
||||
new Provider(ViewResolver, {useClass: MockViewResolver}),
|
||||
Log,
|
||||
TestComponentBuilder,
|
||||
new Provider(NgZone, {useClass: MockNgZone}),
|
||||
new Provider(LocationStrategy, {useClass: MockLocationStrategy}),
|
||||
new Provider(AnimationBuilder, {useClass: MockAnimationBuilder}),
|
||||
]);
|
@ -4,11 +4,11 @@ export 'package:angular2/src/platform/worker_render_common.dart'
|
||||
show
|
||||
WORKER_SCRIPT,
|
||||
WORKER_RENDER_PLATFORM,
|
||||
WORKER_RENDER_APP_COMMON,
|
||||
WORKER_RENDER_APPLICATION_COMMON,
|
||||
initializeGenericWorkerRenderer;
|
||||
|
||||
export 'package:angular2/src/platform/worker_render.dart'
|
||||
show WORKER_RENDER_APP, initIsolate, WebWorkerInstance;
|
||||
show WORKER_RENDER_APPLICATION, initIsolate, WebWorkerInstance;
|
||||
|
||||
export '../src/web_workers/shared/client_message_broker.dart'
|
||||
show ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments;
|
||||
@ -18,3 +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';
|
||||
|
||||
import 'package:angular2/src/platform/worker_render_common.dart';
|
||||
|
||||
const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION_COMMON;
|
||||
|
@ -2,9 +2,9 @@ export {
|
||||
WORKER_SCRIPT,
|
||||
WORKER_RENDER_PLATFORM,
|
||||
initializeGenericWorkerRenderer,
|
||||
WORKER_RENDER_APP_COMMON
|
||||
WORKER_RENDER_APPLICATION_COMMON
|
||||
} from 'angular2/src/platform/worker_render_common';
|
||||
export * from 'angular2/src/platform/worker_render';
|
||||
export {WORKER_RENDER_APPLICATION, WebWorkerInstance} from 'angular2/src/platform/worker_render';
|
||||
export {
|
||||
ClientMessageBroker,
|
||||
ClientMessageBrokerFactory,
|
||||
@ -18,3 +18,9 @@ export {
|
||||
} from '../src/web_workers/shared/service_message_broker';
|
||||
export {PRIMITIVE} from '../src/web_workers/shared/serializer';
|
||||
export * from '../src/web_workers/shared/message_bus';
|
||||
import {WORKER_RENDER_APPLICATION} from 'angular2/src/platform/worker_render';
|
||||
|
||||
/**
|
||||
* @deprecated Use WORKER_RENDER_APPLICATION
|
||||
*/
|
||||
export const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION;
|
||||
|
@ -9,9 +9,8 @@ homepage: <%= packageJson.homepage %>
|
||||
environment:
|
||||
sdk: '>=1.10.0 <2.0.0'
|
||||
dependencies:
|
||||
analyzer: '>=0.24.4 <0.27.0'
|
||||
analyzer: '>=0.24.4 <0.28.0'
|
||||
barback: '^0.15.2+2'
|
||||
code_transformers: '0.2.9+4'
|
||||
dart_style: '>=0.1.8 <0.3.0'
|
||||
glob: '^1.0.0'
|
||||
html: '^0.12.0'
|
||||
@ -23,7 +22,9 @@ dependencies:
|
||||
source_span: '^1.0.0'
|
||||
stack_trace: '^1.1.1'
|
||||
dev_dependencies:
|
||||
code_transformers: '>=0.2.9+4 <0.4.0'
|
||||
guinness: '^0.1.18'
|
||||
test: '^0.12.6'
|
||||
transformers:
|
||||
- angular2
|
||||
- $dart2js:
|
||||
|
@ -4,7 +4,8 @@ import {ListWrapper, Map} from 'angular2/src/facade/collection';
|
||||
|
||||
const _WHEN_DEFAULT = CONST_EXPR(new Object());
|
||||
|
||||
class SwitchView {
|
||||
/** @internal */
|
||||
export class SwitchView {
|
||||
constructor(private _viewContainerRef: ViewContainerRef, private _templateRef: TemplateRef) {}
|
||||
|
||||
create(): void { this._viewContainerRef.createEmbeddedView(this._templateRef); }
|
||||
|
@ -21,7 +21,7 @@ class ObservableListDiff extends DefaultIterableDiffer {
|
||||
}
|
||||
}
|
||||
|
||||
dynamic diff(ObservableList collection) {
|
||||
DefaultIterableDiffer diff(ObservableList collection) {
|
||||
if (collection is! ObservableList) {
|
||||
throw "Cannot change the type of a collection";
|
||||
}
|
||||
|
@ -73,10 +73,13 @@ const $LT = 60;
|
||||
const $EQ = 61;
|
||||
const $GT = 62;
|
||||
const $QUESTION = 63;
|
||||
const $A = 65;
|
||||
const $Z = 90;
|
||||
const $LBRACKET = 91;
|
||||
const $RBRACKET = 93;
|
||||
const $A = 65;
|
||||
const $F = 70;
|
||||
const $X = 88;
|
||||
const $Z = 90;
|
||||
|
||||
const $a = 97;
|
||||
const $f = 102;
|
||||
const $z = 122;
|
||||
@ -102,7 +105,6 @@ class ControlFlowError {
|
||||
// See http://www.w3.org/TR/html51/syntax.html#writing
|
||||
class _HtmlTokenizer {
|
||||
private input: string;
|
||||
private inputLowercase: string;
|
||||
private length: number;
|
||||
// Note: this is always lowercase!
|
||||
private peek: number = -1;
|
||||
@ -117,7 +119,6 @@ class _HtmlTokenizer {
|
||||
|
||||
constructor(private file: ParseSourceFile) {
|
||||
this.input = file.content;
|
||||
this.inputLowercase = file.content.toLowerCase();
|
||||
this.length = file.content.length;
|
||||
this._advance();
|
||||
}
|
||||
@ -133,16 +134,16 @@ class _HtmlTokenizer {
|
||||
while (this.peek !== $EOF) {
|
||||
var start = this._getLocation();
|
||||
try {
|
||||
if (this._attemptChar($LT)) {
|
||||
if (this._attemptChar($BANG)) {
|
||||
if (this._attemptChar($LBRACKET)) {
|
||||
if (this._attemptCharCode($LT)) {
|
||||
if (this._attemptCharCode($BANG)) {
|
||||
if (this._attemptCharCode($LBRACKET)) {
|
||||
this._consumeCdata(start);
|
||||
} else if (this._attemptChar($MINUS)) {
|
||||
} else if (this._attemptCharCode($MINUS)) {
|
||||
this._consumeComment(start);
|
||||
} else {
|
||||
this._consumeDocType(start);
|
||||
}
|
||||
} else if (this._attemptChar($SLASH)) {
|
||||
} else if (this._attemptCharCode($SLASH)) {
|
||||
this._consumeTagClose(start);
|
||||
} else {
|
||||
this._consumeTagOpen(start);
|
||||
@ -205,11 +206,10 @@ class _HtmlTokenizer {
|
||||
this.column++;
|
||||
}
|
||||
this.index++;
|
||||
this.peek = this.index >= this.length ? $EOF : StringWrapper.charCodeAt(this.inputLowercase,
|
||||
this.index);
|
||||
this.peek = this.index >= this.length ? $EOF : StringWrapper.charCodeAt(this.input, this.index);
|
||||
}
|
||||
|
||||
private _attemptChar(charCode: number): boolean {
|
||||
private _attemptCharCode(charCode: number): boolean {
|
||||
if (this.peek === charCode) {
|
||||
this._advance();
|
||||
return true;
|
||||
@ -217,38 +217,55 @@ class _HtmlTokenizer {
|
||||
return false;
|
||||
}
|
||||
|
||||
private _requireChar(charCode: number) {
|
||||
private _attemptCharCodeCaseInsensitive(charCode: number): boolean {
|
||||
if (compareCharCodeCaseInsensitive(this.peek, charCode)) {
|
||||
this._advance();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private _requireCharCode(charCode: number) {
|
||||
var location = this._getLocation();
|
||||
if (!this._attemptChar(charCode)) {
|
||||
if (!this._attemptCharCode(charCode)) {
|
||||
throw this._createError(unexpectedCharacterErrorMsg(this.peek), location);
|
||||
}
|
||||
}
|
||||
|
||||
private _attemptChars(chars: string): boolean {
|
||||
private _attemptStr(chars: string): boolean {
|
||||
for (var i = 0; i < chars.length; i++) {
|
||||
if (!this._attemptChar(StringWrapper.charCodeAt(chars, i))) {
|
||||
if (!this._attemptCharCode(StringWrapper.charCodeAt(chars, i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private _requireChars(chars: string) {
|
||||
private _attemptStrCaseInsensitive(chars: string): boolean {
|
||||
for (var i = 0; i < chars.length; i++) {
|
||||
if (!this._attemptCharCodeCaseInsensitive(StringWrapper.charCodeAt(chars, i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private _requireStr(chars: string) {
|
||||
var location = this._getLocation();
|
||||
if (!this._attemptChars(chars)) {
|
||||
if (!this._attemptStr(chars)) {
|
||||
throw this._createError(unexpectedCharacterErrorMsg(this.peek), location);
|
||||
}
|
||||
}
|
||||
|
||||
private _attemptUntilFn(predicate: Function) {
|
||||
private _attemptCharCodeUntilFn(predicate: Function) {
|
||||
while (!predicate(this.peek)) {
|
||||
this._advance();
|
||||
}
|
||||
}
|
||||
|
||||
private _requireUntilFn(predicate: Function, len: number) {
|
||||
private _requireCharCodeUntilFn(predicate: Function, len: number) {
|
||||
var start = this._getLocation();
|
||||
this._attemptUntilFn(predicate);
|
||||
this._attemptCharCodeUntilFn(predicate);
|
||||
if (this.index - start.offset < len) {
|
||||
throw this._createError(unexpectedCharacterErrorMsg(this.peek), start);
|
||||
}
|
||||
@ -273,10 +290,10 @@ class _HtmlTokenizer {
|
||||
private _decodeEntity(): string {
|
||||
var start = this._getLocation();
|
||||
this._advance();
|
||||
if (this._attemptChar($HASH)) {
|
||||
let isHex = this._attemptChar($x);
|
||||
if (this._attemptCharCode($HASH)) {
|
||||
let isHex = this._attemptCharCode($x) || this._attemptCharCode($X);
|
||||
let numberStart = this._getLocation().offset;
|
||||
this._attemptUntilFn(isDigitEntityEnd);
|
||||
this._attemptCharCodeUntilFn(isDigitEntityEnd);
|
||||
if (this.peek != $SEMICOLON) {
|
||||
throw this._createError(unexpectedCharacterErrorMsg(this.peek), this._getLocation());
|
||||
}
|
||||
@ -291,7 +308,7 @@ class _HtmlTokenizer {
|
||||
}
|
||||
} else {
|
||||
let startPosition = this._savePosition();
|
||||
this._attemptUntilFn(isNamedEntityEnd);
|
||||
this._attemptCharCodeUntilFn(isNamedEntityEnd);
|
||||
if (this.peek != $SEMICOLON) {
|
||||
this._restorePosition(startPosition);
|
||||
return '&';
|
||||
@ -315,7 +332,7 @@ class _HtmlTokenizer {
|
||||
var parts = [];
|
||||
while (true) {
|
||||
tagCloseStart = this._getLocation();
|
||||
if (this._attemptChar(firstCharOfEnd) && attemptEndRest()) {
|
||||
if (this._attemptCharCode(firstCharOfEnd) && attemptEndRest()) {
|
||||
break;
|
||||
}
|
||||
if (this.index > tagCloseStart.offset) {
|
||||
@ -330,18 +347,18 @@ class _HtmlTokenizer {
|
||||
|
||||
private _consumeComment(start: ParseLocation) {
|
||||
this._beginToken(HtmlTokenType.COMMENT_START, start);
|
||||
this._requireChar($MINUS);
|
||||
this._requireCharCode($MINUS);
|
||||
this._endToken([]);
|
||||
var textToken = this._consumeRawText(false, $MINUS, () => this._attemptChars('->'));
|
||||
var textToken = this._consumeRawText(false, $MINUS, () => this._attemptStr('->'));
|
||||
this._beginToken(HtmlTokenType.COMMENT_END, textToken.sourceSpan.end);
|
||||
this._endToken([]);
|
||||
}
|
||||
|
||||
private _consumeCdata(start: ParseLocation) {
|
||||
this._beginToken(HtmlTokenType.CDATA_START, start);
|
||||
this._requireChars('cdata[');
|
||||
this._requireStr('CDATA[');
|
||||
this._endToken([]);
|
||||
var textToken = this._consumeRawText(false, $RBRACKET, () => this._attemptChars(']>'));
|
||||
var textToken = this._consumeRawText(false, $RBRACKET, () => this._attemptStr(']>'));
|
||||
this._beginToken(HtmlTokenType.CDATA_END, textToken.sourceSpan.end);
|
||||
this._endToken([]);
|
||||
}
|
||||
@ -367,7 +384,7 @@ class _HtmlTokenizer {
|
||||
} else {
|
||||
nameStart = nameOrPrefixStart;
|
||||
}
|
||||
this._requireUntilFn(isNameEnd, this.index === nameStart ? 1 : 0);
|
||||
this._requireCharCodeUntilFn(isNameEnd, this.index === nameStart ? 1 : 0);
|
||||
var name = this.input.substring(nameStart, this.index);
|
||||
return [prefix, name];
|
||||
}
|
||||
@ -381,16 +398,16 @@ class _HtmlTokenizer {
|
||||
}
|
||||
var nameStart = this.index;
|
||||
this._consumeTagOpenStart(start);
|
||||
lowercaseTagName = this.inputLowercase.substring(nameStart, this.index);
|
||||
this._attemptUntilFn(isNotWhitespace);
|
||||
lowercaseTagName = this.input.substring(nameStart, this.index).toLowerCase();
|
||||
this._attemptCharCodeUntilFn(isNotWhitespace);
|
||||
while (this.peek !== $SLASH && this.peek !== $GT) {
|
||||
this._consumeAttributeName();
|
||||
this._attemptUntilFn(isNotWhitespace);
|
||||
if (this._attemptChar($EQ)) {
|
||||
this._attemptUntilFn(isNotWhitespace);
|
||||
this._attemptCharCodeUntilFn(isNotWhitespace);
|
||||
if (this._attemptCharCode($EQ)) {
|
||||
this._attemptCharCodeUntilFn(isNotWhitespace);
|
||||
this._consumeAttributeValue();
|
||||
}
|
||||
this._attemptUntilFn(isNotWhitespace);
|
||||
this._attemptCharCodeUntilFn(isNotWhitespace);
|
||||
}
|
||||
this._consumeTagOpenEnd();
|
||||
} catch (e) {
|
||||
@ -416,11 +433,11 @@ class _HtmlTokenizer {
|
||||
|
||||
private _consumeRawTextWithTagClose(lowercaseTagName: string, decodeEntities: boolean) {
|
||||
var textToken = this._consumeRawText(decodeEntities, $LT, () => {
|
||||
if (!this._attemptChar($SLASH)) return false;
|
||||
this._attemptUntilFn(isNotWhitespace);
|
||||
if (!this._attemptChars(lowercaseTagName)) return false;
|
||||
this._attemptUntilFn(isNotWhitespace);
|
||||
if (!this._attemptChar($GT)) return false;
|
||||
if (!this._attemptCharCode($SLASH)) return false;
|
||||
this._attemptCharCodeUntilFn(isNotWhitespace);
|
||||
if (!this._attemptStrCaseInsensitive(lowercaseTagName)) return false;
|
||||
this._attemptCharCodeUntilFn(isNotWhitespace);
|
||||
if (!this._attemptCharCode($GT)) return false;
|
||||
return true;
|
||||
});
|
||||
this._beginToken(HtmlTokenType.TAG_CLOSE, textToken.sourceSpan.end);
|
||||
@ -453,27 +470,27 @@ class _HtmlTokenizer {
|
||||
this._advance();
|
||||
} else {
|
||||
var valueStart = this.index;
|
||||
this._requireUntilFn(isNameEnd, 1);
|
||||
this._requireCharCodeUntilFn(isNameEnd, 1);
|
||||
value = this.input.substring(valueStart, this.index);
|
||||
}
|
||||
this._endToken([this._processCarriageReturns(value)]);
|
||||
}
|
||||
|
||||
private _consumeTagOpenEnd() {
|
||||
var tokenType =
|
||||
this._attemptChar($SLASH) ? HtmlTokenType.TAG_OPEN_END_VOID : HtmlTokenType.TAG_OPEN_END;
|
||||
var tokenType = this._attemptCharCode($SLASH) ? HtmlTokenType.TAG_OPEN_END_VOID :
|
||||
HtmlTokenType.TAG_OPEN_END;
|
||||
this._beginToken(tokenType);
|
||||
this._requireChar($GT);
|
||||
this._requireCharCode($GT);
|
||||
this._endToken([]);
|
||||
}
|
||||
|
||||
private _consumeTagClose(start: ParseLocation) {
|
||||
this._beginToken(HtmlTokenType.TAG_CLOSE, start);
|
||||
this._attemptUntilFn(isNotWhitespace);
|
||||
this._attemptCharCodeUntilFn(isNotWhitespace);
|
||||
var prefixAndName;
|
||||
prefixAndName = this._consumePrefixAndName();
|
||||
this._attemptUntilFn(isNotWhitespace);
|
||||
this._requireChar($GT);
|
||||
this._attemptCharCodeUntilFn(isNotWhitespace);
|
||||
this._requireCharCode($GT);
|
||||
this._endToken(prefixAndName);
|
||||
}
|
||||
|
||||
@ -534,11 +551,19 @@ function isTextEnd(code: number): boolean {
|
||||
}
|
||||
|
||||
function isAsciiLetter(code: number): boolean {
|
||||
return code >= $a && code <= $z;
|
||||
return code >= $a && code <= $z || code >= $A && code <= $Z;
|
||||
}
|
||||
|
||||
function isAsciiHexDigit(code: number): boolean {
|
||||
return code >= $a && code <= $f || code >= $0 && code <= $9;
|
||||
return code >= $a && code <= $f || code >= $A && code <= $F || code >= $0 && code <= $9;
|
||||
}
|
||||
|
||||
function compareCharCodeCaseInsensitive(code1: number, code2: number): boolean {
|
||||
return toUpperCaseCharCode(code1) == toUpperCaseCharCode(code2);
|
||||
}
|
||||
|
||||
function toUpperCaseCharCode(code: number): number {
|
||||
return code >= $a && code <= $z ? code - $a + $A : code;
|
||||
}
|
||||
|
||||
function mergeTextTokens(srcTokens: HtmlToken[]): HtmlToken[] {
|
||||
|
@ -124,7 +124,7 @@ export class TemplateCompiler {
|
||||
var hostMeta: CompileDirectiveMetadata =
|
||||
createHostComponentMeta(compMeta.type, compMeta.selector);
|
||||
|
||||
this._compileComponentRuntime(hostCacheKey, hostMeta, [compMeta], [], new Set());
|
||||
this._compileComponentRuntime(hostCacheKey, hostMeta, [compMeta], [], []);
|
||||
}
|
||||
return this._compiledTemplateDone.get(hostCacheKey)
|
||||
.then((compiledTemplate: CompiledTemplate) =>
|
||||
@ -172,7 +172,7 @@ export class TemplateCompiler {
|
||||
private _compileComponentRuntime(cacheKey: any, compMeta: CompileDirectiveMetadata,
|
||||
viewDirectives: CompileDirectiveMetadata[],
|
||||
pipes: CompilePipeMetadata[],
|
||||
compilingComponentCacheKeys: Set<any>): CompiledTemplate {
|
||||
compilingComponentsPath: any[]): CompiledTemplate {
|
||||
let uniqViewDirectives = <CompileDirectiveMetadata[]>removeDuplicates(viewDirectives);
|
||||
let uniqViewPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
|
||||
var compiledTemplate = this._compiledTemplateCache.get(cacheKey);
|
||||
@ -180,7 +180,6 @@ export class TemplateCompiler {
|
||||
if (isBlank(compiledTemplate)) {
|
||||
compiledTemplate = new CompiledTemplate();
|
||||
this._compiledTemplateCache.set(cacheKey, compiledTemplate);
|
||||
compilingComponentCacheKeys.add(cacheKey);
|
||||
done = PromiseWrapper
|
||||
.all([<any>this._styleCompiler.compileComponentRuntime(compMeta.template)].concat(
|
||||
uniqViewDirectives.map(dirMeta => this.normalizeDirectiveMetadata(dirMeta))))
|
||||
@ -195,14 +194,13 @@ export class TemplateCompiler {
|
||||
var usedDirectives = DirectiveCollector.findUsedDirectives(parsedTemplate);
|
||||
usedDirectives.components.forEach(
|
||||
component => this._compileNestedComponentRuntime(
|
||||
component, compilingComponentCacheKeys, childPromises));
|
||||
component, compilingComponentsPath, childPromises));
|
||||
return PromiseWrapper.all(childPromises)
|
||||
.then((_) => {
|
||||
var filteredPipes = filterPipes(parsedTemplate, uniqViewPipes);
|
||||
compiledTemplate.init(this._createViewFactoryRuntime(
|
||||
compMeta, parsedTemplate, usedDirectives.directives, styles,
|
||||
filteredPipes));
|
||||
SetWrapper.delete(compilingComponentCacheKeys, cacheKey);
|
||||
return compiledTemplate;
|
||||
});
|
||||
});
|
||||
@ -212,16 +210,19 @@ export class TemplateCompiler {
|
||||
}
|
||||
|
||||
private _compileNestedComponentRuntime(childComponentDir: CompileDirectiveMetadata,
|
||||
compilingComponentCacheKeys: Set<Type>,
|
||||
parentCompilingComponentsPath: any[],
|
||||
childPromises: Promise<any>[]) {
|
||||
var compilingComponentsPath = ListWrapper.clone(parentCompilingComponentsPath);
|
||||
|
||||
var childCacheKey = childComponentDir.type.runtime;
|
||||
var childViewDirectives: CompileDirectiveMetadata[] =
|
||||
this._runtimeMetadataResolver.getViewDirectivesMetadata(childComponentDir.type.runtime);
|
||||
var childViewPipes: CompilePipeMetadata[] =
|
||||
this._runtimeMetadataResolver.getViewPipesMetadata(childComponentDir.type.runtime);
|
||||
var childIsRecursive = SetWrapper.has(compilingComponentCacheKeys, childCacheKey);
|
||||
var childIsRecursive = ListWrapper.contains(compilingComponentsPath, childCacheKey);
|
||||
compilingComponentsPath.push(childCacheKey);
|
||||
this._compileComponentRuntime(childCacheKey, childComponentDir, childViewDirectives,
|
||||
childViewPipes, compilingComponentCacheKeys);
|
||||
childViewPipes, compilingComponentsPath);
|
||||
if (!childIsRecursive) {
|
||||
// Only wait for a child if it is not a cycle
|
||||
childPromises.push(this._compiledTemplateDone.get(childCacheKey));
|
||||
|
@ -112,6 +112,10 @@ class TemplatePreparseVisitor implements HtmlAstVisitor {
|
||||
case PreparsedElementType.STYLESHEET:
|
||||
this.styleUrls.push(preparsedElement.hrefAttr);
|
||||
break;
|
||||
default:
|
||||
// DDC reports this as error. See:
|
||||
// https://github.com/dart-lang/dev_compiler/issues/428
|
||||
break;
|
||||
}
|
||||
if (preparsedElement.nonBindable) {
|
||||
this.ngNonBindableStackCount++;
|
||||
|
@ -52,8 +52,8 @@ import {splitAtColon} from './util';
|
||||
// Group 3 = "on-"
|
||||
// Group 4 = "bindon-"
|
||||
// Group 5 = the identifier after "bind-", "var-/#", or "on-"
|
||||
// Group 6 = identifer inside [()]
|
||||
// Group 7 = identifer inside []
|
||||
// Group 6 = identifier inside [()]
|
||||
// Group 7 = identifier inside []
|
||||
// Group 8 = identifier inside ()
|
||||
var BIND_NAME_REGEXP =
|
||||
/^(?:(?:(?:(bind-)|(var-|#)|(on-)|(bindon-))(.+))|\[\(([^\)]+)\)\]|\[([^\]]+)\]|\(([^\)]+)\))$/g;
|
||||
|
@ -112,7 +112,7 @@ interface ViewFactory<EXPRESSION, STATEMENT> {
|
||||
|
||||
createElementEventListener(renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number,
|
||||
renderNode: EXPRESSION, eventAst: BoundEventAst,
|
||||
targetStatements: STATEMENT[]);
|
||||
targetStatements: STATEMENT[]): EXPRESSION;
|
||||
|
||||
setElementAttribute(renderer: EXPRESSION, renderNode: EXPRESSION, attrName: string,
|
||||
attrValue: string, targetStatements: STATEMENT[]);
|
||||
@ -201,9 +201,11 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||
createElementEventListener(renderer: Expression, appView: Expression, boundElementIndex: number,
|
||||
renderNode: Expression, eventAst: BoundEventAst,
|
||||
targetStatements: Statement[]) {
|
||||
var disposableVar = this._nextDisposableVar();
|
||||
var eventHandlerExpr = codeGenEventHandler(appView, boundElementIndex, eventAst.fullName);
|
||||
targetStatements.push(new Statement(
|
||||
`${renderer.expression}.listen(${renderNode.expression}, ${escapeValue(eventAst.name)}, ${eventHandlerExpr});`));
|
||||
`var ${disposableVar} = ${renderer.expression}.listen(${renderNode.expression}, ${escapeValue(eventAst.name)}, ${eventHandlerExpr});`));
|
||||
return new Expression(disposableVar);
|
||||
}
|
||||
|
||||
setElementAttribute(renderer: Expression, renderNode: Expression, attrName: string,
|
||||
@ -345,9 +347,11 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
||||
}
|
||||
|
||||
createElementEventListener(renderer: Renderer, appView: AppView, boundElementIndex: number,
|
||||
renderNode: any, eventAst: BoundEventAst, targetStatements: any[]) {
|
||||
renderer.listen(renderNode, eventAst.name, (event) => appView.triggerEventHandlers(
|
||||
eventAst.fullName, event, boundElementIndex));
|
||||
renderNode: any, eventAst: BoundEventAst,
|
||||
targetStatements: any[]): any {
|
||||
return renderer.listen(
|
||||
renderNode, eventAst.name,
|
||||
(event) => appView.triggerEventHandlers(eventAst.fullName, event, boundElementIndex));
|
||||
}
|
||||
|
||||
setElementAttribute(renderer: Renderer, renderNode: any, attrName: string, attrValue: string,
|
||||
@ -520,14 +524,16 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
||||
var protoEl = this.protoView.protoElements[elementIndex];
|
||||
|
||||
protoEl.renderEvents.forEach((eventAst) => {
|
||||
var disposable;
|
||||
if (isPresent(eventAst.target)) {
|
||||
var disposable = this.factory.createGlobalEventListener(
|
||||
disposable = this.factory.createGlobalEventListener(
|
||||
this.renderer, this.view, protoEl.boundElementIndex, eventAst, this.renderStmts);
|
||||
this.appDisposables.push(disposable);
|
||||
} else {
|
||||
this.factory.createElementEventListener(this.renderer, this.view, protoEl.boundElementIndex,
|
||||
renderNode, eventAst, this.renderStmts);
|
||||
disposable = this.factory.createElementEventListener(this.renderer, this.view,
|
||||
protoEl.boundElementIndex, renderNode,
|
||||
eventAst, this.renderStmts);
|
||||
}
|
||||
this.appDisposables.push(disposable);
|
||||
});
|
||||
for (var i = 0; i < protoEl.attrNameAndValues.length; i++) {
|
||||
var attrName = protoEl.attrNameAndValues[i][0];
|
||||
|
@ -217,25 +217,36 @@ export class PlatformRef_ extends PlatformRef {
|
||||
|
||||
application(providers: Array<Type | Provider | any[]>): ApplicationRef {
|
||||
var app = this._initApp(createNgZone(), providers);
|
||||
return app;
|
||||
if (PromiseWrapper.isPromise(app)) {
|
||||
throw new BaseException(
|
||||
"Cannot use asyncronous app initializers with application. Use asyncApplication instead.");
|
||||
}
|
||||
return <ApplicationRef>app;
|
||||
}
|
||||
|
||||
asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Provider | any[]>>,
|
||||
additionalProviders?: Array<Type | Provider | any[]>): Promise<ApplicationRef> {
|
||||
var zone = createNgZone();
|
||||
var completer = PromiseWrapper.completer();
|
||||
if (bindingFn === null) {
|
||||
completer.resolve(this._initApp(zone, additionalProviders));
|
||||
} else {
|
||||
zone.run(() => {
|
||||
PromiseWrapper.then(bindingFn(zone), (providers: Array<Type | Provider | any[]>) => {
|
||||
if (isPresent(additionalProviders)) {
|
||||
providers = ListWrapper.concat(providers, additionalProviders);
|
||||
}
|
||||
completer.resolve(this._initApp(zone, providers));
|
||||
let promise = this._initApp(zone, providers);
|
||||
completer.resolve(promise);
|
||||
});
|
||||
});
|
||||
}
|
||||
return completer.promise;
|
||||
}
|
||||
|
||||
private _initApp(zone: NgZone, providers: Array<Type | Provider | any[]>): ApplicationRef {
|
||||
private _initApp(zone: NgZone,
|
||||
providers: Array<Type | Provider | any[]>): Promise<ApplicationRef>|
|
||||
ApplicationRef {
|
||||
var injector: Injector;
|
||||
var app: ApplicationRef;
|
||||
zone.run(() => {
|
||||
@ -259,9 +270,13 @@ export class PlatformRef_ extends PlatformRef {
|
||||
});
|
||||
app = new ApplicationRef_(this, zone, injector);
|
||||
this._applications.push(app);
|
||||
_runAppInitializers(injector);
|
||||
var promise = _runAppInitializers(injector);
|
||||
if (promise !== null) {
|
||||
return PromiseWrapper.then(promise, (_) => app);
|
||||
} else {
|
||||
return app;
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
ListWrapper.clone(this._applications).forEach((app) => app.dispose());
|
||||
@ -273,9 +288,22 @@ export class PlatformRef_ extends PlatformRef {
|
||||
_applicationDisposed(app: ApplicationRef): void { ListWrapper.remove(this._applications, app); }
|
||||
}
|
||||
|
||||
function _runAppInitializers(injector: Injector): void {
|
||||
function _runAppInitializers(injector: Injector): Promise<any> {
|
||||
let inits: Function[] = injector.getOptional(APP_INITIALIZER);
|
||||
if (isPresent(inits)) inits.forEach(init => init());
|
||||
let promises: Promise<any>[] = [];
|
||||
if (isPresent(inits)) {
|
||||
inits.forEach(init => {
|
||||
var retVal = init();
|
||||
if (PromiseWrapper.isPromise(retVal)) {
|
||||
promises.push(retVal);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (promises.length > 0) {
|
||||
return PromiseWrapper.all(promises);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -485,5 +513,5 @@ export class ApplicationRef_ extends ApplicationRef {
|
||||
this._platform._applicationDisposed(this);
|
||||
}
|
||||
|
||||
get componentTypes(): any[] { return this._rootComponentTypes; }
|
||||
get componentTypes(): Type[] { return this._rootComponentTypes; }
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import {Locals} from './parser/locals';
|
||||
import {ChangeDetectionStrategy, ChangeDetectorState} from './constants';
|
||||
import {wtfCreateScope, wtfLeave, WtfScopeFn} from '../profile/profile';
|
||||
import {isObservable} from './observable_facade';
|
||||
|
||||
import {ObservableWrapper} from 'angular2/src/facade/async';
|
||||
|
||||
var _scope_check: WtfScopeFn = wtfCreateScope(`ChangeDetector#check(ascii id, bool throwOnChange)`);
|
||||
|
||||
@ -40,6 +40,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
mode: ChangeDetectionStrategy = null;
|
||||
pipes: Pipes = null;
|
||||
propertyBindingIndex: number;
|
||||
outputSubscriptions: any[];
|
||||
|
||||
// This is an experimental feature. Works only in Dart.
|
||||
subscriptions: any[];
|
||||
@ -72,7 +73,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
|
||||
handleEvent(eventName: string, elIndex: number, event: any): boolean {
|
||||
if (!this.hydrated()) {
|
||||
return true;
|
||||
this.throwDehydratedError();
|
||||
}
|
||||
try {
|
||||
var locals = new Map<string, any>();
|
||||
@ -180,6 +181,8 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
this._unsubsribeFromObservables();
|
||||
}
|
||||
|
||||
this._unsubscribeFromOutputs();
|
||||
|
||||
this.dispatcher = null;
|
||||
this.context = null;
|
||||
this.locals = null;
|
||||
@ -258,6 +261,15 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
}
|
||||
}
|
||||
|
||||
private _unsubscribeFromOutputs(): void {
|
||||
if (isPresent(this.outputSubscriptions)) {
|
||||
for (var i = 0; i < this.outputSubscriptions.length; ++i) {
|
||||
ObservableWrapper.dispose(this.outputSubscriptions[i]);
|
||||
this.outputSubscriptions[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is an experimental feature. Works only in Dart.
|
||||
observeValue(value: any, index: number): any {
|
||||
if (isObservable(value)) {
|
||||
|
@ -103,7 +103,7 @@ export class CodegenLogicUtil {
|
||||
break;
|
||||
|
||||
case RecordType.Chain:
|
||||
rhs = 'null';
|
||||
rhs = `${getLocalName(protoRec.args[protoRec.args.length - 1])}`;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -153,6 +153,7 @@ export class CodegenLogicUtil {
|
||||
|
||||
genHydrateDirectives(directiveRecords: DirectiveRecord[]): string {
|
||||
var res = [];
|
||||
var outputCount = 0;
|
||||
for (var i = 0; i < directiveRecords.length; ++i) {
|
||||
var r = directiveRecords[i];
|
||||
var dirVarName = this._names.getDirectiveName(r.directiveIndex);
|
||||
@ -160,14 +161,24 @@ export class CodegenLogicUtil {
|
||||
if (isPresent(r.outputs)) {
|
||||
r.outputs.forEach(output => {
|
||||
var eventHandlerExpr = this._genEventHandler(r.directiveIndex.elementIndex, output[1]);
|
||||
var statementStart =
|
||||
`this.outputSubscriptions[${outputCount++}] = ${dirVarName}.${output[0]}`;
|
||||
if (IS_DART) {
|
||||
res.push(`${dirVarName}.${output[0]}.listen(${eventHandlerExpr});`);
|
||||
res.push(`${statementStart}.listen(${eventHandlerExpr});`);
|
||||
} else {
|
||||
res.push(`${dirVarName}.${output[0]}.subscribe({next: ${eventHandlerExpr}});`);
|
||||
res.push(`${statementStart}.subscribe({next: ${eventHandlerExpr}});`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (outputCount > 0) {
|
||||
var statementStart = 'this.outputSubscriptions';
|
||||
if (IS_DART) {
|
||||
res.unshift(`${statementStart} = new List(${outputCount});`);
|
||||
} else {
|
||||
res.unshift(`${statementStart} = new Array(${outputCount});`);
|
||||
}
|
||||
}
|
||||
return res.join("\n");
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ import {IterableDiffer, IterableDifferFactory} from '../differs/iterable_differs
|
||||
@CONST()
|
||||
export class DefaultIterableDifferFactory implements IterableDifferFactory {
|
||||
supports(obj: Object): boolean { return isListLikeIterable(obj); }
|
||||
create(cdRef: ChangeDetectorRef): any { return new DefaultIterableDiffer(); }
|
||||
create(cdRef: ChangeDetectorRef): DefaultIterableDiffer { return new DefaultIterableDiffer(); }
|
||||
}
|
||||
|
||||
export class DefaultIterableDiffer implements IterableDiffer {
|
||||
|
@ -9,7 +9,7 @@ import {Provider, SkipSelfMetadata, OptionalMetadata, Injectable} from 'angular2
|
||||
* respond to changes in an iterable by effecting equivalent changes in the DOM.
|
||||
*/
|
||||
export interface IterableDiffer {
|
||||
diff(object: Object): any;
|
||||
diff(object: any): any;
|
||||
onDestroy();
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ export interface IterableDiffer {
|
||||
* Provides a factory for {@link IterableDiffer}.
|
||||
*/
|
||||
export interface IterableDifferFactory {
|
||||
supports(objects: Object): boolean;
|
||||
supports(objects: any): boolean;
|
||||
create(cdRef: ChangeDetectorRef): IterableDiffer;
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ export class IterableDiffers {
|
||||
});
|
||||
}
|
||||
|
||||
find(iterable: Object): IterableDifferFactory {
|
||||
find(iterable: any): IterableDifferFactory {
|
||||
var factory = this.factories.find(f => f.supports(iterable));
|
||||
if (isPresent(factory)) {
|
||||
return factory;
|
||||
|
@ -8,7 +8,7 @@ import {Provider, SkipSelfMetadata, OptionalMetadata, Injectable} from 'angular2
|
||||
* A differ that tracks changes made to an object over time.
|
||||
*/
|
||||
export interface KeyValueDiffer {
|
||||
diff(object: Object);
|
||||
diff(object: any);
|
||||
onDestroy();
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ export interface KeyValueDiffer {
|
||||
* Provides a factory for {@link KeyValueDiffer}.
|
||||
*/
|
||||
export interface KeyValueDifferFactory {
|
||||
supports(objects: Object): boolean;
|
||||
supports(objects: any): boolean;
|
||||
create(cdRef: ChangeDetectorRef): KeyValueDiffer;
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
||||
super.observeDirective(this._getDirectiveFor(index), i);
|
||||
}
|
||||
}
|
||||
this.outputSubscriptions = [];
|
||||
for (var i = 0; i < this._directiveRecords.length; ++i) {
|
||||
var r = this._directiveRecords[i];
|
||||
if (isPresent(r.outputs)) {
|
||||
@ -122,7 +123,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
||||
<any>this._createEventHandler(r.directiveIndex.elementIndex, output[1]);
|
||||
var directive = this._getDirectiveFor(r.directiveIndex);
|
||||
var getter = reflector.getter(output[0]);
|
||||
ObservableWrapper.subscribe(getter(directive), eventHandler);
|
||||
this.outputSubscriptions.push(
|
||||
ObservableWrapper.subscribe(getter(directive), eventHandler));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ export class ChangeDetectionError extends WrappedException {
|
||||
* This is an internal Angular error.
|
||||
*/
|
||||
export class DehydratedException extends BaseException {
|
||||
constructor() { super('Attempt to detect changes on a dehydrated detector.'); }
|
||||
constructor() { super('Attempt to use a dehydrated detector.'); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,7 +143,7 @@ export class ProtoInjectorInlineStrategy implements ProtoInjectorStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
getProviderAtIndex(index: number): any {
|
||||
getProviderAtIndex(index: number): ResolvedProvider {
|
||||
if (index == 0) return this.provider0;
|
||||
if (index == 1) return this.provider1;
|
||||
if (index == 2) return this.provider2;
|
||||
@ -181,7 +181,7 @@ export class ProtoInjectorDynamicStrategy implements ProtoInjectorStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
getProviderAtIndex(index: number): any {
|
||||
getProviderAtIndex(index: number): ResolvedProvider {
|
||||
if (index < 0 || index >= this.providers.length) {
|
||||
throw new OutOfBoundsError(index);
|
||||
}
|
||||
@ -210,7 +210,9 @@ export class ProtoInjector {
|
||||
new ProtoInjectorInlineStrategy(this, bwv);
|
||||
}
|
||||
|
||||
getProviderAtIndex(index: number): any { return this._strategy.getProviderAtIndex(index); }
|
||||
getProviderAtIndex(index: number): ResolvedProvider {
|
||||
return this._strategy.getProviderAtIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,6 +2,7 @@ import {resolveForwardRef, Injectable} from 'angular2/src/core/di';
|
||||
import {Type, isPresent, isBlank, stringify} from 'angular2/src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {
|
||||
DirectiveMetadata,
|
||||
ComponentMetadata,
|
||||
@ -38,7 +39,7 @@ export class DirectiveResolver {
|
||||
var metadata = typeMetadata.find(_isDirectiveMetadata);
|
||||
if (isPresent(metadata)) {
|
||||
var propertyMetadata = reflector.propMetadata(type);
|
||||
return this._mergeWithPropertyMetadata(metadata, propertyMetadata);
|
||||
return this._mergeWithPropertyMetadata(metadata, propertyMetadata, type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,7 +47,8 @@ export class DirectiveResolver {
|
||||
}
|
||||
|
||||
private _mergeWithPropertyMetadata(dm: DirectiveMetadata,
|
||||
propertyMetadata: {[key: string]: any[]}): DirectiveMetadata {
|
||||
propertyMetadata: {[key: string]: any[]},
|
||||
directiveType: Type): DirectiveMetadata {
|
||||
var inputs = [];
|
||||
var outputs = [];
|
||||
var host: {[key: string]: string} = {};
|
||||
@ -100,13 +102,27 @@ export class DirectiveResolver {
|
||||
}
|
||||
});
|
||||
});
|
||||
return this._merge(dm, inputs, outputs, host, queries);
|
||||
return this._merge(dm, inputs, outputs, host, queries, directiveType);
|
||||
}
|
||||
|
||||
private _merge(dm: DirectiveMetadata, inputs: string[], outputs: string[],
|
||||
host: {[key: string]: string}, queries: {[key: string]: any}): DirectiveMetadata {
|
||||
host: {[key: string]: string}, queries: {[key: string]: any},
|
||||
directiveType: Type): DirectiveMetadata {
|
||||
var mergedInputs = isPresent(dm.inputs) ? ListWrapper.concat(dm.inputs, inputs) : inputs;
|
||||
var mergedOutputs = isPresent(dm.outputs) ? ListWrapper.concat(dm.outputs, outputs) : outputs;
|
||||
|
||||
var mergedOutputs;
|
||||
if (isPresent(dm.outputs)) {
|
||||
dm.outputs.forEach((propName: string) => {
|
||||
if (ListWrapper.contains(outputs, propName)) {
|
||||
throw new BaseException(
|
||||
`Output event '${propName}' defined multiple times in '${stringify(directiveType)}'`);
|
||||
}
|
||||
});
|
||||
mergedOutputs = ListWrapper.concat(dm.outputs, outputs);
|
||||
} else {
|
||||
mergedOutputs = outputs;
|
||||
}
|
||||
|
||||
var mergedHost = isPresent(dm.host) ? StringMapWrapper.merge(dm.host, host) : host;
|
||||
var mergedQueries =
|
||||
isPresent(dm.queries) ? StringMapWrapper.merge(dm.queries, queries) : queries;
|
||||
|
@ -25,7 +25,7 @@ export abstract class TemplateRef {
|
||||
*
|
||||
*/
|
||||
// TODO(i): rename to anchor or location
|
||||
elementRef: ElementRef;
|
||||
get elementRef(): ElementRef { return null; }
|
||||
}
|
||||
|
||||
export class TemplateRef_ extends TemplateRef {
|
||||
|
@ -250,7 +250,7 @@ export class AppView implements ChangeDispatcher {
|
||||
return this.appElements[directive.elementIndex].getDirectiveAtIndex(directive.directiveIndex);
|
||||
}
|
||||
|
||||
getDetectorFor(directive: DirectiveIndex): any {
|
||||
getDetectorFor(directive: DirectiveIndex): ChangeDetector {
|
||||
var componentView = this.appElements[directive.elementIndex].componentView;
|
||||
return isPresent(componentView) ? componentView.changeDetector : null;
|
||||
}
|
||||
|
@ -133,13 +133,13 @@ export class ViewContainerRef_ extends ViewContainerRef {
|
||||
|
||||
// TODO(rado): profile and decide whether bounds checks should be added
|
||||
// to the methods below.
|
||||
createEmbeddedView(templateRef: TemplateRef_, index: number = -1): EmbeddedViewRef {
|
||||
createEmbeddedView(templateRef: TemplateRef, index: number = -1): EmbeddedViewRef {
|
||||
if (index == -1) index = this.length;
|
||||
var vm = this._element.parentView.viewManager;
|
||||
return vm.createEmbeddedViewInContainer(this._element.ref, index, templateRef);
|
||||
}
|
||||
|
||||
createHostView(hostViewFactoryRef: HostViewFactoryRef_, index: number = -1,
|
||||
createHostView(hostViewFactoryRef: HostViewFactoryRef, index: number = -1,
|
||||
dynamicallyCreatedProviders: ResolvedProvider[] = null,
|
||||
projectableNodes: any[][] = null): HostViewRef {
|
||||
if (index == -1) index = this.length;
|
||||
@ -149,14 +149,14 @@ export class ViewContainerRef_ extends ViewContainerRef {
|
||||
}
|
||||
|
||||
// TODO(i): refactor insert+remove into move
|
||||
insert(viewRef: ViewRef_, index: number = -1): EmbeddedViewRef {
|
||||
insert(viewRef: ViewRef, index: number = -1): EmbeddedViewRef {
|
||||
if (index == -1) index = this.length;
|
||||
var vm = this._element.parentView.viewManager;
|
||||
return vm.attachViewInContainer(this._element.ref, index, viewRef);
|
||||
}
|
||||
|
||||
indexOf(viewRef: ViewRef_): number {
|
||||
return ListWrapper.indexOf(this._element.nestedViews, viewRef.internalView);
|
||||
indexOf(viewRef: ViewRef): number {
|
||||
return ListWrapper.indexOf(this._element.nestedViews, (<ViewRef_>viewRef).internalView);
|
||||
}
|
||||
|
||||
// TODO(i): rename to destroy
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
HostViewFactoryRef_,
|
||||
EmbeddedViewRef,
|
||||
HostViewRef,
|
||||
ViewRef,
|
||||
ViewRef_
|
||||
} from './view_ref';
|
||||
import {ViewContainerRef} from './view_container_ref';
|
||||
@ -189,20 +190,20 @@ export class AppViewManager_ extends AppViewManager {
|
||||
super();
|
||||
}
|
||||
|
||||
getViewContainer(location: ElementRef_): ViewContainerRef {
|
||||
return location.internalElement.getViewContainerRef();
|
||||
getViewContainer(location: ElementRef): ViewContainerRef {
|
||||
return (<ElementRef_>location).internalElement.getViewContainerRef();
|
||||
}
|
||||
|
||||
getHostElement(hostViewRef: ViewRef_): ElementRef {
|
||||
var hostView = hostViewRef.internalView;
|
||||
getHostElement(hostViewRef: ViewRef): ElementRef {
|
||||
var hostView = (<ViewRef_>hostViewRef).internalView;
|
||||
if (hostView.proto.type !== ViewType.HOST) {
|
||||
throw new BaseException('This operation is only allowed on host views');
|
||||
}
|
||||
return hostView.appElements[0].ref;
|
||||
}
|
||||
|
||||
getNamedElementInComponentView(hostLocation: ElementRef_, variableName: string): ElementRef {
|
||||
var appEl = hostLocation.internalElement;
|
||||
getNamedElementInComponentView(hostLocation: ElementRef, variableName: string): ElementRef {
|
||||
var appEl = (<ElementRef_>hostLocation).internalElement;
|
||||
var componentView = appEl.componentView;
|
||||
if (isBlank(componentView)) {
|
||||
throw new BaseException(`There is no component directive at element ${hostLocation}`);
|
||||
@ -216,17 +217,17 @@ export class AppViewManager_ extends AppViewManager {
|
||||
throw new BaseException(`Could not find variable ${variableName}`);
|
||||
}
|
||||
|
||||
getComponent(hostLocation: ElementRef_): any {
|
||||
return hostLocation.internalElement.getComponent();
|
||||
getComponent(hostLocation: ElementRef): any {
|
||||
return (<ElementRef_>hostLocation).internalElement.getComponent();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_createRootHostViewScope: WtfScopeFn = wtfCreateScope('AppViewManager#createRootHostView()');
|
||||
|
||||
createRootHostView(hostViewFactoryRef: HostViewFactoryRef_, overrideSelector: string,
|
||||
createRootHostView(hostViewFactoryRef: HostViewFactoryRef, overrideSelector: string,
|
||||
injector: Injector, projectableNodes: any[][] = null): HostViewRef {
|
||||
var s = this._createRootHostViewScope();
|
||||
var hostViewFactory = hostViewFactoryRef.internalHostViewFactory;
|
||||
var hostViewFactory = (<HostViewFactoryRef_>hostViewFactoryRef).internalHostViewFactory;
|
||||
var selector = isPresent(overrideSelector) ? overrideSelector : hostViewFactory.selector;
|
||||
var view = hostViewFactory.viewFactory(this._renderer, this, null, projectableNodes, selector,
|
||||
null, injector);
|
||||
@ -236,9 +237,9 @@ export class AppViewManager_ extends AppViewManager {
|
||||
/** @internal */
|
||||
_destroyRootHostViewScope: WtfScopeFn = wtfCreateScope('AppViewManager#destroyRootHostView()');
|
||||
|
||||
destroyRootHostView(hostViewRef: ViewRef_) {
|
||||
destroyRootHostView(hostViewRef: ViewRef) {
|
||||
var s = this._destroyRootHostViewScope();
|
||||
var hostView = hostViewRef.internalView;
|
||||
var hostView = (<ViewRef_>hostViewRef).internalView;
|
||||
hostView.renderer.detachView(flattenNestedViewRenderNodes(hostView.rootNodesOrAppElements));
|
||||
hostView.destroy();
|
||||
wtfLeave(s);
|
||||
@ -248,14 +249,14 @@ export class AppViewManager_ extends AppViewManager {
|
||||
_createEmbeddedViewInContainerScope: WtfScopeFn =
|
||||
wtfCreateScope('AppViewManager#createEmbeddedViewInContainer()');
|
||||
|
||||
createEmbeddedViewInContainer(viewContainerLocation: ElementRef_, index: number,
|
||||
templateRef: TemplateRef_): EmbeddedViewRef {
|
||||
createEmbeddedViewInContainer(viewContainerLocation: ElementRef, index: number,
|
||||
templateRef: TemplateRef): EmbeddedViewRef {
|
||||
var s = this._createEmbeddedViewInContainerScope();
|
||||
var contextEl = templateRef.elementRef.internalElement;
|
||||
var contextEl = (<TemplateRef_>templateRef).elementRef.internalElement;
|
||||
var view: AppView =
|
||||
contextEl.embeddedViewFactory(contextEl.parentView.renderer, this, contextEl,
|
||||
contextEl.parentView.projectableNodes, null, null, null);
|
||||
this._attachViewToContainer(view, viewContainerLocation.internalElement, index);
|
||||
this._attachViewToContainer(view, (<ElementRef_>viewContainerLocation).internalElement, index);
|
||||
return wtfLeave(s, view.ref);
|
||||
}
|
||||
|
||||
@ -263,27 +264,29 @@ export class AppViewManager_ extends AppViewManager {
|
||||
_createHostViewInContainerScope: WtfScopeFn =
|
||||
wtfCreateScope('AppViewManager#createHostViewInContainer()');
|
||||
|
||||
createHostViewInContainer(viewContainerLocation: ElementRef_, index: number,
|
||||
hostViewFactoryRef: HostViewFactoryRef_,
|
||||
createHostViewInContainer(viewContainerLocation: ElementRef, index: number,
|
||||
hostViewFactoryRef: HostViewFactoryRef,
|
||||
dynamicallyCreatedProviders: ResolvedProvider[],
|
||||
projectableNodes: any[][]): HostViewRef {
|
||||
var s = this._createHostViewInContainerScope();
|
||||
// TODO(tbosch): This should be specifiable via an additional argument!
|
||||
var contextEl = viewContainerLocation.internalElement;
|
||||
var hostViewFactory = hostViewFactoryRef.internalHostViewFactory;
|
||||
var viewContainerLocation_ = <ElementRef_>viewContainerLocation;
|
||||
var contextEl = viewContainerLocation_.internalElement;
|
||||
var hostViewFactory = (<HostViewFactoryRef_>hostViewFactoryRef).internalHostViewFactory;
|
||||
var view = hostViewFactory.viewFactory(
|
||||
contextEl.parentView.renderer, contextEl.parentView.viewManager, contextEl,
|
||||
projectableNodes, null, dynamicallyCreatedProviders, null);
|
||||
this._attachViewToContainer(view, viewContainerLocation.internalElement, index);
|
||||
this._attachViewToContainer(view, viewContainerLocation_.internalElement, index);
|
||||
return wtfLeave(s, view.ref);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_destroyViewInContainerScope = wtfCreateScope('AppViewMananger#destroyViewInContainer()');
|
||||
|
||||
destroyViewInContainer(viewContainerLocation: ElementRef_, index: number) {
|
||||
destroyViewInContainer(viewContainerLocation: ElementRef, index: number) {
|
||||
var s = this._destroyViewInContainerScope();
|
||||
var view = this._detachViewInContainer(viewContainerLocation.internalElement, index);
|
||||
var view =
|
||||
this._detachViewInContainer((<ElementRef_>viewContainerLocation).internalElement, index);
|
||||
view.destroy();
|
||||
wtfLeave(s);
|
||||
}
|
||||
@ -292,20 +295,23 @@ export class AppViewManager_ extends AppViewManager {
|
||||
_attachViewInContainerScope = wtfCreateScope('AppViewMananger#attachViewInContainer()');
|
||||
|
||||
// TODO(i): refactor detachViewInContainer+attachViewInContainer to moveViewInContainer
|
||||
attachViewInContainer(viewContainerLocation: ElementRef_, index: number,
|
||||
viewRef: ViewRef_): EmbeddedViewRef {
|
||||
attachViewInContainer(viewContainerLocation: ElementRef, index: number,
|
||||
viewRef: ViewRef): EmbeddedViewRef {
|
||||
var viewRef_ = <ViewRef_>viewRef;
|
||||
var s = this._attachViewInContainerScope();
|
||||
this._attachViewToContainer(viewRef.internalView, viewContainerLocation.internalElement, index);
|
||||
return wtfLeave(s, viewRef);
|
||||
this._attachViewToContainer(viewRef_.internalView,
|
||||
(<ElementRef_>viewContainerLocation).internalElement, index);
|
||||
return wtfLeave(s, viewRef_);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_detachViewInContainerScope = wtfCreateScope('AppViewMananger#detachViewInContainer()');
|
||||
|
||||
// TODO(i): refactor detachViewInContainer+attachViewInContainer to moveViewInContainer
|
||||
detachViewInContainer(viewContainerLocation: ElementRef_, index: number): EmbeddedViewRef {
|
||||
detachViewInContainer(viewContainerLocation: ElementRef, index: number): EmbeddedViewRef {
|
||||
var s = this._detachViewInContainerScope();
|
||||
var view = this._detachViewInContainer(viewContainerLocation.internalElement, index);
|
||||
var view =
|
||||
this._detachViewInContainer((<ElementRef_>viewContainerLocation).internalElement, index);
|
||||
return wtfLeave(s, view.ref);
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ class NoReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||
}
|
||||
|
||||
@override
|
||||
List parameters(dynamic type) {
|
||||
List<List> parameters(dynamic type) {
|
||||
throw "Cannot find reflection information on ${stringify(type)}";
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ class NoReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||
}
|
||||
|
||||
@override
|
||||
Map propMetadata(dynamic type) {
|
||||
Map<String, List> propMetadata(dynamic type) {
|
||||
throw "Cannot find reflection information on ${stringify(type)}";
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
library reflection.types;
|
||||
|
||||
typedef SetterFn(Object obj, value);
|
||||
typedef GetterFn(Object obj);
|
||||
typedef MethodFn(Object obj, List args);
|
||||
typedef SetterFn(obj, value);
|
||||
typedef GetterFn(obj);
|
||||
typedef MethodFn(obj, List args);
|
||||
|
@ -28,7 +28,7 @@ export abstract class Renderer implements ParentRenderer {
|
||||
|
||||
abstract destroyView(hostElement: any, viewAllNodes: any[]);
|
||||
|
||||
abstract listen(renderElement: any, name: string, callback: Function);
|
||||
abstract listen(renderElement: any, name: string, callback: Function): Function;
|
||||
|
||||
abstract listenGlobal(target: string, name: string, callback: Function): Function;
|
||||
|
||||
|
@ -15,6 +15,13 @@ import {PromiseWrapper, ObservableWrapper} from 'angular2/src/facade/async';
|
||||
export class Testability {
|
||||
/** @internal */
|
||||
_pendingCount: number = 0;
|
||||
/**
|
||||
* Whether any work was done since the last 'whenStable' callback. This is
|
||||
* useful to detect if this could have potentially destabilized another
|
||||
* component while it is stabilizing.
|
||||
* @internal
|
||||
*/
|
||||
_didWork: boolean = false;
|
||||
/** @internal */
|
||||
_callbacks: Function[] = [];
|
||||
/** @internal */
|
||||
@ -23,8 +30,10 @@ export class Testability {
|
||||
|
||||
/** @internal */
|
||||
_watchAngularEvents(_ngZone: NgZone): void {
|
||||
ObservableWrapper.subscribe(_ngZone.onTurnStart,
|
||||
(_) => { this._isAngularEventPending = true; });
|
||||
ObservableWrapper.subscribe(_ngZone.onTurnStart, (_) => {
|
||||
this._didWork = true;
|
||||
this._isAngularEventPending = true;
|
||||
});
|
||||
|
||||
_ngZone.runOutsideAngular(() => {
|
||||
ObservableWrapper.subscribe(_ngZone.onEventDone, (_) => {
|
||||
@ -38,6 +47,7 @@ export class Testability {
|
||||
|
||||
increasePendingRequestCount(): number {
|
||||
this._pendingCount += 1;
|
||||
this._didWork = true;
|
||||
return this._pendingCount;
|
||||
}
|
||||
|
||||
@ -55,14 +65,16 @@ export class Testability {
|
||||
/** @internal */
|
||||
_runCallbacksIfReady(): void {
|
||||
if (!this.isStable()) {
|
||||
this._didWork = true;
|
||||
return; // Not ready
|
||||
}
|
||||
|
||||
// Schedules the call backs in a new frame so that it is always async.
|
||||
PromiseWrapper.resolve(null).then((_) => {
|
||||
while (this._callbacks.length !== 0) {
|
||||
(this._callbacks.pop())();
|
||||
(this._callbacks.pop())(this._didWork);
|
||||
}
|
||||
this._didWork = false;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -73,16 +73,16 @@ class ObservableWrapper {
|
||||
}
|
||||
|
||||
class EventEmitter<T> extends Stream<T> {
|
||||
StreamController<dynamic> _controller;
|
||||
StreamController<T> _controller;
|
||||
|
||||
/// Creates an instance of [EventEmitter], which depending on [isAsync],
|
||||
/// delivers events synchronously or asynchronously.
|
||||
EventEmitter([bool isAsync = true]) {
|
||||
_controller = new StreamController.broadcast(sync: !isAsync);
|
||||
_controller = new StreamController<T>.broadcast(sync: !isAsync);
|
||||
}
|
||||
|
||||
StreamSubscription listen(void onData(dynamic line),
|
||||
{void onError(Error error), void onDone(), bool cancelOnError}) {
|
||||
StreamSubscription<T> listen(void onData(T event),
|
||||
{Function onError, void onDone(), bool cancelOnError}) {
|
||||
return _controller.stream.listen(onData,
|
||||
onError: onError, onDone: onDone, cancelOnError: cancelOnError);
|
||||
}
|
||||
@ -106,14 +106,14 @@ class EventEmitter<T> extends Stream<T> {
|
||||
|
||||
//todo(robwormald): maybe fix in ts2dart?
|
||||
class Subject<T> extends Stream<T> {
|
||||
StreamController<dynamic> _controller;
|
||||
StreamController<T> _controller;
|
||||
|
||||
Subject([bool isAsync = true]) {
|
||||
_controller = new StreamController.broadcast(sync: !isAsync);
|
||||
_controller = new StreamController<T>.broadcast(sync: !isAsync);
|
||||
}
|
||||
|
||||
StreamSubscription listen(void onData(dynamic line),
|
||||
{void onError(Error error), void onDone(), bool cancelOnError}) {
|
||||
StreamSubscription<T> listen(void onData(T data),
|
||||
{Function onError, void onDone(), bool cancelOnError}) {
|
||||
return _controller.stream.listen(onData,
|
||||
onError: onError, onDone: onDone, cancelOnError: cancelOnError);
|
||||
}
|
||||
|
@ -4,9 +4,11 @@ import 'exception_handler.dart';
|
||||
export 'exception_handler.dart';
|
||||
|
||||
class BaseException extends Error {
|
||||
final String message;
|
||||
final String _message;
|
||||
|
||||
BaseException([this.message]);
|
||||
BaseException([this._message]);
|
||||
|
||||
String get message => _message;
|
||||
|
||||
String toString() {
|
||||
return this.message;
|
||||
@ -14,16 +16,16 @@ class BaseException extends Error {
|
||||
}
|
||||
|
||||
class WrappedException extends Error {
|
||||
final dynamic context;
|
||||
final String wrapperMessage;
|
||||
final dynamic _context;
|
||||
final String _wrapperMessage;
|
||||
final originalException;
|
||||
final originalStack;
|
||||
|
||||
WrappedException(
|
||||
[this.wrapperMessage,
|
||||
[this._wrapperMessage,
|
||||
this.originalException,
|
||||
this.originalStack,
|
||||
this.context]);
|
||||
this._context]);
|
||||
|
||||
get message {
|
||||
return ExceptionHandler.exceptionToString(this);
|
||||
@ -32,6 +34,10 @@ class WrappedException extends Error {
|
||||
String toString() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
dynamic get context => _context;
|
||||
|
||||
String get wrapperMessage => _wrapperMessage;
|
||||
}
|
||||
|
||||
Error makeTypeError([String message = ""]) {
|
||||
|
@ -235,10 +235,26 @@ class FunctionWrapper {
|
||||
|
||||
const _NAN_KEY = const Object();
|
||||
|
||||
// Dart can have identical(str1, str2) == false while str1 == str2. Moreover,
|
||||
// after compiling with dart2js identical(str1, str2) might return true.
|
||||
// (see dartbug.com/22496 for details).
|
||||
bool looseIdentical(a, b) =>
|
||||
// Dart VM implements `identical` as true reference identity. JavaScript does
|
||||
// not have this. The closest we have in JS is `===`. However, for strings JS
|
||||
// would actually compare the contents rather than references. `dart2js`
|
||||
// compiles `identical` to `===` and therefore there is a discrepancy between
|
||||
// Dart VM and `dart2js`. The implementation of `looseIdentical` attempts to
|
||||
// bridge the gap between the two while retaining good performance
|
||||
// characteristics. In JS we use simple `identical`, which compiles to `===`,
|
||||
// and in Dart VM we emulate the semantics of `===` by special-casing strings.
|
||||
// Note that the VM check is a compile-time constant. This allows `dart2js` to
|
||||
// evaluate the conditional during compilation and inline the entire function.
|
||||
//
|
||||
// See: dartbug.com/22496, dartbug.com/25270
|
||||
const _IS_DART_VM = !identical(1.0, 1); // a hack
|
||||
bool looseIdentical(a, b) => _IS_DART_VM
|
||||
? _looseIdentical(a, b)
|
||||
: identical(a, b);
|
||||
|
||||
// This function is intentionally separated from `looseIdentical` to keep the
|
||||
// number of AST nodes low enough for `dart2js` to inline the code.
|
||||
bool _looseIdentical(a, b) =>
|
||||
a is String && b is String ? a == b : identical(a, b);
|
||||
|
||||
// Dart compare map keys by equality and we can have NaN != NaN
|
||||
|
@ -90,7 +90,7 @@ class PublicTestability implements _JsObjectProxyable {
|
||||
'findBindings': (bindingString, [exactMatch, allowNonElementNodes]) =>
|
||||
findBindings(bindingString, exactMatch, allowNonElementNodes),
|
||||
'isStable': () => isStable(),
|
||||
'whenStable': (callback) => whenStable(() => callback.apply([]))
|
||||
'whenStable': (callback) => whenStable((didWork) => callback.apply([didWork]))
|
||||
})..['_dart_'] = this;
|
||||
}
|
||||
}
|
||||
@ -116,7 +116,7 @@ class BrowserGetTestability implements GetTestability {
|
||||
}
|
||||
throw 'Could not find testability for element.';
|
||||
});
|
||||
js.context['getAllAngularTestabilities'] = _jsify(() {
|
||||
var getAllAngularTestabilities = () {
|
||||
var registry = js.context['ngTestabilityRegistries'];
|
||||
var result = [];
|
||||
for (int i = 0; i < registry.length; i++) {
|
||||
@ -125,7 +125,29 @@ class BrowserGetTestability implements GetTestability {
|
||||
if (testabilities != null) result.addAll(testabilities);
|
||||
}
|
||||
return _jsify(result);
|
||||
};
|
||||
js.context['getAllAngularTestabilities'] =
|
||||
_jsify(getAllAngularTestabilities);
|
||||
|
||||
var whenAllStable = _jsify((callback) {
|
||||
var testabilities = getAllAngularTestabilities();
|
||||
var count = testabilities.length;
|
||||
var didWork = false;
|
||||
var decrement = _jsify((bool didWork_) {
|
||||
didWork = didWork || didWork_;
|
||||
count--;
|
||||
if (count == 0) {
|
||||
callback.apply([didWork]);
|
||||
}
|
||||
});
|
||||
testabilities.forEach((testability) {
|
||||
testability.callMethod('whenStable', [decrement]);
|
||||
});
|
||||
});
|
||||
if (js.context['frameworkStabilizers'] == null) {
|
||||
js.context['frameworkStabilizers'] = new js.JsArray();
|
||||
}
|
||||
js.context['frameworkStabilizers'].add(whenAllStable);
|
||||
}
|
||||
jsRegistry.add(this._createRegistry(registry));
|
||||
}
|
||||
|
@ -48,6 +48,25 @@ export class BrowserGetTestability implements GetTestability {
|
||||
var testabilities = registry.getAllTestabilities();
|
||||
return testabilities.map((testability) => { return new PublicTestability(testability); });
|
||||
};
|
||||
|
||||
var whenAllStable = (callback) => {
|
||||
var testabilities = global.getAllAngularTestabilities();
|
||||
var count = testabilities.length;
|
||||
var didWork = false;
|
||||
var decrement = function(didWork_) {
|
||||
didWork = didWork || didWork_;
|
||||
count--;
|
||||
if (count == 0) {
|
||||
callback(didWork);
|
||||
}
|
||||
};
|
||||
testabilities.forEach(function(testability) { testability.whenStable(decrement); });
|
||||
};
|
||||
|
||||
if (!global.frameworkStabilizers) {
|
||||
global.frameworkStabilizers = ListWrapper.createGrowableSize(0);
|
||||
}
|
||||
global.frameworkStabilizers.push(whenAllStable);
|
||||
}
|
||||
|
||||
findTestabilityInTree(registry: TestabilityRegistry, elem: any,
|
||||
|
@ -23,13 +23,17 @@ export abstract class DomAdapter {
|
||||
abstract logGroup(error);
|
||||
abstract logGroupEnd();
|
||||
|
||||
/** @deprecated */
|
||||
abstract getXHR(): Type;
|
||||
|
||||
/**
|
||||
* Maps attribute names to their corresponding property names for cases
|
||||
* where attribute name doesn't match property name.
|
||||
*/
|
||||
attrToPropMap: {[key: string]: string};
|
||||
get attrToPropMap(): {[key: string]: string} { return this._attrToPropMap; };
|
||||
set attrToPropMap(value: {[key: string]: string}) { this._attrToPropMap = value; };
|
||||
/** @internal */
|
||||
_attrToPropMap: {[key: string]: string};
|
||||
|
||||
abstract parse(templateHtml: string);
|
||||
abstract query(selector: string): any;
|
||||
|
@ -155,8 +155,8 @@ export class DomRenderer implements Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
listen(renderElement: any, name: string, callback: Function) {
|
||||
this._rootRenderer.eventManager.addEventListener(renderElement, name,
|
||||
listen(renderElement: any, name: string, callback: Function): Function {
|
||||
return this._rootRenderer.eventManager.addEventListener(renderElement, name,
|
||||
decoratePreventDefault(callback));
|
||||
}
|
||||
|
||||
|
@ -4,16 +4,15 @@ import {EventManagerPlugin, EventManager} from './event_manager';
|
||||
|
||||
@Injectable()
|
||||
export class DomEventsPlugin extends EventManagerPlugin {
|
||||
manager: EventManager;
|
||||
|
||||
// This plugin should come last in the list of plugins, because it accepts all
|
||||
// events.
|
||||
supports(eventName: string): boolean { return true; }
|
||||
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
|
||||
var zone = this.manager.getZone();
|
||||
var outsideHandler = (event) => zone.run(() => handler(event));
|
||||
this.manager.getZone().runOutsideAngular(() => { DOM.on(element, eventName, outsideHandler); });
|
||||
return this.manager.getZone().runOutsideAngular(
|
||||
() => DOM.onAndCancel(element, eventName, outsideHandler));
|
||||
}
|
||||
|
||||
addGlobalEventListener(target: string, eventName: string, handler: Function): Function {
|
||||
@ -21,6 +20,6 @@ export class DomEventsPlugin extends EventManagerPlugin {
|
||||
var zone = this.manager.getZone();
|
||||
var outsideHandler = (event) => zone.run(() => handler(event));
|
||||
return this.manager.getZone().runOutsideAngular(
|
||||
() => { return DOM.onAndCancel(element, eventName, outsideHandler); });
|
||||
() => DOM.onAndCancel(element, eventName, outsideHandler));
|
||||
}
|
||||
}
|
||||
|
@ -16,9 +16,9 @@ export class EventManager {
|
||||
this._plugins = ListWrapper.reversed(plugins);
|
||||
}
|
||||
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
|
||||
var plugin = this._findPluginFor(eventName);
|
||||
plugin.addEventListener(element, eventName, handler);
|
||||
return plugin.addEventListener(element, eventName, handler);
|
||||
}
|
||||
|
||||
addGlobalEventListener(target: string, eventName: string, handler: Function): Function {
|
||||
@ -47,7 +47,7 @@ export class EventManagerPlugin {
|
||||
// That is equivalent to having supporting $event.target
|
||||
supports(eventName: string): boolean { return false; }
|
||||
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
|
||||
throw "not implemented";
|
||||
}
|
||||
|
||||
|
@ -15,17 +15,18 @@ export class HammerGesturesPlugin extends HammerGesturesPluginCommon {
|
||||
return true;
|
||||
}
|
||||
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
|
||||
var zone = this.manager.getZone();
|
||||
eventName = eventName.toLowerCase();
|
||||
|
||||
zone.runOutsideAngular(function() {
|
||||
return zone.runOutsideAngular(function() {
|
||||
// Creating the manager bind events, must be done outside of angular
|
||||
var mc = new Hammer(element);
|
||||
mc.get('pinch').set({enable: true});
|
||||
mc.get('rotate').set({enable: true});
|
||||
|
||||
mc.on(eventName, function(eventObj) { zone.run(function() { handler(eventObj); }); });
|
||||
var handler = function(eventObj) { zone.run(function() { handler(eventObj); }); };
|
||||
mc.on(eventName, handler);
|
||||
return () => { mc.off(eventName, handler); };
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -27,14 +27,15 @@ export class KeyEventsPlugin extends EventManagerPlugin {
|
||||
return isPresent(KeyEventsPlugin.parseEventName(eventName));
|
||||
}
|
||||
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: (Event: any) => any) {
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
|
||||
var parsedEvent = KeyEventsPlugin.parseEventName(eventName);
|
||||
|
||||
var outsideHandler = KeyEventsPlugin.eventCallback(
|
||||
element, StringMapWrapper.get(parsedEvent, 'fullKey'), handler, this.manager.getZone());
|
||||
|
||||
this.manager.getZone().runOutsideAngular(() => {
|
||||
DOM.on(element, StringMapWrapper.get(parsedEvent, 'domEventName'), outsideHandler);
|
||||
return this.manager.getZone().runOutsideAngular(() => {
|
||||
return DOM.onAndCancel(element, StringMapWrapper.get(parsedEvent, 'domEventName'),
|
||||
outsideHandler);
|
||||
});
|
||||
}
|
||||
|
||||
@ -90,8 +91,8 @@ export class KeyEventsPlugin extends EventManagerPlugin {
|
||||
return fullKey;
|
||||
}
|
||||
|
||||
static eventCallback(element: HTMLElement, fullKey: any, handler: (e: Event) => any,
|
||||
zone: NgZone): (event: KeyboardEvent) => void {
|
||||
static eventCallback(element: HTMLElement, fullKey: any, handler: Function,
|
||||
zone: NgZone): Function {
|
||||
return (event) => {
|
||||
if (StringWrapper.equals(KeyEventsPlugin.getEventFullKey(event), fullKey)) {
|
||||
zone.run(() => handler(event));
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
import {WORKER_APP_APPLICATION_COMMON} from './worker_app_common';
|
||||
import {APP_INITIALIZER} from 'angular2/core';
|
||||
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
|
||||
import {COMPILER_PROVIDERS} from 'angular2/src/compiler/compiler';
|
||||
|
||||
// TODO(jteplitz602) remove this and compile with lib.webworker.d.ts (#3492)
|
||||
let _postMessage = {
|
||||
@ -20,6 +21,7 @@ let _postMessage = {
|
||||
|
||||
export const WORKER_APP_APPLICATION: Array<any /*Type | Provider | any[]*/> = [
|
||||
WORKER_APP_APPLICATION_COMMON,
|
||||
COMPILER_PROVIDERS,
|
||||
new Provider(MessageBus, {useFactory: createMessageBus, deps: [NgZone]}),
|
||||
new Provider(APP_INITIALIZER, {useValue: setupWebWorker, multi: true})
|
||||
];
|
||||
|
@ -19,7 +19,6 @@ import {
|
||||
ServiceMessageBrokerFactory,
|
||||
ServiceMessageBrokerFactory_
|
||||
} from 'angular2/src/web_workers/shared/service_message_broker';
|
||||
import {COMPILER_PROVIDERS} from 'angular2/src/compiler/compiler';
|
||||
import {Serializer} from "angular2/src/web_workers/shared/serializer";
|
||||
import {ON_WEB_WORKER} from "angular2/src/web_workers/shared/api";
|
||||
import {Provider} from 'angular2/src/core/di';
|
||||
@ -37,7 +36,6 @@ export const WORKER_APP_PLATFORM: Array<any /*Type | Provider | any[]*/> =
|
||||
|
||||
export const WORKER_APP_APPLICATION_COMMON: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
|
||||
APPLICATION_COMMON_PROVIDERS,
|
||||
COMPILER_PROVIDERS,
|
||||
FORM_PROVIDERS,
|
||||
Serializer,
|
||||
new Provider(PLATFORM_PIPES, {useValue: COMMON_PIPES, multi: true}),
|
||||
|
@ -2,7 +2,7 @@ library angular2.src.platform.worker_render;
|
||||
|
||||
import 'package:angular2/src/platform/worker_render_common.dart'
|
||||
show
|
||||
WORKER_RENDER_APP_COMMON,
|
||||
WORKER_RENDER_APPLICATION_COMMON,
|
||||
WORKER_RENDER_MESSAGING_PROVIDERS,
|
||||
WORKER_SCRIPT,
|
||||
initializeGenericWorkerRenderer;
|
||||
@ -14,14 +14,14 @@ import 'package:angular2/src/core/zone/ng_zone.dart';
|
||||
import 'dart:isolate';
|
||||
import 'dart:async';
|
||||
|
||||
const WORKER_RENDER_APP = WORKER_RENDER_APP_COMMON;
|
||||
const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION_COMMON;
|
||||
|
||||
initIsolate(String scriptUri) {
|
||||
return (NgZone zone) async {
|
||||
var instance = await spawnIsolate(Uri.parse(scriptUri));
|
||||
|
||||
return [
|
||||
WORKER_RENDER_APP_COMMON,
|
||||
WORKER_RENDER_APPLICATION_COMMON,
|
||||
new Provider(WebWorkerInstance, useValue: instance),
|
||||
new Provider(APP_INITIALIZER,
|
||||
useFactory: (injector) => () => initializeGenericWorkerRenderer(injector),
|
||||
|
@ -9,7 +9,7 @@ import {Injector, Injectable, Provider} from 'angular2/src/core/di';
|
||||
import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer';
|
||||
import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl';
|
||||
import {
|
||||
WORKER_RENDER_APP_COMMON,
|
||||
WORKER_RENDER_APPLICATION_COMMON,
|
||||
WORKER_RENDER_MESSAGING_PROVIDERS,
|
||||
WORKER_SCRIPT,
|
||||
initializeGenericWorkerRenderer
|
||||
@ -36,8 +36,8 @@ export class WebWorkerInstance {
|
||||
/**
|
||||
* An array of providers that should be passed into `application()` when initializing a new Worker.
|
||||
*/
|
||||
export const WORKER_RENDER_APP: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
|
||||
WORKER_RENDER_APP_COMMON,
|
||||
export const WORKER_RENDER_APPLICATION: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
|
||||
WORKER_RENDER_APPLICATION_COMMON,
|
||||
WebWorkerInstance,
|
||||
new Provider(APP_INITIALIZER,
|
||||
{
|
||||
|
@ -59,7 +59,7 @@ export const WORKER_RENDER_PLATFORM: Array<any /*Type | Provider | any[]*/> = CO
|
||||
new Provider(PLATFORM_INITIALIZER, {useValue: initWebWorkerRenderPlatform, multi: true})
|
||||
]);
|
||||
|
||||
export const WORKER_RENDER_APP_COMMON: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
|
||||
export const WORKER_RENDER_APPLICATION_COMMON: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
|
||||
APPLICATION_COMMON_PROVIDERS,
|
||||
WORKER_RENDER_MESSAGING_PROVIDERS,
|
||||
new Provider(ExceptionHandler, {useFactory: _exceptionHandler, deps: []}),
|
||||
|
@ -107,9 +107,8 @@ export var BLANK_ROUTE_DATA = new RouteData();
|
||||
* ```
|
||||
*/
|
||||
export abstract class Instruction {
|
||||
public component: ComponentInstruction;
|
||||
public child: Instruction;
|
||||
public auxInstruction: {[key: string]: Instruction} = {};
|
||||
constructor(public component: ComponentInstruction, public child: Instruction,
|
||||
public auxInstruction: {[key: string]: Instruction}) {}
|
||||
|
||||
get urlPath(): string { return isPresent(this.component) ? this.component.urlPath : ''; }
|
||||
|
||||
@ -210,9 +209,9 @@ export abstract class Instruction {
|
||||
* a resolved instruction has an outlet instruction for itself, but maybe not for...
|
||||
*/
|
||||
export class ResolvedInstruction extends Instruction {
|
||||
constructor(public component: ComponentInstruction, public child: Instruction,
|
||||
public auxInstruction: {[key: string]: Instruction}) {
|
||||
super();
|
||||
constructor(component: ComponentInstruction, child: Instruction,
|
||||
auxInstruction: {[key: string]: Instruction}) {
|
||||
super(component, child, auxInstruction);
|
||||
}
|
||||
|
||||
resolveComponent(): Promise<ComponentInstruction> {
|
||||
@ -225,7 +224,9 @@ export class ResolvedInstruction extends Instruction {
|
||||
* Represents a resolved default route
|
||||
*/
|
||||
export class DefaultInstruction extends Instruction {
|
||||
constructor(public component: ComponentInstruction, public child: DefaultInstruction) { super(); }
|
||||
constructor(component: ComponentInstruction, child: DefaultInstruction) {
|
||||
super(component, child, {});
|
||||
}
|
||||
|
||||
resolveComponent(): Promise<ComponentInstruction> {
|
||||
return PromiseWrapper.resolve(this.component);
|
||||
@ -244,7 +245,7 @@ export class DefaultInstruction extends Instruction {
|
||||
export class UnresolvedInstruction extends Instruction {
|
||||
constructor(private _resolver: () => Promise<Instruction>, private _urlPath: string = '',
|
||||
private _urlParams: string[] = CONST_EXPR([])) {
|
||||
super();
|
||||
super(null, null, {});
|
||||
}
|
||||
|
||||
get urlPath(): string {
|
||||
|
@ -202,12 +202,12 @@ export class Router {
|
||||
return this._settleInstruction(instruction)
|
||||
.then((_) => this._routerCanReuse(instruction))
|
||||
.then((_) => this._canActivate(instruction))
|
||||
.then((result) => {
|
||||
.then((result: boolean) => {
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
return this._routerCanDeactivate(instruction)
|
||||
.then((result) => {
|
||||
.then((result: boolean) => {
|
||||
if (result) {
|
||||
return this.commit(instruction, _skipLocationChange)
|
||||
.then((_) => {
|
||||
|
@ -1,130 +1,7 @@
|
||||
import {
|
||||
APP_ID,
|
||||
APPLICATION_COMMON_PROVIDERS,
|
||||
AppViewManager,
|
||||
DirectiveResolver,
|
||||
DynamicComponentLoader,
|
||||
Injector,
|
||||
NgZone,
|
||||
Renderer,
|
||||
Provider,
|
||||
ViewResolver,
|
||||
provide
|
||||
} from 'angular2/core';
|
||||
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
||||
import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock';
|
||||
|
||||
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
|
||||
import {Reflector, reflector} from 'angular2/src/core/reflection/reflection';
|
||||
import {
|
||||
IterableDiffers,
|
||||
defaultIterableDiffers,
|
||||
KeyValueDiffers,
|
||||
defaultKeyValueDiffers,
|
||||
ChangeDetectorGenConfig
|
||||
} from 'angular2/src/core/change_detection/change_detection';
|
||||
import {Injector, Provider, PLATFORM_INITIALIZER} from 'angular2/core';
|
||||
import {BaseException, ExceptionHandler} from 'angular2/src/facade/exceptions';
|
||||
import {PipeResolver} from 'angular2/src/core/linker/pipe_resolver';
|
||||
import {XHR} from 'angular2/src/compiler/xhr';
|
||||
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
|
||||
import {MockDirectiveResolver} from 'angular2/src/mock/directive_resolver_mock';
|
||||
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
|
||||
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
|
||||
import {LocationStrategy} from 'angular2/src/router/location_strategy';
|
||||
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
|
||||
|
||||
import {TestComponentBuilder} from './test_component_builder';
|
||||
|
||||
import {
|
||||
EventManager,
|
||||
EVENT_MANAGER_PLUGINS,
|
||||
ELEMENT_PROBE_PROVIDERS
|
||||
} from 'angular2/platform/common_dom';
|
||||
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {FunctionWrapper, Type} from 'angular2/src/facade/lang';
|
||||
|
||||
import {RootRenderer} from 'angular2/src/core/render/api';
|
||||
|
||||
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
||||
import {DomRootRenderer, DomRootRenderer_} from 'angular2/src/platform/dom/dom_renderer';
|
||||
import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
|
||||
import {SharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
|
||||
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
|
||||
|
||||
import {Serializer} from "angular2/src/web_workers/shared/serializer";
|
||||
import {Log} from './utils';
|
||||
import {COMPILER_PROVIDERS} from 'angular2/src/compiler/compiler';
|
||||
import {DynamicComponentLoader_} from "angular2/src/core/linker/dynamic_component_loader";
|
||||
import {AppViewManager_} from "angular2/src/core/linker/view_manager";
|
||||
|
||||
/**
|
||||
* Returns the root injector providers.
|
||||
*
|
||||
* This must be kept in sync with the _rootBindings in application.js
|
||||
*
|
||||
* @returns {any[]}
|
||||
*/
|
||||
function _getRootProviders() {
|
||||
return [provide(Reflector, {useValue: reflector})];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the application injector providers.
|
||||
*
|
||||
* This must be kept in sync with _injectorBindings() in application.js
|
||||
*
|
||||
* @returns {any[]}
|
||||
*/
|
||||
function _getAppBindings() {
|
||||
var appDoc;
|
||||
|
||||
// The document is only available in browser environment
|
||||
try {
|
||||
appDoc = DOM.defaultDoc();
|
||||
} catch (e) {
|
||||
appDoc = null;
|
||||
}
|
||||
|
||||
return [
|
||||
APPLICATION_COMMON_PROVIDERS,
|
||||
provide(ChangeDetectorGenConfig, {useValue: new ChangeDetectorGenConfig(true, false, false)}),
|
||||
provide(DOCUMENT, {useValue: appDoc}),
|
||||
provide(DomRootRenderer, {useClass: DomRootRenderer_}),
|
||||
provide(RootRenderer, {useExisting: DomRootRenderer}),
|
||||
provide(APP_ID, {useValue: 'a'}),
|
||||
DomSharedStylesHost,
|
||||
provide(SharedStylesHost, {useExisting: DomSharedStylesHost}),
|
||||
provide(AppViewManager, {useClass: AppViewManager_}),
|
||||
Serializer,
|
||||
ELEMENT_PROBE_PROVIDERS,
|
||||
ResolvedMetadataCache,
|
||||
provide(DirectiveResolver, {useClass: MockDirectiveResolver}),
|
||||
provide(ViewResolver, {useClass: MockViewResolver}),
|
||||
provide(IterableDiffers, {useValue: defaultIterableDiffers}),
|
||||
provide(KeyValueDiffers, {useValue: defaultKeyValueDiffers}),
|
||||
Log,
|
||||
provide(DynamicComponentLoader, {useClass: DynamicComponentLoader_}),
|
||||
PipeResolver,
|
||||
provide(ExceptionHandler, {useValue: new ExceptionHandler(DOM)}),
|
||||
provide(LocationStrategy, {useClass: MockLocationStrategy}),
|
||||
provide(XHR, {useClass: DOM.getXHR()}),
|
||||
TestComponentBuilder,
|
||||
provide(NgZone, {useClass: MockNgZone}),
|
||||
provide(AnimationBuilder, {useClass: MockAnimationBuilder}),
|
||||
EventManager,
|
||||
new Provider(EVENT_MANAGER_PLUGINS, {useClass: DomEventsPlugin, multi: true})
|
||||
];
|
||||
}
|
||||
|
||||
function _runtimeCompilerBindings() {
|
||||
return [
|
||||
provide(XHR, {useClass: DOM.getXHR()}),
|
||||
COMPILER_PROVIDERS,
|
||||
];
|
||||
}
|
||||
import {FunctionWrapper, isPresent, Type} from 'angular2/src/facade/lang';
|
||||
|
||||
export class TestInjector {
|
||||
private _instantiated: boolean = false;
|
||||
@ -139,6 +16,10 @@ export class TestInjector {
|
||||
this._instantiated = false;
|
||||
}
|
||||
|
||||
platformProviders: Array<Type | Provider | any[]> = [];
|
||||
|
||||
applicationProviders: Array<Type | Provider | any[]> = [];
|
||||
|
||||
addProviders(providers: Array<Type | Provider | any[]>) {
|
||||
if (this._instantiated) {
|
||||
throw new BaseException('Cannot add providers after test injector is instantiated');
|
||||
@ -147,9 +28,9 @@ export class TestInjector {
|
||||
}
|
||||
|
||||
createInjector() {
|
||||
var rootInjector = Injector.resolveAndCreate(_getRootProviders());
|
||||
this._injector = rootInjector.resolveAndCreateChild(ListWrapper.concat(
|
||||
ListWrapper.concat(_getAppBindings(), _runtimeCompilerBindings()), this._providers));
|
||||
var rootInjector = Injector.resolveAndCreate(this.platformProviders);
|
||||
this._injector = rootInjector.resolveAndCreateChild(
|
||||
ListWrapper.concat(this.applicationProviders, this._providers));
|
||||
this._instantiated = true;
|
||||
return this._injector;
|
||||
}
|
||||
@ -172,19 +53,40 @@ export function getTestInjector() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use TestInjector#createInjector() instead.
|
||||
* Set the providers that the test injector should use. These should be providers
|
||||
* common to every test in the suite.
|
||||
*
|
||||
* This may only be called once, to set up the common providers for the current test
|
||||
* suite on teh current platform. If you absolutely need to change the providers,
|
||||
* first use `resetBaseTestProviders`.
|
||||
*
|
||||
* Test Providers for individual platforms are available from
|
||||
* 'angular2/platform/testing/<platform_name>'.
|
||||
*/
|
||||
export function createTestInjector(providers: Array<Type | Provider | any[]>): Injector {
|
||||
var rootInjector = Injector.resolveAndCreate(_getRootProviders());
|
||||
return rootInjector.resolveAndCreateChild(ListWrapper.concat(_getAppBindings(), providers));
|
||||
export function setBaseTestProviders(platformProviders: Array<Type | Provider | any[]>,
|
||||
applicationProviders: Array<Type | Provider | any[]>) {
|
||||
var testInjector = getTestInjector();
|
||||
if (testInjector.platformProviders.length > 0 || testInjector.applicationProviders.length > 0) {
|
||||
throw new BaseException('Cannot set base providers because it has already been called');
|
||||
}
|
||||
testInjector.platformProviders = platformProviders;
|
||||
testInjector.applicationProviders = applicationProviders;
|
||||
var injector = testInjector.createInjector();
|
||||
let inits: Function[] = injector.getOptional(PLATFORM_INITIALIZER);
|
||||
if (isPresent(inits)) {
|
||||
inits.forEach(init => init());
|
||||
}
|
||||
testInjector.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use TestInjector#createInjector() instead.
|
||||
* Reset the providers for the test injector.
|
||||
*/
|
||||
export function createTestInjectorWithRuntimeCompiler(
|
||||
providers: Array<Type | Provider | any[]>): Injector {
|
||||
return createTestInjector(ListWrapper.concat(_runtimeCompilerBindings(), providers));
|
||||
export function resetBaseTestProviders() {
|
||||
var testInjector = getTestInjector();
|
||||
testInjector.platformProviders = [];
|
||||
testInjector.applicationProviders = [];
|
||||
testInjector.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,77 +126,23 @@ function _isPromiseLike(input): boolean {
|
||||
return input && !!(input.then);
|
||||
}
|
||||
|
||||
function runInTestZone(fnToExecute, finishCallback, failCallback): any {
|
||||
var pendingMicrotasks = 0;
|
||||
var pendingTimeouts = [];
|
||||
|
||||
var ngTestZone = (<Zone>global.zone)
|
||||
.fork({
|
||||
onError: function(e) { failCallback(e); },
|
||||
'$run': function(parentRun) {
|
||||
return function() {
|
||||
try {
|
||||
return parentRun.apply(this, arguments);
|
||||
} finally {
|
||||
if (pendingMicrotasks == 0 && pendingTimeouts.length == 0) {
|
||||
finishCallback();
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
'$scheduleMicrotask': function(parentScheduleMicrotask) {
|
||||
return function(fn) {
|
||||
pendingMicrotasks++;
|
||||
var microtask = function() {
|
||||
try {
|
||||
fn();
|
||||
} finally {
|
||||
pendingMicrotasks--;
|
||||
}
|
||||
};
|
||||
parentScheduleMicrotask.call(this, microtask);
|
||||
};
|
||||
},
|
||||
'$setTimeout': function(parentSetTimeout) {
|
||||
return function(fn: Function, delay: number, ...args) {
|
||||
var id;
|
||||
var cb = function() {
|
||||
fn();
|
||||
ListWrapper.remove(pendingTimeouts, id);
|
||||
};
|
||||
id = parentSetTimeout(cb, delay, args);
|
||||
pendingTimeouts.push(id);
|
||||
return id;
|
||||
};
|
||||
},
|
||||
'$clearTimeout': function(parentClearTimeout) {
|
||||
return function(id: number) {
|
||||
parentClearTimeout(id);
|
||||
ListWrapper.remove(pendingTimeouts, id);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
return ngTestZone.run(fnToExecute);
|
||||
}
|
||||
|
||||
function _it(jsmFn: Function, name: string, testFn: FunctionWithParamTokens | AnyTestFn,
|
||||
testTimeOut: number): void {
|
||||
var timeOut = testTimeOut;
|
||||
|
||||
if (testFn instanceof FunctionWithParamTokens) {
|
||||
jsmFn(name, (done) => {
|
||||
var finishCallback = () => {
|
||||
// Wait one more event loop to make sure we catch unreturned promises and
|
||||
// promise rejections.
|
||||
setTimeout(done, 0);
|
||||
};
|
||||
var returnedTestValue =
|
||||
runInTestZone(() => testInjector.execute(testFn), finishCallback, done.fail);
|
||||
var returnedTestValue;
|
||||
try {
|
||||
returnedTestValue = testInjector.execute(testFn);
|
||||
} catch (err) {
|
||||
done.fail(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (testFn.isAsync) {
|
||||
if (_isPromiseLike(returnedTestValue)) {
|
||||
(<Promise<any>>returnedTestValue).then(null, (err) => { done.fail(err); });
|
||||
(<Promise<any>>returnedTestValue).then(() => { done(); }, (err) => { done.fail(err); });
|
||||
} else {
|
||||
done.fail('Error: injectAsync was expected to return a promise, but the ' +
|
||||
' returned value was: ' + returnedTestValue);
|
||||
@ -206,6 +152,7 @@ function _it(jsmFn: Function, name: string, testFn: FunctionWithParamTokens | An
|
||||
done.fail('Error: inject returned a value. Did you mean to use injectAsync? Returned ' +
|
||||
'value was: ' + returnedTestValue);
|
||||
}
|
||||
done();
|
||||
}
|
||||
}, timeOut);
|
||||
} else {
|
||||
@ -232,17 +179,17 @@ export function beforeEach(fn: FunctionWithParamTokens | AnyTestFn): void {
|
||||
// The test case uses inject(). ie `beforeEach(inject([ClassA], (a) => { ...
|
||||
// }));`
|
||||
jsmBeforeEach((done) => {
|
||||
var finishCallback = () => {
|
||||
// Wait one more event loop to make sure we catch unreturned promises and
|
||||
// promise rejections.
|
||||
setTimeout(done, 0);
|
||||
};
|
||||
|
||||
var returnedTestValue =
|
||||
runInTestZone(() => testInjector.execute(fn), finishCallback, done.fail);
|
||||
var returnedTestValue;
|
||||
try {
|
||||
returnedTestValue = testInjector.execute(fn);
|
||||
} catch (err) {
|
||||
done.fail(err);
|
||||
return;
|
||||
}
|
||||
if (fn.isAsync) {
|
||||
if (_isPromiseLike(returnedTestValue)) {
|
||||
(<Promise<any>>returnedTestValue).then(null, (err) => { done.fail(err); });
|
||||
(<Promise<any>>returnedTestValue).then(() => { done(); }, (err) => { done.fail(err); });
|
||||
} else {
|
||||
done.fail('Error: injectAsync was expected to return a promise, but the ' +
|
||||
' returned value was: ' + returnedTestValue);
|
||||
@ -252,6 +199,7 @@ export function beforeEach(fn: FunctionWithParamTokens | AnyTestFn): void {
|
||||
done.fail('Error: inject returned a value. Did you mean to use injectAsync? Returned ' +
|
||||
'value was: ' + returnedTestValue);
|
||||
}
|
||||
done();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
@ -21,10 +21,13 @@ export class Log {
|
||||
result(): string { return this._result.join("; "); }
|
||||
}
|
||||
|
||||
export var browserDetection: BrowserDetection = null;
|
||||
|
||||
export class BrowserDetection {
|
||||
private _ua: string;
|
||||
|
||||
static setup() { browserDetection = new BrowserDetection(null); }
|
||||
|
||||
constructor(ua: string) {
|
||||
if (isPresent(ua)) {
|
||||
this._ua = ua;
|
||||
@ -61,7 +64,6 @@ export class BrowserDetection {
|
||||
return this._ua.indexOf('Chrome/4') > -1 && this._ua.indexOf('Edge') == -1;
|
||||
}
|
||||
}
|
||||
export var browserDetection: BrowserDetection = new BrowserDetection(null);
|
||||
|
||||
export function dispatchEvent(element, eventType): void {
|
||||
DOM.dispatchEvent(element, DOM.createEvent(eventType));
|
||||
|
@ -9,29 +9,32 @@ import 'package:angular2/src/facade/lang.dart';
|
||||
import 'package:angular2/src/facade/exceptions.dart';
|
||||
|
||||
class GenericMessageBus implements MessageBus {
|
||||
MessageBusSink sink;
|
||||
MessageBusSource source;
|
||||
final MessageBusSink _sink;
|
||||
final MessageBusSource _source;
|
||||
|
||||
MessageBusSink get sink => _sink;
|
||||
MessageBusSource get source => _source;
|
||||
|
||||
GenericMessageBus(MessageBusSink sink, MessageBusSource source)
|
||||
: sink = sink,
|
||||
source = source;
|
||||
: _sink = sink,
|
||||
_source = source;
|
||||
|
||||
void attachToZone(NgZone zone) {
|
||||
sink.attachToZone(zone);
|
||||
source.attachToZone(zone);
|
||||
_sink.attachToZone(zone);
|
||||
_source.attachToZone(zone);
|
||||
}
|
||||
|
||||
void initChannel(String channel, [bool runInZone = true]) {
|
||||
sink.initChannel(channel, runInZone);
|
||||
source.initChannel(channel, runInZone);
|
||||
_sink.initChannel(channel, runInZone);
|
||||
_source.initChannel(channel, runInZone);
|
||||
}
|
||||
|
||||
EventEmitter from(String channel) {
|
||||
return source.from(channel);
|
||||
return _source.from(channel);
|
||||
}
|
||||
|
||||
EventEmitter to(String channel) {
|
||||
return sink.to(channel);
|
||||
return _sink.to(channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,12 +66,12 @@ export class MessageBasedRenderer {
|
||||
bind(this._invokeElementMethod, this));
|
||||
broker.registerMethod("setText", [RenderStoreObject, RenderStoreObject, PRIMITIVE],
|
||||
bind(this._setText, this));
|
||||
broker.registerMethod("listen", [RenderStoreObject, RenderStoreObject, PRIMITIVE],
|
||||
broker.registerMethod("listen", [RenderStoreObject, RenderStoreObject, PRIMITIVE, PRIMITIVE],
|
||||
bind(this._listen, this));
|
||||
broker.registerMethod("listenGlobal", [RenderStoreObject, PRIMITIVE, PRIMITIVE, PRIMITIVE],
|
||||
bind(this._listenGlobal, this));
|
||||
broker.registerMethod("listenGlobalDone", [RenderStoreObject, RenderStoreObject],
|
||||
bind(this._listenGlobalDone, this));
|
||||
broker.registerMethod("listenDone", [RenderStoreObject, RenderStoreObject],
|
||||
bind(this._listenDone, this));
|
||||
}
|
||||
|
||||
private _renderComponent(renderComponentType: RenderComponentType, rendererId: number) {
|
||||
@ -155,9 +155,11 @@ export class MessageBasedRenderer {
|
||||
renderer.setText(renderNode, text);
|
||||
}
|
||||
|
||||
private _listen(renderer: Renderer, renderElement: any, eventName: string) {
|
||||
renderer.listen(renderElement, eventName, (event) => this._eventDispatcher.dispatchRenderEvent(
|
||||
private _listen(renderer: Renderer, renderElement: any, eventName: string, unlistenId: number) {
|
||||
var unregisterCallback = renderer.listen(renderElement, eventName,
|
||||
(event) => this._eventDispatcher.dispatchRenderEvent(
|
||||
renderElement, null, eventName, event));
|
||||
this._renderStore.store(unregisterCallback, unlistenId);
|
||||
}
|
||||
|
||||
private _listenGlobal(renderer: Renderer, eventTarget: string, eventName: string,
|
||||
@ -168,5 +170,5 @@ export class MessageBasedRenderer {
|
||||
this._renderStore.store(unregisterCallback, unlistenId);
|
||||
}
|
||||
|
||||
private _listenGlobalDone(renderer: Renderer, unlistenCallback: Function) { unlistenCallback(); }
|
||||
private _listenDone(renderer: Renderer, unlistenCallback: Function) { unlistenCallback(); }
|
||||
}
|
||||
|
@ -215,10 +215,18 @@ export class WebWorkerRenderer implements Renderer, RenderStoreObject {
|
||||
[new FnArg(renderNode, RenderStoreObject), new FnArg(text, null)]);
|
||||
}
|
||||
|
||||
listen(renderElement: WebWorkerRenderNode, name: string, callback: Function) {
|
||||
listen(renderElement: WebWorkerRenderNode, name: string, callback: Function): Function {
|
||||
renderElement.events.listen(name, callback);
|
||||
this._runOnService('listen',
|
||||
[new FnArg(renderElement, RenderStoreObject), new FnArg(name, null)]);
|
||||
var unlistenCallbackId = this._rootRenderer.allocateId();
|
||||
this._runOnService('listen', [
|
||||
new FnArg(renderElement, RenderStoreObject),
|
||||
new FnArg(name, null),
|
||||
new FnArg(unlistenCallbackId, null)
|
||||
]);
|
||||
return () => {
|
||||
renderElement.events.unlisten(name, callback);
|
||||
this._runOnService('listenDone', [new FnArg(unlistenCallbackId, null)]);
|
||||
};
|
||||
}
|
||||
|
||||
listenGlobal(target: string, name: string, callback: Function): Function {
|
||||
@ -229,7 +237,7 @@ export class WebWorkerRenderer implements Renderer, RenderStoreObject {
|
||||
[new FnArg(target, null), new FnArg(name, null), new FnArg(unlistenCallbackId, null)]);
|
||||
return () => {
|
||||
this._rootRenderer.globalEvents.unlisten(eventNameWithTarget(target, name), callback);
|
||||
this._runOnService('listenGlobalDone', [new FnArg(unlistenCallbackId, null)]);
|
||||
this._runOnService('listenDone', [new FnArg(unlistenCallbackId, null)]);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,7 @@ import 'package:angular2/core.dart' show ChangeDetectorRef;
|
||||
import 'package:angular2/common.dart' show ObservableListDiffFactory;
|
||||
|
||||
@proxy
|
||||
class SpyChangeDetectorRef extends SpyObject implements ChangeDetectorRef {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyChangeDetectorRef extends SpyObject implements ChangeDetectorRef {}
|
||||
|
||||
main() {
|
||||
describe('ObservableListDiff', () {
|
||||
|
@ -5,16 +5,10 @@ import 'package:angular2/src/core/change_detection/change_detection.dart';
|
||||
import 'package:angular2/testing_internal.dart';
|
||||
|
||||
@proxy
|
||||
class SpyNgControl extends SpyObject implements NgControl {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyNgControl extends SpyObject implements NgControl {}
|
||||
|
||||
@proxy
|
||||
class SpyValueAccessor extends SpyObject implements ControlValueAccessor {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyValueAccessor extends SpyObject implements ControlValueAccessor {}
|
||||
|
||||
@proxy
|
||||
class SpyChangeDetectorRef extends SpyObject implements ChangeDetectorRef {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyChangeDetectorRef extends SpyObject implements ChangeDetectorRef {}
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
} from 'angular2/testing_internal';
|
||||
import {provide} from 'angular2/src/core/di';
|
||||
|
||||
import {CONST_EXPR, stringify} from 'angular2/src/facade/lang';
|
||||
import {CONST_EXPR, stringify, IS_DART} from 'angular2/src/facade/lang';
|
||||
import {MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {Promise} from 'angular2/src/facade/async';
|
||||
|
||||
@ -55,6 +55,11 @@ var THIS_MODULE_URL = `package:${THIS_MODULE_ID}${MODULE_SUFFIX}`;
|
||||
var THIS_MODULE_REF = moduleRef(THIS_MODULE_URL);
|
||||
|
||||
export function main() {
|
||||
// Dart's isolate support is broken, and these tests will be obsolote soon with
|
||||
// https://github.com/angular/angular/issues/6270
|
||||
if (IS_DART) {
|
||||
return;
|
||||
}
|
||||
describe('ChangeDetectorCompiler', () => {
|
||||
beforeEachProviders(() => [
|
||||
TEST_PROVIDERS,
|
||||
|
@ -22,6 +22,11 @@ export var TEST_VALUE = 23;
|
||||
const THIS_MODULE_URL = `package:angular2/test/compiler/eval_module_spec${IS_DART?'.dart':'.js'}`;
|
||||
|
||||
export function main() {
|
||||
// Dart's isolate support is broken, and these tests will be obsolote soon with
|
||||
// https://github.com/angular/angular/issues/6270
|
||||
if (IS_DART) {
|
||||
return;
|
||||
}
|
||||
describe('evalModule', () => {
|
||||
it('should call the "run" function and allow to use imports',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
|
@ -114,9 +114,9 @@ export function main() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('cdata', () => {
|
||||
it('should parse cdata', () => {
|
||||
expect(tokenizeAndHumanizeParts('<![cdata[t\ne\rs\r\nt]]>'))
|
||||
describe('CDATA', () => {
|
||||
it('should parse CDATA', () => {
|
||||
expect(tokenizeAndHumanizeParts('<![CDATA[t\ne\rs\r\nt]]>'))
|
||||
.toEqual([
|
||||
[HtmlTokenType.CDATA_START],
|
||||
[HtmlTokenType.RAW_TEXT, 't\ne\ns\nt'],
|
||||
@ -126,22 +126,22 @@ export function main() {
|
||||
});
|
||||
|
||||
it('should store the locations', () => {
|
||||
expect(tokenizeAndHumanizeSourceSpans('<![cdata[t\ne\rs\r\nt]]>'))
|
||||
expect(tokenizeAndHumanizeSourceSpans('<![CDATA[t\ne\rs\r\nt]]>'))
|
||||
.toEqual([
|
||||
[HtmlTokenType.CDATA_START, '<![cdata['],
|
||||
[HtmlTokenType.CDATA_START, '<![CDATA['],
|
||||
[HtmlTokenType.RAW_TEXT, 't\ne\rs\r\nt'],
|
||||
[HtmlTokenType.CDATA_END, ']]>'],
|
||||
[HtmlTokenType.EOF, '']
|
||||
]);
|
||||
});
|
||||
|
||||
it('should report <![ without cdata[', () => {
|
||||
it('should report <![ without CDATA[', () => {
|
||||
expect(tokenizeAndHumanizeErrors('<![a'))
|
||||
.toEqual([[HtmlTokenType.CDATA_START, 'Unexpected character "a"', '0:3']]);
|
||||
});
|
||||
|
||||
it('should report missing end cdata', () => {
|
||||
expect(tokenizeAndHumanizeErrors('<![cdata['))
|
||||
expect(tokenizeAndHumanizeErrors('<![CDATA['))
|
||||
.toEqual([[HtmlTokenType.RAW_TEXT, 'Unexpected character "EOF"', '0:9']]);
|
||||
});
|
||||
});
|
||||
@ -367,8 +367,8 @@ export function main() {
|
||||
});
|
||||
|
||||
it('should parse hexadecimal entities', () => {
|
||||
expect(tokenizeAndHumanizeParts('A'))
|
||||
.toEqual([[HtmlTokenType.TEXT, 'A'], [HtmlTokenType.EOF]]);
|
||||
expect(tokenizeAndHumanizeParts('AA'))
|
||||
.toEqual([[HtmlTokenType.TEXT, 'AA'], [HtmlTokenType.EOF]]);
|
||||
});
|
||||
|
||||
it('should parse decimal entities', () => {
|
||||
@ -473,7 +473,7 @@ export function main() {
|
||||
});
|
||||
|
||||
it('should not detect entities', () => {
|
||||
expect(tokenizeAndHumanizeParts(`<script>&</script>`))
|
||||
expect(tokenizeAndHumanizeParts(`<script>&</SCRIPT>`))
|
||||
.toEqual([
|
||||
[HtmlTokenType.TAG_OPEN_START, null, 'script'],
|
||||
[HtmlTokenType.TAG_OPEN_END],
|
||||
@ -587,6 +587,19 @@ export function main() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('unicode characters', () => {
|
||||
it('should support unicode characters', () => {
|
||||
expect(tokenizeAndHumanizeSourceSpans(`<p>İ</p>`))
|
||||
.toEqual([
|
||||
[HtmlTokenType.TAG_OPEN_START, '<p'],
|
||||
[HtmlTokenType.TAG_OPEN_END, '>'],
|
||||
[HtmlTokenType.TEXT, 'İ'],
|
||||
[HtmlTokenType.TAG_CLOSE, '</p>'],
|
||||
[HtmlTokenType.EOF, '']
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -83,19 +83,19 @@ export function main() {
|
||||
it('should return the directive metadatas',
|
||||
inject([RuntimeMetadataResolver], (resolver: RuntimeMetadataResolver) => {
|
||||
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
||||
.toEqual([resolver.getDirectiveMetadata(SomeDirective)]);
|
||||
.toContain(resolver.getDirectiveMetadata(SomeDirective));
|
||||
}));
|
||||
|
||||
describe("platform directives", () => {
|
||||
beforeEachProviders(() => [provide(PLATFORM_DIRECTIVES, {useValue: [ADirective]})]);
|
||||
beforeEachProviders(
|
||||
() => [provide(PLATFORM_DIRECTIVES, {useValue: [ADirective], multi: true})]);
|
||||
|
||||
it('should include platform directives when available',
|
||||
inject([RuntimeMetadataResolver], (resolver: RuntimeMetadataResolver) => {
|
||||
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
||||
.toEqual([
|
||||
resolver.getDirectiveMetadata(ADirective),
|
||||
resolver.getDirectiveMetadata(SomeDirective)
|
||||
]);
|
||||
.toContain(resolver.getDirectiveMetadata(ADirective));
|
||||
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
||||
.toContain(resolver.getDirectiveMetadata(SomeDirective));
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
@ -5,11 +5,7 @@ import 'package:angular2/testing_internal.dart';
|
||||
import 'package:angular2/src/compiler/template_compiler.dart';
|
||||
|
||||
@proxy
|
||||
class SpyXHR extends SpyObject implements XHR {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyXHR extends SpyObject implements XHR {}
|
||||
|
||||
@proxy
|
||||
class SpyTemplateCompiler extends SpyObject implements TemplateCompiler {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyTemplateCompiler extends SpyObject implements TemplateCompiler {}
|
||||
|
@ -17,7 +17,14 @@ import {SpyXHR} from './spies';
|
||||
import {XHR} from 'angular2/src/compiler/xhr';
|
||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||
|
||||
import {CONST_EXPR, isPresent, isBlank, StringWrapper, isArray} from 'angular2/src/facade/lang';
|
||||
import {
|
||||
CONST_EXPR,
|
||||
isPresent,
|
||||
isBlank,
|
||||
StringWrapper,
|
||||
isArray,
|
||||
IS_DART
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
|
||||
import {evalModule} from './eval_module';
|
||||
import {StyleCompiler} from 'angular2/src/compiler/style_compiler';
|
||||
@ -40,6 +47,11 @@ var IMPORT_ABS_STYLESHEET_URL_WITH_IMPORT =
|
||||
`package:angular2/test/compiler/style_compiler_transitive_import.css`;
|
||||
|
||||
export function main() {
|
||||
// Dart's isolate support is broken, and these tests will be obsolote soon with
|
||||
// https://github.com/angular/angular/issues/6270
|
||||
if (IS_DART) {
|
||||
return;
|
||||
}
|
||||
describe('StyleCompiler', () => {
|
||||
var xhr: SpyXHR;
|
||||
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
} from 'angular2/testing_internal';
|
||||
|
||||
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {Type, isPresent, isBlank, stringify, isString} from 'angular2/src/facade/lang';
|
||||
import {Type, isPresent, isBlank, stringify, isString, IS_DART} from 'angular2/src/facade/lang';
|
||||
import {
|
||||
MapWrapper,
|
||||
SetWrapper,
|
||||
@ -58,6 +58,11 @@ var REFLECTION_CAPS_MODULE_REF =
|
||||
moduleRef(`package:angular2/src/core/reflection/reflection_capabilities${MODULE_SUFFIX}`);
|
||||
|
||||
export function main() {
|
||||
// Dart's isolate support is broken, and these tests will be obsolote soon with
|
||||
// https://github.com/angular/angular/issues/6270
|
||||
if (IS_DART) {
|
||||
return;
|
||||
}
|
||||
describe('TemplateCompiler', () => {
|
||||
var compiler: TemplateCompiler;
|
||||
var runtimeMetadataResolver: RuntimeMetadataResolver;
|
||||
@ -105,6 +110,22 @@ export function main() {
|
||||
});
|
||||
}));
|
||||
|
||||
it('should compile components at various nesting levels',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
compile([CompWith2NestedComps, Comp1, Comp2])
|
||||
.then((humanizedView) => {
|
||||
expect(humanizedView['elements']).toEqual(['<comp-with-2nested>']);
|
||||
expect(humanizedView['componentViews'][0]['elements'])
|
||||
.toEqual(['<comp1>', '<comp2>']);
|
||||
expect(humanizedView['componentViews'][0]['componentViews'][0]['elements'])
|
||||
.toEqual(['<a>', '<comp2>']);
|
||||
expect(humanizedView['componentViews'][0]['componentViews'][1]['elements'])
|
||||
.toEqual(['<b>']);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should compile recursive components', inject([AsyncTestCompleter], (async) => {
|
||||
compile([TreeComp])
|
||||
.then((humanizedView) => {
|
||||
@ -365,6 +386,29 @@ export class NonComponent {
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'comp2', moduleId: THIS_MODULE_ID})
|
||||
@View({template: '<b></b>', encapsulation: ViewEncapsulation.None})
|
||||
export class Comp2 {
|
||||
}
|
||||
|
||||
@Component({selector: 'comp1', moduleId: THIS_MODULE_ID})
|
||||
@View({
|
||||
template: '<a></a>, <comp2></comp2>',
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
directives: [Comp2]
|
||||
})
|
||||
export class Comp1 {
|
||||
}
|
||||
|
||||
@Component({selector: 'comp-with-2nested', moduleId: THIS_MODULE_ID})
|
||||
@View({
|
||||
template: '<comp1></comp1>, <comp2></comp2>',
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
directives: [Comp1, Comp2]
|
||||
})
|
||||
export class CompWith2NestedComps {
|
||||
}
|
||||
|
||||
function testableTemplateModule(sourceModule: SourceModule,
|
||||
normComp: CompileDirectiveMetadata): SourceModule {
|
||||
var testableSource = `
|
||||
|
@ -11,13 +11,14 @@ import {
|
||||
AsyncTestCompleter,
|
||||
fakeAsync,
|
||||
tick,
|
||||
inject
|
||||
inject,
|
||||
SpyObject
|
||||
} from 'angular2/testing_internal';
|
||||
import {SpyChangeDetector} from './spies';
|
||||
import {ApplicationRef_, PlatformRef_} from "angular2/src/core/application_ref";
|
||||
import {Injector, Provider} from "angular2/core";
|
||||
import {ApplicationRef_, ApplicationRef, PlatformRef_} from "angular2/src/core/application_ref";
|
||||
import {Injector, Provider, APP_INITIALIZER} from "angular2/core";
|
||||
import {ChangeDetectorRef_} from "angular2/src/core/change_detection/change_detector_ref";
|
||||
import {PromiseWrapper} from "angular2/src/facade/async";
|
||||
import {PromiseWrapper, PromiseCompleter, TimerWrapper} from "angular2/src/facade/async";
|
||||
import {ListWrapper} from "angular2/src/facade/collection";
|
||||
|
||||
export function main() {
|
||||
@ -33,7 +34,14 @@ export function main() {
|
||||
|
||||
describe("PlatformRef", () => {
|
||||
describe("asyncApplication", () => {
|
||||
it("should merge synchronous and asynchronous providers",
|
||||
function expectProviders(injector: Injector, providers: Array<any>): void {
|
||||
for (let i = 0; i < providers.length; i++) {
|
||||
let provider = providers[i];
|
||||
expect(injector.get(provider.token)).toBe(provider.useValue);
|
||||
}
|
||||
}
|
||||
|
||||
it("should merge syncronous and asyncronous providers",
|
||||
inject([AsyncTestCompleter, Injector], (async, injector) => {
|
||||
let ref = new PlatformRef_(injector, null);
|
||||
let ASYNC_PROVIDERS = [new Provider(Foo, {useValue: new Foo()})];
|
||||
@ -41,13 +49,98 @@ export function main() {
|
||||
ref.asyncApplication((zone) => PromiseWrapper.resolve(ASYNC_PROVIDERS), SYNC_PROVIDERS)
|
||||
.then((appRef) => {
|
||||
var providers = ListWrapper.concat(ASYNC_PROVIDERS, SYNC_PROVIDERS);
|
||||
for (var i = 0; i < providers.length; i++) {
|
||||
var provider = providers[i];
|
||||
expect(appRef.injector.get(provider.token)).toBe(provider.useValue);
|
||||
}
|
||||
expectProviders(appRef.injector, providers);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it("should allow function to be null",
|
||||
inject([AsyncTestCompleter, Injector], (async, injector) => {
|
||||
let ref = new PlatformRef_(injector, null);
|
||||
let SYNC_PROVIDERS = [new Provider(Bar, {useValue: new Bar()})];
|
||||
ref.asyncApplication(null, SYNC_PROVIDERS)
|
||||
.then((appRef) => {
|
||||
expectProviders(appRef.injector, SYNC_PROVIDERS);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
function mockAsyncAppInitializer(completer, providers: Array<any> = null,
|
||||
injector?: Injector) {
|
||||
return () => {
|
||||
if (providers != null) {
|
||||
expectProviders(injector, providers);
|
||||
}
|
||||
TimerWrapper.setTimeout(() => completer.resolve(true), 1);
|
||||
return completer.promise;
|
||||
};
|
||||
}
|
||||
|
||||
function createSpyPromiseCompleter(): SpyObject {
|
||||
let completer = PromiseWrapper.completer();
|
||||
let completerSpy = <any>new SpyObject();
|
||||
// Note that in TypeScript we need to provide a value for the promise attribute
|
||||
// whereas in dart we need to override the promise getter
|
||||
completerSpy.promise = completer.promise;
|
||||
completerSpy.spy("get:promise").andReturn(completer.promise);
|
||||
completerSpy.spy("resolve").andCallFake(completer.resolve);
|
||||
completerSpy.spy("reject").andCallFake(completer.reject);
|
||||
return completerSpy;
|
||||
}
|
||||
|
||||
it("should wait for asyncronous app initializers",
|
||||
inject([AsyncTestCompleter, Injector], (async, injector) => {
|
||||
let ref = new PlatformRef_(injector, null);
|
||||
|
||||
let completer = createSpyPromiseCompleter();
|
||||
let SYNC_PROVIDERS = [
|
||||
new Provider(Bar, {useValue: new Bar()}),
|
||||
new Provider(APP_INITIALIZER,
|
||||
{useValue: mockAsyncAppInitializer(completer), multi: true})
|
||||
];
|
||||
ref.asyncApplication(null, SYNC_PROVIDERS)
|
||||
.then((appRef) => {
|
||||
expectProviders(appRef.injector,
|
||||
SYNC_PROVIDERS.slice(0, SYNC_PROVIDERS.length - 1));
|
||||
expect(completer.spy("resolve")).toHaveBeenCalled();
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it("should wait for async providers and then async app initializers",
|
||||
inject([AsyncTestCompleter, Injector], (async, injector) => {
|
||||
let ref = new PlatformRef_(injector, null);
|
||||
let ASYNC_PROVIDERS = [new Provider(Foo, {useValue: new Foo()})];
|
||||
let completer = createSpyPromiseCompleter();
|
||||
let SYNC_PROVIDERS = [
|
||||
new Provider(Bar, {useValue: new Bar()}),
|
||||
new Provider(APP_INITIALIZER,
|
||||
{
|
||||
useFactory: (injector) => mockAsyncAppInitializer(
|
||||
completer, ASYNC_PROVIDERS, injector),
|
||||
multi: true,
|
||||
deps: [Injector]
|
||||
})
|
||||
];
|
||||
ref.asyncApplication((zone) => PromiseWrapper.resolve(ASYNC_PROVIDERS), SYNC_PROVIDERS)
|
||||
.then((appRef) => {
|
||||
expectProviders(appRef.injector,
|
||||
SYNC_PROVIDERS.slice(0, SYNC_PROVIDERS.length - 1));
|
||||
expect(completer.spy("resolve")).toHaveBeenCalled();
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe("application", () => {
|
||||
it("should throw if an APP_INITIIALIZER returns a promise", inject([Injector], (injector) => {
|
||||
let ref = new PlatformRef_(injector, null);
|
||||
let appInitializer = new Provider(
|
||||
APP_INITIALIZER, {useValue: () => PromiseWrapper.resolve([]), multi: true});
|
||||
expect(() => ref.application([appInitializer]))
|
||||
.toThrowError(
|
||||
"Cannot use asyncronous app initializers with application. Use asyncApplication instead.");
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -438,6 +438,7 @@ var _availableEventDefinitions = [
|
||||
'(event)="a[0]=\$event"',
|
||||
// '(event)="\$event=1"',
|
||||
'(event)="a=a+1; a=a+1;"',
|
||||
'(event)="true; false"',
|
||||
'(event)="false"',
|
||||
'(event)="true"',
|
||||
'(event)="true ? a = a + 1 : a = a + 1"',
|
||||
|
@ -1267,7 +1267,7 @@ export function main() {
|
||||
|
||||
val.changeDetector.dehydrate();
|
||||
expect(() => {val.changeDetector.detectChanges()})
|
||||
.toThrowErrorWith("Attempt to detect changes on a dehydrated detector");
|
||||
.toThrowErrorWith("Attempt to use a dehydrated detector");
|
||||
expect(val.dispatcher.log).toEqual(['propName=Bob']);
|
||||
});
|
||||
});
|
||||
@ -1358,6 +1358,10 @@ export function main() {
|
||||
val = _createChangeDetector('(event)="true"', d, null);
|
||||
res = val.changeDetector.handleEvent("event", 0, event);
|
||||
expect(res).toBe(true);
|
||||
|
||||
val = _createChangeDetector('(event)="true; false"', d, null);
|
||||
res = val.changeDetector.handleEvent("event", 0, event);
|
||||
expect(res).toBe(false);
|
||||
});
|
||||
|
||||
it('should support short-circuiting', () => {
|
||||
|
@ -39,6 +39,12 @@ class SomeDirectiveWithOutputs {
|
||||
c;
|
||||
}
|
||||
|
||||
|
||||
@Directive({selector: 'someDirective', outputs: ['a']})
|
||||
class SomeDirectiveWithDuplicateOutputs {
|
||||
@Output() a;
|
||||
}
|
||||
|
||||
@Directive({selector: 'someDirective', properties: ['a']})
|
||||
class SomeDirectiveWithProperties {
|
||||
}
|
||||
@ -153,6 +159,12 @@ export function main() {
|
||||
var directiveMetadata = resolver.resolve(SomeDirectiveWithGetterOutputs);
|
||||
expect(directiveMetadata.outputs).toEqual(['a: renamed']);
|
||||
});
|
||||
|
||||
it('should throw if duplicate outputs', () => {
|
||||
expect(() => { resolver.resolve(SomeDirectiveWithDuplicateOutputs); })
|
||||
.toThrowError(
|
||||
`Output event 'a' defined multiple times in 'SomeDirectiveWithDuplicateOutputs'`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('host', () => {
|
||||
|
@ -877,13 +877,22 @@ function declareTests() {
|
||||
var listener = tc.inject(DirectiveListeningEvent);
|
||||
|
||||
expect(listener.msg).toEqual('');
|
||||
var eventCount = 0;
|
||||
|
||||
ObservableWrapper.subscribe(emitter.event, (_) => {
|
||||
eventCount++;
|
||||
if (eventCount === 1) {
|
||||
expect(listener.msg).toEqual('fired !');
|
||||
fixture.destroy();
|
||||
emitter.fireEvent('fired again !');
|
||||
} else {
|
||||
expect(listener.msg).toEqual('fired !');
|
||||
async.done();
|
||||
}
|
||||
});
|
||||
|
||||
emitter.fireEvent('fired !');
|
||||
|
||||
});
|
||||
}));
|
||||
|
||||
@ -961,6 +970,11 @@ function declareTests() {
|
||||
.toEqual(
|
||||
['domEvent', 'body_domEvent', 'document_domEvent', 'window_domEvent']);
|
||||
|
||||
fixture.destroy();
|
||||
listener.eventTypes = [];
|
||||
dispatchEvent(tc.nativeElement, 'domEvent');
|
||||
expect(listener.eventTypes).toEqual([]);
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
@ -13,77 +13,47 @@ import 'package:angular2/src/platform/dom/dom_adapter.dart';
|
||||
import 'package:angular2/testing_internal.dart';
|
||||
|
||||
@proxy
|
||||
class SpyDependencyProvider extends SpyObject implements DependencyProvider {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyDependencyProvider extends SpyObject implements DependencyProvider {}
|
||||
|
||||
@proxy
|
||||
class SpyChangeDetector extends SpyObject implements ChangeDetector {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyChangeDetector extends SpyObject implements ChangeDetector {}
|
||||
|
||||
@proxy
|
||||
class SpyChangeDispatcher extends SpyObject implements ChangeDispatcher {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyChangeDispatcher extends SpyObject implements ChangeDispatcher {}
|
||||
|
||||
@proxy
|
||||
class SpyIterableDifferFactory extends SpyObject
|
||||
implements IterableDifferFactory {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
implements IterableDifferFactory {}
|
||||
|
||||
@proxy
|
||||
class SpyInjector extends SpyObject implements Injector {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyInjector extends SpyObject implements Injector {}
|
||||
|
||||
@proxy
|
||||
class SpyDirectiveResolver extends SpyObject implements DirectiveResolver {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyDirectiveResolver extends SpyObject implements DirectiveResolver {}
|
||||
|
||||
@proxy
|
||||
class SpyView extends SpyObject implements AppView {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyView extends SpyObject implements AppView {}
|
||||
|
||||
@proxy
|
||||
class SpyProtoView extends SpyObject implements AppProtoView {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyProtoView extends SpyObject implements AppProtoView {}
|
||||
|
||||
@proxy
|
||||
class SpyHostViewFactory extends SpyObject implements HostViewFactory {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyHostViewFactory extends SpyObject implements HostViewFactory {}
|
||||
|
||||
@proxy
|
||||
class SpyElementRef extends SpyObject implements ElementRef {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyElementRef extends SpyObject implements ElementRef {}
|
||||
|
||||
@proxy
|
||||
class SpyAppViewManager extends SpyObject implements AppViewManager_ {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyAppViewManager extends SpyObject implements AppViewManager_ {}
|
||||
|
||||
@proxy
|
||||
class SpyRenderer extends SpyObject implements Renderer {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyRenderer extends SpyObject implements Renderer {}
|
||||
|
||||
@proxy
|
||||
class SpyRootRenderer extends SpyObject implements RootRenderer {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyRootRenderer extends SpyObject implements RootRenderer {}
|
||||
|
||||
@proxy
|
||||
class SpyAppViewListener extends SpyObject implements AppViewListener {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyAppViewListener extends SpyObject implements AppViewListener {}
|
||||
|
||||
@proxy
|
||||
class SpyDomAdapter extends SpyObject implements DomAdapter {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyDomAdapter extends SpyObject implements DomAdapter {}
|
||||
|
@ -43,12 +43,13 @@ class MockNgZone extends NgZone {
|
||||
|
||||
export function main() {
|
||||
describe('Testability', () => {
|
||||
var testability, execute, ngZone;
|
||||
var testability, execute, execute2, ngZone;
|
||||
|
||||
beforeEach(() => {
|
||||
ngZone = new MockNgZone();
|
||||
testability = new Testability(ngZone);
|
||||
execute = new SpyObject().spy('execute');
|
||||
execute2 = new SpyObject().spy('execute');
|
||||
});
|
||||
|
||||
describe('Pending count logic', () => {
|
||||
@ -109,6 +110,35 @@ export function main() {
|
||||
|
||||
expect(execute).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should fire whenstable callbacks with didWork if pending count is 0',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
testability.whenStable(execute);
|
||||
microTask(() => {
|
||||
expect(execute).toHaveBeenCalledWith(false);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should fire whenstable callbacks with didWork when pending drops to 0',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
testability.increasePendingRequestCount();
|
||||
testability.whenStable(execute);
|
||||
|
||||
microTask(() => {
|
||||
testability.decreasePendingRequestCount();
|
||||
|
||||
microTask(() => {
|
||||
expect(execute).toHaveBeenCalledWith(true);
|
||||
testability.whenStable(execute2);
|
||||
|
||||
microTask(() => {
|
||||
expect(execute2).toHaveBeenCalledWith(false);
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('NgZone callback logic', () => {
|
||||
@ -208,6 +238,43 @@ export function main() {
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should fire whenstable callback with didWork if event is already finished',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
ngZone.start();
|
||||
ngZone.finish();
|
||||
testability.whenStable(execute);
|
||||
|
||||
microTask(() => {
|
||||
expect(execute).toHaveBeenCalledWith(true);
|
||||
testability.whenStable(execute2);
|
||||
|
||||
microTask(() => {
|
||||
expect(execute2).toHaveBeenCalledWith(false);
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should fire whenstable callback with didwork when event finishes',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
ngZone.start();
|
||||
testability.whenStable(execute);
|
||||
|
||||
microTask(() => {
|
||||
ngZone.finish();
|
||||
|
||||
microTask(() => {
|
||||
expect(execute).toHaveBeenCalledWith(true);
|
||||
testability.whenStable(execute2);
|
||||
|
||||
microTask(() => {
|
||||
expect(execute2).toHaveBeenCalledWith(false);
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import 'dart:js';
|
||||
@proxy
|
||||
class SpyApplicationRef extends SpyObject implements ApplicationRef {
|
||||
tick() {}
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
|
||||
@proxy
|
||||
@ -16,11 +15,9 @@ class SpyComponentRef extends SpyObject implements ComponentRef_ {
|
||||
Injector injector;
|
||||
|
||||
SpyComponentRef() {
|
||||
this.injector =
|
||||
Injector.resolveAndCreate([bind(ApplicationRef).toClass(SpyApplicationRef)]);
|
||||
this.injector = Injector
|
||||
.resolveAndCreate([bind(ApplicationRef).toClass(SpyApplicationRef)]);
|
||||
}
|
||||
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
|
||||
void callNgProfilerTimeChangeDetection([config]) {
|
||||
|
@ -1224,7 +1224,6 @@ var NG_CORE = [
|
||||
'SimpleChange.isFirstChange()',
|
||||
'TemplateRef',
|
||||
'TemplateRef.elementRef',
|
||||
'TemplateRef.elementRef=',
|
||||
/*
|
||||
Abstract method
|
||||
'TemplateRef.hasLocal()',
|
||||
|
@ -4,21 +4,14 @@ import 'package:angular2/router.dart';
|
||||
import 'package:angular2/testing_internal.dart';
|
||||
|
||||
@proxy
|
||||
class SpyLocation extends SpyObject implements Location {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyLocation extends SpyObject implements Location {}
|
||||
|
||||
@proxy
|
||||
class SpyRouter extends SpyObject implements Router {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyRouter extends SpyObject implements Router {}
|
||||
|
||||
@proxy
|
||||
class SpyRouterOutlet extends SpyObject implements RouterOutlet {
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
class SpyRouterOutlet extends SpyObject implements RouterOutlet {}
|
||||
|
||||
class SpyPlatformLocation extends SpyObject implements PlatformLocation {
|
||||
String pathname;
|
||||
noSuchMethod(m) => super.noSuchMethod(m);
|
||||
}
|
||||
|
1
modules/angular2/test/testing/static_assets/test.html
Normal file
1
modules/angular2/test/testing/static_assets/test.html
Normal file
@ -0,0 +1 @@
|
||||
<span>from external template</span>
|
@ -24,7 +24,6 @@ class TestObj {
|
||||
|
||||
class SpyTestObj extends SpyObject {
|
||||
constructor() { super(TestObj); }
|
||||
noSuchMethod(m) { return super.noSuchMethod(m) }
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,6 +94,15 @@ class TestViewProvidersComp {
|
||||
constructor(private fancyService: FancyService) {}
|
||||
}
|
||||
|
||||
@Component({selector: 'external-template-comp'})
|
||||
@View({templateUrl: '/base/modules/angular2/test/testing/static_assets/test.html'})
|
||||
class ExternalTemplateComp {
|
||||
}
|
||||
|
||||
@Component({selector: 'bad-template-comp'})
|
||||
@View({templateUrl: 'non-existant.html'})
|
||||
class BadTemplateUrl {
|
||||
}
|
||||
|
||||
export function main() {
|
||||
describe('angular2 jasmine matchers', () => {
|
||||
@ -273,11 +282,12 @@ export function main() {
|
||||
restoreJasmineIt();
|
||||
});
|
||||
|
||||
it('should fail when an asynchronous error is thrown', (done) => {
|
||||
// TODO(juliemr): reenable this test when we are using a test zone and can capture this error.
|
||||
xit('should fail when an asynchronous error is thrown', (done) => {
|
||||
var itPromise = patchJasmineIt();
|
||||
|
||||
it('throws an async error',
|
||||
inject([], () => { setTimeout(() => { throw new Error('bar'); }, 0); }));
|
||||
injectAsync([], () => { setTimeout(() => { throw new Error('bar'); }, 0); }));
|
||||
|
||||
itPromise.then(() => { done.fail('Expected test to fail, but it did not'); }, (err) => {
|
||||
expect(err.message).toEqual('bar');
|
||||
@ -304,6 +314,19 @@ export function main() {
|
||||
restoreJasmineIt();
|
||||
});
|
||||
|
||||
it('should fail when an XHR fails', (done) => {
|
||||
var itPromise = patchJasmineIt();
|
||||
|
||||
it('should fail with an error from a promise',
|
||||
injectAsync([TestComponentBuilder], (tcb) => { return tcb.createAsync(BadTemplateUrl); }));
|
||||
|
||||
itPromise.then(() => { done.fail('Expected test to fail, but it did not'); }, (err) => {
|
||||
expect(err).toEqual('Failed to load non-existant.html');
|
||||
done();
|
||||
});
|
||||
restoreJasmineIt();
|
||||
});
|
||||
|
||||
describe('using beforeEachProviders', () => {
|
||||
beforeEachProviders(() => [bind(FancyService).toValue(new FancyService())]);
|
||||
|
||||
@ -428,5 +451,16 @@ export function main() {
|
||||
.toHaveText('injected value: mocked out value');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow an external templateUrl',
|
||||
injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
||||
return tcb.createAsync(ExternalTemplateComp)
|
||||
.then((componentFixture) => {
|
||||
componentFixture.detectChanges();
|
||||
expect(componentFixture.debugElement.nativeElement)
|
||||
.toHaveText('from external template\n');
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import {getComponentInfo, parseFields} from 'angular2/src/upgrade/metadata';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
|
||||
export function main() {
|
||||
if (!DOM.supportsDOMEvents()) return;
|
||||
describe('upgrade metadata', () => {
|
||||
it('should extract component selector', () => {
|
||||
expect(getComponentInfo(ElementNameComponent).selector).toEqual('elementNameDashed');
|
||||
|
@ -17,7 +17,6 @@ import {UpgradeAdapter} from 'angular2/upgrade';
|
||||
import * as angular from 'angular2/src/upgrade/angular_js';
|
||||
|
||||
export function main() {
|
||||
if (!DOM.supportsDOMEvents()) return;
|
||||
describe('adapter: ng1 to ng2', () => {
|
||||
it('should have angular 1 loaded', () => expect(angular.version.major).toBe(1));
|
||||
|
||||
|
@ -5,15 +5,17 @@ import "dart:async";
|
||||
import "package:angular2/testing_internal.dart"
|
||||
show
|
||||
AsyncTestCompleter,
|
||||
inject,
|
||||
describe,
|
||||
it,
|
||||
iit,
|
||||
expect,
|
||||
SpyObject,
|
||||
beforeEach,
|
||||
beforeEachProviders,
|
||||
SpyObject,
|
||||
proxy;
|
||||
describe,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
proxy,
|
||||
testSetup;
|
||||
import 'package:angular2/src/platform/server/html_adapter.dart';
|
||||
import "package:angular2/src/web_workers/debug_tools/multi_client_server_message_bus.dart";
|
||||
import "package:angular2/src/web_workers/shared/messaging_api.dart";
|
||||
import "./message_bus_common.dart";
|
||||
@ -22,6 +24,9 @@ import "dart:convert" show JSON;
|
||||
import 'dart:math';
|
||||
|
||||
main() {
|
||||
Html5LibDomAdapter.makeCurrent();
|
||||
testSetup();
|
||||
|
||||
List<String> messageHistory = new List<String>();
|
||||
List<int> resultMarkers = new List<int>();
|
||||
describe("MultiClientServerMessageBusSink", () {
|
||||
|
@ -5,20 +5,25 @@ import "dart:async";
|
||||
import "package:angular2/testing_internal.dart"
|
||||
show
|
||||
AsyncTestCompleter,
|
||||
inject,
|
||||
describe,
|
||||
it,
|
||||
expect,
|
||||
SpyObject,
|
||||
beforeEach,
|
||||
beforeEachProviders,
|
||||
SpyObject,
|
||||
proxy;
|
||||
describe,
|
||||
expect,
|
||||
inject,
|
||||
it,
|
||||
proxy,
|
||||
testSetup;
|
||||
import 'package:angular2/src/platform/server/html_adapter.dart';
|
||||
import "package:angular2/src/web_workers/debug_tools/single_client_server_message_bus.dart";
|
||||
import "./message_bus_common.dart";
|
||||
import "./spy_web_socket.dart";
|
||||
import "dart:convert" show JSON;
|
||||
|
||||
main() {
|
||||
Html5LibDomAdapter.makeCurrent();
|
||||
testSetup();
|
||||
|
||||
var MESSAGE = const {'test': 10};
|
||||
const CHANNEL = "TEST_CHANNEL";
|
||||
describe("SingleClientServerMessageBusSink", () {
|
||||
|
@ -60,15 +60,9 @@ main() {
|
||||
@proxy
|
||||
class SpyMessageEvent extends SpyObject implements MessageEvent {
|
||||
SpyMessageEvent() : super(SpyMessageEvent);
|
||||
noSuchMethod(m) {
|
||||
return super.noSuchMethod(m);
|
||||
}
|
||||
}
|
||||
|
||||
@proxy
|
||||
class SpyWebSocket extends SpyObject implements WebSocket {
|
||||
SpyWebSocket() : super(SpyWebSocket);
|
||||
noSuchMethod(m) {
|
||||
return super.noSuchMethod(m);
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,13 @@ import {
|
||||
inject,
|
||||
describe,
|
||||
it,
|
||||
iit,
|
||||
expect,
|
||||
beforeEach,
|
||||
beforeEachProviders,
|
||||
SpyObject,
|
||||
proxy
|
||||
proxy,
|
||||
browserDetection
|
||||
} from 'angular2/testing_internal';
|
||||
import {createPairedMessageBuses} from '../shared/web_worker_test_util';
|
||||
import {Serializer, PRIMITIVE} from 'angular2/src/web_workers/shared/serializer';
|
||||
@ -28,7 +30,7 @@ export function main() {
|
||||
const RESULT = 20;
|
||||
const ID = "methodId";
|
||||
|
||||
beforeEachProviders(() => [provide(ON_WEB_WORKER, {useValue: true}), RenderStore]);
|
||||
beforeEachProviders(() => [Serializer, provide(ON_WEB_WORKER, {useValue: true}), RenderStore]);
|
||||
|
||||
describe("UIMessageBroker", () => {
|
||||
var messageBuses;
|
||||
@ -49,6 +51,9 @@ export function main() {
|
||||
{'method': TEST_METHOD, 'args': [PASSED_ARG_1, PASSED_ARG_2]});
|
||||
}));
|
||||
|
||||
// TODO(pkozlowski): this fails only in Edge with
|
||||
// "No provider for RenderStore! (Serializer -> RenderStore)"
|
||||
if (!browserDetection.isEdge) {
|
||||
it("should return promises to the worker", inject([Serializer], (serializer) => {
|
||||
var broker = new ServiceMessageBroker_(messageBuses.ui, serializer, CHANNEL);
|
||||
broker.registerMethod(TEST_METHOD, [PRIMITIVE], (arg1) => {
|
||||
@ -63,5 +68,6 @@ export function main() {
|
||||
expect(data.value).toEqual(RESULT);
|
||||
});
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -44,7 +44,10 @@ import {
|
||||
ServiceMessageBrokerFactory_
|
||||
} from 'angular2/src/web_workers/shared/service_message_broker';
|
||||
import {ChangeDetectorGenConfig} from 'angular2/src/core/change_detection/change_detection';
|
||||
|
||||
import {
|
||||
TEST_BROWSER_PLATFORM_PROVIDERS,
|
||||
TEST_BROWSER_APPLICATION_PROVIDERS
|
||||
} from 'angular2/platform/testing/browser';
|
||||
|
||||
export function main() {
|
||||
function createWebWorkerBrokerFactory(
|
||||
@ -83,13 +86,16 @@ export function main() {
|
||||
|
||||
beforeEachProviders(() => {
|
||||
uiRenderStore = new RenderStore();
|
||||
var testInjector = new TestInjector();
|
||||
testInjector.addProviders([
|
||||
var testUiInjector = new TestInjector();
|
||||
testUiInjector.platformProviders = TEST_BROWSER_PLATFORM_PROVIDERS;
|
||||
testUiInjector.applicationProviders = TEST_BROWSER_APPLICATION_PROVIDERS;
|
||||
testUiInjector.addProviders([
|
||||
Serializer,
|
||||
provide(RenderStore, {useValue: uiRenderStore}),
|
||||
provide(DomRootRenderer, {useClass: DomRootRenderer_}),
|
||||
provide(RootRenderer, {useExisting: DomRootRenderer})
|
||||
]);
|
||||
uiInjector = testInjector.createInjector();
|
||||
uiInjector = testUiInjector.createInjector();
|
||||
var uiSerializer = uiInjector.get(Serializer);
|
||||
var domRootRenderer = uiInjector.get(DomRootRenderer);
|
||||
workerRenderStore = new RenderStore();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user