diff --git a/.editorconfig b/.editorconfig index bab156b63a..1cf867f786 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,7 +5,6 @@ root = true charset = utf-8 indent_style = space indent_size = 2 -end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000000..d1c2c2b349 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,30 @@ +module.exports = { + "globals": { + "describe": true, + "beforeEach": true, + "it": true, + "expect": true + }, + "env": { + "node": true + }, + "extends": "eslint:recommended", + "rules": { + "indent": [ + "error", + 2 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ] + } +}; \ No newline at end of file diff --git a/.firebaserc b/.firebaserc new file mode 100644 index 0000000000..77c09fb883 --- /dev/null +++ b/.firebaserc @@ -0,0 +1,8 @@ +{ + "projects": { + "live": "angular-io", + "ngdocsdev": "ngdocsdev", + "kw-dev": "kw-angular-io", + "dev": "angular-io-dev" + } +} \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..fa749aa3fd --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,7 @@ +**Please do not add issues or pull requests to this repo.** +We are no longer making changes to documentation in this repository. +We will no longer process new issues or PRs and we will close them automatically. + +**Please post new [issues](https://github.com/angular/angular/issues) and [pull requests](https://github.com/angular/angular/pulls) to the content folder in [https://github.com/angular/angular/tree/master/aio/content](https://github.com/angular/angular/tree/master/aio/content)**. + +Be sure to prefix your issue/PR title with "**docs(aio):**" diff --git a/.github/PULL_REQUEST_TEMPLATE.MD b/.github/PULL_REQUEST_TEMPLATE.MD new file mode 100644 index 0000000000..c4e15a1d58 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.MD @@ -0,0 +1,7 @@ +**Please do not add issues or pull requests to this repo.** +We are no longer making changes to documentation in this repository. +We will no longer process new issues or PRs and we will close them automatically. + +**Please post new [issues](https://github.com/angular/angular/issues) and [pull requests](https://github.com/angular/angular/pulls) to the content folder in [https://github.com/angular/angular/tree/master/aio/content](https://github.com/angular/angular/tree/master/aio/content)**. + +Be sure to prefix your issue/PR title with "**docs(aio):**" diff --git a/.gitignore b/.gitignore index 6ed64fc3f2..c327f2acf5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ node_modules _temp bower_components jspm_packages -typings **/packages build pubspec.lock @@ -12,6 +11,7 @@ pubspec.lock .DS_Store **/*.iml .idea +.vscode **/js/latest/api **/ts/latest/api **/dart/latest/api @@ -20,12 +20,18 @@ _.* **/resources/zips public/docs/xref-*.* _zip-output -www -npm-debug.log -npm-debug.log.* +www* +npm-debug*.log* +**/debug.log *.plnkr.html plnkr.html +*.eplnkr.html +eplnkr.html *plnkr.no-link.html public/docs/*/latest/guide/cheatsheet.json protractor-results.txt link-checker-results.txt +/dist +/public/docs/dart +/public/docs/ts/_cache +/public/docs/_examples/*/dart diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000000..1e8b314962 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +6 diff --git a/.travis.yml b/.travis.yml index f09411f763..edba3b37d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,24 +2,46 @@ dist: trusty sudo: required language: node_js node_js: - - "5" + - "6" os: - linux env: global: + - DBUS_SESSION_BUS_ADDRESS=/dev/null - DISPLAY=:99.0 - CHROME_BIN=chromium-browser + - LATEST_RELEASE=4.0.0 + # Temporarily disabled until there is a new release branch for 4.0.0 + # - LATEST_RELEASE_BRANCH=2.4.x + - TASK_FLAGS="--dgeni-log=warn" matrix: - - SCRIPT="run-e2e-tests --fast" + # current angular release jobs + - TASK=lint + - TASK="run-e2e-tests --fast" SCRIPT=examples-install.sh + - TASK=build-compile SCRIPT=deploy-install.sh WAIT="travis_wait 50" POST_SCRIPT="check-docs.sh -v" + # current angular release branch jobs + # - TASK="run-e2e-tests --fast" SCRIPT=examples-install-preview.sh PREVIEW_BRANCH=$LATEST_RELEASE_BRANCH + # - TASK=build-compile SCRIPT=deploy-install-preview.sh PREVIEW_BRANCH=$LATEST_RELEASE_BRANCH WAIT="travis_wait 50" POST_SCRIPT="check-docs.sh -v" + # angular master jobs + - TASK="run-e2e-tests --fast" SCRIPT=examples-install-preview.sh PREVIEW_BRANCH=master + - TASK=build-compile SCRIPT=deploy-install-preview.sh PREVIEW_BRANCH=master WAIT="travis_wait 50" POST_SCRIPT="check-docs.sh -v" +matrix: + fast_finish: true + allow_failures: + # allow current angular release branch and master to fail + # these should be moved to a daily task instead of being ran on every PR + # - env: TASK="run-e2e-tests --fast" SCRIPT=examples-install-preview.sh PREVIEW_BRANCH=$LATEST_RELEASE_BRANCH + # - env: TASK=build-compile SCRIPT=deploy-install-preview.sh PREVIEW_BRANCH=$LATEST_RELEASE_BRANCH WAIT="travis_wait 50" POST_SCRIPT="check-docs.sh -v" + - env: TASK="run-e2e-tests --fast" SCRIPT=examples-install-preview.sh PREVIEW_BRANCH=master + - env: TASK=build-compile SCRIPT=deploy-install-preview.sh PREVIEW_BRANCH=master WAIT="travis_wait 50" POST_SCRIPT="check-docs.sh -v" before_install: - - npm install -g gulp --no-optional -before_script: - - sh -e /etc/init.d/xvfb start + - source ./scripts/env-set.sh + - ./scripts/before-install.sh install: - npm install --no-optional - - npm install --prefix public/docs/_examples - - npm install --prefix public/docs/_examples/_protractor - - npm run webdriver:update --prefix public/docs/_examples/_protractor - - gulp add-example-boilerplate + - if [[ -n "$SCRIPT" ]]; then echo "EXTRA INSTALL $SCRIPT"; ./scripts/$SCRIPT; fi +before_script: + - sh -e /etc/init.d/xvfb start script: - - gulp $SCRIPT \ No newline at end of file + - $WAIT gulp $TASK $TASK_FLAGS + - if [[ -n "$POST_SCRIPT" ]]; then ./scripts/$POST_SCRIPT; fi diff --git a/LICENSE b/LICENSE index 13a6fd789f..47bfda24ad 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright (c) 2016 Google, Inc. +Copyright (c) 2017 Google, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 59732e1d95..5a68c5c1b7 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,18 @@ +# This angular.io documentation repository is closed and preserved just for archival purposes + +**Please post new [issues](https://github.com/angular/angular/issues) and [pull requests](https://github.com/angular/angular/pulls) to the content folder in [https://github.com/angular/angular/tree/master/aio/content](https://github.com/angular/angular/tree/master/aio/content)**. + +
+ # Angular.io -Angular.io is site for Angular 2 **documentation** . +---------- + +[![Build Status][travis-badge]][travis-badge-url] + +Angular.io is site for Angular **documentation** . This site also includes links to other helpful angular resources including -Angular 2, Angular 1, Angular Material, and AngularFire. +AngularJS, Angular Material, and AngularFire. ## Issues @@ -22,18 +32,21 @@ Learn how to [contribute to Angular.io](https://github.com/angular/angular.js/bl ## Development Setup This site relies heavily on node and npm. -1. Make sure you are using the latest node and npm; +1. Make sure you are using at least node v.5+ and latest npm; if not install [nvm](https://github.com/creationix/nvm) to get node going on your machine. -1. install these npm packages *globally*: `npm install -g harp gulp protractor` +1. Install global npm packages by running `./scripts/before-install.sh` + +1. Clone + + - this repo + - [angular/angular source code repo](https://github.com/angular/angular) -1. clone this repo and the [angular source code repo](https://github.com/angular/angular) to the same parent directory. -The two cloned repo directories must be sibling. + to the same parent directory. The **cloned repo directories must be siblings**, with the latter named **angular**. 1. cd into root directory `angular.io/` -1. install the *all-docs* local packages by running `npm install` -> If running node v.5+, you probably must rebuild `node-sass` in a separate step: `npm rebuild node-sass` +1. Install local npm packages by running `./scripts/install.sh` 1. See [below](#code-sample-development) for code sample development preparation. @@ -69,11 +82,11 @@ If you are only going to work on a specific part of the docs, such as the dev gu ## Code Sample Development All documentation is supported by sample code and plunkers. -Such code resides in the `public/docs/_examples` directory, under chapter-specific directories, further divided by language track. +Such code resides in the `public/docs/_examples` directory, under page-specific directories, further divided by language track. For example, the TypeScript QuickStart sample is in `public/docs/_examples/quickstart/ts`. -All samples are in a consistent directory structure using the same styles and the same npm packages, including the latest release of Angular 2. +All samples are in a consistent directory structure using the same styles and the same npm packages, including the latest release of Angular. This consistency is possible in part thanks to gulp-driven tooling. To run the samples locally and confirm that they work properly, take the following extra steps to prepare the environment: @@ -85,7 +98,7 @@ take the following extra steps to prepare the environment: 1. cd back up to `angular.io` root: `cd ../../..` 1. run `gulp add-example-boilerplate` (elevate to admin on Windows) -to copy canonical files to the sample directories and create symlinks there for node_modules and typings. +to copy canonical files to the sample directories and create symlinks there for node_modules. Now cd into any particular sample's language directory (e.g., `public/docs/_examples/quickstart/ts`) and try: - `npm start` to simultaneously compile-with-watch and serve-in-browser-with-watch @@ -96,20 +109,47 @@ Look at the scripts in `package.json` for other options. Also, open any `plunkr.no-link.html` to see the code execute in plunker (you may have to run `gulp build-plunkers` first to create/update). +You must check that your example is free of lint errors. +- `gulp lint` + ### Sample end-to-end tests All samples should be covered to some degree by end-to-end tests: - `gulp run-e2e-tests` to run all TypeScript and JavaScript tests -- `gulp run-e2e-tests --lang=dart` to run all Dart tests -- `gulp run-e2e-tests --lang=all` to run TypeScript, JavaScript, and Dart tests +- `gulp run-e2e-tests --lang=all` to run TypeScript and JavaScript tests - `gulp run-e2e-tests --filter=quickstart` to filter the examples to run, by name - `gulp run-e2e-tests --fast` to ignore npm install, webdriver update and boilerplate copy Any combination of options is possible. +### Resetting the project +This project generates a lot of untracked files, if you wish to reset it to a mint state, you can run: + +- `git clean -xdf` + +Also, there is a script available for Linux, OSX and Windows Gitbash users that will setup the project using the steps shown in this section: + +- `./scripts/install.sh` + +### Run with current build instead of release packages +Can switch the `@angular` packages in `~/public/docs/_examples/node_modules` to the current build packages with +``` +gulp install-example-angular --build +``` +Restore to RELEASE packages with +``` +gulp install-example-angular +``` +>These commands will fail if something is locking any of the packages ... as an IDE often does. +> +>The symptom typically is an error trying to `rm -rf node_modules/@angular`. +> +>_Solution_: unlock the hold on the package(s). In VS Code, re-load the window (`cmd-P` then enter `>relow`). + ## Technology Used -- Angular 1.x: The production ready version of Angular +- Angular: Current Angular +- AngularJS: A v.1.x version of Angular - Angular Material: An implementation of Material Design in Angular.js - Gulp: node-based tooling - Harp: The static web server with built-in preprocessing. @@ -121,4 +161,7 @@ Any combination of options is possible. ## License -Powered by Google ©2010-2016. Code licensed under an [MIT-style License](https://github.com/angular.io/blob/master/LICENSE). Documentation licensed under [CC BY 4.0](http://creativecommons.org/licenses/by/4.0/). +Powered by Google ©2010-2017. Code licensed under an [MIT-style License](https://github.com/angular.io/blob/master/LICENSE). Documentation licensed under [CC BY 4.0](http://creativecommons.org/licenses/by/4.0/). + +[travis-badge]: https://travis-ci.org/angular/angular.io.svg?branch=master +[travis-badge-url]: https://travis-ci.org/angular/angular.io diff --git a/firebase.json b/firebase.json index 069b61f208..4f6e69080f 100644 --- a/firebase.json +++ b/firebase.json @@ -1,75 +1,121 @@ { - "firebase": "angular-io", - "public": "www", - "rewrites": [ - { - "source": "/docs/dart/latest/testing", - "destination": "/docs/dart/latest/index.html" - }, - { - "source": "/docs/dart/latest/tutorial", - "destination": "/docs/dart/latest/index.html" - }, - { - "source": "/docs/js/latest/testing", - "destination": "/docs/js/latest/index.html" - }, - { - "source": "/docs/js/latest/tutorial", - "destination": "/docs/js/latest/index.html" - }, - { - "source": "/docs/ts/latest/guide/setup.html", - "destination": "/docs/ts/latest/index.html" - }, - { - "source": "/docs/ts/latest/testing", - "destination": "/docs/ts/latest/guide/testing.html" - }, - { - "source": "/cheatsheet", - "destination": "/docs/ts/latest/guide/cheatsheet.html" - }, - { - "source": "/cheatsheet.json", - "destination": "/docs/ts/latest/guide/cheatsheet.json" - }, - { - "source": "/AngularCheatSheet_Letter.pdf", - "destination": "/docs/ts/latest/guide/AngularCheatSheet_Letter.pdf" - }, - { - "source": "/AngularCheatSheet_Poster.pdf", - "destination": "/docs/ts/latest/guide/AngularCheatSheet_Poster.pdf" - }, - { - "source": "/cardboard", - "destination": "/cardboard/index.html" - }, - { - "source": "/license", - "destination": "/license.txt" - }, - { - "source": "/events", - "destination": "/events.html" - }, - { - "source": "/survey", - "destination": "/survey.html" - }, - { - "source": "/dart", - "destination": "/docs/dart/latest/index.html" - }, - { - "source": "/styleguide", - "destination": "/docs/ts/latest/guide/style-guide.html" - } - ], - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**" - ] + "hosting": { + "public": "www", + "redirects": [ + { + "source": "/docs/dart/latest/quickstart.html", + "destination": "https://webdev.dartlang.org/angular/quickstart?utm_campaign=dart_migration&utm_medium=redirect&utm_source=angular.io", + "type": 301 + }, + { + "source": "/docs/dart/latest/tutorial/toh-pt5.html", + "destination": "https://webdev.dartlang.org/angular/tutorial/toh-pt5?utm_campaign=dart_migration&utm_medium=redirect&utm_source=angular.io", + "type": 301 + }, + { + "source": "/docs/dart/latest/tutorial", + "destination": "https://webdev.dartlang.org/angular/tutorial?utm_campaign=dart_migration&utm_medium=redirect&utm_source=angular.io", + "type": 301 + }, + { + "source": "/docs/dart/latest/tutorial/**", + "destination": "https://webdev.dartlang.org/angular/tutorial?utm_campaign=dart_migration&utm_medium=redirect&utm_source=angular.io", + "type": 301 + }, + { + "source": "/docs/dart/latest/api", + "destination": "https://webdev.dartlang.org/angular/api?utm_campaign=dart_migration&utm_medium=redirect&utm_source=angular.io", + "type": 301 + }, + { + "source": "/docs/dart/latest/api/**", + "destination": "https://webdev.dartlang.org/angular/api?utm_campaign=dart_migration&utm_medium=redirect&utm_source=angular.io", + "type": 301 + }, + { + "source": "/docs/dart/latest/guide/**", + "destination": "https://webdev.dartlang.org/angular/guide?utm_campaign=dart_migration&utm_medium=redirect&utm_source=angular.io", + "type": 301 + }, + { + "source": "/**/dart", + "destination": "https://webdev.dartlang.org/angular?utm_campaign=dart_migration&utm_medium=redirect&utm_source=angular.io", + "type": 301 + }, + { + "source": "/**/dart/**", + "destination": "https://webdev.dartlang.org/angular?utm_campaign=dart_migration&utm_medium=redirect&utm_source=angular.io", + "type": 301 + }, + { + "source": "/docs", + "destination": "https://angular.io/docs/ts/latest/", + "type": 301 + } + ], + "rewrites": [ + { + "source": "/docs/js/latest/testing", + "destination": "/docs/js/latest/guide/testing.html" + }, + { + "source": "/docs/js/latest/tutorial", + "destination": "/docs/js/latest/index.html" + }, + { + "source": "/docs/ts/latest/cookbook/a1-a2-quick-reference.html", + "destination": "/docs/ts/latest/cookbook/ajs-quick-reference.html" + }, + { + "source": "/docs/ts/latest/guide/setup.html", + "destination": "/docs/ts/latest/index.html" + }, + { + "source": "/docs/ts/latest/testing", + "destination": "/docs/ts/latest/guide/testing.html" + }, + { + "source": "/cheatsheet", + "destination": "/docs/ts/latest/guide/cheatsheet.html" + }, + { + "source": "/cheatsheet.json", + "destination": "/docs/ts/latest/guide/cheatsheet.json" + }, + { + "source": "/AngularCheatSheet_Letter.pdf", + "destination": "/docs/ts/latest/guide/AngularCheatSheet_Letter.pdf" + }, + { + "source": "/AngularCheatSheet_Poster.pdf", + "destination": "/docs/ts/latest/guide/AngularCheatSheet_Poster.pdf" + }, + { + "source": "/cardboard", + "destination": "/cardboard/index.html" + }, + { + "source": "/license", + "destination": "/license.txt" + }, + { + "source": "/events", + "destination": "/events.html" + }, + { + "source": "/survey", + "destination": "/survey.html" + }, + { + "source": "/styleguide", + "destination": "/docs/ts/latest/guide/style-guide.html" + } + ], + "ignore": [ + "firebase.json", + "**/.*", + "**/node_modules/**", + "docs/dart/**" + ] + } } diff --git a/gulpfile.js b/gulpfile.js index 59e7749515..b6a3900b24 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -14,6 +14,7 @@ var fsExtra = require('fs-extra'); var fs = fsExtra; var exec = require('child_process').exec; var execPromise = Q.denodeify(exec); +var execSync = require('child_process').execSync; // cross platform version of spawn that also works on windows. var xSpawn = require('cross-spawn'); var prompt = require('prompt'); @@ -22,7 +23,7 @@ var globby = require("globby"); // - because childProcess.kill does not work properly on windows var treeKill = require("tree-kill"); var blc = require("broken-link-checker"); - +var less = require('gulp-less'); var tslint = require('gulp-tslint'); // TODO: @@ -30,65 +31,127 @@ var tslint = require('gulp-tslint'); // 2. Think about using spawn instead of exec in case of long error messages. var TOOLS_PATH = './tools'; +var ANGULAR_IO_PROJECT_PATH = path.resolve('.'); var ANGULAR_PROJECT_PATH = '../angular'; var PUBLIC_PATH = './public'; var TEMP_PATH = './_temp'; var DOCS_PATH = path.join(PUBLIC_PATH, 'docs'); var EXAMPLES_PATH = path.join(DOCS_PATH, '_examples'); -var EXAMPLES_PROTRACTOR_PATH = path.join(EXAMPLES_PATH, '_protractor'); -var NOT_API_DOCS_GLOB = path.join(PUBLIC_PATH, './{docs/*/latest/!(api),!(docs)}/**/*'); +var BOILERPLATE_PATH = path.join(EXAMPLES_PATH, '_boilerplate'); +var EXAMPLES_TESTING_PATH = path.join(EXAMPLES_PATH, 'testing/ts'); +var NOT_API_DOCS_GLOB = path.join(PUBLIC_PATH, './{docs/*/latest/!(api),!(docs)}/**/*.*'); var RESOURCES_PATH = path.join(PUBLIC_PATH, 'resources'); var LIVE_EXAMPLES_PATH = path.join(RESOURCES_PATH, 'live-examples'); +var STYLES_SOURCE_PATH = path.join(TOOLS_PATH, 'styles-builder/less'); var docShredder = require(path.resolve(TOOLS_PATH, 'doc-shredder/doc-shredder')); -var exampleZipper = require(path.resolve(TOOLS_PATH, '_example-zipper/exampleZipper')); -var plunkerBuilder = require(path.resolve(TOOLS_PATH, 'plunker-builder/plunkerBuilder')); +var ExampleZipper = require(path.resolve(TOOLS_PATH, 'example-zipper/exampleZipper')); +var regularPlunker = require(path.resolve(TOOLS_PATH, 'plunker-builder/regularPlunker')); +var embeddedPlunker = require(path.resolve(TOOLS_PATH, 'plunker-builder/embeddedPlunker')); var fsUtils = require(path.resolve(TOOLS_PATH, 'fs-utils/fsUtils')); +const WWW = argv.page ? 'www-pages' : 'www' + +const isSilent = !!argv.silent; +if (isSilent) gutil.log = gutil.noop; +const _dgeniLogLevel = argv.dgeniLog || (isSilent ? 'error' : 'info'); var _devguideShredOptions = { examplesDir: path.join(DOCS_PATH, '_examples'), fragmentsDir: path.join(DOCS_PATH, '_fragments'), - zipDir: path.join(RESOURCES_PATH, 'zips') + zipDir: path.join(RESOURCES_PATH, 'zips'), + logLevel: _dgeniLogLevel }; var _devguideShredJadeOptions = { - jadeDir: DOCS_PATH - + jadeDir: DOCS_PATH, + logLevel: _dgeniLogLevel }; var _apiShredOptions = { - examplesDir: path.join(ANGULAR_PROJECT_PATH, 'modules/@angular/examples'), + lang: 'ts', + examplesDir: path.join(ANGULAR_PROJECT_PATH, 'packages/examples'), fragmentsDir: path.join(DOCS_PATH, '_fragments/_api'), - zipDir: path.join(RESOURCES_PATH, 'zips/api') + zipDir: path.join(RESOURCES_PATH, 'zips/api'), + logLevel: _dgeniLogLevel }; -var _excludePatterns = ['**/node_modules/**', '**/typings/**', '**/packages/**']; +var _excludePatterns = ['**/node_modules/**']; var _excludeMatchers = _excludePatterns.map(function(excludePattern){ return new Minimatch(excludePattern) }); var _exampleBoilerplateFiles = [ - '.editorconfig', - 'karma.conf.js', - 'karma-test-shim.js', + 'src/styles.css', + 'src/systemjs.config.js', + 'src/systemjs-angular-loader.js', + 'src/tsconfig.json', + 'bs-config.json', + 'bs-config.e2e.json', 'package.json', - 'styles.css', - 'systemjs.config.js', - 'tsconfig.json', - 'tslint.json', - 'typings.json', - 'wallaby.js' - ]; - -var _exampleDartWebBoilerPlateFiles = ['styles.css']; - -var _exampleProtractorBoilerplateFiles = [ - 'tsconfig.json' + 'tslint.json' ]; +var _exampleUnitTestingBoilerplateFiles = [ + 'src/browser-test-shim.js', + 'karma-test-shim.js', + 'karma.conf.js' +]; + +var _exampleConfigFilename = 'example-config.json'; + +// Gulp flags: +// +// --lang=[all | ts | js | dart | 'ts|js' | 'ts|js|dart' | ...] +// +// This affects which language API docs and E2E tests are run. Can be 'all', +// or a regex pattern to match any one of 'ts', 'js', or 'dart'. +// Default: 'ts|js' except for the "full site build" tasks (see below), +// for which it is 'all'. + +// langs and skipLangs partition ['ts', 'js', 'dart']. +var lang, langs, skipLangs, buildDartApiDocs = false; +function configLangs(langOption) { + const fullSiteBuildTasks = ['build-compile', 'check-deploy', 'harp-compile']; + const buildAllDocs = argv['_'] && + fullSiteBuildTasks.some((task) => argv['_'].indexOf(task) >= 0); + const langDefault = /*buildAllDocs ? 'all' :*/ 'ts|js'; + if (langOption === '') { + lang = ''; + langs = []; + } else { + lang = (langOption || langDefault).toLowerCase(); + if (lang === 'all') lang = 'ts|js|dart'; + langs = lang.match(/\w+/g); // the languages in `lang` as an array + } + gutil.log(`Building docs for: [${langs}]`); + if (langs.indexOf('dart') >= 0) { + buildDartApiDocs = true; + // For Dart, be proactive about checking for the repo + checkAngularProjectPath(ngPathFor('dart')); + } else { + argv.pub = false; + } + skipLangs = []; + ['ts', 'js', 'dart'].forEach(lang => { + if (langs.indexOf(lang) < 0) skipLangs.push(lang); + }); + gutil.log(`Skipped languages: [${skipLangs}]`); +} +configLangs(argv.lang); + +function isDartPath(path) { + // Testing via indexOf() for now. If we need to match only paths with folders + // named 'dart' vs 'dart*' then try: path.match('/dart(/|$)') != null; + return path.indexOf('/dart') > -1; +} + +function excludeDartPaths(paths) { + return paths.filter(function (p) { return !isDartPath(p); }); +} + /** * Run Protractor End-to-End Specs for Doc Samples * Alias for 'run-e2e-tests' @@ -108,10 +171,8 @@ gulp.task('run-e2e-tests', runE2e); * Use it for repeated test runs (but not the FIRST run) * e.g. gulp e2e --fast * - * --lang to filter by code language + * --lang to filter by code language (see above for details) * e.g. gulp e2e --lang=ts // only TypeScript apps - * default is (ts|js) - * all means (ts|js|dart) */ function runE2e() { var promise; @@ -119,28 +180,14 @@ function runE2e() { // fast; skip all setup promise = Promise.resolve(true); } else { - /* - // Not 'fast'; do full setup - var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH}); - promise = spawnInfo.promise.then(function() { - copyExampleBoilerplate(); - spawnInfo = spawnExt('npm', ['run', 'webdriver:update'], {cwd: EXAMPLES_PATH}); - return spawnInfo.promise; - }); - */ // Not 'fast'; do full setup - gutil.log('runE2e: install _protractor stuff'); - var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PROTRACTOR_PATH}); + gutil.log('runE2e: install _examples stuff'); + var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH}); promise = spawnInfo.promise + .then(copyExampleBoilerplate) .then(function() { - gutil.log('runE2e: install _examples stuff'); - spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH}) - return spawnInfo.promise; - }) - .then(function() { - copyExampleBoilerplate(); gutil.log('runE2e: update webdriver'); - spawnInfo = spawnExt('npm', ['run', 'webdriver:update'], {cwd: EXAMPLES_PROTRACTOR_PATH}); + spawnInfo = spawnExt('npm', ['run', 'webdriver:update'], {cwd: EXAMPLES_PATH}); return spawnInfo.promise; }); }; @@ -165,10 +212,7 @@ function runE2e() { // with the corresponding apps that they should run under. Then run // each app/spec collection sequentially. function findAndRunE2eTests(filter, outputFile) { - // create an output file with header. - var lang = (argv.lang || '(ts|js)').toLowerCase(); - if (lang === 'all') { lang = '(ts|js|dart)'; } var startTime = new Date().getTime(); var header = `Doc Sample Protractor Results for ${lang} on ${new Date().toLocaleString()}\n`; header += argv.fast ? @@ -178,22 +222,22 @@ function findAndRunE2eTests(filter, outputFile) { fs.writeFileSync(outputFile, header); // create an array of combos where each - // combo consists of { examplePath: ... , protractorConfigFilename: ... } + // combo consists of { examplePath: ... } var examplePaths = []; var e2eSpecPaths = getE2eSpecPaths(EXAMPLES_PATH); e2eSpecPaths.forEach(function(specPath) { - var destConfig = path.join(specPath, 'protractor.config.js'); // get all of the examples under each dir where a pcFilename is found localExamplePaths = getExamplePaths(specPath, true); - // Filter by language - localExamplePaths = localExamplePaths.filter(function (fn) { - return fn.match('/'+lang+'$') != null; - }); + // Filter by example name if (filter) { localExamplePaths = localExamplePaths.filter(function (fn) { return fn.match(filter) != null; }) } + // Filter by language, also supports variations like js-es6 + localExamplePaths = localExamplePaths.filter(function (fn) { + return fn.match('/'+lang+'(?:-[^/]*)?$') != null; + }); localExamplePaths.forEach(function(examplePath) { examplePaths.push(examplePath); }) @@ -203,8 +247,7 @@ function findAndRunE2eTests(filter, outputFile) { var status = { passed: [], failed: [] }; return examplePaths.reduce(function (promise, examplePath) { return promise.then(function () { - var isDart = examplePath.indexOf('/dart') > -1; - var runTests = isDart ? runE2eDartTests : runE2eTsTests; + var runTests = isDartPath(examplePath) ? runE2eDartTests : runE2eTsTests; return runTests(examplePath, outputFile).then(function(ok) { var arr = ok ? status.passed : status.failed; arr.push(examplePath); @@ -221,11 +264,27 @@ function findAndRunE2eTests(filter, outputFile) { // fileName; then shut down the example. All protractor output is appended // to the outputFile. function runE2eTsTests(appDir, outputFile) { - // start the app - var appRunSpawnInfo = spawnExt('npm',['run','http-server:e2e', '--', '-s' ], { cwd: appDir }); - var tscRunSpawnInfo = spawnExt('npm',['run','tsc'], { cwd: appDir }); + // Grab protractor configuration or defaults to systemjs config. + try { + var exampleConfig = fs.readJsonSync(`${appDir}/${_exampleConfigFilename}`); + } catch (e) { + exampleConfig = {}; + } + + var config = { + build: exampleConfig.build || 'build', + run: exampleConfig.run || 'serve:e2e' + }; + + var appBuildSpawnInfo = spawnExt('npm', ['run', config.build], { cwd: appDir }); + var appRunSpawnInfo = spawnExt('npm', ['run', config.run, '--', '-s'], { cwd: appDir }); - return runProtractor(tscRunSpawnInfo.promise, appDir, appRunSpawnInfo, outputFile); + var run = runProtractor(appBuildSpawnInfo.promise, appDir, appRunSpawnInfo, outputFile); + + if (fs.existsSync(appDir + '/aot/index.html')) { + run = run.then(() => runProtractorAoT(appDir, outputFile)); + } + return run; } function runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile) { @@ -243,7 +302,7 @@ function runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile) { // start protractor var spawnInfo = spawnExt('npm', [ 'run', 'protractor', '--', 'protractor.config.js', - `--specs=${specFilename}`, '--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: EXAMPLES_PROTRACTOR_PATH }); + `--specs=${specFilename}`, '--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: EXAMPLES_PATH }); spawnInfo.proc.stderr.on('data', function (data) { transpileError = transpileError || /npm ERR! Exit status 100/.test(data.toString()); @@ -270,23 +329,44 @@ function runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile) { } } +function runProtractorAoT(appDir, outputFile) { + fs.appendFileSync(outputFile, '++ AoT version ++\n'); + var aotBuildSpawnInfo = spawnExt('npm', ['run', 'build:aot'], { cwd: appDir }); + var promise = aotBuildSpawnInfo.promise; + + var copyFileCmd = 'copy-dist-files.js'; + if (fs.existsSync(appDir + '/' + copyFileCmd)) { + promise = promise.then(() => + spawnExt('node', [copyFileCmd], { cwd: appDir }).promise ); + } + var aotRunSpawnInfo = spawnExt('npm', ['run', 'serve:aot'], { cwd: appDir }); + return runProtractor(promise, appDir, aotRunSpawnInfo, outputFile); +} + // start the server in appDir/build/web; then run protractor with the specified // fileName; then shut down the example. All protractor output is appended // to the outputFile. function runE2eDartTests(appDir, outputFile) { - var deployDir = path.resolve(path.join(appDir, 'build/web')); + // Launch http server out of ts directory because all the config files are there. + var httpLaunchDir = path.resolve(appDir, '../ts'); + var deployDir = path.resolve(appDir, 'build/web'); gutil.log('AppDir for Dart e2e: ' + appDir); gutil.log('Deploying from: ' + deployDir); - var appRunSpawnInfo = spawnExt('npm', ['run', 'http-server:e2e', '--', deployDir, '-s'], { cwd: EXAMPLES_PATH }); + var appRunSpawnInfo = spawnExt('npm', ['run', 'serve:e2e', '--', deployDir, '-s'], { cwd: httpLaunchDir }); if (!appRunSpawnInfo.proc.pid) { gutil.log('http-server failed to launch over ' + deployDir); return false; } - var pubUpgradeSpawnInfo = spawnExt('pub', ['upgrade'], { cwd: appDir }); - var prepPromise = pubUpgradeSpawnInfo.promise.then(function (data) { - return spawnExt('pub', ['build'], { cwd: appDir }).promise; - }); + if (argv.pub === false) { + var prepPromise = Promise.resolve(true); + gutil.log('Skipping pub upgrade and pub build (--no-pub flag present)'); + } else { + var pubUpgradeSpawnInfo = spawnExt('pub', ['upgrade'], { cwd: appDir }); + var prepPromise = pubUpgradeSpawnInfo.promise.then(function (data) { + return spawnExt('pub', ['build'], { cwd: appDir }).promise; + }); + } return runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile); } @@ -359,55 +439,42 @@ gulp.task('help', taskListing.withFilters(function(taskName) { // requires admin access because it adds symlinks gulp.task('add-example-boilerplate', function() { var realPath = path.join(EXAMPLES_PATH, '/node_modules'); - var nodeModulesPaths = getNodeModulesPaths(EXAMPLES_PATH); + var nodeModulesPaths = excludeDartPaths(getNodeModulesPaths(EXAMPLES_PATH)); nodeModulesPaths.forEach(function(linkPath) { gutil.log("symlinking " + linkPath + ' -> ' + realPath) fsUtils.addSymlink(realPath, linkPath); }); - realPath = path.join(EXAMPLES_PATH, '/typings'); - var typingsPaths = getTypingsPaths(EXAMPLES_PATH); - typingsPaths.forEach(function(linkPath) { - gutil.log("symlinking " + linkPath + ' -> ' + realPath) - fsUtils.addSymlink(realPath, linkPath); - }); - return copyExampleBoilerplate(); }); // copies boilerplate files to locations // where an example app is found -gulp.task('_copy-example-boilerplate', copyExampleBoilerplate); - +gulp.task('_copy-example-boilerplate', function (done) { + return argv.fast ? done() : copyExampleBoilerplate(); +}); // copies boilerplate files to locations // where an example app is found // also copies certain web files (e.g., styles.css) to ~/_examples/**/dart/**/web function copyExampleBoilerplate() { gutil.log('Copying example boilerplate files'); - var sourceFiles = _exampleBoilerplateFiles.map(function(fn) { - return path.join(EXAMPLES_PATH, fn); - }); - var examplePaths = getExamplePaths(EXAMPLES_PATH); - - var dartWebSourceFiles = _exampleDartWebBoilerPlateFiles.map(function(fn){ - return path.join(EXAMPLES_PATH, fn); - }); - var dartExampleWebPaths = getDartExampleWebPaths(EXAMPLES_PATH); + var examplePaths = excludeDartPaths(getExamplePaths(EXAMPLES_PATH)); - return copyFiles(sourceFiles, examplePaths) + // Make boilerplate files read-only to avoid that they be edited by mistake. + var destFileMode = '444'; + return copyFiles(_exampleBoilerplateFiles, BOILERPLATE_PATH, examplePaths, destFileMode) + // copy the unit test boilerplate .then(function() { - return copyFiles(dartWebSourceFiles, dartExampleWebPaths); + var unittestPaths = getUnitTestingPaths(EXAMPLES_PATH); + return copyFiles(_exampleUnitTestingBoilerplateFiles, + EXAMPLES_TESTING_PATH, unittestPaths, destFileMode); }) - // copy certain files from _examples/_protractor dir to each subdir that contains an e2e-spec file. - .then(function() { - var protractorSourceFiles = - _exampleProtractorBoilerplateFiles - .map(function(name) {return path.join(EXAMPLES_PROTRACTOR_PATH, name);});; - var e2eSpecPaths = getE2eSpecPaths(EXAMPLES_PATH); - return copyFiles(protractorSourceFiles, e2eSpecPaths); + .catch(function(err) { + gutil.log(err); + throw err; }); } @@ -417,14 +484,61 @@ gulp.task('remove-example-boilerplate', function() { fsUtils.removeSymlink(linkPath); }); - var typingsPaths = getTypingsPaths(EXAMPLES_PATH); - typingsPaths.forEach(function(linkPath) { - fsUtils.removeSymlink(linkPath); - }); - deleteExampleBoilerPlate(); }); +// Npm install Angular libraries into examples/node_modules, +// either release or current build packages +// Examples: +// gulp install-example-angular --build // use current build packages +// gulp install-example-angular --build=2.0.0-b43f954 // use tagged packages +// gulp install-example-angular // restore release packages +// +// Find the tags here: https://github.com/angular/core-builds/releases +gulp.task('install-example-angular', installExampleAngular); + +function installExampleAngular() { + var sources; + var template; + var libs = [ + 'core', 'common', 'compiler', 'compiler-cli', + 'platform-browser', 'platform-browser-dynamic', 'platform-server', + 'forms', 'http', 'router', 'upgrade']; + + var build = argv.build; + if (build) { + if (typeof build === 'string') { + build = (build[0]==='#' ? '' : '#') + build; + } else { + build = ''; + } + } else{ + build = 'npm'; + } + // Like: "angular/core-builds" or "@angular/core" + sources = libs.map( lib => { + return build === 'npm' + ? `@angular/${lib}` + : `git+https://github.com/angular/${lib}-builds${build}`; + }); + + if (argv.build) { + sources.push('@angular/tsc-wrapped'); // tsc-wrapped needed for builds + sources.push('typescript@2.2.1'); // recent builds need recent TypeScript + } + + sources.push('@angular/router-deprecated'); + + gutil.log(`Installing Angular packages from ${build === 'npm' ? 'NPM' : 'BUILD ' + build}`); + + var spawnInfo = spawnExt('node', ['node_modules/rimraf/bin.js', 'node_modules/@angular'], { cwd: EXAMPLES_PATH}); + return spawnInfo.promise + .then(() => { + spawnInfo = spawnExt('npm', ['install', ...sources], {cwd: EXAMPLES_PATH}); + return spawnInfo.promise + }); +} + // deletes boilerplate files that were added by copyExampleBoilerplate // from locations where an example app is found gulp.task('_delete-example-boilerplate', deleteExampleBoilerPlate); @@ -433,15 +547,11 @@ function deleteExampleBoilerPlate() { gutil.log('Deleting example boilerplate files'); var examplePaths = getExamplePaths(EXAMPLES_PATH); var dartExampleWebPaths = getDartExampleWebPaths(EXAMPLES_PATH); + var unittestPaths = getUnitTestingPaths(EXAMPLES_PATH); return deleteFiles(_exampleBoilerplateFiles, examplePaths) .then(function() { - return deleteFiles(_exampleDartWebBoilerPlateFiles, dartExampleWebPaths); - }) - .then(function() { - var protractorFiles = _exampleProtractorBoilerplateFiles; - var e2eSpecPaths = getE2eSpecPaths(EXAMPLES_PATH); - return deleteFiles(protractorFiles, e2eSpecPaths); + return deleteFiles(_exampleUnitTestingBoilerplateFiles, unittestPaths); }); } @@ -466,11 +576,9 @@ gulp.task('build-and-serve', ['build-docs'], function (cb) { watchAndSync({localFiles: true}, cb); }); -gulp.task('build-docs', ['build-devguide-docs', 'build-api-docs', 'build-plunkers']); -// Stop zipping examples Feb 28, 2016 -//gulp.task('build-docs', ['build-devguide-docs', 'build-api-docs', 'build-plunkers', '_zip-examples']); +gulp.task('build-docs', ['build-devguide-docs', 'build-api-docs', 'build-plunkers', '_zip-examples']); -gulp.task('build-api-docs', ['build-js-api-docs', 'build-ts-api-docs', 'build-dart-cheatsheet']); +gulp.task('build-api-docs', ['build-js-api-docs', 'build-ts-api-docs']); gulp.task('build-devguide-docs', ['_shred-devguide-examples', '_shred-devguide-shared-jade'], function() { return buildShredMaps(true); @@ -484,12 +592,10 @@ gulp.task('build-js-api-docs', ['_shred-api-examples'], function() { return buildApiDocs('js'); }); +// Using the --build flag will use systemjs.config.web.build.js (for preview builds) gulp.task('build-plunkers', ['_copy-example-boilerplate'], function() { - return plunkerBuilder.buildPlunkers(EXAMPLES_PATH, LIVE_EXAMPLES_PATH, { errFn: gutil.log }); -}); - -gulp.task('build-dart-cheatsheet', [], function() { - return buildApiDocs('dart'); + regularPlunker.buildPlunkers(EXAMPLES_PATH, LIVE_EXAMPLES_PATH, { errFn: gutil.log, build: argv.build }); + return embeddedPlunker.buildPlunkers(EXAMPLES_PATH, LIVE_EXAMPLES_PATH, { errFn: gutil.log, build: argv.build, targetSelf: argv.targetSelf }); }); gulp.task('git-changed-examples', ['_shred-devguide-examples'], function(){ @@ -538,16 +644,34 @@ gulp.task('git-changed-examples', ['_shred-devguide-examples'], function(){ }); }); -gulp.task('check-deploy', ['build-docs'], function() { +gulp.task('harp-compile', () => { + return harpCompile() +}); + +gulp.task('harp-serve', () => { + // Harp will watch and serve workspace files. + const cmd = 'npm run harp -- server .'; + gutil.log('Launching harp server (over project files)'); + gutil.log(` > ${cmd}`); + gutil.log('Note: issuing this command directly from the command line will show harp comiple warnings.'); + return execPromise(cmd); +}); + +gulp.task('serve-www', () => { + // Serve generated site. + return execPromise(`npm run live-server ${WWW}`); +}); + +gulp.task('build-compile', ['build-docs'], function() { + return harpCompile(); +}); + +gulp.task('check-deploy', ['firebase-use-proj-check', 'build-docs'], () => { return harpCompile().then(function() { gutil.log('compile ok'); - if(argv.dryRun) { - return false; - } else { - gutil.log('running live server ...'); - execPromise('npm run live-server ./www'); - return askDeploy(); - } + gutil.log('running live server ...'); + execPromise(`npm run live-server ${WWW}`); + return askDeploy(); }).then(function(shouldDeploy) { if (shouldDeploy) { gutil.log('deploying...'); @@ -562,6 +686,17 @@ gulp.task('check-deploy', ['build-docs'], function() { }); }); +gulp.task('firebase-use-proj-check', cb => { + try { + execSync('firebase use'); + } catch (e) { + // Rerun command so user gets project + alias info + execSync('firebase use', {stdio:[0,1,2]}); + throw `\nAborting: no firebase project selected. Run:\n\n firebase use \n\n`; + } + return cb(); +}); + gulp.task('test-api-builder', function (cb) { execCommands(['npm run test-api-builder'], {}, cb); }); @@ -570,7 +705,20 @@ gulp.task('test-api-builder', function (cb) { // angular.io: gulp link-checker // local site: gulp link-checker --url=http://localhost:3000 gulp.task('link-checker', function(done) { - return linkChecker(); + var method = 'get'; // the default 'head' fails for some sites + var exclude = [ + // Dart API docs aren't working yet; ignore them + '*/dart/latest/api/*', + // Somehow the link checker sees ng1 {{...}} in the resource page; ignore it + 'resources/%7B%7Bresource.url%7D%7D', + // API docs have links directly into GitHub repo sources; these can + // quickly become invalid, so ignore them for now: + '*/angular/tree/*', + // harp.json "bios" for "Ryan Schmukler", URL isn't valid: + 'http://slingingcode.com' + ]; + var blcOptions = { requestMethod: method, excludedKeywords: exclude}; + return linkChecker({ blcOptions: blcOptions }); }); @@ -594,11 +742,18 @@ gulp.task('_harp-compile', function() { }); gulp.task('_shred-devguide-examples', ['_shred-clean-devguide', '_copy-example-boilerplate'], function() { - return docShredder.shred( _devguideShredOptions); + // Split big shredding task into partials 2016-06-14 + const exPath = path.join(EXAMPLES_PATH, (argv.filter || '') + '*'); + var examplePaths = globby.sync(exPath, {ignore: ['**/node_modules', '**/_boilerplate']}); + var promise = Promise.resolve(true); + examplePaths.forEach(function (examplePath) { + promise = promise.then(() => docShredder.shredSingleExampleDir(_devguideShredOptions, examplePath)); + }); + return promise; }); gulp.task('_shred-devguide-shared-jade', ['_shred-clean-devguide-shared-jade', '_copy-example-boilerplate'], function() { - return docShredder.shred( _devguideShredJadeOptions); + return docShredder.shred(_devguideShredJadeOptions); }); gulp.task('_shred-clean-devguide-shared-jade', function(cb) { @@ -613,13 +768,19 @@ gulp.task('_shred-clean-devguide-shared-jade', function(cb) { }); gulp.task('_shred-clean-devguide', function(cb) { - var cleanPath = path.join(_devguideShredOptions.fragmentsDir, '**/*.*') + var cleanPath = path.join(_devguideShredOptions.fragmentsDir, (argv.filter || '*') + '*/*.*') return del([ cleanPath, '!**/*.ovr.*', '!**/_api/**']); }); gulp.task('_shred-api-examples', ['_shred-clean-api'], function() { - checkAngularProjectPath(); - return docShredder.shred( _apiShredOptions); + const promises = []; + gutil.log('Shredding API examples for languages: ' + langs.join(', ')); + langs.forEach(lang => { + if (lang === 'js') return; // JS is handled via TS. + checkAngularProjectPath(ngPathFor(lang)); + promises.push(docShredder.shred(_apiShredOptions)); + }); + return Q.all(promises); }); gulp.task('_shred-clean-api', function(cb) { @@ -628,15 +789,23 @@ gulp.task('_shred-clean-api', function(cb) { }); gulp.task('_zip-examples', function() { - exampleZipper.zipExamples(_devguideShredOptions.examplesDir, _devguideShredOptions.zipDir); - exampleZipper.zipExamples(_apiShredOptions.examplesDir, _apiShredOptions.zipDir); + new ExampleZipper(_devguideShredOptions.examplesDir, _devguideShredOptions.zipDir); + // exampleZipper.zipExamples(_apiShredOptions.examplesDir, _apiShredOptions.zipDir); }); // Linting gulp.task('lint', function() { - return gulp.src(['./public/docs/_examples/style-guide/ts/**/*.ts', '!./public/docs/_examples/style-guide/ts/**/*.avoid.ts']) + return gulp.src([ + './public/docs/_examples/**/*.ts', + '!./public/docs/_examples/**/ts-snippets/*.ts', + '!./public/docs/_examples/style-guide/ts/**/*.avoid.ts', + '!./public/docs/_examples/**/node_modules/**/*', + '!./public/docs/_examples/**/build/**/*', + // temporary until codelyzer is fixed mgechev/codelyzer#60 + '!./public/docs/_examples/animations/ts/app/hero.service.ts' + ]) .pipe(tslint({ rulesDirectory: ['node_modules/codelyzer'], configuration: require('./tslint.json') @@ -652,26 +821,44 @@ gulp.task('lint', function() { function harpCompile() { // Supposedly running in production makes harp faster // and less likely to drown in node_modules. - env({ - vars: { NODE_ENV: "production" } - }); + env({ vars: { NODE_ENV: "production" } }); gutil.log("NODE_ENV: " + process.env.NODE_ENV); + if(argv.page) harpJsonSetJade2NgTo(true); + + if(skipLangs && fs.existsSync(WWW) && backupApiHtmlFilesExist(WWW)) { + gutil.log(`Harp site recompile: skipping recompilation of API docs for [${skipLangs}]`); + gutil.log(`API docs will be copied from existing ${WWW} folder (if they exist).`) + del.sync(`${WWW}-backup`); // remove existing backup if it exists + renameIfExistsSync(WWW, `${WWW}-backup`); + } else { + gutil.log(`Harp full site compile, including API docs for all languages.`); + if (skipLangs) + gutil.log(`Ignoring API docs skip set (${skipLangs}) because full ` + + `site has not been built yet or some API HTML files are missing.`); + } + var deferred = Q.defer(); gutil.log('running harp compile...'); showHideExampleNodeModules('hide'); - var spawnInfo = spawnExt('npm',['run','harp', '--', 'compile', '.', './www' ]); + showHideApiDir('hide'); + var spawnInfo = spawnExt('npm',['run','harp', '--', 'compile', '.', WWW ]); spawnInfo.promise.then(function(x) { gutil.log("NODE_ENV: " + process.env.NODE_ENV); showHideExampleNodeModules('show'); + showHideApiDir('show'); + harpJsonSetJade2NgTo(false); if (x !== 0) { deferred.reject(x) } else { + restoreApiHtml(); deferred.resolve(x); } }).catch(function(e) { gutil.log("NODE_ENV: " + process.env.NODE_ENV); showHideExampleNodeModules('show'); + showHideApiDir('show'); + harpJsonSetJade2NgTo(false); deferred.reject(e); }); return deferred.promise; @@ -684,12 +871,8 @@ function linkChecker(options) { var blcOptions = options.blcOptions || {}; var customData = options.customData || {}; - var excludeBad; // don't bother reporting bad links matching this RegExp - if (argv.excludeBad) { - excludeBad = new RegExp(argv.excludeBad); - } else { - excludeBad = options.excludeBad === undefined ? /docs\/dart\/latest\/api/ : ''; - } + // don't bother reporting bad links matching this RegExp + var excludeBad = argv.excludeBad ? new RegExp(argv.excludeBad) : (options.excludeBad || ''); var previousPage; var siteUrl = argv.url || options.url || 'https://angular.io/'; @@ -736,7 +919,8 @@ function linkChecker(options) { var outputFile = path.join(process.cwd(), 'link-checker-results.txt'); var header = 'Link checker results for: ' + siteUrl + '\nStarted: ' + (new Date()).toLocaleString() + - '\nSkipping bad links matching regex: ' +excludeBad.toString() + '\n\n'; + '\nExcluded links (blc file globs): ' + blcOptions.excludedKeywords + + '\nExcluded links (custom --exclude-bad regex): ' + excludeBad.toString() + '\n\n'; gutil.log(header); fs.writeFileSync(outputFile, header); @@ -773,16 +957,79 @@ function showHideExampleNodeModules(showOrHide) { } } +// Show/hide the API docs harp source folder for every lang in skipLangs. +function showHideApiDir(showOrHide) { + skipLangs.forEach(lang => { + _showHideApiDir(lang, showOrHide); + }); +} +// Rename the API docs harp source folder for lang to/from 'api' to '_api-tmp-foo'. +function _showHideApiDir(lang, showOrHide) { + const vers = 'latest'; + const basePath = path.join(DOCS_PATH, lang, vers); + const apiDirPath = path.join(basePath, 'api'); + const disabledApiDirPath = path.join(basePath, '_api-tmp-hide-from-jade'); + const args = showOrHide == 'hide' + ? [apiDirPath, disabledApiDirPath] + : [disabledApiDirPath, apiDirPath]; + renameIfExistsSync(...args); +} + +// For each lang in skipLangs, copy the API dir from ${WWW}-backup to WWW. +function restoreApiHtml() { + const vers = 'latest'; + skipLangs.forEach(lang => { + const relApiDir = path.join('docs', lang, vers, 'api'); + const apiSubdir = path.join(WWW, relApiDir); + const backupApiSubdir = path.join(`${WWW}-backup`, relApiDir); + if (fs.existsSync(backupApiSubdir)) { + gutil.log(`cp ${backupApiSubdir} ${apiSubdir}`) + fs.copySync(backupApiSubdir, apiSubdir); + } + }); +} + +// For each lang in skipLangs, ensure API dir exists in folderName +function backupApiHtmlFilesExist(folderName) { + const vers = 'latest'; + var result = 1; + skipLangs.forEach(lang => { + if (lang === 'dart') return true; + const relApiDir = path.join('docs', lang, vers, 'api'); + const backupApiSubdir = path.join(folderName, relApiDir); + if (!fs.existsSync(backupApiSubdir)) { + gutil.log(`WARNING: API docs HTML folder doesn't exist: ${backupApiSubdir}`); + result = 0; + } + }); + return result; +} + +function harpJsonSetJade2NgTo(v) { + const harpJsonPath = path.join(ANGULAR_IO_PROJECT_PATH, 'harp.json'); + execSync(`perl -pi -e 's/("jade2ng": *)\\w+/$1${v}/' ${harpJsonPath}`); + const harpJson = require(harpJsonPath); + gutil.log(`jade2ng: ${harpJson.globals.jade2ng}`); +} + +// Copies fileNames into destPaths, setting the mode of the +// files at the destination as optional_destFileMode if given. // returns a promise -function copyFiles(fileNames, destPaths) { +function copyFiles(fileNames, originPath, destPaths, optional_destFileMode) { var copy = Q.denodeify(fsExtra.copy); + var chmod = Q.denodeify(fsExtra.chmod); var copyPromises = []; destPaths.forEach(function(destPath) { fileNames.forEach(function(fileName) { - var baseName = path.basename(fileName); - var destName = path.join(destPath, baseName); - var p = copy(fileName, destName, { clobber: true}); + var originName = path.join(originPath, fileName); + var destName = path.join(destPath, fileName); + var p = copy(originName, destName, { clobber: true}); + if(optional_destFileMode !== undefined) { + p = p.then(function () { + return chmod(destName, optional_destFileMode); + }); + } copyPromises.push(p); }); }); @@ -816,16 +1063,9 @@ function getNodeModulesPaths(basePath) { return paths; } -function getTypingsPaths(basePath) { - var paths = getExamplePaths(basePath).map(function(examplePath) { - return path.join(examplePath, "/typings"); - }); - return paths; -} - function getExamplePaths(basePath, includeBase) { // includeBase defaults to false - return getPaths(basePath, "example-config.json", includeBase) + return getPaths(basePath, _exampleConfigFilename, includeBase); } function getDartExampleWebPaths(basePath) { @@ -833,6 +1073,14 @@ function getDartExampleWebPaths(basePath) { return paths; } +function getUnitTestingPaths(basePath) { + var examples = getPaths(basePath, _exampleConfigFilename, true); + return examples.filter((example) => { + var exampleConfig = fs.readJsonSync(`${example}/${_exampleConfigFilename}`, {throws: false}); + return exampleConfig && !!exampleConfig.unittesting; + }); +} + function getPaths(basePath, filename, includeBase) { var filenames = getFilenames(basePath, filename, includeBase); var paths = filenames.map(function(fileName) { @@ -848,6 +1096,8 @@ function getFilenames(basePath, filename, includeBase) { // ignore (skip) the top level version. includePatterns.push("!" + path.join(basePath, "/" + filename)); } + // ignore (skip) the files in BOILERPLATE_PATH. + includePatterns.push("!" + path.join(BOILERPLATE_PATH, "/" + filename)); var nmPattern = path.join(basePath, "**/node_modules/**"); var filenames = globby.sync(includePatterns, {ignore: [nmPattern]}); return filenames; @@ -865,11 +1115,16 @@ function watchAndSync(options, cb) { var browserSync = require('browser-sync').create(); browserSync.init({proxy: 'localhost:9000'}); + // When using the --focus=name flag, only **/name/**/*.* example files and + // **/name.jade files are watched. This is useful for performance reasons. + // Example: gulp serve-and-sync --focus=architecture + var focus = argv.focus; + if (options.devGuide) { - devGuideExamplesWatch(_devguideShredOptions, browserSync.reload); + devGuideExamplesWatch(_devguideShredOptions, browserSync.reload, focus); } if (options.devGuideJade) { - devGuideSharedJadeWatch( { jadeDir: DOCS_PATH}, browserSync.reload); + devGuideSharedJadeWatch( { jadeDir: DOCS_PATH}, browserSync.reload, focus); } if (options.apiDocs) { apiSourceWatch(browserSync.reload); @@ -884,11 +1139,12 @@ function watchAndSync(options, cb) { // returns a promise; function askDeploy() { - + // Show user what the currently active firebase project is: + execSync('firebase use', {stdio:[0,1,2]}); prompt.start(); var schema = { name: 'shouldDeploy', - description: 'Deploy to Firebase? (y/n): ', + description: `Deploy ${WWW} to firebase? (y/n)`, type: 'string', pattern: /Y|N|y|n/, message: "Respond with either a 'y' or 'n'", @@ -910,7 +1166,7 @@ function filterOutExcludedPatterns(fileNames, excludeMatchers) { } function apiSourceWatch(postBuildAction) { - var srcPattern = [path.join(ANGULAR_PROJECT_PATH, 'modules/@angular/src/**/*.*')]; + var srcPattern = [path.join(ANGULAR_PROJECT_PATH, 'modules/@angular/**/*.*')]; gulp.watch(srcPattern, {readDelay: 500}, function (event, done) { gutil.log('API source changed'); gutil.log('Event type: ' + event.event); // added, changed, or deleted @@ -937,13 +1193,16 @@ function apiExamplesWatch(postShredAction) { }); } -function devGuideExamplesWatch(shredOptions, postShredAction) { - var includePattern = path.join(shredOptions.examplesDir, '**/*.*'); +function devGuideExamplesWatch(shredOptions, postShredAction, focus) { + var watchPattern = focus ? '{' + focus + ',cb-' + focus+ '}/**/*.*' : '**/*.*'; + var includePattern = path.join(shredOptions.examplesDir, watchPattern); // removed this version because gulp.watch has the same glob issue that dgeni has. // var excludePattern = '!' + path.join(shredOptions.examplesDir, '**/node_modules/**/*.*'); // gulp.watch([includePattern, excludePattern], {readDelay: 500}, function (event, done) { - var files = globby.sync( [includePattern], { ignore: [ '**/node_modules/**', '**/_fragments/**', - '**/dart/build/**' ]}); + var ignoreThese = [ '**/node_modules/**', '**/_fragments/**', '**/dist/**', + '**/dart/.pub/**', '**/dart/build/**']; + ignoreThese = ignoreThese.concat(_exampleBoilerplateFiles.map((file) => `public/docs/_examples/*/*/${file}`)); + var files = globby.sync( [includePattern], { ignore: ignoreThese }); gulp.watch([files], {readDelay: 500}, function (event, done) { gutil.log('Dev Guide example changed') gutil.log('Event type: ' + event.type); // added, changed, or deleted @@ -952,12 +1211,14 @@ function devGuideExamplesWatch(shredOptions, postShredAction) { }); } -function devGuideSharedJadeWatch(shredOptions, postShredAction) { - var includePattern = path.join(DOCS_PATH, '**/*.jade'); +function devGuideSharedJadeWatch(shredOptions, postShredAction, focus) { + var watchPattern = focus ? '**/' + focus + '.jade' : '**/*.jade'; + var includePattern = path.join(DOCS_PATH, watchPattern); // removed this version because gulp.watch has the same glob issue that dgeni has. // var excludePattern = '!' + path.join(shredOptions.jadeDir, '**/node_modules/**/*.*'); // gulp.watch([includePattern, excludePattern], {readDelay: 500}, function (event, done) { - var files = globby.sync( [includePattern], { ignore: [ '**/node_modules/**', '**/_fragments/**']}); + var ignoreThese = [ '**/node_modules/**', '**/_examples/**', '**/_fragments/**', '**/latest/api/**' ]; + var files = globby.sync( [includePattern], { ignore: ignoreThese}); gulp.watch([files], {readDelay: 500}, function (event, done) { gutil.log('Dev Guide jade file changed') gutil.log('Event type: ' + event.type); // added, changed, or deleted @@ -975,7 +1236,8 @@ function buildApiDocs(targetLanguage) { try { // Build a specialized package to generate different versions of the API docs var package = new Package('apiDocs', [require(path.resolve(TOOLS_PATH, 'api-builder/angular.io-package'))]); - package.config(function(targetEnvironments, writeFilesProcessor, readTypeScriptModules) { + package.config(function(log, targetEnvironments, writeFilesProcessor, readTypeScriptModules, linkDocsInlineTagDef) { + log.level = _dgeniLogLevel; ALLOWED_LANGUAGES.forEach(function(target) { targetEnvironments.addAllowed(target); }); if (targetLanguage) { targetEnvironments.activate(targetLanguage); @@ -984,23 +1246,19 @@ function buildApiDocs(targetLanguage) { // Don't read TypeScript modules if we are not generating API docs - Dart I am looking at you! readTypeScriptModules.$enabled = false; } - writeFilesProcessor.outputFolder = targetLanguage + '/latest/api'; + linkDocsInlineTagDef.lang = targetLanguage; + linkDocsInlineTagDef.vers = 'latest'; + writeFilesProcessor.outputFolder = path.join(targetLanguage, linkDocsInlineTagDef.vers, 'api'); } }); var dgeni = new Dgeni([package]); return dgeni.generate(); } catch(err) { - gutil.log(err); - gutil.log(err.stack); + console.error(err); + console.error(err.stack); throw err; } - - function copyApiDocsToJsFolder() { - // Make a copy of the JS API docs to the TS folder - return gulp.src([path.join(DOCS_PATH, 'ts/latest/api/**/*.*'), '!' + path.join(DOCS_PATH, 'ts/latest/api/index.jade')]) - .pipe(gulp.dest('./public/docs/js/latest/api')); - } } function buildShredMaps(shouldWrite) { @@ -1010,7 +1268,8 @@ function buildShredMaps(shouldWrite) { fragmentsDir: _devguideShredOptions.fragmentsDir, jadeDir: './public/docs', outputDir: './public/docs', - writeFilesEnabled: shouldWrite + writeFilesEnabled: shouldWrite, + logLevel: _dgeniLogLevel }; return docShredder.buildShredMap(options).then(function(docs) { return docs; @@ -1173,8 +1432,21 @@ function execCommands(cmds, options, cb) { }); } -function checkAngularProjectPath() { - if (!fs.existsSync(ANGULAR_PROJECT_PATH)) { - throw new Error('API related tasks require the angular2 repo to be at ' + path.resolve(ANGULAR_PROJECT_PATH)); +function ngPathFor(lang) { + return ANGULAR_PROJECT_PATH + (lang === 'dart' ? '-dart' : ''); +} + +function checkAngularProjectPath(_ngPath) { + var ngPath = path.resolve(_ngPath || ngPathFor('ts')); + if (fs.existsSync(ngPath)) return; + throw new Error('API related tasks require the angular2 repo to be at ' + ngPath); +} + +function renameIfExistsSync(oldPath, newPath) { + if (fs.existsSync(oldPath)) { + gutil.log(`Rename: mv ${oldPath} ${newPath}`); + fs.renameSync(oldPath, newPath); + } else { + gutil.log(`renameIfExistsSync cannot rename, path not found: ${oldPath}`); } } diff --git a/harp.json b/harp.json index e79fb92241..82e5ca762f 100644 --- a/harp.json +++ b/harp.json @@ -4,9 +4,7 @@ "description": "Angular is a development platform for building mobile and desktop web applications", "keywords": "Angular, AngularJS, AngularDart, Javscript, Dart, Framework, JavaScript MVC, Google", "siteURL": "http://angular.io", - "jsLatest": "2.0.0-beta.02", - "dartLatest": "2.0.0-beta.02", - + "jade2ng": false, "bios": { "misko": { "name": "Miško Hevery", @@ -31,7 +29,7 @@ "picture": "/resources/images/bios/naomi.jpg", "twitter": "naomitraveller", "website": "http://google.com/+NaomiBlack", - "bio": "Naomi is Angular's TPM generalist and jack-of-all-trades. She leads Angular Material and AngularDart, and acts as webmaster for angular.io. She's been at Google since 2006, as a technical program manager on projects ranging from Accessibility to Google Transit. She fights daleks in her spare time.", + "bio": "Naomi is Angular's TPM generalist and jack-of-all-trades. She supports Angular's internal Google users and solves hard-to-define problems. She's been at Google since 2006, as a technical program manager on projects ranging from Accessibility to Google Transit. She fights daleks in her spare time.", "type": "Lead" }, @@ -40,7 +38,7 @@ "picture": "/resources/images/bios/brad-green.jpg", "twitter": "bradlygreen", "website": "https://plus.google.com/+BradGreen", - "bio": "Brad Green works at Google as an engineering director. Brad manages the Google Sales Platform suite of projects as well as the AngularJS framework. Prior to Google, Brad worked on the early mobile web at AvantGo, founded and sold startups, and spent a few hard years toiling as a caterer. Brad's first job out of school was as lackey to Steve Jobs at NeXT Computer writing demo software and designing his slide presentations. Brad lives in Mountain View, CA with his wife and two children.", + "bio": "Brad Green works at Google as an engineering director. Brad manages the Google Sales Platform suite of projects as well as the AngularJS framework. Prior to Google, Brad worked on the early mobile web at AvantGo, founded and sold startups, and spent a few hard years toiling as a caterer. Brad's first job out of school was as lackey to Steve Jobs at NeXT Computer writing demo software and designing his slide presentations. Brad enjoys throwing dinner parties with his wife Heather and putting on plays with his children.", "type": "Lead" }, @@ -49,7 +47,16 @@ "picture": "/resources/images/bios/juleskremer.jpg", "twitter": "jules_kremer", "website": "https://plus.google.com/+JulesKremer", - "bio": "Jules is a TPM on the Angular team. When not working with developers, Jules is often bending into pretzel-like shapes, climbing mountains or drinking really awesome beer.", + "bio": "Jules is Head of Angular Developer Relations at Google. When not working with developers, Jules is often bending into pretzel-like shapes, climbing mountains or drinking really awesome beer.", + "type": "Lead" + }, + + "jelbourn": { + "name": "Jeremy Elbourn", + "picture": "/resources/images/bios/jelbourn.jpg", + "twitter": "jelbourn", + "website": "https://plus.google.com/+JeremyElbourn/", + "bio": "Angular Material Team Lead. FE Engineer @ Google specializing in AngularJS, component design, and the cleanest of code.", "type": "Lead" }, @@ -58,7 +65,7 @@ "picture": "/resources/images/bios/pete.jpg", "twitter": "petebd", "website": "http://www.bacondarwin.com", - "bio": "Angular 1 for JS Team Lead. Pete has been working on the core team since 2012 and became the team lead for the Angular 1 for JS branch in November 2014. He has co-authored a book on AngularJS and regularly talks about and teaches Angular.", + "bio": "AngularJS for JS Team Lead. Pete has been working on the core team since 2012 and became the team lead for the AngularJS for JS branch in November 2014. He has co-authored a book on AngularJS and regularly talks about and teaches Angular.", "type": "Lead" }, @@ -67,32 +74,39 @@ "picture": "/resources/images/bios/thomas.jpg", "twitter": "ThomasBurleson", "website": "http://www.solutionOptimist.com", - "bio": "Thomas is a software architect for commercial & open-source web solutions. With over 15 years working on thin-client RUX [using Flex and Angular], Thomas is passionate about software excellence, and distributed team-development. Thomas is the Team Lead for Google's Angular Material OSS. His mission is to work with a fantastic team and help deliver a framework of UX components for the AngularJS frameworks (v1.x and v2). He previously worked at SiriusXM as a UX and Principal Architect for their Internet Radio applications.", + "bio": "AngularJS Material and @angular/flex-layout Team Lead. Thomas joined the core team in 2014. He leads a team of developers working on UX components for AngularJS.", "type": "Lead" }, - - "victorsavkin": { - "name": "Victor Savkin", - "picture": "/resources/images/bios/victor.jpg", - "twitter": "victorsavkin", - "bio": "Victor works on Angular at Google. He is interested in functional programming and client-side applications. Being a language nerd he spends a lot of his time playing with TypeScript, Dart, Elm, Haskell, and Clojure.", + "stephenfluin": { + "name": "Stephen Fluin", + "picture": "/resources/images/bios/stephenfluin.jpg", + "twitter": "stephenfluin", + "website": "https://plus.google.com/+stephenfluin", + "bio": "Stephen is a Developer Advocate working on the Angular team. Before joining Google, he was a Google Expert. Stephen loves to help enterprises use technology more effectively.", + "type": "Google" + }, + "robwormald": { + "name": "Rob Wormald", + "picture": "/resources/images/bios/rob-wormald.jpg", + "twitter": "robwormald", + "website": "http://github.com/robwormald", + "bio": "Rob is a Developer Advocate on the Angular team at Google. He's the Angular team's resident reactive programming geek and founded the Reactive Extensions for Angular project, ngrx.", + "type": "Google" + }, + "aaronzhang": { + "name": "Aaron Zhang (章小飞)", + "picture": "/resources/images/bios/xiaofei.jpg", + "twitter": "", + "website": "http://github.com/damoqiongqiu", + "bio": "Aaron is Angular's developer PM in China. He is the lead for angular.cn and social channels in China, and helps developers in China's enterprise and open source communities to be successful with Angular. One of the earliest Angular developers in China since Angular 2012, he translated the first books on Angular into Chinese. Aaron joined the Google team in 2016.", "type": "Google" }, - "tobias": { "name": "Tobias Bosch", "picture": "/resources/images/bios/tobias.jpg", "twitter": "tbosch1009", "website": "https://plus.google.com/+TobiasBosch", - "bio": "Tobias Bosch is a software engineer at Google. He is part of the Angular core team and works on Angular 2.", - "type": "Google" - }, - - "brianford": { - "name": "Brian Ford", - "picture": "/resources/images/bios/brian-ford.jpg", - "twitter": "briantford", - "bio": "Brian works on the AngularJS core team at Google where he tries his very best to make computers do the right thing.", + "bio": "Tobias Bosch is a software engineer at Google. He is part of the Angular core team and works on Angular.", "type": "Google" }, @@ -109,19 +123,10 @@ "name": "David East", "picture": "/resources/images/bios/david-east.jpg", "twitter": "_davideast", + "website":"https://github.com/davideast", "bio": "David East is a Developer Programs Engineer at Google. He works full-time on the Firebase team and part-time on the Angular core team.", "type": "Google" }, - - "jeffcross": { - "name": "Jeff Cross", - "picture": "/resources/images/bios/jeff-cross.jpg", - "twitter": "jeffbcross", - "website": "https://twitter.com/jeffbcross", - "bio": "Jeff is a member of the Angular core team at Google, focusing on data access and application performance. Jeff has an extensive background in open source software, marketing, and user experience design. When not in front of a computer, he spends his time doing whatever his kids tell him to do, which usually involves playing music or making gadgets.", - "type": "Google" - }, - "alexeagle": { "name": "Alex Eagle", "picture": "/resources/images/bios/alex-eagle.jpg", @@ -154,16 +159,7 @@ "picture": "/resources/images/bios/alex-rickabaugh.jpg", "twitter": "synalx", "website": "https://plus.google.com/+AlexRickabaugh/about", - "bio": "I am a new member of the Angular team, solving challenges of data access and RPC for applications of any scale.", - "type": "Google" - }, - - "jelbourn": { - "name": "Jeremy Elbourn", - "picture": "/resources/images/bios/jelbourn.jpg", - "twitter": "jelbourn", - "website": "https://plus.google.com/+JeremyElbourn/", - "bio": "FE Engineer @ Google specializing in AngularJS, component design, and the cleanest of code.", + "bio": "Core team member working to optimize the Angular platform for the next generation of applications, including mobile. Before joining the Angular team, Alex worked in the Google sales organization where he helped build the first large Angular application within Google.", "type": "Google" }, @@ -190,10 +186,26 @@ "picture": "/resources/images/bios/hansl.jpg", "twitter": "hanslatwork", "website": "http://www.codingatwork.com/", - "bio": "Hans is a software engineer at Google on the Angular team and was previously at Slack. He works everyday to help make it easier for everyone to create beautiful, consistent web applications using Angular2, using Material Design components and the CLI tool.", + "bio": "Hans is a software engineer at Google on the Angular team and was previously at Slack. He works everyday to help make it easier for everyone to create beautiful, consistent web applications using Angular, using Material Design components and the CLI tool.", "type": "Google" }, + "victorsavkin": { + "name": "Victor Savkin", + "picture": "/resources/images/bios/victor.jpg", + "twitter": "victorsavkin", + "website": "http://victorsavkin.com/", + "bio": "Victor has been on the Angular team since the inception of Angular. While at Google, Victor developed dependency injection, change detection, forms, and the router. Today he is a co-founder at nrwl.io.", + "type": "Community" + }, + "jeffcross": { + "name": "Jeff Cross", + "picture": "/resources/images/bios/jeff-cross.jpg", + "twitter": "jeffbcross", + "website": "https://twitter.com/jeffbcross", + "bio": "Jeff was one of the earliest core team members on AngularJS. He developed the Angular http and AngularFire modules, contributed to RxJS 5, and was most recently the Tech Lead of the Angular Mobile team at Google. Jeff is a former Googler and co-founder at nrwl.io.", + "type": "Community" + }, "alexwolfe": { "name": "Alex Wolfe", "picture": "/resources/images/bios/alex-wolfe.jpg", @@ -208,7 +220,7 @@ "picture": "/resources/images/bios/marcy.jpg", "twitter": "marcysutton", "website": "http://marcysutton.com", - "bio": "Marcy Sutton is a senior front-end engineer at Deque Systems, where she works on the axe-core team focusing on accessibility test integrations. Marcy is passionate about making the web accessible for everyone. She is a core team member to ngMaterial 1 and 2, where she regularly brings her accessibility expertise to the table–she is also a primary contributor to the ngAria module as well as an accessibility plugin for Protractor. She's in love with riding bicycles and snowboards and can often be found outside.", + "bio": "Marcy Sutton is a senior front-end engineer at Deque Systems, where she works on the axe-core team focusing on accessibility test integrations. Marcy is passionate about making the web accessible for everyone. She is a core team member to Angular Material, where she regularly brings her accessibility expertise to the table–she is also a primary contributor to the ngAria module as well as an accessibility plugin for Protractor. She's in love with riding bicycles and snowboards and can often be found outside.", "type": "Community" }, @@ -225,36 +237,11 @@ "name": "Lucas Mirelmann", "picture": "/resources/images/bios/lucas.jpg", "twitter": "lgalfaso", + "website": "https://github.com/lgalfaso", "bio": "Lucas works as a Software Engineer at Google and is a core Angular contributor.", "type": "Google" }, - "tonyc": { - "name": "Tony Childs", - "picture": "/resources/images/bios/tonyc.jpg", - "twitter": "javatricks", - "website": "http://www.stupidjavatricks.com", - "bio": "Tony Childs is a consultant working for Google. He is a contributor to the Angular Material project and is responsible for the md-icon component.", - "type": "Google" - }, - - "ryan": { - "name": "Ryan Schmukler", - "picture": "/resources/images/bios/ryan.jpg", - "twitter": "rschmukler", - "website": "http://slingingcode.com", - "bio": "Developer on ngMaterial. Full-stack JavaScript hacker. Open-source contributor with libraries totaling over 225K downloads.", - "type": "Community" - }, - - "rmesserle": { - "name": "Robert Messerle", - "picture": "/resources/images/bios/rmesserle.jpg", - "twitter": "Bobbo_O", - "bio": "Robert is a software engineer on the Angular team at Google, working primarily on the Angular Material project.", - "type": "Google" - }, - "kathy": { "name": "Kathy Walrath", "picture": "/resources/images/bios/kathy.jpg", @@ -263,17 +250,12 @@ "bio": "Kathy writes and edits docs about Dart and related technologies. Before Google, she worked at Sun, NeXT, and HP. Long ago, Kathy co-created and maintained The Java Tutorial.", "type": "Google" }, - "scott": { - "name": "Scott Hyndman", - "picture": "/resources/images/bios/scott.jpg", - "bio": "Scott works for Google on the Material Design team, where he brings designers' dreams to life on the web.", - "type": "Google" - }, "kara": { "name": "Kara Erickson", "picture": "/resources/images/bios/kara-erickson.jpg", "twitter": "karaforthewin", + "website": "https://github.com/kara", "bio": "Kara is a software engineer on the Angular team at Google and a co-organizer of the Angular-SF Meetup. Prior to Google, she helped build UI components in Angular for guest management systems at OpenTable. She enjoys snacking indiscriminately and probably other things too.", "type": "Google" }, @@ -286,14 +268,28 @@ "bio": "Chuck is a Software Engineer on the Angular team at Google. He is a programming language geek, UI framework and component library veteran, and has a passion for simplifying the task of programming. Before Google, he worked at Microsoft and Borland.", "type": "Google" }, - "stephenfluin": { - "name": "Stephen Fluin", - "picture": "/resources/images/bios/stephenfluin.jpg", - "twitter": "stephenfluin", - "website": "https://plus.google.com/+stephenfluin", - "bio": "Stephen is a Developer Advocate working on the Angular team. Before joining Google, he was a Google Expert. Stephen loves to help enterprises use technology more effectively.", + "vikram": { + "name": "Vikram Subramanian", + "picture": "/resources/images/bios/vikram.jpg", + "twitter": "vikerman", + "bio": "Vikram is a Software Engineer on the Angular team focused on Engineering Productivity. That means he makes sure people on the team can move fast and not break things. Vikram enjoys doing Yoga and going on walks with his daughter.", + "type": "Google" + }, + "maxsills": { + "name": "Max Sills", + "picture": "/resources/images/bios/max-sills.jpg", + "twitter": "angularjs", + "website": "http://google-opensource.blogspot.com/", + "bio": "Max Sills is Angular's Open Source lawyer.", + "type": "Google" + }, + "shannon": { + "name": "Shannon Ayres", + "picture": "/resources/images/bios/shannon.jpg", + "bio": "Shannon is a technical editor in Developer Relations at Google. She loves movies, especially Sunset Boulevard, and her favorite TV show is The Walking Dead. Her mission: Righting wrong writing!", "type": "Google" }, + "pawel": { "name": "Pawel Kozlowski", "picture": "/resources/images/bios/pawel.jpg", @@ -307,7 +303,7 @@ "picture": "/resources/images/bios/michal.jpg", "twitter": "m_gol", "website": "https://plus.google.com/u/0/103101124310040612163/", - "bio": "Front-end developer at Laboratorium EE, core contributor to Angular & jQuery. Makes sure Angular 1 & jQuery work fine together. Interested in new JavaScript standards.", + "bio": "Front-end developer at Laboratorium EE, core contributor to Angular & jQuery. Makes sure AngularJS & jQuery work fine together. Interested in new JavaScript standards.", "type": "Community" }, @@ -321,7 +317,7 @@ "elad": { "name": "Elad Bezalel", "picture": "/resources/images/bios/eladbezalel.jpg", - "website": "https://github.com/EladBezalel", + "website": "https://github.com/EladBezalel", "bio": "Elad is a fullstack developer with a very strong love for design. Since 8 years old, he's been designing in Photoshop and later on fell in love with programing. This strong bond between design and computer programming gave birth to a new kind of love. And he is currently doing the combination of both, as a core member of the ngMaterial project.", "type": "Community" }, @@ -331,7 +327,7 @@ "picture": "/resources/images/bios/marclaval.jpg", "twitter": "marclaval", "website": "https://github.com/mlaval", - "bio": "Marc is a manager at Amadeus where he leads the team in charge of developing and recommending UI frameworks for the company. He is also an open source developer and a contributor to Angular 2.", + "bio": "Marc is a manager at Amadeus where he leads the team in charge of developing and recommending UI frameworks for the company. He is also an open source developer and a contributor to Angular.", "type": "Community" }, @@ -349,7 +345,7 @@ "picture": "/resources/images/bios/patrick-stapleton.jpg", "twitter": "gdi2290", "website": "https://angularclass.com", - "bio": "Also know as PatrickJS where JS stands for his middle and last names. Patrick is very active in Open-Source with over 4,300+ contributions in the last year alone on projects such as Angular2, AngularJS, FalcorJS, Docker, Bootstrap, gulp, and redis to name a few. He is also working on the development of Angular 2 server-side rendering as Universal Angular 2 and teaching Modern Web Development at AngularClass. He was previously the CTO of Keychain Logistics, a HackReactor Instructor and Alum.", + "bio": "Also know as PatrickJS where JS stands for his middle and last names. Patrick is very active in Open-Source with over 4,300+ contributions in the last year alone on projects such as Angular, AngularJS, FalcorJS, Docker, Bootstrap, gulp, and redis to name a few. He is also working on the development of Angular server-side rendering as Universal Angular and teaching Modern Web Development at AngularClass. He was previously the CTO of Keychain Logistics, a HackReactor Instructor and Alum.", "type": "Community" }, @@ -365,9 +361,11 @@ "name": "Ward Bell", "picture": "/resources/images/bios/wardbell.jpg", "website": "https://github.com/wardbell", + "twitter": "wardbell", "bio": "Ward is an all-around developer with JavaScript, node, and .net chops. He's a frequent conference speaker and podcaster, trainer, Google Developer Expert for Angular, Microsoft MVP, and PluralSight author. He is also president of IdeaBlade, an enterprise software consulting firm and the makers of breeze.js. He would like to get more sleep and spend more time in the mountains.", "type": "Community" }, + "johnpapa": { "name": "John Papa", "picture": "/resources/images/bios/john-papa.jpg", @@ -376,13 +374,15 @@ "bio": "John is a Google Developer Expert, Microsoft Regional Director and MVP, frequent author of courses for Pluralsight, a former technology Evangelist for Microsoft front end teams, and author of the popular Angular Style Guide. He can often be found speaking around the world at keynotes and sessions for many conferences. You can always find John at johnpapa.net or on twitter at @john_papa.", "type": "Community" }, + "martinstaffa": { "name": "Martin Staffa", "picture": "/resources/images/bios/martinstaffa.jpg", "twitter": "Narretz", - "bio": "Martin is an English major turned web developer who loves frontend stuff. He's been part of the Angular 1 team since 2014. If you can't find him roaming the Github issue queues, he's probably out with his camera somewhere.", + "bio": "Martin is an English major turned web developer who loves frontend stuff. He's been part of the AngularJS team since 2014. If you can't find him roaming the Github issue queues, he's probably out with his camera somewhere.", "type": "Community" }, + "topherfangio": { "name": "Topher Fangio", "picture": "/resources/images/bios/topherfangio.jpg", @@ -391,6 +391,7 @@ "bio": "Topher loves the web and how it empowers new forms of creativity, connection and business. He is currently a core contributor on the Angular Material project and sometimes blogs about random things.", "type": "Community" }, + "filipesilva": { "name": "Filipe Silva", "picture": "/resources/images/bios/filipe-silva.jpg", @@ -399,6 +400,7 @@ "bio": "Filipe is a passion-driven developer that always strives for the most elegant solution for each problem. He is currently an author for Angular.io, a core contributor for Angular-CLI and senior front end engineer at KonnectAgain. When not busy going through PRs, you can find him scouring reddit for new dinner recipes to cook or enjoying a craft beer in Dublin.", "type": "Community" }, + "teropa": { "name": "Tero Parviainen", "picture": "/resources/images/bios/teropa.jpg", @@ -407,21 +409,133 @@ "bio": "Tero is an independent software developer and writer. He's been building web applications for his whole professional career, and has almost figured out how to do vertical centering in CSS.", "type": "Community" }, - "deborah": { + + "deborah": { "name": "Deborah Kurata", "picture": "/resources/images/bios/deborah.jpg", "twitter": "deborahkurata", "website": "http://blogs.msmvps.com/deborahk/", "bio": "Deborah is an independent software developer and author. She is author of several Pluralsight courses including: 'Angular 2: Getting Started'", "type": "Community" - }, - "jesusrodriguez": { + }, + + "jesusrodriguez": { "name": "Jesús Rodríguez", "picture": "/resources/images/bios/jesus-rodriguez.jpg", "twitter": "foxandxss", "website": "http://angular-tips.com", "bio": "Jesus is an open source lover, a book author and editor, and AngularUI lead developer. He is currently a core contributor to the UI Bootstrap project.", "type": "Community" + }, + + "torgeirhelgevold": { + "name": "Torgeir Helgevold", + "picture": "/resources/images/bios/torgeirhelgevold.jpg", + "twitter": "helgevold", + "website": "http://www.syntaxsuccess.com", + "bio": "Torgeir (Tor) is a front-end architect with a passion for JavaScript development. He is also an author for angular.io and an active tech blogger.", + "type": "Community" + }, + + "fatimaremtullah": { + "name": "Fatima Remtullah", + "picture": "/resources/images/bios/fatima.jpg", + "twitter": "amitafr", + "website": "http://www.amitafremtullah.com", + "bio": "Fatima is a Product Designer and Front-End Developer. When she is not nerding out she is probably eating an abundance of cookies.", + "type": "Community" + }, + + "eric": { + "name": "Eric Jimenez", + "picture": "/resources/images/bios/eric.jpg", + "twitter": "_ericjim", + "website": "http://eric.to/", + "bio": "Eric is a gamer, writer, and programmer.", + "type": "Community" + }, + + "mikeryan": { + "name": "Mike Ryan", + "picture": "/resources/images/bios/mikeryan.jpg", + "twitter": "mikeryan52", + "website": "https://medium.com/@MikeRyan52", + "bio": "Mike Ryan is a Software Engineer at Synapse Wireless, working on solving challenging problems in the internet-of-things space. He is an advocate of reactive programming and a core contributor to the ngrx project.", + "type": "Community" + }, + + "rex": { + "name": "Rex Ye", + "picture": "/resources/images/bios/rex.jpg", + "twitter": "rexebin", + "bio": "Rex is a full-stack developer. He maintains the Angular.cn website with his old pal Ralph Wang and he plays a key role in bridging between the Chinese Angular community and the world-wide community. He loves playing with flashy new technologies and enjoys the challenge of mastering new skills. His biggest challenge to date is figuring out how to sooth a crying 4-month-old baby.", + "type": "Community" + }, + + "ralph": { + "name": "Ralph Wang", + "picture": "/resources/images/bios/ralph.jpg", + "twitter": "ralph_wang_gde", + "bio": "Ralph(Zhicheng Wang) is a senior consultant at ThoughWorks and also a GDE. He is a technology enthusiast and he is a passionate advocate of “Simplicity, Professionalism and Sharing”. In his eighteen years of R&D career, he worked as tester, R&D engineer, project manager, product manager and CTO. He is looking forward to the birth of his baby.", + "type": "Community" + }, + + "brandonroberts": { + "name": "Brandon Roberts", + "picture": "/resources/images/bios/brandonroberts.jpg", + "twitter": "brandontroberts", + "website": "https://github.com/brandonroberts", + "bio": "Brandon is a front-end developer for a game studio developing web applications for STEM-based learning games. He is also a natural born troubleshooter who helps solve Angular issues on Github and Gitter support channels, particularly dealing with routing. He is also a member of the Angular docs team.", + "type": "Community" + }, + + "crisbeto": { + "name": "Kristiyan Kostadinov", + "picture": "/resources/images/bios/crisbeto.jpg", + "website": "http://crisbeto.com/", + "bio": "Kristiyan is a front-end developer, passionate open-source contributor and a core team member on Angular Material.", + "type": "Community" + }, + + "gkalpak": { + "name": "Georgios Kalpakas", + "picture": "/resources/images/bios/gkalpak.jpg", + "twitter": "gkalpakas", + "website": "https://github.com/gkalpak", + "bio": "George is a Software Engineer with a passion for chess, robotics and automating stuff. He has a strong need to know how things work (so if you already know, he'd love to have a talk with you). He has been a member of the AngularJS team since 2014. When not doing geeky stuff, he is probably trying to convince his wife and kids to apply programming principles in real life. (Or is it the other way around?)", + "type": "Community" + }, + + "kapunahelewong": { + "name": "Kapunahele Wong", + "picture": "/resources/images/bios/kapunahelewong.jpg", + "website": " https://github.com/kapunahelewong", + "twitter": "kapunahele", + "bio": "Kapunahele is a front-end developer and contributor to angular.io. She loves just about anything to do with JavaScript, Angular and electronics. She enjoys mapping Hawaiian star names and constellations to Western ones and loves dancing native Hawaiian hula.", + "type": "Community" + }, + + "devversion": { + "name": "Paul Gschwendtner", + "picture": "/resources/images/bios/devversion.jpg", + "website": "http://github.com/DevVersion/", + "twitter": "DevVersion", + "bio": "Paul is a 16-year-old developer living in Germany. While he attends school, Paul works as a core team member on Angular Material. Paul focuses on tooling and building components for Angular.", + "type": "Community" + }, + + "mmalerba": { + "name": "Miles Malerba", + "picture": "/resources/images/bios/mmalerba.jpg", + "bio": "Miles is a software engineer on the Angular Material team at Google. In addition to Javascripting he enjoys eating food and ogling cute puppies.", + "type": "Google" + }, + + "jasonaden": { + "name": "Jason Aden", + "picture": "/resources/images/bios/jasonaden.jpg", + "bio": "Jason is a software engineer at Google on the Angular Core team. He is enthusiastic about Angular and application development in the modern age. In his free time Jason enjoys spending time with his wife and four children and doing outdoor activities (hiking, fishing, snowboarding, etc.).", + "type": "Google" } } } diff --git a/package.json b/package.json index dcc67e9351..2879b1483d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "angular.io", "version": "0.0.0", "private": true, - "description": "Angular 2 documentation", + "description": "Angular documentation", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -15,36 +15,35 @@ "type": "git", "url": "https://github.com/angular/angular.io.git" }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/angular/angular.io/blob/master/LICENSE" - } - ], + "license": "MIT", "bugs": { "url": "" }, "devDependencies": { "archiver": "^1.0.0", "assert-plus": "^1.0.0", + "bootstrap": "3.3.6", "broken-link-checker": "0.7.1", "browser-sync": "^2.9.3", "canonical-path": "0.0.2", + "cheerio": "^0.20.0", + "codelyzer": "0.0.26", "cross-spawn": "^4.0.0", - "codelyzer": "0.0.20", "del": "^2.2.0", "dgeni": "^0.4.0", - "dgeni-packages": "^0.13.0", + "dgeni-packages": "^0.16.0", "diff": "^2.1.3", "fs-extra": "^0.30.0", "globby": "^4.0.0", "gulp": "^3.5.6", "gulp-env": "0.4.0", + "gulp-less": "^3.1.0", + "gulp-sass": "^2.3.2", "gulp-task-listing": "^1.0.1", "gulp-tslint": "^5.0.0", "gulp-util": "^3.0.6", "gulp-watch": "^4.3.4", - "harp": "^0.20.3", + "harp": "^0.21.0", "html2jade": "^0.8.4", "indent-string": "^2.1.0", "jasmine-core": "^2.3.4", @@ -66,7 +65,8 @@ "protractor": "^3.0.0", "q": "^1.4.1", "tree-kill": "^1.0.0", - "tslint": "^3.2.2", + "tslint": "^3.15.1", + "typescript": "~2.0.10", "yargs": "^4.7.1" }, "dependencies": { diff --git a/public/_data.json b/public/_data.json index cc7f331656..3b224f69eb 100644 --- a/public/_data.json +++ b/public/_data.json @@ -2,7 +2,7 @@ "index": { "hero": "home", "title": "One framework.", - "subtitle": "Mobile and desktop." + "subtitle": "Mobile & desktop." }, "features": { @@ -15,10 +15,6 @@ "autoformat": "true" }, - "news": { - "title": "News" - }, - "events": { "title": "Events", "subtitle": "Where we'll be presenting" @@ -31,21 +27,5 @@ "presskit": { "title": "Press Kit" - }, - - "books": { - "title": "Books" - }, - - "training": { - "title": "Training" - }, - - "communities": { - "title": "Communities" - }, - - "tooling": { - "title": "Tooling and Libraries" } } diff --git a/public/_includes/_footer.jade b/public/_includes/_footer.jade index 1cc8c57ace..421c208aa1 100644 --- a/public/_includes/_footer.jade +++ b/public/_includes/_footer.jade @@ -7,25 +7,25 @@ if version && language else - var styleguide = "/docs/ts/latest/styleguide.html" -.main-footer - nav.background-blue-grey-900.grid-fluid +div(class="main-footer" data-swiftype-index="false") + nav.background-midnight.grid-fluid .c3.main-footer-branding .logo-inverse-large - .c3 + .c2 h3.text-headline RESOURCES ul.text-body - // TODO: (ericjim) make a libraries page to showcase all angular 2 libraries + // TODO: (ericjim) make a libraries page to showcase all angular libraries //li Libraries li About - li Books & Training + li Books & Training li Tools & Libraries li Community li Press Kit - .c3 + .c2 h3.text-headline HELP ul.text-body @@ -35,18 +35,23 @@ else li Report Issues li Site Feedback - .c3 + .c2 h3.text-headline COMMUNITY ul.text-body li Events li Meetups - li Twitter + li Twitter li GitHub li Contribute + .c2 + h3.text-headline LANGUAGES - footer(class="background-steel") - small.text-caption Powered by Google ©2010-2016. Code licensed under an MIT-style License. Documentation licensed under CC BY 4.0. - a(aria-label="View Style Guide" href=styleguide title="Style Guide" class="styleguide-trigger text-snow" md-button) + ul.text-body + li 中文版 + + footer(class="background-midnight") + small.text-caption Powered by Google ©2010-2017. Code licensed under an MIT-style License. Documentation licensed under CC BY 4.0. + a(aria-label="View Style Guide" href=styleguide title="Style Guide" class="styleguide-trigger") span.icon-favorite diff --git a/public/_includes/_head-include.jade b/public/_includes/_head-include.jade index 2e46febe96..489ba51bd2 100644 --- a/public/_includes/_head-include.jade +++ b/public/_includes/_head-include.jade @@ -1,18 +1,25 @@ - var language = current.path[1] - var version = '' +- var section = '' if current.path[2] - var version = current.path[2].replace(/\_+/gm, ".") +if current.path[3] + - var section = current.path[3].toUpperCase() + + if language == 'js' if language == 'dart' if title == "Angular" title #{title} +else if section + title #{title} - #{language} - #{section} else if language title #{title} - #{language} else - title #{title} - Angular 2 + title #{title} - Angular meta(charset="utf-8") meta(http-equiv="X-UA-Compatible" content="IE=edge") @@ -22,14 +29,14 @@ meta(name="robots" content="all") meta(name="referrer" content="origin") meta(name="viewport" id="viewport" content="width=device-width, initial-scale=1") -meta(property="og:title" content="Angular 2") +meta(property="og:title" content="Angular") meta(property="og:image" content="/resources/images/logos/standard/shield-large.png") meta(property="og:image:type" content="image/png") meta(property="og:image:width" content="184") meta(property="og:image:height" content="200") meta(property="og:description" content="#{description}") -meta(itemprop="name" content="Angular 2") +meta(itemprop="name" content="Angular") meta(itemprop="description" content="#{description}") meta(itemprop="image" content="https://angular.io/resources/images/logos/standard/shield-large.png") @@ -57,4 +64,4 @@ link(rel="stylesheet" href="/resources/css/main.css") - \ No newline at end of file + diff --git a/public/_includes/_hero-home.jade b/public/_includes/_hero-home.jade index 7fdccb9f29..b413803e3b 100644 --- a/public/_includes/_hero-home.jade +++ b/public/_includes/_hero-home.jade @@ -1,6 +1,13 @@ -header(class="background-sky") - .hero.background-superhero-paper.is-large - h1.text-headline.hero-logo #{title}
#{subtitle} +header(class="background-sky l-relative") - .hero-cta - a(href="/docs/ts/latest/quickstart.html" class="md-raised button button-large button-plain" md-button) Get Started \ No newline at end of file + .hero.background-superhero-paper.is-large + img(class="hero-logo" src='/resources/images/logos/angular/angular.svg') + h1.text-headline #{title}
#{subtitle} + a(href="/docs/ts/latest/quickstart.html" class="hero-cta md-raised button button-large button-plain" md-button) Get Started + + announcement-bar + .announcement-bar-slide.clearfix + img(src="/resources/images/logos/angular/angular-banner-logo-grey.png" width="64") + p Angular v4.0 is out! Smaller, faster, no biggie... + a(href="http://angularjs.blogspot.com/2017/03/angular-400-now-available.html" target="_blank" class="button md-button") Learn more + diff --git a/public/_includes/_hero.jade b/public/_includes/_hero.jade index 6e301a0b71..bf346a6a3a 100644 --- a/public/_includes/_hero.jade +++ b/public/_includes/_hero.jade @@ -1,11 +1,11 @@ -// Refer to jade.template.html and addJadeDataDocsProcessor to figure out where the context of this jade file originates +//- template: public/_includes/_hero +//- Refer to jade.template.html and addJadeDataDocsProcessor to figure out where the context of this jade file originates - var textFormat = ''; - var headerTitle = title + (typeof varType !== 'undefined' ? (': ' + varType) : ''); - var capitalize = function capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); } - var useBadges = docType || stability; - -// renamer :: String -> String -// Renames `Let` and `Var` into `Const` +//- renamer :: String -> String +//- Renames `Let` and `Var` into `Const` - var renamer = function renamer(docType) { - return (docType === 'Let' || docType === 'Var') ? 'Const' : docType - } @@ -13,25 +13,29 @@ if current.path[4] && current.path[3] == 'api' - var textFormat = 'is-standard-case' -header(class="hero background-sky") - div(class="inner-header") - h1(class="hero-title text-display-1 #{textFormat}") #{headerTitle} - if useBadges - span(class="badges") - if docType - span(class="status-badge"). - #{renamer(capitalize(docType))} - if stability - span(layout="row" class="status-badge") - // badge circle is filled based on stability by matching a css selector in _hero.scss - span(class="status-circle status-#{stability}") - span Stability: #{capitalize(stability)} - if security - span(class="status-badge security-risk-badge"). - Security Risk +if current.path.indexOf('cheatsheet') > 0 || current.path[current.path.length-2] === 'api' + - var base = current.path[4] ? '../guide' : './guide'; + - var ngVersion = '(v4.X.Y)'; + +header.hero.background-sky + h1(class="hero-title #{textFormat}") #{headerTitle} !{ngVersion} + + if useBadges + if stability + span(class="badge is-#{stability}"). + #{capitalize(stability)} + if security + span(class="badge is-deprecated"). + Security Risk + + //- CLEAR FLOAT ELEMENTS + .clear if subtitle - h2.hero-subtitle.text-subhead #{subtitle} + h2.hero-subtitle #{subtitle} + else if docType + h2.hero-subtitle #{renamer(capitalize(docType))} + + if current.path[3] == 'api' && current.path[1] == 'dart' + block breadcrumbs - else if current.path[0] == "docs" - != partial("_version-dropdown") diff --git a/public/_includes/_main-nav.jade b/public/_includes/_main-nav.jade index 272a54d702..5ecfcd7108 100644 --- a/public/_includes/_main-nav.jade +++ b/public/_includes/_main-nav.jade @@ -1,15 +1,13 @@ - var language = current.path[1] || 'ts' - if (language !== 'ts' || language !== 'js' || language !== 'dart') { language = 'ts'; } -md-toolbar(class="main-nav background-regal l-pinned-top l-layer-5",scroll-y-offset-element) - nav - h1 Angular by Google +nav(data-swiftype-index="false" class="main-nav l-pinned-top l-layer-5", scroll-y-offset-element) + h1 Angular by Google - button(class="main-nav-button main-nav-mobile-trigger l-right" aria-label="View Menu" ng-click="appCtrl.toggleMainMenu($event)" md-button) Site Menu + button(class="main-nav-button main-nav-mobile-trigger l-right" aria-label="View Menu" ng-click="appCtrl.toggleMainMenu($event)" md-button) Site Menu - ul(ng-class="appCtrl.showMainNav ? 'is-visible' : ''") - li.l-left Features - li.l-left Docs - li.l-left Events - li.l-left News - li.l-right Get Started + ul(ng-class="appCtrl.showMainNav ? 'is-visible' : ''") + li.l-left Features + li.l-left Docs + li.l-left Events + li.l-right Get Started diff --git a/public/_includes/_next-item.jade b/public/_includes/_next-item.jade index c4626a453f..df379265ae 100644 --- a/public/_includes/_next-item.jade +++ b/public/_includes/_next-item.jade @@ -1,19 +1,24 @@ - var currentPage = false - var nextPage = false +- var hideNextPage = false; + - var data = public.docs[current.path[1]][current.path[2]][current.path[3]]._data for page, slug in data // CHECK IF CURRENT PAGE IS SET, THEN SET NEXT PAGE if currentPage - if !nextPage && page.nextable - .l-sub-section - h3 Next Step - a(href="/docs/#{current.path[1]}/#{current.path[2]}/#{current.path[3]}/#{slug}.html") #{page.title} + if !nextPage && page.nextable && !page.hide + if !hideNextPage + .l-sub-section + h3 Next Step + a(href="/docs/#{current.path[1]}/#{current.path[2]}/#{current.path[3]}/#{slug}.html") #{page.title} //NEXT PAGE HAS NOW BEEN SET - var nextPage = true + - hideNextPage = page.hideNextPage + // SET CURRENT PAGE FLAG WHEN YOU PASS IT if current.path[4] == slug - - var currentPage = true \ No newline at end of file + - var currentPage = true diff --git a/public/_includes/_scripts-include.jade b/public/_includes/_scripts-include.jade index a0b98972f9..aee83952ab 100644 --- a/public/_includes/_scripts-include.jade +++ b/public/_includes/_scripts-include.jade @@ -7,9 +7,9 @@ script(src="/resources/js/vendor/clipboard.min.js") -script(src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js") -script(src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js") -script(src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js") +script(src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js") +script(src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular-animate.min.js") +script(src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular-aria.min.js") script(src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js") @@ -21,43 +21,19 @@ script(src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular script(src="/resources/js/site.js") +script(src="/resources/js/util.js") script(src="/resources/js/controllers/app-controller.js") script(src="/resources/js/controllers/resources-controller.js") script(src="/resources/js/directives/cheatsheet.js") script(src="/resources/js/directives/api-list.js") script(src="/resources/js/directives/bio.js") script(src="/resources/js/directives/bold.js") +script(src="/resources/js/directives/announcement-bar.js") script(src="/resources/js/directives/code.js") script(src="/resources/js/directives/copy.js") script(src="/resources/js/directives/code-tabs.js") script(src="/resources/js/directives/code-pane.js") script(src="/resources/js/directives/code-example.js") +script(src="/resources/js/directives/if-docs.js") +script(src="/resources/js/directives/live-example.js") script(src="/resources/js/directives/scroll-y-offset-element.js") - - -script. - (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ - (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), - m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) - })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - - ga('create', 'UA-8594346-15', 'auto'); - ga('send', 'pageview') - - -if current.path[0] == "docs" - - script. - (function(w,d,t,u,n,s,e){w['SwiftypeObject']=n;w[n]=w[n]||function(){ - (w[n].q=w[n].q||[]).push(arguments);};s=d.createElement(t); - e=d.getElementsByTagName(t)[0];s.async=1;s.src=u;e.parentNode.insertBefore(s,e); - })(window,document,'script','//s.swiftypecdn.com/install/v1/st.js','_st'); - - _st('install','VsuU7kH5Hnnj9tfyNvfK'); - - -script(src="//www.gstatic.com/feedback/api.js" type="text/javascript") - - -script. - (function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}})(document,"script","twitter-wjs"); \ No newline at end of file diff --git a/public/_includes/_scripts-minimum.jade b/public/_includes/_scripts-minimum.jade new file mode 100644 index 0000000000..a568f88d15 --- /dev/null +++ b/public/_includes/_scripts-minimum.jade @@ -0,0 +1,27 @@ + +script. + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-8594346-15', 'auto'); + ga('send', 'pageview') + + +if current.path[0] == "docs" || current.path[0] == "search" +script. + (function(w,d,t,u,n,s,e){w['SwiftypeObject']=n;w[n]=w[n]||function(){ + (w[n].q=w[n].q||[]).push(arguments);};s=d.createElement(t); + e=d.getElementsByTagName(t)[0];s.async=1;s.src=u;e.parentNode.insertBefore(s,e); + })(window,document,'script','//s.swiftypecdn.com/install/v2/st.js','_st'); + + _st('install','VsuU7kH5Hnnj9tfyNvfK','2.0.0'); + + + +script(src="//www.gstatic.com/feedback/api.js" type="text/javascript") + + +script. + (function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}})(document,"script","twitter-wjs"); diff --git a/public/_includes/_util-fns.jade b/public/_includes/_util-fns.jade index b46a6c8c06..7a755027c8 100644 --- a/public/_includes/_util-fns.jade +++ b/public/_includes/_util-fns.jade @@ -37,10 +37,26 @@ //- Location of sample code - var _liveLink = 'live link'; +- var _ngRepoURL = 'https://github.com/angular/angular'; +- var _ngDocRepoURL = 'https://github.com/angular/angular.io'; +- var _qsRepo = 'https://github.com/angular/quickstart'; +- var _qsRepoZip = _qsRepo + '/archive/master.zip'; + +- var _npm = 'npm'; + +//- NgModule related +- var _AppModuleVsAppComp = 'AppModule' +- var _appModuleTsVsAppCompTs = 'src/app/app.module.ts' +- var _appModuleTsVsMainTs = 'src/app/app.module.ts' +- var _bootstrapModule = 'bootstrapModule' +- var _declsVsDirectives = 'declarations' +- var _moduleVsComp = 'module' +- var _moduleVsRootComp = 'module' +- var _platformBrowserDynamicVsBootStrap = 'platformBrowserDynamic' //- Other - var _truthy = 'truthy'; -- var _falsey = 'falsey'; +- var _falsy = 'falsy'; //- Used to prefix identifiers that are private. In Dart this will be '_'. - var _priv = ''; @@ -74,14 +90,14 @@ mixin makeExample(_filePath, region, _title, stylePatterns) - var format = attributes.format || defaultFormat; - if (attributes.format === '.') format = ''; - var avoid = !!attributes.avoid; + - var avoidClass = avoid ? 'is-anti-pattern' : ''; - if (title) - if (avoid) - .example-title.avoid AVOID: #{title} - else - .example-title #{title} - code-example(language="#{language}" format="#{format}") - != styleString(frag, stylePatterns) + div(class="code-example #{avoidClass}") + if (title) + header + h4 #{title} + code-example(language="#{language}" format="#{format}") + != styleString(frag, stylePatterns) //- Like makeExample, but: (1) doesn't show line numbers. (2) If region //- is omitted and title is 'foo (r)' then region is taken as 'r'. @@ -89,21 +105,22 @@ mixin makeExample(_filePath, region, _title, stylePatterns) //- ending is given or is just (), then the title will be suffixed with //- either "(excerpt)", or "(#{_region})" when _region is defined. mixin makeExcerpt(_filePath, _region, _title, stylePatterns) - - var matches = _filePath.match(/(.*)\s+\(([\w ]*)\)$/); + - var matches = _filePath.match(/(.*)\s+\(([^\)]*)\)$/); - var parenText; - if (matches) { _filePath = matches[1]; parenText = matches[2]; } - var adjustments = adjustExamplePathAndTitle({filePath:_filePath, title:_title}); - var filePath = adjustments.filePath; - var title = adjustments.title; - - var region = _region || parenText; - - var excerpt = !region || parenText === '' ? 'excerpt' : region; + - var region = _region || (_region === '' ? '' : parenText); + - var excerpt = parenText || region || 'excerpt'; - if (title) title = title + ' (' + excerpt + ')'; +makeExample(filePath, region, title, stylePatterns)(format='.') -//- Extract the doc example name from `current`. +//- Get the doc example name either from `_example` if set, or +//- extract the example name from `current`. - var getExampleName = function() { - var dir = current.path[current.path.length - 1]; -- return dir == 'latest' ? current.source : dir; +- return _example ? _example : dir == 'latest' ? current.source : dir; - }; mixin makeTabs(filePaths, regions, tabNames, stylePatterns) @@ -132,76 +149,78 @@ mixin makeJson( filePath, jsonConfig, title, stylePatterns) - var json = unescapeHtml(frag); - var jsonExtract = extractJson(json, jsonConfig); - var avoid = !!attributes.avoid; - - if (title) - if (avoid) - .example-title.avoid #{title} - else - .example-title #{title} - code-example(language="#{language}" format="#{format}") - if (jsonExtract == 'ERROR') - err ERROR: Unable to extract json using config: "#{jsonConfig.toString()}" - else - != styleString(jsonExtract, stylePatterns) - -- // Open (and close) an explanation
. See QuickStart -script. - function why(id, backTo) { - var id = "#"+id; - var el = document.querySelector(id); - el.hidden=el.hidden=!el.hidden; - - if (el.hidden && backTo){ - // the next line is required to work around a bug in WebKit (Chrome / Safari) - location.href = "#"; - location.href = "#" + backTo; + - var avoidClass = avoid ? 'is-anti-pattern' : ''; + + div(class="code-example #{avoidClass}") + if (title) + header + h4 #{title} + code-example(language="#{language}" format="#{format}") + if (jsonExtract == 'ERROR') + err ERROR: Unable to extract json using config: "#{jsonConfig.toString()}" + else + != styleString(jsonExtract, stylePatterns) + +if !jade2ng + //- Open (and close) an explanation
. See QuickStart + script. + function why(id, backTo) { + var id = "#"+id; + var el = document.querySelector(id); + el.hidden=el.hidden=!el.hidden; + + if (el.hidden && backTo){ + // the next line is required to work around a bug in WebKit (Chrome / Safari) + location.href = "#"; + location.href = "#" + backTo; + } } - } -script. - function verbose(isVerbose) { - isVerbose = !! isVerbose; - var el = document.querySelector('button.verbose.off'); - el.style.display = isVerbose ? 'block' : 'none'; - var el = document.querySelector('button.verbose.on'); - el.style.display = isVerbose ? 'none' : 'block'; - - CCSStylesheetRuleStyle('main','.l-verbose-section', 'display', - isVerbose ? 'block' : 'none'); - } - -script. - function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){ - /* returns the value of the element style of the rule in the stylesheet - * If no value is given, reads the value - * If value is given, the value is changed and returned - * If '' (empty string) is given, erases the value. - * The browser will apply the default one - * - * string stylesheet: part of the .css name to be recognized, e.g. 'default' - * string selectorText: css selector, e.g. '#myId', '.myClass', 'thead td' - * string style: camelCase element style, e.g. 'fontSize' - * string value optional : the new value - */ - var CCSstyle = undefined, rules, sheet; - for(var m in document.styleSheets){ - sheet = document.styleSheets[m]; - if(sheet.href && sheet.href.indexOf(stylesheet) != -1){ - rules = sheet[document.all ? 'rules' : 'cssRules']; - for(var n in rules){ - console.log(rules[n].selectorText); - if(rules[n].selectorText == selectorText){ - CCSstyle = rules[n].style; - break; + script. + function verbose(isVerbose) { + isVerbose = !! isVerbose; + var el = document.querySelector('button.verbose.off'); + el.style.display = isVerbose ? 'block' : 'none'; + var el = document.querySelector('button.verbose.on'); + el.style.display = isVerbose ? 'none' : 'block'; + + CCSStylesheetRuleStyle('main','.l-verbose-section', 'display', + isVerbose ? 'block' : 'none'); + } + + script. + function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){ + /* returns the value of the element style of the rule in the stylesheet + * If no value is given, reads the value + * If value is given, the value is changed and returned + * If '' (empty string) is given, erases the value. + * The browser will apply the default one + * + * string stylesheet: part of the .css name to be recognized, e.g. 'default' + * string selectorText: css selector, e.g. '#myId', '.myClass', 'thead td' + * string style: camelCase element style, e.g. 'fontSize' + * string value optional : the new value + */ + var CCSstyle = undefined, rules, sheet; + for(var m in document.styleSheets){ + sheet = document.styleSheets[m]; + if(sheet.href && sheet.href.indexOf(stylesheet) != -1){ + rules = sheet[document.all ? 'rules' : 'cssRules']; + for(var n in rules){ + console.log(rules[n].selectorText); + if(rules[n].selectorText == selectorText){ + CCSstyle = rules[n].style; + break; + } + } + break; } } - break; - } + if(value == undefined) + return CCSstyle[style] + else + return CCSstyle[style] = value } - if(value == undefined) - return CCSstyle[style] - else - return CCSstyle[style] = value - } + //--------------------------------------------------------------------------------------------------------- //- Converts the given project-relative path (like 'app/main.ts') //- to a doc folder relative path (like 'quickstart/ts/app/main.ts') @@ -212,8 +231,8 @@ script. - // E.g. of a project relative path is 'app/main.ts' - if (ex.title === null || ex.title === undefined) { - // Title is not given so take it to be ex.filePath. -- // Is title like styles.1.css? Then drop the '.1' qualifier: -- var matches = ex.filePath.match(/^(.*)\.\d(\.\w+)$/); +- // Title like styles.1.css or foo_1.dart? Then drop the '.1' or '_1' qualifier: +- var matches = ex.filePath.match(/^(.*)[\._]\d(\.\w+)$/); - ex.title = matches ? matches[1] + matches[2] : ex.filePath; - } - ex.filePath = getExampleName() + '/' + _docsFor + '/' + ex.filePath; @@ -234,7 +253,7 @@ script. //- Returns truthy iff path is example project relative. - var isProjRelDir = function(path) { -- return !path.match(/\/(js|ts|dart)(-snippets)?\//) && !path.endsWith('e2e-spec.js'); +- return !path.match(/\/(js|ts|dart)(-snippets)?\//) && !path.endsWith('e2e-spec.ts'); - // Last conjunct handles case for shared project e2e test file like - // cb-component-communication/e2e-spec.js (is shared between ts & dart) - // TODO: generalize: compare start with getExampleName(); which needs to be fixed. diff --git a/public/_includes/_version-dropdown.jade b/public/_includes/_version-dropdown.jade index 6bba60975a..d9ebe2b368 100644 --- a/public/_includes/_version-dropdown.jade +++ b/public/_includes/_version-dropdown.jade @@ -5,7 +5,7 @@ - var version = '' - var page = '' - +//- Replace _ underscores with . dots if current.path[2] - var version = current.path[2].replace(/\_+/gm, ".") @@ -33,43 +33,45 @@ else if current.path[3] else - var page = current.path[3] + '.html' - +//- VERSION TREE CREATOR MIXIN mixin tree(directory, urlPrefix, name, latest) - ul - for val, semvar in directory - if semvar !== '.git' && semvar !== '_data' - - var libVersion = (semvar == "latest") ? latest : semvar.replace(/\_+/gm, ".") - li #{name} #{libVersion} + for val, semvar in directory + if semvar !== '.git' && semvar !== '_data' + - var libVersion = (semvar == "latest") ? latest : semvar.replace(/\_+/gm, ".") + li #{name} #{libVersion} - +//- BUTTON TITLE GENERATION if language == 'ts' if version == "latest" - - var title = 'Angular 2 for TypeScript' + - var title = 'Angular for TypeScript' else - var title = 'Angular ' + version + ' for TypeScript' if language == 'js' if version == "latest" - - var title = 'Angular 2 for JavaScript' + - var title = 'Angular for JavaScript' else - var title = 'Angular ' + version + ' for JavaScript' if language == 'dart' if version == "latest" - - var title = 'Angular 2 for Dart' + - var title = 'Angular for Dart' else - var title = 'Angular ' + version + ' for Dart' +if current.path[4] !== 'change-log' + //- DROPDOWN BUTTON + nav.dropdown + button(aria-label="Select a version of Angular" md-button class="dropdown-button" ng-click="appCtrl.toggleVersionMenu($event)") #{title} + div(class="overlay ng-hide" ng-click="appCtrl.toggleVersionMenu($event)" ng-show="appCtrl.showMenu") - -nav.dropdown - button(aria-label="Select a version of Angular" md-button class="dropdown-button" ng-click="appCtrl.toggleVersionMenu($event)") #{title} - div(class="overlay ng-hide" ng-click="appCtrl.toggleVersionMenu($event)" ng-show="appCtrl.showMenu") - - - div(class="dropdown-menu" ng-class="appCtrl.showMenu ? 'is-visible' : ''") - mixin tree(public.docs.ts, "/docs/ts", "Angular 2 for TypeScript") - mixin tree(public.docs.js, "/docs/js", "Angular 2 for JavaScript") - mixin tree(public.docs.dart, "/docs/dart", "Angular 2 for Dart") + //- DROPDOWN MENU + ul(class="dropdown-menu" ng-class="appCtrl.showMenu ? 'is-visible' : ''") + mixin tree(public.docs.ts, "/docs/ts", "Angular for TypeScript") + mixin tree(public.docs.js, "/docs/js", "Angular for JavaScript") + //- Disable cross-language link for API entry pages (but keep for top API search page): + - var isApiEntryPage = current.path[3] === 'api' && public.docs[current.path[1]][current.path[2]][current.path[3]][current.path[4]] + if public.docs.dart && !isApiEntryPage + mixin tree(public.docs.dart, "/docs/dart", "Angular for Dart") diff --git a/public/_layout.jade b/public/_layout.jade index aef7728caa..6f01183b22 100644 --- a/public/_layout.jade +++ b/public/_layout.jade @@ -1,22 +1,33 @@ -doctype html public -html(lang="en" ng-app="angularIOApp" itemscope itemtype="http://schema.org/Framework") - head - != partial("/_includes/_head-include") +if jade2ng + if hero == 'home' + != partial("/_includes/_hero-home") + else + != partial("/_includes/_hero") + != partial("../_includes/_banner") + - var format = autoformat ? 'docs-content' : '' + article(class="l-content #{format}") + != yield +else + doctype html public + html(lang="en" ng-app="angularIOApp" itemscope itemtype="http://schema.org/Framework") + head + != partial("/_includes/_head-include") - body.ng-cloak.l-offset-nav(ng-controller="AppCtrl as appCtrl") - != partial("/_includes/_main-nav") + body.ng-cloak.l-offset-nav(ng-controller="AppCtrl as appCtrl") + != partial("/_includes/_main-nav") - - if hero == 'home' - != partial("/_includes/_hero-home") - else - != partial("/_includes/_hero") + + if hero == 'home' + != partial("/_includes/_hero-home") + else + != partial("/_includes/_hero") - - var format = autoformat ? 'docs-content' : '' + - var format = autoformat ? 'docs-content' : '' - article(class="l-content #{format}") - != yield + article(class="l-content #{format}") + != yield - != partial("/_includes/_footer") - != partial("/_includes/_scripts-include") \ No newline at end of file + != partial("/_includes/_footer") + != partial("/_includes/_scripts-include") + != partial("/_includes/_scripts-minimum") diff --git a/public/about/index.jade b/public/about/index.jade index b6b429b178..1150e51a56 100644 --- a/public/about/index.jade +++ b/public/about/index.jade @@ -22,7 +22,7 @@ for person, name in bios if person.type == type .c3 - md-card(biocard class="bio-card" website="#{person.website}" twitter="#{person.twitter}" pic="#{person.picture}" bio="#{person.bio}" name="#{person.name}") + md-card(biocard class="bio-card" website=person.website twitter=person.twitter pic=person.picture bio=person.bio name=person.name) header image(src="#{person.picture}" alt="#person.name") diff --git a/public/cardboard/index.jade b/public/cardboard/index.jade index 57a8b0bbb6..a0a76d0e80 100644 --- a/public/cardboard/index.jade +++ b/public/cardboard/index.jade @@ -30,7 +30,7 @@ style(rel='stylesheet'). li. Best Technology Demonstration
- Huge hint: Angular 2 scores points + Huge hint: Angular scores points p Don’t have Cardboard and want one? Check out: p.text-center diff --git a/public/contribute.jade b/public/contribute.jade index 451269dd40..994d46a36d 100644 --- a/public/contribute.jade +++ b/public/contribute.jade @@ -3,11 +3,11 @@ p We'd love for you to contribute to our source code and to make Angular projects even better. .l-sub-section - h3 Angular 2 + h3 Angular - p Angular 2, now in beta, is a next generation mobile and desktop application development platform. + p Angular is a next generation mobile and desktop application development platform. - a(href="https://github.com/angular/angular/blob/master/CONTRIBUTING.md" class="button" md-button) Contribute to Angular 2 + a(href="https://github.com/angular/angular/blob/master/CONTRIBUTING.md" class="button" md-button) Contribute to Angular .l-sub-section h3 Angular for JavaScript or Dart diff --git a/public/docs/ImageGuide.pdf b/public/docs/ImageGuide.pdf new file mode 100644 index 0000000000..21280dce88 Binary files /dev/null and b/public/docs/ImageGuide.pdf differ diff --git a/public/docs/README.md b/public/docs/README.md deleted file mode 100644 index 95d331b115..0000000000 --- a/public/docs/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Why the _fragments dir is checked in - -Within this repo files generated as a result of shredding the `_examples` dir ( the contents of the `_fragments` dir) are checked in so that we can avoid running the -shredder over the entire `_examples` dir each time someone refreshes the repo ( the `shred-full` gulp task). -The gulp `serve-and-watch` shredder is only a partial shredder. It only shreds files in directories changed during -the current session. diff --git a/public/docs/_examples/.editorconfig b/public/docs/_examples/.editorconfig deleted file mode 100644 index f2abacf6d3..0000000000 --- a/public/docs/_examples/.editorconfig +++ /dev/null @@ -1,20 +0,0 @@ -# http://editorconfig.org -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - - -[*.md] -max_line_length = 0 -trim_trailing_whitespace = false - -# Indentation override -#[lib/**.js] -#[{package.json,.travis.yml}] -#[**/**.js] diff --git a/public/docs/_examples/.gitignore b/public/docs/_examples/.gitignore index 449fd35581..3fb5ae8562 100644 --- a/public/docs/_examples/.gitignore +++ b/public/docs/_examples/.gitignore @@ -1,26 +1,18 @@ -.editorconfig -.idea -.vscode -styles.css -typings -typings.json -node_modules -jspm_packages -*.js.map -package.json -karma.conf.js -karma-test-shim.js -tsconfig.json -tslint.json -wallaby.js -npm-debug*. -protractor.config.js -systemjs.config.js +# _boilerplate files +!_boilerplate/* +*/*/src/styles.css +*/*/src/systemjs-angular-loader.js +*/*/src/systemjs.config.js +*/*/src/tsconfig.json +*/*/bs-config.e2e.json +*/*/bs-config.json +*/*/package.json +*/*/tslint.json + +# example files _test-output -_temp +protractor-helpers.js +*/e2e-spec.js **/ts/**/*.js +**/js-es6*/**/*.js **/ts-snippets/**/*.js -*.d.ts - -!**/*e2e-spec.js -!systemjs.config.1.js diff --git a/public/docs/_examples/_boilerplate/bs-config.e2e.json b/public/docs/_examples/_boilerplate/bs-config.e2e.json new file mode 100644 index 0000000000..24570dbcc9 --- /dev/null +++ b/public/docs/_examples/_boilerplate/bs-config.e2e.json @@ -0,0 +1,14 @@ +{ + "open": false, + "logLevel": "silent", + "port": 8080, + "server": { + "baseDir": "src", + "routes": { + "/node_modules": "node_modules" + }, + "middleware": { + "0": null + } + } +} diff --git a/public/docs/_examples/_boilerplate/bs-config.json b/public/docs/_examples/_boilerplate/bs-config.json new file mode 100644 index 0000000000..4e58595267 --- /dev/null +++ b/public/docs/_examples/_boilerplate/bs-config.json @@ -0,0 +1,8 @@ +{ + "server": { + "baseDir": "src", + "routes": { + "/node_modules": "node_modules" + } + } +} diff --git a/public/docs/_examples/_boilerplate/example-config.json b/public/docs/_examples/_boilerplate/example-config.json new file mode 100644 index 0000000000..ff5403e6ca --- /dev/null +++ b/public/docs/_examples/_boilerplate/example-config.json @@ -0,0 +1,4 @@ +{ + "build": "build", + "run": "serve" +} diff --git a/public/docs/_examples/_boilerplate/package.json b/public/docs/_examples/_boilerplate/package.json new file mode 100644 index 0000000000..2e4bc19f91 --- /dev/null +++ b/public/docs/_examples/_boilerplate/package.json @@ -0,0 +1,44 @@ +{ + "name": "angular-examples", + "version": "1.0.0", + "private": true, + "description": "Example package.json, only contains needed scripts for examples. See _examples/package.json for master package.json.", + "scripts": { + "build": "tsc -p src/", + "build:watch": "tsc -p src/ -w", + "build:e2e": "tsc -p e2e/", + "serve": "lite-server -c=bs-config.json", + "serve:e2e": "lite-server -c=bs-config.e2e.json", + "prestart": "npm run build", + "start": "concurrently \"npm run build:watch\" \"npm run serve\"", + "pree2e": "webdriver-manager update && npm run build:e2e", + "e2e": "concurrently \"npm run serve:e2e\" \"npm run protractor\" --kill-others --success first", + "protractor": "protractor protractor.config.js", + "pretest": "npm run build", + "test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"", + "pretest:once": "npm run build", + "test:once": "karma start karma.conf.js --single-run", + "lint": "tslint ./src/**/*.ts -t verbose", + + "build:upgrade": "tsc", + "serve:upgrade": "http-server", + "build:cli": "ng build --no-progress", + "serve:cli": "http-server dist/", + "build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup-config.js", + "serve:aot": "lite-server -c bs-config.aot.json", + "start:webpack": "webpack-dev-server --inline --progress --port 8080", + "test:webpack": "karma start karma.webpack.conf.js", + "build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --bail", + "build:babel": "babel src -d src --extensions \".es6\" --source-maps", + "copy-dist-files": "node ./copy-dist-files.js", + "i18n": "ng-xi18n" + }, + "keywords": [], + "author": "", + "license": "MIT", + "dependencies": {}, + "devDependencies": { + "angular-cli": "^1.0.0-rc.0" + }, + "repository": {} +} diff --git a/public/docs/_examples/_boilerplate/plnkr.json b/public/docs/_examples/_boilerplate/plnkr.json new file mode 100644 index 0000000000..5fb55b50ad --- /dev/null +++ b/public/docs/_examples/_boilerplate/plnkr.json @@ -0,0 +1,10 @@ +{ + "description": "QuickStart", + "basePath": "src/", + "files": [ + "app/app.component.ts", + "index.html" + ], + "open": "app/app.component.ts", + "tags": ["quickstart"] +} diff --git a/public/docs/_examples/_boilerplate/src/styles.css b/public/docs/_examples/_boilerplate/src/styles.css new file mode 100644 index 0000000000..d81835d0cd --- /dev/null +++ b/public/docs/_examples/_boilerplate/src/styles.css @@ -0,0 +1,116 @@ +/* #docregion , quickstart, toh */ +/* Master Styles */ +h1 { + color: #369; + font-family: Arial, Helvetica, sans-serif; + font-size: 250%; +} +h2, h3 { + color: #444; + font-family: Arial, Helvetica, sans-serif; + font-weight: lighter; +} +body { + margin: 2em; +} +/* #enddocregion quickstart */ +body, input[text], button { + color: #888; + font-family: Cambria, Georgia; +} +/* #enddocregion toh */ +a { + cursor: pointer; + cursor: hand; +} +button { + font-family: Arial; + background-color: #eee; + border: none; + padding: 5px 10px; + border-radius: 4px; + cursor: pointer; + cursor: hand; +} +button:hover { + background-color: #cfd8dc; +} +button:disabled { + background-color: #eee; + color: #aaa; + cursor: auto; +} + +/* Navigation link styles */ +nav a { + padding: 5px 10px; + text-decoration: none; + margin-right: 10px; + margin-top: 10px; + display: inline-block; + background-color: #eee; + border-radius: 4px; +} +nav a:visited, a:link { + color: #607D8B; +} +nav a:hover { + color: #039be5; + background-color: #CFD8DC; +} +nav a.active { + color: #039be5; +} + +/* items class */ +.items { + margin: 0 0 2em 0; + list-style-type: none; + padding: 0; + width: 24em; +} +.items li { + cursor: pointer; + position: relative; + left: 0; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; +} +.items li:hover { + color: #607D8B; + background-color: #DDD; + left: .1em; +} +.items li.selected { + background-color: #CFD8DC; + color: white; +} +.items li.selected:hover { + background-color: #BBD8DC; +} +.items .text { + position: relative; + top: -3px; +} +.items .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0 0 4px; +} +/* #docregion toh */ +/* everywhere else */ +* { + font-family: Arial, Helvetica, sans-serif; +} diff --git a/public/docs/_examples/_boilerplate/src/systemjs-angular-loader.js b/public/docs/_examples/_boilerplate/src/systemjs-angular-loader.js new file mode 100644 index 0000000000..8b1005444e --- /dev/null +++ b/public/docs/_examples/_boilerplate/src/systemjs-angular-loader.js @@ -0,0 +1,49 @@ +var templateUrlRegex = /templateUrl\s*:(\s*['"`](.*?)['"`]\s*)/gm; +var stylesRegex = /styleUrls *:(\s*\[[^\]]*?\])/g; +var stringRegex = /(['`"])((?:[^\\]\\\1|.)*?)\1/g; + +module.exports.translate = function(load){ + if (load.source.indexOf('moduleId') != -1) return load; + + var url = document.createElement('a'); + url.href = load.address; + + var basePathParts = url.pathname.split('/'); + + basePathParts.pop(); + var basePath = basePathParts.join('/'); + + var baseHref = document.createElement('a'); + baseHref.href = this.baseURL; + baseHref = baseHref.pathname; + + if (!baseHref.startsWith('/base/')) { // it is not karma + basePath = basePath.replace(baseHref, ''); + } + + load.source = load.source + .replace(templateUrlRegex, function(match, quote, url){ + var resolvedUrl = url; + + if (url.startsWith('.')) { + resolvedUrl = basePath + url.substr(1); + } + + return 'templateUrl: "' + resolvedUrl + '"'; + }) + .replace(stylesRegex, function(match, relativeUrls) { + var urls = []; + + while ((match = stringRegex.exec(relativeUrls)) !== null) { + if (match[2].startsWith('.')) { + urls.push('"' + basePath + match[2].substr(1) + '"'); + } else { + urls.push('"' + match[2] + '"'); + } + } + + return "styleUrls: [" + urls.join(', ') + "]"; + }); + + return load; +}; diff --git a/public/docs/_examples/_boilerplate/src/systemjs.config.js b/public/docs/_examples/_boilerplate/src/systemjs.config.js new file mode 100644 index 0000000000..ea7a3879ac --- /dev/null +++ b/public/docs/_examples/_boilerplate/src/systemjs.config.js @@ -0,0 +1,52 @@ +/** + * System configuration for Angular samples + * Adjust as necessary for your application needs. + */ +(function (global) { + System.config({ + paths: { + // paths serve as alias + 'npm:': 'node_modules/' + }, + // map tells the System loader where to look for things + map: { + // our app is within the app folder + 'app': 'app', + + // angular bundles + '@angular/animations': 'npm:@angular/animations/bundles/animations.umd.js', + '@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js', + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js', + '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js', + + // other libraries + 'rxjs': 'npm:rxjs', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' + }, + // packages tells the System loader how to load when no filename and/or no extension + packages: { + app: { + main: './main.js', + defaultExtension: 'js', + meta: { + './*.js': { + loader: 'systemjs-angular-loader.js' + } + } + }, + rxjs: { + defaultExtension: 'js' + } + } + }); +})(this); diff --git a/public/docs/_examples/_boilerplate/src/systemjs.config.web.build.js b/public/docs/_examples/_boilerplate/src/systemjs.config.web.build.js new file mode 100644 index 0000000000..5774fd8187 --- /dev/null +++ b/public/docs/_examples/_boilerplate/src/systemjs.config.web.build.js @@ -0,0 +1,96 @@ +/** + * WEB VERSION FOR CURRENT ANGULAR BUILD + * (based on systemjs.config.js in angular.io) + * System configuration for Angular samples + * Adjust as necessary for your application needs. + * + * UNTESTED ! + */ +(function (global) { + System.config({ + // DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER + transpiler: 'ts', + typescriptOptions: { + // Copy of compiler options in standard tsconfig.json + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es2015", "dom"], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true + }, + meta: { + 'typescript': { + "exports": "ts" + } + }, + paths: { + // paths serve as alias + 'npm:': 'https://unpkg.com/', + 'ng:': 'https://cdn.rawgit.com/angular/' + }, + // map tells the System loader where to look for things + map: { + // our app is within the app folder + 'app': 'app', + + // angular bundles + '@angular/animations': 'ng:animations-builds/master/bundles/animations.umd.js', + '@angular/animations/browser': 'ng:animations-builds/master/bundles/animations-browser.umd.js', + '@angular/core': 'ng:core-builds/master/bundles/core.umd.js', + '@angular/common': 'ng:common-builds/master/bundles/common.umd.js', + '@angular/compiler': 'ng:compiler-builds/master/bundles/compiler.umd.js', + '@angular/platform-browser': 'ng:platform-browser-builds/master/bundles/platform-browser.umd.js', + '@angular/platform-browser/animations': 'ng:animations-builds/master/bundles/platform-browser-animations.umd.js', + '@angular/platform-browser-dynamic': 'ng:platform-browser-dynamic-builds/master/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'ng:http-builds/master/bundles/http.umd.js', + '@angular/router': 'ng:router-builds/master/bundles/router.umd.js', + '@angular/router/upgrade': 'ng:router-builds/master/bundles/router-upgrade.umd.js', + '@angular/forms': 'ng:forms-builds/master/bundles/forms.umd.js', + '@angular/upgrade': 'ng:upgrade-builds/master/bundles/upgrade.umd.js', + '@angular/upgrade/static': 'ng:upgrade-builds/master/bundles/upgrade-static.umd.js', + + // angular testing umd bundles (overwrite the shim mappings) + '@angular/core/testing': 'ng:core-builds/master/bundles/core-testing.umd.js', + '@angular/common/testing': 'ng:common-builds/master/bundles/common-testing.umd.js', + '@angular/compiler/testing': 'ng:compiler-builds/master/bundles/compiler-testing.umd.js', + '@angular/platform-browser/testing': 'ng:platform-browser-builds/master/bundles/platform-browser-testing.umd.js', + '@angular/platform-browser-dynamic/testing': 'ng:platform-browser-dynamic-builds/master/bundles/platform-browser-dynamic-testing.umd.js', + '@angular/http/testing': 'ng:http-builds/master/bundles/http-testing.umd.js', + '@angular/router/testing': 'ng:router-builds/master/bundles/router-testing.umd.js', + '@angular/forms/testing': 'ng:forms-builds/master/bundles/forms-testing.umd.js', + + // other libraries + 'rxjs': 'npm:rxjs@5.0.1', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js', + 'ts': 'npm:plugin-typescript@5.2.7/lib/plugin.js', + 'typescript': 'npm:typescript@2.2.1/lib/typescript.js', + + }, + // packages tells the System loader how to load when no filename and/or no extension + packages: { + app: { + main: './main.ts', + defaultExtension: 'ts', + meta: { + './*.ts': { + loader: 'systemjs-angular-loader.js' + } + } + }, + rxjs: { + defaultExtension: 'js' + } + } + }); + +})(this); + +/* +Copyright 2016 Google Inc. All Rights Reserved. +Use of this source code is governed by an MIT-style license that +can be found in the LICENSE file at http://angular.io/license +*/ diff --git a/public/docs/_examples/_boilerplate/src/systemjs.config.web.js b/public/docs/_examples/_boilerplate/src/systemjs.config.web.js new file mode 100644 index 0000000000..376fcdde8a --- /dev/null +++ b/public/docs/_examples/_boilerplate/src/systemjs.config.web.js @@ -0,0 +1,83 @@ +/** + * WEB ANGULAR VERSION + * (based on systemjs.config.js in angular.io) + * System configuration for Angular samples + * Adjust as necessary for your application needs. + */ +(function (global) { + System.config({ + // DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER + transpiler: 'ts', + typescriptOptions: { + // Copy of compiler options in standard tsconfig.json + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es2015", "dom"], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true + }, + meta: { + 'typescript': { + "exports": "ts" + } + }, + paths: { + // paths serve as alias + 'npm:': 'https://unpkg.com/' + }, + // map tells the System loader where to look for things + map: { + // our app is within the app folder + 'app': 'app', + + // angular bundles + '@angular/animations': 'npm:@angular/animations/bundles/animations.umd.js', + '@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js', + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js', + '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js', + + // other libraries + 'rxjs': 'npm:rxjs@5.0.1', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js', + 'ts': 'npm:plugin-typescript@5.2.7/lib/plugin.js', + 'typescript': 'npm:typescript@2.2.1/lib/typescript.js', + + }, + // packages tells the System loader how to load when no filename and/or no extension + packages: { + app: { + main: './main.ts', + defaultExtension: 'ts', + meta: { + './*.ts': { + loader: 'systemjs-angular-loader.js' + } + } + }, + rxjs: { + defaultExtension: 'js' + } + } + }); + +})(this); + +/* +Copyright 2016 Google Inc. All Rights Reserved. +Use of this source code is governed by an MIT-style license that +can be found in the LICENSE file at http://angular.io/license +*/ diff --git a/public/docs/_examples/_boilerplate/src/tsconfig.json b/public/docs/_examples/_boilerplate/src/tsconfig.json new file mode 100644 index 0000000000..05839ec2ff --- /dev/null +++ b/public/docs/_examples/_boilerplate/src/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ "es2015", "dom" ], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "../../../node_modules/@types/" + ] + }, + "compileOnSave": true, + "exclude": [ + "node_modules/*", + "**/*-aot.ts" + ] +} diff --git a/public/docs/_examples/tslint.json b/public/docs/_examples/_boilerplate/tslint.json similarity index 100% rename from public/docs/_examples/tslint.json rename to public/docs/_examples/_boilerplate/tslint.json diff --git a/public/docs/_examples/_protractor/e2e.d.ts b/public/docs/_examples/_protractor/e2e.d.ts deleted file mode 100644 index ab91658443..0000000000 --- a/public/docs/_examples/_protractor/e2e.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -/// - -// Defined in protractor.config.js -declare function setProtractorToNg1Mode(): void; -declare function sendKeys(element: protractor.ElementFinder, str: string): webdriver.promise.Promise; -declare function describeIf(cond: boolean, name: string, func: Function): void; -declare function itIf(cond: boolean, name: string, func: Function): void; - -declare namespace protractor { - interface IBrowser { - appIsTs: boolean; - appIsJs: boolean; - } -} diff --git a/public/docs/_examples/_protractor/package.json b/public/docs/_examples/_protractor/package.json deleted file mode 100644 index eca5cae41f..0000000000 --- a/public/docs/_examples/_protractor/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "angular2-examples-protractor", - "version": "1.0.0", - "description": "Manage _protractor folder installations", - "scripts": { - "postinstall": "typings install", - "typings": "typings", - "protractor": "protractor", - "webdriver:update": "webdriver-manager update" - }, - "keywords": [], - "author": "", - "license": "ISC", - "devDependencies": { - "protractor": "^3.3.0", - "typings": "^1.0.4" - }, - "repository": {} -} diff --git a/public/docs/_examples/_protractor/tsconfig.json b/public/docs/_examples/_protractor/tsconfig.json deleted file mode 100644 index eab9c24f92..0000000000 --- a/public/docs/_examples/_protractor/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "moduleResolution": "node", - "sourceMap": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "removeComments": false, - "noImplicitAny": true, - "suppressImplicitAnyIndexErrors": true - }, - "files": [ - "e2e-spec.ts" - ] -} diff --git a/public/docs/_examples/_protractor/typings.json b/public/docs/_examples/_protractor/typings.json deleted file mode 100644 index 6962cc930f..0000000000 --- a/public/docs/_examples/_protractor/typings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "globalDependencies": { - "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459", - "core-js": "registry:dt/core-js#0.0.0+20160317120654", - "jasmine": "registry:dt/jasmine#2.2.0+20160505161446", - "node": "registry:dt/node#4.0.0+20160509154515", - "selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654" - } -} diff --git a/public/docs/_examples/animations/e2e-spec.ts b/public/docs/_examples/animations/e2e-spec.ts new file mode 100644 index 0000000000..4fba7ec475 --- /dev/null +++ b/public/docs/_examples/animations/e2e-spec.ts @@ -0,0 +1,351 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by, ElementFinder } from 'protractor'; +import { logging, promise } from 'selenium-webdriver'; + +/** + * The tests here basically just checking that the end styles + * of each animation are in effect. + * + * Relies on the Angular testability only becoming stable once + * animation(s) have finished. + * + * Ideally we'd use https://developer.mozilla.org/en-US/docs/Web/API/Document/getAnimations + * but they're not supported in Chrome at the moment. The upcoming nganimate polyfill + * may also add some introspection support. + */ +describe('Animation Tests', () => { + + const INACTIVE_COLOR = 'rgba(238, 238, 238, 1)'; + const ACTIVE_COLOR = 'rgba(207, 216, 220, 1)'; + const NO_TRANSFORM_MATRIX_REGEX = /matrix\(1,\s*0,\s*0,\s*1,\s*0,\s*0\)/; + + beforeEach(() => { + browser.get(''); + }); + + describe('basic states', () => { + + let host: ElementFinder; + + beforeEach(() => { + host = element(by.css('hero-list-basic')); + }); + + it('animates between active and inactive', () => { + addInactiveHero(); + + let li = host.element(by.css('li')); + + expect(getScaleX(li)).toBe(1.0); + expect(li.getCssValue('backgroundColor')).toBe(INACTIVE_COLOR); + + li.click(); + browser.driver.sleep(300); + expect(getScaleX(li)).toBe(1.1); + expect(li.getCssValue('backgroundColor')).toBe(ACTIVE_COLOR); + + li.click(); + browser.driver.sleep(300); + expect(getScaleX(li)).toBe(1.0); + expect(li.getCssValue('backgroundColor')).toBe(INACTIVE_COLOR); + }); + + }); + + describe('styles inline in transitions', () => { + + let host: ElementFinder; + + beforeEach(function() { + host = element(by.css('hero-list-inline-styles')); + }); + + it('are not kept after animation', () => { + addInactiveHero(); + + let li = host.element(by.css('li')); + + li.click(); + browser.driver.sleep(300); + expect(getScaleX(li)).toBe(1.0); + expect(li.getCssValue('backgroundColor')).toBe(INACTIVE_COLOR); + }); + + }); + + describe('combined transition syntax', () => { + + let host: ElementFinder; + + beforeEach(() => { + host = element(by.css('hero-list-combined-transitions')); + }); + + it('animates between active and inactive', () => { + addInactiveHero(); + + let li = host.element(by.css('li')); + + expect(getScaleX(li)).toBe(1.0); + expect(li.getCssValue('backgroundColor')).toBe(INACTIVE_COLOR); + + li.click(); + browser.driver.sleep(300); + expect(getScaleX(li)).toBe(1.1); + expect(li.getCssValue('backgroundColor')).toBe(ACTIVE_COLOR); + + li.click(); + browser.driver.sleep(300); + expect(getScaleX(li)).toBe(1.0); + expect(li.getCssValue('backgroundColor')).toBe(INACTIVE_COLOR); + }); + + }); + + describe('two-way transition syntax', () => { + + let host: ElementFinder; + + beforeEach(() => { + host = element(by.css('hero-list-twoway')); + }); + + it('animates between active and inactive', () => { + addInactiveHero(); + + let li = host.element(by.css('li')); + + expect(getScaleX(li)).toBe(1.0); + expect(li.getCssValue('backgroundColor')).toBe(INACTIVE_COLOR); + + li.click(); + browser.driver.sleep(300); + expect(getScaleX(li)).toBe(1.1); + expect(li.getCssValue('backgroundColor')).toBe(ACTIVE_COLOR); + + li.click(); + browser.driver.sleep(300); + expect(getScaleX(li)).toBe(1.0); + expect(li.getCssValue('backgroundColor')).toBe(INACTIVE_COLOR); + }); + + }); + + describe('enter & leave', () => { + + let host: ElementFinder; + + beforeEach(() => { + host = element(by.css('hero-list-enter-leave')); + }); + + it('adds and removes element', () => { + addInactiveHero(); + + let li = host.element(by.css('li')); + expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX); + + removeHero(); + expect(li.isPresent()).toBe(false); + }); + + }); + + describe('enter & leave & states', () => { + + let host: ElementFinder; + + beforeEach(function() { + host = element(by.css('hero-list-enter-leave-states')); + }); + + it('adds and removes and animates between active and inactive', () => { + addInactiveHero(); + + let li = host.element(by.css('li')); + + expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX); + + li.click(); + browser.driver.sleep(300); + expect(getScaleX(li)).toBe(1.1); + + li.click(); + browser.driver.sleep(300); + expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX); + + removeHero(); + expect(li.isPresent()).toBe(false); + }); + + }); + + describe('auto style calc', () => { + + let host: ElementFinder; + + beforeEach(function() { + host = element(by.css('hero-list-auto')); + }); + + it('adds and removes element', () => { + addInactiveHero(); + + let li = host.element(by.css('li')); + expect(li.getCssValue('height')).toBe('50px'); + + removeHero(); + expect(li.isPresent()).toBe(false); + }); + + }); + + describe('different timings', () => { + + let host: ElementFinder; + + beforeEach(() => { + host = element(by.css('hero-list-timings')); + }); + + it('adds and removes element', () => { + addInactiveHero(); + + let li = host.element(by.css('li')); + expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX); + expect(li.getCssValue('opacity')).toMatch('1'); + + removeHero(); + expect(li.isPresent()).toBe(false); + }); + + }); + + describe('multiple keyframes', () => { + + let host: ElementFinder; + + beforeEach(() => { + host = element(by.css('hero-list-multistep')); + }); + + it('adds and removes element', () => { + addInactiveHero(); + + let li = host.element(by.css('li')); + expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX); + expect(li.getCssValue('opacity')).toMatch('1'); + + removeHero(); + expect(li.isPresent()).toBe(false); + }); + + }); + + describe('parallel groups', () => { + + let host: ElementFinder; + + beforeEach(() => { + host = element(by.css('hero-list-groups')); + }); + + it('adds and removes element', () => { + addInactiveHero(); + + let li = host.element(by.css('li')); + expect(li.getCssValue('transform')).toMatch(NO_TRANSFORM_MATRIX_REGEX); + expect(li.getCssValue('opacity')).toMatch('1'); + + removeHero(700); + expect(li.isPresent()).toBe(false); + }); + + }); + + describe('adding active heroes', () => { + + let host: ElementFinder; + + beforeEach(() => { + host = element(by.css('hero-list-basic')); + }); + + it('animates between active and inactive', () => { + addActiveHero(); + + let li = host.element(by.css('li')); + + expect(getScaleX(li)).toBe(1.1); + expect(li.getCssValue('backgroundColor')).toBe(ACTIVE_COLOR); + + li.click(); + browser.driver.sleep(300); + expect(getScaleX(li)).toBe(1.0); + expect(li.getCssValue('backgroundColor')).toBe(INACTIVE_COLOR); + + li.click(); + browser.driver.sleep(300); + expect(getScaleX(li)).toBe(1.1); + expect(li.getCssValue('backgroundColor')).toBe(ACTIVE_COLOR); + }); + }); + + describe('callbacks', () => { + it('fires a callback on start and done', () => { + addActiveHero(); + browser.manage().logs().get(logging.Type.BROWSER) + .then((logs: logging.Entry[]) => { + const animationMessages = logs.filter((log) => { + return log.message.indexOf('Animation') !== -1 ? true : false; + }); + + expect(animationMessages.length).toBeGreaterThan(0); + }); + }); + }); + + function addActiveHero(sleep?: number) { + sleep = sleep || 500; + element(by.buttonText('Add active hero')).click(); + browser.driver.sleep(sleep); + } + + function addInactiveHero(sleep?: number) { + sleep = sleep || 500; + element(by.buttonText('Add inactive hero')).click(); + browser.driver.sleep(sleep); + } + + function removeHero(sleep?: number) { + sleep = sleep || 500; + element(by.buttonText('Remove hero')).click(); + browser.driver.sleep(sleep); + } + + function getScaleX(el: ElementFinder) { + return Promise.all([ + getBoundingClientWidth(el), + getOffsetWidth(el) + ]).then(function(promiseResolutions) { + let clientWidth = promiseResolutions[0]; + let offsetWidth = promiseResolutions[1]; + return clientWidth / offsetWidth; + }); + } + + function getBoundingClientWidth(el: ElementFinder): promise.Promise { + return browser.executeScript( + 'return arguments[0].getBoundingClientRect().width', + el.getWebElement() + ); + } + + function getOffsetWidth(el: ElementFinder): promise.Promise { + return browser.executeScript( + 'return arguments[0].offsetWidth', + el.getWebElement() + ); + } +}); diff --git a/public/docs/_examples/animations/ts/.gitignore b/public/docs/_examples/animations/ts/.gitignore new file mode 100644 index 0000000000..2cb7d2a2e9 --- /dev/null +++ b/public/docs/_examples/animations/ts/.gitignore @@ -0,0 +1 @@ +**/*.js diff --git a/public/docs/_examples/architecture/dart/example-config.json b/public/docs/_examples/animations/ts/example-config.json similarity index 100% rename from public/docs/_examples/architecture/dart/example-config.json rename to public/docs/_examples/animations/ts/example-config.json diff --git a/public/docs/_examples/animations/ts/plnkr.json b/public/docs/_examples/animations/ts/plnkr.json new file mode 100644 index 0000000000..f047395e7f --- /dev/null +++ b/public/docs/_examples/animations/ts/plnkr.json @@ -0,0 +1,8 @@ +{ + "description": "Angular Animations", + "basePath": "src/", + "files":[ + "!**/*.d.ts", + "!**/*.js" + ] +} diff --git a/public/docs/_examples/animations/ts/src/app/app.module.ts b/public/docs/_examples/animations/ts/src/app/app.module.ts new file mode 100644 index 0000000000..0773357c58 --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/app.module.ts @@ -0,0 +1,38 @@ +// #docregion animations-module +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +// #enddocregion animations-module + +import { HeroTeamBuilderComponent } from './hero-team-builder.component'; +import { HeroListBasicComponent } from './hero-list-basic.component'; +import { HeroListInlineStylesComponent } from './hero-list-inline-styles.component'; +import { HeroListEnterLeaveComponent } from './hero-list-enter-leave.component'; +import { HeroListEnterLeaveStatesComponent } from './hero-list-enter-leave-states.component'; +import { HeroListCombinedTransitionsComponent } from './hero-list-combined-transitions.component'; +import { HeroListTwowayComponent } from './hero-list-twoway.component'; +import { HeroListAutoComponent } from './hero-list-auto.component'; +import { HeroListGroupsComponent } from './hero-list-groups.component'; +import { HeroListMultistepComponent } from './hero-list-multistep.component'; +import { HeroListTimingsComponent } from './hero-list-timings.component'; + +// #docregion animation-module +@NgModule({ + imports: [ BrowserModule, BrowserAnimationsModule ], + // #enddocregion animation-module + declarations: [ + HeroTeamBuilderComponent, + HeroListBasicComponent, + HeroListInlineStylesComponent, + HeroListCombinedTransitionsComponent, + HeroListTwowayComponent, + HeroListEnterLeaveComponent, + HeroListEnterLeaveStatesComponent, + HeroListAutoComponent, + HeroListTimingsComponent, + HeroListMultistepComponent, + HeroListGroupsComponent + ], + bootstrap: [ HeroTeamBuilderComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/animations/ts/src/app/hero-list-auto.component.ts b/public/docs/_examples/animations/ts/src/app/hero-list-auto.component.ts new file mode 100644 index 0000000000..84b25c05de --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-list-auto.component.ts @@ -0,0 +1,47 @@ +import { + Component, + Input +} from '@angular/core'; +import { + trigger, + state, + style, + animate, + transition +} from '@angular/animations'; + +import { Heroes } from './hero.service'; + +@Component({ + selector: 'hero-list-auto', + // #docregion template + template: ` +
    +
  • + {{hero.name}} +
  • +
+ `, + // #enddocregion template + styleUrls: ['./hero-list.component.css'], + + /* When the element leaves (transition "in => void" occurs), + * get the element's current computed height and animate + * it down to 0. + */ + // #docregion animationdef + animations: [ + trigger('shrinkOut', [ + state('in', style({height: '*'})), + transition('* => void', [ + style({height: '*'}), + animate(250, style({height: 0})) + ]) + ]) + ] + // #enddocregion animationdef +}) +export class HeroListAutoComponent { + @Input() heroes: Heroes; +} diff --git a/public/docs/_examples/animations/ts/src/app/hero-list-basic.component.ts b/public/docs/_examples/animations/ts/src/app/hero-list-basic.component.ts new file mode 100644 index 0000000000..76d5ba686c --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-list-basic.component.ts @@ -0,0 +1,70 @@ +// #docplaster +// #docregion +// #docregion imports +import { + Component, + Input +} from '@angular/core'; +import { + trigger, + state, + style, + animate, + transition +} from '@angular/animations'; +// #enddocregion imports + +import { Heroes } from './hero.service'; + +@Component({ + selector: 'hero-list-basic', + // #enddocregion + /* The click event calls hero.toggleState(), which + * causes the state of that hero to switch from + * active to inactive or vice versa. + */ + // #docregion + // #docregion template + template: ` +
    +
  • + {{hero.name}} +
  • +
+ `, + // #enddocregion template + styleUrls: ['./hero-list.component.css'], + // #enddocregion + /** + * Define two states, "inactive" and "active", and the end + * styles that apply whenever the element is in those states. + * Then define animations for transitioning between the states, + * one in each direction + */ + // #docregion + // #docregion animationdef + animations: [ + trigger('heroState', [ + // #docregion states + state('inactive', style({ + backgroundColor: '#eee', + transform: 'scale(1)' + })), + state('active', style({ + backgroundColor: '#cfd8dc', + transform: 'scale(1.1)' + })), + // #enddocregion states + // #docregion transitions + transition('inactive => active', animate('100ms ease-in')), + transition('active => inactive', animate('100ms ease-out')) + // #enddocregion transitions + ]) + ] + // #enddocregion animationdef +}) +export class HeroListBasicComponent { + @Input() heroes: Heroes; +} diff --git a/public/docs/_examples/animations/ts/src/app/hero-list-combined-transitions.component.ts b/public/docs/_examples/animations/ts/src/app/hero-list-combined-transitions.component.ts new file mode 100644 index 0000000000..fc654cbcb5 --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-list-combined-transitions.component.ts @@ -0,0 +1,59 @@ +// #docregion +// #docregion imports +import { + Component, + Input +} from '@angular/core'; +import { + trigger, + state, + style, + animate, + transition +} from '@angular/animations'; +// #enddocregion imports + +import { Heroes } from './hero.service'; + +@Component({ + selector: 'hero-list-combined-transitions', + // #docregion template + template: ` +
    +
  • + {{hero.name}} +
  • +
+ `, + // #enddocregion template + styleUrls: ['./hero-list.component.css'], + /* + * Define two states, "inactive" and "active", and the end + * styles that apply whenever the element is in those states. + * Then define an animated transition between these two + * states, in *both* directions. + */ + // #docregion animationdef + animations: [ + trigger('heroState', [ + state('inactive', style({ + backgroundColor: '#eee', + transform: 'scale(1)' + })), + state('active', style({ + backgroundColor: '#cfd8dc', + transform: 'scale(1.1)' + })), + // #docregion transitions + transition('inactive => active, active => inactive', + animate('100ms ease-out')) + // #enddocregion transitions + ]) + ] + // #enddocregion animationdef +}) +export class HeroListCombinedTransitionsComponent { + @Input() heroes: Heroes; +} diff --git a/public/docs/_examples/animations/ts/src/app/hero-list-enter-leave-states.component.ts b/public/docs/_examples/animations/ts/src/app/hero-list-enter-leave-states.component.ts new file mode 100644 index 0000000000..c01e182e8b --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-list-enter-leave-states.component.ts @@ -0,0 +1,63 @@ +import { + Component, + Input +} from '@angular/core'; +import { + trigger, + state, + style, + animate, + transition +} from '@angular/animations'; + +import { Heroes } from './hero.service'; + +@Component({ + selector: 'hero-list-enter-leave-states', + // #docregion template + template: ` +
    +
  • + {{hero.name}} +
  • +
+ `, + // #enddocregion template + styleUrls: ['./hero-list.component.css'], + /* The elements here have two possible states based + * on the hero state, "active", or "inactive". We animate + * six transitions: Between the two states in both directions, + * and between each state and void. With this we can animate + * the enter and leave of elements differently based on which + * state they are in when they are added and removed. + */ + // #docregion animationdef + animations: [ + trigger('heroState', [ + state('inactive', style({transform: 'translateX(0) scale(1)'})), + state('active', style({transform: 'translateX(0) scale(1.1)'})), + transition('inactive => active', animate('100ms ease-in')), + transition('active => inactive', animate('100ms ease-out')), + transition('void => inactive', [ + style({transform: 'translateX(-100%) scale(1)'}), + animate(100) + ]), + transition('inactive => void', [ + animate(100, style({transform: 'translateX(100%) scale(1)'})) + ]), + transition('void => active', [ + style({transform: 'translateX(0) scale(0)'}), + animate(200) + ]), + transition('active => void', [ + animate(200, style({transform: 'translateX(0) scale(0)'})) + ]) + ]) + ] + // #enddocregion animationdef +}) +export class HeroListEnterLeaveStatesComponent { + @Input() heroes: Heroes; +} diff --git a/public/docs/_examples/animations/ts/src/app/hero-list-enter-leave.component.ts b/public/docs/_examples/animations/ts/src/app/hero-list-enter-leave.component.ts new file mode 100644 index 0000000000..f27b5f10e1 --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-list-enter-leave.component.ts @@ -0,0 +1,51 @@ +import { + Component, + Input +} from '@angular/core'; +import { + trigger, + state, + style, + animate, + transition +} from '@angular/animations'; + +import { Heroes } from './hero.service'; + +@Component({ + selector: 'hero-list-enter-leave', + // #docregion template + template: ` +
    +
  • + {{hero.name}} +
  • +
+ `, + // #enddocregion template + styleUrls: ['./hero-list.component.css'], + /* The element here always has the state "in" when it + * is present. We animate two transitions: From void + * to in and from in to void, to achieve an animated + * enter and leave transition. The element enters from + * the left and leaves to the right using translateX. + */ + // #docregion animationdef + animations: [ + trigger('flyInOut', [ + state('in', style({transform: 'translateX(0)'})), + transition('void => *', [ + style({transform: 'translateX(-100%)'}), + animate(100) + ]), + transition('* => void', [ + animate(100, style({transform: 'translateX(100%)'})) + ]) + ]) + ] + // #enddocregion animationdef +}) +export class HeroListEnterLeaveComponent { + @Input() heroes: Heroes; +} diff --git a/public/docs/_examples/animations/ts/src/app/hero-list-groups.component.ts b/public/docs/_examples/animations/ts/src/app/hero-list-groups.component.ts new file mode 100644 index 0000000000..12a57292f7 --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-list-groups.component.ts @@ -0,0 +1,80 @@ +import { + Component, + Input +} from '@angular/core'; +import { + trigger, + state, + style, + animate, + transition, + group +} from '@angular/animations'; + +import { Heroes } from './hero.service'; + +@Component({ + selector: 'hero-list-groups', + template: ` +
    +
  • + {{hero.name}} +
  • +
+ `, + styleUrls: ['./hero-list.component.css'], + styles: [` + li { + padding: 0 !important; + text-align: center; + } + `], + /* The element here always has the state "in" when it + * is present. We animate two transitions: From void + * to in and from in to void, to achieve an animated + * enter and leave transition. + * + * The transitions have *parallel group* that allow + * animating several properties at the same time but + * with different timing configurations. On enter + * (void => *) we start the opacity animation 0.1s + * earlier than the translation/width animation. + * On leave (* => void) we do the opposite - + * the translation/width animation begins immediately + * and the opacity animation 0.1s later. + */ + // #docregion animationdef + animations: [ + trigger('flyInOut', [ + state('in', style({width: 120, transform: 'translateX(0)', opacity: 1})), + transition('void => *', [ + style({width: 10, transform: 'translateX(50px)', opacity: 0}), + group([ + animate('0.3s 0.1s ease', style({ + transform: 'translateX(0)', + width: 120 + })), + animate('0.3s ease', style({ + opacity: 1 + })) + ]) + ]), + transition('* => void', [ + group([ + animate('0.3s ease', style({ + transform: 'translateX(50px)', + width: 10 + })), + animate('0.3s 0.2s ease', style({ + opacity: 0 + })) + ]) + ]) + ]) + ] + // #enddocregion animationdef +}) +export class HeroListGroupsComponent { + @Input() heroes: Heroes; +} diff --git a/public/docs/_examples/animations/ts/src/app/hero-list-inline-styles.component.ts b/public/docs/_examples/animations/ts/src/app/hero-list-inline-styles.component.ts new file mode 100644 index 0000000000..ed1bdb7646 --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-list-inline-styles.component.ts @@ -0,0 +1,60 @@ +// #docregion +// #docregion imports +import { + Component, + Input, +} from '@angular/core'; +import { + trigger, + style, + animate, + transition +} from '@angular/animations'; +// #enddocregion imports + +import { Heroes } from './hero.service'; + +@Component({ + selector: 'hero-list-inline-styles', + // #docregion template + template: ` +
    +
  • + {{hero.name}} +
  • +
+ `, + // #enddocregion template + styleUrls: ['./hero-list.component.css'], + /** + * Define two states, "inactive" and "active", and the end + * styles that apply whenever the element is in those states. + * Then define an animation for the inactive => active transition. + * This animation has no end styles, but only styles that are + * defined inline inside the transition and thus are only kept + * as long as the animation is running. + */ + // #docregion animationdef + animations: [ + trigger('heroState', [ + // #docregion transitions + transition('inactive => active', [ + style({ + backgroundColor: '#cfd8dc', + transform: 'scale(1.3)' + }), + animate('80ms ease-in', style({ + backgroundColor: '#eee', + transform: 'scale(1)' + })) + ]), + // #enddocregion transitions + ]) + ] + // #enddocregion animationdef +}) +export class HeroListInlineStylesComponent { + @Input() heroes: Heroes; +} diff --git a/public/docs/_examples/animations/ts/src/app/hero-list-multistep.component.ts b/public/docs/_examples/animations/ts/src/app/hero-list-multistep.component.ts new file mode 100644 index 0000000000..4e57896de5 --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-list-multistep.component.ts @@ -0,0 +1,71 @@ +import { + Component, + Input, +} from '@angular/core'; +import { + trigger, + state, + style, + animate, + transition, + keyframes, + AnimationEvent +} from '@angular/animations'; + +import { Heroes } from './hero.service'; + +@Component({ + selector: 'hero-list-multistep', + // #docregion template + template: ` +
    +
  • + {{hero.name}} +
  • +
+ `, + // #enddocregion template + styleUrls: ['./hero-list.component.css'], + /* The element here always has the state "in" when it + * is present. We animate two transitions: From void + * to in and from in to void, to achieve an animated + * enter and leave transition. Each transition is + * defined in terms of multiple keyframes, to give it + * a bounce effect. + */ + // #docregion animationdef + animations: [ + trigger('flyInOut', [ + state('in', style({transform: 'translateX(0)'})), + transition('void => *', [ + animate(300, keyframes([ + style({opacity: 0, transform: 'translateX(-100%)', offset: 0}), + style({opacity: 1, transform: 'translateX(15px)', offset: 0.3}), + style({opacity: 1, transform: 'translateX(0)', offset: 1.0}) + ])) + ]), + transition('* => void', [ + animate(300, keyframes([ + style({opacity: 1, transform: 'translateX(0)', offset: 0}), + style({opacity: 1, transform: 'translateX(-15px)', offset: 0.7}), + style({opacity: 0, transform: 'translateX(100%)', offset: 1.0}) + ])) + ]) + ]) + ] + // #enddocregion animationdef +}) +export class HeroListMultistepComponent { + @Input() heroes: Heroes; + + animationStarted(event: AnimationEvent) { + console.warn('Animation started: ', event); + } + + animationDone(event: AnimationEvent) { + console.warn('Animation done: ', event); + } +} diff --git a/public/docs/_examples/animations/ts/src/app/hero-list-timings.component.ts b/public/docs/_examples/animations/ts/src/app/hero-list-timings.component.ts new file mode 100644 index 0000000000..3218609b4a --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-list-timings.component.ts @@ -0,0 +1,58 @@ +import { + Component, + Input +} from '@angular/core'; +import { + trigger, + state, + style, + animate, + transition +} from '@angular/animations'; + +import { Heroes } from './hero.service'; + +@Component({ + selector: 'hero-list-timings', + template: ` +
    +
  • + {{hero.name}} +
  • +
+ `, + styleUrls: ['./hero-list.component.css'], + /* The element here always has the state "in" when it + * is present. We animate two transitions: From void + * to in and from in to void, to achieve an animated + * enter and leave transition. The element enters from + * the left and leaves to the right using translateX, + * and fades in/out using opacity. We use different easings + * for enter and leave. + */ + // #docregion animationdef + animations: [ + trigger('flyInOut', [ + state('in', style({opacity: 1, transform: 'translateX(0)'})), + transition('void => *', [ + style({ + opacity: 0, + transform: 'translateX(-100%)' + }), + animate('0.2s ease-in') + ]), + transition('* => void', [ + animate('0.2s 10 ease-out', style({ + opacity: 0, + transform: 'translateX(100%)' + })) + ]) + ]) + ] + // #enddocregion animationdef +}) +export class HeroListTimingsComponent { + @Input() heroes: Heroes; +} diff --git a/public/docs/_examples/animations/ts/src/app/hero-list-twoway.component.ts b/public/docs/_examples/animations/ts/src/app/hero-list-twoway.component.ts new file mode 100644 index 0000000000..46d0c64a68 --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-list-twoway.component.ts @@ -0,0 +1,58 @@ +// #docregion +// #docregion imports +import { + Component, + Input +} from '@angular/core'; +import { + trigger, + state, + style, + animate, + transition +} from '@angular/animations'; +// #enddocregion imports + +import { Heroes } from './hero.service'; + +@Component({ + selector: 'hero-list-twoway', + // #docregion template + template: ` +
    +
  • + {{hero.name}} +
  • +
+ `, + // #enddocregion template + styleUrls: ['./hero-list.component.css'], + /* + * Define two states, "inactive" and "active", and the end + * styles that apply whenever the element is in those states. + * Then define an animated transition between these two + * states, in *both* directions. + */ + // #docregion animationdef + animations: [ + trigger('heroState', [ + state('inactive', style({ + backgroundColor: '#eee', + transform: 'scale(1)' + })), + state('active', style({ + backgroundColor: '#cfd8dc', + transform: 'scale(1.1)' + })), + // #docregion transitions + transition('inactive <=> active', animate('100ms ease-out')) + // #enddocregion transitions + ]) + ] + // #enddocregion animationdef +}) +export class HeroListTwowayComponent { + @Input() heroes: Heroes; +} diff --git a/public/docs/_examples/animations/ts/src/app/hero-list.component.css b/public/docs/_examples/animations/ts/src/app/hero-list.component.css new file mode 100644 index 0000000000..b256521e49 --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-list.component.css @@ -0,0 +1,27 @@ +ul { + list-style-type: none; + padding: 0; +} + +li { + display: block; + width: 120px; + line-height: 50px; + padding: 0 10px; + box-sizing: border-box; + background-color: #eee; + border-radius: 4px; + margin: 10px; + cursor: pointer; + overflow: hidden; + white-space: nowrap; +} + +.active { + background-color: #cfd8dc; + transform: scale(1.1); +} +.inactive { + background-color: #eee; + transform: scale(1); +} diff --git a/public/docs/_examples/animations/ts/src/app/hero-team-builder.component.ts b/public/docs/_examples/animations/ts/src/app/hero-team-builder.component.ts new file mode 100644 index 0000000000..e5413be50e --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero-team-builder.component.ts @@ -0,0 +1,94 @@ +import { Component } from '@angular/core'; + +import { Heroes } from './hero.service'; + +@Component({ + selector: 'hero-team-builder', + template: ` +
+ + + +
+
+
+

Basic State

+

Switch between active/inactive on click.

+ +
+
+

Styles inline in transitions

+

Animated effect on click, no persistend end styles.

+ +
+
+

Combined transition syntax

+

Switch between active/inactive on click. Define just one transition used in both directions.

+ +
+
+

Two-way transition syntax

+

Switch between active/inactive on click. Define just one transition used in both directions using the <=> syntax.

+ +
+
+

Enter & Leave

+

Enter and leave animations using the void state.

+ +
+
+
+
+

Enter & Leave & States

+

+ Enter and leave animations combined with active/inactive state animations. + Different enter and leave transitions depending on state. +

+ +
+
+

Auto Style Calc

+

Leave animation from the current computed height using the auto-style value *.

+ +
+
+

Different Timings

+

Enter and leave animations with different easings, ease-in for enter, ease-out for leave.

+ +
+
+

Multiple Keyframes

+

Enter and leave animations with three keyframes in each, to give the transition some bounce.

+ +
+
+

Parallel Groups

+

Enter and leave animations with multiple properties animated in parallel with different timings.

+ +
+
+ `, + styles: [` + .buttons { + text-align: center; + } + button { + padding: 1.5em 3em; + } + .columns { + display: flex; + flex-direction: row; + } + .column { + flex: 1; + padding: 10px; + } + .column p { + min-height: 6em; + } + `], + providers: [Heroes] +}) +export class HeroTeamBuilderComponent { + constructor(private heroes: Heroes) { } +} diff --git a/public/docs/_examples/animations/ts/src/app/hero.service.ts b/public/docs/_examples/animations/ts/src/app/hero.service.ts new file mode 100644 index 0000000000..6bdeb5a512 --- /dev/null +++ b/public/docs/_examples/animations/ts/src/app/hero.service.ts @@ -0,0 +1,60 @@ +import { Injectable } from '@angular/core'; + +class Hero { + constructor(public name: string, + public state = 'inactive') { + } + + toggleState() { + this.state = (this.state === 'active' ? 'inactive' : 'active'); + } +} + +let ALL_HEROES = [ + 'Windstorm', + 'RubberMan', + 'Bombasto', + 'Magneta', + 'Dynama', + 'Narco', + 'Celeritas', + 'Dr IQ', + 'Magma', + 'Tornado', + 'Mr. Nice' +].map(name => new Hero(name)); + +@Injectable() +export class Heroes implements Iterable { + + currentHeroes: Hero[] = []; + + [Symbol.iterator]() { + return this.currentHeroes.values(); + } + + canAdd() { + return this.currentHeroes.length < ALL_HEROES.length; + } + + canRemove() { + return this.currentHeroes.length > 0; + } + + addActive() { + let hero = ALL_HEROES[this.currentHeroes.length]; + hero.state = 'active'; + this.currentHeroes.push(hero); + } + + addInactive() { + let hero = ALL_HEROES[this.currentHeroes.length]; + hero.state = 'inactive'; + this.currentHeroes.push(hero); + } + + remove() { + this.currentHeroes.splice(this.currentHeroes.length - 1, 1); + } + +} diff --git a/public/docs/_examples/animations/ts/src/index.html b/public/docs/_examples/animations/ts/src/index.html new file mode 100644 index 0000000000..6c4a13adb2 --- /dev/null +++ b/public/docs/_examples/animations/ts/src/index.html @@ -0,0 +1,34 @@ + + + + + Animations + + + + + + + + + + + + + + + + + + +

External H1 Title for E2E test

+ + +
    +
  • External list for E2E test
  • +
+ + + diff --git a/public/docs/_examples/animations/ts/src/main.ts b/public/docs/_examples/animations/ts/src/main.ts new file mode 100644 index 0000000000..f22933ba8e --- /dev/null +++ b/public/docs/_examples/animations/ts/src/main.ts @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/architecture/dart/.docsync.json b/public/docs/_examples/architecture/dart/.docsync.json deleted file mode 100644 index f47a6645ce..0000000000 --- a/public/docs/_examples/architecture/dart/.docsync.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "Architecture overview", - "docHref": "https://angular.io/docs/dart/latest/guide/architecture.html" -} diff --git a/public/docs/_examples/architecture/dart/lib/backend_service.dart b/public/docs/_examples/architecture/dart/lib/backend_service.dart deleted file mode 100644 index d0f6886dbf..0000000000 --- a/public/docs/_examples/architecture/dart/lib/backend_service.dart +++ /dev/null @@ -1,24 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'logger_service.dart'; - -@Injectable() -class BackendService { - final Logger _logger; - List getAll(type) { - // TODO get from the database and return as a promise - if (type == Hero) { - return [ - new Hero('Windstorm', power: 'Weather mastery'), - new Hero('Mr. Nice', power: 'Killing them with kindness'), - new Hero('Magneta', power: 'Manipulates metalic objects') - ]; - } - _logger.error('Cannot get object of this type'); - throw new ArgumentError("TODO: put log content here"); - } - - BackendService(Logger this._logger); -} diff --git a/public/docs/_examples/architecture/dart/lib/hero.dart b/public/docs/_examples/architecture/dart/lib/hero.dart deleted file mode 100644 index 1aa20e0ee8..0000000000 --- a/public/docs/_examples/architecture/dart/lib/hero.dart +++ /dev/null @@ -1,11 +0,0 @@ -// #docregion -class Hero { - static int _nextId = 1; - int id; - String name; - String power; - - Hero(this.name, {this.power}) { - id = _nextId++; - } -} diff --git a/public/docs/_examples/architecture/dart/lib/hero_detail_component.dart b/public/docs/_examples/architecture/dart/lib/hero_detail_component.dart deleted file mode 100644 index 94c26abbd0..0000000000 --- a/public/docs/_examples/architecture/dart/lib/hero_detail_component.dart +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; - -@Component(selector: 'hero-detail', templateUrl: 'hero_detail_component.html') -class HeroDetailComponent { - @Input() Hero hero; -} diff --git a/public/docs/_examples/architecture/dart/lib/hero_detail_component.html b/public/docs/_examples/architecture/dart/lib/hero_detail_component.html deleted file mode 100644 index 7dde3107e4..0000000000 --- a/public/docs/_examples/architecture/dart/lib/hero_detail_component.html +++ /dev/null @@ -1,9 +0,0 @@ -
-

{{hero.name}} Detail

-
Id: {{hero.id}}
-
Name: - -
- -
Power: -
diff --git a/public/docs/_examples/architecture/dart/lib/hero_list_component.dart b/public/docs/_examples/architecture/dart/lib/hero_list_component.dart deleted file mode 100644 index ba2b75de70..0000000000 --- a/public/docs/_examples/architecture/dart/lib/hero_list_component.dart +++ /dev/null @@ -1,37 +0,0 @@ -// #docplaster -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'hero_detail_component.dart'; -import 'hero_service.dart'; - -// #docregion metadata -// #docregion providers -@Component( -// #enddocregion providers - selector: 'hero-list', - templateUrl: 'hero_list_component.html', - directives: const [HeroDetailComponent], -// #docregion providers - providers: const [HeroService]) -// #enddocregion providers -// #enddocregion metadata -/* -// #docregion metadata, providers -class HeroListComponent { ... } -// #enddocregion metadata, providers -*/ -// #docregion class -class HeroListComponent { - List heroes; - Hero selectedHero; -// #docregion ctor - HeroListComponent(HeroService heroService) { - heroes = heroService.getHeroes(); - } -// #enddocregion ctor - selectHero(Hero hero) { - selectedHero = hero; - } -} -// #enddocregion class diff --git a/public/docs/_examples/architecture/dart/lib/hero_list_component.html b/public/docs/_examples/architecture/dart/lib/hero_list_component.html deleted file mode 100644 index e493e949fb..0000000000 --- a/public/docs/_examples/architecture/dart/lib/hero_list_component.html +++ /dev/null @@ -1,8 +0,0 @@ - -

Hero List

- -
- {{hero.name}} -
- - diff --git a/public/docs/_examples/architecture/dart/lib/hero_list_component_1.html b/public/docs/_examples/architecture/dart/lib/hero_list_component_1.html deleted file mode 100644 index 7a08bd2f8b..0000000000 --- a/public/docs/_examples/architecture/dart/lib/hero_list_component_1.html +++ /dev/null @@ -1,10 +0,0 @@ - -
{{hero.name}}
- -
...
- - - -
...
- - diff --git a/public/docs/_examples/architecture/dart/lib/hero_service.dart b/public/docs/_examples/architecture/dart/lib/hero_service.dart deleted file mode 100644 index 794e79927e..0000000000 --- a/public/docs/_examples/architecture/dart/lib/hero_service.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:angular2/core.dart'; - -import 'backend_service.dart'; -import 'hero.dart'; -import 'logger_service.dart'; - -// #docregion class -@Injectable() -class HeroService { - final BackendService _backendService; - final Logger _logger; - HeroService(Logger this._logger, BackendService this._backendService); - List getHeroes() { - List heroes = _backendService.getAll(Hero); - _logger.log('Got ${heroes.length} heroes from the server.'); - return heroes; - } -} -// #enddocregion class diff --git a/public/docs/_examples/architecture/dart/lib/logger_service.dart b/public/docs/_examples/architecture/dart/lib/logger_service.dart deleted file mode 100644 index 2d6d1c4f75..0000000000 --- a/public/docs/_examples/architecture/dart/lib/logger_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -// #docregion -import 'dart:html'; - -import 'package:angular2/core.dart'; - -/// A service for logging messages of various types. -/// -/// We could switch this implementation to use package:logging. -@Injectable() -class Logger { - void log(Object msg) => window.console.log(msg); - - void error(Object msg) => window.console.error(msg); - - void warn(Object msg) => window.console.warn(msg); -} diff --git a/public/docs/_examples/architecture/dart/pubspec.yaml b/public/docs/_examples/architecture/dart/pubspec.yaml deleted file mode 100644 index 9418b2ec76..0000000000 --- a/public/docs/_examples/architecture/dart/pubspec.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# #docregion -name: developer_guide_intro -description: Developer Guide Intro -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: 'package:angular2/common.dart#CORE_DIRECTIVES' - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/architecture/dart/web/index.html b/public/docs/_examples/architecture/dart/web/index.html deleted file mode 100644 index 17a00ffbed..0000000000 --- a/public/docs/_examples/architecture/dart/web/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - Intro to Angular 2 - - - - - - Loading... - - diff --git a/public/docs/_examples/architecture/dart/web/main.dart b/public/docs/_examples/architecture/dart/web/main.dart deleted file mode 100644 index acb382ab8e..0000000000 --- a/public/docs/_examples/architecture/dart/web/main.dart +++ /dev/null @@ -1,13 +0,0 @@ -// #docregion -import 'package:angular2/platform/browser.dart'; - -import 'package:developer_guide_intro/backend_service.dart'; -import 'package:developer_guide_intro/hero_list_component.dart'; -import 'package:developer_guide_intro/hero_service.dart'; -import 'package:developer_guide_intro/logger_service.dart'; - -main() { - // #docregion bootstrap - bootstrap(HeroListComponent, [BackendService, HeroService, Logger]); - // #enddocregion bootstrap -} diff --git a/public/docs/_examples/architecture/e2e-spec.ts b/public/docs/_examples/architecture/e2e-spec.ts index 66ea2a1081..e967804483 100644 --- a/public/docs/_examples/architecture/e2e-spec.ts +++ b/public/docs/_examples/architecture/e2e-spec.ts @@ -1,62 +1,100 @@ -/// -describe('Architecture', function () { - - let title = 'Hero List'; - - beforeAll(function () { - browser.get(''); - }); - - function itReset(name: string, func: () => any) { - it(name, function() { - browser.get('').then(func); - }); - } - - it(`should display correct title: ${title}`, function () { - expect(element(by.css('h2')).getText()).toEqual(title); - }); - - it('should display correct detail after selection', function() { - let detailView = element(by.css('hero-detail')); - expect(detailView.isPresent()).toBe(false); - // select the 2nd element - let selectEle = element.all(by.css('hero-list > div')).get(1); - selectEle.click().then(function() { - return selectEle.getText(); - }).then(function(selectedHeroName) { - // works but too specific if we change the app - // expect(selectedHeroName).toEqual('Mr. Nice'); - expect(detailView.isDisplayed()).toBe(true); - let detailTitleEle = element(by.css('hero-detail > h4')); - expect(detailTitleEle.getText()).toContain(selectedHeroName); - }); - }); - - itReset('should display correct detail after modification', function() { - let detailView = element(by.css('hero-detail')); - expect(detailView.isPresent()).toBe(false); - // select the 2nd element - let selectEle = element.all(by.css('hero-list > div')).get(1); - selectEle.click().then(function () { - return selectEle.getText(); - }).then(function (selectedHeroName) { - let detailTitleEle = element(by.css('hero-detail > h4')); - expect(detailTitleEle.getText()).toContain(selectedHeroName); - let heroNameEle = element.all(by.css('hero-detail input')).get(0); - - // check that both the initial selected item and the detail title reflect changes - // made to the input box. - // heroNameEle.sendKeys('foo'); - sendKeys(heroNameEle, 'foo'); - expect(detailTitleEle.getText()).toContain('foo'); - expect(selectEle.getText()).toContain('foo'); - - // getText on an input element always returns null - // http://stackoverflow.com/questions/20310442/how-to-gettext-on-an-input-in-protractor - // expect(heroNameEle.getText()).toEqual(selectedHeroName); - expect(heroNameEle.getAttribute('value')).toEqual(selectedHeroName + 'foo'); - }); +'use strict'; // necessary for es6 output in node + +import { protractor, browser, element, by, ElementFinder } from 'protractor'; + +const nameSuffix = 'X'; + +class Hero { + id: number; + name: string; +} + +describe('Architecture', () => { + + const expectedTitle = 'Architecture of Angular'; + const expectedH2 = ['Hero List', 'Sales Tax Calculator']; + + beforeAll(() => browser.get('')); + + it(`has title '${expectedTitle}'`, () => { + expect(browser.getTitle()).toEqual(expectedTitle); }); + it(`has h2 '${expectedH2}'`, () => { + let h2 = element.all(by.css('h2')).map((elt: any) => elt.getText()); + expect(h2).toEqual(expectedH2); + }); + + describe('Hero', heroTests); + describe('Salex tax', salesTaxTests); }); + +function heroTests() { + + const targetHero: Hero = { id: 2, name: 'Mr. Nice' }; + + it('has the right number of heroes', () => { + let page = getPageElts(); + expect(page.heroes.count()).toEqual(3); + }); + + it('has no hero details initially', function () { + let page = getPageElts(); + expect(page.heroDetail.isPresent()).toBeFalsy('no hero detail'); + }); + + it('shows selected hero details', async () => { + await element(by.cssContainingText('li', targetHero.name)).click(); + let page = getPageElts(); + let hero = await heroFromDetail(page.heroDetail); + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(targetHero.name); + }); + + it(`shows updated hero name in details`, async () => { + let input = element.all(by.css('input')).first(); + input.sendKeys(nameSuffix); + let page = getPageElts(); + let hero = await heroFromDetail(page.heroDetail); + let newName = targetHero.name + nameSuffix; + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(newName); + }); +} + +function salesTaxTests() { + it('has no sales tax initially', function () { + let page = getPageElts(); + expect(page.salesTaxDetail.isPresent()).toBeFalsy('no sales tax info'); + }); + + it('shows sales tax', async function () { + let page = getPageElts(); + page.salesTaxAmountInput.sendKeys('10', protractor.Key.ENTER); + expect(page.salesTaxDetail.getText()).toEqual('The sales tax is $1.00'); + }); +} + +// Helper functions + +function getPageElts() { + return { + heroes: element.all(by.css('my-app li')), + heroDetail: element(by.css('my-app hero-detail')), + salesTaxAmountInput: element(by.css('my-app sales-tax input')), + salesTaxDetail: element(by.css('my-app sales-tax div')) + }; +} + +async function heroFromDetail(detail: ElementFinder): Promise { + // Get hero id from the first
+ // let _id = await detail.all(by.css('div')).first().getText(); + let _id = await detail.all(by.css('div')).first().getText(); + // Get name from the h2 + // let _name = await detail.element(by.css('h4')).getText(); + let _name = await detail.element(by.css('h4')).getText(); + return { + id: +_id.substr(_id.indexOf(' ') + 1), + name: _name.substr(0, _name.lastIndexOf(' ')) + }; +} diff --git a/public/docs/_examples/architecture/ts/app/app.component.ts b/public/docs/_examples/architecture/ts/app/app.component.ts deleted file mode 100644 index 930cf5f045..0000000000 --- a/public/docs/_examples/architecture/ts/app/app.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -// #docregion import -import { Component } from '@angular/core'; -// #enddocregion import -import { HeroListComponent } from './hero-list.component'; -import { SalesTaxComponent } from './sales-tax.component'; - -@Component({ - selector: 'my-app', - template: ` - - - `, - directives: [HeroListComponent, SalesTaxComponent] -}) -// #docregion export -export class AppComponent { } -// #enddocregion export diff --git a/public/docs/_examples/architecture/ts/app/hero-detail.component.html b/public/docs/_examples/architecture/ts/app/hero-detail.component.html deleted file mode 100644 index baa3e8d9f9..0000000000 --- a/public/docs/_examples/architecture/ts/app/hero-detail.component.html +++ /dev/null @@ -1,9 +0,0 @@ -
-

{{hero.name}} Detail

-
Id: {{hero.id}}
-
Name: - - - -
-
Power:
\ No newline at end of file diff --git a/public/docs/_examples/architecture/ts/app/hero-detail.component.ts b/public/docs/_examples/architecture/ts/app/hero-detail.component.ts deleted file mode 100644 index 579ef637b0..0000000000 --- a/public/docs/_examples/architecture/ts/app/hero-detail.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, Input} from '@angular/core'; - -import { Hero } from './hero'; - -@Component({ - selector: 'hero-detail', - templateUrl: 'app/hero-detail.component.html', - directives: [HeroDetailComponent] -}) -export class HeroDetailComponent { - @Input() hero: Hero; -} diff --git a/public/docs/_examples/architecture/ts/app/hero-list.component.1.html b/public/docs/_examples/architecture/ts/app/hero-list.component.1.html deleted file mode 100644 index d4d6b905fa..0000000000 --- a/public/docs/_examples/architecture/ts/app/hero-list.component.1.html +++ /dev/null @@ -1,12 +0,0 @@ - -
{{hero.name}}
- -
- - - - -
- - - diff --git a/public/docs/_examples/architecture/ts/app/hero-list.component.html b/public/docs/_examples/architecture/ts/app/hero-list.component.html deleted file mode 100644 index f3c92b3141..0000000000 --- a/public/docs/_examples/architecture/ts/app/hero-list.component.html +++ /dev/null @@ -1,9 +0,0 @@ - -

Hero List

- -

Pick a hero from the list

-
- {{hero.name}} -
- - diff --git a/public/docs/_examples/architecture/ts/app/hero-list.component.ts b/public/docs/_examples/architecture/ts/app/hero-list.component.ts deleted file mode 100644 index 8e4ca9b1ae..0000000000 --- a/public/docs/_examples/architecture/ts/app/hero-list.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -// #docplaster -import { Component, OnInit } from '@angular/core'; - -import { Hero } from './hero'; -import { HeroDetailComponent } from './hero-detail.component'; -import { HeroService } from './hero.service'; - -// #docregion metadata -// #docregion providers -@Component({ -// #enddocregion providers - selector: 'hero-list', - templateUrl: 'app/hero-list.component.html', - directives: [HeroDetailComponent], -// #docregion providers - providers: [HeroService] -}) -// #enddocregion providers -// #enddocregion metadata -/* -// #docregion metadata, providers -export class HeroesComponent { ... } -// #enddocregion metadata, providers -*/ -// #docregion class -export class HeroListComponent implements OnInit { -// #docregion ctor - constructor(private service: HeroService) { } -// #enddocregion ctor - - heroes: Hero[]; - selectedHero: Hero; - - ngOnInit() { - this.heroes = this.service.getHeroes(); - } - - selectHero(hero: Hero) { this.selectedHero = hero; } -} -// #enddocregion class diff --git a/public/docs/_examples/architecture/ts/app/hero.service.ts b/public/docs/_examples/architecture/ts/app/hero.service.ts deleted file mode 100644 index d5df3bdf31..0000000000 --- a/public/docs/_examples/architecture/ts/app/hero.service.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Injectable } from '@angular/core'; - -import { Hero } from './hero'; -import { BackendService } from './backend.service'; -import { Logger } from './logger.service'; - -@Injectable() -// #docregion class -export class HeroService { - // #docregion ctor - constructor( - private backend: BackendService, - private logger: Logger) { } - // #enddocregion ctor - - private heroes: Hero[] = []; - - getHeroes() { - this.backend.getAll(Hero).then( (heroes: Hero[]) => { - this.logger.log(`Fetched ${heroes.length} heroes.`); - this.heroes.push(...heroes); // fill cache - }); - return this.heroes; - } -} -// #enddocregion class diff --git a/public/docs/_examples/architecture/ts/app/logger.service.ts b/public/docs/_examples/architecture/ts/app/logger.service.ts deleted file mode 100644 index 2d66d202eb..0000000000 --- a/public/docs/_examples/architecture/ts/app/logger.service.ts +++ /dev/null @@ -1,11 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -@Injectable() -// #docregion class -export class Logger { - log(msg: any) { console.log(msg); } - error(msg: any) { console.error(msg); } - warn(msg: any) { console.warn(msg); } -} -// #enddocregion class diff --git a/public/docs/_examples/architecture/ts/app/main.ts b/public/docs/_examples/architecture/ts/app/main.ts deleted file mode 100644 index 4e8c107afd..0000000000 --- a/public/docs/_examples/architecture/ts/app/main.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; -// #docregion import -import { AppComponent } from './app.component'; -// #enddocregion import -import { HeroService } from './hero.service'; -import { BackendService } from './backend.service'; -import { Logger } from './logger.service'; - -// #docregion bootstrap -bootstrap(AppComponent, [BackendService, HeroService, Logger]); -// #enddocregion bootstrap diff --git a/public/docs/_examples/architecture/ts/app/sales-tax.component.ts b/public/docs/_examples/architecture/ts/app/sales-tax.component.ts deleted file mode 100644 index 6d0c668578..0000000000 --- a/public/docs/_examples/architecture/ts/app/sales-tax.component.ts +++ /dev/null @@ -1,42 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; - -import { SalesTaxService } from './sales-tax.service'; -import { TaxRateService } from './tax-rate.service'; - -// #docregion metadata -// #docregion providers -@Component({ -// #enddocregion providers - selector: 'sales-tax', - template: ` -

Sales Tax Calculator

- Amount: - -
- The sales tax is - {{ getTax(amountBox.value) | currency:'USD':true:'1.2-2' }} -
- `, -// #docregion providers - providers: [SalesTaxService, TaxRateService] -}) -// #enddocregion providers -// #enddocregion metadata -/* -// #docregion metadata, providers -export class SalesTaxComponent { ... } -// #enddocregion metadata, providers -*/ -// #docregion class -export class SalesTaxComponent { -// #docregion ctor - constructor(private salesTaxService: SalesTaxService) { } -// #enddocregion ctor - - getTax(value:string | number){ - return this.salesTaxService.getVAT(value); - } -} -// #enddocregion class diff --git a/public/docs/_examples/architecture/ts/app/sales-tax.service.ts b/public/docs/_examples/architecture/ts/app/sales-tax.service.ts deleted file mode 100644 index 813cb4c9c0..0000000000 --- a/public/docs/_examples/architecture/ts/app/sales-tax.service.ts +++ /dev/null @@ -1,20 +0,0 @@ -// #docregion -import { Inject, Injectable } from '@angular/core'; - -import { TaxRateService } from './tax-rate.service'; - -// #docregion class -@Injectable() -export class SalesTaxService { - constructor(private rateService: TaxRateService) { } - getVAT(value:string | number){ - let amount:number; - if (typeof value === "string"){ - amount = parseFloat(value); - } else { - amount = value; - } - return (amount || 0) * this.rateService.getRate('VAT'); - } -} -// #enddocregion class diff --git a/public/docs/_examples/architecture/ts/app/tax-rate.service.ts b/public/docs/_examples/architecture/ts/app/tax-rate.service.ts deleted file mode 100644 index baaa8f49c7..0000000000 --- a/public/docs/_examples/architecture/ts/app/tax-rate.service.ts +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -// #docregion class -@Injectable() -export class TaxRateService { - getRate(rateName:string){return 0.10;} // always 10% everywhere -} -// #enddocregion class diff --git a/public/docs/_examples/architecture/ts/index.html b/public/docs/_examples/architecture/ts/index.html deleted file mode 100644 index e365c39f02..0000000000 --- a/public/docs/_examples/architecture/ts/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - Architecture of Angular 2 - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/architecture/ts/plnkr.json b/public/docs/_examples/architecture/ts/plnkr.json index 3acf69014c..b2f47131df 100644 --- a/public/docs/_examples/architecture/ts/plnkr.json +++ b/public/docs/_examples/architecture/ts/plnkr.json @@ -1,5 +1,6 @@ { - "description": "Intro to Angular2", + "description": "Intro to Angular", + "basePath": "src/", "files":[ "!**/*.d.ts", "!**/*.js", diff --git a/public/docs/_examples/architecture/ts/src/app/app.component.ts b/public/docs/_examples/architecture/ts/src/app/app.component.ts new file mode 100644 index 0000000000..b987f17e44 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/app.component.ts @@ -0,0 +1,14 @@ +// #docregion import +import { Component } from '@angular/core'; +// #enddocregion import + +@Component({ + selector: 'my-app', + template: ` + + + ` +}) +// #docregion export +export class AppComponent { } +// #enddocregion export diff --git a/public/docs/_examples/architecture/ts/src/app/app.module.ts b/public/docs/_examples/architecture/ts/src/app/app.module.ts new file mode 100644 index 0000000000..f6e64beecd --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/app.module.ts @@ -0,0 +1,36 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +// #docregion imports +import { NgModule } from '@angular/core'; +import { AppComponent } from './app.component'; +// #enddocregion imports +import { HeroDetailComponent } from './hero-detail.component'; +import { HeroListComponent } from './hero-list.component'; +import { SalesTaxComponent } from './sales-tax.component'; +import { HeroService } from './hero.service'; +import { BackendService } from './backend.service'; +import { Logger } from './logger.service'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule + ], + declarations: [ + AppComponent, + HeroDetailComponent, + HeroListComponent, + SalesTaxComponent + ], +// #docregion providers + providers: [ + BackendService, + HeroService, + Logger + ], +// #enddocregion providers + bootstrap: [ AppComponent ] +}) +// #docregion export +export class AppModule { } +// #enddocregion export diff --git a/public/docs/_examples/architecture/ts/app/backend.service.ts b/public/docs/_examples/architecture/ts/src/app/backend.service.ts similarity index 92% rename from public/docs/_examples/architecture/ts/app/backend.service.ts rename to public/docs/_examples/architecture/ts/src/app/backend.service.ts index 907a40696e..e47cfc8ace 100644 --- a/public/docs/_examples/architecture/ts/app/backend.service.ts +++ b/public/docs/_examples/architecture/ts/src/app/backend.service.ts @@ -13,7 +13,7 @@ const HEROES = [ export class BackendService { constructor(private logger: Logger) {} - getAll(type:Type) : PromiseLike{ + getAll(type: Type): PromiseLike { if (type === Hero) { // TODO get from the database return Promise.resolve(HEROES); diff --git a/public/docs/_examples/architecture/ts/src/app/hero-detail.component.html b/public/docs/_examples/architecture/ts/src/app/hero-detail.component.html new file mode 100644 index 0000000000..224de8bb86 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/hero-detail.component.html @@ -0,0 +1,9 @@ +
+

{{hero.name}} Detail

+
Id: {{hero.id}}
+
Name: + + + +
+
Power:
diff --git a/public/docs/_examples/architecture/ts/src/app/hero-detail.component.ts b/public/docs/_examples/architecture/ts/src/app/hero-detail.component.ts new file mode 100644 index 0000000000..b75d6dd225 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/hero-detail.component.ts @@ -0,0 +1,11 @@ +import { Component, Input } from '@angular/core'; + +import { Hero } from './hero'; + +@Component({ + selector: 'hero-detail', + templateUrl: './hero-detail.component.html' +}) +export class HeroDetailComponent { + @Input() hero: Hero; +} diff --git a/public/docs/_examples/architecture/ts/src/app/hero-list.component.1.html b/public/docs/_examples/architecture/ts/src/app/hero-list.component.1.html new file mode 100644 index 0000000000..c6e6dd5133 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/hero-list.component.1.html @@ -0,0 +1,9 @@ + +
  • {{hero.name}}
  • + +
  • + + + +
  • + diff --git a/public/docs/_examples/architecture/ts/src/app/hero-list.component.html b/public/docs/_examples/architecture/ts/src/app/hero-list.component.html new file mode 100644 index 0000000000..b46a307bd3 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/hero-list.component.html @@ -0,0 +1,11 @@ + +

    Hero List

    + +

    Pick a hero from the list

    +
      +
    • + {{hero.name}} +
    • +
    + + diff --git a/public/docs/_examples/architecture/ts/src/app/hero-list.component.ts b/public/docs/_examples/architecture/ts/src/app/hero-list.component.ts new file mode 100644 index 0000000000..a3d372f00b --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/hero-list.component.ts @@ -0,0 +1,29 @@ +import { Component, OnInit } from '@angular/core'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +// #docregion metadata, providers +@Component({ + selector: 'hero-list', + templateUrl: './hero-list.component.html', + providers: [ HeroService ] +}) +// #enddocregion providers +// #docregion class +export class HeroListComponent implements OnInit { + // #enddocregion metadata + heroes: Hero[]; + selectedHero: Hero; + + // #docregion ctor + constructor(private service: HeroService) { } + // #enddocregion ctor + + ngOnInit() { + this.heroes = this.service.getHeroes(); + } + + selectHero(hero: Hero) { this.selectedHero = hero; } + // #docregion metadata +} diff --git a/public/docs/_examples/architecture/ts/src/app/hero.service.ts b/public/docs/_examples/architecture/ts/src/app/hero.service.ts new file mode 100644 index 0000000000..493f064e40 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/hero.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from '@angular/core'; + +import { Hero } from './hero'; +import { BackendService } from './backend.service'; +import { Logger } from './logger.service'; + +@Injectable() +// #docregion class +export class HeroService { + private heroes: Hero[] = []; + + constructor( + private backend: BackendService, + private logger: Logger) { } + + getHeroes() { + this.backend.getAll(Hero).then( (heroes: Hero[]) => { + this.logger.log(`Fetched ${heroes.length} heroes.`); + this.heroes.push(...heroes); // fill cache + }); + return this.heroes; + } +} diff --git a/public/docs/_examples/architecture/ts/app/hero.ts b/public/docs/_examples/architecture/ts/src/app/hero.ts similarity index 100% rename from public/docs/_examples/architecture/ts/app/hero.ts rename to public/docs/_examples/architecture/ts/src/app/hero.ts diff --git a/public/docs/_examples/architecture/ts/src/app/logger.service.ts b/public/docs/_examples/architecture/ts/src/app/logger.service.ts new file mode 100644 index 0000000000..9277ee8bc0 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/logger.service.ts @@ -0,0 +1,9 @@ +import { Injectable } from '@angular/core'; + +@Injectable() +// #docregion class +export class Logger { + log(msg: any) { console.log(msg); } + error(msg: any) { console.error(msg); } + warn(msg: any) { console.warn(msg); } +} diff --git a/public/docs/_examples/architecture/ts/src/app/mini-app.ts b/public/docs/_examples/architecture/ts/src/app/mini-app.ts new file mode 100644 index 0000000000..b064428be3 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/mini-app.ts @@ -0,0 +1,45 @@ +// #docplaster +// A mini-application +import { Injectable } from '@angular/core'; + +@Injectable() +export class Logger { + log(message: string) { console.log(message); } +} + +// #docregion import-core-component +import { Component } from '@angular/core'; +// #enddocregion import-core-component + +@Component({ + selector: 'my-app', + template: 'Welcome to Angular' +}) +export class AppComponent { + constructor(logger: Logger) { + logger.log('Let the fun begin!'); + } +} + +// #docregion module +import { NgModule } from '@angular/core'; +// #docregion import-browser-module +import { BrowserModule } from '@angular/platform-browser'; +// #enddocregion import-browser-module +@NgModule({ +// #docregion ngmodule-imports + imports: [ BrowserModule ], +// #enddocregion ngmodule-imports + providers: [ Logger ], + declarations: [ AppComponent ], + exports: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +// #docregion export +export class AppModule { } +// #enddocregion export +// #enddocregion module + +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/architecture/ts/src/app/sales-tax.component.ts b/public/docs/_examples/architecture/ts/src/app/sales-tax.component.ts new file mode 100644 index 0000000000..02201afe05 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/sales-tax.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; + +import { SalesTaxService } from './sales-tax.service'; +import { TaxRateService } from './tax-rate.service'; + +@Component({ + selector: 'sales-tax', + template: ` +

    Sales Tax Calculator

    + Amount: + +
    + The sales tax is + {{ getTax(amountBox.value) | currency:'USD':true:'1.2-2' }} +
    + `, + providers: [SalesTaxService, TaxRateService] +}) +export class SalesTaxComponent { + constructor(private salesTaxService: SalesTaxService) { } + + getTax(value: string | number) { + return this.salesTaxService.getVAT(value); + } +} diff --git a/public/docs/_examples/architecture/ts/src/app/sales-tax.service.ts b/public/docs/_examples/architecture/ts/src/app/sales-tax.service.ts new file mode 100644 index 0000000000..d859dc1595 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/sales-tax.service.ts @@ -0,0 +1,14 @@ +import { Injectable } from '@angular/core'; + +import { TaxRateService } from './tax-rate.service'; + +@Injectable() +export class SalesTaxService { + constructor(private rateService: TaxRateService) { } + + getVAT(value: string | number) { + let amount = (typeof value === 'string') ? + parseFloat(value) : value; + return (amount || 0) * this.rateService.getRate('VAT'); + } +} diff --git a/public/docs/_examples/architecture/ts/src/app/tax-rate.service.ts b/public/docs/_examples/architecture/ts/src/app/tax-rate.service.ts new file mode 100644 index 0000000000..fff2f4df8f --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/app/tax-rate.service.ts @@ -0,0 +1,6 @@ +import { Injectable } from '@angular/core'; + +@Injectable() +export class TaxRateService { + getRate(rateName: string) { return 0.10; } // 10% everywhere +} diff --git a/public/docs/_examples/architecture/ts/src/index.html b/public/docs/_examples/architecture/ts/src/index.html new file mode 100644 index 0000000000..9aadf6e109 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/index.html @@ -0,0 +1,26 @@ + + + + Architecture of Angular + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/architecture/ts/src/main.ts b/public/docs/_examples/architecture/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/architecture/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/attribute-directives/dart/lib/app_component.dart b/public/docs/_examples/attribute-directives/dart/lib/app_component.dart deleted file mode 100644 index 29f44ea6e9..0000000000 --- a/public/docs/_examples/attribute-directives/dart/lib/app_component.dart +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'highlight_directive.dart'; - -@Component( - selector: 'my-app', - templateUrl: 'app_component.html', - directives: const [HighlightDirective]) -class AppComponent { - String color; -} diff --git a/public/docs/_examples/attribute-directives/dart/lib/app_component.html b/public/docs/_examples/attribute-directives/dart/lib/app_component.html deleted file mode 100644 index f174bebbbb..0000000000 --- a/public/docs/_examples/attribute-directives/dart/lib/app_component.html +++ /dev/null @@ -1,20 +0,0 @@ - - -

    My First Attribute Directive

    -

    Pick a highlight color

    -
    - Green - Yellow - Cyan -
    - -

    Highlight me!

    - - - - -

    -Highlight me too! -

    - - diff --git a/public/docs/_examples/attribute-directives/dart/lib/app_component_1.html b/public/docs/_examples/attribute-directives/dart/lib/app_component_1.html deleted file mode 100644 index e5ee1c6463..0000000000 --- a/public/docs/_examples/attribute-directives/dart/lib/app_component_1.html +++ /dev/null @@ -1,7 +0,0 @@ - -

    My First Attribute Directive

    -

    Highlight me!

    - - -

    I am green with envy!

    - diff --git a/public/docs/_examples/attribute-directives/dart/lib/highlight_directive.dart b/public/docs/_examples/attribute-directives/dart/lib/highlight_directive.dart deleted file mode 100644 index e6190a443c..0000000000 --- a/public/docs/_examples/attribute-directives/dart/lib/highlight_directive.dart +++ /dev/null @@ -1,43 +0,0 @@ -// #docplaster -// #docregion full -import 'package:angular2/core.dart'; - -@Directive(selector: '[myHighlight]', host: const { - '(mouseenter)': 'onMouseEnter()', - '(mouseleave)': 'onMouseLeave()' -}) -// #docregion class-1 -class HighlightDirective { - String _defaultColor = 'red'; - final dynamic _el; - - HighlightDirective(ElementRef elRef) : _el = elRef.nativeElement; - // #enddocregion class-1 - - // #docregion defaultColor - @Input() set defaultColor(String colorName) { - _defaultColor = (colorName ?? _defaultColor); - } - // #enddocregion defaultColor - // #docregion class-1 - - // #docregion color - @Input('myHighlight') String highlightColor; - // #enddocregion color - - // #docregion mouse-enter - void onMouseEnter() { _highlight(highlightColor ?? _defaultColor); } - // #enddocregion mouse-enter - void onMouseLeave() { _highlight(); } - - void _highlight([String color]) { - if(_el != null) _el.style.backgroundColor = color; - } -} -// #enddocregion class-1 -// #enddocregion full -/* -// #docregion highlight -@Input() String myHighlight; -// #enddocregion highlight -*/ diff --git a/public/docs/_examples/attribute-directives/dart/lib/highlight_directive_1.dart b/public/docs/_examples/attribute-directives/dart/lib/highlight_directive_1.dart deleted file mode 100644 index 2ce0e35919..0000000000 --- a/public/docs/_examples/attribute-directives/dart/lib/highlight_directive_1.dart +++ /dev/null @@ -1,11 +0,0 @@ -// #docregion -library attribute_directives.highlight_directive; - -import 'package:angular2/core.dart'; - -@Directive(selector: '[myHighlight]') -class HighlightDirective { - HighlightDirective(ElementRef element) { - element.nativeElement.style.backgroundColor = 'yellow'; - } -} diff --git a/public/docs/_examples/attribute-directives/dart/lib/highlight_directive_2.dart b/public/docs/_examples/attribute-directives/dart/lib/highlight_directive_2.dart deleted file mode 100644 index 8546f36279..0000000000 --- a/public/docs/_examples/attribute-directives/dart/lib/highlight_directive_2.dart +++ /dev/null @@ -1,28 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -@Directive(selector: '[myHighlight]', - // #docregion host - host: const { - '(mouseenter)': 'onMouseEnter()', - '(mouseleave)': 'onMouseLeave()' - } - // #enddocregion host -) -class HighlightDirective { - // #docregion ctor - final dynamic _el; - - HighlightDirective(ElementRef elRef) : _el = elRef.nativeElement; - // #enddocregion ctor - - // #docregion mouse-methods - void onMouseEnter() { _highlight("yellow"); } - void onMouseLeave() { _highlight(); } - - void _highlight([String color]) { - if (_el != null) _el.style.backgroundColor = color; - } - // #enddocregion mouse-methods -} -// #enddocregion diff --git a/public/docs/_examples/attribute-directives/dart/pubspec.yaml b/public/docs/_examples/attribute-directives/dart/pubspec.yaml deleted file mode 100644 index 0472ac2166..0000000000 --- a/public/docs/_examples/attribute-directives/dart/pubspec.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# #docregion -name: attribute_directives -description: Attribute directives example -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: 'package:angular2/common.dart#CORE_DIRECTIVES' - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/attribute-directives/dart/web/index.html b/public/docs/_examples/attribute-directives/dart/web/index.html deleted file mode 100644 index ad852ad9eb..0000000000 --- a/public/docs/_examples/attribute-directives/dart/web/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Attribute Directives - - - - - - Loading... - - diff --git a/public/docs/_examples/attribute-directives/dart/web/main.dart b/public/docs/_examples/attribute-directives/dart/web/main.dart deleted file mode 100644 index 0703b7ab25..0000000000 --- a/public/docs/_examples/attribute-directives/dart/web/main.dart +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -import 'package:angular2/platform/browser.dart'; - -import 'package:attribute_directives/app_component.dart'; - -main() { - bootstrap(AppComponent); -} diff --git a/public/docs/_examples/attribute-directives/e2e-spec.ts b/public/docs/_examples/attribute-directives/e2e-spec.ts index b15d85220f..79425d7923 100644 --- a/public/docs/_examples/attribute-directives/e2e-spec.ts +++ b/public/docs/_examples/attribute-directives/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Attribute directives', function () { let _title = 'My First Attribute Directive'; @@ -12,7 +15,7 @@ describe('Attribute directives', function () { }); it('should be able to select green highlight', function () { - let highlightedEle = element(by.cssContainingText('p', 'Highlight me')); + let highlightedEle = element(by.cssContainingText('p', 'Highlight me!')); let lightGreen = 'rgba(144, 238, 144, 1)'; expect(highlightedEle.getCssValue('background-color')).not.toEqual(lightGreen); diff --git a/public/docs/_examples/attribute-directives/ts/app/app.component.1.html b/public/docs/_examples/attribute-directives/ts/app/app.component.1.html deleted file mode 100644 index e5ee1c6463..0000000000 --- a/public/docs/_examples/attribute-directives/ts/app/app.component.1.html +++ /dev/null @@ -1,7 +0,0 @@ - -

    My First Attribute Directive

    -

    Highlight me!

    - - -

    I am green with envy!

    - diff --git a/public/docs/_examples/attribute-directives/ts/app/app.component.html b/public/docs/_examples/attribute-directives/ts/app/app.component.html deleted file mode 100644 index e4e445b1a8..0000000000 --- a/public/docs/_examples/attribute-directives/ts/app/app.component.html +++ /dev/null @@ -1,20 +0,0 @@ - - -

    My First Attribute Directive

    -

    Pick a highlight color

    -
    - Green - Yellow - Cyan -
    - -

    Highlight me!

    - - - - -

    - Highlight me too! -

    - - diff --git a/public/docs/_examples/attribute-directives/ts/app/app.component.ts b/public/docs/_examples/attribute-directives/ts/app/app.component.ts deleted file mode 100644 index 15167310c6..0000000000 --- a/public/docs/_examples/attribute-directives/ts/app/app.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { HighlightDirective } from './highlight.directive'; - -@Component({ - selector: 'my-app', - templateUrl: 'app/app.component.html', - directives: [HighlightDirective] -}) - -export class AppComponent { } - -// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.2.ts b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.2.ts deleted file mode 100644 index 8e64391f05..0000000000 --- a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.2.ts +++ /dev/null @@ -1,31 +0,0 @@ -// #docregion -import { Directive, ElementRef, Input } from '@angular/core'; - -@Directive({ - selector: '[myHighlight]', - // #docregion host - host: { - '(mouseenter)': 'onMouseEnter()', - '(mouseleave)': 'onMouseLeave()' - } - // #enddocregion host -}) - -export class HighlightDirective { - - // #docregion ctor - private el:HTMLElement; - constructor(el: ElementRef) { this.el = el.nativeElement; } - // #enddocregion ctor - - // #docregion mouse-methods - onMouseEnter() { this.highlight("yellow"); } - onMouseLeave() { this.highlight(null); } - - private highlight(color: string) { - this.el.style.backgroundColor = color; - } - // #enddocregion mouse-methods - -} -// #enddocregion diff --git a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.ts b/public/docs/_examples/attribute-directives/ts/app/highlight.directive.ts deleted file mode 100644 index 6ec9842602..0000000000 --- a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.ts +++ /dev/null @@ -1,46 +0,0 @@ -// #docplaster -// #docregion full -import { Directive, ElementRef, Input } from '@angular/core'; - -@Directive({ - selector: '[myHighlight]', - host: { - '(mouseenter)': 'onMouseEnter()', - '(mouseleave)': 'onMouseLeave()' - } -}) -// #docregion class-1 -export class HighlightDirective { - private _defaultColor = 'red'; - private el: HTMLElement; - - constructor(el: ElementRef) { this.el = el.nativeElement; } - // #enddocregion class-1 - - // #docregion defaultColor - @Input() set defaultColor(colorName:string){ - this._defaultColor = colorName || this._defaultColor; - } - // #enddocregion defaultColor - // #docregion class-1 - - // #docregion color - @Input('myHighlight') highlightColor: string; - // #enddocregion color - - // #docregion mouse-enter - onMouseEnter() { this.highlight(this.highlightColor || this._defaultColor); } - // #enddocregion mouse-enter - onMouseLeave() { this.highlight(null); } - - private highlight(color:string) { - this.el.style.backgroundColor = color; - } -} -// #enddocregion class-1 -// #enddocregion full -/* -// #docregion highlight -@Input() myHighlight: string; -// #enddocregion highlight -*/ diff --git a/public/docs/_examples/attribute-directives/ts/app/main.ts b/public/docs/_examples/attribute-directives/ts/app/main.ts deleted file mode 100644 index 4fc79adda1..0000000000 --- a/public/docs/_examples/attribute-directives/ts/app/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); - diff --git a/public/docs/_examples/attribute-directives/ts/index.html b/public/docs/_examples/attribute-directives/ts/index.html deleted file mode 100644 index 197f1a8280..0000000000 --- a/public/docs/_examples/attribute-directives/ts/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - Attribute Directives - - - - - - - - - - - - - - - loading... - - diff --git a/public/docs/_examples/attribute-directives/ts/plnkr.json b/public/docs/_examples/attribute-directives/ts/plnkr.json index 7124dcb6a7..112e1de6f4 100644 --- a/public/docs/_examples/attribute-directives/ts/plnkr.json +++ b/public/docs/_examples/attribute-directives/ts/plnkr.json @@ -1,9 +1,10 @@ { "description": "Attribute Directive", + "basePath": "src/", "files":[ "!**/*.d.ts", "!**/*.js", - "!app/*.[1,2].*" + "!app/*.[1,2,3].*" ], "tags": ["attribute", "directive"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/attribute-directives/ts/src/app/app.component.1.html b/public/docs/_examples/attribute-directives/ts/src/app/app.component.1.html new file mode 100644 index 0000000000..9505bc9dff --- /dev/null +++ b/public/docs/_examples/attribute-directives/ts/src/app/app.component.1.html @@ -0,0 +1,14 @@ + +

    My First Attribute Directive

    + +

    Highlight me!

    + + + +

    Highlighted in yellow

    +

    Highlighted in orange

    + + + +

    Highlighted with parent component's color

    + diff --git a/public/docs/_examples/attribute-directives/ts/src/app/app.component.1.ts b/public/docs/_examples/attribute-directives/ts/src/app/app.component.1.ts new file mode 100644 index 0000000000..d9b98ef3fd --- /dev/null +++ b/public/docs/_examples/attribute-directives/ts/src/app/app.component.1.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.1.html' +}) +// #docregion class +export class AppComponent { + color = 'yellow'; +} diff --git a/public/docs/_examples/attribute-directives/ts/src/app/app.component.html b/public/docs/_examples/attribute-directives/ts/src/app/app.component.html new file mode 100644 index 0000000000..3adb52bc1e --- /dev/null +++ b/public/docs/_examples/attribute-directives/ts/src/app/app.component.html @@ -0,0 +1,24 @@ + +

    My First Attribute Directive

    + +

    Pick a highlight color

    +
    + Green + Yellow + Cyan +
    + +

    Highlight me!

    + + + +

    + Highlight me too! +

    + + +
    +

    Mouse over the following lines to see fixed highlights

    + +

    Highlighted in yellow

    +

    Highlighted in orange

    diff --git a/public/docs/_examples/attribute-directives/ts/src/app/app.component.ts b/public/docs/_examples/attribute-directives/ts/src/app/app.component.ts new file mode 100644 index 0000000000..693918d8d6 --- /dev/null +++ b/public/docs/_examples/attribute-directives/ts/src/app/app.component.ts @@ -0,0 +1,11 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html' +}) +// #docregion class +export class AppComponent { + color: string; +} diff --git a/public/docs/_examples/attribute-directives/ts/src/app/app.module.ts b/public/docs/_examples/attribute-directives/ts/src/app/app.module.ts new file mode 100644 index 0000000000..ca35d560fb --- /dev/null +++ b/public/docs/_examples/attribute-directives/ts/src/app/app.module.ts @@ -0,0 +1,16 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { HighlightDirective } from './highlight.directive'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ + AppComponent, + HighlightDirective + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/attribute-directives/ts/src/app/dummy.module.1.ts b/public/docs/_examples/attribute-directives/ts/src/app/dummy.module.1.ts new file mode 100644 index 0000000000..7ba41d53bb --- /dev/null +++ b/public/docs/_examples/attribute-directives/ts/src/app/dummy.module.1.ts @@ -0,0 +1,17 @@ +// Not used. Keep away from plunker +// Keeps ATLS from complaining about undeclared directives. +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component.1'; +import { HighlightDirective as HLD1 } from './highlight.directive.1'; +import { HighlightDirective as HLD2 } from './highlight.directive.2'; +import { HighlightDirective as HLD3 } from './highlight.directive.3'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ + AppComponent, HLD1, HLD2, HLD3 + ] +}) +export class DummyModule { } diff --git a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.1.ts b/public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.1.ts similarity index 86% rename from public/docs/_examples/attribute-directives/ts/app/highlight.directive.1.ts rename to public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.1.ts index f8c1a95ea1..4cacc0d22e 100644 --- a/public/docs/_examples/attribute-directives/ts/app/highlight.directive.1.ts +++ b/public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.1.ts @@ -1,3 +1,4 @@ +/* tslint:disable:no-unused-variable */ // #docregion import { Directive, ElementRef, Input } from '@angular/core'; diff --git a/public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.2.ts b/public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.2.ts new file mode 100644 index 0000000000..4696132f64 --- /dev/null +++ b/public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.2.ts @@ -0,0 +1,41 @@ +/* tslint:disable:no-unused-variable member-ordering */ +// #docplaster +// #docregion +import { Directive, ElementRef, HostListener, Input } from '@angular/core'; + +@Directive({ + selector: '[myHighlight]' +}) +export class HighlightDirective { + // #docregion ctor + constructor(private el: ElementRef) { } + // #enddocregion ctor + + // #docregion mouse-methods, host + @HostListener('mouseenter') onMouseEnter() { + // #enddocregion host + this.highlight('yellow'); + // #docregion host + } + + @HostListener('mouseleave') onMouseLeave() { + // #enddocregion host + this.highlight(null); + // #docregion host + } + // #enddocregion host + + private highlight(color: string) { + this.el.nativeElement.style.backgroundColor = color; + } + // #enddocregion mouse-methods, + + // #docregion color + @Input() highlightColor: string; + // #enddocregion color + + // #docregion color-2 + @Input() myHighlight: string; + // #enddocregion color-2 +} + diff --git a/public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.3.ts b/public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.3.ts new file mode 100644 index 0000000000..bf76769c93 --- /dev/null +++ b/public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.3.ts @@ -0,0 +1,27 @@ +/* tslint:disable:member-ordering */ +// #docregion +import { Directive, ElementRef, HostListener, Input } from '@angular/core'; + +@Directive({ + selector: '[myHighlight]' +}) +export class HighlightDirective { + + constructor(private el: ElementRef) { } + + @Input('myHighlight') highlightColor: string; + + // #docregion mouse-enter + @HostListener('mouseenter') onMouseEnter() { + this.highlight(this.highlightColor || 'red'); + } + // #enddocregion mouse-enter + + @HostListener('mouseleave') onMouseLeave() { + this.highlight(null); + } + + private highlight(color: string) { + this.el.nativeElement.style.backgroundColor = color; + } +} diff --git a/public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.ts b/public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.ts new file mode 100644 index 0000000000..97b1497013 --- /dev/null +++ b/public/docs/_examples/attribute-directives/ts/src/app/highlight.directive.ts @@ -0,0 +1,34 @@ +/* tslint:disable:member-ordering */ +// #docregion imports, +import { Directive, ElementRef, HostListener, Input } from '@angular/core'; +// #enddocregion imports + +@Directive({ + selector: '[myHighlight]' +}) +export class HighlightDirective { + + constructor(private el: ElementRef) { } + + // #docregion defaultColor + @Input() defaultColor: string; + // #enddocregion defaultColor + + // #docregion color + @Input('myHighlight') highlightColor: string; + // #enddocregion color + + // #docregion mouse-enter + @HostListener('mouseenter') onMouseEnter() { + this.highlight(this.highlightColor || this.defaultColor || 'red'); + } + // #enddocregion mouse-enter + + @HostListener('mouseleave') onMouseLeave() { + this.highlight(null); + } + + private highlight(color: string) { + this.el.nativeElement.style.backgroundColor = color; + } +} diff --git a/public/docs/_examples/attribute-directives/ts/src/index.html b/public/docs/_examples/attribute-directives/ts/src/index.html new file mode 100644 index 0000000000..97662437f0 --- /dev/null +++ b/public/docs/_examples/attribute-directives/ts/src/index.html @@ -0,0 +1,25 @@ + + + + + + Attribute Directives + + + + + + + + + + + + + + + loading... + + diff --git a/public/docs/_examples/attribute-directives/ts/src/main.ts b/public/docs/_examples/attribute-directives/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/attribute-directives/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/e2e-spec.ts b/public/docs/_examples/cb-a1-a2-quick-reference/e2e-spec.ts deleted file mode 100644 index f75a17ee6e..0000000000 --- a/public/docs/_examples/cb-a1-a2-quick-reference/e2e-spec.ts +++ /dev/null @@ -1,113 +0,0 @@ -/// -describe('Angular 1 to 2 Quick Reference Tests', function () { - - beforeAll(function () { - browser.get(''); - }); - - it('should display no poster images after bootstrap', function () { - testImagesAreDisplayed(false); - }); - - it('should display proper movie data', function () { - // We check only a few samples - let expectedSamples: any[] = [ - {row: 0, column: 0, element: 'img', attr: 'src', value: 'images/hero.png', contains: true}, - {row: 0, column: 2, value: 'Celeritas'}, - {row: 1, column: 3, matches: /Dec 1[678], 2015/}, // absorb timezone dif; we care about date format - {row: 1, column: 5, value: '$14.95'}, - {row: 2, column: 4, value: 'PG-13'}, - {row: 2, column: 7, value: '100%'}, - {row: 2, column: 0, element: 'img', attr: 'src', value: 'images/ng-logo.png', contains: true}, - ]; - - // Go through the samples - let movieRows = getMovieRows(); - for (let i = 0; i < expectedSamples.length; i++) { - let sample = expectedSamples[i]; - let tableCell = movieRows.get(sample.row) - .all(by.tagName('td')).get(sample.column); - // Check the cell or its nested element - let elementToCheck = sample.element - ? tableCell.element(by.tagName(sample.element)) - : tableCell; - - // Check element attribute or text - let valueToCheck = sample.attr - ? elementToCheck.getAttribute(sample.attr) - : elementToCheck.getText(); - - // Test for equals/contains/match - if (sample.contains) { - expect(valueToCheck).toContain(sample.value); - } else if (sample.matches) { - expect(valueToCheck).toMatch(sample.matches); - } else { - expect(valueToCheck).toEqual(sample.value); - } - } - }); - - it('should display images after Show Poster', function () { - testPosterButtonClick('Show Poster', true); - }); - - it('should hide images after Hide Poster', function () { - testPosterButtonClick('Hide Poster', false); - }); - - it('should display no movie when no favorite hero is specified', function () { - testFavoriteHero(null, 'Please enter your favorite hero.'); - }); - - it('should display no movie for Magneta', function () { - testFavoriteHero('Magneta', 'No movie, sorry!'); - }); - - it('should display a movie for Mr. Nice', function () { - testFavoriteHero('Mr. Nice', 'Excellent choice!'); - }); - - function testImagesAreDisplayed(isDisplayed: boolean) { - let expectedMovieCount = 3; - - let movieRows = getMovieRows(); - expect(movieRows.count()).toBe(expectedMovieCount); - for (let i = 0; i < expectedMovieCount; i++) { - let movieImage = movieRows.get(i).element(by.css('td > img')); - expect(movieImage.isDisplayed()).toBe(isDisplayed); - } - } - - function testPosterButtonClick(expectedButtonText: string, isDisplayed: boolean) { - let posterButton = element(by.css('movie-list tr > th > button')); - expect(posterButton.getText()).toBe(expectedButtonText); - - posterButton.click().then(function () { - testImagesAreDisplayed(isDisplayed); - }) - } - - function getMovieRows() { - return element.all(by.css('movie-list tbody > tr')); - } - - function testFavoriteHero(heroName: string, expectedLabel: string) { - let movieListComp = element(by.tagName('movie-list')); - let heroInput = movieListComp.element(by.tagName('input')); - let favoriteHeroLabel = movieListComp.element(by.tagName('h3')); - let resultLabel = movieListComp.element(by.css('span > p')); - - heroInput.clear().then(function () { - sendKeys(heroInput, heroName || '').then(function () { - expect(resultLabel.getText()).toBe(expectedLabel); - if (heroName) { - expect(favoriteHeroLabel.isDisplayed()).toBe(true); - expect(favoriteHeroLabel.getText()).toContain(heroName); - } else { - expect(favoriteHeroLabel.isDisplayed()).toBe(false); - } - }) - }) - } -}); diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.component.html b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.component.html deleted file mode 100644 index 9626afd5cb..0000000000 --- a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.component.html +++ /dev/null @@ -1,112 +0,0 @@ - -

    {{title}}

    - -

    Routed Movies

    - - - -
    - -

    Example Snippets

    - - -
    - - [ngClass] active -
    - -
    - - [ngClass] active and boldly important -
    - -
    - - [class.active] -
    - -

    - -Angular Docs - - -

    -
    - - - - -

    Image toggle event type was {{eventType}}

    -
    - -

    -
    - - - -
    - -

    - -
    - - color preference #1 -
    - -
    - - color preference #2 -
    - -

    Movie as JSON

    - -
    {{movie | json}}
    - - -

    Movie Titles via local variable

    - - - - - - -
    {{movie.title}}
    - -

    Sliced Movies with pipes

    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{movie.title | uppercase}}{{movie.title | lowercase}}{{movie.releaseDate | date}}{{movie.price | currency:'USD':true}}{{movie.starRating | number}}{{movie.starRating | number:'1.1-2'}}{{movie.approvalRating | percent: '1.0-2'}}
    diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.component.ts b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.component.ts deleted file mode 100644 index f2ca099297..0000000000 --- a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Component } from '@angular/core'; -import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated'; - -import { MovieListComponent } from './movie-list.component'; -import { MovieService } from './movie.service'; -import { IMovie } from './movie'; -import { StringSafeDatePipe } from './date.pipe'; - -@Component({ - selector: 'my-app', - templateUrl: 'app/app.component.html', - styleUrls: ['app/app.component.css'], - directives: [MovieListComponent, ROUTER_DIRECTIVES], - pipes: [StringSafeDatePipe], - providers: [MovieService, ROUTER_PROVIDERS] -}) -@RouteConfig([ - {path: '/movies', name: 'Movies', component: MovieListComponent, useAsDefault: true} -]) -export class AppComponent { - - angularDocsUrl = 'https://angular.io/'; - colorPreference = 'red'; - eventType = ''; - isActive = true; - isImportant = true; - movie: IMovie = null; - movies: IMovie[] = []; - showImage = true; - title: string = 'A1-A2 Quick Ref Cookbook'; - toggleImage(event: UIEvent) { - this.showImage = !this.showImage; - this.eventType = (event && event.type) || 'not provided'; - } - - constructor(movieService: MovieService) { - this.movies = movieService.getMovies(); - this.movie = this.movies[0]; - } -} diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/date.pipe.ts b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/date.pipe.ts deleted file mode 100644 index c04e64247d..0000000000 --- a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/date.pipe.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Injectable, Pipe } from '@angular/core'; -import { DatePipe } from '@angular/common'; - -@Injectable() -// #docregion date-pipe -@Pipe({name: 'date', pure: true}) -export class StringSafeDatePipe extends DatePipe { - transform(value: any, format: string): string { - value = typeof value === 'string' ? - Date.parse(value) : value; - return super.transform(value, format); - } -} -// #enddocregion date-pipe diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/main.ts b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/main.ts deleted file mode 100644 index 52b47899ef..0000000000 --- a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.ts b/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.ts deleted file mode 100644 index 99f0699410..0000000000 --- a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.ts +++ /dev/null @@ -1,48 +0,0 @@ -// #docplaster -// #docregion import -import { Component } from '@angular/core'; -import { ROUTER_DIRECTIVES } from '@angular/router-deprecated'; -// #enddocregion import -import { MovieService } from './movie.service'; -import { IMovie } from './movie'; -import { StringSafeDatePipe } from './date.pipe'; - - -// #docregion component -@Component({ - selector: 'movie-list', - templateUrl:'app/movie-list.component.html', -// #enddocregion component -// #docregion style-url - styleUrls: ['app/movie-list.component.css'], -// #enddocregion style-url -// #docregion date-pipe - pipes: [StringSafeDatePipe] -// #enddocregion date-pipe -}) -// #enddocregion component -// #docregion class -export class MovieListComponent { -// #enddocregion class - favoriteHero: string; - showImage: boolean = false; - movies: IMovie[]; - -// #docregion di - constructor(movieService: MovieService) { -// #enddocregion di - this.movies = movieService.getMovies(); -// #docregion di - } -// #enddocregion di - - toggleImage(): void { - this.showImage = !this.showImage; - } - - checkMovieHero(value: string): boolean { - return this.movies.filter(movie => movie.hero === value).length > 0 ; - } -// #docregion class -} -// #enddocregion class diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/hero.png b/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/hero.png deleted file mode 100644 index b60c3ecc30..0000000000 Binary files a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/hero.png and /dev/null differ diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/ng-logo.png b/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/ng-logo.png deleted file mode 100644 index 7929242740..0000000000 Binary files a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/ng-logo.png and /dev/null differ diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/villain.png b/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/villain.png deleted file mode 100644 index d1e71cf00b..0000000000 Binary files a/public/docs/_examples/cb-a1-a2-quick-reference/ts/images/villain.png and /dev/null differ diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/index.html b/public/docs/_examples/cb-a1-a2-quick-reference/ts/index.html deleted file mode 100644 index ee2eb6fdec..0000000000 --- a/public/docs/_examples/cb-a1-a2-quick-reference/ts/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - Angular 1 to Angular 2 Quick Reference - - - - - - - - - - - - - - - - - - Loading app... - - - diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/plnkr.json b/public/docs/_examples/cb-a1-a2-quick-reference/ts/plnkr.json deleted file mode 100644 index 4f3ebce61d..0000000000 --- a/public/docs/_examples/cb-a1-a2-quick-reference/ts/plnkr.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "description": "Angular 1 to Angular 2 Quick Reference", - "files":[ - "!**/*.d.ts", - "!**/*.js", - "!**/*.[1].*" - ], - "tags":["cookbook"] -} diff --git a/public/docs/_examples/cb-ajs-quick-reference/e2e-spec.ts b/public/docs/_examples/cb-ajs-quick-reference/e2e-spec.ts new file mode 100644 index 0000000000..81a5faa5e7 --- /dev/null +++ b/public/docs/_examples/cb-ajs-quick-reference/e2e-spec.ts @@ -0,0 +1,115 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + +describe('AngularJS to Angular Quick Reference Tests', function () { + + beforeAll(function () { + browser.get(''); + }); + + it('should display no poster images after bootstrap', function () { + testImagesAreDisplayed(false); + }); + + it('should display proper movie data', function () { + // We check only a few samples + let expectedSamples: any[] = [ + {row: 0, column: 0, element: 'img', attr: 'src', value: 'images/hero.png', contains: true}, + {row: 0, column: 2, value: 'Celeritas'}, + {row: 1, column: 3, matches: /Dec 1[678], 2015/}, // absorb timezone dif; we care about date format + {row: 1, column: 5, value: '$14.95'}, + {row: 2, column: 4, value: 'PG-13'}, + {row: 2, column: 7, value: '100%'}, + {row: 2, column: 0, element: 'img', attr: 'src', value: 'images/ng-logo.png', contains: true}, + ]; + + // Go through the samples + let movieRows = getMovieRows(); + for (let i = 0; i < expectedSamples.length; i++) { + let sample = expectedSamples[i]; + let tableCell = movieRows.get(sample.row) + .all(by.tagName('td')).get(sample.column); + // Check the cell or its nested element + let elementToCheck = sample.element + ? tableCell.element(by.tagName(sample.element)) + : tableCell; + + // Check element attribute or text + let valueToCheck = sample.attr + ? elementToCheck.getAttribute(sample.attr) + : elementToCheck.getText(); + + // Test for equals/contains/match + if (sample.contains) { + expect(valueToCheck).toContain(sample.value); + } else if (sample.matches) { + expect(valueToCheck).toMatch(sample.matches); + } else { + expect(valueToCheck).toEqual(sample.value); + } + } + }); + + it('should display images after Show Poster', function () { + testPosterButtonClick('Show Poster', true); + }); + + it('should hide images after Hide Poster', function () { + testPosterButtonClick('Hide Poster', false); + }); + + it('should display no movie when no favorite hero is specified', function () { + testFavoriteHero(null, 'Please enter your favorite hero.'); + }); + + it('should display no movie for Magneta', function () { + testFavoriteHero('Magneta', 'No movie, sorry!'); + }); + + it('should display a movie for Mr. Nice', function () { + testFavoriteHero('Mr. Nice', 'Excellent choice!'); + }); + + function testImagesAreDisplayed(isDisplayed: boolean) { + let expectedMovieCount = 3; + + let movieRows = getMovieRows(); + expect(movieRows.count()).toBe(expectedMovieCount); + for (let i = 0; i < expectedMovieCount; i++) { + let movieImage = movieRows.get(i).element(by.css('td > img')); + expect(movieImage.isDisplayed()).toBe(isDisplayed); + } + } + + function testPosterButtonClick(expectedButtonText: string, isDisplayed: boolean) { + let posterButton = element(by.css('movie-list tr > th > button')); + expect(posterButton.getText()).toBe(expectedButtonText); + + posterButton.click().then(function () { + testImagesAreDisplayed(isDisplayed); + }); + } + + function getMovieRows() { + return element.all(by.css('movie-list tbody > tr')); + } + + function testFavoriteHero(heroName: string, expectedLabel: string) { + let movieListComp = element(by.tagName('movie-list')); + let heroInput = movieListComp.element(by.tagName('input')); + let favoriteHeroLabel = movieListComp.element(by.tagName('h3')); + let resultLabel = movieListComp.element(by.css('span > p')); + + heroInput.clear().then(function () { + heroInput.sendKeys(heroName || ''); + expect(resultLabel.getText()).toBe(expectedLabel); + if (heroName) { + expect(favoriteHeroLabel.isDisplayed()).toBe(true); + expect(favoriteHeroLabel.getText()).toContain(heroName); + } else { + expect(favoriteHeroLabel.isDisplayed()).toBe(false); + } + }); + } +}); diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/example-config.json b/public/docs/_examples/cb-ajs-quick-reference/ts/example-config.json similarity index 100% rename from public/docs/_examples/cb-a1-a2-quick-reference/ts/example-config.json rename to public/docs/_examples/cb-ajs-quick-reference/ts/example-config.json diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/plnkr.json b/public/docs/_examples/cb-ajs-quick-reference/ts/plnkr.json new file mode 100644 index 0000000000..1ff34275f7 --- /dev/null +++ b/public/docs/_examples/cb-ajs-quick-reference/ts/plnkr.json @@ -0,0 +1,10 @@ +{ + "description": "AngularJS to Angular Quick Reference", + "basePath": "src/", + "files":[ + "!**/*.d.ts", + "!**/*.js", + "!**/*.[1].*" + ], + "tags":["cookbook", "angularjs"] +} diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app-routing.module.ts b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app-routing.module.ts new file mode 100644 index 0000000000..a7cbe8a74d --- /dev/null +++ b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app-routing.module.ts @@ -0,0 +1,16 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { MovieListComponent } from './movie-list.component'; + +const routes: Routes = [ + { path: '', redirectTo: '/movies', pathMatch: 'full' }, + { path: 'movies', component: MovieListComponent } +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.component.css b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.component.css similarity index 100% rename from public/docs/_examples/cb-a1-a2-quick-reference/ts/app/app.component.css rename to public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.component.css diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.component.html b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.component.html new file mode 100644 index 0000000000..72fd3de86f --- /dev/null +++ b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.component.html @@ -0,0 +1,112 @@ + +

    {{title}}

    + +

    Routed Movies

    + + + +
    + +

    Example Snippets

    + + +
    + + [ngClass] active +
    + +
    + + [ngClass] active and boldly important +
    + +
    + + [class.active] +
    + +

    + +Angular Docs + + +

    +
    + + + + +

    Image toggle event type was {{eventType}}

    +
    + +

    +
    + + + +
    + +

    + +
    + + color preference #1 +
    + +
    + + color preference #2 +
    + +

    Movie as JSON

    + +
    {{movie | json}}
    + + +

    Movie Titles via local variable

    + + + + + + +
    {{movie.title}}
    + +

    Sliced Movies with pipes

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {{movie.title | uppercase}}{{movie.title | lowercase}}{{movie.releaseDate | date}}{{movie.price | currency:'USD':true}}{{movie.starRating | number}}{{movie.starRating | number:'1.1-2'}}{{movie.approvalRating | percent: '1.0-2'}}
    diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.component.ts b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.component.ts new file mode 100644 index 0000000000..e1b71e37dc --- /dev/null +++ b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.component.ts @@ -0,0 +1,32 @@ +import { Component } from '@angular/core'; + +import { MovieService } from './movie.service'; +import { IMovie } from './movie'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html', + styleUrls: [ './app.component.css' ], + providers: [ MovieService ] +}) +export class AppComponent { + + angularDocsUrl = 'https://angular.io/'; + colorPreference = 'red'; + eventType = ''; + isActive = true; + isImportant = true; + movie: IMovie = null; + movies: IMovie[] = []; + showImage = true; + title: string = 'AngularJS to Angular Quick Ref Cookbook'; + toggleImage(event: UIEvent) { + this.showImage = !this.showImage; + this.eventType = (event && event.type) || 'not provided'; + } + + constructor(movieService: MovieService) { + this.movies = movieService.getMovies(); + this.movie = this.movies[0]; + } +} diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.module.1.ts b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.module.1.ts new file mode 100644 index 0000000000..5b24020186 --- /dev/null +++ b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.module.1.ts @@ -0,0 +1,12 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.module.ts b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.module.ts new file mode 100644 index 0000000000..1dc46ad17c --- /dev/null +++ b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/app.module.ts @@ -0,0 +1,22 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { MovieListComponent } from './movie-list.component'; +import { AppRoutingModule } from './app-routing.module'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + AppRoutingModule + ], + declarations: [ + AppComponent, + MovieListComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/date.pipe.ts b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/date.pipe.ts new file mode 100644 index 0000000000..e1421fa530 --- /dev/null +++ b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/date.pipe.ts @@ -0,0 +1,14 @@ +import { Injectable, Pipe, PipeTransform } from '@angular/core'; +import { DatePipe } from '@angular/common'; + +@Injectable() +// #docregion date-pipe +@Pipe({name: 'date', pure: true}) +export class StringSafeDatePipe extends DatePipe implements PipeTransform { + transform(value: any, format: string): string { + value = typeof value === 'string' ? + Date.parse(value) : value; + return super.transform(value, format); + } +} +// #enddocregion date-pipe diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.css b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie-list.component.css similarity index 100% rename from public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.css rename to public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie-list.component.css diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.html b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie-list.component.html similarity index 96% rename from public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.html rename to public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie-list.component.html index 91f7f416cd..9de98806d7 100644 --- a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie-list.component.html +++ b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie-list.component.html @@ -10,10 +10,10 @@

    Movie List

    -

    +

    Excellent choice!

    -

    +

    No movie, sorry!

    diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie-list.component.ts b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie-list.component.ts new file mode 100644 index 0000000000..b0b57f018c --- /dev/null +++ b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie-list.component.ts @@ -0,0 +1,42 @@ +/* tslint:disable:no-unused-variable */ +// #docplaster +// #docregion import +import { Component } from '@angular/core'; +// #enddocregion import +import { IMovie } from './movie'; +import { MovieService } from './movie.service'; + +// #docregion component +@Component({ + selector: 'movie-list', + templateUrl: './movie-list.component.html', +// #docregion style-url + styleUrls: [ './movie-list.component.css' ], +// #enddocregion style-url +}) +// #enddocregion component +// #docregion class +export class MovieListComponent { +// #enddocregion class + favoriteHero: string; + showImage: boolean = false; + movies: IMovie[]; + +// #docregion di + constructor(movieService: MovieService) { +// #enddocregion di + this.movies = movieService.getMovies(); +// #docregion di + } +// #enddocregion di + + toggleImage(): void { + this.showImage = !this.showImage; + } + + checkMovieHero(value: string): boolean { + return this.movies.filter(movie => movie.hero === value).length > 0 ; + } +// #docregion class +} +// #enddocregion class diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie.service.ts b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie.service.ts similarity index 100% rename from public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie.service.ts rename to public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie.service.ts diff --git a/public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie.ts b/public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie.ts similarity index 100% rename from public/docs/_examples/cb-a1-a2-quick-reference/ts/app/movie.ts rename to public/docs/_examples/cb-ajs-quick-reference/ts/src/app/movie.ts diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/images/hero.png b/public/docs/_examples/cb-ajs-quick-reference/ts/src/images/hero.png new file mode 100644 index 0000000000..2a128ac367 Binary files /dev/null and b/public/docs/_examples/cb-ajs-quick-reference/ts/src/images/hero.png differ diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/images/ng-logo.png b/public/docs/_examples/cb-ajs-quick-reference/ts/src/images/ng-logo.png new file mode 100644 index 0000000000..1e488b1a49 Binary files /dev/null and b/public/docs/_examples/cb-ajs-quick-reference/ts/src/images/ng-logo.png differ diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/images/villain.png b/public/docs/_examples/cb-ajs-quick-reference/ts/src/images/villain.png new file mode 100644 index 0000000000..26697d1a42 Binary files /dev/null and b/public/docs/_examples/cb-ajs-quick-reference/ts/src/images/villain.png differ diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/index.html b/public/docs/_examples/cb-ajs-quick-reference/ts/src/index.html new file mode 100644 index 0000000000..829f080ae3 --- /dev/null +++ b/public/docs/_examples/cb-ajs-quick-reference/ts/src/index.html @@ -0,0 +1,28 @@ + + + + + + AngularJS to Angular Quick Reference + + + + + + + + + + + + + + + + + Loading app... + + + diff --git a/public/docs/_examples/cb-ajs-quick-reference/ts/src/main.ts b/public/docs/_examples/cb-ajs-quick-reference/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/cb-ajs-quick-reference/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-aot-compiler/e2e-spec.ts b/public/docs/_examples/cb-aot-compiler/e2e-spec.ts new file mode 100644 index 0000000000..4744f06e50 --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/e2e-spec.ts @@ -0,0 +1,27 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + +/* tslint:disable:quotemark */ +describe('AOT Compilation', function () { + + beforeAll(function () { + browser.get(''); + }); + + it('should load page and click button', function (done: any) { + let headingSelector = element.all(by.css('h1')).get(0); + expect(headingSelector.getText()).toEqual('Hello Angular'); + + expect(element.all(by.xpath('//div[text()="Magneta"]')).get(0).isPresent()).toBe(true); + expect(element.all(by.xpath('//div[text()="Bombasto"]')).get(0).isPresent()).toBe(true); + expect(element.all(by.xpath('//div[text()="Magma"]')).get(0).isPresent()).toBe(true); + expect(element.all(by.xpath('//div[text()="Tornado"]')).get(0).isPresent()).toBe(true); + + let toggleButton = element.all(by.css('button')).get(0); + toggleButton.click().then(function() { + expect(headingSelector.isPresent()).toBe(false); + done(); + }); + }); +}); diff --git a/public/docs/_examples/cb-aot-compiler/ts/.gitignore b/public/docs/_examples/cb-aot-compiler/ts/.gitignore new file mode 100644 index 0000000000..91da4c79a2 --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/ts/.gitignore @@ -0,0 +1,7 @@ +**/*.ngfactory.ts +**/*.ngsummary.json +**/*.shim.ngstyle.ts +**/*.metadata.json +dist +!app/tsconfig.json +!rollup-config.js diff --git a/public/docs/_examples/cb-aot-compiler/ts/example-config.json b/public/docs/_examples/cb-aot-compiler/ts/example-config.json new file mode 100644 index 0000000000..473b80a572 --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/ts/example-config.json @@ -0,0 +1,3 @@ +{ + "build": "build:aot" +} diff --git a/public/docs/_examples/cb-aot-compiler/ts/rollup-config.js b/public/docs/_examples/cb-aot-compiler/ts/rollup-config.js new file mode 100644 index 0000000000..1cd25515ba --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/ts/rollup-config.js @@ -0,0 +1,34 @@ +// #docregion +import rollup from 'rollup' +import nodeResolve from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs'; +import uglify from 'rollup-plugin-uglify' + +// #docregion config +export default { + entry: 'src/main.js', + dest: 'src/build.js', // output a single application bundle + sourceMap: false, + format: 'iife', + onwarn: function(warning) { + // Skip certain warnings + + // should intercept ... but doesn't in some rollup versions + if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; } + + // console.warn everything else + console.warn( warning.message ); + }, + plugins: [ + nodeResolve({jsnext: true, module: true}), + // #docregion commonjs + commonjs({ + include: 'node_modules/rxjs/**', + }), + // #enddocregion commonjs + // #docregion uglify + uglify() + // #enddocregion uglify + ] +} +// #enddocregion config diff --git a/public/docs/_examples/cb-aot-compiler/ts/src/app/app.component.html b/public/docs/_examples/cb-aot-compiler/ts/src/app/app.component.html new file mode 100644 index 0000000000..1d3a8de932 --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/ts/src/app/app.component.html @@ -0,0 +1,7 @@ + + +

    Hello Angular

    + +

    List of Heroes

    +
    {{hero}}
    + diff --git a/public/docs/_examples/cb-aot-compiler/ts/src/app/app.component.ts b/public/docs/_examples/cb-aot-compiler/ts/src/app/app.component.ts new file mode 100644 index 0000000000..879f7f663c --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/ts/src/app/app.component.ts @@ -0,0 +1,15 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html' +}) +export class AppComponent { + showHeading = true; + heroes = ['Magneta', 'Bombasto', 'Magma', 'Tornado']; + + toggleHeading() { + this.showHeading = !this.showHeading; + } +} diff --git a/public/docs/_examples/cb-aot-compiler/ts/src/app/app.module.ts b/public/docs/_examples/cb-aot-compiler/ts/src/app/app.module.ts new file mode 100644 index 0000000000..b4fc185c24 --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/ts/src/app/app.module.ts @@ -0,0 +1,12 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/cb-aot-compiler/ts/src/index-jit.html b/public/docs/_examples/cb-aot-compiler/ts/src/index-jit.html new file mode 100644 index 0000000000..713a04970e --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/ts/src/index-jit.html @@ -0,0 +1,24 @@ + + + + + Ahead of time compilation (JIT) + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/cb-aot-compiler/ts/src/index.html b/public/docs/_examples/cb-aot-compiler/ts/src/index.html new file mode 100644 index 0000000000..09e5f0de0e --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/ts/src/index.html @@ -0,0 +1,20 @@ + + + + + Ahead of time compilation + + + + + + + + + + Loading... + + + + + diff --git a/public/docs/_examples/cb-aot-compiler/ts/src/main-jit.ts b/public/docs/_examples/cb-aot-compiler/ts/src/main-jit.ts new file mode 100644 index 0000000000..88e2c16ed5 --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/ts/src/main-jit.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +console.log('Running JIT compiled'); +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-aot-compiler/ts/src/main.ts b/public/docs/_examples/cb-aot-compiler/ts/src/main.ts new file mode 100644 index 0000000000..4446bc07d1 --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowser } from '@angular/platform-browser'; +import { AppModuleNgFactory } from '../aot/src/app/app.module.ngfactory'; + +console.log('Running AOT compiled'); +platformBrowser().bootstrapModuleFactory(AppModuleNgFactory); diff --git a/public/docs/_examples/cb-aot-compiler/ts/tsconfig-aot.json b/public/docs/_examples/cb-aot-compiler/ts/tsconfig-aot.json new file mode 100644 index 0000000000..d0a3d00ad4 --- /dev/null +++ b/public/docs/_examples/cb-aot-compiler/ts/tsconfig-aot.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "es2015", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es2015", "dom"], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true + }, + + "files": [ + "src/app/app.module.ts", + "src/main.ts" + ], + + "angularCompilerOptions": { + "genDir": "aot", + "skipMetadataEmit" : true + } +} diff --git a/public/docs/_examples/cb-component-communication/e2e-spec.ts b/public/docs/_examples/cb-component-communication/e2e-spec.ts index fc2566662d..d78e0784d9 100644 --- a/public/docs/_examples/cb-component-communication/e2e-spec.ts +++ b/public/docs/_examples/cb-component-communication/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Component Communication Cookbook Tests', function () { // Note: '?e2e' which app can read to know it is running in protractor @@ -20,8 +23,8 @@ describe('Component Communication Cookbook Tests', function () { for (let i = 0; i < _heroNames.length; i++) { let childTitle = heroes.get(i).element(by.tagName('h3')).getText(); let childDetail = heroes.get(i).element(by.tagName('p')).getText(); - expect(childTitle).toEqual(_heroNames[i] + ' says:') - expect(childDetail).toContain(_masterName) + expect(childTitle).toEqual(_heroNames[i] + ' says:'); + expect(childDetail).toContain(_masterName); } }); // ... @@ -38,7 +41,7 @@ describe('Component Communication Cookbook Tests', function () { let hero = parent.all(by.tagName('name-child')).get(_nonEmptyNameIndex); let displayName = hero.element(by.tagName('h3')).getText(); - expect(displayName).toEqual(_nonEmptyName) + expect(displayName).toEqual(_nonEmptyName); }); it('should replace empty name with default name', function () { @@ -48,7 +51,7 @@ describe('Component Communication Cookbook Tests', function () { let hero = parent.all(by.tagName('name-child')).get(_emptyNameIndex); let displayName = hero.element(by.tagName('h3')).getText(); - expect(displayName).toEqual(_defaultName) + expect(displayName).toEqual(_defaultName); }); // ... // #enddocregion parent-to-child-setter @@ -62,7 +65,7 @@ describe('Component Communication Cookbook Tests', function () { let actual = getActual(); let initialLabel = 'Version 1.23'; - let initialLog = 'major changed from {} to 1, minor changed from {} to 23'; + let initialLog = 'Initial value of major set to 1, Initial value of minor set to 23'; expect(actual.label).toBe(initialLabel); expect(actual.count).toBe(1); @@ -83,7 +86,7 @@ describe('Component Communication Cookbook Tests', function () { expect(actual.label).toBe(labelAfter2Minor); expect(actual.count).toBe(3); expect(actual.logs.get(2).getText()).toBe(logAfter2Minor); - }) + }); }); }); @@ -155,11 +158,11 @@ describe('Component Communication Cookbook Tests', function () { // Can't run timer tests in protractor because // interaction w/ zones causes all tests to freeze & timeout. xdescribe('Parent calls child via local var', function() { - countDownTimerTests('countdown-parent-lv') + countDownTimerTests('countdown-parent-lv'); }); xdescribe('Parent calls ViewChild', function() { - countDownTimerTests('countdown-parent-vc') + countDownTimerTests('countdown-parent-vc'); }); function countDownTimerTests(parentTag: string) { diff --git a/public/docs/_examples/cb-component-communication/ts/app/app.component.ts b/public/docs/_examples/cb-component-communication/ts/app/app.component.ts deleted file mode 100644 index 5b2442b195..0000000000 --- a/public/docs/_examples/cb-component-communication/ts/app/app.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroParentComponent } from './hero-parent.component'; -import { NameParentComponent } from './name-parent.component'; -import { VersionParentComponent } from './version-parent.component'; -import { VoteTakerComponent } from './votetaker.component'; -import { CountdownLocalVarParentComponent, - CountdownViewChildParentComponent } from './countdown-parent.component'; -import { MissionControlComponent } from './missioncontrol.component'; - -let directives: any[] = [ - HeroParentComponent, - NameParentComponent, - VersionParentComponent, - VoteTakerComponent, - MissionControlComponent, - ]; - -// Include Countdown examples -// unless in e2e tests which they break. -if (!/e2e/.test(location.search)) { - console.log('adding countdown timer examples') - directives.push(CountdownLocalVarParentComponent); - directives.push(CountdownViewChildParentComponent); -} - -@Component({ - selector: 'app', - templateUrl: 'app/app.component.html', - directives: directives -}) -export class AppComponent { } diff --git a/public/docs/_examples/cb-component-communication/ts/app/hero.ts b/public/docs/_examples/cb-component-communication/ts/app/hero.ts deleted file mode 100644 index 16ce60d8ed..0000000000 --- a/public/docs/_examples/cb-component-communication/ts/app/hero.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class Hero { - name: string; -} - -export const HEROES = [ - {name: 'Mr. IQ'}, - {name: 'Magneta'}, - {name: 'Bombasto'} -]; \ No newline at end of file diff --git a/public/docs/_examples/cb-component-communication/ts/app/main.ts b/public/docs/_examples/cb-component-communication/ts/app/main.ts deleted file mode 100644 index 9451f9b495..0000000000 --- a/public/docs/_examples/cb-component-communication/ts/app/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); \ No newline at end of file diff --git a/public/docs/_examples/cb-component-communication/ts/app/name-child.component.ts b/public/docs/_examples/cb-component-communication/ts/app/name-child.component.ts deleted file mode 100644 index 8e826075b0..0000000000 --- a/public/docs/_examples/cb-component-communication/ts/app/name-child.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -// #docregion -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'name-child', - template: ` -

    "{{name}}"

    - ` -}) -export class NameChildComponent { - _name: string = ''; - - @Input() - set name(name: string) { - this._name = (name && name.trim()) || ''; - } - - get name() { return this._name; } -} -// #enddocregion diff --git a/public/docs/_examples/cb-component-communication/ts/app/name-parent.component.ts b/public/docs/_examples/cb-component-communication/ts/app/name-parent.component.ts deleted file mode 100644 index aa7382503a..0000000000 --- a/public/docs/_examples/cb-component-communication/ts/app/name-parent.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { NameChildComponent } from './name-child.component'; - -@Component({ - selector: 'name-parent', - template: ` -

    Master controls {{names.length}} names

    - - - `, - directives: [NameChildComponent] -}) -export class NameParentComponent { - // Displays 'Mr. IQ', '', 'Bombasto' - names = ['Mr. IQ', ' ', ' Bombasto ']; -} -// #enddocregion diff --git a/public/docs/_examples/cb-component-communication/ts/app/version-child.component.ts b/public/docs/_examples/cb-component-communication/ts/app/version-child.component.ts deleted file mode 100644 index 91f5d547f7..0000000000 --- a/public/docs/_examples/cb-component-communication/ts/app/version-child.component.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* tslint:disable:forin */ -// #docregion -import { Component, Input, OnChanges, SimpleChange } from '@angular/core'; - -@Component({ - selector: 'version-child', - template: ` -

    Version {{major}}.{{minor}}

    -

    Change log:

    -
      -
    • {{change}}
    • -
    - ` -}) -export class VersionChildComponent implements OnChanges { - @Input() major: number; - @Input() minor: number; - changeLog: string[] = []; - - ngOnChanges(changes: {[propKey:string]: SimpleChange}){ - let log: string[] = []; - for (let propName in changes) { - let changedProp = changes[propName]; - let from = JSON.stringify(changedProp.previousValue); - let to = JSON.stringify(changedProp.currentValue); - log.push( `${propName} changed from ${from} to ${to}`); - } - this.changeLog.push(log.join(', ')); - } -} -// #enddocregion diff --git a/public/docs/_examples/cb-component-communication/ts/index.html b/public/docs/_examples/cb-component-communication/ts/index.html deleted file mode 100644 index 51adcdaf23..0000000000 --- a/public/docs/_examples/cb-component-communication/ts/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Passing information from parent to child - - - - - - - - - - - - - - - - - loading... - - - diff --git a/public/docs/_examples/cb-component-communication/ts/plnkr.json b/public/docs/_examples/cb-component-communication/ts/plnkr.json index 3c83b2d0f9..03bd55cd1a 100644 --- a/public/docs/_examples/cb-component-communication/ts/plnkr.json +++ b/public/docs/_examples/cb-component-communication/ts/plnkr.json @@ -1,8 +1,9 @@ { "description": "Component Communication Cookbook samples", + "basePath": "src/", "files":[ - "!**/*.d.ts", + "!**/*.d.ts", "!**/*.js" ], "tags":["cookbook", "component"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/cb-component-communication/ts/app/app.component.html b/public/docs/_examples/cb-component-communication/ts/src/app/app.component.html similarity index 100% rename from public/docs/_examples/cb-component-communication/ts/app/app.component.html rename to public/docs/_examples/cb-component-communication/ts/src/app/app.component.html diff --git a/public/docs/_examples/cb-component-communication/ts/src/app/app.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/app.component.ts new file mode 100644 index 0000000000..7556beb1ff --- /dev/null +++ b/public/docs/_examples/cb-component-communication/ts/src/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html' +}) +export class AppComponent { } diff --git a/public/docs/_examples/cb-component-communication/ts/src/app/app.module.ts b/public/docs/_examples/cb-component-communication/ts/src/app/app.module.ts new file mode 100644 index 0000000000..a008fc5486 --- /dev/null +++ b/public/docs/_examples/cb-component-communication/ts/src/app/app.module.ts @@ -0,0 +1,54 @@ +import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { AstronautComponent } from './astronaut.component'; +import { CountdownLocalVarParentComponent, CountdownViewChildParentComponent } from './countdown-parent.component'; +import { CountdownTimerComponent } from './countdown-timer.component'; +import { HeroChildComponent } from './hero-child.component'; +import { HeroParentComponent } from './hero-parent.component'; +import { MissionControlComponent } from './missioncontrol.component'; +import { NameChildComponent } from './name-child.component'; +import { NameParentComponent } from './name-parent.component'; +import { VersionChildComponent } from './version-child.component'; +import { VersionParentComponent } from './version-parent.component'; +import { VoterComponent } from './voter.component'; +import { VoteTakerComponent } from './votetaker.component'; + +let directives: any[] = [ + AppComponent, + AstronautComponent, + CountdownTimerComponent, + HeroChildComponent, + HeroParentComponent, + MissionControlComponent, + NameChildComponent, + NameParentComponent, + VersionChildComponent, + VersionParentComponent, + VoterComponent, + VoteTakerComponent + ]; + +let schemas: any[] = []; + +// Include Countdown examples +// unless in e2e tests which they break. +if (!/e2e/.test(location.search)) { + console.log('adding countdown timer examples'); + directives.push(CountdownLocalVarParentComponent); + directives.push(CountdownViewChildParentComponent); +} else { + // In e2e test use CUSTOM_ELEMENTS_SCHEMA to supress unknown element errors + schemas.push(CUSTOM_ELEMENTS_SCHEMA); +} + +@NgModule({ + imports: [ + BrowserModule + ], + declarations: directives, + bootstrap: [ AppComponent ], + schemas: schemas +}) +export class AppModule { } diff --git a/public/docs/_examples/cb-component-communication/ts/app/astronaut.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/astronaut.component.ts similarity index 85% rename from public/docs/_examples/cb-component-communication/ts/app/astronaut.component.ts rename to public/docs/_examples/cb-component-communication/ts/src/app/astronaut.component.ts index 7bda2b100f..bc24964f86 100644 --- a/public/docs/_examples/cb-component-communication/ts/app/astronaut.component.ts +++ b/public/docs/_examples/cb-component-communication/ts/src/app/astronaut.component.ts @@ -17,12 +17,12 @@ import { Subscription } from 'rxjs/Subscription';

    ` }) -export class AstronautComponent implements OnDestroy{ +export class AstronautComponent implements OnDestroy { @Input() astronaut: string; - mission = ""; + mission = ''; confirmed = false; announced = false; - subscription:Subscription; + subscription: Subscription; constructor(private missionService: MissionService) { this.subscription = missionService.missionAnnounced$.subscribe( @@ -30,7 +30,7 @@ export class AstronautComponent implements OnDestroy{ this.mission = mission; this.announced = true; this.confirmed = false; - }) + }); } confirm() { @@ -38,9 +38,9 @@ export class AstronautComponent implements OnDestroy{ this.missionService.confirmMission(this.astronaut); } - ngOnDestroy(){ + ngOnDestroy() { // prevent memory leak when component destroyed this.subscription.unsubscribe(); } } -// #enddocregion \ No newline at end of file +// #enddocregion diff --git a/public/docs/_examples/cb-component-communication/ts/app/countdown-parent.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/countdown-parent.component.ts similarity index 85% rename from public/docs/_examples/cb-component-communication/ts/app/countdown-parent.component.ts rename to public/docs/_examples/cb-component-communication/ts/src/app/countdown-parent.component.ts index 95425deef2..5bcf0645c9 100644 --- a/public/docs/_examples/cb-component-communication/ts/app/countdown-parent.component.ts +++ b/public/docs/_examples/cb-component-communication/ts/src/app/countdown-parent.component.ts @@ -11,7 +11,7 @@ import { CountdownTimerComponent } from './countdown-timer.component'; //// Local variable, #timer, version // #docregion lv @Component({ - selector:'countdown-parent-lv', + selector: 'countdown-parent-lv', template: `

    Countdown to Liftoff (via local variable)

    @@ -19,7 +19,6 @@ import { CountdownTimerComponent } from './countdown-timer.component';
    {{timer.seconds}}
    `, - directives: [CountdownTimerComponent], styleUrls: ['demo.css'] }) export class CountdownLocalVarParentComponent { } @@ -28,7 +27,7 @@ export class CountdownLocalVarParentComponent { } //// View Child version // #docregion vc @Component({ - selector:'countdown-parent-vc', + selector: 'countdown-parent-vc', template: `

    Countdown to Liftoff (via ViewChild)

    @@ -36,13 +35,12 @@ export class CountdownLocalVarParentComponent { }
    {{ seconds() }}
    `, - directives: [CountdownTimerComponent], styleUrls: ['demo.css'] }) export class CountdownViewChildParentComponent implements AfterViewInit { @ViewChild(CountdownTimerComponent) - private timerComponent:CountdownTimerComponent; + private timerComponent: CountdownTimerComponent; seconds() { return 0; } @@ -50,10 +48,10 @@ export class CountdownViewChildParentComponent implements AfterViewInit { // Redefine `seconds()` to get from the `CountdownTimerComponent.seconds` ... // but wait a tick first to avoid one-time devMode // unidirectional-data-flow-violation error - setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0) + setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0); } - start(){ this.timerComponent.start(); } + start() { this.timerComponent.start(); } stop() { this.timerComponent.stop(); } } // #enddocregion vc diff --git a/public/docs/_examples/cb-component-communication/ts/app/countdown-timer.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/countdown-timer.component.ts similarity index 94% rename from public/docs/_examples/cb-component-communication/ts/app/countdown-timer.component.ts rename to public/docs/_examples/cb-component-communication/ts/src/app/countdown-timer.component.ts index 262ed6f832..a9a1a2fa7c 100644 --- a/public/docs/_examples/cb-component-communication/ts/app/countdown-timer.component.ts +++ b/public/docs/_examples/cb-component-communication/ts/src/app/countdown-timer.component.ts @@ -11,7 +11,7 @@ export class CountdownTimerComponent implements OnInit, OnDestroy { message = ''; seconds = 11; - clearTimer() {clearInterval(this.intervalId);} + clearTimer() { clearInterval(this.intervalId); } ngOnInit() { this.start(); } ngOnDestroy() { this.clearTimer(); } diff --git a/public/docs/_examples/cb-component-communication/ts/app/hero-child.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/hero-child.component.ts similarity index 100% rename from public/docs/_examples/cb-component-communication/ts/app/hero-child.component.ts rename to public/docs/_examples/cb-component-communication/ts/src/app/hero-child.component.ts diff --git a/public/docs/_examples/cb-component-communication/ts/app/hero-parent.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/hero-parent.component.ts similarity index 80% rename from public/docs/_examples/cb-component-communication/ts/app/hero-parent.component.ts rename to public/docs/_examples/cb-component-communication/ts/src/app/hero-parent.component.ts index 6d82f53a4d..bf3861c455 100644 --- a/public/docs/_examples/cb-component-communication/ts/app/hero-parent.component.ts +++ b/public/docs/_examples/cb-component-communication/ts/src/app/hero-parent.component.ts @@ -1,7 +1,6 @@ // #docregion import { Component } from '@angular/core'; -import { HeroChildComponent } from './hero-child.component'; import { HEROES } from './hero'; @Component({ @@ -12,8 +11,7 @@ import { HEROES } from './hero'; [hero]="hero" [master]="master"> - `, - directives: [HeroChildComponent] + ` }) export class HeroParentComponent { heroes = HEROES; diff --git a/public/docs/_examples/cb-component-communication/ts/src/app/hero.ts b/public/docs/_examples/cb-component-communication/ts/src/app/hero.ts new file mode 100644 index 0000000000..a7b70f48e8 --- /dev/null +++ b/public/docs/_examples/cb-component-communication/ts/src/app/hero.ts @@ -0,0 +1,9 @@ +export class Hero { + name: string; +} + +export const HEROES = [ + {name: 'Mr. IQ'}, + {name: 'Magneta'}, + {name: 'Bombasto'} +]; diff --git a/public/docs/_examples/cb-component-communication/ts/app/mission.service.ts b/public/docs/_examples/cb-component-communication/ts/src/app/mission.service.ts similarity index 86% rename from public/docs/_examples/cb-component-communication/ts/app/mission.service.ts rename to public/docs/_examples/cb-component-communication/ts/src/app/mission.service.ts index 0c284389b6..25c86866b0 100644 --- a/public/docs/_examples/cb-component-communication/ts/app/mission.service.ts +++ b/public/docs/_examples/cb-component-communication/ts/src/app/mission.service.ts @@ -1,5 +1,5 @@ // #docregion -import { Injectable } from '@angular/core' +import { Injectable } from '@angular/core'; import { Subject } from 'rxjs/Subject'; @Injectable() @@ -15,7 +15,7 @@ export class MissionService { // Service message commands announceMission(mission: string) { - this.missionAnnouncedSource.next(mission) + this.missionAnnouncedSource.next(mission); } confirmMission(astronaut: string) { diff --git a/public/docs/_examples/cb-component-communication/ts/app/missioncontrol.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/missioncontrol.component.ts similarity index 88% rename from public/docs/_examples/cb-component-communication/ts/app/missioncontrol.component.ts rename to public/docs/_examples/cb-component-communication/ts/src/app/missioncontrol.component.ts index eff2b229c9..a27e9b16b1 100644 --- a/public/docs/_examples/cb-component-communication/ts/app/missioncontrol.component.ts +++ b/public/docs/_examples/cb-component-communication/ts/src/app/missioncontrol.component.ts @@ -1,7 +1,6 @@ // #docregion import { Component } from '@angular/core'; -import { AstronautComponent } from './astronaut.component'; import { MissionService } from './mission.service'; @Component({ @@ -17,11 +16,10 @@ import { MissionService } from './mission.service';
  • {{event}}
  • `, - directives: [AstronautComponent], providers: [MissionService] }) export class MissionControlComponent { - astronauts = ['Lovell', 'Swigert', 'Haise'] + astronauts = ['Lovell', 'Swigert', 'Haise']; history: string[] = []; missions = ['Fly to the moon!', 'Fly to mars!', @@ -32,7 +30,7 @@ export class MissionControlComponent { missionService.missionConfirmed$.subscribe( astronaut => { this.history.push(`${astronaut} confirmed the mission`); - }) + }); } announce() { diff --git a/public/docs/_examples/cb-component-communication/ts/src/app/name-child.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/name-child.component.ts new file mode 100644 index 0000000000..bc6d3c6f59 --- /dev/null +++ b/public/docs/_examples/cb-component-communication/ts/src/app/name-child.component.ts @@ -0,0 +1,18 @@ +// #docregion +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'name-child', + template: '

    "{{name}}"

    ' +}) +export class NameChildComponent { + private _name = ''; + + @Input() + set name(name: string) { + this._name = (name && name.trim()) || ''; + } + + get name(): string { return this._name; } +} +// #enddocregion diff --git a/public/docs/_examples/cb-component-communication/ts/src/app/name-parent.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/name-parent.component.ts new file mode 100644 index 0000000000..99753303aa --- /dev/null +++ b/public/docs/_examples/cb-component-communication/ts/src/app/name-parent.component.ts @@ -0,0 +1,15 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'name-parent', + template: ` +

    Master controls {{names.length}} names

    + + ` +}) +export class NameParentComponent { + // Displays 'Mr. IQ', '', 'Bombasto' + names = ['Mr. IQ', ' ', ' Bombasto ']; +} +// #enddocregion diff --git a/public/docs/_examples/cb-component-communication/ts/src/app/version-child.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/version-child.component.ts new file mode 100644 index 0000000000..89d365cf9f --- /dev/null +++ b/public/docs/_examples/cb-component-communication/ts/src/app/version-child.component.ts @@ -0,0 +1,35 @@ +/* tslint:disable:forin */ +// #docregion +import { Component, Input, OnChanges, SimpleChange } from '@angular/core'; + +@Component({ + selector: 'version-child', + template: ` +

    Version {{major}}.{{minor}}

    +

    Change log:

    +
      +
    • {{change}}
    • +
    + ` +}) +export class VersionChildComponent implements OnChanges { + @Input() major: number; + @Input() minor: number; + changeLog: string[] = []; + + ngOnChanges(changes: {[propKey: string]: SimpleChange}) { + let log: string[] = []; + for (let propName in changes) { + let changedProp = changes[propName]; + let to = JSON.stringify(changedProp.currentValue); + if (changedProp.isFirstChange()) { + log.push(`Initial value of ${propName} set to ${to}`); + } else { + let from = JSON.stringify(changedProp.previousValue); + log.push(`${propName} changed from ${from} to ${to}`); + } + } + this.changeLog.push(log.join(', ')); + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-component-communication/ts/app/version-parent.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/version-parent.component.ts similarity index 82% rename from public/docs/_examples/cb-component-communication/ts/app/version-parent.component.ts rename to public/docs/_examples/cb-component-communication/ts/src/app/version-parent.component.ts index cdb590b87a..bbc9101702 100644 --- a/public/docs/_examples/cb-component-communication/ts/app/version-parent.component.ts +++ b/public/docs/_examples/cb-component-communication/ts/src/app/version-parent.component.ts @@ -1,8 +1,6 @@ // #docregion import { Component } from '@angular/core'; -import { VersionChildComponent } from './version-child.component'; - @Component({ selector: 'version-parent', template: ` @@ -10,8 +8,7 @@ import { VersionChildComponent } from './version-child.component'; - `, - directives: [VersionChildComponent] + ` }) export class VersionParentComponent { major: number = 1; diff --git a/public/docs/_examples/cb-component-communication/ts/app/voter.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/voter.component.ts similarity index 91% rename from public/docs/_examples/cb-component-communication/ts/app/voter.component.ts rename to public/docs/_examples/cb-component-communication/ts/src/app/voter.component.ts index c68409a73a..c0cb23abc0 100644 --- a/public/docs/_examples/cb-component-communication/ts/app/voter.component.ts +++ b/public/docs/_examples/cb-component-communication/ts/src/app/voter.component.ts @@ -14,9 +14,9 @@ export class VoterComponent { @Output() onVoted = new EventEmitter(); voted = false; - vote(agreed:boolean){ + vote(agreed: boolean) { this.onVoted.emit(agreed); this.voted = true; } } -// #enddocregion \ No newline at end of file +// #enddocregion diff --git a/public/docs/_examples/cb-component-communication/ts/app/votetaker.component.ts b/public/docs/_examples/cb-component-communication/ts/src/app/votetaker.component.ts similarity index 78% rename from public/docs/_examples/cb-component-communication/ts/app/votetaker.component.ts rename to public/docs/_examples/cb-component-communication/ts/src/app/votetaker.component.ts index 3e2970b691..87f06161f5 100644 --- a/public/docs/_examples/cb-component-communication/ts/app/votetaker.component.ts +++ b/public/docs/_examples/cb-component-communication/ts/src/app/votetaker.component.ts @@ -1,8 +1,6 @@ // #docregion import { Component } from '@angular/core'; -import { VoterComponent } from './voter.component'; - @Component({ selector: 'vote-taker', template: ` @@ -12,13 +10,12 @@ import { VoterComponent } from './voter.component'; [name]="voter" (onVoted)="onVoted($event)"> - `, - directives: [VoterComponent] + ` }) export class VoteTakerComponent { agreed = 0; disagreed = 0; - voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto'] + voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto']; onVoted(agreed: boolean) { agreed ? this.agreed++ : this.disagreed++; diff --git a/public/docs/_examples/cb-component-communication/ts/demo.css b/public/docs/_examples/cb-component-communication/ts/src/demo.css similarity index 100% rename from public/docs/_examples/cb-component-communication/ts/demo.css rename to public/docs/_examples/cb-component-communication/ts/src/demo.css diff --git a/public/docs/_examples/cb-component-communication/ts/src/index.html b/public/docs/_examples/cb-component-communication/ts/src/index.html new file mode 100644 index 0000000000..64c8a3430f --- /dev/null +++ b/public/docs/_examples/cb-component-communication/ts/src/index.html @@ -0,0 +1,29 @@ + + + + + Passing information from parent to child + + + + + + + + + + + + + + + + + loading... + + + diff --git a/public/docs/_examples/cb-component-communication/ts/src/main.ts b/public/docs/_examples/cb-component-communication/ts/src/main.ts new file mode 100644 index 0000000000..311c44b76d --- /dev/null +++ b/public/docs/_examples/cb-component-communication/ts/src/main.ts @@ -0,0 +1,5 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-component-relative-paths/e2e-spec.ts b/public/docs/_examples/cb-component-relative-paths/e2e-spec.ts deleted file mode 100644 index e39dfdb8a9..0000000000 --- a/public/docs/_examples/cb-component-relative-paths/e2e-spec.ts +++ /dev/null @@ -1,39 +0,0 @@ -/// -describe('Cookbook: component-relative paths', function () { - - interface Page { - title: protractor.ElementFinder; - absComp: protractor.ElementFinder; - relComp: protractor.ElementFinder; - - } - function getPageStruct() { - return { - title: element( by.tagName( 'h1' )), - absComp: element( by.css( 'absolute-path div' ) ), - relComp: element( by.css( 'relative-path div' ) ) - } - } - - let page: Page; - beforeAll(function () { - browser.get(''); - page = getPageStruct(); - }); - - it('should display title of the sample', function () { - expect(element(by.tagName('h1')).getText()).toContain('Paths'); - }); - - it('should have absolute-path element', function () { - expect(page.absComp.isPresent()).toBe(true, 'no element'); - }); - - it('should display the absolute path text', function () { - expect(page.absComp.getText()).toContain('Absolute'); - }); - - it('should display the component-relative path text', function () { - expect(page.relComp.getText()).toContain('Component-relative'); - }); -}); diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/app.component.ts b/public/docs/_examples/cb-component-relative-paths/ts/app/app.component.ts deleted file mode 100644 index 09ccc94591..0000000000 --- a/public/docs/_examples/cb-component-relative-paths/ts/app/app.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { SomeAbsoluteComponent, SomeRelativeComponent} from './some.component'; - -@Component({ -selector: 'my-app', -template: - `

    Absolute & Component-Relative Paths

    - - - `, - directives: [SomeAbsoluteComponent, SomeRelativeComponent] -}) -export class AppComponent {} diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/main.ts b/public/docs/_examples/cb-component-relative-paths/ts/app/main.ts deleted file mode 100644 index 42dbeb9f7d..0000000000 --- a/public/docs/_examples/cb-component-relative-paths/ts/app/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.css b/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.css deleted file mode 100644 index f43e11f60e..0000000000 --- a/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.css +++ /dev/null @@ -1,22 +0,0 @@ -/* #docregion */ -div.absolute { - background: beige; - border: 1px solid darkred; - color: red; - margin: 8px; - max-width: 20em; - padding: 4px; - text-align: center; -} - -div.relative { - background: powderblue; - border: 1px solid darkblue; - color: Blue; - font-style: italic; - margin: 8px; - max-width: 20em; - padding: 4px; - text-align: center; -} - diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.html b/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.html deleted file mode 100644 index 027741ce55..0000000000 --- a/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.html +++ /dev/null @@ -1,4 +0,0 @@ - -
    - {{type}}
    {{path}} -
    diff --git a/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.ts b/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.ts deleted file mode 100644 index 2bd56c6930..0000000000 --- a/public/docs/_examples/cb-component-relative-paths/ts/app/some.component.ts +++ /dev/null @@ -1,37 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -///////// Using Absolute Paths /////// - -// #docregion absolute-config -@Component({ - selector: 'absolute-path', - templateUrl: 'app/some.component.html', - styleUrls: ['app/some.component.css'] -}) -// #enddocregion absolute-config -export class SomeAbsoluteComponent { - class = 'absolute'; - type = 'Absolute template & style URLs'; - path = 'app/path.component.html'; -} - -///////// Using Relative Paths /////// - -// #docregion relative-config -@Component({ - // #docregion module-id - moduleId: module.id, - // #enddocregion module-id - selector: 'relative-path', - templateUrl: 'some.component.html', - styleUrls: ['some.component.css'] -}) -// #enddocregion relative-config - -export class SomeRelativeComponent { - class = 'relative'; - type = 'Component-relative template & style URLs'; - path = 'path.component.html'; - -} diff --git a/public/docs/_examples/cb-component-relative-paths/ts/index.html b/public/docs/_examples/cb-component-relative-paths/ts/index.html deleted file mode 100644 index cc0d972df2..0000000000 --- a/public/docs/_examples/cb-component-relative-paths/ts/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - Component-Relative Paths - - - - - - - - - - - - - - - - - - Loading app... - - diff --git a/public/docs/_examples/cb-component-relative-paths/ts/plnkr.json b/public/docs/_examples/cb-component-relative-paths/ts/plnkr.json deleted file mode 100644 index a4c33bbde3..0000000000 --- a/public/docs/_examples/cb-component-relative-paths/ts/plnkr.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "description": "Module-relative Paths", - "files": [ - "!**/*.d.ts", - "!**/*.js" - ], - "tags": [ "cookbook" ] -} diff --git a/public/docs/_examples/cb-dependency-injection/e2e-spec.ts b/public/docs/_examples/cb-dependency-injection/e2e-spec.ts index 29a8822110..8c9d163d5e 100644 --- a/public/docs/_examples/cb-dependency-injection/e2e-spec.ts +++ b/public/docs/_examples/cb-dependency-injection/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Dependency Injection Cookbook', function () { beforeAll(function () { @@ -66,11 +69,11 @@ describe('Dependency Injection Cookbook', function () { }); it('should highlight Hero Bios and Contacts container when mouseover', function () { - let target = element(by.css('div[myHighlight="yellow"]')) + let target = element(by.css('div[myHighlight="yellow"]')); let yellow = 'rgba(255, 255, 0, 1)'; expect(target.getCssValue('background-color')).not.toEqual(yellow); - browser.actions().mouseMove(target as any as webdriver.WebElement).perform(); + browser.actions().mouseMove(target.getWebElement()).perform(); expect(target.getCssValue('background-color')).toEqual(yellow); }); diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/app.component.ts b/public/docs/_examples/cb-dependency-injection/ts/app/app.component.ts deleted file mode 100644 index a72af9e6da..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/app/app.component.ts +++ /dev/null @@ -1,46 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { HeroBiosComponent, - HeroBiosAndContactsComponent} from './hero-bios.component'; -import { HeroOfTheMonthComponent } from './hero-of-the-month.component'; -import { HeroesBaseComponent, - SortedHeroesComponent } from './sorted-heroes.component'; -import { HighlightDirective } from './highlight.directive'; -import { ParentFinderComponent } from './parent-finder.component'; - -const DIRECTIVES = [ - HeroBiosComponent, HeroBiosAndContactsComponent, - HeroesBaseComponent, SortedHeroesComponent, - HeroOfTheMonthComponent, - HighlightDirective, - ParentFinderComponent -]; - -// #docregion import-services -import { LoggerService } from './logger.service'; -import { UserContextService } from './user-context.service'; -import { UserService } from './user.service'; - -@Component({ - selector: 'my-app', - templateUrl: 'app/app.component.html', - directives: DIRECTIVES, -// #docregion providers - providers: [LoggerService, UserContextService, UserService] -// #enddocregion providers -}) -export class AppComponent { -// #enddocregion import-services - - private userId: number = 1; - - // #docregion ctor - constructor(logger: LoggerService, public userContext: UserContextService) { - userContext.loadUser(this.userId); - logger.logInfo('AppComponent initialized'); - } - // #enddocregion ctor -// #docregion import-services -} -// #enddocregion import-services diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/date-logger.service.ts b/public/docs/_examples/cb-dependency-injection/ts/app/date-logger.service.ts deleted file mode 100644 index e5b597db02..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/app/date-logger.service.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* tslint:disable:one-line:check-open-brace*/ -// #docregion -import { Injectable } from '@angular/core'; - -import { LoggerService } from './logger.service'; - -// #docregion minimal-logger -// class used as a restricting interface (hides other public members) -export abstract class MinimalLogger { - logInfo: (msg: string) => void; - logs: string[]; -} -// #enddocregion minimal-logger - -/* -// Transpiles to: -// #docregion minimal-logger-transpiled - var MinimalLogger = (function () { - function MinimalLogger() {} - return MinimalLogger; - }()); - exports("MinimalLogger", MinimalLogger); -// #enddocregion minimal-logger-transpiled - */ - -// #docregion date-logger-service -@Injectable() -// #docregion date-logger-service-signature -export class DateLoggerService extends LoggerService implements MinimalLogger -// #enddocregion date-logger-service-signature -{ - logInfo(msg: any) { super.logInfo(stamp(msg)); } - logDebug(msg: any) { super.logInfo(stamp(msg)); } - logError(msg: any) { super.logError(stamp(msg)); } -} - -function stamp(msg: any) { return msg + ' at ' + new Date(); } -// #enddocregion date-logger-service diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/hero-bios.component.ts b/public/docs/_examples/cb-dependency-injection/ts/app/hero-bios.component.ts deleted file mode 100644 index 05610bb9c9..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/app/hero-bios.component.ts +++ /dev/null @@ -1,52 +0,0 @@ -// #docplaster -// #docregion -import { Component} from '@angular/core'; - -import { HeroContactComponent } from './hero-contact.component'; -import { HeroBioComponent } from './hero-bio.component'; -import { HeroService } from './hero.service'; -import { LoggerService } from './logger.service'; - -//////// HeroBiosComponent //// -// #docregion simple -@Component({ - selector:'hero-bios', - template:` - - - `, - directives:[HeroBioComponent], - providers: [HeroService] -}) -export class HeroBiosComponent{ -// #enddocregion simple -// #docregion ctor - constructor(logger: LoggerService) { - logger.logInfo('Creating HeroBiosComponent'); - } -// #enddocregion ctor -// #docregion simple -} -// #enddocregion simple - -//////// HeroBiosAndContactsComponent //// -// #docregion hero-bios-and-contacts -@Component({ - selector:'hero-bios-and-contacts', - // #docregion template - template:` - - - `, - // #enddocregion template - directives:[HeroBioComponent, HeroContactComponent], - // #docregion class-provider - providers: [HeroService] - // #enddocregion class-provider -}) -export class HeroBiosAndContactsComponent{ - constructor(logger: LoggerService) { - logger.logInfo('Creating HeroBiosAndContactsComponent'); - } -} -// #enddocregion hero-bios-and-contacts \ No newline at end of file diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/hero-cache.service.ts b/public/docs/_examples/cb-dependency-injection/ts/app/hero-cache.service.ts deleted file mode 100644 index c8e6104666..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/app/hero-cache.service.ts +++ /dev/null @@ -1,20 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -import { Hero } from './hero'; -import { HeroService } from './hero.service'; - -// #docregion service -@Injectable() -export class HeroCacheService { - hero:Hero; - constructor(private heroService:HeroService){} - - fetchCachedHero(id:number){ - if (!this.hero) { - this.hero = this.heroService.getHeroById(id); - } - return this.hero - } -} -// #enddocregion service diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/hero-data.ts b/public/docs/_examples/cb-dependency-injection/ts/app/hero-data.ts deleted file mode 100644 index decccdbf72..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/app/hero-data.ts +++ /dev/null @@ -1,14 +0,0 @@ -// #docregion -import { Hero } from './hero'; - -export class HeroData { - createDb() { - let heroes = [ - new Hero(1,"Windstorm"), - new Hero(2,"Bombasto"), - new Hero(3,"Magneta"), - new Hero(4,"Tornado") - ]; - return {heroes}; - } -} diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/hero-of-the-month.component.ts b/public/docs/_examples/cb-dependency-injection/ts/app/hero-of-the-month.component.ts deleted file mode 100644 index c5bafca36d..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/app/hero-of-the-month.component.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* tslint:disable:one-line:check-open-brace*/ -// #docplaster -// #docregion opaque-token -import { OpaqueToken } from '@angular/core'; - -export const TITLE = new OpaqueToken('title'); -// #enddocregion opaque-token - -// #docregion hero-of-the-month -import { Component, Inject } from '@angular/core'; - -import { DateLoggerService, - MinimalLogger } from './date-logger.service'; -import { Hero } from './hero'; -import { HeroService } from './hero.service'; -import { LoggerService } from './logger.service'; -import { RUNNERS_UP, - runnersUpFactory } from './runners-up'; - -// #enddocregion hero-of-the-month -// #docregion some-hero -const someHero = new Hero(42, 'Magma', 'Had a great month!', '555-555-5555'); -// #enddocregion some-hero - -const template = ` -

    {{title}}

    -
    Winner: {{heroOfTheMonth.name}}
    -
    Reason for award: {{heroOfTheMonth.description}}
    -
    Runners-up: {{runnersUp}}
    - -

    Logs:

    -
    -
    {{log}}
    -
    - `; - -// #docregion hero-of-the-month -@Component({ - selector: 'hero-of-the-month', - template: template, - providers: [ - // #docregion use-value - { provide: Hero, useValue: someHero }, - // #docregion provide-opaque-token - { provide: TITLE, useValue: 'Hero of the Month' }, - // #enddocregion provide-opaque-token - // #enddocregion use-value - // #docregion use-class - { provide: HeroService, useClass: HeroService }, - { provide: LoggerService, useClass: DateLoggerService }, - // #enddocregion use-class - // #docregion use-existing - { provide: MinimalLogger, useExisting: LoggerService }, - // #enddocregion use-existing - // #docregion provide-opaque-token, use-factory - { provide: RUNNERS_UP, useFactory: runnersUpFactory(2), deps: [Hero, HeroService] } - // #enddocregion provide-opaque-token, use-factory - ] -}) -export class HeroOfTheMonthComponent { - logs: string[] = []; - -// #docregion ctor-signature - constructor( - logger: MinimalLogger, - public heroOfTheMonth: Hero, - @Inject(RUNNERS_UP) public runnersUp: string, - @Inject(TITLE) public title: string) -// #enddocregion ctor-signature - { - this.logs = logger.logs; - logger.logInfo('starting up'); - } -} -// #enddocregion hero-of-the-month diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/hero.service.ts b/public/docs/_examples/cb-dependency-injection/ts/app/hero.service.ts deleted file mode 100644 index 0222f6cd32..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/app/hero.service.ts +++ /dev/null @@ -1,22 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; -import { Hero } from './hero'; - -@Injectable() -export class HeroService { - - //TODO move to database - private heroes:Array = [ - new Hero(1, 'RubberMan','Hero of many talents', '123-456-7899'), - new Hero(2, 'Magma','Hero of all trades', '555-555-5555'), - new Hero(3, 'Mr. Nice','The name says it all','111-222-3333') - ]; - - getHeroById(id:number):Hero{ - return this.heroes.filter(hero => hero.id === id)[0]; - } - - getAllHeroes():Array{ - return this.heroes; - } -} diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/hero.ts b/public/docs/_examples/cb-dependency-injection/ts/app/hero.ts deleted file mode 100644 index 51ce8ebbff..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/app/hero.ts +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion -export class Hero{ - constructor( - public id: number, - public name:string, - public description?:string, - public phone?:string) { - } -} \ No newline at end of file diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/highlight.directive.ts b/public/docs/_examples/cb-dependency-injection/ts/app/highlight.directive.ts deleted file mode 100644 index 69bd1a1577..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/app/highlight.directive.ts +++ /dev/null @@ -1,28 +0,0 @@ -// #docplaster -// #docregion -import { Directive, ElementRef, Input } from '@angular/core'; - -@Directive({ - selector: '[myHighlight]', - host: { - '(mouseenter)': 'onMouseEnter()', - '(mouseleave)': 'onMouseLeave()' - } -}) -export class HighlightDirective { - - @Input('myHighlight') highlightColor: string; - - private el: HTMLElement; - - constructor(el: ElementRef) { - this.el = el.nativeElement; - } - - onMouseEnter() { this.highlight(this.highlightColor || 'cyan'); } - onMouseLeave() { this.highlight(null); } - - private highlight(color: string) { - this.el.style.backgroundColor = color; - } -} diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/main.ts b/public/docs/_examples/cb-dependency-injection/ts/app/main.ts deleted file mode 100644 index fd4646a055..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/app/main.ts +++ /dev/null @@ -1,22 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { XHRBackend } from '@angular/http'; -import { ROUTER_PROVIDERS } from '@angular/router-deprecated'; -import { LocationStrategy, - HashLocationStrategy } from '@angular/common'; - -import { HeroData } from './hero-data'; -import { InMemoryBackendService, - SEED_DATA } from 'angular2-in-memory-web-api'; - -import { AppComponent } from './app.component'; - -// #docregion bootstrap -bootstrap(AppComponent, [ - ROUTER_PROVIDERS, - { provide: LocationStrategy, useClass: HashLocationStrategy }, - - { provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server - { provide: SEED_DATA, useClass: HeroData } // in-mem server data -]).catch((err: any) => console.error(err)); -// #enddocregion bootstrap diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/user.service.ts b/public/docs/_examples/cb-dependency-injection/ts/app/user.service.ts deleted file mode 100644 index d4ca4fda2a..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/app/user.service.ts +++ /dev/null @@ -1,10 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -@Injectable() -export class UserService { - - getUserById(userId:number):any{ - return {name:'Bombasto',role:'Admin'}; - } -} diff --git a/public/docs/_examples/cb-dependency-injection/ts/index.html b/public/docs/_examples/cb-dependency-injection/ts/index.html deleted file mode 100644 index ba1d2761e1..0000000000 --- a/public/docs/_examples/cb-dependency-injection/ts/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Dependency Injection - - - - - - - - - - - - - - - - - - - Loading app... - - - diff --git a/public/docs/_examples/cb-dependency-injection/ts/plnkr.json b/public/docs/_examples/cb-dependency-injection/ts/plnkr.json index d20b01cf1d..ff0aedca01 100644 --- a/public/docs/_examples/cb-dependency-injection/ts/plnkr.json +++ b/public/docs/_examples/cb-dependency-injection/ts/plnkr.json @@ -1,9 +1,10 @@ { "description": "Dependency Injection", + "basePath": "src/", "files":[ - "!**/*.d.ts", + "!**/*.d.ts", "!**/*.js", "!**/*.[1].*" ], "tags":["cookbook"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/app-routing.module.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/app-routing.module.ts new file mode 100644 index 0000000000..09a0592d00 --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/app-routing.module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +const routes: Routes = []; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + providers: [], + exports: [RouterModule] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/app.component.html b/public/docs/_examples/cb-dependency-injection/ts/src/app/app.component.html similarity index 100% rename from public/docs/_examples/cb-dependency-injection/ts/app/app.component.html rename to public/docs/_examples/cb-dependency-injection/ts/src/app/app.component.html diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/app.component.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/app.component.ts new file mode 100644 index 0000000000..3045893c58 --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/app.component.ts @@ -0,0 +1,29 @@ +// #docregion +import { Component } from '@angular/core'; + +// #docregion import-services +import { LoggerService } from './logger.service'; +import { UserContextService } from './user-context.service'; +import { UserService } from './user.service'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html', +// #docregion providers + providers: [ LoggerService, UserContextService, UserService ] +// #enddocregion providers +}) +export class AppComponent { +// #enddocregion import-services + + private userId: number = 1; + + // #docregion ctor + constructor(logger: LoggerService, public userContext: UserContextService) { + userContext.loadUser(this.userId); + logger.logInfo('AppComponent initialized'); + } + // #enddocregion ctor +// #docregion import-services +} +// #enddocregion import-services diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/app.module.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/app.module.ts new file mode 100644 index 0000000000..a240e21f7c --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/app.module.ts @@ -0,0 +1,74 @@ +// #docregion +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +// import { AppRoutingModule } from './app-routing.module'; +import { LocationStrategy, + HashLocationStrategy } from '@angular/common'; +import { NgModule } from '@angular/core'; + +import { HeroData } from './hero-data'; +import { InMemoryWebApiModule } from 'angular-in-memory-web-api'; + + +import { AppComponent } from './app.component'; +import { HeroBioComponent } from './hero-bio.component'; +import { HeroBiosComponent, + HeroBiosAndContactsComponent } from './hero-bios.component'; +import { HeroOfTheMonthComponent } from './hero-of-the-month.component'; +import { HeroContactComponent } from './hero-contact.component'; +import { HeroesBaseComponent, + SortedHeroesComponent } from './sorted-heroes.component'; +import { HighlightDirective } from './highlight.directive'; +import { ParentFinderComponent, + AlexComponent, + AliceComponent, + CarolComponent, + ChrisComponent, + CraigComponent, + CathyComponent, + BarryComponent, + BethComponent, + BobComponent } from './parent-finder.component'; + +const declarations = [ + AppComponent, + HeroBiosComponent, HeroBiosAndContactsComponent, HeroBioComponent, + HeroesBaseComponent, SortedHeroesComponent, + HeroOfTheMonthComponent, HeroContactComponent, + HighlightDirective, + ParentFinderComponent, +]; + +const a_components = [AliceComponent, AlexComponent ]; + +const b_components = [ BarryComponent, BethComponent, BobComponent ]; + +const c_components = [ + CarolComponent, ChrisComponent, CraigComponent, + CathyComponent +]; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HttpModule, + InMemoryWebApiModule.forRoot(HeroData) + // AppRoutingModule TODO: add routes + ], + declarations: [ + declarations, + a_components, + b_components, + c_components, + ], + bootstrap: [ AppComponent ], + // #docregion providers + providers: [ + { provide: LocationStrategy, useClass: HashLocationStrategy } + ] + // #enddocregion providers +}) +export class AppModule { } diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/date-logger.service.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/date-logger.service.ts new file mode 100644 index 0000000000..875779be40 --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/date-logger.service.ts @@ -0,0 +1,19 @@ +/* tslint:disable:one-line:check-open-brace*/ +// #docregion +import { Injectable } from '@angular/core'; + +import { LoggerService } from './logger.service'; + +// #docregion date-logger-service +@Injectable() +// #docregion date-logger-service-signature +export class DateLoggerService extends LoggerService +// #enddocregion date-logger-service-signature +{ + logInfo(msg: any) { super.logInfo(stamp(msg)); } + logDebug(msg: any) { super.logInfo(stamp(msg)); } + logError(msg: any) { super.logError(stamp(msg)); } +} + +function stamp(msg: any) { return msg + ' at ' + new Date(); } +// #enddocregion date-logger-service diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/hero-bio.component.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-bio.component.ts similarity index 77% rename from public/docs/_examples/cb-dependency-injection/ts/app/hero-bio.component.ts rename to public/docs/_examples/cb-dependency-injection/ts/src/app/hero-bio.component.ts index b4d122bfe4..84f8e05e66 100644 --- a/public/docs/_examples/cb-dependency-injection/ts/app/hero-bio.component.ts +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-bio.component.ts @@ -1,14 +1,13 @@ // #docregion import { Component, Input, OnInit } from '@angular/core'; -import { Hero } from './hero'; import { HeroCacheService } from './hero-cache.service'; // #docregion component @Component({ - selector:'hero-bio', + selector: 'hero-bio', // #docregion template - template:` + template: `

    {{hero.name}}

    `, @@ -17,10 +16,9 @@ import { HeroCacheService } from './hero-cache.service'; }) export class HeroBioComponent implements OnInit { + @Input() heroId: number; - @Input() heroId:number; - - constructor(private heroCache:HeroCacheService) { } + constructor(private heroCache: HeroCacheService) { } ngOnInit() { this.heroCache.fetchCachedHero(this.heroId); } diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-bios.component.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-bios.component.ts new file mode 100644 index 0000000000..217c5edcd0 --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-bios.component.ts @@ -0,0 +1,48 @@ +// #docplaster +// #docregion +import { Component } from '@angular/core'; + +import { HeroService } from './hero.service'; +import { LoggerService } from './logger.service'; + +//////// HeroBiosComponent //// +// #docregion simple +@Component({ + selector: 'hero-bios', + template: ` + + + `, + providers: [HeroService] +}) +export class HeroBiosComponent { +// #enddocregion simple +// #docregion ctor + constructor(logger: LoggerService) { + logger.logInfo('Creating HeroBiosComponent'); + } +// #enddocregion ctor +// #docregion simple +} +// #enddocregion simple + +//////// HeroBiosAndContactsComponent //// +// #docregion hero-bios-and-contacts +@Component({ + selector: 'hero-bios-and-contacts', + // #docregion template + template: ` + + + `, + // #enddocregion template + // #docregion class-provider + providers: [HeroService] + // #enddocregion class-provider +}) +export class HeroBiosAndContactsComponent { + constructor(logger: LoggerService) { + logger.logInfo('Creating HeroBiosAndContactsComponent'); + } +} +// #enddocregion hero-bios-and-contacts diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-cache.service.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-cache.service.ts new file mode 100644 index 0000000000..6dbc7a0c4f --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-cache.service.ts @@ -0,0 +1,20 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +// #docregion service +@Injectable() +export class HeroCacheService { + hero: Hero; + constructor(private heroService: HeroService) {} + + fetchCachedHero(id: number) { + if (!this.hero) { + this.hero = this.heroService.getHeroById(id); + } + return this.hero; + } +} +// #enddocregion service diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/hero-contact.component.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-contact.component.ts similarity index 88% rename from public/docs/_examples/cb-dependency-injection/ts/app/hero-contact.component.ts rename to public/docs/_examples/cb-dependency-injection/ts/src/app/hero-contact.component.ts index a91f01b104..add6df91c5 100644 --- a/public/docs/_examples/cb-dependency-injection/ts/app/hero-contact.component.ts +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-contact.component.ts @@ -1,14 +1,14 @@ // #docplaster // #docregion -import { Component, ElementRef, Host, Inject, Optional } from '@angular/core'; +import { Component, Host, Optional } from '@angular/core'; import { HeroCacheService } from './hero-cache.service'; import { LoggerService } from './logger.service'; // #docregion component @Component({ - selector:'hero-contact', - template:` + selector: 'hero-contact', + template: `
    Phone #: {{phoneNumber}} !!!
    ` }) diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-data.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-data.ts new file mode 100644 index 0000000000..10cdbcaab1 --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-data.ts @@ -0,0 +1,14 @@ +// #docregion +import { Hero } from './hero'; + +export class HeroData { + createDb() { + let heroes = [ + new Hero(1, 'Windstorm'), + new Hero(2, 'Bombasto'), + new Hero(3, 'Magneta'), + new Hero(4, 'Tornado') + ]; + return {heroes}; + } +} diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-of-the-month.component.1.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-of-the-month.component.1.ts new file mode 100644 index 0000000000..da2c57aeaf --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-of-the-month.component.1.ts @@ -0,0 +1,26 @@ +// Illustrative (not used), mini-version of the actual HeroOfTheMonthComponent +// Injecting with the MinimalLogger "interface-class" +import { Component, NgModule } from '@angular/core'; +import { LoggerService } from './logger.service'; +import { MinimalLogger } from './minimal-logger.service'; + +// #docregion +@Component({ + selector: 'hero-of-the-month', + templateUrl: './hero-of-the-month.component.html', + // Todo: move this aliasing, `useExisting` provider to the AppModule + providers: [{ provide: MinimalLogger, useExisting: LoggerService }] +}) +export class HeroOfTheMonthComponent { + logs: string[] = []; + constructor(logger: MinimalLogger) { + logger.logInfo('starting up'); + } +} +// #enddocregion + +// This NgModule exists only to avoid the Angular language service's "undeclared component" error +@NgModule({ + declarations: [ HeroOfTheMonthComponent ] +}) +class NoopModule {} diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-of-the-month.component.html b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-of-the-month.component.html new file mode 100644 index 0000000000..f0ae619d6a --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-of-the-month.component.html @@ -0,0 +1,9 @@ +

    {{title}}

    +
    Winner: {{heroOfTheMonth.name}}
    +
    Reason for award: {{heroOfTheMonth.description}}
    +
    Runners-up: {{runnersUp}}
    + +

    Logs:

    +
    +
    {{log}}
    +
    diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-of-the-month.component.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-of-the-month.component.ts new file mode 100644 index 0000000000..90ad13d639 --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero-of-the-month.component.ts @@ -0,0 +1,63 @@ +/* tslint:disable:one-line:check-open-brace*/ +// #docplaster +// #docregion injection-token +import { InjectionToken } from '@angular/core'; + +export const TITLE = new InjectionToken('title'); +// #enddocregion injection-token + +// #docregion hero-of-the-month +import { Component, Inject } from '@angular/core'; + +import { DateLoggerService } from './date-logger.service'; +import { Hero } from './hero'; +import { HeroService } from './hero.service'; +import { LoggerService } from './logger.service'; +import { MinimalLogger } from './minimal-logger.service'; +import { RUNNERS_UP, + runnersUpFactory } from './runners-up'; + +// #enddocregion hero-of-the-month +// #docregion some-hero +const someHero = new Hero(42, 'Magma', 'Had a great month!', '555-555-5555'); +// #enddocregion some-hero + +// #docregion hero-of-the-month +@Component({ + selector: 'hero-of-the-month', + templateUrl: './hero-of-the-month.component.html', + providers: [ + // #docregion use-value + { provide: Hero, useValue: someHero }, + // #docregion provide-injection-token + { provide: TITLE, useValue: 'Hero of the Month' }, + // #enddocregion provide-injection-token + // #enddocregion use-value + // #docregion use-class + { provide: HeroService, useClass: HeroService }, + { provide: LoggerService, useClass: DateLoggerService }, + // #enddocregion use-class + // #docregion use-existing + { provide: MinimalLogger, useExisting: LoggerService }, + // #enddocregion use-existing + // #docregion provide-injection-token, use-factory + { provide: RUNNERS_UP, useFactory: runnersUpFactory(2), deps: [Hero, HeroService] } + // #enddocregion provide-injection-token, use-factory + ] +}) +export class HeroOfTheMonthComponent { + logs: string[] = []; + +// #docregion ctor-signature + constructor( + logger: MinimalLogger, + public heroOfTheMonth: Hero, + @Inject(RUNNERS_UP) public runnersUp: string, + @Inject(TITLE) public title: string) +// #enddocregion ctor-signature + { + this.logs = logger.logs; + logger.logInfo('starting up'); + } +} +// #enddocregion hero-of-the-month diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/hero.service.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero.service.ts new file mode 100644 index 0000000000..2063c30d7a --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero.service.ts @@ -0,0 +1,22 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { Hero } from './hero'; + +@Injectable() +export class HeroService { + + // TODO move to database + private heroes: Array = [ + new Hero(1, 'RubberMan', 'Hero of many talents', '123-456-7899'), + new Hero(2, 'Magma', 'Hero of all trades', '555-555-5555'), + new Hero(3, 'Mr. Nice', 'The name says it all', '111-222-3333') + ]; + + getHeroById(id: number): Hero { + return this.heroes.find(hero => hero.id === id); + } + + getAllHeroes(): Array { + return this.heroes; + } +} diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/hero.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero.ts new file mode 100644 index 0000000000..c17069e727 --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/hero.ts @@ -0,0 +1,9 @@ +// #docregion +export class Hero { + constructor( + public id: number, + public name: string, + public description?: string, + public phone?: string) { + } +} diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/highlight.directive.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/highlight.directive.ts new file mode 100644 index 0000000000..e220114daa --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/highlight.directive.ts @@ -0,0 +1,29 @@ +// #docplaster +// #docregion +import { Directive, ElementRef, HostListener, Input } from '@angular/core'; + +@Directive({ + selector: '[myHighlight]' +}) +export class HighlightDirective { + + @Input('myHighlight') highlightColor: string; + + private el: HTMLElement; + + constructor(el: ElementRef) { + this.el = el.nativeElement; + } + + @HostListener('mouseenter') onMouseEnter() { + this.highlight(this.highlightColor || 'cyan'); + } + + @HostListener('mouseleave') onMouseLeave() { + this.highlight(null); + } + + private highlight(color: string) { + this.el.style.backgroundColor = color; + } +} diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/logger.service.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/logger.service.ts similarity index 100% rename from public/docs/_examples/cb-dependency-injection/ts/app/logger.service.ts rename to public/docs/_examples/cb-dependency-injection/ts/src/app/logger.service.ts diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/minimal-logger.service.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/minimal-logger.service.ts new file mode 100644 index 0000000000..d87fa594d1 --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/minimal-logger.service.ts @@ -0,0 +1,22 @@ +// #docregion +// Class used as a "narrowing" interface that exposes a minimal logger +// Other members of the actual implementation are invisible +export abstract class MinimalLogger { + logs: string[]; + logInfo: (msg: string) => void; +} +// #enddocregion + +/* +// Transpiles to: +// #docregion minimal-logger-transpiled + var MinimalLogger = (function () { + function MinimalLogger() {} + return MinimalLogger; + }()); + exports("MinimalLogger", MinimalLogger); +// #enddocregion minimal-logger-transpiled +*/ + +// See http://stackoverflow.com/questions/43154832/unexpected-token-export-in-angular-app-with-systemjs-and-typescript/ +export const _ = 0; diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/parent-finder.component.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/parent-finder.component.ts similarity index 87% rename from public/docs/_examples/cb-dependency-injection/ts/app/parent-finder.component.ts rename to public/docs/_examples/cb-dependency-injection/ts/src/app/parent-finder.component.ts index 045ce8c545..c6f208f79b 100644 --- a/public/docs/_examples/cb-dependency-injection/ts/app/parent-finder.component.ts +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/parent-finder.component.ts @@ -1,8 +1,8 @@ -/* tslint:disable:no-unused-variable */ -/* tslint:disable:one-line:check-open-brace*/ +/* tslint:disable:no-unused-variable component-selector-name one-line check-open-brace */ +/* tslint:disable:*/ // #docplaster // #docregion -import { Component, forwardRef, Optional, provide, SkipSelf } from '@angular/core'; +import { Component, forwardRef, Optional, SkipSelf } from '@angular/core'; // A component base class (see AlexComponent) export abstract class Base { name = 'Count Basie'; } @@ -23,7 +23,7 @@ const provideParent = // #enddocregion provide-parent, provide-the-parent // #docregion provide-parent (component: any, parentType?: any) => { - return { provide: parentType || Parent, useExisting: forwardRef(() => component) } + return { provide: parentType || Parent, useExisting: forwardRef(() => component) }; }; // #enddocregion provide-parent @@ -31,7 +31,7 @@ const provideParent = const provideTheParent = // #docregion provide-the-parent (component: any) => { - return { provide: Parent, useExisting: forwardRef(() => component) } + return { provide: Parent, useExisting: forwardRef(() => component) }; }; // #enddocregion provide-the-parent @@ -85,13 +85,6 @@ export class CraigComponent { } // #enddocregion craig -// #docregion C_DIRECTIVES -const C_DIRECTIVES = [ - CarolComponent, ChrisComponent, CraigComponent, - forwardRef(() => CathyComponent) -]; -// #enddocregion C_DIRECTIVES - //////// B - Parent ///////// // #docregion barry const templateB = ` @@ -107,7 +100,6 @@ const templateB = ` @Component({ selector: 'barry', template: templateB, - directives: C_DIRECTIVES, providers: [{ provide: Parent, useExisting: forwardRef(() => BarryComponent) }] }) export class BarryComponent implements Parent { @@ -121,7 +113,6 @@ export class BarryComponent implements Parent { @Component({ selector: 'bob', template: templateB, - directives: C_DIRECTIVES, providers: [ provideParent(BobComponent) ] }) export class BobComponent implements Parent { @@ -132,7 +123,6 @@ export class BobComponent implements Parent { @Component({ selector: 'beth', template: templateB, - directives: C_DIRECTIVES, // #docregion beth-providers providers: [ provideParent(BethComponent, DifferentParent) ] // #enddocregion beth-providers @@ -142,8 +132,6 @@ export class BethComponent implements Parent { constructor( @SkipSelf() @Optional() public parent: Parent ) { } } -const B_DIRECTIVES = [ BarryComponent, BethComponent, BobComponent ]; - ///////// A - Grandparent ////// // #docregion alex, alex-1 @@ -161,7 +149,6 @@ const B_DIRECTIVES = [ BarryComponent, BethComponent, BobComponent ]; providers: [{ provide: Parent, useExisting: forwardRef(() => AlexComponent) }], // #enddocregion alex-providers // #docregion alex-1 - directives: C_DIRECTIVES }) // #enddocregion alex-1 // Todo: Add `... implements Parent` to class signature @@ -187,7 +174,6 @@ export class AlexComponent extends Base
    `, - directives: [ B_DIRECTIVES, C_DIRECTIVES ], // #docregion alice-providers providers: [ provideParent(AliceComponent) ] // #enddocregion alice-providers @@ -224,7 +210,6 @@ export class CathyComponent { template: `

    Parent Finder

    - `, - directives: [ AlexComponent, AliceComponent ] + ` }) export class ParentFinderComponent { } diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/runners-up.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/runners-up.ts similarity index 80% rename from public/docs/_examples/cb-dependency-injection/ts/app/runners-up.ts rename to public/docs/_examples/cb-dependency-injection/ts/src/app/runners-up.ts index 0bc3069883..0ce81ca55c 100644 --- a/public/docs/_examples/cb-dependency-injection/ts/app/runners-up.ts +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/runners-up.ts @@ -1,13 +1,13 @@ // #docplaster // #docregion -import { OpaqueToken } from '@angular/core'; +import { InjectionToken } from '@angular/core'; import { Hero } from './hero'; import { HeroService } from './hero.service'; // #docregion runners-up -export const RUNNERS_UP = new OpaqueToken('RunnersUp'); -// #docregion runners-up +export const RUNNERS_UP = new InjectionToken('RunnersUp'); +// #enddocregion runners-up // #docregion factory-synopsis export function runnersUpFactory(take: number) { diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/sorted-heroes.component.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/sorted-heroes.component.ts similarity index 100% rename from public/docs/_examples/cb-dependency-injection/ts/app/sorted-heroes.component.ts rename to public/docs/_examples/cb-dependency-injection/ts/src/app/sorted-heroes.component.ts diff --git a/public/docs/_examples/cb-dependency-injection/ts/app/user-context.service.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/user-context.service.ts similarity index 80% rename from public/docs/_examples/cb-dependency-injection/ts/app/user-context.service.ts rename to public/docs/_examples/cb-dependency-injection/ts/src/app/user-context.service.ts index 782e65043d..ed394fc734 100644 --- a/public/docs/_examples/cb-dependency-injection/ts/app/user-context.service.ts +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/user-context.service.ts @@ -9,19 +9,19 @@ import { UserService } from './user.service'; @Injectable() export class UserContextService { // #enddocregion injectables, injectable - name:string; - role:string; - loggedInSince:Date; + name: string; + role: string; + loggedInSince: Date; // #docregion ctor, injectables - constructor(private userService:UserService, private loggerService:LoggerService){ + constructor(private userService: UserService, private loggerService: LoggerService) { // #enddocregion ctor, injectables this.loggedInSince = new Date(); // #docregion ctor, injectables } // #enddocregion ctor, injectables - loadUser(userId:number){ + loadUser(userId: number) { let user = this.userService.getUserById(userId); this.name = user.name; this.role = user.role; diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/app/user.service.ts b/public/docs/_examples/cb-dependency-injection/ts/src/app/user.service.ts new file mode 100644 index 0000000000..c48b025a08 --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/app/user.service.ts @@ -0,0 +1,10 @@ +// #docregion +import { Injectable } from '@angular/core'; + +@Injectable() +export class UserService { + + getUserById(userId: number): any { + return {name: 'Bombasto', role: 'Admin'}; + } +} diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/index.html b/public/docs/_examples/cb-dependency-injection/ts/src/index.html new file mode 100644 index 0000000000..0308c72155 --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/index.html @@ -0,0 +1,29 @@ + + + + + + Dependency Injection + + + + + + + + + + + + + + + + + + Loading app... + + + diff --git a/public/docs/_examples/cb-dependency-injection/ts/src/main.ts b/public/docs/_examples/cb-dependency-injection/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/cb-dependency-injection/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-dependency-injection/ts/sample.css b/public/docs/_examples/cb-dependency-injection/ts/src/sample.css similarity index 100% rename from public/docs/_examples/cb-dependency-injection/ts/sample.css rename to public/docs/_examples/cb-dependency-injection/ts/src/sample.css diff --git a/public/docs/_examples/cb-dynamic-component-loader/e2e-spec.ts b/public/docs/_examples/cb-dynamic-component-loader/e2e-spec.ts new file mode 100644 index 0000000000..5036ac2a88 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/e2e-spec.ts @@ -0,0 +1,21 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + +/* tslint:disable:quotemark */ +describe('Dynamic Component Loader', function () { + + beforeEach(function () { + browser.get(''); + }); + + it('should load ad banner', function () { + let headline = element(by.xpath("//h4[text()='Featured Hero Profile']")); + let name = element(by.xpath("//h3[text()='Bombasto']")); + let bio = element(by.xpath("//p[text()='Brave as they come']")); + + expect(name).toBeDefined(); + expect(headline).toBeDefined(); + expect(bio).toBeDefined(); + }); +}); diff --git a/public/docs/_examples/cb-component-relative-paths/ts/example-config.json b/public/docs/_examples/cb-dynamic-component-loader/ts/example-config.json similarity index 100% rename from public/docs/_examples/cb-component-relative-paths/ts/example-config.json rename to public/docs/_examples/cb-dynamic-component-loader/ts/example-config.json diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/plnkr.json b/public/docs/_examples/cb-dynamic-component-loader/ts/plnkr.json new file mode 100644 index 0000000000..c43fb15c12 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/plnkr.json @@ -0,0 +1,9 @@ +{ + "description": "Dynamic Component Loader", + "basePath": "src/", + "files":[ + "!**/*.d.ts", + "!**/*.js" + ], + "tags":["cookbook component"] +} diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad-banner.component.ts b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad-banner.component.ts new file mode 100644 index 0000000000..8489fce5b2 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad-banner.component.ts @@ -0,0 +1,57 @@ +// #docregion +import { Component, Input, AfterViewInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core'; + +import { AdDirective } from './ad.directive'; +import { AdItem } from './ad-item'; +import { AdComponent } from './ad.component'; + +@Component({ + selector: 'add-banner', + // #docregion ad-host + template: ` +
    +

    Advertisements

    + +
    + ` + // #enddocregion ad-host +}) +// #docregion class +export class AdBannerComponent implements AfterViewInit, OnDestroy { + @Input() ads: AdItem[]; + currentAddIndex: number = -1; + @ViewChild(AdDirective) adHost: AdDirective; + subscription: any; + interval: any; + + constructor(private _componentFactoryResolver: ComponentFactoryResolver) { } + + ngAfterViewInit() { + this.loadComponent(); + this.getAds(); + } + + ngOnDestroy() { + clearInterval(this.interval); + } + + loadComponent() { + this.currentAddIndex = (this.currentAddIndex + 1) % this.ads.length; + let adItem = this.ads[this.currentAddIndex]; + + let componentFactory = this._componentFactoryResolver.resolveComponentFactory(adItem.component); + + let viewContainerRef = this.adHost.viewContainerRef; + viewContainerRef.clear(); + + let componentRef = viewContainerRef.createComponent(componentFactory); + (componentRef.instance).data = adItem.data; + } + + getAds() { + this.interval = setInterval(() => { + this.loadComponent(); + }, 3000); + } +} +// #enddocregion class diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad-item.ts b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad-item.ts new file mode 100644 index 0000000000..ef8ca70577 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad-item.ts @@ -0,0 +1,6 @@ +// #docregion +import { Type } from '@angular/core'; + +export class AdItem { + constructor(public component: Type, public data: any) {} +} diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad.component.ts b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad.component.ts new file mode 100644 index 0000000000..dee3b47953 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad.component.ts @@ -0,0 +1,4 @@ +// #docregion +export interface AdComponent { + data: any; +} diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad.directive.ts b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad.directive.ts new file mode 100644 index 0000000000..312e605228 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad.directive.ts @@ -0,0 +1,10 @@ +// #docregion +import { Directive, ViewContainerRef } from '@angular/core'; + +@Directive({ + selector: '[ad-host]', +}) +export class AdDirective { + constructor(public viewContainerRef: ViewContainerRef) { } +} + diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad.service.ts b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad.service.ts new file mode 100644 index 0000000000..91b0758771 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/ad.service.ts @@ -0,0 +1,23 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { HeroJobAdComponent } from './hero-job-ad.component'; +import { HeroProfileComponent } from './hero-profile.component'; +import { AdItem } from './ad-item'; + +@Injectable() +export class AdService { + getAds() { + return [ + new AdItem(HeroProfileComponent, {name: 'Bombasto', bio: 'Brave as they come'}), + + new AdItem(HeroProfileComponent, {name: 'Dr IQ', bio: 'Smart as they come'}), + + new AdItem(HeroJobAdComponent, {headline: 'Hiring for several positions', + body: 'Submit your resume today!'}), + + new AdItem(HeroJobAdComponent, {headline: 'Openings in all departments', + body: 'Apply today'}), + ]; + } +} diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/app.component.ts b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/app.component.ts new file mode 100644 index 0000000000..89359ccdf6 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/app.component.ts @@ -0,0 +1,24 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; + +import { AdService } from './ad.service'; +import { AdItem } from './ad-item'; + +@Component({ + selector: 'my-app', + template: ` +
    + +
    + ` +}) +export class AppComponent implements OnInit { + ads: AdItem[]; + + constructor(private adService: AdService) {} + + ngOnInit() { + this.ads = this.adService.getAds(); + } +} + diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/app.module.ts b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/app.module.ts new file mode 100644 index 0000000000..a65d394709 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/app.module.ts @@ -0,0 +1,27 @@ +// #docregion +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { AppComponent } from './app.component'; +import { HeroJobAdComponent } from './hero-job-ad.component'; +import { AdBannerComponent } from './ad-banner.component'; +import { HeroProfileComponent } from './hero-profile.component'; +import { AdDirective } from './ad.directive'; +import { AdService } from './ad.service'; + +@NgModule({ + imports: [ BrowserModule ], + providers: [AdService], + declarations: [ AppComponent, + AdBannerComponent, + HeroJobAdComponent, + HeroProfileComponent, + AdDirective ], + // #docregion entry-components + entryComponents: [ HeroJobAdComponent, HeroProfileComponent ], + // #enddocregion entry-components + bootstrap: [ AppComponent ] +}) +export class AppModule { + constructor() {} +} + diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/hero-job-ad.component.ts b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/hero-job-ad.component.ts new file mode 100644 index 0000000000..675a03d0e0 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/hero-job-ad.component.ts @@ -0,0 +1,19 @@ +// #docregion +import { Component, Input } from '@angular/core'; + +import { AdComponent } from './ad.component'; + +@Component({ + template: ` +
    +

    {{data.headline}}

    + + {{data.body}} +
    + ` +}) +export class HeroJobAdComponent implements AdComponent { + @Input() data: any; + +} + diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/hero-profile.component.ts b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/hero-profile.component.ts new file mode 100644 index 0000000000..1c266db3c9 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/app/hero-profile.component.ts @@ -0,0 +1,22 @@ +// #docregion +import { Component, Input } from '@angular/core'; + +import { AdComponent } from './ad.component'; + +@Component({ + template: ` +
    +

    Featured Hero Profile

    +

    {{data.name}}

    + +

    {{data.bio}}

    + + Hire this hero today! +
    + ` +}) +export class HeroProfileComponent implements AdComponent { + @Input() data: any; +} + + diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/index.html b/public/docs/_examples/cb-dynamic-component-loader/ts/src/index.html new file mode 100644 index 0000000000..9239d91d9a --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/index.html @@ -0,0 +1,26 @@ + + + + + + Dynamic Component Loader + + + + + + + + + + + + + + + Loading app... + + + diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/main.ts b/public/docs/_examples/cb-dynamic-component-loader/ts/src/main.ts new file mode 100644 index 0000000000..53d16fa43a --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); + diff --git a/public/docs/_examples/cb-dynamic-component-loader/ts/src/sample.css b/public/docs/_examples/cb-dynamic-component-loader/ts/src/sample.css new file mode 100644 index 0000000000..7a2ca1f2dc --- /dev/null +++ b/public/docs/_examples/cb-dynamic-component-loader/ts/src/sample.css @@ -0,0 +1,23 @@ +.hero-profile { + border: 1px solid gray; + padding: 5px; + padding-bottom: 20px; + padding-left: 20px; + border-radius: 10px; + background-color: lightgreen; + color: black; +} + +.job-ad { + border: 1px solid gray; + padding: 5px; + padding-bottom: 20px; + padding-left: 20px; + border-radius: 10px; + background-color: lightblue; + color: black; +} + +.ad-banner { + width: 400px; +} \ No newline at end of file diff --git a/public/docs/_examples/cb-dynamic-form/e2e-spec.ts b/public/docs/_examples/cb-dynamic-form/e2e-spec.ts index d526626b24..408ac75766 100644 --- a/public/docs/_examples/cb-dynamic-form/e2e-spec.ts +++ b/public/docs/_examples/cb-dynamic-form/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + /* tslint:disable:quotemark */ describe('Dynamic Form', function () { @@ -15,7 +18,7 @@ describe('Dynamic Form', function () { emailElement.sendKeys(email); expect(emailElement.getAttribute('value')).toEqual(email); - element(by.css('select option[value="solid"]')).click() + element(by.css('select option[value="solid"]')).click(); let saveButton = element.all(by.css('button')).get(0); saveButton.click().then(function(){ diff --git a/public/docs/_examples/cb-dynamic-form/ts/app/app.component.ts b/public/docs/_examples/cb-dynamic-form/ts/app/app.component.ts deleted file mode 100644 index 01a5401003..0000000000 --- a/public/docs/_examples/cb-dynamic-form/ts/app/app.component.ts +++ /dev/null @@ -1,24 +0,0 @@ -// #docregion -import { Component } from '@angular/core' - -import { DynamicForm } from './dynamic-form.component'; -import { QuestionService } from './question.service'; - -@Component({ - selector: 'my-app', - template: ` -
    -

    Job Application for Heroes

    - -
    - `, - directives: [DynamicForm], - providers: [QuestionService] -}) -export class AppComponent { - questions:any[] - - constructor(service: QuestionService) { - this.questions = service.getQuestions(); - } -} diff --git a/public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form-question.component.html b/public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form-question.component.html deleted file mode 100644 index ceb2f41177..0000000000 --- a/public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form-question.component.html +++ /dev/null @@ -1,17 +0,0 @@ - -
    - - -
    - - - - - -
    - -
    {{question.label}} is required
    -
    diff --git a/public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form-question.component.ts b/public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form-question.component.ts deleted file mode 100644 index d039931f61..0000000000 --- a/public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form-question.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -// #docregion -import { Component, Input } from '@angular/core'; -import { ControlGroup } from '@angular/common'; - -import { QuestionBase } from './question-base'; - -@Component({ - selector:'df-question', - templateUrl:'app/dynamic-form-question.component.html' -}) -export class DynamicFormQuestionComponent { - @Input() question:QuestionBase; - @Input() form:ControlGroup; - get isValid() { return this.form.controls[this.question.key].valid; } -} diff --git a/public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form.component.ts b/public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form.component.ts deleted file mode 100644 index 68aafc839b..0000000000 --- a/public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form.component.ts +++ /dev/null @@ -1,30 +0,0 @@ -// #docregion -import { Component, Input, OnInit } from '@angular/core'; -import { ControlGroup } from '@angular/common'; - -import { QuestionBase } from './question-base'; -import { QuestionControlService } from './question-control.service'; -import { DynamicFormQuestionComponent } from './dynamic-form-question.component'; - -@Component({ - selector:'dynamic-form', - templateUrl:'app/dynamic-form.component.html', - directives: [DynamicFormQuestionComponent], - providers: [QuestionControlService] -}) -export class DynamicForm { - - @Input() questions: QuestionBase[] = []; - form: ControlGroup; - payLoad = ''; - - constructor(private qcs: QuestionControlService) { } - - ngOnInit(){ - this.form = this.qcs.toControlGroup(this.questions); - } - - onSubmit() { - this.payLoad = JSON.stringify(this.form.value); - } -} diff --git a/public/docs/_examples/cb-dynamic-form/ts/app/main.ts b/public/docs/_examples/cb-dynamic-form/ts/app/main.ts deleted file mode 100644 index aca0a06056..0000000000 --- a/public/docs/_examples/cb-dynamic-form/ts/app/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent, []) - .catch((err:any) => console.error(err)); diff --git a/public/docs/_examples/cb-dynamic-form/ts/app/question-base.ts b/public/docs/_examples/cb-dynamic-form/ts/app/question-base.ts deleted file mode 100644 index c22de02989..0000000000 --- a/public/docs/_examples/cb-dynamic-form/ts/app/question-base.ts +++ /dev/null @@ -1,25 +0,0 @@ -// #docregion -export class QuestionBase{ - value:T; - key:string; - label:string; - required:boolean; - order:number; - controlType:string; - - constructor(options:{ - value?:T, - key?:string, - label?:string, - required?:boolean, - order?:number, - controlType?:string - } = {}){ - this.value = options.value; - this.key = options.key || ''; - this.label = options.label || ''; - this.required = !!options.required; - this.order = options.order === undefined ? 1 : options.order; - this.controlType = options.controlType || ''; - } -} diff --git a/public/docs/_examples/cb-dynamic-form/ts/app/question-control.service.ts b/public/docs/_examples/cb-dynamic-form/ts/app/question-control.service.ts deleted file mode 100644 index d4cf25951c..0000000000 --- a/public/docs/_examples/cb-dynamic-form/ts/app/question-control.service.ts +++ /dev/null @@ -1,18 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; -import { ControlGroup, FormBuilder, Validators } from '@angular/common'; -import { QuestionBase } from './question-base'; - -@Injectable() -export class QuestionControlService { - constructor(private fb:FormBuilder){ } - - toControlGroup(questions:QuestionBase[] ) { - let group = {}; - - questions.forEach(question => { - group[question.key] = question.required ? [question.value || '', Validators.required] : [question.value || '']; - }); - return this.fb.group(group); - } -} diff --git a/public/docs/_examples/cb-dynamic-form/ts/app/question-dropdown.ts b/public/docs/_examples/cb-dynamic-form/ts/app/question-dropdown.ts deleted file mode 100644 index 50b5d64a1d..0000000000 --- a/public/docs/_examples/cb-dynamic-form/ts/app/question-dropdown.ts +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -import { QuestionBase } from './question-base'; - -export class DropdownQuestion extends QuestionBase{ - controlType = 'dropdown'; - options:{key:string, value:string}[] = []; - - constructor(options:{} = {}){ - super(options); - this.options = options['options'] || []; - } -} diff --git a/public/docs/_examples/cb-dynamic-form/ts/app/question-textbox.ts b/public/docs/_examples/cb-dynamic-form/ts/app/question-textbox.ts deleted file mode 100644 index a1c9980de5..0000000000 --- a/public/docs/_examples/cb-dynamic-form/ts/app/question-textbox.ts +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -import { QuestionBase } from './question-base'; - -export class TextboxQuestion extends QuestionBase{ - controlType = 'textbox'; - type:string; - - constructor(options:{} = {}){ - super(options); - this.type = options['type'] || ''; - } -} diff --git a/public/docs/_examples/cb-dynamic-form/ts/app/question.service.ts b/public/docs/_examples/cb-dynamic-form/ts/app/question.service.ts deleted file mode 100644 index 52b4fc70ff..0000000000 --- a/public/docs/_examples/cb-dynamic-form/ts/app/question.service.ts +++ /dev/null @@ -1,48 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -import { QuestionBase } from './question-base'; -import { DynamicForm } from './dynamic-form.component'; -import { TextboxQuestion } from './question-textbox'; -import { DropdownQuestion } from './question-dropdown'; - -@Injectable() -export class QuestionService { - - // Todo: get from a remote source of question metadata - // Todo: make asynchronous - getQuestions() { - - let questions:QuestionBase[] = [ - - new DropdownQuestion({ - key:'brave', - label: 'Bravery Rating', - options: [ - {key:'solid', value:'Solid'}, - {key:'great', value:'Great'}, - {key:'good', value:'Good'}, - {key:'unproven',value:'Unproven'} - ], - order: 3 - }), - - new TextboxQuestion({ - key:'firstName', - label:'First name', - value:'Bombasto', - required: true, - order: 1 - }), - - new TextboxQuestion({ - key:'emailAddress', - label:'Email', - type: 'email', - order: 2 - }) - ]; - - return questions.sort((a,b) => a.order - b.order); - } -} diff --git a/public/docs/_examples/cb-dynamic-form/ts/index.html b/public/docs/_examples/cb-dynamic-form/ts/index.html deleted file mode 100644 index ec3e1cbbb2..0000000000 --- a/public/docs/_examples/cb-dynamic-form/ts/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - Dynamic Form - - - - - - - - - - - - - - - - - - Loading app... - - - diff --git a/public/docs/_examples/cb-dynamic-form/ts/plnkr.json b/public/docs/_examples/cb-dynamic-form/ts/plnkr.json index faa498f46f..1f50b4a992 100644 --- a/public/docs/_examples/cb-dynamic-form/ts/plnkr.json +++ b/public/docs/_examples/cb-dynamic-form/ts/plnkr.json @@ -1,7 +1,8 @@ { "description": "Dynamic Form", + "basePath": "src/", "files":[ - "!**/*.d.ts", + "!**/*.d.ts", "!**/*.js", "!**/*.[1].*" ], diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/app/app.component.ts b/public/docs/_examples/cb-dynamic-form/ts/src/app/app.component.ts new file mode 100644 index 0000000000..582daced2e --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/app/app.component.ts @@ -0,0 +1,22 @@ +// #docregion +import { Component } from '@angular/core'; + +import { QuestionService } from './question.service'; + +@Component({ + selector: 'my-app', + template: ` +
    +

    Job Application for Heroes

    + +
    + `, + providers: [QuestionService] +}) +export class AppComponent { + questions: any[]; + + constructor(service: QuestionService) { + this.questions = service.getQuestions(); + } +} diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/app/app.module.ts b/public/docs/_examples/cb-dynamic-form/ts/src/app/app.module.ts new file mode 100644 index 0000000000..7a68e45a92 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/app/app.module.ts @@ -0,0 +1,18 @@ +// #docregion +import { BrowserModule } from '@angular/platform-browser'; +import { ReactiveFormsModule } from '@angular/forms'; +import { NgModule } from '@angular/core'; + +import { AppComponent } from './app.component'; +import { DynamicFormComponent } from './dynamic-form.component'; +import { DynamicFormQuestionComponent } from './dynamic-form-question.component'; + +@NgModule({ + imports: [ BrowserModule, ReactiveFormsModule ], + declarations: [ AppComponent, DynamicFormComponent, DynamicFormQuestionComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { + constructor() { + } +} diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form-question.component.html b/public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form-question.component.html new file mode 100644 index 0000000000..9f1b8cd4a6 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form-question.component.html @@ -0,0 +1,17 @@ + +
    + + +
    + + + + + +
    + +
    {{question.label}} is required
    +
    diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form-question.component.ts b/public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form-question.component.ts new file mode 100644 index 0000000000..024571a7c2 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form-question.component.ts @@ -0,0 +1,15 @@ +// #docregion +import { Component, Input } from '@angular/core'; +import { FormGroup } from '@angular/forms'; + +import { QuestionBase } from './question-base'; + +@Component({ + selector: 'df-question', + templateUrl: './dynamic-form-question.component.html' +}) +export class DynamicFormQuestionComponent { + @Input() question: QuestionBase; + @Input() form: FormGroup; + get isValid() { return this.form.controls[this.question.key].valid; } +} diff --git a/public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form.component.html b/public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form.component.html similarity index 88% rename from public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form.component.html rename to public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form.component.html index e8f14612c9..717f09ff71 100644 --- a/public/docs/_examples/cb-dynamic-form/ts/app/dynamic-form.component.html +++ b/public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form.component.html @@ -1,6 +1,6 @@
    -
    +
    diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form.component.ts b/public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form.component.ts new file mode 100644 index 0000000000..8d95c0d3a4 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/app/dynamic-form.component.ts @@ -0,0 +1,28 @@ +// #docregion +import { Component, Input, OnInit } from '@angular/core'; +import { FormGroup } from '@angular/forms'; + +import { QuestionBase } from './question-base'; +import { QuestionControlService } from './question-control.service'; + +@Component({ + selector: 'dynamic-form', + templateUrl: './dynamic-form.component.html', + providers: [ QuestionControlService ] +}) +export class DynamicFormComponent implements OnInit { + + @Input() questions: QuestionBase[] = []; + form: FormGroup; + payLoad = ''; + + constructor(private qcs: QuestionControlService) { } + + ngOnInit() { + this.form = this.qcs.toFormGroup(this.questions); + } + + onSubmit() { + this.payLoad = JSON.stringify(this.form.value); + } +} diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/app/question-base.ts b/public/docs/_examples/cb-dynamic-form/ts/src/app/question-base.ts new file mode 100644 index 0000000000..2b32b00f2a --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/app/question-base.ts @@ -0,0 +1,25 @@ +// #docregion +export class QuestionBase{ + value: T; + key: string; + label: string; + required: boolean; + order: number; + controlType: string; + + constructor(options: { + value?: T, + key?: string, + label?: string, + required?: boolean, + order?: number, + controlType?: string + } = {}) { + this.value = options.value; + this.key = options.key || ''; + this.label = options.label || ''; + this.required = !!options.required; + this.order = options.order === undefined ? 1 : options.order; + this.controlType = options.controlType || ''; + } +} diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/app/question-control.service.ts b/public/docs/_examples/cb-dynamic-form/ts/src/app/question-control.service.ts new file mode 100644 index 0000000000..1378ba8490 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/app/question-control.service.ts @@ -0,0 +1,20 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; + +import { QuestionBase } from './question-base'; + +@Injectable() +export class QuestionControlService { + constructor() { } + + toFormGroup(questions: QuestionBase[] ) { + let group: any = {}; + + questions.forEach(question => { + group[question.key] = question.required ? new FormControl(question.value || '', Validators.required) + : new FormControl(question.value || ''); + }); + return new FormGroup(group); + } +} diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/app/question-dropdown.ts b/public/docs/_examples/cb-dynamic-form/ts/src/app/question-dropdown.ts new file mode 100644 index 0000000000..35a9074c74 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/app/question-dropdown.ts @@ -0,0 +1,12 @@ +// #docregion +import { QuestionBase } from './question-base'; + +export class DropdownQuestion extends QuestionBase { + controlType = 'dropdown'; + options: {key: string, value: string}[] = []; + + constructor(options: {} = {}) { + super(options); + this.options = options['options'] || []; + } +} diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/app/question-textbox.ts b/public/docs/_examples/cb-dynamic-form/ts/src/app/question-textbox.ts new file mode 100644 index 0000000000..aaa7edf267 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/app/question-textbox.ts @@ -0,0 +1,12 @@ +// #docregion +import { QuestionBase } from './question-base'; + +export class TextboxQuestion extends QuestionBase { + controlType = 'textbox'; + type: string; + + constructor(options: {} = {}) { + super(options); + this.type = options['type'] || ''; + } +} diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/app/question.service.ts b/public/docs/_examples/cb-dynamic-form/ts/src/app/question.service.ts new file mode 100644 index 0000000000..bb452cf5e6 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/app/question.service.ts @@ -0,0 +1,47 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { DropdownQuestion } from './question-dropdown'; +import { QuestionBase } from './question-base'; +import { TextboxQuestion } from './question-textbox'; + +@Injectable() +export class QuestionService { + + // Todo: get from a remote source of question metadata + // Todo: make asynchronous + getQuestions() { + + let questions: QuestionBase[] = [ + + new DropdownQuestion({ + key: 'brave', + label: 'Bravery Rating', + options: [ + {key: 'solid', value: 'Solid'}, + {key: 'great', value: 'Great'}, + {key: 'good', value: 'Good'}, + {key: 'unproven', value: 'Unproven'} + ], + order: 3 + }), + + new TextboxQuestion({ + key: 'firstName', + label: 'First name', + value: 'Bombasto', + required: true, + order: 1 + }), + + new TextboxQuestion({ + key: 'emailAddress', + label: 'Email', + type: 'email', + order: 2 + }) + ]; + + return questions.sort((a, b) => a.order - b.order); + } +} diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/index.html b/public/docs/_examples/cb-dynamic-form/ts/src/index.html new file mode 100644 index 0000000000..01963f71e2 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/index.html @@ -0,0 +1,28 @@ + + + + + + Dynamic Form + + + + + + + + + + + + + + + + + Loading app... + + + diff --git a/public/docs/_examples/cb-dynamic-form/ts/src/main.ts b/public/docs/_examples/cb-dynamic-form/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/cb-dynamic-form/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-dynamic-form/ts/sample.css b/public/docs/_examples/cb-dynamic-form/ts/src/sample.css similarity index 100% rename from public/docs/_examples/cb-dynamic-form/ts/sample.css rename to public/docs/_examples/cb-dynamic-form/ts/src/sample.css diff --git a/public/docs/_examples/cb-form-validation/e2e-spec.ts b/public/docs/_examples/cb-form-validation/e2e-spec.ts new file mode 100644 index 0000000000..8ffc01e250 --- /dev/null +++ b/public/docs/_examples/cb-form-validation/e2e-spec.ts @@ -0,0 +1,182 @@ +'use strict'; // necessary for node! + +import { browser, element, by, protractor, ElementFinder, ElementArrayFinder } from 'protractor'; +import { appLang, describeIf } from '../protractor-helpers'; + +// THESE TESTS ARE INCOMPLETE +describeIf(appLang.appIsTs || appLang.appIsJs, 'Form Validation Tests', function () { + + beforeAll(function () { + browser.get(''); + }); + + describe('Hero Form 1', () => { + beforeAll(() => { + getPage('hero-form-template1'); + }); + + tests(); + }); + + describe('Hero Form 2', () => { + beforeAll(() => { + getPage('hero-form-template2'); + }); + + tests(); + bobTests(); + }); + + describe('Hero Form 3 (Reactive)', () => { + beforeAll(() => { + getPage('hero-form-reactive3'); + makeNameTooLong(); + }); + + tests(); + bobTests(); + }); +}); + +////////// + +const testName = 'Test Name'; + +let page: { + section: ElementFinder, + form: ElementFinder, + title: ElementFinder, + nameInput: ElementFinder, + alterEgoInput: ElementFinder, + powerSelect: ElementFinder, + errorMessages: ElementArrayFinder, + heroFormButtons: ElementArrayFinder, + heroSubmitted: ElementFinder +}; + +function getPage(sectionTag: string) { + let section = element(by.css(sectionTag)); + let buttons = section.all(by.css('button')); + + page = { + section: section, + form: section.element(by.css('form')), + title: section.element(by.css('h1')), + nameInput: section.element(by.css('#name')), + alterEgoInput: section.element(by.css('#alterEgo')), + powerSelect: section.element(by.css('#power')), + errorMessages: section.all(by.css('div.alert')), + heroFormButtons: buttons, + heroSubmitted: section.element(by.css('hero-submitted > div')) + }; +} + +function tests() { + it('should display correct title', function () { + expect(page.title.getText()).toContain('Hero Form'); + }); + + it('should not display submitted message before submit', function () { + expect(page.heroSubmitted.isElementPresent(by.css('h2'))).toBe(false); + }); + + it('should have form buttons', function () { + expect(page.heroFormButtons.count()).toEqual(2); + }); + + it('should have error at start', function () { + expectFormIsInvalid(); + }); + + // it('showForm', function () { + // page.form.getInnerHtml().then(html => console.log(html)); + // }); + + it('should have disabled submit button', function () { + expect(page.heroFormButtons.get(0).isEnabled()).toBe(false); + }); + + it('resetting name to valid name should clear errors', function () { + const ele = page.nameInput; + expect(ele.isPresent()).toBe(true, 'nameInput should exist'); + ele.clear(); + ele.sendKeys(testName); + expectFormIsValid(); + }); + + it('should produce "required" error after clearing name', function () { + page.nameInput.clear(); + // page.alterEgoInput.click(); // to blur ... didn't work + page.nameInput.sendKeys('x', protractor.Key.BACK_SPACE); // ugh! + expect(page.form.getAttribute('class')).toMatch('ng-invalid'); + expect(page.errorMessages.get(0).getText()).toContain('required'); + }); + + it('should produce "at least 4 characters" error when name="x"', function () { + page.nameInput.clear(); + page.nameInput.sendKeys('x'); // too short + expectFormIsInvalid(); + expect(page.errorMessages.get(0).getText()).toContain('at least 4 characters'); + }); + + it('resetting name to valid name again should clear errors', function () { + page.nameInput.sendKeys(testName); + expectFormIsValid(); + }); + + it('should have enabled submit button', function () { + const submitBtn = page.heroFormButtons.get(0); + expect(submitBtn.isEnabled()).toBe(true); + }); + + it('should hide form after submit', function () { + page.heroFormButtons.get(0).click(); + expect(page.title.isDisplayed()).toBe(false); + }); + + it('submitted form should be displayed', function () { + expect(page.heroSubmitted.isElementPresent(by.css('h2'))).toBe(true); + }); + + it('submitted form should have new hero name', function () { + expect(page.heroSubmitted.getText()).toContain(testName); + }); + + it('clicking edit button should reveal form again', function () { + const editBtn = page.heroSubmitted.element(by.css('button')); + editBtn.click(); + expect(page.heroSubmitted.isElementPresent(by.css('h2'))) + .toBe(false, 'submitted hidden again'); + expect(page.title.isDisplayed()).toBe(true, 'can see form title'); + }); +} + +function expectFormIsValid() { + expect(page.form.getAttribute('class')).toMatch('ng-valid'); +} + +function expectFormIsInvalid() { + expect(page.form.getAttribute('class')).toMatch('ng-invalid'); +} + +function bobTests() { + const emsg = 'Someone named "Bob" cannot be a hero.'; + + it('should produce "no bob" error after setting name to "Bobby"', function () { + page.nameInput.clear(); + page.nameInput.sendKeys('Bobby'); + expectFormIsInvalid(); + expect(page.errorMessages.get(0).getText()).toBe(emsg); + }); + + it('should be ok again with valid name', function () { + page.nameInput.clear(); + page.nameInput.sendKeys(testName); + expectFormIsValid(); + }); +} + +function makeNameTooLong() { + // make the first name invalid + page.nameInput.sendKeys('ThisHeroNameHasWayWayTooManyLetters'); +} diff --git a/public/docs/_examples/dependency-injection/dart/example-config.json b/public/docs/_examples/cb-form-validation/ts/example-config.json similarity index 100% rename from public/docs/_examples/dependency-injection/dart/example-config.json rename to public/docs/_examples/cb-form-validation/ts/example-config.json diff --git a/public/docs/_examples/cb-form-validation/ts/plnkr.json b/public/docs/_examples/cb-form-validation/ts/plnkr.json new file mode 100644 index 0000000000..c5656d77f7 --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/plnkr.json @@ -0,0 +1,8 @@ +{ + "description": "Validation", + "basePath": "src/", + "files":[ + "!**/*.d.ts", + "!**/*.js" + ] +} diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/app.component.ts b/public/docs/_examples/cb-form-validation/ts/src/app/app.component.ts new file mode 100644 index 0000000000..2da4dc4d0a --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/app.component.ts @@ -0,0 +1,12 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` +
    + +
    + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/app.module.ts b/public/docs/_examples/cb-form-validation/ts/src/app/app.module.ts new file mode 100644 index 0000000000..72b4e3a770 --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/app.module.ts @@ -0,0 +1,18 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { HeroFormTemplateModule } from './template/hero-form-template.module'; +import { HeroFormReactiveModule } from './reactive/hero-form-reactive.module'; + +@NgModule({ + imports: [ + BrowserModule, + HeroFormTemplateModule, + HeroFormReactiveModule + ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/reactive/hero-form-reactive.component.html b/public/docs/_examples/cb-form-validation/ts/src/app/reactive/hero-form-reactive.component.html new file mode 100644 index 0000000000..149537bd3e --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/reactive/hero-form-reactive.component.html @@ -0,0 +1,47 @@ + +
    +
    +

    Hero Form 3 (Reactive)

    + + + +
    + + + + + +
    + {{ formErrors.name }} +
    + +
    + +
    + + +
    + +
    + + + +
    + {{ formErrors.power }} +
    +
    + + + + +
    + + +
    diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/reactive/hero-form-reactive.component.ts b/public/docs/_examples/cb-form-validation/ts/src/app/reactive/hero-form-reactive.component.ts new file mode 100644 index 0000000000..241ff1e782 --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/reactive/hero-form-reactive.component.ts @@ -0,0 +1,116 @@ +/* tslint:disable: member-ordering forin */ +// #docplaster +// #docregion +import { Component, OnInit } from '@angular/core'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; + +import { Hero } from '../shared/hero'; +import { forbiddenNameValidator } from '../shared/forbidden-name.directive'; + +@Component({ + selector: 'hero-form-reactive3', + templateUrl: './hero-form-reactive.component.html' +}) +export class HeroFormReactiveComponent implements OnInit { + + powers = ['Really Smart', 'Super Flexible', 'Weather Changer']; + + hero = new Hero(18, 'Dr. WhatIsHisName', this.powers[0], 'Dr. What'); + + submitted = false; + + // #docregion on-submit + onSubmit() { + this.submitted = true; + this.hero = this.heroForm.value; + } + // #enddocregion on-submit +// #enddocregion + + // Reset the form with a new hero AND restore 'pristine' class state + // by toggling 'active' flag which causes the form + // to be removed/re-added in a tick via NgIf + // TODO: Workaround until NgForm has a reset method (#6822) + active = true; +// #docregion class + // #docregion add-hero + addHero() { + this.hero = new Hero(42, '', ''); + this.buildForm(); + // #enddocregion add-hero +// #enddocregion class + + this.active = false; + setTimeout(() => this.active = true, 0); +// #docregion + // #docregion add-hero + } + // #enddocregion add-hero + + // #docregion form-builder + heroForm: FormGroup; + constructor(private fb: FormBuilder) { } + + ngOnInit(): void { + this.buildForm(); + } + + buildForm(): void { + this.heroForm = this.fb.group({ + // #docregion name-validators + 'name': [this.hero.name, [ + Validators.required, + Validators.minLength(4), + Validators.maxLength(24), + forbiddenNameValidator(/bob/i) + ] + ], + // #enddocregion name-validators + 'alterEgo': [this.hero.alterEgo], + 'power': [this.hero.power, Validators.required] + }); + + this.heroForm.valueChanges + .subscribe(data => this.onValueChanged(data)); + + this.onValueChanged(); // (re)set validation messages now + } + + // #enddocregion form-builder + + onValueChanged(data?: any) { + if (!this.heroForm) { return; } + const form = this.heroForm; + + for (const field in this.formErrors) { + // clear previous error message (if any) + this.formErrors[field] = ''; + const control = form.get(field); + + if (control && control.dirty && !control.valid) { + const messages = this.validationMessages[field]; + for (const key in control.errors) { + this.formErrors[field] += messages[key] + ' '; + } + } + } + } + + formErrors = { + 'name': '', + 'power': '' + }; + + validationMessages = { + 'name': { + 'required': 'Name is required.', + 'minlength': 'Name must be at least 4 characters long.', + 'maxlength': 'Name cannot be more than 24 characters long.', + 'forbiddenName': 'Someone named "Bob" cannot be a hero.' + }, + 'power': { + 'required': 'Power is required.' + } + }; +} +// #enddocregion diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/reactive/hero-form-reactive.module.ts b/public/docs/_examples/cb-form-validation/ts/src/app/reactive/hero-form-reactive.module.ts new file mode 100644 index 0000000000..6ff9265e92 --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/reactive/hero-form-reactive.module.ts @@ -0,0 +1,13 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; + +import { SharedModule } from '../shared/shared.module'; +import { HeroFormReactiveComponent } from './hero-form-reactive.component'; + +@NgModule({ + imports: [ SharedModule, ReactiveFormsModule ], + declarations: [ HeroFormReactiveComponent ], + exports: [ HeroFormReactiveComponent ] +}) +export class HeroFormReactiveModule { } diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/shared/forbidden-name.directive.ts b/public/docs/_examples/cb-form-validation/ts/src/app/shared/forbidden-name.directive.ts new file mode 100644 index 0000000000..870f514842 --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/shared/forbidden-name.directive.ts @@ -0,0 +1,43 @@ +// #docregion +import { Directive, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { AbstractControl, NG_VALIDATORS, Validator, ValidatorFn, Validators } from '@angular/forms'; + +// #docregion custom-validator +/** A hero's name can't match the given regular expression */ +export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn { + return (control: AbstractControl): {[key: string]: any} => { + const name = control.value; + const no = nameRe.test(name); + return no ? {'forbiddenName': {name}} : null; + }; +} +// #enddocregion custom-validator + +// #docregion directive +@Directive({ + selector: '[forbiddenName]', + // #docregion directive-providers + providers: [{provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true}] + // #enddocregion directive-providers +}) +export class ForbiddenValidatorDirective implements Validator, OnChanges { + @Input() forbiddenName: string; + private valFn = Validators.nullValidator; + + ngOnChanges(changes: SimpleChanges): void { + const change = changes['forbiddenName']; + if (change) { + const val: string | RegExp = change.currentValue; + const re = val instanceof RegExp ? val : new RegExp(val, 'i'); + this.valFn = forbiddenNameValidator(re); + } else { + this.valFn = Validators.nullValidator; + } + } + + validate(control: AbstractControl): {[key: string]: any} { + return this.valFn(control); + } +} +// #enddocregion directive + diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/shared/hero.ts b/public/docs/_examples/cb-form-validation/ts/src/app/shared/hero.ts new file mode 100644 index 0000000000..fe2b55e51a --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/shared/hero.ts @@ -0,0 +1,9 @@ +// #docregion +export class Hero { + constructor( + public id: number, + public name: string, + public power: string, + public alterEgo?: string + ) { } +} diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/shared/shared.module.ts b/public/docs/_examples/cb-form-validation/ts/src/app/shared/shared.module.ts new file mode 100644 index 0000000000..2b0ada59bd --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/shared/shared.module.ts @@ -0,0 +1,14 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { ForbiddenValidatorDirective } from './forbidden-name.directive'; +import { SubmittedComponent } from './submitted.component'; + +@NgModule({ + imports: [ CommonModule], + declarations: [ ForbiddenValidatorDirective, SubmittedComponent ], + exports: [ ForbiddenValidatorDirective, SubmittedComponent, + CommonModule ] +}) +export class SharedModule { } diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/shared/submitted.component.ts b/public/docs/_examples/cb-form-validation/ts/src/app/shared/submitted.component.ts new file mode 100644 index 0000000000..18cea6563f --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/shared/submitted.component.ts @@ -0,0 +1,32 @@ +// #docregion +import { Component, EventEmitter, Input, Output } from '@angular/core'; + +import { Hero } from './hero'; + +@Component({ + selector: 'hero-submitted', + template: ` +
    +

    You submitted the following:

    +
    +
    Name
    +
    {{ hero.name }}
    +
    +
    +
    Alter Ego
    +
    {{ hero.alterEgo }}
    +
    +
    +
    Power
    +
    {{ hero.power }}
    +
    +
    + +
    ` +}) +export class SubmittedComponent { + @Input() hero: Hero; + @Input() submitted = false; + @Output() submittedChange = new EventEmitter(); + onClick() { this.submittedChange.emit(false); } +} diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template.module.ts b/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template.module.ts new file mode 100644 index 0000000000..042c019d5e --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template.module.ts @@ -0,0 +1,14 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +import { SharedModule } from '../shared/shared.module'; +import { HeroFormTemplate1Component } from './hero-form-template1.component'; +import { HeroFormTemplate2Component } from './hero-form-template2.component'; + +@NgModule({ + imports: [ SharedModule, FormsModule ], + declarations: [ HeroFormTemplate1Component, HeroFormTemplate2Component ], + exports: [ HeroFormTemplate1Component, HeroFormTemplate2Component ] +}) +export class HeroFormTemplateModule { } diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template1.component.html b/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template1.component.html new file mode 100644 index 0000000000..22b374b622 --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template1.component.html @@ -0,0 +1,61 @@ + +
    +
    +

    Hero Form 1 (Template)

    + +
    + +
    + + + + + +
    +
    + Name is required +
    +
    + Name must be at least 4 characters long. +
    +
    + Name cannot be more than 24 characters long. +
    +
    + +
    + +
    + + +
    + +
    + + + +
    +
    Power is required
    +
    +
    + + + +
    +
    + + +
    diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template1.component.ts b/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template1.component.ts new file mode 100644 index 0000000000..1bc29db44d --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template1.component.ts @@ -0,0 +1,47 @@ +/* tslint:disable: member-ordering */ +// #docplaster +// #docregion +import { Component } from '@angular/core'; + + +import { Hero } from '../shared/hero'; + +@Component({ + selector: 'hero-form-template1', + templateUrl: './hero-form-template1.component.html' +}) +// #docregion class +export class HeroFormTemplate1Component { + + powers = ['Really Smart', 'Super Flexible', 'Weather Changer']; + + hero = new Hero(18, 'Dr. WhatIsHisWayTooLongName', this.powers[0], 'Dr. What'); + + submitted = false; + + onSubmit() { + this.submitted = true; + } +// #enddocregion class +// #enddocregion + // Reset the form with a new hero AND restore 'pristine' class state + // by toggling 'active' flag which causes the form + // to be removed/re-added in a tick via NgIf + // TODO: Workaround until NgForm has a reset method (#6822) + active = true; +// #docregion +// #docregion class + + addHero() { + this.hero = new Hero(42, '', ''); +// #enddocregion class +// #enddocregion + + this.active = false; + setTimeout(() => this.active = true, 0); +// #docregion +// #docregion class + } +} +// #enddocregion class +// #enddocregion diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template2.component.html b/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template2.component.html new file mode 100644 index 0000000000..8bb7066541 --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template2.component.html @@ -0,0 +1,52 @@ + +
    +
    +

    Hero Form 2 (Template & Messages)

    + +
    + +
    + + + + + + + +
    + {{ formErrors.name }} +
    + +
    + +
    + + +
    + +
    + + + +
    + {{ formErrors.power }} +
    +
    + + + +
    +
    + + +
    diff --git a/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template2.component.ts b/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template2.component.ts new file mode 100644 index 0000000000..320ef09efd --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/app/template/hero-form-template2.component.ts @@ -0,0 +1,99 @@ +/* tslint:disable: member-ordering forin */ +// #docplaster +// #docregion +import { Component, AfterViewChecked, ViewChild } from '@angular/core'; +import { NgForm } from '@angular/forms'; + +import { Hero } from '../shared/hero'; + +@Component({ + selector: 'hero-form-template2', + templateUrl: './hero-form-template2.component.html' +}) +export class HeroFormTemplate2Component implements AfterViewChecked { + + powers = ['Really Smart', 'Super Flexible', 'Weather Changer']; + + hero = new Hero(18, 'Dr. WhatIsHisWayTooLongName', this.powers[0], 'Dr. What'); + + submitted = false; + + onSubmit() { + this.submitted = true; + } +// #enddocregion + + // Reset the form with a new hero AND restore 'pristine' class state + // by toggling 'active' flag which causes the form + // to be removed/re-added in a tick via NgIf + // TODO: Workaround until NgForm has a reset method (#6822) + active = true; +// #docregion + + addHero() { + this.hero = new Hero(42, '', ''); +// #enddocregion + + this.active = false; + setTimeout(() => this.active = true, 0); +// #docregion + } + + // #docregion view-child + heroForm: NgForm; + @ViewChild('heroForm') currentForm: NgForm; + + ngAfterViewChecked() { + this.formChanged(); + } + + formChanged() { + if (this.currentForm === this.heroForm) { return; } + this.heroForm = this.currentForm; + if (this.heroForm) { + this.heroForm.valueChanges + .subscribe(data => this.onValueChanged(data)); + } + } + // #enddocregion view-child + + // #docregion handler + onValueChanged(data?: any) { + if (!this.heroForm) { return; } + const form = this.heroForm.form; + + for (const field in this.formErrors) { + // clear previous error message (if any) + this.formErrors[field] = ''; + const control = form.get(field); + + if (control && control.dirty && !control.valid) { + const messages = this.validationMessages[field]; + for (const key in control.errors) { + this.formErrors[field] += messages[key] + ' '; + } + } + } + } + + formErrors = { + 'name': '', + 'power': '' + }; + // #enddocregion handler + + // #docregion messages + validationMessages = { + 'name': { + 'required': 'Name is required.', + 'minlength': 'Name must be at least 4 characters long.', + 'maxlength': 'Name cannot be more than 24 characters long.', + 'forbiddenName': 'Someone named "Bob" cannot be a hero.' + }, + 'power': { + 'required': 'Power is required.' + } + }; + // #enddocregion messages +} +// #enddocregion diff --git a/public/docs/_examples/cb-form-validation/ts/src/forms.css b/public/docs/_examples/cb-form-validation/ts/src/forms.css new file mode 100644 index 0000000000..67ad13037b --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/forms.css @@ -0,0 +1,7 @@ +.ng-valid[required], .ng-valid.required { + border-left: 5px solid #42A948; /* green */ +} + +.ng-invalid:not(form) { + border-left: 5px solid #a94442; /* red */ +} diff --git a/public/docs/_examples/cb-form-validation/ts/src/index.html b/public/docs/_examples/cb-form-validation/ts/src/index.html new file mode 100644 index 0000000000..e7201508d7 --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/index.html @@ -0,0 +1,29 @@ + + + Hero Form with Validation + + + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/cb-form-validation/ts/src/main.ts b/public/docs/_examples/cb-form-validation/ts/src/main.ts new file mode 100644 index 0000000000..f332d1d245 --- /dev/null +++ b/public/docs/_examples/cb-form-validation/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-i18n/e2e-spec.ts b/public/docs/_examples/cb-i18n/e2e-spec.ts new file mode 100644 index 0000000000..3dcca5a670 --- /dev/null +++ b/public/docs/_examples/cb-i18n/e2e-spec.ts @@ -0,0 +1,33 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + +describe('i18n E2E Tests', () => { + + beforeEach(function () { + browser.get(''); + }); + + it('should display i18n translated welcome: ¡Hola i18n!', function () { + expect(element(by.css('h1')).getText()).toEqual('¡Hola i18n!'); + }); + + it('should display the node texts without elements', function () { + expect(element(by.css('my-app')).getText()).toContain('No genero ningún elemento'); + expect(element(by.css('my-app')).getText()).toContain('Yo tampoco genero ningún elemento'); + }); + + it('should display the translated title attribute', function () { + const title = element(by.css('img')).getAttribute('title'); + expect(title).toBe('Logo de Angular'); + }); + + it('should display the plural of: a horde of wolves', function () { + expect(element.all(by.css('span')).get(0).getText()).toBe('ningún lobo'); + }); + + it('should display the select of gender', function () { + expect(element.all(by.css('span')).get(1).getText()).toBe('El heroe es mujer'); + }); + +}); diff --git a/public/docs/_examples/cb-i18n/ts/.gitignore b/public/docs/_examples/cb-i18n/ts/.gitignore new file mode 100644 index 0000000000..d38bb50aa9 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/.gitignore @@ -0,0 +1,6 @@ +**/*.ngfactory.ts +**/*.metadata.json +dist +!app/tsconfig.json +!rollup.js +!src/systemjs-text-plugin.js diff --git a/public/docs/_examples/displaying-data/dart/example-config.json b/public/docs/_examples/cb-i18n/ts/example-config.json similarity index 100% rename from public/docs/_examples/displaying-data/dart/example-config.json rename to public/docs/_examples/cb-i18n/ts/example-config.json diff --git a/public/docs/_examples/cb-i18n/ts/messages.xlf b/public/docs/_examples/cb-i18n/ts/messages.xlf new file mode 100644 index 0000000000..dee8b65aca --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/messages.xlf @@ -0,0 +1,47 @@ + + + + + + Hello i18n! + + An introduction header for this sample + User welcome + + + I don't output any element + + + + +I don't output any element either + + + optional description + optional meaning + + + Angular logo + + + + + + + + + + + + + + The hero is + + + + + + + + + diff --git a/public/docs/_examples/cb-i18n/ts/plnkr.json b/public/docs/_examples/cb-i18n/ts/plnkr.json new file mode 100644 index 0000000000..36f2685129 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/plnkr.json @@ -0,0 +1,19 @@ +{ + "description": "i18n", + "basePath": "src/", + "files": [ + "app/**/*.css", + "app/**/*.html", + "app/**/*.ts", + "messages.xlf", + "locale/messages.*.xlf", + + "!**/*.[1].*", + + "main.ts", + "styles.css", + "systemjs-text-plugin.js", + "index.html" + ], + "tags": ["i18n"] +} diff --git a/public/docs/_examples/cb-i18n/ts/src/app/app.component.1.html b/public/docs/_examples/cb-i18n/ts/src/app/app.component.1.html new file mode 100644 index 0000000000..cc7d4f1155 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/src/app/app.component.1.html @@ -0,0 +1,15 @@ + +

    Hello i18n!

    + + + +

    Hello i18n!

    + + + +

    Hello i18n!

    + + + + + diff --git a/public/docs/_examples/cb-i18n/ts/src/app/app.component.html b/public/docs/_examples/cb-i18n/ts/src/app/app.component.html new file mode 100644 index 0000000000..39ace24f79 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/src/app/app.component.html @@ -0,0 +1,34 @@ + + +

    Hello i18n!

    + + + +I don't output any element + + +
    + + + +I don't output any element either + + + +
    + + + + +
    + + +{wolves, plural, =0 {no wolves} =1 {one wolf} =2 {two wolves} other {a wolf pack}} + +({{wolves}}) +

    + + +The hero is {gender, select, m {male} f {female}} + +
    diff --git a/public/docs/_examples/cb-i18n/ts/src/app/app.component.ts b/public/docs/_examples/cb-i18n/ts/src/app/app.component.ts new file mode 100644 index 0000000000..09b8722e9b --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/src/app/app.component.ts @@ -0,0 +1,19 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html' +}) +export class AppComponent { + wolves = 0; + gender = 'f'; + fly = true; + logo = 'https://angular.io/resources/images/logos/angular/angular.png'; + inc(i: number) { + this.wolves = Math.min(5, Math.max(0, this.wolves + i)); + } + male() { this.gender = 'm'; } + female() { this.gender = 'f'; } +} + diff --git a/public/docs/_examples/cb-i18n/ts/src/app/app.module.ts b/public/docs/_examples/cb-i18n/ts/src/app/app.module.ts new file mode 100644 index 0000000000..64ad44075b --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/src/app/app.module.ts @@ -0,0 +1,13 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) + +export class AppModule { } diff --git a/public/docs/_examples/cb-i18n/ts/src/app/i18n-providers.ts b/public/docs/_examples/cb-i18n/ts/src/app/i18n-providers.ts new file mode 100644 index 0000000000..f0bb662dc3 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/src/app/i18n-providers.ts @@ -0,0 +1,33 @@ +// #docregion +import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID } from '@angular/core'; + +export function getTranslationProviders(): Promise { + + // Get the locale id from the global + const locale = document['locale'] as string; + + // return no providers if fail to get translation file for locale + const noProviders: Object[] = []; + + // No locale or U.S. English: no translation providers + if (!locale || locale === 'en-US') { + return Promise.resolve(noProviders); + } + + // Ex: 'locale/messages.es.xlf` + const translationFile = `./locale/messages.${locale}.xlf`; + + return getTranslationsWithSystemJs(translationFile) + .then( (translations: string ) => [ + { provide: TRANSLATIONS, useValue: translations }, + { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }, + { provide: LOCALE_ID, useValue: locale } + ]) + .catch(() => noProviders); // ignore if file not found +} + +declare var System: any; + +function getTranslationsWithSystemJs(file: string) { + return System.import(file + '!text'); // relies on text plugin +} diff --git a/public/docs/_examples/cb-i18n/ts/src/index.html b/public/docs/_examples/cb-i18n/ts/src/index.html new file mode 100644 index 0000000000..ce90cd24c4 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/src/index.html @@ -0,0 +1,39 @@ + + + + + Angular i18n example + + + + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/cb-i18n/ts/src/locale/messages.es.xlf b/public/docs/_examples/cb-i18n/ts/src/locale/messages.es.xlf new file mode 100644 index 0000000000..7b813c38dd --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/src/locale/messages.es.xlf @@ -0,0 +1,41 @@ + + + + + + Hello i18n! + ¡Hola i18n! + An introduction header for this sample + User welcome + + + I don't output any element + No genero ningún elemento + + + +I don't output any element either + + Yo tampoco genero ningún elemento + optional description + optional meaning + + + Angular logo + Logo de Angular + + + + {wolves, plural, =0 {ningún lobo} =1 {un lobo} =2 {dos lobos} other {una horda de lobos}} + + + The hero is + El heroe es + + + + {gender, select, m {hombre} f {mujer}} + + + + diff --git a/public/docs/_examples/cb-i18n/ts/src/locale/messages.es.xlf.html b/public/docs/_examples/cb-i18n/ts/src/locale/messages.es.xlf.html new file mode 100644 index 0000000000..a6cdccc6c1 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/src/locale/messages.es.xlf.html @@ -0,0 +1,54 @@ + + + + + + + + + Hello i18n! + ¡Hola i18n! + An introduction header for this sample + User welcome + + + + + I don't output any element + No genero ningún elemento + + + I don't output any element either + Yo tampoco genero ningún elemento + optional description + optional meaning + + + Angular logo + Logo de Angular + + + + + + {wolves, plural, =0 {ningún lobo} =1 {un lobo} =2 {dos lobos} other {una horda de lobos}} + + + + + + The hero is + El heroe es + + + + + + {gender, select, m {hombre} f {mujer}} + + + + + + + diff --git a/public/docs/_examples/cb-i18n/ts/src/main.1.ts b/public/docs/_examples/cb-i18n/ts/src/main.1.ts new file mode 100644 index 0000000000..f332d1d245 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/src/main.1.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-i18n/ts/src/main.ts b/public/docs/_examples/cb-i18n/ts/src/main.ts new file mode 100644 index 0000000000..894cecfb10 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/src/main.ts @@ -0,0 +1,10 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { getTranslationProviders } from './app/i18n-providers'; + +import { AppModule } from './app/app.module'; + +getTranslationProviders().then(providers => { + const options = { providers }; + platformBrowserDynamic().bootstrapModule(AppModule, options); +}); diff --git a/public/docs/_examples/cb-i18n/ts/src/systemjs-text-plugin.js b/public/docs/_examples/cb-i18n/ts/src/systemjs-text-plugin.js new file mode 100644 index 0000000000..d5ca508fe0 --- /dev/null +++ b/public/docs/_examples/cb-i18n/ts/src/systemjs-text-plugin.js @@ -0,0 +1,14 @@ +// #docregion +/* + SystemJS Text plugin from + https://github.com/systemjs/plugin-text/blob/master/text.js +*/ +exports.translate = function(load) { + if (this.builder && this.transpiler) { + load.metadata.format = 'esm'; + return 'exp' + 'ort var __useDefault = true; exp' + 'ort default ' + JSON.stringify(load.source) + ';'; + } + + load.metadata.format = 'amd'; + return 'def' + 'ine(function() {\nreturn ' + JSON.stringify(load.source) + ';\n});'; +} diff --git a/public/docs/_examples/cb-set-document-title/e2e-spec.ts b/public/docs/_examples/cb-set-document-title/e2e-spec.ts index 9029c164e0..801b732995 100644 --- a/public/docs/_examples/cb-set-document-title/e2e-spec.ts +++ b/public/docs/_examples/cb-set-document-title/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by, ElementFinder } from 'protractor'; + // gulp run-e2e-tests --filter=cb-set-document-title describe('Set Document Title', function () { @@ -15,7 +18,7 @@ describe('Set Document Title', function () { ]; element.all( by.css( 'ul li a' ) ).each( - function iterator( element, i ) { + function iterator( element: ElementFinder, i: number ) { element.click(); expect( browser.getTitle() ).toEqual( titles[ i ] ); diff --git a/public/docs/_examples/cb-set-document-title/ts/app/main.ts b/public/docs/_examples/cb-set-document-title/ts/app/main.ts deleted file mode 100644 index c5134d3214..0000000000 --- a/public/docs/_examples/cb-set-document-title/ts/app/main.ts +++ /dev/null @@ -1,21 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -// While Angular supplies a Title service for setting the HTML document title -// it doesn't include this service as part of the default Browser platform providers. -// As such, if we want to inject it into the components within our application, -// we have to explicitly provide the Angular service in our top component. -// #docregion bootstrap-title -import { Title } from '@angular/platform-browser'; - -bootstrap(AppComponent, [ Title ]) -// #enddocregion bootstrap-title - .then( - () => window.console.info( 'Angular finished bootstrapping your application!' ), - (error) => { - console.warn( 'Angular was not able to bootstrap your application.' ); - console.error( error ); - } - ); diff --git a/public/docs/_examples/cb-set-document-title/ts/index.html b/public/docs/_examples/cb-set-document-title/ts/index.html deleted file mode 100644 index 8f1ad96812..0000000000 --- a/public/docs/_examples/cb-set-document-title/ts/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - Setting The Document Title Using The Title Service - - - - - - - - - - - - - - - - - - - -

    - Setting The Document Title Using The Title Service -

    - - Loading app... - - - diff --git a/public/docs/_examples/cb-set-document-title/ts/plnkr.json b/public/docs/_examples/cb-set-document-title/ts/plnkr.json index 0131610c20..020d5a1db2 100644 --- a/public/docs/_examples/cb-set-document-title/ts/plnkr.json +++ b/public/docs/_examples/cb-set-document-title/ts/plnkr.json @@ -1,7 +1,8 @@ { - "description": "Set The Document Title In Angular 2", + "description": "Set The Document Title In Angular", + "basePath": "src/", "files": [ - "!**/*.d.ts", + "!**/*.d.ts", "!**/*.js", "!**/*.[1].*" ], diff --git a/public/docs/_examples/cb-set-document-title/ts/sample.css b/public/docs/_examples/cb-set-document-title/ts/sample.css deleted file mode 100644 index 13acd31061..0000000000 --- a/public/docs/_examples/cb-set-document-title/ts/sample.css +++ /dev/null @@ -1,4 +0,0 @@ -a { - color: #607D8B ; - text-decoration: underline ; -} diff --git a/public/docs/_examples/cb-set-document-title/ts/app/app.component.ts b/public/docs/_examples/cb-set-document-title/ts/src/app/app.component.ts similarity index 100% rename from public/docs/_examples/cb-set-document-title/ts/app/app.component.ts rename to public/docs/_examples/cb-set-document-title/ts/src/app/app.component.ts diff --git a/public/docs/_examples/cb-set-document-title/ts/src/app/app.module.ts b/public/docs/_examples/cb-set-document-title/ts/src/app/app.module.ts new file mode 100644 index 0000000000..81f13c244c --- /dev/null +++ b/public/docs/_examples/cb-set-document-title/ts/src/app/app.module.ts @@ -0,0 +1,19 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule, Title } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule + ], + declarations: [ + AppComponent + ], + providers: [ + Title + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/cb-set-document-title/ts/src/index.html b/public/docs/_examples/cb-set-document-title/ts/src/index.html new file mode 100644 index 0000000000..6b00948530 --- /dev/null +++ b/public/docs/_examples/cb-set-document-title/ts/src/index.html @@ -0,0 +1,39 @@ + + + + + + + + + Setting The Document Title Using The Title Service + + + + + + + + + + + + + + + + + + +

    + Setting The Document Title Using The Title Service +

    + + Loading app... + + + diff --git a/public/docs/_examples/cb-set-document-title/ts/src/main.ts b/public/docs/_examples/cb-set-document-title/ts/src/main.ts new file mode 100644 index 0000000000..f332d1d245 --- /dev/null +++ b/public/docs/_examples/cb-set-document-title/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-ts-to-js/e2e-spec.ts b/public/docs/_examples/cb-ts-to-js/e2e-spec.ts index dbb308fbf7..bc67bac8f0 100644 --- a/public/docs/_examples/cb-ts-to-js/e2e-spec.ts +++ b/public/docs/_examples/cb-ts-to-js/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('TypeScript to Javascript tests', function () { beforeAll(function () { @@ -6,7 +9,7 @@ describe('TypeScript to Javascript tests', function () { }); it('should display the basic component example', function () { - testTag('hero-view', 'Hero: Windstorm'); + testTag('hero-view', 'Hero Detail: Windstorm'); }); it('should display the component example with lifecycle methods', function () { @@ -24,7 +27,7 @@ describe('TypeScript to Javascript tests', function () { it('should support optional, attribute, and query injections', function () { let app = element(by.css('hero-di-inject-additional')); let h1 = app.element(by.css('h1')); - let okMsg = app.element(by.css('.ok-msg')); + let okMsg = app.element(by.css('p')); expect(h1.getText()).toBe('Tour of Heroes'); app.element(by.buttonText('OK')).click(); @@ -33,7 +36,7 @@ describe('TypeScript to Javascript tests', function () { it('should support component with inputs and outputs', function () { let app = element(by.css('hero-io')); - let confirmComponent = app.element(by.css('my-confirm')); + let confirmComponent = app.element(by.css('app-confirm')); confirmComponent.element(by.buttonText('OK')).click(); expect(app.element(by.cssContainingText('span', 'OK clicked')).isPresent()).toBe(true); @@ -43,27 +46,27 @@ describe('TypeScript to Javascript tests', function () { }); it('should support host bindings and host listeners', function() { - let app = element(by.css('heroes-bindings')); + let app = element(by.css('hero-host')); let h1 = app.element(by.css('h1')); expect(app.getAttribute('class')).toBe('heading'); - expect(app.getAttribute('title')).toBe('Tooltip content'); + expect(app.getAttribute('title')).toContain('Tooltip'); h1.click(); expect(h1.getAttribute('class')).toBe('active'); h1.click(); - browser.actions().doubleClick(h1 as any as webdriver.WebElement).perform(); + browser.actions().doubleClick(h1.getWebElement()).perform(); expect(h1.getAttribute('class')).toBe('active'); }); it('should support content and view queries', function() { - let app = element(by.css('heroes-queries')); - let windstorm = app.element(by.css('hero:first-child')); + let app = element(by.css('hero-queries')); + let windstorm = app.element(by.css('view-child:first-child')); - app.element(by.buttonText('Activate')).click(); + app.element(by.css('button')).click(); expect(windstorm.element(by.css('h2')).getAttribute('class')).toBe('active'); - expect(windstorm.element(by.css('active-label')).getText()).toBe('Active'); + expect(windstorm.element(by.css('content-child')).getText()).toBe('Active'); }); function testTag(selector: string, expectedText: string) { diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/example-config.json b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/example-config.json new file mode 100644 index 0000000000..81f31aaf0d --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/example-config.json @@ -0,0 +1,3 @@ +{ + "build": "build:babel" +} diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/plnkr.json b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/plnkr.json new file mode 100644 index 0000000000..447fc5f605 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/plnkr.json @@ -0,0 +1,9 @@ +{ + "description": "TypeScript to JavaScript", + "basePath": "src/", + "files":[ + "!**/*.d.ts", + "!**/*.js" + ], + "tags":["cookbook"] +} diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/.babelrc b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/.babelrc new file mode 100644 index 0000000000..3aaf507508 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/.babelrc @@ -0,0 +1,6 @@ +{ + "presets": [ + "es2015", + "angular2" + ] +} diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/app.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/app.component.es6 new file mode 100644 index 0000000000..d425788f46 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/app.component.es6 @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html', + styles: [ + // See hero-di-inject-additional.component + 'hero-host, hero-host-meta { border: 1px dashed black; display: block; padding: 4px;}', + '.heading {font-style: italic}' + ] +}) +export class AppComponent { + title = 'ES6 JavaScript with Decorators'; +} diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/app.component.html b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/app.component.html new file mode 100644 index 0000000000..995645073a --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/app.component.html @@ -0,0 +1,31 @@ + +

    {{title}}

    +Classes and Class Metadata
    +Input and Output Decorators
    +Dependency Injection
    +Host Metadata
    +View and Child Metadata
    + +
    +

    Classes and Class Metadata

    + + + +
    +

    Input and Output Metadata

    + + +
    +

    Dependency Injection

    + + + + +
    +

    Host Metadata

    + + + +
    +

    View and Child Metadata

    + diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/app.module.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/app.module.es6 new file mode 100644 index 0000000000..9c248a7ad3 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/app.module.es6 @@ -0,0 +1,55 @@ +import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { ConfirmComponent } from './confirm.component'; +// #docregion appimport +import { HeroComponent } from './hero.component'; +// #enddocregion appimport +import { HeroComponent as HeroDIComponent } from './hero-di.component'; +import { HeroComponent as HeroDIInjectComponent } from './hero-di-inject.component'; +import { HeroComponent as HeroDIInjectAdditionalComponent } from './hero-di-inject-additional.component'; +import { HeroHostComponent } from './hero-host.component'; +import { HeroHostMetaComponent } from './hero-host-meta.component'; +import { HeroIOComponent } from './hero-io.component'; +import { HeroComponent as HeroLifecycleComponent } from './hero-lifecycle.component'; +import { HeroQueriesComponent, ViewChildComponent, ContentChildComponent } from './hero-queries.component'; +import { HeroTitleComponent } from './hero-title.component'; + +import { DataService } from './data.service'; + +@NgModule({ + imports: [ + BrowserModule + ], + declarations: [ + AppComponent, + ConfirmComponent, + HeroComponent, + HeroDIComponent, + HeroDIInjectComponent, + HeroDIInjectAdditionalComponent, + HeroHostComponent, HeroHostMetaComponent, + HeroIOComponent, + HeroLifecycleComponent, + HeroQueriesComponent, ViewChildComponent, ContentChildComponent, + HeroTitleComponent + ], + providers: [ + DataService, + { provide: 'heroName', useValue: 'Windstorm' } + ], + bootstrap: [ AppComponent ], + + // schemas: [ NO_ERRORS_SCHEMA ] // helpful for debugging +}) +export class AppModule { } + +/* tslint:disable no-unused-variable */ +// #docregion ng2import +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { + LocationStrategy, + HashLocationStrategy +} from '@angular/common'; +// #enddocregion ng2import diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/confirm.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/confirm.component.es6 new file mode 100644 index 0000000000..f01fa4de40 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/confirm.component.es6 @@ -0,0 +1,21 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; + +// #docregion +@Component({ + selector: 'app-confirm', + templateUrl: './confirm.component.html' +}) +export class ConfirmComponent { + @Input() okMsg = ''; + @Input('cancelMsg') notOkMsg = ''; + @Output() ok = new EventEmitter(); + @Output('cancel') notOk = new EventEmitter(); + + onOkClick() { + this.ok.emit(true); + } + onNotOkClick() { + this.notOk.emit(true); + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/confirm.component.html b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/confirm.component.html new file mode 100644 index 0000000000..45275d218a --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/confirm.component.html @@ -0,0 +1,6 @@ + + diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/data.service.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/data.service.es6 new file mode 100644 index 0000000000..cd7f9e1aae --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/data.service.es6 @@ -0,0 +1,10 @@ +import { Injectable } from '@angular/core'; + +@Injectable() +export class DataService { + constructor() { } + + getHeroName() { + return 'Windstorm'; + } +} diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-di-inject-additional.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-di-inject-additional.component.es6 new file mode 100644 index 0000000000..ec460a9dbc --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-di-inject-additional.component.es6 @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'hero-di-inject-additional', + template: `` +}) +export class HeroComponent { } diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-di-inject.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-di-inject.component.es6 new file mode 100644 index 0000000000..94b42f956a --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-di-inject.component.es6 @@ -0,0 +1,13 @@ +import { Component, Inject } from '@angular/core'; + +// #docregion +@Component({ + selector: 'hero-di-inject', + template: `

    Hero: {{name}}

    ` +}) +export class HeroComponent { + constructor(@Inject('heroName') name) { + this.name = name; + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-di.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-di.component.es6 new file mode 100644 index 0000000000..3a17abd281 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-di.component.es6 @@ -0,0 +1,15 @@ +// #docregion +import { Component } from '@angular/core'; +import { DataService } from './data.service'; + +@Component({ + selector: 'hero-di', + template: `

    Hero: {{name}}

    ` +}) +export class HeroComponent { + name = ''; + constructor(dataService: DataService) { + this.name = dataService.getHeroName(); + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-host-meta.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-host-meta.component.es6 new file mode 100644 index 0000000000..fefe4a5470 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-host-meta.component.es6 @@ -0,0 +1,44 @@ +import { Component } from '@angular/core'; + +// #docregion +@Component({ + selector: 'hero-host-meta', + template: ` +

    Hero Host in Metadata

    +
    Heading clicks: {{clicks}}
    + `, + host: { + // HostBindings to the element + '[title]': 'title', + '[class.heading]': 'headingClass', + + // HostListeners on the entire element + '(click)': 'clicked()', + '(mouseenter)': 'enter($event)', + '(mouseleave)': 'leave($event)' + }, + // Styles within (but excluding) the element + styles: ['.active {background-color: coral;}'] +}) +export class HeroHostMetaComponent { + title = 'Hero Host in Metadata Tooltip'; + headingClass = true; + + active = false; + clicks = 0; + + clicked() { + this.clicks += 1; + } + + enter(event: Event) { + this.active = true; + this.headingClass = false; + } + + leave(event: Event) { + this.active = false; + this.headingClass = true; + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-host.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-host.component.es6 new file mode 100644 index 0000000000..e8d72233c8 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-host.component.es6 @@ -0,0 +1,39 @@ +import { Component, HostBinding, HostListener } from '@angular/core'; + +// #docregion +@Component({ + selector: 'hero-host', + template: ` +

    Hero Host in Decorators

    +
    Heading clicks: {{clicks}}
    + `, + // Styles within (but excluding) the element + styles: ['.active {background-color: yellow;}'] +}) +export class HeroHostComponent { + // HostBindings to the element + @HostBinding() title = 'Hero Host in Decorators Tooltip'; + @HostBinding('class.heading') headingClass = true; + + active = false; + clicks = 0; + + // HostListeners on the entire element + @HostListener('click') + clicked() { + this.clicks += 1; + } + + @HostListener('mouseenter', ['$event']) + enter(event: Event) { + this.active = true; + this.headingClass = false; + } + + @HostListener('mouseleave', ['$event']) + leave(event: Event) { + this.active = false; + this.headingClass = true; + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-io.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-io.component.es6 new file mode 100644 index 0000000000..4b36411e78 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-io.component.es6 @@ -0,0 +1,26 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'hero-io', + template: ` + + + OK clicked + Cancel clicked + ` +}) +export class HeroIOComponent { + okClicked = false; + cancelClicked = false; + + onOk() { + this.okClicked = true; + } + + onCancel() { + this.cancelClicked = true; + } +} diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-lifecycle.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-lifecycle.component.es6 new file mode 100644 index 0000000000..2539266597 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-lifecycle.component.es6 @@ -0,0 +1,14 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'hero-lifecycle', + template: `

    Hero: {{name}}

    ` +}) +export class HeroComponent { + name = ''; + ngOnInit() { + // todo: fetch from server async + setTimeout(() => this.name = 'Windstorm', 0); + } +} diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-queries.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-queries.component.es6 new file mode 100644 index 0000000000..fced43d4d7 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-queries.component.es6 @@ -0,0 +1,81 @@ +import { + Component, + ContentChild, + Input, + QueryList, + ViewChildren +} from '@angular/core'; + +@Component({ + selector: 'content-child', + template: ` + + Active + ` +}) +export class ContentChildComponent { + active = false; + + activate() { + this.active = true; + } +} + +//////////////////// + +// #docregion content +@Component({ + selector: 'view-child', + template: ` +

    + {{hero.name}} + +

    `, + styles: ['.active {font-weight: bold; background-color: skyblue;}'] +}) +export class ViewChildComponent { + @Input() hero; + active = false; + + @ContentChild(ContentChildComponent) content; + + activate() { + this.active = !this.active; + this.content.activate(); + } +} +// #enddocregion content + +//////////////////// + +// #docregion view +@Component({ + selector: 'hero-queries', + template: ` + + + + + ` +}) +export class HeroQueriesComponent { + active = false; + heroData = [ + {id: 1, name: 'Windstorm'}, + {id: 2, name: 'LaughingGas'} + ]; + + @ViewChildren(ViewChildComponent) views; + + activate() { + this.active = !this.active; + this.views.forEach( + view => view.activate() + ); + } + + get buttonLabel() { + return this.active ? 'Deactivate' : 'Activate'; + } +} +// #enddocregion view diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-title.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-title.component.es6 new file mode 100644 index 0000000000..04c14a9631 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-title.component.es6 @@ -0,0 +1,25 @@ +import { Attribute, Component, Inject, Optional } from '@angular/core'; + +// #docregion +// #docregion templateUrl +@Component({ + selector: 'hero-title', + templateUrl: './hero-title.component.html' +}) +// #enddocregion templateUrl +export class HeroTitleComponent { + msg = ''; + constructor( + @Inject('titlePrefix') @Optional() titlePrefix, + @Attribute('title') title + ) { + this.titlePrefix = titlePrefix; + this.title = title; + } + + ok() { + this.msg = 'OK!'; + } +} +// #enddocregion + diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-title.component.html b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-title.component.html new file mode 100644 index 0000000000..164683cb7c --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero-title.component.html @@ -0,0 +1,4 @@ + +

    {{titlePrefix}} {{title}}

    + +

    {{ msg }}

    diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero.component.es6 new file mode 100644 index 0000000000..2976ec605e --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/app/hero.component.es6 @@ -0,0 +1,15 @@ +// #docregion +// #docregion metadata +import { Component } from '@angular/core'; + +@Component({ + selector: 'hero-view', + template: '

    {{title}}: {{getName()}}

    ' +}) +// #docregion appexport, class +export class HeroComponent { + title = 'Hero Detail'; + getName() {return 'Windstorm'; } +} +// #enddocregion appexport, class +// #enddocregion metadata diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/index.html b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/index.html new file mode 100644 index 0000000000..2a94db38cc --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/index.html @@ -0,0 +1,26 @@ + + + + + + + + TypeScript to JavaScript + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/main.es6 b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/main.es6 new file mode 100644 index 0000000000..f22933ba8e --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6-decorators/src/main.es6 @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/example-config.json b/public/docs/_examples/cb-ts-to-js/js-es6/example-config.json new file mode 100644 index 0000000000..81f31aaf0d --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/example-config.json @@ -0,0 +1,3 @@ +{ + "build": "build:babel" +} diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/plnkr.json b/public/docs/_examples/cb-ts-to-js/js-es6/plnkr.json new file mode 100644 index 0000000000..447fc5f605 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/plnkr.json @@ -0,0 +1,9 @@ +{ + "description": "TypeScript to JavaScript", + "basePath": "src/", + "files":[ + "!**/*.d.ts", + "!**/*.js" + ], + "tags":["cookbook"] +} diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/.babelrc b/public/docs/_examples/cb-ts-to-js/js-es6/src/.babelrc new file mode 100644 index 0000000000..3c078e9f99 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/.babelrc @@ -0,0 +1,5 @@ +{ + "presets": [ + "es2015" + ] +} diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/app.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/app.component.es6 new file mode 100644 index 0000000000..6079f7f246 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/app.component.es6 @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; + +export class AppComponent { + constructor() { + this.title = 'Plain ES6 JavaScript'; + } +} + +AppComponent.annotations = [ + new Component({ + selector: 'my-app', + templateUrl: './app.component.html', + styles: [ + // See hero-di-inject-additional.component + 'hero-host { border: 1px dashed black; display: block; padding: 4px;}', + '.heading {font-style: italic}' + ] + }) +]; diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/app.component.html b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/app.component.html new file mode 100644 index 0000000000..52b9b4580e --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/app.component.html @@ -0,0 +1,30 @@ + +

    {{title}}

    +Classes and Class Metadata
    +Input and Output Metadata
    +Dependency Injection
    +Host Metadata
    +View and Child Metadata
    + +
    +

    Classes and Class Metadata

    + + + +
    +

    Input and Output Metadata

    + + +
    +

    Dependency Injection

    + + + + +
    +

    Host Metadata

    + + +
    +

    View and Child Metadata

    + diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/app.module.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/app.module.es6 new file mode 100644 index 0000000000..f31141e78f --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/app.module.es6 @@ -0,0 +1,56 @@ +import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { ConfirmComponent } from './confirm.component'; +// #docregion appimport +import { HeroComponent } from './hero.component'; + +// #enddocregion appimport +import { HeroComponent as HeroDIComponent } from './hero-di.component'; +import { HeroComponent as HeroDIInjectComponent } from './hero-di-inject.component'; +import { HeroComponent as HeroDIInjectAdditionalComponent } from './hero-di-inject-additional.component'; +import { HeroHostComponent } from './hero-host.component'; +import { HeroIOComponent } from './hero-io.component'; +import { HeroComponent as HeroLifecycleComponent } from './hero-lifecycle.component'; +import { HeroQueriesComponent, ViewChildComponent, ContentChildComponent } from './hero-queries.component'; +import { HeroTitleComponent } from './hero-title.component'; + +import { DataService } from './data.service'; + +export class AppModule { } + +AppModule.annotations = [ + new NgModule({ + imports: [ BrowserModule], + declarations: [ + AppComponent, + ConfirmComponent, + HeroComponent, + HeroDIComponent, + HeroDIInjectComponent, + HeroDIInjectAdditionalComponent, + HeroHostComponent, + HeroIOComponent, + HeroLifecycleComponent, + HeroQueriesComponent, ViewChildComponent, ContentChildComponent, + HeroTitleComponent + ], + providers: [ + DataService, + { provide: 'heroName', useValue: 'Windstorm' } + ], + bootstrap: [ AppComponent ], + + // schemas: [ NO_ERRORS_SCHEMA ] // helpful for debugging + }) +] + +/* tslint:disable no-unused-variable */ +// #docregion ng2import +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { + LocationStrategy, + HashLocationStrategy +} from '@angular/common'; +// #enddocregion ng2import diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/confirm.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/confirm.component.es6 new file mode 100644 index 0000000000..296268dda4 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/confirm.component.es6 @@ -0,0 +1,31 @@ +import { Component, EventEmitter } from '@angular/core'; + +// #docregion +export class ConfirmComponent { + constructor(){ + this.ok = new EventEmitter(); + this.notOk = new EventEmitter(); + } + onOkClick() { + this.ok.emit(true); + } + onNotOkClick() { + this.notOk.emit(true); + } +} + +ConfirmComponent.annotations = [ + new Component({ + selector: 'app-confirm', + templateUrl: './confirm.component.html', + inputs: [ + 'okMsg', + 'notOkMsg: cancelMsg' + ], + outputs: [ + 'ok', + 'notOk: cancel' + ] + }) +]; +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/confirm.component.html b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/confirm.component.html new file mode 100644 index 0000000000..45275d218a --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/confirm.component.html @@ -0,0 +1,6 @@ + + diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/data.service.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/data.service.es6 new file mode 100644 index 0000000000..de023ce5a0 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/data.service.es6 @@ -0,0 +1,13 @@ +import { Injectable } from '@angular/core'; + +export class DataService { + constructor() { + } + getHeroName() { + return 'Windstorm'; + } +} + +DataService.annotations = [ + new Injectable() +]; diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-di-inject-additional.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-di-inject-additional.component.es6 new file mode 100644 index 0000000000..5eb9bab815 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-di-inject-additional.component.es6 @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +export class HeroComponent { } + +HeroComponent.annotations = [ + new Component({ + selector: 'hero-di-inject-additional', + template: `` + }) +]; diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-di-inject.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-di-inject.component.es6 new file mode 100644 index 0000000000..2f95a0b981 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-di-inject.component.es6 @@ -0,0 +1,20 @@ +import { Component, Inject } from '@angular/core'; + +// #docregion +export class HeroComponent { + constructor(name) { + this.name = name; + } +} + +HeroComponent.annotations = [ + new Component({ + selector: 'hero-di-inject', + template: `

    Hero: {{name}}

    ` + }) +]; + +HeroComponent.parameters = [ + [new Inject('heroName')] +]; +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-di.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-di.component.es6 new file mode 100644 index 0000000000..a18b1ba777 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-di.component.es6 @@ -0,0 +1,21 @@ +// #docregion +import { Component } from '@angular/core'; +import { DataService } from './data.service'; + +export class HeroComponent { + constructor(dataService) { + this.name = dataService.getHeroName(); + } +} + +HeroComponent.annotations = [ + new Component({ + selector: 'hero-di', + template: `

    Hero: {{name}}

    ` + }) +]; + +HeroComponent.parameters = [ + [DataService] +]; +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-host.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-host.component.es6 new file mode 100644 index 0000000000..b06701ee8d --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-host.component.es6 @@ -0,0 +1,50 @@ +import { Component } from '@angular/core'; + +// #docregion +export class HeroHostComponent { + constructor() { + this.active = false; + this.clicks = 0; + this.headingClass = true; + this.title = 'Hero Host Tooltip'; + } + + clicked() { + this.clicks += 1; + } + + enter(event) { + this.active = true; + this.headingClass = false; + } + + leave(event) { + this.active = false; + this.headingClass = true; + } +} + +// #docregion metadata +HeroHostComponent.annotations = [ + new Component({ + selector: 'hero-host', + template: ` +

    Hero Host

    +
    Heading clicks: {{clicks}}
    + `, + host: { + // HostBindings to the element + '[title]': 'title', + '[class.heading]': 'headingClass', + '(click)': 'clicked()', + + // HostListeners on the entire element + '(mouseenter)': 'enter($event)', + '(mouseleave)': 'leave($event)' + }, + // Styles within (but excluding) the element + styles: ['.active {background-color: yellow;}'] + }) +]; +// #enddocregion metadata +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-io.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-io.component.es6 new file mode 100644 index 0000000000..0dc8c08f2d --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-io.component.es6 @@ -0,0 +1,31 @@ +import { Component } from '@angular/core'; + +export class HeroIOComponent { + constructor() { + this.okClicked = false; + this.cancelClicked = false; + } + + onOk() { + this.okClicked = true; + } + + onCancel() { + this.cancelClicked = true; + } +} + +HeroIOComponent.annotations = [ + new Component({ + selector: 'hero-io', + template: ` + + + OK clicked + Cancel clicked + ` + }) +]; diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-lifecycle.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-lifecycle.component.es6 new file mode 100644 index 0000000000..b394ff59aa --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-lifecycle.component.es6 @@ -0,0 +1,15 @@ +// #docregion +import { Component } from '@angular/core'; +export class HeroComponent { + ngOnInit() { + // todo: fetch from server async + setTimeout(() => this.name = 'Windstorm', 0); + } +} + +HeroComponent.annotations = [ + new Component({ + selector: 'hero-lifecycle', + template: `

    Hero: {{name}}

    ` + }) +]; diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-queries.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-queries.component.es6 new file mode 100644 index 0000000000..bf3b914406 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-queries.component.es6 @@ -0,0 +1,97 @@ +import { + Component, + ContentChild, + Input, + QueryList, + ViewChildren +} from '@angular/core'; + +export class ContentChildComponent { + constructor() { + this.active = false; + } + + activate() { + this.active = !this.active; + } +} + +ContentChildComponent.annotations = [ + new Component({ + selector: 'content-child', + template: ` + + Active + ` + }) +]; + +//////////////////// + +// #docregion content +export class ViewChildComponent { + constructor() { + this.active = false; + } + + activate() { + this.active = !this.active; + this.content.activate(); + } +} + +ViewChildComponent.annotations = [ + new Component({ + selector: 'view-child', + template: `

    + {{hero.name}} + +

    `, + styles: ['.active {font-weight: bold; background-color: skyblue;}'], + inputs: ['hero'], + queries: { + content: new ContentChild(ContentChildComponent) + } + }) +]; +// #enddocregion content + +//////////////////// + +// #docregion view +export class HeroQueriesComponent { + constructor(){ + this.active = false; + this.heroData = [ + {id: 1, name: 'Windstorm'}, + {id: 2, name: 'LaughingGas'} + ]; + } + + activate() { + this.active = !this.active; + this.views.forEach( + view => view.activate() + ); + } + + get buttonLabel() { + return this.active ? 'Deactivate' : 'Activate'; + } +} + +HeroQueriesComponent.annotations = [ + new Component({ + selector: 'hero-queries', + template: ` + + + + + `, + queries: { + views: new ViewChildren(ViewChildComponent) + } + }) +]; +// #enddocregion view diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-title.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-title.component.es6 new file mode 100644 index 0000000000..4b89dfba83 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-title.component.es6 @@ -0,0 +1,28 @@ +import { Attribute, Component, Inject, Optional } from '@angular/core'; + +// #docregion +export class HeroTitleComponent { + constructor(titlePrefix, title) { + this.titlePrefix = titlePrefix; + this.title = title; + this.msg = ''; + } + + ok() { + this.msg = 'OK!'; + } +} + +// #docregion templateUrl +HeroTitleComponent.annotations = [ + new Component({ + selector: 'hero-title', + templateUrl: './hero-title.component.html' + }) +]; +// #enddocregion templateUrl + +HeroTitleComponent.parameters = [ + [new Optional(), new Inject('titlePrefix')], + [new Attribute('title')] +]; diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-title.component.html b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-title.component.html new file mode 100644 index 0000000000..164683cb7c --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero-title.component.html @@ -0,0 +1,4 @@ + +

    {{titlePrefix}} {{title}}

    + +

    {{ msg }}

    diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero.component.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero.component.es6 new file mode 100644 index 0000000000..350f946460 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/app/hero.component.es6 @@ -0,0 +1,21 @@ +// #docplaster +// #docregion +// #docregion metadata +import { Component } from '@angular/core'; + +// #docregion appexport, class +export class HeroComponent { + constructor() { + this.title = 'Hero Detail'; + } + getName() {return 'Windstorm'; } +} +// #enddocregion appexport, class + +HeroComponent.annotations = [ + new Component({ + selector: 'hero-view', + template: '

    {{title}}: {{getName()}}

    ' + }) +]; +// #enddocregion metadata diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/index.html b/public/docs/_examples/cb-ts-to-js/js-es6/src/index.html new file mode 100644 index 0000000000..2a94db38cc --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/index.html @@ -0,0 +1,26 @@ + + + + + + + + TypeScript to JavaScript + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/cb-ts-to-js/js-es6/src/main.es6 b/public/docs/_examples/cb-ts-to-js/js-es6/src/main.es6 new file mode 100644 index 0000000000..f22933ba8e --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js-es6/src/main.es6 @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-ts-to-js/js/app/data.service.js b/public/docs/_examples/cb-ts-to-js/js/app/data.service.js deleted file mode 100644 index c060e2b39d..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/data.service.js +++ /dev/null @@ -1,13 +0,0 @@ -(function(app) { - - function DataService() { - } - DataService.annotations = [ - new ng.core.Injectable() - ]; - DataService.prototype.getHeroName = function() { - return 'Windstorm'; - }; - app.DataService = DataService; - -})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inject-additional.component.js b/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inject-additional.component.js deleted file mode 100644 index 413ccfc8f3..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inject-additional.component.js +++ /dev/null @@ -1,47 +0,0 @@ -(function(app) { - - // #docregion - var TitleComponent = ng.core.Component({ - selector: 'hero-title', - template: - '

    {{titlePrefix}} {{title}}

    ' + - '' + - '' - }).Class({ - constructor: [ - [ - new ng.core.Optional(), - new ng.core.Inject('titlePrefix') - ], - new ng.core.Attribute('title'), - [ - new ng.core.Query('okMsg'), - ng.core.ElementRef - ], - function(titlePrefix, title, msg) { - this.titlePrefix = titlePrefix; - this.title = title; - this.msg = msg; - } - ], - ok: function() { - var msgEl = - this.msg.first.nativeElement; - msgEl.textContent = 'OK!'; - } - }); - // #enddocregion - - var AppComponent = ng.core.Component({ - selector: 'hero-di-inject-additional', - template: '' + - '' + - '', - directives: [TitleComponent] - }).Class({ - constructor: function() { } - }); - - app.HeroDIInjectAdditionalComponent = AppComponent; - -})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inject.component.js b/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inject.component.js deleted file mode 100644 index 71bdbb57f9..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inject.component.js +++ /dev/null @@ -1,39 +0,0 @@ -(function(app) { - -// #docregion parameters - function HeroComponent(name) { - this.name = name; - } - HeroComponent.parameters = [ - 'heroName' - ]; - HeroComponent.annotations = [ - new ng.core.Component({ - selector: 'hero-di-inject', - template: '

    Hero: {{name}}

    ' - }) - ]; -// #enddocregion parameters - - app.HeroDIInjectComponent = HeroComponent; - -})(window.app = window.app || {}); - -(function(app) { -// #docregion ctor - var HeroComponent = ng.core.Component({ - selector: 'hero-di-inline2', - template: '

    Hero: {{name}}

    ' - }) - .Class({ - constructor: - [new ng.core.Inject('heroName'), - function(name) { - this.name = name; - }] - }); -// #enddocregion ctor - - app.HeroDIInjectComponent2 = HeroComponent; - -})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inline.component.js b/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inline.component.js deleted file mode 100644 index 90c3d69cba..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/hero-di-inline.component.js +++ /dev/null @@ -1,16 +0,0 @@ -(function(app) { - // #docregion - var HeroComponent = ng.core.Component({ - selector: 'hero-di-inline', - template: '

    Hero: {{name}}

    ' - }) - .Class({ - constructor: - [app.DataService, - function(service) { - this.name = service.getHeroName(); - }] - }); - // #enddocregion - app.HeroDIInlineComponent = HeroComponent; -})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/app/hero-di.component.js b/public/docs/_examples/cb-ts-to-js/js/app/hero-di.component.js deleted file mode 100644 index 2963258292..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/hero-di.component.js +++ /dev/null @@ -1,20 +0,0 @@ -(function(app) { - - // #docregion - app.HeroDIComponent = HeroComponent; - - function HeroComponent(dataService) { - this.name = dataService.getHeroName(); - } - HeroComponent.parameters = [ - app.DataService - ]; - HeroComponent.annotations = [ - new ng.core.Component({ - selector: 'hero-di', - template: '

    Hero: {{name}}

    ' - }) - ]; - // #enddocregion - -})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/app/hero-dsl.component.js b/public/docs/_examples/cb-ts-to-js/js/app/hero-dsl.component.js deleted file mode 100644 index 2890e006a2..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/hero-dsl.component.js +++ /dev/null @@ -1,23 +0,0 @@ -// #docplaster -// #docregion appexport -(function(app) { - - // #docregion component - var HeroComponent = ng.core.Component({ - selector: 'hero-view-2', - template: - '

    Name: {{getName()}}

    ', - }) - .Class({ - constructor: function() { - }, - getName: function() { - return 'Windstorm'; - } - }); - // #enddocregion component - - app.HeroComponentDsl = HeroComponent; - -})(window.app = window.app || {}); -// #enddocregion appexport diff --git a/public/docs/_examples/cb-ts-to-js/js/app/hero-io.component.js b/public/docs/_examples/cb-ts-to-js/js/app/hero-io.component.js deleted file mode 100644 index f00ce8065c..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/hero-io.component.js +++ /dev/null @@ -1,57 +0,0 @@ -(function(app) { - // #docregion - var ConfirmComponent = ng.core.Component({ - selector: 'my-confirm', - inputs: [ - 'okMsg', - 'notOkMsg: cancelMsg' - ], - outputs: [ - 'ok', - 'notOk: cancel' - ], - template: - '' + - '' - }).Class({ - constructor: function() { - this.ok = new ng.core.EventEmitter(); - this.notOk = new ng.core.EventEmitter(); - }, - onOkClick: function() { - this.ok.next(true); - }, - onNotOkClick: function() { - this.notOk.next(true); - } - }); - // #enddocregion - - function AppComponent() { - } - AppComponent.annotations = [ - new ng.core.Component({ - selector: 'hero-io', - template: '' + - '' + - 'OK clicked' + - 'Cancel clicked', - directives: [ConfirmComponent] - }) - ]; - AppComponent.prototype.onOk = function() { - this.okClicked = true; - } - AppComponent.prototype.onCancel = function() { - this.cancelClicked = true; - } - app.HeroIOComponent = AppComponent; - -})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/app/hero-lifecycle.component.js b/public/docs/_examples/cb-ts-to-js/js/app/hero-lifecycle.component.js deleted file mode 100644 index b8a2148a64..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/hero-lifecycle.component.js +++ /dev/null @@ -1,21 +0,0 @@ -// #docplaster -(function(app) { - // #docregion - function HeroComponent() {} - // #enddocregion - HeroComponent.annotations = [ - new ng.core.Component({ - selector: 'hero-lifecycle', - template: '

    Hero: {{name}}

    ' - }) - ]; - // #docregion - HeroComponent.prototype.ngOnInit = - function() { - this.name = 'Windstorm'; - }; - // #enddocregion - - app.HeroLifecycleComponent = HeroComponent; - -})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/app/hero.component.js b/public/docs/_examples/cb-ts-to-js/js/app/hero.component.js deleted file mode 100644 index f741285617..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/hero.component.js +++ /dev/null @@ -1,32 +0,0 @@ -// #docplaster -// #docregion appexport -(function(app) { - // #enddocregion appexport - - // #docregion metadata - // #docregion appexport - // #docregion constructorproto - function HeroComponent() { - this.title = "Hero Detail"; - } - - // #enddocregion constructorproto - // #enddocregion appexport - HeroComponent.annotations = [ - new ng.core.Component({ - selector: 'hero-view', - template: - '

    Hero: {{getName()}}

    ' - }) - ]; - // #docregion constructorproto - HeroComponent.prototype.getName = - function() {return 'Windstorm';}; - // #enddocregion constructorproto - // #enddocregion metadata - - // #docregion appexport - app.HeroComponent = HeroComponent; - -})(window.app = window.app || {}); -// #enddocregion appexport diff --git a/public/docs/_examples/cb-ts-to-js/js/app/heroes-bindings.component.js b/public/docs/_examples/cb-ts-to-js/js/app/heroes-bindings.component.js deleted file mode 100644 index 0c4ee7d7cf..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/heroes-bindings.component.js +++ /dev/null @@ -1,30 +0,0 @@ -(function(app) { - - // #docregion - var HeroesComponent = ng.core.Component({ - selector: 'heroes-bindings', - template: '

    ' + - 'Tour of Heroes' + - '

    ', - host: { - '[title]': 'title', - '[class.heading]': 'hClass', - '(click)': 'clicked()', - '(dblclick)': 'doubleClicked($event)' - } - }).Class({ - constructor: function() { - this.title = 'Tooltip content'; - this.hClass = true; - }, - clicked: function() { - this.active = !this.active; - }, - doubleClicked: function(evt) { - this.active = true; - } - }); - // #enddocregion - app.HeroesHostBindingsComponent = HeroesComponent; - -})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/app/heroes-queries.component.js b/public/docs/_examples/cb-ts-to-js/js/app/heroes-queries.component.js deleted file mode 100644 index cd49a01754..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/heroes-queries.component.js +++ /dev/null @@ -1,73 +0,0 @@ -(function(app) { - - var ActiveLabelComponent = ng.core.Component({ - selector: 'active-label', - template: '' + - 'Active' + - '' - }).Class({ - constructor: function() { }, - activate: function() { - this.active = true; - } - }); - - // #docregion content - var HeroComponent = ng.core.Component({ - selector: 'hero', - template: '

    ' + - '{{hero.name}} ' + - '' + - '

    ', - inputs: ['hero'], - queries: { - label: new ng.core.ContentChild( - ActiveLabelComponent) - } - }).Class({ - constructor: function() { }, - activate: function() { - this.active = true; - this.label.activate(); - } - }); - // #enddocregion content - - // #docregion view - var AppComponent = ng.core.Component({ - selector: 'heroes-queries', - template: - '' + - '' + - '' + - '', - directives: [ - HeroComponent, - ActiveLabelComponent - ], - queries: { - heroCmps: new ng.core.ViewChildren( - HeroComponent) - } - }).Class({ - constructor: function() { - this.heroData = [ - {id: 1, name: 'Windstorm'}, - {id: 2, name: 'Superman'} - ]; - }, - activate: function() { - this.heroCmps.forEach(function(cmp) { - cmp.activate(); - }); - } - }); - // #enddocregion view - - app.HeroesQueriesComponent = AppComponent; - -})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/app/main.js b/public/docs/_examples/cb-ts-to-js/js/app/main.js deleted file mode 100644 index f483a7c8cd..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/app/main.js +++ /dev/null @@ -1,39 +0,0 @@ -// #docplaster -// #docregion appimport -(function(app) { - // #enddocregion appimport - - // #docregion ng2import - var bootstrap = - ng.platformBrowserDynamic.bootstrap; - var LocationStrategy = - ng.common.LocationStrategy; - var HashLocationStrategy = - ng.common.HashLocationStrategy; - // #enddocregion ng2import - - // #docregion appimport - var HeroComponent = app.HeroComponent; - // #enddocregion appimport - - document.addEventListener('DOMContentLoaded', function() { - bootstrap(HeroComponent); - bootstrap(app.HeroComponentDsl); - bootstrap(app.HeroLifecycleComponent); - bootstrap(app.HeroDIComponent, [app.DataService]); - bootstrap(app.HeroDIInlineComponent, [app.DataService]); - bootstrap(app.HeroDIInjectComponent, [ - { provide: 'heroName', useValue: 'Windstorm' } - ]); - bootstrap(app.HeroDIInjectComponent2, [ - { provide: 'heroName', useValue: 'Bombasto' } - ]); - bootstrap(app.HeroDIInjectAdditionalComponent); - bootstrap(app.HeroIOComponent); - bootstrap(app.HeroesHostBindingsComponent); - bootstrap(app.HeroesQueriesComponent); - }); - - // #docregion appimport -})(window.app = window.app || {}); -// #enddocregion appimport diff --git a/public/docs/_examples/cb-ts-to-js/js/example-config.json b/public/docs/_examples/cb-ts-to-js/js/example-config.json index e69de29bb2..81f31aaf0d 100644 --- a/public/docs/_examples/cb-ts-to-js/js/example-config.json +++ b/public/docs/_examples/cb-ts-to-js/js/example-config.json @@ -0,0 +1,3 @@ +{ + "build": "build:babel" +} diff --git a/public/docs/_examples/cb-ts-to-js/js/index.html b/public/docs/_examples/cb-ts-to-js/js/index.html deleted file mode 100644 index b1c1449fb2..0000000000 --- a/public/docs/_examples/cb-ts-to-js/js/index.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    TypeScript to JavaScript

    - Classes and Class Metadata
    - Input and Output Metadata
    - Dependency Injection
    - Host and Query Metadata
    - -
    -

    Classes and Class Metadata

    - Loading hero-view... - Loading hero-view2... - Loading hero-lifecycle... - -
    -

    Input and Output Metadata

    - Loading hero-io... - -
    -

    Dependency Injection

    - Loading hero-di... - Loading hero-di-inline... - Loading hero-di-inline2... - Loading hero-di-inject... - Loading hero-di-inject-additional... - -
    -

    Host and Query Metadata

    - Loading heroes-bindings... - Loading heroes-queries... - - - diff --git a/public/docs/_examples/cb-ts-to-js/js/plnkr.json b/public/docs/_examples/cb-ts-to-js/js/plnkr.json index 729230c2d1..5e1eb188be 100644 --- a/public/docs/_examples/cb-ts-to-js/js/plnkr.json +++ b/public/docs/_examples/cb-ts-to-js/js/plnkr.json @@ -1,5 +1,6 @@ { "description": "TypeScript to JavaScript", + "basePath": "src/", "files":[ "!**/karma*.*" ], diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/app.component.html b/public/docs/_examples/cb-ts-to-js/js/src/app/app.component.html new file mode 100644 index 0000000000..4ca26f2657 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/app.component.html @@ -0,0 +1,47 @@ + +

    {{title}}

    +Classes and Class Metadata
    +Interfaces
    +Input and Output Metadata
    +Dependency Injection
    +Host Metadata
    +View and Child Metadata
    + +
    +

    Classes and Class Metadata

    + +

    Classes and Class Metadata (DSL)

    + + +
    +

    Interfaces

    + +

    Interfaces (DSL)

    + + +
    +

    Input and Output Metadata

    + +

    Input and Output Metadata (DSL)

    + + +
    +

    Dependency Injection

    + + + + +

    Dependency Injection (DSL)

    + + + + +
    +

    Host Metadata

    + +

    Host Metadata (DSL)

    + + +
    +

    View and Child Metadata (DSL)

    + diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/app.component.js b/public/docs/_examples/cb-ts-to-js/js/src/app/app.component.js new file mode 100644 index 0000000000..b6d1ec29b0 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/app.component.js @@ -0,0 +1,20 @@ +(function(app) { + +app.AppComponent = AppComponent; +function AppComponent() { + this.title = 'ES5 JavaScript'; +} + +AppComponent.annotations = [ + new ng.core.Component({ + selector: 'my-app', + templateUrl: 'app/app.component.html', + styles: [ + // See hero-di-inject-additional.component + 'hero-host, hero-host-dsl { border: 1px dashed black; display: block; padding: 4px;}', + '.heading {font-style: italic}' + ] + }) +]; + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/app.module.js b/public/docs/_examples/cb-ts-to-js/js/src/app/app.module.js new file mode 100644 index 0000000000..fc2300a89b --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/app.module.js @@ -0,0 +1,46 @@ +(function(app) { + +app.AppModule = AppModule; +function AppModule() { } + +AppModule.annotations = [ + new ng.core.NgModule({ + imports: [ ng.platformBrowser.BrowserModule ], + declarations: [ + app.AppComponent, + app.ConfirmComponent, app.ConfirmDslComponent, + app.HeroComponent, app.HeroDslComponent, + app.HeroDIComponent, app.HeroDIDslComponent, + app.HeroDIInjectComponent, app.HeroDIInjectDslComponent, + app.HeroDIInjectAdditionalComponent, app.HeroDIInjectAdditionalDslComponent, + app.HeroHostComponent, app.HeroHostDslComponent, + app.HeroIOComponent, app.HeroIODslComponent, + app.HeroLifecycleComponent, app.HeroLifecycleDslComponent, + app.heroQueries.HeroQueriesComponent, app.heroQueries.ViewChildComponent, app.heroQueries.ContentChildComponent, + app.HeroTitleComponent, app.HeroTitleDslComponent + ], + providers: [ + app.DataService, + { provide: 'heroName', useValue: 'Windstorm' } + ], + bootstrap: [ app.AppComponent ], + + // schemas: [ ng.core.NO_ERRORS_SCHEMA ] // helpful for debugging! + }) +] + +})(window.app = window.app || {}); + + +///// For documentation only ///// +(function () { + // #docregion appimport + var HeroComponent = app.HeroComponent; + // #enddocregion appimport + + // #docregion ng2import + var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic; + var LocationStrategy = ng.common.LocationStrategy; + var HashLocationStrategy = ng.common.HashLocationStrategy; + // #enddocregion ng2import +}) diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/confirm.component.html b/public/docs/_examples/cb-ts-to-js/js/src/app/confirm.component.html new file mode 100644 index 0000000000..45275d218a --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/confirm.component.html @@ -0,0 +1,6 @@ + + diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/confirm.component.js b/public/docs/_examples/cb-ts-to-js/js/src/app/confirm.component.js new file mode 100644 index 0000000000..b76d3f54aa --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/confirm.component.js @@ -0,0 +1,75 @@ +(function(app) { + + // #docregion + app.ConfirmComponent = ConfirmComponent; + + ConfirmComponent.annotations = [ + new ng.core.Component({ + selector: 'app-confirm', + templateUrl: 'app/confirm.component.html', + inputs: [ + 'okMsg', + 'notOkMsg: cancelMsg' + ], + outputs: [ + 'ok', + 'notOk: cancel' + ] + }) + ]; + + function ConfirmComponent() { + this.ok = new ng.core.EventEmitter(); + this.notOk = new ng.core.EventEmitter(); + } + + ConfirmComponent.prototype.onOkClick = function() { + this.ok.emit(true); + } + + ConfirmComponent.prototype.onNotOkClick = function() { + this.notOk.emit(true); + } + // #enddocregion + +})(window.app = window.app || {}); + +/////// DSL version //////// + +(function(app) { + + var old = app.ConfirmComponent; + + // #docregion dsl + app.ConfirmComponent = ng.core.Component({ + selector: 'app-confirm-dsl', + templateUrl: 'app/confirm.component.html', + inputs: [ + 'okMsg', + 'notOkMsg: cancelMsg' + ], + outputs: [ + 'ok', + 'notOk: cancel' + ] + }) + .Class({ + constructor: function ConfirmComponent() { + this.ok = new ng.core.EventEmitter(); + this.notOk = new ng.core.EventEmitter(); + }, + + onOkClick: function() { + this.ok.emit(true); + }, + + onNotOkClick: function() { + this.notOk.emit(true); + } + }); + // #enddocregion dsl + + app.ConfirmDslComponent = app.ConfirmComponent; + app.ConfirmComponent = old; + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/data.service.js b/public/docs/_examples/cb-ts-to-js/js/src/app/data.service.js new file mode 100644 index 0000000000..643bb57dca --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/data.service.js @@ -0,0 +1,10 @@ +(function(app) { + + app.DataService = DataService; + function DataService() { } + + DataService.prototype.getHeroName = function() { + return 'Windstorm'; + }; + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero-di-inject-additional.component.js b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-di-inject-additional.component.js new file mode 100644 index 0000000000..450cc53847 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-di-inject-additional.component.js @@ -0,0 +1,36 @@ +(function(app) { + + var old = app.HeroComponent; + + app.HeroComponent = HeroComponent; + + HeroComponent.annotations = [ + new ng.core.Component({ + selector: 'hero-di-inject-additional', + template: '' + }) + ]; + + function HeroComponent() {} + + app.HeroDIInjectAdditionalComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); + +////// DSL Version ///////// +(function(app) { + + var old = app.HeroComponent; + + app.HeroComponent = ng.core.Component({ + selector: 'hero-di-inject-additional-dsl', + template: '' + }).Class({ + constructor: function HeroComponent() { } + }); + + app.HeroDIInjectAdditionalDslComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero-di-inject.component.js b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-di-inject.component.js new file mode 100644 index 0000000000..879365208c --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-di-inject.component.js @@ -0,0 +1,51 @@ +(function(app) { + + var old = app.HeroComponent; + + // #docregion + app.HeroComponent = HeroComponent; + + HeroComponent.annotations = [ + new ng.core.Component({ + selector: 'hero-di-inject', + template: '

    Hero: {{name}}

    ' + }) + ]; + + HeroComponent.parameters = [ 'heroName' ]; + + function HeroComponent(name) { + this.name = name; + } + // #enddocregion + + app.HeroDIInjectComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); + +/////// DSL version //////// + +(function(app) { + + var old = app.HeroComponent; + + // #docregion dsl + app.HeroComponent = ng.core.Component({ + selector: 'hero-di-inject-dsl', + template: '

    Hero: {{name}}

    ' + }) + .Class({ + constructor: [ + new ng.core.Inject('heroName'), + function HeroComponent(name) { + this.name = name; + } + ] + }); + // #enddocregion dsl + + app.HeroDIInjectDslComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero-di.component.js b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-di.component.js new file mode 100644 index 0000000000..2f49a85079 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-di.component.js @@ -0,0 +1,51 @@ +(function(app) { + + var old = app.HeroComponent; + + // #docregion + app.HeroComponent = HeroComponent; + + HeroComponent.annotations = [ + new ng.core.Component({ + selector: 'hero-di', + template: '

    Hero: {{name}}

    ' + }) + ]; + + HeroComponent.parameters = [ app.DataService ]; + + function HeroComponent(dataService) { + this.name = dataService.getHeroName(); + } + // #enddocregion + + app.HeroDIComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); + +////// DSL Version ///// + +(function(app) { + + var old = app.HeroComponent; + + // #docregion dsl + app.HeroComponent = ng.core.Component({ + selector: 'hero-di-dsl', + template: '

    Hero: {{name}}

    ' + }) + .Class({ + constructor: [ + app.DataService, + function HeroComponent(service) { + this.name = service.getHeroName(); + } + ] + }); + // #enddocregion dsl + + app.HeroDIDslComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero-host.component.js b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-host.component.js new file mode 100644 index 0000000000..b73e50aae0 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-host.component.js @@ -0,0 +1,107 @@ +(function(app) { + + var old = app.HeroComponent + + // #docregion + app.HeroComponent = HeroComponent; + + HeroComponent.annotations = [ + new ng.core.Component({ + selector: 'hero-host', + template: + '

    Hero Host

    ' + + '
    Heading clicks: {{clicks}}
    ', + host: { + // HostBindings to the element + '[title]': 'title', + '[class.heading]': 'headingClass', + '(click)': 'clicked()', + + // HostListeners on the entire element + '(mouseenter)': 'enter($event)', + '(mouseleave)': 'leave($event)' + }, + // Styles within (but excluding) the element + styles: ['.active {background-color: yellow;}'] + }) + ]; + + function HeroComponent() { + this.clicks = 0; + this.headingClass = true; + this.title = 'Hero Host Tooltip content'; + } + + HeroComponent.prototype.clicked = function() { + this.clicks += 1; + } + + HeroComponent.prototype.enter = function(event) { + this.active = true; + this.headingClass = false; + } + + HeroComponent.prototype.leave = function(event) { + this.active = false; + this.headingClass = true; + } + // #enddocregion + + app.HeroHostComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); + +//// DSL Version //// + +(function(app) { + + var old = app.HeroComponent; + + // #docregion dsl + app.HeroComponent = ng.core.Component({ + selector: 'hero-host-dsl', + template: ` +

    Hero Host (DSL)

    +
    Heading clicks: {{clicks}}
    + `, + host: { + // HostBindings to the element + '[title]': 'title', + '[class.heading]': 'headingClass', + '(click)': 'clicked()', + + // HostListeners on the entire element + '(mouseenter)': 'enter($event)', + '(mouseleave)': 'leave($event)' + }, + // Styles within (but excluding) the element + styles: ['.active {background-color: coral;}'] + }) + .Class({ + constructor: function HeroComponent() { + this.clicks = 0; + this.headingClass = true; + this.title = 'Hero Host Tooltip DSL content'; + }, + + clicked() { + this.clicks += 1; + }, + + enter(event) { + this.active = true; + this.headingClass = false; + }, + + leave(event) { + this.active = false; + this.headingClass = true; + } + }); + // #enddocregion dsl + + app.HeroHostDslComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero-io-dsl.component.html b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-io-dsl.component.html new file mode 100644 index 0000000000..c8023ccb45 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-io-dsl.component.html @@ -0,0 +1,7 @@ + + +OK clicked +Cancel clicked diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero-io.component.html b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-io.component.html new file mode 100644 index 0000000000..215ddccf92 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-io.component.html @@ -0,0 +1,7 @@ + + +OK clicked +Cancel clicked diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero-io.component.js b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-io.component.js new file mode 100644 index 0000000000..b09208ce68 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-io.component.js @@ -0,0 +1,52 @@ +(function(app) { + + var old = app.HeroComponent + + app.HeroComponent = HeroComponent; + + HeroComponent.annotations = [ + new ng.core.Component({ + selector: 'hero-io', + templateUrl: 'app/hero-io.component.html' + }) + ]; + + function HeroComponent() { } + + HeroComponent.prototype.onOk = function() { + this.okClicked = true; + } + + HeroComponent.prototype.onCancel = function() { + this.cancelClicked = true; + } + + app.HeroIOComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); + +///// DSL Version //// + +(function(app) { + + var old = app.HeroComponent + + app.HeroComponent = ng.core.Component({ + selector: 'hero-io-dsl', + templateUrl: 'app/hero-io-dsl.component.html' + }) + .Class({ + constructor: function HeroComponent() { }, + onOk: function() { + this.okClicked = true; + }, + onCancel: function() { + this.cancelClicked = true; + } + }); + + app.HeroIODslComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero-lifecycle.component.js b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-lifecycle.component.js new file mode 100644 index 0000000000..2a68288f92 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-lifecycle.component.js @@ -0,0 +1,52 @@ +// #docplaster +(function(app) { + + var old = app.HeroComponent; + + // #docregion + app.HeroComponent = HeroComponent; + + HeroComponent.annotations = [ + new ng.core.Component({ + selector: 'hero-lifecycle', + template: '

    Hero: {{name}}

    ' + }) + ]; + + function HeroComponent() { } + + HeroComponent.prototype.ngOnInit = function() { + // todo: fetch from server async + setTimeout(() => this.name = 'Windstorm', 0); + }; + // #enddocregion + + app.HeroLifecycleComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); + +/////// DSL version //// + +(function(app) { + + var old = app.HeroComponent; + + // #docregion dsl + app.HeroComponent = ng.core.Component({ + selector: 'hero-lifecycle-dsl', + template: '

    Hero: {{name}}

    ' + }) + .Class({ + constructor: function HeroComponent() { }, + ngOnInit: function() { + // todo: fetch from server async + setTimeout(() => this.name = 'Windstorm', 0); + } + }); + // #enddocregion dsl + + app.HeroLifecycleDslComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero-queries.component.js b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-queries.component.js new file mode 100644 index 0000000000..5e8de58d41 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-queries.component.js @@ -0,0 +1,92 @@ +(function(app) { + + app.heroQueries = app.heroQueries || {}; + + app.heroQueries.ContentChildComponent = ng.core.Component({ + selector: 'content-child', + template: + '' + + 'Active' + + '' + }).Class({ + constructor: function ContentChildComponent() { + this.active = false; + }, + + activate: function() { + this.active = !this.active; + } + }); + + //////////////////// + + // #docregion content + app.heroQueries.ViewChildComponent = ng.core.Component({ + selector: 'view-child', + template: + '

    ' + + '{{hero.name}} ' + + '' + + '

    ', + styles: ['.active {font-weight: bold; background-color: skyblue;}'], + inputs: ['hero'], + queries: { + content: new ng.core.ContentChild(app.heroQueries.ContentChildComponent) + } + }) + .Class({ + constructor: function HeroQueriesHeroComponent() { + this.active = false; + }, + + activate: function() { + this.active = !this.active; + this.content.activate(); + } + }); + // #enddocregion content + + //////////////////// + + // #docregion view + app.heroQueries.HeroQueriesComponent = ng.core.Component({ + selector: 'hero-queries', + template: + '' + + '' + + '' + + '', + queries: { + views: new ng.core.ViewChildren(app.heroQueries.ViewChildComponent) + } + }) + .Class({ + constructor: function HeroQueriesComponent() { + this.active = false; + this.heroData = [ + {id: 1, name: 'Windstorm'}, + {id: 2, name: 'LaughingGas'} + ]; + }, + + activate: function() { + this.active = !this.active; + this.views.forEach(function(view) { + view.activate(); + }); + }, + }); + + // #docregion defined-property + // add prototype property w/ getter outside the DSL + var proto = app.heroQueries.HeroQueriesComponent.prototype; + Object.defineProperty(proto, "buttonLabel", { + get: function () { + return this.active ? 'Deactivate' : 'Activate'; + }, + enumerable: true + }); + // #enddocregion defined-property + // #enddocregion view + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero-title.component.html b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-title.component.html new file mode 100644 index 0000000000..164683cb7c --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-title.component.html @@ -0,0 +1,4 @@ + +

    {{titlePrefix}} {{title}}

    + +

    {{ msg }}

    diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero-title.component.js b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-title.component.js new file mode 100644 index 0000000000..f0770e1228 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero-title.component.js @@ -0,0 +1,64 @@ +(function(app) { + + // #docregion + app.HeroTitleComponent = HeroTitleComponent; + + // #docregion templateUrl + HeroTitleComponent.annotations = [ + new ng.core.Component({ + selector: 'hero-title', + templateUrl: 'app/hero-title.component.html' + }) + ]; + // #enddocregion templateUrl + + function HeroTitleComponent(titlePrefix, title) { + this.titlePrefix = titlePrefix; + this.title = title; + this.msg = ''; + } + + HeroTitleComponent.prototype.ok = function() { + this.msg = 'OK!'; + } + + HeroTitleComponent.parameters = [ + [new ng.core.Optional(), new ng.core.Inject('titlePrefix')], + [new ng.core.Attribute('title')] + ]; + // #enddocregion + +})(window.app = window.app || {}); + +////////// DSL version //////////// + +(function(app) { + + var old = app.HeroTitleComponent; + + // #docregion dsl + app.HeroTitleComponent = ng.core.Component({ + selector: 'hero-title-dsl', + templateUrl: 'app/hero-title.component.html' + }) + .Class({ + constructor: [ + [ new ng.core.Optional(), new ng.core.Inject('titlePrefix') ], + new ng.core.Attribute('title'), + function HeroTitleComponent(titlePrefix, title) { + this.titlePrefix = titlePrefix; + this.title = title; + this.msg = ''; + } + ], + + ok: function() { + this.msg = 'OK!'; + } + }); + // #enddocregion dsl + + app.HeroTitleDslComponent = app.HeroTitleComponent; + app.HeroTitleComponent = old; + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/app/hero.component.js b/public/docs/_examples/cb-ts-to-js/js/src/app/hero.component.js new file mode 100644 index 0000000000..e1407b2635 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/app/hero.component.js @@ -0,0 +1,53 @@ +// #docplaster +(function(app) { + +// #docregion +// #docregion appexport +// #docregion metadata +app.HeroComponent = HeroComponent; // "export" + +HeroComponent.annotations = [ + new ng.core.Component({ + selector: 'hero-view', + template: '

    {{title}}: {{getName()}}

    ' + }) +]; + +// #docregion constructorproto +function HeroComponent() { + this.title = "Hero Detail"; +} + +HeroComponent.prototype.getName = function() { return 'Windstorm'; }; +// #enddocregion constructorproto + +// #enddocregion metadata +// #enddocregion appexport +// #enddocregion + +})(window.app = window.app || {}); + +//////////// DSL version /////////// + +(function(app) { + + var old = app.HeroComponent; + + // #docregion dsl + app.HeroComponent = ng.core.Component({ + selector: 'hero-view-dsl', + template: '

    {{title}}: {{getName()}}

    ', + }) + .Class({ + constructor: function HeroComponent() { + this.title = "Hero Detail"; + }, + + getName: function() { return 'Windstorm'; } + }); + // #enddocregion dsl + + app.HeroDslComponent = app.HeroComponent; + app.HeroComponent = old; + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/js/src/index.html b/public/docs/_examples/cb-ts-to-js/js/src/index.html new file mode 100644 index 0000000000..00338aa55a --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/index.html @@ -0,0 +1,43 @@ + + + + + + + TypeScript to JavaScript + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/cb-ts-to-js/js/src/main.js b/public/docs/_examples/cb-ts-to-js/js/src/main.js new file mode 100644 index 0000000000..fd3e737c9e --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/js/src/main.js @@ -0,0 +1,9 @@ +(function(app) { + +var platformBrowserDynamic = ng.platformBrowserDynamic.platformBrowserDynamic; + +document.addEventListener('DOMContentLoaded', function() { + platformBrowserDynamic().bootstrapModule(app.AppModule); +}); + +})(window.app = window.app || {}); diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/data.service.ts b/public/docs/_examples/cb-ts-to-js/ts/app/data.service.ts deleted file mode 100644 index 7e9c7456c6..0000000000 --- a/public/docs/_examples/cb-ts-to-js/ts/app/data.service.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class DataService { - constructor() { - } - getHeroName() { - return 'Windstorm'; - } -} diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/hero-di-inject-additional.component.ts b/public/docs/_examples/cb-ts-to-js/ts/app/hero-di-inject-additional.component.ts deleted file mode 100644 index 6ed0b9166d..0000000000 --- a/public/docs/_examples/cb-ts-to-js/ts/app/hero-di-inject-additional.component.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { - Attribute, - Component, - ElementRef, - Inject, - Optional, - Query, - QueryList -} from '@angular/core'; - -// #docregion -@Component({ - selector: 'hero-title', - template: ` -

    {{titlePrefix}} {{title}}

    - - - ` -}) -export class TitleComponent { - constructor( - @Inject('titlePrefix') - @Optional() - private titlePrefix:string, - @Attribute('title') - private title:string, - @Query('okMsg') - private msg:QueryList) { - } - - ok() { - let msgEl = - this.msg.first.nativeElement; - msgEl.textContent = 'OK!'; - } -} -// #enddocregion - -@Component({ - selector: 'hero-di-inject-additional', - template: ` - - `, - directives: [TitleComponent] -}) -export class AppComponent { - -} diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/hero-di-inject.component.ts b/public/docs/_examples/cb-ts-to-js/ts/app/hero-di-inject.component.ts deleted file mode 100644 index 5d78a5cbbf..0000000000 --- a/public/docs/_examples/cb-ts-to-js/ts/app/hero-di-inject.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component, Inject } from '@angular/core'; - -// #docregion -@Component({ - selector: 'hero-di-inject', - template: `

    Hero: {{name}}

    ` -}) -export class HeroComponent { - constructor( - @Inject('heroName') - private name:string) { - } -} -// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/hero-di.component.ts b/public/docs/_examples/cb-ts-to-js/ts/app/hero-di.component.ts deleted file mode 100644 index e6b81b6af7..0000000000 --- a/public/docs/_examples/cb-ts-to-js/ts/app/hero-di.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component } from '@angular/core'; - -import { DataService } from './data.service'; - -// #docregion -@Component({ - selector: 'hero-di', - template: `

    Hero: {{name}}

    ` -}) -export class HeroComponent { - name:string; - constructor(dataService:DataService) { - this.name = dataService.getHeroName(); - } -} -// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/hero-io.component.ts b/public/docs/_examples/cb-ts-to-js/ts/app/hero-io.component.ts deleted file mode 100644 index 936bf2854e..0000000000 --- a/public/docs/_examples/cb-ts-to-js/ts/app/hero-io.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; - -// #docregion -@Component({ - selector: 'my-confirm', - template: ` - - - ` -}) -export class ConfirmComponent { - @Input() okMsg:string; - @Input('cancelMsg') notOkMsg:string; - @Output() ok = - new EventEmitter(); - @Output('cancel') notOk = - new EventEmitter(); - - onOkClick() { - this.ok.next(true); - } - onNotOkClick() { - this.notOk.next(true); - } -} -// #enddocregion - - -@Component({ - selector: 'hero-io', - template: ` - - - OK clicked - Cancel clicked - `, - directives: [ConfirmComponent] -}) -export class AppComponent { - okClicked:boolean; - cancelClicked:boolean; - - onOk() { - this.okClicked = true; - } - onCancel() { - this.cancelClicked = true; - } -} diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/hero-lifecycle.component.ts b/public/docs/_examples/cb-ts-to-js/ts/app/hero-lifecycle.component.ts deleted file mode 100644 index 94d79274fc..0000000000 --- a/public/docs/_examples/cb-ts-to-js/ts/app/hero-lifecycle.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -// #docplaster -// #docregion -import { Component, OnInit } - from '@angular/core'; - // #enddocregion - -@Component({ - selector: 'hero-lifecycle', - template: `

    Hero: {{name}}

    ` -}) -// #docregion -export class HeroComponent - implements OnInit { - name:string; - ngOnInit() { - this.name = 'Windstorm'; - } -} -// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/hero.component.ts b/public/docs/_examples/cb-ts-to-js/ts/app/hero.component.ts deleted file mode 100644 index 85d2772c63..0000000000 --- a/public/docs/_examples/cb-ts-to-js/ts/app/hero.component.ts +++ /dev/null @@ -1,18 +0,0 @@ -// #docplaster -// #docregion metadata -import { Component } from '@angular/core'; - -@Component({ - selector: 'hero-view', - template: - '

    Hero: {{getName()}}

    ' -}) -// #docregion appexport -// #docregion class -export class HeroComponent { - title = 'Hero Detail'; - getName() {return 'Windstorm';} -} -// #enddocregion class -// #enddocregion appexport -// #enddocregion metadata diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/heroes-bindings.component.ts b/public/docs/_examples/cb-ts-to-js/ts/app/heroes-bindings.component.ts deleted file mode 100644 index 317d434b9d..0000000000 --- a/public/docs/_examples/cb-ts-to-js/ts/app/heroes-bindings.component.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Component, HostBinding, HostListener } from '@angular/core'; - -// #docregion -@Component({ - selector: 'heroes-bindings', - template: `

    - Tour ofHeroes -

    ` -}) -export class HeroesComponent { - @HostBinding() title = 'Tooltip content'; - @HostBinding('class.heading') - hClass = true - active:boolean; - - constructor() {} - - @HostListener('click') - clicked() { - this.active = !this.active; - } - - @HostListener('dblclick', ['$event']) - doubleClicked(evt:Event) { - this.active = true; - } -} -// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/heroes-queries.component.ts b/public/docs/_examples/cb-ts-to-js/ts/app/heroes-queries.component.ts deleted file mode 100644 index 68ccb975e7..0000000000 --- a/public/docs/_examples/cb-ts-to-js/ts/app/heroes-queries.component.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { - Component, - ViewChildren, - ContentChild, - QueryList, - Input -} from '@angular/core'; - -@Component({ - selector: 'active-label', - template: ` - Active - ` -}) -class ActiveLabelComponent { - active:boolean; - - activate() { - this.active = true; - } -} - -// #docregion content -@Component({ - selector: 'hero', - template: `

    - {{hero.name}} - -

    ` -}) -class HeroComponent { - @Input() hero:any; - active:boolean; - - @ContentChild(ActiveLabelComponent) - label:ActiveLabelComponent - - activate() { - this.active = true; - this.label.activate(); - } -} -// #enddocregion content - - -// #docregion view -@Component({ - selector: 'heroes-queries', - template: ` - - - - - `, - directives: [ - HeroComponent, - ActiveLabelComponent - ] -}) -export class HeroesQueriesComponent { - heroData = [ - {id: 1, name: 'Windstorm'}, - {id: 2, name: 'Superman'} - ]; - - @ViewChildren(HeroComponent) - heroCmps:QueryList; - - activate() { - this.heroCmps.forEach( - (cmp) => cmp.activate() - ); - } -} -// #enddocregion view diff --git a/public/docs/_examples/cb-ts-to-js/ts/app/main.ts b/public/docs/_examples/cb-ts-to-js/ts/app/main.ts deleted file mode 100644 index ea8f8377e1..0000000000 --- a/public/docs/_examples/cb-ts-to-js/ts/app/main.ts +++ /dev/null @@ -1,35 +0,0 @@ -// #docregion ng2import -import { bootstrap } - from '@angular/platform-browser-dynamic'; -import { -} from '@angular/router'; -import { - LocationStrategy, - HashLocationStrategy -} from '@angular/common'; -// #enddocregion ng2import - -// #docregion appimport -import { HeroComponent } - from './hero.component'; -// #enddocregion appimport -import { HeroComponent as HeroLifecycleComponent } from './hero-lifecycle.component'; -import { HeroComponent as HeroDIComponent } from './hero-di.component'; -import { HeroComponent as HeroDIInjectComponent } from './hero-di-inject.component'; -import { AppComponent as AppDIInjectAdditionalComponent } from './hero-di-inject-additional.component'; -import { AppComponent as AppIOComponent } from './hero-io.component'; -import { HeroesComponent as HeroesHostBindingsComponent } from './heroes-bindings.component'; -import { HeroesQueriesComponent } from './heroes-queries.component'; - -import { DataService } from './data.service'; - -bootstrap(HeroComponent); -bootstrap(HeroLifecycleComponent); -bootstrap(HeroDIComponent, [DataService]); -bootstrap(HeroDIInjectComponent, [ - { provide: 'heroName', useValue: 'Windstorm' } -]); -bootstrap(AppDIInjectAdditionalComponent); -bootstrap(AppIOComponent); -bootstrap(HeroesHostBindingsComponent); -bootstrap(HeroesQueriesComponent); diff --git a/public/docs/_examples/cb-ts-to-js/ts/index.html b/public/docs/_examples/cb-ts-to-js/ts/index.html deleted file mode 100644 index 005fe67c31..0000000000 --- a/public/docs/_examples/cb-ts-to-js/ts/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - -

    TypeScript to JavaScript

    - Classes and Class Metadata
    - Input and Output Metadata
    - Dependency Injection
    - Host and Query Metadata
    - -
    -

    Classes and Class Metadata

    - Loading hero-view... - Loading hero-lifecycle... - -
    -

    Input and Output Metadata

    - Loading hero-io... - -
    -

    Dependency Injection

    - Loading hero-di... - Loading hero-di-inject... - Loading hero-di-inject-additional... - -
    -

    Host and Query Metadata

    - Loading heroes-bindings... - Loading heroes-queries... - - - diff --git a/public/docs/_examples/cb-ts-to-js/ts/plnkr.json b/public/docs/_examples/cb-ts-to-js/ts/plnkr.json index 5c7a5acd44..447fc5f605 100644 --- a/public/docs/_examples/cb-ts-to-js/ts/plnkr.json +++ b/public/docs/_examples/cb-ts-to-js/ts/plnkr.json @@ -1,5 +1,6 @@ { "description": "TypeScript to JavaScript", + "basePath": "src/", "files":[ "!**/*.d.ts", "!**/*.js" diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/app.component.html b/public/docs/_examples/cb-ts-to-js/ts/src/app/app.component.html new file mode 100644 index 0000000000..995645073a --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/app.component.html @@ -0,0 +1,31 @@ + +

    {{title}}

    +Classes and Class Metadata
    +Input and Output Decorators
    +Dependency Injection
    +Host Metadata
    +View and Child Metadata
    + +
    +

    Classes and Class Metadata

    + + + +
    +

    Input and Output Metadata

    + + +
    +

    Dependency Injection

    + + + + +
    +

    Host Metadata

    + + + +
    +

    View and Child Metadata

    + diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/app.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/app.component.ts new file mode 100644 index 0000000000..912c9e1a80 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/app.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html', + styles: [ + // See hero-di-inject-additional.component + 'hero-host, hero-host-meta { border: 1px dashed black; display: block; padding: 4px;}', + '.heading {font-style: italic}' + ] +}) +export class AppComponent { + title = 'TypeScript'; +} diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/app.module.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/app.module.ts new file mode 100644 index 0000000000..992c3c3514 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/app.module.ts @@ -0,0 +1,56 @@ +/* tslint:disable-next-line:no-unused-variable */ +import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { ConfirmComponent } from './confirm.component'; +// #docregion appimport +import { HeroComponent } from './hero.component'; +// #enddocregion appimport +import { HeroComponent as HeroDIComponent } from './hero-di.component'; +import { HeroComponent as HeroDIInjectComponent } from './hero-di-inject.component'; +import { HeroComponent as HeroDIInjectAdditionalComponent } from './hero-di-inject-additional.component'; +import { HeroHostComponent } from './hero-host.component'; +import { HeroHostMetaComponent } from './hero-host-meta.component'; +import { HeroIOComponent } from './hero-io.component'; +import { HeroComponent as HeroLifecycleComponent } from './hero-lifecycle.component'; +import { HeroQueriesComponent, ViewChildComponent, ContentChildComponent } from './hero-queries.component'; +import { HeroTitleComponent } from './hero-title.component'; + +import { DataService } from './data.service'; + +@NgModule({ + imports: [ + BrowserModule + ], + declarations: [ + AppComponent, + ConfirmComponent, + HeroComponent, + HeroDIComponent, + HeroDIInjectComponent, + HeroDIInjectAdditionalComponent, + HeroHostComponent, HeroHostMetaComponent, + HeroIOComponent, + HeroLifecycleComponent, + HeroQueriesComponent, ViewChildComponent, ContentChildComponent, + HeroTitleComponent + ], + providers: [ + DataService, + { provide: 'heroName', useValue: 'Windstorm' } + ], + bootstrap: [ AppComponent ], + + // schemas: [ NO_ERRORS_SCHEMA ] // helpful for debugging! +}) +export class AppModule { } + +/* tslint:disable no-unused-variable */ +// #docregion ng2import +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { + LocationStrategy, + HashLocationStrategy +} from '@angular/common'; +// #enddocregion ng2import diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/confirm.component.html b/public/docs/_examples/cb-ts-to-js/ts/src/app/confirm.component.html new file mode 100644 index 0000000000..45275d218a --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/confirm.component.html @@ -0,0 +1,6 @@ + + diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/confirm.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/confirm.component.ts new file mode 100644 index 0000000000..f01fa4de40 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/confirm.component.ts @@ -0,0 +1,21 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; + +// #docregion +@Component({ + selector: 'app-confirm', + templateUrl: './confirm.component.html' +}) +export class ConfirmComponent { + @Input() okMsg = ''; + @Input('cancelMsg') notOkMsg = ''; + @Output() ok = new EventEmitter(); + @Output('cancel') notOk = new EventEmitter(); + + onOkClick() { + this.ok.emit(true); + } + onNotOkClick() { + this.notOk.emit(true); + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/data.service.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/data.service.ts new file mode 100644 index 0000000000..cd7f9e1aae --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/data.service.ts @@ -0,0 +1,10 @@ +import { Injectable } from '@angular/core'; + +@Injectable() +export class DataService { + constructor() { } + + getHeroName() { + return 'Windstorm'; + } +} diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-di-inject-additional.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-di-inject-additional.component.ts new file mode 100644 index 0000000000..ec460a9dbc --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-di-inject-additional.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'hero-di-inject-additional', + template: `` +}) +export class HeroComponent { } diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-di-inject.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-di-inject.component.ts new file mode 100644 index 0000000000..c583a1b0f6 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-di-inject.component.ts @@ -0,0 +1,11 @@ +import { Component, Inject } from '@angular/core'; + +// #docregion +@Component({ + selector: 'hero-di-inject', + template: `

    Hero: {{name}}

    ` +}) +export class HeroComponent { + constructor(@Inject('heroName') private name: string) { } +} +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-di.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-di.component.ts new file mode 100644 index 0000000000..3a17abd281 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-di.component.ts @@ -0,0 +1,15 @@ +// #docregion +import { Component } from '@angular/core'; +import { DataService } from './data.service'; + +@Component({ + selector: 'hero-di', + template: `

    Hero: {{name}}

    ` +}) +export class HeroComponent { + name = ''; + constructor(dataService: DataService) { + this.name = dataService.getHeroName(); + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-host-meta.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-host-meta.component.ts new file mode 100644 index 0000000000..fefe4a5470 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-host-meta.component.ts @@ -0,0 +1,44 @@ +import { Component } from '@angular/core'; + +// #docregion +@Component({ + selector: 'hero-host-meta', + template: ` +

    Hero Host in Metadata

    +
    Heading clicks: {{clicks}}
    + `, + host: { + // HostBindings to the element + '[title]': 'title', + '[class.heading]': 'headingClass', + + // HostListeners on the entire element + '(click)': 'clicked()', + '(mouseenter)': 'enter($event)', + '(mouseleave)': 'leave($event)' + }, + // Styles within (but excluding) the element + styles: ['.active {background-color: coral;}'] +}) +export class HeroHostMetaComponent { + title = 'Hero Host in Metadata Tooltip'; + headingClass = true; + + active = false; + clicks = 0; + + clicked() { + this.clicks += 1; + } + + enter(event: Event) { + this.active = true; + this.headingClass = false; + } + + leave(event: Event) { + this.active = false; + this.headingClass = true; + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-host.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-host.component.ts new file mode 100644 index 0000000000..e8d72233c8 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-host.component.ts @@ -0,0 +1,39 @@ +import { Component, HostBinding, HostListener } from '@angular/core'; + +// #docregion +@Component({ + selector: 'hero-host', + template: ` +

    Hero Host in Decorators

    +
    Heading clicks: {{clicks}}
    + `, + // Styles within (but excluding) the element + styles: ['.active {background-color: yellow;}'] +}) +export class HeroHostComponent { + // HostBindings to the element + @HostBinding() title = 'Hero Host in Decorators Tooltip'; + @HostBinding('class.heading') headingClass = true; + + active = false; + clicks = 0; + + // HostListeners on the entire element + @HostListener('click') + clicked() { + this.clicks += 1; + } + + @HostListener('mouseenter', ['$event']) + enter(event: Event) { + this.active = true; + this.headingClass = false; + } + + @HostListener('mouseleave', ['$event']) + leave(event: Event) { + this.active = false; + this.headingClass = true; + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-io.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-io.component.ts new file mode 100644 index 0000000000..4b36411e78 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-io.component.ts @@ -0,0 +1,26 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'hero-io', + template: ` + + + OK clicked + Cancel clicked + ` +}) +export class HeroIOComponent { + okClicked = false; + cancelClicked = false; + + onOk() { + this.okClicked = true; + } + + onCancel() { + this.cancelClicked = true; + } +} diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-lifecycle.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-lifecycle.component.ts new file mode 100644 index 0000000000..2629c85a1a --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-lifecycle.component.ts @@ -0,0 +1,14 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'hero-lifecycle', + template: `

    Hero: {{name}}

    ` +}) +export class HeroComponent implements OnInit { + name: string; + ngOnInit() { + // todo: fetch from server async + setTimeout(() => this.name = 'Windstorm', 0); + } +} diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-queries.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-queries.component.ts new file mode 100644 index 0000000000..8b2d91ea85 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-queries.component.ts @@ -0,0 +1,83 @@ +import { + Component, + ContentChild, + Input, + QueryList, + ViewChildren +} from '@angular/core'; + +@Component({ + selector: 'content-child', + template: ` + + Active + ` +}) +export class ContentChildComponent { + active = false; + + activate() { + this.active = !this.active; + } +} + +//////////////////// + +// #docregion content +@Component({ + selector: 'view-child', + template: ` +

    + {{hero.name}} + +

    `, + styles: ['.active {font-weight: bold; background-color: skyblue;}'] +}) +export class ViewChildComponent { + @Input() hero: any; + active = false; + + @ContentChild(ContentChildComponent) content: ContentChildComponent; + + activate() { + this.active = !this.active; + this.content.activate(); + } +} +// #enddocregion content + +//////////////////// + +// #docregion view +@Component({ + selector: 'hero-queries', + template: ` + + + + + ` +}) +export class HeroQueriesComponent { + active = false; + heroData = [ + {id: 1, name: 'Windstorm'}, + {id: 2, name: 'LaughingGas'} + ]; + + @ViewChildren(ViewChildComponent) views: QueryList; + + activate() { + this.active = !this.active; + this.views.forEach( + view => view.activate() + ); + } + + // #docregion defined-property + get buttonLabel() { + return this.active ? 'Deactivate' : 'Activate'; + } + // #enddocregion defined-property +} +// #enddocregion view diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-title.component.html b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-title.component.html new file mode 100644 index 0000000000..164683cb7c --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-title.component.html @@ -0,0 +1,4 @@ + +

    {{titlePrefix}} {{title}}

    + +

    {{ msg }}

    diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-title.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-title.component.ts new file mode 100644 index 0000000000..48aaae7d44 --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero-title.component.ts @@ -0,0 +1,21 @@ +import { Attribute, Component, Inject, Optional } from '@angular/core'; + +// #docregion +// #docregion templateUrl +@Component({ + selector: 'hero-title', + templateUrl: './hero-title.component.html' +}) +// #enddocregion templateUrl +export class HeroTitleComponent { + msg: string = ''; + constructor( + @Inject('titlePrefix') @Optional() private titlePrefix: string, + @Attribute('title') private title: string + ) { } + + ok() { + this.msg = 'OK!'; + } +} +// #enddocregion diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/app/hero.component.ts b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero.component.ts new file mode 100644 index 0000000000..2976ec605e --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/app/hero.component.ts @@ -0,0 +1,15 @@ +// #docregion +// #docregion metadata +import { Component } from '@angular/core'; + +@Component({ + selector: 'hero-view', + template: '

    {{title}}: {{getName()}}

    ' +}) +// #docregion appexport, class +export class HeroComponent { + title = 'Hero Detail'; + getName() {return 'Windstorm'; } +} +// #enddocregion appexport, class +// #enddocregion metadata diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/index.html b/public/docs/_examples/cb-ts-to-js/ts/src/index.html new file mode 100644 index 0000000000..d9ad1f7aef --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/index.html @@ -0,0 +1,26 @@ + + + + + + + + TypeScript to JavaScript + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/cb-ts-to-js/ts/src/main.ts b/public/docs/_examples/cb-ts-to-js/ts/src/main.ts new file mode 100644 index 0000000000..f22933ba8e --- /dev/null +++ b/public/docs/_examples/cb-ts-to-js/ts/src/main.ts @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cb-visual-studio-2015/ts/.gitignore b/public/docs/_examples/cb-visual-studio-2015/ts/.gitignore new file mode 100644 index 0000000000..ca3f2dbd5e --- /dev/null +++ b/public/docs/_examples/cb-visual-studio-2015/ts/.gitignore @@ -0,0 +1 @@ +!tsconfig.json diff --git a/public/docs/_examples/cb-visual-studio-2015/ts/tsconfig.json b/public/docs/_examples/cb-visual-studio-2015/ts/tsconfig.json new file mode 100644 index 0000000000..2624488890 --- /dev/null +++ b/public/docs/_examples/cb-visual-studio-2015/ts/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "removeComments": false, + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "node_modules/@types" + ] + }, + "compileOnSave": true +} diff --git a/public/docs/_examples/cli-quickstart/e2e-spec.ts b/public/docs/_examples/cli-quickstart/e2e-spec.ts new file mode 100644 index 0000000000..59816e13c2 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/e2e-spec.ts @@ -0,0 +1,14 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + +describe('cli-quickstart App', () => { + beforeEach(() => { + return browser.get('/'); + }); + + it('should display message saying app works', () => { + let pageTitle = element(by.css('app-root h1')).getText(); + expect(pageTitle).toEqual('My First Angular App'); + }); +}); diff --git a/public/docs/_examples/cli-quickstart/ts/.angular-cli.json b/public/docs/_examples/cli-quickstart/ts/.angular-cli.json new file mode 100644 index 0000000000..49a6b93bd0 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/.angular-cli.json @@ -0,0 +1,57 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "project": { + "name": "master-project" + }, + "apps": [ + { + "root": "src", + "outDir": "dist", + "assets": [ + "assets", + "favicon.ico" + ], + "index": "index.html", + "main": "main.ts", + "polyfills": "polyfills.ts", + "test": "test.ts", + "tsconfig": "tsconfig.app.json", + "testTsconfig": "tsconfig.spec.json", + "prefix": "app", + "styles": [ + "styles.css" + ], + "scripts": [], + "environmentSource": "environments/environment.ts", + "environments": { + "dev": "environments/environment.ts", + "prod": "environments/environment.prod.ts" + } + } + ], + "e2e": { + "protractor": { + "config": "./protractor.conf.js" + } + }, + "lint": [ + { + "project": "src/tsconfig.app.json" + }, + { + "project": "src/tsconfig.spec.json" + }, + { + "project": "e2e/tsconfig.e2e.json" + } + ], + "test": { + "karma": { + "config": "./karma.conf.js" + } + }, + "defaults": { + "styleExt": "css", + "component": {} + } +} diff --git a/public/docs/_examples/cli-quickstart/ts/.editorconfig b/public/docs/_examples/cli-quickstart/ts/.editorconfig new file mode 100644 index 0000000000..6e87a003da --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/public/docs/_examples/cli-quickstart/ts/.gitignore b/public/docs/_examples/cli-quickstart/ts/.gitignore new file mode 100644 index 0000000000..04a48dc643 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/.gitignore @@ -0,0 +1,45 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp + +# dependencies +/node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage/* +/libpeerconnection.log +npm-debug.log +testem.log +/typings + +# e2e +/e2e/*.js +/e2e/*.map + +#System Files +.DS_Store +Thumbs.db + +!src/styles.css +!karma.conf.js +!protractor.conf.js diff --git a/public/docs/_examples/cli-quickstart/ts/README.md b/public/docs/_examples/cli-quickstart/ts/README.md new file mode 100644 index 0000000000..efe9ec67ae --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/README.md @@ -0,0 +1,27 @@ +# MasterProject + +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.0-rc.0. + +## Development server +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. + +## Running unit tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Running end-to-end tests + +Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). +Before running the tests make sure you are serving the app via `ng serve`. + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). diff --git a/public/docs/_examples/cli-quickstart/ts/bs-config.cli.json b/public/docs/_examples/cli-quickstart/ts/bs-config.cli.json new file mode 100644 index 0000000000..ac61d35f83 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/bs-config.cli.json @@ -0,0 +1,11 @@ +{ + "open": false, + "logLevel": "silent", + "port": 8080, + "server": { + "baseDir": "dist", + "middleware": { + "0": null + } + } +} diff --git a/public/docs/_examples/cli-quickstart/ts/e2e/app.e2e-spec.ts b/public/docs/_examples/cli-quickstart/ts/e2e/app.e2e-spec.ts new file mode 100644 index 0000000000..4346d120c8 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/e2e/app.e2e-spec.ts @@ -0,0 +1,14 @@ +import { MyAppPage } from './app.po'; + +describe('my-app App', function() { + let page: MyAppPage; + + beforeEach(() => { + page = new MyAppPage(); + }); + + it('should display message saying app works', () => { + page.navigateTo(); + expect(page.getParagraphText()).toEqual('app works!'); + }); +}); diff --git a/public/docs/_examples/cli-quickstart/ts/e2e/app.po.ts b/public/docs/_examples/cli-quickstart/ts/e2e/app.po.ts new file mode 100644 index 0000000000..5d82157326 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/e2e/app.po.ts @@ -0,0 +1,11 @@ +import { browser, element, by } from 'protractor'; + +export class MyAppPage { + navigateTo() { + return browser.get('/'); + } + + getParagraphText() { + return element(by.css('app-root h1')).getText(); + } +} diff --git a/public/docs/_examples/cli-quickstart/ts/e2e/tsconfig.e2e.json b/public/docs/_examples/cli-quickstart/ts/e2e/tsconfig.e2e.json new file mode 100644 index 0000000000..74c2bca131 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/e2e/tsconfig.e2e.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ + "es2016" + ], + "outDir": "../dist/out-tsc-e2e", + "module": "commonjs", + "target": "es6", + "types":[ + "jasmine", + "node" + ] + } +} diff --git a/public/docs/_examples/cli-quickstart/ts/example-config.json b/public/docs/_examples/cli-quickstart/ts/example-config.json new file mode 100644 index 0000000000..313764c3c6 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/example-config.json @@ -0,0 +1,4 @@ +{ + "build": "build:cli", + "run": "serve:cli" +} diff --git a/public/docs/_examples/cli-quickstart/ts/karma.conf.js b/public/docs/_examples/cli-quickstart/ts/karma.conf.js new file mode 100644 index 0000000000..84b4cd5aca --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/karma.conf.js @@ -0,0 +1,44 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/0.13/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular/cli'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage-istanbul-reporter'), + require('@angular/cli/plugins/karma') + ], + client:{ + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + files: [ + { pattern: './src/test.ts', watched: false } + ], + preprocessors: { + './src/test.ts': ['@angular/cli'] + }, + mime: { + 'text/x-typescript': ['ts','tsx'] + }, + coverageIstanbulReporter: { + reports: [ 'html', 'lcovonly' ], + fixWebpackSourcePaths: true + }, + angularCli: { + environment: 'dev' + }, + reporters: config.angularCli && config.angularCli.codeCoverage + ? ['progress', 'coverage-istanbul'] + : ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false + }); +}; diff --git a/public/docs/_examples/cli-quickstart/ts/protractor.conf.js b/public/docs/_examples/cli-quickstart/ts/protractor.conf.js new file mode 100644 index 0000000000..2cbc329391 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/protractor.conf.js @@ -0,0 +1,31 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +/*global jasmine */ +const { SpecReporter } = require('jasmine-spec-reporter'); + +exports.config = { + allScriptsTimeout: 11000, + specs: [ + './e2e/**/*.e2e-spec.ts' + ], + capabilities: { + 'browserName': 'chrome' + }, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function() {} + }, + beforeLaunch: function() { + require('ts-node').register({ + project: 'e2e/tsconfig.e2e.json' + }); + }, + onPrepare() { + jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + } +}; diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/app.component.css b/public/docs/_examples/cli-quickstart/ts/src/app/app.component.css new file mode 100644 index 0000000000..a2b21fae82 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/app/app.component.css @@ -0,0 +1,6 @@ +/* #docregion */ +h1 { + color: #369; + font-family: Arial, Helvetica, sans-serif; + font-size: 250%; +} diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/app.component.html b/public/docs/_examples/cli-quickstart/ts/src/app/app.component.html new file mode 100644 index 0000000000..b6931b538a --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/app/app.component.html @@ -0,0 +1,3 @@ +

    + {{title}} +

    diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/app.component.spec.ts b/public/docs/_examples/cli-quickstart/ts/src/app/app.component.spec.ts new file mode 100644 index 0000000000..c740bcd745 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/app/app.component.spec.ts @@ -0,0 +1,32 @@ +import { TestBed, async } from '@angular/core/testing'; + +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + AppComponent + ], + }).compileComponents(); + })); + + it('should create the app', async(() => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + })); + + it(`should have as title 'app works!'`, async(() => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('app works!'); + })); + + it('should render title in a h1 tag', async(() => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('app works!'); + })); +}); diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/app.component.ts b/public/docs/_examples/cli-quickstart/ts/src/app/app.component.ts new file mode 100644 index 0000000000..4c1b4a9bf7 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/app/app.component.ts @@ -0,0 +1,16 @@ +// #docregion import +import { Component } from '@angular/core'; +// #enddocregion import + +// #docregion metadata +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'] +}) +// #enddocregion metadata +// #docregion title, class +export class AppComponent { + title = 'My First Angular App'; +} +// #enddocregion title, class diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/app.module.ts b/public/docs/_examples/cli-quickstart/ts/src/app/app.module.ts new file mode 100644 index 0000000000..67ae49119b --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/app/app.module.ts @@ -0,0 +1,20 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +import { AppComponent } from './app.component'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ + BrowserModule, + FormsModule, + HttpModule + ], + providers: [], + bootstrap: [AppComponent] +}) +export class AppModule { } diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/.gitkeep b/public/docs/_examples/cli-quickstart/ts/src/assets/.gitkeep similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/.gitkeep rename to public/docs/_examples/cli-quickstart/ts/src/assets/.gitkeep diff --git a/public/docs/_examples/cli-quickstart/ts/src/environments/environment.prod.ts b/public/docs/_examples/cli-quickstart/ts/src/environments/environment.prod.ts new file mode 100644 index 0000000000..3612073bc3 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true +}; diff --git a/public/docs/_examples/cli-quickstart/ts/src/environments/environment.ts b/public/docs/_examples/cli-quickstart/ts/src/environments/environment.ts new file mode 100644 index 0000000000..b7f639aeca --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/environments/environment.ts @@ -0,0 +1,8 @@ +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. + +export const environment = { + production: false +}; diff --git a/public/docs/_examples/cli-quickstart/ts/src/favicon.ico b/public/docs/_examples/cli-quickstart/ts/src/favicon.ico new file mode 100644 index 0000000000..8081c7ceaf Binary files /dev/null and b/public/docs/_examples/cli-quickstart/ts/src/favicon.ico differ diff --git a/public/docs/_examples/cli-quickstart/ts/src/index.html b/public/docs/_examples/cli-quickstart/ts/src/index.html new file mode 100644 index 0000000000..8a1a7b32b3 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/index.html @@ -0,0 +1,14 @@ + + + + + MyApp + + + + + + + Loading... + + diff --git a/public/docs/_examples/cli-quickstart/ts/src/main.ts b/public/docs/_examples/cli-quickstart/ts/src/main.ts new file mode 100644 index 0000000000..a9ca1caf8c --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/main.ts @@ -0,0 +1,11 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/cli-quickstart/ts/src/polyfills.ts b/public/docs/_examples/cli-quickstart/ts/src/polyfills.ts new file mode 100644 index 0000000000..53bdaf1b86 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/polyfills.ts @@ -0,0 +1,68 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/set'; + +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** IE10 and IE11 requires the following to support `@angular/animation`. */ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + + +/** Evergreen browsers require these. **/ +import 'core-js/es6/reflect'; +import 'core-js/es7/reflect'; + + +/** ALL Firefox browsers require the following to support `@angular/animation`. **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + + + +/*************************************************************************************************** + * Zone JS is required by Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ + +/** + * Date, currency, decimal and percent pipes. + * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 + */ +// import 'intl'; // Run `npm install --save intl`. diff --git a/public/docs/_examples/cli-quickstart/ts/src/styles.css b/public/docs/_examples/cli-quickstart/ts/src/styles.css new file mode 100644 index 0000000000..d81835d0cd --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/styles.css @@ -0,0 +1,116 @@ +/* #docregion , quickstart, toh */ +/* Master Styles */ +h1 { + color: #369; + font-family: Arial, Helvetica, sans-serif; + font-size: 250%; +} +h2, h3 { + color: #444; + font-family: Arial, Helvetica, sans-serif; + font-weight: lighter; +} +body { + margin: 2em; +} +/* #enddocregion quickstart */ +body, input[text], button { + color: #888; + font-family: Cambria, Georgia; +} +/* #enddocregion toh */ +a { + cursor: pointer; + cursor: hand; +} +button { + font-family: Arial; + background-color: #eee; + border: none; + padding: 5px 10px; + border-radius: 4px; + cursor: pointer; + cursor: hand; +} +button:hover { + background-color: #cfd8dc; +} +button:disabled { + background-color: #eee; + color: #aaa; + cursor: auto; +} + +/* Navigation link styles */ +nav a { + padding: 5px 10px; + text-decoration: none; + margin-right: 10px; + margin-top: 10px; + display: inline-block; + background-color: #eee; + border-radius: 4px; +} +nav a:visited, a:link { + color: #607D8B; +} +nav a:hover { + color: #039be5; + background-color: #CFD8DC; +} +nav a.active { + color: #039be5; +} + +/* items class */ +.items { + margin: 0 0 2em 0; + list-style-type: none; + padding: 0; + width: 24em; +} +.items li { + cursor: pointer; + position: relative; + left: 0; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; +} +.items li:hover { + color: #607D8B; + background-color: #DDD; + left: .1em; +} +.items li.selected { + background-color: #CFD8DC; + color: white; +} +.items li.selected:hover { + background-color: #BBD8DC; +} +.items .text { + position: relative; + top: -3px; +} +.items .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0 0 4px; +} +/* #docregion toh */ +/* everywhere else */ +* { + font-family: Arial, Helvetica, sans-serif; +} diff --git a/public/docs/_examples/cli-quickstart/ts/src/test.ts b/public/docs/_examples/cli-quickstart/ts/src/test.ts new file mode 100644 index 0000000000..9bf72267e9 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/test.ts @@ -0,0 +1,32 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/long-stack-trace-zone'; +import 'zone.js/dist/proxy.js'; +import 'zone.js/dist/sync-test'; +import 'zone.js/dist/jasmine-patch'; +import 'zone.js/dist/async-test'; +import 'zone.js/dist/fake-async-test'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. +declare var __karma__: any; +declare var require: any; + +// Prevent Karma from running prematurely. +__karma__.loaded = function () {}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); +// Finally, start Karma to run the tests. +__karma__.start(); diff --git a/public/docs/_examples/cli-quickstart/ts/src/tsconfig.app.json b/public/docs/_examples/cli-quickstart/ts/src/tsconfig.app.json new file mode 100644 index 0000000000..9f12c4b849 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/tsconfig.app.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ + "es2016", + "dom" + ], + "outDir": "../out-tsc/app", + "target": "es5", + "module": "es2015", + "baseUrl": "", + "types": [] + }, + "exclude": [ + "test.ts", + "**/*.spec.ts" + ] +} diff --git a/public/docs/_examples/cli-quickstart/ts/src/tsconfig.spec.json b/public/docs/_examples/cli-quickstart/ts/src/tsconfig.spec.json new file mode 100644 index 0000000000..6c5160e12e --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/tsconfig.spec.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ + "es2016" + ], + "outDir": "../out-tsc/spec", + "module": "commonjs", + "target": "es6", + "baseUrl": "", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "test.ts" + ], + "include": [ + "**/*.spec.ts" + ] +} diff --git a/public/docs/_examples/cli-quickstart/ts/tsconfig.json b/public/docs/_examples/cli-quickstart/ts/tsconfig.json new file mode 100644 index 0000000000..cde5e35054 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ + "es2016" + ] + } +} diff --git a/public/docs/_examples/cli-quickstart/ts/zipper.json b/public/docs/_examples/cli-quickstart/ts/zipper.json new file mode 100644 index 0000000000..70bf41659e --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/zipper.json @@ -0,0 +1,11 @@ +{ + "files":[ + "!**/*.d.ts", + "!**/*.js", + "!**/*.[0-9].*", + ".angular-cli.json", + "protractor.conf.js" + ], + "removeSystemJsConfig": true, + "type": "cli" +} diff --git a/public/docs/_examples/component-styles/dart/lib/hero.dart b/public/docs/_examples/component-styles/dart/lib/hero.dart deleted file mode 100755 index cdfecf4d79..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/hero.dart +++ /dev/null @@ -1,8 +0,0 @@ -class Hero { - bool active = false; - - final String name; - final List team; - - Hero(this.name, this.team); -} diff --git a/public/docs/_examples/component-styles/dart/lib/hero_app_component.dart b/public/docs/_examples/component-styles/dart/lib/hero_app_component.dart deleted file mode 100755 index bba326e603..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/hero_app_component.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:angular2/core.dart'; -import 'hero.dart'; -import 'hero_app_main_component.dart'; - -// #docregion -@Component( - selector: 'hero-app', - template: ''' -

    Tour of Heroes

    - ''', - styles: const ['h1 { font-weight: normal; }'], - directives: const [HeroAppMainComponent]) -class HeroAppComponent { -// #enddocregion - Hero hero = - new Hero('Human Torch', ['Mister Fantastic', 'Invisible Woman', 'Thing']); - - @HostBinding('class') - String get themeClass => 'theme-light'; -// #docregion -} diff --git a/public/docs/_examples/component-styles/dart/lib/hero_app_main_component.dart b/public/docs/_examples/component-styles/dart/lib/hero_app_main_component.dart deleted file mode 100755 index ddec19537b..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/hero_app_main_component.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'hero_details_component.dart'; -import 'hero_controls_component.dart'; -import 'quest_summary_component.dart'; - -@Component( - selector: 'hero-app-main', - template: ''' - - - - ''', - directives: const [ - HeroDetailsComponent, - HeroControlsComponent, - QuestSummaryComponent - ]) -class HeroAppMainComponent { - @Input() Hero hero; -} diff --git a/public/docs/_examples/component-styles/dart/lib/hero_controls_component.dart b/public/docs/_examples/component-styles/dart/lib/hero_controls_component.dart deleted file mode 100755 index 52ec2e1acb..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/hero_controls_component.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:angular2/core.dart'; -import 'hero.dart'; - -// #docregion inlinestyles -@Component( - selector: 'hero-controls', - template: ''' - -

    Controls

    - ''') -class HeroControlsComponent { - @Input() - Hero hero; - - void activate() { - hero.active = true; - } -} diff --git a/public/docs/_examples/component-styles/dart/lib/hero_details_box.css b/public/docs/_examples/component-styles/dart/lib/hero_details_box.css deleted file mode 100755 index 443c863cb4..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/hero_details_box.css +++ /dev/null @@ -1,6 +0,0 @@ -:host { - padding: 10px; -} -h3 { - background-color: yellow; -} diff --git a/public/docs/_examples/component-styles/dart/lib/hero_details_component.css b/public/docs/_examples/component-styles/dart/lib/hero_details_component.css deleted file mode 100755 index 6e4cd2bb26..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/hero_details_component.css +++ /dev/null @@ -1,32 +0,0 @@ -/* #docregion import */ -/* pub build fails on - @ import 'hero_details_box.css'; - See https://github.com/angular/angular/issues/8518 */ - -@import '/packages/component_styles/hero_details_box.css'; -/* #enddocregion import */ - -/* #docregion host */ -:host { - display: block; - border: 1px solid black; -} -/* #enddocregion host */ - -/* #docregion hostfunction */ -:host(.active) { - border-width: 3px; -} -/* #enddocregion hostfunction */ - -/* #docregion hostcontext */ -:host-context(.theme-light) h2 { - background-color: #eef; -} -/* #enddocregion hostcontext */ - -/* #docregion deep */ -:host /deep/ h3 { - font-style: italic; -} -/* #enddocregion deep */ diff --git a/public/docs/_examples/component-styles/dart/lib/hero_details_component.dart b/public/docs/_examples/component-styles/dart/lib/hero_details_component.dart deleted file mode 100755 index 023cc1c170..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/hero_details_component.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:angular2/core.dart'; -import 'hero.dart'; -import 'hero_team_component.dart'; - -// #docregion styleurls -@Component( - selector: 'hero-details', - template: ''' -

    {{hero.name}}

    - - ''', - styleUrls: const ['hero_details_component.css'], - directives: const [HeroTeamComponent]) -class HeroDetailsComponent { - // #enddocregion styleurls - @Input() Hero hero; - // #docregion styleurls -} diff --git a/public/docs/_examples/component-styles/dart/lib/hero_team_component.css b/public/docs/_examples/component-styles/dart/lib/hero_team_component.css deleted file mode 100755 index b87679886b..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/hero_team_component.css +++ /dev/null @@ -1,3 +0,0 @@ -li { - list-style-type: square; -} diff --git a/public/docs/_examples/component-styles/dart/lib/hero_team_component.dart b/public/docs/_examples/component-styles/dart/lib/hero_team_component.dart deleted file mode 100755 index ec8323b633..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/hero_team_component.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:angular2/core.dart'; -import 'hero.dart'; - -// #docregion stylelink -@Component( - selector: 'hero-team', - template: ''' - -

    Team

    -
      -
    • - {{member}} -
    • -
    ''') -class HeroTeamComponent { - @Input() Hero hero; -} diff --git a/public/docs/_examples/component-styles/dart/lib/quest_summary_component.css b/public/docs/_examples/component-styles/dart/lib/quest_summary_component.css deleted file mode 100755 index 207fa981dd..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/quest_summary_component.css +++ /dev/null @@ -1,5 +0,0 @@ -:host { - display: block; - background-color: green; - color: white; -} diff --git a/public/docs/_examples/component-styles/dart/lib/quest_summary_component.dart b/public/docs/_examples/component-styles/dart/lib/quest_summary_component.dart deleted file mode 100755 index dbfe8d99d0..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/quest_summary_component.dart +++ /dev/null @@ -1,18 +0,0 @@ -// #docplaster -import 'package:angular2/core.dart'; - -// #docregion -@Component( - selector: 'quest-summary', -// #docregion urls - templateUrl: 'quest_summary_component.html', - styleUrls: const ['quest_summary_component.css']) -// #enddocregion urls -class QuestSummaryComponent {} -// #enddocregion -/* -// #docregion encapsulation.native - // warning: few browsers support shadow DOM encapsulation at this time - encapsulation: ViewEncapsulation.Native - // #enddocregion encapsulation.native -*/ diff --git a/public/docs/_examples/component-styles/dart/lib/quest_summary_component.html b/public/docs/_examples/component-styles/dart/lib/quest_summary_component.html deleted file mode 100755 index ace27d2a1c..0000000000 --- a/public/docs/_examples/component-styles/dart/lib/quest_summary_component.html +++ /dev/null @@ -1 +0,0 @@ -

    No quests in progress

    diff --git a/public/docs/_examples/component-styles/dart/pubspec.yaml b/public/docs/_examples/component-styles/dart/pubspec.yaml deleted file mode 100755 index 39769cb7e5..0000000000 --- a/public/docs/_examples/component-styles/dart/pubspec.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# #docregion -name: component_styles -description: Component Styles example -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: 'package:angular2/common.dart#COMMON_DIRECTIVES' - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/component-styles/dart/web/index.html b/public/docs/_examples/component-styles/dart/web/index.html deleted file mode 100755 index a74d581227..0000000000 --- a/public/docs/_examples/component-styles/dart/web/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - Component Styles - - - - - - - - -

    External H1 Title for E2E test

    - - -
      -
    • External list for E2E test
    • -
    - - - diff --git a/public/docs/_examples/component-styles/dart/web/main.dart b/public/docs/_examples/component-styles/dart/web/main.dart deleted file mode 100755 index 536b8c155a..0000000000 --- a/public/docs/_examples/component-styles/dart/web/main.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:angular2/platform/browser.dart'; -import 'package:component_styles/hero_app_component.dart'; - -main() { - bootstrap(HeroAppComponent); -} diff --git a/public/docs/_examples/component-styles/e2e-spec.ts b/public/docs/_examples/component-styles/e2e-spec.ts index dac3cd55a2..32bd30832c 100644 --- a/public/docs/_examples/component-styles/e2e-spec.ts +++ b/public/docs/_examples/component-styles/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Component Style Tests', function () { beforeAll(function () { @@ -62,9 +65,4 @@ describe('Component Style Tests', function () { expect(externalLi.getCssValue('listStyleType')).not.toEqual('square'); }); - it('supports relative loading with moduleId', function() { - let host = element(by.css('quest-summary')); - expect(host.getCssValue('color')).toEqual('rgba(255, 255, 255, 1)'); // #ffffff - }); - }); diff --git a/public/docs/_examples/component-styles/ts/app/hero-app-main.component.ts b/public/docs/_examples/component-styles/ts/app/hero-app-main.component.ts deleted file mode 100644 index fb5b5d9d98..0000000000 --- a/public/docs/_examples/component-styles/ts/app/hero-app-main.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Component, Input } from '@angular/core'; - -import { Hero } from './hero'; -import { HeroDetailsComponent } from './hero-details.component'; -import { HeroControlsComponent } from './hero-controls.component'; -import { QuestSummaryComponent } from './quest-summary.component'; - -@Component({ - selector: 'hero-app-main', - template: ` - - - - - `, - directives: [HeroDetailsComponent, HeroControlsComponent, QuestSummaryComponent] -}) -export class HeroAppMainComponent { - @Input() hero: Hero; -} diff --git a/public/docs/_examples/component-styles/ts/app/hero-details.component.ts b/public/docs/_examples/component-styles/ts/app/hero-details.component.ts deleted file mode 100644 index f530ec0757..0000000000 --- a/public/docs/_examples/component-styles/ts/app/hero-details.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Component, Input } from '@angular/core'; -import { Hero } from './hero'; -import { HeroTeamComponent } from './hero-team.component'; - -// #docregion styleurls -@Component({ - selector: 'hero-details', - template: ` -

    {{hero.name}}

    - - - `, - styleUrls: ['app/hero-details.component.css'], - directives: [HeroTeamComponent] -}) -export class HeroDetailsComponent { - // #enddocregion styleurls - @Input() hero: Hero; - // #docregion styleurls -} diff --git a/public/docs/_examples/component-styles/ts/app/hero.ts b/public/docs/_examples/component-styles/ts/app/hero.ts deleted file mode 100644 index 8b58c8a8f8..0000000000 --- a/public/docs/_examples/component-styles/ts/app/hero.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class Hero { - active:boolean; - - constructor(public name:string, - public team:string[]) { - } -} diff --git a/public/docs/_examples/component-styles/ts/app/main.ts b/public/docs/_examples/component-styles/ts/app/main.ts deleted file mode 100644 index 1d1e75499c..0000000000 --- a/public/docs/_examples/component-styles/ts/app/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { HeroAppComponent } from './hero-app.component'; - -bootstrap(HeroAppComponent); diff --git a/public/docs/_examples/component-styles/ts/index.html b/public/docs/_examples/component-styles/ts/index.html deleted file mode 100644 index 9345f5b221..0000000000 --- a/public/docs/_examples/component-styles/ts/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - Component Styles - - - - - - - - - - - - - - - -

    External H1 Title for E2E test

    - - -
      -
    • External list for E2E test
    • -
    - - - diff --git a/public/docs/_examples/component-styles/ts/plnkr.json b/public/docs/_examples/component-styles/ts/plnkr.json index fb313556fc..e045ebcb38 100644 --- a/public/docs/_examples/component-styles/ts/plnkr.json +++ b/public/docs/_examples/component-styles/ts/plnkr.json @@ -1,5 +1,6 @@ { "description": "Component Styles", + "basePath": "src/", "files": [ "!**/*.d.ts", "!**/*.js", diff --git a/public/docs/_examples/component-styles/ts/src/app/app.module.ts b/public/docs/_examples/component-styles/ts/src/app/app.module.ts new file mode 100644 index 0000000000..31c72cbbf2 --- /dev/null +++ b/public/docs/_examples/component-styles/ts/src/app/app.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { HeroAppComponent } from './hero-app.component'; +import { HeroAppMainComponent } from './hero-app-main.component'; +import { HeroDetailsComponent } from './hero-details.component'; +import { HeroControlsComponent } from './hero-controls.component'; +import { QuestSummaryComponent } from './quest-summary.component'; +import { HeroTeamComponent } from './hero-team.component'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ + HeroAppComponent, + HeroAppMainComponent, + HeroDetailsComponent, + HeroControlsComponent, + QuestSummaryComponent, + HeroTeamComponent + ], + bootstrap: [ HeroAppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/component-styles/ts/src/app/hero-app-main.component.ts b/public/docs/_examples/component-styles/ts/src/app/hero-app-main.component.ts new file mode 100644 index 0000000000..aebb1f729e --- /dev/null +++ b/public/docs/_examples/component-styles/ts/src/app/hero-app-main.component.ts @@ -0,0 +1,16 @@ +import { Component, Input } from '@angular/core'; + +import { Hero } from './hero'; + +@Component({ + selector: 'hero-app-main', + template: ` + + + + + ` +}) +export class HeroAppMainComponent { + @Input() hero: Hero; +} diff --git a/public/docs/_examples/component-styles/ts/app/hero-app.component.ts b/public/docs/_examples/component-styles/ts/src/app/hero-app.component.ts similarity index 76% rename from public/docs/_examples/component-styles/ts/app/hero-app.component.ts rename to public/docs/_examples/component-styles/ts/src/app/hero-app.component.ts index b196584abb..5f1923e6f3 100644 --- a/public/docs/_examples/component-styles/ts/app/hero-app.component.ts +++ b/public/docs/_examples/component-styles/ts/src/app/hero-app.component.ts @@ -1,6 +1,5 @@ import { Component, HostBinding } from '@angular/core'; import { Hero } from './hero'; -import { HeroAppMainComponent } from './hero-app-main.component'; // #docregion @Component({ @@ -8,15 +7,14 @@ import { HeroAppMainComponent } from './hero-app-main.component'; template: `

    Tour of Heroes

    `, - styles: ['h1 { font-weight: normal; }'], - directives: [HeroAppMainComponent] + styles: ['h1 { font-weight: normal; }'] }) export class HeroAppComponent { // #enddocregion hero = new Hero( 'Human Torch', ['Mister Fantastic', 'Invisible Woman', 'Thing'] - ) + ); @HostBinding('class') get themeClass() { return 'theme-light'; diff --git a/public/docs/_examples/component-styles/ts/app/hero-controls.component.ts b/public/docs/_examples/component-styles/ts/src/app/hero-controls.component.ts similarity index 100% rename from public/docs/_examples/component-styles/ts/app/hero-controls.component.ts rename to public/docs/_examples/component-styles/ts/src/app/hero-controls.component.ts diff --git a/public/docs/_examples/component-styles/ts/app/hero-details-box.css b/public/docs/_examples/component-styles/ts/src/app/hero-details-box.css similarity index 100% rename from public/docs/_examples/component-styles/ts/app/hero-details-box.css rename to public/docs/_examples/component-styles/ts/src/app/hero-details-box.css diff --git a/public/docs/_examples/component-styles/ts/app/hero-details.component.css b/public/docs/_examples/component-styles/ts/src/app/hero-details.component.css similarity index 100% rename from public/docs/_examples/component-styles/ts/app/hero-details.component.css rename to public/docs/_examples/component-styles/ts/src/app/hero-details.component.css diff --git a/public/docs/_examples/component-styles/ts/src/app/hero-details.component.ts b/public/docs/_examples/component-styles/ts/src/app/hero-details.component.ts new file mode 100644 index 0000000000..bd86a63e04 --- /dev/null +++ b/public/docs/_examples/component-styles/ts/src/app/hero-details.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core'; +import { Hero } from './hero'; + +// #docregion styleurls +@Component({ + selector: 'hero-details', + template: ` +

    {{hero.name}}

    + + + `, + styleUrls: ['app/hero-details.component.css'] +}) +export class HeroDetailsComponent { + // #enddocregion styleurls + @Input() hero: Hero; + // #docregion styleurls +} diff --git a/public/docs/_examples/component-styles/ts/app/hero-team.component.css b/public/docs/_examples/component-styles/ts/src/app/hero-team.component.css similarity index 100% rename from public/docs/_examples/component-styles/ts/app/hero-team.component.css rename to public/docs/_examples/component-styles/ts/src/app/hero-team.component.css diff --git a/public/docs/_examples/component-styles/ts/app/hero-team.component.ts b/public/docs/_examples/component-styles/ts/src/app/hero-team.component.ts similarity index 100% rename from public/docs/_examples/component-styles/ts/app/hero-team.component.ts rename to public/docs/_examples/component-styles/ts/src/app/hero-team.component.ts diff --git a/public/docs/_examples/component-styles/ts/src/app/hero.ts b/public/docs/_examples/component-styles/ts/src/app/hero.ts new file mode 100644 index 0000000000..7f8969e682 --- /dev/null +++ b/public/docs/_examples/component-styles/ts/src/app/hero.ts @@ -0,0 +1,7 @@ +export class Hero { + active: boolean; + + constructor(public name: string, + public team: string[]) { + } +} diff --git a/public/docs/_examples/component-styles/ts/app/quest-summary.component.css b/public/docs/_examples/component-styles/ts/src/app/quest-summary.component.css similarity index 100% rename from public/docs/_examples/component-styles/ts/app/quest-summary.component.css rename to public/docs/_examples/component-styles/ts/src/app/quest-summary.component.css diff --git a/public/docs/_examples/component-styles/ts/app/quest-summary.component.html b/public/docs/_examples/component-styles/ts/src/app/quest-summary.component.html similarity index 100% rename from public/docs/_examples/component-styles/ts/app/quest-summary.component.html rename to public/docs/_examples/component-styles/ts/src/app/quest-summary.component.html diff --git a/public/docs/_examples/component-styles/ts/app/quest-summary.component.ts b/public/docs/_examples/component-styles/ts/src/app/quest-summary.component.ts similarity index 80% rename from public/docs/_examples/component-styles/ts/app/quest-summary.component.ts rename to public/docs/_examples/component-styles/ts/src/app/quest-summary.component.ts index 9952702ddf..2a2dc65fe0 100644 --- a/public/docs/_examples/component-styles/ts/app/quest-summary.component.ts +++ b/public/docs/_examples/component-styles/ts/src/app/quest-summary.component.ts @@ -4,11 +4,10 @@ import { Component, ViewEncapsulation } from '@angular/core'; // #docregion @Component({ - moduleId: module.id, selector: 'quest-summary', // #docregion urls - templateUrl: 'quest-summary.component.html', - styleUrls: ['quest-summary.component.css'] + templateUrl: './quest-summary.component.html', + styleUrls: ['./quest-summary.component.css'] // #enddocregion urls }) export class QuestSummaryComponent { } diff --git a/public/docs/_examples/component-styles/ts/src/index.html b/public/docs/_examples/component-styles/ts/src/index.html new file mode 100644 index 0000000000..6e9dc51b32 --- /dev/null +++ b/public/docs/_examples/component-styles/ts/src/index.html @@ -0,0 +1,31 @@ + + + + + Component Styles + + + + + + + + + + + + + + + +

    External H1 Title for E2E test

    + + +
      +
    • External list for E2E test
    • +
    + + + diff --git a/public/docs/_examples/component-styles/ts/src/main.ts b/public/docs/_examples/component-styles/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/component-styles/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/dependency-injection/dart/.analysis_options b/public/docs/_examples/dependency-injection/dart/.analysis_options deleted file mode 100644 index d8c582e96f..0000000000 --- a/public/docs/_examples/dependency-injection/dart/.analysis_options +++ /dev/null @@ -1,16 +0,0 @@ -# Supported lint rules and documentation: http://dart-lang.github.io/linter/lints/ -linter: - rules: - - always_declare_return_types - - camel_case_types - - empty_constructor_bodies - - annotate_overrides - - avoid_init_to_null - - constant_identifier_names - - one_member_abstracts - - slash_for_doc_comments - - sort_constructors_first - - unnecessary_brace_in_string_interp - -analyzer: - # strong-mode: true diff --git a/public/docs/_examples/dependency-injection/dart/.docsync.json b/public/docs/_examples/dependency-injection/dart/.docsync.json deleted file mode 100644 index 3695627e50..0000000000 --- a/public/docs/_examples/dependency-injection/dart/.docsync.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "Dependency injection", - "docHref": "https://angular.io/docs/dart/latest/guide/dependency-injection.html" -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/app_component.dart b/public/docs/_examples/dependency-injection/dart/lib/app_component.dart deleted file mode 100644 index cb29545084..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/app_component.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:angular2/core.dart'; - -import 'app_config.dart'; -import 'car/car_component.dart'; -import 'heroes/heroes_component.dart'; -import 'logger_service.dart'; -import 'user_service.dart'; -import 'injector_component.dart'; -import 'test_component.dart'; -import 'providers_component.dart'; - -@Component( - selector: 'my-app', - template: ''' -

    {{title}}

    - - - -

    User

    -

    - {{userInfo}} - -

    - - ''', - directives: const [ - CarComponent, - HeroesComponent, - InjectorComponent, - TestComponent, - ProvidersComponent - ], - // #docregion providers - providers: const [ - Logger, UserService, - const Provider(APP_CONFIG, useFactory: heroDiConfigFactory)] - // #enddocregion providers -) -class AppComponent { - final UserService _userService; - final String title; - - // #docregion ctor - AppComponent(@Inject(APP_CONFIG) AppConfig config, this._userService) - : title = config.title; - // #enddocregion ctor - - bool get isAuthorized { - return user.isAuthorized; - } - - void nextUser() { - _userService.getNewUser(); - } - - User get user { - return _userService.user; - } - - String get userInfo => 'Current user, ${user.name}, is' + - (isAuthorized ? '' : ' not') + ' authorized. '; -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/app_component_1.dart b/public/docs/_examples/dependency-injection/dart/lib/app_component_1.dart deleted file mode 100644 index ad1527f131..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/app_component_1.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Early versions - -// #docregion -import 'package:angular2/core.dart'; - -import 'car/car_component.dart'; -import 'heroes/heroes_component_1.dart'; - -@Component( - selector: 'my-app', - template: ''' -

    {{title}}

    - - ''', - directives: const [CarComponent, HeroesComponent]) -class AppComponent { - final String title = 'Dependency Injection'; -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/app_component_2.dart b/public/docs/_examples/dependency-injection/dart/lib/app_component_2.dart deleted file mode 100644 index 6017a9019f..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/app_component_2.dart +++ /dev/null @@ -1,36 +0,0 @@ -// #docregion - -// #docregion imports -import 'package:angular2/core.dart'; - -import 'app_config.dart'; -import 'car/car_component.dart'; -import 'heroes/heroes_component_1.dart'; -import 'logger_service.dart'; -// #enddocregion imports - -@Component( - selector: 'my-app', - template: ''' -

    {{title}}

    - - ''', - directives: const [ - CarComponent, - HeroesComponent - ], - providers: const [ - Logger, - // #docregion providers - const Provider(APP_CONFIG, useValue: heroDiConfig) - // #enddocregion providers - ] -) -class AppComponent { - final String title; - - // #docregion ctor - AppComponent(@Inject(APP_CONFIG) Map config) - : title = config['title']; - // #enddocregion ctor -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/app_config.dart b/public/docs/_examples/dependency-injection/dart/lib/app_config.dart deleted file mode 100644 index faadf62126..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/app_config.dart +++ /dev/null @@ -1,27 +0,0 @@ -// #docregion token -import 'package:angular2/core.dart'; - -const APP_CONFIG = const OpaqueToken('app.config'); -// #enddocregion token - -// #docregion config -const Map heroDiConfig = const { - 'apiEndpoint' : 'api.heroes.com', - 'title' : 'Dependency Injection' -}; -// #enddocregion config - -// #docregion config-alt -class AppConfig { - String apiEndpoint; - String title; -} - -AppConfig heroDiConfigFactory() => new AppConfig() - ..apiEndpoint = 'api.heroes.com' - ..title = 'Dependency Injection'; -// #enddocregion config-alt - -const appConfigProvider = const Provider(APP_CONFIG, - useFactory: heroDiConfigFactory, - deps: const []); diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car.dart deleted file mode 100644 index ff812c9dfa..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/car/car.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:angular2/core.dart'; - -@Injectable() -class Engine { - final int cylinders; - - Engine() : cylinders = 4; - Engine.withCylinders(this.cylinders); -} - -@Injectable() -class Tires { - String make = 'Flintstone'; - String model = 'Square'; -} - -@Injectable() -class Car { - //#docregion car-ctor - final Engine engine; - final Tires tires; - String description = 'DI'; - - Car(this.engine, this.tires); - // #enddocregion car-ctor - - // Method using the engine and tires - String drive() => '$description car with ' - '${engine.cylinders} cylinders and ' - '${tires.make} tires.'; -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car_component.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car_component.dart deleted file mode 100644 index b7e663b019..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/car/car_component.dart +++ /dev/null @@ -1,33 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'car.dart'; -import 'car_creations.dart' as carCreations; -import 'car_factory.dart'; -import 'car_injector.dart'; -import 'car_no_di.dart' as carNoDi; - -@Component( - selector: 'my-car', - template: ''' -

    Cars

    -
    {{car.drive()}}
    -
    {{noDiCar.drive()}}
    -
    {{injectorCar.drive()}}
    -
    {{factoryCar.drive()}}
    -
    {{simpleCar.drive()}}
    -
    {{superCar.drive()}}
    -
    {{testCar.drive()}}
    ''', - providers: const [Car, Engine, Tires]) -class CarComponent { - final Car car; - - CarComponent(this.car); - - Car factoryCar = (new CarFactory()).createCar(); - Car injectorCar = useInjector(); - carNoDi.Car noDiCar = new carNoDi.Car(); - Car simpleCar = carCreations.simpleCar(); - Car superCar = carCreations.superCar(); - Car testCar = carCreations.testCar(); -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car_creations.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car_creations.dart deleted file mode 100644 index 96674b83f0..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/car/car_creations.dart +++ /dev/null @@ -1,41 +0,0 @@ -// #docplaster -// Examples with car and engine variations -import 'car.dart'; - -///////// example 1 //////////// -Car simpleCar() => - // #docregion car-ctor-instantiation - // Simple car with 4 cylinders and Flintstone tires. - new Car(new Engine(), new Tires()) - // #enddocregion car-ctor-instantiation - ..description = 'Simple'; - -///////// example 2 //////////// - -// #docregion car-ctor-instantiation-with-param -class Engine2 extends Engine { - Engine2(cylinders) : super.withCylinders(cylinders); -} - -Car superCar() => - // Super car with 12 cylinders and Flintstone tires. - new Car(new Engine2(12), new Tires()) - ..description = 'Super'; -// #enddocregion car-ctor-instantiation-with-param - -/////////// example 3 ////////// - -// #docregion car-ctor-instantiation-with-mocks -class MockEngine extends Engine { - MockEngine() : super.withCylinders(8); -} - -class MockTires extends Tires { - MockTires() { make = 'YokoGoodStone'; } -} - -Car testCar() => - // Test car with 8 cylinders and YokoGoodStone tires. - new Car(new MockEngine(), new MockTires()) - ..description = 'Test'; -// #enddocregion car-ctor-instantiation-with-mocks diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car_factory.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car_factory.dart deleted file mode 100644 index 6107c894b7..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/car/car_factory.dart +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -import 'car.dart'; - -// BAD pattern! -class CarFactory { - Car createCar() => - new Car(createEngine(), createTires()) - ..description = 'Factory'; - - Engine createEngine() => new Engine(); - Tires createTires() => new Tires(); -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car_injector.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car_injector.dart deleted file mode 100644 index 07d78559eb..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/car/car_injector.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:angular2/core.dart'; - -import '../logger_service.dart'; -import 'car.dart'; - -// #docregion injector -Car useInjector() { - ReflectiveInjector injector; - // #enddocregion injector - /* - // #docregion injector-no-new - // Cannot instantiate an ReflectiveInjector like this! - var injector = new ReflectiveInjector([Car, Engine, Tires]); - // #enddocregion injector-no-new - */ - // #docregion injector, injector-create-and-call - injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires]); - // #docregion injector-call - var car = injector.get(Car); - // #enddocregion injector-call, injector-create-and-call - car.description = 'Injector'; - - injector = ReflectiveInjector.resolveAndCreate([Logger]); - var logger = injector.get(Logger); - logger.log('Injector car.drive() said: ' + car.drive()); - return car; -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/car/car_no_di.dart b/public/docs/_examples/dependency-injection/dart/lib/car/car_no_di.dart deleted file mode 100644 index 7db13b87f0..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/car/car_no_di.dart +++ /dev/null @@ -1,23 +0,0 @@ -// Car without DI - -import 'car.dart'; - -//#docregion car -class Car { - //#docregion car-ctor - Engine engine; - Tires tires; - var description = 'No DI'; - - Car() { - engine = new Engine(); - tires = new Tires(); - } - //#enddocregion car-ctor - - // Method using the engine and tires - String drive() => '$description car with ' - '${engine.cylinders} cylinders and ' - '${tires.make} tires.'; -} -//#enddocregion car diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero.dart deleted file mode 100644 index 369ef1a5fe..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero.dart +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -class Hero { - final int id; - final String name; - final bool isSecret; - - Hero(this.id, this.name, [this.isSecret = false]); -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component.dart deleted file mode 100644 index 829fd60bec..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component.dart +++ /dev/null @@ -1,21 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'hero_service.dart'; - -@Component( - selector: 'hero-list', - template: ''' -
    - {{hero.id}} - {{hero.name}} - ({{hero.isSecret ? 'secret' : 'public'}}) -
    ''') -class HeroListComponent { - final List heroes; - - // #docregion ctor-signature - HeroListComponent(HeroService heroService) - // #enddocregion ctor-signature - : heroes = heroService.getHeroes(); -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_1.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_1.dart deleted file mode 100644 index 4abee51561..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_1.dart +++ /dev/null @@ -1,15 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'mock_heroes.dart'; - -@Component( - selector: 'hero-list', - template: ''' -
    - {{hero.id}} - {{hero.name}} -
    ''') -class HeroListComponent { - final List heroes = HEROES; -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_2.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_2.dart deleted file mode 100644 index 6a85c0a5d5..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_list_component_2.dart +++ /dev/null @@ -1,28 +0,0 @@ -// #docplaster -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; -// #enddocregion -import 'hero_service_1.dart'; -/* -// #docregion -import 'hero_service.dart'; -// #enddocregion -*/ -// #docregion - -@Component( - selector: 'hero-list', - template: ''' -
    - {{hero.id}} - {{hero.name}} -
    ''') -class HeroListComponent { - final List heroes; - - // #docregion ctor - HeroListComponent(HeroService heroService) - : heroes = heroService.getHeroes(); - // #enddocregion ctor -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service.dart deleted file mode 100644 index f66bd7ef6d..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service.dart +++ /dev/null @@ -1,24 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import '../logger_service.dart'; -import 'hero.dart'; -import 'mock_heroes.dart'; - -@Injectable() -class HeroService { - // #docregion internals - final Logger _logger; - final bool _isAuthorized; - - HeroService(this._logger, this._isAuthorized); - - List getHeroes() { - var auth = _isAuthorized ? 'authorized' : 'unauthorized'; - _logger.log('Getting heroes for $auth user.'); - return HEROES - .where((hero) => _isAuthorized || !hero.isSecret) - .toList(); - } - // #enddocregion internals -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_1.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_1.dart deleted file mode 100644 index 666c2a2815..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_1.dart +++ /dev/null @@ -1,10 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'mock_heroes.dart'; - -@Injectable() -class HeroService { - List getHeroes() => HEROES; -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_2.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_2.dart deleted file mode 100644 index b4ef2a2a41..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_2.dart +++ /dev/null @@ -1,19 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import '../logger_service.dart'; -import 'hero.dart'; -import 'mock_heroes.dart'; - -@Injectable() -class HeroService { - final Logger _logger; - - //#docregion ctor - HeroService(this._logger); - //#enddocregion ctor - List getHeroes() { - _logger.log('Getting heroes ...'); - return HEROES; - } -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_provider.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_provider.dart deleted file mode 100644 index 1dd52cf3e2..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/heroes/hero_service_provider.dart +++ /dev/null @@ -1,17 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import '../logger_service.dart'; -import '../user_service.dart'; -import 'hero_service.dart'; - -// #docregion factory -HeroService heroServiceFactory(Logger logger, UserService userService) => - new HeroService(logger, userService.user.isAuthorized); -// #enddocregion factory - -// #docregion provider -const heroServiceProvider = const Provider(HeroService, - useFactory: heroServiceFactory, - deps: const [Logger, UserService]); -// #enddocregion provider diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component.dart deleted file mode 100644 index d90871de73..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component.dart +++ /dev/null @@ -1,14 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'hero_list_component.dart'; -import 'hero_service_provider.dart'; - -@Component( - selector: 'my-heroes', - template: ''' -

    Heroes

    - ''', - providers: const [heroServiceProvider], - directives: const [HeroListComponent]) -class HeroesComponent {} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component_1.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component_1.dart deleted file mode 100644 index 4546a7c5c3..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/heroes/heroes_component_1.dart +++ /dev/null @@ -1,27 +0,0 @@ -// #docplaster -// #docregion -// #docregion full, v1 -import 'package:angular2/core.dart'; - -// #enddocregion full, v1 -import 'hero_list_component_2.dart'; -import 'hero_service_1.dart'; -/* -// #docregion full -import 'hero_list_component.dart'; -// #docregion v1 -import 'hero_service.dart'; -// #enddocregion full, v1 -*/ -// #docregion full, v1 - -@Component( - selector: 'my-heroes', - template: ''' -

    Heroes

    - ''', - // #enddocregion v1 - providers: const [HeroService], - // #docregion v1 - directives: const [HeroListComponent]) -class HeroesComponent {} diff --git a/public/docs/_examples/dependency-injection/dart/lib/heroes/mock_heroes.dart b/public/docs/_examples/dependency-injection/dart/lib/heroes/mock_heroes.dart deleted file mode 100644 index 70a38c878d..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/heroes/mock_heroes.dart +++ /dev/null @@ -1,18 +0,0 @@ -// #docregion -import 'hero.dart'; - -List HEROES = [ - {'id': 11, 'isSecret': false, 'name': 'Mr. Nice'}, - {'id': 12, 'isSecret': false, 'name': 'Narco'}, - {'id': 13, 'isSecret': false, 'name': 'Bombasto'}, - {'id': 14, 'isSecret': false, 'name': 'Celeritas'}, - {'id': 15, 'isSecret': false, 'name': 'Magneta'}, - {'id': 16, 'isSecret': false, 'name': 'RubberMan'}, - {'id': 17, 'isSecret': false, 'name': 'Dynama'}, - {'id': 18, 'isSecret': true, 'name': 'Dr IQ'}, - {'id': 19, 'isSecret': true, 'name': 'Magma'}, - {'id': 20, 'isSecret': true, 'name': 'Tornado'} -].map(_initHero).toList(); - -Hero _initHero(Map heroProperties) => new Hero( - heroProperties['id'], heroProperties['name'], heroProperties['isSecret']); diff --git a/public/docs/_examples/dependency-injection/dart/lib/injector_component.dart b/public/docs/_examples/dependency-injection/dart/lib/injector_component.dart deleted file mode 100644 index 477bc3bc6c..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/injector_component.dart +++ /dev/null @@ -1,43 +0,0 @@ -// #docplaster - -// #docregion -import 'package:angular2/core.dart'; - -import 'car/car.dart'; -import 'heroes/hero.dart'; -import 'heroes/hero_service.dart'; -import 'heroes/hero_service_provider.dart'; -import 'logger_service.dart'; - -// #docregion injector -@Component( - selector: 'my-injectors', - template: ''' -

    Other Injections

    -
    {{car.drive()}}
    -
    {{hero.name}}
    -
    {{rodent}}
    ''', - providers: const [ - Car, Engine, Tires, heroServiceProvider, Logger]) -class InjectorComponent { - final Injector _injector; - Car car; - HeroService heroService; - Hero hero; - - InjectorComponent(this._injector) { - car = _injector.get(Car); - // #docregion get-hero-service - heroService = _injector.get(HeroService); - // #enddocregion get-hero-service - hero = heroService.getHeroes()[0]; - } - - String get rodent => - _injector.get(ROUS, "R.O.U.S.'s? I don't think they exist!"); -} -// #enddocregion injector - -/// R.O.U.S. - Rodents Of Unusual Size -/// https://www.youtube.com/watch?v=BOv5ZjAOpC8 -class ROUS {} diff --git a/public/docs/_examples/dependency-injection/dart/lib/logger_service.dart b/public/docs/_examples/dependency-injection/dart/lib/logger_service.dart deleted file mode 100644 index ac1e87fa10..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/logger_service.dart +++ /dev/null @@ -1,13 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -@Injectable() -class Logger { - List _logs = []; - List get logs => _logs; - - void log(String message) { - _logs.add(message); - print(message); - } -} diff --git a/public/docs/_examples/dependency-injection/dart/lib/providers_component.dart b/public/docs/_examples/dependency-injection/dart/lib/providers_component.dart deleted file mode 100644 index 11f2184242..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/providers_component.dart +++ /dev/null @@ -1,274 +0,0 @@ -// Examples of provider arrays -// #docplaster -import 'package:angular2/core.dart'; - -import 'app_config.dart'; -import 'heroes/hero_service_provider.dart'; -import 'heroes/hero_service.dart'; -import 'logger_service.dart'; -import 'user_service.dart'; - -// TODO file an issue: cannot use the following const in metadata. -const template = '{{log}}'; - -@Component( - selector: 'provider-1', - template: '{{log}}', - // #docregion providers-1, providers-logger - providers: const [Logger] - // #enddocregion providers-1, providers-logger -) -class ProviderComponent1 { - String log; - - ProviderComponent1(Logger logger) { - logger.log('Hello from logger provided with Logger class'); - log = logger.logs[0]; - } -} - -/// Component just used to ensure that shared E2E tests pass. -@Component( - selector: 'provider-3a', - template: '{{log}}', - providers: const [const Provider(Logger, useClass: Logger)] -) -class ProviderComponent3a { - String log; - - ProviderComponent3a(Logger logger) { - logger.log('Hello from logger provided with {provide: Logger, useClass: Logger}'); - log = logger.logs[0]; - } -} - -@Injectable() -class BetterLogger extends Logger {} - -@Component( - selector: 'provider-4', - template: '{{log}}', - providers: - // #docregion providers-4 - const [const Provider(Logger, useClass: BetterLogger)] - // #enddocregion providers-4 -) -class ProviderComponent4 { - String log; - - ProviderComponent4(Logger logger) { - logger.log('Hello from logger provided with useClass:BetterLogger'); - log = logger.logs[0]; - } -} - -// #docregion EvenBetterLogger -@Injectable() -class EvenBetterLogger extends Logger { - final UserService _userService; - - EvenBetterLogger(this._userService); - - @override void log(String message) { - var name = _userService.user.name; - super.log('Message to $name: $message'); - } -} -// #enddocregion EvenBetterLogger - -@Component( - selector: 'provider-5', - template: '{{log}}', - providers: - // #docregion providers-5 - const [UserService, const Provider(Logger, useClass: EvenBetterLogger)] - // #enddocregion providers-5 -) -class ProviderComponent5 { - String log; - - ProviderComponent5(Logger logger) { - logger.log('Hello from EvenBetterlogger'); - log = logger.logs[0]; - } -} - -@Injectable() -class NewLogger extends Logger implements OldLogger {} - -class OldLogger extends Logger { - @override - void log(String message) { - throw new Exception('Should not call the old logger!'); - } -} - -@Component( - selector: 'provider-6a', - template: '{{log}}', - providers: - // #docregion providers-6a - const [NewLogger, - // Not aliased! Creates two instances of `NewLogger` - const Provider(OldLogger, useClass: NewLogger)] - // #enddocregion providers-6a -) -class ProviderComponent6a { - String log; - - ProviderComponent6a(NewLogger newLogger, OldLogger oldLogger) { - if (newLogger == oldLogger) { - throw new Exception('expected the two loggers to be different instances'); - } - oldLogger.log('Hello OldLogger (but we want NewLogger)'); - // The newLogger wasn't called so no logs[] - // display the logs of the oldLogger. - log = newLogger.logs.isEmpty ? oldLogger.logs[0] : newLogger.logs[0]; - } -} - -@Component( - selector: 'provider-6b', - template: '{{log}}', - providers: - // #docregion providers-6b - const [NewLogger, - // Alias OldLogger with reference to NewLogger - const Provider(OldLogger, useExisting: NewLogger)] - // #enddocregion providers-6b -) -class ProviderComponent6b { - String log; - - ProviderComponent6b(NewLogger newLogger, OldLogger oldLogger) { - if (newLogger != oldLogger) { - throw new Exception('expected the two loggers to be the same instance'); - } - oldLogger.log('Hello from NewLogger (via aliased OldLogger)'); - log = newLogger.logs[0]; - } -} - -// #docregion silent-logger -// #docregion const-class -class SilentLogger implements Logger { - @override - final List logs = const ['Silent logger says "Shhhhh!". Provided via "useValue"']; - - const SilentLogger(); - - @override - void log(String message) { } -} -// #enddocregion const-class -// #docregion const-object - -const silentLogger = const SilentLogger(); -// #enddocregion const-object -// #enddocregion silent-logger - -@Component( - selector: 'provider-7', - template: '{{log}}', - providers: - // #docregion providers-7 - const [const Provider(Logger, useValue: silentLogger)] - // #enddocregion providers-7 -) -class ProviderComponent7 { - String log; - - ProviderComponent7(Logger logger) { - logger.log('Hello from logger provided with useValue'); - log = logger.logs[0]; - } -} - -@Component( - selector: 'provider-8', - template: '{{log}}', - providers: const [heroServiceProvider, Logger, UserService]) -class ProviderComponent8 { - // #docregion provider-8-ctor - ProviderComponent8(HeroService heroService); - // #enddocregion provider-8-ctor - - // must be true else this component would have blown up at runtime - var log = 'Hero service injected successfully via heroServiceProvider'; -} - -@Component( - selector: 'provider-9', - template: '{{log}}', - // #docregion providers-9 - providers: const [ - const Provider(APP_CONFIG, useValue: heroDiConfig)] - // #enddocregion providers-9 -) -class ProviderComponent9 implements OnInit { - Map _config; - String log; - - // #docregion provider-9-ctor - ProviderComponent9(@Inject(APP_CONFIG) this._config); - // #enddocregion provider-9-ctor - - @override - void ngOnInit() { - log = 'APP_CONFIG Application title is ${_config['title']}'; - } -} - -// Sample providers 1 to 7 illustrate a required logger dependency. -// Optional logger, can be null. -@Component(selector: 'provider-10', template: '{{log}}') -class ProviderComponent10 implements OnInit { - final Logger _logger; - String log; - - /* - // #docregion provider-10-ctor - HeroService(@Optional() this._logger) { - // #enddocregion provider-10-ctor - */ - ProviderComponent10(@Optional() this._logger) { - const someMessage = 'Hello from the injected logger'; - // #docregion provider-10-ctor - if (_logger != null) - _logger.log(someMessage); - } - // #enddocregion provider-10-ctor - - @override - void ngOnInit() { - log = _logger == null ? 'Optional logger was not available' : _logger.logs[0]; - } -} - -@Component( - selector: 'my-providers', - template: ''' -

    Provider variations

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    ''', - directives: const [ - ProviderComponent1, - ProviderComponent3a, - ProviderComponent4, - ProviderComponent5, - ProviderComponent6a, - ProviderComponent6b, - ProviderComponent7, - ProviderComponent8, - ProviderComponent9, - ProviderComponent10 - ]) -class ProvidersComponent {} diff --git a/public/docs/_examples/dependency-injection/dart/lib/test_component.dart b/public/docs/_examples/dependency-injection/dart/lib/test_component.dart deleted file mode 100644 index 24920bd7d2..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/test_component.dart +++ /dev/null @@ -1,65 +0,0 @@ -// Simulate a simple test -// Reader should look to the testing chapter for the real thing - -import 'package:angular2/core.dart'; - -import 'heroes/hero.dart'; -import 'heroes/hero_list_component.dart'; -import 'heroes/hero_service.dart'; - -@Component( - selector: 'my-tests', - template: ''' -

    Tests

    -

    Tests {{results['pass']}}: {{results['message']}}

    - ''') -class TestComponent { - var results = runTests(); -} - -class MockHeroService implements HeroService { - final List _heroes; - MockHeroService(this._heroes); - - @override - List getHeroes() => _heroes; -} - -///////////////////////////////////// -dynamic runTests() { - //#docregion spec - var expectedHeroes = [new Hero(0, 'A'), new Hero(1, 'B')]; - var mockService = new MockHeroService(expectedHeroes); - it('should have heroes when HeroListComponent created', () { - var hlc = new HeroListComponent(mockService); - expect(hlc.heroes.length).toEqual(expectedHeroes.length); - }); - //#enddocregion spec - return testResults; -} -////////////////////////////////// - -// Fake Jasmine infrastructure -String testName; -dynamic testResults; -dynamic expect(dynamic actual) => new ExpectResult(actual); - -class ExpectResult { - final actual; - ExpectResult(this.actual); - - void toEqual(dynamic expected) { - testResults = actual == expected - ? {'pass': 'passed', 'message': testName} - : { - 'pass': 'failed', - 'message': '$testName; expected $actual to equal $expected.' - }; - } -} - -void it(String label, void test()) { - testName = label; - test(); -} - diff --git a/public/docs/_examples/dependency-injection/dart/lib/user_service.dart b/public/docs/_examples/dependency-injection/dart/lib/user_service.dart deleted file mode 100644 index 24b61468db..0000000000 --- a/public/docs/_examples/dependency-injection/dart/lib/user_service.dart +++ /dev/null @@ -1,23 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -class User { - final String name; - final bool isAuthorized; - - User(this.name, [this.isAuthorized = false]); -} - -// Todo: get the user; don't 'new' it. -final User _alice = new User('Alice', true); -final User _bob = new User('Bob', false); - -@Injectable() -class UserService { - User user; - - UserService() : user = _bob; - - // swap users - User getNewUser() => user = user == _bob ? _alice : _bob; -} diff --git a/public/docs/_examples/dependency-injection/dart/pubspec.yaml b/public/docs/_examples/dependency-injection/dart/pubspec.yaml deleted file mode 100644 index 5a6661b0d1..0000000000 --- a/public/docs/_examples/dependency-injection/dart/pubspec.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# #docregion -name: dependency_injection -description: Dependency injection sample -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: 'package:angular2/common.dart#COMMON_DIRECTIVES' - platform_pipes: 'package:angular2/common.dart#COMMON_PIPES' - entry_points: web/main.dart -- dart_to_js_script_rewriter -dev_dependencies: - test: any diff --git a/public/docs/_examples/dependency-injection/dart/test/hero_list_component_test.dart b/public/docs/_examples/dependency-injection/dart/test/hero_list_component_test.dart deleted file mode 100644 index 4936a3e7f8..0000000000 --- a/public/docs/_examples/dependency-injection/dart/test/hero_list_component_test.dart +++ /dev/null @@ -1,29 +0,0 @@ -// A simple test -// More details will be in the testing chapter. -import 'package:angular2/core.dart'; -import 'package:dependency_injection/heroes/hero.dart'; -import 'package:dependency_injection/heroes/hero_list_component.dart'; -import 'package:dependency_injection/heroes/hero_service.dart'; -import 'package:test/test.dart'; - -/////////////////////////////////////// -////#docregion spec -List expectedHeroes = [ - new Hero(1, 'hero1'), - new Hero(2, 'hero2', true) -]; - -class HeroServiceMock implements HeroService { - @override - List getHeroes() => expectedHeroes; -} - -var mockService = new HeroServiceMock(); - -void main() { - test('should have heroes when HeroListComponent created', () { - var hlc = new HeroListComponent(mockService); - expect(hlc.heroes.length, expectedHeroes.length); - }); -} -//#enddocregion spec diff --git a/public/docs/_examples/dependency-injection/dart/web/index.html b/public/docs/_examples/dependency-injection/dart/web/index.html deleted file mode 100644 index cd3dfdb6cf..0000000000 --- a/public/docs/_examples/dependency-injection/dart/web/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Dependency Injection - - - - - - - Loading... - Loading my-providers ... - - diff --git a/public/docs/_examples/dependency-injection/dart/web/main.dart b/public/docs/_examples/dependency-injection/dart/web/main.dart deleted file mode 100644 index 5ec8717ed2..0000000000 --- a/public/docs/_examples/dependency-injection/dart/web/main.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:angular2/platform/browser.dart'; - -import 'package:dependency_injection/app_component.dart'; -import 'package:dependency_injection/providers_component.dart'; - -void main() { - //#docregion bootstrap - bootstrap(AppComponent); - //#enddocregion bootstrap - bootstrap(ProvidersComponent); -} diff --git a/public/docs/_examples/dependency-injection/dart/web/main_1.dart b/public/docs/_examples/dependency-injection/dart/web/main_1.dart deleted file mode 100644 index 561c6ba946..0000000000 --- a/public/docs/_examples/dependency-injection/dart/web/main_1.dart +++ /dev/null @@ -1,21 +0,0 @@ -// **WARNING** -// To try out this version of the app, ensure that you update: -// - web/index.html -// - pubspec.yaml -// to refer to this file instead of main.dart - -import 'package:angular2/platform/browser.dart'; - -import 'package:dependency_injection/app_component_1.dart'; -import 'package:dependency_injection/heroes/hero_service_1.dart'; - -void main() { - bootstrap(AppComponent); -} - -void main_alt() { - // #docregion bootstrap-discouraged - bootstrap(AppComponent, - [HeroService]); // DISCOURAGED (but works) - // #enddocregion bootstrap-discouraged -} diff --git a/public/docs/_examples/dependency-injection/e2e-spec.ts b/public/docs/_examples/dependency-injection/e2e-spec.ts index 1f7226867d..5b46dd77d9 100644 --- a/public/docs/_examples/dependency-injection/e2e-spec.ts +++ b/public/docs/_examples/dependency-injection/e2e-spec.ts @@ -1,6 +1,8 @@ -/// -describe('Dependency Injection Tests', function () { +'use strict'; // necessary for es6 output in node + +import { browser, element, by, ElementFinder } from 'protractor'; +describe('Dependency Injection Tests', function () { let expectedMsg: string; let expectedMsgRx: RegExp; @@ -80,9 +82,9 @@ describe('Dependency Injection Tests', function () { expect(element(by.css('#p1')).getText()).toEqual(expectedMsg); }); - it('P3a (provide) displays as expected', function () { - expectedMsg = 'Hello from logger provided with { provide: Logger, useClass: Logger }'; - expect(element(by.css('#p3a')).getText()).toEqual(expectedMsg); + it('P3 (provide) displays as expected', function () { + expectedMsg = 'Hello from logger provided with useClass:Logger'; + expect(element(by.css('#p3')).getText()).toEqual(expectedMsg); }); it('P4 (useClass:BetterLogger) displays as expected', function () { @@ -123,7 +125,7 @@ describe('Dependency Injection Tests', function () { it('P10 (optional dependency) displays as expected', function () { expectedMsg = 'Optional logger was not available'; expect(element(by.css('#p10')).getText()).toEqual(expectedMsg); - }) + }); }); describe('User/Heroes:', function() { @@ -146,14 +148,13 @@ describe('Dependency Injection Tests', function () { let heroes = element.all(by.css('#unauthorized hero-list div')); expect(heroes.count()).toBeGreaterThan(0); - heroes.filter(function(elem, index){ - return elem.getText().then(function(text) { + let filteredHeroes = heroes.filter((elem: ElementFinder, index: number) => { + return elem.getText().then((text: string) => { return /secret/.test(text); }); - }).then(function(filteredElements) { - // console.log("******Secret heroes count: "+filteredElements.length); - expect(filteredElements.length).toEqual(0); }); + + expect(filteredHeroes.count()).toEqual(0); }); it('unauthorized user should have no authorized heroes listed', function () { @@ -162,9 +163,9 @@ describe('Dependency Injection Tests', function () { describe('after button click', function() { - beforeAll(function (done) { - let buttonEle = element.all(by.cssContainingText('button','Next User')).get(0); - buttonEle.click().then(done,done); + beforeAll(function (done: any) { + let buttonEle = element.all(by.cssContainingText('button', 'Next User')).get(0); + buttonEle.click().then(done, done); }); it('User is Alice - authorized', function () { @@ -181,14 +182,13 @@ describe('Dependency Injection Tests', function () { let heroes = element.all(by.css('#authorized hero-list div')); expect(heroes.count()).toBeGreaterThan(0); - heroes.filter(function(elem, index){ - return elem.getText().then(function(text) { + let filteredHeroes = heroes.filter(function(elem: ElementFinder, index: number){ + return elem.getText().then(function(text: string) { return /secret/.test(text); }); - }).then(function(filteredElements) { - // console.log("******Secret heroes count: "+filteredElements.length); - expect(filteredElements.length).toBeGreaterThan(0); }); + + expect(filteredHeroes.count()).toBeGreaterThan(0); }); it('authorized user should have no unauthorized heroes listed', function () { diff --git a/public/docs/_examples/dependency-injection/ts/app/app.component.1.ts b/public/docs/_examples/dependency-injection/ts/app/app.component.1.ts deleted file mode 100644 index bec40f397d..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/app.component.1.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Early versions - -// #docregion -import { Component } from '@angular/core'; - -import { CarComponent } from './car/car.component'; -import { HeroesComponent } from './heroes/heroes.component.1'; - -@Component({ - selector: 'my-app', - template: ` -

    {{title}}

    - - - `, - directives:[CarComponent, HeroesComponent] -}) - -export class AppComponent { - title = 'Dependency Injection'; -} diff --git a/public/docs/_examples/dependency-injection/ts/app/app.component.2.ts b/public/docs/_examples/dependency-injection/ts/app/app.component.2.ts deleted file mode 100644 index 78e3f5483e..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/app.component.2.ts +++ /dev/null @@ -1,36 +0,0 @@ -// #docregion -// #docregion imports -import { Component } from '@angular/core'; -import { CarComponent } from './car/car.component'; -import { HeroesComponent } from './heroes/heroes.component.1'; - -import { Inject } from '@angular/core'; -import { APP_CONFIG, AppConfig, - HERO_DI_CONFIG } from './app.config'; -import { Logger } from './logger.service'; -// #enddocregion imports - -@Component({ - selector: 'my-app', - template: ` -

    {{title}}

    - - - `, - directives:[CarComponent, HeroesComponent], - providers: [ - Logger, - // #docregion providers - { provide: APP_CONFIG, useValue: HERO_DI_CONFIG } - // #enddocregion providers - ] -}) -export class AppComponent { - title:string; - - // #docregion ctor - constructor(@Inject(APP_CONFIG) config:AppConfig) { - this.title = config.title; - } - // #enddocregion ctor -} diff --git a/public/docs/_examples/dependency-injection/ts/app/app.component.ts b/public/docs/_examples/dependency-injection/ts/app/app.component.ts deleted file mode 100644 index 659d5c1faf..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/app.component.ts +++ /dev/null @@ -1,63 +0,0 @@ -// #docplaster -// #docregion -// #docregion imports -import { Component, Inject } from '@angular/core'; - -import { CarComponent } from './car/car.component'; -import { HeroesComponent } from './heroes/heroes.component'; - -import { APP_CONFIG, AppConfig, - HERO_DI_CONFIG } from './app.config'; -import { Logger } from './logger.service'; - -import { User, UserService } from './user.service'; -// #enddocregion imports -import { InjectorComponent } from './injector.component'; -import { TestComponent } from './test.component'; -import { ProvidersComponent } from './providers.component'; - -@Component({ - selector: 'my-app', - template: ` -

    {{title}}

    - - - -

    User

    -

    - {{userInfo}} - -

    - - - `, - directives:[CarComponent, HeroesComponent, - InjectorComponent, TestComponent, ProvidersComponent], - // #docregion providers - providers: [ - Logger, - UserService, - { provide: APP_CONFIG, useValue: HERO_DI_CONFIG } - ] - // #enddocregion providers -}) -export class AppComponent { - title:string; - - // #docregion ctor - constructor( - @Inject(APP_CONFIG) config:AppConfig, - private userService: UserService) { - this.title = config.title; - } - // #enddocregion ctor - - get isAuthorized() { return this.user.isAuthorized;} - nextUser() { this.userService.getNewUser(); } - get user() { return this.userService.user; } - - get userInfo() { - return `Current user, ${this.user.name}, is `+ - `${this.isAuthorized ? '' : 'not'} authorized. `; - } -} diff --git a/public/docs/_examples/dependency-injection/ts/app/app.config.ts b/public/docs/_examples/dependency-injection/ts/app/app.config.ts deleted file mode 100644 index fcffa83628..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/app.config.ts +++ /dev/null @@ -1,16 +0,0 @@ -// #docregion token -import { OpaqueToken } from '@angular/core'; - -export let APP_CONFIG = new OpaqueToken('app.config'); -// #enddocregion token - -//#docregion config -export interface AppConfig { - apiEndpoint: string, - title: string -} - -export const HERO_DI_CONFIG: AppConfig = { - apiEndpoint: 'api.heroes.com', - title: 'Dependency Injection' -}; diff --git a/public/docs/_examples/dependency-injection/ts/app/car/car-creations.ts b/public/docs/_examples/dependency-injection/ts/app/car/car-creations.ts deleted file mode 100644 index 2693ba37ca..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/car/car-creations.ts +++ /dev/null @@ -1,46 +0,0 @@ -// Examples with car and engine variations - -// #docplaster -import { Car, Engine, Tires } from './car'; - -///////// example 1 //////////// -export function simpleCar() { - //#docregion car-ctor-instantiation - // Simple car with 4 cylinders and Flintstone tires. - var car = new Car(new Engine(), new Tires()); - //#enddocregion car-ctor-instantiation - car.description = 'Simple'; - return car; -} - - -///////// example 2 //////////// -//#docregion car-ctor-instantiation-with-param - class Engine2 { - constructor(public cylinders: number) { } - } -//#enddocregion car-ctor-instantiation-with-param -export function superCar() { -//#docregion car-ctor-instantiation-with-param - // Super car with 12 cylinders and Flintstone tires. - var bigCylinders = 12; - var car = new Car(new Engine2(bigCylinders), new Tires()); -//#enddocregion car-ctor-instantiation-with-param - car.description = 'Super'; - return car; -} - -/////////// example 3 ////////// - //#docregion car-ctor-instantiation-with-mocks - class MockEngine extends Engine { cylinders = 8; } - class MockTires extends Tires { make = "YokoGoodStone"; } - - //#enddocregion car-ctor-instantiation-with-mocks -export function testCar() { - //#docregion car-ctor-instantiation-with-mocks - // Test car with 8 cylinders and YokoGoodStone tires. - var car = new Car(new MockEngine(), new MockTires()); - //#enddocregion car-ctor-instantiation-with-mocks - car.description = 'Test'; - return car; -} diff --git a/public/docs/_examples/dependency-injection/ts/app/heroes/hero-list.component.ts b/public/docs/_examples/dependency-injection/ts/app/heroes/hero-list.component.ts deleted file mode 100644 index e841669661..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/heroes/hero-list.component.ts +++ /dev/null @@ -1,25 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { Hero } from './hero'; -import { HeroService } from './hero.service'; - -@Component({ - selector: 'hero-list', - template: ` -

    - {{hero.id}} - {{hero.name}} - ({{hero.isSecret ? 'secret' : 'public'}}) -
    - `, -}) -export class HeroListComponent { - heroes: Hero[]; - - // #docregion ctor-signature - constructor(heroService: HeroService) - // #enddocregion ctor-signature - { - this.heroes = heroService.getHeroes(); - } -} diff --git a/public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.1.ts b/public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.1.ts deleted file mode 100644 index a5a715dbae..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.1.ts +++ /dev/null @@ -1,10 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -import { Hero } from './hero'; -import { HEROES } from './mock-heroes'; - -@Injectable() -export class HeroService { - getHeroes() { return HEROES; } -} diff --git a/public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.2.ts b/public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.2.ts deleted file mode 100644 index 0947d60494..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.2.ts +++ /dev/null @@ -1,19 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -import { Hero } from './hero'; -import { HEROES } from './mock-heroes'; -import { Logger } from '../logger.service'; - -@Injectable() -export class HeroService { - - //#docregion ctor - constructor(private logger: Logger) { } - //#enddocregion ctor - - getHeroes() { - this.logger.log('Getting heroes ...') - return HEROES; - } -} diff --git a/public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.ts b/public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.ts deleted file mode 100644 index 7e84ae5058..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.ts +++ /dev/null @@ -1,23 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -import { Hero } from './hero'; -import { HEROES } from './mock-heroes'; -import { Logger } from '../logger.service'; - -@Injectable() -export class HeroService { - private _user:string; - - // #docregion internals - constructor( - private logger: Logger, - private isAuthorized: boolean) { } - - getHeroes() { - let auth = this.isAuthorized ? 'authorized ': 'unauthorized'; - this.logger.log(`Getting heroes for ${auth} user.`); - return HEROES.filter(hero => this.isAuthorized || !hero.isSecret); - } - // #enddocregion internals -} diff --git a/public/docs/_examples/dependency-injection/ts/app/heroes/heroes.component.1.ts b/public/docs/_examples/dependency-injection/ts/app/heroes/heroes.component.1.ts deleted file mode 100644 index 247b8c7841..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/heroes/heroes.component.1.ts +++ /dev/null @@ -1,28 +0,0 @@ -// #docplaster -// #docregion full, v1 -import { Component } from '@angular/core'; - -// #enddocregion full, v1 -import { HeroListComponent } from './hero-list.component.2'; -import { HeroService } from './hero.service.1'; -/* -// #docregion full -import { HeroListComponent } from './hero-list.component'; -// #docregion v1 -import { HeroService } from './hero.service'; -// #enddocregion full, v1 -*/ -// #docregion full, v1 - -@Component({ - selector: 'my-heroes', - template: ` -

    Heroes

    - - `, - // #enddocregion v1 - providers:[HeroService], - // #docregion v1 - directives:[HeroListComponent] -}) -export class HeroesComponent { } diff --git a/public/docs/_examples/dependency-injection/ts/app/heroes/heroes.component.ts b/public/docs/_examples/dependency-injection/ts/app/heroes/heroes.component.ts deleted file mode 100644 index de46be16c3..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/heroes/heroes.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { HeroListComponent } from './hero-list.component'; -import { heroServiceProvider} from './hero.service.provider'; - -@Component({ - selector: 'my-heroes', - template: ` -

    Heroes

    - - `, - providers:[heroServiceProvider], - directives:[HeroListComponent] -}) -export class HeroesComponent { } diff --git a/public/docs/_examples/dependency-injection/ts/app/heroes/mock-heroes.ts b/public/docs/_examples/dependency-injection/ts/app/heroes/mock-heroes.ts deleted file mode 100644 index 98695e90ce..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/heroes/mock-heroes.ts +++ /dev/null @@ -1,15 +0,0 @@ -// #docregion -import { Hero } from './hero'; - -export var HEROES: Hero[] = [ - { id: 11, isSecret: false, name: "Mr. Nice" }, - { id: 12, isSecret: false, name: "Narco" }, - { id: 13, isSecret: false, name: "Bombasto" }, - { id: 14, isSecret: false, name: "Celeritas" }, - { id: 15, isSecret: false, name: "Magneta" }, - { id: 16, isSecret: false, name: "RubberMan" }, - { id: 17, isSecret: false, name: "Dynama" }, - { id: 18, isSecret: true, name: "Dr IQ" }, - { id: 19, isSecret: true, name: "Magma" }, - { id: 20, isSecret: true, name: "Tornado" } -]; diff --git a/public/docs/_examples/dependency-injection/ts/app/injector.component.ts b/public/docs/_examples/dependency-injection/ts/app/injector.component.ts deleted file mode 100644 index 84c8de4a95..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/injector.component.ts +++ /dev/null @@ -1,43 +0,0 @@ -// #docplaster -// #docregion -import { Component, Injector } from '@angular/core'; - -import { Car, Engine, Tires } from './car/car'; -import { Hero } from './heroes/hero'; -import { HeroService } from './heroes/hero.service'; -import { heroServiceProvider } from './heroes/hero.service.provider'; -import { Logger } from './logger.service'; - -// #docregion injector -@Component({ - selector: 'my-injectors', - template: ` -

    Other Injections

    -
    {{car.drive()}}
    -
    {{hero.name}}
    -
    {{rodent}}
    - `, - providers: [Car, Engine, Tires, heroServiceProvider, Logger] -}) -export class InjectorComponent { - constructor(private injector: Injector) { } - - car: Car = this.injector.get(Car); - - // #docregion get-hero-service - heroService: HeroService = this.injector.get(HeroService); - // #enddocregion get-hero-service - hero: Hero = this.heroService.getHeroes()[0]; - - get rodent() { - let rousDontExist = "R.O.U.S.'s? I don't think they exist!"; - return this.injector.get(ROUS, rousDontExist); - } -} -// #enddocregion injector - -/** - * R.O.U.S. - Rodents Of Unusual Size - * // https://www.youtube.com/watch?v=BOv5ZjAOpC8 - */ -class ROUS { } diff --git a/public/docs/_examples/dependency-injection/ts/app/logger.service.ts b/public/docs/_examples/dependency-injection/ts/app/logger.service.ts deleted file mode 100644 index 4812ccd3ac..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/logger.service.ts +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -@Injectable() -export class Logger { - logs:string[] = []; // capture logs for testing - - log(message: string) { - this.logs.push(message); - console.log(message); - } -} diff --git a/public/docs/_examples/dependency-injection/ts/app/main.1.ts b/public/docs/_examples/dependency-injection/ts/app/main.1.ts deleted file mode 100644 index 56169511d5..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/main.1.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { AppComponent } from './app.component.1'; -import { HeroService } from './heroes/hero.service.1'; - -bootstrap(AppComponent); - -function discouraged() { - //#docregion bootstrap-discouraged - bootstrap(AppComponent, - [HeroService]); // DISCOURAGED (but works) - //#enddocregion bootstrap-discouraged -} diff --git a/public/docs/_examples/dependency-injection/ts/app/main.ts b/public/docs/_examples/dependency-injection/ts/app/main.ts deleted file mode 100644 index 8e480e8d7f..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { AppComponent } from './app.component'; -import { ProvidersComponent } from './providers.component'; - -//#docregion bootstrap -bootstrap(AppComponent); -//#enddocregion bootstrap -bootstrap(ProvidersComponent); diff --git a/public/docs/_examples/dependency-injection/ts/app/test.component.ts b/public/docs/_examples/dependency-injection/ts/app/test.component.ts deleted file mode 100644 index 068cf65e7b..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/test.component.ts +++ /dev/null @@ -1,54 +0,0 @@ -// Simulate a simple test -// Reader should look to the testing chapter for the real thing - -import { Component } from '@angular/core'; - -import { HeroService } from './heroes/hero.service'; -import { HeroListComponent } from './heroes/hero-list.component'; - -@Component({ - selector: 'my-tests', - template: ` -

    Tests

    -

    Tests {{results.pass}}: {{results.message}}

    - ` -}) -export class TestComponent { - results = runTests(); -} - -///////////////////////////////////// -function runTests() { - - //#docregion spec - let expectedHeroes = [{name: 'A'}, {name: 'B'}] - let mockService = {getHeroes: () => expectedHeroes } - - it("should have heroes when HeroListComponent created", () => { - let hlc = new HeroListComponent(mockService); - expect(hlc.heroes.length).toEqual(expectedHeroes.length); - }) - //#enddocregion spec - - return testResults; -} - -////////////////////////////////// -// Fake Jasmine infrastructure -var testName: string; -var testResults: {pass:string; message:string}; - -function expect(actual:any) { - return { - toEqual: function(expected:any){ - testResults = actual === expected? - {pass:'passed', message: testName} : - {pass:'failed', message: `${testName}; expected ${actual} to equal ${expected}.`}; - } - } -} - -function it(label:string, test: () => void) { - testName = label; - test(); -} diff --git a/public/docs/_examples/dependency-injection/ts/app/user.service.ts b/public/docs/_examples/dependency-injection/ts/app/user.service.ts deleted file mode 100644 index 25e09ecaf8..0000000000 --- a/public/docs/_examples/dependency-injection/ts/app/user.service.ts +++ /dev/null @@ -1,22 +0,0 @@ -// #docregion -import {Injectable} from '@angular/core'; - -export class User { - constructor( - public name:string, - public isAuthorized:boolean = false) { } -} - -// Todo: get the user; don't 'new' it. -let alice = new User('Alice', true); -let bob = new User('Bob', false); - -@Injectable() -export class UserService { - user = bob; // initial user is Bob - - // swap users - getNewUser() { - return this.user = this.user === bob ? alice : bob; - } -} diff --git a/public/docs/_examples/dependency-injection/ts/index.html b/public/docs/_examples/dependency-injection/ts/index.html deleted file mode 100644 index 74f8ed8894..0000000000 --- a/public/docs/_examples/dependency-injection/ts/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Dependency Injection - - - - - - - - - - - - - - - - - - Loading my-app ... - Loading my-providers ... - - - diff --git a/public/docs/_examples/dependency-injection/ts/plnkr.json b/public/docs/_examples/dependency-injection/ts/plnkr.json index dff3dc4110..e8d1ab24b2 100644 --- a/public/docs/_examples/dependency-injection/ts/plnkr.json +++ b/public/docs/_examples/dependency-injection/ts/plnkr.json @@ -1,9 +1,10 @@ { "description": "Dependency Injection", + "basePath": "src/", "files":[ "!**/*.d.ts", "!**/*.js", "!**/*.[1,2].*" ], "tags": ["dependency", "di"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/dependency-injection/ts/src/app/app.component.1.ts b/public/docs/_examples/dependency-injection/ts/src/app/app.component.1.ts new file mode 100644 index 0000000000..b398ebeb57 --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/app.component.1.ts @@ -0,0 +1,17 @@ +// Early versions + +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` +

    {{title}}

    + + + ` +}) + +export class AppComponent { + title = 'Dependency Injection'; +} diff --git a/public/docs/_examples/dependency-injection/ts/src/app/app.component.2.ts b/public/docs/_examples/dependency-injection/ts/src/app/app.component.2.ts new file mode 100644 index 0000000000..d24df5568c --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/app.component.2.ts @@ -0,0 +1,25 @@ +// #docregion +// #docregion imports +import { Component } from '@angular/core'; +import { Inject } from '@angular/core'; + +import { APP_CONFIG, AppConfig } from './app.config'; +// #enddocregion imports + +@Component({ + selector: 'my-app', + template: ` +

    {{title}}

    + + + ` +}) +export class AppComponent { + title: string; + + // #docregion ctor + constructor(@Inject(APP_CONFIG) config: AppConfig) { + this.title = config.title; + } + // #enddocregion ctor +} diff --git a/public/docs/_examples/dependency-injection/ts/src/app/app.component.ts b/public/docs/_examples/dependency-injection/ts/src/app/app.component.ts new file mode 100644 index 0000000000..3563fdc070 --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/app.component.ts @@ -0,0 +1,48 @@ +// #docplaster +// #docregion +// #docregion imports +import { Component, Inject } from '@angular/core'; + +import { APP_CONFIG, AppConfig } from './app.config'; +import { Logger } from './logger.service'; +import { UserService } from './user.service'; +// #enddocregion imports + +@Component({ + selector: 'my-app', + template: ` +

    {{title}}

    + + + +

    User

    +

    + {{userInfo}} + +

    + + + + `, + providers: [Logger] +}) +export class AppComponent { + title: string; + + // #docregion ctor + constructor( + @Inject(APP_CONFIG) config: AppConfig, + private userService: UserService) { + this.title = config.title; + } + // #enddocregion ctor + + get isAuthorized() { return this.user.isAuthorized; } + nextUser() { this.userService.getNewUser(); } + get user() { return this.userService.user; } + + get userInfo() { + return `Current user, ${this.user.name}, is ` + + `${this.isAuthorized ? '' : 'not'} authorized. `; + } +} diff --git a/public/docs/_examples/dependency-injection/ts/src/app/app.config.ts b/public/docs/_examples/dependency-injection/ts/src/app/app.config.ts new file mode 100644 index 0000000000..f224e6e1ab --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/app.config.ts @@ -0,0 +1,16 @@ +// #docregion token +import { InjectionToken } from '@angular/core'; + +export let APP_CONFIG = new InjectionToken('app.config'); +// #enddocregion token + +// #docregion config +export interface AppConfig { + apiEndpoint: string; + title: string; +} + +export const HERO_DI_CONFIG: AppConfig = { + apiEndpoint: 'api.heroes.com', + title: 'Dependency Injection' +}; diff --git a/public/docs/_examples/dependency-injection/ts/src/app/app.module.ts b/public/docs/_examples/dependency-injection/ts/src/app/app.module.ts new file mode 100644 index 0000000000..67ae8ae913 --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/app.module.ts @@ -0,0 +1,60 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { CarComponent } from './car/car.component'; +import { HeroesComponent } from './heroes/heroes.component'; +import { HeroListComponent } from './heroes/hero-list.component'; +import { InjectorComponent } from './injector.component'; +import { TestComponent } from './test.component'; +import { APP_CONFIG, HERO_DI_CONFIG } from './app.config'; +import { UserService } from './user.service'; +import { + ProvidersComponent, + Provider1Component, + Provider3Component, + Provider4Component, + Provider5Component, + Provider6aComponent, + Provider6bComponent, + Provider7Component, + Provider8Component, + Provider9Component, + Provider10Component, +} from './providers.component'; + +// #docregion ngmodule +@NgModule({ + imports: [ + BrowserModule + ], + declarations: [ + AppComponent, + CarComponent, + HeroesComponent, + // #enddocregion ngmodule + HeroListComponent, + InjectorComponent, + TestComponent, + ProvidersComponent, + Provider1Component, + Provider3Component, + Provider4Component, + Provider5Component, + Provider6aComponent, + Provider6bComponent, + Provider7Component, + Provider8Component, + Provider9Component, + Provider10Component, + // #docregion ngmodule + ], + // #docregion ngmodule-providers + providers: [ + UserService, + { provide: APP_CONFIG, useValue: HERO_DI_CONFIG } + ], + // #enddocregion ngmodule-providers + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/dependency-injection/ts/src/app/car/car-creations.ts b/public/docs/_examples/dependency-injection/ts/src/app/car/car-creations.ts new file mode 100644 index 0000000000..c758c72951 --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/car/car-creations.ts @@ -0,0 +1,46 @@ +// Examples with car and engine variations + +// #docplaster +import { Car, Engine, Tires } from './car'; + +///////// example 1 //////////// +export function simpleCar() { + // #docregion car-ctor-instantiation + // Simple car with 4 cylinders and Flintstone tires. + let car = new Car(new Engine(), new Tires()); + // #enddocregion car-ctor-instantiation + car.description = 'Simple'; + return car; +} + + +///////// example 2 //////////// +// #docregion car-ctor-instantiation-with-param + class Engine2 { + constructor(public cylinders: number) { } + } +// #enddocregion car-ctor-instantiation-with-param +export function superCar() { +// #docregion car-ctor-instantiation-with-param + // Super car with 12 cylinders and Flintstone tires. + let bigCylinders = 12; + let car = new Car(new Engine2(bigCylinders), new Tires()); +// #enddocregion car-ctor-instantiation-with-param + car.description = 'Super'; + return car; +} + +/////////// example 3 ////////// + // #docregion car-ctor-instantiation-with-mocks + class MockEngine extends Engine { cylinders = 8; } + class MockTires extends Tires { make = 'YokoGoodStone'; } + + // #enddocregion car-ctor-instantiation-with-mocks +export function testCar() { + // #docregion car-ctor-instantiation-with-mocks + // Test car with 8 cylinders and YokoGoodStone tires. + let car = new Car(new MockEngine(), new MockTires()); + // #enddocregion car-ctor-instantiation-with-mocks + car.description = 'Test'; + return car; +} diff --git a/public/docs/_examples/dependency-injection/ts/app/car/car-factory.ts b/public/docs/_examples/dependency-injection/ts/src/app/car/car-factory.ts similarity index 100% rename from public/docs/_examples/dependency-injection/ts/app/car/car-factory.ts rename to public/docs/_examples/dependency-injection/ts/src/app/car/car-factory.ts diff --git a/public/docs/_examples/dependency-injection/ts/app/car/car-injector.ts b/public/docs/_examples/dependency-injection/ts/src/app/car/car-injector.ts similarity index 75% rename from public/docs/_examples/dependency-injection/ts/app/car/car-injector.ts rename to public/docs/_examples/dependency-injection/ts/src/app/car/car-injector.ts index 04d379785f..4f7498ee4e 100644 --- a/public/docs/_examples/dependency-injection/ts/app/car/car-injector.ts +++ b/public/docs/_examples/dependency-injection/ts/src/app/car/car-injector.ts @@ -5,23 +5,23 @@ import { Logger } from '../logger.service'; // #docregion injector export function useInjector() { - var injector: ReflectiveInjector; + let injector: ReflectiveInjector; // #enddocregion injector /* // #docregion injector-no-new // Cannot instantiate an ReflectiveInjector like this! - var injector = new ReflectiveInjector([Car, Engine, Tires]); + let injector = new ReflectiveInjector([Car, Engine, Tires]); // #enddocregion injector-no-new */ // #docregion injector, injector-create-and-call injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires]); // #docregion injector-call - var car = injector.get(Car); + let car = injector.get(Car); // #enddocregion injector-call, injector-create-and-call car.description = 'Injector'; injector = ReflectiveInjector.resolveAndCreate([Logger]); - var logger = injector.get(Logger); - logger.log('Injector car.drive() said: '+car.drive()); + let logger = injector.get(Logger); + logger.log('Injector car.drive() said: ' + car.drive()); return car; } diff --git a/public/docs/_examples/dependency-injection/ts/app/car/car-no-di.ts b/public/docs/_examples/dependency-injection/ts/src/app/car/car-no-di.ts similarity index 80% rename from public/docs/_examples/dependency-injection/ts/app/car/car-no-di.ts rename to public/docs/_examples/dependency-injection/ts/src/app/car/car-no-di.ts index 059dccd4b7..9026edebc2 100644 --- a/public/docs/_examples/dependency-injection/ts/app/car/car-no-di.ts +++ b/public/docs/_examples/dependency-injection/ts/src/app/car/car-no-di.ts @@ -1,10 +1,10 @@ // Car without DI import { Engine, Tires } from './car'; -//#docregion car +// #docregion car export class Car { - //#docregion car-ctor + // #docregion car-ctor public engine: Engine; public tires: Tires; public description = 'No DI'; @@ -13,12 +13,12 @@ export class Car { this.engine = new Engine(); this.tires = new Tires(); } - //#enddocregion car-ctor + // #enddocregion car-ctor // Method using the engine and tires drive() { return `${this.description} car with ` + - `${this.engine.cylinders} cylinders and ${this.tires.make} tires.` + `${this.engine.cylinders} cylinders and ${this.tires.make} tires.`; } } -//#enddocregion car \ No newline at end of file +// #enddocregion car diff --git a/public/docs/_examples/dependency-injection/ts/app/car/car.component.ts b/public/docs/_examples/dependency-injection/ts/src/app/car/car.component.ts similarity index 94% rename from public/docs/_examples/dependency-injection/ts/app/car/car.component.ts rename to public/docs/_examples/dependency-injection/ts/src/app/car/car.component.ts index f9f982ebd0..9a835ef124 100644 --- a/public/docs/_examples/dependency-injection/ts/app/car/car.component.ts +++ b/public/docs/_examples/dependency-injection/ts/src/app/car/car.component.ts @@ -1,5 +1,5 @@ // #docregion -import { Component, Injector } from '@angular/core'; +import { Component } from '@angular/core'; import { Car, Engine, Tires } from './car'; import { Car as CarNoDi } from './car-no-di'; @@ -27,12 +27,12 @@ import { useInjector } from './car-injector'; providers: [Car, Engine, Tires] }) export class CarComponent { - constructor(public car: Car) {} - factoryCar = (new CarFactory).createCar(); injectorCar = useInjector(); noDiCar = new CarNoDi; simpleCar = simpleCar(); superCar = superCar(); testCar = testCar(); + + constructor(public car: Car) {} } diff --git a/public/docs/_examples/dependency-injection/ts/app/car/car.ts b/public/docs/_examples/dependency-injection/ts/src/app/car/car.ts similarity index 93% rename from public/docs/_examples/dependency-injection/ts/app/car/car.ts rename to public/docs/_examples/dependency-injection/ts/src/app/car/car.ts index 0e4a4a1415..37162c570b 100644 --- a/public/docs/_examples/dependency-injection/ts/app/car/car.ts +++ b/public/docs/_examples/dependency-injection/ts/src/app/car/car.ts @@ -11,7 +11,7 @@ export class Tires { @Injectable() export class Car { - //#docregion car-ctor + // #docregion car-ctor public description = 'DI'; constructor(public engine: Engine, public tires: Tires) { } @@ -20,6 +20,6 @@ export class Car { // Method using the engine and tires drive() { return `${this.description} car with ` + - `${this.engine.cylinders} cylinders and ${this.tires.make} tires.` + `${this.engine.cylinders} cylinders and ${this.tires.make} tires.`; } } diff --git a/public/docs/_examples/dependency-injection/ts/app/heroes/hero-list.component.1.ts b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero-list.component.1.ts similarity index 100% rename from public/docs/_examples/dependency-injection/ts/app/heroes/hero-list.component.1.ts rename to public/docs/_examples/dependency-injection/ts/src/app/heroes/hero-list.component.1.ts diff --git a/public/docs/_examples/dependency-injection/ts/app/heroes/hero-list.component.2.ts b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero-list.component.2.ts similarity index 99% rename from public/docs/_examples/dependency-injection/ts/app/heroes/hero-list.component.2.ts rename to public/docs/_examples/dependency-injection/ts/src/app/heroes/hero-list.component.2.ts index 6b55f78a6e..cb23d3257c 100644 --- a/public/docs/_examples/dependency-injection/ts/app/heroes/hero-list.component.2.ts +++ b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero-list.component.2.ts @@ -18,7 +18,7 @@ import { HeroService } from './hero.service';

    {{hero.id}} - {{hero.name}}
    - `, + ` }) export class HeroListComponent { heroes: Hero[]; diff --git a/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero-list.component.ts b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero-list.component.ts new file mode 100644 index 0000000000..db3a325bdb --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero-list.component.ts @@ -0,0 +1,26 @@ +/* tslint:disable:one-line */ +// #docregion +import { Component } from '@angular/core'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +@Component({ + selector: 'hero-list', + template: ` +
    + {{hero.id}} - {{hero.name}} + ({{hero.isSecret ? 'secret' : 'public'}}) +
    + `, +}) +export class HeroListComponent { + heroes: Hero[]; + + // #docregion ctor-signature + constructor(heroService: HeroService) + // #enddocregion ctor-signature + { + this.heroes = heroService.getHeroes(); + } +} diff --git a/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.1.ts b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.1.ts new file mode 100644 index 0000000000..2e0e3ca734 --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.1.ts @@ -0,0 +1,9 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { HEROES } from './mock-heroes'; + +@Injectable() +export class HeroService { + getHeroes() { return HEROES; } +} diff --git a/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.2.ts b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.2.ts new file mode 100644 index 0000000000..6b3a98306a --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.2.ts @@ -0,0 +1,18 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { HEROES } from './mock-heroes'; +import { Logger } from '../logger.service'; + +@Injectable() +export class HeroService { + + // #docregion ctor + constructor(private logger: Logger) { } + // #enddocregion ctor + + getHeroes() { + this.logger.log('Getting heroes ...'); + return HEROES; + } +} diff --git a/public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.provider.ts b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.provider.ts similarity index 89% rename from public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.provider.ts rename to public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.provider.ts index 557e9b9534..6de4ebee90 100644 --- a/public/docs/_examples/dependency-injection/ts/app/heroes/hero.service.provider.ts +++ b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.provider.ts @@ -1,3 +1,4 @@ +/* tslint:disable:one-line */ // #docregion import { HeroService } from './hero.service'; import { Logger } from '../logger.service'; @@ -6,12 +7,12 @@ import { UserService } from '../user.service'; // #docregion factory let heroServiceFactory = (logger: Logger, userService: UserService) => { return new HeroService(logger, userService.user.isAuthorized); -} +}; // #enddocregion factory // #docregion provider export let heroServiceProvider = - { provide: HeroService, + { provide: HeroService, useFactory: heroServiceFactory, deps: [Logger, UserService] }; diff --git a/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.ts b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.ts new file mode 100644 index 0000000000..fb03ec1de6 --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.service.ts @@ -0,0 +1,20 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { HEROES } from './mock-heroes'; +import { Logger } from '../logger.service'; + +@Injectable() +export class HeroService { + // #docregion internals + constructor( + private logger: Logger, + private isAuthorized: boolean) { } + + getHeroes() { + let auth = this.isAuthorized ? 'authorized ' : 'unauthorized'; + this.logger.log(`Getting heroes for ${auth} user.`); + return HEROES.filter(hero => this.isAuthorized || !hero.isSecret); + } + // #enddocregion internals +} diff --git a/public/docs/_examples/dependency-injection/ts/app/heroes/hero.ts b/public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.ts similarity index 100% rename from public/docs/_examples/dependency-injection/ts/app/heroes/hero.ts rename to public/docs/_examples/dependency-injection/ts/src/app/heroes/hero.ts diff --git a/public/docs/_examples/dependency-injection/ts/src/app/heroes/heroes.component.1.ts b/public/docs/_examples/dependency-injection/ts/src/app/heroes/heroes.component.1.ts new file mode 100644 index 0000000000..e0e9deae08 --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/heroes/heroes.component.1.ts @@ -0,0 +1,21 @@ +// #docplaster +// #docregion full, v1 +import { Component } from '@angular/core'; +// #enddocregion v1 + +import { HeroService } from './hero.service'; +// #enddocregion full + +// #docregion full, v1 + +@Component({ + selector: 'my-heroes', + // #enddocregion v1 + providers: [HeroService], + // #docregion v1 + template: ` +

    Heroes

    + + ` +}) +export class HeroesComponent { } diff --git a/public/docs/_examples/dependency-injection/ts/src/app/heroes/heroes.component.ts b/public/docs/_examples/dependency-injection/ts/src/app/heroes/heroes.component.ts new file mode 100644 index 0000000000..5923f7590b --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/heroes/heroes.component.ts @@ -0,0 +1,14 @@ +// #docregion +import { Component } from '@angular/core'; + +import { heroServiceProvider } from './hero.service.provider'; + +@Component({ + selector: 'my-heroes', + template: ` +

    Heroes

    + + `, + providers: [heroServiceProvider] +}) +export class HeroesComponent { } diff --git a/public/docs/_examples/dependency-injection/ts/src/app/heroes/mock-heroes.ts b/public/docs/_examples/dependency-injection/ts/src/app/heroes/mock-heroes.ts new file mode 100644 index 0000000000..79a91dc03a --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/heroes/mock-heroes.ts @@ -0,0 +1,15 @@ +// #docregion +import { Hero } from './hero'; + +export var HEROES: Hero[] = [ + { id: 11, isSecret: false, name: 'Mr. Nice' }, + { id: 12, isSecret: false, name: 'Narco' }, + { id: 13, isSecret: false, name: 'Bombasto' }, + { id: 14, isSecret: false, name: 'Celeritas' }, + { id: 15, isSecret: false, name: 'Magneta' }, + { id: 16, isSecret: false, name: 'RubberMan' }, + { id: 17, isSecret: false, name: 'Dynama' }, + { id: 18, isSecret: true, name: 'Dr IQ' }, + { id: 19, isSecret: true, name: 'Magma' }, + { id: 20, isSecret: true, name: 'Tornado' } +]; diff --git a/public/docs/_examples/dependency-injection/ts/src/app/injector.component.ts b/public/docs/_examples/dependency-injection/ts/src/app/injector.component.ts new file mode 100644 index 0000000000..1b1a065e4c --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/injector.component.ts @@ -0,0 +1,49 @@ +// #docplaster +// #docregion +import { Component, Injector, OnInit } from '@angular/core'; + +import { Car, Engine, Tires } from './car/car'; +import { Hero } from './heroes/hero'; +import { HeroService } from './heroes/hero.service'; +import { heroServiceProvider } from './heroes/hero.service.provider'; +import { Logger } from './logger.service'; + +// #docregion injector +@Component({ + selector: 'my-injectors', + template: ` +

    Other Injections

    +
    {{car.drive()}}
    +
    {{hero.name}}
    +
    {{rodent}}
    + `, + providers: [Car, Engine, Tires, heroServiceProvider, Logger] +}) +export class InjectorComponent implements OnInit { + car: Car; + + // #docregion get-hero-service + heroService: HeroService; + // #enddocregion get-hero-service + hero: Hero; + + constructor(private injector: Injector) { } + + ngOnInit() { + this.car = this.injector.get(Car); + this.heroService = this.injector.get(HeroService); + this.hero = this.heroService.getHeroes()[0]; + } + + get rodent() { + let rousDontExist = `R.O.U.S.'s? I don't think they exist!`; + return this.injector.get(ROUS, rousDontExist); + } +} +// #enddocregion injector + +/** + * R.O.U.S. - Rodents Of Unusual Size + * // https://www.youtube.com/watch?v=BOv5ZjAOpC8 + */ +class ROUS { } diff --git a/public/docs/_examples/dependency-injection/ts/src/app/logger.service.ts b/public/docs/_examples/dependency-injection/ts/src/app/logger.service.ts new file mode 100644 index 0000000000..e943523ad2 --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/logger.service.ts @@ -0,0 +1,12 @@ +// #docregion +import { Injectable } from '@angular/core'; + +@Injectable() +export class Logger { + logs: string[] = []; // capture logs for testing + + log(message: string) { + this.logs.push(message); + console.log(message); + } +} diff --git a/public/docs/_examples/dependency-injection/ts/app/providers.component.ts b/public/docs/_examples/dependency-injection/ts/src/app/providers.component.ts similarity index 86% rename from public/docs/_examples/dependency-injection/ts/app/providers.component.ts rename to public/docs/_examples/dependency-injection/ts/src/app/providers.component.ts index 640247d4b6..a96bfce99e 100644 --- a/public/docs/_examples/dependency-injection/ts/app/providers.component.ts +++ b/public/docs/_examples/dependency-injection/ts/src/app/providers.component.ts @@ -1,7 +1,7 @@ /* tslint:disable:one-line:check-open-brace*/ // Examples of provider arrays // #docplaster -import { Component, Inject, Injectable } from '@angular/core'; +import { Component, Inject, Injectable, OnInit } from '@angular/core'; import { APP_CONFIG, AppConfig, HERO_DI_CONFIG } from './app.config'; @@ -21,7 +21,7 @@ let template = '{{log}}'; providers: [Logger] // #enddocregion providers-1, providers-logger }) -export class ProviderComponent1 { +export class Provider1Component { log: string; constructor(logger: Logger) { logger.log('Hello from logger provided with Logger class'); @@ -31,17 +31,17 @@ export class ProviderComponent1 { ////////////////////////////////////////// @Component({ - selector: 'provider-3a', + selector: 'provider-3', template: template, providers: - // #docregion providers-3a + // #docregion providers-3 [{ provide: Logger, useClass: Logger }] - // #enddocregion providers-3a + // #enddocregion providers-3 }) -export class ProviderComponent3a { +export class Provider3Component { log: string; constructor(logger: Logger) { - logger.log('Hello from logger provided with { provide: Logger, useClass: Logger }'); + logger.log('Hello from logger provided with useClass:Logger'); this.log = logger.logs[0]; } } @@ -57,7 +57,7 @@ class BetterLogger extends Logger {} [{ provide: Logger, useClass: BetterLogger }] // #enddocregion providers-4 }) -export class ProviderComponent4 { +export class Provider4Component { log: string; constructor(logger: Logger) { logger.log('Hello from logger provided with useClass:BetterLogger'); @@ -87,7 +87,7 @@ class EvenBetterLogger extends Logger { { provide: Logger, useClass: EvenBetterLogger }] // #enddocregion providers-5 }) -export class ProviderComponent5 { +export class Provider5Component { log: string; constructor(logger: Logger) { logger.log('Hello from EvenBetterlogger'); @@ -114,7 +114,7 @@ class OldLogger { { provide: OldLogger, useClass: NewLogger}] // #enddocregion providers-6a }) -export class ProviderComponent6a { +export class Provider6aComponent { log: string; constructor(newLogger: NewLogger, oldLogger: OldLogger) { if (newLogger === oldLogger){ @@ -137,7 +137,7 @@ export class ProviderComponent6a { { provide: OldLogger, useExisting: NewLogger}] // #enddocregion providers-6b }) -export class ProviderComponent6b { +export class Provider6bComponent { log: string; constructor(newLogger: NewLogger, oldLogger: OldLogger) { if (newLogger !== oldLogger){ @@ -165,7 +165,7 @@ let silentLogger = { [{ provide: Logger, useValue: silentLogger }] // #enddocregion providers-7 }) -export class ProviderComponent7 { +export class Provider7Component { log: string; constructor(logger: Logger) { logger.log('Hello from logger provided with useValue'); @@ -179,13 +179,13 @@ export class ProviderComponent7 { template: template, providers: [heroServiceProvider, Logger, UserService] }) -export class ProviderComponent8 { +export class Provider8Component { + // must be true else this component would have blown up at runtime + log = 'Hero service injected successfully via heroServiceProvider'; + // #docregion provider-8-ctor constructor(heroService: HeroService) { } // #enddocregion provider-8-ctor - - // must be true else this component would have blown up at runtime - log = 'Hero service injected successfully via heroServiceProvider'; } ///////////////// @@ -194,7 +194,7 @@ export class ProviderComponent8 { template: template, /* // #docregion providers-9-interface - // FAIL! Can't use interface as provider token + // FAIL! Can't use interface as provider token [{ provide: AppConfig, useValue: HERO_DI_CONFIG })] // #enddocregion providers-9-interface */ @@ -202,7 +202,7 @@ export class ProviderComponent8 { providers: [{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }] // #enddocregion providers-9 }) -export class ProviderComponent9 { +export class Provider9Component implements OnInit { log: string; /* // #docregion provider-9-ctor-interface @@ -225,18 +225,20 @@ export class ProviderComponent9 { import { Optional } from '@angular/core'; // #enddocregion import-optional -let some_message: string = 'Hello from the injected logger'; +let some_message = 'Hello from the injected logger'; @Component({ selector: 'provider-10', - template: template + template: template, + providers: [{ provide: Logger, useValue: null }] }) -export class ProviderComponent10 { +export class Provider10Component implements OnInit { log: string; // #docregion provider-10-ctor constructor(@Optional() private logger: Logger) { - if (this.logger) + if (this.logger) { this.logger.log(some_message); + } } // #enddocregion provider-10-ctor @@ -251,7 +253,7 @@ export class ProviderComponent10 { template: `

    Provider variations

    -
    +
    @@ -260,18 +262,6 @@ export class ProviderComponent10 {
    - `, - directives: [ - ProviderComponent1, - ProviderComponent3a, - ProviderComponent4, - ProviderComponent5, - ProviderComponent6a, - ProviderComponent6b, - ProviderComponent7, - ProviderComponent8, - ProviderComponent9, - ProviderComponent10, - ], + ` }) export class ProvidersComponent { } diff --git a/public/docs/_examples/dependency-injection/ts/src/app/test.component.ts b/public/docs/_examples/dependency-injection/ts/src/app/test.component.ts new file mode 100644 index 0000000000..fc0fef75a8 --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/test.component.ts @@ -0,0 +1,55 @@ +/* tslint:disable */ +// Simulate a simple test +// Reader should look to the testing chapter for the real thing + +import { Component } from '@angular/core'; + +import { HeroService } from './heroes/hero.service'; +import { HeroListComponent } from './heroes/hero-list.component'; + +@Component({ + selector: 'my-tests', + template: ` +

    Tests

    +

    Tests {{results.pass}}: {{results.message}}

    + ` +}) +export class TestComponent { + results = runTests(); +} + +///////////////////////////////////// +function runTests() { + + // #docregion spec + let expectedHeroes = [{name: 'A'}, {name: 'B'}] + let mockService = {getHeroes: () => expectedHeroes } + + it('should have heroes when HeroListComponent created', () => { + let hlc = new HeroListComponent(mockService); + expect(hlc.heroes.length).toEqual(expectedHeroes.length); + }); + // #enddocregion spec + + return testResults; +} + +////////////////////////////////// +// Fake Jasmine infrastructure +var testName: string; +var testResults: {pass: string; message: string}; + +function expect(actual: any) { + return { + toEqual: function(expected: any){ + testResults = actual === expected ? + {pass: 'passed', message: testName} : + {pass: 'failed', message: `${testName}; expected ${actual} to equal ${expected}.`}; + } + }; +} + +function it(label: string, test: () => void) { + testName = label; + test(); +} diff --git a/public/docs/_examples/dependency-injection/ts/src/app/user.service.ts b/public/docs/_examples/dependency-injection/ts/src/app/user.service.ts new file mode 100644 index 0000000000..8fdda925db --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/app/user.service.ts @@ -0,0 +1,22 @@ +// #docregion +import { Injectable } from '@angular/core'; + +export class User { + constructor( + public name: string, + public isAuthorized = false) { } +} + +// Todo: get the user; don't 'new' it. +let alice = new User('Alice', true); +let bob = new User('Bob', false); + +@Injectable() +export class UserService { + user = bob; // initial user is Bob + + // swap users + getNewUser() { + return this.user = this.user === bob ? alice : bob; + } +} diff --git a/public/docs/_examples/dependency-injection/ts/src/index.html b/public/docs/_examples/dependency-injection/ts/src/index.html new file mode 100644 index 0000000000..87a9d7e694 --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/index.html @@ -0,0 +1,27 @@ + + + + + Dependency Injection + + + + + + + + + + + + + + + + + Loading my-app ... + + + diff --git a/public/docs/_examples/dependency-injection/ts/src/main.ts b/public/docs/_examples/dependency-injection/ts/src/main.ts new file mode 100644 index 0000000000..1a1d481719 --- /dev/null +++ b/public/docs/_examples/dependency-injection/ts/src/main.ts @@ -0,0 +1,6 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +// #docregion bootstrap +platformBrowserDynamic().bootstrapModule(AppModule); +// #enddocregion bootstrap diff --git a/public/docs/_examples/deployment/ts/.gitignore b/public/docs/_examples/deployment/ts/.gitignore new file mode 100644 index 0000000000..7f794a0b16 --- /dev/null +++ b/public/docs/_examples/deployment/ts/.gitignore @@ -0,0 +1 @@ +!systemjs.config.server.js diff --git a/public/docs/_examples/example-config.json b/public/docs/_examples/deployment/ts/example-config.json similarity index 100% rename from public/docs/_examples/example-config.json rename to public/docs/_examples/deployment/ts/example-config.json diff --git a/public/docs/_examples/deployment/ts/src/app/app.component.ts b/public/docs/_examples/deployment/ts/src/app/app.component.ts new file mode 100644 index 0000000000..47731c13a4 --- /dev/null +++ b/public/docs/_examples/deployment/ts/src/app/app.component.ts @@ -0,0 +1,15 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` +

    Simple Deployment

    + + + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/deployment/ts/src/app/app.module.ts b/public/docs/_examples/deployment/ts/src/app/app.module.ts new file mode 100644 index 0000000000..a885bc2918 --- /dev/null +++ b/public/docs/_examples/deployment/ts/src/app/app.module.ts @@ -0,0 +1,29 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule, Routes } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { CrisisListComponent } from './crisis-list.component'; +import { HeroListComponent } from './hero-list.component'; + +const appRoutes: Routes = [ + { path: 'crisis-center', component: CrisisListComponent }, + { path: 'heroes', component: HeroListComponent }, + + { path: '', redirectTo: '/heroes', pathMatch: 'full' } +]; + +@NgModule({ + imports: [ + BrowserModule, + RouterModule.forRoot(appRoutes) + ], + declarations: [ + AppComponent, + CrisisListComponent, + HeroListComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/deployment/ts/src/app/crisis-list.component.ts b/public/docs/_examples/deployment/ts/src/app/crisis-list.component.ts new file mode 100644 index 0000000000..62ef9e7555 --- /dev/null +++ b/public/docs/_examples/deployment/ts/src/app/crisis-list.component.ts @@ -0,0 +1,9 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + template: ` +

    CRISIS CENTER

    +

    Get your crisis here

    ` +}) +export class CrisisListComponent { } diff --git a/public/docs/_examples/deployment/ts/src/app/hero-list.component.ts b/public/docs/_examples/deployment/ts/src/app/hero-list.component.ts new file mode 100644 index 0000000000..479f73b508 --- /dev/null +++ b/public/docs/_examples/deployment/ts/src/app/hero-list.component.ts @@ -0,0 +1,10 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + template: ` +

    HEROES

    +

    Get your heroes here

    + ` +}) +export class HeroListComponent { } diff --git a/public/docs/_examples/deployment/ts/src/index.html b/public/docs/_examples/deployment/ts/src/index.html new file mode 100644 index 0000000000..770e64bc4d --- /dev/null +++ b/public/docs/_examples/deployment/ts/src/index.html @@ -0,0 +1,38 @@ + + + + + + + + + Simple Deployment + + + + + + + + + + + + + + + + + + + + + + + loading... + + + diff --git a/public/docs/_examples/deployment/ts/src/main.ts b/public/docs/_examples/deployment/ts/src/main.ts new file mode 100644 index 0000000000..6f82bbc745 --- /dev/null +++ b/public/docs/_examples/deployment/ts/src/main.ts @@ -0,0 +1,15 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +// #docregion enableProdMode +import { enableProdMode } from '@angular/core'; + +// Enable production mode unless running locally +if (!/localhost/.test(document.location.host)) { + enableProdMode(); +} +// #enddocregion enableProdMode + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/deployment/ts/src/systemjs.config.server.js b/public/docs/_examples/deployment/ts/src/systemjs.config.server.js new file mode 100644 index 0000000000..40c4426064 --- /dev/null +++ b/public/docs/_examples/deployment/ts/src/systemjs.config.server.js @@ -0,0 +1,46 @@ +// #docregion +/** + * System configuration for deployment without installing node_modules + * Loads umd packages from the web instead + * Adjust as necessary for your application needs. + */ +(function (global) { + System.config({ + // #docregion paths + paths: { + 'npm:': 'https://unpkg.com/' // path serves as alias + }, + // #enddocregion paths + // map tells the System loader where to look for things + map: { + app: 'app', // location of transpiled app files + + // angular minimized umd bundles + '@angular/core': 'npm:@angular/core/bundles/core.umd.min.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.min.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.min.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.min.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.min.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.min.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.min.js', + '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.min.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.min.js', + '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.min.js', + '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.min.js', + + // other libraries + 'rxjs': 'npm:rxjs@5.0.1', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' + }, + // packages tells the System loader how to load when no filename and/or no extension + packages: { + app: { + main: './main.js', + defaultExtension: 'js' + }, + rxjs: { + defaultExtension: 'js' + } + } + }); + })(this); diff --git a/public/docs/_examples/displaying-data/dart/.docsync.json b/public/docs/_examples/displaying-data/dart/.docsync.json deleted file mode 100644 index 3d1d13a2df..0000000000 --- a/public/docs/_examples/displaying-data/dart/.docsync.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "Displaying data", - "docHref": "https://angular.io/docs/dart/latest/guide/displaying-data.html" -} diff --git a/public/docs/_examples/displaying-data/dart/lib/app_component.dart b/public/docs/_examples/displaying-data/dart/lib/app_component.dart deleted file mode 100644 index 25402e3e3b..0000000000 --- a/public/docs/_examples/displaying-data/dart/lib/app_component.dart +++ /dev/null @@ -1,32 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; - -final List _heroes = [ - new Hero(1, 'Windstorm'), - new Hero(13, 'Bombasto'), - new Hero(15, 'Magneta'), - new Hero(20, 'Tornado') -]; - -@Component( - selector: 'my-app', - template: ''' -

    {{title}}

    -

    My favorite hero is: {{myHero.name}}

    -

    Heroes:

    -
      -
    • - {{ hero.name }} -
    • -
    -// #docregion message -

    There are many heroes!

    -// #enddocregion message -''') -class AppComponent { - String title = 'Tour of Heroes'; - List heroes = _heroes; - Hero myHero = _heroes[0]; -} diff --git a/public/docs/_examples/displaying-data/dart/lib/app_component_1.dart b/public/docs/_examples/displaying-data/dart/lib/app_component_1.dart deleted file mode 100644 index 20f946fcc5..0000000000 --- a/public/docs/_examples/displaying-data/dart/lib/app_component_1.dart +++ /dev/null @@ -1,15 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -@Component( - selector: 'my-app', -// #docregion template - template: ''' -

    {{title}}

    -

    My favorite hero is: {{myHero}}

    ''' -// #enddocregion template - ) -class AppComponent { - String title = 'Tour of Heroes'; - String myHero = 'Windstorm'; -} diff --git a/public/docs/_examples/displaying-data/dart/lib/app_component_2.dart b/public/docs/_examples/displaying-data/dart/lib/app_component_2.dart deleted file mode 100644 index 3d64fd0c02..0000000000 --- a/public/docs/_examples/displaying-data/dart/lib/app_component_2.dart +++ /dev/null @@ -1,36 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -// #docregion mock-heroes -const List _heroes = const [ - 'Windstorm', - 'Bombasto', - 'Magneta', - 'Tornado' -]; -// #enddocregion mock-heroes - -@Component( - selector: 'my-app', -// #docregion template - template: ''' -

    {{title}}

    -

    My favorite hero is: {{myHero}}

    -

    Heroes:

    -
      -// #docregion li-repeater -
    • - {{ hero }} -
    • -// #enddocregion li-repeater -
    ''' -// #enddocregion template - ) -// #docregion mock-heroes -class AppComponent { - String title = 'Tour of Heroes'; - List heroes = _heroes; - String myHero = _heroes[0]; -} -// #enddocregion mock-heroes -// #enddocregion diff --git a/public/docs/_examples/displaying-data/dart/lib/app_component_3.dart b/public/docs/_examples/displaying-data/dart/lib/app_component_3.dart deleted file mode 100644 index 51d2827a2a..0000000000 --- a/public/docs/_examples/displaying-data/dart/lib/app_component_3.dart +++ /dev/null @@ -1,35 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; -// #docregion heroes -import 'hero.dart'; - -final List _heroes = [ - new Hero(1, 'Windstorm'), - new Hero(13, 'Bombasto'), - new Hero(15, 'Magneta'), - new Hero(20, 'Tornado') -]; -// #enddocregion heroes - -@Component( - selector: 'my-app', -// #docregion template - template: ''' -

    {{title}}

    -

    My favorite hero is: {{myHero.name}}

    -

    Heroes:

    -
      -
    • - {{ hero.name }} -
    • -
    ''' -// #enddocregion template - ) -// #docregion heroes -class AppComponent { - String title = 'Tour of Heroes'; - List heroes = _heroes; - Hero myHero = _heroes[0]; -} -// #enddocregion heroes -// #enddocregion diff --git a/public/docs/_examples/displaying-data/dart/lib/hero.dart b/public/docs/_examples/displaying-data/dart/lib/hero.dart deleted file mode 100644 index 6542e4f4ca..0000000000 --- a/public/docs/_examples/displaying-data/dart/lib/hero.dart +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion -class Hero { - int id; - String name; - - Hero(this.id, this.name); - String toString() => '$id: $name'; -} -// #enddocregion diff --git a/public/docs/_examples/displaying-data/dart/pubspec.yaml b/public/docs/_examples/displaying-data/dart/pubspec.yaml deleted file mode 100644 index f01749b0ac..0000000000 --- a/public/docs/_examples/displaying-data/dart/pubspec.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# #docregion -name: displaying_data -description: Displaying Data Example -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: 'package:angular2/common.dart#CORE_DIRECTIVES' - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/displaying-data/dart/web/index.html b/public/docs/_examples/displaying-data/dart/web/index.html deleted file mode 100644 index 6585d21511..0000000000 --- a/public/docs/_examples/displaying-data/dart/web/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Displaying Data - - - - - - - Loading... - - - diff --git a/public/docs/_examples/displaying-data/dart/web/main.dart b/public/docs/_examples/displaying-data/dart/web/main.dart deleted file mode 100644 index 6a3620979c..0000000000 --- a/public/docs/_examples/displaying-data/dart/web/main.dart +++ /dev/null @@ -1,21 +0,0 @@ -// #docplaster -// #docregion final -import 'package:angular2/platform/browser.dart'; -// #enddocregion final - -//import 'package:displaying_data/app_component_1.dart' as v1; -//import 'package:displaying_data/app_component_2.dart' as v2; -//import 'package:displaying_data/app_component_3.dart' as v3; -// #docregion final -import 'package:displaying_data/app_component.dart'; - -main() { -// #enddocregion final -// pick one -// bootstrap(v1.AppComponent); -// bootstrap(v2.AppComponent); -// bootstrap(v3.AppComponent); -// #docregion final - bootstrap(AppComponent); -} -// #enddocregion final diff --git a/public/docs/_examples/displaying-data/e2e-spec.ts b/public/docs/_examples/displaying-data/e2e-spec.ts index 9e4e4a9df1..96c52c5d00 100644 --- a/public/docs/_examples/displaying-data/e2e-spec.ts +++ b/public/docs/_examples/displaying-data/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Displaying Data Tests', function () { let _title = 'Tour of Heroes'; let _defaultHero = 'Windstorm'; diff --git a/public/docs/_examples/displaying-data/ts/app/app.component.2.ts b/public/docs/_examples/displaying-data/ts/app/app.component.2.ts deleted file mode 100644 index 506215b36e..0000000000 --- a/public/docs/_examples/displaying-data/ts/app/app.component.2.ts +++ /dev/null @@ -1,28 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -@Component({ - selector: 'my-app', - // #docregion template - template: ` -

    {{title}}

    -

    My favorite hero is: {{myHero}}

    -

    Heroes:

    -
      - // #docregion li-repeater -
    • - {{ hero }} -
    • - // #enddocregion li-repeater -
    - ` - // #enddocregion template -}) -// #docregion mock-heroes -export class AppComponent { - title = 'Tour of Heroes'; - heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado']; - myHero = this.heroes[0]; -} -// #enddocregion mock-heroes -// #enddocregion diff --git a/public/docs/_examples/displaying-data/ts/app/app.component.3.ts b/public/docs/_examples/displaying-data/ts/app/app.component.3.ts deleted file mode 100644 index 301343f851..0000000000 --- a/public/docs/_examples/displaying-data/ts/app/app.component.3.ts +++ /dev/null @@ -1,36 +0,0 @@ -// #docregion -import { Component} from '@angular/core'; -// #docregion import-hero -import { Hero} from './hero'; -// #enddocregion import-hero - -@Component({ - selector: 'my-app', - // #docregion template - template: ` -

    {{title}}

    -

    My favorite hero is: {{myHero.name}}

    -

    Heroes:

    -
      -
    • - {{ hero.name }} -
    • -
    - ` - // #enddocregion template -}) -// #docregion class -export class AppComponent { - title = 'Tour of Heroes'; - // #docregion heroes - heroes = [ - new Hero(1, 'Windstorm'), - new Hero(13, 'Bombasto'), - new Hero(15, 'Magneta'), - new Hero(20, 'Tornado') - ]; - myHero = this.heroes[0]; - // #enddocregion heroes -} -// #enddocregion class -// #enddocregion diff --git a/public/docs/_examples/displaying-data/ts/app/app.component.ts b/public/docs/_examples/displaying-data/ts/app/app.component.ts deleted file mode 100644 index 1ba40c62c9..0000000000 --- a/public/docs/_examples/displaying-data/ts/app/app.component.ts +++ /dev/null @@ -1,35 +0,0 @@ -// #docplaster -// #docregion final -// #docregion imports -import { Component } from '@angular/core'; -// #enddocregion imports -import { Hero } from './hero'; - -@Component({ - selector: 'my-app', - template: ` -

    {{title}}

    -

    My favorite hero is: {{myHero.name}}

    -

    Heroes:

    -
      -
    • - {{ hero.name }} -
    • -
    - // #docregion message -

    There are many heroes!

    - // #enddocregion message -` -}) - -export class AppComponent { - title = 'Tour of Heroes'; - heroes = [ - new Hero(1, 'Windstorm'), - new Hero(13, 'Bombasto'), - new Hero(15, 'Magneta'), - new Hero(20, 'Tornado') - ]; - myHero = this.heroes[0]; -} diff --git a/public/docs/_examples/displaying-data/ts/app/hero.ts b/public/docs/_examples/displaying-data/ts/app/hero.ts deleted file mode 100644 index 8b4f06b658..0000000000 --- a/public/docs/_examples/displaying-data/ts/app/hero.ts +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion -export class Hero { - constructor( - // #docregion id-parameter - public id:number, - // #enddocregion id-parameter - public name:string) { } -} -// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/displaying-data/ts/app/main.1.ts b/public/docs/_examples/displaying-data/ts/app/main.1.ts deleted file mode 100644 index 2e0a4bc6f4..0000000000 --- a/public/docs/_examples/displaying-data/ts/app/main.1.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppCtorComponent } from './app-ctor.component'; -import { AppComponent as v1 } from './app.component.1'; -import { AppComponent as v2 } from './app.component.2'; -import { AppComponent as v3 } from './app.component.3'; - -import { AppComponent as final } from './app.component'; - -// pick one -//bootstrap(v1); -//bootstrap(v2); -//bootstrap(v3); -bootstrap(final); - -// for doc testing -bootstrap(AppCtorComponent); diff --git a/public/docs/_examples/displaying-data/ts/app/main.ts b/public/docs/_examples/displaying-data/ts/app/main.ts deleted file mode 100644 index 52b47899ef..0000000000 --- a/public/docs/_examples/displaying-data/ts/app/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); diff --git a/public/docs/_examples/displaying-data/ts/index.html b/public/docs/_examples/displaying-data/ts/index.html deleted file mode 100644 index e74be1c5de..0000000000 --- a/public/docs/_examples/displaying-data/ts/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - Displaying Data - - - - - - - - - - - - - - - - - - loading... - - - - diff --git a/public/docs/_examples/displaying-data/ts/plnkr.json b/public/docs/_examples/displaying-data/ts/plnkr.json index ee037aec0b..b4572f0fb6 100644 --- a/public/docs/_examples/displaying-data/ts/plnkr.json +++ b/public/docs/_examples/displaying-data/ts/plnkr.json @@ -1,5 +1,6 @@ { "description": "Displaying Data", + "basePath": "src/", "files": [ "!**/*.d.ts", "!**/*.js", @@ -7,4 +8,4 @@ "!**/*.[1,2,3].*" ], "tags": ["Template"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/displaying-data/ts/app/app-ctor.component.ts b/public/docs/_examples/displaying-data/ts/src/app/app-ctor.component.ts similarity index 87% rename from public/docs/_examples/displaying-data/ts/app/app-ctor.component.ts rename to public/docs/_examples/displaying-data/ts/src/app/app-ctor.component.ts index ed59b40b2c..b275baa8e6 100644 --- a/public/docs/_examples/displaying-data/ts/app/app-ctor.component.ts +++ b/public/docs/_examples/displaying-data/ts/src/app/app-ctor.component.ts @@ -7,7 +7,7 @@ import { Component } from '@angular/core';

    My favorite hero is: {{myHero}}

    ` }) -// #docregion app-ctor +// #docregion class export class AppCtorComponent { title: string; myHero: string; @@ -17,4 +17,3 @@ export class AppCtorComponent { this.myHero = 'Windstorm'; } } -// #enddocregion app-ctor \ No newline at end of file diff --git a/public/docs/_examples/displaying-data/ts/app/app.component.1.ts b/public/docs/_examples/displaying-data/ts/src/app/app.component.1.ts similarity index 100% rename from public/docs/_examples/displaying-data/ts/app/app.component.1.ts rename to public/docs/_examples/displaying-data/ts/src/app/app.component.1.ts diff --git a/public/docs/_examples/displaying-data/ts/src/app/app.component.2.ts b/public/docs/_examples/displaying-data/ts/src/app/app.component.2.ts new file mode 100644 index 0000000000..da7a653973 --- /dev/null +++ b/public/docs/_examples/displaying-data/ts/src/app/app.component.2.ts @@ -0,0 +1,26 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + // #docregion template + template: ` +

    {{title}}

    +

    My favorite hero is: {{myHero}}

    +

    Heroes:

    +
      + // #docregion li +
    • + {{ hero }} +
    • + // #enddocregion li +
    + ` + // #enddocregion template +}) +// #docregion class +export class AppComponent { + title = 'Tour of Heroes'; + heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado']; + myHero = this.heroes[0]; +} diff --git a/public/docs/_examples/displaying-data/ts/src/app/app.component.3.ts b/public/docs/_examples/displaying-data/ts/src/app/app.component.3.ts new file mode 100644 index 0000000000..06ab060557 --- /dev/null +++ b/public/docs/_examples/displaying-data/ts/src/app/app.component.3.ts @@ -0,0 +1,35 @@ +// #docregion +import { Component } from '@angular/core'; + +// #docregion import +import { Hero } from './hero'; +// #enddocregion import + +@Component({ + selector: 'my-app', + // #docregion template + template: ` +

    {{title}}

    +

    My favorite hero is: {{myHero.name}}

    +

    Heroes:

    +
      +
    • + {{ hero.name }} +
    • +
    + ` + // #enddocregion template +}) +// #docregion class +export class AppComponent { + title = 'Tour of Heroes'; + // #docregion heroes + heroes = [ + new Hero(1, 'Windstorm'), + new Hero(13, 'Bombasto'), + new Hero(15, 'Magneta'), + new Hero(20, 'Tornado') + ]; + myHero = this.heroes[0]; + // #enddocregion heroes +} diff --git a/public/docs/_examples/displaying-data/ts/src/app/app.component.ts b/public/docs/_examples/displaying-data/ts/src/app/app.component.ts new file mode 100644 index 0000000000..7234959265 --- /dev/null +++ b/public/docs/_examples/displaying-data/ts/src/app/app.component.ts @@ -0,0 +1,32 @@ +// #docplaster +// #docregion final +import { Component } from '@angular/core'; + +import { Hero } from './hero'; + +@Component({ + selector: 'my-app', + template: ` +

    {{title}}

    +

    My favorite hero is: {{myHero.name}}

    +

    Heroes:

    +
      +
    • + {{ hero.name }} +
    • +
    + // #docregion message +

    There are many heroes!

    + // #enddocregion message +` +}) +export class AppComponent { + title = 'Tour of Heroes'; + heroes = [ + new Hero(1, 'Windstorm'), + new Hero(13, 'Bombasto'), + new Hero(15, 'Magneta'), + new Hero(20, 'Tornado') + ]; + myHero = this.heroes[0]; +} diff --git a/public/docs/_examples/displaying-data/ts/src/app/app.module.ts b/public/docs/_examples/displaying-data/ts/src/app/app.module.ts new file mode 100644 index 0000000000..362f3401fa --- /dev/null +++ b/public/docs/_examples/displaying-data/ts/src/app/app.module.ts @@ -0,0 +1,16 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule + ], + declarations: [ + AppComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/displaying-data/ts/src/app/hero.ts b/public/docs/_examples/displaying-data/ts/src/app/hero.ts new file mode 100644 index 0000000000..f89d26ad63 --- /dev/null +++ b/public/docs/_examples/displaying-data/ts/src/app/hero.ts @@ -0,0 +1,9 @@ +// #docregion +export class Hero { + constructor( + // #docregion id + public id: number, + // #enddocregion id + public name: string) { } +} +// #enddocregion diff --git a/public/docs/_examples/displaying-data/ts/src/index.html b/public/docs/_examples/displaying-data/ts/src/index.html new file mode 100644 index 0000000000..ddcbade46b --- /dev/null +++ b/public/docs/_examples/displaying-data/ts/src/index.html @@ -0,0 +1,28 @@ + + + + Displaying Data + + + + + + + + + + + + + + + + + + loading... + + + + diff --git a/public/docs/_examples/displaying-data/ts/src/main.ts b/public/docs/_examples/displaying-data/ts/src/main.ts new file mode 100644 index 0000000000..f332d1d245 --- /dev/null +++ b/public/docs/_examples/displaying-data/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/forms/dart/.docsync.json b/public/docs/_examples/forms/dart/.docsync.json deleted file mode 100644 index 066f6e56e9..0000000000 --- a/public/docs/_examples/forms/dart/.docsync.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "Forms", - "docHref": "https://angular.io/docs/dart/latest/guide/forms.html" -} diff --git a/public/docs/_examples/forms/dart/lib/hero.dart b/public/docs/_examples/forms/dart/lib/hero.dart deleted file mode 100644 index 6ade27c4d3..0000000000 --- a/public/docs/_examples/forms/dart/lib/hero.dart +++ /dev/null @@ -1,20 +0,0 @@ -// #docregion all -class Hero { - int number; - String name; - String power; - String alterEgo; - - Hero(this.number, this.name, this.power, [this.alterEgo]); - - String toString() => '$number: $name ($alterEgo). Super power: $power'; -} -// #enddocregion all - -main() { - // #docregion newhero - var myHero = new Hero( - 42, 'SkyDog', 'Fetch any object at any distance', 'Leslie Rollover'); - print('My hero is ${myHero.name}.'); // "My hero is SkyDog." - // #enddocregion newhero -} diff --git a/public/docs/_examples/forms/dart/lib/hero_form_component.dart b/public/docs/_examples/forms/dart/lib/hero_form_component.dart deleted file mode 100644 index e5d49a08c9..0000000000 --- a/public/docs/_examples/forms/dart/lib/hero_form_component.dart +++ /dev/null @@ -1,34 +0,0 @@ -// #docplaster -// #docregion -// #docregion no-todo -import 'package:angular2/core.dart'; - -import 'hero.dart'; - -const List _powers = const [ - 'Really Smart', - 'Super Flexible', - 'Super Hot', - 'Weather Changer' -]; - -@Component( - selector: 'hero-form', - templateUrl: 'hero_form_component.html') -class HeroFormComponent { - List get powers => _powers; -// #docregion submitted - bool submitted = false; -// #enddocregion submitted - Hero model = new Hero(18, 'Dr IQ', _powers[0], 'Chuck Overstreet'); -// #enddocregion no-todo - // TODO: Remove this when we're done - String get diagnostic => 'DIAGNOSTIC: $model'; -// #docregion no-todo - -// #docregion submitted - onSubmit() { - submitted = true; - } -// #enddocregion submitted -} diff --git a/public/docs/_examples/forms/dart/lib/hero_form_component.html b/public/docs/_examples/forms/dart/lib/hero_form_component.html deleted file mode 100644 index dd3b91167f..0000000000 --- a/public/docs/_examples/forms/dart/lib/hero_form_component.html +++ /dev/null @@ -1,67 +0,0 @@ - - -
    - -
    -

    Hero Form

    - -
    - - -
    - - - -
    - Name is required -
    - -
    - -
    - - -
    - -
    - - -
    - - - - - -
    -
    - - - -
    -

    You submitted the following:

    -
    -
    Name
    -
    {{ model.name }}
    -
    -
    -
    Alter Ego
    -
    {{ model.alterEgo }}
    -
    -
    -
    Power
    -
    {{ model.power }}
    -
    -
    - -
    - -
    diff --git a/public/docs/_examples/forms/dart/lib/hero_form_component_initial.dart b/public/docs/_examples/forms/dart/lib/hero_form_component_initial.dart deleted file mode 100644 index 53a2c20482..0000000000 --- a/public/docs/_examples/forms/dart/lib/hero_form_component_initial.dart +++ /dev/null @@ -1,5 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -@Component(selector: 'hero-form', template: 'Hero form will go here') -class HeroFormComponent {} diff --git a/public/docs/_examples/forms/dart/lib/hero_form_component_initial.html b/public/docs/_examples/forms/dart/lib/hero_form_component_initial.html deleted file mode 100644 index 155ea07fa9..0000000000 --- a/public/docs/_examples/forms/dart/lib/hero_form_component_initial.html +++ /dev/null @@ -1,15 +0,0 @@ - -
    -

    Hero Form

    -
    -
    - - -
    -
    - - -
    - -
    -
    diff --git a/public/docs/_examples/forms/dart/lib/hero_form_component_ngcontrol.html b/public/docs/_examples/forms/dart/lib/hero_form_component_ngcontrol.html deleted file mode 100644 index 16eee0a1cf..0000000000 --- a/public/docs/_examples/forms/dart/lib/hero_form_component_ngcontrol.html +++ /dev/null @@ -1,32 +0,0 @@ - -
    -

    Hero Form

    -
    -
    - - - - -
    - -
    - - -
    - -
    - - -
    - - -
    -
    diff --git a/public/docs/_examples/forms/dart/lib/hero_form_component_ngmodel2.html b/public/docs/_examples/forms/dart/lib/hero_form_component_ngmodel2.html deleted file mode 100644 index 650c974957..0000000000 --- a/public/docs/_examples/forms/dart/lib/hero_form_component_ngmodel2.html +++ /dev/null @@ -1,30 +0,0 @@ - -
    -

    Hero Form

    -
    - - {{diagnostic}} -
    - - -
    - -
    - - -
    - -
    - - -
    - - - -
    -
    diff --git a/public/docs/_examples/forms/dart/lib/hero_form_component_ngmodel_ngfor.html b/public/docs/_examples/forms/dart/lib/hero_form_component_ngmodel_ngfor.html deleted file mode 100644 index a0b851a09c..0000000000 --- a/public/docs/_examples/forms/dart/lib/hero_form_component_ngmodel_ngfor.html +++ /dev/null @@ -1,30 +0,0 @@ - -
    -

    Hero Form

    -
    -
    - - - - TODO: remove this: {{model.name}} - -
    - -
    - - -
    - - -
    - - -
    - - - -
    -
    diff --git a/public/docs/_examples/forms/dart/lib/hero_form_component_ngmodelchange.html b/public/docs/_examples/forms/dart/lib/hero_form_component_ngmodelchange.html deleted file mode 100644 index 96c55b9740..0000000000 --- a/public/docs/_examples/forms/dart/lib/hero_form_component_ngmodelchange.html +++ /dev/null @@ -1,31 +0,0 @@ - -
    -

    Hero Form

    -
    -
    - - - - TODO: remove this: {{model.name}} - -
    - -
    - - -
    - -
    - - -
    - - -
    -
    diff --git a/public/docs/_examples/forms/dart/lib/hero_form_component_spy.html b/public/docs/_examples/forms/dart/lib/hero_form_component_spy.html deleted file mode 100644 index 4c77cd14ab..0000000000 --- a/public/docs/_examples/forms/dart/lib/hero_form_component_spy.html +++ /dev/null @@ -1,33 +0,0 @@ - -
    -

    Hero Form

    -
    -
    - - - - TODO: remove this: {{spy.className}} - -
    - -
    - - -
    - -
    - - -
    - - -
    -
    diff --git a/public/docs/_examples/forms/dart/pubspec.yaml b/public/docs/_examples/forms/dart/pubspec.yaml deleted file mode 100644 index 6c350a3657..0000000000 --- a/public/docs/_examples/forms/dart/pubspec.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# #docregion -name: hero_form -description: Form example -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: - - 'package:angular2/common.dart#CORE_DIRECTIVES' - - 'package:angular2/common.dart#FORM_DIRECTIVES' - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/forms/dart/web/bootstrap.min.css b/public/docs/_examples/forms/dart/web/bootstrap.min.css deleted file mode 100644 index d65c66b1ba..0000000000 --- a/public/docs/_examples/forms/dart/web/bootstrap.min.css +++ /dev/null @@ -1,5 +0,0 @@ -/*! - * Bootstrap v3.3.5 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/public/docs/_examples/forms/dart/web/index.html b/public/docs/_examples/forms/dart/web/index.html deleted file mode 100644 index e99d87d263..0000000000 --- a/public/docs/_examples/forms/dart/web/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - Hero Form - - - - - - - - - - - - - - - - Loading... - - diff --git a/public/docs/_examples/forms/dart/web/main.dart b/public/docs/_examples/forms/dart/web/main.dart deleted file mode 100644 index 7d21d9e9ba..0000000000 --- a/public/docs/_examples/forms/dart/web/main.dart +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -import 'package:angular2/platform/browser.dart'; - -import 'package:hero_form/hero_form_component.dart'; - -main() { - bootstrap(HeroFormComponent); -} diff --git a/public/docs/_examples/forms/e2e-spec.ts b/public/docs/_examples/forms/e2e-spec.ts index 5e68d6e657..2afd370103 100644 --- a/public/docs/_examples/forms/e2e-spec.ts +++ b/public/docs/_examples/forms/e2e-spec.ts @@ -1,5 +1,7 @@ -/// -describeIf(browser.appIsTs || browser.appIsJs, 'Forms Tests', function () { +import { browser, element, by } from 'protractor'; +import { appLang, describeIf } from '../protractor-helpers'; + +describeIf(appLang.appIsTs || appLang.appIsJs, 'Forms Tests', function () { beforeEach(function () { browser.get(''); @@ -32,7 +34,7 @@ describeIf(browser.appIsTs || browser.appIsJs, 'Forms Tests', function () { }); it('should hide form after submit', function () { - let alterEgoEle = element.all(by.css('input[ngcontrol=alterEgo]')).get(0); + let alterEgoEle = element.all(by.css('input[name=alterEgo]')).get(0); expect(alterEgoEle.isDisplayed()).toBe(true); let submitButtonEle = element.all(by.css('button[type=submit]')).get(0); submitButtonEle.click().then(function() { @@ -43,13 +45,11 @@ describeIf(browser.appIsTs || browser.appIsJs, 'Forms Tests', function () { it('should reflect submitted data after submit', function () { let test = 'testing 1 2 3'; let newValue: string; - let alterEgoEle = element.all(by.css('input[ngcontrol=alterEgo]')).get(0); - alterEgoEle.getAttribute('value').then(function(value) { - // alterEgoEle.sendKeys(test); - sendKeys(alterEgoEle, test); + let alterEgoEle = element.all(by.css('input[name=alterEgo]')).get(0); + alterEgoEle.getAttribute('value').then(function(value: string) { + alterEgoEle.sendKeys(test); newValue = value + test; expect(alterEgoEle.getAttribute('value')).toEqual(newValue); - }).then(function() { let b = element.all(by.css('button[type=submit]')).get(0); return b.click(); }).then(function() { diff --git a/public/docs/_examples/forms/js/app/app.component.js b/public/docs/_examples/forms/js/app/app.component.js deleted file mode 100644 index bb6b789938..0000000000 --- a/public/docs/_examples/forms/js/app/app.component.js +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -(function(app) { - app.AppComponent = ng.core - .Component({ - selector: 'my-app', - template: '', - directives: [app.HeroFormComponent] - }) - .Class({ - constructor: function() {} - }); -})(window.app || (window.app = {})); diff --git a/public/docs/_examples/forms/js/app/hero-form.component.html b/public/docs/_examples/forms/js/app/hero-form.component.html deleted file mode 100644 index fdf8e08396..0000000000 --- a/public/docs/_examples/forms/js/app/hero-form.component.html +++ /dev/null @@ -1,195 +0,0 @@ - - -
    - -
    -

    Hero Form

    - -
    - - -
    - - - -
    - Name is required -
    - -
    - -
    - - -
    - -
    - - -
    - Power is required -
    -
    - - - - -
    -
    - - -
    -

    You submitted the following:

    -
    -
    Name
    -
    {{ model.name }}
    -
    -
    -
    Alter Ego
    -
    {{ model.alterEgo }}
    -
    -
    -
    Power
    -
    {{ model.power }}
    -
    -
    - -
    - -
    - - - -
    -
    - - - - -
    -
    - - - -
    - -
    - -
    -

    Hero Form

    -
    -
    - - -
    - -
    - - -
    - - - -
    - - -
    - - - - -
    -
    - - - - -
    - -
    -

    Hero Form

    -
    - - {{diagnostic()}} -
    - - -
    - -
    - - -
    - -
    - - -
    - - - - -
    -
    - - - -
    - - - TODO: remove this: {{model.name}} - -
    - - - TODO: remove this: {{model.name}} - -
    -
    - - - -
    - - -
    TODO: remove this: {{spy.className}} - -
    - -
    -
    - Name via form.controls = {{showFormControls(heroForm)}} -
    - -
    diff --git a/public/docs/_examples/forms/js/app/main.js b/public/docs/_examples/forms/js/app/main.js deleted file mode 100644 index 5930bdd061..0000000000 --- a/public/docs/_examples/forms/js/app/main.js +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -(function(app) { - document.addEventListener('DOMContentLoaded', function() { - ng.platformBrowserDynamic.bootstrap(app.AppComponent); - }); -})(window.app || (window.app = {})); diff --git a/public/docs/_examples/forms/js/example-config.json b/public/docs/_examples/forms/js/example-config.json index e69de29bb2..81f31aaf0d 100644 --- a/public/docs/_examples/forms/js/example-config.json +++ b/public/docs/_examples/forms/js/example-config.json @@ -0,0 +1,3 @@ +{ + "build": "build:babel" +} diff --git a/public/docs/_examples/forms/js/forms.css b/public/docs/_examples/forms/js/forms.css deleted file mode 100644 index d7e11405b1..0000000000 --- a/public/docs/_examples/forms/js/forms.css +++ /dev/null @@ -1,9 +0,0 @@ -/* #docregion */ -.ng-valid[required] { - border-left: 5px solid #42A948; /* green */ -} - -.ng-invalid { - border-left: 5px solid #a94442; /* red */ -} -/* #enddocregion */ \ No newline at end of file diff --git a/public/docs/_examples/forms/js/index.html b/public/docs/_examples/forms/js/index.html deleted file mode 100644 index 55b7d2ba1d..0000000000 --- a/public/docs/_examples/forms/js/index.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - Hero Form - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/forms/js/plnkr.json b/public/docs/_examples/forms/js/plnkr.json index 0105283bd3..946cbb88f6 100644 --- a/public/docs/_examples/forms/js/plnkr.json +++ b/public/docs/_examples/forms/js/plnkr.json @@ -1,4 +1,5 @@ { "description": "Forms", + "basePath": "src/", "files":["app/**/*.js", "**/*.html", "**/*.css"] } diff --git a/public/docs/_examples/forms/js/src/app/app.component.js b/public/docs/_examples/forms/js/src/app/app.component.js new file mode 100644 index 0000000000..56bd982416 --- /dev/null +++ b/public/docs/_examples/forms/js/src/app/app.component.js @@ -0,0 +1,11 @@ +// #docregion +(function(app) { + app.AppComponent = ng.core + .Component({ + selector: 'my-app', + template: '' + }) + .Class({ + constructor: function() {} + }); +})(window.app || (window.app = {})); diff --git a/public/docs/_examples/forms/js/src/app/app.module.js b/public/docs/_examples/forms/js/src/app/app.module.js new file mode 100644 index 0000000000..92c7f8b9e5 --- /dev/null +++ b/public/docs/_examples/forms/js/src/app/app.module.js @@ -0,0 +1,19 @@ +// #docplaster +// #docregion +(function(app) { + app.AppModule = + ng.core.NgModule({ + imports: [ + ng.platformBrowser.BrowserModule, + ng.forms.FormsModule + ], + declarations: [ + app.AppComponent, + app.HeroFormComponent + ], + bootstrap: [ app.AppComponent ] + }) + .Class({ + constructor: function() {} + }); +})(window.app || (window.app = {})); diff --git a/public/docs/_examples/forms/js/src/app/hero-form.component.html b/public/docs/_examples/forms/js/src/app/hero-form.component.html new file mode 100644 index 0000000000..279ded0866 --- /dev/null +++ b/public/docs/_examples/forms/js/src/app/hero-form.component.html @@ -0,0 +1,196 @@ + + +
    + +
    +

    Hero Form

    + +
    + + +
    + + + +
    + Name is required +
    + +
    + +
    + + +
    + +
    + + +
    + Power is required +
    +
    + + + + +
    +
    + + +
    +

    You submitted the following:

    +
    +
    Name
    +
    {{ model.name }}
    +
    +
    +
    Alter Ego
    +
    {{ model.alterEgo }}
    +
    +
    +
    Power
    +
    {{ model.power }}
    +
    +
    + +
    + +
    + + + +
    +
    + + + + +
    +
    + + + +
    + + +
    + +
    +

    Hero Form

    +
    +
    + + +
    + +
    + + +
    + + + +
    + + +
    + + + + +
    +
    + + + + +
    + +
    +

    Hero Form

    +
    + + {{diagnostic()}} +
    + + +
    + +
    + + +
    + +
    + + +
    + + + + +
    +
    + + + +
    + + + TODO: remove this: {{model.name}} + +
    + + + TODO: remove this: {{model.name}} + +
    +
    + + + +
    + + +
    TODO: remove this: {{spy.className}} + +
    + +
    +
    + Name via form.controls = {{showFormControls(heroForm)}} +
    + +
    diff --git a/public/docs/_examples/forms/js/app/hero-form.component.js b/public/docs/_examples/forms/js/src/app/hero-form.component.js similarity index 94% rename from public/docs/_examples/forms/js/app/hero-form.component.js rename to public/docs/_examples/forms/js/src/app/hero-form.component.js index 8988231189..505993a1fd 100644 --- a/public/docs/_examples/forms/js/app/hero-form.component.js +++ b/public/docs/_examples/forms/js/src/app/hero-form.component.js @@ -9,7 +9,7 @@ }) .Class({ // #docregion submitted - constructor: function() { + constructor: [function() { // #enddocregion submitted this.powers = ['Really Smart', 'Super Flexible', 'Super Hot', 'Weather Changer' @@ -20,7 +20,7 @@ // #docregion submitted this.submitted = false; - }, + }], onSubmit: function() { this.submitted = true; }, @@ -48,5 +48,5 @@ // #docregion first, final }); - // #enddocregion first, final })(window.app || (window.app = {})); +// #enddocregion first, final diff --git a/public/docs/_examples/forms/js/app/hero.js b/public/docs/_examples/forms/js/src/app/hero.js similarity index 100% rename from public/docs/_examples/forms/js/app/hero.js rename to public/docs/_examples/forms/js/src/app/hero.js diff --git a/public/docs/_examples/forms/dart/web/forms.css b/public/docs/_examples/forms/js/src/forms.css similarity index 100% rename from public/docs/_examples/forms/dart/web/forms.css rename to public/docs/_examples/forms/js/src/forms.css diff --git a/public/docs/_examples/forms/js/src/index.html b/public/docs/_examples/forms/js/src/index.html new file mode 100644 index 0000000000..3a41d74a3b --- /dev/null +++ b/public/docs/_examples/forms/js/src/index.html @@ -0,0 +1,47 @@ + + + + + + Hero Form + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/forms/js/src/main.js b/public/docs/_examples/forms/js/src/main.js new file mode 100644 index 0000000000..785823fa84 --- /dev/null +++ b/public/docs/_examples/forms/js/src/main.js @@ -0,0 +1,8 @@ +// #docregion +(function(app) { + document.addEventListener('DOMContentLoaded', function() { + ng.platformBrowserDynamic + .platformBrowserDynamic() + .bootstrapModule(app.AppModule); + }); +})(window.app || (window.app = {})); diff --git a/public/docs/_examples/forms/ts/app/app.component.ts b/public/docs/_examples/forms/ts/app/app.component.ts deleted file mode 100644 index b8551a0520..0000000000 --- a/public/docs/_examples/forms/ts/app/app.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { HeroFormComponent } from './hero-form.component' - -@Component({ - selector: 'my-app', - template: '', - directives: [HeroFormComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/forms/ts/app/hero-form.component.html b/public/docs/_examples/forms/ts/app/hero-form.component.html deleted file mode 100644 index 6fcfc2a7cb..0000000000 --- a/public/docs/_examples/forms/ts/app/hero-form.component.html +++ /dev/null @@ -1,208 +0,0 @@ - - -
    - -
    -

    Hero Form

    - -
    - - -
    - - - - -
    - - Name is required -
    - -
    - -
    - - -
    - -
    - - -
    - Power is required -
    -
    - - - - - - - - - - - -
    -
    - Name via form.controls = {{showFormControls(heroForm)}} -
    - - -
    -
    - - -
    -

    You submitted the following:

    -
    -
    Name
    -
    {{ model.name }}
    -
    -
    -
    Alter Ego
    -
    {{ model.alterEgo }}
    -
    -
    -
    Power
    -
    {{ model.power }}
    -
    -
    - -
    - -
    - - - -
    -
    - - - - -
    -
    - - - -
    - -
    - -
    -

    Hero Form

    -
    -
    - - -
    - -
    - - -
    - - - -
    - - -
    - - - - - -
    -
    - - - - -
    - -
    -

    Hero Form

    -
    - - {{diagnostic}} -
    - - -
    - -
    - - -
    - -
    - - -
    - - - - -
    -
    - - - -
    - - - TODO: remove this: {{model.name}} - -
    - - - TODO: remove this: {{model.name}} - -
    - -
    - - - - - -
    - - -
    TODO: remove this: {{spy.className}} - -
    - -
    diff --git a/public/docs/_examples/forms/ts/app/hero-form.component.ts b/public/docs/_examples/forms/ts/app/hero-form.component.ts deleted file mode 100644 index c4876d8203..0000000000 --- a/public/docs/_examples/forms/ts/app/hero-form.component.ts +++ /dev/null @@ -1,66 +0,0 @@ -// #docplaster -// #docregion -// #docregion first, final -import { Component } from '@angular/core'; -import { NgForm } from '@angular/common'; - -import { Hero } from './hero'; - -@Component({ - selector: 'hero-form', - templateUrl: 'app/hero-form.component.html' -}) -export class HeroFormComponent { - - powers = ['Really Smart', 'Super Flexible', - 'Super Hot', 'Weather Changer']; - - model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet'); - - // #docregion submitted - submitted = false; - - onSubmit() { this.submitted = true; } - // #enddocregion submitted - - // #enddocregion final - // TODO: Remove this when we're done - get diagnostic() { return JSON.stringify(this.model); } - // #enddocregion first - - // #docregion final - // Reset the form with a new hero AND restore 'pristine' class state - // by toggling 'active' flag which causes the form - // to be removed/re-added in a tick via NgIf - // TODO: Workaround until NgForm has a reset method (#6822) - // #docregion new-hero - active = true; - - // #docregion new-hero-v1 - newHero() { - this.model = new Hero(42, '', ''); - // #enddocregion new-hero-v1 - this.active = false; - setTimeout(()=> this.active=true, 0); - // #docregion new-hero-v1 - } - // #enddocregion new-hero-v1 - // #enddocregion new-hero - // #enddocregion final - //////// NOT SHOWN IN DOCS //////// - - // Reveal in html: - // Name via form.controls = {{showFormControls(heroForm)}} - showFormControls(form:NgForm){ - - return form && form.controls['name'] && - // #docregion form-controls - form.controls['name'].value; // Dr. IQ - // #enddocregion form-controls - } - - ///////////////////////////// - - // #docregion first, final -} -// #enddocregion first, final diff --git a/public/docs/_examples/forms/ts/app/main.ts b/public/docs/_examples/forms/ts/app/main.ts deleted file mode 100644 index 5338161d66..0000000000 --- a/public/docs/_examples/forms/ts/app/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); diff --git a/public/docs/_examples/forms/ts/forms.css b/public/docs/_examples/forms/ts/forms.css deleted file mode 100644 index d7e11405b1..0000000000 --- a/public/docs/_examples/forms/ts/forms.css +++ /dev/null @@ -1,9 +0,0 @@ -/* #docregion */ -.ng-valid[required] { - border-left: 5px solid #42A948; /* green */ -} - -.ng-invalid { - border-left: 5px solid #a94442; /* red */ -} -/* #enddocregion */ \ No newline at end of file diff --git a/public/docs/_examples/forms/ts/index.html b/public/docs/_examples/forms/ts/index.html deleted file mode 100644 index 4df2d32d46..0000000000 --- a/public/docs/_examples/forms/ts/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - Hero Form - - - - - - - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/forms/ts/plnkr.json b/public/docs/_examples/forms/ts/plnkr.json index 60063d7d2c..3f0abbfc3d 100644 --- a/public/docs/_examples/forms/ts/plnkr.json +++ b/public/docs/_examples/forms/ts/plnkr.json @@ -1,7 +1,8 @@ { "description": "Forms", + "basePath": "src/", "files":[ - "!**/*.d.ts", + "!**/*.d.ts", "!**/*.js" ] -} \ No newline at end of file +} diff --git a/public/docs/_examples/forms/ts/src/app/app.component.ts b/public/docs/_examples/forms/ts/src/app/app.component.ts new file mode 100644 index 0000000000..454f7e03db --- /dev/null +++ b/public/docs/_examples/forms/ts/src/app/app.component.ts @@ -0,0 +1,8 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: '' +}) +export class AppComponent { } diff --git a/public/docs/_examples/forms/ts/src/app/app.module.ts b/public/docs/_examples/forms/ts/src/app/app.module.ts new file mode 100644 index 0000000000..f214c02714 --- /dev/null +++ b/public/docs/_examples/forms/ts/src/app/app.module.ts @@ -0,0 +1,20 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { HeroFormComponent } from './hero-form.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule + ], + declarations: [ + AppComponent, + HeroFormComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/forms/ts/src/app/hero-form.component.html b/public/docs/_examples/forms/ts/src/app/hero-form.component.html new file mode 100644 index 0000000000..73b703f789 --- /dev/null +++ b/public/docs/_examples/forms/ts/src/app/hero-form.component.html @@ -0,0 +1,212 @@ + + +
    + +
    +

    Hero Form

    + +
    + +
    + + + + +
    + + Name is required +
    + +
    + +
    + + +
    + +
    + + +
    + Power is required +
    +
    + + + + + + + + + with reset + +    + + + + without reset + + +
    +
    + Name via form.controls = {{showFormControls(heroForm)}} +
    + + +
    +
    + + +
    +

    You submitted the following:

    +
    +
    Name
    +
    {{ model.name }}
    +
    +
    +
    Alter Ego
    +
    {{ model.alterEgo }}
    +
    +
    +
    Power
    +
    {{ model.power }}
    +
    +
    + +
    + +
    + + + +
    +
    + + + + +
    +
    + + + +
    + + +
    + +
    +

    Hero Form

    +
    +
    + + +
    + +
    + + +
    + + + +
    + + +
    + + + + + +
    +
    + + + + +
    + +
    +

    Hero Form

    + +
    + + + {{diagnostic}} +
    + + +
    + +
    + + +
    + +
    + + +
    + + + + +
    +
    + + + +
    + + + TODO: remove this: {{model.name}} + +
    + + + TODO: remove this: {{model.name}} + +
    + + +
    TODO: remove this: {{spy.className}} + + +
    diff --git a/public/docs/_examples/forms/ts/src/app/hero-form.component.ts b/public/docs/_examples/forms/ts/src/app/hero-form.component.ts new file mode 100644 index 0000000000..34be523a7f --- /dev/null +++ b/public/docs/_examples/forms/ts/src/app/hero-form.component.ts @@ -0,0 +1,59 @@ +// #docplaster +// #docregion , v1, final +import { Component } from '@angular/core'; + +import { Hero } from './hero'; + +@Component({ + selector: 'hero-form', + templateUrl: './hero-form.component.html' +}) +export class HeroFormComponent { + + powers = ['Really Smart', 'Super Flexible', + 'Super Hot', 'Weather Changer']; + + model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet'); + + // #docregion submitted + submitted = false; + + onSubmit() { this.submitted = true; } + // #enddocregion submitted + + // #enddocregion final + // TODO: Remove this when we're done + get diagnostic() { return JSON.stringify(this.model); } + // #enddocregion v1 + + // #docregion final, new-hero + newHero() { + this.model = new Hero(42, '', ''); + } + // #enddocregion final, new-hero + + skyDog(): Hero { + // #docregion SkyDog + let myHero = new Hero(42, 'SkyDog', + 'Fetch any object at any distance', + 'Leslie Rollover'); + console.log('My hero is called ' + myHero.name); // "My hero is called SkyDog" + // #enddocregion SkyDog + return myHero; + } + + //////// NOT SHOWN IN DOCS //////// + + // Reveal in html: + // Name via form.controls = {{showFormControls(heroForm)}} + showFormControls(form: any) { + return form && form.controls['name'] && + // #docregion form-controls + form.controls['name'].value; // Dr. IQ + // #enddocregion form-controls + } + + ///////////////////////////// + + // #docregion v1, final +} diff --git a/public/docs/_examples/forms/ts/app/hero.ts b/public/docs/_examples/forms/ts/src/app/hero.ts similarity index 100% rename from public/docs/_examples/forms/ts/app/hero.ts rename to public/docs/_examples/forms/ts/src/app/hero.ts diff --git a/public/docs/_examples/forms/ts/src/forms.css b/public/docs/_examples/forms/ts/src/forms.css new file mode 100644 index 0000000000..13ffbe1203 --- /dev/null +++ b/public/docs/_examples/forms/ts/src/forms.css @@ -0,0 +1,9 @@ +/* #docregion */ +.ng-valid[required], .ng-valid.required { + border-left: 5px solid #42A948; /* green */ +} + +.ng-invalid:not(form) { + border-left: 5px solid #a94442; /* red */ +} +/* #enddocregion */ diff --git a/public/docs/_examples/forms/ts/src/index.html b/public/docs/_examples/forms/ts/src/index.html new file mode 100644 index 0000000000..032888ca3e --- /dev/null +++ b/public/docs/_examples/forms/ts/src/index.html @@ -0,0 +1,35 @@ + + + + + Hero Form + + + + + + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/forms/ts/src/main.ts b/public/docs/_examples/forms/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/forms/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/edit_item.dart b/public/docs/_examples/hierarchical-dependency-injection/dart/lib/edit_item.dart deleted file mode 100644 index c5de35a9ed..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/edit_item.dart +++ /dev/null @@ -1,7 +0,0 @@ -// #docregion -class EditItem { - bool editing = false; - T item; - EditItem(this.item); -} -// #enddocregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/hero.dart b/public/docs/_examples/hierarchical-dependency-injection/dart/lib/hero.dart deleted file mode 100644 index 273bb21aba..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/hero.dart +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -class Hero { - String name; - String power; - - Hero clone() { - return new Hero() - ..name = name - ..power = power; - } -} -// #enddocregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/hero_card_component.dart b/public/docs/_examples/hierarchical-dependency-injection/dart/lib/hero_card_component.dart deleted file mode 100644 index 6fa8aeb6cd..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/hero_card_component.dart +++ /dev/null @@ -1,17 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; - -@Component( - selector: 'hero-card', - template: ''' -
    - Name: - {{hero.name}} -
    - ''') -class HeroCardComponent { - @Input() Hero hero; -} -// #docregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/hero_editor_component.dart b/public/docs/_examples/hierarchical-dependency-injection/dart/lib/hero_editor_component.dart deleted file mode 100644 index 7ad3226755..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/hero_editor_component.dart +++ /dev/null @@ -1,48 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'restore_service.dart'; - -@Component( - selector: 'hero-editor', - // #docregion providers - providers: const [RestoreService], - // #enddocregion providers - template: ''' -
    - Name: - -
    - - -
    -
    - ''') -class HeroEditorComponent { - @Output() final EventEmitter canceled = new EventEmitter(); - @Output() final EventEmitter saved = new EventEmitter(); - - RestoreService _restoreService; - - HeroEditorComponent(this._restoreService); - - @Input() - set hero(Hero hero) { - _restoreService.setItem(hero); - } - - Hero get hero { - return _restoreService.getItem(); - } - - onSaved() { - saved.add(_restoreService.getItem()); - } - - onCanceled() { - hero = _restoreService.restoreItem(); - canceled.add(hero); - } -} -// #enddocregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/heroes_list_component.dart b/public/docs/_examples/hierarchical-dependency-injection/dart/lib/heroes_list_component.dart deleted file mode 100644 index 2810e1cdb4..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/heroes_list_component.dart +++ /dev/null @@ -1,54 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'edit_item.dart'; -import 'hero.dart'; -import 'hero_card_component.dart'; -import 'hero_editor_component.dart'; -import 'heroes_service.dart'; - -@Component( - selector: 'heroes-list', - template: ''' -
    -
      -
    • - - - - - -
    • -
    -
    - ''', - directives: const [HeroCardComponent, HeroEditorComponent]) -class HeroesListComponent { - List> heroes; - HeroesListComponent(HeroesService heroesService) { - heroes = heroesService - .getHeroes() - .map((Hero item) => new EditItem(item)) - .toList(); - } - - onCanceled(EditItem editItem) { - editItem.editing = false; - } - - onSaved(EditItem editItem, Hero updatedHero) { - editItem.item = updatedHero; - editItem.editing = false; - } -} -// #enddocregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/heroes_service.dart b/public/docs/_examples/hierarchical-dependency-injection/dart/lib/heroes_service.dart deleted file mode 100644 index c02eeb7539..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/heroes_service.dart +++ /dev/null @@ -1,20 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; - -@Injectable() -class HeroesService { - List _heroes = [ - new Hero() - ..name = "RubberMan" - ..power = 'Flexibility', - new Hero() - ..name = "Tornado" - ..power = 'Weather changer' - ]; - - List getHeroes() { - return _heroes; - } -} diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/restore_service.dart b/public/docs/_examples/hierarchical-dependency-injection/dart/lib/restore_service.dart deleted file mode 100644 index 50f4ce9bdb..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/dart/lib/restore_service.dart +++ /dev/null @@ -1,28 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -@Injectable() -class RestoreService { - T _originalItem; - T _currentItem; - - setItem(T item) { - _originalItem = item; - _currentItem = clone(item); - } - - T getItem() { - return _currentItem; - } - - T restoreItem() { - _currentItem = _originalItem; - return getItem(); - } - - T clone(T item) { - // super poor clone implementation - return item.clone(); - } -} -// #enddocregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/pubspec.yaml b/public/docs/_examples/hierarchical-dependency-injection/dart/pubspec.yaml deleted file mode 100644 index 7f4fcce629..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/dart/pubspec.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# #docregion -name: 'hierarchical_di' -description: Hierarchical dependency injection example -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: 'package:angular2/common.dart#COMMON_DIRECTIVES' - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/web/index.html b/public/docs/_examples/hierarchical-dependency-injection/dart/web/index.html deleted file mode 100644 index 598203b414..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/dart/web/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - Hierarchical Injector - - - - - - - - loading... - - - - diff --git a/public/docs/_examples/hierarchical-dependency-injection/dart/web/main.dart b/public/docs/_examples/hierarchical-dependency-injection/dart/web/main.dart deleted file mode 100644 index 4b181c2ab5..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/dart/web/main.dart +++ /dev/null @@ -1,16 +0,0 @@ -// #docregion -import 'package:angular2/platform/browser.dart'; - -import 'package:hierarchical_di/heroes_list_component.dart'; -import 'package:hierarchical_di/heroes_service.dart'; - -void main() { - bootstrap(HeroesListComponent, [HeroesService]); -} - -/* Documentation artifact below -// #docregion bad-alternative -// Don't do this! -bootstrap(HeroesListComponent, [HeroesService, RestoreService]) -// #enddocregion bad-alternative -*/ diff --git a/public/docs/_examples/hierarchical-dependency-injection/e2e-spec.ts b/public/docs/_examples/hierarchical-dependency-injection/e2e-spec.ts index 1342869429..4630453f78 100644 --- a/public/docs/_examples/hierarchical-dependency-injection/e2e-spec.ts +++ b/public/docs/_examples/hierarchical-dependency-injection/e2e-spec.ts @@ -1,56 +1,103 @@ -/// -describe('Hierarchical dependency injection', function () { +'use strict'; // necessary for es6 output in node - beforeEach(function () { +import { browser, by, element } from 'protractor'; + +describe('Hierarchical dependency injection', () => { + + beforeAll(() => { browser.get(''); }); - it('should open with a card view', function () { - expect(element.all(by.cssContainingText('button','edit')).get(0).isDisplayed()).toBe(true, - "edit button should be displayed"); - }); + describe('Heroes Scenario', () => { + let page = { + heroName: '', + income: '', - it('should have multiple heroes listed', function () { - expect(element.all(by.css('heroes-list li')).count()).toBeGreaterThan(1); - }); + // queries + heroEl: element.all(by.css('heroes-list li')).get(0), // first hero + heroCardEl: element(by.css('heroes-list hero-tax-return')), // first hero tax-return + taxReturnNameEl: element.all(by.css('heroes-list hero-tax-return #name')).get(0), + incomeInputEl: element.all(by.css('heroes-list hero-tax-return input')).get(0), + cancelButtonEl: element(by.cssContainingText('heroes-list hero-tax-return button', 'Cancel')), + closeButtonEl: element(by.cssContainingText('heroes-list hero-tax-return button', 'Close')), + saveButtonEl: element(by.cssContainingText('heroes-list hero-tax-return button', 'Save')) + }; - it('should change to editor view after selection', function () { - let editButtonEle = element.all(by.cssContainingText('button','edit')).get(0); - editButtonEle.click().then(function() { - expect(editButtonEle.isDisplayed()).toBe(false, "edit button should be hidden after selection"); - }) - }); + it('should list multiple heroes', () => { + expect(element.all(by.css('heroes-list li')).count()).toBeGreaterThan(1); + }); + + it('should show no hero tax-returns at the start', () => { + expect(element.all(by.css('heroes-list li hero-tax-return')).count()).toBe(0); + }); + + it('should open first hero in hero-tax-return view after click', () => { + page.heroEl.getText() + .then(val => { + page.heroName = val; + }) + .then(() => page.heroEl.click()) + .then(() => { + expect(page.heroCardEl.isDisplayed()).toBe(true); + }); + }); + + it('hero tax-return should have first hero\'s name', () => { + // Not `page.tax-returnNameInputEl.getAttribute('value')` although later that is essential + expect(page.taxReturnNameEl.getText()).toEqual(page.heroName); + }); + + it('should be able to cancel change', () => { + page.incomeInputEl.clear() + .then(() => page.incomeInputEl.sendKeys('777')) + .then(() => { + expect(page.incomeInputEl.getAttribute('value')).toBe('777', 'income should be 777'); + return page.cancelButtonEl.click(); + }) + .then(() => { + expect(page.incomeInputEl.getAttribute('value')).not.toBe('777', 'income should not be 777'); + }); + }); + + it('should be able to save change', () => { + page.incomeInputEl.clear() + .then(() => page.incomeInputEl.sendKeys('999')) + .then(() => { + expect(page.incomeInputEl.getAttribute('value')).toBe('999', 'income should be 999'); + return page.saveButtonEl.click(); + }) + .then(() => { + expect(page.incomeInputEl.getAttribute('value')).toBe('999', 'income should still be 999'); + }); + }); + + it('should be able to close tax-return', () => { + page.saveButtonEl.click() + .then(() => { + expect(element.all(by.css('heroes-list li hero-tax-return')).count()).toBe(0); + }); + }); - it('should be able to save editor change', function () { - testEdit(true); }); - it('should be able to cancel editor change', function () { - testEdit(false); + describe('Villains Scenario', () => { + it('should list multiple villains', () => { + expect(element.all(by.css('villains-list li')).count()).toBeGreaterThan(1); + }); }); - function testEdit(shouldSave: boolean) { - // select 2nd ele - let heroEle = element.all(by.css('heroes-list li')).get(1); - // get the 2nd span which is the name of the hero - let heroNameEle = heroEle.all(by.css('hero-card span')).get(1); - let editButtonEle = heroEle.element(by.cssContainingText('button','edit')); - editButtonEle.click().then(function() { - let inputEle = heroEle.element(by.css('hero-editor input')); - // return inputEle.sendKeys("foo"); - return sendKeys(inputEle, "foo"); - }).then(function() { - let buttonName = shouldSave ? 'save' : 'cancel'; - let buttonEle = heroEle.element(by.cssContainingText('button', buttonName)); - return buttonEle.click(); - }).then(function() { - if (shouldSave) { - expect(heroNameEle.getText()).toContain('foo'); - } else { - expect(heroNameEle.getText()).not.toContain('foo'); - } - }) - } + describe('Cars Scenario', () => { + + it('A-component should use expected services', () => { + expect(element(by.css('a-car')).getText()).toContain('C1-E1-T1'); + }); + it('B-component should use expected services', () => { + expect(element(by.css('b-car')).getText()).toContain('C2-E2-T1'); + }); + it('C-component should use expected services', () => { + expect(element(by.css('c-car')).getText()).toContain('C3-E2-T1'); + }); + }); }); diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/app/edit-item.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/app/edit-item.ts deleted file mode 100644 index abbeabf2b0..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/ts/app/edit-item.ts +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -export class EditItem { - editing: boolean - constructor (public item: T) {} -} -// #docregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/app/hero-card.component.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/app/hero-card.component.ts deleted file mode 100644 index a888168848..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/ts/app/hero-card.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -// #docregion -import { Component, Input } from '@angular/core'; - -import { Hero } from './hero'; - -@Component({ - selector: 'hero-card', - template: ` -
    - Name: - {{hero.name}} -
    ` -}) -export class HeroCardComponent { - @Input() hero: Hero; -} -// #docregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/app/hero-editor.component.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/app/hero-editor.component.ts deleted file mode 100644 index 65f0b7f066..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/ts/app/hero-editor.component.ts +++ /dev/null @@ -1,47 +0,0 @@ -// #docregion -import { Component, EventEmitter, Input, Output } from '@angular/core'; - -import { RestoreService } from './restore.service'; -import { Hero } from './hero'; - -@Component({ - selector: 'hero-editor', - // #docregion providers - providers: [RestoreService], - // #enddocregion providers - template: ` -
    - Name: - -
    - - -
    -
    ` -}) - -export class HeroEditorComponent { - @Output() canceled = new EventEmitter(); - @Output() saved = new EventEmitter(); - - constructor(private restoreService: RestoreService) {} - - @Input() - set hero (hero: Hero) { - this.restoreService.setItem(hero); - } - - get hero () { - return this.restoreService.getItem(); - } - - onSaved () { - this.saved.next(this.restoreService.getItem()); - } - - onCanceled () { - this.hero = this.restoreService.restoreItem(); - this.canceled.next(this.hero); - } -} -// #enddocregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/app/hero.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/app/hero.ts deleted file mode 100644 index 76f808b1c5..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/ts/app/hero.ts +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -export class Hero { - name: string; - power: string; -} -// #enddocregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/app/heroes-list.component.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/app/heroes-list.component.ts deleted file mode 100644 index 0fef36e205..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/ts/app/heroes-list.component.ts +++ /dev/null @@ -1,54 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { EditItem } from './edit-item'; -import { HeroesService } from './heroes.service'; -import { HeroCardComponent } from './hero-card.component'; -import { HeroEditorComponent } from './hero-editor.component'; -import { Hero } from './hero'; - -@Component({ - selector: 'heroes-list', - template: ` -
    -
      -
    • - - - - - -
    • -
    -
    `, - directives: [HeroCardComponent, HeroEditorComponent] -}) -export class HeroesListComponent { - heroes: Array>; - constructor(heroesService: HeroesService) { - this.heroes = heroesService.getHeroes() - .map(item => new EditItem(item)); - } - - onSaved (editItem: EditItem, updatedHero: Hero) { - editItem.item = updatedHero; - editItem.editing = false; - } - - onCanceled (editItem: EditItem) { - editItem.editing = false; - } -} - - -// #enddocregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/app/heroes.service.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/app/heroes.service.ts deleted file mode 100644 index b863ee7af8..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/ts/app/heroes.service.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Hero } from './hero'; - -export class HeroesService { - heroes: Array = [ - { name: "RubberMan", power: 'flexibility'}, - { name: "Tornado", power: 'Weather changer'} - ]; - - getHeroes () { - return this.heroes; - } -} diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/app/main.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/app/main.ts deleted file mode 100644 index 5a96ae391b..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/ts/app/main.ts +++ /dev/null @@ -1,14 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { HeroesListComponent } from './heroes-list.component'; -import { HeroesService } from './heroes.service'; - -bootstrap(HeroesListComponent, [HeroesService]) - -/* Documentation artifact below -// #docregion bad-alternative -// Don't do this! -bootstrap(HeroesListComponent, [HeroesService, RestoreService]) -// #enddocregion bad-alternative -*/ diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/app/restore.service.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/app/restore.service.ts deleted file mode 100644 index c81786b2a3..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/ts/app/restore.service.ts +++ /dev/null @@ -1,25 +0,0 @@ -// #docregion -export class RestoreService { - originalItem: T; - currentItem: T; - - setItem (item: T) { - this.originalItem = item; - this.currentItem = this.clone(item); - } - - getItem () :T { - return this.currentItem; - } - - restoreItem () :T { - this.currentItem = this.originalItem; - return this.getItem(); - } - - clone (item: T) :T { - // super poor clone implementation - return JSON.parse(JSON.stringify(item)); - } -} -// #enddocregion diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/index.html b/public/docs/_examples/hierarchical-dependency-injection/ts/index.html deleted file mode 100644 index 91d2dc8894..0000000000 --- a/public/docs/_examples/hierarchical-dependency-injection/ts/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - Hierarchical Injectors - - - - - - - - - - - - - - - - - - loading... - - - - diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/plnkr.json b/public/docs/_examples/hierarchical-dependency-injection/ts/plnkr.json index 84cd89d7ca..ca92b93b06 100644 --- a/public/docs/_examples/hierarchical-dependency-injection/ts/plnkr.json +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/plnkr.json @@ -1,5 +1,9 @@ { - "description": "Hierachical Injectors", - "files":["!**/*.d.ts", "!**/*.js"], + "description": "Hierachical Dependency Injection", + "basePath": "src/", + "files":[ + "!**/*.d.ts", + "!**/*.js" + ], "tags": ["dependency", "injection"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/app.component.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/app.component.ts new file mode 100644 index 0000000000..34b5dd0a5a --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/app.component.ts @@ -0,0 +1,21 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` + + + + +

    Hierarchical Dependency Injection

    + + + + + ` +}) +export class AppComponent { + showCars = true; + showHeroes = true; + showVillains = true; +} diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/app.module.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/app.module.ts new file mode 100644 index 0000000000..6ea18655af --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/app.module.ts @@ -0,0 +1,33 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { HeroTaxReturnComponent } from './hero-tax-return.component'; +import { HeroesListComponent } from './heroes-list.component'; +import { HeroesService } from './heroes.service'; +import { VillainsListComponent } from './villains-list.component'; + +import { carComponents, carServices } from './car.components'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule + ], + providers: [ + carServices, + HeroesService + ], + declarations: [ + AppComponent, + carComponents, + HeroesListComponent, + HeroTaxReturnComponent, + VillainsListComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } + diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/car.components.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/car.components.ts new file mode 100644 index 0000000000..5b4df19696 --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/car.components.ts @@ -0,0 +1,74 @@ +import { Component } from '@angular/core'; + +import { + CarService, CarService2, CarService3, + EngineService, EngineService2, TiresService +} from './car.services'; + +////////// CCarComponent //////////// +@Component({ + selector: 'c-car', + template: `
    C: {{description}}
    `, + providers: [ + { provide: CarService, useClass: CarService3 } + ] +}) +export class CCarComponent { + description: string; + constructor(carService: CarService) { + this.description = `${carService.getCar().description} (${carService.name})`; + } +} + +////////// BCarComponent //////////// +@Component({ + selector: 'b-car', + template: ` +
    B: {{description}}
    + + `, + providers: [ + { provide: CarService, useClass: CarService2 }, + { provide: EngineService, useClass: EngineService2 } + ] +}) +export class BCarComponent { + description: string; + constructor(carService: CarService) { + this.description = `${carService.getCar().description} (${carService.name})`; + } +} + +////////// ACarComponent //////////// +@Component({ + selector: 'a-car', + template: ` +
    A: {{description}}
    + ` +}) +export class ACarComponent { + description: string; + constructor(carService: CarService) { + this.description = `${carService.getCar().description} (${carService.name})`; + } +} +////////// CarsComponent //////////// +@Component({ + selector: 'my-cars', + template: ` +

    Cars

    + ` +}) +export class CarsComponent { } + +//////////////// + +export const carComponents = [ + CarsComponent, + ACarComponent, BCarComponent, CCarComponent +]; + +// generic car-related services +export const carServices = [ + CarService, EngineService, TiresService +]; diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/car.services.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/car.services.ts new file mode 100644 index 0000000000..03c79270b0 --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/car.services.ts @@ -0,0 +1,95 @@ +import { Injectable } from '@angular/core'; + +/// Model /// +export class Car { + name = 'Avocado Motors'; + constructor(public engine: Engine, public tires: Tires) { } + + get description() { + return `${this.name} car with ` + + `${this.engine.cylinders} cylinders and ${this.tires.make} tires.`; + } +} + +export class Engine { + cylinders = 4; +} + +export class Tires { + make = 'Flintstone'; + model = 'Square'; +} + +//// Engine services /// +@Injectable() +export class EngineService { + id = 'E1'; + getEngine() { return new Engine(); } +} + +@Injectable() +export class EngineService2 { + id = 'E2'; + getEngine() { + const eng = new Engine(); + eng.cylinders = 8; + return eng; + } +} + +//// Tire services /// +@Injectable() +export class TiresService { + id = 'T1'; + getTires() { return new Tires(); } +} + +/// Car Services /// +@Injectable() +export class CarService { + id = 'C1'; + constructor( + protected engineService: EngineService, + protected tiresService: TiresService) { } + + getCar() { + return new Car( + this.engineService.getEngine(), + this.tiresService.getTires()); + } + + get name() { + return `${this.id}-${this.engineService.id}-${this.tiresService.id}`; + } +} + +@Injectable() +export class CarService2 extends CarService { + id = 'C2'; + constructor( + protected engineService: EngineService, + protected tiresService: TiresService) { + super(engineService, tiresService); + } + getCar() { + const car = super.getCar(); + car.name = 'BamBam Motors, BroVan 2000'; + return car; + } +} + +@Injectable() +export class CarService3 extends CarService2 { + id = 'C3'; + constructor( + protected engineService: EngineService, + protected tiresService: TiresService) { + super(engineService, tiresService); + } + getCar() { + const car = super.getCar(); + car.name = 'Chizzamm Motors, Calico UltraMax Supreme'; + return car; + } +} + diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.component.css b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.component.css new file mode 100644 index 0000000000..1d29a1d168 --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.component.css @@ -0,0 +1,22 @@ +.tax-return { border: thin dashed green; margin: 1em; padding: 1em; width: 18em; position: relative } +#name { font-weight: bold;} +#tid { float: right; } +input { font-size: 100%; padding-left: 2px; width: 6em; } +input.num { text-align: right; padding-left: 0; padding-right: 4px; width: 4em;} +fieldset { border: 0 none;} + +.msg { + color: white; + font-size: 150%; + position: absolute; + /*opacity: 0.3;*/ + left: 2px; + top: 3em; + width: 98%; + background-color: green; + text-align: center; +} +.msg.canceled { + color: white; + background-color: red; +} diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.component.html b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.component.html new file mode 100644 index 0000000000..ebf2dcbaaa --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.component.html @@ -0,0 +1,20 @@ +
    +
    {{message}}
    +
    + {{taxReturn.name}} + +
    +
    + +
    +
    + +
    +
    + + + +
    +
    diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.component.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.component.ts new file mode 100644 index 0000000000..ad8e0153d9 --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.component.ts @@ -0,0 +1,44 @@ +// #docregion +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { HeroTaxReturn } from './hero'; +import { HeroTaxReturnService } from './hero-tax-return.service'; + +@Component({ + selector: 'hero-tax-return', + templateUrl: './hero-tax-return.component.html', + styleUrls: [ './hero-tax-return.component.css' ], + // #docregion providers + providers: [ HeroTaxReturnService ] + // #enddocregion providers +}) +export class HeroTaxReturnComponent { + message = ''; + @Output() close = new EventEmitter(); + + get taxReturn(): HeroTaxReturn { + return this.heroTaxReturnService.taxReturn; + } + @Input() + set taxReturn (htr: HeroTaxReturn) { + this.heroTaxReturnService.taxReturn = htr; + } + + constructor(private heroTaxReturnService: HeroTaxReturnService ) { } + + onCanceled() { + this.flashMessage('Canceled'); + this.heroTaxReturnService.restoreTaxReturn(); + }; + + onClose() { this.close.emit(); }; + + onSaved() { + this.flashMessage('Saved'); + this.heroTaxReturnService.saveTaxReturn(); + } + + flashMessage(msg: string) { + this.message = msg; + setTimeout(() => this.message = '', 500); + } +} diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.service.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.service.ts new file mode 100644 index 0000000000..d6ff0f7fff --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero-tax-return.service.ts @@ -0,0 +1,30 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { HeroTaxReturn } from './hero'; +import { HeroesService } from './heroes.service'; + +@Injectable() +export class HeroTaxReturnService { + private currentTaxReturn: HeroTaxReturn; + private originalTaxReturn: HeroTaxReturn; + + constructor(private heroService: HeroesService) { } + + set taxReturn (htr: HeroTaxReturn) { + this.originalTaxReturn = htr; + this.currentTaxReturn = htr.clone(); + } + + get taxReturn (): HeroTaxReturn { + return this.currentTaxReturn; + } + + restoreTaxReturn() { + this.taxReturn = this.originalTaxReturn; + } + + saveTaxReturn() { + this.taxReturn = this.currentTaxReturn; + this.heroService.saveTaxReturn(this.currentTaxReturn).subscribe(); + } +} diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero.ts new file mode 100644 index 0000000000..4ad6ccd8eb --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/hero.ts @@ -0,0 +1,31 @@ +// #docregion + +export class Hero { + id: number; + name: string; + tid: string; // tax id +} + +//// HeroTaxReturn //// +let nextId = 100; + +export class HeroTaxReturn { + constructor( + public id = nextId++, + public hero: Hero, + public income = 0 ) { + if (id === 0) { id = nextId++; } + } + + get name() { return this.hero.name; } + get tax() { return this.income ? .10 * this.income : 0; } + get tid() { return this.hero.tid; } + + toString() { + return `${this.hero.name}`; + } + + clone() { + return new HeroTaxReturn(this.id, this.hero, this.income); + } +} diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/heroes-list.component.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/heroes-list.component.ts new file mode 100644 index 0000000000..36cb5ec1c3 --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/heroes-list.component.ts @@ -0,0 +1,48 @@ +// #docregion +import { Component } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; + +import { Hero, HeroTaxReturn } from './hero'; +import { HeroesService } from './heroes.service'; + +@Component({ + selector: 'heroes-list', + template: ` +
    +

    Hero Tax Returns

    +
      +
    • {{hero.name}} +
    • +
    + + +
    + `, + styles: [ 'li {cursor: pointer;}' ] +}) +export class HeroesListComponent { + heroes: Observable; + selectedTaxReturns: HeroTaxReturn[] = []; + + constructor(private heroesService: HeroesService) { + this.heroes = heroesService.getHeroes(); + } + + showTaxReturn(hero: Hero) { + this.heroesService.getTaxReturn(hero) + .subscribe(htr => { + // show if not currently shown + if (!this.selectedTaxReturns.find(tr => tr.id === htr.id)) { + this.selectedTaxReturns.push(htr); + } + }); + } + + closeTaxReturn(ix: number) { + this.selectedTaxReturns.splice(ix, 1); + } +} diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/heroes.service.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/heroes.service.ts new file mode 100644 index 0000000000..85b33c89a0 --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/heroes.service.ts @@ -0,0 +1,47 @@ +import { Injectable } from '@angular/core'; + +import { Observable } from 'rxjs/Observable'; +import { Observer } from 'rxjs/Observer'; + +import { Hero, HeroTaxReturn } from './hero'; + +@Injectable() +export class HeroesService { + heroes: Hero[] = [ + { id: 1, name: 'RubberMan', tid: '082-27-5678'}, + { id: 2, name: 'Tornado', tid: '099-42-4321'} + ]; + + heroTaxReturns: HeroTaxReturn[] = [ + new HeroTaxReturn(10, this.heroes[0], 35000), + new HeroTaxReturn(20, this.heroes[1], 1250000) + ]; + + getHeroes(): Observable { + return new Observable((observer: Observer) => { + observer.next(this.heroes); + observer.complete(); + }); + } + + getTaxReturn(hero: Hero): Observable { + return new Observable((observer: Observer) => { + const htr = this.heroTaxReturns.find(t => t.hero.id === hero.id); + observer.next(htr || new HeroTaxReturn(0, hero)); + observer.complete(); + }); + } + + saveTaxReturn(heroTaxReturn: HeroTaxReturn): Observable { + return new Observable((observer: Observer) => { + const htr = this.heroTaxReturns.find(t => t.id === heroTaxReturn.id); + if (htr) { + heroTaxReturn = Object.assign(htr, heroTaxReturn); // demo: mutate + } else { + this.heroTaxReturns.push(heroTaxReturn); + } + observer.next(heroTaxReturn); + observer.complete(); + }); + } +} diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/villains-list.component.html b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/villains-list.component.html new file mode 100644 index 0000000000..75e5ba3237 --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/villains-list.component.html @@ -0,0 +1,6 @@ +
    +

    Villains

    +
      +
    • {{villain.name}}
    • +
    +
    diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/villains-list.component.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/villains-list.component.ts new file mode 100644 index 0000000000..5226d4f2a9 --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/villains-list.component.ts @@ -0,0 +1,20 @@ +// #docregion +import { Component } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; + +import { Villain, VillainsService } from './villains.service'; + +// #docregion metadata +@Component({ + selector: 'villains-list', + templateUrl: './villains-list.component.html', + providers: [ VillainsService ] +}) +// #enddocregion metadata +export class VillainsListComponent { + villains: Observable; + + constructor(private villainsService: VillainsService) { + this.villains = villainsService.getVillains(); + } +} diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/villains.service.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/villains.service.ts new file mode 100644 index 0000000000..3d480c20af --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/app/villains.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@angular/core'; + +import { of } from 'rxjs/observable/of'; + +export interface Villain { id: number; name: string; } + +@Injectable() +export class VillainsService { + villains: Villain[] = [ + { id: 1, name: 'Dr. Evil'}, + { id: 2, name: 'Moriarty'} + ]; + + getVillains() { + return of(this.villains); + } +} diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/index.html b/public/docs/_examples/hierarchical-dependency-injection/ts/src/index.html new file mode 100644 index 0000000000..0ea32679e6 --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/index.html @@ -0,0 +1,26 @@ + + + + Hierarchical Injectors + + + + + + + + + + + + + + + + + loading... + + + diff --git a/public/docs/_examples/hierarchical-dependency-injection/ts/src/main.ts b/public/docs/_examples/hierarchical-dependency-injection/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/hierarchical-dependency-injection/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/homepage-hello-world/e2e-spec.ts b/public/docs/_examples/homepage-hello-world/e2e-spec.ts index 4200429a4f..c4c6464937 100644 --- a/public/docs/_examples/homepage-hello-world/e2e-spec.ts +++ b/public/docs/_examples/homepage-hello-world/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Homepage Hello World', function () { beforeAll(function () { @@ -10,13 +13,12 @@ describe('Homepage Hello World', function () { it(`should display the label: ${expectedLabel}`, function () { expect(element(by.css('label')).getText()).toEqual(expectedLabel); }); - + it('should display entered name', function () { let testName = 'Bobby Joe'; let nameEle = element.all(by.css('input')).get(0); - nameEle.getAttribute('value').then(function(value) { - // nameEle.sendKeys(testName); // should work but doesn't - sendKeys(nameEle, testName); // utility that does work + nameEle.getAttribute('value').then(function(value: string) { + nameEle.sendKeys(testName); let newValue = value + testName; // old input box value + new name expect(nameEle.getAttribute('value')).toEqual(newValue); }).then(function() { diff --git a/public/docs/_examples/homepage-hello-world/ts/app/main.ts b/public/docs/_examples/homepage-hello-world/ts/app/main.ts deleted file mode 100644 index 625a9c338f..0000000000 --- a/public/docs/_examples/homepage-hello-world/ts/app/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { HelloWorld } from './hello_world'; - -bootstrap(HelloWorld); diff --git a/public/docs/_examples/homepage-hello-world/ts/index.1.html b/public/docs/_examples/homepage-hello-world/ts/index.1.html deleted file mode 100644 index ce0bdfbaf9..0000000000 --- a/public/docs/_examples/homepage-hello-world/ts/index.1.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - Angular 2 Hello World - - - - - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/homepage-hello-world/ts/index.html b/public/docs/_examples/homepage-hello-world/ts/index.html deleted file mode 100644 index 794935d3bb..0000000000 --- a/public/docs/_examples/homepage-hello-world/ts/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Angular 2 Hello World - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/homepage-hello-world/ts/plnkr.json b/public/docs/_examples/homepage-hello-world/ts/plnkr.json index 78f6fd979d..bfe6aecc8b 100644 --- a/public/docs/_examples/homepage-hello-world/ts/plnkr.json +++ b/public/docs/_examples/homepage-hello-world/ts/plnkr.json @@ -1,8 +1,9 @@ { "description": "Hello World", + "basePath": "src/", "files":[ - "!**/*.d.ts", + "!**/*.d.ts", "!**/*.js", "!**/*.[1].*" ] -} \ No newline at end of file +} diff --git a/public/docs/_examples/homepage-hello-world/ts/src/app/app.module.ts b/public/docs/_examples/homepage-hello-world/ts/src/app/app.module.ts new file mode 100644 index 0000000000..55a2ef3693 --- /dev/null +++ b/public/docs/_examples/homepage-hello-world/ts/src/app/app.module.ts @@ -0,0 +1,16 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { HelloWorldComponent } from './hello_world'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule + ], + declarations: [ HelloWorldComponent ], + bootstrap: [ HelloWorldComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/homepage-hello-world/ts/app/hello_world.html b/public/docs/_examples/homepage-hello-world/ts/src/app/hello_world.html similarity index 100% rename from public/docs/_examples/homepage-hello-world/ts/app/hello_world.html rename to public/docs/_examples/homepage-hello-world/ts/src/app/hello_world.html diff --git a/public/docs/_examples/homepage-hello-world/ts/app/hello_world.ts b/public/docs/_examples/homepage-hello-world/ts/src/app/hello_world.ts similarity index 81% rename from public/docs/_examples/homepage-hello-world/ts/app/hello_world.ts rename to public/docs/_examples/homepage-hello-world/ts/src/app/hello_world.ts index 67850d5749..145d22e1e9 100644 --- a/public/docs/_examples/homepage-hello-world/ts/app/hello_world.ts +++ b/public/docs/_examples/homepage-hello-world/ts/src/app/hello_world.ts @@ -6,9 +6,9 @@ import { Component } from '@angular/core'; selector: 'hello-world', // Location of the template for this component - templateUrl: 'app/hello_world.html' + templateUrl: './hello_world.html' }) -export class HelloWorld { +export class HelloWorldComponent { // Declaring the variable for binding with initial value yourName: string = ''; diff --git a/public/docs/_examples/homepage-hello-world/ts/src/index.1.html b/public/docs/_examples/homepage-hello-world/ts/src/index.1.html new file mode 100644 index 0000000000..37c1bf787c --- /dev/null +++ b/public/docs/_examples/homepage-hello-world/ts/src/index.1.html @@ -0,0 +1,32 @@ + + + + + Angular Hello World + + + + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/homepage-hello-world/ts/src/index.html b/public/docs/_examples/homepage-hello-world/ts/src/index.html new file mode 100644 index 0000000000..9dab660d10 --- /dev/null +++ b/public/docs/_examples/homepage-hello-world/ts/src/index.html @@ -0,0 +1,28 @@ + + + + + Angular Hello World + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/homepage-hello-world/ts/src/main.ts b/public/docs/_examples/homepage-hello-world/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/homepage-hello-world/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/homepage-tabs/e2e-spec.ts b/public/docs/_examples/homepage-tabs/e2e-spec.ts index 71f8bcd262..2131d75906 100644 --- a/public/docs/_examples/homepage-tabs/e2e-spec.ts +++ b/public/docs/_examples/homepage-tabs/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Homepage Tabs', function () { beforeAll(function () { diff --git a/public/docs/_examples/homepage-tabs/ts/app/di_demo.ts b/public/docs/_examples/homepage-tabs/ts/app/di_demo.ts deleted file mode 100644 index 1e170bcd6f..0000000000 --- a/public/docs/_examples/homepage-tabs/ts/app/di_demo.ts +++ /dev/null @@ -1,48 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { UiTabs, UiPane } from './ui_tabs'; - -class Detail { - title: string; - text: string; -} - -@Component({ - selector: 'di-demo', - template: ` -

    Tabs Demo

    - - - - - -
    - - `, - directives: [UiTabs, UiPane] -}) -export class DiDemo { - details: Detail[] = []; - id: number = 0; - - addDetail() { - this.id++; - this.details.push({ - title: `Detail ${this.id}`, - text: `Some detail text for ${this.id}...` - }); - } - - removeDetail(detail: Detail) { - this.details = this.details.filter((d) => d !== detail); - } -} - diff --git a/public/docs/_examples/homepage-tabs/ts/app/main.ts b/public/docs/_examples/homepage-tabs/ts/app/main.ts deleted file mode 100644 index b7904fd356..0000000000 --- a/public/docs/_examples/homepage-tabs/ts/app/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { DiDemo } from './di_demo'; - -bootstrap(DiDemo); diff --git a/public/docs/_examples/homepage-tabs/ts/index.1.html b/public/docs/_examples/homepage-tabs/ts/index.1.html deleted file mode 100644 index c790439682..0000000000 --- a/public/docs/_examples/homepage-tabs/ts/index.1.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - Angular 2 Tabs - - - - - - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/homepage-tabs/ts/index.html b/public/docs/_examples/homepage-tabs/ts/index.html deleted file mode 100644 index 1fe2ebc8ba..0000000000 --- a/public/docs/_examples/homepage-tabs/ts/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Angular 2 Tabs - - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/homepage-tabs/ts/plnkr.json b/public/docs/_examples/homepage-tabs/ts/plnkr.json index 05ee7a2b9d..c1a33dc8f0 100644 --- a/public/docs/_examples/homepage-tabs/ts/plnkr.json +++ b/public/docs/_examples/homepage-tabs/ts/plnkr.json @@ -1,8 +1,9 @@ { "description": "Tabs", + "basePath": "src/", "files":[ - "!**/*.d.ts", + "!**/*.d.ts", "!**/*.js", "!**/*.[1].*" ] -} \ No newline at end of file +} diff --git a/public/docs/_examples/homepage-tabs/ts/src/app/app.module.ts b/public/docs/_examples/homepage-tabs/ts/src/app/app.module.ts new file mode 100644 index 0000000000..bd2193755c --- /dev/null +++ b/public/docs/_examples/homepage-tabs/ts/src/app/app.module.ts @@ -0,0 +1,17 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { DiDemoComponent } from './di_demo'; +import { UiTabsComponent, UiPaneDirective } from './ui_tabs'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ + DiDemoComponent, + UiTabsComponent, + UiPaneDirective + ], + bootstrap: [ DiDemoComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/homepage-tabs/ts/src/app/di_demo.ts b/public/docs/_examples/homepage-tabs/ts/src/app/di_demo.ts new file mode 100644 index 0000000000..be72ae5c79 --- /dev/null +++ b/public/docs/_examples/homepage-tabs/ts/src/app/di_demo.ts @@ -0,0 +1,45 @@ +// #docregion +import { Component } from '@angular/core'; + +class Detail { + title: string; + text: string; +} + +@Component({ + selector: 'di-demo', + template: ` +

    Tabs Demo

    + + + + + +
    + + ` +}) +export class DiDemoComponent { + details: Detail[] = []; + id: number = 0; + + addDetail() { + this.id++; + this.details.push({ + title: `Detail ${this.id}`, + text: `Some detail text for ${this.id}...` + }); + } + + removeDetail(detail: Detail) { + this.details = this.details.filter((d) => d !== detail); + } +} + diff --git a/public/docs/_examples/homepage-tabs/ts/app/ui_tabs.ts b/public/docs/_examples/homepage-tabs/ts/src/app/ui_tabs.ts similarity index 78% rename from public/docs/_examples/homepage-tabs/ts/app/ui_tabs.ts rename to public/docs/_examples/homepage-tabs/ts/src/app/ui_tabs.ts index a9798d07e6..5e2f47b140 100644 --- a/public/docs/_examples/homepage-tabs/ts/app/ui_tabs.ts +++ b/public/docs/_examples/homepage-tabs/ts/src/app/ui_tabs.ts @@ -3,9 +3,9 @@ import { Component, Directive, Input, QueryList, ViewContainerRef, TemplateRef, ContentChildren } from '@angular/core'; @Directive({ - selector: '[ui-pane]' + selector: '[uiPane]' }) -export class UiPane { +export class UiPaneDirective { @Input() title: string; private _active: boolean = false; @@ -41,11 +41,11 @@ export class UiPane { `, styles: ['a { cursor: pointer; cursor: hand; }'] }) -export class UiTabs { - @ContentChildren(UiPane) panes: QueryList; +export class UiTabsComponent { + @ContentChildren(UiPaneDirective) panes: QueryList; - select(pane: UiPane) { - this.panes.toArray().forEach((p: UiPane) => p.active = p === pane); + select(pane: UiPaneDirective) { + this.panes.toArray().forEach((p: UiPaneDirective) => p.active = p === pane); } } diff --git a/public/docs/_examples/homepage-tabs/ts/src/index.1.html b/public/docs/_examples/homepage-tabs/ts/src/index.1.html new file mode 100644 index 0000000000..a25071b484 --- /dev/null +++ b/public/docs/_examples/homepage-tabs/ts/src/index.1.html @@ -0,0 +1,33 @@ + + + + + Angular Tabs + + + + + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/homepage-tabs/ts/src/index.html b/public/docs/_examples/homepage-tabs/ts/src/index.html new file mode 100644 index 0000000000..d38b36e033 --- /dev/null +++ b/public/docs/_examples/homepage-tabs/ts/src/index.html @@ -0,0 +1,29 @@ + + + + + Angular Tabs + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/homepage-tabs/ts/src/main.ts b/public/docs/_examples/homepage-tabs/ts/src/main.ts new file mode 100644 index 0000000000..f332d1d245 --- /dev/null +++ b/public/docs/_examples/homepage-tabs/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/homepage-todo/e2e-spec.ts b/public/docs/_examples/homepage-todo/e2e-spec.ts index 28b3db24e5..fb74e4e70f 100644 --- a/public/docs/_examples/homepage-todo/e2e-spec.ts +++ b/public/docs/_examples/homepage-todo/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Homepage Todo', function () { beforeAll(function () { diff --git a/public/docs/_examples/homepage-todo/ts/app/main.ts b/public/docs/_examples/homepage-todo/ts/app/main.ts deleted file mode 100644 index 1beb139138..0000000000 --- a/public/docs/_examples/homepage-todo/ts/app/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { TodoApp } from './todo_app'; - -bootstrap(TodoApp); diff --git a/public/docs/_examples/homepage-todo/ts/app/todo.ts b/public/docs/_examples/homepage-todo/ts/app/todo.ts deleted file mode 100644 index 57070dc72c..0000000000 --- a/public/docs/_examples/homepage-todo/ts/app/todo.ts +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -// Declare an interaface for type safety -export interface Todo { - text: string, - done: boolean -} diff --git a/public/docs/_examples/homepage-todo/ts/index.1.html b/public/docs/_examples/homepage-todo/ts/index.1.html deleted file mode 100644 index d926bbe323..0000000000 --- a/public/docs/_examples/homepage-todo/ts/index.1.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - Angular 2 Todos - - - - - - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/homepage-todo/ts/index.html b/public/docs/_examples/homepage-todo/ts/index.html deleted file mode 100644 index 2bddce017c..0000000000 --- a/public/docs/_examples/homepage-todo/ts/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Angular 2 Todos - - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/homepage-todo/ts/plnkr.json b/public/docs/_examples/homepage-todo/ts/plnkr.json index 7fecc539f7..8e69701221 100644 --- a/public/docs/_examples/homepage-todo/ts/plnkr.json +++ b/public/docs/_examples/homepage-todo/ts/plnkr.json @@ -1,8 +1,9 @@ { "description": "Todo", + "basePath": "src/", "files":[ - "!**/*.d.ts", + "!**/*.d.ts", "!**/*.js", "!**/*.[1].*" ] -} \ No newline at end of file +} diff --git a/public/docs/_examples/homepage-todo/ts/src/app/app.module.ts b/public/docs/_examples/homepage-todo/ts/src/app/app.module.ts new file mode 100644 index 0000000000..a77bb640ab --- /dev/null +++ b/public/docs/_examples/homepage-todo/ts/src/app/app.module.ts @@ -0,0 +1,22 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { TodoAppComponent } from './todo_app'; +import { TodoListComponent } from './todo_list'; +import { TodoFormComponent } from './todo_form'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule + ], + declarations: [ + TodoAppComponent, + TodoListComponent, + TodoFormComponent + ], + bootstrap: [ TodoAppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/homepage-todo/ts/src/app/todo.ts b/public/docs/_examples/homepage-todo/ts/src/app/todo.ts new file mode 100644 index 0000000000..35faec9705 --- /dev/null +++ b/public/docs/_examples/homepage-todo/ts/src/app/todo.ts @@ -0,0 +1,6 @@ +// #docregion +// Declare an interaface for type safety +export interface Todo { + text: string; + done: boolean; +} diff --git a/public/docs/_examples/homepage-todo/ts/app/todo_app.ts b/public/docs/_examples/homepage-todo/ts/src/app/todo_app.ts similarity index 80% rename from public/docs/_examples/homepage-todo/ts/app/todo_app.ts rename to public/docs/_examples/homepage-todo/ts/src/app/todo_app.ts index 96cb759eeb..e56bad95b6 100644 --- a/public/docs/_examples/homepage-todo/ts/app/todo_app.ts +++ b/public/docs/_examples/homepage-todo/ts/src/app/todo_app.ts @@ -2,8 +2,6 @@ import { Component } from '@angular/core'; import { Todo } from './todo'; -import { TodoList } from './todo_list'; -import { TodoForm } from './todo_form'; @Component({ selector: 'todo-app', @@ -14,10 +12,9 @@ import { TodoForm } from './todo_form'; `, - styles:['a { cursor: pointer; cursor: hand; }'], - directives: [TodoList, TodoForm] + styles: ['a { cursor: pointer; cursor: hand; }'] }) -export class TodoApp { +export class TodoAppComponent { todos: Todo[] = [ {text: 'learn angular', done: true}, {text: 'build an angular app', done: false} diff --git a/public/docs/_examples/homepage-todo/ts/app/todo_form.ts b/public/docs/_examples/homepage-todo/ts/src/app/todo_form.ts similarity index 85% rename from public/docs/_examples/homepage-todo/ts/app/todo_form.ts rename to public/docs/_examples/homepage-todo/ts/src/app/todo_form.ts index ecc8596772..38e8d991a7 100644 --- a/public/docs/_examples/homepage-todo/ts/app/todo_form.ts +++ b/public/docs/_examples/homepage-todo/ts/src/app/todo_form.ts @@ -11,13 +11,13 @@ import { Todo } from './todo'; ` }) -export class TodoForm { +export class TodoFormComponent { @Output() newTask = new EventEmitter(); task: string = ''; addTodo() { if (this.task) { - this.newTask.next({text:this.task, done:false}); + this.newTask.emit({text: this.task, done: false}); } this.task = ''; } diff --git a/public/docs/_examples/homepage-todo/ts/app/todo_list.ts b/public/docs/_examples/homepage-todo/ts/src/app/todo_list.ts similarity index 93% rename from public/docs/_examples/homepage-todo/ts/app/todo_list.ts rename to public/docs/_examples/homepage-todo/ts/src/app/todo_list.ts index bdeff74a27..b6495f37c2 100644 --- a/public/docs/_examples/homepage-todo/ts/app/todo_list.ts +++ b/public/docs/_examples/homepage-todo/ts/src/app/todo_list.ts @@ -1,5 +1,6 @@ // #docregion import { Component, Input } from '@angular/core'; + import { Todo } from './todo'; @Component({ @@ -18,6 +19,6 @@ import { Todo } from './todo'; ` }) -export class TodoList { +export class TodoListComponent { @Input() todos: Todo[]; } diff --git a/public/docs/_examples/homepage-todo/ts/src/index.1.html b/public/docs/_examples/homepage-todo/ts/src/index.1.html new file mode 100644 index 0000000000..4e8d034fd3 --- /dev/null +++ b/public/docs/_examples/homepage-todo/ts/src/index.1.html @@ -0,0 +1,33 @@ + + + + + Angular Todos + + + + + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/homepage-todo/ts/src/index.html b/public/docs/_examples/homepage-todo/ts/src/index.html new file mode 100644 index 0000000000..e7a656a106 --- /dev/null +++ b/public/docs/_examples/homepage-todo/ts/src/index.html @@ -0,0 +1,29 @@ + + + + + Angular Todos + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/homepage-todo/ts/src/main.ts b/public/docs/_examples/homepage-todo/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/homepage-todo/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/homepage-todo/ts/systemjs.config.1.js b/public/docs/_examples/homepage-todo/ts/systemjs.config.1.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/public/docs/_examples/karma-test-shim.js b/public/docs/_examples/karma-test-shim.js deleted file mode 100644 index ec50e1ff66..0000000000 --- a/public/docs/_examples/karma-test-shim.js +++ /dev/null @@ -1,54 +0,0 @@ -// /*global jasmine, __karma__, window*/ -Error.stackTraceLimit = Infinity; -jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; - -__karma__.loaded = function () { -}; - -function isJsFile(path) { - return path.slice(-3) == '.js'; -} - -function isSpecFile(path) { - return /\.spec\.js$/.test(path); -} - -function isBuiltFile(path) { - var builtPath = '/base/app/'; - return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath); -} - -var allSpecFiles = Object.keys(window.__karma__.files) - .filter(isSpecFile) - .filter(isBuiltFile); - -System.config({ - baseURL: '/base', - packageWithIndex: true // sadly, we can't use umd packages (yet?) -}); - -System.import('systemjs.config.js') - .then(function () { - return Promise.all([ - System.import('@angular/core/testing'), - System.import('@angular/platform-browser-dynamic/testing') - ]) - }) - .then(function (providers) { - var testing = providers[0]; - var testingBrowser = providers[1]; - - testing.setBaseTestProviders( - testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, - testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS); - - }) - .then(function() { - // Finally, load all spec files. - // This will run the tests directly. - return Promise.all( - allSpecFiles.map(function (moduleName) { - return System.import(moduleName); - })); - }) - .then(__karma__.start, __karma__.error); diff --git a/public/docs/_examples/karma.conf.js b/public/docs/_examples/karma.conf.js deleted file mode 100644 index faa52df98e..0000000000 --- a/public/docs/_examples/karma.conf.js +++ /dev/null @@ -1,88 +0,0 @@ -module.exports = function(config) { - - var appBase = 'app/'; // transpiled app JS files - var appAssets ='/base/app/'; // component assets fetched by Angular's compiler - - config.set({ - basePath: '', - frameworks: ['jasmine'], - plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-htmlfile-reporter') - ], - - customLaunchers: { - // From the CLI. Not used here but interesting - // chrome setup for travis CI using chromium - Chrome_travis_ci: { - base: 'Chrome', - flags: ['--no-sandbox'] - } - }, - files: [ - // System.js for module loading - 'node_modules/systemjs/dist/system.src.js', - - // Polyfills - 'node_modules/core-js/client/shim.js', - - // Reflect and Zone.js - 'node_modules/reflect-metadata/Reflect.js', - 'node_modules/zone.js/dist/zone.js', - 'node_modules/zone.js/dist/jasmine-patch.js', - 'node_modules/zone.js/dist/async-test.js', - 'node_modules/zone.js/dist/fake-async-test.js', - - // RxJs. - { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, - { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false }, - - // Angular 2 itself and the testing library - {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false}, - {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false}, - - {pattern: 'systemjs.config.js', included: false, watched: false}, - 'karma-test-shim.js', - - // transpiled application & spec code paths loaded via module imports - {pattern: appBase + '**/*.js', included: false, watched: true}, - - // asset (HTML & CSS) paths loaded via Angular's component compiler - // (these paths need to be rewritten, see proxies section) - {pattern: appBase + '**/*.html', included: false, watched: true}, - {pattern: appBase + '**/*.css', included: false, watched: true}, - - // paths for debugging with source maps in dev tools - {pattern: appBase + '**/*.ts', included: false, watched: false}, - {pattern: appBase + '**/*.js.map', included: false, watched: false} - ], - - // proxied base paths for loading assets - proxies: { - // required for component assets fetched by Angular's compiler - "/app/": appAssets - }, - - exclude: [], - preprocessors: {}, - reporters: ['progress', 'html'], - - // HtmlReporter configuration - htmlReporter: { - // Open this file to see results in browser - outputFile: '_test-output/tests.html', - - // Optional - pageTitle: 'Unit Tests', - subPageTitle: __dirname - }, - - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['Chrome'], - singleRun: false - }) -} diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/after_content_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/after_content_component.dart deleted file mode 100644 index 4e11dc702b..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/after_content_component.dart +++ /dev/null @@ -1,115 +0,0 @@ -// #docplaster -// #docregion -import 'package:angular2/core.dart'; - -import 'logger_service.dart'; - -////////////////// -@Component( - selector: 'my-child', - template: '') -class ChildComponent { - String hero = 'Magneta'; -} - -////////////////////// -@Component( - selector: 'after-content', -// #docregion template - template: ''' -
    -- projected content begins --
    - -
    -- projected content ends --
    -

    {{comment}}

    - ''' -// #enddocregion template - ) -// #docregion hooks -class AfterContentComponent implements AfterContentChecked, AfterContentInit { - String _prevHero = ''; - String comment = ''; - - // Query for a CONTENT child of type `ChildComponent` - @ContentChild(ChildComponent) ChildComponent contentChild; - -// #enddocregion hooks - final LoggerService _logger; - - AfterContentComponent(this._logger) { - _logIt('AfterContent constructor'); - } - -// #docregion hooks - ngAfterContentInit() { - // contentChild is set after the content has been initialized - _logIt('AfterContentInit'); - _doSomething(); - } - - ngAfterContentChecked() { - // contentChild is updated after the content has been checked - if (_prevHero == contentChild?.hero) { - _logIt('AfterContentChecked (no change)'); - } else { - _prevHero = contentChild?.hero; - _logIt('AfterContentChecked'); - _doSomething(); - } - } -// #enddocregion hooks -// #docregion do-something - /// This surrogate for real business logic; sets the `comment` - void _doSomething() { - comment = contentChild.hero.length > 10 ? "That's a long name" : ''; - } -// #enddocregion do-something - - void _logIt(String method) { - var child = contentChild; - var message = "${method}: ${child?.hero ?? 'no'} child content"; - _logger.log(message); - } -// #docregion hooks - // ... -} -// #enddocregion hooks - -////////////// -@Component( - selector: 'after-content-parent', -// #docregion parent-template - template: ''' -
    -

    AfterContent

    - -
    - - - -
    - -

    -- AfterContent Logs --

    -

    -
    {{msg}}
    -
    - ''', -// #enddocregion parent-template - styles: const ['.parent {background: burlywood}'], - providers: const [LoggerService], - directives: const [AfterContentComponent, ChildComponent]) -class AfterContentParentComponent { - final LoggerService _logger; - bool show = true; - - AfterContentParentComponent(this._logger); - - List get logs => _logger.logs; - - void reset() { - logs.clear(); - // quickly remove and reload AfterViewComponent which recreates it - show = false; - _logger.tick().then((_) { show = true; }); - } - -} diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/after_view_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/after_view_component.dart deleted file mode 100644 index 308e36d9cd..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/after_view_component.dart +++ /dev/null @@ -1,117 +0,0 @@ -// #docplaster -// #docregion -import 'package:angular2/core.dart'; - -import 'logger_service.dart'; - -////////////////// -// #docregion child-view -@Component( - selector: 'my-child', - template: '') -class ChildViewComponent { - String hero = 'Magneta'; -} -// #enddocregion child-view - -////////////////////// -@Component( - selector: 'after-view', -// #docregion template - template: ''' -
    -- child view begins --
    - -
    -- child view ends --
    -

    {{comment}}

    ''', -// #enddocregion template - directives: const [ChildViewComponent]) -// #docregion hooks -class AfterViewComponent implements AfterViewChecked, AfterViewInit { - var _prevHero = ''; - - // Query for a VIEW child of type `ChildViewComponent` - @ViewChild(ChildViewComponent) ChildViewComponent viewChild; - -// #enddocregion hooks - final LoggerService _logger; - - AfterViewComponent(this._logger) { - _logIt('AfterView constructor'); - } - -// #docregion hooks - ngAfterViewInit() { - // viewChild is set after the view has been initialized - _logIt('AfterViewInit'); - _doSomething(); - } - - ngAfterViewChecked() { - // viewChild is updated after the view has been checked - if (_prevHero == viewChild.hero) { - _logIt('AfterViewChecked (no change)'); - } else { - _prevHero = viewChild.hero; - _logIt('AfterViewChecked'); - _doSomething(); - } - } -// #enddocregion hooks - - String comment = ''; - -// #docregion do-something - // This surrogate for real business logic sets the `comment` - void _doSomething() { - var c = viewChild.hero.length > 10 ? "That's a long name" : ''; - if (c != comment) { - // Wait a tick because the component's view has already been checked - _logger.tick().then((_) { comment = c; }); - } - } -// #enddocregion do-something - - void _logIt(String method) { - var child = viewChild; - var message = "${method}: ${child != null ? child.hero:'no'} child view"; - _logger.log(message); - } -// #docregion hooks - // ... -} -// #enddocregion hooks - -////////////// -@Component( - selector: 'after-view-parent', - template: ''' -
    -

    AfterView

    - - - -

    -- AfterView Logs --

    -

    -
    {{msg}}
    -
    - ''', - styles: const ['.parent {background: burlywood}'], - providers: const [LoggerService], - directives: const [AfterViewComponent]) -class AfterViewParentComponent { - final LoggerService _logger; - bool show = true; - - AfterViewParentComponent(this._logger); - - List get logs => _logger.logs; - - void reset() { - logs.clear(); - // quickly remove and reload AfterViewComponent which recreates it - show = false; - _logger.tick().then((_) { show = true; }); - } - -} -// #enddocregion diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/app_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/app_component.dart deleted file mode 100644 index 36a2667f9e..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/app_component.dart +++ /dev/null @@ -1,24 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'after_content_component.dart'; -import 'after_view_component.dart'; -import 'counter_component.dart'; -import 'do_check_component.dart'; -import 'on_changes_component.dart'; -import 'peek_a_boo_parent_component.dart'; -import 'spy_component.dart'; - -@Component( - selector: 'my-app', - templateUrl: 'app_component.html', - directives: const [ - AfterContentParentComponent, - AfterViewParentComponent, - CounterParentComponent, - DoCheckParentComponent, - OnChangesParentComponent, - PeekABooParentComponent, - SpyParentComponent, - ]) -class AppComponent {} diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/app_component.html b/public/docs/_examples/lifecycle-hooks/dart/lib/app_component.html deleted file mode 100644 index d0692e28ac..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/app_component.html +++ /dev/null @@ -1,37 +0,0 @@ - -

    Component Lifecycle Hooks

    -Peek-a-boo: (most) lifecycle hooks
    -OnChanges
    -DoCheck
    -AfterViewInit & AfterViewChecked
    -AfterContentInit & AfterContentChecked
    -Spy: directive with OnInit & OnDestroy
    -Counter: OnChanges + Spy directive
    - - - -back to top - - - -back to top - - - -back to top - - - -back to top - - - -back to top - - - -back to top - - - -back to top diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/counter_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/counter_component.dart deleted file mode 100644 index 65ae6d00f6..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/counter_component.dart +++ /dev/null @@ -1,78 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'logger_service.dart'; -import 'spy_directive.dart'; - -@Component( - selector: 'my-counter', - template: ''' -
    - Counter = {{counter}} - -
    -- Counter Change Log --
    -
    {{chg}}
    -
    - ''', - styles: const [ - '.counter {background: LightYellow; padding: 8px; margin-top: 8px}' - ], - directives: const [Spy]) -class MyCounter implements OnChanges { - @Input() num counter; - List changeLog = []; - - ngOnChanges(Map changes) { - // Empty the changeLog whenever counter goes to zero - // hint: this is a way to respond programmatically to external value changes. - if (this.counter == 0) { - changeLog.clear(); - } - - // A change to `counter` is the only change we care about - SimpleChange chng = changes['counter']; - var cur = chng.currentValue; - var prev = chng.isFirstChange() ? "{}" : chng.previousValue; - changeLog.add('counter: currentValue = $cur, previousValue = $prev'); - } -} - -@Component( - selector: 'counter-parent', - template: ''' -
    -

    Counter Spy

    - - - - - - -

    -- Spy Lifecycle Hook Log --

    -
    {{msg}}
    -
    - ''', - styles: const ['.parent {background: gold;}'], - directives: const [MyCounter], - providers: const [LoggerService]) -class CounterParentComponent { - final LoggerService _logger; - num value; - - CounterParentComponent(this._logger) { - reset(); - } - - List get logs => _logger.logs; - - void updateCounter() { - value += 1; - _logger.tick(); - } - - void reset() { - _logger.log('-- reset --'); - value = 0; - _logger.tick(); - } -} diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/do_check_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/do_check_component.dart deleted file mode 100644 index 5483b9be8f..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/do_check_component.dart +++ /dev/null @@ -1,114 +0,0 @@ -// #docregion -import 'dart:convert'; - -import 'package:angular2/core.dart'; - -class Hero { - String name; - Hero(this.name); - Map toJson() => {'name': name}; -} - -@Component( - selector: 'do-check', - template: ''' -
    -

    {{hero.name}} can {{power}}

    - -

    -- Change Log --

    -
    {{chg}}
    -
    - ''', - styles: const [ - '.hero {background: LightYellow; padding: 8px; margin-top: 8px}', - 'p {background: Yellow; padding: 8px; margin-top: 8px}' - ]) -class DoCheckComponent implements DoCheck, OnChanges { - @Input() - Hero hero; - @Input() - String power; - - bool changeDetected = false; - List changeLog = []; - - String oldHeroName = ''; - String oldPower = ''; - int oldLogLength = 0; - int noChangeCount = 0; - - // #docregion ng-do-check - ngDoCheck() { - if (hero.name != oldHeroName) { - changeDetected = true; - changeLog.add( - 'DoCheck: Hero name changed to "${hero.name}" from "$oldHeroName"'); - oldHeroName = hero.name; - } - - if (power != oldPower) { - changeDetected = true; - changeLog.add('DoCheck: Power changed to "$power" from "$oldPower"'); - oldPower = power; - } - - if (changeDetected) { - noChangeCount = 0; - } else { - // log that hook was called when there was no relevant change. - var count = noChangeCount += 1; - var noChangeMsg = - 'DoCheck called ${count}x when no change to hero or power'; - if (count == 1) { - // add new "no change" message - changeLog.add(noChangeMsg); - } else { - // update last "no change" message - changeLog[changeLog.length - 1] = noChangeMsg; - } - } - - changeDetected = false; - } - // #enddocregion ng-do-check - - // Copied from OnChangesComponent - ngOnChanges(Map changes) { - changes.forEach((String propName, SimpleChange change) { - String cur = JSON.encode(change.currentValue); - String prev = - change.isFirstChange() ? "{}" : JSON.encode(change.previousValue); - changeLog.add('$propName: currentValue = $cur, previousValue = $prev'); - }); - } - - void reset() { - changeDetected = true; - changeLog.clear(); - } -} - -/***************************************/ - -@Component( - selector: 'do-check-parent', - templateUrl: 'on_changes_parent_component.html', - styles: const ['.parent {background: Lavender}'], - directives: const [DoCheckComponent]) -class DoCheckParentComponent { - Hero hero; - String power; - String title = 'DoCheck'; - @ViewChild(DoCheckComponent) - DoCheckComponent childView; - - DoCheckParentComponent() { - reset(); - } - - void reset() { - hero = new Hero('Windstorm'); - power = 'sing'; - childView?.reset(); - } -} diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/logger_service.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/logger_service.dart deleted file mode 100644 index cc048579e0..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/logger_service.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'dart:async'; - -import 'package:angular2/core.dart'; - -@Injectable() -class LoggerService { - List logs = []; - String _prevMsg = ''; - int _prevMsgCount = 1; - - void log(String msg) { - if (msg == _prevMsg) { - // Repeat message; update last log entry with count. - logs[logs.length - 1] = "$msg (${_prevMsgCount += 1}x)"; - } else { - // New message; log it. - _prevMsg = msg; - _prevMsgCount = 1; - logs.add(msg); - } - } - - void clear() => logs.clear(); - - // schedules a view refresh to ensure display catches up - tick() => new Future(() {}); -} diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/on_changes_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/on_changes_component.dart deleted file mode 100644 index 06b9824aaa..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/on_changes_component.dart +++ /dev/null @@ -1,70 +0,0 @@ -// #docregion -import 'dart:convert'; - -import 'package:angular2/core.dart'; - -class Hero { - String name; - Hero(this.name); - Map toJson() => {'name': name}; -} - -@Component( - selector: 'on-changes', - template: ''' -
    -

    {{hero.name}} can {{power}}

    - -

    -- Change Log --

    -
    {{chg}}
    -
    - ''', - styles: const [ - '.hero {background: LightYellow; padding: 8px; margin-top: 8px}', - 'p {background: Yellow; padding: 8px; margin-top: 8px}' - ]) -class OnChangesComponent implements OnChanges { -// #docregion inputs - @Input() Hero hero; - @Input() String power; -// #enddocregion inputs - - List changeLog = []; - - // #docregion ng-on-changes - ngOnChanges(Map changes) { - changes.forEach((String propName, SimpleChange change) { - String cur = JSON.encode(change.currentValue); - String prev = - change.isFirstChange() ? "{}" : JSON.encode(change.previousValue); - changeLog.add('$propName: currentValue = $cur, previousValue = $prev'); - }); - } - // #enddocregion ng-on-changes - - void reset() { changeLog.clear(); } -} - -@Component( - selector: 'on-changes-parent', - templateUrl: 'on_changes_parent_component.html', - styles: const ['.parent {background: Lavender}'], - directives: const [OnChangesComponent]) -class OnChangesParentComponent { - Hero hero; - String power; - String title = 'OnChanges'; - @ViewChild(OnChangesComponent) OnChangesComponent childView; - - OnChangesParentComponent() { - reset(); - } - - void reset() { - // new Hero object every time; triggers onChange - hero = new Hero('Windstorm'); - // setting power only triggers onChange if this value is different - power = 'sing'; - childView?.reset(); - } -} diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/on_changes_parent_component.html b/public/docs/_examples/lifecycle-hooks/dart/lib/on_changes_parent_component.html deleted file mode 100644 index 7889ce8e91..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/on_changes_parent_component.html +++ /dev/null @@ -1,14 +0,0 @@ -
    -

    {{title}}

    - - - - -
    Power:
    Hero.name:
    -

    - - - - - -
    diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/peek_a_boo_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/peek_a_boo_component.dart deleted file mode 100644 index 5ce146ea51..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/peek_a_boo_component.dart +++ /dev/null @@ -1,87 +0,0 @@ -// #docregion -// #docregion lc-imports -import 'package:angular2/core.dart'; - -import 'logger_service.dart'; - -int _nextId = 1; - -// #docregion ngOnInit -class PeekABoo implements OnInit { - final LoggerService _logger; - - PeekABoo(this._logger); - - // implement OnInit's `ngOnInit` method - void ngOnInit() { _logIt('OnInit'); } - - void _logIt(String msg) { - // Don't tick or else - // the AfterContentChecked and AfterViewChecked recurse. - // Let parent call tick() - _logger.log("#${_nextId++} $msg"); - } -} -// #enddocregion ngOnInit - -@Component( - selector: 'peek-a-boo', - template: '

    Now you see my hero, {{name}}

    ', - styles: const ['p {background: LightYellow; padding: 8px}']) -// Don't HAVE to mention the Lifecycle Hook interfaces -// unless we want typing and tool support. -class PeekABooComponent extends PeekABoo - implements - OnChanges, - OnInit, - DoCheck, - AfterContentInit, - AfterContentChecked, - AfterViewInit, - AfterViewChecked, - OnDestroy { - @Input() String name; - - int _afterContentCheckedCounter = 1; - int _afterViewCheckedCounter = 1; - int _onChangesCounter = 1; - String _verb = 'initialized'; - - PeekABooComponent(LoggerService logger) : super(logger) { - var _is = name != null ? 'is' : 'is not'; - _logIt('name $_is known at construction'); - } - - // Only called if there is an @input variable set by parent. - ngOnChanges(Map changes) { - List messages = []; - changes.forEach((String propName, SimpleChange change) { - if (propName == 'name') { - var name = changes['name'].currentValue; - messages.add('name $_verb to "$name"'); - } else { - messages.add('$propName $_verb'); - } - }); - _logIt('OnChanges (${_onChangesCounter++}): ${messages.join('; ')}'); - _verb = 'changed'; // Next time it will be a change - } - - // Beware! Called frequently! - // Called in every change detection cycle anywhere on the page - ngDoCheck() => _logIt('DoCheck'); - - ngAfterContentInit() => _logIt('AfterContentInit'); - - // Beware! Called frequently! - // Called in every change detection cycle anywhere on the page - ngAfterContentChecked() { _logIt('AfterContentChecked (${_afterContentCheckedCounter++})'); } - - ngAfterViewInit() => _logIt('AfterViewInit'); - - // Beware! Called frequently! - // Called in every change detection cycle anywhere on the page - ngAfterViewChecked() { _logIt('AfterViewChecked (${_afterViewCheckedCounter++})'); } - - ngOnDestroy() => _logIt('OnDestroy'); -} diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/peek_a_boo_parent_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/peek_a_boo_parent_component.dart deleted file mode 100644 index a1e4c397d9..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/peek_a_boo_parent_component.dart +++ /dev/null @@ -1,50 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'logger_service.dart'; -import 'peek_a_boo_component.dart'; - -@Component( - selector: 'peek-a-boo-parent', - template: ''' -
    -

    Peek-A-Boo

    - - - - - - - -

    -- Lifecycle Hook Log --

    -
    {{msg}}
    -
    - ''', - styles: const ['.parent {background: moccasin}'], - directives: const [PeekABooComponent], - providers: const [LoggerService]) -class PeekABooParentComponent { - final LoggerService _logger; - bool hasChild = false; - String heroName = 'Windstorm'; - - PeekABooParentComponent(this._logger); - - List get logs => _logger.logs; - - toggleChild() { - hasChild = !hasChild; - if (hasChild) { - heroName = 'Windstorm'; - _logger.clear(); // clear log on create - } - _logger.tick(); - } - - updateHero() { - heroName += '!'; - _logger.tick(); - } -} diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/spy_component.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/spy_component.dart deleted file mode 100644 index 815c8441d1..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/spy_component.dart +++ /dev/null @@ -1,40 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'logger_service.dart'; -import 'spy_directive.dart'; - -@Component( - selector: 'spy-parent', - templateUrl: 'spy_component.html', - styles: const [ - '.parent {background: khaki}', - '.heroes {background: LightYellow; padding: 0 8px}' - ], - directives: const [Spy], - providers: const [LoggerService]) -class SpyParentComponent { - final LoggerService _logger; - String newName = 'Herbie'; - List heroes = ['Windstorm', 'Magneta']; - - SpyParentComponent(this._logger); - - List get logs => _logger.logs; - - addHero() { - if (newName.trim().isNotEmpty) { - heroes.add(newName.trim()); - newName = ''; - _logger.tick(); - } - } - - // removeHero(String hero) { } is not used. - - void reset() { - _logger.log('-- reset --'); - heroes.clear(); - _logger.tick(); - } -} diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/spy_component.html b/public/docs/_examples/lifecycle-hooks/dart/lib/spy_component.html deleted file mode 100644 index 0207792703..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/spy_component.html +++ /dev/null @@ -1,16 +0,0 @@ -
    -

    Spy Directive

    - - - - - -

    - -
    - {{hero}} -
    - -

    -- Spy Lifecycle Hook Log --

    -
    {{msg}}
    -
    diff --git a/public/docs/_examples/lifecycle-hooks/dart/lib/spy_directive.dart b/public/docs/_examples/lifecycle-hooks/dart/lib/spy_directive.dart deleted file mode 100644 index 42db9f591a..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/lib/spy_directive.dart +++ /dev/null @@ -1,23 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'logger_service.dart'; - -int _nextId = 1; - -// #docregion spy-directive -// Spy on any element to which it is applied. -// Usage:
    ...
    -@Directive(selector: '[mySpy]') -class Spy implements OnInit, OnDestroy { - final LoggerService _logger; - - Spy(this._logger); - - ngOnInit() => _logIt('onInit'); - - ngOnDestroy() => _logIt('onDestroy'); - - _logIt(String msg) => _logger.log('Spy #${_nextId++} $msg'); -} -// #enddocregion spy-directive diff --git a/public/docs/_examples/lifecycle-hooks/dart/pubspec.yaml b/public/docs/_examples/lifecycle-hooks/dart/pubspec.yaml deleted file mode 100644 index a1e6f25956..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/pubspec.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# #docregion -name: lifecycle_hooks -description: Lifecycle Hooks -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: - - 'package:angular2/common.dart#CORE_DIRECTIVES' - - 'package:angular2/common.dart#FORM_DIRECTIVES' - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/lifecycle-hooks/dart/web/index.html b/public/docs/_examples/lifecycle-hooks/dart/web/index.html deleted file mode 100644 index e698da98bc..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/web/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - Angular 2 Lifecycle Hooks - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/lifecycle-hooks/dart/web/main.dart b/public/docs/_examples/lifecycle-hooks/dart/web/main.dart deleted file mode 100644 index 5013275e6a..0000000000 --- a/public/docs/_examples/lifecycle-hooks/dart/web/main.dart +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -import 'package:angular2/platform/browser.dart'; - -import 'package:lifecycle_hooks/app_component.dart'; - -main() { - bootstrap(AppComponent); -} diff --git a/public/docs/_examples/lifecycle-hooks/e2e-spec.ts b/public/docs/_examples/lifecycle-hooks/e2e-spec.ts index 763fb3e5a0..8e9acb1c76 100644 --- a/public/docs/_examples/lifecycle-hooks/e2e-spec.ts +++ b/public/docs/_examples/lifecycle-hooks/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Lifecycle hooks', function () { beforeAll(function () { @@ -11,22 +14,22 @@ describe('Lifecycle hooks', function () { it('should support peek-a-boo', function () { let pabComp = element(by.css('peek-a-boo-parent peek-a-boo')); - expect(pabComp.isPresent()).toBe(false, "should not be able to find the 'peek-a-boo' component"); + expect(pabComp.isPresent()).toBe(false, 'should not be able to find the "peek-a-boo" component'); let pabButton = element.all(by.css('peek-a-boo-parent button')).get(0); let updateHeroButton = element.all(by.css('peek-a-boo-parent button')).get(1); expect(pabButton.getText()).toContain('Create Peek'); pabButton.click().then(function () { expect(pabButton.getText()).toContain('Destroy Peek'); - expect(pabComp.isDisplayed()).toBe(true, "should be able to see the 'peek-a-boo' component"); + expect(pabComp.isDisplayed()).toBe(true, 'should be able to see the "peek-a-boo" component'); expect(pabComp.getText()).toContain('Windstorm'); expect(pabComp.getText()).not.toContain('Windstorm!'); - expect(updateHeroButton.isPresent()).toBe(true, "should be able to see the update hero button"); + expect(updateHeroButton.isPresent()).toBe(true, 'should be able to see the update hero button'); return updateHeroButton.click(); }).then(function () { expect(pabComp.getText()).toContain('Windstorm!'); return pabButton.click(); }).then(function () { - expect(pabComp.isPresent()).toBe(false, "should no longer be able to find the 'peek-a-boo' component"); + expect(pabComp.isPresent()).toBe(false, 'should no longer be able to find the "peek-a-boo" component'); }); }); @@ -39,19 +42,14 @@ describe('Lifecycle hooks', function () { let changeLogEles = onChangesViewEle.all(by.css('div')); expect(titleEle.getText()).toContain('Windstorm can sing'); - expect(changeLogEles.count()).toEqual(2, "should start with 2 messages"); - // heroNameInputEle.sendKeys('-foo-').then(function () { - sendKeys(heroNameInputEle, '-foo-').then(function () { - expect(titleEle.getText()).toContain('Windstorm-foo- can sing'); - expect(changeLogEles.count()).toEqual(2, "should still have 2 messages"); - // protractor bug with sendKeys means that line below does not work. - // return powerInputEle.sendKeys('-bar-'); - return sendKeys(powerInputEle, '-bar-'); - }).then(function () { - expect(titleEle.getText()).toContain('Windstorm-foo- can sing-bar-'); - // 7 == 2 previously + length of '-bar-' - expect(changeLogEles.count()).toEqual(7, "should have 7 messages now"); - }); + expect(changeLogEles.count()).toEqual(2, 'should start with 2 messages'); + heroNameInputEle.sendKeys('-foo-'); + expect(titleEle.getText()).toContain('Windstorm-foo- can sing'); + expect(changeLogEles.count()).toEqual(2, 'should still have 2 messages'); + powerInputEle.sendKeys('-bar-'); + expect(titleEle.getText()).toContain('Windstorm-foo- can sing-bar-'); + // 7 == 2 previously + length of '-bar-' + expect(changeLogEles.count()).toEqual(7, 'should have 7 messages now'); }); it('should support DoCheck hook', function () { @@ -64,25 +62,22 @@ describe('Lifecycle hooks', function () { let logCount: number; expect(titleEle.getText()).toContain('Windstorm can sing'); - changeLogEles.count().then(function(count) { - // Empirically 5 messages to start - expect(count).toBeGreaterThan(4, "should start with some messages"); + changeLogEles.count().then(function(count: number) { + // 3 messages to start + expect(count).toEqual(3, 'should start with 3 messages'); logCount = count; - // heroNameInputEle.sendKeys('-foo-').then(function () { - return sendKeys(heroNameInputEle, '-foo-') + return heroNameInputEle.sendKeys('-foo-'); }).then(function () { expect(titleEle.getText()).toContain('Windstorm-foo- can sing'); - return changeLogEles.count() - }).then(function (count) { - // two more for each keystroke except the 1st - expect(count).toEqual(logCount + 9, 'should add 9 more messages') + return changeLogEles.count(); + }).then(function(count: number) { + // one more for each keystroke + expect(count).toEqual(logCount + 5, 'should add 5 more messages'); logCount = count; - // return powerInputEle.sendKeys('-bar-'); - return sendKeys(powerInputEle, '-bar-'); + return powerInputEle.sendKeys('-bar-'); }).then(function () { expect(titleEle.getText()).toContain('Windstorm-foo- can sing-bar-'); - // 7 == 2 previously + length of '-bar-' - expect(changeLogEles.count()).toEqual(logCount + 15, 'should add 15 more messages'); + expect(changeLogEles.count()).toEqual(logCount + 6, 'should add 6 more messages'); }); }); @@ -91,26 +86,26 @@ describe('Lifecycle hooks', function () { let buttonEle = parentEle.element(by.tagName('button')); // Reset let commentEle = parentEle.element(by.className('comment')); let logEles = parentEle.all(by.css('h4 ~ div')); - let childViewInputEle = parentEle.element(by.css('my-child input')); + let childViewInputEle = parentEle.element(by.css('my-child-view input')); let logCount: number; expect(childViewInputEle.getAttribute('value')).toContain('Magneta'); expect(commentEle.isPresent()).toBe(false, 'comment should not be in DOM'); - logEles.count().then(function(count) { + logEles.count().then(function(count: number) { logCount = count; - return sendKeys(childViewInputEle, "-test-"); + return childViewInputEle.sendKeys('-test-'); }).then(function() { expect(childViewInputEle.getAttribute('value')).toContain('-test-'); - expect(commentEle.isPresent()).toBe(true,'should have comment because >10 chars'); + expect(commentEle.isPresent()).toBe(true, 'should have comment because >10 chars'); expect(commentEle.getText()).toContain('long name'); return logEles.count(); - }).then(function(count) { - expect(logCount + 10).toEqual(count, "10 additional log messages should have been added"); + }).then(function(count: number) { + expect(logCount + 7).toEqual(count, '7 additional log messages should have been added'); logCount = count; return buttonEle.click(); }).then(function() { - expect(logEles.count()).toBeLessThan(logCount, "log should shrink after reset"); + expect(logEles.count()).toBeLessThan(logCount, 'log should shrink after reset'); }); }); @@ -126,32 +121,32 @@ describe('Lifecycle hooks', function () { expect(childViewInputEle.getAttribute('value')).toContain('Magneta'); expect(commentEle.isPresent()).toBe(false, 'comment should not be in DOM'); - logEles.count().then(function(count) { + logEles.count().then(function(count: number) { logCount = count; - return sendKeys(childViewInputEle, "-test-"); + return childViewInputEle.sendKeys('-test-'); }).then(function() { expect(childViewInputEle.getAttribute('value')).toContain('-test-'); - expect(commentEle.isPresent()).toBe(true,'should have comment because >10 chars'); + expect(commentEle.isPresent()).toBe(true, 'should have comment because >10 chars'); expect(commentEle.getText()).toContain('long name'); return logEles.count(); - }).then(function(count) { - expect(logCount + 10).toEqual(count, "10 additional log messages should have been added"); + }).then(function(count: number) { + expect(logCount + 5).toEqual(count, '5 additional log messages should have been added'); logCount = count; return buttonEle.click(); }).then(function() { - expect(logEles.count()).toBeLessThan(logCount, "log should shrink after reset"); + expect(logEles.count()).toBeLessThan(logCount, 'log should shrink after reset'); }); }); it('should support spy\'s OnInit & OnDestroy hooks', function () { let inputEle = element(by.css('spy-parent input')); - let addHeroButtonEle = element(by.cssContainingText('spy-parent button','Add Hero')); - let resetHeroesButtonEle = element(by.cssContainingText('spy-parent button','Reset Heroes')); + let addHeroButtonEle = element(by.cssContainingText('spy-parent button', 'Add Hero')); + let resetHeroesButtonEle = element(by.cssContainingText('spy-parent button', 'Reset Heroes')); let heroEles = element.all(by.css('spy-parent div[mySpy')); let logEles = element.all(by.css('spy-parent h4 ~ div')); expect(heroEles.count()).toBe(2, 'should have two heroes displayed'); expect(logEles.count()).toBe(2, 'should have two log entries'); - sendKeys(inputEle, "-test-").then(function() { + inputEle.sendKeys('-test-').then(function() { return addHeroButtonEle.click(); }).then(function() { expect(heroEles.count()).toBe(3, 'should have added one hero'); @@ -161,12 +156,12 @@ describe('Lifecycle hooks', function () { }).then(function() { expect(heroEles.count()).toBe(0, 'should no longer have any heroes'); expect(logEles.count()).toBe(7, 'should now have 7 log entries - 3 orig + 1 reset + 3 removeall'); - }) + }); }); it('should support "spy counter"', function () { - let updateCounterButtonEle = element(by.cssContainingText('counter-parent button','Update')); - let resetCounterButtonEle = element(by.cssContainingText('counter-parent button','Reset')); + let updateCounterButtonEle = element(by.cssContainingText('counter-parent button', 'Update')); + let resetCounterButtonEle = element(by.cssContainingText('counter-parent button', 'Reset')); let textEle = element(by.css('counter-parent my-counter > div')); let logEles = element.all(by.css('counter-parent h4 ~ div')); expect(textEle.getText()).toContain('Counter = 0'); @@ -178,8 +173,6 @@ describe('Lifecycle hooks', function () { }).then(function() { expect(textEle.getText()).toContain('Counter = 0'); expect(logEles.count()).toBe(7, 'should now have 7 log entries - 3 prev + 1 reset + 2 destroy + 1 init'); - }) + }); }); - - }); diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/app.component.ts b/public/docs/_examples/lifecycle-hooks/ts/app/app.component.ts deleted file mode 100644 index b3d5e45b76..0000000000 --- a/public/docs/_examples/lifecycle-hooks/ts/app/app.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { AfterContentParentComponent } from './after-content.component'; -import { AfterViewParentComponent } from './after-view.component'; -import { CounterParentComponent } from './counter.component'; -import { DoCheckParentComponent } from './do-check.component'; -import { OnChangesParentComponent } from './on-changes.component'; -import { PeekABooParentComponent } from './peek-a-boo-parent.component'; -import { SpyParentComponent } from './spy.component'; - -@Component({ - selector: 'my-app', - templateUrl: 'app/app.component.html', - directives: [ - AfterContentParentComponent, - AfterViewParentComponent, - CounterParentComponent, - DoCheckParentComponent, - OnChangesParentComponent, - PeekABooParentComponent, - SpyParentComponent, - ] -}) -export class AppComponent { -} diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/main.ts b/public/docs/_examples/lifecycle-hooks/ts/app/main.ts deleted file mode 100644 index 1e9be2601e..0000000000 --- a/public/docs/_examples/lifecycle-hooks/ts/app/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent).catch(err => console.error(err)); diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/on-changes-parent.component.html b/public/docs/_examples/lifecycle-hooks/ts/app/on-changes-parent.component.html deleted file mode 100644 index 7889ce8e91..0000000000 --- a/public/docs/_examples/lifecycle-hooks/ts/app/on-changes-parent.component.html +++ /dev/null @@ -1,14 +0,0 @@ -
    -

    {{title}}

    - - - - -
    Power:
    Hero.name:
    -

    - - - - - -
    diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/spy.directive.ts b/public/docs/_examples/lifecycle-hooks/ts/app/spy.directive.ts deleted file mode 100644 index ba7582ea50..0000000000 --- a/public/docs/_examples/lifecycle-hooks/ts/app/spy.directive.ts +++ /dev/null @@ -1,24 +0,0 @@ -// #docregion -import {Directive, OnInit, OnDestroy} from '@angular/core'; - -import {LoggerService} from './logger.service'; - -let nextId = 1; - -// #docregion spy-directive -// Spy on any element to which it is applied. -// Usage:
    ...
    -@Directive({selector: '[mySpy]'}) -export class Spy implements OnInit, OnDestroy { - - constructor(private logger: LoggerService) { } - - ngOnInit() { this.logIt(`onInit`); } - - ngOnDestroy() { this.logIt(`onDestroy`); } - - private logIt(msg: string) { - this.logger.log(`Spy #${nextId++} ${msg}`); - } -} -// #enddocregion spy-directive diff --git a/public/docs/_examples/lifecycle-hooks/ts/index.html b/public/docs/_examples/lifecycle-hooks/ts/index.html deleted file mode 100644 index 6fa866c6e6..0000000000 --- a/public/docs/_examples/lifecycle-hooks/ts/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Angular 2 Lifecycle Hooks - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/lifecycle-hooks/ts/plnkr.json b/public/docs/_examples/lifecycle-hooks/ts/plnkr.json index 21c8aaad89..49290aa804 100644 --- a/public/docs/_examples/lifecycle-hooks/ts/plnkr.json +++ b/public/docs/_examples/lifecycle-hooks/ts/plnkr.json @@ -1,8 +1,9 @@ { "description": "Lifecycle Hooks", + "basePath": "src/", "files":["!**/*.d.ts", "!**/*.js"], "tags": ["lifecycle", "hooks", "OnInit", "OnDestroy", "OnChange", "DoCheck", "AfterContentInit", "AfterContentChecked", "AfterViewInit", "AfterViewChecked"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/lifecycle-hooks/ts/sample.css b/public/docs/_examples/lifecycle-hooks/ts/sample.css deleted file mode 100644 index df17c897c6..0000000000 --- a/public/docs/_examples/lifecycle-hooks/ts/sample.css +++ /dev/null @@ -1,13 +0,0 @@ -.parent { - color: #666; - margin: 14px 0; - padding: 8px; -} -input { - margin: 4px; - padding: 4px; -} -.comment { - color: red; - font-style: italic; -} diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/after-content.component.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/after-content.component.ts similarity index 92% rename from public/docs/_examples/lifecycle-hooks/ts/app/after-content.component.ts rename to public/docs/_examples/lifecycle-hooks/ts/src/app/after-content.component.ts index 6d970f8aa0..dfd2b80d24 100644 --- a/public/docs/_examples/lifecycle-hooks/ts/app/after-content.component.ts +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/after-content.component.ts @@ -2,7 +2,7 @@ // #docregion import { AfterContentChecked, AfterContentInit, Component, ContentChild } from '@angular/core'; -import {LoggerService} from './logger.service'; +import { LoggerService } from './logger.service'; ////////////////// @Component({ @@ -63,7 +63,7 @@ export class AfterContentComponent implements AfterContentChecked, AfterContentI // This surrogate for real business logic sets the `comment` private doSomething() { - this.comment = this.contentChild.hero.length > 10 ? 'That\'s a long name' : ''; + this.comment = this.contentChild.hero.length > 10 ? `That's a long name` : ''; } private logIt(method: string) { @@ -97,8 +97,7 @@ export class AfterContentComponent implements AfterContentChecked, AfterContentI
    `, styles: ['.parent {background: burlywood}'], - providers: [LoggerService], - directives: [AfterContentComponent, ChildComponent] + providers: [LoggerService] }) export class AfterContentParentComponent { logs: string[]; diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/after-view.component.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/after-view.component.ts similarity index 84% rename from public/docs/_examples/lifecycle-hooks/ts/app/after-view.component.ts rename to public/docs/_examples/lifecycle-hooks/ts/src/app/after-view.component.ts index 800a43fcc3..71310e4530 100644 --- a/public/docs/_examples/lifecycle-hooks/ts/app/after-view.component.ts +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/after-view.component.ts @@ -2,12 +2,12 @@ // #docregion import { AfterViewChecked, AfterViewInit, Component, ViewChild } from '@angular/core'; -import {LoggerService} from './logger.service'; +import { LoggerService } from './logger.service'; ////////////////// // #docregion child-view @Component({ - selector: 'my-child', + selector: 'my-child-view', template: '' }) export class ChildViewComponent { @@ -21,15 +21,14 @@ export class ChildViewComponent { // #docregion template template: `
    -- child view begins --
    - +
    -- child view ends --
    ` // #enddocregion template + `

    {{comment}}

    - `, - directives: [ChildViewComponent] + ` }) // #docregion hooks export class AfterViewComponent implements AfterViewChecked, AfterViewInit { @@ -39,7 +38,7 @@ export class AfterViewComponent implements AfterViewChecked, AfterViewInit { @ViewChild(ChildViewComponent) viewChild: ChildViewComponent; // #enddocregion hooks - constructor(private logger:LoggerService){ + constructor(private logger: LoggerService) { this.logIt('AfterView constructor'); } @@ -67,7 +66,7 @@ export class AfterViewComponent implements AfterViewChecked, AfterViewInit { // #docregion do-something // This surrogate for real business logic sets the `comment` private doSomething() { - let c = this.viewChild.hero.length > 10 ? "That's a long name" : ''; + let c = this.viewChild.hero.length > 10 ? `That's a long name` : ''; if (c !== this.comment) { // Wait a tick because the component's view has already been checked this.logger.tick_then(() => this.comment = c); @@ -75,9 +74,9 @@ export class AfterViewComponent implements AfterViewChecked, AfterViewInit { } // #enddocregion do-something - private logIt(method:string){ + private logIt(method: string) { let child = this.viewChild; - let message = `${method}: ${child ? child.hero:'no'} child view` + let message = `${method}: ${child ? child.hero : 'no'} child view`; this.logger.log(message); } // #docregion hooks @@ -100,11 +99,10 @@ export class AfterViewComponent implements AfterViewChecked, AfterViewInit {
    `, styles: ['.parent {background: burlywood}'], - providers:[LoggerService], - directives: [AfterViewComponent] + providers: [LoggerService] }) export class AfterViewParentComponent { - logs:string[]; + logs: string[]; show = true; constructor(private logger: LoggerService) { @@ -112,7 +110,7 @@ export class AfterViewParentComponent { } reset() { - this.logs.length=0; + this.logs.length = 0; // quickly remove and reload AfterViewComponent which recreates it this.show = false; this.logger.tick_then(() => this.show = true); diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/app.component.html b/public/docs/_examples/lifecycle-hooks/ts/src/app/app.component.html similarity index 100% rename from public/docs/_examples/lifecycle-hooks/ts/app/app.component.html rename to public/docs/_examples/lifecycle-hooks/ts/src/app/app.component.html diff --git a/public/docs/_examples/lifecycle-hooks/ts/src/app/app.component.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/app.component.ts new file mode 100644 index 0000000000..5bd535a113 --- /dev/null +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/app.component.ts @@ -0,0 +1,7 @@ +// #docregion +import { Component } from '@angular/core'; +@Component({ + selector: 'my-app', + templateUrl: './app.component.html' +}) +export class AppComponent { } diff --git a/public/docs/_examples/lifecycle-hooks/ts/src/app/app.module.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/app.module.ts new file mode 100644 index 0000000000..4d9cabf218 --- /dev/null +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/app.module.ts @@ -0,0 +1,67 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; + +import { + AfterContentParentComponent, + AfterContentComponent, + ChildComponent +} from './after-content.component'; + +import { + AfterViewParentComponent, + AfterViewComponent, + ChildViewComponent +} from './after-view.component'; + +import { + CounterParentComponent, + MyCounterComponent +} from './counter.component'; + +import { + DoCheckParentComponent, + DoCheckComponent +} from './do-check.component'; + +import { + OnChangesParentComponent, + OnChangesComponent +} from './on-changes.component'; + +import { PeekABooParentComponent } from './peek-a-boo-parent.component'; +import { PeekABooComponent } from './peek-a-boo.component'; + +import { SpyParentComponent } from './spy.component'; +import { SpyDirective } from './spy.directive'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule + ], + declarations: [ + AppComponent, + AfterContentParentComponent, + AfterContentComponent, + ChildComponent, + AfterViewParentComponent, + AfterViewComponent, + ChildViewComponent, + CounterParentComponent, + MyCounterComponent, + DoCheckParentComponent, + DoCheckComponent, + OnChangesParentComponent, + OnChangesComponent, + PeekABooParentComponent, + PeekABooComponent, + SpyParentComponent, + SpyDirective + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/counter.component.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/counter.component.ts similarity index 88% rename from public/docs/_examples/lifecycle-hooks/ts/app/counter.component.ts rename to public/docs/_examples/lifecycle-hooks/ts/src/app/counter.component.ts index 5abf4c6656..8efd1fbd52 100644 --- a/public/docs/_examples/lifecycle-hooks/ts/app/counter.component.ts +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/counter.component.ts @@ -1,10 +1,9 @@ // #docregion import { Component, Input, - OnChanges, SimpleChange, + OnChanges, SimpleChanges, } from '@angular/core'; -import { Spy } from './spy.directive'; import { LoggerService } from './logger.service'; @Component({ @@ -17,14 +16,13 @@ import { LoggerService } from './logger.service';
    {{chg}}
    `, - styles: ['.counter {background: LightYellow; padding: 8px; margin-top: 8px}'], - directives: [Spy] + styles: ['.counter {background: LightYellow; padding: 8px; margin-top: 8px}'] }) -export class MyCounter implements OnChanges { +export class MyCounterComponent implements OnChanges { @Input() counter: number; changeLog: string[] = []; - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { + ngOnChanges(changes: SimpleChanges) { // Empty the changeLog whenever counter goes to zero // hint: this is a way to respond programmatically to external value changes. @@ -38,7 +36,6 @@ export class MyCounter implements OnChanges { let prev = JSON.stringify(chng.previousValue); // first time is {}; after is integer this.changeLog.push(`counter: currentValue = ${cur}, previousValue = ${prev}`); } - } /***************************************/ @@ -59,7 +56,6 @@ export class MyCounter implements OnChanges {
    `, styles: ['.parent {background: gold;}'], - directives: [MyCounter], providers: [LoggerService] }) export class CounterParentComponent { diff --git a/public/docs/_examples/lifecycle-hooks/ts/src/app/do-check-parent.component.html b/public/docs/_examples/lifecycle-hooks/ts/src/app/do-check-parent.component.html new file mode 100644 index 0000000000..cf7c2b91ce --- /dev/null +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/do-check-parent.component.html @@ -0,0 +1,13 @@ +
    +

    {{title}}

    + + + + +
    Power:
    Hero.name:
    +

    + + + + +
    diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/do-check.component.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/do-check.component.ts similarity index 76% rename from public/docs/_examples/lifecycle-hooks/ts/app/do-check.component.ts rename to public/docs/_examples/lifecycle-hooks/ts/src/app/do-check.component.ts index 64b998c25a..6196dd8edd 100644 --- a/public/docs/_examples/lifecycle-hooks/ts/app/do-check.component.ts +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/do-check.component.ts @@ -1,6 +1,6 @@ /* tslint:disable:forin */ // #docregion -import { Component, DoCheck, Input, OnChanges, SimpleChange, ViewChild } from '@angular/core'; +import { Component, DoCheck, Input, ViewChild } from '@angular/core'; class Hero { constructor(public name: string) {} @@ -21,7 +21,7 @@ class Hero { 'p {background: Yellow; padding: 8px; margin-top: 8px}' ] }) -export class DoCheckComponent implements DoCheck, OnChanges { +export class DoCheckComponent implements DoCheck { @Input() hero: Hero; @Input() power: string; @@ -66,16 +66,6 @@ export class DoCheckComponent implements DoCheck, OnChanges { } // #enddocregion ng-do-check - // Copied from OnChangesComponent - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { - for (let propName in changes) { - let chng = changes[propName]; - let cur = JSON.stringify(chng.currentValue); - let prev = JSON.stringify(chng.previousValue); - this.changeLog.push(`OnChanges: ${propName}: currentValue = ${cur}, previousValue = ${prev}`); - } - } - reset() { this.changeDetected = true; this.changeLog.length = 0; @@ -86,9 +76,8 @@ export class DoCheckComponent implements DoCheck, OnChanges { @Component({ selector: 'do-check-parent', - templateUrl: 'app/on-changes-parent.component.html', - styles: ['.parent {background: Lavender}'], - directives: [DoCheckComponent] + templateUrl: './do-check-parent.component.html', + styles: ['.parent {background: Lavender}'] }) export class DoCheckParentComponent { hero: Hero; diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/logger.service.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/logger.service.ts similarity index 100% rename from public/docs/_examples/lifecycle-hooks/ts/app/logger.service.ts rename to public/docs/_examples/lifecycle-hooks/ts/src/app/logger.service.ts diff --git a/public/docs/_examples/lifecycle-hooks/ts/src/app/on-changes-parent.component.html b/public/docs/_examples/lifecycle-hooks/ts/src/app/on-changes-parent.component.html new file mode 100644 index 0000000000..a0fd404931 --- /dev/null +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/on-changes-parent.component.html @@ -0,0 +1,13 @@ +
    +

    {{title}}

    + + + + +
    Power:
    Hero.name:
    +

    + + + + +
    diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/on-changes.component.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/on-changes.component.ts similarity index 87% rename from public/docs/_examples/lifecycle-hooks/ts/app/on-changes.component.ts rename to public/docs/_examples/lifecycle-hooks/ts/src/app/on-changes.component.ts index 81de85633a..a5a49a61e9 100644 --- a/public/docs/_examples/lifecycle-hooks/ts/app/on-changes.component.ts +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/on-changes.component.ts @@ -2,10 +2,9 @@ // #docregion import { Component, Input, OnChanges, - SimpleChange, ViewChild + SimpleChanges, ViewChild } from '@angular/core'; - class Hero { constructor(public name: string) {} } @@ -34,7 +33,7 @@ export class OnChangesComponent implements OnChanges { changeLog: string[] = []; // #docregion ng-on-changes - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { + ngOnChanges(changes: SimpleChanges) { for (let propName in changes) { let chng = changes[propName]; let cur = JSON.stringify(chng.currentValue); @@ -51,9 +50,8 @@ export class OnChangesComponent implements OnChanges { @Component({ selector: 'on-changes-parent', - templateUrl: 'app/on-changes-parent.component.html', - styles: ['.parent {background: Lavender;}'], - directives: [OnChangesComponent] + templateUrl: './on-changes-parent.component.html', + styles: ['.parent {background: Lavender;}'] }) export class OnChangesParentComponent { hero: Hero; diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/peek-a-boo-parent.component.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/peek-a-boo-parent.component.ts similarity index 90% rename from public/docs/_examples/lifecycle-hooks/ts/app/peek-a-boo-parent.component.ts rename to public/docs/_examples/lifecycle-hooks/ts/src/app/peek-a-boo-parent.component.ts index e218dc3fc5..3f2bd8585d 100644 --- a/public/docs/_examples/lifecycle-hooks/ts/app/peek-a-boo-parent.component.ts +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/peek-a-boo-parent.component.ts @@ -1,7 +1,6 @@ // #docregion import { Component } from '@angular/core'; -import { PeekABooComponent } from './peek-a-boo.component'; import { LoggerService } from './logger.service'; @Component({ @@ -23,8 +22,7 @@ import { LoggerService } from './logger.service'; `, styles: ['.parent {background: moccasin}'], - directives: [PeekABooComponent], - providers: [LoggerService] + providers: [ LoggerService ] }) export class PeekABooParentComponent { diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/peek-a-boo.component.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/peek-a-boo.component.ts similarity index 91% rename from public/docs/_examples/lifecycle-hooks/ts/app/peek-a-boo.component.ts rename to public/docs/_examples/lifecycle-hooks/ts/src/app/peek-a-boo.component.ts index 1485f2992a..dcee428753 100644 --- a/public/docs/_examples/lifecycle-hooks/ts/app/peek-a-boo.component.ts +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/peek-a-boo.component.ts @@ -7,10 +7,10 @@ import { OnChanges, OnDestroy, OnInit, - SimpleChange + SimpleChanges } from '@angular/core'; -import {Component, Input} from '@angular/core'; -import {LoggerService} from './logger.service'; +import { Component, Input } from '@angular/core'; +import { LoggerService } from './logger.service'; let nextId = 1; @@ -21,7 +21,7 @@ export class PeekABoo implements OnInit { // implement OnInit's `ngOnInit` method ngOnInit() { this.logIt(`OnInit`); } - protected logIt(msg: string) { + logIt(msg: string) { this.logger.log(`#${nextId++} ${msg}`); } } @@ -51,7 +51,7 @@ export class PeekABooComponent extends PeekABoo implements } // only called for/if there is an @input variable set by parent. - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { + ngOnChanges(changes: SimpleChanges) { let changesMsgs: string[] = []; for (let propName in changes) { if (propName === 'name') { diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/spy.component.html b/public/docs/_examples/lifecycle-hooks/ts/src/app/spy.component.html similarity index 100% rename from public/docs/_examples/lifecycle-hooks/ts/app/spy.component.html rename to public/docs/_examples/lifecycle-hooks/ts/src/app/spy.component.html diff --git a/public/docs/_examples/lifecycle-hooks/ts/app/spy.component.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/spy.component.ts similarity index 89% rename from public/docs/_examples/lifecycle-hooks/ts/app/spy.component.ts rename to public/docs/_examples/lifecycle-hooks/ts/src/app/spy.component.ts index 9711fd31bb..0f3b0d35f1 100644 --- a/public/docs/_examples/lifecycle-hooks/ts/app/spy.component.ts +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/spy.component.ts @@ -2,16 +2,14 @@ import { Component } from '@angular/core'; import { LoggerService } from './logger.service'; -import { Spy } from './spy.directive'; @Component({ selector: 'spy-parent', - templateUrl: 'app/spy.component.html', + templateUrl: './spy.component.html', styles: [ '.parent {background: khaki;}', '.heroes {background: LightYellow; padding: 0 8px}' ], - directives: [Spy], providers: [LoggerService] }) export class SpyParentComponent { diff --git a/public/docs/_examples/lifecycle-hooks/ts/src/app/spy.directive.ts b/public/docs/_examples/lifecycle-hooks/ts/src/app/spy.directive.ts new file mode 100644 index 0000000000..01f3f95880 --- /dev/null +++ b/public/docs/_examples/lifecycle-hooks/ts/src/app/spy.directive.ts @@ -0,0 +1,24 @@ +// #docregion +import { Directive, OnInit, OnDestroy } from '@angular/core'; + +import { LoggerService } from './logger.service'; + +let nextId = 1; + +// #docregion spy-directive +// Spy on any element to which it is applied. +// Usage:
    ...
    +@Directive({selector: '[mySpy]'}) +export class SpyDirective implements OnInit, OnDestroy { + + constructor(private logger: LoggerService) { } + + ngOnInit() { this.logIt(`onInit`); } + + ngOnDestroy() { this.logIt(`onDestroy`); } + + private logIt(msg: string) { + this.logger.log(`Spy #${nextId++} ${msg}`); + } +} +// #enddocregion spy-directive diff --git a/public/docs/_examples/lifecycle-hooks/ts/src/index.html b/public/docs/_examples/lifecycle-hooks/ts/src/index.html new file mode 100644 index 0000000000..cf7059f780 --- /dev/null +++ b/public/docs/_examples/lifecycle-hooks/ts/src/index.html @@ -0,0 +1,28 @@ + + + + + Angular Lifecycle Hooks + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/lifecycle-hooks/ts/src/main.ts b/public/docs/_examples/lifecycle-hooks/ts/src/main.ts new file mode 100644 index 0000000000..f22933ba8e --- /dev/null +++ b/public/docs/_examples/lifecycle-hooks/ts/src/main.ts @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/lifecycle-hooks/dart/web/sample.css b/public/docs/_examples/lifecycle-hooks/ts/src/sample.css similarity index 100% rename from public/docs/_examples/lifecycle-hooks/dart/web/sample.css rename to public/docs/_examples/lifecycle-hooks/ts/src/sample.css diff --git a/public/docs/_examples/forms/dart/example-config.json b/public/docs/_examples/ngcontainer/ts/example-config.json similarity index 100% rename from public/docs/_examples/forms/dart/example-config.json rename to public/docs/_examples/ngcontainer/ts/example-config.json diff --git a/public/docs/_examples/ngcontainer/ts/plnkr.json b/public/docs/_examples/ngcontainer/ts/plnkr.json new file mode 100644 index 0000000000..a6cdc4ba1a --- /dev/null +++ b/public/docs/_examples/ngcontainer/ts/plnkr.json @@ -0,0 +1,11 @@ +{ + "description": "", + "basePath": "src/", + "files": [ + "!**/*.d.ts", + "!**/*.js" + ], + "tags": [ + "ngcontainer", "structural", "directives" + ] +} diff --git a/public/docs/_examples/ngcontainer/ts/src/app/app.component.css b/public/docs/_examples/ngcontainer/ts/src/app/app.component.css new file mode 100644 index 0000000000..953ed3c39d --- /dev/null +++ b/public/docs/_examples/ngcontainer/ts/src/app/app.component.css @@ -0,0 +1,34 @@ +/* #docregion */ +button { + min-width: 100px; + font-size: 100%; +} + +code, .code { + background-color: #eee; + color: black; + font-family: Courier, sans-serif; + font-size: 85%; +} + +div.code { + width: 400px; +} + +.heroic { + font-size: 150%; + font-weight: bold; +} + +hr { + margin: 40px 0 +} + +td, th { + text-align: left; + vertical-align: top; +} + +/* #docregion p-span */ +p span { color: red; font-size: 70%; } +/* #enddocregion p-span */ diff --git a/public/docs/_examples/ngcontainer/ts/src/app/app.component.html b/public/docs/_examples/ngcontainer/ts/src/app/app.component.html new file mode 100644 index 0000000000..afd0b00f36 --- /dev/null +++ b/public/docs/_examples/ngcontainer/ts/src/app/app.component.html @@ -0,0 +1,279 @@ + + +

    <ng-container>

    + + +
    {{hero.name}}
    + + +
    + +

    <ng-container> and CSS

    +

    Examples demonstrating issues with rigid CSS styles.

    + + + +

    #1 <ng-container> and <p>

    + +

    + I turned the corner + + and saw {{hero.name}}. I waved + + and continued on my way. +

    + + +

    + I turned the corner + + and saw {{hero.name}}. I waved + + and continued on my way. +

    + + +

    #2 <ng-container> and <p>

    + +
    + +

    + {{hero.name}} is + + , + and + {{trait}} + . +

    + + + +

    + {{hero.name}} is + + , + and + {{trait}} + . +

    + + +
    + +

    #3 <ng-container> and <p>

    + +

    + +

    + + +
    + The hero.id in the <span> + is caught by the p-span CSS: + +

    + + Id: ({{hero.id}}) + + Name: {{hero.name}} +

    + +
    + +
    + The hero.id in the <ng-container> + is unaffected by the p-span CSS: +

    + + Id: ({{hero.id}}) + + Name: {{hero.name}} +

    +
    + +
    + The hero.id in the <template *ngIf> disappears: +

    + + Name: {{hero.name}} +

    +
    + +
    + The hero.id in the <template [ngIf]> + is unaffected by the p-span CSS: +

    + + Name: {{hero.name}} +

    +
    + +
    + +
    + +

    <ng-container> and layout-sensitive elements

    +

    + Examples demonstrating issues with layout-sensitive elements + such as <select> and <table>. +

    + +

    #1 <ng-container> and <options>

    + +

    <select> with <span>

    +
    + Pick your favorite hero + () +
    + + + + +

    <select> with <ng-container>

    +
    + Pick your favorite hero + () +
    + + + + +



    + +

    #2 <ng-container> and <options>

    +

    + +

    + +

    Options with <ng-container>

    + + + + +

    Options with <span>

    + + + + +
    + +

    <ng-container> and <table>

    +

    + + + +

    + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectiveTypeDescription
    NgClassAAdd or remove multiple CSS classes.
    xxxSdiv with *ngIf formats crazy.
    yyySdiv with *ngIf formats crazy.
    NgForSRepeat the template for each item in a list.
    NgIfSAdd or remove DOM elements.
    NgStyleAAdd or remove multiple style attributes.
    NgSwitchSInclude in DOM if case matches the switch value.
    + +
    + +

    Do not confuse <ng-container> with <ng-content>

    + +

    <ng-container>Inside ng-container</ng-container>

    + +Inside ng-container + + +

    <ng-content>this is an Angular parse error</ng-content>

    + + + +
    Template parse errors:
    +<ng-content> element cannot have content.
    + +

    Demo of </ng-content>

    + + + Projected content + + diff --git a/public/docs/_examples/ngcontainer/ts/src/app/app.component.ts b/public/docs/_examples/ngcontainer/ts/src/app/app.component.ts new file mode 100644 index 0000000000..65c511acd2 --- /dev/null +++ b/public/docs/_examples/ngcontainer/ts/src/app/app.component.ts @@ -0,0 +1,24 @@ +// #docregion +import { Component } from '@angular/core'; + +import { heroes } from './hero'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html', + styleUrls: [ './app.component.css' ] +}) +export class AppComponent { + heroes = heroes; + hero = this.heroes[0]; + heroTraits = [ 'honest', 'brave', 'considerate' ]; + + // flags for the table + attrDirs = true; + strucDirs = true; + divNgIf = false; + + showId = true; + showDefaultTraits = true; + showSad = true; +} diff --git a/public/docs/_examples/ngcontainer/ts/src/app/app.module.ts b/public/docs/_examples/ngcontainer/ts/src/app/app.module.ts new file mode 100644 index 0000000000..57ac92f518 --- /dev/null +++ b/public/docs/_examples/ngcontainer/ts/src/app/app.module.ts @@ -0,0 +1,19 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { ContentComponent } from './content.component'; +import { heroComponents } from './hero.components'; + +@NgModule({ + imports: [ BrowserModule, FormsModule ], + declarations: [ + AppComponent, + ContentComponent, + heroComponents + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/ngcontainer/ts/src/app/content.component.ts b/public/docs/_examples/ngcontainer/ts/src/app/content.component.ts new file mode 100644 index 0000000000..63c5646f99 --- /dev/null +++ b/public/docs/_examples/ngcontainer/ts/src/app/content.component.ts @@ -0,0 +1,16 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'content-comp', + // #docregion template + template: + `
    + +
    `, + // #enddocregion template + styles: [ ` + div { border: medium dashed green; padding: 1em; width: 150px; text-align: center} + `] +}) +export class ContentComponent { } diff --git a/public/docs/_examples/ngcontainer/ts/src/app/hero.components.ts b/public/docs/_examples/ngcontainer/ts/src/app/hero.components.ts new file mode 100644 index 0000000000..43e400ed8e --- /dev/null +++ b/public/docs/_examples/ngcontainer/ts/src/app/hero.components.ts @@ -0,0 +1,43 @@ +// #docregion +import { Component, Input } from '@angular/core'; +import { Hero } from './hero'; + +@Component({ + selector: 'happy-hero', + template: `Wow. You like {{hero.name}}. What a happy hero ... just like you.` +}) +export class HappyHeroComponent { + @Input() hero: Hero; +} + +@Component({ + selector: 'sad-hero', + template: `You like {{hero.name}}? Such a sad hero. Are you sad too?` +}) +export class SadHeroComponent { + @Input() hero: Hero; +} + +@Component({ + selector: 'confused-hero', + template: `Are you as confused as {{hero.name}}?` +}) +export class ConfusedHeroComponent { + @Input() hero: Hero; +} + +@Component({ + selector: 'unknown-hero', + template: `{{message}}` +}) +export class UnknownHeroComponent { + @Input() hero: Hero; + get message() { + return this.hero && this.hero.name ? + `${this.hero.name} is strange and mysterious.` : + 'Are you feeling indecisive?'; + } +} + +export const heroComponents = + [ HappyHeroComponent, SadHeroComponent, ConfusedHeroComponent, UnknownHeroComponent ]; diff --git a/public/docs/_examples/ngcontainer/ts/src/app/hero.ts b/public/docs/_examples/ngcontainer/ts/src/app/hero.ts new file mode 100644 index 0000000000..a1de3b3b82 --- /dev/null +++ b/public/docs/_examples/ngcontainer/ts/src/app/hero.ts @@ -0,0 +1,13 @@ +// #docregion +export class Hero { + id: number; + name: string; + emotion?: string; +} + +export const heroes: Hero[] = [ + { id: 1, name: 'Mr. Nice', emotion: 'happy'}, + { id: 2, name: 'Narco', emotion: 'sad' }, + { id: 3, name: 'Windstorm', emotion: 'confused' }, + { id: 4, name: 'Magneta'} +]; diff --git a/public/docs/_examples/ngcontainer/ts/src/index.html b/public/docs/_examples/ngcontainer/ts/src/index.html new file mode 100644 index 0000000000..fc5ff417c3 --- /dev/null +++ b/public/docs/_examples/ngcontainer/ts/src/index.html @@ -0,0 +1,26 @@ + + + + + Angular <ng-container> + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/ngcontainer/ts/src/main.ts b/public/docs/_examples/ngcontainer/ts/src/main.ts new file mode 100644 index 0000000000..105b06712d --- /dev/null +++ b/public/docs/_examples/ngcontainer/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); + diff --git a/public/docs/_examples/ngmodule/e2e-spec.ts b/public/docs/_examples/ngmodule/e2e-spec.ts new file mode 100644 index 0000000000..0fbce1213d --- /dev/null +++ b/public/docs/_examples/ngmodule/e2e-spec.ts @@ -0,0 +1,223 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + +describe('NgModule', function () { + + // helpers + const gold = 'rgba(255, 215, 0, 1)'; + const powderblue = 'rgba(176, 224, 230, 1)'; + const lightgray = 'rgba(211, 211, 211, 1)'; + const white = 'rgba(0, 0, 0, 0)'; + + function getCommonsSectionStruct() { + const buttons = element.all(by.css('nav a')); + + return { + title: element.all(by.tagName('h1')).get(0), + subtitle: element.all(by.css('app-title p i')).get(0), + contactButton: buttons.get(0), + crisisButton: buttons.get(1), + heroesButton: buttons.get(2) + }; + } + + function getContactSectionStruct() { + const buttons = element.all(by.css('app-contact form button')); + + return { + header: element.all(by.css('app-contact h2')).get(0), + popupMessage: element.all(by.css('app-contact div')).get(0), + contactNameHeader: element.all(by.css('app-contact form h3')).get(0), + input: element.all(by.css('app-contact form input')).get(0), + validationError: element.all(by.css('app-contact form .alert')).get(0), + saveButton: buttons.get(0), // can't be tested + nextContactButton: buttons.get(1), + newContactButton: buttons.get(2) + }; + } + + function getCrisisSectionStruct() { + return { + title: element.all(by.css('ng-component h3')).get(0), + items: element.all(by.css('ng-component a')), + itemId: element.all(by.css('ng-component div')).get(0), + listLink: element.all(by.css('ng-component a')).get(0), + }; + } + + function getHeroesSectionStruct() { + return { + header: element.all(by.css('ng-component h2')).get(0), + title: element.all(by.css('ng-component h3')).get(0), + items: element.all(by.css('ng-component a')), + itemId: element.all(by.css('ng-component ng-component div div')).get(0), + itemInput: element.all(by.css('ng-component ng-component input')).get(0), + listLink: element.all(by.css('ng-component ng-component a')).get(0), + }; + } + + // tests + function appTitleTests(color: string, name?: string) { + return function() { + it('should have a gray header', function() { + const commons = getCommonsSectionStruct(); + expect(commons.title.getCssValue('backgroundColor')).toBe(color); + }); + + it('should welcome us', function () { + const commons = getCommonsSectionStruct(); + expect(commons.subtitle.getText()).toBe('Welcome, ' + (name || 'Sherlock Holmes')); + }); + }; + } + + function contactTests(color: string, name?: string) { + return function() { + it('shows the contact\'s owner', function() { + const contacts = getContactSectionStruct(); + expect(contacts.header.getText()).toBe('Contact of ' + (name || 'Sherlock Holmes')); + }); + + it('can cycle between contacts', function () { + const contacts = getContactSectionStruct(); + const nextButton = contacts.nextContactButton; + expect(contacts.contactNameHeader.getText()).toBe('Awesome Sam Spade'); + expect(contacts.contactNameHeader.getCssValue('backgroundColor')).toBe(color); + nextButton.click().then(function () { + expect(contacts.contactNameHeader.getText()).toBe('Awesome Nick Danger'); + return nextButton.click(); + }).then(function () { + expect(contacts.contactNameHeader.getText()).toBe('Awesome Nancy Drew'); + }); + }); + + it('can change an existing contact', function () { + const contacts = getContactSectionStruct(); + contacts.input.sendKeys('a'); + expect(contacts.input.getCssValue('backgroundColor')).toBe(color); + expect(contacts.contactNameHeader.getText()).toBe('Awesome Sam Spadea'); + }); + + it('can create a new contact', function () { + const contacts = getContactSectionStruct(); + const newContactButton = contacts.newContactButton; + newContactButton.click().then(function () { + expect(contacts.validationError.getText()).toBe('Name is required'); + contacts.input.sendKeys('John Doe'); + expect(contacts.contactNameHeader.getText()).toBe('Awesome John Doe'); + expect(contacts.validationError.getText()).toBe(''); + }); + }); + }; + } + + describe('index.html', function () { + beforeEach(function () { + browser.get(''); + }); + + describe('app-title', appTitleTests(white, 'Miss Marple')); + + describe('contact', contactTests(lightgray, 'Miss Marple')); + + describe('crisis center', function () { + beforeEach(function () { + getCommonsSectionStruct().crisisButton.click(); + }); + + it('shows a list of crisis', function () { + const crisis = getCrisisSectionStruct(); + expect(crisis.title.getText()).toBe('Crisis List'); + expect(crisis.items.count()).toBe(4); + expect(crisis.items.get(0).getText()).toBe('1 - Dragon Burning Cities'); + }); + + it('can navigate to one crisis details', function () { + const crisis = getCrisisSectionStruct(); + crisis.items.get(0).click().then(function() { + expect(crisis.itemId.getText()).toBe('Crisis id: 1'); + return crisis.listLink.click(); + }).then(function () { + // We are back to the list + expect(crisis.items.count()).toBe(4); + }); + }); + }); + + describe('heroes', function () { + beforeEach(function () { + getCommonsSectionStruct().heroesButton.click(); + }); + + it('shows a list of heroes', function() { + const heroes = getHeroesSectionStruct(); + expect(heroes.header.getText()).toBe('Heroes of Miss Marple'); + expect(heroes.title.getText()).toBe('Hero List'); + expect(heroes.items.count()).toBe(6); + expect(heroes.items.get(0).getText()).toBe('11 - Mr. Nice'); + }); + + it('can navigate and edit one hero details', function () { + const heroes = getHeroesSectionStruct(); + heroes.items.get(0).click().then(function () { + expect(heroes.itemId.getText()).toBe('Id: 11'); + heroes.itemInput.sendKeys(' try'); + return heroes.listLink.click(); + }).then(function () { + // We are back to the list + expect(heroes.items.count()).toBe(6); + expect(heroes.items.get(0).getText()).toBe('11 - Mr. Nice try'); + }); + }); + }); + }); + + describe('index.0.html', function() { + beforeEach(function () { + browser.get('index.0.html'); + }); + + it('has a title', function () { + const title = element.all(by.tagName('h1')).get(0); + expect(title.getText()).toBe('Minimal NgModule'); + }); + }); + + describe('index.1.html', function () { + beforeEach(function () { + browser.get('index.1.html'); + }); + + describe('app-title', appTitleTests(powderblue)); + }); + + describe('index.1b.html', function () { + beforeEach(function () { + browser.get('index.1b.html'); + }); + + describe('app-title', appTitleTests(powderblue)); + + describe('contact', contactTests(powderblue)); + }); + + describe('index.2.html', function () { + beforeEach(function () { + browser.get('index.2.html'); + }); + + describe('app-title', appTitleTests(gold)); + + describe('contact', contactTests(powderblue)); + }); + + describe('index.3.html', function () { + beforeEach(function () { + browser.get('index.3.html'); + }); + + describe('app-title', appTitleTests(gold)); + }); + +}); diff --git a/public/docs/_examples/ngmodule/ts/contact.1b.plnkr.json b/public/docs/_examples/ngmodule/ts/contact.1b.plnkr.json new file mode 100644 index 0000000000..0f61c91f75 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/contact.1b.plnkr.json @@ -0,0 +1,25 @@ +{ + "description": "Contact NgModule v.1", + "basePath": "src/", + "files": [ + "app/app.component.1b.ts", + "app/app.module.1b.ts", + "app/highlight.directive.ts", + "app/title.component.html", + "app/title.component.ts", + "app/user.service.ts", + + "app/contact/awesome.pipe.ts", + "app/contact/contact.component.css", + "app/contact/contact.component.html", + "app/contact/contact.component.3.ts", + "app/contact/contact.service.ts", + "app/contact/highlight.directive.ts", + + "main.1b.ts", + "styles.css", + "index.1b.html" + ], + "main": "index.1b.html", + "tags": ["NgModule"] +} diff --git a/public/docs/_examples/ngmodule/ts/contact.2.plnkr.json b/public/docs/_examples/ngmodule/ts/contact.2.plnkr.json new file mode 100644 index 0000000000..6555b76dcd --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/contact.2.plnkr.json @@ -0,0 +1,27 @@ +{ + "description": "Contact NgModule v.2", + "basePath": "src/", + "files": [ + "app/app.component.2.ts", + "app/app.module.2.ts", + "app/highlight.directive.ts", + "app/title.component.html", + "app/title.component.ts", + "app/user.service.ts", + + "app/contact/contact.component.css", + "app/contact/contact.component.html", + "app/contact/contact.service.ts", + + "app/contact/awesome.pipe.ts", + "app/contact/contact.component.3.ts", + "app/contact/contact.module.2.ts", + "app/contact/highlight.directive.ts", + + "main.2.ts", + "styles.css", + "index.2.html" + ], + "main": "index.2.html", + "tags": ["NgModule"] +} diff --git a/public/docs/_examples/pipes/dart/example-config.json b/public/docs/_examples/ngmodule/ts/example-config.json similarity index 100% rename from public/docs/_examples/pipes/dart/example-config.json rename to public/docs/_examples/ngmodule/ts/example-config.json diff --git a/public/docs/_examples/ngmodule/ts/minimal.0.plnkr.json b/public/docs/_examples/ngmodule/ts/minimal.0.plnkr.json new file mode 100644 index 0000000000..e5e37ac4ee --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/minimal.0.plnkr.json @@ -0,0 +1,13 @@ +{ + "description": "Minimal NgModule", + "basePath": "src/", + "files": [ + "app/app.component.0.ts", + "app/app.module.0.ts", + "main.0.ts", + "styles.css", + "index.0.html" + ], + "main": "index.0.html", + "tags": ["NgModule"] +} diff --git a/public/docs/_examples/ngmodule/ts/plnkr.json b/public/docs/_examples/ngmodule/ts/plnkr.json new file mode 100644 index 0000000000..4d9d2ec20b --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/plnkr.json @@ -0,0 +1,41 @@ +{ + "description": "NgModule Final", + "basePath": "src/", + "files": [ + "app/app.component.ts", + "app/app.module.ts", + "app/app-routing.module.ts", + + "app/contact/contact.component.css", + "app/contact/contact.component.html", + "app/contact/contact.service.ts", + + "app/contact/contact.component.ts", + "app/contact/contact.module.ts", + "app/contact/contact-routing.module.ts", + + "app/crisis/*.ts", + + "app/hero/hero-detail.component.ts", + "app/hero/hero-list.component.ts", + "app/hero/hero.service.ts", + + "app/hero/hero.component.ts", + "app/hero/hero.module.ts", + "app/hero/hero-routing.module.ts", + + "app/core/*.css", + "app/core/*.html", + "app/core/*.ts", + + "app/shared/*.css", + "app/shared/*.html", + "app/shared/*.ts", + + "main.ts", + "styles.css", + "index.html" + ], + "main": "index.html", + "tags": ["NgModule"] +} diff --git a/public/docs/_examples/ngmodule/ts/pre-shared.3.plnkr.json b/public/docs/_examples/ngmodule/ts/pre-shared.3.plnkr.json new file mode 100644 index 0000000000..9747801604 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/pre-shared.3.plnkr.json @@ -0,0 +1,41 @@ +{ + "description": "NgModule v.3", + "basePath": "src/", + "files": [ + "app/app.component.3.ts", + "app/app.module.3.ts", + "app/app-routing.module.3.ts", + + "app/highlight.directive.ts", + "app/title.component.html", + "app/title.component.ts", + "app/user.service.ts", + + "app/contact/contact.component.css", + "app/contact/contact.component.html", + "app/contact/contact.service.ts", + + "app/contact/awesome.pipe.ts", + "app/contact/contact.component.3.ts", + "app/contact/contact.module.3.ts", + "app/contact/contact-routing.module.3.ts", + "app/contact/highlight.directive.ts", + + "app/crisis/*.ts", + + "app/hero/hero-detail.component.ts", + "app/hero/hero-list.component.ts", + "app/hero/hero.service.ts", + + "app/hero/hero.component.3.ts", + "app/hero/hero.module.3.ts", + "app/hero/hero-routing.module.3.ts", + "app/hero/highlight.directive.ts", + + "main.3.ts", + "styles.css", + "index.3.html" + ], + "main": "index.3.html", + "tags": ["NgModule"] +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/app-routing.module.3.ts b/public/docs/_examples/ngmodule/ts/src/app/app-routing.module.3.ts new file mode 100644 index 0000000000..1d53b708f8 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app-routing.module.3.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +export const routes: Routes = [ + { path: '', redirectTo: 'contact', pathMatch: 'full'}, + { path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' }, + { path: 'heroes', loadChildren: 'app/hero/hero.module.3#HeroModule' } +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/ngmodule/ts/src/app/app-routing.module.ts b/public/docs/_examples/ngmodule/ts/src/app/app-routing.module.ts new file mode 100644 index 0000000000..c753dcd488 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app-routing.module.ts @@ -0,0 +1,19 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +export const routes: Routes = [ + { path: '', redirectTo: 'contact', pathMatch: 'full'}, +// #docregion lazy-routes + { path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' }, + { path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule' } +// #enddocregion lazy-routes +]; + +// #docregion forRoot +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule {} +// #enddocregion forRoot diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.component.0.ts b/public/docs/_examples/ngmodule/ts/src/app/app.component.0.ts new file mode 100644 index 0000000000..4977890c3b --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.component.0.ts @@ -0,0 +1,10 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: '

    {{title}}

    ', +}) +export class AppComponent { + title = 'Minimal NgModule'; +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.component.1.ts b/public/docs/_examples/ngmodule/ts/src/app/app.component.1.ts new file mode 100644 index 0000000000..ccf44d4416 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.component.1.ts @@ -0,0 +1,19 @@ +// #docplaster +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', +// #enddocregion + /* + // #docregion template + template: '

    {{title}}

    ' + // #enddocregion template + */ +// #docregion + template: '' +}) +export class AppComponent { + subtitle = '(v1)'; +} +// #enddocregion diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.component.1b.ts b/public/docs/_examples/ngmodule/ts/src/app/app.component.1b.ts new file mode 100644 index 0000000000..291bf0ac6b --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.component.1b.ts @@ -0,0 +1,15 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + // #docregion template + template: ` + + + ` + // #enddocregion template +}) +export class AppComponent { + subtitle = '(v1)'; +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.component.2.ts b/public/docs/_examples/ngmodule/ts/src/app/app.component.2.ts new file mode 100644 index 0000000000..a68b7d337d --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.component.2.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` + + + ` +}) +export class AppComponent { + subtitle = '(v2)'; +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.component.3.ts b/public/docs/_examples/ngmodule/ts/src/app/app.component.3.ts new file mode 100644 index 0000000000..6d69a56f70 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.component.3.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + // #docregion template + template: ` + + + + ` + // #enddocregion template +}) +export class AppComponent { + subtitle = '(v3)'; +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.component.ts b/public/docs/_examples/ngmodule/ts/src/app/app.component.ts new file mode 100644 index 0000000000..67336c8b08 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.component.ts @@ -0,0 +1,19 @@ +// #docplaster +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` + + + + ` +}) +export class AppComponent { + subtitle = '(Final)'; +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.module.0.ts b/public/docs/_examples/ngmodule/ts/src/app/app.module.0.ts new file mode 100644 index 0000000000..144ad7bb50 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.module.0.ts @@ -0,0 +1,23 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import +// #enddocregion + { AppComponent } from './app.component.0'; +/* +// #docregion + { AppComponent } from './app.component'; +// #enddocregion +*/ +// #docregion + +@NgModule({ +// #docregion imports + imports: [ BrowserModule ], +// #enddocregion imports + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.module.1.ts b/public/docs/_examples/ngmodule/ts/src/app/app.module.1.ts new file mode 100644 index 0000000000..f9f50e18d0 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.module.1.ts @@ -0,0 +1,54 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import +// #enddocregion + { AppComponent } from './app.component.1'; +/* +// #docregion + { AppComponent } from './app.component'; +// #enddocregion +*/ +// #docregion +import { HighlightDirective } from './highlight.directive'; +import { TitleComponent } from './title.component'; +import { UserService } from './user.service'; + +/* Contact Related Imports */ +import { FormsModule } from '@angular/forms'; + +import { AwesomePipe } from './contact/awesome.pipe'; +import { ContactComponent } from './contact/contact.component.3'; + +// #docregion import-contact-directive +import { + HighlightDirective as ContactHighlightDirective +} from './contact/highlight.directive'; +// #enddocregion import-contact-directive + +@NgModule({ +// #docregion imports + imports: [ BrowserModule, FormsModule ], +// #enddocregion imports +// #docregion declarations, directive, component + declarations: [ + AppComponent, + HighlightDirective, +// #enddocregion directive + TitleComponent, +// #enddocregion component + + AwesomePipe, + ContactComponent, + ContactHighlightDirective +// #docregion directive, component + ], +// #enddocregion declarations, directive, component +// #docregion providers + providers: [ UserService ], +// #enddocregion providers + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.module.1b.ts b/public/docs/_examples/ngmodule/ts/src/app/app.module.1b.ts new file mode 100644 index 0000000000..ae04326239 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.module.1b.ts @@ -0,0 +1,53 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +/* App Root */ +import +// #enddocregion + { AppComponent } from './app.component.1b'; +/* +// #docregion + { AppComponent } from './app.component'; +// #enddocregion +*/ +// #docregion +import { HighlightDirective } from './highlight.directive'; +import { TitleComponent } from './title.component'; +import { UserService } from './user.service'; + +/* Contact Imports */ +import +// #enddocregion + { ContactComponent } from './contact/contact.component.3'; +/* +// #docregion + { ContactComponent } from './contact/contact.component'; +// #enddocregion +*/ +// #docregion +import { ContactService } from './contact/contact.service'; +import { AwesomePipe } from './contact/awesome.pipe'; + +// #docregion import-alias +import { + HighlightDirective as ContactHighlightDirective +} from './contact/highlight.directive'; +// #enddocregion import-alias + +import { FormsModule } from '@angular/forms'; + +@NgModule({ + imports: [ BrowserModule, FormsModule ], +// #docregion declarations + declarations: [ + AppComponent, HighlightDirective, TitleComponent, + AwesomePipe, ContactComponent, ContactHighlightDirective + ], +// #docregion providers + providers: [ ContactService, UserService ], +// #enddocregion providers + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.module.2.ts b/public/docs/_examples/ngmodule/ts/src/app/app.module.2.ts new file mode 100644 index 0000000000..f00e9b5d27 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.module.2.ts @@ -0,0 +1,37 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +/* App Root */ +import +// #enddocregion + { AppComponent } from './app.component.2'; +/* +// #docregion + { AppComponent } from './app.component'; +// #enddocregion +*/ +// #docregion +import { HighlightDirective } from './highlight.directive'; +import { TitleComponent } from './title.component'; +import { UserService } from './user.service'; + +/* Contact Imports */ +import +// #enddocregion + { ContactModule } from './contact/contact.module.2'; +/* +// #docregion + { ContactModule } from './contact/contact.module'; +// #enddocregion +*/ +// #docregion + +@NgModule({ + imports: [ BrowserModule, ContactModule ], + declarations: [ AppComponent, HighlightDirective, TitleComponent ], + providers: [ UserService ], + bootstrap: [ AppComponent ], +}) +export class AppModule { } diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.module.3.ts b/public/docs/_examples/ngmodule/ts/src/app/app.module.3.ts new file mode 100644 index 0000000000..8ca0a46d9a --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.module.3.ts @@ -0,0 +1,30 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +/* App Root */ +import { AppComponent } from './app.component.3'; +import { HighlightDirective } from './highlight.directive'; +import { TitleComponent } from './title.component'; +import { UserService } from './user.service'; + +/* Feature Modules */ +import { ContactModule } from './contact/contact.module.3'; + +/* Routing Module */ +import { AppRoutingModule } from './app-routing.module.3'; + +@NgModule({ +// #docregion imports + imports: [ + BrowserModule, + ContactModule, + AppRoutingModule + ], +// #enddocregion imports + providers: [ UserService ], + declarations: [ AppComponent, HighlightDirective, TitleComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/ngmodule/ts/src/app/app.module.ts b/public/docs/_examples/ngmodule/ts/src/app/app.module.ts new file mode 100644 index 0000000000..da03420804 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/app.module.ts @@ -0,0 +1,40 @@ +// #docplaster +// #docregion +// #docregion v4 +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +/* App Root */ +import { AppComponent } from './app.component'; + +/* Feature Modules */ +import { ContactModule } from './contact/contact.module'; +import { CoreModule } from './core/core.module'; + +/* Routing Module */ +import { AppRoutingModule } from './app-routing.module'; + +@NgModule({ + // #docregion import-for-root + imports: [ + BrowserModule, + ContactModule, +// #enddocregion v4 +// #enddocregion import-for-root +/* +// #docregion v4 + CoreModule, +// #enddocregion v4 +*/ +// #docregion import-for-root + CoreModule.forRoot({userName: 'Miss Marple'}), +// #docregion v4 + AppRoutingModule + ], + // #enddocregion import-for-root + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +// #enddocregion v4 +// #enddocregion diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/awesome.pipe.ts b/public/docs/_examples/ngmodule/ts/src/app/contact/awesome.pipe.ts new file mode 100644 index 0000000000..d6dce99901 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/awesome.pipe.ts @@ -0,0 +1,10 @@ +// #docregion +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ name: 'awesome' }) +/** Precede the input string with the word "Awesome " */ +export class AwesomePipe implements PipeTransform { + transform(phrase: string) { + return phrase ? 'Awesome ' + phrase : ''; + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/contact-routing.module.3.ts b/public/docs/_examples/ngmodule/ts/src/app/contact/contact-routing.module.3.ts new file mode 100644 index 0000000000..27dfc232b7 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/contact-routing.module.3.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { ContactComponent } from './contact.component.3'; + +@NgModule({ + imports: [RouterModule.forChild([ + { path: 'contact', component: ContactComponent} + ])], + exports: [RouterModule] +}) +export class ContactRoutingModule {} diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/contact-routing.module.ts b/public/docs/_examples/ngmodule/ts/src/app/contact/contact-routing.module.ts new file mode 100644 index 0000000000..2fa81af5a9 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/contact-routing.module.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { ContactComponent } from './contact.component'; + +// #docregion routing +@NgModule({ + imports: [RouterModule.forChild([ + { path: 'contact', component: ContactComponent } + ])], + exports: [RouterModule] +}) +export class ContactRoutingModule {} +// #enddocregion diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.3.ts b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.3.ts new file mode 100644 index 0000000000..ea6e9868ba --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.3.ts @@ -0,0 +1,53 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; + +import { Contact, ContactService } from './contact.service'; +import { UserService } from '../user.service'; + +@Component({ + selector: 'app-contact', + templateUrl: './contact.component.html', + styleUrls: [ './contact.component.css' ] +}) +export class ContactComponent implements OnInit { + contact: Contact; + contacts: Contact[]; + + msg = 'Loading contacts ...'; + userName = ''; + + constructor(private contactService: ContactService, userService: UserService) { + this.userName = userService.userName; + } + + ngOnInit() { + this.contactService.getContacts().then(contacts => { + this.msg = ''; + this.contacts = contacts; + this.contact = contacts[0]; + }); + } + + next() { + let ix = 1 + this.contacts.indexOf(this.contact); + if (ix >= this.contacts.length) { ix = 0; } + this.contact = this.contacts[ix]; + } + + onSubmit() { + // POST-DEMO TODO: do something like save it + this.displayMessage('Saved ' + this.contact.name); + } + + newContact() { + this.displayMessage('New contact'); + this.contact = {id: 42, name: ''}; + this.contacts.push(this.contact); + } + + /** Display a message briefly, then remove it. */ + displayMessage(msg: string) { + this.msg = msg; + setTimeout(() => this.msg = '', 1500); + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.css b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.css new file mode 100644 index 0000000000..45e8f6e76d --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.css @@ -0,0 +1,29 @@ +/* #docregion */ +.ng-valid[required] { + border-left: 5px solid #42A948; /* green */ +} + +.ng-invalid { + border-left: 5px solid #a94442; /* red */ +} + +.alert { + padding: 15px; + margin: 8px 0; + border: 1px solid transparent; + border-radius: 4px; +} +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} + +.msg { + color: blue; + background-color: whitesmoke; + border: 1px solid transparent; + border-radius: 4px; + margin-bottom: 20px; +} + diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.html b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.html new file mode 100644 index 0000000000..483480571e --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.html @@ -0,0 +1,23 @@ + +

    Contact of {{userName}}

    +
    {{msg}}
    + +
    + +

    {{ contact.name | awesome }}

    + +
    + + +
    + Name is required +
    +
    +
    + + + +
    + diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.ts b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.ts new file mode 100644 index 0000000000..d6dcbbc53f --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.component.ts @@ -0,0 +1,54 @@ +// Exact copy except import UserService from core +// #docregion +import { Component, OnInit } from '@angular/core'; + +import { Contact, ContactService } from './contact.service'; +import { UserService } from '../core/user.service'; + +@Component({ + selector: 'app-contact', + templateUrl: './contact.component.html', + styleUrls: [ './contact.component.css' ] +}) +export class ContactComponent implements OnInit { + contact: Contact; + contacts: Contact[]; + + msg = 'Loading contacts ...'; + userName = ''; + + constructor(private contactService: ContactService, userService: UserService) { + this.userName = userService.userName; + } + + ngOnInit() { + this.contactService.getContacts().then(contacts => { + this.msg = ''; + this.contacts = contacts; + this.contact = contacts[0]; + }); + } + + next() { + let ix = 1 + this.contacts.indexOf(this.contact); + if (ix >= this.contacts.length) { ix = 0; } + this.contact = this.contacts[ix]; + } + + onSubmit() { + // POST-DEMO TODO: do something like save it + this.displayMessage('Saved ' + this.contact.name); + } + + newContact() { + this.displayMessage('New contact'); + this.contact = {id: 42, name: ''}; + this.contacts.push(this.contact); + } + + /** Display a message briefly, then remove it. */ + displayMessage(msg: string) { + this.msg = msg; + setTimeout(() => this.msg = '', 1500); + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/contact.module.2.ts b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.module.2.ts new file mode 100644 index 0000000000..f347bd3b51 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.module.2.ts @@ -0,0 +1,30 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { AwesomePipe } from './awesome.pipe'; + +import +// #enddocregion + { ContactComponent } from './contact.component.3'; +/* +// #docregion + { ContactComponent } from './contact.component'; +// #enddocregion +*/ +// #docregion +import { ContactService } from './contact.service'; +import { HighlightDirective } from './highlight.directive'; + +// #docregion class +@NgModule({ + imports: [ CommonModule, FormsModule ], + declarations: [ ContactComponent, HighlightDirective, AwesomePipe ], + exports: [ ContactComponent ], + providers: [ ContactService ] +}) +export class ContactModule { } +// #enddocregion class +// #enddocregion diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/contact.module.3.ts b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.module.3.ts new file mode 100644 index 0000000000..ff70721b2f --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.module.3.ts @@ -0,0 +1,22 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { AwesomePipe } from './awesome.pipe'; + +import { ContactComponent } from './contact.component.3'; +import { ContactService } from './contact.service'; +import { HighlightDirective } from './highlight.directive'; + +import { ContactRoutingModule } from './contact-routing.module.3'; + +// #docregion class +@NgModule({ + imports: [ CommonModule, FormsModule, ContactRoutingModule ], + declarations: [ ContactComponent, HighlightDirective, AwesomePipe ], + providers: [ ContactService ] +}) +export class ContactModule { } +// #enddocregion class +// #enddocregion diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/contact.module.ts b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.module.ts new file mode 100644 index 0000000000..9456de7654 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.module.ts @@ -0,0 +1,16 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { SharedModule } from '../shared/shared.module'; + +import { ContactComponent } from './contact.component'; +import { ContactService } from './contact.service'; +import { ContactRoutingModule } from './contact-routing.module'; + +// #docregion class +@NgModule({ + imports: [ SharedModule, ContactRoutingModule ], + declarations: [ ContactComponent ], + providers: [ ContactService ] +}) +export class ContactModule { } +// #enddocregion class diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/contact.service.ts b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.service.ts new file mode 100644 index 0000000000..28b18bd84a --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/contact.service.ts @@ -0,0 +1,29 @@ +// #docregion +import { Injectable } from '@angular/core'; + +export class Contact { + constructor(public id: number, public name: string) { } +} + +const CONTACTS: Contact[] = [ + new Contact(21, 'Sam Spade'), + new Contact(22, 'Nick Danger'), + new Contact(23, 'Nancy Drew') +]; + +const FETCH_LATENCY = 500; + +@Injectable() +export class ContactService { + + getContacts() { + return new Promise(resolve => { + setTimeout(() => { resolve(CONTACTS); }, FETCH_LATENCY); + }); + } + + getContact(id: number | string) { + return this.getContacts() + .then(heroes => heroes.find(hero => hero.id === +id)); + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/contact/highlight.directive.ts b/public/docs/_examples/ngmodule/ts/src/app/contact/highlight.directive.ts new file mode 100644 index 0000000000..64338b1377 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/contact/highlight.directive.ts @@ -0,0 +1,18 @@ +/* tslint:disable */ +// Same directive name and selector as +// HighlightDirective in parent AppModule +// It selects for both input boxes and 'highlight' attr +// and it highlights in blue instead of gold + +// #docregion +import { Directive, ElementRef } from '@angular/core'; + +@Directive({ selector: '[highlight], input' }) +/** Highlight the attached element or an InputElement in blue */ +export class HighlightDirective { + constructor(el: ElementRef) { + el.nativeElement.style.backgroundColor = 'powderblue'; + console.log( + `* Contact highlight called for ${el.nativeElement.tagName}`); + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/core/core.module.ts b/public/docs/_examples/ngmodule/ts/src/app/core/core.module.ts new file mode 100644 index 0000000000..27cb9a2193 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/core/core.module.ts @@ -0,0 +1,48 @@ +/* tslint:disable:member-ordering no-unused-variable */ +// #docplaster +// #docregion +// #docregion v4 +import { + ModuleWithProviders, NgModule, + Optional, SkipSelf } from '@angular/core'; + +import { CommonModule } from '@angular/common'; + +import { TitleComponent } from './title.component'; +import { UserService } from './user.service'; +// #enddocregion +import { UserServiceConfig } from './user.service'; + +// #docregion v4 +@NgModule({ + imports: [ CommonModule ], + declarations: [ TitleComponent ], + exports: [ TitleComponent ], + providers: [ UserService ] +}) +export class CoreModule { +// #enddocregion v4 + + // #docregion ctor + constructor (@Optional() @SkipSelf() parentModule: CoreModule) { + if (parentModule) { + throw new Error( + 'CoreModule is already loaded. Import it in the AppModule only'); + } + } + // #enddocregion ctor + + // #docregion for-root + static forRoot(config: UserServiceConfig): ModuleWithProviders { + return { + ngModule: CoreModule, + providers: [ + {provide: UserServiceConfig, useValue: config } + ] + }; + } + // #enddocregion for-root +// #docregion v4 +} +// #enddocregion v4 +// #enddocregion diff --git a/public/docs/_examples/ngmodule/ts/src/app/core/title.component.html b/public/docs/_examples/ngmodule/ts/src/app/core/title.component.html new file mode 100644 index 0000000000..8ebd08ae43 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/core/title.component.html @@ -0,0 +1,6 @@ + +

    {{title}} {{subtitle}}

    +

    + Welcome, {{user}} +

    + diff --git a/public/docs/_examples/ngmodule/ts/src/app/core/title.component.ts b/public/docs/_examples/ngmodule/ts/src/app/core/title.component.ts new file mode 100644 index 0000000000..b52a57aa13 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/core/title.component.ts @@ -0,0 +1,17 @@ +// Exact copy of app/title.component.ts except import UserService from shared +import { Component, Input } from '@angular/core'; +import { UserService } from '../core/user.service'; + +@Component({ + selector: 'app-title', + templateUrl: './title.component.html', +}) +export class TitleComponent { + @Input() subtitle = ''; + title = 'Angular Modules'; + user = ''; + + constructor(userService: UserService) { + this.user = userService.userName; + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/core/user.service.ts b/public/docs/_examples/ngmodule/ts/src/app/core/user.service.ts new file mode 100644 index 0000000000..8fe839075e --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/core/user.service.ts @@ -0,0 +1,32 @@ +// Crazy copy of the app/user.service +// Proves that UserService is an app-wide singleton and only instantiated once +// IFF shared.module follows the `forRoot` pattern +// +// If it didn't, a new instance of UserService would be created +// after each lazy load and the userName would double up. + +import { Injectable, Optional } from '@angular/core'; + +let nextId = 1; + +export class UserServiceConfig { + userName = 'Philip Marlowe'; +} + +@Injectable() +export class UserService { + id = nextId++; + private _userName = 'Sherlock Holmes'; + + // #docregion ctor + constructor(@Optional() config: UserServiceConfig) { + if (config) { this._userName = config.userName; } + } + // #enddocregion ctor + + get userName() { + // Demo: add a suffix if this service has been created more than once + const suffix = this.id > 1 ? ` times ${this.id}` : ''; + return this._userName + suffix; + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis-detail.component.ts b/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis-detail.component.ts new file mode 100644 index 0000000000..9749029d62 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis-detail.component.ts @@ -0,0 +1,19 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; + +@Component({ + template: ` +

    Crisis Detail

    +
    Crisis id: {{id}}
    +
    + Crisis List + ` +}) +export class CrisisDetailComponent implements OnInit { + id: number; + constructor(private route: ActivatedRoute) { } + + ngOnInit() { + this.id = parseInt(this.route.snapshot.params['id'], 10); + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis-list.component.ts b/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis-list.component.ts new file mode 100644 index 0000000000..ae459cdf1b --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis-list.component.ts @@ -0,0 +1,22 @@ +import { Component, OnInit } from '@angular/core'; + +import { Crisis, + CrisisService } from './crisis.service'; + +@Component({ + template: ` +

    Crisis List

    +
    + {{crisis.id}} - {{crisis.name}} +
    + ` +}) +export class CrisisListComponent implements OnInit { + crisises: Promise; + + constructor(private crisisService: CrisisService) { } + + ngOnInit() { + this.crisises = this.crisisService.getCrises(); + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis-routing.module.ts b/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis-routing.module.ts new file mode 100644 index 0000000000..c60efa8cb4 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { Routes, + RouterModule } from '@angular/router'; + +import { CrisisListComponent } from './crisis-list.component'; +import { CrisisDetailComponent } from './crisis-detail.component'; + +const routes: Routes = [ + { path: '', redirectTo: 'list', pathMatch: 'full'}, + { path: 'list', component: CrisisListComponent }, + { path: ':id', component: CrisisDetailComponent } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class CrisisRoutingModule {} diff --git a/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis.module.ts b/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis.module.ts new file mode 100644 index 0000000000..f557bd6423 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis.module.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { CrisisListComponent } from './crisis-list.component'; +import { CrisisDetailComponent } from './crisis-detail.component'; +import { CrisisService } from './crisis.service'; +import { CrisisRoutingModule } from './crisis-routing.module'; + +@NgModule({ + imports: [ CommonModule, CrisisRoutingModule ], + declarations: [ CrisisDetailComponent, CrisisListComponent ], + providers: [ CrisisService ] +}) +export class CrisisModule {} diff --git a/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis.service.ts b/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis.service.ts new file mode 100644 index 0000000000..419ee19b36 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/crisis/crisis.service.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@angular/core'; + +export class Crisis { + constructor(public id: number, public name: string) { } +} + +const CRISES: Crisis[] = [ + new Crisis(1, 'Dragon Burning Cities'), + new Crisis(2, 'Sky Rains Great White Sharks'), + new Crisis(3, 'Giant Asteroid Heading For Earth'), + new Crisis(4, 'Procrastinators Meeting Delayed Again'), +]; + +const FETCH_LATENCY = 500; + +@Injectable() +export class CrisisService { + + getCrises() { + return new Promise(resolve => { + setTimeout(() => { resolve(CRISES); }, FETCH_LATENCY); + }); + } + + getCrisis(id: number | string) { + return this.getCrises() + .then(heroes => heroes.find(hero => hero.id === +id)); + } + +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/hero/hero-detail.component.ts b/public/docs/_examples/ngmodule/ts/src/app/hero/hero-detail.component.ts new file mode 100644 index 0000000000..1478ad350c --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/hero/hero-detail.component.ts @@ -0,0 +1,31 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; + +import { Hero, + HeroService } from './hero.service'; + +@Component({ + template: ` +

    Hero Detail

    +
    +
    Id: {{hero.id}}

    + +
    +
    + Hero List + ` +}) +export class HeroDetailComponent implements OnInit { + hero: Hero; + + constructor( + private route: ActivatedRoute, + private heroService: HeroService) { } + + ngOnInit() { + let id = parseInt(this.route.snapshot.params['id'], 10); + this.heroService.getHero(id).then(hero => this.hero = hero); + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/hero/hero-list.component.ts b/public/docs/_examples/ngmodule/ts/src/app/hero/hero-list.component.ts new file mode 100644 index 0000000000..5a4e9ef0c4 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/hero/hero-list.component.ts @@ -0,0 +1,21 @@ +import { Component, OnInit } from '@angular/core'; + +import { Hero, + HeroService } from './hero.service'; + +@Component({ + template: ` +

    Hero List

    + + ` +}) +export class HeroListComponent implements OnInit { + heroes: Promise; + constructor(private heroService: HeroService) { } + + ngOnInit() { + this.heroes = this.heroService.getHeroes(); + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/hero/hero-routing.module.3.ts b/public/docs/_examples/ngmodule/ts/src/app/hero/hero-routing.module.3.ts new file mode 100644 index 0000000000..588ffd94be --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/hero/hero-routing.module.3.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; +import { Routes, + RouterModule } from '@angular/router'; + +import { HeroComponent } from './hero.component.3'; +import { HeroListComponent } from './hero-list.component'; +import { HeroDetailComponent } from './hero-detail.component'; + +const routes: Routes = [ + { path: '', + component: HeroComponent, + children: [ + { path: '', component: HeroListComponent }, + { path: ':id', component: HeroDetailComponent } + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class HeroRoutingModule {} diff --git a/public/docs/_examples/ngmodule/ts/src/app/hero/hero-routing.module.ts b/public/docs/_examples/ngmodule/ts/src/app/hero/hero-routing.module.ts new file mode 100644 index 0000000000..d97aab3beb --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/hero/hero-routing.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; +import { Routes, + RouterModule } from '@angular/router'; + +import { HeroComponent } from './hero.component'; +import { HeroListComponent } from './hero-list.component'; +import { HeroDetailComponent } from './hero-detail.component'; + +const routes: Routes = [ + { path: '', + component: HeroComponent, + children: [ + { path: '', component: HeroListComponent }, + { path: ':id', component: HeroDetailComponent } + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class HeroRoutingModule {} diff --git a/public/docs/_examples/ngmodule/ts/src/app/hero/hero.component.3.ts b/public/docs/_examples/ngmodule/ts/src/app/hero/hero.component.3.ts new file mode 100644 index 0000000000..d52bc253df --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/hero/hero.component.3.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; + +import { HeroService } from './hero.service'; +import { UserService } from '../user.service'; + +@Component({ + template: ` +

    Heroes of {{userName}}

    + + `, + providers: [ HeroService ] +}) +export class HeroComponent { + userName = ''; + constructor(userService: UserService) { + this.userName = userService.userName; + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/hero/hero.component.ts b/public/docs/_examples/ngmodule/ts/src/app/hero/hero.component.ts new file mode 100644 index 0000000000..86338fb0ae --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/hero/hero.component.ts @@ -0,0 +1,19 @@ +// Exact copy except import UserService from core +import { Component } from '@angular/core'; + +import { HeroService } from './hero.service'; +import { UserService } from '../core/user.service'; + +@Component({ + template: ` +

    Heroes of {{userName}}

    + + `, + providers: [ HeroService ] +}) +export class HeroComponent { + userName = ''; + constructor(userService: UserService) { + this.userName = userService.userName; + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/hero/hero.module.3.ts b/public/docs/_examples/ngmodule/ts/src/app/hero/hero.module.3.ts new file mode 100644 index 0000000000..c00f4eedd5 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/hero/hero.module.3.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { HeroComponent } from './hero.component.3'; +import { HeroDetailComponent } from './hero-detail.component'; +import { HeroListComponent } from './hero-list.component'; +import { HighlightDirective } from './highlight.directive'; +import { HeroRoutingModule } from './hero-routing.module.3'; + +// #docregion class +@NgModule({ + imports: [ CommonModule, FormsModule, HeroRoutingModule ], + declarations: [ + HeroComponent, HeroDetailComponent, HeroListComponent, + HighlightDirective + ] +}) +export class HeroModule { } +// #enddocregion class diff --git a/public/docs/_examples/ngmodule/ts/src/app/hero/hero.module.ts b/public/docs/_examples/ngmodule/ts/src/app/hero/hero.module.ts new file mode 100644 index 0000000000..98d7b76b00 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/hero/hero.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../shared/shared.module'; + +import { HeroComponent } from './hero.component'; +import { HeroDetailComponent } from './hero-detail.component'; +import { HeroListComponent } from './hero-list.component'; +import { HeroRoutingModule } from './hero-routing.module'; + +@NgModule({ + imports: [ SharedModule, HeroRoutingModule ], + declarations: [ + HeroComponent, HeroDetailComponent, HeroListComponent, + ] +}) +export class HeroModule { } diff --git a/public/docs/_examples/ngmodule/ts/src/app/hero/hero.service.ts b/public/docs/_examples/ngmodule/ts/src/app/hero/hero.service.ts new file mode 100644 index 0000000000..bb7ff5fa5c --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/hero/hero.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@angular/core'; + +export class Hero { + constructor(public id: number, public name: string) { } +} + +const HEROES: Hero[] = [ + new Hero(11, 'Mr. Nice'), + new Hero(12, 'Narco'), + new Hero(13, 'Bombasto'), + new Hero(14, 'Celeritas'), + new Hero(15, 'Magneta'), + new Hero(16, 'RubberMan') +]; + +const FETCH_LATENCY = 500; + +@Injectable() +export class HeroService { + + getHeroes() { + return new Promise(resolve => { + setTimeout(() => { resolve(HEROES); }, FETCH_LATENCY); + }); + } + + getHero(id: number | string) { + return this.getHeroes() + .then(heroes => heroes.find(hero => hero.id === +id)); + } + +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/hero/highlight.directive.ts b/public/docs/_examples/ngmodule/ts/src/app/hero/highlight.directive.ts new file mode 100644 index 0000000000..d7e39afd05 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/hero/highlight.directive.ts @@ -0,0 +1,14 @@ +// #docregion +import { Directive, ElementRef } from '@angular/core'; + +// Same directive name and selector as +// HighlightDirective in parent AppRootModule +// It selects for both input boxes and 'highlight' attr +// and it highlights in beige instead of yellow +@Directive({ selector: '[highlight]' }) +export class HighlightDirective { + constructor(el: ElementRef) { + el.nativeElement.style.backgroundColor = 'beige'; + console.log(`* Hero highlight called for ${el.nativeElement.tagName}`); + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/highlight.directive.ts b/public/docs/_examples/ngmodule/ts/src/app/highlight.directive.ts new file mode 100644 index 0000000000..df67a3ae89 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/highlight.directive.ts @@ -0,0 +1,12 @@ +// #docregion +import { Directive, ElementRef } from '@angular/core'; + +@Directive({ selector: '[highlight]' }) +/** Highlight the attached element in gold */ +export class HighlightDirective { + constructor(el: ElementRef) { + el.nativeElement.style.backgroundColor = 'gold'; + console.log( + `* AppRoot highlight called for ${el.nativeElement.tagName}`); + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/shared/awesome.pipe.ts b/public/docs/_examples/ngmodule/ts/src/app/shared/awesome.pipe.ts new file mode 100644 index 0000000000..a1a0001d24 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/shared/awesome.pipe.ts @@ -0,0 +1,10 @@ +// Exact copy of contact.awesome.pipe +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ name: 'awesome' }) +/** Precede the input string with the word "Awesome " */ +export class AwesomePipe implements PipeTransform { + transform(phrase: string) { + return phrase ? 'Awesome ' + phrase : ''; + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/shared/highlight.directive.ts b/public/docs/_examples/ngmodule/ts/src/app/shared/highlight.directive.ts new file mode 100644 index 0000000000..63fbd4e488 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/shared/highlight.directive.ts @@ -0,0 +1,13 @@ +/* tslint:disable */ +// Exact copy of contact/highlight.directive except for color and message +import { Directive, ElementRef } from '@angular/core'; + +@Directive({ selector: '[highlight], input' }) +/** Highlight the attached element or an InputElement in gray */ +export class HighlightDirective { + constructor(el: ElementRef) { + el.nativeElement.style.backgroundColor = 'lightgray'; + console.log( + `* Shared highlight called for ${el.nativeElement.tagName}`); + } +} diff --git a/public/docs/_examples/ngmodule/ts/src/app/shared/shared.module.ts b/public/docs/_examples/ngmodule/ts/src/app/shared/shared.module.ts new file mode 100644 index 0000000000..2da7d7b2a5 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/shared/shared.module.ts @@ -0,0 +1,18 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { AwesomePipe } from './awesome.pipe'; +import { HighlightDirective } from './highlight.directive'; + +// #docregion module +@NgModule({ + imports: [ CommonModule ], + declarations: [ AwesomePipe, HighlightDirective ], + exports: [ AwesomePipe, HighlightDirective, + CommonModule, FormsModule ] +}) +export class SharedModule { } +// #enddocregion module +// #enddocregion diff --git a/public/docs/_examples/ngmodule/ts/src/app/title.component.html b/public/docs/_examples/ngmodule/ts/src/app/title.component.html new file mode 100644 index 0000000000..3db364cd4b --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/title.component.html @@ -0,0 +1,10 @@ + + +

    {{title}} {{subtitle}}

    + + +

    + Welcome, {{user}} +

    + + diff --git a/public/docs/_examples/ngmodule/ts/src/app/title.component.ts b/public/docs/_examples/ngmodule/ts/src/app/title.component.ts new file mode 100644 index 0000000000..9a2ef1c4b8 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/title.component.ts @@ -0,0 +1,24 @@ +// #docplaster +// #docregion +// #docregion v1 +import { Component, Input } from '@angular/core'; +// #enddocregion v1 +import { UserService } from './user.service'; +// #docregion v1 + +@Component({ + selector: 'app-title', + templateUrl: './title.component.html', +}) +export class TitleComponent { + @Input() subtitle = ''; + title = 'Angular Modules'; +// #enddocregion v1 + user = ''; + + constructor(userService: UserService) { + this.user = userService.userName; + } +// #docregion v1 +} +// #enddocregion v1 diff --git a/public/docs/_examples/ngmodule/ts/src/app/user.service.ts b/public/docs/_examples/ngmodule/ts/src/app/user.service.ts new file mode 100644 index 0000000000..7d996b26fa --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/app/user.service.ts @@ -0,0 +1,8 @@ +// #docregion +import { Injectable } from '@angular/core'; + +@Injectable() +/** Dummy version of an authenticated user service */ +export class UserService { + userName = 'Sherlock Holmes'; +} diff --git a/public/docs/_examples/ngmodule/ts/src/index.0.html b/public/docs/_examples/ngmodule/ts/src/index.0.html new file mode 100644 index 0000000000..2281b9fecb --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/index.0.html @@ -0,0 +1,24 @@ + + + + + NgModule Minimal + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/ngmodule/ts/src/index.1.html b/public/docs/_examples/ngmodule/ts/src/index.1.html new file mode 100644 index 0000000000..65f7991a26 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/index.1.html @@ -0,0 +1,24 @@ + + + + + NgModule - Contact + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/ngmodule/ts/src/index.1b.html b/public/docs/_examples/ngmodule/ts/src/index.1b.html new file mode 100644 index 0000000000..b4a89d6549 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/index.1b.html @@ -0,0 +1,24 @@ + + + + + NgModule - Contact + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/ngmodule/ts/src/index.2.html b/public/docs/_examples/ngmodule/ts/src/index.2.html new file mode 100644 index 0000000000..72c545f1f3 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/index.2.html @@ -0,0 +1,24 @@ + + + + + NgModule - Contact + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/ngmodule/ts/src/index.3.html b/public/docs/_examples/ngmodule/ts/src/index.3.html new file mode 100644 index 0000000000..ec55dd984e --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/index.3.html @@ -0,0 +1,24 @@ + + + + + NgModule - Contact + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/ngmodule/ts/src/index.html b/public/docs/_examples/ngmodule/ts/src/index.html new file mode 100644 index 0000000000..9fc50c02a5 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/index.html @@ -0,0 +1,25 @@ + + + + + NgModule Deluxe + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/ngmodule/ts/src/main-static.ts b/public/docs/_examples/ngmodule/ts/src/main-static.ts new file mode 100644 index 0000000000..a1bcf466d2 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/main-static.ts @@ -0,0 +1,13 @@ +// #docplaster +/* +// #docregion +// The browser platform without a compiler +import { platformBrowser } from '@angular/platform-browser'; + +// The app module factory produced by the static offline compiler +import { AppModuleNgFactory } from './app/app.module.ngfactory'; + +// Launch with the app module factory. +platformBrowser().bootstrapModuleFactory(AppModuleNgFactory); +// #enddocregion +*/ diff --git a/public/docs/_examples/ngmodule/ts/src/main.0.ts b/public/docs/_examples/ngmodule/ts/src/main.0.ts new file mode 100644 index 0000000000..6d1d712f07 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/main.0.ts @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module.0'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/ngmodule/ts/src/main.1.ts b/public/docs/_examples/ngmodule/ts/src/main.1.ts new file mode 100644 index 0000000000..48129f4cc9 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/main.1.ts @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module.1'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/ngmodule/ts/src/main.1b.ts b/public/docs/_examples/ngmodule/ts/src/main.1b.ts new file mode 100644 index 0000000000..7a7bfae22f --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/main.1b.ts @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module.1b'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/ngmodule/ts/src/main.2.ts b/public/docs/_examples/ngmodule/ts/src/main.2.ts new file mode 100644 index 0000000000..c535e2e775 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/main.2.ts @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module.2'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/ngmodule/ts/src/main.3.ts b/public/docs/_examples/ngmodule/ts/src/main.3.ts new file mode 100644 index 0000000000..72f21dd142 --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/main.3.ts @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module.3'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/ngmodule/ts/src/main.ts b/public/docs/_examples/ngmodule/ts/src/main.ts new file mode 100644 index 0000000000..c8424d8c4c --- /dev/null +++ b/public/docs/_examples/ngmodule/ts/src/main.ts @@ -0,0 +1,9 @@ +// #docregion +// The browser platform with a compiler +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +// The app module +import { AppModule } from './app/app.module'; + +// Compile and launch the module +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/package.json b/public/docs/_examples/package.json index e783edfb73..41dc5e5b56 100644 --- a/public/docs/_examples/package.json +++ b/public/docs/_examples/package.json @@ -1,80 +1,89 @@ { - "name": "angular2-examples-master", + "name": "angular-examples-master", "version": "1.0.0", - "description": "Master package.json, the superset of all dependencies for all of the _example package.json files.", + "private": true, + "description": "Master package.json, the superset of all dependencies for all of the _example package.json files. See _boilerplate/package.json for example npm scripts.", "scripts": { - "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ", - "e2e": "tsc && concurrently \"http-server\" \"protractor protractor.config.js\"", - "http-server": "tsc && http-server", - "http-server:e2e": "http-server", - "lite": "lite-server", - "postinstall": "typings install", - "test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"", - "tsc": "tsc", - "tsc:w": "tsc -w", - "typings": "typings", + "http-server": "http-server", "protractor": "protractor", - "webdriver:update": "webdriver-manager update", - "start:webpack": "webpack-dev-server --inline --progress --port 8080", - "test:webpack": "karma start karma.webpack.conf.js", - "build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail" + "webdriver:update": "webdriver-manager update --standalone false --gecko false" }, "keywords": [], "author": "", - "license": "ISC", + "license": "MIT", "dependencies": { - "@angular/common": "2.0.0-rc.1", - "@angular/compiler": "2.0.0-rc.1", - "@angular/core": "2.0.0-rc.1", - "@angular/http": "2.0.0-rc.1", - "@angular/platform-browser": "2.0.0-rc.1", - "@angular/platform-browser-dynamic": "2.0.0-rc.1", - "@angular/router": "2.0.0-rc.1", - "@angular/router-deprecated": "2.0.0-rc.1", - "@angular/upgrade": "2.0.0-rc.1", - - "systemjs": "0.19.27", - "core-js": "^2.4.0", - "reflect-metadata": "^0.1.3", - "rxjs": "5.0.0-beta.6", - "zone.js": "^0.6.12", - - "angular2-in-memory-web-api": "0.0.11", - "bootstrap": "^3.3.6" + "@angular/animations": "~4.0.0", + "@angular/common": "~4.0.0", + "@angular/compiler": "~4.0.0", + "@angular/compiler-cli": "~4.0.0", + "@angular/core": "~4.0.0", + "@angular/forms": "~4.0.0", + "@angular/http": "~4.0.0", + "@angular/platform-browser": "~4.0.0", + "@angular/platform-browser-dynamic": "~4.0.0", + "@angular/platform-server": "~4.0.0", + "@angular/router": "~4.0.0", + "@angular/tsc-wrapped": "~4.0.0", + "@angular/upgrade": "~4.0.0", + "angular-in-memory-web-api": "~0.3.1", + "core-js": "^2.4.1", + "rxjs": "5.0.1", + "systemjs": "0.19.39", + "zone.js": "^0.8.4" }, "devDependencies": { + "@angular/cli": "^1.0.0", + "@types/angular": "^1.5.16", + "@types/angular-animate": "^1.5.5", + "@types/angular-cookies": "^1.4.2", + "@types/angular-mocks": "^1.5.5", + "@types/angular-resource": "^1.5.6", + "@types/angular-route": "^1.3.2", + "@types/angular-sanitize": "^1.3.3", + "@types/jasmine": "2.5.36", + "@types/node": "^6.0.45", + "angular2-template-loader": "^0.6.0", + "awesome-typescript-loader": "^3.0.4", + "babel-cli": "^6.16.0", + "babel-preset-angular2": "^0.0.2", + "babel-preset-es2015": "^6.16.0", "canonical-path": "0.0.2", - "concurrently": "^2.0.0", - "css-loader": "^0.23.1", - "extract-text-webpack-plugin": "^1.0.1", - "file-loader": "^0.8.5", + "concurrently": "^3.0.0", + "css-loader": "^0.26.1", + "extract-text-webpack-plugin": "2.0.0-beta.5", + "file-loader": "^0.9.0", "html-loader": "^0.4.3", "html-webpack-plugin": "^2.16.1", "http-server": "^0.9.0", - "jasmine-core": "^2.4.1", - "karma": "^0.13.22", - "karma-chrome-launcher": "^1.0.1", - "karma-cli": "^1.0.0", - "karma-htmlfile-reporter": "^0.3.1", + "jasmine": "~2.4.1", + "jasmine-core": "~2.4.1", + "karma": "^1.3.0", + "karma-chrome-launcher": "^2.0.0", + "karma-cli": "^1.0.1", "karma-jasmine": "^1.0.2", - "karma-phantomjs-launcher": "^1.0.0", + "karma-jasmine-html-reporter": "^0.2.2", + "karma-phantomjs-launcher": "^1.0.2", "karma-sourcemap-loader": "^0.3.7", - "karma-webpack": "^1.7.0", - "lite-server": "^2.2.0", - "lodash": "^4.11.1", + "karma-webpack": "^2.0.1", + "lite-server": "^2.2.2", + "lodash": "^4.16.2", "null-loader": "^0.1.1", "phantomjs-prebuilt": "^2.1.7", - "protractor": "^3.3.0", + "protractor": "~4.0.14", "raw-loader": "^0.5.1", - "rimraf": "^2.5.2", + "rimraf": "^2.5.4", + "rollup": "^0.41.6", + "rollup-plugin-commonjs": "^8.0.2", + "rollup-plugin-node-resolve": "2.0.0", + "rollup-plugin-uglify": "^1.0.1", + "source-map-explorer": "^1.3.2", "style-loader": "^0.13.1", - "ts-loader": "^0.8.2", - "ts-node": "^0.7.3", - "typescript": "^1.8.10", - "typings": "^1.0.4", - "webpack": "^1.13.0", - "webpack-dev-server": "^1.14.1", - "webpack-merge": "^0.14.0" + "ts-node": "^1.3.0", + "tslint": "^3.15.1", + "typescript": "~2.2.0", + "webpack": "2.2.1", + "webpack-dev-server": "2.4.1", + "webpack-merge": "^3.0.0" }, "repository": {} } diff --git a/public/docs/_examples/pipes/dart/lib/app_component.dart b/public/docs/_examples/pipes/dart/lib/app_component.dart deleted file mode 100644 index 85b32279a2..0000000000 --- a/public/docs/_examples/pipes/dart/lib/app_component.dart +++ /dev/null @@ -1,27 +0,0 @@ -// #docregion -import 'package:angular2/angular2.dart'; - -import 'flying_heroes_component.dart'; -import 'hero_async_message_component.dart'; -import 'hero_birthday1_component.dart'; -import 'hero_birthday2_component.dart'; -import 'hero_list_component.dart'; -import 'power_boost_calculator_component.dart'; -import 'power_booster_component.dart'; - -@Component( - selector: 'my-app', - templateUrl: 'app_component.html', - directives: const [ - FlyingHeroesComponent, - FlyingHeroesImpureComponent, - HeroAsyncMessageComponent, - HeroBirthday, - HeroBirthday2, - HeroListComponent, - PowerBoostCalculator, - PowerBooster, - ]) -class AppComponent { - DateTime birthday = new DateTime(1988, 4, 15); // April 15, 1988 -} diff --git a/public/docs/_examples/pipes/dart/lib/app_component.html b/public/docs/_examples/pipes/dart/lib/app_component.html deleted file mode 100644 index a27d587fcd..0000000000 --- a/public/docs/_examples/pipes/dart/lib/app_component.html +++ /dev/null @@ -1,83 +0,0 @@ - -

    Pipes

    -Happy Birthday v1
    -Birthday DatePipe
    -Happy Birthday v2
    -Birthday Pipe Chaining
    -Power Booster custom pipe
    -Power Boost Calculator custom pipe with params
    -Flying Heroes filter pipe (pure)
    -Flying Heroes filter pipe (impure)
    -Async Hero Message and AsyncPipe
    -Hero List with caching FetchJsonPipe
    - - -
    - -

    Hero Birthday v1

    - - -
    - -

    Birthday DatePipe

    - -

    The hero's birthday is {{ birthday | date }}

    - - - -

    The hero's birthday is {{ birthday | date:"MM/dd/yy" }}

    - - -
    - -

    Hero Birthday v2

    - - -
    - -

    Birthday Pipe Chaining

    -

    - - The chained hero's birthday is - {{ birthday | date | uppercase}} - -

    - -

    - - The chained hero's birthday is - {{ birthday | date:'fullDate' | uppercase}} - -

    -

    - - The chained hero's birthday is - {{ ( birthday | date:'fullDate' ) | uppercase}} - -

    -
    - - - -
    - -loading - -
    - - - -
    - - - -
    - - - - -
    - - - -
    diff --git a/public/docs/_examples/pipes/dart/lib/exponential_strength_pipe.dart b/public/docs/_examples/pipes/dart/lib/exponential_strength_pipe.dart deleted file mode 100644 index 1e66b9c791..0000000000 --- a/public/docs/_examples/pipes/dart/lib/exponential_strength_pipe.dart +++ /dev/null @@ -1,25 +0,0 @@ -// #docregion -import 'dart:math' as math; -import 'package:angular2/angular2.dart'; - -/* - * Raise the value exponentially - * Takes an exponent argument that defaults to 1. - * Usage: - * value | exponentialStrength:exponent - * Example: - * {{ 2 | exponentialStrength:10}} - * formats to: 1024 - */ -@Pipe(name: 'exponentialStrength') -class ExponentialStrengthPipe extends PipeTransform { - num transform(dynamic _value, [List args]) { - var exponent = args.isEmpty - ? 1 - : args.first is num - ? args.first - : num.parse(args.first.toString(), (_) => 1); - var value = _value is num ? _value : num.parse(_value.toString(), (_) => 0); - return math.pow(value, exponent); - } -} diff --git a/public/docs/_examples/pipes/dart/lib/fetch_json_pipe.dart b/public/docs/_examples/pipes/dart/lib/fetch_json_pipe.dart deleted file mode 100644 index 4ff5eab8d9..0000000000 --- a/public/docs/_examples/pipes/dart/lib/fetch_json_pipe.dart +++ /dev/null @@ -1,24 +0,0 @@ -// #docregion -import 'dart:convert'; -import 'dart:html'; - -import 'package:angular2/angular2.dart'; - -// #docregion pipe-metadata -@Pipe(name: 'fetch', pure: false) -// #enddocregion pipe-metadata -class FetchJsonPipe extends PipeTransform { - dynamic _fetchedJson; - String _prevUrl; - - dynamic transform(dynamic url, [List args]) { - if (url != _prevUrl) { - _prevUrl = url; - _fetchedJson = null; - HttpRequest.getString(url).then((s) { - _fetchedJson = JSON.decode(s); - }); - } - return _fetchedJson; - } -} diff --git a/public/docs/_examples/pipes/dart/lib/flying_heroes_component.dart b/public/docs/_examples/pipes/dart/lib/flying_heroes_component.dart deleted file mode 100644 index 040bc6ae37..0000000000 --- a/public/docs/_examples/pipes/dart/lib/flying_heroes_component.dart +++ /dev/null @@ -1,66 +0,0 @@ -// #docplaster -// #docregion -import 'package:angular2/angular2.dart'; -import 'flying_heroes_pipe.dart'; -import 'heroes.dart'; - -@Component( - selector: 'flying-heroes', - templateUrl: 'flying_heroes_component.html', - styles: const ['#flyers, #all {font-style: italic}'], - pipes: const [FlyingHeroesPipe]) -// #docregion v1 -class FlyingHeroesComponent { - List heroes; - bool canFly = true; - // #enddocregion v1 - bool mutate = true; - String title = 'Flying Heroes (pure pipe)'; - - // #docregion v1 - FlyingHeroesComponent() { - reset(); - } - - void addHero(String name) { - name = name.trim(); - if (name.isEmpty) return; - - var hero = new Hero(name, canFly); - // #enddocregion v1 - if (mutate) { - // Pure pipe won't update display because heroes list - // reference is unchanged; Impure pipe will display. - // #docregion v1, push - heroes.add(hero); - // #enddocregion v1, push - } else { - // Pipe updates display because heroes list is a new object - // #docregion concat - heroes = new List.from(heroes)..add(hero); - // #enddocregion concat - } - // #docregion v1 - } - - void reset() { - heroes = new List.from(mockHeroes); - } -} -// #enddocregion v1 - -//\\\\ Identical except for impure pipe \\\\\\ -// #docregion impure-component -@Component( - selector: 'flying-heroes-impure', - templateUrl: 'flying_heroes_component.html', - // #enddocregion impure-component - styles: const ['.flyers, .all {font-style: italic}'], - // #docregion impure-component - pipes: const [FlyingHeroesImpurePipe]) -class FlyingHeroesImpureComponent extends FlyingHeroesComponent { - FlyingHeroesImpureComponent() { - title = 'Flying Heroes (impure pipe)'; - } -} -// #docregion impure-component diff --git a/public/docs/_examples/pipes/dart/lib/flying_heroes_component.html b/public/docs/_examples/pipes/dart/lib/flying_heroes_component.html deleted file mode 100644 index 5d2a5d8a40..0000000000 --- a/public/docs/_examples/pipes/dart/lib/flying_heroes_component.html +++ /dev/null @@ -1,38 +0,0 @@ - - -

    {{title}}

    -

    - -New hero: - - - can fly -

    -

    - Mutate array - - - -

    - -

    Heroes who fly (piped)

    -
    - -
    - {{hero.name}} -
    - -
    - -

    All Heroes (no pipe)

    -
    - - -
    - {{hero.name}} -
    - - -
    diff --git a/public/docs/_examples/pipes/dart/lib/flying_heroes_pipe.dart b/public/docs/_examples/pipes/dart/lib/flying_heroes_pipe.dart deleted file mode 100644 index fe20fe1ea3..0000000000 --- a/public/docs/_examples/pipes/dart/lib/flying_heroes_pipe.dart +++ /dev/null @@ -1,19 +0,0 @@ -// #docregion -// #docregion pure -import 'package:angular2/angular2.dart'; -import 'heroes.dart'; - -@Pipe(name: 'flyingHeroes') -class FlyingHeroesPipe extends PipeTransform { - // #docregion filter - List transform(dynamic value, [List args]) => - value.where((hero) => hero.canFly).toList(); - // #enddocregion filter -} -// #enddocregion pure - -// Identical except for the pure flag -// #docregion impure, pipe-decorator -@Pipe(name: 'flyingHeroes', pure: false) -// #enddocregion pipe-decorator -class FlyingHeroesImpurePipe extends FlyingHeroesPipe {} diff --git a/public/docs/_examples/pipes/dart/lib/hero_async_message_component.dart b/public/docs/_examples/pipes/dart/lib/hero_async_message_component.dart deleted file mode 100644 index c3ab0dee94..0000000000 --- a/public/docs/_examples/pipes/dart/lib/hero_async_message_component.dart +++ /dev/null @@ -1,32 +0,0 @@ -// #docregion -import 'dart:async'; - -import 'package:angular2/angular2.dart'; - -@Component( - selector: 'hero-message', - template: ''' -

    Async Hero Message and AsyncPipe

    -

    Message: {{ message | async }}

    - - ''') -class HeroAsyncMessageComponent { - static const _msgEventDelay = const Duration(milliseconds: 500); - - Stream message; - - HeroAsyncMessageComponent() { - resend(); - } - - void resend() { - message = - new Stream.periodic(_msgEventDelay, (i) => _msgs[i]).take(_msgs.length); - } - - List _msgs = [ - 'You are my hero!', - 'You are the best hero!', - 'Will you be my hero?' - ]; -} diff --git a/public/docs/_examples/pipes/dart/lib/hero_birthday1_component.dart b/public/docs/_examples/pipes/dart/lib/hero_birthday1_component.dart deleted file mode 100644 index accb756c37..0000000000 --- a/public/docs/_examples/pipes/dart/lib/hero_birthday1_component.dart +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -import 'package:angular2/angular2.dart'; - -@Component( - selector: 'hero-birthday', - // #docregion hero-birthday-template - template: "

    The hero's birthday is {{ birthday | date }}

    " - // #enddocregion hero-birthday-template - ) -class HeroBirthday { - DateTime birthday = new DateTime(1988, 4, 15); // April 15, 1988 -} diff --git a/public/docs/_examples/pipes/dart/lib/hero_birthday2_component.dart b/public/docs/_examples/pipes/dart/lib/hero_birthday2_component.dart deleted file mode 100644 index eb76d84859..0000000000 --- a/public/docs/_examples/pipes/dart/lib/hero_birthday2_component.dart +++ /dev/null @@ -1,24 +0,0 @@ -// #docregion -import 'package:angular2/angular2.dart'; - -@Component( - selector: 'hero-birthday2', - // #docregion template - template: ''' -

    The hero's birthday is {{ birthday | date:format }}

    - - ''' - // #enddocregion template - ) -// #docregion class -class HeroBirthday2 { - DateTime birthday = new DateTime(1988, 4, 15); // April 15, 1988 - - bool toggle = true; - - get format => toggle ? 'shortDate' : 'fullDate'; - - void toggleFormat() { - toggle = !toggle; - } -} diff --git a/public/docs/_examples/pipes/dart/lib/hero_list_component.dart b/public/docs/_examples/pipes/dart/lib/hero_list_component.dart deleted file mode 100644 index 6088fa547f..0000000000 --- a/public/docs/_examples/pipes/dart/lib/hero_list_component.dart +++ /dev/null @@ -1,21 +0,0 @@ -// #docregion -import 'package:angular2/angular2.dart'; - -import 'fetch_json_pipe.dart'; - -@Component( - selector: 'hero-list', - // #docregion template - template: ''' -

    Heroes from JSON File

    - -
    - {{hero['name']}} -
    - -

    Heroes as JSON: - {{'heroes.json' | fetch | json}} -

    - ''', - pipes: const [FetchJsonPipe]) -class HeroListComponent {} diff --git a/public/docs/_examples/pipes/dart/lib/heroes.dart b/public/docs/_examples/pipes/dart/lib/heroes.dart deleted file mode 100644 index 2c06ca83cc..0000000000 --- a/public/docs/_examples/pipes/dart/lib/heroes.dart +++ /dev/null @@ -1,15 +0,0 @@ -class Hero { - final String name; - final bool canFly; - - const Hero(this.name, this.canFly); - - String toString() => "$name (${canFly ? 'can fly' : 'doesn\'t fly'})"; -} - -const List mockHeroes = const [ - const Hero("Windstorm", true), - const Hero("Bombasto", false), - const Hero("Magneto", false), - const Hero("Tornado", true), -]; diff --git a/public/docs/_examples/pipes/dart/lib/power_boost_calculator_component.dart b/public/docs/_examples/pipes/dart/lib/power_boost_calculator_component.dart deleted file mode 100644 index 7c726ce511..0000000000 --- a/public/docs/_examples/pipes/dart/lib/power_boost_calculator_component.dart +++ /dev/null @@ -1,19 +0,0 @@ -// #docregion -import 'package:angular2/angular2.dart'; -import 'exponential_strength_pipe.dart'; - -@Component( - selector: 'power-boost-calculator', - template: ''' -

    Power Boost Calculator

    -
    Normal power:
    -
    Boost factor:
    -

    - Super Hero Power: {{power | exponentialStrength: factor}} -

    - ''', - pipes: const [ExponentialStrengthPipe]) -class PowerBoostCalculator { - num power = 5; - num factor = 1; -} diff --git a/public/docs/_examples/pipes/dart/lib/power_booster_component.dart b/public/docs/_examples/pipes/dart/lib/power_booster_component.dart deleted file mode 100644 index 9152a2cc52..0000000000 --- a/public/docs/_examples/pipes/dart/lib/power_booster_component.dart +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -import 'package:angular2/angular2.dart'; -import 'exponential_strength_pipe.dart'; - -@Component( - selector: 'power-booster', - template: ''' -

    Power Booster

    -

    Super power boost: {{2 | exponentialStrength: 10}}

    - ''', - pipes: const [ExponentialStrengthPipe]) -class PowerBooster {} diff --git a/public/docs/_examples/pipes/dart/pubspec.yaml b/public/docs/_examples/pipes/dart/pubspec.yaml deleted file mode 100644 index ff1fc42531..0000000000 --- a/public/docs/_examples/pipes/dart/pubspec.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# #docregion -name: pipe_examples -description: Pipes Example -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.15 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: 'package:angular2/common.dart#COMMON_DIRECTIVES' - platform_pipes: 'package:angular2/common.dart#COMMON_PIPES' - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/pipes/dart/web/heroes.json b/public/docs/_examples/pipes/dart/web/heroes.json deleted file mode 100644 index 436b220d53..0000000000 --- a/public/docs/_examples/pipes/dart/web/heroes.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - {"name": "Windstorm"}, - {"name": "Bombasto"}, - {"name": "Magneto"}, - {"name": "Tornado"} -] diff --git a/public/docs/_examples/pipes/dart/web/index.html b/public/docs/_examples/pipes/dart/web/index.html deleted file mode 100644 index 01bdf05322..0000000000 --- a/public/docs/_examples/pipes/dart/web/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - Pipes Example - - - - - - - my-app loading ... - - - diff --git a/public/docs/_examples/pipes/dart/web/main.dart b/public/docs/_examples/pipes/dart/web/main.dart deleted file mode 100644 index 98e9c1b34b..0000000000 --- a/public/docs/_examples/pipes/dart/web/main.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:angular2/platform/browser.dart'; - -import 'package:pipe_examples/app_component.dart'; -import 'package:pipe_examples/hero_birthday1_component.dart'; - -main() { - bootstrap(AppComponent); - bootstrap(HeroBirthday); -} diff --git a/public/docs/_examples/pipes/e2e-spec.ts b/public/docs/_examples/pipes/e2e-spec.ts index 9b626d48bb..00277e3657 100644 --- a/public/docs/_examples/pipes/e2e-spec.ts +++ b/public/docs/_examples/pipes/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Pipes', function () { beforeAll(function () { @@ -7,7 +10,7 @@ describe('Pipes', function () { it('should open correctly', function () { expect(element.all(by.tagName('h1')).get(0).getText()).toEqual('Pipes'); - expect(element(by.css('hero-birthday p')).getText()).toEqual("The hero's birthday is Apr 15, 1988"); + expect(element(by.css('hero-birthday p')).getText()).toEqual(`The hero's birthday is Apr 15, 1988`); }); it('should show 4 heroes', function () { @@ -19,23 +22,23 @@ describe('Pipes', function () { }); it('should show alternate birthday formats', function () { - expect(element(by.cssContainingText('my-app > p', "The hero's birthday is Apr 15, 1988")).isDisplayed()).toBe(true); - expect(element(by.cssContainingText('my-app > p', "The hero's birthday is 04/15/88")).isDisplayed()).toBe(true); + expect(element(by.cssContainingText('my-app > p', `The hero's birthday is Apr 15, 1988`)).isDisplayed()).toBe(true); + expect(element(by.cssContainingText('my-app > p', `The hero's birthday is 04/15/88`)).isDisplayed()).toBe(true); }); it('should be able to toggle birthday formats', function () { let birthDayEle = element(by.css('hero-birthday2 > p')); - expect(birthDayEle.getText()).toEqual("The hero's birthday is 4/15/1988"); - let buttonEle = element(by.cssContainingText('hero-birthday2 > button', "Toggle Format")); + expect(birthDayEle.getText()).toEqual(`The hero's birthday is 4/15/1988`); + let buttonEle = element(by.cssContainingText('hero-birthday2 > button', 'Toggle Format')); expect(buttonEle.isDisplayed()).toBe(true); buttonEle.click().then(function() { - expect(birthDayEle.getText()).toEqual("The hero's birthday is Friday, April 15, 1988"); + expect(birthDayEle.getText()).toEqual(`The hero's birthday is Friday, April 15, 1988`); }); }); it('should be able to chain and compose pipes', function () { - let chainedPipeEles = element.all(by.cssContainingText('my-app p', "The chained hero's")); - expect(chainedPipeEles.count()).toBe(3, "should have 3 chained pipe examples"); + let chainedPipeEles = element.all(by.cssContainingText('my-app p', `The chained hero's`)); + expect(chainedPipeEles.count()).toBe(3, 'should have 3 chained pipe examples'); expect(chainedPipeEles.get(0).getText()).toContain('APR 15, 1988'); expect(chainedPipeEles.get(1).getText()).toContain('FRIDAY, APRIL 15, 1988'); expect(chainedPipeEles.get(2).getText()).toContain('FRIDAY, APRIL 15, 1988'); @@ -52,13 +55,11 @@ describe('Pipes', function () { let factorInputEle = eles.get(1); let outputEle = element(by.css('power-boost-calculator p')); baseInputEle.clear().then(function() { - return sendKeys(baseInputEle, "7"); - }).then(function() { + baseInputEle.sendKeys('7'); return factorInputEle.clear(); }).then(function() { - return sendKeys(factorInputEle, "3"); - }).then(function() { - expect(outputEle.getText()).toContain("343"); + factorInputEle.sendKeys('3'); + expect(outputEle.getText()).toContain('343'); }); }); @@ -73,16 +74,11 @@ describe('Pipes', function () { expect(canFlyCheckEle.getAttribute('checked')).toEqual('true', 'should default to "can fly"'); expect(mutateCheckEle.getAttribute('checked')).toEqual('true', 'should default to mutating array'); expect(flyingHeroesEle.count()).toEqual(2, 'only two of the original heroes can fly'); - - return sendKeys(nameEle, "test1\n") - .then(function(){ - expect(flyingHeroesEle.count()).toEqual(2, 'no change while mutating array'); - return mutateCheckEle.click(); - }) - .then(function() { - return sendKeys(nameEle, "test2\n"); - }) - .then(function() { + + nameEle.sendKeys('test1\n'); + expect(flyingHeroesEle.count()).toEqual(2, 'no change while mutating array'); + mutateCheckEle.click().then(function() { + nameEle.sendKeys('test2\n'); expect(flyingHeroesEle.count()).toEqual(4, 'not mutating; should see both adds'); expect(flyingHeroesEle.get(2).getText()).toContain('test1'); expect(flyingHeroesEle.get(3).getText()).toContain('test2'); @@ -90,25 +86,22 @@ describe('Pipes', function () { }) .then(function() { expect(flyingHeroesEle.count()).toEqual(2, 'reset should restore orginal flying heroes'); - }) + }); }); - - + + it('should support flying heroes (impure) ', function () { let nameEle = element(by.css('flying-heroes-impure input[type="text"]')); - let canFlyCheckEle = element(by.css('flying-heroes-impure #can-fly')); + let canFlyCheckEle = element(by.css('flying-heroes-impure #can-fly')); let mutateCheckEle = element(by.css('flying-heroes-impure #mutate')); - let resetEle = element(by.css('flying-heroes-impure button')); let flyingHeroesEle = element.all(by.css('flying-heroes-impure #flyers div')); expect(canFlyCheckEle.getAttribute('checked')).toEqual('true', 'should default to "can fly"'); expect(mutateCheckEle.getAttribute('checked')).toEqual('true', 'should default to mutating array'); expect(flyingHeroesEle.count()).toEqual(2, 'only two of the original heroes can fly'); - - return sendKeys(nameEle, "test1\n") - .then(function(){ - expect(flyingHeroesEle.count()).toEqual(3, 'new flying hero should show in mutating array'); - }) + + nameEle.sendKeys('test1\n'); + expect(flyingHeroesEle.count()).toEqual(3, 'new flying hero should show in mutating array'); }); it('should show an async hero message', function () { diff --git a/public/docs/_examples/pipes/ts/app/app.component.ts b/public/docs/_examples/pipes/ts/app/app.component.ts deleted file mode 100644 index c79c1305df..0000000000 --- a/public/docs/_examples/pipes/ts/app/app.component.ts +++ /dev/null @@ -1,29 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { HTTP_PROVIDERS } from '@angular/http'; - -import { FlyingHeroesComponent, - FlyingHeroesImpureComponent } from './flying-heroes.component'; -import { HeroAsyncMessageComponent } from './hero-async-message.component'; -import { HeroBirthday } from './hero-birthday1.component'; -import { HeroBirthday2 } from './hero-birthday2.component'; -import { HeroListComponent } from './hero-list.component'; -import { PowerBooster } from './power-booster.component'; -import { PowerBoostCalculator } from './power-boost-calculator.component'; - -@Component({ - selector: 'my-app', - templateUrl: 'app/app.component.html', - directives:[ - FlyingHeroesComponent, FlyingHeroesImpureComponent, - HeroAsyncMessageComponent, - HeroBirthday, - HeroBirthday2, - HeroListComponent, - PowerBooster, PowerBoostCalculator - ], - providers:[HTTP_PROVIDERS] -}) -export class AppComponent { - birthday = new Date(1988,3,15); // April 15, 1988 -} diff --git a/public/docs/_examples/pipes/ts/app/fetch-json.pipe.ts b/public/docs/_examples/pipes/ts/app/fetch-json.pipe.ts deleted file mode 100644 index 72fd58e178..0000000000 --- a/public/docs/_examples/pipes/ts/app/fetch-json.pipe.ts +++ /dev/null @@ -1,28 +0,0 @@ -// #docregion -import { Pipe, PipeTransform } from '@angular/core'; -import { Http } from '@angular/http'; - -// #docregion pipe-metadata -@Pipe({ - name: 'fetch', - pure: false -}) -// #enddocregion pipe-metadata -export class FetchJsonPipe implements PipeTransform{ - private fetchedJson: any = null; - private prevUrl = ''; - - constructor(private _http: Http) { } - - transform(url: string): any { - if (url !== this.prevUrl) { - this.prevUrl = url; - this.fetchedJson = null; - this._http.get(url) - .map( result => result.json() ) - .subscribe( result => this.fetchedJson = result ); - } - - return this.fetchedJson; - } -} diff --git a/public/docs/_examples/pipes/ts/app/hero-birthday1.component.ts b/public/docs/_examples/pipes/ts/app/hero-birthday1.component.ts deleted file mode 100644 index 52a462757b..0000000000 --- a/public/docs/_examples/pipes/ts/app/hero-birthday1.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -import { Component } from '@angular/core' - -@Component({ - selector: 'hero-birthday', - // #docregion hero-birthday-template - template: `

    The hero's birthday is {{ birthday | date }}

    ` - // #enddocregion hero-birthday-template -}) -export class HeroBirthday { - birthday = new Date(1988,3,15); // April 15, 1988 -} diff --git a/public/docs/_examples/pipes/ts/app/hero-list.component.ts b/public/docs/_examples/pipes/ts/app/hero-list.component.ts deleted file mode 100644 index 0b9d8df37e..0000000000 --- a/public/docs/_examples/pipes/ts/app/hero-list.component.ts +++ /dev/null @@ -1,23 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { FetchJsonPipe } from './fetch-json.pipe'; - -@Component({ - selector: 'hero-list', - // #docregion template - template: ` -

    Heroes from JSON File

    - -
    - {{hero.name}} -
    - -

    Heroes as JSON: - {{'heroes.json' | fetch | json}} -

    - `, - // #enddocregion template - pipes: [FetchJsonPipe] -}) -export class HeroListComponent { } diff --git a/public/docs/_examples/pipes/ts/app/heroes.ts b/public/docs/_examples/pipes/ts/app/heroes.ts deleted file mode 100644 index fe30ad84f4..0000000000 --- a/public/docs/_examples/pipes/ts/app/heroes.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface Flyer { canFly: boolean } -export const HEROES = [ - {"name": "Windstorm", "canFly": true}, - {"name": "Bombasto", "canFly": false}, - {"name": "Magneto", "canFly": false}, - {"name": "Tornado", "canFly": true} -]; \ No newline at end of file diff --git a/public/docs/_examples/pipes/ts/app/main.ts b/public/docs/_examples/pipes/ts/app/main.ts deleted file mode 100644 index dd9994d2b6..0000000000 --- a/public/docs/_examples/pipes/ts/app/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; -import 'rxjs/Rx'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); diff --git a/public/docs/_examples/pipes/ts/app/power-boost-calculator.component.ts b/public/docs/_examples/pipes/ts/app/power-boost-calculator.component.ts deleted file mode 100644 index 549056afb1..0000000000 --- a/public/docs/_examples/pipes/ts/app/power-boost-calculator.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { ExponentialStrengthPipe } from './exponential-strength.pipe'; - -@Component({ - selector: 'power-boost-calculator', - template: ` -

    Power Boost Calculator

    -
    Normal power:
    -
    Boost factor:
    -

    - Super Hero Power: {{power | exponentialStrength: factor}} -

    - `, - pipes: [ExponentialStrengthPipe] -}) -export class PowerBoostCalculator { - power = 5; - factor = 1; -} diff --git a/public/docs/_examples/pipes/ts/app/power-booster.component.ts b/public/docs/_examples/pipes/ts/app/power-booster.component.ts deleted file mode 100644 index 78c6f9c127..0000000000 --- a/public/docs/_examples/pipes/ts/app/power-booster.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { ExponentialStrengthPipe } from './exponential-strength.pipe'; - -@Component({ - selector: 'power-booster', - template: ` -

    Power Booster

    -

    Super power boost: {{2 | exponentialStrength: 10}}

    - `, - pipes: [ExponentialStrengthPipe] -}) -export class PowerBooster { } diff --git a/public/docs/_examples/pipes/ts/index.html b/public/docs/_examples/pipes/ts/index.html deleted file mode 100644 index 0b1a46f328..0000000000 --- a/public/docs/_examples/pipes/ts/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - Pipes - - - - - - - - - - - - - - - - - my-app loading ... - - - diff --git a/public/docs/_examples/pipes/ts/plnkr.json b/public/docs/_examples/pipes/ts/plnkr.json index 60e5a54c08..3c07266109 100644 --- a/public/docs/_examples/pipes/ts/plnkr.json +++ b/public/docs/_examples/pipes/ts/plnkr.json @@ -1,7 +1,8 @@ { "description": "Pipes", + "basePath": "src/", "files":[ "!**/*.d.ts", "!**/*.js"], "tags": ["pipe"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/pipes/ts/app/app.component.html b/public/docs/_examples/pipes/ts/src/app/app.component.html similarity index 100% rename from public/docs/_examples/pipes/ts/app/app.component.html rename to public/docs/_examples/pipes/ts/src/app/app.component.html diff --git a/public/docs/_examples/pipes/ts/src/app/app.component.ts b/public/docs/_examples/pipes/ts/src/app/app.component.ts new file mode 100644 index 0000000000..090eae7766 --- /dev/null +++ b/public/docs/_examples/pipes/ts/src/app/app.component.ts @@ -0,0 +1,10 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html' +}) +export class AppComponent { + birthday = new Date(1988, 3, 15); // April 15, 1988 +} diff --git a/public/docs/_examples/pipes/ts/src/app/app.module.ts b/public/docs/_examples/pipes/ts/src/app/app.module.ts new file mode 100644 index 0000000000..89a3a29505 --- /dev/null +++ b/public/docs/_examples/pipes/ts/src/app/app.module.ts @@ -0,0 +1,48 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +import { AppComponent } from './app.component'; +import { + FlyingHeroesComponent, + FlyingHeroesImpureComponent +} from './flying-heroes.component'; +import { HeroAsyncMessageComponent } from './hero-async-message.component'; +import { HeroBirthdayComponent } from './hero-birthday1.component'; +import { HeroBirthday2Component } from './hero-birthday2.component'; +import { HeroListComponent } from './hero-list.component'; +import { PowerBoosterComponent } from './power-booster.component'; +import { PowerBoostCalculatorComponent } from './power-boost-calculator.component'; +import { + FlyingHeroesPipe, + FlyingHeroesImpurePipe +} from './flying-heroes.pipe'; +import { FetchJsonPipe } from './fetch-json.pipe'; +import { ExponentialStrengthPipe } from './exponential-strength.pipe'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HttpModule + ], + declarations: [ + AppComponent, + FlyingHeroesComponent, + FlyingHeroesImpureComponent, + HeroAsyncMessageComponent, + HeroBirthdayComponent, + HeroBirthday2Component, + HeroListComponent, + PowerBoosterComponent, + PowerBoostCalculatorComponent, + FlyingHeroesPipe, + FlyingHeroesImpurePipe, + FetchJsonPipe, + ExponentialStrengthPipe + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/pipes/ts/app/exponential-strength.pipe.ts b/public/docs/_examples/pipes/ts/src/app/exponential-strength.pipe.ts similarity index 100% rename from public/docs/_examples/pipes/ts/app/exponential-strength.pipe.ts rename to public/docs/_examples/pipes/ts/src/app/exponential-strength.pipe.ts diff --git a/public/docs/_examples/pipes/ts/src/app/fetch-json.pipe.ts b/public/docs/_examples/pipes/ts/src/app/fetch-json.pipe.ts new file mode 100644 index 0000000000..4d56e865f3 --- /dev/null +++ b/public/docs/_examples/pipes/ts/src/app/fetch-json.pipe.ts @@ -0,0 +1,30 @@ +// #docregion +import { Pipe, PipeTransform } from '@angular/core'; +import { Http } from '@angular/http'; + +import 'rxjs/add/operator/map'; + +// #docregion pipe-metadata +@Pipe({ + name: 'fetch', + pure: false +}) +// #enddocregion pipe-metadata +export class FetchJsonPipe implements PipeTransform { + private cachedData: any = null; + private cachedUrl = ''; + + constructor(private http: Http) { } + + transform(url: string): any { + if (url !== this.cachedUrl) { + this.cachedData = null; + this.cachedUrl = url; + this.http.get(url) + .map( result => result.json() ) + .subscribe( result => this.cachedData = result ); + } + + return this.cachedData; + } +} diff --git a/public/docs/_examples/pipes/ts/src/app/flying-heroes-impure.component.html b/public/docs/_examples/pipes/ts/src/app/flying-heroes-impure.component.html new file mode 100644 index 0000000000..66bd86f81c --- /dev/null +++ b/public/docs/_examples/pipes/ts/src/app/flying-heroes-impure.component.html @@ -0,0 +1,38 @@ + + +

    {{title}}

    +

    + +New hero: + + + can fly +

    +

    + Mutate array + + + +

    + +

    Heroes who fly (piped)

    +
    + +
    + {{hero.name}} +
    + +
    + +

    All Heroes (no pipe)

    +
    + + +
    + {{hero.name}} +
    + + +
    diff --git a/public/docs/_examples/pipes/ts/app/flying-heroes.component.html b/public/docs/_examples/pipes/ts/src/app/flying-heroes.component.html similarity index 100% rename from public/docs/_examples/pipes/ts/app/flying-heroes.component.html rename to public/docs/_examples/pipes/ts/src/app/flying-heroes.component.html diff --git a/public/docs/_examples/pipes/ts/app/flying-heroes.component.ts b/public/docs/_examples/pipes/ts/src/app/flying-heroes.component.ts similarity index 76% rename from public/docs/_examples/pipes/ts/app/flying-heroes.component.ts rename to public/docs/_examples/pipes/ts/src/app/flying-heroes.component.ts index 94323297ba..e4abb09a2f 100644 --- a/public/docs/_examples/pipes/ts/app/flying-heroes.component.ts +++ b/public/docs/_examples/pipes/ts/src/app/flying-heroes.component.ts @@ -2,19 +2,16 @@ // #docregion import { Component } from '@angular/core'; -import { FlyingHeroesPipe, - FlyingHeroesImpurePipe } from './flying-heroes.pipe'; import { HEROES } from './heroes'; @Component({ selector: 'flying-heroes', - templateUrl: 'app/flying-heroes.component.html', - styles: ['#flyers, #all {font-style: italic}'], - pipes: [FlyingHeroesPipe] + templateUrl: './flying-heroes.component.html', + styles: ['#flyers, #all {font-style: italic}'] }) // #docregion v1 export class FlyingHeroesComponent { - heroes:any[] = []; + heroes: any[] = []; canFly = true; // #enddocregion v1 mutate = true; @@ -23,7 +20,7 @@ export class FlyingHeroesComponent { // #docregion v1 constructor() { this.reset(); } - addHero(name:string) { + addHero(name: string) { name = name.trim(); if (!name) { return; } let hero = {name, canFly: this.canFly}; @@ -33,7 +30,7 @@ export class FlyingHeroesComponent { // Impure pipe will display // #docregion v1 // #docregion push - this.heroes.push(hero) + this.heroes.push(hero); // #enddocregion push // #enddocregion v1 } else { @@ -53,13 +50,12 @@ export class FlyingHeroesComponent { // #docregion impure-component @Component({ selector: 'flying-heroes-impure', - templateUrl: 'app/flying-heroes.component.html', + templateUrl: './flying-heroes-impure.component.html', // #enddocregion impure-component styles: ['.flyers, .all {font-style: italic}'], // #docregion impure-component - pipes: [FlyingHeroesImpurePipe] }) export class FlyingHeroesImpureComponent extends FlyingHeroesComponent { title = 'Flying Heroes (impure pipe)'; } -// #docregion impure-component +// #enddocregion impure-component diff --git a/public/docs/_examples/pipes/ts/app/flying-heroes.pipe.ts b/public/docs/_examples/pipes/ts/src/app/flying-heroes.pipe.ts similarity index 83% rename from public/docs/_examples/pipes/ts/app/flying-heroes.pipe.ts rename to public/docs/_examples/pipes/ts/src/app/flying-heroes.pipe.ts index 3dee7d6757..87db9c277e 100644 --- a/public/docs/_examples/pipes/ts/app/flying-heroes.pipe.ts +++ b/public/docs/_examples/pipes/ts/src/app/flying-heroes.pipe.ts @@ -1,3 +1,4 @@ +/* tslint:disable use-pipe-transform-interface */ // #docregion // #docregion pure import { Pipe, PipeTransform } from '@angular/core'; @@ -6,7 +7,7 @@ import { Flyer } from './heroes'; @Pipe({ name: 'flyingHeroes' }) export class FlyingHeroesPipe implements PipeTransform { - transform(allHeroes:Flyer[]) { + transform(allHeroes: Flyer[]) { // #docregion filter return allHeroes.filter(hero => hero.canFly); // #enddocregion filter @@ -18,7 +19,7 @@ export class FlyingHeroesPipe implements PipeTransform { // #docregion impure // #docregion pipe-decorator @Pipe({ - name: 'flyingHeroes', + name: 'flyingHeroesImpure', pure: false }) // #enddocregion pipe-decorator diff --git a/public/docs/_examples/pipes/ts/app/hero-async-message.component.ts b/public/docs/_examples/pipes/ts/src/app/hero-async-message.component.ts similarity index 80% rename from public/docs/_examples/pipes/ts/app/hero-async-message.component.ts rename to public/docs/_examples/pipes/ts/src/app/hero-async-message.component.ts index cced9f3e57..d5bbd9fb0e 100644 --- a/public/docs/_examples/pipes/ts/app/hero-async-message.component.ts +++ b/public/docs/_examples/pipes/ts/src/app/hero-async-message.component.ts @@ -1,6 +1,10 @@ // #docregion import { Component } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/interval'; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/take'; @Component({ selector: 'hero-message', @@ -10,7 +14,13 @@ import { Observable } from 'rxjs/Rx'; `, }) export class HeroAsyncMessageComponent { - message$:Observable; + message$: Observable; + + private messages = [ + 'You are my hero!', + 'You are the best hero!', + 'Will you be my hero?' + ]; constructor() { this.resend(); } @@ -19,12 +29,6 @@ export class HeroAsyncMessageComponent { .map(i => this.messages[i]) .take(this.messages.length); } - - private messages = [ - 'You are my hero!', - 'You are the best hero!', - 'Will you be my hero?' - ]; } // #enddocregion diff --git a/public/docs/_examples/pipes/ts/src/app/hero-birthday1.component.ts b/public/docs/_examples/pipes/ts/src/app/hero-birthday1.component.ts new file mode 100644 index 0000000000..a670a807a8 --- /dev/null +++ b/public/docs/_examples/pipes/ts/src/app/hero-birthday1.component.ts @@ -0,0 +1,12 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'hero-birthday', + // #docregion hero-birthday-template + template: `

    The hero's birthday is {{ birthday | date }}

    ` + // #enddocregion hero-birthday-template +}) +export class HeroBirthdayComponent { + birthday = new Date(1988, 3, 15); // April 15, 1988 +} diff --git a/public/docs/_examples/pipes/ts/app/hero-birthday2.component.ts b/public/docs/_examples/pipes/ts/src/app/hero-birthday2.component.ts similarity index 75% rename from public/docs/_examples/pipes/ts/app/hero-birthday2.component.ts rename to public/docs/_examples/pipes/ts/src/app/hero-birthday2.component.ts index 683f082e27..87481aa121 100644 --- a/public/docs/_examples/pipes/ts/app/hero-birthday2.component.ts +++ b/public/docs/_examples/pipes/ts/src/app/hero-birthday2.component.ts @@ -1,5 +1,5 @@ // #docregion -import { Component } from '@angular/core' +import { Component } from '@angular/core'; @Component({ selector: 'hero-birthday2', @@ -11,10 +11,10 @@ import { Component } from '@angular/core' // #enddocregion template }) // #docregion class -export class HeroBirthday2 { - birthday = new Date(1988,3,15); // April 15, 1988 +export class HeroBirthday2Component { + birthday = new Date(1988, 3, 15); // April 15, 1988 toggle = true; // start with true == shortDate - get format() { return this.toggle ? 'shortDate' : 'fullDate'} + get format() { return this.toggle ? 'shortDate' : 'fullDate'; } toggleFormat() { this.toggle = !this.toggle; } } diff --git a/public/docs/_examples/pipes/ts/src/app/hero-list.component.ts b/public/docs/_examples/pipes/ts/src/app/hero-list.component.ts new file mode 100644 index 0000000000..df231120ce --- /dev/null +++ b/public/docs/_examples/pipes/ts/src/app/hero-list.component.ts @@ -0,0 +1,17 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'hero-list', + template: ` +

    Heroes from JSON File

    + +
    + {{hero.name}} +
    + +

    Heroes as JSON: + {{'heroes.json' | fetch | json}} +

    ` +}) +export class HeroListComponent { } diff --git a/public/docs/_examples/pipes/ts/src/app/heroes.ts b/public/docs/_examples/pipes/ts/src/app/heroes.ts new file mode 100644 index 0000000000..b2edabe0da --- /dev/null +++ b/public/docs/_examples/pipes/ts/src/app/heroes.ts @@ -0,0 +1,7 @@ +export interface Flyer { canFly: boolean; } +export const HEROES = [ + {name: 'Windstorm', canFly: true}, + {name: 'Bombasto', canFly: false}, + {name: 'Magneto', canFly: false}, + {name: 'Tornado', canFly: true} +]; diff --git a/public/docs/_examples/pipes/ts/src/app/power-boost-calculator.component.ts b/public/docs/_examples/pipes/ts/src/app/power-boost-calculator.component.ts new file mode 100644 index 0000000000..e65e29ad4c --- /dev/null +++ b/public/docs/_examples/pipes/ts/src/app/power-boost-calculator.component.ts @@ -0,0 +1,18 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'power-boost-calculator', + template: ` +

    Power Boost Calculator

    +
    Normal power:
    +
    Boost factor:
    +

    + Super Hero Power: {{power | exponentialStrength: factor}} +

    + ` +}) +export class PowerBoostCalculatorComponent { + power = 5; + factor = 1; +} diff --git a/public/docs/_examples/pipes/ts/src/app/power-booster.component.ts b/public/docs/_examples/pipes/ts/src/app/power-booster.component.ts new file mode 100644 index 0000000000..08e3e24c7b --- /dev/null +++ b/public/docs/_examples/pipes/ts/src/app/power-booster.component.ts @@ -0,0 +1,11 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'power-booster', + template: ` +

    Power Booster

    +

    Super power boost: {{2 | exponentialStrength: 10}}

    + ` +}) +export class PowerBoosterComponent { } diff --git a/public/docs/_examples/pipes/ts/heroes.json b/public/docs/_examples/pipes/ts/src/heroes.json similarity index 100% rename from public/docs/_examples/pipes/ts/heroes.json rename to public/docs/_examples/pipes/ts/src/heroes.json diff --git a/public/docs/_examples/pipes/ts/src/index.html b/public/docs/_examples/pipes/ts/src/index.html new file mode 100644 index 0000000000..fedb5c2e5e --- /dev/null +++ b/public/docs/_examples/pipes/ts/src/index.html @@ -0,0 +1,26 @@ + + + + Pipes + + + + + + + + + + + + + + + + + my-app loading ... + + + diff --git a/public/docs/_examples/pipes/ts/src/main.ts b/public/docs/_examples/pipes/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/pipes/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/protractor-helpers.ts b/public/docs/_examples/protractor-helpers.ts new file mode 100644 index 0000000000..61af74ba30 --- /dev/null +++ b/public/docs/_examples/protractor-helpers.ts @@ -0,0 +1,35 @@ +import { browser } from 'protractor'; + +export var appLang = { + appIsTs: false, + appIsJs: false, + appIsDart: false, + appIsUnknown: false +}; + +export function describeIf(cond: boolean, name: string, func: () => void): void { + if (cond) { + describe(name, func); + } else { + xdescribe(name, func); + } +} + +export function itIf(cond: boolean, name: string, func: (done: DoneFn) => void): void { + if (cond) { + it(name, func); + } else { + xit(name, func); + } +} + +// protractor.config.js is set to ng2 mode by default, so we must manually +// change it for upgradeAdapter tests +export function setProtractorToNg1Mode(): void { + browser.rootEl = 'body'; +} + +export function setProtractorToHybridMode() { + setProtractorToNg1Mode(); + browser.ng12Hybrid = true; +} diff --git a/public/docs/_examples/_protractor/protractor.config.js b/public/docs/_examples/protractor.config.js similarity index 76% rename from public/docs/_examples/_protractor/protractor.config.js rename to public/docs/_examples/protractor.config.js index fc68f03b98..92b5e1fda5 100644 --- a/public/docs/_examples/_protractor/protractor.config.js +++ b/public/docs/_examples/protractor.config.js @@ -26,7 +26,7 @@ exports.config = { // Framework to use. Jasmine is recommended. framework: 'jasmine', - // For angular2 tests + // For angular tests useAllAngular2AppRoots: true, // Base URL for application server @@ -43,39 +43,23 @@ exports.config = { // debugging // console.log('browser.params:' + JSON.stringify(browser.params)); + var protractorHelpers = require('./protractor-helpers.ts'); var appDir = browser.params.appDir; if (appDir) { if (appDir.match('/ts') != null) { - browser.appIsTs = true; + protractorHelpers.appLang.appIsTs = true; } else if (appDir.match('/js') != null) { - browser.appIsJs = true; + protractorHelpers.appLang.appIsJs = true; } else if (appDir.match('/dart') != null) { - browser.appIsDart = true; + protractorHelpers.appLang.appIsDart = true; } else { - browser.appIsUnknown = true; + protractorHelpers.appLang.appIsUnknown = true; } } else { - browser.appIsUnknown = true; + protractorHelpers.appLang.appIsUnknown = true; } - jasmine.getEnv().addReporter(new Reporter( browser.params )) ; - global.describeIf = describeIf; - global.itIf = itIf; - global.sendKeys = sendKeys; - - // Allow changing bootstrap mode to NG1 for upgrade tests - global.setProtractorToNg1Mode = function() { - browser.useAllAngular2AppRoots = false; - browser.rootEl = 'body'; - - var disableNgAnimate = function() { - angular.module('disableNgAnimate', []).run(['$animate', function($animate) { - $animate.enabled(false); - }]); - }; - - browser.addMockModule('disableNgAnimate', disableNgAnimate); - }; + jasmine.getEnv().addReporter(new Reporter( browser.params )); }, jasmineNodeOpts: { @@ -87,40 +71,15 @@ exports.config = { beforeLaunch: function() { // add TS support for specs - require('ts-node').register(); - } -}; - -function describeIf(cond, name, func) { - if (cond) { - describe(name, func); - } else { - xdescribe(name, func); - } -} - -function itIf(cond, name, func) { - if (cond) { - it(name, func); - } else { - xit(name, func); - } -} - -// Hack - because of bug with protractor send keys -// Hack - because of bug with send keys -function sendKeys(element, str) { - return str.split('').reduce(function (promise, char) { - return promise.then(function () { - return element.sendKeys(char); + require('ts-node').register({ + project: './tsconfig.json' }); - }, element.getAttribute('value')); - // better to create a resolved promise here but ... don't know how with protractor; } +}; // See http://jasmine.github.io/2.1/custom_reporter.html function Reporter(options) { - var _defaultOutputFile = path.resolve(process.cwd(), "../../../../", 'protractor-results.txt'); + var _defaultOutputFile = path.resolve(process.cwd(), "../../../", 'protractor-results.txt'); options.outputFile = options.outputFile || _defaultOutputFile; var _root = { appDir: options.appDir, suites: [] }; diff --git a/public/docs/_examples/quickstart/dart/lib/app_component.dart b/public/docs/_examples/quickstart/dart/lib/app_component.dart deleted file mode 100644 index a54b6f7a1f..0000000000 --- a/public/docs/_examples/quickstart/dart/lib/app_component.dart +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -// #docregion import -import 'package:angular2/core.dart'; -// #enddocregion import - -// #docregion metadata -@Component( - selector: 'my-app', - template: '

    My First Angular 2 App

    ') -// #enddocregion metadata -// #docregion class -class AppComponent {} diff --git a/public/docs/_examples/quickstart/dart/pubspec.yaml b/public/docs/_examples/quickstart/dart/pubspec.yaml deleted file mode 100644 index 1144889e3d..0000000000 --- a/public/docs/_examples/quickstart/dart/pubspec.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# #docplaster -# #docregion -# #docregion no-rewriter -name: angular2_getting_started -description: QuickStart -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 -# #enddocregion no-rewriter - dart_to_js_script_rewriter: ^1.0.1 -# #docregion no-rewriter -transformers: -- angular2: - entry_points: web/main.dart -# #enddocregion no-rewriter -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/quickstart/dart/web/index.html b/public/docs/_examples/quickstart/dart/web/index.html deleted file mode 100644 index a1e925b8fb..0000000000 --- a/public/docs/_examples/quickstart/dart/web/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Getting Started - - - - - - - - - Loading... - - diff --git a/public/docs/_examples/quickstart/dart/web/main.dart b/public/docs/_examples/quickstart/dart/web/main.dart deleted file mode 100644 index 19b47a1237..0000000000 --- a/public/docs/_examples/quickstart/dart/web/main.dart +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -import 'package:angular2/platform/browser.dart'; - -import 'package:angular2_getting_started/app_component.dart'; - -void main() { - bootstrap(AppComponent); -} diff --git a/public/docs/_examples/quickstart/dart/web/styles_1.css b/public/docs/_examples/quickstart/dart/web/styles_1.css deleted file mode 100644 index 27e60d67c0..0000000000 --- a/public/docs/_examples/quickstart/dart/web/styles_1.css +++ /dev/null @@ -1,14 +0,0 @@ -/* #docregion */ -h1 { - color: #369; - font-family: Arial, Helvetica, sans-serif; - font-size: 250%; -} -body { - margin: 2em; -} - -/* -* See https://github.com/angular/angular.io/blob/master/public/docs/_examples/styles.css -* for the full set of master styles used by the documentation samples -*/ diff --git a/public/docs/_examples/quickstart/e2e-spec.ts b/public/docs/_examples/quickstart/e2e-spec.ts index d38d6a3157..73921707ee 100644 --- a/public/docs/_examples/quickstart/e2e-spec.ts +++ b/public/docs/_examples/quickstart/e2e-spec.ts @@ -1,7 +1,10 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('QuickStart E2E Tests', function () { - let expectedMsg = 'My First Angular 2 App'; + let expectedMsg = 'Hello Angular'; beforeEach(function () { browser.get(''); diff --git a/public/docs/_examples/quickstart/js/app/app.component.js b/public/docs/_examples/quickstart/js/app/app.component.js deleted file mode 100644 index f86b3bde46..0000000000 --- a/public/docs/_examples/quickstart/js/app/app.component.js +++ /dev/null @@ -1,27 +0,0 @@ -// #docplaster -// #docregion -// #docregion iife -(function(app) { - // #enddocregion iife - // #docregion ng-namespace-funcs, export - app.AppComponent = - // #enddocregion export - // #docregion component - ng.core.Component({ - // #enddocregion ng-namespace-funcs - selector: 'my-app', - template: '

    My First Angular 2 App

    ' - // #docregion ng-namespace-funcs - }) - // #enddocregion component - // #docregion class - .Class({ - // #enddocregion ng-namespace-funcs - constructor: function() {} - // #docregion ng-namespace-funcs - }); - // #enddocregion class - // #enddocregion ng-namespace-funcs -// #docregion iife -})(window.app || (window.app = {})); -// #enddocregion iife diff --git a/public/docs/_examples/quickstart/js/app/main.js b/public/docs/_examples/quickstart/js/app/main.js deleted file mode 100644 index 55a77b9ddd..0000000000 --- a/public/docs/_examples/quickstart/js/app/main.js +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -(function(app) { - document.addEventListener('DOMContentLoaded', function() { - // #docregion import - ng.platformBrowserDynamic.bootstrap(app.AppComponent); - // #enddocregion import - }); -})(window.app || (window.app = {})); diff --git a/public/docs/_examples/quickstart/js/bs-config.1.json b/public/docs/_examples/quickstart/js/bs-config.1.json new file mode 100644 index 0000000000..4e58595267 --- /dev/null +++ b/public/docs/_examples/quickstart/js/bs-config.1.json @@ -0,0 +1,8 @@ +{ + "server": { + "baseDir": "src", + "routes": { + "/node_modules": "node_modules" + } + } +} diff --git a/public/docs/_examples/quickstart/js/example-config.json b/public/docs/_examples/quickstart/js/example-config.json index e69de29bb2..81f31aaf0d 100644 --- a/public/docs/_examples/quickstart/js/example-config.json +++ b/public/docs/_examples/quickstart/js/example-config.json @@ -0,0 +1,3 @@ +{ + "build": "build:babel" +} diff --git a/public/docs/_examples/quickstart/js/index.html b/public/docs/_examples/quickstart/js/index.html deleted file mode 100644 index bec42f9dea..0000000000 --- a/public/docs/_examples/quickstart/js/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - Angular 2 QuickStart JS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Loading... - - - - diff --git a/public/docs/_examples/quickstart/js/package.1.json b/public/docs/_examples/quickstart/js/package.1.json index b9365ca90d..28aee2b92e 100644 --- a/public/docs/_examples/quickstart/js/package.1.json +++ b/public/docs/_examples/quickstart/js/package.1.json @@ -1,32 +1,29 @@ { - "name": "angular2-quickstart", + "name": "angular-quickstart", "version": "1.0.0", "scripts": { "start": "npm run lite", "lite": "lite-server" }, - "license": "ISC", + "license": "MIT", "dependencies": { - "@angular/common": "2.0.0-rc.1", - "@angular/compiler": "2.0.0-rc.1", - "@angular/core": "2.0.0-rc.1", - "@angular/http": "2.0.0-rc.1", - "@angular/platform-browser": "2.0.0-rc.1", - "@angular/platform-browser-dynamic": "2.0.0-rc.1", - "@angular/router": "2.0.0-rc.1", - "@angular/router-deprecated": "2.0.0-rc.1", - "@angular/upgrade": "2.0.0-rc.1", + "@angular/common": "~2.4.0", + "@angular/compiler": "~2.4.0", + "@angular/core": "~2.4.0", + "@angular/forms": "~2.4.0", + "@angular/http": "~2.4.0", + "@angular/platform-browser": "~2.4.0", + "@angular/platform-browser-dynamic": "~2.4.0", + "@angular/router": "~3.4.0", + "@angular/upgrade": "~2.4.0", - "core-js": "^2.4.0", - "reflect-metadata": "0.1.3", - "rxjs": "5.0.0-beta.6", - "zone.js": "0.6.12", - - "angular2-in-memory-web-api": "0.0.11", - "bootstrap": "^3.3.6" + "angular-in-memory-web-api": "~0.3.1", + "core-js": "^2.4.1", + "rxjs": "5.0.1", + "zone.js": "^0.8.4" }, "devDependencies": { - "concurrently": "^2.0.0", - "lite-server": "^2.2.0" + "concurrently": "^3.0.0", + "lite-server": "^2.2.2" } } diff --git a/public/docs/_examples/quickstart/js/plnkr.json b/public/docs/_examples/quickstart/js/plnkr.json index 16a1c9a6c0..5e24ad9790 100644 --- a/public/docs/_examples/quickstart/js/plnkr.json +++ b/public/docs/_examples/quickstart/js/plnkr.json @@ -1,5 +1,6 @@ { "description": "QuickStart", + "basePath": "src/", "files": [ "!**/*.[1].*" ], diff --git a/public/docs/_examples/quickstart/js/spec.js b/public/docs/_examples/quickstart/js/spec.js deleted file mode 100644 index 83f3eaea94..0000000000 --- a/public/docs/_examples/quickstart/js/spec.js +++ /dev/null @@ -1,9 +0,0 @@ -describe("Jasmine sample test", function() { - - it("1+1 should be 2", function() { - - var result = 1 + 1; - - expect(result).toBe(2); - }); -}); \ No newline at end of file diff --git a/public/docs/_examples/quickstart/js/src/app/app.component.js b/public/docs/_examples/quickstart/js/src/app/app.component.js new file mode 100644 index 0000000000..26ba116efe --- /dev/null +++ b/public/docs/_examples/quickstart/js/src/app/app.component.js @@ -0,0 +1,27 @@ +// #docplaster +// #docregion +// #docregion iife +(function(app) { + // #enddocregion iife + // #docregion ng-namespace-funcs, export + app.AppComponent = + // #enddocregion export + // #docregion component + ng.core.Component({ + // #enddocregion ng-namespace-funcs + selector: 'my-app', + template: '

    Hello Angular

    ' + // #docregion ng-namespace-funcs + }) + // #enddocregion component + // #docregion class + .Class({ + // #enddocregion ng-namespace-funcs + constructor: function() {} + // #docregion ng-namespace-funcs + }); + // #enddocregion class + // #enddocregion ng-namespace-funcs +// #docregion iife +})(window.app || (window.app = {})); +// #enddocregion iife diff --git a/public/docs/_examples/quickstart/js/src/app/app.module.js b/public/docs/_examples/quickstart/js/src/app/app.module.js new file mode 100644 index 0000000000..0f3d5f82cf --- /dev/null +++ b/public/docs/_examples/quickstart/js/src/app/app.module.js @@ -0,0 +1,15 @@ +// #docplaster +// #docregion +(function(app) { + app.AppModule = + ng.core.NgModule({ + imports: [ ng.platformBrowser.BrowserModule ], + // #docregion import + declarations: [ app.AppComponent ], + // #enddocregion import + bootstrap: [ app.AppComponent ] + }) + .Class({ + constructor: function() {} + }); +})(window.app || (window.app = {})); diff --git a/public/docs/_examples/quickstart/js/src/index.html b/public/docs/_examples/quickstart/js/src/index.html new file mode 100644 index 0000000000..43d63e9c83 --- /dev/null +++ b/public/docs/_examples/quickstart/js/src/index.html @@ -0,0 +1,42 @@ + + + + + Angular QuickStart JS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Loading... + + + + diff --git a/public/docs/_examples/quickstart/js/src/main.js b/public/docs/_examples/quickstart/js/src/main.js new file mode 100644 index 0000000000..785823fa84 --- /dev/null +++ b/public/docs/_examples/quickstart/js/src/main.js @@ -0,0 +1,8 @@ +// #docregion +(function(app) { + document.addEventListener('DOMContentLoaded', function() { + ng.platformBrowserDynamic + .platformBrowserDynamic() + .bootstrapModule(app.AppModule); + }); +})(window.app || (window.app = {})); diff --git a/public/docs/_examples/quickstart/ts/styles.1.css b/public/docs/_examples/quickstart/js/src/styles.1.css similarity index 100% rename from public/docs/_examples/quickstart/ts/styles.1.css rename to public/docs/_examples/quickstart/js/src/styles.1.css diff --git a/public/docs/_examples/quickstart/ts/.gitignore b/public/docs/_examples/quickstart/ts/.gitignore deleted file mode 100644 index d30e27f5f7..0000000000 --- a/public/docs/_examples/quickstart/ts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!systemjs.config.1.js diff --git a/public/docs/_examples/quickstart/ts/app/app.component.ts b/public/docs/_examples/quickstart/ts/app/app.component.ts deleted file mode 100644 index ea76b32116..0000000000 --- a/public/docs/_examples/quickstart/ts/app/app.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -// #docregion -// #docregion import -import { Component } from '@angular/core'; -// #enddocregion import - -// #docregion metadata -@Component({ - selector: 'my-app', - template: '

    My First Angular 2 App

    ' -}) -// #enddocregion metadata -// #docregion class -export class AppComponent { } -// #enddocregion class diff --git a/public/docs/_examples/quickstart/ts/app/main.ts b/public/docs/_examples/quickstart/ts/app/main.ts deleted file mode 100644 index 2aede345e9..0000000000 --- a/public/docs/_examples/quickstart/ts/app/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; - -// #docregion import -import { AppComponent } from './app.component'; -// #enddocregion import - -bootstrap(AppComponent); diff --git a/public/docs/_examples/quickstart/ts/bs-config.1.json b/public/docs/_examples/quickstart/ts/bs-config.1.json new file mode 100644 index 0000000000..4e58595267 --- /dev/null +++ b/public/docs/_examples/quickstart/ts/bs-config.1.json @@ -0,0 +1,8 @@ +{ + "server": { + "baseDir": "src", + "routes": { + "/node_modules": "node_modules" + } + } +} diff --git a/public/docs/_examples/quickstart/ts/index.html b/public/docs/_examples/quickstart/ts/index.html deleted file mode 100644 index a0a64d1122..0000000000 --- a/public/docs/_examples/quickstart/ts/index.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - Angular 2 QuickStart - - - - - - - - - - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/quickstart/ts/package.1.json b/public/docs/_examples/quickstart/ts/package.1.json deleted file mode 100644 index 8798091f8b..0000000000 --- a/public/docs/_examples/quickstart/ts/package.1.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "angular2-quickstart", - "version": "1.0.0", - "scripts": { - "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ", - "lite": "lite-server", - "postinstall": "typings install", - "tsc": "tsc", - "tsc:w": "tsc -w", - "typings": "typings" - }, - "license": "ISC", - "dependencies": { - "@angular/common": "2.0.0-rc.1", - "@angular/compiler": "2.0.0-rc.1", - "@angular/core": "2.0.0-rc.1", - "@angular/http": "2.0.0-rc.1", - "@angular/platform-browser": "2.0.0-rc.1", - "@angular/platform-browser-dynamic": "2.0.0-rc.1", - "@angular/router": "2.0.0-rc.1", - "@angular/router-deprecated": "2.0.0-rc.1", - "@angular/upgrade": "2.0.0-rc.1", - - "systemjs": "0.19.27", - "core-js": "^2.4.0", - "reflect-metadata": "^0.1.3", - "rxjs": "5.0.0-beta.6", - "zone.js": "^0.6.12", - - "angular2-in-memory-web-api": "0.0.11", - "bootstrap": "^3.3.6" - }, - "devDependencies": { - "concurrently": "^2.0.0", - "lite-server": "^2.2.0", - "typescript": "^1.8.10", - "typings":"^1.0.4" - } -} diff --git a/public/docs/_examples/quickstart/ts/plnkr.json b/public/docs/_examples/quickstart/ts/plnkr.json index a4449b444f..8edf7c25ea 100644 --- a/public/docs/_examples/quickstart/ts/plnkr.json +++ b/public/docs/_examples/quickstart/ts/plnkr.json @@ -1,9 +1,12 @@ { "description": "QuickStart", + "basePath": "src/", "files": [ - "!**/*.d.ts", - "!**/*.js", - "!**/*.[1].*" + "app/app.component.ts", + "app/app.module.ts", + "main.ts", + "index.html" ], + "open": "app/app.component.ts", "tags": ["quickstart"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/quickstart/ts/src/app/app.component.ts b/public/docs/_examples/quickstart/ts/src/app/app.component.ts new file mode 100644 index 0000000000..1ef28fc5c4 --- /dev/null +++ b/public/docs/_examples/quickstart/ts/src/app/app.component.ts @@ -0,0 +1,8 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: `

    Hello {{name}}

    ` +}) +export class AppComponent { name = 'Angular'; } diff --git a/public/docs/_examples/quickstart/ts/src/app/app.module.ts b/public/docs/_examples/quickstart/ts/src/app/app.module.ts new file mode 100644 index 0000000000..50a0e6eb47 --- /dev/null +++ b/public/docs/_examples/quickstart/ts/src/app/app.module.ts @@ -0,0 +1,11 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/quickstart/ts/src/index.html b/public/docs/_examples/quickstart/ts/src/index.html new file mode 100644 index 0000000000..21fb56edb9 --- /dev/null +++ b/public/docs/_examples/quickstart/ts/src/index.html @@ -0,0 +1,31 @@ + + + + Angular Quickstart + + + + + + + + + + + + + + + + + + + Loading AppComponent content here ... + + + + diff --git a/public/docs/_examples/quickstart/ts/src/main.ts b/public/docs/_examples/quickstart/ts/src/main.ts new file mode 100644 index 0000000000..311c44b76d --- /dev/null +++ b/public/docs/_examples/quickstart/ts/src/main.ts @@ -0,0 +1,5 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/quickstart/ts/src/tsconfig.1.json b/public/docs/_examples/quickstart/ts/src/tsconfig.1.json new file mode 100644 index 0000000000..2c7260d1bc --- /dev/null +++ b/public/docs/_examples/quickstart/ts/src/tsconfig.1.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ "es2015", "dom" ], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true + } +} diff --git a/public/docs/_examples/quickstart/ts/systemjs.config.1.js b/public/docs/_examples/quickstart/ts/systemjs.config.1.js deleted file mode 100644 index 449e847339..0000000000 --- a/public/docs/_examples/quickstart/ts/systemjs.config.1.js +++ /dev/null @@ -1,59 +0,0 @@ -// #docregion -/** - * System configuration for Angular 2 samples - * Adjust as necessary for your application needs. - */ -(function(global) { - - // map tells the System loader where to look for things - var map = { - 'app': 'app', // 'dist', - - '@angular': 'node_modules/@angular', - 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api', - 'rxjs': 'node_modules/rxjs' - }; - - // packages tells the System loader how to load when no filename and/or no extension - var packages = { - 'app': { main: 'main.js', defaultExtension: 'js' }, - 'rxjs': { defaultExtension: 'js' }, - 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, - }; - - var ngPackageNames = [ - 'common', - 'compiler', - 'core', - 'http', - 'platform-browser', - 'platform-browser-dynamic', - 'router', - 'router-deprecated', - 'upgrade', - ]; - - // Individual files (~300 requests): - function packIndex(pkgName) { - packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; - } - - // Bundled (~40 requests): - function packUmd(pkgName) { - packages['@angular/'+pkgName] = { main: pkgName + '.umd.js', defaultExtension: 'js' }; - }; - - // Most environments should use UMD; some (Karma) need the individual index files - var setPackageConfig = System.packageWithIndex ? packIndex : packUmd; - - // Add package entries for angular packages - ngPackageNames.forEach(setPackageConfig); - - var config = { - map: map, - packages: packages - } - - System.config(config); - -})(this); diff --git a/public/docs/_examples/quickstart/ts/tsconfig.1.json b/public/docs/_examples/quickstart/ts/tsconfig.1.json deleted file mode 100644 index e6a6eac11d..0000000000 --- a/public/docs/_examples/quickstart/ts/tsconfig.1.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "moduleResolution": "node", - "sourceMap": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "removeComments": false, - "noImplicitAny": false - } -} diff --git a/public/docs/_examples/quickstart/ts/typings.1.json b/public/docs/_examples/quickstart/ts/typings.1.json deleted file mode 100644 index 7e0e18568d..0000000000 --- a/public/docs/_examples/quickstart/ts/typings.1.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "globalDependencies": { - "core-js": "registry:dt/core-js#0.0.0+20160317120654", - "jasmine": "registry:dt/jasmine#2.2.0+20160505161446", - "node": "registry:dt/node#4.0.0+20160509154515" - } -} diff --git a/public/docs/_examples/reactive-forms/e2e-spec.ts b/public/docs/_examples/reactive-forms/e2e-spec.ts new file mode 100644 index 0000000000..bb788397ef --- /dev/null +++ b/public/docs/_examples/reactive-forms/e2e-spec.ts @@ -0,0 +1,1020 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + +function finalDemoAddressForm(element: any, index: number) { + let form = { + street: element.all(by.css('input[formcontrolname=street]')).get(index).getAttribute('value'), + city: element.all(by.css('input[formcontrolname=city]')).get(index).getAttribute('value'), + state: element.all(by.css('select[formcontrolname=state]')).get(index).getAttribute('value'), + zip: element.all(by.css('input[formcontrolname=zip]')).get(index).getAttribute('value') + }; + return form; +} + +describe('Reactive forms', function() { + let select: any; + + beforeEach(function() { + browser.get(''); + select = element(by.css('.container > h4 > select')); + }); + + describe('navigation', function() { + it('should display the title', function() { + let title = element(by.css('.container > h1')); + expect(title.getText()).toBe('Reactive Forms'); + }); + + it('should contain a dropdown with each example', function() { + expect(select.isDisplayed()).toBe(true); + }); + + it('should have 9 options for different demos', function() { + let options = select.all(by.tagName('option')); + expect(options.count()).toBe(9); + }); + + it('should start with Final Demo', function() { + select.getAttribute('value').then(function(demo: string) { + expect(demo).toBe('Final Demo'); + }); + }); + }); + +// *************Begin Final Demo test******************************* + + describe('final demo', function() { + it('does not select any hero by default', function() { + let heroSection = element(by.css('hero-list > div')); + expect(heroSection.isPresent()).toBe(false); + }); + + it('refreshes the page upon button click', function() { + // We move to another page... + let whirlwindButton = element.all(by.css('nav a')).get(0); + whirlwindButton.click(); + let refresh = element(by.css('button')); + refresh.click(); + let heroSection = element(by.css('hero-list > div')); + expect(heroSection.isPresent()).toBe(false); + }); + + describe('Whirlwind form', function() { + beforeEach(function() { + let whirlwindButton = element.all(by.css('nav a')).get(0); + whirlwindButton.click(); + }); + + it('should show a hero information when the button is clicked', function() { + let editMessage = element(by.css('hero-list > div > h3')); + expect(editMessage.getText()).toBe('Editing: Whirlwind'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe('Whirlwind'); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe('123 Main'); + expect(address1.state).toBe('CA'); + expect(address1.zip).toBe('94801'); + expect(address1.city).toBe('Anywhere'); + let address2 = finalDemoAddressForm(element, 1); + expect(address2.street).toBe('456 Maple'); + expect(address2.state).toBe('VA'); + expect(address2.zip).toBe('23226'); + expect(address2.city).toBe('Somewhere'); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail > p')); + expect(json.getText()).toContain('Whirlwind'); + expect(json.getText()).toContain('Anywhere'); + expect(json.getText()).toContain('Somewhere'); + expect(json.getText()).toContain('VA'); + }); + + it('has two disabled buttons by default', function() { + let buttons = element.all(by.css('hero-detail > form > div > button')); + expect(buttons.get(0).getAttribute('disabled')).toBe('true'); + expect(buttons.get(1).getAttribute('disabled')).toBe('true'); + }); + + it('enables the buttons after we edit the form', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + nameInput.sendKeys('a'); + let buttons = element.all(by.css('hero-detail > form > div > button')); + expect(buttons.get(0).getAttribute('disabled')).toBeNull(); + expect(buttons.get(1).getAttribute('disabled')).toBeNull(); + }); + + it('saves the changes when the save button is clicked', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + nameInput.sendKeys('a'); + let save = element.all(by.css('hero-detail > form > div > button')).get(0); + save.click(); + let editMessage = element(by.css('hero-list > div > h3')); + expect(editMessage.getText()).toBe('Editing: Whirlwinda'); + }); + + it('reverts the changes when the revert button is clicked', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + nameInput.sendKeys('a'); + let revert = element.all(by.css('hero-detail > form > div > button')).get(1); + revert.click(); + let editMessage = element(by.css('hero-list > div > h3')); + expect(editMessage.getText()).toBe('Editing: Whirlwind'); + expect(nameInput.getAttribute('value')).toBe('Whirlwind'); + }); + + it('is able to add a new empty address', function() { + let newLairButton = element.all(by.css('button')).get(3); + newLairButton.click(); + let address3 = finalDemoAddressForm(element, 2); + expect(address3.street).toBe(''); + expect(address3.state).toBe(''); + expect(address3.zip).toBe(''); + expect(address3.city).toBe(''); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + }); + + describe('Bombastic form', function() { + beforeEach(function() { + let bombastaButton = element.all(by.css('nav a')).get(1); + bombastaButton.click(); + }); + + it('should show a hero information when the button is clicked', function() { + let editMessage = element(by.css('hero-list > div > h3')); + expect(editMessage.getText()).toBe('Editing: Bombastic'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe('Bombastic'); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe('789 Elm'); + // expect(address1.state).toBe('OH'); + expect(address1.zip).toBe('04501'); + expect(address1.city).toBe('Smallville'); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail > p')); + expect(json.getText()).toContain('Bombastic'); + expect(json.getText()).toContain('Smallville'); + expect(json.getText()).toContain('OH'); + expect(json.getText()).toContain('04501'); + }); + + it('has two disabled buttons by default', function() { + let buttons = element.all(by.css('hero-detail > form > div > button')); + expect(buttons.get(0).getAttribute('disabled')).toBe('true'); + expect(buttons.get(1).getAttribute('disabled')).toBe('true'); + }); + + it('enables the buttons after we edit the form', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + nameInput.sendKeys('a'); + let buttons = element.all(by.css('hero-detail > form > div > button')); + expect(buttons.get(0).getAttribute('disabled')).toBeNull(); + expect(buttons.get(1).getAttribute('disabled')).toBeNull(); + }); + + it('saves the changes when the save button is clicked', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + nameInput.sendKeys('a'); + let save = element.all(by.css('hero-detail > form > div > button')).get(0); + save.click(); + let editMessage = element(by.css('hero-list > div > h3')); + expect(editMessage.getText()).toBe('Editing: Bombastica'); + }); + + it('reverts the changes when the revert button is clicked', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + nameInput.sendKeys('a'); + let revert = element.all(by.css('hero-detail > form > div > button')).get(1); + revert.click(); + let editMessage = element(by.css('hero-list > div > h3')); + expect(editMessage.getText()).toBe('Editing: Bombastic'); + expect(nameInput.getAttribute('value')).toBe('Bombastic'); + }); + + it('is able to add a new empty address', function() { + let newLairButton = element.all(by.css('button')).get(3); + newLairButton.click(); + let address2 = finalDemoAddressForm(element, 1); + expect(address2.street).toBe(''); + expect(address2.state).toBe(''); + expect(address2.zip).toBe(''); + expect(address2.city).toBe(''); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + }); + + describe('Magneta form', function() { + + beforeEach(function() { + let magnetaButton = element.all(by.css('nav a')).get(2); + magnetaButton.click(); + }); + + it('should show hero information when the button is clicked', function() { + let editMessage = element(by.css('hero-list > div > h3')); + expect(editMessage.getText()).toBe('Editing: Magneta'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe('Magneta'); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail > p')); + expect(json.getText()).toContain('Magneta'); + }); + + it('has two disabled buttons by default', function() { + let buttons = element.all(by.css('hero-detail > form > div > button')); + expect(buttons.get(0).getAttribute('disabled')).toBe('true'); + expect(buttons.get(1).getAttribute('disabled')).toBe('true'); + }); + + it('enables the buttons after we edit the form', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + nameInput.sendKeys('a'); + let buttons = element.all(by.css('hero-detail > form > div > button')); + expect(buttons.get(0).getAttribute('disabled')).toBeNull(); + expect(buttons.get(1).getAttribute('disabled')).toBeNull(); + }); + + it('saves the changes when the save button is clicked', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + nameInput.sendKeys('a'); + let save = element.all(by.css('hero-detail > form > div > button')).get(0); + save.click(); + let editMessage = element(by.css('hero-list > div > h3')); + expect(editMessage.getText()).toBe('Editing: Magnetaa'); + }); + + it('reverts the changes when the revert button is clicked', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + nameInput.sendKeys('a'); + let revert = element.all(by.css('hero-detail > form > div > button')).get(1); + revert.click(); + let editMessage = element(by.css('hero-list > div > h3')); + expect(editMessage.getText()).toBe('Editing: Magneta'); + expect(nameInput.getAttribute('value')).toBe('Magneta'); + }); + + it('is able to add a new empty address', function() { + let newLairButton = element.all(by.css('button')).get(3); + newLairButton.click(); + let address = finalDemoAddressForm(element, 0); + expect(address.street).toBe(''); + expect(address.state).toBe(''); + expect(address.zip).toBe(''); + expect(address.city).toBe(''); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + }); + }); // final demo + +// *************Begin FormArray Demo test******************************* + + + describe('formArray demo', function() { + beforeEach(function() { + let FormArrayOption = element.all(by.css('select option')).get(7); + FormArrayOption.click(); + }); + + it('should show FormArray Demo', function() { + select.getAttribute('value').then(function(demo: string) { + expect(demo).toBe('FormArray Demo'); + }); + }); + + it('does not select any hero by default', function() { + let heroSection = element(by.css('hero-list > div')); + expect(heroSection.isPresent()).toBe(false); + }); + + it('refreshes the page upon button click', function() { + // We move to another page... + let whirlwindButton = element.all(by.css('nav a')).get(0); + whirlwindButton.click(); + let refresh = element(by.css('button')); + refresh.click(); + let heroSection = element(by.css('hero-list > div')); + expect(heroSection.isPresent()).toBe(false); + }); + + describe('Whirlwind form', function() { + beforeEach(function() { + let whirlwindButton = element.all(by.css('nav a')).get(0); + whirlwindButton.click(); + }); + + it('should show hero information when the button is clicked', function() { + let editMessage = element(by.css('div.demo > div > div > h3')); + expect(editMessage.getText()).toBe('Editing: Whirlwind'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe('Whirlwind'); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe('123 Main'); + expect(address1.state).toBe('CA'); + expect(address1.zip).toBe('94801'); + expect(address1.city).toBe('Anywhere'); + let address2 = finalDemoAddressForm(element, 1); + expect(address2.street).toBe('456 Maple'); + expect(address2.state).toBe('VA'); + expect(address2.zip).toBe('23226'); + expect(address2.city).toBe('Somewhere'); + }); + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-8 > p')); + expect(json.getText()).toContain('Whirlwind'); + expect(json.getText()).toContain('Anywhere'); + expect(json.getText()).toContain('Somewhere'); + expect(json.getText()).toContain('VA'); + }); + + it('is able to add a new empty address', function() { + let newLairButton = element.all(by.css('button')).get(1); + newLairButton.click(); + let address2 = finalDemoAddressForm(element, 2); + expect(address2.street).toBe(''); + expect(address2.state).toBe(''); + expect(address2.zip).toBe(''); + expect(address2.city).toBe(''); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + + }); // Whirlwind form + + describe('Bombastic FormArray form', function() { + beforeEach(function() { + let bombasticButton = element.all(by.css('nav a')).get(1); + bombasticButton.click(); + }); + + it('should show a hero information when the button is clicked', function() { + let editMessage = element(by.css('div.demo > div > div > h3')); + expect(editMessage.getText()).toBe('Editing: Bombastic'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + // nameInput.getAttribute('value').then(function(name: string) { + // expect(name).toBe('Whirlwind'); + // }); + expect(nameInput.getAttribute('value')).toBe('Bombastic'); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe('789 Elm'); + // expect(address1.state).toBe('OH'); + // This select should be OH not CA, which it shows in the UI, the JSON shows OH. + expect(address1.zip).toBe('04501'); + expect(address1.city).toBe('Smallville'); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-8 > p')); + expect(json.getText()).toContain('Bombastic'); + expect(json.getText()).toContain('Smallville'); + expect(json.getText()).toContain('04501'); + expect(json.getText()).toContain('789 Elm'); + }); + + it('is able to add a new empty address', function() { + let newLairButton = element.all(by.css('button')).get(1); + newLairButton.click(); + let address1 = finalDemoAddressForm(element, 1); + expect(address1.street).toBe(''); + expect(address1.state).toBe(''); + expect(address1.zip).toBe(''); + expect(address1.city).toBe(''); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + + }); // Bombastic FormArray form + + describe('Magneta FormArray form', function() { + beforeEach(function() { + let magnetaButton = element.all(by.css('nav a')).get(2); + magnetaButton.click(); + }); + + it('should show a hero information when the button is clicked', function() { + let editMessage = element(by.css('div.demo > div > div > h3')); + expect(editMessage.getText()).toBe('Editing: Magneta'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe('Magneta'); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-8 > p')); + expect(json.getText()).toContain('Magneta'); + }); + + it('is able to add a new empty address', function() { + let newLairButton = element.all(by.css('button')).get(1); + newLairButton.click(); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe(''); + expect(address1.state).toBe(''); + expect(address1.zip).toBe(''); + expect(address1.city).toBe(''); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + + }); // Magneta FormArray form + + }); // formArray demo + + +// *************Begin SetValue Demo test******************************* + + describe('SetValue demo', function() { + beforeEach(function() { + let SetValueOption = element.all(by.css('select option')).get(6); + SetValueOption.click(); + }); + + it('should show SetValue Demo', function() { + select.getAttribute('value').then(function(demo: string) { + expect(demo).toBe('SetValue Demo'); + }); + }); + + it('does not select any hero by default', function() { + let heroSection = element(by.css('hero-list > div')); + expect(heroSection.isPresent()).toBe(false); + }); + + it('refreshes the page upon button click', function() { + // We move to another page... + let whirlwindButton = element.all(by.css('nav a')).get(0); + whirlwindButton.click(); + let refresh = element(by.css('button')); + refresh.click(); + let heroSection = element(by.css('hero-list > div')); + expect(heroSection.isPresent()).toBe(false); + }); + + describe('Whirlwind setValue form', function() { + beforeEach(function() { + let whirlwindButton = element.all(by.css('nav a')).get(0); + whirlwindButton.click(); + }); + + it('should show a hero information when the button is clicked', function() { + let editMessage = element(by.css('.demo > div > div > h3')); + expect(editMessage.getText()).toBe('Editing: Whirlwind'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe('Whirlwind'); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe('123 Main'); + expect(address1.state).toBe('CA'); + expect(address1.zip).toBe('94801'); + expect(address1.city).toBe('Anywhere'); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-7 > p')); + expect(json.getText()).toContain('Whirlwind'); + expect(json.getText()).toContain('Anywhere'); + let nameOutput = element(by.css('hero-detail-7 > p ~ p')); + expect(nameOutput.getText()).toContain('Name value: Whirlwind'); + let streetOutput = element(by.css('hero-detail-7 > p ~ p ~ p')); + expect(streetOutput.getText()).toContain('Street value: 123 Main'); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + + }); // Whirlwind setValue form + + describe('Bombastic setValue form', function() { + beforeEach(function() { + let bombasticButton = element.all(by.css('nav a')).get(1); + bombasticButton.click(); + }); + + it('should show a hero information when the button is clicked', function() { + let editMessage = element(by.css('.demo > div > div > h3')); + expect(editMessage.getText()).toBe('Editing: Bombastic'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe('Bombastic'); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe('789 Elm'); + expect(address1.state).toBe('OH'); + expect(address1.zip).toBe('04501'); + expect(address1.city).toBe('Smallville'); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-7 > p')); + expect(json.getText()).toContain('Bombastic'); + expect(json.getText()).toContain('Smallville'); + expect(json.getText()).toContain('04501'); + expect(json.getText()).toContain('789 Elm'); + let nameOutput = element(by.css('hero-detail-7 > p ~ p')); + expect(nameOutput.getText()).toContain('Name value: Bombastic'); + let streetOutput = element(by.css('hero-detail-7 > p ~ p ~ p')); + expect(streetOutput.getText()).toContain('Street value: 789 Elm'); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + + }); // Bombastic setValue form + + describe('Magneta setValue form', function() { + beforeEach(function() { + let magnetaButton = element.all(by.css('nav a')).get(2); + magnetaButton.click(); + }); + + it('should show a hero information when the button is clicked', function() { + let editMessage = element(by.css('.demo > div > div > h3')); + expect(editMessage.getText()).toBe('Editing: Magneta'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe('Magneta'); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-7 > p')); + expect(json.getText()).toContain('Magneta'); + let nameOutput = element(by.css('hero-detail-7 > p ~ p')); + expect(nameOutput.getText()).toContain('Name value: Magneta'); + let streetOutput = element(by.css('hero-detail-7 > p ~ p ~ p')); + expect(streetOutput.getText()).toContain('Street value:'); + }); + + }); // Magneta setValue form + }); // SetValue demo + +// *************Begin patchValue Demo test******************************* + + describe('patchValue demo', function() { + beforeEach(function() { + let SetValueOption = element.all(by.css('select option')).get(5); + SetValueOption.click(); + }); + + it('should show patchValue Demo', function() { + select.getAttribute('value').then(function(demo: string) { + expect(demo).toBe('PatchValue Demo'); + }); + }); + + it('does not select any hero by default', function() { + let heroSection = element(by.css('.demo > div > div')); + expect(heroSection.isPresent()).toBe(false); + }); + + it('refreshes the page upon button click', function() { + // We move to another page... + let whirlwindButton = element.all(by.css('nav a')).get(0); + whirlwindButton.click(); + let refresh = element(by.css('button')); + refresh.click(); + let heroSection = element(by.css('.demo > div > div')); + expect(heroSection.isPresent()).toBe(false); + }); + + describe('Whirlwind patchValue form', function() { + beforeEach(function() { + let whirlwindButton = element.all(by.css('nav a')).get(0); + whirlwindButton.click(); + }); + + it('should show a hero information when the button is clicked', function() { + let editMessage = element(by.css('h2 ~ h3')); + expect(editMessage.getText()).toBe('Editing: Whirlwind'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe('Whirlwind'); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe(''); + expect(address1.state).toBe(''); + expect(address1.zip).toBe(''); + expect(address1.city).toBe(''); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-6 > p')); + expect(json.getText()).toContain('Whirlwind'); + let nameOutput = element(by.css('hero-detail-6 > p ~ p')); + expect(nameOutput.getText()).toContain('Name value: Whirlwind'); + let streetOutput = element(by.css('hero-detail-6 > p ~ p ~ p')); + expect(streetOutput.getText()).toContain('Street value:'); + }); + + + }); // Bombastic patchValue form + describe('Bombastic patchValue form', function() { + beforeEach(function() { + let bombasticButton = element.all(by.css('nav a')).get(1); + bombasticButton.click(); + }); + + it('should show a hero information when the button is clicked', function() { + let editMessage = element(by.css('h2 ~ h3')); + expect(editMessage.getText()).toBe('Editing: Bombastic'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe('Bombastic'); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe(''); + expect(address1.state).toBe(''); + expect(address1.zip).toBe(''); + expect(address1.city).toBe(''); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-6 > p')); + expect(json.getText()).toContain('Bombastic'); + let nameOutput = element(by.css('hero-detail-6 > p ~ p')); + expect(nameOutput.getText()).toContain('Name value: Bombastic'); + let streetOutput = element(by.css('hero-detail-6 > p ~ p ~ p')); + expect(streetOutput.getText()).toContain('Street value:'); + }); + }); // Bombastic patchValue form + + describe('Magneta patchValue form', function() { + beforeEach(function() { + let magnetaButton = element.all(by.css('nav a')).get(2); + magnetaButton.click(); + }); + + it('should show a hero information when the button is clicked', function() { + let editMessage = element(by.css('h2 ~ h3')); + expect(editMessage.getText()).toBe('Editing: Magneta'); + }); + + it('should show a form with the selected hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe('Magneta'); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe(''); + expect(address1.state).toBe(''); + expect(address1.zip).toBe(''); + expect(address1.city).toBe(''); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-6 > p')); + expect(json.getText()).toContain('Magneta'); + let nameOutput = element(by.css('hero-detail-6 > p ~ p')); + expect(nameOutput.getText()).toContain('Name value: Magneta'); + let streetOutput = element(by.css('hero-detail-6 > p ~ p ~ p')); + expect(streetOutput.getText()).toContain('Street value:'); + }); + + }); // Magneta patchValue form + }); // PatchValue demo + + + +// *************Begin Nested FormBuilder Demo test******************************* + + describe('Nested FormBuilder demo', function() { + beforeEach(function() { + let NestedFormBuilderOption = element.all(by.css('select option')).get(4); + NestedFormBuilderOption.click(); + }); + + it('should show Nested FormBuilder Demo', function() { + select.getAttribute('value').then(function(demo: string) { + expect(demo).toBe('Nested FormBuilder group Demo'); + }); + }); + + it('should show a form for hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe(''); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe(''); + expect(address1.state).toBe(''); + expect(address1.zip).toBe(''); + expect(address1.city).toBe(''); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-5 > p')); + expect(json.getText()).toContain('address'); + let nameOutput = element(by.css('hero-detail-5 > p ~ p')); + expect(nameOutput.getText()).toContain('Name value:'); + let streetOutput = element(by.css('hero-detail-5 > p ~ p ~ p')); + expect(streetOutput.getText()).toContain('Street value:'); + }); + + }); // Nested FormBuilder demo + +// *************Begin Group with multiple controls Demo test******************************* + + describe('Group with multiple controls demo', function() { + beforeEach(function() { + let NestedFormBuilderOption = element.all(by.css('select option')).get(3); + NestedFormBuilderOption.click(); + }); + + it('should show Group with multiple controls Demo', function() { + select.getAttribute('value').then(function(demo: string) { + expect(demo).toBe('Group with multiple controls Demo'); + }); + }); + + it('should show header', function() { + let header = element(by.css('hero-detail-4 > h3')); + expect(header.getText()).toBe('A FormGroup with multiple FormControls'); + }); + + it('should show a form for hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe(''); + let address1 = finalDemoAddressForm(element, 0); + expect(address1.street).toBe(''); + expect(address1.state).toBe(''); + expect(address1.zip).toBe(''); + expect(address1.city).toBe(''); + }); + + it('should show three radio buttons', function() { + let radioButtons = element.all(by.css('input[formcontrolname=power]')); + expect(radioButtons.get(0).getAttribute('value')).toBe('flight'); + expect(radioButtons.get(1).getAttribute('value')).toBe('x-ray vision'); + expect(radioButtons.get(2).getAttribute('value')).toBe('strength'); + }); + it('should show a checkbox', function() { + let checkbox = element(by.css('input[formcontrolname=sidekick]')); + expect(checkbox.getAttribute('checked')).toBe(null); + }); + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-4 > p')); + expect(json.getText()).toContain('power'); + }); + +}); // Group with multiple controls demo + + + +// *************Begin Group with multiple controls Demo test******************************* + + describe('Simple FormBuilder Group demo', function() { + beforeEach(function() { + let SimpleFormBuilderOption = element.all(by.css('select option')).get(2); + SimpleFormBuilderOption.click(); + }); + + it('should show Simple FormBuilder group Demo', function() { + select.getAttribute('value').then(function(demo: string) { + expect(demo).toBe('Simple FormBuilder group Demo'); + }); + }); + + it('should show header', function() { + let header = element(by.css('hero-detail-3 > h3')); + expect(header.getText()).toBe('A FormGroup with a single FormControl using FormBuilder'); + }); + + it('should show a form for hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe(''); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-3 > p')); + expect(json.getText()).toContain('name'); + let validStatus = element(by.css('hero-detail-3 > p ~ p')); + expect(validStatus.getText()).toContain('INVALID'); + }); + +}); // Group with multiple controls demo + + +// *************Begin FormControl in a FormGroup Demo test******************************* + + describe('FormControl in a FormGroup demo', function() { + beforeEach(function() { + let SimpleFormBuilderOption = element.all(by.css('select option')).get(1); + SimpleFormBuilderOption.click(); + }); + + it('should show FormControl in a FormGroup Demo', function() { + select.getAttribute('value').then(function(demo: string) { + expect(demo).toBe('FormControl in a FormGroup Demo'); + }); + }); + + it('should show header', function() { + let header = element(by.css('hero-detail-2 > h3')); + expect(header.getText()).toBe('FormControl in a FormGroup'); + }); + + it('should show a form for hero information', function() { + let nameInput = element(by.css('input[formcontrolname=name]')); + expect(nameInput.getAttribute('value')).toBe(''); + }); + + it('shows a json output from the form', function() { + let json = element(by.css('hero-detail-2 > p')); + expect(json.getText()).toContain('name'); + }); + +}); // Group with multiple controls demo + +// *************Begin Just A FormControl Demo test******************************* + + describe('Just a FormControl demo', function() { + beforeEach(function() { + let FormControlOption = element.all(by.css('select option')).get(0); + FormControlOption.click(); + }); + + it('should show Just a FormControl demo', function() { + select.getAttribute('value').then(function(demo: string) { + expect(demo).toBe('Just a FormControl Demo'); + }); + }); + + it('should show header', function() { + let header = element(by.css('hero-detail-1 > h3')); + expect(header.getText()).toBe('Just a FormControl'); + }); + + it('should show a form for hero information', function() { + let nameInput = element(by.css('input')); + expect(nameInput.getAttribute('value')).toBe(''); + }); + + }); // Just a FormControl demo test + + +}); // reactive forms diff --git a/public/docs/_examples/quickstart/dart/example-config.json b/public/docs/_examples/reactive-forms/ts/example-config.json similarity index 100% rename from public/docs/_examples/quickstart/dart/example-config.json rename to public/docs/_examples/reactive-forms/ts/example-config.json diff --git a/public/docs/_examples/reactive-forms/ts/final.plnkr.json b/public/docs/_examples/reactive-forms/ts/final.plnkr.json new file mode 100644 index 0000000000..41481acc99 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/final.plnkr.json @@ -0,0 +1,21 @@ +{ + "description": "Angular Reactive Forms (final)", + "basePath": "src/", + "files":[ + "styles.css", + + "app/app.component.ts", + "app/app.module.ts", + "app/data-model.ts", + "app/hero.service.ts", + "app/hero-detail.component.html", + "app/hero-detail.component.ts", + "app/hero-list.component.html", + "app/hero-list.component.ts", + + "main-final.ts", + "index-final.html" + ], + "main": "index-final.html", + "tags": ["reactive", "forms"] +} diff --git a/public/docs/_examples/reactive-forms/ts/plnkr.json b/public/docs/_examples/reactive-forms/ts/plnkr.json new file mode 100644 index 0000000000..f0daeb4aad --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/plnkr.json @@ -0,0 +1,15 @@ +{ + "description": "Angular Reactive Forms (Demo runner)", + "basePath": "src/", + "files":[ + "!**/*.d.ts", + "!**/*.js", + + "!app/app.component.1.ts", + "!app/hero-list.component.1.html", + + "!app/main-final.ts", + "!index-final.html" + ], + "tags": ["reactive", "forms"] +} diff --git a/public/docs/_examples/reactive-forms/ts/src/app/app.component.1.ts b/public/docs/_examples/reactive-forms/ts/src/app/app.component.1.ts new file mode 100644 index 0000000000..3023618334 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/app.component.1.ts @@ -0,0 +1,12 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` +
    +

    Reactive Forms

    + +
    ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/reactive-forms/ts/src/app/app.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/app.component.ts new file mode 100644 index 0000000000..d30a38e979 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/app.component.ts @@ -0,0 +1,12 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` +
    +

    Reactive Forms

    + +
    ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/reactive-forms/ts/src/app/app.module.ts b/public/docs/_examples/reactive-forms/ts/src/app/app.module.ts new file mode 100644 index 0000000000..b9f2ea8f99 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/app.module.ts @@ -0,0 +1,39 @@ +// #docplaster +// #docregion +// #docregion v1 +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { ReactiveFormsModule } from '@angular/forms'; // <-- #1 import module + +import { AppComponent } from './app.component'; +import { HeroDetailComponent } from './hero-detail.component'; // <-- #1 import component +// #enddocregion v1 +import { HeroListComponent } from './hero-list.component'; + +import { HeroService } from './hero.service'; // <-- #1 import service +// #docregion v1 + +@NgModule({ + imports: [ + BrowserModule, + ReactiveFormsModule // <-- #2 add to Angular module imports + ], + declarations: [ + AppComponent, + HeroDetailComponent, // <-- #3 declare app component +// #enddocregion v1 + HeroListComponent +// #docregion v1 + ], +// #enddocregion v1 + exports: [ // export for the DemoModule + AppComponent, + HeroDetailComponent, + HeroListComponent + ], + providers: [ HeroService ], // <-- #4 provide HeroService +// #docregion v1 + bootstrap: [ AppComponent ] +}) +export class AppModule { } +// #enddocregion v1 diff --git a/public/docs/_examples/reactive-forms/ts/src/app/data-model.ts b/public/docs/_examples/reactive-forms/ts/src/app/data-model.ts new file mode 100644 index 0000000000..ad01ddee56 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/data-model.ts @@ -0,0 +1,40 @@ +// #docregion +// #docregion model-classes +export class Hero { + id = 0; + name = ''; + addresses: Address[]; +} + +export class Address { + street = ''; + city = ''; + state = ''; + zip = ''; +} +// #enddocregion model-classes + +export const heroes: Hero[] = [ + { + id: 1, + name: 'Whirlwind', + addresses: [ + {street: '123 Main', city: 'Anywhere', state: 'CA', zip: '94801'}, + {street: '456 Maple', city: 'Somewhere', state: 'VA', zip: '23226'}, + ] + }, + { + id: 2, + name: 'Bombastic', + addresses: [ + {street: '789 Elm', city: 'Smallville', state: 'OH', zip: '04501'}, + ] + }, + { + id: 3, + name: 'Magneta', + addresses: [ ] + }, +]; + +export const states = ['CA', 'MD', 'OH', 'VA']; diff --git a/public/docs/_examples/reactive-forms/ts/src/app/demo.component.html b/public/docs/_examples/reactive-forms/ts/src/app/demo.component.html new file mode 100644 index 0000000000..1caae127af --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/demo.component.html @@ -0,0 +1,40 @@ +
    +

    Reactive Forms

    +

    Pick a demo: + +

    + +
    + +
    + + + + + + + +
    + +

    Loading heroes ...

    +

    Select a hero:

    + + + +
    +
    +

    Hero Detail

    +

    Editing: {{selectedHero.name}}

    + + + + +
    +
    +
    +
    diff --git a/public/docs/_examples/reactive-forms/ts/src/app/demo.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/demo.component.ts new file mode 100644 index 0000000000..181726eb66 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/demo.component.ts @@ -0,0 +1,47 @@ +/* tslint:disable:member-ordering */ +import { Component } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; + +import { Hero } from './data-model'; +import { HeroService } from './hero.service'; + +@Component({ + selector: 'my-app', + templateUrl: './demo.component.html' +}) +export class DemoComponent { + + demos: string[] = [ + 'Just a FormControl', + 'FormControl in a FormGroup', + 'Simple FormBuilder group', + 'Group with multiple controls', + 'Nested FormBuilder group', + 'PatchValue', + 'SetValue', + 'FormArray', + 'Final'].map(n => n + ' Demo'); + + final = this.demos.length; + demo = this.final; // current demo + + heroes: Observable; + isLoading = false; + selectedHero: Hero; + + constructor(private heroService: HeroService) { } + + getHeroes() { + this.isLoading = true; + this.heroes = this.heroService.getHeroes() + .finally(() => this.isLoading = false); + this.selectedHero = undefined; + } + + select(hero: Hero) { this.selectedHero = hero; } + + selectDemo(demo: number) { + this.demo = demo + 1; + this.getHeroes(); + } +} diff --git a/public/docs/_examples/reactive-forms/ts/src/app/demo.module.ts b/public/docs/_examples/reactive-forms/ts/src/app/demo.module.ts new file mode 100644 index 0000000000..dac9145ca9 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/demo.module.ts @@ -0,0 +1,33 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { ReactiveFormsModule } from '@angular/forms'; + +import { AppModule } from './app.module'; +import { DemoComponent } from './demo.component'; +import { HeroDetailComponent1 } from './hero-detail-1.component'; +import { HeroDetailComponent2 } from './hero-detail-2.component'; +import { HeroDetailComponent3 } from './hero-detail-3.component'; +import { HeroDetailComponent4 } from './hero-detail-4.component'; +import { HeroDetailComponent5 } from './hero-detail-5.component'; +import { HeroDetailComponent6 } from './hero-detail-6.component'; +import { HeroDetailComponent7 } from './hero-detail-7.component'; +import { HeroDetailComponent8 } from './hero-detail-8.component'; + +@NgModule({ + imports: [ + BrowserModule, + ReactiveFormsModule, + AppModule, + ], + declarations: [ DemoComponent, + HeroDetailComponent1, + HeroDetailComponent2, + HeroDetailComponent3, + HeroDetailComponent4, + HeroDetailComponent5, + HeroDetailComponent6, + HeroDetailComponent7, + HeroDetailComponent8], + bootstrap: [ DemoComponent ] +}) +export class DemoModule { } diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-1.component.html b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-1.component.html new file mode 100644 index 0000000000..7217708d22 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-1.component.html @@ -0,0 +1,8 @@ + +

    Hero Detail

    +

    Just a FormControl

    + + + diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-1.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-1.component.ts new file mode 100644 index 0000000000..318dfff145 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-1.component.ts @@ -0,0 +1,14 @@ +/* tslint:disable:component-class-suffix */ +// #docregion imports +import { Component } from '@angular/core'; +import { FormControl } from '@angular/forms'; +// #enddocregion + +@Component({ + selector: 'hero-detail-1', + templateUrl: './hero-detail-1.component.html' +}) +// #docregion v1 +export class HeroDetailComponent1 { + name = new FormControl(); +} diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-2.component.html b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-2.component.html new file mode 100644 index 0000000000..1e98354842 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-2.component.html @@ -0,0 +1,18 @@ + +

    Hero Detail

    +

    FormControl in a FormGroup

    +
    +
    + +
    +
    + + + +

    Form value: {{ heroForm.value | json }}

    + + + + diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-2.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-2.component.ts new file mode 100644 index 0000000000..6aa3c1ed3a --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-2.component.ts @@ -0,0 +1,17 @@ +/* tslint:disable:component-class-suffix */ +// #docregion imports +import { Component } from '@angular/core'; +import { FormControl, FormGroup } from '@angular/forms'; +// #enddocregion imports + +@Component({ + selector: 'hero-detail-2', + templateUrl: './hero-detail-2.component.html' +}) +// #docregion v2 +export class HeroDetailComponent2 { + heroForm = new FormGroup ({ + name: new FormControl() + }); +} +// #enddocregion v2 diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-3.component.html b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-3.component.html new file mode 100644 index 0000000000..8edc544dd4 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-3.component.html @@ -0,0 +1,16 @@ + +

    Hero Detail

    +

    A FormGroup with a single FormControl using FormBuilder

    +
    +
    + +
    +
    + + + +

    Form value: {{ heroForm.value | json }}

    +

    Form status: {{ heroForm.status | json }}

    + diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-3.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-3.component.ts new file mode 100644 index 0000000000..54a4e93361 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-3.component.ts @@ -0,0 +1,27 @@ +/* tslint:disable:component-class-suffix */ +// #docregion imports +import { Component } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +// #enddocregion imports + +@Component({ + selector: 'hero-detail-3', + templateUrl: './hero-detail-3.component.html' +}) +// #docregion v3 +export class HeroDetailComponent3 { + heroForm: FormGroup; // <--- heroForm is of type FormGroup + + constructor(private fb: FormBuilder) { // <--- inject FormBuilder + this.createForm(); + } + + createForm() { + // #docregion required + this.heroForm = this.fb.group({ + name: ['', Validators.required ], + }); + // #enddocregion required + } +} +// #enddocregion v3 diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-3a.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-3a.component.ts new file mode 100644 index 0000000000..2347869967 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-3a.component.ts @@ -0,0 +1,25 @@ +/* tslint:disable:component-class-suffix */ +// #docregion imports +import { Component } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +// #enddocregion imports + +@Component({ + selector: 'hero-detail-3', + templateUrl: './hero-detail-3.component.html' +}) +// #docregion v3a +export class HeroDetailComponent3 { + heroForm: FormGroup; // <--- heroForm is of type FormGroup + + constructor(private fb: FormBuilder) { // <--- inject FormBuilder + this.createForm(); + } + + createForm() { + this.heroForm = this.fb.group({ + name: '', // <--- the FormControl called "name" + }); + } +} +// #enddocregion v3a diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-4.component.html b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-4.component.html new file mode 100644 index 0000000000..30529868e9 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-4.component.html @@ -0,0 +1,46 @@ + +

    Hero Detail

    +

    A FormGroup with multiple FormControls

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Super power:

    + + + +
    +
    + +
    +
    + + +

    Form value: {{ heroForm.value | json }}

    diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-4.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-4.component.ts new file mode 100644 index 0000000000..d2f1ea2f96 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-4.component.ts @@ -0,0 +1,34 @@ +/* tslint:disable:component-class-suffix */ +// #docregion imports +import { Component } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; + +import { states } from './data-model'; +// #enddocregion imports + +@Component({ + selector: 'hero-detail-4', + templateUrl: './hero-detail-4.component.html' +}) +// #docregion v4 +export class HeroDetailComponent4 { + heroForm: FormGroup; + states = states; + + constructor(private fb: FormBuilder) { + this.createForm(); + } + + createForm() { + this.heroForm = this.fb.group({ + name: ['', Validators.required ], + street: '', + city: '', + state: '', + zip: '', + power: '', + sidekick: '' + }); + } +} +// #enddocregion v4 diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-5.component.html b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-5.component.html new file mode 100644 index 0000000000..2a41b4f2f9 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-5.component.html @@ -0,0 +1,56 @@ + +
    +
    + +
    + +
    +

    Secret Lair

    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +

    Super power:

    + + + +
    +
    + +
    +
    + +

    heroForm value: {{ heroForm.value | json}}

    +

    Extra info for the curious:

    + +

    Name value: {{ heroForm.get('name').value }}

    + + + +

    Street value: {{ heroForm.get('address.street').value}}

    + diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-5.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-5.component.ts new file mode 100644 index 0000000000..f4be33389f --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-5.component.ts @@ -0,0 +1,35 @@ +/* tslint:disable:component-class-suffix */ +import { Component } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; + +import { states } from './data-model'; + +@Component({ + selector: 'hero-detail-5', + templateUrl: './hero-detail-5.component.html' +}) +// #docregion v5 +export class HeroDetailComponent5 { + heroForm: FormGroup; + states = states; + + constructor(private fb: FormBuilder) { + this.createForm(); + } + + createForm() { + this.heroForm = this.fb.group({ // <-- the parent FormGroup + name: ['', Validators.required ], + address: this.fb.group({ // <-- the child FormGroup + street: '', + city: '', + state: '', + zip: '' + }), + power: '', + sidekick: '' + }); + } +} +// #enddocregion v5 + diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-6.component.html b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-6.component.html new file mode 100644 index 0000000000..4c8b5c9e05 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-6.component.html @@ -0,0 +1,46 @@ + +

    Hero Detail

    +

    PatchValue to initialize a value

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Super power:

    + + + +
    +
    + +
    +
    + + +

    Form value: {{ heroForm.value | json }}

    diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-6.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-6.component.ts new file mode 100644 index 0000000000..d5136822d1 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-6.component.ts @@ -0,0 +1,58 @@ +/* tslint:disable:component-class-suffix */ +// #docregion import-input +import { Component, Input, OnChanges } from '@angular/core'; +// #enddocregion import-input +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; + +// #docregion import-hero +import { Hero, states } from './data-model'; +// #enddocregion import-hero + +////////// 6 //////////////////// + +@Component({ + selector: 'hero-detail-6', + templateUrl: './hero-detail-5.component.html' +}) +// #docregion v6 +export class HeroDetailComponent6 implements OnChanges { + // #docregion hero + @Input() hero: Hero; + // #enddocregion hero + + heroForm: FormGroup; + states = states; + + constructor(private fb: FormBuilder) { + this.createForm(); + } + + createForm() { + // #docregion hero-form-model + this.heroForm = this.fb.group({ + name: ['', Validators.required ], + address: this.fb.group({ + street: '', + city: '', + state: '', + zip: '' + }), + power: '', + sidekick: '' + }); + // #enddocregion hero-form-model + } + + // #docregion patch-value-on-changes + ngOnChanges() { // <-- wrap patchValue in ngOnChanges + this.heroForm.reset(); + // #docregion patch-value + this.heroForm.patchValue({ + name: this.hero.name + }); + // #enddocregion patch-value + } + // #enddocregion patch-value-on-changes +} + +// #enddocregion v6 diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-7.component.html b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-7.component.html new file mode 100644 index 0000000000..6d68b49b4d --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-7.component.html @@ -0,0 +1,46 @@ + +

    Hero Detail

    +

    A FormGroup with multiple FormControls

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +

    Super power:

    + + + +
    +
    + +
    +
    + + +

    Form value: {{ heroForm.value | json }}

    diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-7.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-7.component.ts new file mode 100644 index 0000000000..497c7f6a56 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-7.component.ts @@ -0,0 +1,69 @@ +/* tslint:disable:component-class-suffix */ +// #docplaster +// #docregion imports +import { Component, Input, OnChanges } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; + +// #docregion import-address +import { Address, Hero, states } from './data-model'; +// #enddocregion import-address + +// #enddocregion imports + +@Component({ + selector: 'hero-detail-7', + templateUrl: './hero-detail-5.component.html' +}) +// #docregion v7 +export class HeroDetailComponent7 implements OnChanges { + @Input() hero: Hero; + + heroForm: FormGroup; + states = states; + + constructor(private fb: FormBuilder) { + this.createForm(); + } + + createForm() { + // #docregion address-form-group + this.heroForm = this.fb.group({ + name: ['', Validators.required ], + address: this.fb.group(new Address()), // <-- a FormGroup with a new address + power: '', + sidekick: '' + }); + // #enddocregion address-form-group + } + + // #docregion ngOnChanges + ngOnChanges() { + this.heroForm.reset({ + name: this.hero.name, + address: this.hero.addresses[0] || new Address() + }); + } + // #enddocregion ngOnChanges + + /* First version of ngOnChanges + // #docregion ngOnChanges-1 + ngOnChanges() + // #enddocregion ngOnChanges-1 + */ + ngOnChanges1() { + // #docregion reset + this.heroForm.reset(); + // #enddocregion reset + // #docregion ngOnChanges-1 + // #docregion set-value + this.heroForm.setValue({ + name: this.hero.name, + // #docregion set-value-address + address: this.hero.addresses[0] || new Address() + // #enddocregion set-value-address + }); + // #enddocregion set-value + } + // #enddocregion ngOnChanges-1 +} + diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-8.component.html b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-8.component.html new file mode 100644 index 0000000000..d8e47ae798 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-8.component.html @@ -0,0 +1,70 @@ + +

    Using FormArray to add groups

    + +
    +

    Form Changed: {{ heroForm.dirty }}

    + +
    + +
    + + +
    +
    + + +

    Address #{{i + 1}}

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + + +
    + + + + + + + +
    + + +
    +

    Super power:

    + + + +
    +
    + +
    +
    + +

    heroForm value: {{ heroForm.value | json}}

    diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-8.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-8.component.ts new file mode 100644 index 0000000000..1141c836a7 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail-8.component.ts @@ -0,0 +1,68 @@ +/* tslint:disable:component-class-suffix */ +// #docregion imports +import { Component, Input, OnChanges } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; + +import { Address, Hero, states } from './data-model'; +// #enddocregion imports + +@Component({ + selector: 'hero-detail-8', + templateUrl: './hero-detail-8.component.html' +}) +// #docregion v8 +export class HeroDetailComponent8 implements OnChanges { + @Input() hero: Hero; + + heroForm: FormGroup; + states = states; + + // #docregion ctor + constructor(private fb: FormBuilder) { + this.createForm(); + this.logNameChange(); + } + // #enddocregion ctor + + createForm() { + // #docregion secretLairs-form-array + this.heroForm = this.fb.group({ + name: ['', Validators.required ], + secretLairs: this.fb.array([]), // <-- secretLairs as an empty FormArray + power: '', + sidekick: '' + }); + // #enddocregion secretLairs-form-array + } + + logNameChange() {/* Coming soon */} + + // #docregion onchanges + ngOnChanges() { + this.heroForm.reset({ + name: this.hero.name + }); + this.setAddresses(this.hero.addresses); + } + // #enddocregion onchanges + + // #docregion get-secret-lairs + get secretLairs(): FormArray { + return this.heroForm.get('secretLairs') as FormArray; + }; + // #enddocregion get-secret-lairs + + // #docregion set-addresses + setAddresses(addresses: Address[]) { + const addressFGs = addresses.map(address => this.fb.group(address)); + const addressFormArray = this.fb.array(addressFGs); + this.heroForm.setControl('secretLairs', addressFormArray); + } + // #enddocregion set-addresses + + // #docregion add-lair + addLair() { + this.secretLairs.push(this.fb.group(new Address())); + } + // #enddocregion add-lair +} diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail.component.html b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail.component.html new file mode 100644 index 0000000000..8f5b8bf2c8 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail.component.html @@ -0,0 +1,73 @@ + + + +
    +
    +   + +
    + + + +
    + +
    + +
    +
    + +

    Address #{{i + 1}}

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    + +
    + +
    +

    Super power:

    + + + +
    +
    + +
    +
    + + +

    heroForm value: {{ heroForm.value | json}}

    + + +

    Name change log

    +
    {{name}}
    + diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-detail.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail.component.ts new file mode 100644 index 0000000000..4cb69aaedf --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-detail.component.ts @@ -0,0 +1,107 @@ +// #docplaster +// #docregion +import { Component, Input, OnChanges } from '@angular/core'; +import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; + +import { Address, Hero, states } from './data-model'; +// #docregion import-service +import { HeroService } from './hero.service'; +// #enddocregion import-service + +// #docregion metadata +@Component({ + selector: 'hero-detail', + templateUrl: './hero-detail.component.html' +}) +// #enddocregion metadata +export class HeroDetailComponent implements OnChanges { + @Input() hero: Hero; + + heroForm: FormGroup; + // #docregion log-name-change + nameChangeLog: string[] = []; + // #enddocregion log-name-change + states = states; + + // #docregion ctor + constructor( + private fb: FormBuilder, + private heroService: HeroService) { + + this.createForm(); + this.logNameChange(); + } + // #enddocregion ctor + + createForm() { + this.heroForm = this.fb.group({ + name: '', + secretLairs: this.fb.array([]), + power: '', + sidekick: '' + }); + } + + ngOnChanges() { + this.heroForm.reset({ + name: this.hero.name + }); + this.setAddresses(this.hero.addresses); + } + + get secretLairs(): FormArray { + return this.heroForm.get('secretLairs') as FormArray; + }; + + setAddresses(addresses: Address[]) { + const addressFGs = addresses.map(address => this.fb.group(address)); + const addressFormArray = this.fb.array(addressFGs); + this.heroForm.setControl('secretLairs', addressFormArray); + } + + addLair() { + this.secretLairs.push(this.fb.group(new Address())); + } + + // #docregion on-submit + onSubmit() { + this.hero = this.prepareSaveHero(); + this.heroService.updateHero(this.hero).subscribe(/* error handling */); + this.ngOnChanges(); + } + // #enddocregion on-submit + + // #docregion prepare-save-hero + prepareSaveHero(): Hero { + const formModel = this.heroForm.value; + + // deep copy of form model lairs + const secretLairsDeepCopy: Address[] = formModel.secretLairs.map( + (address: Address) => Object.assign({}, address) + ); + + // return new `Hero` object containing a combination of original hero value(s) + // and deep copies of changed form model values + const saveHero: Hero = { + id: this.hero.id, + name: formModel.name as string, + // addresses: formModel.secretLairs // <-- bad! + addresses: secretLairsDeepCopy + }; + return saveHero; + } + // #enddocregion prepare-save-hero + + // #docregion revert + revert() { this.ngOnChanges(); } + // #enddocregion revert + + // #docregion log-name-change + logNameChange() { + const nameControl = this.heroForm.get('name'); + nameControl.valueChanges.forEach( + (value: string) => this.nameChangeLog.push(value) + ); + } + // #enddocregion log-name-change +} diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-list.component.1.html b/public/docs/_examples/reactive-forms/ts/src/app/hero-list.component.1.html new file mode 100644 index 0000000000..fa76c84f54 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-list.component.1.html @@ -0,0 +1,8 @@ + + + +
    + +
    diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-list.component.html b/public/docs/_examples/reactive-forms/ts/src/app/hero-list.component.html new file mode 100644 index 0000000000..d0fb2ee920 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-list.component.html @@ -0,0 +1,17 @@ + +

    Loading heroes ...

    +

    Select a hero:

    + + + +
    +
    +

    Hero Detail

    +

    Editing: {{selectedHero.name}}

    + + + +
    diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero-list.component.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero-list.component.ts new file mode 100644 index 0000000000..98092adcdb --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero-list.component.ts @@ -0,0 +1,31 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/finally'; + +import { Hero } from './data-model'; +import { HeroService } from './hero.service'; + +@Component({ + selector: 'hero-list', + templateUrl: './hero-list.component.html' +}) +export class HeroListComponent implements OnInit { + heroes: Observable; + isLoading = false; + selectedHero: Hero; + + constructor(private heroService: HeroService) { } + + ngOnInit() { this.getHeroes(); } + + getHeroes() { + this.isLoading = true; + this.heroes = this.heroService.getHeroes() + // Todo: error handling + .finally(() => this.isLoading = false); + this.selectedHero = undefined; + } + + select(hero: Hero) { this.selectedHero = hero; } +} diff --git a/public/docs/_examples/reactive-forms/ts/src/app/hero.service.ts b/public/docs/_examples/reactive-forms/ts/src/app/hero.service.ts new file mode 100644 index 0000000000..6600586de7 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/app/hero.service.ts @@ -0,0 +1,26 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { Observable } from 'rxjs/Observable'; +import { of } from 'rxjs/observable/of'; +import 'rxjs/add/operator/delay'; + +import { Hero, heroes } from './data-model'; + +@Injectable() +export class HeroService { + + delayMs = 500; + + // Fake server get; assume nothing can go wrong + getHeroes(): Observable { + return of(heroes).delay(this.delayMs); // simulate latency with delay + } + + // Fake server update; assume nothing can go wrong + updateHero(hero: Hero): Observable { + const oldHero = heroes.find(h => h.id === hero.id); + const newHero = Object.assign(oldHero, hero); // Demo: mutate cached hero + return of(newHero).delay(this.delayMs); // simulate latency with delay + } +} diff --git a/public/docs/_examples/reactive-forms/ts/src/index-final.html b/public/docs/_examples/reactive-forms/ts/src/index-final.html new file mode 100644 index 0000000000..9ef0a379e0 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/index-final.html @@ -0,0 +1,31 @@ + + + + + Hero Form + + + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/reactive-forms/ts/src/index.html b/public/docs/_examples/reactive-forms/ts/src/index.html new file mode 100644 index 0000000000..802d12f211 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/index.html @@ -0,0 +1,31 @@ + + + + + Hero Form + + + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/reactive-forms/ts/src/main-final.ts b/public/docs/_examples/reactive-forms/ts/src/main-final.ts new file mode 100644 index 0000000000..7572d1f1d3 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/main-final.ts @@ -0,0 +1,5 @@ +// tslint:disable:no-unused-variable +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/reactive-forms/ts/src/main.ts b/public/docs/_examples/reactive-forms/ts/src/main.ts new file mode 100644 index 0000000000..f415a71708 --- /dev/null +++ b/public/docs/_examples/reactive-forms/ts/src/main.ts @@ -0,0 +1,6 @@ +// tslint:disable:no-unused-variable +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; // just the final version +import { DemoModule } from './app/demo.module'; // demo picker + +platformBrowserDynamic().bootstrapModule(DemoModule); // (AppModule); diff --git a/public/docs/_examples/router-deprecated/e2e-spec.ts b/public/docs/_examples/router-deprecated/e2e-spec.ts deleted file mode 100644 index 85b0598df5..0000000000 --- a/public/docs/_examples/router-deprecated/e2e-spec.ts +++ /dev/null @@ -1,126 +0,0 @@ -/// -describe('Router', function () { - - beforeAll(function () { - browser.get(''); - }); - - function getPageStruct() { - let hrefEles = element.all(by.css('my-app a')); - - return { - hrefs: hrefEles, - routerParent: element(by.css('my-app > undefined')), - routerTitle: element(by.css('my-app > undefined > h2')), - - crisisHref: hrefEles.get(0), - crisisList: element.all(by.css('my-app > undefined > undefined li')), - crisisDetail: element(by.css('my-app > undefined > undefined > div')), - crisisDetailTitle: element(by.css('my-app > undefined > undefined > div > h3')), - - heroesHref: hrefEles.get(1), - heroesList: element.all(by.css('my-app > undefined li')), - heroDetail: element(by.css('my-app > undefined > div')), - heroDetailTitle: element(by.css('my-app > undefined > div > h3')), - - } - } - - it('should be able to see the start screen', function () { - let page = getPageStruct(); - expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices'); - expect(page.crisisHref.getText()).toEqual("Crisis Center"); - expect(page.heroesHref.getText()).toEqual("Heroes"); - }); - - it('should be able to see crises center items', function () { - let page = getPageStruct(); - expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries at start"); - }); - - it('should be able to see hero items', function () { - let page = getPageStruct(); - page.heroesHref.click().then(function() { - expect(page.routerTitle.getText()).toContain('HEROES'); - expect(page.heroesList.count()).toBe(6, "should be 6 heroes"); - }); - }); - - it('should be able to toggle the views', function () { - let page = getPageStruct(); - page.crisisHref.click().then(function() { - expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries"); - return page.heroesHref.click(); - }).then(function() { - expect(page.heroesList.count()).toBe(6, "should be 6 heroes"); - }); - }); - - it('should be able to edit and save details from the crisis center view', function () { - crisisCenterEdit(2, true); - }); - - it('should be able to edit and cancel details from the crisis center view', function () { - crisisCenterEdit(3, false); - }); - - it('should be able to edit and save details from the heroes view', function () { - let page = getPageStruct(); - let heroEle: protractor.ElementFinder; - let heroText: string; - page.heroesHref.click().then(function() { - heroEle = page.heroesList.get(4); - return heroEle.getText(); - }).then(function(text) { - expect(text.length).toBeGreaterThan(0, 'should have some text'); - // remove leading id from text - heroText = text.substr(text.indexOf(' ')).trim(); - return heroEle.click(); - }).then(function() { - expect(page.heroesList.count()).toBe(0, "should no longer see crisis center entries"); - expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail'); - expect(page.heroDetailTitle.getText()).toContain(heroText); - let inputEle = page.heroDetail.element(by.css('input')); - return sendKeys(inputEle, '-foo'); - }).then(function() { - expect(page.heroDetailTitle.getText()).toContain(heroText + '-foo'); - let buttonEle = page.heroDetail.element(by.css('button')); - return buttonEle.click(); - }).then(function() { - expect(heroEle.getText()).toContain(heroText + '-foo'); - }) - }); - - function crisisCenterEdit(index: number, shouldSave: boolean) { - let page = getPageStruct(); - let crisisEle: protractor.ElementFinder; - let crisisText: string; - page.crisisHref.click() - .then(function () { - crisisEle = page.crisisList.get(index); - return crisisEle.getText(); - }).then(function (text) { - expect(text.length).toBeGreaterThan(0, 'should have some text'); - // remove leading id from text - crisisText = text.substr(text.indexOf(' ')).trim(); - return crisisEle.click(); - }).then(function () { - expect(page.crisisList.count()).toBe(0, "should no longer see crisis center entries"); - expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail'); - expect(page.crisisDetailTitle.getText()).toContain(crisisText); - let inputEle = page.crisisDetail.element(by.css('input')); - return sendKeys(inputEle, '-foo'); - }).then(function () { - expect(page.crisisDetailTitle.getText()).toContain(crisisText + '-foo'); - let buttonEle = page.crisisDetail.element(by.cssContainingText('button', shouldSave ? 'Save' : 'Cancel')); - return buttonEle.click(); - }).then(function () { - if (shouldSave) { - expect(crisisEle.getText()).toContain(crisisText + '-foo'); - } else { - expect(crisisEle.getText()).not.toContain(crisisText + '-foo'); - } - }); - } - -}); diff --git a/public/docs/_examples/router-deprecated/ts/app/app.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/app.component.1.ts deleted file mode 100644 index 0e20623fd3..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/app.component.1.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* First version */ -// #docplaster - -// #docregion -import { Component } from '@angular/core'; -// #docregion import-router -import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated'; -// #enddocregion import-router - -import { CrisisListComponent } from './crisis-list.component'; -import { HeroListComponent } from './hero-list.component'; - -@Component({ - selector: 'my-app', -// #docregion template - template: ` -

    Component Router (Deprecated)

    - - - `, -// #enddocregion template - directives: [ROUTER_DIRECTIVES] -}) -// #enddocregion -/* -// #docregion route-config -@Component({ ... }) -// #enddocregion route-config -*/ -// #docregion -// #docregion route-config -@RouteConfig([ -// #docregion route-defs - {path: '/crisis-center', name: 'CrisisCenter', component: CrisisListComponent}, - {path: '/heroes', name: 'Heroes', component: HeroListComponent} -// #enddocregion route-defs -]) -export class AppComponent { } -// #enddocregion route-config -// #enddocregion diff --git a/public/docs/_examples/router-deprecated/ts/app/app.component.2.ts b/public/docs/_examples/router-deprecated/ts/app/app.component.2.ts deleted file mode 100644 index e4685ff418..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/app.component.2.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* Second Heroes version */ -// #docplaster - -// #docregion -import { Component } from '@angular/core'; -import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated'; - -import { CrisisListComponent } from './crisis-list.component'; -// #enddocregion -/* -// Apparent Milestone 2 imports -// #docregion -// #docregion hero-import -import { HeroListComponent } from './heroes/hero-list.component'; -import { HeroDetailComponent } from './heroes/hero-detail.component'; -import { HeroService } from './heroes/hero.service'; -// #enddocregion hero-import -// #enddocregion -*/ -// Actual Milestone 2 imports -import { HeroListComponent } from './heroes/hero-list.component.1'; -import { HeroDetailComponent } from './heroes/hero-detail.component.1'; -import { HeroService } from './heroes/hero.service'; -// #docregion - -@Component({ - selector: 'my-app', - template: ` -

    Component Router (Deprecated)

    - - - `, - providers: [HeroService], - directives: [ROUTER_DIRECTIVES] -}) -// #enddocregion -/* -// #docregion route-config -@Component({ ... }) -// #enddocregion route-config -*/ -// #docregion -// #docregion route-config -@RouteConfig([ -// #docregion route-defs - {path: '/crisis-center', name: 'CrisisCenter', component: CrisisListComponent}, - {path: '/heroes', name: 'Heroes', component: HeroListComponent}, - // #docregion hero-detail-route - {path: '/hero/:id', name: 'HeroDetail', component: HeroDetailComponent} - // #enddocregion hero-detail-route -// #enddocregion route-defs -]) -export class AppComponent { } -// #enddocregion route-config -// #enddocregion diff --git a/public/docs/_examples/router-deprecated/ts/app/app.component.3.ts b/public/docs/_examples/router-deprecated/ts/app/app.component.3.ts deleted file mode 100644 index 68635e8aad..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/app.component.3.ts +++ /dev/null @@ -1,52 +0,0 @@ -// #docplaster -import { Component } from '@angular/core'; -import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated'; - -import { CrisisCenterComponent } from './crisis-center/crisis-center.component.1'; -import { DialogService } from './dialog.service'; -import { HeroService } from './heroes/hero.service'; - -@Component({ - selector: 'my-app', -// #enddocregion - /* Typical link - // #docregion h-anchor - Heroes - // #enddocregion h-anchor - */ - /* Incomplete Crisis Center link when CC lacks a default - // #docregion cc-anchor-fail - // The link now fails with a "non-terminal link" error - // #docregion cc-anchor-w-default - Crisis Center - // #enddocregion cc-anchor-w-default - // #enddocregion cc-anchor-fail - */ - /* Crisis Center link when CC lacks a default - // #docregion cc-anchor-no-default - Crisis Center - // #enddocregion cc-anchor-no-default - */ - /* Crisis Center Detail link - // #docregion Dragon-anchor - Dragon Crisis - // #enddocregion Dragon-anchor - */ -// #docregion template - template: ` -

    Component Router (Deprecated)

    - - - `, -// #enddocregion template - providers: [DialogService, HeroService], - directives: [ROUTER_DIRECTIVES] -}) -@RouteConfig([ - {path: '/crisis-center/...', name: 'CrisisCenter', component: CrisisCenterComponent}, -]) -export class AppComponent { } diff --git a/public/docs/_examples/router-deprecated/ts/app/app.component.ts b/public/docs/_examples/router-deprecated/ts/app/app.component.ts deleted file mode 100644 index a6f784cda9..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/app.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; -import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated'; - -import { CrisisCenterComponent } from './crisis-center/crisis-center.component'; -import { HeroListComponent } from './heroes/hero-list.component'; -import { HeroDetailComponent } from './heroes/hero-detail.component'; - -import { DialogService } from './dialog.service'; -import { HeroService } from './heroes/hero.service'; - -@Component({ - selector: 'my-app', -// #docregion template - template: ` -

    Component Router (Deprecated)

    - - - `, -// #enddocregion template - providers: [DialogService, HeroService], - directives: [ROUTER_DIRECTIVES] -}) -// #docregion route-config -@RouteConfig([ - - // #docregion route-config-cc - { // Crisis Center child route - path: '/crisis-center/...', - name: 'CrisisCenter', - component: CrisisCenterComponent, - useAsDefault: true - }, - // #enddocregion route-config-cc - - {path: '/heroes', name: 'Heroes', component: HeroListComponent}, - {path: '/hero/:id', name: 'HeroDetail', component: HeroDetailComponent}, -]) -// #enddocregion route-config -export class AppComponent { } diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/add-crisis.component.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/add-crisis.component.ts deleted file mode 100644 index 5067e8aa3f..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/add-crisis.component.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Component } from '@angular/core'; -import { CanDeactivate, ComponentInstruction, Router } from '@angular/router-deprecated'; - -import { Crisis, CrisisService } from './crisis.service'; -import { DialogService } from '../dialog.service'; - -@Component({ - template: ` -

    "{{editName}}"

    -
    - - -
    - - - `, - styles: ['input {width: 20em}'] -}) -export class AddCrisisComponent implements CanDeactivate { - editName: string; - - constructor( - private service: CrisisService, - private router: Router, - private dialog: DialogService) { } - - routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) { - return !!this.editName.trim() || - this.dialog.confirm('Discard changes?'); - } - - cancel() { this.gotoCrises(); } - - save() { - this.service.addCrisis(this.editName); - this.gotoCrises(); - } - - gotoCrises() { - this.router.navigate(['CrisisCenter']); - } -} \ No newline at end of file diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.1.ts deleted file mode 100644 index 496b8ba11e..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.1.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Component } from '@angular/core'; -import { RouteConfig, RouterOutlet } from '@angular/router-deprecated'; - -import { CrisisListComponent } from './crisis-list.component.1'; -import { CrisisDetailComponent } from './crisis-detail.component.1'; -import { CrisisService } from './crisis.service'; - -// #docregion minus-imports -@Component({ - template: ` -

    CRISIS CENTER

    - - `, - directives: [RouterOutlet], -// #docregion providers - providers: [CrisisService] -// #enddocregion providers -}) -// #docregion route-config -@RouteConfig([ - // #docregion default-route - {path:'/', name: 'CrisisList', component: CrisisListComponent, useAsDefault: true}, - // #enddocregion default-route - {path:'/:id', name: 'CrisisDetail', component: CrisisDetailComponent} -]) -// #enddocregion route-config -export class CrisisCenterComponent { } -// #enddocregion minus-imports diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.ts deleted file mode 100644 index 27f9ff09ac..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-center.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { RouteConfig, RouterOutlet } from '@angular/router-deprecated'; - -import { CrisisListComponent } from './crisis-list.component'; -import { CrisisDetailComponent } from './crisis-detail.component'; -import { CrisisService } from './crisis.service'; - -@Component({ - template: ` -

    CRISIS CENTER

    - - `, - directives: [RouterOutlet], - providers: [CrisisService] -}) -@RouteConfig([ - {path:'/', name: 'CrisisList', component: CrisisListComponent, useAsDefault: true}, - {path:'/:id', name: 'CrisisDetail', component: CrisisDetailComponent} -]) -export class CrisisCenterComponent { } -// #enddocregion diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-detail.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-detail.component.1.ts deleted file mode 100644 index 8fb93b371a..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-detail.component.1.ts +++ /dev/null @@ -1,95 +0,0 @@ -// #docplaster - -// #docregion -import { Component, OnInit } from '@angular/core'; -import { RouteParams, Router } from '@angular/router-deprecated'; -// #docregion routerCanDeactivate -import { CanDeactivate, ComponentInstruction } from '@angular/router-deprecated'; - -import { DialogService } from '../dialog.service'; - -// #enddocregion routerCanDeactivate -import { Crisis, CrisisService } from './crisis.service'; - -@Component({ - // #docregion template - template: ` -
    -

    "{{editName}}"

    -
    - {{crisis.id}}
    -
    - - -
    -

    - - -

    -
    - `, - // #enddocregion template - styles: ['input {width: 20em}'] -}) -// #docregion routerCanDeactivate, cancel-save -export class CrisisDetailComponent implements OnInit, CanDeactivate { - - crisis: Crisis; - editName: string; - -// #enddocregion routerCanDeactivate, cancel-save - constructor( - private service: CrisisService, - private router: Router, - private routeParams: RouteParams, - private dialog: DialogService - ) { } - - // #docregion ngOnInit - ngOnInit() { - let id = +this.routeParams.get('id'); - this.service.getCrisis(id).then(crisis => { - if (crisis) { - this.editName = crisis.name; - this.crisis = crisis; - } else { // id not found - this.gotoCrises(); - } - }); - } - // #enddocregion ngOnInit - - // #docregion routerCanDeactivate - routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) : any { - // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged. - if (!this.crisis || this.crisis.name === this.editName) { - return true; - } - // Otherwise ask the user with the dialog service and return its - // promise which resolves to true or false when the user decides - return this.dialog.confirm('Discard changes?'); - } - // #enddocregion routerCanDeactivate - - // #docregion cancel-save - cancel() { - this.editName = this.crisis.name; - this.gotoCrises(); - } - - save() { - this.crisis.name = this.editName; - this.gotoCrises(); - } - // #enddocregion cancel-save - - // #docregion gotoCrises - gotoCrises() { - // Like Crisis Center -

    "{{editName}}"

    -
    - {{crisis.id}}
    -
    - - -
    -

    - - -

    - - `, - styles: ['input {width: 20em}'] -}) - -export class CrisisDetailComponent implements OnInit, CanDeactivate { - - crisis: Crisis; - editName: string; - - constructor( - private service: CrisisService, - private router: Router, - private routeParams: RouteParams, - private _dialog: DialogService - ) { } - - ngOnInit() { - let id = +this.routeParams.get('id'); - this.service.getCrisis(id).then(crisis => { - if (crisis) { - this.editName = crisis.name; - this.crisis = crisis; - } else { // id not found - this.gotoCrises(); - } - }); - } - - routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) : any { - // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged. - if (!this.crisis || this.crisis.name === this.editName) { - return true; - } - // Otherwise ask the user with the dialog service and return its - // promise which resolves to true or false when the user decides - return this._dialog.confirm('Discard changes?'); - } - - cancel() { - this.editName = this.crisis.name; - this.gotoCrises(); - } - - save() { - this.crisis.name = this.editName; - this.gotoCrises(); - } - - // #docregion gotoCrises - gotoCrises() { - let crisisId = this.crisis ? this.crisis.id : null; - // Pass along the hero id if available - // so that the CrisisListComponent can select that hero. - // Add a totally useless `foo` parameter for kicks. - // #docregion gotoCrises-navigate - this.router.navigate(['CrisisList', {id: crisisId, foo: 'foo'} ]); - // #enddocregion gotoCrises-navigate - } - // #enddocregion gotoCrises -} diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.1.ts deleted file mode 100644 index 45121da69e..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.1.ts +++ /dev/null @@ -1,37 +0,0 @@ -// #docplaster - -// #docregion -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router-deprecated'; - -import { Crisis, CrisisService } from './crisis.service'; - -@Component({ - // #docregion template - template: ` -
      -
    • - {{crisis.id}} {{crisis.name}} -
    • -
    - `, - // #enddocregion template -}) -export class CrisisListComponent implements OnInit { - crises: Crisis[]; - - constructor( - private service: CrisisService, - private router: Router) {} - - ngOnInit() { - this.service.getCrises().then(crises => this.crises = crises); - } - - // #docregion select - onSelect(crisis: Crisis) { - this.router.navigate(['CrisisDetail', { id: crisis.id }] ); - } - // #enddocregion select -} diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.ts deleted file mode 100644 index a5770d256f..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis-list.component.ts +++ /dev/null @@ -1,41 +0,0 @@ -// #docplaster - -// #docregion -import { Component, OnInit } from '@angular/core'; -import { RouteParams, Router } from '@angular/router-deprecated'; - -import { Crisis, CrisisService } from './crisis.service'; - -@Component({ - template: ` -
      -
    • - {{crisis.id}} {{crisis.name}} -
    • -
    - `, -}) -export class CrisisListComponent implements OnInit { - crises: Crisis[]; - - private selectedId: number; - - constructor( - private service: CrisisService, - private router: Router, - routeParams: RouteParams) { - this.selectedId = +routeParams.get('id'); - } - - isSelected(crisis: Crisis) { return crisis.id === this.selectedId; } - - ngOnInit() { - this.service.getCrises().then(crises => this.crises = crises); - } - - onSelect(crisis: Crisis) { - this.router.navigate( ['CrisisDetail', { id: crisis.id }] ); - } -} diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis.service.ts b/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis.service.ts deleted file mode 100644 index 949ccd4e00..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/crisis-center/crisis.service.ts +++ /dev/null @@ -1,41 +0,0 @@ -// #docplaster - -// #docregion -import { Injectable } from '@angular/core'; - -export class Crisis { - constructor(public id: number, public name: string) { } -} - -@Injectable() -export class CrisisService { - getCrises() { return crisesPromise; } - - getCrisis(id: number | string) { - return crisesPromise - .then(crises => crises.filter(c => c.id === +id)[0]); - } - -// #enddocregion - - static nextCrisisId = 100; - - addCrisis(name:string) { - name = name.trim(); - if (name){ - let crisis = new Crisis(CrisisService.nextCrisisId++, name); - crisesPromise.then(crises => crises.push(crisis)); - } - } -// #docregion -} - -var crises = [ - new Crisis(1, 'Dragon Burning Cities'), - new Crisis(2, 'Sky Rains Great White Sharks'), - new Crisis(3, 'Giant Asteroid Heading For Earth'), - new Crisis(4, 'Procrastinators Meeting Delayed Again'), -]; - -var crisesPromise = Promise.resolve(crises); -// #enddocregion diff --git a/public/docs/_examples/router-deprecated/ts/app/dialog.service.ts b/public/docs/_examples/router-deprecated/ts/app/dialog.service.ts deleted file mode 100644 index 3f5ceba475..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/dialog.service.ts +++ /dev/null @@ -1,18 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; -/** - * Async modal dialog service - * DialogService makes this app easier to test by faking this service. - * TODO: better modal implementation that doesn't use window.confirm - */ -@Injectable() -export class DialogService { - /** - * Ask user to confirm an action. `message` explains the action and choices. - * Returns promise resolving to `true`=confirm or `false`=cancel - */ - confirm(message?:string) { - return new Promise((resolve, reject) => - resolve(window.confirm(message || 'Is it OK?'))); - }; -} diff --git a/public/docs/_examples/router-deprecated/ts/app/hero-list.component.ts b/public/docs/_examples/router-deprecated/ts/app/hero-list.component.ts deleted file mode 100644 index 5dbbe17d8e..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/hero-list.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -/// Initial empty version -// #docregion -import { Component } from '@angular/core'; - -@Component({ - template: ` -

    HEROES

    -

    Get your heroes here

    ` -}) -export class HeroListComponent { } diff --git a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.1.ts deleted file mode 100644 index bb8509af21..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.1.ts +++ /dev/null @@ -1,47 +0,0 @@ -// #docregion -import { Component, OnInit } from '@angular/core'; -import { RouteParams, Router } from '@angular/router-deprecated'; - -import { Hero, HeroService } from './hero.service'; - -@Component({ - template: ` -

    HEROES

    -
    -

    "{{hero.name}}"

    -
    - {{hero.id}}
    -
    - - -
    -

    - -

    -
    - `, -}) -export class HeroDetailComponent implements OnInit { - hero: Hero; - - // #docregion ctor - constructor( - private router:Router, - private routeParams:RouteParams, - private service:HeroService){} - // #enddocregion ctor - - // #docregion ngOnInit - ngOnInit() { - let id = this.routeParams.get('id'); - this.service.getHero(id).then(hero => this.hero = hero); - } - // #enddocregion ngOnInit - - // #docregion gotoHeroes - gotoHeroes() { - // Like Heroes - this.router.navigate(['Heroes']); - } - // #enddocregion gotoHeroes -} diff --git a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.ts b/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.ts deleted file mode 100644 index abf4d4dd3b..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-detail.component.ts +++ /dev/null @@ -1,52 +0,0 @@ -// #docregion -import { Component, OnInit } from '@angular/core'; -import { RouteParams, Router } from '@angular/router-deprecated'; - -import { Hero, HeroService } from './hero.service'; - -@Component({ - template: ` -

    HEROES

    -
    -

    "{{hero.name}}"

    -
    - {{hero.id}}
    -
    - - -
    -

    - -

    -
    - `, -}) -export class HeroDetailComponent implements OnInit { - hero: Hero; - - // #docregion ctor - constructor( - private router:Router, - private routeParams:RouteParams, - private service:HeroService){} - // #enddocregion ctor - - // #docregion ngOnInit - ngOnInit() { - let id = this.routeParams.get('id'); - this.service.getHero(id).then(hero => this.hero = hero); - } - // #enddocregion ngOnInit - - // #docregion gotoHeroes - gotoHeroes() { - let heroId = this.hero ? this.hero.id : null; - // Pass along the hero id if available - // so that the HeroList component can select that hero. - // Add a totally useless `foo` parameter for kicks. - // #docregion gotoHeroes-navigate - this.router.navigate(['Heroes', {id: heroId, foo: 'foo'} ]); - // #enddocregion gotoHeroes-navigate - } - // #enddocregion gotoHeroes -} diff --git a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.1.ts b/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.1.ts deleted file mode 100644 index cd11dc8e1a..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.1.ts +++ /dev/null @@ -1,50 +0,0 @@ -// #docplaster - -// #docregion -// TODO SOMEDAY: Feature Componetized like HeroCenter -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router-deprecated'; - -import { Hero, HeroService } from './hero.service'; - -@Component({ - // #docregion template - template: ` -

    HEROES

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    - ` - // #enddocregion template -}) -export class HeroListComponent implements OnInit { - heroes: Hero[]; - - // #docregion ctor - constructor( - private router: Router, - private service: HeroService) { } - // #enddocregion ctor - - ngOnInit() { - this.service.getHeroes().then(heroes => this.heroes = heroes) - } - - // #docregion select - onSelect(hero: Hero) { - // #docregion nav-to-detail - this.router.navigate( ['HeroDetail', { id: hero.id }] ); - // #enddocregion nav-to-detail - } - // #enddocregion select -} -// #enddocregion - -/* A link parameters array -// #docregion link-parameters-array -['HeroDetail', { id: hero.id }] // {id: 15} -// #enddocregion link-parameters-array -*/ \ No newline at end of file diff --git a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.ts b/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.ts deleted file mode 100644 index 0f27e98cd6..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/heroes/hero-list.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -// #docplaster - -// TODO SOMEDAY: Feature Componetized like CrisisCenter -// #docregion -import { Component, OnInit } from '@angular/core'; -// #docregion import-route-params -import { RouteParams, Router } from '@angular/router-deprecated'; -// #enddocregion import-route-params - -import { Hero, HeroService } from './hero.service'; - -@Component({ - // #docregion template - template: ` -

    HEROES

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    - ` - // #enddocregion template -}) -export class HeroListComponent implements OnInit { - heroes: Hero[]; - - // #docregion ctor - private selectedId: number; - - constructor( - private service: HeroService, - private router: Router, - routeParams: RouteParams) { - this.selectedId = +routeParams.get('id'); - } - // #enddocregion ctor - - // #docregion isSelected - isSelected(hero: Hero) { return hero.id === this.selectedId; } - // #enddocregion isSelected - - // #docregion select - onSelect(hero: Hero) { - this.router.navigate( ['HeroDetail', { id: hero.id }] ); - } - // #enddocregion select - - ngOnInit() { - - - this.service.getHeroes().then(heroes => this.heroes = heroes) - } -} -// #enddocregion diff --git a/public/docs/_examples/router-deprecated/ts/app/heroes/hero.service.ts b/public/docs/_examples/router-deprecated/ts/app/heroes/hero.service.ts deleted file mode 100644 index a2c4495cb6..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/heroes/hero.service.ts +++ /dev/null @@ -1,27 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -export class Hero { - constructor(public id: number, public name: string) { } -} - -@Injectable() -export class HeroService { - getHeroes() { return heroesPromise; } - - getHero(id: number | string) { - return heroesPromise - .then(heroes => heroes.filter(h => h.id === +id)[0]); - } -} - -var HEROES = [ - new Hero(11, 'Mr. Nice'), - new Hero(12, 'Narco'), - new Hero(13, 'Bombasto'), - new Hero(14, 'Celeritas'), - new Hero(15, 'Magneta'), - new Hero(16, 'RubberMan') -]; - -var heroesPromise = Promise.resolve(HEROES); diff --git a/public/docs/_examples/router-deprecated/ts/app/main.1.ts b/public/docs/_examples/router-deprecated/ts/app/main.1.ts deleted file mode 100644 index 8ff3ff84fb..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/main.1.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* First version */ -// #docplaster - -// #docregion all -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { ROUTER_PROVIDERS } from '@angular/router-deprecated'; - -import { AppComponent } from './app.component'; - -// #enddocregion all - -/* Can't use AppComponent ... but display as if we can -// #docregion all -bootstrap(AppComponent, [ -// #enddocregion all -*/ - -// Actually use the v.1 component -import { AppComponent as ac} from './app.component.1'; -bootstrap(ac, [ -// #docregion all - ROUTER_PROVIDERS -]); -// #enddocregion all diff --git a/public/docs/_examples/router-deprecated/ts/app/main.2.ts b/public/docs/_examples/router-deprecated/ts/app/main.2.ts deleted file mode 100644 index 74862cdd0a..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/main.2.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* Second version */ -// For Milestone #2 -// Also includes digression on HashPathStrategy (not used in the final app) -// #docplaster - -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { ROUTER_PROVIDERS } from '@angular/router-deprecated'; - -// Add these symbols to override the `LocationStrategy` -import { LocationStrategy, - HashLocationStrategy } from '@angular/common'; - -import { AppComponent } from './app.component'; -// #enddocregion -/* Can't use AppComponent ... but display as if we can -// #docregion - -bootstrap(AppComponent, [ -// #enddocregion -*/ - -// Actually use the v.2 component -import { AppComponent as ac } from './app.component.2'; - -bootstrap(ac, [ -// #docregion - ROUTER_PROVIDERS, - { provide: LocationStrategy, useClass: HashLocationStrategy } // .../#/crisis-center/ -]); -// #enddocregion diff --git a/public/docs/_examples/router-deprecated/ts/app/main.3.ts b/public/docs/_examples/router-deprecated/ts/app/main.3.ts deleted file mode 100644 index 9e9eb04721..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/main.3.ts +++ /dev/null @@ -1,7 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { ROUTER_PROVIDERS } from '@angular/router-deprecated'; - -import { AppComponent } from './app.component.3'; - -bootstrap(AppComponent, [ROUTER_PROVIDERS]); diff --git a/public/docs/_examples/router-deprecated/ts/app/main.ts b/public/docs/_examples/router-deprecated/ts/app/main.ts deleted file mode 100644 index 08bbbef6e8..0000000000 --- a/public/docs/_examples/router-deprecated/ts/app/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { ROUTER_PROVIDERS } from '@angular/router-deprecated'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent, [ROUTER_PROVIDERS]); diff --git a/public/docs/_examples/router-deprecated/ts/index.1.html b/public/docs/_examples/router-deprecated/ts/index.1.html deleted file mode 100644 index 53a6d4832f..0000000000 --- a/public/docs/_examples/router-deprecated/ts/index.1.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - Router (Deprecated) Sample v.1 - - - - - - - - - - - - - - - - -

    Milestone 1

    - loading... - - - - diff --git a/public/docs/_examples/router-deprecated/ts/index.2.html b/public/docs/_examples/router-deprecated/ts/index.2.html deleted file mode 100644 index d71bd929cb..0000000000 --- a/public/docs/_examples/router-deprecated/ts/index.2.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Router (Deprecated) Sample v.2 - - - - - - - - - - - - - - - - -

    Milestone 2

    - loading... - - - - diff --git a/public/docs/_examples/router-deprecated/ts/index.3.html b/public/docs/_examples/router-deprecated/ts/index.3.html deleted file mode 100644 index abbb771beb..0000000000 --- a/public/docs/_examples/router-deprecated/ts/index.3.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Router (Deprecated) Sample v.3 - - - - - - - - - - - - - - - - -

    Milestone 3

    - loading... - - - - diff --git a/public/docs/_examples/router-deprecated/ts/index.html b/public/docs/_examples/router-deprecated/ts/index.html deleted file mode 100644 index 35a6ddfc73..0000000000 --- a/public/docs/_examples/router-deprecated/ts/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - Router (Deprecated) Sample - - - - - - - - - - - - - - - - - loading... - - - - diff --git a/public/docs/_examples/router-deprecated/ts/plnkr.json b/public/docs/_examples/router-deprecated/ts/plnkr.json deleted file mode 100644 index 91eff6fdb9..0000000000 --- a/public/docs/_examples/router-deprecated/ts/plnkr.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "description": "Router (Deprecated Beta)", - "files":[ - "!**/*.d.ts", - "!**/*.js", - "!**/*.[1,2,3].*", - "!app/crisis-list.component.ts", - "!app/hero-list.component.ts", - "!app/crisis-center/add-crisis.component.ts" - ], - "tags": ["router", "deprecated"] -} diff --git a/public/docs/_examples/router/e2e-spec.ts b/public/docs/_examples/router/e2e-spec.ts index 780b5e229a..2e9c6bafeb 100644 --- a/public/docs/_examples/router/e2e-spec.ts +++ b/public/docs/_examples/router/e2e-spec.ts @@ -1,126 +1,162 @@ -/// -describe('Router', function () { +'use strict'; // necessary for es6 output in node - beforeAll(function () { - browser.get(''); - }); +import { browser, element, by, ExpectedConditions } from 'protractor'; + +const numDashboardTabs = 5; +const numCrises = 4; +const numHeroes = 6; +const EC = ExpectedConditions; + +describe('Router', () => { + + beforeAll(() => browser.get('')); function getPageStruct() { - let hrefEles = element.all(by.css('my-app a')); + const hrefEles = element.all(by.css('my-app a')); + const crisisDetail = element.all(by.css('my-app > ng-component > ng-component > ng-component > div')).first(); + const heroDetail = element(by.css('my-app > ng-component > div')); return { hrefs: hrefEles, - routerParent: element(by.css('my-app > undefined')), - routerTitle: element(by.css('my-app > undefined > h2')), + activeHref: element(by.css('my-app a.active')), crisisHref: hrefEles.get(0), - crisisList: element.all(by.css('my-app > undefined > undefined li')), - crisisDetail: element(by.css('my-app > undefined > undefined > div')), - crisisDetailTitle: element(by.css('my-app > undefined > undefined > div > h3')), + crisisList: element.all(by.css('my-app > ng-component > ng-component li')), + crisisDetail: crisisDetail, + crisisDetailTitle: crisisDetail.element(by.xpath('*[1]')), heroesHref: hrefEles.get(1), - heroesList: element.all(by.css('my-app > undefined li')), - heroDetail: element(by.css('my-app > undefined > div')), - heroDetailTitle: element(by.css('my-app > undefined > div > h3')), + heroesList: element.all(by.css('my-app > ng-component li')), + heroDetail: heroDetail, + heroDetailTitle: heroDetail.element(by.xpath('*[1]')), - } + adminHref: hrefEles.get(2), + adminPreloadList: element.all(by.css('my-app > ng-component > ng-component > ul > li')), + + loginHref: hrefEles.get(3), + loginButton: element.all(by.css('my-app > ng-component > p > button')), + + contactHref: hrefEles.get(4), + contactCancelButton: element.all(by.buttonText('Cancel')), + + outletComponents: element.all(by.css('my-app > ng-component')) + }; } - it('should be able to see the start screen', function () { - let page = getPageStruct(); - expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices'); - expect(page.crisisHref.getText()).toEqual("Crisis Center"); - expect(page.heroesHref.getText()).toEqual("Heroes"); + it('has expected dashboard tabs', () => { + const page = getPageStruct(); + expect(page.hrefs.count()).toEqual(numDashboardTabs, 'dashboard tab count'); + expect(page.crisisHref.getText()).toEqual('Crisis Center'); + expect(page.heroesHref.getText()).toEqual('Heroes'); + expect(page.adminHref.getText()).toEqual('Admin'); + expect(page.loginHref.getText()).toEqual('Login'); + expect(page.contactHref.getText()).toEqual('Contact'); }); - it('should be able to see crises center items', function () { - let page = getPageStruct(); - expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries at start"); + it('has heroes selected as opening tab', () => { + const page = getPageStruct(); + expect(page.activeHref.getText()).toEqual('Heroes'); }); - it('should be able to see hero items', function () { - let page = getPageStruct(); - page.heroesHref.click().then(function() { - expect(page.routerTitle.getText()).toContain('HEROES'); - expect(page.heroesList.count()).toBe(6, "should be 6 heroes"); - }); + it('has crises center items', async () => { + const page = getPageStruct(); + await page.crisisHref.click(); + expect(page.activeHref.getText()).toEqual('Crisis Center'); + expect(page.crisisList.count()).toBe(numCrises, 'crisis list count'); }); - it('should be able to toggle the views', function () { - let page = getPageStruct(); - page.crisisHref.click().then(function() { - expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries"); - return page.heroesHref.click(); - }).then(function() { - expect(page.heroesList.count()).toBe(6, "should be 6 heroes"); - }); + it('has hero items', async () => { + const page = getPageStruct(); + await page.heroesHref.click(); + expect(page.activeHref.getText()).toEqual('Heroes'); + expect(page.heroesList.count()).toBe(numHeroes, 'hero list count'); }); - it('should be able to edit and save details from the crisis center view', function () { - crisisCenterEdit(2, true); + it('toggles views', async () => { + const page = getPageStruct(); + await page.crisisHref.click(); + expect(page.activeHref.getText()).toEqual('Crisis Center'); + expect(page.crisisList.count()).toBe(numCrises, 'crisis list count'); + await page.heroesHref.click(); + expect(page.activeHref.getText()).toEqual('Heroes'); + expect(page.heroesList.count()).toBe(numHeroes, 'hero list count'); }); - xit('should be able to edit and cancel details from the crisis center view', function () { - crisisCenterEdit(3, false); + it('saves changed crisis details', async () => { + const page = getPageStruct(); + await page.crisisHref.click(); + await crisisCenterEdit(2, true); }); - it('should be able to edit and save details from the heroes view', function () { - let page = getPageStruct(); - let heroEle: protractor.ElementFinder; - let heroText: string; - page.heroesHref.click().then(function() { - heroEle = page.heroesList.get(4); - return heroEle.getText(); - }).then(function(text) { - expect(text.length).toBeGreaterThan(0, 'should have some text'); - // remove leading id from text - heroText = text.substr(text.indexOf(' ')).trim(); - return heroEle.click(); - }).then(function() { - expect(page.heroesList.count()).toBe(0, "should no longer see crisis center entries"); - expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail'); - expect(page.heroDetailTitle.getText()).toContain(heroText); - let inputEle = page.heroDetail.element(by.css('input')); - return sendKeys(inputEle, '-foo'); - }).then(function() { - expect(page.heroDetailTitle.getText()).toContain(heroText + '-foo'); - let buttonEle = page.heroDetail.element(by.css('button')); - return buttonEle.click(); - }).then(function() { - expect(heroEle.getText()).toContain(heroText + '-foo'); - }) + it('can cancel changed crisis details', async () => { + const page = getPageStruct(); + await page.crisisHref.click(); + await crisisCenterEdit(3, false); }); - function crisisCenterEdit(index: number, shouldSave: boolean) { - let page = getPageStruct(); - let crisisEle: protractor.ElementFinder; - let crisisText: string; - page.crisisHref.click() - .then(function () { - crisisEle = page.crisisList.get(index); - return crisisEle.getText(); - }).then(function (text) { - expect(text.length).toBeGreaterThan(0, 'should have some text'); - // remove leading id from text - crisisText = text.substr(text.indexOf(' ')).trim(); - return crisisEle.click(); - }).then(function () { - expect(page.crisisList.count()).toBe(0, "should no longer see crisis center entries"); - expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail'); - expect(page.crisisDetailTitle.getText()).toContain(crisisText); - let inputEle = page.crisisDetail.element(by.css('input')); - return sendKeys(inputEle, '-foo'); - }).then(function () { - expect(page.crisisDetailTitle.getText()).toContain(crisisText + '-foo'); - let buttonEle = page.crisisDetail.element(by.cssContainingText('button', shouldSave ? 'Save' : 'Cancel')); - return buttonEle.click(); - }).then(function () { - if (shouldSave) { - expect(crisisEle.getText()).toContain(crisisText + '-foo'); - } else { - expect(crisisEle.getText()).not.toContain(crisisText + '-foo'); - } - }); + it('saves changed hero details', async () => { + const page = getPageStruct(); + await page.heroesHref.click(); + const heroEle = page.heroesList.get(4); + let text = await heroEle.getText(); + expect(text.length).toBeGreaterThan(0, 'hero item text length'); + // remove leading id from text + const heroText = text.substr(text.indexOf(' ')).trim(); + + await heroEle.click(); + expect(page.heroesList.count()).toBe(0, 'hero list count'); + expect(page.heroDetail.isPresent()).toBe(true, 'hero detail'); + expect(page.heroDetailTitle.getText()).toContain(heroText); + let inputEle = page.heroDetail.element(by.css('input')); + await inputEle.sendKeys('-foo'); + expect(page.heroDetailTitle.getText()).toContain(heroText + '-foo'); + + let buttonEle = page.heroDetail.element(by.css('button')); + await buttonEle.click(); + expect(heroEle.getText()).toContain(heroText + '-foo'); + }); + + it('sees preloaded modules', async () => { + const page = getPageStruct(); + await page.loginHref.click(); + await page.loginButton.click(); + const list = page.adminPreloadList; + expect(list.count()).toBe(1, 'preloaded module'); + expect(await list.first().getText()).toBe('crisis-center', 'first preloaded module'); + }); + + it('sees the secondary route', async () => { + const page = getPageStruct(); + await page.heroesHref.click(); + await page.contactHref.click(); + expect(page.outletComponents.count()).toBe(2, 'route count'); + }); + + async function crisisCenterEdit(index: number, save: boolean) { + const page = getPageStruct(); + await page.crisisHref.click(); + let crisisEle = page.crisisList.get(index); + let text = await crisisEle.getText(); + expect(text.length).toBeGreaterThan(0, 'crisis item text length'); + // remove leading id from text + const crisisText = text.substr(text.indexOf(' ')).trim(); + + await crisisEle.click(); + expect(page.crisisDetail.isPresent()).toBe(true, 'crisis detail present'); + expect(page.crisisDetailTitle.getText()).toContain(crisisText); + let inputEle = page.crisisDetail.element(by.css('input')); + await inputEle.sendKeys('-foo'); + + let buttonEle = page.crisisDetail.element(by.buttonText(save ? 'Save' : 'Cancel')); + await buttonEle.click(); + crisisEle = page.crisisList.get(index); + if (save) { + expect(crisisEle.getText()).toEqual(crisisText + '-foo'); + } else { + await browser.wait(EC.alertIsPresent(), 4000); + await browser.switchTo().alert().accept(); + expect(crisisEle.getText()).toEqual(crisisText); + } } }); diff --git a/public/docs/_examples/router/ts/app/app.component.1.ts b/public/docs/_examples/router/ts/app/app.component.1.ts deleted file mode 100644 index a041cb2198..0000000000 --- a/public/docs/_examples/router/ts/app/app.component.1.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* First version */ -// #docplaster - -// #docregion -import { Component } from '@angular/core'; -import { ROUTER_DIRECTIVES, Routes } from '@angular/router'; - -import { CrisisListComponent } from './crisis-list.component'; -import { HeroListComponent } from './hero-list.component'; - -@Component({ - selector: 'my-app', -// #docregion template - template: ` -

    Component Router

    - - - `, -// #enddocregion template - directives: [ROUTER_DIRECTIVES] -}) -// #enddocregion -/* - // #docregion route-config - @Component({ ... }) - // #enddocregion route-config - */ -// #docregion -// #docregion route-config -@Routes([ -// #docregion route-defs - {path: '/crisis-center', component: CrisisListComponent}, - {path: '/heroes', component: HeroListComponent}, - {path: '*', component: CrisisListComponent} -// #enddocregion route-defs -]) -export class AppComponent { } -// #enddocregion route-config -// #enddocregion diff --git a/public/docs/_examples/router/ts/app/app.component.2.ts b/public/docs/_examples/router/ts/app/app.component.2.ts deleted file mode 100644 index 5cbe9b1e7e..0000000000 --- a/public/docs/_examples/router/ts/app/app.component.2.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* Second Heroes version */ -// #docplaster - -// #docregion -import { Component, OnInit } from '@angular/core'; -import { Router, ROUTER_DIRECTIVES, Routes } from '@angular/router'; - -import { CrisisListComponent } from './crisis-list.component'; -// #enddocregion -/* - // Apparent Milestone 2 imports - // #docregion - // #docregion hero-import - import { HeroDetailComponent } from './heroes/hero-detail.component'; - import { HeroListComponent } from './heroes/hero-list.component'; - import { HeroService } from './heroes/hero.service'; - // #enddocregion hero-import - // #enddocregion - */ -// Actual Milestone 2 imports -import { HeroDetailComponent } from './heroes/hero-detail.component.1'; -import { HeroListComponent } from './heroes/hero-list.component.1'; -import { HeroService } from './heroes/hero.service'; -// #docregion - -@Component({ - selector: 'my-app', - template: ` -

    Component Router

    - - - `, - providers: [HeroService], - directives: [ROUTER_DIRECTIVES] -}) -// #enddocregion -/* - // #docregion route-config - @Component({ ... }) - // #enddocregion route-config - */ -// #docregion -// #docregion route-config -@Routes([ -// #docregion route-defs - {path: '/crisis-center', component: CrisisListComponent}, - {path: '/heroes', component: HeroListComponent}, - // #docregion hero-detail-route - {path: '/hero/:id', component: HeroDetailComponent} - // #enddocregion hero-detail-route -// #enddocregion route-defs -]) -export class AppComponent implements OnInit { - constructor(private router: Router) {} - - ngOnInit() { - this.router.navigate(['/crisis-center']); - } -} -// #enddocregion route-config -// #enddocregion diff --git a/public/docs/_examples/router/ts/app/app.component.3.ts b/public/docs/_examples/router/ts/app/app.component.3.ts deleted file mode 100644 index b44db38fc6..0000000000 --- a/public/docs/_examples/router/ts/app/app.component.3.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* tslint:disable:no-unused-variable */ -// #docplaster -import { Component, OnInit } from '@angular/core'; -import { Router, ROUTER_DIRECTIVES, Routes } from '@angular/router'; - -import { CrisisCenterComponent } from './crisis-center/crisis-center.component.1'; -import { HeroDetailComponent } from './heroes/hero-detail.component.1'; -import { HeroListComponent } from './heroes/hero-list.component.1'; - -import { DialogService } from './dialog.service'; -import { HeroService } from './heroes/hero.service'; - -@Component({ - selector: 'my-app', -// #enddocregion - /* Typical link - // #docregion h-anchor - Heroes - // #enddocregion h-anchor - */ - /* Incomplete Crisis Center link when CC lacks a default - // #docregion cc-anchor-fail - // The link now fails with a "non-terminal link" error - // #docregion cc-anchor-w-default - Crisis Center - // #enddocregion cc-anchor-w-default - // #enddocregion cc-anchor-fail - */ - /* Crisis Center link when CC lacks a default - // #docregion cc-anchor-no-default - Crisis Center - // #enddocregion cc-anchor-no-default - */ - /* Crisis Center Detail link - // #docregion Dragon-anchor - Dragon Crisis - // #enddocregion Dragon-anchor - */ -// #docregion template - template: ` -

    Component Router

    - - - `, -// #enddocregion template - providers: [DialogService, HeroService], - directives: [ROUTER_DIRECTIVES] -}) -@Routes([ - {path: '/crisis-center', component: CrisisCenterComponent}, - {path: '*', component: CrisisCenterComponent} -]) -export class AppComponent implements OnInit { - constructor(private router: Router) {} - - ngOnInit() { - this.router.navigate(['/crisis-center']); - } -} diff --git a/public/docs/_examples/router/ts/app/app.component.ts b/public/docs/_examples/router/ts/app/app.component.ts deleted file mode 100644 index aeee375e61..0000000000 --- a/public/docs/_examples/router/ts/app/app.component.ts +++ /dev/null @@ -1,41 +0,0 @@ -// #docplaster -// #docregion -import { Component, OnInit } from '@angular/core'; -import { Routes, Router, ROUTER_DIRECTIVES } from '@angular/router'; - -import { CrisisCenterComponent } from './crisis-center/crisis-center.component'; -import { HeroListComponent } from './heroes/hero-list.component'; -import { HeroDetailComponent } from './heroes/hero-detail.component'; - -import { DialogService } from './dialog.service'; -import { HeroService } from './heroes/hero.service'; - -@Component({ - selector: 'my-app', -// #docregion template - template: ` -

    Component Router

    - - - `, -// #enddocregion template - providers: [DialogService, HeroService], - directives: [ROUTER_DIRECTIVES] -}) -// #docregion routes -@Routes([ - {path: '/crisis-center', component: CrisisCenterComponent}, - {path: '/heroes', component: HeroListComponent}, - {path: '/hero/:id', component: HeroDetailComponent}, -]) -// #enddocregion routes -export class AppComponent implements OnInit { - constructor(private router: Router) {} - - ngOnInit() { - this.router.navigate(['/crisis-center']); - } -} diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.1.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.1.ts deleted file mode 100644 index d195a4a162..0000000000 --- a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.1.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Component } from '@angular/core'; -import { ROUTER_DIRECTIVES, Routes } from '@angular/router'; - -import { CrisisDetailComponent } from './crisis-detail.component.1'; -import { CrisisListComponent } from './crisis-list.component.1'; -import { CrisisService } from './crisis.service'; - -// #docregion minus-imports -@Component({ - template: ` -

    CRISIS CENTER

    - - `, - directives: [ROUTER_DIRECTIVES], -// #docregion providers - providers: [CrisisService] -// #enddocregion providers -}) -// #docregion route-config -@Routes([ - // #docregion default-route - {path: '/', component: CrisisListComponent}, // , useAsDefault: true}, // coming soon - // #enddocregion default-route - {path: '/:id', component: CrisisDetailComponent} -]) -// #enddocregion route-config -export class CrisisCenterComponent { } -// #enddocregion minus-imports diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.ts deleted file mode 100644 index 73cee8baac..0000000000 --- a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { ROUTER_DIRECTIVES, Routes } from '@angular/router'; - -import { CrisisDetailComponent } from './crisis-detail.component'; -import { CrisisListComponent } from './crisis-list.component'; -import { CrisisService } from './crisis.service'; - -@Component({ - template: ` -

    CRISIS CENTER

    - - `, - directives: [ROUTER_DIRECTIVES], - providers: [CrisisService] -}) -@Routes([ - {path: '', component: CrisisListComponent}, // , useAsDefault: true}, // coming soon - {path: '/:id', component: CrisisDetailComponent} -]) -export class CrisisCenterComponent { } -// #enddocregion diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.1.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.1.ts deleted file mode 100644 index 9ac3df8eb8..0000000000 --- a/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.1.ts +++ /dev/null @@ -1,93 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; -import { OnActivate, Router, RouteSegment } from '@angular/router'; - -import { Crisis, CrisisService } from './crisis.service'; -// #docregion routerCanDeactivate -// import { CanDeactivate } from '@angular/router'; -import { DialogService } from '../dialog.service'; - -// #enddocregion routerCanDeactivate -@Component({ - // #docregion template - template: ` -
    -

    "{{editName}}"

    -
    - {{crisis.id}}
    -
    - - -
    -

    - - -

    -
    - `, - // #enddocregion template - styles: ['input {width: 20em}'] -}) -// #docregion routerCanDeactivate, cancel-save -export class CrisisDetailComponent implements OnActivate {// , CanDeactivate { - - crisis: Crisis; - editName: string; - -// #enddocregion routerCanDeactivate, cancel-save - constructor( - private service: CrisisService, - private router: Router, - private dialog: DialogService - ) { } - - // #docregion ngOnActivate - routerOnActivate(curr: RouteSegment): void { - let id = +curr.getParam('id'); - this.service.getCrisis(id).then(crisis => { - if (crisis) { - this.editName = crisis.name; - this.crisis = crisis; - } else { // id not found - this.gotoCrises(); - } - }); - } - // #enddocregion ngOnActivate - - // #docregion routerCanDeactivate - // NOT IMPLEMENTED YET - routerCanDeactivate(): any { - // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged. - if (!this.crisis || this.crisis.name === this.editName) { - return true; - } - // Otherwise ask the user with the dialog service and return its - // promise which resolves to true or false when the user decides - return this.dialog.confirm('Discard changes?'); - } - // #enddocregion routerCanDeactivate - - // #docregion cancel-save - cancel() { - this.editName = this.crisis.name; - this.gotoCrises(); - } - - save() { - this.crisis.name = this.editName; - this.gotoCrises(); - } - // #enddocregion cancel-save - - // #docregion gotoCrises - gotoCrises() { - // Like Crisis Center -

    "{{editName}}"

    -
    - {{crisis.id}}
    -
    - - -
    -

    - - -

    - - `, - styles: ['input {width: 20em}'] -}) - -export class CrisisDetailComponent implements OnActivate, CanDeactivate { - crisis: Crisis; - editName: string; - private curSegment: RouteSegment; - - constructor( - private service: CrisisService, - private router: Router, - private dialog: DialogService - ) { } - - routerOnActivate(curr: RouteSegment) { - this.curSegment = curr; - - let id = +curr.getParam('id'); - this.service.getCrisis(id).then(crisis => { - if (crisis) { - this.editName = crisis.name; - this.crisis = crisis; - } else { // id not found - this.gotoCrises(); - } - }); - } - - routerCanDeactivate(): any { - // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged. - if (!this.crisis || this.crisis.name === this.editName) { - return true; - } - // Otherwise ask the user with the dialog service and return its - // promise which resolves to true or false when the user decides - return this.dialog.confirm('Discard changes?'); - } - - cancel() { - this.editName = this.crisis.name; - this.gotoCrises(); - } - - save() { - this.crisis.name = this.editName; - this.gotoCrises(); - } - - // #docregion gotoCrises - gotoCrises() { - let crisisId = this.crisis ? this.crisis.id : null; - // Pass along the hero id if available - // so that the CrisisListComponent can select that hero. - // Add a totally useless `foo` parameter for kicks. - // #docregion gotoCrises-navigate - // Absolute link - this.router.navigate(['/crisis-center', {id: crisisId, foo: 'foo'}]); - - // Relative link - // this.router.navigate(['../', {id: crisisId, foo: 'foo'}], this.curSegment); - // #enddocregion gotoCrises-navigate - } - // #enddocregion gotoCrises -} diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.1.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.1.ts deleted file mode 100644 index 7c78a63bf6..0000000000 --- a/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.1.ts +++ /dev/null @@ -1,36 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; -import { OnActivate, Router, RouteSegment } from '@angular/router'; - -import { Crisis, CrisisService } from './crisis.service'; - -@Component({ - // #docregion template - template: ` -
      -
    • - {{crisis.id}} {{crisis.name}} -
    • -
    - `, - // #enddocregion template -}) -export class CrisisListComponent implements OnActivate { - crises: Crisis[]; - - constructor( - private service: CrisisService, - private router: Router) {} - - routerOnActivate(curr: RouteSegment): void { - this.service.getCrises().then(crises => this.crises = crises); - } - - // #docregion select - onSelect(crisis: Crisis) { - this.router.navigateByUrl( `/crisis-list/${crisis.id}`); - } - // #enddocregion select -} diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.ts deleted file mode 100644 index d6f99ff4b5..0000000000 --- a/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.ts +++ /dev/null @@ -1,43 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; -import { OnActivate, Router, RouteSegment, RouteTree } from '@angular/router'; - -import { Crisis, CrisisService } from './crisis.service'; - -@Component({ - template: ` -
      -
    • - {{crisis.id}} {{crisis.name}} -
    • -
    - `, -}) -export class CrisisListComponent implements OnActivate { - crises: Crisis[]; - private currSegment: RouteSegment; - private selectedId: number; - - constructor( - private service: CrisisService, - private router: Router) { } - - isSelected(crisis: Crisis) { return crisis.id === this.selectedId; } - - routerOnActivate(curr: RouteSegment, prev: RouteSegment, currTree: RouteTree) { - this.currSegment = curr; - this.selectedId = +currTree.parent(curr).getParam('id'); - this.service.getCrises().then(crises => this.crises = crises); - } - - onSelect(crisis: Crisis) { - // Absolute link - // this.router.navigate([`/crisis-center`, crisis.id]); - - // Relative link - this.router.navigate([`./${crisis.id}`], this.currSegment); - } -} diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis.service.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis.service.ts deleted file mode 100644 index 46158da480..0000000000 --- a/public/docs/_examples/router/ts/app/crisis-center/crisis.service.ts +++ /dev/null @@ -1,42 +0,0 @@ -// #docplaster - -export class Crisis { - constructor(public id: number, public name: string) { } -} - -const CRISES = [ - new Crisis(1, 'Dragon Burning Cities'), - new Crisis(2, 'Sky Rains Great White Sharks'), - new Crisis(3, 'Giant Asteroid Heading For Earth'), - new Crisis(4, 'Procrastinators Meeting Delayed Again'), -]; - -let crisesPromise = Promise.resolve(CRISES); - -// #docregion -import { Injectable } from '@angular/core'; - -@Injectable() -export class CrisisService { - - static nextCrisisId = 100; - - getCrises() { return crisesPromise; } - - getCrisis(id: number | string) { - return crisesPromise - .then(crises => crises.filter(c => c.id === +id)[0]); - } - -// #enddocregion - - addCrisis(name: string) { - name = name.trim(); - if (name) { - let crisis = new Crisis(CrisisService.nextCrisisId++, name); - crisesPromise.then(crises => crises.push(crisis)); - } - } -// #docregion -} -// #enddocregion diff --git a/public/docs/_examples/router/ts/app/crisis-list.component.ts b/public/docs/_examples/router/ts/app/crisis-list.component.ts deleted file mode 100644 index 6caa3653b5..0000000000 --- a/public/docs/_examples/router/ts/app/crisis-list.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Initial empty version -// #docregion -import { Component } from '@angular/core'; - -@Component({ - template: ` -

    CRISIS CENTER

    -

    Get your crisis here

    ` -}) -export class CrisisListComponent { } diff --git a/public/docs/_examples/router/ts/app/dialog.service.ts b/public/docs/_examples/router/ts/app/dialog.service.ts deleted file mode 100644 index 71a342cbe8..0000000000 --- a/public/docs/_examples/router/ts/app/dialog.service.ts +++ /dev/null @@ -1,18 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; -/** - * Async modal dialog service - * DialogService makes this app easier to test by faking this service. - * TODO: better modal implementation that doesn't use window.confirm - */ -@Injectable() -export class DialogService { - /** - * Ask user to confirm an action. `message` explains the action and choices. - * Returns promise resolving to `true`=confirm or `false`=cancel - */ - confirm(message?: string) { - return new Promise((resolve, reject) => - resolve(window.confirm(message || 'Is it OK?'))); - }; -} diff --git a/public/docs/_examples/router/ts/app/hero-list.component.ts b/public/docs/_examples/router/ts/app/hero-list.component.ts deleted file mode 100644 index 5dbbe17d8e..0000000000 --- a/public/docs/_examples/router/ts/app/hero-list.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -/// Initial empty version -// #docregion -import { Component } from '@angular/core'; - -@Component({ - template: ` -

    HEROES

    -

    Get your heroes here

    ` -}) -export class HeroListComponent { } diff --git a/public/docs/_examples/router/ts/app/heroes/hero-detail.component.1.ts b/public/docs/_examples/router/ts/app/heroes/hero-detail.component.1.ts deleted file mode 100644 index eecc838ab3..0000000000 --- a/public/docs/_examples/router/ts/app/heroes/hero-detail.component.1.ts +++ /dev/null @@ -1,46 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { OnActivate, Router, RouteSegment } from '@angular/router'; - -import { Hero, HeroService } from './hero.service'; - -@Component({ - template: ` -

    HEROES

    -
    -

    "{{hero.name}}"

    -
    - {{hero.id}}
    -
    - - -
    -

    - -

    -
    - `, -}) -export class HeroDetailComponent implements OnActivate { - hero: Hero; - - // #docregion ctor - constructor( - private router: Router, - private service: HeroService) {} - // #enddocregion ctor - - // #docregion OnActivate - routerOnActivate(curr: RouteSegment): void { - let id = +curr.getParam('id'); - this.service.getHero(id).then(hero => this.hero = hero); - } - // #enddocregion OnActivate - - // #docregion gotoHeroes - gotoHeroes() { - // Like Heroes - this.router.navigate(['/heroes']); - } - // #enddocregion gotoHeroes -} diff --git a/public/docs/_examples/router/ts/app/heroes/hero-detail.component.ts b/public/docs/_examples/router/ts/app/heroes/hero-detail.component.ts deleted file mode 100644 index 21ab9fba8c..0000000000 --- a/public/docs/_examples/router/ts/app/heroes/hero-detail.component.ts +++ /dev/null @@ -1,50 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { OnActivate, Router, RouteSegment } from '@angular/router'; - -import { Hero, HeroService } from './hero.service'; - -@Component({ - template: ` -

    HEROES

    -
    -

    "{{hero.name}}"

    -
    - {{hero.id}}
    -
    - - -
    -

    - -

    -
    - `, -}) -export class HeroDetailComponent implements OnActivate { - hero: Hero; - - // #docregion ctor - constructor( - private router: Router, - private service: HeroService) {} - // #enddocregion ctor - - - // #docregion OnActivate - routerOnActivate(curr: RouteSegment): void { - let id = +curr.getParam('id'); - this.service.getHero(id).then(hero => this.hero = hero); - } - // #enddocregion OnActivate - - gotoHeroes() { - let heroId = this.hero ? this.hero.id : null; - // Pass along the hero id if available - // so that the HeroList component can select that hero. - // Add a totally useless `foo` parameter for kicks. - // #docregion gotoHeroes-navigate - this.router.navigate([`/heroes`, {id: heroId, foo: 'foo'}]); - // #enddocregion gotoHeroes-navigate - } -} diff --git a/public/docs/_examples/router/ts/app/heroes/hero-list.component.1.ts b/public/docs/_examples/router/ts/app/heroes/hero-list.component.1.ts deleted file mode 100644 index 967ca97ccb..0000000000 --- a/public/docs/_examples/router/ts/app/heroes/hero-list.component.1.ts +++ /dev/null @@ -1,49 +0,0 @@ -// #docplaster -// #docregion -// TODO SOMEDAY: Feature Componetized like HeroCenter -import {Component, OnInit} from '@angular/core'; -import {Router} from '@angular/router'; - -import {Hero, HeroService} from './hero.service'; - -@Component({ - // #docregion template - template: ` -

    HEROES

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    - ` - // #enddocregion template -}) -export class HeroListComponent implements OnInit { - heroes: Hero[]; - - // #docregion ctor - constructor( - private router: Router, - private service: HeroService) { } - // #enddocregion ctor - - ngOnInit() { - this.service.getHeroes().then(heroes => this.heroes = heroes) - } - - // #docregion select - onSelect(hero: Hero) { - // #docregion nav-to-detail - this.router.navigate(['/hero', hero.id]); - // #enddocregion nav-to-detail - } - // #enddocregion select -} -// #enddocregion - -/* A link parameters array - // #docregion link-parameters-array - ['HeroDetail', { id: hero.id }] // {id: 15} - // #enddocregion link-parameters-array - */ diff --git a/public/docs/_examples/router/ts/app/heroes/hero-list.component.ts b/public/docs/_examples/router/ts/app/heroes/hero-list.component.ts deleted file mode 100644 index 00361ac9fe..0000000000 --- a/public/docs/_examples/router/ts/app/heroes/hero-list.component.ts +++ /dev/null @@ -1,52 +0,0 @@ -// #docplaster -// #docregion -// TODO SOMEDAY: Feature Componetized like CrisisCenter -import { Component } from '@angular/core'; -// #docregion import-router -import { OnActivate, Router, RouteSegment, RouteTree } from '@angular/router'; -// #enddocregion import-router - -import { Hero, HeroService} from './hero.service'; - -@Component({ - // #docregion template - template: ` -

    HEROES

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    - ` - // #enddocregion template -}) -export class HeroListComponent implements OnActivate { - heroes: Hero[]; - - // #docregion ctor - private selectedId: number; - - constructor( - private service: HeroService, - private router: Router) { } - // #enddocregion ctor - - routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: RouteTree, prevTree?: RouteTree): void { - this.selectedId = +curr.getParam('id'); - this.service.getHeroes().then(heroes => this.heroes = heroes); - } - - // #docregion isSelected - isSelected(hero: Hero) { return hero.id === this.selectedId; } - // #enddocregion isSelected - - // #docregion select - onSelect(hero: Hero) { - this.router.navigate(['/hero', hero.id]); - } - // #enddocregion select - -} -// #enddocregion diff --git a/public/docs/_examples/router/ts/app/heroes/hero.service.ts b/public/docs/_examples/router/ts/app/heroes/hero.service.ts deleted file mode 100644 index 7ead04d9a4..0000000000 --- a/public/docs/_examples/router/ts/app/heroes/hero.service.ts +++ /dev/null @@ -1,27 +0,0 @@ -// #docregion -import {Injectable} from '@angular/core'; - -export class Hero { - constructor(public id: number, public name: string) { } -} - -let HEROES = [ - new Hero(11, 'Mr. Nice'), - new Hero(12, 'Narco'), - new Hero(13, 'Bombasto'), - new Hero(14, 'Celeritas'), - new Hero(15, 'Magneta'), - new Hero(16, 'RubberMan') -]; - -let heroesPromise = Promise.resolve(HEROES); - -@Injectable() -export class HeroService { - getHeroes() { return heroesPromise; } - - getHero(id: number | string) { - return heroesPromise - .then(heroes => heroes.filter(h => h.id === +id)[0]); - } -} diff --git a/public/docs/_examples/router/ts/app/main.1.ts b/public/docs/_examples/router/ts/app/main.1.ts deleted file mode 100644 index 92ff416326..0000000000 --- a/public/docs/_examples/router/ts/app/main.1.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* First version */ -// #docplaster - -// #docregion all -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { ROUTER_PROVIDERS } from '@angular/router'; - -import { AppComponent } from './app.component'; -// #enddocregion all - -/* Can't use AppComponent ... but display as if we can -// #docregion all -bootstrap(AppComponent, [ -// #enddocregion all -*/ - -// Actually use the v.1 component -import { AppComponent as ac } from './app.component.1'; -bootstrap(ac, [ -// #docregion all - ROUTER_PROVIDERS -]); -// #enddocregion all diff --git a/public/docs/_examples/router/ts/app/main.2.ts b/public/docs/_examples/router/ts/app/main.2.ts deleted file mode 100644 index 0740a43a08..0000000000 --- a/public/docs/_examples/router/ts/app/main.2.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* Second version */ -// For Milestone #2 -// Also includes digression on HashPathStrategy (not used in the final app) -// #docplaster - -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { ROUTER_PROVIDERS } from '@angular/router'; - -// Add these symbols to override the `LocationStrategy` -import { LocationStrategy, - HashLocationStrategy } from '@angular/common'; - -import { AppComponent } from './app.component'; -// #enddocregion -/* Can't use AppComponent ... but display as if we can -// #docregion - -bootstrap(AppComponent, [ -// #enddocregion -*/ - -// Actually use the v.2 component -import {AppComponent as ac} from './app.component.2'; - -bootstrap(ac, [ -// #docregion - ROUTER_PROVIDERS, - { provide: LocationStrategy, useClass: HashLocationStrategy } // .../#/crisis-center/ -]); -// #enddocregion diff --git a/public/docs/_examples/router/ts/app/main.3.ts b/public/docs/_examples/router/ts/app/main.3.ts deleted file mode 100644 index 9ee2055ee6..0000000000 --- a/public/docs/_examples/router/ts/app/main.3.ts +++ /dev/null @@ -1,7 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { ROUTER_PROVIDERS } from '@angular/router'; - -import { AppComponent } from './app.component.3'; - -bootstrap(AppComponent, [ROUTER_PROVIDERS]); diff --git a/public/docs/_examples/router/ts/app/main.ts b/public/docs/_examples/router/ts/app/main.ts deleted file mode 100644 index 34079f84f0..0000000000 --- a/public/docs/_examples/router/ts/app/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { ROUTER_PROVIDERS } from '@angular/router'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent, [ROUTER_PROVIDERS]); diff --git a/public/docs/_examples/router/ts/index.1.html b/public/docs/_examples/router/ts/index.1.html deleted file mode 100644 index c04b769a2c..0000000000 --- a/public/docs/_examples/router/ts/index.1.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - Router Sample v.1 - - - - - - - - - - - - - - - - -

    Milestone 1

    - loading... - - - - diff --git a/public/docs/_examples/router/ts/index.2.html b/public/docs/_examples/router/ts/index.2.html deleted file mode 100644 index 01e521e896..0000000000 --- a/public/docs/_examples/router/ts/index.2.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - Router Sample v.2 - - - - - - - - - - - - - - - - -

    Milestone 2

    - loading... - - - -

    Milestone 2

    - loading... - - - - diff --git a/public/docs/_examples/router/ts/index.3.html b/public/docs/_examples/router/ts/index.3.html deleted file mode 100644 index f60cdd8163..0000000000 --- a/public/docs/_examples/router/ts/index.3.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Router Sample v.3 - - - - - - - - - - - - - - - - -

    Milestone 3

    - loading... - - - - diff --git a/public/docs/_examples/router/ts/index.html b/public/docs/_examples/router/ts/index.html deleted file mode 100644 index b7b5ba9f7f..0000000000 --- a/public/docs/_examples/router/ts/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - Router Sample - - - - - - - - - - - - - - - - - loading... - - - - diff --git a/public/docs/_examples/router/ts/plnkr.json b/public/docs/_examples/router/ts/plnkr.json index 741f87caa6..23ed1a1606 100644 --- a/public/docs/_examples/router/ts/plnkr.json +++ b/public/docs/_examples/router/ts/plnkr.json @@ -1,12 +1,12 @@ { "description": "Router", + "basePath": "src/", "files":[ "!**/*.d.ts", "!**/*.js", - "!**/*.[1,2,3].*", + "!**/*.[0-9].*", "!app/crisis-list.component.ts", - "!app/hero-list.component.ts", - "!app/crisis-center/add-crisis.component.ts" + "!app/hero-list.component.ts" ], "tags": ["router"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/router/ts/src/app/admin/admin-dashboard.component.1.ts b/public/docs/_examples/router/ts/src/app/admin/admin-dashboard.component.1.ts new file mode 100644 index 0000000000..ffa3e3cb8f --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/admin/admin-dashboard.component.1.ts @@ -0,0 +1,9 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + template: ` +

    Dashboard

    + ` +}) +export class AdminDashboardComponent { } diff --git a/public/docs/_examples/router/ts/src/app/admin/admin-dashboard.component.2.ts b/public/docs/_examples/router/ts/src/app/admin/admin-dashboard.component.2.ts new file mode 100644 index 0000000000..8c8e481643 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/admin/admin-dashboard.component.2.ts @@ -0,0 +1,33 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/map'; + +@Component({ + template: ` +

    Dashboard

    + +

    Session ID: {{ sessionId | async }}

    + +

    Token: {{ token | async }}

    + ` +}) +export class AdminDashboardComponent implements OnInit { + sessionId: Observable; + token: Observable; + + constructor(private route: ActivatedRoute) {} + + ngOnInit() { + // Capture the session ID if available + this.sessionId = this.route + .queryParams + .map(params => params['session_id'] || 'None'); + + // Capture the fragment if available + this.token = this.route + .fragment + .map(fragment => fragment || 'None'); + } +} diff --git a/public/docs/_examples/router/ts/src/app/admin/admin-dashboard.component.ts b/public/docs/_examples/router/ts/src/app/admin/admin-dashboard.component.ts new file mode 100644 index 0000000000..b3fc839616 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/admin/admin-dashboard.component.ts @@ -0,0 +1,47 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; + +import { SelectivePreloadingStrategy } from '../selective-preloading-strategy'; + +import 'rxjs/add/operator/map'; + +@Component({ + template: ` +

    Dashboard

    + +

    Session ID: {{ sessionId | async }}

    + +

    Token: {{ token | async }}

    + + Preloaded Modules +
      +
    • {{ module }}
    • +
    + ` +}) +export class AdminDashboardComponent implements OnInit { + sessionId: Observable; + token: Observable; + modules: string[]; + + constructor( + private route: ActivatedRoute, + private preloadStrategy: SelectivePreloadingStrategy + ) { + this.modules = preloadStrategy.preloadedModules; + } + + ngOnInit() { + // Capture the session ID if available + this.sessionId = this.route + .queryParams + .map(params => params['session_id'] || 'None'); + + // Capture the fragment if available + this.token = this.route + .fragment + .map(fragment => fragment || 'None'); + } +} diff --git a/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.1.ts b/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.1.ts new file mode 100644 index 0000000000..e7d83f113f --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.1.ts @@ -0,0 +1,39 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { AdminComponent } from './admin.component'; +import { AdminDashboardComponent } from './admin-dashboard.component'; +import { ManageCrisesComponent } from './manage-crises.component'; +import { ManageHeroesComponent } from './manage-heroes.component'; + +// #docregion admin-routes +const adminRoutes: Routes = [ + { + path: 'admin', + component: AdminComponent, + children: [ + { + path: '', + children: [ + { path: 'crises', component: ManageCrisesComponent }, + { path: 'heroes', component: ManageHeroesComponent }, + { path: '', component: AdminDashboardComponent } + ] + } + ] + } +]; + +@NgModule({ + imports: [ + RouterModule.forChild(adminRoutes) + ], + exports: [ + RouterModule + ] +}) +export class AdminRoutingModule {} +// #enddocregion admin-routes +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.2.ts b/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.2.ts new file mode 100644 index 0000000000..d945201afe --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.2.ts @@ -0,0 +1,44 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { AdminComponent } from './admin.component'; +import { AdminDashboardComponent } from './admin-dashboard.component'; +import { ManageCrisesComponent } from './manage-crises.component'; +import { ManageHeroesComponent } from './manage-heroes.component'; + +// #docregion admin-route +import { AuthGuard } from '../auth-guard.service'; + +const adminRoutes: Routes = [ + { + path: 'admin', + component: AdminComponent, + canActivate: [AuthGuard], + children: [ + { + path: '', + children: [ + { path: 'crises', component: ManageCrisesComponent }, + { path: 'heroes', component: ManageHeroesComponent }, + { path: '', component: AdminDashboardComponent } + ], + // #enddocregion admin-route + canActivateChild: [AuthGuard] + // #docregion admin-route + } + ] + } +]; + +@NgModule({ + imports: [ + RouterModule.forChild(adminRoutes) + ], + exports: [ + RouterModule + ] +}) +export class AdminRoutingModule {} +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.3.ts b/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.3.ts new file mode 100644 index 0000000000..63f1c9aaf4 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.3.ts @@ -0,0 +1,43 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { AdminComponent } from './admin.component'; +import { AdminDashboardComponent } from './admin-dashboard.component'; +import { ManageCrisesComponent } from './manage-crises.component'; +import { ManageHeroesComponent } from './manage-heroes.component'; + +// #docregion admin-route +import { AuthGuard } from '../auth-guard.service'; + +// #docregion can-activate-child +const adminRoutes: Routes = [ + { + path: 'admin', + component: AdminComponent, + canActivate: [AuthGuard], + children: [ + { + path: '', + canActivateChild: [AuthGuard], + children: [ + { path: 'crises', component: ManageCrisesComponent }, + { path: 'heroes', component: ManageHeroesComponent }, + { path: '', component: AdminDashboardComponent } + ] + } + ] + } +]; + +@NgModule({ + imports: [ + RouterModule.forChild(adminRoutes) + ], + exports: [ + RouterModule + ] +}) +export class AdminRoutingModule {} +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.ts b/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.ts new file mode 100644 index 0000000000..2b1048d110 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/admin/admin-routing.module.ts @@ -0,0 +1,41 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { AdminComponent } from './admin.component'; +import { AdminDashboardComponent } from './admin-dashboard.component'; +import { ManageCrisesComponent } from './manage-crises.component'; +import { ManageHeroesComponent } from './manage-heroes.component'; + +import { AuthGuard } from '../auth-guard.service'; + +const adminRoutes: Routes = [ + { + path: '', + component: AdminComponent, + canActivate: [AuthGuard], + children: [ + { + path: '', + canActivateChild: [AuthGuard], + children: [ + { path: 'crises', component: ManageCrisesComponent }, + { path: 'heroes', component: ManageHeroesComponent }, + { path: '', component: AdminDashboardComponent } + ] + } + ] + } +]; + +@NgModule({ + imports: [ + RouterModule.forChild(adminRoutes) + ], + exports: [ + RouterModule + ] +}) +export class AdminRoutingModule {} +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/admin/admin.component.ts b/public/docs/_examples/router/ts/src/app/admin/admin.component.ts new file mode 100644 index 0000000000..30abfa4524 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/admin/admin.component.ts @@ -0,0 +1,17 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + template: ` +

    ADMIN

    + + + ` +}) +export class AdminComponent { +} diff --git a/public/docs/_examples/router/ts/src/app/admin/admin.module.ts b/public/docs/_examples/router/ts/src/app/admin/admin.module.ts new file mode 100644 index 0000000000..2736f00e1d --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/admin/admin.module.ts @@ -0,0 +1,24 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { AdminComponent } from './admin.component'; +import { AdminDashboardComponent } from './admin-dashboard.component'; +import { ManageCrisesComponent } from './manage-crises.component'; +import { ManageHeroesComponent } from './manage-heroes.component'; + +import { AdminRoutingModule } from './admin-routing.module'; + +@NgModule({ + imports: [ + CommonModule, + AdminRoutingModule + ], + declarations: [ + AdminComponent, + AdminDashboardComponent, + ManageCrisesComponent, + ManageHeroesComponent + ] +}) +export class AdminModule {} diff --git a/public/docs/_examples/router/ts/src/app/admin/manage-crises.component.ts b/public/docs/_examples/router/ts/src/app/admin/manage-crises.component.ts new file mode 100644 index 0000000000..d3176563eb --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/admin/manage-crises.component.ts @@ -0,0 +1,9 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + template: ` +

    Manage your crises here

    + ` +}) +export class ManageCrisesComponent { } diff --git a/public/docs/_examples/router/ts/src/app/admin/manage-heroes.component.ts b/public/docs/_examples/router/ts/src/app/admin/manage-heroes.component.ts new file mode 100644 index 0000000000..7f3a39893d --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/admin/manage-heroes.component.ts @@ -0,0 +1,9 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + template: ` +

    Manage your heroes here

    + ` +}) +export class ManageHeroesComponent { } diff --git a/public/docs/_examples/router/ts/src/app/animations.ts b/public/docs/_examples/router/ts/src/app/animations.ts new file mode 100644 index 0000000000..d7a55d721f --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/animations.ts @@ -0,0 +1,26 @@ +// #docregion +import { animate, AnimationEntryMetadata, state, style, transition, trigger } from '@angular/core'; + +// Component transition animations +export const slideInDownAnimation: AnimationEntryMetadata = + trigger('routeAnimation', [ + state('*', + style({ + opacity: 1, + transform: 'translateX(0)' + }) + ), + transition(':enter', [ + style({ + opacity: 0, + transform: 'translateX(-100%)' + }), + animate('0.2s ease-in') + ]), + transition(':leave', [ + animate('0.5s ease-out', style({ + opacity: 0, + transform: 'translateY(100%)' + })) + ]) + ]); diff --git a/public/docs/_examples/router/ts/src/app/app-routing.module.1.ts b/public/docs/_examples/router/ts/src/app/app-routing.module.1.ts new file mode 100644 index 0000000000..8146e54671 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app-routing.module.1.ts @@ -0,0 +1,26 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { CrisisListComponent } from './crisis-list.component'; +import { HeroListComponent } from './hero-list.component'; +import { PageNotFoundComponent } from './not-found.component'; + +// #docregion appRoutes +const appRoutes: Routes = [ + { path: 'crisis-center', component: CrisisListComponent }, + { path: 'heroes', component: HeroListComponent }, + { path: '', redirectTo: '/heroes', pathMatch: 'full' }, + { path: '**', component: PageNotFoundComponent } +]; +// #enddocregion appRoutes + +@NgModule({ + imports: [ + RouterModule.forRoot(appRoutes) + ], + exports: [ + RouterModule + ] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/router/ts/src/app/app-routing.module.2.ts b/public/docs/_examples/router/ts/src/app/app-routing.module.2.ts new file mode 100644 index 0000000000..42ac84a481 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app-routing.module.2.ts @@ -0,0 +1,24 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { CrisisListComponent } from './crisis-list.component'; +// import { HeroListComponent } from './hero-list.component'; // <-- delete this line +import { PageNotFoundComponent } from './not-found.component'; + +const appRoutes: Routes = [ + { path: 'crisis-center', component: CrisisListComponent }, + // { path: 'heroes', component: HeroListComponent }, // <-- delete this line + { path: '', redirectTo: '/heroes', pathMatch: 'full' }, + { path: '**', component: PageNotFoundComponent } +]; + +@NgModule({ + imports: [ + RouterModule.forRoot(appRoutes) + ], + exports: [ + RouterModule + ] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/router/ts/src/app/app-routing.module.3.ts b/public/docs/_examples/router/ts/src/app/app-routing.module.3.ts new file mode 100644 index 0000000000..538ff9aafc --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app-routing.module.3.ts @@ -0,0 +1,31 @@ +// #docplaster +// #docregion , v3 +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { ComposeMessageComponent } from './compose-message.component'; +import { PageNotFoundComponent } from './not-found.component'; + +const appRoutes: Routes = [ +// #enddocregion v3 +// #docregion compose + { + path: 'compose', + component: ComposeMessageComponent, + outlet: 'popup' + }, +// #enddocregion compose +// #docregion v3 + { path: '', redirectTo: '/heroes', pathMatch: 'full' }, + { path: '**', component: PageNotFoundComponent } +]; + +@NgModule({ + imports: [ + RouterModule.forRoot(appRoutes) + ], + exports: [ + RouterModule + ] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/router/ts/src/app/app-routing.module.4.ts b/public/docs/_examples/router/ts/src/app/app-routing.module.4.ts new file mode 100644 index 0000000000..6835d24a85 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app-routing.module.4.ts @@ -0,0 +1,30 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { ComposeMessageComponent } from './compose-message.component'; +import { CanDeactivateGuard } from './can-deactivate-guard.service'; +import { PageNotFoundComponent } from './not-found.component'; + +const appRoutes: Routes = [ + { + path: 'compose', + component: ComposeMessageComponent, + outlet: 'popup' + }, + { path: '', redirectTo: '/heroes', pathMatch: 'full' }, + { path: '**', component: PageNotFoundComponent } +]; + +@NgModule({ + imports: [ + RouterModule.forRoot(appRoutes) + ], + exports: [ + RouterModule + ], + providers: [ + CanDeactivateGuard + ] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/router/ts/src/app/app-routing.module.5.ts b/public/docs/_examples/router/ts/src/app/app-routing.module.5.ts new file mode 100644 index 0000000000..2badf7f593 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app-routing.module.5.ts @@ -0,0 +1,45 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +// #docregion import-router +import { RouterModule, Routes } from '@angular/router'; +// #enddocregion import-router + +import { ComposeMessageComponent } from './compose-message.component'; +import { PageNotFoundComponent } from './not-found.component'; + +import { CanDeactivateGuard } from './can-deactivate-guard.service'; +import { AuthGuard } from './auth-guard.service'; + + +const appRoutes: Routes = [ + { + path: 'compose', + component: ComposeMessageComponent, + outlet: 'popup' + }, +// #docregion admin, admin-1 + { + path: 'admin', + loadChildren: 'app/admin/admin.module#AdminModule', +// #enddocregion admin-1 + canLoad: [AuthGuard] +// #docregion admin-1 + }, +// #enddocregion admin, admin-1 + { path: '', redirectTo: '/heroes', pathMatch: 'full' }, + { path: '**', component: PageNotFoundComponent } +]; + +@NgModule({ + imports: [ + RouterModule.forRoot(appRoutes) + ], + exports: [ + RouterModule + ], + providers: [ + CanDeactivateGuard + ] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/router/ts/src/app/app-routing.module.6.ts b/public/docs/_examples/router/ts/src/app/app-routing.module.6.ts new file mode 100644 index 0000000000..df2c8c097d --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app-routing.module.6.ts @@ -0,0 +1,54 @@ +// #docplaster +// #docregion, preload-v1 +import { NgModule } from '@angular/core'; +import { + RouterModule, Routes, +// #enddocregion preload-v1 + PreloadAllModules +// #docregion preload-v1 +} from '@angular/router'; + +import { ComposeMessageComponent } from './compose-message.component'; +import { PageNotFoundComponent } from './not-found.component'; + +import { CanDeactivateGuard } from './can-deactivate-guard.service'; +import { AuthGuard } from './auth-guard.service'; + +const appRoutes: Routes = [ + { + path: 'compose', + component: ComposeMessageComponent, + outlet: 'popup' + }, + { + path: 'admin', + loadChildren: 'app/admin/admin.module#AdminModule', + canLoad: [AuthGuard] + }, + { + path: 'crisis-center', + loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule' + }, + { path: '', redirectTo: '/heroes', pathMatch: 'full' }, + { path: '**', component: PageNotFoundComponent } +]; + +@NgModule({ + imports: [ + // #docregion forRoot + RouterModule.forRoot( + appRoutes + // #enddocregion preload-v1 + , { preloadingStrategy: PreloadAllModules } + // #docregion preload-v1 + ) + // #enddocregion forRoot + ], + exports: [ + RouterModule + ], + providers: [ + CanDeactivateGuard + ] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/router/ts/src/app/app-routing.module.ts b/public/docs/_examples/router/ts/src/app/app-routing.module.ts new file mode 100644 index 0000000000..cc01ced890 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app-routing.module.ts @@ -0,0 +1,50 @@ +// #docplaster +// #docregion, preload-v1 +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { ComposeMessageComponent } from './compose-message.component'; +import { PageNotFoundComponent } from './not-found.component'; + +import { CanDeactivateGuard } from './can-deactivate-guard.service'; +import { AuthGuard } from './auth-guard.service'; +import { SelectivePreloadingStrategy } from './selective-preloading-strategy'; + +const appRoutes: Routes = [ + { + path: 'compose', + component: ComposeMessageComponent, + outlet: 'popup' + }, + { + path: 'admin', + loadChildren: 'app/admin/admin.module#AdminModule', + canLoad: [AuthGuard] + }, + // #docregion preload-v2 + { + path: 'crisis-center', + loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule', + data: { preload: true } + }, + // #enddocregion preload-v2 + { path: '', redirectTo: '/heroes', pathMatch: 'full' }, + { path: '**', component: PageNotFoundComponent } +]; + +@NgModule({ + imports: [ + RouterModule.forRoot( + appRoutes, + { preloadingStrategy: SelectivePreloadingStrategy } + ) + ], + exports: [ + RouterModule + ], + providers: [ + CanDeactivateGuard, + SelectivePreloadingStrategy + ] +}) +export class AppRoutingModule { } diff --git a/public/docs/_examples/router/ts/src/app/app.component.1.ts b/public/docs/_examples/router/ts/src/app/app.component.1.ts new file mode 100644 index 0000000000..21e9aa417d --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.component.1.ts @@ -0,0 +1,18 @@ +/* First version */ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + // #docregion template + template: ` +

    Angular Router

    + + + ` + // #enddocregion template +}) +export class AppComponent { } diff --git a/public/docs/_examples/router/ts/src/app/app.component.2.ts b/public/docs/_examples/router/ts/src/app/app.component.2.ts new file mode 100644 index 0000000000..ffd4d8dfae --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.component.2.ts @@ -0,0 +1,16 @@ +/* Second Heroes version */ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` +

    Angular Router

    + + + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/router/ts/src/app/app.component.3.ts b/public/docs/_examples/router/ts/src/app/app.component.3.ts new file mode 100644 index 0000000000..6013df6321 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.component.3.ts @@ -0,0 +1,48 @@ +/* tslint:disable:no-unused-variable */ +// #docplaster +import { Component } from '@angular/core'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'my-app', + /* Typical link + // #docregion h-anchor + Heroes + // #enddocregion h-anchor + */ + /* Incomplete Crisis Center link when CC lacks a default + // #docregion cc-anchor-fail + // The link now fails with a "non-terminal link" error + // #docregion cc-anchor-w-default + Crisis Center + // #enddocregion cc-anchor-w-default + // #enddocregion cc-anchor-fail + */ + /* Crisis Center link when CC lacks a default + // #docregion cc-anchor-no-default + Crisis Center + // #enddocregion cc-anchor-no-default + */ + /* Crisis Center Detail link + // #docregion Dragon-anchor + Dragon Crisis + // #enddocregion Dragon-anchor + */ + /* Crisis Center link with optional query params + // #docregion cc-query-params + Crisis Center + // #enddocregion cc-query-params + */ +// #docregion template + template: ` +

    Angular Router

    + + + ` +// #enddocregion template +}) +export class AppComponent { } diff --git a/public/docs/_examples/router/ts/src/app/app.component.4.ts b/public/docs/_examples/router/ts/src/app/app.component.4.ts new file mode 100644 index 0000000000..a630703c28 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.component.4.ts @@ -0,0 +1,23 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + // #docregion template + template: ` +

    Angular Router

    + + // #docregion outlets + + + // #enddocregion outlets + ` + // #enddocregion template +}) +export class AppComponent { } diff --git a/public/docs/_examples/router/ts/src/app/app.component.5.ts b/public/docs/_examples/router/ts/src/app/app.component.5.ts new file mode 100644 index 0000000000..24162c6136 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.component.5.ts @@ -0,0 +1,20 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + // #docregion template + template: ` +

    Angular Router

    + + + + ` + // #enddocregion template +}) +export class AppComponent { } diff --git a/public/docs/_examples/router/ts/src/app/app.component.ts b/public/docs/_examples/router/ts/src/app/app.component.ts new file mode 100644 index 0000000000..a479680cbe --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.component.ts @@ -0,0 +1,23 @@ +// #docplaster +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + // #docregion template + template: ` +

    Angular Router

    + + + + ` + // #enddocregion template +}) +export class AppComponent { +} diff --git a/public/docs/_examples/router/ts/src/app/app.module.0.ts b/public/docs/_examples/router/ts/src/app/app.module.0.ts new file mode 100644 index 0000000000..a195dbdd7a --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.module.0.ts @@ -0,0 +1,41 @@ +// NEVER USED. For docs only. Should compile though +// #docplaster +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { HeroListComponent } from './hero-list.component'; +import { CrisisListComponent } from './crisis-list.component'; +import { PageNotFoundComponent } from './not-found.component'; +import { PageNotFoundComponent as HeroDetailComponent } from './not-found.component'; + +// #docregion +const appRoutes: Routes = [ + { path: 'crisis-center', component: CrisisListComponent }, + { path: 'hero/:id', component: HeroDetailComponent }, + { + path: 'heroes', + component: HeroListComponent, + data: { title: 'Heroes List' } + }, + { path: '', + redirectTo: '/heroes', + pathMatch: 'full' + }, + { path: '**', component: PageNotFoundComponent } +]; + +@NgModule({ + imports: [ + RouterModule.forRoot(appRoutes) + // other imports here + ], +// #enddocregion +/* +// #docregion + ... +}) +export class AppModule { } +// #enddocregion +*/ +}) +export class AppModule0 { } diff --git a/public/docs/_examples/router/ts/src/app/app.module.1.ts b/public/docs/_examples/router/ts/src/app/app.module.1.ts new file mode 100644 index 0000000000..32f93b8f79 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.module.1.ts @@ -0,0 +1,49 @@ +// #docplaster +// #docregion +// #docregion first-config +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +// #docregion import-router +import { RouterModule, Routes } from '@angular/router'; +// #enddocregion import-router + +import { AppComponent } from './app.component'; +import { CrisisListComponent } from './crisis-list.component'; +import { HeroListComponent } from './hero-list.component'; +// #enddocregion first-config +import { PageNotFoundComponent } from './not-found.component'; +// #docregion first-config + +// #docregion appRoutes +const appRoutes: Routes = [ + { path: 'crisis-center', component: CrisisListComponent }, + { path: 'heroes', component: HeroListComponent }, +// #enddocregion first-config + + { path: '', redirectTo: '/heroes', pathMatch: 'full' }, +// #docregion wildcard + { path: '**', component: PageNotFoundComponent } +// #enddocregion wildcard +// #docregion first-config +]; +// #enddocregion appRoutes + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + RouterModule.forRoot(appRoutes) + ], + declarations: [ + AppComponent, + HeroListComponent, + CrisisListComponent, +// #enddocregion first-config + PageNotFoundComponent +// #docregion first-config + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/app.module.2.ts b/public/docs/_examples/router/ts/src/app/app.module.2.ts new file mode 100644 index 0000000000..2ba739168c --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.module.2.ts @@ -0,0 +1,31 @@ +// #docplaster +// #docregion +// #docregion hero-import +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { AppRoutingModule } from './app-routing.module'; + +import { CrisisListComponent } from './crisis-list.component'; +import { HeroListComponent } from './hero-list.component'; +import { PageNotFoundComponent } from './not-found.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + AppRoutingModule + ], + declarations: [ + AppComponent, + HeroListComponent, + CrisisListComponent, + PageNotFoundComponent + ], + bootstrap: [ AppComponent ] +}) +// #enddocregion hero-import +export class AppModule { } +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/app.module.3.ts b/public/docs/_examples/router/ts/src/app/app.module.3.ts new file mode 100644 index 0000000000..862faf1c51 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.module.3.ts @@ -0,0 +1,29 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { AppRoutingModule } from './app-routing.module'; +import { HeroesModule } from './heroes/heroes.module'; + +import { CrisisListComponent } from './crisis-list.component'; +import { PageNotFoundComponent } from './not-found.component'; + +@NgModule({ +// #docregion module-imports + imports: [ + BrowserModule, + FormsModule, + HeroesModule, + AppRoutingModule + ], +// #enddocregion module-imports + declarations: [ + AppComponent, + CrisisListComponent, + PageNotFoundComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/router/ts/src/app/app.module.4.ts b/public/docs/_examples/router/ts/src/app/app.module.4.ts new file mode 100644 index 0000000000..4825572361 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.module.4.ts @@ -0,0 +1,46 @@ +// #docplaster +// #docregion +// #docregion crisis-center-module, admin-module +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { PageNotFoundComponent } from './not-found.component'; + +import { AppRoutingModule } from './app-routing.module'; +import { HeroesModule } from './heroes/heroes.module'; +import { CrisisCenterModule } from './crisis-center/crisis-center.module'; +// #enddocregion crisis-center-module, admin-module +import { ComposeMessageComponent } from './compose-message.component'; +// #docregion admin-module +import { AdminModule } from './admin/admin.module'; +// #docregion crisis-center-module + +import { DialogService } from './dialog.service'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + HeroesModule, + CrisisCenterModule, +// #enddocregion crisis-center-module + AdminModule, +// #docregion crisis-center-module + AppRoutingModule + ], + declarations: [ + AppComponent, +// #enddocregion admin-module, crisis-center-module + ComposeMessageComponent, +// #docregion admin-module, crisis-center-module + PageNotFoundComponent + ], + providers: [ + DialogService + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/app.module.5.ts b/public/docs/_examples/router/ts/src/app/app.module.5.ts new file mode 100644 index 0000000000..ad34668cea --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.module.5.ts @@ -0,0 +1,38 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { AppRoutingModule } from './app-routing.module'; + +import { HeroesModule } from './heroes/heroes.module'; +import { CrisisCenterModule } from './crisis-center/crisis-center.module'; + +import { ComposeMessageComponent } from './compose-message.component'; +import { PageNotFoundComponent } from './not-found.component'; + +import { AdminModule } from './admin/admin.module'; +import { DialogService } from './dialog.service'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + HeroesModule, + CrisisCenterModule, + AdminModule, + AppRoutingModule + ], + declarations: [ + AppComponent, + ComposeMessageComponent, + PageNotFoundComponent + ], + providers: [ + DialogService + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/router/ts/src/app/app.module.6.ts b/public/docs/_examples/router/ts/src/app/app.module.6.ts new file mode 100644 index 0000000000..4cb0b1fdd5 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.module.6.ts @@ -0,0 +1,29 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { Routes, RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { PageNotFoundComponent } from './not-found.component'; + +const routes: Routes = [ + +]; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + RouterModule.forRoot(routes, { useHash: true }) // .../#/crisis-center/ + ], + declarations: [ + AppComponent, + PageNotFoundComponent + ], + providers: [ + + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/router/ts/src/app/app.module.7.ts b/public/docs/_examples/router/ts/src/app/app.module.7.ts new file mode 100644 index 0000000000..b6ca81ddea --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.module.7.ts @@ -0,0 +1,38 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { AppRoutingModule } from './app-routing.module'; + +import { HeroesModule } from './heroes/heroes.module'; +import { CrisisCenterModule } from './crisis-center/crisis-center.module'; +import { ComposeMessageComponent } from './compose-message.component'; +import { LoginRoutingModule } from './login-routing.module'; +import { LoginComponent } from './login.component'; +import { PageNotFoundComponent } from './not-found.component'; + +import { DialogService } from './dialog.service'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HeroesModule, + CrisisCenterModule, + LoginRoutingModule, + AppRoutingModule + ], + declarations: [ + AppComponent, + ComposeMessageComponent, + LoginComponent, + PageNotFoundComponent + ], + providers: [ + DialogService + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/router/ts/src/app/app.module.ts b/public/docs/_examples/router/ts/src/app/app.module.ts new file mode 100644 index 0000000000..dcf3401ded --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/app.module.ts @@ -0,0 +1,56 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +// #docregion animations-module +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; + +// #enddocregion animations-module +// #docregion inspect-config +import { Router } from '@angular/router'; + +// #enddocregion inspect-config +import { AppComponent } from './app.component'; +import { AppRoutingModule } from './app-routing.module'; + +import { HeroesModule } from './heroes/heroes.module'; +import { ComposeMessageComponent } from './compose-message.component'; +import { LoginRoutingModule } from './login-routing.module'; +import { LoginComponent } from './login.component'; +import { PageNotFoundComponent } from './not-found.component'; + +import { DialogService } from './dialog.service'; + +// #docregion animations-module +@NgModule({ + imports: [ + // #enddocregion animations-module + BrowserModule, + FormsModule, + HeroesModule, + LoginRoutingModule, + AppRoutingModule, + // #docregion animations-module + BrowserAnimationsModule + // #enddocregion animations-module + ], + declarations: [ + AppComponent, + ComposeMessageComponent, + LoginComponent, + PageNotFoundComponent + ], + providers: [ + DialogService + ], + bootstrap: [ AppComponent ] +}) +// #docregion inspect-config +export class AppModule { + // Diagnostic only: inspect router configuration + constructor(router: Router) { + console.log('Routes: ', JSON.stringify(router.config, undefined, 2)); + } +} +// #enddocregion inspect-config diff --git a/public/docs/_examples/router/ts/src/app/auth-guard.service.1.ts b/public/docs/_examples/router/ts/src/app/auth-guard.service.1.ts new file mode 100644 index 0000000000..c824bcb208 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/auth-guard.service.1.ts @@ -0,0 +1,11 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { CanActivate } from '@angular/router'; + +@Injectable() +export class AuthGuard implements CanActivate { + canActivate() { + console.log('AuthGuard#canActivate called'); + return true; + } +} diff --git a/public/docs/_examples/router/ts/src/app/auth-guard.service.2.ts b/public/docs/_examples/router/ts/src/app/auth-guard.service.2.ts new file mode 100644 index 0000000000..8fd00e151a --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/auth-guard.service.2.ts @@ -0,0 +1,37 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { + CanActivate, Router, + ActivatedRouteSnapshot, + RouterStateSnapshot +} from '@angular/router'; +import { AuthService } from './auth.service'; + +@Injectable() +export class AuthGuard implements CanActivate { + constructor(private authService: AuthService, private router: Router) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { + let url: string = state.url; + + return this.checkLogin(url); + } + + checkLogin(url: string): boolean { + if (this.authService.isLoggedIn) { return true; } + + // Store the attempted URL for redirecting + this.authService.redirectUrl = url; + + // Navigate to the login page with extras + this.router.navigate(['/login']); + return false; + } +} +// #enddocregion + +/* +// #docregion can-load-interface +export class AuthGuard implements CanActivate, CanLoad { +// #enddocregion can-load-interface +*/ diff --git a/public/docs/_examples/router/ts/src/app/auth-guard.service.3.ts b/public/docs/_examples/router/ts/src/app/auth-guard.service.3.ts new file mode 100644 index 0000000000..dd89006411 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/auth-guard.service.3.ts @@ -0,0 +1,39 @@ +// #docregion +// #docregion can-activate-child +import { Injectable } from '@angular/core'; +import { + CanActivate, Router, + ActivatedRouteSnapshot, + RouterStateSnapshot, + CanActivateChild +} from '@angular/router'; +import { AuthService } from './auth.service'; + +@Injectable() +export class AuthGuard implements CanActivate, CanActivateChild { + constructor(private authService: AuthService, private router: Router) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { + let url: string = state.url; + + return this.checkLogin(url); + } + + canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { + return this.canActivate(route, state); + } + +// #enddocregion can-activate-child + checkLogin(url: string): boolean { + if (this.authService.isLoggedIn) { return true; } + + // Store the attempted URL for redirecting + this.authService.redirectUrl = url; + + // Navigate to the login page + this.router.navigate(['/login']); + return false; + } +// #docregion can-activate-child +} +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/auth-guard.service.4.ts b/public/docs/_examples/router/ts/src/app/auth-guard.service.4.ts new file mode 100644 index 0000000000..5d239a8432 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/auth-guard.service.4.ts @@ -0,0 +1,47 @@ +// #docplaster +// #docregion +import { Injectable } from '@angular/core'; +import { + CanActivate, Router, + ActivatedRouteSnapshot, + RouterStateSnapshot, + CanActivateChild, + NavigationExtras +} from '@angular/router'; +import { AuthService } from './auth.service'; + +@Injectable() +export class AuthGuard implements CanActivate, CanActivateChild { + constructor(private authService: AuthService, private router: Router) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { + let url: string = state.url; + + return this.checkLogin(url); + } + + canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { + return this.canActivate(route, state); + } + + checkLogin(url: string): boolean { + if (this.authService.isLoggedIn) { return true; } + + // Store the attempted URL for redirecting + this.authService.redirectUrl = url; + + // Create a dummy session id + let sessionId = 123456789; + + // Set our navigation extras object + // that contains our global query params and fragment + let navigationExtras: NavigationExtras = { + queryParams: { 'session_id': sessionId }, + fragment: 'anchor' + }; + + // Navigate to the login page with extras + this.router.navigate(['/login'], navigationExtras); + return false; + } +} diff --git a/public/docs/_examples/router/ts/src/app/auth-guard.service.ts b/public/docs/_examples/router/ts/src/app/auth-guard.service.ts new file mode 100644 index 0000000000..a32b5cc2b8 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/auth-guard.service.ts @@ -0,0 +1,56 @@ +// #docplaster +import { Injectable } from '@angular/core'; +import { + CanActivate, Router, + ActivatedRouteSnapshot, + RouterStateSnapshot, + CanActivateChild, + NavigationExtras, + CanLoad, Route +} from '@angular/router'; +import { AuthService } from './auth.service'; + +@Injectable() +export class AuthGuard implements CanActivate, CanActivateChild, CanLoad { + constructor(private authService: AuthService, private router: Router) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { + let url: string = state.url; + + return this.checkLogin(url); + } + + canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { + return this.canActivate(route, state); + } + +// #docregion, canLoad + canLoad(route: Route): boolean { + let url = `/${route.path}`; + + return this.checkLogin(url); + } +// #enddocregion canLoad + + checkLogin(url: string): boolean { + if (this.authService.isLoggedIn) { return true; } + + // Store the attempted URL for redirecting + this.authService.redirectUrl = url; + + // Create a dummy session id + let sessionId = 123456789; + + // Set our navigation extras object + // that contains our global query params and fragment + let navigationExtras: NavigationExtras = { + queryParams: { 'session_id': sessionId }, + fragment: 'anchor' + }; + + // Navigate to the login page with extras + this.router.navigate(['/login'], navigationExtras); + return false; + } +// #docregion admin-can-load +} diff --git a/public/docs/_examples/router/ts/src/app/auth.service.ts b/public/docs/_examples/router/ts/src/app/auth.service.ts new file mode 100644 index 0000000000..f86a80ebfe --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/auth.service.ts @@ -0,0 +1,23 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/delay'; + +@Injectable() +export class AuthService { + isLoggedIn: boolean = false; + + // store the URL so we can redirect after logging in + redirectUrl: string; + + login(): Observable { + return Observable.of(true).delay(1000).do(val => this.isLoggedIn = true); + } + + logout(): void { + this.isLoggedIn = false; + } +} diff --git a/public/docs/_examples/router/ts/src/app/can-deactivate-guard.service.1.ts b/public/docs/_examples/router/ts/src/app/can-deactivate-guard.service.1.ts new file mode 100644 index 0000000000..0b7c8247cf --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/can-deactivate-guard.service.1.ts @@ -0,0 +1,31 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { CanDeactivate, + ActivatedRouteSnapshot, + RouterStateSnapshot } from '@angular/router'; + +import { CrisisDetailComponent } from './crisis-center/crisis-detail.component'; + +@Injectable() +export class CanDeactivateGuard implements CanDeactivate { + + canDeactivate( + component: CrisisDetailComponent, + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Promise | boolean { + // Get the Crisis Center ID + console.log(route.params['id']); + + // Get the current URL + console.log(state.url); + + // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged + if (!component.crisis || component.crisis.name === component.editName) { + return true; + } + // Otherwise ask the user with the dialog service and return its + // promise which resolves to true or false when the user decides + return component.dialogService.confirm('Discard changes?'); + } +} diff --git a/public/docs/_examples/router/ts/src/app/can-deactivate-guard.service.ts b/public/docs/_examples/router/ts/src/app/can-deactivate-guard.service.ts new file mode 100644 index 0000000000..44da69f9c7 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/can-deactivate-guard.service.ts @@ -0,0 +1,15 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { CanDeactivate } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; + +export interface CanComponentDeactivate { + canDeactivate: () => Observable | Promise | boolean; +} + +@Injectable() +export class CanDeactivateGuard implements CanDeactivate { + canDeactivate(component: CanComponentDeactivate) { + return component.canDeactivate ? component.canDeactivate() : true; + } +} diff --git a/public/docs/_examples/router/ts/src/app/compose-message.component.html b/public/docs/_examples/router/ts/src/app/compose-message.component.html new file mode 100644 index 0000000000..f0b964e6ac --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/compose-message.component.html @@ -0,0 +1,17 @@ + +

    Contact Crisis Center

    +
    + {{ details }} +
    +
    +
    + +
    +
    + +
    +
    +

    + + +

    diff --git a/public/docs/_examples/router/ts/src/app/compose-message.component.ts b/public/docs/_examples/router/ts/src/app/compose-message.component.ts new file mode 100644 index 0000000000..17a0953378 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/compose-message.component.ts @@ -0,0 +1,43 @@ +// #docregion +import { Component, HostBinding } from '@angular/core'; +import { Router } from '@angular/router'; + +import { slideInDownAnimation } from './animations'; + +@Component({ + templateUrl: './compose-message.component.html', + styles: [ ':host { position: relative; bottom: 10%; }' ], + animations: [ slideInDownAnimation ] +}) +export class ComposeMessageComponent { + @HostBinding('@routeAnimation') routeAnimation = true; + @HostBinding('style.display') display = 'block'; + @HostBinding('style.position') position = 'absolute'; + + details: string; + sending: boolean = false; + + constructor(private router: Router) {} + + send() { + this.sending = true; + this.details = 'Sending Message...'; + + setTimeout(() => { + this.sending = false; + this.closePopup(); + }, 1000); + } + + cancel() { + this.closePopup(); + } + + // #docregion closePopup + closePopup() { + // Providing a `null` value to the named outlet + // clears the contents of the named outlet + this.router.navigate([{ outlets: { popup: null }}]); + } + // #enddocregion closePopup +} diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-home.component.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-home.component.ts new file mode 100644 index 0000000000..a71d485c02 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-home.component.ts @@ -0,0 +1,13 @@ +// #docregion +// #docplaster +import { Component } from '@angular/core'; + +// #docregion minus-imports +@Component({ + template: ` +

    Welcome to the Crisis Center

    + ` +}) +export class CrisisCenterHomeComponent { } +// #enddocregion minus-imports +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.1.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.1.ts new file mode 100644 index 0000000000..e646f467d1 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.1.ts @@ -0,0 +1,44 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { CrisisCenterHomeComponent } from './crisis-center-home.component'; +import { CrisisListComponent } from './crisis-list.component'; +import { CrisisCenterComponent } from './crisis-center.component'; +import { CrisisDetailComponent } from './crisis-detail.component'; + +// #docregion routes +const crisisCenterRoutes: Routes = [ + { + path: 'crisis-center', + component: CrisisCenterComponent, + children: [ + { + path: '', + component: CrisisListComponent, + children: [ + { + path: ':id', + component: CrisisDetailComponent + }, + { + path: '', + component: CrisisCenterHomeComponent + } + ] + } + ] + } +]; + +@NgModule({ + imports: [ + RouterModule.forChild(crisisCenterRoutes) + ], + exports: [ + RouterModule + ] +}) +export class CrisisCenterRoutingModule { } +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.2.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.2.ts new file mode 100644 index 0000000000..9e9b514968 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.2.ts @@ -0,0 +1,72 @@ +// #docplaster +// #docregion routes +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { CrisisCenterHomeComponent } from './crisis-center-home.component'; +import { CrisisListComponent } from './crisis-list.component'; +import { CrisisCenterComponent } from './crisis-center.component'; +import { CrisisDetailComponent } from './crisis-detail.component'; +// #enddocregion routes + +// #docregion can-deactivate-guard +import { CanDeactivateGuard } from '../can-deactivate-guard.service'; +// #enddocregion can-deactivate-guard +// #docregion crisis-detail-resolver +import { CrisisDetailResolver } from './crisis-detail-resolver.service'; + +// #enddocregion crisis-detail-resolver +// #docregion routes + +const crisisCenterRoutes: Routes = [ +// #enddocregion routes + // #docregion redirect, routes + { + path: '', + redirectTo: '/crisis-center', + pathMatch: 'full' + }, + // #enddocregion redirect, routes + // #docregion routes + { + path: 'crisis-center', + component: CrisisCenterComponent, + children: [ + { + path: '', + component: CrisisListComponent, + children: [ + { + path: ':id', + component: CrisisDetailComponent, + // #enddocregion routes + // #docregion can-deactivate-guard + canDeactivate: [CanDeactivateGuard], + // #enddocregion can-deactivate-guard + // #docregion crisis-detail-resolver + resolve: { + crisis: CrisisDetailResolver + } + // #enddocregion crisis-detail-resolver + // #docregion routes + }, + { + path: '', + component: CrisisCenterHomeComponent + } + ] + } + ] + } + // #enddocregion routes +]; + +@NgModule({ + imports: [ + RouterModule.forChild(crisisCenterRoutes) + ], + exports: [ + RouterModule + ] +}) +export class CrisisCenterRoutingModule { } diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.3.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.3.ts new file mode 100644 index 0000000000..6d605dbe84 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.3.ts @@ -0,0 +1,52 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { CrisisCenterHomeComponent } from './crisis-center-home.component'; +import { CrisisListComponent } from './crisis-list.component'; +import { CrisisCenterComponent } from './crisis-center.component'; +import { CrisisDetailComponent } from './crisis-detail.component'; + +// #docregion can-deactivate-guard +import { CanDeactivateGuard } from '../can-deactivate-guard.service'; + +const crisisCenterRoutes: Routes = [ + { + path: '', + redirectTo: '/crisis-center', + pathMatch: 'full' + }, + { + path: 'crisis-center', + component: CrisisCenterComponent, + children: [ + { + path: '', + component: CrisisListComponent, + children: [ + { + path: ':id', + component: CrisisDetailComponent, + canDeactivate: [CanDeactivateGuard] + }, + { + path: '', + component: CrisisCenterHomeComponent + } + ] + } + ] + } +]; + +@NgModule({ + imports: [ + RouterModule.forChild(crisisCenterRoutes) + ], + exports: [ + RouterModule + ] +}) +export class CrisisCenterRoutingModule { } +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.4.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.4.ts new file mode 100644 index 0000000000..b7ac88e852 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.4.ts @@ -0,0 +1,65 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { CrisisCenterHomeComponent } from './crisis-center-home.component'; +import { CrisisListComponent } from './crisis-list.component'; +import { CrisisCenterComponent } from './crisis-center.component'; +import { CrisisDetailComponent } from './crisis-detail.component'; + +import { CanDeactivateGuard } from '../can-deactivate-guard.service'; + +// #docregion crisis-detail-resolver +import { CrisisDetailResolver } from './crisis-detail-resolver.service'; + +// #enddocregion crisis-detail-resolver +const crisisCenterRoutes: Routes = [ + // #docregion redirect + { + path: '', + redirectTo: '/crisis-center', + pathMatch: 'full' + }, + // #enddocregion redirect + { + path: 'crisis-center', + component: CrisisCenterComponent, + children: [ + { + path: '', + component: CrisisListComponent, + children: [ + { + path: ':id', + component: CrisisDetailComponent, + canDeactivate: [CanDeactivateGuard], + resolve: { + crisis: CrisisDetailResolver + } + }, + { + path: '', + component: CrisisCenterHomeComponent + } + ] + } + ] + } +]; + +// #docregion crisis-detail-resolver +@NgModule({ + imports: [ + RouterModule.forChild(crisisCenterRoutes) + ], + exports: [ + RouterModule + ], + providers: [ + CrisisDetailResolver + ] +}) +export class CrisisCenterRoutingModule { } +// #enddocregion crisis-detail-resolver +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.ts new file mode 100644 index 0000000000..c01d592455 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center-routing.module.ts @@ -0,0 +1,53 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { CrisisCenterHomeComponent } from './crisis-center-home.component'; +import { CrisisListComponent } from './crisis-list.component'; +import { CrisisCenterComponent } from './crisis-center.component'; +import { CrisisDetailComponent } from './crisis-detail.component'; + +import { CanDeactivateGuard } from '../can-deactivate-guard.service'; +import { CrisisDetailResolver } from './crisis-detail-resolver.service'; + +const crisisCenterRoutes: Routes = [ + { + path: '', + component: CrisisCenterComponent, + children: [ + { + path: '', + component: CrisisListComponent, + children: [ + { + path: ':id', + component: CrisisDetailComponent, + canDeactivate: [CanDeactivateGuard], + resolve: { + crisis: CrisisDetailResolver + } + }, + { + path: '', + component: CrisisCenterHomeComponent + } + ] + } + ] + } +]; + +@NgModule({ + imports: [ + RouterModule.forChild(crisisCenterRoutes) + ], + exports: [ + RouterModule + ], + providers: [ + CrisisDetailResolver + ] +}) +export class CrisisCenterRoutingModule { } +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center.component.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center.component.ts new file mode 100644 index 0000000000..31d1790f45 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center.component.ts @@ -0,0 +1,14 @@ +// #docregion +// #docplaster +import { Component } from '@angular/core'; + +// #docregion minus-imports +@Component({ + template: ` +

    CRISIS CENTER

    + + ` +}) +export class CrisisCenterComponent { } +// #enddocregion minus-imports +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center.module.1.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center.module.1.ts new file mode 100644 index 0000000000..5a3e45f58f --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center.module.1.ts @@ -0,0 +1,36 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { CommonModule } from '@angular/common'; + +import { CrisisService } from './crisis.service'; + +import { CrisisCenterComponent } from './crisis-center.component'; +import { CrisisListComponent } from './crisis-list.component'; +import { CrisisCenterHomeComponent } from './crisis-center-home.component'; +import { CrisisDetailComponent } from './crisis-detail.component'; + +import { CrisisCenterRoutingModule } from './crisis-center-routing.module'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + CrisisCenterRoutingModule + ], + declarations: [ + CrisisCenterComponent, + CrisisListComponent, + CrisisCenterHomeComponent, + CrisisDetailComponent + ], + + // #docregion providers + providers: [ + CrisisService + ] + // #enddocregion providers +}) +export class CrisisCenterModule {} +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center.module.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center.module.ts new file mode 100644 index 0000000000..4061ceac60 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-center.module.ts @@ -0,0 +1,35 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { CommonModule } from '@angular/common'; + +import { CrisisService } from './crisis.service'; + +import { CrisisCenterComponent } from './crisis-center.component'; +import { CrisisListComponent } from './crisis-list.component'; +import { CrisisCenterHomeComponent } from './crisis-center-home.component'; +import { CrisisDetailComponent } from './crisis-detail.component'; + +import { CrisisCenterRoutingModule } from './crisis-center-routing.module'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + CrisisCenterRoutingModule + ], + declarations: [ + CrisisCenterComponent, + CrisisListComponent, + CrisisCenterHomeComponent, + CrisisDetailComponent + ], + providers: [ + CrisisService + ] +}) +// #docregion crisis-center-module-export +export class CrisisCenterModule {} +// #enddocregion crisis-center-module-export +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-detail-resolver.service.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-detail-resolver.service.ts new file mode 100644 index 0000000000..94b4cd33e7 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-detail-resolver.service.ts @@ -0,0 +1,24 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { Router, Resolve, RouterStateSnapshot, + ActivatedRouteSnapshot } from '@angular/router'; + +import { Crisis, CrisisService } from './crisis.service'; + +@Injectable() +export class CrisisDetailResolver implements Resolve { + constructor(private cs: CrisisService, private router: Router) {} + + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise { + let id = route.params['id']; + + return this.cs.getCrisis(id).then(crisis => { + if (crisis) { + return crisis; + } else { // id not found + this.router.navigate(['/crisis-center']); + return null; + } + }); + } +} diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-detail.component.1.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-detail.component.1.ts new file mode 100644 index 0000000000..d6fa27f629 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-detail.component.1.ts @@ -0,0 +1,87 @@ +// #docplaster +// #docregion +import 'rxjs/add/operator/switchMap'; +import { Component, OnInit, HostBinding } from '@angular/core'; +import { ActivatedRoute, Router, Params } from '@angular/router'; + +import { slideInDownAnimation } from '../animations'; +import { Crisis, CrisisService } from './crisis.service'; +import { DialogService } from '../dialog.service'; + +@Component({ + template: ` +
    +

    "{{ editName }}"

    +
    + {{ crisis.id }}
    +
    + + +
    +

    + + +

    +
    + `, + styles: ['input {width: 20em}'], + animations: [ slideInDownAnimation ] +}) +export class CrisisDetailComponent implements OnInit { + @HostBinding('@routeAnimation') routeAnimation = true; + @HostBinding('style.display') display = 'block'; + @HostBinding('style.position') position = 'absolute'; + + crisis: Crisis; + editName: string; + + constructor( + private service: CrisisService, + private router: Router, + private route: ActivatedRoute, + public dialogService: DialogService + ) {} + + // #docregion ngOnInit + ngOnInit() { + this.route.params + .switchMap((params: Params) => this.service.getCrisis(params['id'])) + .subscribe((crisis: Crisis) => { + if (crisis) { + this.editName = crisis.name; + this.crisis = crisis; + } else { // id not found + this.gotoCrises(); + } + }); + } + // #enddocregion ngOnInit + + cancel() { + this.gotoCrises(); + } + + save() { + this.crisis.name = this.editName; + this.gotoCrises(); + } + + canDeactivate(): Promise | boolean { + // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged + if (!this.crisis || this.crisis.name === this.editName) { + return true; + } + // Otherwise ask the user with the dialog service and return its + // promise which resolves to true or false when the user decides + return this.dialogService.confirm('Discard changes?'); + } + + gotoCrises() { + let crisisId = this.crisis ? this.crisis.id : null; + // Pass along the crisis id if available + // so that the CrisisListComponent can select that crisis. + // Add a totally useless `foo` parameter for kicks. + // Relative navigation back to the crises + this.router.navigate(['../', { id: crisisId, foo: 'foo' }], { relativeTo: this.route }); + } +} diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-detail.component.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-detail.component.ts new file mode 100644 index 0000000000..f0939b47a8 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-detail.component.ts @@ -0,0 +1,86 @@ +// #docplaster +// #docregion +import { Component, OnInit, HostBinding } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; + +import { slideInDownAnimation } from '../animations'; +import { Crisis } from './crisis.service'; +import { DialogService } from '../dialog.service'; + +@Component({ + template: ` +
    +

    "{{ editName }}"

    +
    + {{ crisis.id }}
    +
    + + +
    +

    + + +

    +
    + `, + styles: ['input {width: 20em}'], + animations: [ slideInDownAnimation ] +}) +export class CrisisDetailComponent implements OnInit { + @HostBinding('@routeAnimation') routeAnimation = true; + @HostBinding('style.display') display = 'block'; + @HostBinding('style.position') position = 'absolute'; + + crisis: Crisis; + editName: string; + + constructor( + private route: ActivatedRoute, + private router: Router, + public dialogService: DialogService + ) {} + +// #docregion ngOnInit + ngOnInit() { + this.route.data + .subscribe((data: { crisis: Crisis }) => { + this.editName = data.crisis.name; + this.crisis = data.crisis; + }); + } +// #enddocregion ngOnInit + + // #docregion cancel-save + cancel() { + this.gotoCrises(); + } + + save() { + this.crisis.name = this.editName; + this.gotoCrises(); + } + // #enddocregion cancel-save + + // #docregion canDeactivate + canDeactivate(): Promise | boolean { + // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged + if (!this.crisis || this.crisis.name === this.editName) { + return true; + } + // Otherwise ask the user with the dialog service and return its + // promise which resolves to true or false when the user decides + return this.dialogService.confirm('Discard changes?'); + } + // #enddocregion canDeactivate + + gotoCrises() { + let crisisId = this.crisis ? this.crisis.id : null; + // Pass along the crisis id if available + // so that the CrisisListComponent can select that crisis. + // Add a totally useless `foo` parameter for kicks. + // #docregion gotoCrises-navigate + // Relative navigation back to the crises + this.router.navigate(['../', { id: crisisId, foo: 'foo' }], { relativeTo: this.route }); + // #enddocregion gotoCrises-navigate + } +} diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-list.component.1.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-list.component.1.ts new file mode 100644 index 0000000000..0000dde082 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-list.component.1.ts @@ -0,0 +1,44 @@ +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/switchMap'; +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router, Params } from '@angular/router'; + +import { Crisis, CrisisService } from './crisis.service'; +import { Observable } from 'rxjs/Observable'; + +@Component({ + // #docregion relative-navigation-router-link + template: ` + ` + // #enddocregion relative-navigation-router-link +}) +export class CrisisListComponent implements OnInit { + crises: Observable; + selectedId: number; + + constructor( + private service: CrisisService, + private route: ActivatedRoute, + private router: Router + ) {} + + ngOnInit() { + this.crises = this.route.params + .switchMap((params: Params) => { + this.selectedId = +params['id']; + return this.service.getCrises(); + }); + } + + isSelected(crisis: Crisis) { + return crisis.id === this.selectedId; + } +} diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis-list.component.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-list.component.ts new file mode 100644 index 0000000000..4498a55c0f --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis-list.component.ts @@ -0,0 +1,56 @@ +// #docregion +import 'rxjs/add/operator/switchMap'; +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router, Params } from '@angular/router'; + +import { Observable } from 'rxjs/Observable'; + +import { Crisis, CrisisService } from './crisis.service'; + +@Component({ + template: ` +
      +
    • + {{ crisis.id }} + {{ crisis.name }} +
    • +
    + + + ` +}) +export class CrisisListComponent implements OnInit { + crises: Observable; + selectedId: number; + + // #docregion ctor + constructor( + private service: CrisisService, + private route: ActivatedRoute, + private router: Router + ) {} + // #enddocregion ctor + + isSelected(crisis: Crisis) { + return crisis.id === this.selectedId; + } + + ngOnInit() { + this.crises = this.route.params + .switchMap((params: Params) => { + this.selectedId = +params['id']; + return this.service.getCrises(); + }); + } + + // #docregion onSelect + onSelect(crisis: Crisis) { + this.selectedId = crisis.id; + + // Navigate with relative link + this.router.navigate([crisis.id], { relativeTo: this.route }); + } + // #enddocregion onSelect +} diff --git a/public/docs/_examples/router/ts/src/app/crisis-center/crisis.service.ts b/public/docs/_examples/router/ts/src/app/crisis-center/crisis.service.ts new file mode 100644 index 0000000000..e7fd34d387 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/crisis-center/crisis.service.ts @@ -0,0 +1,40 @@ +// #docplaster +// #docregion , mock-crises +export class Crisis { + constructor(public id: number, public name: string) { } +} + +const CRISES = [ + new Crisis(1, 'Dragon Burning Cities'), + new Crisis(2, 'Sky Rains Great White Sharks'), + new Crisis(3, 'Giant Asteroid Heading For Earth'), + new Crisis(4, 'Procrastinators Meeting Delayed Again'), +]; +// #enddocregion mock-crises + +let crisesPromise = Promise.resolve(CRISES); + +import { Injectable } from '@angular/core'; + +@Injectable() +export class CrisisService { + + static nextCrisisId = 100; + + getCrises() { return crisesPromise; } + + getCrisis(id: number | string) { + return crisesPromise + .then(crises => crises.find(crisis => crisis.id === +id)); + } + + // #enddocregion + addCrisis(name: string) { + name = name.trim(); + if (name) { + let crisis = new Crisis(CrisisService.nextCrisisId++, name); + crisesPromise.then(crises => crises.push(crisis)); + } + } + // #docregion +} diff --git a/public/docs/_examples/router-deprecated/ts/app/crisis-list.component.ts b/public/docs/_examples/router/ts/src/app/crisis-list.component.ts similarity index 100% rename from public/docs/_examples/router-deprecated/ts/app/crisis-list.component.ts rename to public/docs/_examples/router/ts/src/app/crisis-list.component.ts diff --git a/public/docs/_examples/router/ts/src/app/dialog.service.ts b/public/docs/_examples/router/ts/src/app/dialog.service.ts new file mode 100644 index 0000000000..0f09e4936d --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/dialog.service.ts @@ -0,0 +1,19 @@ +// #docregion +import { Injectable } from '@angular/core'; +/** + * Async modal dialog service + * DialogService makes this app easier to test by faking this service. + * TODO: better modal implementation that doesn't use window.confirm + */ +@Injectable() +export class DialogService { + /** + * Ask user to confirm an action. `message` explains the action and choices. + * Returns promise resolving to `true`=confirm or `false`=cancel + */ + confirm(message?: string) { + return new Promise(resolve => { + return resolve(window.confirm(message || 'Is it OK?')); + }); + }; +} diff --git a/public/docs/_examples/router/ts/src/app/hero-list.component.ts b/public/docs/_examples/router/ts/src/app/hero-list.component.ts new file mode 100644 index 0000000000..7a8f97ca1e --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/hero-list.component.ts @@ -0,0 +1,13 @@ +/// Initial empty version +// #docregion +import { Component } from '@angular/core'; + +@Component({ + template: ` +

    HEROES

    +

    Get your heroes here

    + + + ` +}) +export class HeroListComponent { } diff --git a/public/docs/_examples/router/ts/src/app/heroes/hero-detail.component.1.ts b/public/docs/_examples/router/ts/src/app/heroes/hero-detail.component.1.ts new file mode 100644 index 0000000000..93f0efaf0b --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/heroes/hero-detail.component.1.ts @@ -0,0 +1,55 @@ +// #docplaster +// #docregion +// #docregion rxjs-operator-import +import 'rxjs/add/operator/switchMap'; +// #enddocregion rxjs-operator-import +import { Component, OnInit } from '@angular/core'; +// #docregion imports +import { Router, ActivatedRoute, Params } from '@angular/router'; +// #enddocregion imports + +import { Hero, HeroService } from './hero.service'; + +@Component({ + template: ` +

    HEROES

    +
    +

    "{{ hero.name }}"

    +
    + {{ hero.id }}
    +
    + + +
    +

    + +

    +
    + ` +}) +export class HeroDetailComponent implements OnInit { + hero: Hero; + + // #docregion ctor + constructor( + private route: ActivatedRoute, + private router: Router, + private service: HeroService + ) {} + // #enddocregion ctor + + // #docregion ngOnInit + ngOnInit() { + this.route.params + // (+) converts string 'id' to a number + .switchMap((params: Params) => this.service.getHero(+params['id'])) + .subscribe((hero: Hero) => this.hero = hero); + } + // #enddocregion ngOnInit + + // #docregion gotoHeroes + gotoHeroes() { + this.router.navigate(['/heroes']); + } + // #enddocregion gotoHeroes +} diff --git a/public/docs/_examples/router/ts/src/app/heroes/hero-detail.component.2.ts b/public/docs/_examples/router/ts/src/app/heroes/hero-detail.component.2.ts new file mode 100644 index 0000000000..c3b69be965 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/heroes/hero-detail.component.2.ts @@ -0,0 +1,47 @@ +// Snapshot version +// #docregion +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; + +import { Hero, HeroService } from './hero.service'; + +@Component({ + template: ` +

    HEROES

    +
    +

    "{{ hero.name }}"

    +
    + {{ hero.id }}
    +
    + + +
    +

    + +

    +
    + ` +}) +export class HeroDetailComponent implements OnInit { + hero: Hero; + + constructor( + private route: ActivatedRoute, + private router: Router, + private service: HeroService + ) {} + + // #docregion snapshot + ngOnInit() { + // (+) converts string 'id' to a number + let id = +this.route.snapshot.params['id']; + + this.service.getHero(id) + .then((hero: Hero) => this.hero = hero); + } + // #enddocregion snapshot + + gotoHeroes() { + this.router.navigate(['/heroes']); + } +} diff --git a/public/docs/_examples/router/ts/src/app/heroes/hero-detail.component.ts b/public/docs/_examples/router/ts/src/app/heroes/hero-detail.component.ts new file mode 100644 index 0000000000..8135d37d32 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/heroes/hero-detail.component.ts @@ -0,0 +1,66 @@ +// #docplaster +// #docregion +// #docregion rxjs-operator-import +import 'rxjs/add/operator/switchMap'; +// #enddocregion rxjs-operator-import +import { Component, OnInit, HostBinding } from '@angular/core'; +import { Router, ActivatedRoute, Params } from '@angular/router'; + +import { slideInDownAnimation } from '../animations'; + +import { Hero, HeroService } from './hero.service'; + +@Component({ + template: ` +

    HEROES

    +
    +

    "{{ hero.name }}"

    +
    + {{ hero.id }}
    +
    + + +
    +

    + +

    +
    + `, + animations: [ slideInDownAnimation ] +}) +export class HeroDetailComponent implements OnInit { +// #docregion host-bindings + @HostBinding('@routeAnimation') routeAnimation = true; + @HostBinding('style.display') display = 'block'; + @HostBinding('style.position') position = 'absolute'; +// #enddocregion host-bindings + + hero: Hero; + + // #docregion ctor + constructor( + private route: ActivatedRoute, + private router: Router, + private service: HeroService + ) {} + // #enddocregion ctor + + // #docregion ngOnInit + ngOnInit() { + this.route.params + // (+) converts string 'id' to a number + .switchMap((params: Params) => this.service.getHero(+params['id'])) + .subscribe((hero: Hero) => this.hero = hero); + } + // #enddocregion ngOnInit + + // #docregion gotoHeroes + gotoHeroes() { + let heroId = this.hero ? this.hero.id : null; + // Pass along the hero id if available + // so that the HeroList component can select that hero. + // Include a junk 'foo' property for fun. + this.router.navigate(['/heroes', { id: heroId, foo: 'foo' }]); + } + // #enddocregion gotoHeroes +} diff --git a/public/docs/_examples/router/ts/src/app/heroes/hero-list.component.1.ts b/public/docs/_examples/router/ts/src/app/heroes/hero-list.component.1.ts new file mode 100644 index 0000000000..59552830a4 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/heroes/hero-list.component.1.ts @@ -0,0 +1,52 @@ +// #docplaster +// #docregion +// TODO SOMEDAY: Feature Componetized like HeroCenter +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +import { Hero, HeroService } from './hero.service'; + +@Component({ + // #docregion template + template: ` +

    HEROES

    +
      +
    • + {{ hero.id }} {{ hero.name }} +
    • +
    + + + ` + // #enddocregion template +}) +export class HeroListComponent implements OnInit { + heroes: Promise; + + // #docregion ctor + constructor( + private router: Router, + private service: HeroService + ) {} + // #enddocregion ctor + + ngOnInit() { + this.heroes = this.service.getHeroes(); + } + + // #docregion select + onSelect(hero: Hero) { + // #docregion nav-to-detail + this.router.navigate(['/hero', hero.id]); + // #enddocregion nav-to-detail + } + // #enddocregion select +} +// #enddocregion + +/* A link parameters array +// #docregion link-parameters-array +['/hero', hero.id] // { 15 } +// #enddocregion link-parameters-array +*/ diff --git a/public/docs/_examples/router/ts/src/app/heroes/hero-list.component.ts b/public/docs/_examples/router/ts/src/app/heroes/hero-list.component.ts new file mode 100644 index 0000000000..c7dcc3877e --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/heroes/hero-list.component.ts @@ -0,0 +1,63 @@ +// #docplaster +// #docregion +// TODO SOMEDAY: Feature Componetized like CrisisCenter +// #docregion rxjs-imports +import 'rxjs/add/operator/switchMap'; +import { Observable } from 'rxjs/Observable'; +// #enddocregion rxjs-imports +import { Component, OnInit } from '@angular/core'; +// #docregion import-router +import { Router, ActivatedRoute, Params } from '@angular/router'; +// #enddocregion import-router + +import { Hero, HeroService } from './hero.service'; + +@Component({ + // #docregion template + template: ` +

    HEROES

    +
      +
    • + {{ hero.id }} {{ hero.name }} +
    • +
    + + + ` + // #enddocregion template +}) +// #docregion ctor +export class HeroListComponent implements OnInit { + heroes: Observable; + + private selectedId: number; + + constructor( + private service: HeroService, + private route: ActivatedRoute, + private router: Router + ) {} + + ngOnInit() { + this.heroes = this.route.params + .switchMap((params: Params) => { + this.selectedId = +params['id']; + return this.service.getHeroes(); + }); + } + // #enddocregion ctor + + // #docregion isSelected + isSelected(hero: Hero) { return hero.id === this.selectedId; } + // #enddocregion isSelected + + // #docregion select + onSelect(hero: Hero) { + this.router.navigate(['/hero', hero.id]); + } + // #enddocregion select +// #docregion ctor +} +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/heroes/hero.service.ts b/public/docs/_examples/router/ts/src/app/heroes/hero.service.ts new file mode 100644 index 0000000000..6e4e7bee60 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/heroes/hero.service.ts @@ -0,0 +1,27 @@ +// #docregion +import { Injectable } from '@angular/core'; + +export class Hero { + constructor(public id: number, public name: string) { } +} + +let HEROES = [ + new Hero(11, 'Mr. Nice'), + new Hero(12, 'Narco'), + new Hero(13, 'Bombasto'), + new Hero(14, 'Celeritas'), + new Hero(15, 'Magneta'), + new Hero(16, 'RubberMan') +]; + +let heroesPromise = Promise.resolve(HEROES); + +@Injectable() +export class HeroService { + getHeroes() { return heroesPromise; } + + getHero(id: number | string) { + return heroesPromise + .then(heroes => heroes.find(hero => hero.id === +id)); + } +} diff --git a/public/docs/_examples/router/ts/src/app/heroes/heroes-routing.module.ts b/public/docs/_examples/router/ts/src/app/heroes/heroes-routing.module.ts new file mode 100644 index 0000000000..dbee521793 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/heroes/heroes-routing.module.ts @@ -0,0 +1,24 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { HeroListComponent } from './hero-list.component'; +import { HeroDetailComponent } from './hero-detail.component'; + +const heroesRoutes: Routes = [ + { path: 'heroes', component: HeroListComponent }, +// #docregion hero-detail-route + { path: 'hero/:id', component: HeroDetailComponent } +// #enddocregion hero-detail-route +]; + +@NgModule({ + imports: [ + RouterModule.forChild(heroesRoutes) + ], + exports: [ + RouterModule + ] +}) +export class HeroRoutingModule { } +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/heroes/heroes.module.ts b/public/docs/_examples/router/ts/src/app/heroes/heroes.module.ts new file mode 100644 index 0000000000..95ee64a182 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/heroes/heroes.module.ts @@ -0,0 +1,33 @@ +// #docplaster +// #docregion +// #docregion v1 +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { HeroListComponent } from './hero-list.component'; +import { HeroDetailComponent } from './hero-detail.component'; + +import { HeroService } from './hero.service'; + +// #enddocregion v1 +import { HeroRoutingModule } from './heroes-routing.module'; + +// #docregion v1 +@NgModule({ + imports: [ + CommonModule, + FormsModule, +// #enddocregion v1 + HeroRoutingModule +// #docregion v1 + ], + declarations: [ + HeroListComponent, + HeroDetailComponent + ], + providers: [ HeroService ] +}) +export class HeroesModule {} +// #enddocregion v1 +// #enddocregion diff --git a/public/docs/_examples/router/ts/src/app/login-routing.module.ts b/public/docs/_examples/router/ts/src/app/login-routing.module.ts new file mode 100644 index 0000000000..96d05e7972 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/login-routing.module.ts @@ -0,0 +1,24 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { AuthGuard } from './auth-guard.service'; +import { AuthService } from './auth.service'; +import { LoginComponent } from './login.component'; + +const loginRoutes: Routes = [ + { path: 'login', component: LoginComponent } +]; + +@NgModule({ + imports: [ + RouterModule.forChild(loginRoutes) + ], + exports: [ + RouterModule + ], + providers: [ + AuthGuard, + AuthService + ] +}) +export class LoginRoutingModule {} diff --git a/public/docs/_examples/router/ts/src/app/login.component.1.ts b/public/docs/_examples/router/ts/src/app/login.component.1.ts new file mode 100644 index 0000000000..ddee339011 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/login.component.1.ts @@ -0,0 +1,46 @@ +// #docregion +import { Component } from '@angular/core'; +import { Router } from '@angular/router'; +import { AuthService } from './auth.service'; + +@Component({ + template: ` +

    LOGIN

    +

    {{message}}

    +

    + + +

    ` +}) +export class LoginComponent { + message: string; + + constructor(public authService: AuthService, public router: Router) { + this.setMessage(); + } + + setMessage() { + this.message = 'Logged ' + (this.authService.isLoggedIn ? 'in' : 'out'); + } + + login() { + this.message = 'Trying to log in ...'; + + this.authService.login().subscribe(() => { + this.setMessage(); + if (this.authService.isLoggedIn) { + // Get the redirect URL from our auth service + // If no redirect has been set, use the default + let redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/crisis-center/admin'; + + // Redirect the user + this.router.navigate([redirect]); + } + }); + } + + logout() { + this.authService.logout(); + this.setMessage(); + } +} diff --git a/public/docs/_examples/router/ts/src/app/login.component.ts b/public/docs/_examples/router/ts/src/app/login.component.ts new file mode 100644 index 0000000000..41c88f4068 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/login.component.ts @@ -0,0 +1,56 @@ +// #docregion +import { Component } from '@angular/core'; +import { Router, + NavigationExtras } from '@angular/router'; +import { AuthService } from './auth.service'; + +@Component({ + template: ` +

    LOGIN

    +

    {{message}}

    +

    + + +

    ` +}) +export class LoginComponent { + message: string; + + constructor(public authService: AuthService, public router: Router) { + this.setMessage(); + } + + setMessage() { + this.message = 'Logged ' + (this.authService.isLoggedIn ? 'in' : 'out'); + } + + login() { + this.message = 'Trying to log in ...'; + + this.authService.login().subscribe(() => { + this.setMessage(); + if (this.authService.isLoggedIn) { + // Get the redirect URL from our auth service + // If no redirect has been set, use the default + let redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/admin'; + + // #docregion preserve + // Set our navigation extras object + // that passes on our global query params and fragment + let navigationExtras: NavigationExtras = { + preserveQueryParams: true, + preserveFragment: true + }; + + // Redirect the user + this.router.navigate([redirect], navigationExtras); + // #enddocregion preserve + } + }); + } + + logout() { + this.authService.logout(); + this.setMessage(); + } +} diff --git a/public/docs/_examples/router/ts/src/app/not-found.component.ts b/public/docs/_examples/router/ts/src/app/not-found.component.ts new file mode 100644 index 0000000000..2e74544e17 --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/not-found.component.ts @@ -0,0 +1,7 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + template: '

    Page not found

    ' +}) +export class PageNotFoundComponent {} diff --git a/public/docs/_examples/router/ts/src/app/selective-preloading-strategy.ts b/public/docs/_examples/router/ts/src/app/selective-preloading-strategy.ts new file mode 100644 index 0000000000..395f1056ef --- /dev/null +++ b/public/docs/_examples/router/ts/src/app/selective-preloading-strategy.ts @@ -0,0 +1,24 @@ +// #docregion +import 'rxjs/add/observable/of'; +import { Injectable } from '@angular/core'; +import { PreloadingStrategy, Route } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; + +@Injectable() +export class SelectivePreloadingStrategy implements PreloadingStrategy { + preloadedModules: string[] = []; + + preload(route: Route, load: () => Observable): Observable { + if (route.data && route.data['preload']) { + // add the route path to the preloaded module array + this.preloadedModules.push(route.path); + + // log the route path to the console + console.log('Preloaded: ' + route.path); + + return load(); + } else { + return Observable.of(null); + } + } +} diff --git a/public/docs/_examples/router/ts/src/index.html b/public/docs/_examples/router/ts/src/index.html new file mode 100644 index 0000000000..0fa6453c36 --- /dev/null +++ b/public/docs/_examples/router/ts/src/index.html @@ -0,0 +1,32 @@ + + + + + + + + + Angular Router + + + + + + + + + + + + + + + + loading... + + + + diff --git a/public/docs/_examples/router/ts/src/main.ts b/public/docs/_examples/router/ts/src/main.ts new file mode 100644 index 0000000000..f332d1d245 --- /dev/null +++ b/public/docs/_examples/router/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/security/e2e-spec.ts b/public/docs/_examples/security/e2e-spec.ts new file mode 100644 index 0000000000..23d11cd12b --- /dev/null +++ b/public/docs/_examples/security/e2e-spec.ts @@ -0,0 +1,37 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, By } from 'protractor'; + +describe('Security E2E Tests', () => { + beforeAll(() => browser.get('')); + + it('sanitizes innerHTML', () => { + let interpolated = element(By.className('e2e-inner-html-interpolated')); + expect(interpolated.getText()) + .toContain('Template Syntax'); + let bound = element(By.className('e2e-inner-html-bound')); + expect(bound.getText()).toContain('Template alert("0wned") Syntax'); + let bold = element(By.css('.e2e-inner-html-bound b')); + expect(bold.getText()).toContain('Syntax'); + }); + + it('escapes untrusted URLs', () => { + let untrustedUrl = element(By.className('e2e-dangerous-url')); + expect(untrustedUrl.getAttribute('href')).toMatch(/^unsafe:javascript/); + }); + + it('binds trusted URLs', () => { + let trustedUrl = element(By.className('e2e-trusted-url')); + expect(trustedUrl.getAttribute('href')).toMatch(/^javascript:alert/); + }); + + it('escapes untrusted resource URLs', () => { + let iframe = element(By.className('e2e-iframe-untrusted-src')); + expect(iframe.getAttribute('src')).toBe(''); + }); + + it('binds trusted resource URLs', () => { + let iframe = element(By.className('e2e-iframe-trusted-src')); + expect(iframe.getAttribute('src')).toMatch(/^https:\/\/www.youtube.com\//); + }); +}); diff --git a/public/docs/_examples/router-deprecated/ts/example-config.json b/public/docs/_examples/security/ts/example-config.json similarity index 100% rename from public/docs/_examples/router-deprecated/ts/example-config.json rename to public/docs/_examples/security/ts/example-config.json diff --git a/public/docs/_examples/security/ts/plnkr.json b/public/docs/_examples/security/ts/plnkr.json new file mode 100644 index 0000000000..4c9e85ce1e --- /dev/null +++ b/public/docs/_examples/security/ts/plnkr.json @@ -0,0 +1,9 @@ +{ + "description": "Content Security", + "basePath": "src/", + "files": [ + "!**/*.d.ts", + "!**/*.js" + ], + "tags": ["security"] +} diff --git a/public/docs/_examples/security/ts/src/app/app.component.ts b/public/docs/_examples/security/ts/src/app/app.component.ts new file mode 100644 index 0000000000..c30235e8e7 --- /dev/null +++ b/public/docs/_examples/security/ts/src/app/app.component.ts @@ -0,0 +1,13 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` +

    Security

    + + + ` +}) +export class AppComponent { +} diff --git a/public/docs/_examples/security/ts/src/app/app.module.ts b/public/docs/_examples/security/ts/src/app/app.module.ts new file mode 100644 index 0000000000..21d880be3b --- /dev/null +++ b/public/docs/_examples/security/ts/src/app/app.module.ts @@ -0,0 +1,18 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { BypassSecurityComponent } from './bypass-security.component'; +import { InnerHtmlBindingComponent } from './inner-html-binding.component'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ + AppComponent, + BypassSecurityComponent, + InnerHtmlBindingComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/security/ts/src/app/bypass-security.component.html b/public/docs/_examples/security/ts/src/app/bypass-security.component.html new file mode 100644 index 0000000000..96adf058e2 --- /dev/null +++ b/public/docs/_examples/security/ts/src/app/bypass-security.component.html @@ -0,0 +1,17 @@ + +

    Bypass Security Component

    + + +

    An untrusted URL:

    +

    Click me

    +

    A trusted URL:

    +

    Click me

    + + + +

    Resource URL:

    +

    Showing: {{dangerousVideoUrl}}

    +

    Trusted:

    + +

    Untrusted:

    + diff --git a/public/docs/_examples/security/ts/src/app/bypass-security.component.ts b/public/docs/_examples/security/ts/src/app/bypass-security.component.ts new file mode 100644 index 0000000000..ff41e287ba --- /dev/null +++ b/public/docs/_examples/security/ts/src/app/bypass-security.component.ts @@ -0,0 +1,38 @@ +// #docplaster +// #docregion +import { Component } from '@angular/core'; +import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser'; + +@Component({ + selector: 'bypass-security', + templateUrl: './bypass-security.component.html', +}) +export class BypassSecurityComponent { + dangerousUrl: string; + trustedUrl: SafeUrl; + dangerousVideoUrl: string; + videoUrl: SafeResourceUrl; + + // #docregion trust-url + constructor(private sanitizer: DomSanitizer) { + // javascript: URLs are dangerous if attacker controlled. + // Angular sanitizes them in data binding, but you can + // explicitly tell Angular to trust this value: + this.dangerousUrl = 'javascript:alert("Hi there")'; + this.trustedUrl = sanitizer.bypassSecurityTrustUrl(this.dangerousUrl); + // #enddocregion trust-url + this.updateVideoUrl('PUBnlbjZFAI'); + } + + // #docregion trust-video-url + updateVideoUrl(id: string) { + // Appending an ID to a YouTube URL is safe. + // Always make sure to construct SafeValue objects as + // close as possible to the input data so + // that it's easier to check if the value is safe. + this.dangerousVideoUrl = 'https://www.youtube.com/embed/' + id; + this.videoUrl = + this.sanitizer.bypassSecurityTrustResourceUrl(this.dangerousVideoUrl); + } + // #enddocregion trust-video-url +} diff --git a/public/docs/_examples/security/ts/src/app/inner-html-binding.component.html b/public/docs/_examples/security/ts/src/app/inner-html-binding.component.html new file mode 100644 index 0000000000..fe540d25fe --- /dev/null +++ b/public/docs/_examples/security/ts/src/app/inner-html-binding.component.html @@ -0,0 +1,6 @@ + +

    Binding innerHTML

    +

    Bound value:

    +

    {{htmlSnippet}}

    +

    Result of binding to innerHTML:

    +

    diff --git a/public/docs/_examples/security/ts/src/app/inner-html-binding.component.ts b/public/docs/_examples/security/ts/src/app/inner-html-binding.component.ts new file mode 100644 index 0000000000..8319503686 --- /dev/null +++ b/public/docs/_examples/security/ts/src/app/inner-html-binding.component.ts @@ -0,0 +1,12 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'inner-html-binding', + templateUrl: './inner-html-binding.component.html', +}) +// #docregion class +export class InnerHtmlBindingComponent { + // For example, a user/attacker-controlled value from a URL. + htmlSnippet = 'Template Syntax'; +} diff --git a/public/docs/_examples/security/ts/src/index.html b/public/docs/_examples/security/ts/src/index.html new file mode 100644 index 0000000000..d5dd11c038 --- /dev/null +++ b/public/docs/_examples/security/ts/src/index.html @@ -0,0 +1,26 @@ + + + + + Angular Content Security + + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/security/ts/src/main.ts b/public/docs/_examples/security/ts/src/main.ts new file mode 100644 index 0000000000..105b06712d --- /dev/null +++ b/public/docs/_examples/security/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); + diff --git a/public/docs/_examples/server-communication/dart/.docsync.json b/public/docs/_examples/server-communication/dart/.docsync.json deleted file mode 100644 index baa578054f..0000000000 --- a/public/docs/_examples/server-communication/dart/.docsync.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "HTTP client (server communication)", - "docHref": "https://angular.io/docs/dart/latest/guide/server-communication.html" -} diff --git a/public/docs/_examples/server-communication/dart/lib/app_component.dart b/public/docs/_examples/server-communication/dart/lib/app_component.dart deleted file mode 100644 index cd52ca413f..0000000000 --- a/public/docs/_examples/server-communication/dart/lib/app_component.dart +++ /dev/null @@ -1,31 +0,0 @@ -// #docplaster -// #docregion -import 'package:angular2/core.dart'; - -import 'toh/hero_list_component.dart'; -import 'wiki/wiki_component.dart'; -import 'wiki/wiki_smart_component.dart'; - -@Component( - selector: 'my-app', - template: ''' - - - - ''', - // #enddocregion - /* - // #docregion http-providers - providers: const [ - // in-memory web api provider - const Provider(BrowserClient, - useFactory: HttpClientBackendServiceFactory, deps: const [])], - // #enddocregion http-providers - */ - // #docregion - directives: const [ - HeroListComponent, - WikiComponent, - WikiSmartComponent - ]) -class AppComponent {} diff --git a/public/docs/_examples/server-communication/dart/lib/hero_data.dart b/public/docs/_examples/server-communication/dart/lib/hero_data.dart deleted file mode 100644 index ae0480b98d..0000000000 --- a/public/docs/_examples/server-communication/dart/lib/hero_data.dart +++ /dev/null @@ -1,15 +0,0 @@ -// #docregion -import 'package:http/browser_client.dart'; -import 'package:http_in_memory_web_api/http_in_memory_web_api.dart'; - -CreateDb _createDb = () => { - 'heroes': [ - {"id": "1", "name": "Windstorm"}, - {"id": "2", "name": "Bombasto"}, - {"id": "3", "name": "Magneta"}, - {"id": "4", "name": "Tornado"} - ] - }; - -BrowserClient HttpClientBackendServiceFactory() => - new HttpClientInMemoryBackendService(_createDb); diff --git a/public/docs/_examples/server-communication/dart/lib/toh/hero.dart b/public/docs/_examples/server-communication/dart/lib/toh/hero.dart deleted file mode 100644 index a990373a72..0000000000 --- a/public/docs/_examples/server-communication/dart/lib/toh/hero.dart +++ /dev/null @@ -1,14 +0,0 @@ -// #docregion -int _toInt(id) => id is int ? id : int.parse(id); - -class Hero { - final int id; - final String name; - - Hero(this.id, this.name); - - factory Hero.fromJson(Map hero) => - new Hero(_toInt(hero['id']), hero['name']); - - Map toJson() => {'id': id, 'name': name}; -} diff --git a/public/docs/_examples/server-communication/dart/lib/toh/hero_list_component.dart b/public/docs/_examples/server-communication/dart/lib/toh/hero_list_component.dart deleted file mode 100644 index 23e1d6e9d7..0000000000 --- a/public/docs/_examples/server-communication/dart/lib/toh/hero_list_component.dart +++ /dev/null @@ -1,47 +0,0 @@ -// #docregion -import 'dart:async'; - -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'hero_service.dart'; - -@Component( - selector: 'hero-list', - templateUrl: 'hero_list_component.html', - providers: const [HeroService]) -// #docregion component -class HeroListComponent implements OnInit { - final HeroService _heroService; - String errorMessage; - List heroes = []; - - HeroListComponent(this._heroService); - - Future ngOnInit() => getHeroes(); - - // #docregion methods - // #docregion getHeroes - Future getHeroes() async { - try { - heroes = await _heroService.getHeroes(); - } catch (e) { - errorMessage = e.toString(); - } - } - // #enddocregion getHeroes - - // #docregion addHero - Future addHero(String name) async { - name = name.trim(); - if (name.isEmpty) return; - try { - heroes.add(await _heroService.addHero(name)); - } catch (e) { - errorMessage = e.toString(); - } - } - // #enddocregion addHero - // #enddocregion methods -} -// #enddocregion component diff --git a/public/docs/_examples/server-communication/dart/lib/toh/hero_list_component.html b/public/docs/_examples/server-communication/dart/lib/toh/hero_list_component.html deleted file mode 100644 index 297ffaa6c6..0000000000 --- a/public/docs/_examples/server-communication/dart/lib/toh/hero_list_component.html +++ /dev/null @@ -1,14 +0,0 @@ - -

    Tour of Heroes

    -

    Heroes:

    -
      -
    • - {{hero.name}} -
    • -
    -New hero name: - - -
    {{errorMessage}}
    diff --git a/public/docs/_examples/server-communication/dart/lib/toh/hero_service.dart b/public/docs/_examples/server-communication/dart/lib/toh/hero_service.dart deleted file mode 100644 index 5da269fff7..0000000000 --- a/public/docs/_examples/server-communication/dart/lib/toh/hero_service.dart +++ /dev/null @@ -1,74 +0,0 @@ -// #docplaster -// #docregion -// #docregion v1 -import 'dart:async'; -import 'dart:convert'; -import 'hero.dart'; -import 'package:angular2/core.dart'; -import 'package:http/browser_client.dart'; -import 'package:http/http.dart'; - -@Injectable() -class HeroService { - // #docregion endpoint, http-get - static const _heroesUrl = 'app/heroes'; // URL to web API - // #enddocregion endpoint, http-get - final BrowserClient _http; - - // #docregion ctor - HeroService(this._http); - // #enddocregion ctor - - // #docregion methods, error-handling, http-get - Future> getHeroes() async { - try { - final response = await _http.get(_heroesUrl); - final heroes = _extractData(response) - .map((value) => new Hero.fromJson(value)) - .toList(); - return heroes; - } catch (e) { - throw _handleError(e); - } - } - // #enddocregion error-handling, http-get, v1 - - // #docregion addhero, addhero-sig - Future addHero(String name) async { - // #enddocregion addhero-sig - try { - final response = await _http.post(_heroesUrl, - headers: {'Content-Type': 'application/json'}, - body: JSON.encode({'name': name})); - return new Hero.fromJson(_extractData(response)); - } catch (e) { - throw _handleError(e); - } - } - // #enddocregion addhero, v1 - - // #docregion extract-data - dynamic _extractData(Response res) { - var body = JSON.decode(res.body); - // TODO: https://github.com/adaojunior/http-in-memory-web-api/issues/1 - // Once #1 is fixed, drop the `?? body` term: - return body['data'] ?? body; - } - // #enddocregion extract-data - // #docregion error-handling - - Exception _handleError(dynamic e) { - // In a real world app, we might use a remote logging infrastructure - // We'd also dig deeper into the error to get a better message - print(e); // log to console instead - return new Exception('Server error; cause: $e'); - } - // #enddocregion error-handling, methods -} -// #enddocregion - -/* - // #docregion endpoint-json - static const _heroesUrl = 'heroes.json'; // URL to JSON file - // #enddocregion endpoint-json -*/ diff --git a/public/docs/_examples/server-communication/dart/lib/wiki/wiki_component.dart b/public/docs/_examples/server-communication/dart/lib/wiki/wiki_component.dart deleted file mode 100644 index f8856b25cf..0000000000 --- a/public/docs/_examples/server-communication/dart/lib/wiki/wiki_component.dart +++ /dev/null @@ -1,28 +0,0 @@ -// #docregion -import 'dart:async'; - -import 'package:angular2/core.dart'; - -import 'wikipedia_service.dart'; - -@Component( - selector: 'my-wiki', - template: ''' -

    Wikipedia Demo

    -

    Fetches after each keystroke

    - -
      -
    • {{item}}
    • -
    - ''', - providers: const [WikipediaService]) -class WikiComponent { - final WikipediaService _wikipediaService; - List items = []; - - WikiComponent(this._wikipediaService); - - Future search(String term) async { - items = await this._wikipediaService.search(term); - } -} diff --git a/public/docs/_examples/server-communication/dart/lib/wiki/wiki_smart_component.dart b/public/docs/_examples/server-communication/dart/lib/wiki/wiki_smart_component.dart deleted file mode 100644 index 70f5f7bfe3..0000000000 --- a/public/docs/_examples/server-communication/dart/lib/wiki/wiki_smart_component.dart +++ /dev/null @@ -1,37 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; -import 'package:stream_transformers/stream_transformers.dart'; - -import 'wikipedia_service.dart'; - -@Component( - selector: 'my-wiki-smart', - template: ''' -

    Smarter Wikipedia Demo

    -

    Fetches when typing stops

    - - -
      -
    • {{item}}
    • -
    - ''', - providers: const [WikipediaService]) -class WikiSmartComponent { - final WikipediaService _wikipediaService; - List items = []; - - WikiSmartComponent(this._wikipediaService) { - _searchTermStream - .transform(new Debounce(new Duration(milliseconds: 300))) - .distinct() - .transform(new FlatMapLatest( - (term) => _wikipediaService.search(term).asStream())) - .forEach((data) { - items = data; - }); - } - - final EventEmitter _searchTermStream = new EventEmitter(); - - void search(String term) => _searchTermStream.add(term); -} diff --git a/public/docs/_examples/server-communication/dart/lib/wiki/wikipedia_service.dart b/public/docs/_examples/server-communication/dart/lib/wiki/wikipedia_service.dart deleted file mode 100644 index 6942f7fa93..0000000000 --- a/public/docs/_examples/server-communication/dart/lib/wiki/wikipedia_service.dart +++ /dev/null @@ -1,25 +0,0 @@ -// #docregion -import 'dart:async'; - -import 'package:angular2/core.dart'; -import 'package:jsonpadding/jsonpadding.dart'; - -@Injectable() -class WikipediaService { - Future> search(String term) async { - // #docregion call-jsonp - Uri uri = new Uri( - scheme: 'http', - host: 'en.wikipedia.org', - path: 'w/api.php', - queryParameters: { - 'search': term, - 'action': 'opensearch', - 'format': 'json' - }); - // TODO: Error handling - List result = await jsonp(uri); - return result[1]; - // #enddocregion call-jsonp - } -} diff --git a/public/docs/_examples/server-communication/dart/pubspec.yaml b/public/docs/_examples/server-communication/dart/pubspec.yaml deleted file mode 100644 index 6b1e961d75..0000000000 --- a/public/docs/_examples/server-communication/dart/pubspec.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# #docregion -name: server_communication -description: Server Communication -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 - http: ^0.11.3+3 - jsonpadding: ^0.1.0 - stream_transformers: ^0.3.0+3 - http_in_memory_web_api: ^0.0.1 -# #docregion transformers -transformers: -- angular2: - platform_directives: - - 'package:angular2/common.dart#CORE_DIRECTIVES' - platform_pipes: - - 'package:angular2/common.dart#COMMON_PIPES' - entry_points: 'web/main.dart' - resolved_identifiers: - BrowserClient: 'package:http/browser_client.dart' -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/server-communication/dart/web/heroes.json b/public/docs/_examples/server-communication/dart/web/heroes.json deleted file mode 100644 index c6b5cc91df..0000000000 --- a/public/docs/_examples/server-communication/dart/web/heroes.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "data": [ - { "id": "1", "name": "Windstorm" }, - { "id": "2", "name": "Bombasto" }, - { "id": "3", "name": "Magneta" }, - { "id": "4", "name": "Tornado" } - ] -} diff --git a/public/docs/_examples/server-communication/dart/web/index.html b/public/docs/_examples/server-communication/dart/web/index.html deleted file mode 100644 index fc365968c2..0000000000 --- a/public/docs/_examples/server-communication/dart/web/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - Angular 2 Http Demo - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/server-communication/dart/web/main.dart b/public/docs/_examples/server-communication/dart/web/main.dart deleted file mode 100644 index ca055c9d10..0000000000 --- a/public/docs/_examples/server-communication/dart/web/main.dart +++ /dev/null @@ -1,34 +0,0 @@ -// #docplaster -// #docregion final -import 'package:angular2/core.dart'; -// #docregion v1 -import 'package:angular2/platform/browser.dart'; -// #docregion http-providers -import 'package:http/browser_client.dart'; -// #enddocregion http-providers - -import 'package:server_communication/app_component.dart'; -// #enddocregion v1 -// #docregion in-mem-web-api-imports -import "package:server_communication/hero_data.dart"; - -// #enddocregion in-mem-web-api-imports -// #docregion in-mem-web-api-providers -void main() { - bootstrap(AppComponent, const [ - // in-memory web api provider - const Provider(BrowserClient, - useFactory: HttpClientBackendServiceFactory, deps: const []) - // TODO: drop `deps` once fix lands for - // https://github.com/angular/angular/issues/5266 - ]); -} -// #enddocregion final, in-mem-web-api-providers -/* -// #docregion v1 - -void main() { - bootstrap(AppComponent, const [BrowserClient]); -} -// #enddocregion v1 -*/ diff --git a/public/docs/_examples/server-communication/dart/web/sample.css b/public/docs/_examples/server-communication/dart/web/sample.css deleted file mode 100644 index 3bb281e096..0000000000 --- a/public/docs/_examples/server-communication/dart/web/sample.css +++ /dev/null @@ -1 +0,0 @@ -.error {color:red;} diff --git a/public/docs/_examples/server-communication/e2e-spec.ts b/public/docs/_examples/server-communication/e2e-spec.ts index 417be6f6e8..a85c7489f8 100644 --- a/public/docs/_examples/server-communication/e2e-spec.ts +++ b/public/docs/_examples/server-communication/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Server Communication', function () { beforeAll(function () { @@ -29,18 +32,18 @@ describe('Server Communication', function () { addButton.click().then(function() { expect(heroTags.count()).toBe(initialHeroCount, 'No new hero should be added'); }); - }) + }); it('should add a new hero to the list', function () { expect(heroNameInput).toBeDefined(' for hero name must exist'); expect(addButton).toBeDefined('"Add Hero" button must be defined'); - sendKeys(heroNameInput, newHeroName); + heroNameInput.sendKeys(newHeroName); addButton.click().then(function() { expect(heroTags.count()).toBe(heroCountAfterAdd, 'A new hero should be added'); let newHeroInList = heroTags.get(heroCountAfterAdd - 1).getText(); expect(newHeroInList).toBe(newHeroName, 'The hero should be added to the end of the list'); }); - }) + }); }); describe('Wikipedia Demo', function () { @@ -53,25 +56,25 @@ describe('Server Communication', function () { }); describe('Fetches after each keystroke', function () { - it('should fetch results after "B"', function(done) { + it('should fetch results after "B"', function(done: any) { testForRefreshedResult('B', done); }); - it('should fetch results after "Ba"', function(done) { + it('should fetch results after "Ba"', function(done: any) { testForRefreshedResult('a', done); }); - it('should fetch results after "Bas"', function(done) { + it('should fetch results after "Bas"', function(done: any) { testForRefreshedResult('s', done); }); - it('should fetch results after "Basic"', function(done) { + it('should fetch results after "Basic"', function(done: any) { testForRefreshedResult('ic', done); }); }); function testForRefreshedResult(keyPressed: string, done: () => void) { - testForResult('my-wiki', keyPressed, false, done) + testForResult('my-wiki', keyPressed, false, done); } }); @@ -84,29 +87,29 @@ describe('Server Communication', function () { expect(resultList.count()).toBe(0, 'result list must be empty'); }); - it('should fetch results after "Java"', function(done) { + it('should fetch results after "Java"', function(done: any) { testForNewResult('Java', done); }); - it('should fetch results after "JavaS"', function(done) { + it('should fetch results after "JavaS"', function(done: any) { testForStaleResult('S', done); }); - it('should fetch results after "JavaSc"', function(done) { + it('should fetch results after "JavaSc"', function(done: any) { testForStaleResult('c', done); }); - it('should fetch results after "JavaScript"', function(done) { + it('should fetch results after "JavaScript"', function(done: any) { testForStaleResult('ript', done); }); function testForNewResult(keyPressed: string, done: () => void) { - testForResult('my-wiki-smart', keyPressed, false, done) + testForResult('my-wiki-smart', keyPressed, false, done); } function testForStaleResult(keyPressed: string, done: () => void) { - testForResult('my-wiki-smart', keyPressed, true, done) + testForResult('my-wiki-smart', keyPressed, true, done); } }); diff --git a/public/docs/_examples/server-communication/ts/app/app.component.ts b/public/docs/_examples/server-communication/ts/app/app.component.ts deleted file mode 100644 index 144475d0e4..0000000000 --- a/public/docs/_examples/server-communication/ts/app/app.component.ts +++ /dev/null @@ -1,37 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; - -// #docregion import-rxjs -// Add the RxJS Observable operators we need in this app. -import './rxjs-operators'; -// #enddocregion import-rxjs - -import { HeroListComponent } from './toh/hero-list.component'; -import { HeroListPromiseComponent } from './toh/hero-list.component.promise'; - -import { WikiComponent } from './wiki/wiki.component'; -import { WikiSmartComponent } from './wiki/wiki-smart.component'; - -@Component({ - selector: 'my-app', - template: ` - - - - - `, -// #enddocregion -/* -// #docregion http-providers - providers: [ HTTP_PROVIDERS ] -// #enddocregion http-providers -*/ -// #docregion - directives: [ - HeroListComponent, HeroListPromiseComponent, - WikiComponent, WikiSmartComponent - ] -}) -export class AppComponent { } -// #enddocregion diff --git a/public/docs/_examples/server-communication/ts/app/hero-data.ts b/public/docs/_examples/server-communication/ts/app/hero-data.ts deleted file mode 100644 index ad10b464c7..0000000000 --- a/public/docs/_examples/server-communication/ts/app/hero-data.ts +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -export class HeroData { - createDb() { - let heroes = [ - { id: '1', name: 'Windstorm' }, - { id: '2', name: 'Bombasto' }, - { id: '3', name: 'Magneta' }, - { id: '4', name: 'Tornado' } - ]; - return {heroes}; - } -} diff --git a/public/docs/_examples/server-communication/ts/app/heroes.json b/public/docs/_examples/server-communication/ts/app/heroes.json deleted file mode 100644 index c6b5cc91df..0000000000 --- a/public/docs/_examples/server-communication/ts/app/heroes.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "data": [ - { "id": "1", "name": "Windstorm" }, - { "id": "2", "name": "Bombasto" }, - { "id": "3", "name": "Magneta" }, - { "id": "4", "name": "Tornado" } - ] -} diff --git a/public/docs/_examples/server-communication/ts/app/main.ts b/public/docs/_examples/server-communication/ts/app/main.ts deleted file mode 100644 index 194ab5c5fb..0000000000 --- a/public/docs/_examples/server-communication/ts/app/main.ts +++ /dev/null @@ -1,29 +0,0 @@ -// #docplaster -// #docregion final -// Imports for loading & configuring the in-memory web api -import { XHRBackend } from '@angular/http'; - -import { InMemoryBackendService, - SEED_DATA } from 'angular2-in-memory-web-api'; -import { HeroData } from './hero-data'; - -// The usual bootstrapping imports -// #docregion v1 -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { HTTP_PROVIDERS } from '@angular/http'; - -import { AppComponent } from './app.component'; - -// #enddocregion v1, final -/* -// #docregion v1 -bootstrap(AppComponent, [ HTTP_PROVIDERS ]); -// #enddocregion v1 - */ -// #docregion final -bootstrap(AppComponent, [ - HTTP_PROVIDERS, - { provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server - { provide: SEED_DATA, useClass: HeroData } // in-mem server data -]); -// #enddocregion final diff --git a/public/docs/_examples/server-communication/ts/app/rxjs-operators.ts b/public/docs/_examples/server-communication/ts/app/rxjs-operators.ts deleted file mode 100644 index 6f8d626267..0000000000 --- a/public/docs/_examples/server-communication/ts/app/rxjs-operators.ts +++ /dev/null @@ -1,16 +0,0 @@ -// #docregion -// import 'rxjs/Rx'; // adds ALL RxJS statics & operators to Observable - -// See node_module/rxjs/Rxjs.js -// Import just the rxjs statics and operators we need for THIS app. - -// Statics -import 'rxjs/add/observable/throw'; - -// Operators -import 'rxjs/add/operator/catch'; -import 'rxjs/add/operator/debounceTime'; -import 'rxjs/add/operator/distinctUntilChanged'; -import 'rxjs/add/operator/map'; -import 'rxjs/add/operator/switchMap'; -import 'rxjs/add/operator/toPromise'; diff --git a/public/docs/_examples/server-communication/ts/app/toh/hero-list.component.html b/public/docs/_examples/server-communication/ts/app/toh/hero-list.component.html deleted file mode 100644 index 36666f2ed3..0000000000 --- a/public/docs/_examples/server-communication/ts/app/toh/hero-list.component.html +++ /dev/null @@ -1,14 +0,0 @@ - -

    Tour of Heroes ({{mode}})

    -

    Heroes:

    -
      -
    • - {{hero.name}} -
    • -
    -New hero name: - - -
    {{errorMessage}}
    diff --git a/public/docs/_examples/server-communication/ts/app/toh/hero-list.component.ts b/public/docs/_examples/server-communication/ts/app/toh/hero-list.component.ts deleted file mode 100644 index f582cfcc65..0000000000 --- a/public/docs/_examples/server-communication/ts/app/toh/hero-list.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -// #docregion -// Observable Version -import { Component, OnInit } from '@angular/core'; -import { Hero } from './hero'; -import { HeroService } from './hero.service'; - -@Component({ - selector: 'hero-list', - templateUrl: 'app/toh/hero-list.component.html', - providers: [ HeroService ] -}) -// #docregion component -export class HeroListComponent implements OnInit { - - constructor (private heroService: HeroService) {} - - errorMessage: string; - heroes: Hero[]; - mode = 'Observable'; - - ngOnInit() { this.getHeroes(); } - - // #docregion methods - // #docregion getHeroes - getHeroes() { - this.heroService.getHeroes() - .subscribe( - heroes => this.heroes = heroes, - error => this.errorMessage = error); - } - // #enddocregion getHeroes - - // #docregion addHero - addHero (name: string) { - if (!name) { return; } - this.heroService.addHero(name) - .subscribe( - hero => this.heroes.push(hero), - error => this.errorMessage = error); - } - // #enddocregion addHero - // #enddocregion methods -} -// #enddocregion component diff --git a/public/docs/_examples/server-communication/ts/app/toh/hero.service.promise.ts b/public/docs/_examples/server-communication/ts/app/toh/hero.service.promise.ts deleted file mode 100644 index c3ecd07e49..0000000000 --- a/public/docs/_examples/server-communication/ts/app/toh/hero.service.promise.ts +++ /dev/null @@ -1,51 +0,0 @@ -// #docplaster -// #docregion -// Promise Version -import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; -import { Headers, RequestOptions } from '@angular/http'; -import { Hero } from './hero'; - -@Injectable() -export class HeroService { - constructor (private http: Http) {} - - // URL to web api - private heroesUrl = 'app/heroes.json'; - - // #docregion methods - getHeroes (): Promise { - return this.http.get(this.heroesUrl) - .toPromise() - .then(this.extractData) - .catch(this.handleError); - } - - addHero (name: string): Promise { - let body = JSON.stringify({ name }); - let headers = new Headers({ 'Content-Type': 'application/json' }); - let options = new RequestOptions({ headers: headers }); - - return this.http.post(this.heroesUrl, body, options) - .toPromise() - .then(this.extractData) - .catch(this.handleError); - } - - private extractData(res: Response) { - let body = res.json(); - return body.data || { }; - } - - private handleError (error: any) { - // In a real world app, we might use a remote logging infrastructure - // We'd also dig deeper into the error to get a better message - let errMsg = (error.message) ? error.message : - error.status ? `${error.status} - ${error.statusText}` : 'Server error'; - console.error(errMsg); // log to console instead - return Promise.reject(errMsg); - } - -// #enddocregion methods -} -// #enddocregion diff --git a/public/docs/_examples/server-communication/ts/app/toh/hero.service.ts b/public/docs/_examples/server-communication/ts/app/toh/hero.service.ts deleted file mode 100644 index f1f749b507..0000000000 --- a/public/docs/_examples/server-communication/ts/app/toh/hero.service.ts +++ /dev/null @@ -1,71 +0,0 @@ -// #docplaster -// #docregion -// Observable Version -// #docregion v1 -import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; -// #enddocregion v1 -// #docregion import-request-options -import { Headers, RequestOptions } from '@angular/http'; -// #enddocregion import-request-options -// #docregion v1 - -import { Hero } from './hero'; -import { Observable } from 'rxjs/Observable'; - -@Injectable() -export class HeroService { - // #docregion ctor - constructor (private http: Http) {} - // #enddocregion ctor - - // #docregion endpoint - private heroesUrl = 'app/heroes'; // URL to web API - // #enddocregion endpoint - - // #docregion methods, error-handling, http-get - getHeroes (): Observable { - return this.http.get(this.heroesUrl) - .map(this.extractData) - .catch(this.handleError); - } - // #enddocregion error-handling, http-get, v1 - - // #docregion addhero, addhero-sig - addHero (name: string): Observable { - // #enddocregion addhero-sig - let body = JSON.stringify({ name }); - let headers = new Headers({ 'Content-Type': 'application/json' }); - let options = new RequestOptions({ headers: headers }); - - return this.http.post(this.heroesUrl, body, options) - .map(this.extractData) - .catch(this.handleError); - } - // #enddocregion addhero - - // #docregion v1, extract-data - private extractData(res: Response) { - let body = res.json(); - return body.data || { }; - } - // #enddocregion extract-data - - // #docregion error-handling - private handleError (error: any) { - // In a real world app, we might use a remote logging infrastructure - // We'd also dig deeper into the error to get a better message - let errMsg = (error.message) ? error.message : - error.status ? `${error.status} - ${error.statusText}` : 'Server error'; - console.error(errMsg); // log to console instead - return Observable.throw(errMsg); - } - // #enddocregion error-handling, methods -} -// #enddocregion - -/* - // #docregion endpoint-json - private heroesUrl = 'app/heroes.json'; // URL to JSON file - // #enddocregion endpoint-json -*/ diff --git a/public/docs/_examples/server-communication/ts/app/wiki/wiki-smart.component.ts b/public/docs/_examples/server-communication/ts/app/wiki/wiki-smart.component.ts deleted file mode 100644 index 55485b8ff4..0000000000 --- a/public/docs/_examples/server-communication/ts/app/wiki/wiki-smart.component.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* tslint:disable:member-ordering */ -// #docregion -import { Component } from '@angular/core'; -import { JSONP_PROVIDERS } from '@angular/http'; -import { Observable } from 'rxjs/Observable'; -// #docregion import-subject -import { Subject } from 'rxjs/Subject'; -// #enddocregion import-subject - -import { WikipediaService } from './wikipedia.service'; - -@Component({ - selector: 'my-wiki-smart', - template: ` -

    Smarter Wikipedia Demo

    -

    Fetches when typing stops

    - - - -
      -
    • {{item}}
    • -
    - `, - providers: [JSONP_PROVIDERS, WikipediaService] -}) -export class WikiSmartComponent { - - constructor (private wikipediaService: WikipediaService) { } - - // #docregion subject - private searchTermStream = new Subject(); - - search(term: string) { this.searchTermStream.next(term); } - // #enddocregion subject - - // #docregion observable-operators - items: Observable = this.searchTermStream - .debounceTime(300) - .distinctUntilChanged() - .switchMap((term: string) => this.wikipediaService.search(term)); -// #enddocregion observable-operators -} diff --git a/public/docs/_examples/server-communication/ts/app/wiki/wiki.component.ts b/public/docs/_examples/server-communication/ts/app/wiki/wiki.component.ts deleted file mode 100644 index 63a0bc5f81..0000000000 --- a/public/docs/_examples/server-communication/ts/app/wiki/wiki.component.ts +++ /dev/null @@ -1,31 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { JSONP_PROVIDERS } from '@angular/http'; -import { Observable } from 'rxjs/Observable'; - -import { WikipediaService } from './wikipedia.service'; - -@Component({ - selector: 'my-wiki', - template: ` -

    Wikipedia Demo

    -

    Fetches after each keystroke

    - - - -
      -
    • {{item}}
    • -
    - `, - providers: [JSONP_PROVIDERS, WikipediaService] -}) -export class WikiComponent { - - constructor (private wikipediaService: WikipediaService) {} - - items: Observable; - - search (term: string) { - this.items = this.wikipediaService.search(term); - } -} diff --git a/public/docs/_examples/server-communication/ts/index.html b/public/docs/_examples/server-communication/ts/index.html deleted file mode 100644 index c2d2656c84..0000000000 --- a/public/docs/_examples/server-communication/ts/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Angular 2 Http Demo - - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/server-communication/ts/plnkr.json b/public/docs/_examples/server-communication/ts/plnkr.json index fd35eda20d..fe966be012 100644 --- a/public/docs/_examples/server-communication/ts/plnkr.json +++ b/public/docs/_examples/server-communication/ts/plnkr.json @@ -1,9 +1,10 @@ { "description": "Http", + "basePath": "src/", "files":[ "!**/*.d.ts", "!**/*.js", "!**/*.[1].*" ], "tags": ["http", "jsonp"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/server-communication/ts/sample.css b/public/docs/_examples/server-communication/ts/sample.css deleted file mode 100644 index 3bb281e096..0000000000 --- a/public/docs/_examples/server-communication/ts/sample.css +++ /dev/null @@ -1 +0,0 @@ -.error {color:red;} diff --git a/public/docs/_examples/server-communication/ts/src/app/app.component.ts b/public/docs/_examples/server-communication/ts/src/app/app.component.ts new file mode 100644 index 0000000000..780d044cab --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/app.component.ts @@ -0,0 +1,13 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` + + + + + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/server-communication/ts/src/app/app.module.1.ts b/public/docs/_examples/server-communication/ts/src/app/app.module.1.ts new file mode 100644 index 0000000000..fb7012aa02 --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/app.module.1.ts @@ -0,0 +1,23 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpModule, JsonpModule } from '@angular/http'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HttpModule, + JsonpModule + ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { +} + + + diff --git a/public/docs/_examples/server-communication/ts/src/app/app.module.ts b/public/docs/_examples/server-communication/ts/src/app/app.module.ts new file mode 100644 index 0000000000..fd0c720c3c --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/app.module.ts @@ -0,0 +1,46 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpModule, JsonpModule } from '@angular/http'; + + +import { InMemoryWebApiModule } from 'angular-in-memory-web-api'; +import { HeroData } from './hero-data'; +import { requestOptionsProvider } from './default-request-options.service'; + +import { AppComponent } from './app.component'; + +import { HeroListComponent } from './toh/hero-list.component'; +import { HeroListPromiseComponent } from './toh/hero-list.component.promise'; + +import { WikiComponent } from './wiki/wiki.component'; +import { WikiSmartComponent } from './wiki/wiki-smart.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HttpModule, + JsonpModule, + // #docregion in-mem-web-api + InMemoryWebApiModule.forRoot(HeroData) + // #enddocregion in-mem-web-api + ], + declarations: [ + AppComponent, + HeroListComponent, + HeroListPromiseComponent, + WikiComponent, + WikiSmartComponent + ], +// #docregion provide-default-request-options + providers: [ requestOptionsProvider ], +// #enddocregion provide-default-request-options + bootstrap: [ AppComponent ] +}) +export class AppModule {} + + + diff --git a/public/docs/_examples/server-communication/ts/src/app/default-request-options.service.ts b/public/docs/_examples/server-communication/ts/src/app/default-request-options.service.ts new file mode 100644 index 0000000000..9ec52daa80 --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/default-request-options.service.ts @@ -0,0 +1,16 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { BaseRequestOptions, RequestOptions } from '@angular/http'; + +@Injectable() +export class DefaultRequestOptions extends BaseRequestOptions { + + constructor() { + super(); + + // Set the default 'Content-Type' header + this.headers.set('Content-Type', 'application/json'); + } +} + +export const requestOptionsProvider = { provide: RequestOptions, useClass: DefaultRequestOptions }; diff --git a/public/docs/_examples/server-communication/ts/src/app/hero-data.ts b/public/docs/_examples/server-communication/ts/src/app/hero-data.ts new file mode 100644 index 0000000000..4db6aca115 --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/hero-data.ts @@ -0,0 +1,13 @@ +// #docregion +import { InMemoryDbService } from 'angular-in-memory-web-api'; +export class HeroData implements InMemoryDbService { + createDb() { + let heroes = [ + { id: 1, name: 'Windstorm' }, + { id: 2, name: 'Bombasto' }, + { id: 3, name: 'Magneta' }, + { id: 4, name: 'Tornado' } + ]; + return {heroes}; + } +} diff --git a/public/docs/_examples/server-communication/ts/src/app/heroes.json b/public/docs/_examples/server-communication/ts/src/app/heroes.json new file mode 100644 index 0000000000..dfb589066b --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/heroes.json @@ -0,0 +1,8 @@ +{ + "data": [ + { "id": 1, "name": "Windstorm" }, + { "id": 2, "name": "Bombasto" }, + { "id": 3, "name": "Magneta" }, + { "id": 4, "name": "Tornado" } + ] +} diff --git a/public/docs/_examples/server-communication/ts/src/app/toh/hero-list.component.html b/public/docs/_examples/server-communication/ts/src/app/toh/hero-list.component.html new file mode 100644 index 0000000000..65ca9cfbb7 --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/toh/hero-list.component.html @@ -0,0 +1,11 @@ + +

    Tour of Heroes ({{mode}})

    +

    Heroes:

    +
      +
    • {{hero.name}}
    • +
    + + + + +

    {{errorMessage}}

    diff --git a/public/docs/_examples/server-communication/ts/app/toh/hero-list.component.promise.ts b/public/docs/_examples/server-communication/ts/src/app/toh/hero-list.component.promise.ts similarity index 90% rename from public/docs/_examples/server-communication/ts/app/toh/hero-list.component.promise.ts rename to public/docs/_examples/server-communication/ts/src/app/toh/hero-list.component.promise.ts index 7df0676a9a..4bbe7eade2 100644 --- a/public/docs/_examples/server-communication/ts/app/toh/hero-list.component.promise.ts +++ b/public/docs/_examples/server-communication/ts/src/app/toh/hero-list.component.promise.ts @@ -6,18 +6,18 @@ import { HeroService } from './hero.service.promise'; @Component({ selector: 'hero-list-promise', - templateUrl: 'app/toh/hero-list.component.html', - providers: [ HeroService ] + templateUrl: './hero-list.component.html', + providers: [ HeroService ], + styles: ['.error {color:red;}'] }) // #docregion component export class HeroListPromiseComponent implements OnInit { - - constructor (private heroService: HeroService) {} - errorMessage: string; heroes: Hero[]; mode = 'Promise'; + constructor (private heroService: HeroService) {} + ngOnInit() { this.getHeroes(); } // #docregion methods diff --git a/public/docs/_examples/server-communication/ts/src/app/toh/hero-list.component.ts b/public/docs/_examples/server-communication/ts/src/app/toh/hero-list.component.ts new file mode 100644 index 0000000000..8cca504762 --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/toh/hero-list.component.ts @@ -0,0 +1,44 @@ +// #docregion +// Observable Version +import { Component, OnInit } from '@angular/core'; +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +@Component({ + selector: 'hero-list', + templateUrl: './hero-list.component.html', + providers: [ HeroService ], + styles: ['.error {color:red;}'] +}) +// #docregion component +export class HeroListComponent implements OnInit { + errorMessage: string; + heroes: Hero[]; + mode = 'Observable'; + + constructor (private heroService: HeroService) {} + + ngOnInit() { this.getHeroes(); } + + // #docregion methods + // #docregion getHeroes + getHeroes() { + this.heroService.getHeroes() + .subscribe( + heroes => this.heroes = heroes, + error => this.errorMessage = error); + } + // #enddocregion getHeroes + + // #docregion addHero + addHero(name: string) { + if (!name) { return; } + this.heroService.create(name) + .subscribe( + hero => this.heroes.push(hero), + error => this.errorMessage = error); + } + // #enddocregion addHero + // #enddocregion methods +} +// #enddocregion component diff --git a/public/docs/_examples/server-communication/ts/src/app/toh/hero.service.promise.ts b/public/docs/_examples/server-communication/ts/src/app/toh/hero.service.promise.ts new file mode 100644 index 0000000000..e38bd4bebf --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/toh/hero.service.promise.ts @@ -0,0 +1,60 @@ +// #docplaster +// #docregion +// Promise Version +import { Injectable } from '@angular/core'; +import { Http, Response } from '@angular/http'; +import { Headers, RequestOptions } from '@angular/http'; + +// #docregion rxjs-imports +import 'rxjs/add/operator/toPromise'; +// #enddocregion rxjs-imports + +import { Hero } from './hero'; + +@Injectable() +export class HeroService { + // URL to web api + private heroesUrl = 'app/heroes'; + + constructor (private http: Http) {} + + // #docregion methods + getHeroes (): Promise { + return this.http.get(this.heroesUrl) + .toPromise() + .then(this.extractData) + .catch(this.handleError); + } + + addHero (name: string): Promise { + let headers = new Headers({ 'Content-Type': 'application/json' }); + let options = new RequestOptions({ headers: headers }); + + return this.http.post(this.heroesUrl, { name }, options) + .toPromise() + .then(this.extractData) + .catch(this.handleError); + } + + private extractData(res: Response) { + let body = res.json(); + return body.data || { }; + } + + private handleError (error: Response | any) { + // In a real world app, we might use a remote logging infrastructure + let errMsg: string; + if (error instanceof Response) { + const body = error.json() || ''; + const err = body.error || JSON.stringify(body); + errMsg = `${error.status} - ${error.statusText || ''} ${err}`; + } else { + errMsg = error.message ? error.message : error.toString(); + } + console.error(errMsg); + return Promise.reject(errMsg); + } + +// #enddocregion methods +} +// #enddocregion diff --git a/public/docs/_examples/server-communication/ts/src/app/toh/hero.service.ts b/public/docs/_examples/server-communication/ts/src/app/toh/hero.service.ts new file mode 100644 index 0000000000..4f0da49021 --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/toh/hero.service.ts @@ -0,0 +1,80 @@ +// #docplaster +// #docregion +// Observable Version +// #docregion v1 +import { Injectable } from '@angular/core'; +import { Http, Response } from '@angular/http'; +// #enddocregion v1 +// #docregion import-request-options +import { Headers, RequestOptions } from '@angular/http'; +// #enddocregion import-request-options +// #docregion v1 + +// #docregion rxjs-imports +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/catch'; +import 'rxjs/add/operator/map'; +// #enddocregion rxjs-imports + +import { Hero } from './hero'; + +@Injectable() +export class HeroService { + // #docregion endpoint + private heroesUrl = 'api/heroes'; // URL to web API + // #enddocregion endpoint + + // #docregion ctor + constructor (private http: Http) {} + // #enddocregion ctor + + // #docregion methods, error-handling, http-get + getHeroes(): Observable { + return this.http.get(this.heroesUrl) + .map(this.extractData) + .catch(this.handleError); + } + // #enddocregion error-handling, http-get, v1 + + // #docregion create, create-sig + create(name: string): Observable { + // #enddocregion create-sig + let headers = new Headers({ 'Content-Type': 'application/json' }); + let options = new RequestOptions({ headers: headers }); + + return this.http.post(this.heroesUrl, { name }, options) + .map(this.extractData) + .catch(this.handleError); + } + // #enddocregion create + + // #docregion v1, extract-data + private extractData(res: Response) { + let body = res.json(); + return body.data || { }; + } + // #enddocregion extract-data + // #docregion error-handling + + private handleError (error: Response | any) { + // In a real world app, you might use a remote logging infrastructure + let errMsg: string; + if (error instanceof Response) { + const body = error.json() || ''; + const err = body.error || JSON.stringify(body); + errMsg = `${error.status} - ${error.statusText || ''} ${err}`; + } else { + errMsg = error.message ? error.message : error.toString(); + } + console.error(errMsg); + return Observable.throw(errMsg); + } + // #enddocregion error-handling, methods +} +// #enddocregion + +/* + // #docregion endpoint-json + private heroesUrl = 'app/heroes.json'; // URL to JSON file + // #enddocregion endpoint-json +*/ diff --git a/public/docs/_examples/server-communication/ts/app/toh/hero.ts b/public/docs/_examples/server-communication/ts/src/app/toh/hero.ts similarity index 100% rename from public/docs/_examples/server-communication/ts/app/toh/hero.ts rename to public/docs/_examples/server-communication/ts/src/app/toh/hero.ts diff --git a/public/docs/_examples/server-communication/ts/src/app/wiki/wiki-smart.component.ts b/public/docs/_examples/server-communication/ts/src/app/wiki/wiki-smart.component.ts new file mode 100644 index 0000000000..fc453a820e --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/wiki/wiki-smart.component.ts @@ -0,0 +1,47 @@ +/* tslint:disable: member-ordering forin */ +// #docplaster +// #docregion +import { Component, OnInit } from '@angular/core'; + +// #docregion rxjs-imports +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/debounceTime'; +import 'rxjs/add/operator/distinctUntilChanged'; +import 'rxjs/add/operator/switchMap'; + +// #docregion import-subject +import { Subject } from 'rxjs/Subject'; +// #enddocregion import-subject + +import { WikipediaService } from './wikipedia.service'; + +@Component({ + selector: 'my-wiki-smart', + template: ` +

    Smarter Wikipedia Demo

    +

    Search when typing stops

    + +
      +
    • {{item}}
    • +
    `, + providers: [ WikipediaService ] +}) +export class WikiSmartComponent implements OnInit { + items: Observable; + + constructor (private wikipediaService: WikipediaService) {} + + // #docregion subject + private searchTermStream = new Subject(); + search(term: string) { this.searchTermStream.next(term); } + // #enddocregion subject + + ngOnInit() { + // #docregion observable-operators + this.items = this.searchTermStream + .debounceTime(300) + .distinctUntilChanged() + .switchMap((term: string) => this.wikipediaService.search(term)); + // #enddocregion observable-operators + } +} diff --git a/public/docs/_examples/server-communication/ts/src/app/wiki/wiki.component.ts b/public/docs/_examples/server-communication/ts/src/app/wiki/wiki.component.ts new file mode 100644 index 0000000000..4230df12a1 --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/app/wiki/wiki.component.ts @@ -0,0 +1,26 @@ +// #docregion +import { Component } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; + +import { WikipediaService } from './wikipedia.service'; + +@Component({ + selector: 'my-wiki', + template: ` +

    Wikipedia Demo

    +

    Search after each keystroke

    + +
      +
    • {{item}}
    • +
    `, + providers: [ WikipediaService ] +}) +export class WikiComponent { + items: Observable; + + constructor (private wikipediaService: WikipediaService) { } + + search (term: string) { + this.items = this.wikipediaService.search(term); + } +} diff --git a/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.1.ts b/public/docs/_examples/server-communication/ts/src/app/wiki/wikipedia.service.1.ts similarity index 83% rename from public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.1.ts rename to public/docs/_examples/server-communication/ts/src/app/wiki/wikipedia.service.1.ts index f57bbf06d3..5cbcb7d707 100644 --- a/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.1.ts +++ b/public/docs/_examples/server-communication/ts/src/app/wiki/wikipedia.service.1.ts @@ -3,6 +3,8 @@ import { Injectable } from '@angular/core'; import { Jsonp } from '@angular/http'; +import 'rxjs/add/operator/map'; + @Injectable() export class WikipediaService { constructor(private jsonp: Jsonp) { } @@ -14,11 +16,11 @@ export class WikipediaService { // #docregion query-string let queryString = - `?search=${term}&action=opensearch&format=json&callback=JSONP_CALLBACK` + `?search=${term}&action=opensearch&format=json&callback=JSONP_CALLBACK`; return this.jsonp .get(wikiUrl + queryString) - .map(request => request.json()[1]); + .map(response => response.json()[1]); // #enddocregion query-string } } diff --git a/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.ts b/public/docs/_examples/server-communication/ts/src/app/wiki/wikipedia.service.ts similarity index 81% rename from public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.ts rename to public/docs/_examples/server-communication/ts/src/app/wiki/wikipedia.service.ts index 8bc5747e43..a38167d1c6 100644 --- a/public/docs/_examples/server-communication/ts/app/wiki/wikipedia.service.ts +++ b/public/docs/_examples/server-communication/ts/src/app/wiki/wikipedia.service.ts @@ -2,6 +2,8 @@ import { Injectable } from '@angular/core'; import { Jsonp, URLSearchParams } from '@angular/http'; +import 'rxjs/add/operator/map'; + @Injectable() export class WikipediaService { constructor(private jsonp: Jsonp) {} @@ -12,7 +14,7 @@ export class WikipediaService { // #docregion search-parameters let params = new URLSearchParams(); -params.set('search', term); // the user's search value + params.set('search', term); // the user's search value params.set('action', 'opensearch'); params.set('format', 'json'); params.set('callback', 'JSONP_CALLBACK'); @@ -22,7 +24,7 @@ params.set('search', term); // the user's search value // TODO: Add error handling return this.jsonp .get(wikiUrl, { search: params }) - .map(request => request.json()[1]); + .map(response => response.json()[1]); // #enddocregion call-jsonp } } diff --git a/public/docs/_examples/server-communication/ts/src/index.html b/public/docs/_examples/server-communication/ts/src/index.html new file mode 100644 index 0000000000..5c51f21c91 --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/index.html @@ -0,0 +1,27 @@ + + + + + Angular Http Demo + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/server-communication/ts/src/main.ts b/public/docs/_examples/server-communication/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/server-communication/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/setup/e2e-spec.ts b/public/docs/_examples/setup/e2e-spec.ts new file mode 100644 index 0000000000..73921707ee --- /dev/null +++ b/public/docs/_examples/setup/e2e-spec.ts @@ -0,0 +1,17 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + +describe('QuickStart E2E Tests', function () { + + let expectedMsg = 'Hello Angular'; + + beforeEach(function () { + browser.get(''); + }); + + it(`should display: ${expectedMsg}`, function () { + expect(element(by.css('h1')).getText()).toEqual(expectedMsg); + }); + +}); diff --git a/public/docs/_examples/setup/ts/example-config.json b/public/docs/_examples/setup/ts/example-config.json new file mode 100644 index 0000000000..eb33c943c7 --- /dev/null +++ b/public/docs/_examples/setup/ts/example-config.json @@ -0,0 +1,3 @@ +{ + "unittesting": true +} diff --git a/public/docs/_examples/setup/ts/non-essential-files.txt b/public/docs/_examples/setup/ts/non-essential-files.txt new file mode 100644 index 0000000000..3c9cdde9dc --- /dev/null +++ b/public/docs/_examples/setup/ts/non-essential-files.txt @@ -0,0 +1,13 @@ +.git +.gitignore +.travis.yml +*.spec*.ts +CHANGELOG.md +e2e +favicon.ico +karma.conf.js +karma-test-shim.js +LICENSE +non-essential-files.txt +protractor.config.js +README.md diff --git a/public/docs/_examples/setup/ts/plnkr.json b/public/docs/_examples/setup/ts/plnkr.json new file mode 100644 index 0000000000..22b528eec5 --- /dev/null +++ b/public/docs/_examples/setup/ts/plnkr.json @@ -0,0 +1,13 @@ +{ + "description": "QuickStart Setup", + "basePath": "src/", + "files": [ + "app/app.component.ts", + "app/app.module.ts", + "index.html", + "main.ts", + "styles.css" + ], + "open": "app/app.component.ts", + "tags": ["quickstart", "setup", "seed"] +} diff --git a/public/docs/_examples/setup/ts/quickstart-specs.plnkr.json b/public/docs/_examples/setup/ts/quickstart-specs.plnkr.json new file mode 100644 index 0000000000..a7dfedb595 --- /dev/null +++ b/public/docs/_examples/setup/ts/quickstart-specs.plnkr.json @@ -0,0 +1,13 @@ +{ + "description": "Quickstart AppComponent Testing", + "basePath": "src/", + "files":[ + "browser-test-shim.js", + "app/app.component.ts", + "app/app.component.spec.ts", + "quickstart-specs.html" + ], + "main": "quickstart-specs.html", + "open": "app/app.component.spec.ts", + "tags": ["quickstart", "setup", "testing"] +} diff --git a/public/docs/_examples/setup/ts/src/app/app.component.spec.ts b/public/docs/_examples/setup/ts/src/app/app.component.spec.ts new file mode 100644 index 0000000000..7769024464 --- /dev/null +++ b/public/docs/_examples/setup/ts/src/app/app.component.spec.ts @@ -0,0 +1,33 @@ +import { AppComponent } from './app.component'; + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +describe('AppComponent', function () { + let de: DebugElement; + let comp: AppComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AppComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AppComponent); + comp = fixture.componentInstance; + de = fixture.debugElement.query(By.css('h1')); + }); + + it('should create component', () => expect(comp).toBeDefined() ); + + it('should have expected

    text', () => { + fixture.detectChanges(); + const h1 = de.nativeElement; + expect(h1.innerText).toMatch(/angular/i, + '

    should say something about "Angular"'); + }); +}); diff --git a/public/docs/_examples/setup/ts/src/app/app.component.ts b/public/docs/_examples/setup/ts/src/app/app.component.ts new file mode 100644 index 0000000000..1ef28fc5c4 --- /dev/null +++ b/public/docs/_examples/setup/ts/src/app/app.component.ts @@ -0,0 +1,8 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: `

    Hello {{name}}

    ` +}) +export class AppComponent { name = 'Angular'; } diff --git a/public/docs/_examples/setup/ts/src/app/app.module.ts b/public/docs/_examples/setup/ts/src/app/app.module.ts new file mode 100644 index 0000000000..50a0e6eb47 --- /dev/null +++ b/public/docs/_examples/setup/ts/src/app/app.module.ts @@ -0,0 +1,11 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/setup/ts/src/index.html b/public/docs/_examples/setup/ts/src/index.html new file mode 100644 index 0000000000..58e5112308 --- /dev/null +++ b/public/docs/_examples/setup/ts/src/index.html @@ -0,0 +1,28 @@ + + + + + Angular Quickstart Seed + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/setup/ts/src/main.ts b/public/docs/_examples/setup/ts/src/main.ts new file mode 100644 index 0000000000..02d58dceac --- /dev/null +++ b/public/docs/_examples/setup/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/setup/ts/src/quickstart-specs.html b/public/docs/_examples/setup/ts/src/quickstart-specs.html new file mode 100644 index 0000000000..9bc81ccf2e --- /dev/null +++ b/public/docs/_examples/setup/ts/src/quickstart-specs.html @@ -0,0 +1,41 @@ + + + + + + + 1st Specs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/setup/ts/src/systemjs.config.extras.js b/public/docs/_examples/setup/ts/src/systemjs.config.extras.js new file mode 100644 index 0000000000..027dfe58cf --- /dev/null +++ b/public/docs/_examples/setup/ts/src/systemjs.config.extras.js @@ -0,0 +1,11 @@ +/** + * Add barrels and stuff + * Adjust as necessary for your application needs. + */ +// (function (global) { +// System.config({ +// packages: { +// // add packages here +// } +// }); +// })(this); diff --git a/public/docs/_examples/structural-directives/dart/lib/heavy_loader_component.dart b/public/docs/_examples/structural-directives/dart/lib/heavy_loader_component.dart deleted file mode 100644 index a2efd3b2f1..0000000000 --- a/public/docs/_examples/structural-directives/dart/lib/heavy_loader_component.dart +++ /dev/null @@ -1,32 +0,0 @@ -// #docregion -import 'dart:async'; - -import 'package:angular2/core.dart'; - -int nextId = 1; - -@Component( - selector: 'heavy-loader', - template: 'heavy loader #{{id}} on duty!') -class HeavyLoaderComponent implements OnInit, OnDestroy { - int id = nextId++; - @Input() List logs; - - // Mock todo: get 10,000 rows of data from the server - ngOnInit() => _log( - "heavy-loader $id initialized, loading 10,000 rows of data from the server"); - - // Mock todo: clean-up - ngOnDestroy() => _log("heavy-loader $id destroyed, cleaning up"); - - _log(String msg) { - logs.add(msg); - _tick(); - } - - /// Triggers the next round of Angular change detection - /// after one turn of the browser event loop - /// ensuring display of msg added in onDestroy - _tick() => new Future(() {}); -} -// #enddocregion diff --git a/public/docs/_examples/structural-directives/dart/lib/structural_directives_component.dart b/public/docs/_examples/structural-directives/dart/lib/structural_directives_component.dart deleted file mode 100644 index 901c8b18b1..0000000000 --- a/public/docs/_examples/structural-directives/dart/lib/structural_directives_component.dart +++ /dev/null @@ -1,21 +0,0 @@ -// #docplaster -// #docregion -import 'package:angular2/core.dart'; - -import 'heavy_loader_component.dart'; -import 'unless_directive.dart'; - -@Component( - selector: 'structural-directives', - templateUrl: 'structural_directives_component.html', - styles: const ['button { min-width: 100px; }'], - directives: const [UnlessDirective, HeavyLoaderComponent]) -class StructuralDirectivesComponent { - List heroes = ['Mr. Nice', 'Narco', 'Bombasto']; - bool condition = true; - bool isVisible = true; - List logs = []; - String status = 'ready'; - - get hero => heroes[0]; -} diff --git a/public/docs/_examples/structural-directives/dart/lib/structural_directives_component.html b/public/docs/_examples/structural-directives/dart/lib/structural_directives_component.html deleted file mode 100644 index 7ad7cf2247..0000000000 --- a/public/docs/_examples/structural-directives/dart/lib/structural_directives_component.html +++ /dev/null @@ -1,108 +0,0 @@ - - -

    Structural Directives

    - - - -
    {{hero}}
    -
    {{hero}}
    - - -
    - - - -
    - - - -
    - - - - -

    - condition is true and ngIf is true. -

    -

    - condition is false and ngIf is false. -

    - - -

    - condition is false and myUnless is true. -

    - -

    - condition is true and myUnless is false. -

    - - -
    - - -
    - - -
    - -
    - - -
    - -

    heavy-loader log:

    -
    {{message}}
    - - -
    - - -

    - Hip! -

    - -

    - Hooray! -

    - - -
    - - - - -

    - Our heroes are true! -

    - - - - - -
    - - - - - -
    {{ hero }}
    - - - - diff --git a/public/docs/_examples/structural-directives/dart/lib/unless_directive.dart b/public/docs/_examples/structural-directives/dart/lib/unless_directive.dart deleted file mode 100644 index 907e0edd15..0000000000 --- a/public/docs/_examples/structural-directives/dart/lib/unless_directive.dart +++ /dev/null @@ -1,31 +0,0 @@ -// #docplaster -// #docregion -// #docregion unless-declaration -import 'package:angular2/core.dart'; -// #enddocregion unless-declaration - -// #docregion unless-declaration -@Directive(selector: '[myUnless]') -class UnlessDirective { - // #enddocregion unless-declaration - - // #docregion unless-constructor - TemplateRef _templateRef; - ViewContainerRef _viewContainer; - - UnlessDirective(this._templateRef, this._viewContainer); - // #enddocregion unless-constructor - - // #docregion unless-set - @Input() - set myUnless(bool condition) { - if (!condition) { - _viewContainer.createEmbeddedView(_templateRef); - } else { - _viewContainer.clear(); - } - } - // #enddocregion unless-set - // #docregion unless-declaration -} -// #enddocregion unless-declaration diff --git a/public/docs/_examples/structural-directives/dart/pubspec.yaml b/public/docs/_examples/structural-directives/dart/pubspec.yaml deleted file mode 100644 index 70e2e63855..0000000000 --- a/public/docs/_examples/structural-directives/dart/pubspec.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# #docregion -name: structural_directives -description: Structural directives example -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: 'package:angular2/common.dart#CORE_DIRECTIVES' - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/structural-directives/dart/web/index.html b/public/docs/_examples/structural-directives/dart/web/index.html deleted file mode 100644 index 38da87dc69..0000000000 --- a/public/docs/_examples/structural-directives/dart/web/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - Angular 2 Structural Directives - - - - - - - Loading... - - - diff --git a/public/docs/_examples/structural-directives/dart/web/main.dart b/public/docs/_examples/structural-directives/dart/web/main.dart deleted file mode 100644 index f26456b187..0000000000 --- a/public/docs/_examples/structural-directives/dart/web/main.dart +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -import 'package:angular2/platform/browser.dart'; - -import 'package:structural_directives/structural_directives_component.dart'; - -main() { - bootstrap(StructuralDirectivesComponent); -} diff --git a/public/docs/_examples/structural-directives/e2e-spec.ts b/public/docs/_examples/structural-directives/e2e-spec.ts index 607990a68b..51f30bf0bb 100644 --- a/public/docs/_examples/structural-directives/e2e-spec.ts +++ b/public/docs/_examples/structural-directives/e2e-spec.ts @@ -1,65 +1,58 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Structural Directives', function () { - // tests interact - so we need beforeEach instead of beforeAll - beforeEach(function () { + beforeAll(function () { browser.get(''); }); - it('should be able to use ngFor, ngIf and ngWhen together', function () { - let allDivEles = element.all(by.css('structural-directives > div')); - expect(allDivEles.get(0).getText()).toEqual('Mr. Nice'); - expect(allDivEles.get(1).getText()).toEqual('Mr. Nice'); - expect(allDivEles.get(4).getText()).toEqual('Ready'); + it('first div should show hero name with *ngIf', function () { + const allDivs = element.all(by.tagName('div')); + expect(allDivs.get(0).getText()).toEqual('Mr. Nice'); }); - it('should be able to toggle ngIf with a button', function () { - let setConditionButtonEle = element.all(by.css('button')).get(0); - let conditionTrueEles = element.all(by.cssContainingText('p', 'condition is true')); - let conditionFalseEles = element.all(by.cssContainingText('p', 'condition is false')); - expect(conditionTrueEles.count()).toBe(2, 'should be two condition true elements'); - expect(conditionFalseEles.count()).toBe(0, 'should be no condition false elements'); - setConditionButtonEle.click().then(function() { - expect(conditionTrueEles.count()).toBe(0, 'should be no condition true elements'); - expect(conditionFalseEles.count()).toBe(2, 'should be two condition false elements'); - }); + it('first li should show hero name with *ngFor', function () { + const allLis = element.all(by.tagName('li')); + expect(allLis.get(0).getText()).toEqual('Mr. Nice'); }); - it('should be able to compare use of ngIf with changing css visibility', function () { - let setConditionButtonEle = element.all(by.css('button')).get(0); - let ngIfButtonEle = element(by.cssContainingText('button', 'if | !if')); - let ngIfParentEle = ngIfButtonEle.element(by.xpath('..')); - let ngIfSiblingEle = ngIfParentEle.element(by.css('heavy-loader')); - let cssButtonEle = element(by.cssContainingText('button', 'show | hide')); - let cssSiblingEle = cssButtonEle.element(by.xpath('..')).element(by.css('heavy-loader')); - let setConditionText: string; - setConditionButtonEle.getText().then(function(text) { - setConditionText = text; - expect(ngIfButtonEle.isPresent()).toBe(true, 'should be able to find ngIfButton'); - expect(cssButtonEle.isPresent()).toBe(true, 'should be able to find cssButton'); - expect(ngIfParentEle.isPresent()).toBe(true, 'should be able to find ngIfButton parent'); - expect(ngIfSiblingEle.isPresent()).toBe(true, 'should be able to find ngIfButton sibling'); - expect(cssSiblingEle.isPresent()).toBe(true, 'should be able to find cssButton sibling'); - return ngIfButtonEle.click(); - }).then(function() { - expect(ngIfSiblingEle.isPresent()).toBe(false, 'now should NOT be able to find ngIfButton sibling'); - expect(setConditionButtonEle.getText()).not.toEqual(setConditionText); - return cssButtonEle.click(); - }).then(function() { - expect(cssSiblingEle.isPresent()).toBe(true, 'now should still be able to find cssButton sibling'); - expect(cssSiblingEle.isDisplayed()).toBe(false, 'now cssButton sibling should NOT be visible'); - return ngIfButtonEle.click(); - }).then(function() { - expect(setConditionButtonEle.getText()).toEqual(setConditionText); + it('ngSwitch have three instances', function () { + const happyHeroEls = element.all(by.tagName('happy-hero')); + expect(happyHeroEls.count()).toEqual(3); + }); + + it('should toggle *ngIf="hero" with a button', function () { + const toggleHeroButton = element.all(by.cssContainingText('button', 'Toggle hero')).get(0); + const paragraph = element.all(by.cssContainingText('p', 'I turned the corner')); + expect(paragraph.get(0).getText()).toContain('I waved'); + toggleHeroButton.click().then(() => { + expect(paragraph.get(0).getText()).not.toContain('I waved'); }); }); - it('should be able to use *ngIf ', function () { - let setConditionButtonEle = element.all(by.css('button')).get(0); - let displayEles = element.all(by.cssContainingText('p', 'Our heroes are true!')); - expect(displayEles.count()).toBe(2, "should be displaying two ngIf elements"); - setConditionButtonEle.click().then(function() { - expect(displayEles.count()).toBe(0, "should nog longer be displaying ngIf elements"); + it('should have only one "Hip!" (the other is erased)', function () { + const paragraph = element.all(by.cssContainingText('p', 'Hip!')); + expect(paragraph.count()).toEqual(1); + }); + + it('myUnless should show 3 paragraph (A)s and (B)s at the start', function () { + const paragraph = element.all(by.css('p.unless')); + expect(paragraph.count()).toEqual(3); + for (let i = 0; i < 3; i++) { + expect(paragraph.get(i).getText()).toContain('(A)'); + } + }); + + it('myUnless should show 1 paragraph (B) after toggling condition', function () { + const toggleConditionButton = element.all(by.cssContainingText('button', 'Toggle condition')).get(0); + const paragraph = element.all(by.css('p.unless')); + + toggleConditionButton.click().then(() => { + expect(paragraph.count()).toEqual(1); + expect(paragraph.get(0).getText()).toContain('(B)'); }); }); }); + diff --git a/public/docs/_examples/structural-directives/ts/app/heavy-loader.component.ts b/public/docs/_examples/structural-directives/ts/app/heavy-loader.component.ts deleted file mode 100644 index 8272048b96..0000000000 --- a/public/docs/_examples/structural-directives/ts/app/heavy-loader.component.ts +++ /dev/null @@ -1,35 +0,0 @@ -// #docregion -import { Component, Input, Output } from '@angular/core'; - -let nextId = 1; - -@Component({ - selector: 'heavy-loader', - template: 'heavy loader #{{id}} on duty!' -}) -export class HeavyLoaderComponent { - id = nextId++; - @Input() logs: string[]; - - ngOnInit() { - // Mock todo: get 10,000 rows of data from the server - this.log(`heavy-loader ${this.id} initialized, - loading 10,000 rows of data from the server`); - } - - ngOnDestroy() { - // Mock todo: clean-up - this.log(`heavy-loader ${this.id} destroyed, cleaning up`); - } - - private log(msg: string) { - this.logs.push(msg); - this.tick(); - } - - // Triggers the next round of Angular change detection - // after one turn of the browser event loop - // ensuring display of msg added in onDestroy - private tick() { setTimeout(() => { }, 0); } -} -// #enddocregion diff --git a/public/docs/_examples/structural-directives/ts/app/main.ts b/public/docs/_examples/structural-directives/ts/app/main.ts deleted file mode 100644 index 5f5b5aeb19..0000000000 --- a/public/docs/_examples/structural-directives/ts/app/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { StructuralDirectivesComponent } from './structural-directives.component'; - -bootstrap(StructuralDirectivesComponent); diff --git a/public/docs/_examples/structural-directives/ts/app/structural-directives.component.html b/public/docs/_examples/structural-directives/ts/app/structural-directives.component.html deleted file mode 100644 index 3599c77271..0000000000 --- a/public/docs/_examples/structural-directives/ts/app/structural-directives.component.html +++ /dev/null @@ -1,109 +0,0 @@ - - -

    Structural Directives

    - - - -
    {{hero}}
    -
    {{hero}}
    - - -
    - - - -
    - - - -
    - - - - -

    - condition is true and ngIf is true. -

    -

    - condition is false and ngIf is false. -

    - - -

    - condition is false and myUnless is true. -

    - -

    - condition is true and myUnless is false. -

    - - -
    - - -
    - - -
    - -
    - - -
    - -

    heavy-loader log:

    -
    {{message}}
    - - -
    - - -

    - Hip! -

    - -

    - Hooray! -

    - - -
    - - - - -

    - Our heroes are true! -

    - - - - - -
    - - - - - -
    {{ hero }}
    - - - - - diff --git a/public/docs/_examples/structural-directives/ts/app/structural-directives.component.ts b/public/docs/_examples/structural-directives/ts/app/structural-directives.component.ts deleted file mode 100644 index 4620905568..0000000000 --- a/public/docs/_examples/structural-directives/ts/app/structural-directives.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -// #docplaster -// #docregion -import { Component, Input, Output } from '@angular/core'; -import { UnlessDirective } from './unless.directive'; -import { HeavyLoaderComponent } from './heavy-loader.component'; - -@Component({ - selector: 'structural-directives', - templateUrl: 'app/structural-directives.component.html', - styles: ['button { min-width: 100px; }'], - directives: [UnlessDirective, HeavyLoaderComponent] -}) -export class StructuralDirectivesComponent { - heroes = ['Mr. Nice', 'Narco', 'Bombasto']; - hero = this.heroes[0]; - condition = true; - isVisible = true; - logs: string[] = []; - status = 'ready'; -} -//#enddocregion diff --git a/public/docs/_examples/structural-directives/ts/app/unless.directive.ts b/public/docs/_examples/structural-directives/ts/app/unless.directive.ts deleted file mode 100644 index 105fdde4ae..0000000000 --- a/public/docs/_examples/structural-directives/ts/app/unless.directive.ts +++ /dev/null @@ -1,33 +0,0 @@ -// #docplaster -// #docregion -// #docregion unless-declaration -import { Directive, Input } from '@angular/core'; - -// #enddocregion unless-declaration -import { TemplateRef, ViewContainerRef } from '@angular/core'; - -// #docregion unless-declaration -@Directive({ selector: '[myUnless]' }) -export class UnlessDirective { - // #enddocregion unless-declaration - - // #docregion unless-constructor - constructor( - private templateRef: TemplateRef, - private viewContainer: ViewContainerRef - ) { } - // #enddocregion unless-constructor - - // #docregion unless-set - @Input() set myUnless(condition: boolean) { - if (!condition) { - this.viewContainer.createEmbeddedView(this.templateRef); - } else { - this.viewContainer.clear(); - } - } - // #enddocregion unless-set - // #docregion unless-declaration -} -// #enddocregion unless-declaration -// #enddocregion diff --git a/public/docs/_examples/structural-directives/ts/index.html b/public/docs/_examples/structural-directives/ts/index.html deleted file mode 100644 index da815d8e69..0000000000 --- a/public/docs/_examples/structural-directives/ts/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - Angular 2 Structural Directives - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/structural-directives/ts/plnkr.json b/public/docs/_examples/structural-directives/ts/plnkr.json index 32bfd6302a..58a26d7b4f 100644 --- a/public/docs/_examples/structural-directives/ts/plnkr.json +++ b/public/docs/_examples/structural-directives/ts/plnkr.json @@ -1,6 +1,11 @@ { "description": "Structural directives", - "files": ["!**/*.d.ts", "!**/*.js"], + "basePath": "src/", + "files": [ + "!**/*.d.ts", + "!**/*.js", + "!app/scrap.txt" + ], "tags": [ "structural", "directives", "template", "ngIf", "ngSwitch", "ngFor" diff --git a/public/docs/_examples/structural-directives/ts/src/app/app.component.css b/public/docs/_examples/structural-directives/ts/src/app/app.component.css new file mode 100644 index 0000000000..e28be894f8 --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/src/app/app.component.css @@ -0,0 +1,70 @@ +/* #docregion */ +button { + min-width: 100px; + font-size: 100%; +} + +.box { + border: 1px solid gray; + max-width: 600px; + padding: 4px; +} +.choices { + font-style: italic; +} + +code, .code { + background-color: #eee; + color: black; + font-family: Courier, sans-serif; + font-size: 85%; +} + +div.code { + width: 400px; +} + +.heroic { + font-size: 150%; + font-weight: bold; +} + +hr { + margin: 40px 0 +} + +.odd { + background-color: palegoldenrod; +} + +td, th { + text-align: left; + vertical-align: top; +} + +/* #docregion p-span */ +p span { color: red; font-size: 70%; } +/* #enddocregion p-span */ + +.unless { + border: 2px solid; + padding: 6px; +} + +p.unless { + width: 500px; +} + +button.a, span.a, .unless.a { + color: red; + border-color: gold; + background-color: yellow; + font-size: 100%; +} + +button.b, span.b, .unless.b { + color: black; + border-color: green; + background-color: lightgreen; + font-size: 100%; +} diff --git a/public/docs/_examples/structural-directives/ts/src/app/app.component.html b/public/docs/_examples/structural-directives/ts/src/app/app.component.html new file mode 100644 index 0000000000..49c4928aad --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/src/app/app.component.html @@ -0,0 +1,250 @@ + + +

    Structural Directives

    + +

    Conditional display of hero

    + +
    + +
    {{hero.name}}
    + +
    + +

    List of heroes

    + + +
      + +
    • {{hero.name}}
    • + +
    + + + +
    + +

    NgIf

    + + +

    + Expression is true and ngIf is true. + This paragraph is in the DOM. +

    +

    + Expression is false and ngIf is false. + This paragraph is not in the DOM. +

    + + + +

    + Expression sets display to "block". + This paragraph is visible. +

    +

    + Expression sets display to "none". + This paragraph is hidden but still in the DOM. +

    + + +

    NgIf with template

    +

    <ng-template> element

    + + +
    {{hero.name}}
    +
    + + +

    template attribute

    + +
    {{hero.name}}
    + + +
    + +

    <ng-container>

    + +

    *ngIf with a <ng-container>

    + + + + +

    + I turned the corner + + and saw {{hero.name}}. I waved + + and continued on my way. +

    + + +

    + I turned the corner + + and saw {{hero.name}}. I waved + + and continued on my way. +

    + + +

    <select> with <span>

    + +
    + Pick your favorite hero + () +
    + + + +

    <select> with <ng-container>

    + +
    + Pick your favorite hero + () +
    + + +

    + +
    + +

    NgFor

    + +
    + +

    <div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd">

    + +
    + ({{i}}) {{hero.name}} +
    + + +

    <div template="ngFor let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd">

    + +
    + ({{i}}) {{hero.name}} +
    + + +

    <template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById">

    + + +
    ({{i}}) {{hero.name}}
    +
    + + +
    +
    + +

    NgSwitch

    + +
    Pick your favorite hero
    +

    + + +

    + +

    NgSwitch

    + + +
    + + + + +
    + + +

    NgSwitch with template attribute

    + +
    + + + + +
    + + +

    NgSwitch with <ng-template>

    + +
    + + + + + + + + + + + + +
    + + +
    + +

    <template>

    + +

    Hip!

    + +

    Hip!

    +
    +

    Hooray!

    + + +
    + +

    UnlessDirective

    +

    + The condition is currently + {{condition}}. + +

    + +

    + (A) This paragraph is displayed because the condition is false. +

    + +

    + (B) Although the condition is true, + this paragraph is displayed because myUnless is set to false. +

    + + + +

    UnlessDirective with template

    + + +

    Show this sentence unless the condition is true.

    + + +

    + (A) <p template="myUnless condition" class="code unless"> +

    + + +

    + (A) <template [myUnless]="condition"> +

    +
    + diff --git a/public/docs/_examples/structural-directives/ts/src/app/app.component.ts b/public/docs/_examples/structural-directives/ts/src/app/app.component.ts new file mode 100644 index 0000000000..ff6f0e65a1 --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/src/app/app.component.ts @@ -0,0 +1,23 @@ +// #docregion +import { Component } from '@angular/core'; + +import { Hero, heroes } from './hero'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html', + styleUrls: [ './app.component.css' ] +}) +export class AppComponent { + heroes = heroes; + hero = this.heroes[0]; + + condition = false; + logs: string[] = []; + showSad = true; + status = 'ready'; + + // #docregion trackByHero + trackById(index: number, hero: Hero): number { return hero.id; } + // #enddocregion trackByHero +} diff --git a/public/docs/_examples/structural-directives/ts/src/app/app.module.ts b/public/docs/_examples/structural-directives/ts/src/app/app.module.ts new file mode 100644 index 0000000000..b6ffb456c9 --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/src/app/app.module.ts @@ -0,0 +1,19 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { heroSwitchComponents } from './hero-switch.components'; +import { UnlessDirective } from './unless.directive'; + +@NgModule({ + imports: [ BrowserModule, FormsModule ], + declarations: [ + AppComponent, + heroSwitchComponents, + UnlessDirective + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/structural-directives/ts/src/app/hero-switch.components.ts b/public/docs/_examples/structural-directives/ts/src/app/hero-switch.components.ts new file mode 100644 index 0000000000..6608422d15 --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/src/app/hero-switch.components.ts @@ -0,0 +1,43 @@ +// #docregion +import { Component, Input } from '@angular/core'; +import { Hero } from './hero'; + +@Component({ + selector: 'happy-hero', + template: `Wow. You like {{hero.name}}. What a happy hero ... just like you.` +}) +export class HappyHeroComponent { + @Input() hero: Hero; +} + +@Component({ + selector: 'sad-hero', + template: `You like {{hero.name}}? Such a sad hero. Are you sad too?` +}) +export class SadHeroComponent { + @Input() hero: Hero; +} + +@Component({ + selector: 'confused-hero', + template: `Are you as confused as {{hero.name}}?` +}) +export class ConfusedHeroComponent { + @Input() hero: Hero; +} + +@Component({ + selector: 'unknown-hero', + template: `{{message}}` +}) +export class UnknownHeroComponent { + @Input() hero: Hero; + get message() { + return this.hero && this.hero.name ? + `${this.hero.name} is strange and mysterious.` : + 'Are you feeling indecisive?'; + } +} + +export const heroSwitchComponents = + [ HappyHeroComponent, SadHeroComponent, ConfusedHeroComponent, UnknownHeroComponent ]; diff --git a/public/docs/_examples/structural-directives/ts/src/app/hero.ts b/public/docs/_examples/structural-directives/ts/src/app/hero.ts new file mode 100644 index 0000000000..a1de3b3b82 --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/src/app/hero.ts @@ -0,0 +1,13 @@ +// #docregion +export class Hero { + id: number; + name: string; + emotion?: string; +} + +export const heroes: Hero[] = [ + { id: 1, name: 'Mr. Nice', emotion: 'happy'}, + { id: 2, name: 'Narco', emotion: 'sad' }, + { id: 3, name: 'Windstorm', emotion: 'confused' }, + { id: 4, name: 'Magneta'} +]; diff --git a/public/docs/_examples/structural-directives/ts/src/app/scrap.txt b/public/docs/_examples/structural-directives/ts/src/app/scrap.txt new file mode 100644 index 0000000000..96426d37f0 --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/src/app/scrap.txt @@ -0,0 +1,21 @@ +// interesting but unused code + heroChooser(picker: HTMLFieldSetElement) { + let choices = picker.children; + this.favoriteHero = undefined; + for (let i = 0; i < choices.length; i++) { + let choice = choices[i].children[0] as HTMLInputElement; + if (choice.checked) { this.favoriteHero = this.heroes[i]; } + } + } + + +

    Switch with *ngFor repeated switchCases using <ng-container>

    + +
    + Your favorite hero is ... + + {{hero.name}} + + None of the above +
    + diff --git a/public/docs/_examples/structural-directives/ts/src/app/unless.directive.ts b/public/docs/_examples/structural-directives/ts/src/app/unless.directive.ts new file mode 100644 index 0000000000..470bbd932f --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/src/app/unless.directive.ts @@ -0,0 +1,51 @@ +// #docplaster +// #docregion +// #docregion no-docs, skeleton +import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; + +// #enddocregion skeleton +/** + * Add the template content to the DOM unless the condition is true. +// #enddocregion no-docs + * + * If the expression assigned to `myUnless` evaluates to a truthy value + * then the templated elements are removed removed from the DOM, + * the templated elements are (re)inserted into the DOM. + * + *
    + * Congrats! Everything is great! + *
    + * + * ### Syntax + * + * - `
    ...
    ` + * - `
    ...
    ` + * - `` + * +// #docregion no-docs + */ +// #docregion skeleton +@Directive({ selector: '[myUnless]'}) +export class UnlessDirective { + // #enddocregion skeleton + private hasView = false; + + // #docregion ctor + constructor( + private templateRef: TemplateRef, + private viewContainer: ViewContainerRef) { } + // #enddocregion ctor + + // #docregion set + @Input() set myUnless(condition: boolean) { + if (!condition && !this.hasView) { + this.viewContainer.createEmbeddedView(this.templateRef); + this.hasView = true; + } else if (condition && this.hasView) { + this.viewContainer.clear(); + this.hasView = false; + } + } + // #enddocregion set + // #docregion skeleton +} diff --git a/public/docs/_examples/structural-directives/ts/src/index.html b/public/docs/_examples/structural-directives/ts/src/index.html new file mode 100644 index 0000000000..ce7a33266d --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/src/index.html @@ -0,0 +1,27 @@ + + + + + Angular Structural Directives + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/structural-directives/ts/src/main.ts b/public/docs/_examples/structural-directives/ts/src/main.ts new file mode 100644 index 0000000000..105b06712d --- /dev/null +++ b/public/docs/_examples/structural-directives/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); + diff --git a/public/docs/_examples/style-guide/e2e-spec.ts b/public/docs/_examples/style-guide/e2e-spec.ts index 1a64dd1598..d143ae5573 100644 --- a/public/docs/_examples/style-guide/e2e-spec.ts +++ b/public/docs/_examples/style-guide/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Style Guide', function () { it('01-01', function () { browser.get('#/01-01'); @@ -56,19 +59,6 @@ describe('Style Guide', function () { expect(buttons.get(1).getText()).toBe('Hide toast'); }); - it('03-05', function () { - browser.get('#/03-05'); - - let div = element(by.tagName('sg-app > div')); - expect(div.getText()).toBe('Actual favorite: Windstorm'); - - let lis = element.all(by.tagName('sg-app > ul > li')); - expect(lis.get(0).getText()).toBe('Windstorm'); - expect(lis.get(1).getText()).toBe('Bombasto'); - expect(lis.get(2).getText()).toBe('Magneta'); - expect(lis.get(3).getText()).toBe('Tornado'); - }); - it('03-06', function () { browser.get('#/03-06'); @@ -89,13 +79,6 @@ describe('Style Guide', function () { expect(div.getText()).toBe('This is heroes component'); }); - it('04-14', function () { - browser.get('#/04-14'); - - let h2 = element(by.tagName('sg-app > toh-heroes > div > h2')); - expect(h2.getText()).toBe('My Heroes'); - }); - it('05-02', function () { browser.get('#/05-02'); diff --git a/public/docs/_examples/style-guide/ts/01-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/01-01/app/app.component.ts deleted file mode 100644 index 67ae0213be..0000000000 --- a/public/docs/_examples/style-guide/ts/01-01/app/app.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { HeroesComponent, HeroService } from './heroes'; - -@Component({ - moduleId: module.id, - selector: 'toh-app', - template: ` - - `, - styleUrls: ['app.component.css'], - directives: [HeroesComponent], - providers: [HeroService] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/01-01/app/heroes/hero.component.avoid.ts b/public/docs/_examples/style-guide/ts/01-01/app/heroes/hero.component.avoid.ts deleted file mode 100644 index e19934c4d2..0000000000 --- a/public/docs/_examples/style-guide/ts/01-01/app/heroes/hero.component.avoid.ts +++ /dev/null @@ -1,40 +0,0 @@ -// #docregion -/* avoid */ - -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { Component, OnInit } from '@angular/core'; - -class Hero { - id: number; - name: string; -} - -@Component({ - selector: 'my-app', - template: ` -

    {{title}}

    -
    {{heroes | json}}
    - `, - styleUrls: ['app/app.component.css'] -}) -class AppComponent implements OnInit { - title = 'Tour of Heroes'; - - heroes: Hero[] = []; - - ngOnInit() { - getHeroes().then(heroes => this.heroes = heroes); - } -} - -bootstrap(AppComponent, []); - -const HEROES: Hero[] = [ - {id: 1, name: 'Bombasto'}, - {id: 2, name: 'Tornado'}, - {id: 3, name: 'Magneta'}, -]; - -function getHeroes(): Promise { - return Promise.resolve(HEROES); // TODO: get hero data from the server; -} diff --git a/public/docs/_examples/style-guide/ts/01-01/app/index.ts b/public/docs/_examples/style-guide/ts/01-01/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/01-01/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/01-01/main.ts b/public/docs/_examples/style-guide/ts/01-01/main.ts deleted file mode 100644 index 6b97e81a59..0000000000 --- a/public/docs/_examples/style-guide/ts/01-01/main.ts +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app/app.component'; - -bootstrap(AppComponent, []); diff --git a/public/docs/_examples/style-guide/ts/02-07/app/app.component.ts b/public/docs/_examples/style-guide/ts/02-07/app/app.component.ts deleted file mode 100644 index 9e4bb0b8c5..0000000000 --- a/public/docs/_examples/style-guide/ts/02-07/app/app.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroComponent } from './heroes'; -import { UsersComponent } from './users'; - -@Component({ - selector: 'sg-app', - template: ` - - - `, - directives: [HeroComponent, UsersComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/02-07/app/index.ts b/public/docs/_examples/style-guide/ts/02-07/app/index.ts deleted file mode 100644 index c6b22b0506..0000000000 --- a/public/docs/_examples/style-guide/ts/02-07/app/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './heroes'; -export * from './users'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/02-08/app/app.component.ts b/public/docs/_examples/style-guide/ts/02-08/app/app.component.ts deleted file mode 100644 index 29b3ed7062..0000000000 --- a/public/docs/_examples/style-guide/ts/02-08/app/app.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; - -import { ValidateDirective } from './shared'; - -@Component({ - selector: 'sg-app', - template: '', - directives: [ValidateDirective] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/02-08/app/index.ts b/public/docs/_examples/style-guide/ts/02-08/app/index.ts deleted file mode 100644 index d5721a3934..0000000000 --- a/public/docs/_examples/style-guide/ts/02-08/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/02-08/app/shared/index.ts b/public/docs/_examples/style-guide/ts/02-08/app/shared/index.ts deleted file mode 100644 index 2534dc7b6d..0000000000 --- a/public/docs/_examples/style-guide/ts/02-08/app/shared/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './validate.directive'; diff --git a/public/docs/_examples/style-guide/ts/03-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-01/app/app.component.ts deleted file mode 100644 index 20bedca7d5..0000000000 --- a/public/docs/_examples/style-guide/ts/03-01/app/app.component.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { ExceptionService } from './shared'; - -@Component({ - selector: 'sg-app', - template: '
    The expected error is {{errorCode}}
    ', - providers: [ExceptionService] -}) -export class AppComponent implements OnInit { - errorCode: number; - - constructor(private exceptionService: ExceptionService) { } - - ngOnInit() { - this.errorCode = this.exceptionService.getException(); - } -} diff --git a/public/docs/_examples/style-guide/ts/03-01/app/index.ts b/public/docs/_examples/style-guide/ts/03-01/app/index.ts deleted file mode 100644 index d5721a3934..0000000000 --- a/public/docs/_examples/style-guide/ts/03-01/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/03-02/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-02/app/app.component.ts deleted file mode 100644 index 15ccb3c351..0000000000 --- a/public/docs/_examples/style-guide/ts/03-02/app/app.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component } from '@angular/core'; - -import { HEROES_URL, VILLAINS_URL } from './shared'; - -@Component({ - selector: 'sg-app', - template: ` -
    Heroes url: {{heroesUrl}}
    -
    Villains url: {{villainsUrl}}
    - `, -}) -export class AppComponent { - heroesUrl = HEROES_URL; - villainsUrl = VILLAINS_URL; -} diff --git a/public/docs/_examples/style-guide/ts/03-02/app/index.ts b/public/docs/_examples/style-guide/ts/03-02/app/index.ts deleted file mode 100644 index d5721a3934..0000000000 --- a/public/docs/_examples/style-guide/ts/03-02/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/03-02/app/shared/data.service.avoid.ts b/public/docs/_examples/style-guide/ts/03-02/app/shared/data.service.avoid.ts deleted file mode 100644 index 49d5cb0d35..0000000000 --- a/public/docs/_examples/style-guide/ts/03-02/app/shared/data.service.avoid.ts +++ /dev/null @@ -1,7 +0,0 @@ -// #docregion -// #docregion example -/* avoid */ - -export const heroesUrl = 'api/heroes'; -export const villainsUrl = 'api/villains'; -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/03-02/app/shared/data.service.ts b/public/docs/_examples/style-guide/ts/03-02/app/shared/data.service.ts deleted file mode 100644 index ad665a99c2..0000000000 --- a/public/docs/_examples/style-guide/ts/03-02/app/shared/data.service.ts +++ /dev/null @@ -1,5 +0,0 @@ -// #docregion -// #docregion example -export const HEROES_URL = 'api/heroes'; -export const VILLAINS_URL = 'api/villains'; -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/03-03/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-03/app/app.component.ts deleted file mode 100644 index 2bab2c3c47..0000000000 --- a/public/docs/_examples/style-guide/ts/03-03/app/app.component.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { Hero, HeroCollectorService } from './shared'; - -@Component({ - selector: 'sg-app', - template: '
    Our hero is {{hero.name}} and {{hero.power}}
    ', - providers: [HeroCollectorService] -}) -export class AppComponent implements OnInit { - hero: Hero; - - constructor(private heroCollectorService: HeroCollectorService) { } - - ngOnInit() { - this.hero = this.heroCollectorService.getHero(); - } -} diff --git a/public/docs/_examples/style-guide/ts/03-03/app/index.ts b/public/docs/_examples/style-guide/ts/03-03/app/index.ts deleted file mode 100644 index d5721a3934..0000000000 --- a/public/docs/_examples/style-guide/ts/03-03/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/03-04/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-04/app/app.component.ts deleted file mode 100644 index d7da5134bc..0000000000 --- a/public/docs/_examples/style-guide/ts/03-04/app/app.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { ToastService } from './shared'; - -@Component({ - selector: 'sg-app', - template: ` - - - `, - providers: [ToastService] -}) -export class AppComponent implements OnInit { - constructor(private toastService: ToastService) { } - - hide() { - this.toastService.hide(); - } - - show() { - this.toastService.show(); - } - - ngOnInit() { - this.toastService.activate('Hello style-guide!'); - } -} diff --git a/public/docs/_examples/style-guide/ts/03-04/app/index.ts b/public/docs/_examples/style-guide/ts/03-04/app/index.ts deleted file mode 100644 index d5721a3934..0000000000 --- a/public/docs/_examples/style-guide/ts/03-04/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.avoid.ts b/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.avoid.ts deleted file mode 100644 index cff95fd096..0000000000 --- a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.avoid.ts +++ /dev/null @@ -1,33 +0,0 @@ -// #docregion -// #docregion example -/* avoid */ - -import {Injectable} from '@angular/core'; -import {Http, Response} from '@angular/http'; - -import {Hero} from './hero.model'; -import {ExceptionService, SpinnerService, ToastService} from '../../shared'; -// #enddocregion example - -@Injectable() -export class HeroService { - - constructor( - private exceptionService: ExceptionService, - private spinnerService: SpinnerService, - private toastService: ToastService, - private http: Http - ) { } - - getHero(id: number) { - return this.http.get(`api/heroes/${id}`) - .map((res: Response) => res.json().data); - } - - getHeroes() { - return this.http.get(`api/heroes`) - .map((res: Response) => res.json().data); - } - -} - diff --git a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.ts deleted file mode 100644 index 85fa486432..0000000000 --- a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.service.ts +++ /dev/null @@ -1,32 +0,0 @@ -// #docregion -// #docregion example -import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; - -import { Hero } from './hero.model'; -import { ExceptionService, SpinnerService, ToastService } from '../../shared'; -// #enddocregion example - -@Injectable() -export class HeroService { - cachedHeroes: Hero[]; - - constructor( - private exceptionService: ExceptionService, - private spinnerService: SpinnerService, - private toastService: ToastService, - private http: Http - ) { } - - getHero(id: number) { - return this.http.get(`app/heroes/${id}`) - .map((res: Response) => res.json().data); - } - - getHeroes() { - return this.http.get(`api/heroes`) - .map((res: Response) => res.json().data); - } - -} - diff --git a/public/docs/_examples/style-guide/ts/03-05/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-05/app/app.component.ts deleted file mode 100644 index 8268f0d0b9..0000000000 --- a/public/docs/_examples/style-guide/ts/03-05/app/app.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { Hero, HeroService } from './+heroes'; -import { ExceptionService, SpinnerService, ToastService } from './shared'; - -@Component({ - moduleId: module.id, - selector: 'sg-app', - templateUrl: 'app.component.html', - providers: [HeroService, ExceptionService, SpinnerService, ToastService] -}) -export class AppComponent implements OnInit { - favorite: Hero; - heroes: Hero[]; - - constructor(private heroService: HeroService) { } - - ngOnInit() { - this.heroService.getHero(1).subscribe(hero => this.favorite = hero); - this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes); - } -} diff --git a/public/docs/_examples/style-guide/ts/03-05/app/index.ts b/public/docs/_examples/style-guide/ts/03-05/app/index.ts deleted file mode 100644 index 6dd278f3c2..0000000000 --- a/public/docs/_examples/style-guide/ts/03-05/app/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './+heroes'; -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/toast.component.ts b/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/toast.component.ts deleted file mode 100644 index 24afa50a5b..0000000000 --- a/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/toast.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { ToastService } from './toast.service'; - -@Component({ - moduleId: module.id, - selector: 'toh-toast', - templateUrl: '
    toast
    ' -}) -export class ToastComponent implements OnInit { - constructor(toastService: ToastService) { } - - ngOnInit() { } -} diff --git a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.model.ts deleted file mode 100644 index c3277621cb..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.model.ts +++ /dev/null @@ -1,7 +0,0 @@ -// #docregion -// #docregion example -export class Hero { - name: string; - power: string; -} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.service.avoid.ts b/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.service.avoid.ts deleted file mode 100644 index 6c15ba46bd..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.service.avoid.ts +++ /dev/null @@ -1,32 +0,0 @@ -// #docregion -// #docregion example -/* avoid */ - -import { ExceptionService, SpinnerService, ToastService } from '../../shared'; -import { Http, Response } from '@angular/http'; -import { Injectable } from '@angular/core'; -import { Hero } from './hero.model'; -// #enddocregion example - -@Injectable() -export class HeroService { - - constructor( - private exceptionService: ExceptionService, - private spinnerService: SpinnerService, - private toastService: ToastService, - private http: Http - ) { } - - getHero(id: number) { - return this.http.get(`api/heroes/${id}`) - .map((res: Response) => res.json().data); - } - - getHeroes() { - return this.http.get(`api/heroes`) - .map((res: Response) => res.json().data); - } - -} - diff --git a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.service.ts deleted file mode 100644 index 817fdbead1..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/hero.service.ts +++ /dev/null @@ -1,32 +0,0 @@ -// #docregion -// #docregion example -import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; - -import { Hero } from './hero.model'; -import { ExceptionService, SpinnerService, ToastService } from '../../shared'; -// #enddocregion example - -@Injectable() -export class HeroService { - cachedHeroes: Hero[]; - - constructor( - private exceptionService: ExceptionService, - private spinnerService: SpinnerService, - private toastService: ToastService, - private http: Http - ) { } - - getHero(id: number) { - return this.http.get(`api/heroes/${id}`) - .map((res: Response) => res.json().data); - } - - getHeroes() { - return this.http.get(`api/heroes`) - .map((res: Response) => res.json().data); - } - -} - diff --git a/public/docs/_examples/style-guide/ts/03-06/app/app.component.html b/public/docs/_examples/style-guide/ts/03-06/app/app.component.html deleted file mode 100644 index 67fb0d5964..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/app.component.html +++ /dev/null @@ -1,6 +0,0 @@ -
    Actual favorite: {{favorite?.name}}
    -
      -
    • - {{hero.name}} -
    • -
    diff --git a/public/docs/_examples/style-guide/ts/03-06/app/app.component.ts b/public/docs/_examples/style-guide/ts/03-06/app/app.component.ts deleted file mode 100644 index 8268f0d0b9..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/app.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { Hero, HeroService } from './+heroes'; -import { ExceptionService, SpinnerService, ToastService } from './shared'; - -@Component({ - moduleId: module.id, - selector: 'sg-app', - templateUrl: 'app.component.html', - providers: [HeroService, ExceptionService, SpinnerService, ToastService] -}) -export class AppComponent implements OnInit { - favorite: Hero; - heroes: Hero[]; - - constructor(private heroService: HeroService) { } - - ngOnInit() { - this.heroService.getHero(1).subscribe(hero => this.favorite = hero); - this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes); - } -} diff --git a/public/docs/_examples/style-guide/ts/03-06/app/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/index.ts deleted file mode 100644 index 6dd278f3c2..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './+heroes'; -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/exception.service.ts b/public/docs/_examples/style-guide/ts/03-06/app/shared/exception.service.ts deleted file mode 100644 index 7180c88e6b..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/shared/exception.service.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class ExceptionService { } diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/shared/index.ts deleted file mode 100644 index e4e6723f91..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/shared/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -// #docregion -// #docregion example -export * from './exception.service'; -export * from './spinner'; -export * from './toast'; -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/index.ts deleted file mode 100644 index 1d619300c0..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -export * from './spinner.component'; -export * from './spinner.service'; diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/spinner.component.ts b/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/spinner.component.ts deleted file mode 100644 index 1fd2a01500..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/spinner.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; - -import { SpinnerService } from './spinner.service'; - -@Component({ - selector: 'toh-spinner', - template: '
    spinner
    ' -}) - -export class SpinnerComponent implements OnDestroy, OnInit { - constructor(private spinnerService: SpinnerService) { } - - ngOnInit() { } - - ngOnDestroy() { } -} diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/spinner.service.ts b/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/spinner.service.ts deleted file mode 100644 index ad5d2ed6e0..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/shared/spinner/spinner.service.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Injectable } from '@angular/core'; - -export interface ISpinnerState { } - -@Injectable() -export class SpinnerService { - spinnerState: any; - - show() { } - - hide() { } -} diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/index.ts b/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/index.ts deleted file mode 100644 index 01b41aff98..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -export * from './toast.component'; -export * from './toast.service'; diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.component.ts b/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.component.ts deleted file mode 100644 index 24afa50a5b..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { ToastService } from './toast.service'; - -@Component({ - moduleId: module.id, - selector: 'toh-toast', - templateUrl: '
    toast
    ' -}) -export class ToastComponent implements OnInit { - constructor(toastService: ToastService) { } - - ngOnInit() { } -} diff --git a/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.service.ts b/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.service.ts deleted file mode 100644 index e92e75ee45..0000000000 --- a/public/docs/_examples/style-guide/ts/03-06/app/shared/toast/toast.service.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class ToastService { - activate: (message?: string, title?: string) => void; -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/+heroes/heroes.component.avoid.ts b/public/docs/_examples/style-guide/ts/04-10/app/+heroes/heroes.component.avoid.ts deleted file mode 100644 index b61e3ab782..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/+heroes/heroes.component.avoid.ts +++ /dev/null @@ -1,25 +0,0 @@ -// #docregion -// #docregion example -/* avoid */ - -import { Component, OnInit } from '@angular/core'; - -import { CONFIG } from '../shared/config'; -import { EntityService } from '../shared/entity.service'; -import { ExceptionService } from '../shared/exception.service'; -import { FilterTextComponent } from '../shared/filter-text/filter-text.component'; -import { InitCapsPipe } from '../shared/init-caps.pipe'; -import { SpinnerService } from '../shared/spinner/spinner.service'; -import { ToastService } from '../shared/toast/toast.service'; - -@Component({ - selector: 'toh-heroes', - templateUrl: 'app/+heroes/heroes.component.html' -}) -export class HeroesComponent implements OnInit { - constructor() { } - - ngOnInit() { } -} -// #enddocregion example - diff --git a/public/docs/_examples/style-guide/ts/04-10/app/+heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/+heroes/heroes.component.ts deleted file mode 100644 index 9ca611ee5c..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/+heroes/heroes.component.ts +++ /dev/null @@ -1,35 +0,0 @@ -// #docplaster -// #docregion -// #docregion example -import { Component, OnInit } from '@angular/core'; - -import { - CONFIG, - EntityService, - ExceptionService, - FilterTextComponent, - InitCapsPipe, - SpinnerService, - ToastService -} from '../shared'; - -@Component({ - // #enddocregion example - moduleId: module.id, - providers: [EntityService, ExceptionService, SpinnerService, ToastService], - directives: [FilterTextComponent], - pipes: [InitCapsPipe], - // #docregion example - selector: 'toh-heroes', - templateUrl: 'heroes.component.html' -}) -export class HeroesComponent implements OnInit { - // #enddocregion example - urls = CONFIG.baseUrls; - // #docregion example - constructor() { } - - ngOnInit() { } -} -// #enddocregion example - diff --git a/public/docs/_examples/style-guide/ts/04-10/app/+heroes/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/+heroes/index.ts deleted file mode 100644 index dbf3079697..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/+heroes/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './heroes.component'; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/app.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/app.component.ts deleted file mode 100644 index b7554b8d06..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/app.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -// #docregion example -import { HeroesComponent } from './+heroes'; -// #enddocregion example - -@Component({ - selector: 'sg-app', - template: '', - directives: [HeroesComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/04-10/app/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/index.ts deleted file mode 100644 index 6dd278f3c2..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './+heroes'; -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/config.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/config.ts deleted file mode 100644 index cf7281ecf1..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -export let CONFIG = { - baseUrls: { - heroes: 'api/heroes.json', - villains: 'api/villains.json' - } -}; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/entity.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/entity.service.ts deleted file mode 100644 index 2d2a13db6d..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/entity.service.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class EntityService { } diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/exception.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/exception.service.ts deleted file mode 100644 index 7180c88e6b..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/exception.service.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class ExceptionService { } diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.component.ts deleted file mode 100644 index 8b058c7ba7..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, EventEmitter, Output } from '@angular/core'; - -@Component({ - moduleId: module.id, - selector: 'toh-filter-text', - template: '
    filter
    ' -}) -export class FilterTextComponent { - @Output() changed: EventEmitter; - filter: string; - - constructor() { } - - clear() { - } - - filterChanged(event: any) { - } -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.service.ts deleted file mode 100644 index 9c8cc0ce3f..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/filter-text.service.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class FilterService { - constructor() { } - - filter(data: string, props: Array, originalList: Array) { - let filteredList: any[]; - return filteredList; - } -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/index.ts deleted file mode 100644 index 4641503ec4..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/filter-text/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -export * from './filter-text.component'; -export * from './filter-text.service'; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/index.ts deleted file mode 100644 index e4f31e4c62..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -// #docregion example -export * from './config'; -export * from './entity.service'; -export * from './exception.service'; -export * from './filter-text'; -export * from './init-caps.pipe'; -export * from './modal'; -export * from './nav'; -export * from './spinner'; -export * from './toast'; -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/index.ts deleted file mode 100644 index 03bebd34d4..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -export * from './modal.component'; -export * from './modal.service'; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.component.ts deleted file mode 100644 index ab62348e10..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { ModalService } from './modal.service'; - -@Component({ - moduleId: module.id, - selector: 'toh-modal-confirm', - template: '
    modal
    ' -}) -export class ModalComponent implements OnInit { - constructor(modalService: ModalService) { } - - ngOnInit() { } -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.service.ts deleted file mode 100644 index d5fad3a815..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/modal/modal.service.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class ModalService { - activate: (message?: string, title?: string) => Promise; -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/index.ts deleted file mode 100644 index 4236f3e9e1..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// #docregion -export * from './nav.component'; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/nav.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/nav.component.ts deleted file mode 100644 index 97d6313cf3..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/nav/nav.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { ModalService } from '../'; - -@Component({ - moduleId: module.id, - selector: 'toh-nav', - template: '
    nav
    ' -}) -export class NavComponent implements OnInit { - - ngOnInit() { } - - constructor(private modalService: ModalService) { } - - resetDb() { } -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/index.ts deleted file mode 100644 index 1d619300c0..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -export * from './spinner.component'; -export * from './spinner.service'; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.component.ts deleted file mode 100644 index 74a83800e7..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {Component, OnDestroy, OnInit} from '@angular/core'; - -import { SpinnerService } from './spinner.service'; - -@Component({ - selector: 'toh-spinner', - template: '
    spinner
    ' -}) - -export class SpinnerComponent implements OnDestroy, OnInit { - constructor(private spinnerService: SpinnerService) { } - - ngOnInit() { } - - ngOnDestroy() { } -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.service.ts deleted file mode 100644 index ad5d2ed6e0..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/spinner/spinner.service.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Injectable } from '@angular/core'; - -export interface ISpinnerState { } - -@Injectable() -export class SpinnerService { - spinnerState: any; - - show() { } - - hide() { } -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/index.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/index.ts deleted file mode 100644 index 01b41aff98..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -export * from './toast.component'; -export * from './toast.service'; diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/toast.component.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/toast.component.ts deleted file mode 100644 index 24afa50a5b..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/toast.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { ToastService } from './toast.service'; - -@Component({ - moduleId: module.id, - selector: 'toh-toast', - templateUrl: '
    toast
    ' -}) -export class ToastComponent implements OnInit { - constructor(toastService: ToastService) { } - - ngOnInit() { } -} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/toast.service.ts b/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/toast.service.ts deleted file mode 100644 index e92e75ee45..0000000000 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/toast/toast.service.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class ToastService { - activate: (message?: string, title?: string) => void; -} diff --git a/public/docs/_examples/style-guide/ts/04-13/app/+heroes/index.ts b/public/docs/_examples/style-guide/ts/04-13/app/+heroes/index.ts deleted file mode 100644 index 45d52e8c70..0000000000 --- a/public/docs/_examples/style-guide/ts/04-13/app/+heroes/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Needed for the .avoid code to compile -export const HeroesComponent = 42; diff --git a/public/docs/_examples/style-guide/ts/04-13/app/app.component.avoid.ts b/public/docs/_examples/style-guide/ts/04-13/app/app.component.avoid.ts deleted file mode 100644 index d41269c2c5..0000000000 --- a/public/docs/_examples/style-guide/ts/04-13/app/app.component.avoid.ts +++ /dev/null @@ -1,11 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -// #docregion example -import { HeroesComponent } from './+heroes'; -// #enddocregion example - -@Component({ - selector: 'toh-app' -}) -export class AppComponent {} diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.html deleted file mode 100644 index b6bf75ef1a..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.html +++ /dev/null @@ -1,12 +0,0 @@ - -
    -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    -
    -

    {{selectedHero.name | uppercase}} is my hero

    -
    -
    diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.ts deleted file mode 100644 index e12f8af5d9..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -// #docregion -import { Component, OnInit } from '@angular/core'; - -import { Hero } from './shared'; -// #docregion example -import { Logger } from '../shared'; -// #enddocregion example - -@Component({ - moduleId: module.id, - selector: 'toh-heroes', - templateUrl: 'heroes.component.html', - styleUrls: ['heroes.component.css'], - providers: [Logger] -}) -export class HeroesComponent implements OnInit { - heroes: Hero[]; - selectedHero: Hero; - - ngOnInit() { } -} diff --git a/public/docs/_examples/style-guide/ts/04-14/app/app.component.ts b/public/docs/_examples/style-guide/ts/04-14/app/app.component.ts deleted file mode 100644 index ebf8146349..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/app.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroesComponent } from './+heroes'; - -@Component({ - selector: 'sg-app', - template: '', - directives: [HeroesComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/04-14/app/index.ts b/public/docs/_examples/style-guide/ts/04-14/app/index.ts deleted file mode 100644 index 6dd278f3c2..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './+heroes'; -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/04-14/app/shared/index.ts b/public/docs/_examples/style-guide/ts/04-14/app/shared/index.ts deleted file mode 100644 index 6820e22fc7..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/shared/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './logger.service'; diff --git a/public/docs/_examples/style-guide/ts/04-14/app/shared/logger.service.ts b/public/docs/_examples/style-guide/ts/04-14/app/shared/logger.service.ts deleted file mode 100644 index b1f8c7ff21..0000000000 --- a/public/docs/_examples/style-guide/ts/04-14/app/shared/logger.service.ts +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; - -@Injectable() -export class Logger { - - constructor() { } - -} diff --git a/public/docs/_examples/style-guide/ts/05-02/app/app.component.ts b/public/docs/_examples/style-guide/ts/05-02/app/app.component.ts deleted file mode 100644 index 76bf4eafd5..0000000000 --- a/public/docs/_examples/style-guide/ts/05-02/app/app.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroButtonComponent } from './heroes'; - -@Component({ - moduleId: module.id, - selector: 'sg-app', - templateUrl: 'app.component.html', - directives: [HeroButtonComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts b/public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts deleted file mode 100644 index 7be30dc913..0000000000 --- a/public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts +++ /dev/null @@ -1,15 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; -// #docregion example -/* avoid */ - -@Component({ - // #enddocregion example - moduleId: module.id, - // #docregion example - selector: 'tohHeroButton', - templateUrl: 'hero-button.component.html' -}) -export class HeroButtonComponent {} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/hero-button/hero-button.component.ts b/public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/hero-button/hero-button.component.ts deleted file mode 100644 index 439ce328d5..0000000000 --- a/public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/hero-button/hero-button.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; - -// #docregion example -@Component({ - // #enddocregion example - moduleId: module.id, - // #docregion example - selector: 'toh-hero-button', - templateUrl: 'hero-button.component.html' -}) -export class HeroButtonComponent {} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-02/app/index.ts b/public/docs/_examples/style-guide/ts/05-02/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/05-02/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/05-03/app/app.component.ts b/public/docs/_examples/style-guide/ts/05-03/app/app.component.ts deleted file mode 100644 index 76bf4eafd5..0000000000 --- a/public/docs/_examples/style-guide/ts/05-03/app/app.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroButtonComponent } from './heroes'; - -@Component({ - moduleId: module.id, - selector: 'sg-app', - templateUrl: 'app.component.html', - directives: [HeroButtonComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/hero-button/hero-button.component.avoid.ts b/public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/hero-button/hero-button.component.avoid.ts deleted file mode 100644 index 4cbf731912..0000000000 --- a/public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/hero-button/hero-button.component.avoid.ts +++ /dev/null @@ -1,15 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; -// #docregion example -/* avoid */ - -@Component({ - // #enddocregion example - moduleId: module.id, - // #docregion example - selector: '[tohHeroButton]', - templateUrl: 'hero-button.component.html' -}) -export class HeroButtonComponent {} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/hero-button/hero-button.component.ts b/public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/hero-button/hero-button.component.ts deleted file mode 100644 index 439ce328d5..0000000000 --- a/public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/hero-button/hero-button.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; - -// #docregion example -@Component({ - // #enddocregion example - moduleId: module.id, - // #docregion example - selector: 'toh-hero-button', - templateUrl: 'hero-button.component.html' -}) -export class HeroButtonComponent {} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-03/app/index.ts b/public/docs/_examples/style-guide/ts/05-03/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/05-03/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/05-04/app/app.component.ts b/public/docs/_examples/style-guide/ts/05-04/app/app.component.ts deleted file mode 100644 index c8e62772b4..0000000000 --- a/public/docs/_examples/style-guide/ts/05-04/app/app.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroesComponent } from './heroes'; - -@Component({ - selector: 'sg-app', - template: '', - directives: [HeroesComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.avoid.ts b/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.avoid.ts deleted file mode 100644 index cced0be5dc..0000000000 --- a/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.avoid.ts +++ /dev/null @@ -1,59 +0,0 @@ -// #docregion -import { Component, OnInit } from '@angular/core'; - -import { Hero } from './shared/hero.model'; -// #docregion example -/* avoid */ - -@Component({ - selector: 'toh-heroes', - template: ` -
    -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    -
    -

    {{selectedHero.name | uppercase}} is my hero

    -
    -
    - `, - styleUrls: [` - .heroes { - margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 15em; - } - .heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; - } - .heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; - } - `] -}) -export class HeroesComponent implements OnInit { - heroes: Hero[]; - selectedHero: Hero; - - ngOnInit() {} -} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.css b/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.css deleted file mode 100644 index 82f0c1d0ab..0000000000 --- a/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.css +++ /dev/null @@ -1,28 +0,0 @@ -/* #docregion */ -.heroes { - margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 15em; -} -.heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; -} -.heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; -} diff --git a/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.html deleted file mode 100644 index b6bf75ef1a..0000000000 --- a/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.html +++ /dev/null @@ -1,12 +0,0 @@ - -
    -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    -
    -

    {{selectedHero.name | uppercase}} is my hero

    -
    -
    diff --git a/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.ts deleted file mode 100644 index 9db7e50a35..0000000000 --- a/public/docs/_examples/style-guide/ts/05-04/app/heroes/heroes.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -// #docplaster -// #docregion -import { Component, OnInit } from '@angular/core'; - -import { Hero } from './shared'; - -// #docregion example -@Component({ - // #enddocregion example - moduleId: module.id, - // #docregion example - selector: 'toh-heroes', - templateUrl: 'heroes.component.html', - styleUrls: ['heroes.component.css'] -}) -export class HeroesComponent implements OnInit { - heroes: Hero[]; - selectedHero: Hero; - - ngOnInit() { } -} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-04/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/05-04/app/heroes/index.ts deleted file mode 100644 index a8d7f1d422..0000000000 --- a/public/docs/_examples/style-guide/ts/05-04/app/heroes/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './shared'; -export * from './heroes.component'; diff --git a/public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/index.ts deleted file mode 100644 index 0dceb684c4..0000000000 --- a/public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './hero.model'; diff --git a/public/docs/_examples/style-guide/ts/05-04/app/index.ts b/public/docs/_examples/style-guide/ts/05-04/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/05-04/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/05-12/app/app.component.ts b/public/docs/_examples/style-guide/ts/05-12/app/app.component.ts deleted file mode 100644 index c6bf721e40..0000000000 --- a/public/docs/_examples/style-guide/ts/05-12/app/app.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroButtonComponent } from './heroes'; - -@Component({ - selector: 'sg-app', - template: '', - directives: [HeroButtonComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/05-12/app/index.ts b/public/docs/_examples/style-guide/ts/05-12/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/05-12/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/05-13/app/app.component.html b/public/docs/_examples/style-guide/ts/05-13/app/app.component.html deleted file mode 100644 index 094f24b258..0000000000 --- a/public/docs/_examples/style-guide/ts/05-13/app/app.component.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/docs/_examples/style-guide/ts/05-13/app/app.component.ts b/public/docs/_examples/style-guide/ts/05-13/app/app.component.ts deleted file mode 100644 index 76bf4eafd5..0000000000 --- a/public/docs/_examples/style-guide/ts/05-13/app/app.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroButtonComponent } from './heroes'; - -@Component({ - moduleId: module.id, - selector: 'sg-app', - templateUrl: 'app.component.html', - directives: [HeroButtonComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts b/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts deleted file mode 100644 index 9724ad437d..0000000000 --- a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts +++ /dev/null @@ -1,14 +0,0 @@ -// #docregion -import { Component, EventEmitter, Input, Output } from '@angular/core'; -// #docregion example -/* avoid */ - -@Component({ - selector: 'toh-hero-button', - template: `` -}) -export class HeroButtonComponent { - @Output('changeEvent') change = new EventEmitter(); - @Input('labelAttribute') label: string; -} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.ts b/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.ts deleted file mode 100644 index b299740765..0000000000 --- a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/hero-button.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -// #docregion -import { Component, EventEmitter, Input, Output } from '@angular/core'; - -// #docregion example -@Component({ - selector: 'toh-hero-button', - template: `` -}) -export class HeroButtonComponent { - @Output() change = new EventEmitter(); - @Input() label: string; -} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-13/app/index.ts b/public/docs/_examples/style-guide/ts/05-13/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/05-13/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/05-14/app/app.component.ts b/public/docs/_examples/style-guide/ts/05-14/app/app.component.ts deleted file mode 100644 index 05e38bf35c..0000000000 --- a/public/docs/_examples/style-guide/ts/05-14/app/app.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; - -import { ToastComponent } from './shared'; - -@Component({ - selector: 'sg-app', - template: ``, - directives: [ToastComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/05-14/app/index.ts b/public/docs/_examples/style-guide/ts/05-14/app/index.ts deleted file mode 100644 index d5721a3934..0000000000 --- a/public/docs/_examples/style-guide/ts/05-14/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/05-14/app/shared/toast/toast.component.ts b/public/docs/_examples/style-guide/ts/05-14/app/shared/toast/toast.component.ts deleted file mode 100644 index 5a56ad6c04..0000000000 --- a/public/docs/_examples/style-guide/ts/05-14/app/shared/toast/toast.component.ts +++ /dev/null @@ -1,45 +0,0 @@ -// #docregion -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'toh-toast', - template: `...` -}) -// #docregion example -export class ToastComponent implements OnInit { - // public properties - message: string; - title: string; - - // private fields - private defaults = { - title: '', - message: 'May the Force be with You' - }; - private toastElement: any; - - // public methods - activate(message = this.defaults.message, title = this.defaults.title) { - this.title = title; - this.message = message; - this.show(); - } - - ngOnInit() { - this.toastElement = document.getElementById('toh-toast'); - } - - // private methods - private hide() { - this.toastElement.style.opacity = 0; - window.setTimeout(() => this.toastElement.style.zIndex = 0, 400); - } - - private show() { - console.log(this.message); - this.toastElement.style.opacity = 1; - this.toastElement.style.zIndex = 9999; - window.setTimeout(() => this.hide(), 2500); - } -} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-15/app/app.component.ts b/public/docs/_examples/style-guide/ts/05-15/app/app.component.ts deleted file mode 100644 index 7fd78842b8..0000000000 --- a/public/docs/_examples/style-guide/ts/05-15/app/app.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroListComponent, HeroService } from './heroes'; - -@Component({ - selector: 'sg-app', - template: '', - directives: [HeroListComponent], - providers: [HeroService] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/05-15/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/05-15/app/heroes/shared/hero.service.ts deleted file mode 100644 index f8690e9c2f..0000000000 --- a/public/docs/_examples/style-guide/ts/05-15/app/heroes/shared/hero.service.ts +++ /dev/null @@ -1,13 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; - -import { Hero } from './hero.model.ts'; - -@Injectable() -export class HeroService { - getHeroes() { - let heroes: Hero[] = []; - return Observable.of(heroes); - } -} diff --git a/public/docs/_examples/style-guide/ts/05-15/app/index.ts b/public/docs/_examples/style-guide/ts/05-15/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/05-15/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/05-16/app/app.component.ts b/public/docs/_examples/style-guide/ts/05-16/app/app.component.ts deleted file mode 100644 index 39fab1a724..0000000000 --- a/public/docs/_examples/style-guide/ts/05-16/app/app.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroComponent } from './heroes'; - -@Component({ - moduleId: module.id, - selector: 'sg-app', - templateUrl: 'app.component.html', - directives: [HeroComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/05-16/app/index.ts b/public/docs/_examples/style-guide/ts/05-16/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/05-16/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/05-17/app/app.component.ts b/public/docs/_examples/style-guide/ts/05-17/app/app.component.ts deleted file mode 100644 index 8e2e7e727c..0000000000 --- a/public/docs/_examples/style-guide/ts/05-17/app/app.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroListComponent } from './heroes'; - -@Component({ - selector: 'sg-app', - template: '', - directives: [HeroListComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/05-17/app/heroes/hero-list/hero-list.component.ts b/public/docs/_examples/style-guide/ts/05-17/app/heroes/hero-list/hero-list.component.ts deleted file mode 100644 index 8570544a36..0000000000 --- a/public/docs/_examples/style-guide/ts/05-17/app/heroes/hero-list/hero-list.component.ts +++ /dev/null @@ -1,35 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; - -import { Hero } from '../shared/hero.model.ts'; - -// #docregion example -@Component({ - selector: 'toh-hero-list', - template: ` -
    - Our list of heroes: - - - Total powers: {{totalPowers}}
    - Average power: {{avgPower}} -
    - ` -}) -export class HeroListComponent { - heroes: Hero[]; - totalPowers: number; - - // #enddocregion example - // testing harness - constructor() { - this.heroes = []; - } - - // #docregion example - get avgPower() { - return this.totalPowers / this.heroes.length; - } -} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-17/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/05-17/app/heroes/shared/index.ts deleted file mode 100644 index 0dceb684c4..0000000000 --- a/public/docs/_examples/style-guide/ts/05-17/app/heroes/shared/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './hero.model'; diff --git a/public/docs/_examples/style-guide/ts/05-17/app/index.ts b/public/docs/_examples/style-guide/ts/05-17/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/05-17/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/06-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/06-01/app/app.component.ts deleted file mode 100644 index 97a52c0c0c..0000000000 --- a/public/docs/_examples/style-guide/ts/06-01/app/app.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component } from '@angular/core'; - -import { HighlightDirective } from './shared'; - -@Component({ - moduleId: module.id, - selector: 'sg-app', - templateUrl: 'app.component.html', - directives: [HighlightDirective] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/06-01/app/index.ts b/public/docs/_examples/style-guide/ts/06-01/app/index.ts deleted file mode 100644 index d5721a3934..0000000000 --- a/public/docs/_examples/style-guide/ts/06-01/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/06-03/app/app.component.ts b/public/docs/_examples/style-guide/ts/06-03/app/app.component.ts deleted file mode 100644 index c40b5c0406..0000000000 --- a/public/docs/_examples/style-guide/ts/06-03/app/app.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; - -import { ValidatorDirective } from './shared'; - -@Component({ - selector: 'sg-app', - template: '', - directives: [ValidatorDirective] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/06-03/app/index.ts b/public/docs/_examples/style-guide/ts/06-03/app/index.ts deleted file mode 100644 index d5721a3934..0000000000 --- a/public/docs/_examples/style-guide/ts/06-03/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/06-03/app/shared/index.ts b/public/docs/_examples/style-guide/ts/06-03/app/shared/index.ts deleted file mode 100644 index 2168f8b2c6..0000000000 --- a/public/docs/_examples/style-guide/ts/06-03/app/shared/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './validator.directive'; diff --git a/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.avoid.ts b/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.avoid.ts deleted file mode 100644 index c9b724dc53..0000000000 --- a/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.avoid.ts +++ /dev/null @@ -1,20 +0,0 @@ -// #docregion -import { Directive, HostBinding, HostListener } from '@angular/core'; - -// #docregion example -/* avoid */ - -@Directive({ - selector: '[tohValidator]', - host: { - '(mouseenter)': 'onMouseEnter()', - 'attr.role': 'button' - } -}) -export class ValidatorDirective { - role = 'button'; - onMouseEnter() { - // do work - } -} -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/07-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/07-01/app/app.component.ts deleted file mode 100644 index 5b10b49c37..0000000000 --- a/public/docs/_examples/style-guide/ts/07-01/app/app.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { Hero, HeroService } from './heroes'; - -@Component({ - moduleId: module.id, - selector: 'sg-app', - templateUrl: 'app.component.html', - providers: [HeroService] -}) -export class AppComponent implements OnInit { - heroes: Hero[]; - - constructor(private heroService: HeroService) { } - - ngOnInit() { - this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes); - } -} diff --git a/public/docs/_examples/style-guide/ts/07-01/app/index.ts b/public/docs/_examples/style-guide/ts/07-01/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/07-01/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/07-03/app/app.component.ts b/public/docs/_examples/style-guide/ts/07-03/app/app.component.ts deleted file mode 100644 index 276321e2f1..0000000000 --- a/public/docs/_examples/style-guide/ts/07-03/app/app.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { HeroListComponent, HeroService } from './heroes'; - -@Component({ - selector: 'toh-app', - template: ` - - `, - directives: [HeroListComponent], - providers: [HeroService] -}) -export class AppComponent {} diff --git a/public/docs/_examples/style-guide/ts/07-03/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/07-03/app/heroes/index.ts deleted file mode 100644 index f1112f1c7c..0000000000 --- a/public/docs/_examples/style-guide/ts/07-03/app/heroes/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './hero-list'; -export * from './shared'; diff --git a/public/docs/_examples/style-guide/ts/07-03/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/07-03/app/heroes/shared/hero.service.ts deleted file mode 100644 index f8690e9c2f..0000000000 --- a/public/docs/_examples/style-guide/ts/07-03/app/heroes/shared/hero.service.ts +++ /dev/null @@ -1,13 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; - -import { Hero } from './hero.model.ts'; - -@Injectable() -export class HeroService { - getHeroes() { - let heroes: Hero[] = []; - return Observable.of(heroes); - } -} diff --git a/public/docs/_examples/style-guide/ts/07-03/app/index.ts b/public/docs/_examples/style-guide/ts/07-03/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/07-03/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/07-04/app/app.component.ts b/public/docs/_examples/style-guide/ts/07-04/app/app.component.ts deleted file mode 100644 index e938b12036..0000000000 --- a/public/docs/_examples/style-guide/ts/07-04/app/app.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { HeroArena, HeroService, Hero } from './heroes'; - -@Component({ - selector: 'toh-app', - template: '
    {{heroes | json}}
    ', - providers: [HeroArena, HeroService] -}) -export class AppComponent { - heroes: Hero[] = []; - - constructor(private heroArena: HeroArena) { } - - ngOnInit() { - this.heroArena.getParticipants().subscribe(heroes => this.heroes = heroes); - } -} diff --git a/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero.model.ts deleted file mode 100644 index 8f7cc205c8..0000000000 --- a/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -// #docregion -export class Hero { - id: number; - name: string; -} diff --git a/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero.service.ts deleted file mode 100644 index f8690e9c2f..0000000000 --- a/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero.service.ts +++ /dev/null @@ -1,13 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; - -import { Hero } from './hero.model.ts'; - -@Injectable() -export class HeroService { - getHeroes() { - let heroes: Hero[] = []; - return Observable.of(heroes); - } -} diff --git a/public/docs/_examples/style-guide/ts/07-04/app/index.ts b/public/docs/_examples/style-guide/ts/07-04/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/07-04/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/09-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/09-01/app/app.component.ts deleted file mode 100644 index 50ddf5fe1e..0000000000 --- a/public/docs/_examples/style-guide/ts/09-01/app/app.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; - -import { HeroButtonComponent } from './heroes'; - -@Component({ - selector: 'sg-app', - template: '', - directives: [HeroButtonComponent] -}) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/09-01/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/09-01/app/heroes/index.ts deleted file mode 100644 index c3da79f741..0000000000 --- a/public/docs/_examples/style-guide/ts/09-01/app/heroes/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './shared'; diff --git a/public/docs/_examples/style-guide/ts/09-01/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/09-01/app/heroes/shared/index.ts deleted file mode 100644 index 2334d49c9a..0000000000 --- a/public/docs/_examples/style-guide/ts/09-01/app/heroes/shared/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './hero-button'; diff --git a/public/docs/_examples/style-guide/ts/09-01/app/index.ts b/public/docs/_examples/style-guide/ts/09-01/app/index.ts deleted file mode 100644 index 0d27e4612c..0000000000 --- a/public/docs/_examples/style-guide/ts/09-01/app/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './heroes'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/10-01/app/+dashboard/dashboard.component.ts b/public/docs/_examples/style-guide/ts/10-01/app/+dashboard/dashboard.component.ts deleted file mode 100644 index 925b3c0365..0000000000 --- a/public/docs/_examples/style-guide/ts/10-01/app/+dashboard/dashboard.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'toh-dashboard', - templateUrl: 'app/dashboard/dashboard.component.html' -}) -export class DashboardComponent implements OnInit { - constructor() { } - - ngOnInit() { } -} diff --git a/public/docs/_examples/style-guide/ts/10-01/app/+dashboard/index.ts b/public/docs/_examples/style-guide/ts/10-01/app/+dashboard/index.ts deleted file mode 100644 index 28b2996161..0000000000 --- a/public/docs/_examples/style-guide/ts/10-01/app/+dashboard/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './dashboard.component'; diff --git a/public/docs/_examples/style-guide/ts/10-01/app/+heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/10-01/app/+heroes/heroes.component.ts deleted file mode 100644 index 569a25f688..0000000000 --- a/public/docs/_examples/style-guide/ts/10-01/app/+heroes/heroes.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'toh-heroes', - templateUrl: 'app/heroes/heroes.component.html' -}) -export class HeroesComponent implements OnInit { - constructor() { } - - ngOnInit() { } -} diff --git a/public/docs/_examples/style-guide/ts/10-01/app/+heroes/index.ts b/public/docs/_examples/style-guide/ts/10-01/app/+heroes/index.ts deleted file mode 100644 index d85a0c81c4..0000000000 --- a/public/docs/_examples/style-guide/ts/10-01/app/+heroes/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './shared'; -export * from './heroes.component.ts'; diff --git a/public/docs/_examples/style-guide/ts/10-01/app/+heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/10-01/app/+heroes/shared/hero.service.ts deleted file mode 100644 index 6d9ec12949..0000000000 --- a/public/docs/_examples/style-guide/ts/10-01/app/+heroes/shared/hero.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class HeroService { - - constructor() { } - -} diff --git a/public/docs/_examples/style-guide/ts/10-01/app/+heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/10-01/app/+heroes/shared/index.ts deleted file mode 100644 index 9edcfff7fb..0000000000 --- a/public/docs/_examples/style-guide/ts/10-01/app/+heroes/shared/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './hero.service'; diff --git a/public/docs/_examples/style-guide/ts/10-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/10-01/app/app.component.ts deleted file mode 100644 index 38d27afd5d..0000000000 --- a/public/docs/_examples/style-guide/ts/10-01/app/app.component.ts +++ /dev/null @@ -1,23 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { Routes, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router'; - -import { NavComponent } from './shared'; -import { DashboardComponent } from './+dashboard'; -import { HeroesComponent, HeroService } from './+heroes'; - -@Component({ - selector: 'toh-app', - templateUrl: 'app/app.component.html', - styleUrls: ['app/app.component.css'], - directives: [ROUTER_DIRECTIVES, NavComponent], - providers: [ - ROUTER_PROVIDERS, - HeroService - ] -}) -@Routes([ - { path: '/dashboard', component: DashboardComponent }, // , useAsDefault: true}, // coming soon - { path: '/heroes/...', component: HeroesComponent }, -]) -export class AppComponent {} diff --git a/public/docs/_examples/style-guide/ts/10-01/app/index.ts b/public/docs/_examples/style-guide/ts/10-01/app/index.ts deleted file mode 100644 index 0a909b24c9..0000000000 --- a/public/docs/_examples/style-guide/ts/10-01/app/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './+dashboard'; -export * from './+heroes'; -export * from './shared'; -export * from './app.component'; \ No newline at end of file diff --git a/public/docs/_examples/style-guide/ts/10-01/app/shared/index.ts b/public/docs/_examples/style-guide/ts/10-01/app/shared/index.ts deleted file mode 100644 index 38d6745899..0000000000 --- a/public/docs/_examples/style-guide/ts/10-01/app/shared/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './nav'; diff --git a/public/docs/_examples/style-guide/ts/10-01/app/shared/nav/index.ts b/public/docs/_examples/style-guide/ts/10-01/app/shared/nav/index.ts deleted file mode 100644 index ca588a3642..0000000000 --- a/public/docs/_examples/style-guide/ts/10-01/app/shared/nav/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './nav.component'; diff --git a/public/docs/_examples/style-guide/ts/10-01/app/shared/nav/nav.component.ts b/public/docs/_examples/style-guide/ts/10-01/app/shared/nav/nav.component.ts deleted file mode 100644 index 79dc0b0710..0000000000 --- a/public/docs/_examples/style-guide/ts/10-01/app/shared/nav/nav.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'toh-nav', - templateUrl: 'app/shared/nav/nav.component.html' -}) -export class NavComponent implements OnInit { - constructor() { } - - ngOnInit() { } - -} diff --git a/public/docs/_examples/style-guide/ts/app/app.component.ts b/public/docs/_examples/style-guide/ts/app/app.component.ts deleted file mode 100644 index 27287bfd7c..0000000000 --- a/public/docs/_examples/style-guide/ts/app/app.component.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Component } from '@angular/core'; -import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated'; - -import { AppComponent as S0101 } from '../01-01/app'; -import { AppComponent as S0207 } from '../02-07/app'; -import { AppComponent as S0208 } from '../02-08/app'; -import { AppComponent as S0301 } from '../03-01/app'; -import { AppComponent as S0302 } from '../03-02/app'; -import { AppComponent as S0303 } from '../03-03/app'; -import { AppComponent as S0304 } from '../03-04/app'; -import { AppComponent as S0305 } from '../03-05/app'; -import { AppComponent as S0306 } from '../03-06/app'; -import { AppComponent as S0410 } from '../04-10/app'; -import { AppComponent as S0414 } from '../04-14/app'; -import { AppComponent as S0502 } from '../05-02/app'; -import { AppComponent as S0503 } from '../05-03/app'; -import { AppComponent as S0504 } from '../05-04/app'; -import { AppComponent as S0512 } from '../05-12/app'; -import { AppComponent as S0513 } from '../05-13/app'; -import { AppComponent as S0514 } from '../05-14/app'; -import { AppComponent as S0515 } from '../05-15/app'; -import { AppComponent as S0516 } from '../05-16/app'; -import { AppComponent as S0517 } from '../05-17/app'; -import { AppComponent as S0601 } from '../06-01/app'; -import { AppComponent as S0603 } from '../06-03/app'; -import { AppComponent as S0701 } from '../07-01/app'; -import { AppComponent as S0703 } from '../07-03/app'; -import { AppComponent as S0704 } from '../07-04/app'; -import { AppComponent as S0901 } from '../09-01/app'; - -@Component({ - selector: 'my-app', - templateUrl: 'app/app.component.html', - directives: [ROUTER_DIRECTIVES] -}) -@RouteConfig([ - { path: '/01-01', name: '01-01', component: S0101 }, - { path: '/02-07', name: '02-07', component: S0207 }, - { path: '/02-08', name: '02-08', component: S0208 }, - { path: '/03-01', name: '03-01', component: S0301 }, - { path: '/03-02', name: '03-02', component: S0302 }, - { path: '/03-03', name: '03-03', component: S0303 }, - { path: '/03-04', name: '03-04', component: S0304 }, - { path: '/03-05', name: '03-05', component: S0305 }, - { path: '/03-06', name: '03-06', component: S0306 }, - { path: '/04-10', name: '04-10', component: S0410 }, - { path: '/04-14', name: '04-14', component: S0414 }, - { path: '/05-02', name: '05-02', component: S0502 }, - { path: '/05-03', name: '05-03', component: S0503 }, - { path: '/05-04', name: '05-04', component: S0504 }, - { path: '/05-12', name: '05-12', component: S0512 }, - { path: '/05-13', name: '05-13', component: S0513 }, - { path: '/05-14', name: '05-14', component: S0514 }, - { path: '/05-15', name: '05-15', component: S0515 }, - { path: '/05-16', name: '05-16', component: S0516 }, - { path: '/05-17', name: '05-17', component: S0517 }, - { path: '/06-01', name: '06-01', component: S0601 }, - { path: '/06-03', name: '06-03', component: S0603 }, - { path: '/07-01', name: '07-01', component: S0701 }, - { path: '/07-03', name: '07-03', component: S0703 }, - { path: '/07-04', name: '07-04', component: S0704 }, - { path: '/09-01', name: '09-01', component: S0901 }, - -]) -export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/app/main.ts b/public/docs/_examples/style-guide/ts/app/main.ts deleted file mode 100644 index 5eec1d8f88..0000000000 --- a/public/docs/_examples/style-guide/ts/app/main.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { ROUTER_PROVIDERS } from '@angular/router-deprecated'; -import { XHRBackend, HTTP_PROVIDERS } from '@angular/http'; -import { HashLocationStrategy, LocationStrategy } from '@angular/common'; -import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api'; -import 'rxjs/add/operator/map'; - -import { HeroData } from './hero-data'; -import { AppComponent } from './app.component'; - -bootstrap(AppComponent, [ - ROUTER_PROVIDERS, - HTTP_PROVIDERS, - { provide: LocationStrategy, useClass: HashLocationStrategy }, - { provide: XHRBackend, useClass: InMemoryBackendService }, - { provide: SEED_DATA, useClass: HeroData } - ]); diff --git a/public/docs/_examples/style-guide/ts/index.html b/public/docs/_examples/style-guide/ts/index.html deleted file mode 100644 index 44a280de44..0000000000 --- a/public/docs/_examples/style-guide/ts/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Style Guide Sample - - - - - - - - - - - - - - - - - - loading... - - - - diff --git a/public/docs/_examples/style-guide/ts/plnkr.json b/public/docs/_examples/style-guide/ts/plnkr.json index 334ad918b8..bf9e9681c5 100644 --- a/public/docs/_examples/style-guide/ts/plnkr.json +++ b/public/docs/_examples/style-guide/ts/plnkr.json @@ -1,8 +1,9 @@ { "description": "Style Guide", + "basePath": "src/", "files":[ "!**/*.d.ts", "!**/*.js" ], "tags": ["style guide, styleguide"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/style-guide/ts/01-01/app/app.component.css b/public/docs/_examples/style-guide/ts/src/01-01/app/app.component.css similarity index 100% rename from public/docs/_examples/style-guide/ts/01-01/app/app.component.css rename to public/docs/_examples/style-guide/ts/src/01-01/app/app.component.css diff --git a/public/docs/_examples/style-guide/ts/src/01-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/01-01/app/app.component.ts new file mode 100644 index 0000000000..d5bb953540 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/01-01/app/app.component.ts @@ -0,0 +1,14 @@ +// #docregion +import { Component } from '@angular/core'; + +import { HeroService } from './heroes'; + +@Component({ + selector: 'toh-app', + template: ` + + `, + styleUrls: ['./app.component.css'], + providers: [ HeroService ] +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/01-01/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/01-01/app/app.module.ts new file mode 100644 index 0000000000..53f29ea8cb --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/01-01/app/app.module.ts @@ -0,0 +1,27 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroesComponent } from './heroes/heroes.component'; + +@NgModule({ + imports: [ + BrowserModule, + // #enddocregion + RouterModule.forChild([{ path: '01-01', component: AppComponent }]) + // #docregion + ], + declarations: [ + AppComponent, + HeroesComponent + ], + exports: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +// #enddocregion + + diff --git a/public/docs/_examples/style-guide/ts/src/01-01/app/heroes/hero.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/01-01/app/heroes/hero.component.avoid.ts new file mode 100644 index 0000000000..853e6ab64e --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/01-01/app/heroes/hero.component.avoid.ts @@ -0,0 +1,49 @@ +// #docregion +/* avoid */ + +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule, Component, OnInit } from '@angular/core'; + +class Hero { + id: number; + name: string; +} + +@Component({ + selector: 'my-app', + template: ` +

    {{title}}

    +
    {{heroes | json}}
    + `, + styleUrls: ['app/app.component.css'] +}) +class AppComponent implements OnInit { + title = 'Tour of Heroes'; + + heroes: Hero[] = []; + + ngOnInit() { + getHeroes().then(heroes => this.heroes = heroes); + } +} + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ AppComponent ], + exports: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } + +platformBrowserDynamic().bootstrapModule(AppModule); + +const HEROES: Hero[] = [ + {id: 1, name: 'Bombasto'}, + {id: 2, name: 'Tornado'}, + {id: 3, name: 'Magneta'}, +]; + +function getHeroes(): Promise { + return Promise.resolve(HEROES); // TODO: get hero data from the server; +} diff --git a/public/docs/_examples/style-guide/ts/01-01/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/src/01-01/app/heroes/heroes.component.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/01-01/app/heroes/heroes.component.ts rename to public/docs/_examples/style-guide/ts/src/01-01/app/heroes/heroes.component.ts diff --git a/public/docs/_examples/style-guide/ts/01-01/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/01-01/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/01-01/app/heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/01-01/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/01-01/app/heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/src/01-01/app/heroes/shared/hero.model.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/01-01/app/heroes/shared/hero.model.ts rename to public/docs/_examples/style-guide/ts/src/01-01/app/heroes/shared/hero.model.ts diff --git a/public/docs/_examples/style-guide/ts/01-01/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/src/01-01/app/heroes/shared/hero.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/01-01/app/heroes/shared/hero.service.ts rename to public/docs/_examples/style-guide/ts/src/01-01/app/heroes/shared/hero.service.ts diff --git a/public/docs/_examples/style-guide/ts/01-01/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/01-01/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/01-01/app/heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/01-01/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/01-01/app/heroes/shared/mock-heroes.ts b/public/docs/_examples/style-guide/ts/src/01-01/app/heroes/shared/mock-heroes.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/01-01/app/heroes/shared/mock-heroes.ts rename to public/docs/_examples/style-guide/ts/src/01-01/app/heroes/shared/mock-heroes.ts diff --git a/public/docs/_examples/style-guide/ts/src/01-01/app/index.ts b/public/docs/_examples/style-guide/ts/src/01-01/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/01-01/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/01-01/main.ts b/public/docs/_examples/style-guide/ts/src/01-01/main.ts new file mode 100644 index 0000000000..7e8269bd65 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/01-01/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/style-guide/ts/src/02-05/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/02-05/app/app.component.ts new file mode 100644 index 0000000000..66ebfa954e --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/02-05/app/app.component.ts @@ -0,0 +1,10 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'toh-app', + template: ` + Tour of Heroes + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/02-05/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/02-05/app/app.module.ts new file mode 100644 index 0000000000..306ec125e0 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/02-05/app/app.module.ts @@ -0,0 +1,23 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule, + // #enddocregion + RouterModule.forChild([{ path: '02-05', component: AppComponent }]) + // #docregion + ], + declarations: [ + AppComponent + ], + exports: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +// #enddocregion diff --git a/public/docs/_examples/style-guide/ts/src/02-05/main.ts b/public/docs/_examples/style-guide/ts/src/02-05/main.ts new file mode 100644 index 0000000000..6c32161f84 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/02-05/main.ts @@ -0,0 +1,8 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule) + .then(success => console.log(`Bootstrap success`)) + .catch(err => console.error(err)); diff --git a/public/docs/_examples/style-guide/ts/src/02-07/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/02-07/app/app.component.ts new file mode 100644 index 0000000000..c82e12624d --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/02-07/app/app.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + template: ` + + + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/02-07/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/02-07/app/app.module.ts new file mode 100644 index 0000000000..4320fe67d5 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/02-07/app/app.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroComponent } from './heroes'; +import { UsersComponent } from './users'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '02-07', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HeroComponent, + UsersComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/02-07/app/heroes/hero.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/02-07/app/heroes/hero.component.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/02-07/app/heroes/hero.component.avoid.ts rename to public/docs/_examples/style-guide/ts/src/02-07/app/heroes/hero.component.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/02-07/app/heroes/hero.component.ts b/public/docs/_examples/style-guide/ts/src/02-07/app/heroes/hero.component.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/02-07/app/heroes/hero.component.ts rename to public/docs/_examples/style-guide/ts/src/02-07/app/heroes/hero.component.ts diff --git a/public/docs/_examples/style-guide/ts/02-07/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/02-07/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/02-07/app/heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/02-07/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/02-07/app/index.ts b/public/docs/_examples/style-guide/ts/src/02-07/app/index.ts new file mode 100644 index 0000000000..fc87f976b3 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/02-07/app/index.ts @@ -0,0 +1,3 @@ +export * from './heroes'; +export * from './users'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/02-07/app/users/index.ts b/public/docs/_examples/style-guide/ts/src/02-07/app/users/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/02-07/app/users/index.ts rename to public/docs/_examples/style-guide/ts/src/02-07/app/users/index.ts diff --git a/public/docs/_examples/style-guide/ts/02-07/app/users/users.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/02-07/app/users/users.component.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/02-07/app/users/users.component.avoid.ts rename to public/docs/_examples/style-guide/ts/src/02-07/app/users/users.component.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/02-07/app/users/users.component.ts b/public/docs/_examples/style-guide/ts/src/02-07/app/users/users.component.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/02-07/app/users/users.component.ts rename to public/docs/_examples/style-guide/ts/src/02-07/app/users/users.component.ts diff --git a/public/docs/_examples/style-guide/ts/src/02-08/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/02-08/app/app.component.ts new file mode 100644 index 0000000000..bf27aeaf8a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/02-08/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + template: '' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/02-08/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/02-08/app/app.module.ts new file mode 100644 index 0000000000..e840cc50a5 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/02-08/app/app.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { InputHighlightDirective, + ValidateDirective } from './shared'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '02-08', component: AppComponent }]) + ], + declarations: [ + AppComponent, + InputHighlightDirective, + ValidateDirective + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/src/02-08/app/index.ts b/public/docs/_examples/style-guide/ts/src/02-08/app/index.ts new file mode 100644 index 0000000000..ebe5c92f03 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/02-08/app/index.ts @@ -0,0 +1,2 @@ +export * from './shared'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/02-08/app/shared/index.ts b/public/docs/_examples/style-guide/ts/src/02-08/app/shared/index.ts new file mode 100644 index 0000000000..b844b75492 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/02-08/app/shared/index.ts @@ -0,0 +1,2 @@ +export * from './input-highlight.directive'; +export * from './validate.directive'; diff --git a/public/docs/_examples/style-guide/ts/src/02-08/app/shared/input-highlight.directive.ts b/public/docs/_examples/style-guide/ts/src/02-08/app/shared/input-highlight.directive.ts new file mode 100644 index 0000000000..fd74771981 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/02-08/app/shared/input-highlight.directive.ts @@ -0,0 +1,10 @@ +// #docregion +import { Directive, ElementRef } from '@angular/core'; + +@Directive({ selector: 'input'}) +/** Highlight the attached input text element in blue */ +export class InputHighlightDirective { + constructor(el: ElementRef) { + el.nativeElement.style.backgroundColor = 'powderblue'; + } +} diff --git a/public/docs/_examples/style-guide/ts/02-08/app/shared/validate.directive.avoid.ts b/public/docs/_examples/style-guide/ts/src/02-08/app/shared/validate.directive.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/02-08/app/shared/validate.directive.avoid.ts rename to public/docs/_examples/style-guide/ts/src/02-08/app/shared/validate.directive.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/02-08/app/shared/validate.directive.ts b/public/docs/_examples/style-guide/ts/src/02-08/app/shared/validate.directive.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/02-08/app/shared/validate.directive.ts rename to public/docs/_examples/style-guide/ts/src/02-08/app/shared/validate.directive.ts diff --git a/public/docs/_examples/style-guide/ts/src/03-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/03-01/app/app.component.ts new file mode 100644 index 0000000000..cb9479d2d9 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-01/app/app.component.ts @@ -0,0 +1,18 @@ +import { Component, OnInit } from '@angular/core'; + +import { ExceptionService } from './core'; + +@Component({ + selector: 'sg-app', + template: '
    The expected error is {{errorCode}}
    ', + providers: [ExceptionService] +}) +export class AppComponent implements OnInit { + errorCode: number; + + constructor(private exceptionService: ExceptionService) { } + + ngOnInit() { + this.errorCode = this.exceptionService.getException(); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/03-01/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/03-01/app/app.module.ts new file mode 100644 index 0000000000..48079f21c7 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-01/app/app.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '03-01', component: AppComponent }]) + ], + declarations: [ + AppComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/03-01/app/shared/exception.service.avoid.ts b/public/docs/_examples/style-guide/ts/src/03-01/app/core/exception.service.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-01/app/shared/exception.service.avoid.ts rename to public/docs/_examples/style-guide/ts/src/03-01/app/core/exception.service.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/03-01/app/shared/exception.service.ts b/public/docs/_examples/style-guide/ts/src/03-01/app/core/exception.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-01/app/shared/exception.service.ts rename to public/docs/_examples/style-guide/ts/src/03-01/app/core/exception.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-01/app/shared/index.ts b/public/docs/_examples/style-guide/ts/src/03-01/app/core/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-01/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/03-01/app/core/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/03-01/app/index.ts b/public/docs/_examples/style-guide/ts/src/03-01/app/index.ts new file mode 100644 index 0000000000..e120e2dbfd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-01/app/index.ts @@ -0,0 +1,2 @@ +export * from './core'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/03-02/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/03-02/app/app.component.ts new file mode 100644 index 0000000000..132ea54c85 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-02/app/app.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; + +import { heroesUrl, mockHeroes, VILLAINS_URL } from './core'; + +@Component({ + selector: 'sg-app', + template: ` +
    Heroes url: {{heroesUrl}}
    +
    Villains url: {{villainsUrl}}
    + +

    Mock Heroes

    +
    {{hero}}
    + ` +}) +export class AppComponent { + heroes = mockHeroes; // prefer + heroesUrl = heroesUrl; // prefer + villainsUrl = VILLAINS_URL; // tolerate +} diff --git a/public/docs/_examples/style-guide/ts/src/03-02/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/03-02/app/app.module.ts new file mode 100644 index 0000000000..2db4012ebf --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-02/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule, + RouterModule.forChild([{ path: '03-02', component: AppComponent }]) + ], + declarations: [ + AppComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/src/03-02/app/core/data.service.ts b/public/docs/_examples/style-guide/ts/src/03-02/app/core/data.service.ts new file mode 100644 index 0000000000..5c26478c7b --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-02/app/core/data.service.ts @@ -0,0 +1,4 @@ +// #docregion +export const mockHeroes = ['Sam', 'Jill']; // prefer +export const heroesUrl = 'api/heroes'; // prefer +export const VILLAINS_URL = 'api/villains'; // tolerate diff --git a/public/docs/_examples/style-guide/ts/03-02/app/shared/index.ts b/public/docs/_examples/style-guide/ts/src/03-02/app/core/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-02/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/03-02/app/core/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/03-02/app/index.ts b/public/docs/_examples/style-guide/ts/src/03-02/app/index.ts new file mode 100644 index 0000000000..e120e2dbfd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-02/app/index.ts @@ -0,0 +1,2 @@ +export * from './core'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/03-03/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/03-03/app/app.component.ts new file mode 100644 index 0000000000..3ca522bc45 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-03/app/app.component.ts @@ -0,0 +1,18 @@ +import { Component, OnInit } from '@angular/core'; + +import { Hero, HeroCollectorService } from './core'; + +@Component({ + selector: 'sg-app', + template: '
    Our hero is {{hero.name}} and {{hero.power}}
    ', + providers: [HeroCollectorService] +}) +export class AppComponent implements OnInit { + hero: Hero; + + constructor(private heroCollectorService: HeroCollectorService) { } + + ngOnInit() { + this.hero = this.heroCollectorService.getHero(); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/03-03/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/03-03/app/app.module.ts new file mode 100644 index 0000000000..29b3d2e765 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-03/app/app.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '03-03', component: AppComponent }]) + ], + declarations: [ + AppComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/03-03/app/shared/hero-collector.service.avoid.ts b/public/docs/_examples/style-guide/ts/src/03-03/app/core/hero-collector.service.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-03/app/shared/hero-collector.service.avoid.ts rename to public/docs/_examples/style-guide/ts/src/03-03/app/core/hero-collector.service.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/03-03/app/shared/hero-collector.service.ts b/public/docs/_examples/style-guide/ts/src/03-03/app/core/hero-collector.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-03/app/shared/hero-collector.service.ts rename to public/docs/_examples/style-guide/ts/src/03-03/app/core/hero-collector.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-03/app/shared/hero.model.avoid.ts b/public/docs/_examples/style-guide/ts/src/03-03/app/core/hero.model.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-03/app/shared/hero.model.avoid.ts rename to public/docs/_examples/style-guide/ts/src/03-03/app/core/hero.model.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/03-03/app/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/src/03-03/app/core/hero.model.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-03/app/shared/hero.model.ts rename to public/docs/_examples/style-guide/ts/src/03-03/app/core/hero.model.ts diff --git a/public/docs/_examples/style-guide/ts/03-03/app/shared/index.ts b/public/docs/_examples/style-guide/ts/src/03-03/app/core/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-03/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/03-03/app/core/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/03-03/app/index.ts b/public/docs/_examples/style-guide/ts/src/03-03/app/index.ts new file mode 100644 index 0000000000..e120e2dbfd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-03/app/index.ts @@ -0,0 +1,2 @@ +export * from './core'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/03-04/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/03-04/app/app.component.ts new file mode 100644 index 0000000000..555c9e9441 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-04/app/app.component.ts @@ -0,0 +1,27 @@ +import { Component, OnInit } from '@angular/core'; + +import { ToastService } from './core'; + +@Component({ + selector: 'sg-app', + template: ` + + + `, + providers: [ToastService] +}) +export class AppComponent implements OnInit { + constructor(private toastService: ToastService) { } + + hide() { + this.toastService.hide(); + } + + show() { + this.toastService.show(); + } + + ngOnInit() { + this.toastService.activate('Hello style-guide!'); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/03-04/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/03-04/app/app.module.ts new file mode 100644 index 0000000000..a5a8d5bb4e --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-04/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule, + RouterModule.forChild([{ path: '03-04', component: AppComponent }]) + ], + declarations: [ + AppComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/03-04/app/shared/index.ts b/public/docs/_examples/style-guide/ts/src/03-04/app/core/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-04/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/03-04/app/core/index.ts diff --git a/public/docs/_examples/style-guide/ts/03-04/app/shared/toast.service.avoid.ts b/public/docs/_examples/style-guide/ts/src/03-04/app/core/toast.service.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-04/app/shared/toast.service.avoid.ts rename to public/docs/_examples/style-guide/ts/src/03-04/app/core/toast.service.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/03-04/app/shared/toast.service.ts b/public/docs/_examples/style-guide/ts/src/03-04/app/core/toast.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-04/app/shared/toast.service.ts rename to public/docs/_examples/style-guide/ts/src/03-04/app/core/toast.service.ts diff --git a/public/docs/_examples/style-guide/ts/src/03-04/app/index.ts b/public/docs/_examples/style-guide/ts/src/03-04/app/index.ts new file mode 100644 index 0000000000..e120e2dbfd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-04/app/index.ts @@ -0,0 +1,2 @@ +export * from './core'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/03-05/app/app.component.html b/public/docs/_examples/style-guide/ts/src/03-06/app/app.component.html similarity index 100% rename from public/docs/_examples/style-guide/ts/03-05/app/app.component.html rename to public/docs/_examples/style-guide/ts/src/03-06/app/app.component.html diff --git a/public/docs/_examples/style-guide/ts/src/03-06/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/app.component.ts new file mode 100644 index 0000000000..8ec308bc6a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-06/app/app.component.ts @@ -0,0 +1,21 @@ +import { Component, OnInit } from '@angular/core'; + +import { Hero, HeroService } from './heroes'; +import { ExceptionService, SpinnerService, ToastService } from './core'; + +@Component({ + selector: 'sg-app', + templateUrl: './app.component.html', + providers: [HeroService, ExceptionService, SpinnerService, ToastService] +}) +export class AppComponent implements OnInit { + favorite: Hero; + heroes: Hero[]; + + constructor(private heroService: HeroService) { } + + ngOnInit() { + this.heroService.getHero(1).subscribe(hero => this.favorite = hero); + this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/03-06/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/app.module.ts new file mode 100644 index 0000000000..f259ce23a2 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-06/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule, + RouterModule.forChild([{ path: '03-06', component: AppComponent }]) + ], + declarations: [ + AppComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/exception.service.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/core/exception.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-05/app/shared/exception.service.ts rename to public/docs/_examples/style-guide/ts/src/03-06/app/core/exception.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/index.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/core/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-05/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/03-06/app/core/index.ts diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/index.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/core/spinner/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/index.ts rename to public/docs/_examples/style-guide/ts/src/03-06/app/core/spinner/index.ts diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/spinner.component.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/core/spinner/spinner.component.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/spinner.component.ts rename to public/docs/_examples/style-guide/ts/src/03-06/app/core/spinner/spinner.component.ts diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/spinner.service.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/core/spinner/spinner.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-05/app/shared/spinner/spinner.service.ts rename to public/docs/_examples/style-guide/ts/src/03-06/app/core/spinner/spinner.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/index.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/core/toast/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-05/app/shared/toast/index.ts rename to public/docs/_examples/style-guide/ts/src/03-06/app/core/toast/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/03-06/app/core/toast/toast.component.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/core/toast/toast.component.ts new file mode 100644 index 0000000000..dd0bba5eba --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-06/app/core/toast/toast.component.ts @@ -0,0 +1,13 @@ +import { Component, OnInit } from '@angular/core'; + +import { ToastService } from './toast.service'; + +@Component({ + selector: 'toh-toast', + template: '
    toast
    ' +}) +export class ToastComponent implements OnInit { + constructor(toastService: ToastService) { } + + ngOnInit() { } +} diff --git a/public/docs/_examples/style-guide/ts/03-05/app/shared/toast/toast.service.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/core/toast/toast.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-05/app/shared/toast/toast.service.ts rename to public/docs/_examples/style-guide/ts/src/03-06/app/core/toast/toast.service.ts diff --git a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/index.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-05/app/+heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/03-06/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/heroes/shared/hero.model.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/hero.model.ts rename to public/docs/_examples/style-guide/ts/src/03-06/app/heroes/shared/hero.model.ts diff --git a/public/docs/_examples/style-guide/ts/src/03-06/app/heroes/shared/hero.service.avoid.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/heroes/shared/hero.service.avoid.ts new file mode 100644 index 0000000000..8287c567a7 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-06/app/heroes/shared/hero.service.avoid.ts @@ -0,0 +1,32 @@ +// #docregion +// #docregion example +/* avoid */ + +import { ExceptionService, SpinnerService, ToastService } from '../../core'; +import { Http } from '@angular/http'; +import { Injectable } from '@angular/core'; +import { Hero } from './hero.model'; +// #enddocregion example + +@Injectable() +export class HeroService { + + constructor( + private exceptionService: ExceptionService, + private spinnerService: SpinnerService, + private toastService: ToastService, + private http: Http + ) { } + + getHero(id: number) { + return this.http.get(`api/heroes/${id}`) + .map(response => response.json().data as Hero); + } + + getHeroes() { + return this.http.get(`api/heroes`) + .map(response => response.json().data as Hero[]); + } + +} + diff --git a/public/docs/_examples/style-guide/ts/src/03-06/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/heroes/shared/hero.service.ts new file mode 100644 index 0000000000..5792cd1ab2 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-06/app/heroes/shared/hero.service.ts @@ -0,0 +1,32 @@ +// #docregion +// #docregion example +import { Injectable } from '@angular/core'; +import { Http } from '@angular/http'; + +import { Hero } from './hero.model'; +import { ExceptionService, SpinnerService, ToastService } from '../../core'; +// #enddocregion example + +@Injectable() +export class HeroService { + cachedHeroes: Hero[]; + + constructor( + private exceptionService: ExceptionService, + private spinnerService: SpinnerService, + private toastService: ToastService, + private http: Http + ) { } + + getHero(id: number) { + return this.http.get(`api/heroes/${id}`) + .map(response => response.json().data as Hero); + } + + getHeroes() { + return this.http.get(`api/heroes`) + .map(response => response.json().data as Hero[]); + } + +} + diff --git a/public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-05/app/+heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/03-06/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/03-06/app/index.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/index.ts new file mode 100644 index 0000000000..cf861e261a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-06/app/index.ts @@ -0,0 +1,3 @@ +export * from './heroes'; +export * from './core'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/03-06/app/shared/toast/toast.component.ts b/public/docs/_examples/style-guide/ts/src/03-06/app/shared/toast/toast.component.ts new file mode 100644 index 0000000000..e1c1ae6665 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/03-06/app/shared/toast/toast.component.ts @@ -0,0 +1,13 @@ +import { Component, OnInit } from '@angular/core'; + +import { ToastService } from '../../core'; + +@Component({ + selector: 'toh-toast', + template: '
    toast
    ' +}) +export class ToastComponent implements OnInit { + constructor(toastService: ToastService) { } + + ngOnInit() { } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-08/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/04-08/app/app.component.ts new file mode 100644 index 0000000000..fdd8e6ef56 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-08/app/app.component.ts @@ -0,0 +1,8 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + template: '' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/04-08/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/04-08/app/app.module.ts new file mode 100644 index 0000000000..25568b7fb4 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-08/app/app.module.ts @@ -0,0 +1,28 @@ +// #docplaster +// #docregion +// #docregion example +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +// #enddocregion example +import { RouterModule } from '@angular/router'; +// #docregion example + +import { AppComponent } from './app.component'; +import { HeroesComponent } from './heroes/heroes.component'; + +@NgModule({ + imports: [ + BrowserModule, +// #enddocregion example + RouterModule.forChild([{ path: '04-08', component: AppComponent }]) +// #docregion example + ], + declarations: [ + AppComponent, + HeroesComponent + ], + exports: [ AppComponent ], + entryComponents: [ AppComponent ] +}) +export class AppModule {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-10/app/+heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/src/04-08/app/heroes/heroes.component.html similarity index 100% rename from public/docs/_examples/style-guide/ts/04-10/app/+heroes/heroes.component.html rename to public/docs/_examples/style-guide/ts/src/04-08/app/heroes/heroes.component.html diff --git a/public/docs/_examples/style-guide/ts/src/04-08/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/src/04-08/app/heroes/heroes.component.ts new file mode 100644 index 0000000000..e2df4c91fd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-08/app/heroes/heroes.component.ts @@ -0,0 +1,11 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'toh-heroes', + templateUrl: './heroes.component.html' +}) +export class HeroesComponent implements OnInit { + constructor() { /* ... */ } + + ngOnInit() { /* ... */ } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-10/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/04-10/app/app.component.ts new file mode 100644 index 0000000000..fdd8e6ef56 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-10/app/app.component.ts @@ -0,0 +1,8 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + template: '' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/04-10/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/04-10/app/app.module.ts new file mode 100644 index 0000000000..78106657ad --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-10/app/app.module.ts @@ -0,0 +1,30 @@ +// #docplaster +// #docregion +// #docregion example +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +// #enddocregion example +import { RouterModule } from '@angular/router'; +// #docregion example + +import { AppComponent } from './app.component'; +import { HeroesComponent } from './heroes/heroes.component'; +import { SharedModule } from './shared/shared.module'; + +@NgModule({ + imports: [ + BrowserModule, + SharedModule, +// #enddocregion example + RouterModule.forChild([{ path: '04-10', component: AppComponent }]) +// #docregion example + ], + declarations: [ + AppComponent, + HeroesComponent + ], + exports: [ AppComponent ], + entryComponents: [ AppComponent ] +}) +export class AppModule {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/src/04-10/app/heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/src/04-10/app/heroes/heroes.component.html new file mode 100644 index 0000000000..170f76aee1 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-10/app/heroes/heroes.component.html @@ -0,0 +1,8 @@ + +
    This is heroes component
    +
      +
    • + {{hero.name}} +
    • +
    + diff --git a/public/docs/_examples/style-guide/ts/src/04-10/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/src/04-10/app/heroes/heroes.component.ts new file mode 100644 index 0000000000..376567650e --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-10/app/heroes/heroes.component.ts @@ -0,0 +1,27 @@ +// #docregion +import { Component } from '@angular/core'; + +import { FilterTextService } from '../shared/filter-text/filter-text.service'; + +@Component({ + selector: 'toh-heroes', + templateUrl: './heroes.component.html' +}) +export class HeroesComponent { + + heroes = [ + { id: 1, name: 'Windstorm' }, + { id: 2, name: 'Bombasto' }, + { id: 3, name: 'Magneta' }, + { id: 4, name: 'Tornado' } + ]; + + filteredHeroes = this.heroes; + + constructor(private filterService: FilterTextService) { } + + filterChanged(searchText: string) { + this.filteredHeroes = this.filterService.filter(searchText, ['id', 'name'], this.heroes); + } +} + diff --git a/public/docs/_examples/style-guide/ts/src/04-10/app/shared/filter-text/filter-text.component.ts b/public/docs/_examples/style-guide/ts/src/04-10/app/shared/filter-text/filter-text.component.ts new file mode 100644 index 0000000000..fffe4bf0b7 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-10/app/shared/filter-text/filter-text.component.ts @@ -0,0 +1,26 @@ +// #docregion +import { Component, EventEmitter, Output } from '@angular/core'; + +@Component({ + selector: 'toh-filter-text', + template: '' +}) +export class FilterTextComponent { + @Output() changed: EventEmitter; + + filter: string; + + constructor() { + this.changed = new EventEmitter(); + } + + clear() { + this.filter = ''; + } + + filterChanged(event: any) { + event.preventDefault(); + console.log(`Filter Changed: ${this.filter}`); + this.changed.emit(this.filter); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-10/app/shared/filter-text/filter-text.service.ts b/public/docs/_examples/style-guide/ts/src/04-10/app/shared/filter-text/filter-text.service.ts new file mode 100644 index 0000000000..87978e10e5 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-10/app/shared/filter-text/filter-text.service.ts @@ -0,0 +1,30 @@ +// #docregion +import { Injectable } from '@angular/core'; + +@Injectable() +export class FilterTextService { + constructor() { + console.log('Created an instance of FilterTextService'); + } + + filter(data: string, props: Array, originalList: Array) { + let filteredList: any[]; + if (data && props && originalList) { + data = data.toLowerCase(); + let filtered = originalList.filter(item => { + let match = false; + for (let prop of props) { + if (item[prop].toString().toLowerCase().indexOf(data) > -1) { + match = true; + break; + } + }; + return match; + }); + filteredList = filtered; + } else { + filteredList = originalList; + } + return filteredList; + } +} diff --git a/public/docs/_examples/style-guide/ts/04-10/app/shared/init-caps.pipe.ts b/public/docs/_examples/style-guide/ts/src/04-10/app/shared/init-caps.pipe.ts similarity index 92% rename from public/docs/_examples/style-guide/ts/04-10/app/shared/init-caps.pipe.ts rename to public/docs/_examples/style-guide/ts/src/04-10/app/shared/init-caps.pipe.ts index a7bd0c6521..5019bcb234 100644 --- a/public/docs/_examples/style-guide/ts/04-10/app/shared/init-caps.pipe.ts +++ b/public/docs/_examples/style-guide/ts/src/04-10/app/shared/init-caps.pipe.ts @@ -1,8 +1,7 @@ +// #docregion import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'initCaps' }) export class InitCapsPipe implements PipeTransform { transform = (value: string) => value; } - - diff --git a/public/docs/_examples/style-guide/ts/src/04-10/app/shared/shared.module.ts b/public/docs/_examples/style-guide/ts/src/04-10/app/shared/shared.module.ts new file mode 100644 index 0000000000..6160abcc84 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-10/app/shared/shared.module.ts @@ -0,0 +1,24 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { FilterTextComponent } from './filter-text/filter-text.component'; +import { FilterTextService } from './filter-text/filter-text.service'; +import { InitCapsPipe } from './init-caps.pipe'; + +@NgModule({ + imports: [CommonModule, FormsModule], + declarations: [ + FilterTextComponent, + InitCapsPipe + ], + providers: [FilterTextService], + exports: [ + CommonModule, + FormsModule, + FilterTextComponent, + InitCapsPipe + ] +}) +export class SharedModule { } diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/04-11/app/app.component.ts new file mode 100644 index 0000000000..693619a982 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/app.component.ts @@ -0,0 +1,12 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'toh-app', + template: ` + + + + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/04-11/app/app.module.ts new file mode 100644 index 0000000000..ef3c156bcf --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/app.module.ts @@ -0,0 +1,30 @@ +// #docplaster +// #docregion +// #docregion example +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +// #enddocregion example +import { RouterModule } from '@angular/router'; +// #docregion example + +import { AppComponent } from './app.component'; +import { HeroesComponent } from './heroes/heroes.component'; +import { CoreModule } from './core/core.module'; + +@NgModule({ + imports: [ + BrowserModule, + CoreModule, +// #enddocregion example + RouterModule.forChild([{ path: '04-11', component: AppComponent }]) +// #docregion example + ], + declarations: [ + AppComponent, + HeroesComponent + ], + exports: [ AppComponent ], + entryComponents: [ AppComponent ] +}) +export class AppModule {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/core/core.module.ts b/public/docs/_examples/style-guide/ts/src/04-11/app/core/core.module.ts new file mode 100644 index 0000000000..4ba5c79a14 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/core/core.module.ts @@ -0,0 +1,19 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { LoggerService } from './logger.service'; +import { NavComponent } from './nav/nav.component'; +import { SpinnerComponent } from './spinner/spinner.component'; +import { SpinnerService } from './spinner/spinner.service'; + +@NgModule({ + imports: [ + CommonModule // we use ngFor + ], +  exports: [NavComponent, SpinnerComponent], +  declarations: [NavComponent, SpinnerComponent], + providers: [LoggerService, SpinnerService] +}) +export class CoreModule { } + diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/core/index.ts b/public/docs/_examples/style-guide/ts/src/04-11/app/core/index.ts new file mode 100644 index 0000000000..098f40c7d5 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/core/index.ts @@ -0,0 +1,4 @@ +// #docregion +export * from './logger.service'; +export * from './spinner/spinner.service'; +export * from './nav/nav.component'; diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/core/logger.service.ts b/public/docs/_examples/style-guide/ts/src/04-11/app/core/logger.service.ts new file mode 100644 index 0000000000..9c7080f07a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/core/logger.service.ts @@ -0,0 +1,13 @@ +// #docregion +import { Injectable } from '@angular/core'; + +@Injectable() +export class LoggerService { + log(msg: string) { + console.log(msg); + } + + error(msg: string) { + console.error(msg); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/core/nav/nav.component.css b/public/docs/_examples/style-guide/ts/src/04-11/app/core/nav/nav.component.css new file mode 100644 index 0000000000..c7903fd25c --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/core/nav/nav.component.css @@ -0,0 +1,63 @@ +/*#docregion*/ +.mdl-layout__header { + display: flex; + position: fixed; + background-color: #222; +} + +.nav-link { + padding: 0 1em; + width: 100px; + color: rgba(255,255,255,.6); + text-align: center; + text-decoration: none; +} + +.nav-link.router-link-active { + color: rgba(255,255,255, 1); +} + +.nav-link.router-link-active::after { + height: 3px; + width: 100%; + display: block; + content: " "; + bottom: 0; + left: 0; + position: inherit; + background: rgb(83,109,254); +} + +.md-title-icon > i { + background-image: url("assets/ng.png"); + background-repeat: no-repeat; + background-position: center center; + padding: 1em 2em; +} + +.mdl-layout__header-row { + height: 56px; + padding: 0 16px 0 72px; + padding-left: 8px; + background-color: #673AB7; + background: #0033FF; + background-color: #222; +} + +#reset-button { + position: fixed; + right: 2em; + top: 1em; +} + +@media (max-width: 480px) { + #reset-button { + display: none + } +} + +@media (max-width: 320px) { + a.nav-link { + font-size: 12px; + } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/core/nav/nav.component.html b/public/docs/_examples/style-guide/ts/src/04-11/app/core/nav/nav.component.html new file mode 100644 index 0000000000..b3c7e441e0 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/core/nav/nav.component.html @@ -0,0 +1,14 @@ + +
    +
    +

    Tour of Heroes

    +
    + +
    +
    diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/core/nav/nav.component.ts b/public/docs/_examples/style-guide/ts/src/04-11/app/core/nav/nav.component.ts new file mode 100644 index 0000000000..7e21016e2b --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/core/nav/nav.component.ts @@ -0,0 +1,19 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'toh-nav', + templateUrl: './nav.component.html', + styleUrls: ['./nav.component.css'], +}) +export class NavComponent implements OnInit { + menuItems = [ + 'Heroes', + 'Villains', + 'Other' + ]; + + ngOnInit() { } + + constructor() { } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.component.css b/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.component.css new file mode 100644 index 0000000000..afad0fe8e3 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.component.css @@ -0,0 +1,21 @@ +/*#docregion*/ +.spinner { + position: absolute; + left: 7em; + top: 20em; + position: absolute; + background-color: blue; + height: .3em; + width: 6em; + margin:-60px 0 0 -60px; + -webkit-animation:spin 4s linear infinite; + -moz-animation:spin 4s linear infinite; + animation:spin 4s linear infinite; +} +@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } } +@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } } +@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } } + +.spinner-hidden { + display:none; +} diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.component.html b/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.component.html new file mode 100644 index 0000000000..a07e3378c0 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.component.html @@ -0,0 +1,2 @@ + +
    diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.component.ts b/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.component.ts new file mode 100644 index 0000000000..de24167a2b --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.component.ts @@ -0,0 +1,35 @@ +// #docregion +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs/Subscription'; + +import { LoggerService } from '../logger.service'; +import { SpinnerState, SpinnerService } from './spinner.service'; + +@Component({ + selector: 'toh-spinner', + templateUrl: './spinner.component.html', + styleUrls: ['./spinner.component.css'] +}) +export class SpinnerComponent implements OnDestroy, OnInit { + visible = false; + + private spinnerStateChanged: Subscription; + + constructor( + private loggerService: LoggerService, + private spinnerService: SpinnerService + ) { } + + ngOnInit() { + console.log(this.visible); + this.spinnerStateChanged = this.spinnerService.spinnerState + .subscribe((state: SpinnerState) => { + this.visible = state.show; + this.loggerService.log(`visible=${this.visible}`); + }); + } + + ngOnDestroy() { + this.spinnerStateChanged.unsubscribe(); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.service.ts b/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.service.ts new file mode 100644 index 0000000000..85e366c43e --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/core/spinner/spinner.service.ts @@ -0,0 +1,24 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { Subject } from 'rxjs/Subject'; + +export interface SpinnerState { + show: boolean; +} + +@Injectable() +export class SpinnerService { + private spinnerSubject = new Subject(); + + spinnerState = this.spinnerSubject.asObservable(); + + constructor() { } + + show() { + this.spinnerSubject.next({ show: true }); + } + + hide() { + this.spinnerSubject.next({ show: false }); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/src/04-11/app/heroes/heroes.component.html new file mode 100644 index 0000000000..9035a4b8ff --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/heroes/heroes.component.html @@ -0,0 +1,12 @@ + +
    + + + +
      +
    • + {{hero.name}} +
    • +
    + +
    diff --git a/public/docs/_examples/style-guide/ts/src/04-11/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/src/04-11/app/heroes/heroes.component.ts new file mode 100644 index 0000000000..856baadd74 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-11/app/heroes/heroes.component.ts @@ -0,0 +1,32 @@ +import { Component } from '@angular/core'; + +import { LoggerService } from '../core/logger.service'; +import { SpinnerService } from '../core/spinner/spinner.service'; + +@Component({ + selector: 'toh-heroes', + templateUrl: './heroes.component.html' +}) +export class HeroesComponent { + heroes: any[]; + + constructor( + private loggerService: LoggerService, + private spinnerService: SpinnerService + ) { } + + getHeroes() { + this.loggerService.log(`Getting heroes`); + this.spinnerService.show(); + setTimeout(() => { + this.heroes = [ + { id: 1, name: 'Windstorm' }, + { id: 2, name: 'Bombasto' }, + { id: 3, name: 'Magneta' }, + { id: 4, name: 'Tornado' } + ]; + this.loggerService.log(`We have ${HeroesComponent.length} heroes`); + this.spinnerService.hide(); + }, 2000); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-12/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/04-12/app/app.component.ts new file mode 100644 index 0000000000..dc85b06e9f --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-12/app/app.component.ts @@ -0,0 +1,11 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'toh-app', + template: ` + + + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/04-12/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/04-12/app/app.module.ts new file mode 100644 index 0000000000..7c9fb44182 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-12/app/app.module.ts @@ -0,0 +1,30 @@ +// #docplaster +// #docregion +// #docregion example +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +// #enddocregion example +import { RouterModule } from '@angular/router'; +// #docregion example + +import { AppComponent } from './app.component'; +import { HeroesComponent } from './heroes/heroes.component'; +import { CoreModule } from './core/core.module'; + +@NgModule({ + imports: [ + BrowserModule, + CoreModule, +// #enddocregion example + RouterModule.forChild([{ path: '04-12', component: AppComponent }]) +// #docregion example + ], + declarations: [ + AppComponent, + HeroesComponent + ], + exports: [ AppComponent ], + entryComponents: [ AppComponent ] +}) +export class AppModule {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/src/04-12/app/core/core.module.ts b/public/docs/_examples/style-guide/ts/src/04-12/app/core/core.module.ts new file mode 100644 index 0000000000..069141bf2a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-12/app/core/core.module.ts @@ -0,0 +1,21 @@ +// #docregion +import { NgModule, Optional, SkipSelf } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { LoggerService } from './logger.service'; +import { NavComponent } from './nav/nav.component'; +import { throwIfAlreadyLoaded } from './module-import-guard'; + +@NgModule({ + imports: [ + CommonModule // we use ngFor + ], +  exports: [NavComponent], +  declarations: [NavComponent], + providers: [LoggerService] +}) +export class CoreModule { + constructor( @Optional() @SkipSelf() parentModule: CoreModule) { + throwIfAlreadyLoaded(parentModule, 'CoreModule'); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-12/app/core/index.ts b/public/docs/_examples/style-guide/ts/src/04-12/app/core/index.ts new file mode 100644 index 0000000000..8768b77f41 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-12/app/core/index.ts @@ -0,0 +1,3 @@ +// #docregion +export * from './logger.service'; +export * from './nav/nav.component'; diff --git a/public/docs/_examples/style-guide/ts/src/04-12/app/core/logger.service.ts b/public/docs/_examples/style-guide/ts/src/04-12/app/core/logger.service.ts new file mode 100644 index 0000000000..9c7080f07a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-12/app/core/logger.service.ts @@ -0,0 +1,13 @@ +// #docregion +import { Injectable } from '@angular/core'; + +@Injectable() +export class LoggerService { + log(msg: string) { + console.log(msg); + } + + error(msg: string) { + console.error(msg); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-12/app/core/module-import-guard.ts b/public/docs/_examples/style-guide/ts/src/04-12/app/core/module-import-guard.ts new file mode 100644 index 0000000000..5248b15b2e --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-12/app/core/module-import-guard.ts @@ -0,0 +1,6 @@ +// #docregion +export function throwIfAlreadyLoaded(parentModule: any, moduleName: string) { + if (parentModule) { + throw new Error(`${moduleName} has already been loaded. Import Core modules in the AppModule only.`); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-12/app/core/nav/nav.component.css b/public/docs/_examples/style-guide/ts/src/04-12/app/core/nav/nav.component.css new file mode 100644 index 0000000000..c7903fd25c --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-12/app/core/nav/nav.component.css @@ -0,0 +1,63 @@ +/*#docregion*/ +.mdl-layout__header { + display: flex; + position: fixed; + background-color: #222; +} + +.nav-link { + padding: 0 1em; + width: 100px; + color: rgba(255,255,255,.6); + text-align: center; + text-decoration: none; +} + +.nav-link.router-link-active { + color: rgba(255,255,255, 1); +} + +.nav-link.router-link-active::after { + height: 3px; + width: 100%; + display: block; + content: " "; + bottom: 0; + left: 0; + position: inherit; + background: rgb(83,109,254); +} + +.md-title-icon > i { + background-image: url("assets/ng.png"); + background-repeat: no-repeat; + background-position: center center; + padding: 1em 2em; +} + +.mdl-layout__header-row { + height: 56px; + padding: 0 16px 0 72px; + padding-left: 8px; + background-color: #673AB7; + background: #0033FF; + background-color: #222; +} + +#reset-button { + position: fixed; + right: 2em; + top: 1em; +} + +@media (max-width: 480px) { + #reset-button { + display: none + } +} + +@media (max-width: 320px) { + a.nav-link { + font-size: 12px; + } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-12/app/core/nav/nav.component.html b/public/docs/_examples/style-guide/ts/src/04-12/app/core/nav/nav.component.html new file mode 100644 index 0000000000..b3c7e441e0 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-12/app/core/nav/nav.component.html @@ -0,0 +1,14 @@ + +
    +
    +

    Tour of Heroes

    +
    + +
    +
    diff --git a/public/docs/_examples/style-guide/ts/src/04-12/app/core/nav/nav.component.ts b/public/docs/_examples/style-guide/ts/src/04-12/app/core/nav/nav.component.ts new file mode 100644 index 0000000000..7e21016e2b --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-12/app/core/nav/nav.component.ts @@ -0,0 +1,19 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'toh-nav', + templateUrl: './nav.component.html', + styleUrls: ['./nav.component.css'], +}) +export class NavComponent implements OnInit { + menuItems = [ + 'Heroes', + 'Villains', + 'Other' + ]; + + ngOnInit() { } + + constructor() { } +} diff --git a/public/docs/_examples/style-guide/ts/src/04-12/app/heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/src/04-12/app/heroes/heroes.component.html new file mode 100644 index 0000000000..9035a4b8ff --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-12/app/heroes/heroes.component.html @@ -0,0 +1,12 @@ + +
    + + + +
      +
    • + {{hero.name}} +
    • +
    + +
    diff --git a/public/docs/_examples/style-guide/ts/src/04-12/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/src/04-12/app/heroes/heroes.component.ts new file mode 100644 index 0000000000..f84b16c140 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/04-12/app/heroes/heroes.component.ts @@ -0,0 +1,24 @@ +import { Component } from '@angular/core'; + +import { LoggerService } from '../core/logger.service'; + +@Component({ + selector: 'toh-heroes', + templateUrl: './heroes.component.html' +}) +export class HeroesComponent { + heroes: any[]; + + constructor(private loggerService: LoggerService) { } + + getHeroes() { + this.loggerService.log(`Getting heroes`); + this.heroes = [ + { id: 1, name: 'Windstorm' }, + { id: 2, name: 'Bombasto' }, + { id: 3, name: 'Magneta' }, + { id: 4, name: 'Tornado' } + ]; + this.loggerService.log(`We have ${HeroesComponent.length} heroes`); + } +} diff --git a/public/docs/_examples/style-guide/ts/05-02/app/app.component.html b/public/docs/_examples/style-guide/ts/src/05-02/app/app.component.html similarity index 100% rename from public/docs/_examples/style-guide/ts/05-02/app/app.component.html rename to public/docs/_examples/style-guide/ts/src/05-02/app/app.component.html diff --git a/public/docs/_examples/style-guide/ts/src/05-02/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/05-02/app/app.component.ts new file mode 100644 index 0000000000..7c9f37919f --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-02/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + templateUrl: './app.component.html' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/05-02/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/05-02/app/app.module.ts new file mode 100644 index 0000000000..1c458e2ca1 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-02/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroButtonComponent } from './heroes'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '05-02', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HeroButtonComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/index.ts b/public/docs/_examples/style-guide/ts/src/05-02/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-06/app/+heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/05-02/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts new file mode 100644 index 0000000000..e48d41f721 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts @@ -0,0 +1,11 @@ +// #docplaster +import { Component } from '@angular/core'; +// #docregion example +/* avoid */ + +@Component({ + selector: 'tohHeroButton', + templateUrl: './hero-button.component.html' +}) +export class HeroButtonComponent {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/hero-button/hero-button.component.html b/public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/hero-button/hero-button.component.html similarity index 100% rename from public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/hero-button/hero-button.component.html rename to public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/hero-button/hero-button.component.html diff --git a/public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/hero-button/hero-button.component.ts b/public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/hero-button/hero-button.component.ts new file mode 100644 index 0000000000..c90c966f1a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/hero-button/hero-button.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +// #docregion example +@Component({ + selector: 'toh-hero-button', + templateUrl: './hero-button.component.html' +}) +export class HeroButtonComponent {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/hero-button/index.ts b/public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/hero-button/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/hero-button/index.ts rename to public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/hero-button/index.ts diff --git a/public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-02/app/heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/05-02/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-02/app/index.ts b/public/docs/_examples/style-guide/ts/src/05-02/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-02/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/05-03/app/app.component.avoid.html b/public/docs/_examples/style-guide/ts/src/05-03/app/app.component.avoid.html similarity index 100% rename from public/docs/_examples/style-guide/ts/05-03/app/app.component.avoid.html rename to public/docs/_examples/style-guide/ts/src/05-03/app/app.component.avoid.html diff --git a/public/docs/_examples/style-guide/ts/05-03/app/app.component.html b/public/docs/_examples/style-guide/ts/src/05-03/app/app.component.html similarity index 100% rename from public/docs/_examples/style-guide/ts/05-03/app/app.component.html rename to public/docs/_examples/style-guide/ts/src/05-03/app/app.component.html diff --git a/public/docs/_examples/style-guide/ts/src/05-03/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/05-03/app/app.component.ts new file mode 100644 index 0000000000..7c9f37919f --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-03/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + templateUrl: './app.component.html' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/05-03/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/05-03/app/app.module.ts new file mode 100644 index 0000000000..1b754e3ee5 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-03/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroButtonComponent } from './heroes'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '05-03', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HeroButtonComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/05-02/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/05-03/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-02/app/heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/05-03/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/hero-button/hero-button.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/hero-button/hero-button.component.avoid.ts new file mode 100644 index 0000000000..74f5c36339 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/hero-button/hero-button.component.avoid.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +// #docregion example +/* avoid */ + +@Component({ + selector: '[tohHeroButton]', + templateUrl: './hero-button.component.html' +}) +export class HeroButtonComponent {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/hero-button/hero-button.component.html b/public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/hero-button/hero-button.component.html similarity index 100% rename from public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/hero-button/hero-button.component.html rename to public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/hero-button/hero-button.component.html diff --git a/public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/hero-button/hero-button.component.ts b/public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/hero-button/hero-button.component.ts new file mode 100644 index 0000000000..c90c966f1a --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/hero-button/hero-button.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +// #docregion example +@Component({ + selector: 'toh-hero-button', + templateUrl: './hero-button.component.html' +}) +export class HeroButtonComponent {} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/hero-button/index.ts b/public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/hero-button/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/hero-button/index.ts rename to public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/hero-button/index.ts diff --git a/public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-03/app/heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/05-03/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-03/app/index.ts b/public/docs/_examples/style-guide/ts/src/05-03/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-03/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/05-04/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/05-04/app/app.component.ts new file mode 100644 index 0000000000..0e43893f7f --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-04/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + template: '' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/05-04/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/05-04/app/app.module.ts new file mode 100644 index 0000000000..07f97cc6e4 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-04/app/app.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroesComponent } from './heroes'; +import { HeroService } from './heroes/shared'; + +@NgModule({ + imports: [ + BrowserModule, + RouterModule.forChild([{ path: '05-04', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HeroesComponent + ], + exports: [ AppComponent ], + providers: [ HeroService ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/heroes.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/heroes.component.avoid.ts new file mode 100644 index 0000000000..0ceb37032d --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/heroes.component.avoid.ts @@ -0,0 +1,64 @@ +import { Component, OnInit } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; + +import { Hero, HeroService } from './shared'; + +// #docregion example +/* avoid */ + +@Component({ + selector: 'toh-heroes', + template: ` +
    +

    My Heroes

    +
      +
    • + {{hero.id}} {{hero.name}} +
    • +
    +
    +

    {{selectedHero.name | uppercase}} is my hero

    +
    +
    + `, + styles: [` + .heroes { + margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 15em; + } + .heroes li { + cursor: pointer; + position: relative; + left: 0; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; + } + .heroes .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0 0 4px; + } + `] +}) +export class HeroesComponent implements OnInit { + heroes: Observable; + selectedHero: Hero; + + constructor(private heroService: HeroService) { } + + ngOnInit() { + this.heroes = this.heroService.getHeroes(); + } +} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.css b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/heroes.component.css similarity index 100% rename from public/docs/_examples/style-guide/ts/04-14/app/+heroes/heroes.component.css rename to public/docs/_examples/style-guide/ts/src/05-04/app/heroes/heroes.component.css diff --git a/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/heroes.component.html b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/heroes.component.html new file mode 100644 index 0000000000..bab05ceb2b --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/heroes.component.html @@ -0,0 +1,12 @@ + +
    +

    My Heroes

    +
      +
    • + {{hero.id}} {{hero.name}} +
    • +
    +
    +

    {{selectedHero.name | uppercase}} is my hero

    +
    +
    diff --git a/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/heroes.component.ts b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/heroes.component.ts new file mode 100644 index 0000000000..c19bc997ae --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/heroes.component.ts @@ -0,0 +1,22 @@ +import { Component, OnInit } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; + +import { Hero, HeroService } from './shared'; + +// #docregion example +@Component({ + selector: 'toh-heroes', + templateUrl: './heroes.component.html', + styleUrls: ['./heroes.component.css'] +}) +export class HeroesComponent implements OnInit { + heroes: Observable; + selectedHero: Hero; + + constructor(private heroService: HeroService) { } + + ngOnInit() { + this.heroes = this.heroService.getHeroes(); + } +} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/index.ts b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/04-14/app/+heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/05-04/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/shared/hero.model.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/04-14/app/+heroes/shared/hero.model.ts rename to public/docs/_examples/style-guide/ts/src/05-04/app/heroes/shared/hero.model.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/shared/hero.service.ts new file mode 100644 index 0000000000..9d388780a6 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/shared/hero.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@angular/core'; +import { Http } from '@angular/http'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/map'; + +import { Hero } from './hero.model'; + +@Injectable() +export class HeroService { + + constructor(private http: Http) {} + + getHeroes(): Observable { + return this.http.get('api/heroes') + .map(resp => resp.json().data as Hero[]); + } +} diff --git a/public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/05-04/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/03-06/app/+heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/05-04/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-04/app/index.ts b/public/docs/_examples/style-guide/ts/src/05-04/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-04/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/05-12/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/05-12/app/app.component.ts new file mode 100644 index 0000000000..dac40205c9 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-12/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + template: '' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/05-12/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/05-12/app/app.module.ts new file mode 100644 index 0000000000..5177b2cc64 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-12/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroButtonComponent } from './heroes'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '05-12', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HeroButtonComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/05-03/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/05-12/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-03/app/heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/05-12/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/05-12/app/heroes/shared/hero-button/hero-button.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/05-12/app/heroes/shared/hero-button/hero-button.component.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-12/app/heroes/shared/hero-button/hero-button.component.avoid.ts rename to public/docs/_examples/style-guide/ts/src/05-12/app/heroes/shared/hero-button/hero-button.component.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/05-12/app/heroes/shared/hero-button/hero-button.component.ts b/public/docs/_examples/style-guide/ts/src/05-12/app/heroes/shared/hero-button/hero-button.component.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-12/app/heroes/shared/hero-button/hero-button.component.ts rename to public/docs/_examples/style-guide/ts/src/05-12/app/heroes/shared/hero-button/hero-button.component.ts diff --git a/public/docs/_examples/style-guide/ts/05-12/app/heroes/shared/hero-button/index.ts b/public/docs/_examples/style-guide/ts/src/05-12/app/heroes/shared/hero-button/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-12/app/heroes/shared/hero-button/index.ts rename to public/docs/_examples/style-guide/ts/src/05-12/app/heroes/shared/hero-button/index.ts diff --git a/public/docs/_examples/style-guide/ts/05-12/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/05-12/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-12/app/heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/05-12/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-12/app/index.ts b/public/docs/_examples/style-guide/ts/src/05-12/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-12/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/05-13/app/app.component.avoid.html b/public/docs/_examples/style-guide/ts/src/05-13/app/app.component.avoid.html similarity index 100% rename from public/docs/_examples/style-guide/ts/05-13/app/app.component.avoid.html rename to public/docs/_examples/style-guide/ts/src/05-13/app/app.component.avoid.html diff --git a/public/docs/_examples/style-guide/ts/src/05-13/app/app.component.html b/public/docs/_examples/style-guide/ts/src/05-13/app/app.component.html new file mode 100644 index 0000000000..3cd94ca772 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-13/app/app.component.html @@ -0,0 +1,6 @@ + + + + + +

    The Great Bombasto

    diff --git a/public/docs/_examples/style-guide/ts/src/05-13/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/05-13/app/app.component.ts new file mode 100644 index 0000000000..7c9f37919f --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-13/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + templateUrl: './app.component.html' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/05-13/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/05-13/app/app.module.ts new file mode 100644 index 0000000000..7ebe91dbbc --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-13/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroButtonComponent, HeroHighlightDirective } from './heroes'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '05-13', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HeroButtonComponent, HeroHighlightDirective + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/05-12/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-12/app/heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/05-13/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts new file mode 100644 index 0000000000..4e67a14113 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts @@ -0,0 +1,14 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; +// #docregion example +/* avoid pointless aliasing */ + +@Component({ + selector: 'toh-hero-button', + template: `` +}) +export class HeroButtonComponent { + // Pointless aliases + @Output('changeEvent') change = new EventEmitter(); + @Input('labelAttribute') label: string; +} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/hero-button/hero-button.component.ts b/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/hero-button/hero-button.component.ts new file mode 100644 index 0000000000..af6e7d46b7 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/hero-button/hero-button.component.ts @@ -0,0 +1,14 @@ +// #docregion +import { Component, EventEmitter, Input, Output } from '@angular/core'; + +// #docregion example +@Component({ + selector: 'toh-hero-button', + template: `` +}) +export class HeroButtonComponent { + // No aliases + @Output() change = new EventEmitter(); + @Input() label: string; +} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/index.ts b/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/hero-button/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/hero-button/index.ts rename to public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/hero-button/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/hero-highlight.directive.ts b/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/hero-highlight.directive.ts new file mode 100644 index 0000000000..737af31f4f --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/hero-highlight.directive.ts @@ -0,0 +1,15 @@ +// #docregion +import { Directive, ElementRef, Input, OnChanges } from '@angular/core'; + +@Directive({ selector: '[heroHighlight]' }) +export class HeroHighlightDirective implements OnChanges { + + // Aliased because `color` is a better property name than `heroHighlight` + @Input('heroHighlight') color: string; + + constructor(private el: ElementRef) {} + + ngOnChanges() { + this.el.nativeElement.style.backgroundColor = this.color || 'yellow'; + } +} diff --git a/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/index.ts new file mode 100644 index 0000000000..565f46cf4f --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-13/app/heroes/shared/index.ts @@ -0,0 +1,2 @@ +export * from './hero-button'; +export * from './hero-highlight.directive'; diff --git a/public/docs/_examples/style-guide/ts/src/05-13/app/index.ts b/public/docs/_examples/style-guide/ts/src/05-13/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-13/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/05-14/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/05-14/app/app.component.ts new file mode 100644 index 0000000000..8ed6da4c82 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-14/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + template: `` +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/05-14/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/05-14/app/app.module.ts new file mode 100644 index 0000000000..0b294573d2 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-14/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { ToastComponent } from './shared'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '05-14', component: AppComponent }]) + ], + declarations: [ + AppComponent, + ToastComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/src/05-14/app/index.ts b/public/docs/_examples/style-guide/ts/src/05-14/app/index.ts new file mode 100644 index 0000000000..ebe5c92f03 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-14/app/index.ts @@ -0,0 +1,2 @@ +export * from './shared'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/05-14/app/shared/index.ts b/public/docs/_examples/style-guide/ts/src/05-14/app/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-14/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/05-14/app/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/05-14/app/shared/toast/index.ts b/public/docs/_examples/style-guide/ts/src/05-14/app/shared/toast/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-14/app/shared/toast/index.ts rename to public/docs/_examples/style-guide/ts/src/05-14/app/shared/toast/index.ts diff --git a/public/docs/_examples/style-guide/ts/05-14/app/shared/toast/toast.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/05-14/app/shared/toast/toast.component.avoid.ts similarity index 95% rename from public/docs/_examples/style-guide/ts/05-14/app/shared/toast/toast.component.avoid.ts rename to public/docs/_examples/style-guide/ts/src/05-14/app/shared/toast/toast.component.avoid.ts index 5e7a39c758..037ff2c8b5 100644 --- a/public/docs/_examples/style-guide/ts/05-14/app/shared/toast/toast.component.avoid.ts +++ b/public/docs/_examples/style-guide/ts/src/05-14/app/shared/toast/toast.component.avoid.ts @@ -7,7 +7,7 @@ export class ToastComponent implements OnInit { private defaults = { title: '', - message: 'May the Force be with You' + message: 'May the Force be with you' }; message: string; title: string; diff --git a/public/docs/_examples/style-guide/ts/src/05-14/app/shared/toast/toast.component.ts b/public/docs/_examples/style-guide/ts/src/05-14/app/shared/toast/toast.component.ts new file mode 100644 index 0000000000..d7b8ea4af0 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-14/app/shared/toast/toast.component.ts @@ -0,0 +1,45 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'toh-toast', + template: `...` +}) +// #docregion example +export class ToastComponent implements OnInit { + // public properties + message: string; + title: string; + + // private fields + private defaults = { + title: '', + message: 'May the Force be with you' + }; + private toastElement: any; + + // public methods + activate(message = this.defaults.message, title = this.defaults.title) { + this.title = title; + this.message = message; + this.show(); + } + + ngOnInit() { + this.toastElement = document.getElementById('toh-toast'); + } + + // private methods + private hide() { + this.toastElement.style.opacity = 0; + window.setTimeout(() => this.toastElement.style.zIndex = 0, 400); + } + + private show() { + console.log(this.message); + this.toastElement.style.opacity = 1; + this.toastElement.style.zIndex = 9999; + window.setTimeout(() => this.hide(), 2500); + } +} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/src/05-15/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/05-15/app/app.component.ts new file mode 100644 index 0000000000..91b569b1e7 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-15/app/app.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +import { HeroService } from './heroes'; + +@Component({ + selector: 'sg-app', + template: '', + providers: [HeroService] +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/05-15/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/05-15/app/app.module.ts new file mode 100644 index 0000000000..9bd4b8c9a2 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-15/app/app.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroListComponent } from './heroes'; + +@NgModule({ + imports: [ + BrowserModule, + RouterModule.forChild([{ path: '05-15', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HeroListComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/05-15/app/heroes/hero-list/hero-list.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/05-15/app/heroes/hero-list/hero-list.component.avoid.ts similarity index 89% rename from public/docs/_examples/style-guide/ts/05-15/app/heroes/hero-list/hero-list.component.avoid.ts rename to public/docs/_examples/style-guide/ts/src/05-15/app/heroes/hero-list/hero-list.component.avoid.ts index b66bb9e81f..c323ba2b1c 100644 --- a/public/docs/_examples/style-guide/ts/05-15/app/heroes/hero-list/hero-list.component.avoid.ts +++ b/public/docs/_examples/style-guide/ts/src/05-15/app/heroes/hero-list/hero-list.component.avoid.ts @@ -3,7 +3,11 @@ import { OnInit } from '@angular/core'; import { Http, Response } from '@angular/http'; + import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/catch'; +import 'rxjs/add/operator/finally'; +import 'rxjs/add/operator/map'; import { Hero } from '../shared/hero.model'; diff --git a/public/docs/_examples/style-guide/ts/05-15/app/heroes/hero-list/hero-list.component.ts b/public/docs/_examples/style-guide/ts/src/05-15/app/heroes/hero-list/hero-list.component.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-15/app/heroes/hero-list/hero-list.component.ts rename to public/docs/_examples/style-guide/ts/src/05-15/app/heroes/hero-list/hero-list.component.ts diff --git a/public/docs/_examples/style-guide/ts/05-15/app/heroes/hero-list/index.ts b/public/docs/_examples/style-guide/ts/src/05-15/app/heroes/hero-list/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-15/app/heroes/hero-list/index.ts rename to public/docs/_examples/style-guide/ts/src/05-15/app/heroes/hero-list/index.ts diff --git a/public/docs/_examples/style-guide/ts/05-15/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/05-15/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-15/app/heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/05-15/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/src/05-15/app/heroes/shared/hero.model.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-04/app/heroes/shared/hero.model.ts rename to public/docs/_examples/style-guide/ts/src/05-15/app/heroes/shared/hero.model.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-15/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/src/05-15/app/heroes/shared/hero.service.ts new file mode 100644 index 0000000000..72d07bbed4 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-15/app/heroes/shared/hero.service.ts @@ -0,0 +1,15 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; + +import { Hero } from './hero.model'; + +@Injectable() +export class HeroService { + getHeroes() { + let heroes: Hero[] = []; + return Observable.of(heroes); + } +} diff --git a/public/docs/_examples/style-guide/ts/05-15/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/05-15/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-15/app/heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/05-15/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-15/app/index.ts b/public/docs/_examples/style-guide/ts/src/05-15/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-15/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/05-16/app/app.component.avoid.html b/public/docs/_examples/style-guide/ts/src/05-16/app/app.component.avoid.html similarity index 100% rename from public/docs/_examples/style-guide/ts/05-16/app/app.component.avoid.html rename to public/docs/_examples/style-guide/ts/src/05-16/app/app.component.avoid.html diff --git a/public/docs/_examples/style-guide/ts/05-16/app/app.component.html b/public/docs/_examples/style-guide/ts/src/05-16/app/app.component.html similarity index 100% rename from public/docs/_examples/style-guide/ts/05-16/app/app.component.html rename to public/docs/_examples/style-guide/ts/src/05-16/app/app.component.html diff --git a/public/docs/_examples/style-guide/ts/src/05-16/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/05-16/app/app.component.ts new file mode 100644 index 0000000000..7c9f37919f --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-16/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + templateUrl: './app.component.html' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/05-16/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/05-16/app/app.module.ts new file mode 100644 index 0000000000..c3fb36f8ac --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-16/app/app.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroComponent } from './heroes'; + +@NgModule({ + imports: [ + BrowserModule, + RouterModule.forChild([{ path: '05-16', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HeroComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/05-16/app/heroes/hero.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/05-16/app/heroes/hero.component.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-16/app/heroes/hero.component.avoid.ts rename to public/docs/_examples/style-guide/ts/src/05-16/app/heroes/hero.component.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/05-16/app/heroes/hero.component.ts b/public/docs/_examples/style-guide/ts/src/05-16/app/heroes/hero.component.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-16/app/heroes/hero.component.ts rename to public/docs/_examples/style-guide/ts/src/05-16/app/heroes/hero.component.ts diff --git a/public/docs/_examples/style-guide/ts/05-16/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/05-16/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-16/app/heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/05-16/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-16/app/index.ts b/public/docs/_examples/style-guide/ts/src/05-16/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-16/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/05-17/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/05-17/app/app.component.ts new file mode 100644 index 0000000000..86728b8b80 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-17/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + template: '' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/05-17/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/05-17/app/app.module.ts new file mode 100644 index 0000000000..e850d80ae3 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-17/app/app.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroComponent, HeroListComponent } from './heroes'; + +@NgModule({ + imports: [ + BrowserModule, + RouterModule.forChild([{ path: '05-17', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HeroComponent, + HeroListComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/05-17/app/heroes/hero-list/hero-list.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero-list/hero-list.component.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-17/app/heroes/hero-list/hero-list.component.avoid.ts rename to public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero-list/hero-list.component.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero-list/hero-list.component.ts b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero-list/hero-list.component.ts new file mode 100644 index 0000000000..5f18cc5b0c --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero-list/hero-list.component.ts @@ -0,0 +1,35 @@ +// #docplaster +// #docregion +import { Component } from '@angular/core'; + +import { Hero } from '../shared/hero.model'; + +// #docregion example +@Component({ + selector: 'toh-hero-list', + template: ` +
    + Our list of heroes: + + + Total powers: {{totalPowers}}
    + Average power: {{avgPower}} +
    + ` +}) +export class HeroListComponent { + heroes: Hero[]; + totalPowers: number; + + // #enddocregion example + // testing harness + constructor() { + this.heroes = []; + } + + // #docregion example + get avgPower() { + return this.totalPowers / this.heroes.length; + } +} +// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/05-17/app/heroes/hero-list/index.ts b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero-list/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-17/app/heroes/hero-list/index.ts rename to public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero-list/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero/hero.component.ts b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero/hero.component.ts new file mode 100644 index 0000000000..334f836a7d --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero/hero.component.ts @@ -0,0 +1,13 @@ +import { Component, Input } from '@angular/core'; + +import { Hero } from '../shared/hero.model'; + +@Component({ + selector: 'toh-hero', + template: `...` +}) +export class HeroComponent { + @Input() hero: Hero; +} + + diff --git a/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero/index.ts b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero/index.ts new file mode 100644 index 0000000000..084f36d703 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/hero/index.ts @@ -0,0 +1 @@ +export * from './hero.component'; diff --git a/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/index.ts new file mode 100644 index 0000000000..dcf3e79bd3 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/index.ts @@ -0,0 +1,3 @@ +export * from './hero'; +export * from './hero-list'; +export * from './shared'; diff --git a/public/docs/_examples/style-guide/ts/05-15/app/heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/shared/hero.model.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-15/app/heroes/shared/hero.model.ts rename to public/docs/_examples/style-guide/ts/src/05-17/app/heroes/shared/hero.model.ts diff --git a/public/docs/_examples/style-guide/ts/04-14/app/+heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/05-17/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/04-14/app/+heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/05-17/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/05-17/app/index.ts b/public/docs/_examples/style-guide/ts/src/05-17/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/05-17/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/06-01/app/app.component.html b/public/docs/_examples/style-guide/ts/src/06-01/app/app.component.html similarity index 100% rename from public/docs/_examples/style-guide/ts/06-01/app/app.component.html rename to public/docs/_examples/style-guide/ts/src/06-01/app/app.component.html diff --git a/public/docs/_examples/style-guide/ts/src/06-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/06-01/app/app.component.ts new file mode 100644 index 0000000000..7c9f37919f --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/06-01/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + templateUrl: './app.component.html' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/06-01/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/06-01/app/app.module.ts new file mode 100644 index 0000000000..318cd306d7 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/06-01/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HighlightDirective } from './shared'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '06-01', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HighlightDirective + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/src/06-01/app/index.ts b/public/docs/_examples/style-guide/ts/src/06-01/app/index.ts new file mode 100644 index 0000000000..ebe5c92f03 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/06-01/app/index.ts @@ -0,0 +1,2 @@ +export * from './shared'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/06-01/app/shared/highlight.directive.ts b/public/docs/_examples/style-guide/ts/src/06-01/app/shared/highlight.directive.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/06-01/app/shared/highlight.directive.ts rename to public/docs/_examples/style-guide/ts/src/06-01/app/shared/highlight.directive.ts diff --git a/public/docs/_examples/style-guide/ts/06-01/app/shared/index.ts b/public/docs/_examples/style-guide/ts/src/06-01/app/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/06-01/app/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/06-01/app/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/06-03/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/06-03/app/app.component.ts new file mode 100644 index 0000000000..0d0a7d107b --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/06-03/app/app.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + template: ` + + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/06-03/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/06-03/app/app.module.ts new file mode 100644 index 0000000000..b19f3fdc00 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/06-03/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { ValidatorDirective, Validator2Directive } from './shared'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '06-03', component: AppComponent }]) + ], + declarations: [ + AppComponent, + ValidatorDirective, Validator2Directive + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/src/06-03/app/index.ts b/public/docs/_examples/style-guide/ts/src/06-03/app/index.ts new file mode 100644 index 0000000000..ebe5c92f03 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/06-03/app/index.ts @@ -0,0 +1,2 @@ +export * from './shared'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/06-03/app/shared/index.ts b/public/docs/_examples/style-guide/ts/src/06-03/app/shared/index.ts new file mode 100644 index 0000000000..ba25e4c458 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/06-03/app/shared/index.ts @@ -0,0 +1,2 @@ +export * from './validator.directive'; +export * from './validator2.directive'; diff --git a/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.ts b/public/docs/_examples/style-guide/ts/src/06-03/app/shared/validator.directive.ts similarity index 85% rename from public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.ts rename to public/docs/_examples/style-guide/ts/src/06-03/app/shared/validator.directive.ts index 4271da0ef6..d9e32c017f 100644 --- a/public/docs/_examples/style-guide/ts/06-03/app/shared/validator.directive.ts +++ b/public/docs/_examples/style-guide/ts/src/06-03/app/shared/validator.directive.ts @@ -1,7 +1,6 @@ // #docregion import { Directive, HostBinding, HostListener } from '@angular/core'; -// #docregion example @Directive({ selector: '[tohValidator]' }) @@ -11,4 +10,3 @@ export class ValidatorDirective { // do work } } -// #enddocregion example diff --git a/public/docs/_examples/style-guide/ts/src/06-03/app/shared/validator2.directive.ts b/public/docs/_examples/style-guide/ts/src/06-03/app/shared/validator2.directive.ts new file mode 100644 index 0000000000..7936a83cb1 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/06-03/app/shared/validator2.directive.ts @@ -0,0 +1,16 @@ +// #docregion +import { Directive } from '@angular/core'; + +@Directive({ + selector: '[tohValidator2]', + host: { + 'attr.role': 'button', + '(mouseenter)': 'onMouseEnter()' + } +}) +export class Validator2Directive { + role = 'button'; + onMouseEnter() { + // do work + } +} diff --git a/public/docs/_examples/style-guide/ts/07-01/app/app.component.html b/public/docs/_examples/style-guide/ts/src/07-01/app/app.component.html similarity index 100% rename from public/docs/_examples/style-guide/ts/07-01/app/app.component.html rename to public/docs/_examples/style-guide/ts/src/07-01/app/app.component.html diff --git a/public/docs/_examples/style-guide/ts/src/07-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/07-01/app/app.component.ts new file mode 100644 index 0000000000..354b0ec303 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/07-01/app/app.component.ts @@ -0,0 +1,18 @@ +import { Component, OnInit } from '@angular/core'; + +import { Hero, HeroService } from './heroes'; + +@Component({ + selector: 'sg-app', + templateUrl: './app.component.html', + providers: [HeroService] +}) +export class AppComponent implements OnInit { + heroes: Hero[]; + + constructor(private heroService: HeroService) { } + + ngOnInit() { + this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/07-01/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/07-01/app/app.module.ts new file mode 100644 index 0000000000..0077500dea --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/07-01/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule, + RouterModule.forChild([{ path: '07-01', component: AppComponent }]) + ], + declarations: [ + AppComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/05-13/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/07-01/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-13/app/heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/07-01/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/05-17/app/heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/src/07-01/app/heroes/shared/hero.model.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-17/app/heroes/shared/hero.model.ts rename to public/docs/_examples/style-guide/ts/src/07-01/app/heroes/shared/hero.model.ts diff --git a/public/docs/_examples/style-guide/ts/07-01/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/src/07-01/app/heroes/shared/hero.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-01/app/heroes/shared/hero.service.ts rename to public/docs/_examples/style-guide/ts/src/07-01/app/heroes/shared/hero.service.ts diff --git a/public/docs/_examples/style-guide/ts/07-01/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/07-01/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-01/app/heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/07-01/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/07-01/app/index.ts b/public/docs/_examples/style-guide/ts/src/07-01/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/07-01/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/07-03/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/07-03/app/app.component.ts new file mode 100644 index 0000000000..f4d25e1ab6 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/07-03/app/app.component.ts @@ -0,0 +1,13 @@ +// #docregion +import { Component } from '@angular/core'; + +import { HeroService } from './heroes'; + +@Component({ + selector: 'toh-app', + template: ` + + `, + providers: [HeroService] +}) +export class AppComponent {} diff --git a/public/docs/_examples/style-guide/ts/src/07-03/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/07-03/app/app.module.ts new file mode 100644 index 0000000000..8ba06d22be --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/07-03/app/app.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroListComponent } from './heroes'; + +@NgModule({ + imports: [ + BrowserModule, + RouterModule.forChild([{ path: '07-03', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HeroListComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/07-03/app/heroes/hero-list/hero-list.component.ts b/public/docs/_examples/style-guide/ts/src/07-03/app/heroes/hero-list/hero-list.component.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-03/app/heroes/hero-list/hero-list.component.ts rename to public/docs/_examples/style-guide/ts/src/07-03/app/heroes/hero-list/hero-list.component.ts diff --git a/public/docs/_examples/style-guide/ts/07-03/app/heroes/hero-list/index.ts b/public/docs/_examples/style-guide/ts/src/07-03/app/heroes/hero-list/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-03/app/heroes/hero-list/index.ts rename to public/docs/_examples/style-guide/ts/src/07-03/app/heroes/hero-list/index.ts diff --git a/public/docs/_examples/style-guide/ts/05-17/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/07-03/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-17/app/heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/07-03/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/07-01/app/heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/src/07-03/app/heroes/shared/hero.model.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-01/app/heroes/shared/hero.model.ts rename to public/docs/_examples/style-guide/ts/src/07-03/app/heroes/shared/hero.model.ts diff --git a/public/docs/_examples/style-guide/ts/src/07-03/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/src/07-03/app/heroes/shared/hero.service.ts new file mode 100644 index 0000000000..72d07bbed4 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/07-03/app/heroes/shared/hero.service.ts @@ -0,0 +1,15 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; + +import { Hero } from './hero.model'; + +@Injectable() +export class HeroService { + getHeroes() { + let heroes: Hero[] = []; + return Observable.of(heroes); + } +} diff --git a/public/docs/_examples/style-guide/ts/07-03/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/07-03/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-03/app/heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/07-03/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/07-03/app/index.ts b/public/docs/_examples/style-guide/ts/src/07-03/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/07-03/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/07-04/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/07-04/app/app.component.ts new file mode 100644 index 0000000000..b0bc9677fe --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/07-04/app/app.component.ts @@ -0,0 +1,19 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; + +import { HeroArena, HeroService, Hero } from './heroes'; + +@Component({ + selector: 'toh-app', + template: '
    {{heroes | json}}
    ', + providers: [HeroArena, HeroService] +}) +export class AppComponent implements OnInit { + heroes: Hero[] = []; + + constructor(private heroArena: HeroArena) { } + + ngOnInit() { + this.heroArena.getParticipants().subscribe(heroes => this.heroes = heroes); + } +} diff --git a/public/docs/_examples/style-guide/ts/src/07-04/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/07-04/app/app.module.ts new file mode 100644 index 0000000000..71c515c9c9 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/07-04/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule, + RouterModule.forChild([{ path: '07-04', component: AppComponent }]) + ], + declarations: [ + AppComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/07-01/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/07-04/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-01/app/heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/07-04/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero-arena.service.avoid.ts b/public/docs/_examples/style-guide/ts/src/07-04/app/heroes/shared/hero-arena.service.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero-arena.service.avoid.ts rename to public/docs/_examples/style-guide/ts/src/07-04/app/heroes/shared/hero-arena.service.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero-arena.service.ts b/public/docs/_examples/style-guide/ts/src/07-04/app/heroes/shared/hero-arena.service.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/hero-arena.service.ts rename to public/docs/_examples/style-guide/ts/src/07-04/app/heroes/shared/hero-arena.service.ts diff --git a/public/docs/_examples/style-guide/ts/07-03/app/heroes/shared/hero.model.ts b/public/docs/_examples/style-guide/ts/src/07-04/app/heroes/shared/hero.model.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-03/app/heroes/shared/hero.model.ts rename to public/docs/_examples/style-guide/ts/src/07-04/app/heroes/shared/hero.model.ts diff --git a/public/docs/_examples/style-guide/ts/src/07-04/app/heroes/shared/hero.service.ts b/public/docs/_examples/style-guide/ts/src/07-04/app/heroes/shared/hero.service.ts new file mode 100644 index 0000000000..72d07bbed4 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/07-04/app/heroes/shared/hero.service.ts @@ -0,0 +1,15 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; + +import { Hero } from './hero.model'; + +@Injectable() +export class HeroService { + getHeroes() { + let heroes: Hero[] = []; + return Observable.of(heroes); + } +} diff --git a/public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/07-04/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-04/app/heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/07-04/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/07-04/app/index.ts b/public/docs/_examples/style-guide/ts/src/07-04/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/07-04/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/src/09-01/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/09-01/app/app.component.ts new file mode 100644 index 0000000000..ebc904f722 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/09-01/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sg-app', + template: '' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/09-01/app/app.module.ts b/public/docs/_examples/style-guide/ts/src/09-01/app/app.module.ts new file mode 100644 index 0000000000..5872e801d6 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/09-01/app/app.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroButtonComponent } from './heroes'; + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '09-01', component: AppComponent }]) + ], + declarations: [ + AppComponent, + HeroButtonComponent + ], + exports: [ AppComponent ] +}) +export class AppModule {} diff --git a/public/docs/_examples/style-guide/ts/07-04/app/heroes/index.ts b/public/docs/_examples/style-guide/ts/src/09-01/app/heroes/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/07-04/app/heroes/index.ts rename to public/docs/_examples/style-guide/ts/src/09-01/app/heroes/index.ts diff --git a/public/docs/_examples/style-guide/ts/09-01/app/heroes/shared/hero-button/hero-button.component.avoid.ts b/public/docs/_examples/style-guide/ts/src/09-01/app/heroes/shared/hero-button/hero-button.component.avoid.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/09-01/app/heroes/shared/hero-button/hero-button.component.avoid.ts rename to public/docs/_examples/style-guide/ts/src/09-01/app/heroes/shared/hero-button/hero-button.component.avoid.ts diff --git a/public/docs/_examples/style-guide/ts/09-01/app/heroes/shared/hero-button/hero-button.component.ts b/public/docs/_examples/style-guide/ts/src/09-01/app/heroes/shared/hero-button/hero-button.component.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/09-01/app/heroes/shared/hero-button/hero-button.component.ts rename to public/docs/_examples/style-guide/ts/src/09-01/app/heroes/shared/hero-button/hero-button.component.ts diff --git a/public/docs/_examples/style-guide/ts/09-01/app/heroes/shared/hero-button/index.ts b/public/docs/_examples/style-guide/ts/src/09-01/app/heroes/shared/hero-button/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/09-01/app/heroes/shared/hero-button/index.ts rename to public/docs/_examples/style-guide/ts/src/09-01/app/heroes/shared/hero-button/index.ts diff --git a/public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/index.ts b/public/docs/_examples/style-guide/ts/src/09-01/app/heroes/shared/index.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/05-13/app/heroes/shared/index.ts rename to public/docs/_examples/style-guide/ts/src/09-01/app/heroes/shared/index.ts diff --git a/public/docs/_examples/style-guide/ts/src/09-01/app/index.ts b/public/docs/_examples/style-guide/ts/src/09-01/app/index.ts new file mode 100644 index 0000000000..fe8300f1dd --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/09-01/app/index.ts @@ -0,0 +1,2 @@ +export * from './heroes'; +export * from './app.component'; diff --git a/public/docs/_examples/style-guide/ts/app/app.component.html b/public/docs/_examples/style-guide/ts/src/app/app.component.html similarity index 100% rename from public/docs/_examples/style-guide/ts/app/app.component.html rename to public/docs/_examples/style-guide/ts/src/app/app.component.html diff --git a/public/docs/_examples/style-guide/ts/src/app/app.component.ts b/public/docs/_examples/style-guide/ts/src/app/app.component.ts new file mode 100644 index 0000000000..7556beb1ff --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html' +}) +export class AppComponent { } diff --git a/public/docs/_examples/style-guide/ts/src/app/app.routes.ts b/public/docs/_examples/style-guide/ts/src/app/app.routes.ts new file mode 100644 index 0000000000..bce6b4df06 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/app/app.routes.ts @@ -0,0 +1,8 @@ +import { Routes } from '@angular/router'; + +import { AppComponent as S0101 } from '../01-01/app'; + +export const routes: Routes = [ + { path: '', redirectTo: '/01-01', pathMatch: 'full' }, + { path: '01-01', component: S0101 }, +]; diff --git a/public/docs/_examples/style-guide/ts/app/hero-data.ts b/public/docs/_examples/style-guide/ts/src/app/hero-data.ts similarity index 100% rename from public/docs/_examples/style-guide/ts/app/hero-data.ts rename to public/docs/_examples/style-guide/ts/src/app/hero-data.ts diff --git a/public/docs/_examples/style-guide/ts/src/index.html b/public/docs/_examples/style-guide/ts/src/index.html new file mode 100644 index 0000000000..188c2c26a1 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/index.html @@ -0,0 +1,30 @@ + + + + + + + Style Guide Sample + + + + + + + + + + + + + + + + + loading... + + + + diff --git a/public/docs/_examples/style-guide/ts/src/main.ts b/public/docs/_examples/style-guide/ts/src/main.ts new file mode 100644 index 0000000000..5b4c98ba69 --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/main.ts @@ -0,0 +1,99 @@ +import { NgModule } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { BrowserModule } from '@angular/platform-browser'; + +import { HttpModule } from '@angular/http'; +import { InMemoryWebApiModule } from 'angular-in-memory-web-api'; + +import { RouterModule } from '@angular/router'; + +import { HashLocationStrategy, + LocationStrategy } from '@angular/common'; + +import 'rxjs/add/operator/map'; + +import { HeroData } from './app/hero-data'; +import { AppComponent } from './app/app.component'; + +import * as s0101 from './01-01/app/app.module'; +import * as s0205 from './02-05/app/app.module'; +import * as s0207 from './02-07/app/app.module'; +import * as s0208 from './02-08/app/app.module'; +import * as s0301 from './03-01/app/app.module'; +import * as s0302 from './03-02/app/app.module'; +import * as s0303 from './03-03/app/app.module'; +import * as s0304 from './03-04/app/app.module'; +import * as s0306 from './03-06/app/app.module'; +import * as s0408 from './04-08/app/app.module'; +import * as s0410 from './04-10/app/app.module'; +import * as s0411 from './04-11/app/app.module'; +import * as s0412 from './04-12/app/app.module'; +import * as s0502 from './05-02/app/app.module'; +import * as s0503 from './05-03/app/app.module'; +import * as s0504 from './05-04/app/app.module'; +import * as s0512 from './05-12/app/app.module'; +import * as s0513 from './05-13/app/app.module'; +import * as s0514 from './05-14/app/app.module'; +import * as s0515 from './05-15/app/app.module'; +import * as s0516 from './05-16/app/app.module'; +import * as s0517 from './05-17/app/app.module'; +import * as s0601 from './06-01/app/app.module'; +import * as s0603 from './06-03/app/app.module'; +import * as s0701 from './07-01/app/app.module'; +import * as s0703 from './07-03/app/app.module'; +import * as s0704 from './07-04/app/app.module'; +import * as s0901 from './09-01/app/app.module'; + +/////////////////// +const moduleMetadata = { + imports: [ + BrowserModule, + HttpModule, + InMemoryWebApiModule.forRoot(HeroData), + + s0101.AppModule, + s0205.AppModule, + s0207.AppModule, + s0208.AppModule, + s0301.AppModule, + s0302.AppModule, + s0303.AppModule, + s0304.AppModule, + s0306.AppModule, + s0408.AppModule, + s0410.AppModule, + s0411.AppModule, + s0412.AppModule, + s0502.AppModule, + s0503.AppModule, + s0504.AppModule, + s0512.AppModule, + s0513.AppModule, + s0514.AppModule, + s0515.AppModule, + s0516.AppModule, + s0517.AppModule, + s0601.AppModule, + s0603.AppModule, + s0701.AppModule, + s0703.AppModule, + s0704.AppModule, + s0901.AppModule, + + RouterModule.forRoot([ + { path: '', redirectTo: '/01-01', pathMatch: 'full' } + ], {/* enableTracing: true */}), + ], + providers: [ + { provide: LocationStrategy, useClass: HashLocationStrategy } + ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}; + +@NgModule(moduleMetadata) +class MainModule { } + +platformBrowserDynamic().bootstrapModule(MainModule); + + diff --git a/public/docs/_examples/style-guide/ts/src/systemjs.custom.js b/public/docs/_examples/style-guide/ts/src/systemjs.custom.js new file mode 100644 index 0000000000..3424b2b62d --- /dev/null +++ b/public/docs/_examples/style-guide/ts/src/systemjs.custom.js @@ -0,0 +1,51 @@ +(function(global) { + // extra local packages + var packageNames = [ + '01-01', '01-01/app', '01-01/app/heroes', '01-01/app/heroes/shared', + '02-05', '02-05/app', + '02-07', '02-07/app', '02-07/app/heroes', '02-07/app/users', + '02-08', '02-08/app', '02-08/app/shared', + '03-01', '03-01/app', '03-01/app/core', + '03-02', '03-02/app', '03-02/app/core', + '03-03', '03-03/app', '03-03/app/core', + '03-04', '03-04/app', '03-04/app/core', + '03-05', '03-05/app', '03-05/app/core', '03-05/app/core/spinner', '03-05/app/core/toast', + '03-05/app/heroes', '03-05/app/heroes/shared', + '03-06', '03-06/app', '03-06/app/core', '03-06/app/core/spinner', '03-06/app/core/toast', + '03-06/app/heroes', '03-06/app/heroes/shared', + '04-08', '04-08/app', '04-08/app/heroes', + '04-10', '04-10/app', '04-10/app/shared', '04-10/app/heroes', '04-10/app/shared/spinner', '04-10/app/shared/toast', + '04-10/app/shared/filter-text', + '04-11', '04-11/app', '04-11/app/core', '04-11/app/heroes', '04-11/app/core/spinner', + '04-11/app/core/nav', + '04-12', '04-12/app', '04-12/app/core', '04-12/app/heroes', '04-12/app/core/nav', + '05-02', '05-02/app', '05-02/app/heroes', '05-02/app/heroes/shared', '05-02/app/heroes/shared/hero-button', + '05-03', '05-03/app', '05-03/app/heroes', '05-03/app/heroes/shared', '05-03/app/heroes/shared/hero-button', + '05-04', '05-04/app', '05-04/app/heroes', '05-04/app/heroes/shared', + '05-12', '05-12/app', '05-12/app/heroes', '05-12/app/heroes/shared', '05-12/app/heroes/shared/hero-button', + '05-13', '05-13/app', '05-13/app/heroes', '05-13/app/heroes/shared', '05-13/app/heroes/shared/hero-button', + '05-14', '05-14/app', '05-14/app/shared', '05-14/app/shared/toast', + '05-15', '05-15/app', '05-15/app/heroes', '05-15/app/heroes/hero-list', '05-15/app/heroes/shared', + '05-16', '05-16/app', '05-16/app/heroes', + '05-17', '05-17/app', '05-17/app/heroes', '05-17/app/heroes/hero', '05-17/app/heroes/hero-list', + '05-17/app/heroes/shared', + '06-01', '06-01/app', '06-01/app/shared', + '06-03', '06-03/app', '06-03/app/shared', + '07-01', '07-01/app', '07-01/app/heroes', '07-01/app/heroes/shared', + '07-03', '07-03/app', '07-03/app/heroes', '07-03/app/heroes/hero-list', '07-03/app/heroes/shared', + '07-04', '07-04/app', '07-04/app/heroes', '07-04/app/heroes/shared', + '09-01', '09-01/app', '09-01/app/heroes', '09-01/app/heroes/shared', '09-01/app/heroes/shared/hero-button' + ]; + + var packages = {}; + packageNames.forEach(function(pkgName) { + packages[pkgName] = { main: 'index.js', defaultExtension: 'js', meta: { './*.js': { loader: 'systemjs-angular-loader.js' }} }; + }); + + var config = { + packages: packages + } + + System.config(config); + +})(this); diff --git a/public/docs/_examples/style-guide/ts/systemjs.custom.js b/public/docs/_examples/style-guide/ts/systemjs.custom.js deleted file mode 100644 index 10f13fe801..0000000000 --- a/public/docs/_examples/style-guide/ts/systemjs.custom.js +++ /dev/null @@ -1,46 +0,0 @@ -(function(global) { - // extra local packages - var packageNames = [ - '01-01', '01-01/app', '01-01/app/heroes', '01-01/app/heroes/shared', - '02-07', '02-07/app', '02-07/app/heroes', '02-07/app/users', - '02-08', '02-08/app', '02-08/app/shared', - '03-01', '03-01/app', '03-01/app/shared', - '03-02', '03-02/app', '03-02/app/shared', - '03-03', '03-03/app', '03-03/app/shared', - '03-04', '03-04/app', '03-04/app/shared', - '03-05', '03-05/app', '03-05/app/shared', '03-05/app/shared/spinner', '03-05/app/shared/toast', - '03-05/app/+heroes', '03-05/app/+heroes/shared', - '03-06', '03-06/app', '03-06/app/shared', '03-06/app/shared/spinner', '03-06/app/shared/toast', - '03-06/app/+heroes', '03-06/app/+heroes/shared', - '04-10', '04-10/app', '04-10/app/shared', '04-10/app/+heroes', '04-10/app/shared/spinner', '04-10/app/shared/toast', - '04-10/app/shared/filter-text', '04-10/app/shared/modal', '04-10/app/shared/nav', - '04-14', '04-14/app', '04-14/app/+heroes', '04-14/app/+heroes/shared', '04-14/app/shared', - '05-02', '05-02/app', '05-02/app/heroes', '05-02/app/heroes/shared', '05-02/app/heroes/shared/hero-button', - '05-03', '05-03/app', '05-03/app/heroes', '05-03/app/heroes/shared', '05-03/app/heroes/shared/hero-button', - '05-04', '05-04/app', '05-04/app/heroes', '05-04/app/heroes/shared', - '05-12', '05-12/app', '05-12/app/heroes', '05-12/app/heroes/shared', '05-12/app/heroes/shared/hero-button', - '05-13', '05-13/app', '05-13/app/heroes', '05-13/app/heroes/shared', '05-13/app/heroes/shared/hero-button', - '05-14', '05-14/app', '05-14/app/shared', '05-14/app/shared/toast', - '05-15', '05-15/app', '05-15/app/heroes', '05-15/app/heroes/hero-list', '05-15/app/heroes/shared', - '05-16', '05-16/app', '05-16/app/heroes', - '05-17', '05-17/app', '05-17/app/heroes', '05-17/app/heroes/hero-list', '05-17/app/heroes/shared', - '06-01', '06-01/app', '06-01/app/shared', - '06-03', '06-03/app', '06-03/app/shared', - '07-01', '07-01/app', '07-01/app/heroes', '07-01/app/heroes/shared', - '07-03', '07-03/app', '07-03/app/heroes', '07-03/app/heroes/hero-list', '07-03/app/heroes/shared', - '07-04', '07-04/app', '07-04/app/heroes', '07-04/app/heroes/shared', - '09-01', '09-01/app', '09-01/app/heroes', '09-01/app/heroes/shared', '09-01/app/heroes/shared/hero-button' - ]; - - var packages = {}; - packageNames.forEach(function(pkgName) { - packages[pkgName] = { main: 'index.js', defaultExtension: 'js' }; - }); - - var config = { - packages: packages - } - - System.config(config); - -})(this); diff --git a/public/docs/_examples/styleguide/e2e-spec.ts b/public/docs/_examples/styleguide/e2e-spec.ts index d22930b144..af10d2b71d 100644 --- a/public/docs/_examples/styleguide/e2e-spec.ts +++ b/public/docs/_examples/styleguide/e2e-spec.ts @@ -1,7 +1,10 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + describe('Documentation StyleGuide E2E Tests', function() { - let expectedMsg = 'My First Angular 2 App'; + let expectedMsg = 'My First Angular App'; beforeEach(function () { browser.get(''); diff --git a/public/docs/_examples/styleguide/js/app.js b/public/docs/_examples/styleguide/js/app.js deleted file mode 100644 index 51a17a2429..0000000000 --- a/public/docs/_examples/styleguide/js/app.js +++ /dev/null @@ -1,43 +0,0 @@ -(function(app) { - -// #docregion -// #docregion class-w-annotations -app.AppComponent = - // #docregion component - ng.core.Component({ - selector: 'my-app', - // #enddocregion - // #docregion view - template: '

    My First Angular 2 App

    ' - }) - // #enddocregion - // #docregion class - .Class({ - constructor: function () { } - }); - // #enddocregion -// #enddocregion - -// #docregion bootstrap -document.addEventListener('DOMContentLoaded', function() { - ng.platformBrowserDynamic.bootstrap(app.AppComponent); -}); -// #enddocregion -// #enddocregion - -})(window.app || (window.app = {})); - -/* Non DSL Approach */ -(function(app) { - -// #docregion no-dsl -app.AppComponent = function AppComponent () {} - -app.AppComponent.annotations = [ - new ng.core.Component({ - selector: 'my-app', - template: '

    My First Angular 2 App

    ' - }) -]; -// #enddocregion -})(window.app || (window.app = {})); diff --git a/public/docs/_examples/styleguide/js/example-config.json b/public/docs/_examples/styleguide/js/example-config.json index e69de29bb2..81f31aaf0d 100644 --- a/public/docs/_examples/styleguide/js/example-config.json +++ b/public/docs/_examples/styleguide/js/example-config.json @@ -0,0 +1,3 @@ +{ + "build": "build:babel" +} diff --git a/public/docs/_examples/styleguide/js/index.html b/public/docs/_examples/styleguide/js/index.html deleted file mode 100644 index 6840d677d0..0000000000 --- a/public/docs/_examples/styleguide/js/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - Documentation Style - - - - - - - - - - - - - - - - - - - - foo2 - - - diff --git a/public/docs/_examples/styleguide/js/src/app.js b/public/docs/_examples/styleguide/js/src/app.js new file mode 100644 index 0000000000..d38669cd78 --- /dev/null +++ b/public/docs/_examples/styleguide/js/src/app.js @@ -0,0 +1,55 @@ +(function(app) { + +// #docregion +// #docregion class-w-annotations +app.AppComponent = + // #docregion component + ng.core.Component({ + selector: 'my-app', + // #enddocregion + // #docregion view + template: '

    My First Angular App

    ' + }) + // #enddocregion + // #docregion class + .Class({ + constructor: function () { } + }); + // #enddocregion +// #enddocregion + +// #docregion bootstrap +app.AppModule = + ng.core.NgModule({ + imports: [ ng.platformBrowser.BrowserModule ], + declarations: [ app.AppComponent ], + bootstrap: [ app.AppComponent ] + }) + .Class({ + constructor: function() {} + }); + +document.addEventListener('DOMContentLoaded', function() { + ng.platformBrowserDynamic + .platformBrowserDynamic() + .bootstrapModule(app.AppModule); +}); +// #enddocregion +// #enddocregion + +})(window.app || (window.app = {})); + +/* Non DSL Approach */ +(function(app) { + +// #docregion no-dsl +app.AppComponent = function AppComponent () {} + +app.AppComponent.annotations = [ + new ng.core.Component({ + selector: 'my-app', + template: '

    My First Angular App

    ' + }) +]; +// #enddocregion +})(window.app || (window.app = {})); diff --git a/public/docs/_examples/styleguide/js/src/index.html b/public/docs/_examples/styleguide/js/src/index.html new file mode 100644 index 0000000000..ac2d34ba5d --- /dev/null +++ b/public/docs/_examples/styleguide/js/src/index.html @@ -0,0 +1,27 @@ + + + + Documentation Style + + + + + + + + + + + + + + + + + + + + foo2 + + + diff --git a/public/docs/_examples/styleguide/package.1.json b/public/docs/_examples/styleguide/package.1.json index f4c2fdaef5..481f99fb12 100644 --- a/public/docs/_examples/styleguide/package.1.json +++ b/public/docs/_examples/styleguide/package.1.json @@ -7,12 +7,11 @@ "lite": "lite-server", "start": "concurrently \"npm run tsc:w\" \"npm run lite\" " }, - "license": "ISC", + "license": "MIT", "dependencies": { "angular2": "2.0.0-beta.0", "systemjs": "0.19.6", "core-js": "^2.4.0", - "reflect-metadata": "0.1.2", "rxjs": "5.0.0-beta.0", "zone.js": "0.5.10" }, diff --git a/public/docs/_examples/styleguide/ts/app/app.component.ts b/public/docs/_examples/styleguide/ts/app/app.component.ts deleted file mode 100644 index 7659920b9f..0000000000 --- a/public/docs/_examples/styleguide/ts/app/app.component.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Component } from '@angular/core'; -@Component({ - selector: 'my-app', - template: '

    My First Angular 2 App

    ' -}) -export class AppComponent { } - diff --git a/public/docs/_examples/styleguide/ts/app/main.ts b/public/docs/_examples/styleguide/ts/app/main.ts deleted file mode 100644 index ad256f0823..0000000000 --- a/public/docs/_examples/styleguide/ts/app/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); diff --git a/public/docs/_examples/styleguide/ts/index.html b/public/docs/_examples/styleguide/ts/index.html deleted file mode 100644 index 5983457e07..0000000000 --- a/public/docs/_examples/styleguide/ts/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - Documentation Style - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/styleguide/ts/src/app/app.component.ts b/public/docs/_examples/styleguide/ts/src/app/app.component.ts new file mode 100644 index 0000000000..8b71f6ddc4 --- /dev/null +++ b/public/docs/_examples/styleguide/ts/src/app/app.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; +@Component({ + selector: 'my-app', + template: '

    My First Angular App

    ' +}) +export class AppComponent { } + diff --git a/public/docs/_examples/styleguide/ts/src/app/app.module.ts b/public/docs/_examples/styleguide/ts/src/app/app.module.ts new file mode 100644 index 0000000000..0a9ee6adf7 --- /dev/null +++ b/public/docs/_examples/styleguide/ts/src/app/app.module.ts @@ -0,0 +1,11 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ BrowserModule ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/styleguide/ts/src/index.html b/public/docs/_examples/styleguide/ts/src/index.html new file mode 100644 index 0000000000..5cb8919509 --- /dev/null +++ b/public/docs/_examples/styleguide/ts/src/index.html @@ -0,0 +1,25 @@ + + + + + Documentation Style + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/styleguide/ts/src/main.ts b/public/docs/_examples/styleguide/ts/src/main.ts new file mode 100644 index 0000000000..6b6532d428 --- /dev/null +++ b/public/docs/_examples/styleguide/ts/src/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/styles.css b/public/docs/_examples/styles.css deleted file mode 100644 index 054b417f6f..0000000000 --- a/public/docs/_examples/styles.css +++ /dev/null @@ -1,142 +0,0 @@ -/* Master Styles */ -h1 { - color: #369; - font-family: Arial, Helvetica, sans-serif; - font-size: 250%; -} -h2, h3 { - color: #444; - font-family: Arial, Helvetica, sans-serif; - font-weight: lighter; -} -body { - margin: 2em; -} -body, input[text], button { - color: #888; - font-family: Cambria, Georgia; -} -a { - cursor: pointer; - cursor: hand; -} -button { - font-family: Arial; - background-color: #eee; - border: none; - padding: 5px 10px; - border-radius: 4px; - cursor: pointer; - cursor: hand; -} -button:hover { - background-color: #cfd8dc; -} -button:disabled { - background-color: #eee; - color: #aaa; - cursor: auto; -} - -/* Navigation link styles */ -nav a { - padding: 5px 10px; - text-decoration: none; - margin-top: 10px; - display: inline-block; - background-color: #eee; - border-radius: 4px; -} -nav a:visited, a:link { - color: #607D8B; -} -nav a:hover { - color: #039be5; - background-color: #CFD8DC; -} -nav a.router-link-active { - color: #039be5; -} - -/* items class */ -.items { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 24em; -} -.items li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; -} -.items li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; -} -.items li.selected:hover { - background-color: #BBD8DC; - color: white; -} -.items .text { - position: relative; - top: -3px; -} -.items { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 24em; -} -.items li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; -} -.items li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; -} -.items li.selected { - background-color: #CFD8DC; - color: white; -} - -.items li.selected:hover { - background-color: #BBD8DC; -} -.items .text { - position: relative; - top: -3px; -} -.items .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; -} - -/* everywhere else */ -* { - font-family: Arial, Helvetica, sans-serif; -} diff --git a/public/docs/_examples/systemjs.config.js b/public/docs/_examples/systemjs.config.js deleted file mode 100644 index e362b122a2..0000000000 --- a/public/docs/_examples/systemjs.config.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * System configuration for Angular 2 samples - * Adjust as necessary for your application needs. - */ -(function(global) { - - // map tells the System loader where to look for things - var map = { - 'app': 'app', // 'dist', - - '@angular': 'node_modules/@angular', - 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api', - 'rxjs': 'node_modules/rxjs' - }; - - // packages tells the System loader how to load when no filename and/or no extension - var packages = { - 'app': { main: 'main.js', defaultExtension: 'js' }, - 'rxjs': { defaultExtension: 'js' }, - 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, - }; - - var ngPackageNames = [ - 'common', - 'compiler', - 'core', - 'http', - 'platform-browser', - 'platform-browser-dynamic', - 'router', - 'router-deprecated', - 'upgrade', - ]; - - // Individual files (~300 requests): - function packIndex(pkgName) { - packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; - } - - // Bundled (~40 requests): - function packUmd(pkgName) { - packages['@angular/'+pkgName] = { main: pkgName + '.umd.js', defaultExtension: 'js' }; - }; - - // Most environments should use UMD; some (Karma) need the individual index files - var setPackageConfig = System.packageWithIndex ? packIndex : packUmd; - - // Add package entries for angular packages - ngPackageNames.forEach(setPackageConfig); - - var config = { - map: map, - packages: packages - } - - System.config(config); - -})(this); diff --git a/public/docs/_examples/systemjs.config.plunker.js b/public/docs/_examples/systemjs.config.plunker.js deleted file mode 100644 index 9e13e14edb..0000000000 --- a/public/docs/_examples/systemjs.config.plunker.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * PLUNKER VERSION (based on systemjs.config.js in angular.io) - * System configuration for Angular 2 samples - * Adjust as necessary for your application needs. - */ -(function(global) { - - var ngVer = '@2.0.0-rc.1'; // lock in the angular package version; do not let it float to current! - - //map tells the System loader where to look for things - var map = { - 'app': 'app', - - '@angular': 'https://npmcdn.com/@angular', // sufficient if we didn't pin the version - 'angular2-in-memory-web-api': 'https://npmcdn.com/angular2-in-memory-web-api', // get latest - 'rxjs': 'https://npmcdn.com/rxjs@5.0.0-beta.6', - 'ts': 'https://npmcdn.com/plugin-typescript@4.0.10/lib/plugin.js', - 'typescript': 'https://npmcdn.com/typescript@1.8.10/lib/typescript.js', - }; - - //packages tells the System loader how to load when no filename and/or no extension - var packages = { - 'app': { main: 'main.ts', defaultExtension: 'ts' }, - 'rxjs': { defaultExtension: 'js' }, - 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, - }; - - var ngPackageNames = [ - 'common', - 'compiler', - 'core', - 'http', - 'platform-browser', - 'platform-browser-dynamic', - 'router', - 'router-deprecated', - 'upgrade', - ]; - - // Add map entries for each angular package - // only because we're pinning the version with `ngVer`. - ngPackageNames.forEach(function(pkgName) { - map['@angular/'+pkgName] = 'https://npmcdn.com/@angular/' + pkgName + ngVer; - }); - - // Add package entries for angular packages - ngPackageNames.forEach(function(pkgName) { - - // Bundled (~40 requests): - packages['@angular/'+pkgName] = { main: pkgName + '.umd.js', defaultExtension: 'js' }; - - // Individual files (~300 requests): - //packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; - }); - - var config = { - // DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER - transpiler: 'ts', - typescriptOptions: { - tsconfig: true - }, - meta: { - 'typescript': { - "exports": "ts" - } - }, - map: map, - packages: packages - } - - System.config(config); - -})(this); diff --git a/public/docs/_examples/template-syntax/dart/.analysis_options b/public/docs/_examples/template-syntax/dart/.analysis_options deleted file mode 100644 index d8c582e96f..0000000000 --- a/public/docs/_examples/template-syntax/dart/.analysis_options +++ /dev/null @@ -1,16 +0,0 @@ -# Supported lint rules and documentation: http://dart-lang.github.io/linter/lints/ -linter: - rules: - - always_declare_return_types - - camel_case_types - - empty_constructor_bodies - - annotate_overrides - - avoid_init_to_null - - constant_identifier_names - - one_member_abstracts - - slash_for_doc_comments - - sort_constructors_first - - unnecessary_brace_in_string_interp - -analyzer: - # strong-mode: true diff --git a/public/docs/_examples/template-syntax/dart/.docsync.json b/public/docs/_examples/template-syntax/dart/.docsync.json deleted file mode 100644 index 0caee30723..0000000000 --- a/public/docs/_examples/template-syntax/dart/.docsync.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "Template Syntax", - "docHref": "https://angular.io/docs/ts/latest/guide/template-syntax.html" -} diff --git a/public/docs/_examples/template-syntax/dart/lib/app_component.dart b/public/docs/_examples/template-syntax/dart/lib/app_component.dart deleted file mode 100644 index 6d9199c175..0000000000 --- a/public/docs/_examples/template-syntax/dart/lib/app_component.dart +++ /dev/null @@ -1,234 +0,0 @@ -// #docregion -import 'dart:convert'; -import 'dart:html'; - -import 'package:angular2/core.dart'; -import 'package:angular2/common.dart'; - -import 'hero.dart'; -import 'hero_detail_component.dart'; -import 'my_click_directive.dart'; - -enum Color { red, green, blue } - -@Component( - selector: 'my-app', - templateUrl: 'app_component.html', - directives: const [ - HeroDetailComponent, - BigHeroDetailComponent, - MyClickDirective, - MyClickDirective2 - ]) -class AppComponent implements OnInit, AfterViewInit { - @override - void ngOnInit() { - refreshHeroes(); - } - - @override - void ngAfterViewInit() { - _detectNgForTrackByEffects(); - } - - String heroName; - String help; - String actionName = 'Go for it'; - String badCurly = 'bad curly'; - String classes = 'special'; - bool canSave = true; - bool isActive = false; - bool isSpecial = true; - bool isUnchanged = true; - bool isSelected = false; - final Color colorRed = Color.red; - Color color = Color.red; - var colorEnum = Color; - - List heroes; - Hero currentHero; - - // #docregion refresh-heroes - /// Updates [this.heroes] with fresh set of cloned heroes. - void refreshHeroes() { - heroes = mockHeroes.map((hero) => hero.clone()).toList(); - currentHero = heroes[0]; - } - // #enddocregion refresh-heroes - - final Hero nullHero = null; - Map product = {'name': 'frimfram', 'price': 42}; - FormElement form; - String clicked = ''; - String clickMessage = ''; - String clickMessage2 = ''; - final String iconUrl = 'assets/images/ng-logo.png'; - - // heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png'; - // Public Domain terms of use: http://www.wpclipart.com/terms.html - final String heroImageUrl = 'assets/images/hero.png'; - - // villainImageUrl = 'http://www.clker.com/cliparts/u/s/y/L/x/9/villain-man-hi.png' - // Public Domain terms of use http://www.clker.com/disclaimer.html - final String villainImageUrl = 'assets/images/villain.png'; - - void alerter(String msg) { - window.alert(msg); - } - - void callFax(String value) { - alerter('Faxing $value ...'); - } - - void callPhone(String value) { - alerter('Calling $value ...'); - } - - void colorToggle() { - color = (color == Color.red) ? Color.blue : Color.red; - } - - int getVal() => val; - - void onCancel(UIEvent event) { - HtmlElement el = event?.target; - var evtMsg = event != null ? 'Event target is ${el.innerHtml}.' : ''; - alerter('Canceled. $evtMsg'); - } - - void onClickMe(UIEvent event) { - HtmlElement el = event?.target; - var evtMsg = event != null ? 'Event target class is ${el.className}.' : ''; - alerter('Click me. $evtMsg'); - } - - void deleteHero([Hero hero]) { - alerter('Deleted hero: ${hero?.firstName}'); - } - - bool onSave([UIEvent event = null]) { - HtmlElement el = event?.target; - var evtMsg = - event != null ? ' Event target is ${el.innerHtml}.' : ''; - alerter('Saved. $evtMsg'); - return false; - } - - void onSubmit(NgForm form) { - var evtMsg = form.valid - ? ' Form value is ${JSON.encode(form.value)}' - : ' Form is invalid'; - alerter('Form submitted. $evtMsg'); - } - - void setUpperCaseFirstName(String firstName) { - currentHero.firstName = firstName.toUpperCase(); - } - - String getStyles(Element el) { - var showStyles = setStyles(); - return JSON.encode(showStyles); - } - - Map _previousClasses = {}; - // #docregion setClasses - Map setClasses() { - final classes = { - 'saveable': canSave, // true - 'modified': !isUnchanged, // false - 'special': isSpecial // true - }; - // #docregion setClasses - // compensate for DevMode (sigh) - if (JSON.encode(_previousClasses) == - JSON.encode(classes)) return _previousClasses; - _previousClasses = classes; - // #enddocregion setClasses - return classes; - } - // #enddocregion setClasses - - // #docregion setStyles - Map setStyles() { - return { - 'font-style': canSave ? 'italic' : 'normal', // italic - 'font-weight': !isUnchanged ? 'bold' : 'normal', // normal - 'font-size': isSpecial ? '24px' : '8px' // 24px - }; - } - // #enddocregion setStyles - - String title = 'Template Syntax'; - String toeChoice; - String toeChooser(Element picker) { - List choices = picker.children; - for (var i = 0; i < choices.length; i++) { - var choice = choices[i] as CheckboxInputElement; - if (choice.checked) { - toeChoice = choice.value; - return toeChoice; - } - } - - return null; - } - - // #docregion trackByHeroes - int trackByHeroes(int index, Hero hero) => hero.id; - // #enddocregion trackByHeroes - - // #docregion trackById - int trackById(int index, dynamic item) => item.id; - // #enddocregion trackById - - int val = 2; - - //////// Detect effects of NgForTrackBy /////////////// - int heroesNoTrackByChangeCount = 0; - int heroesWithTrackByChangeCount = 0; - - @ViewChildren('noTrackBy') QueryList childrenNoTrackBy; - @ViewChildren('withTrackBy') QueryList childrenWithTrackBy; - - void _detectNgForTrackByEffects() { - /// Converts [viewChildren] to a list of [Element]. - List _extractChildren(QueryList viewChildren) => - viewChildren.toList()[0].nativeElement.children.toList() as List; - - { - // Updates 'without TrackBy' statistics. - List _oldNoTrackBy = _extractChildren(this.childrenNoTrackBy); - - this.childrenNoTrackBy.changes.listen((Iterable changes) { - final newNoTrackBy = _extractChildren(changes); - final isSame = newNoTrackBy.fold(true, (bool isSame, Element elt) { - return isSame && _oldNoTrackBy.contains(elt); - }); - - if (!isSame) { - _oldNoTrackBy = newNoTrackBy; - this.heroesNoTrackByChangeCount++; - } - }); - } - - { - // Updates 'with TrackBy' statistics. - List _oldWithTrackBy = - _extractChildren(this.childrenWithTrackBy); - - this.childrenWithTrackBy.changes.listen((Iterable changes) { - final newWithTrackBy = _extractChildren(changes); - final isSame = newWithTrackBy.fold(true, (bool isSame, Element elt) { - return isSame && _oldWithTrackBy.contains(elt); - }); - - if (!isSame) { - _oldWithTrackBy = newWithTrackBy; - this.heroesWithTrackByChangeCount++; - } - }); - } - } - /////////////////// -} diff --git a/public/docs/_examples/template-syntax/dart/lib/app_component.html b/public/docs/_examples/template-syntax/dart/lib/app_component.html deleted file mode 100644 index c7542c3039..0000000000 --- a/public/docs/_examples/template-syntax/dart/lib/app_component.html +++ /dev/null @@ -1,795 +0,0 @@ - - -

    Template Syntax

    -Interpolation
    -Mental Model
    -Buttons
    -Properties vs. Attributes
    -
    -Property Binding
    - -
    -Event Binding
    - -
    -
    Directives
    - -
    -* prefix and <template>
    -Template reference variables
    -Inputs and outputs
    -Pipes
    -Safe navigation operator ?.
    -Enums
    - - -

    Interpolation

    - - -

    My current hero is {{currentHero.firstName}}

    - - - -

    - {{title}} - -

    - - - - -

    The sum of 1 + 1 is {{1 + 1}}

    - - - - -

    The sum of 1 + 1 is not {{1 + 1 + getVal()}}

    - - -top - - -

    New Mental Model

    - - - - -
    Mental Model
    - - - -

    - -
    - - -
    Mental Model
    - - - -
    -

    - -
    - - - - -
    -

    - -
    - - - -
    - -
    -

    - - - - -
    click me
    - -{{clicked}} -

    - -
    - - - - Hero Name: {{heroName}} -
    -

    - - - - -

    - - -
    Special
    - -

    - - - - -top - - -

    Property vs. Attribute (img examples)

    - - - -

    - - - - - -top - - -

    Buttons

    - - - - -

    - - -

    - - - -top - - -

    Property Binding

    - - - - - - - - -
    [ngClass] binding to the classes property
    - - - - - - - - - - - -
    - - - -
    - - - - - -Interpolated:
    -Property bound: - -
    The interpolated title is {{title}}
    -
    - - -top - - -

    Attribute Binding

    - - - - - - - - - - -
    One-Two
    FiveSix
    - - -
    - - - - -

    - - -
    - - - - - - - - - - -
    - -top - - -

    Class Binding

    - - - -
    Bad curly special
    - - - - -
    Bad curly
    - - - - - -
    The class binding is special
    - - - -
    This one is not so special
    - - -
    This class binding is special too
    - -top - - -

    Style Binding

    - - - - - - - - - - - -top - - -

    Event Binding

    - - - - - - - - - -
    - - - -
    click with myClick
    - - -{{clickMessage}} -
    - - - - - - -
    - - - - - -
    Click me -
    Click me too!
    -
    - -

    - - - -
    - -
    - -

    - - -
    - -
    - -

    - -top - - -

    NgModel (two-way) Binding

    - -

    Result: {{currentHero.firstName}}

    - - - - -without NgModel -
    - - - -[(ngModel)] -
    - - - -bindon-ngModel -
    - - - -(ngModelChange) = "...firstName=$event" -
    - - - -(ngModelChange) = "setUpperCaseFirstName($event)" -
    - -top - - -

    NgClass Binding

    - -

    setClasses returns {{setClasses() | json}}

    - -
    This div is saveable and special
    - -
    - After setClasses(), the classes are "{{classDiv.className}}" -
    - - - -
    This div is special
    - -
    Bad curly special
    -
    Curly special
    - -top - - -

    NgStyle Binding

    - - -
    - This div is x-large. -
    - - -

    Use setStyles() - CSS property names

    -

    setStyles returns {{setStyles()}}.

    - -
    - This div is italic, normal weight, and extra large (24px). -
    - -

    After setStyles(), the DOM confirms that the styles are - - {{getStyles(styleDiv)}} - . -

    - - - -top - - -

    NgIf Binding

    - - -
    Hello, {{currentHero.firstName}}
    - - - - -
    Hello, {{nullHero.firstName}}
    - - - - - - - - - - -
    Hero Detail removed from DOM (via template) because isActive is false
    - - - - -
    Show with class
    -
    Hide with class
    - - - - -
    Show with style
    -
    Hide with style
    - - -top - - -

    NgSwitch Binding

    - -
    - Eenie - Meanie - Miney - Moe - ??? -
    - -
    -
    Pick a toe
    -
    - You picked ... - - - - - - - Eenie - Meanie - Miney - Moe - other - - - - - - - - - - - - -
    -
    - -top - - -

    NgFor Binding

    - -
    - -
    {{hero.fullName}}
    - -
    -
    - -
    - - - - -
    - -top - -

    NgFor with index

    -

    with semi-colon separator

    -
    - -
    {{i + 1}} - {{hero.fullName}}
    - -
    - -

    with comma separator

    -
    - -
    {{i + 1}} - {{hero.fullName}}
    -
    - -top - -

    NgForTrackBy

    - -

    First hero:

    - -

    without trackBy

    -
    - -
    ({{hero.id}}) {{hero.fullName}}
    - -
    -
    - Hero DOM elements change #{{heroesNoTrackByChangeCount}} without trackBy -
    - -

    with trackBy and semi-colon separator

    -
    - -
    ({{hero.id}}) {{hero.fullName}}
    - -
    -
    - Hero DOM elements change #{{heroesWithTrackByChangeCount}} with trackBy -
    - -

    with trackBy and comma separator

    -
    -
    ({{hero.id}}) {{hero.fullName}}
    -
    - -

    with trackBy and space separator

    -
    -
    ({{hero.id}}) {{hero.fullName}}
    -
    - -

    with *ngForTrackBy

    -
    - -
    ({{hero.id}}) {{hero.fullName}}
    - -
    - -

    with generic trackById function

    -
    - -
    ({{hero.id}}) {{hero.fullName}}
    - -
    - -top - - -

    * prefix and <template>

    - -

    *ngIf expansion

    -

    *ngIf

    - - - - -

    expand to template = "..."

    - - - - -

    expand to <template>

    - - - - -

    *ngFor expansion

    -

    *ngFor

    - - - - - -

    expand to template = "..."

    -
    - - - - -
    - -

    expand to <template>

    -
    - - - - -
    - -top - - -

    Template reference variables

    - - - - - - - - - - - -

    Example Form

    - - -
    - -
    - - -
    - - -
    - - -

    - - - - -top - - -

    Inputs and Outputs

    - - - - - - - - - - - -
    myClick2
    -{{clickMessage2}} - -top - - -

    Pipes

    - - -
    Title through uppercase pipe: {{title | uppercase}}
    - - - - -
    - Title through a pipe chain: - {{title | uppercase | lowercase}} -
    - - - - -
    Birthdate: {{currentHero?.birthdate | date:'longDate'}}
    - - - -
    {{currentHero}}
    - - -
    Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}
    - -
    - - {{product['price'] | currency:'USD':false}} -
    - -top - - -

    Safe navigation operator ?.

    - -
    - - The title is {{title}} - -
    - -
    - - The current hero's name is {{currentHero?.firstName}} - -
    - -
    - - The current hero's name is {{currentHero.firstName}} - -
    - - - - - - -
    The null hero's name is {{nullHero.firstName}}
    - - - - -
    - - - The null hero's name is {{nullHero?.firstName}} - -
    - - -top - - - -

    Enums in binding

    - -

    - - The name of the Color.red enum is {{colorRed}}.
    - The current color is {{color}} and its index is {{color.index}}.
    - - -

    - -top diff --git a/public/docs/_examples/template-syntax/dart/lib/hero.dart b/public/docs/_examples/template-syntax/dart/lib/hero.dart deleted file mode 100644 index d366a23c19..0000000000 --- a/public/docs/_examples/template-syntax/dart/lib/hero.dart +++ /dev/null @@ -1,37 +0,0 @@ -// #docregion -class Hero { - static int _nextId = 1; - - final int id; - String firstName; - String lastName; - DateTime birthdate; - String url; - int rate = 100; - - Hero(this.firstName, - {this.lastName, this.birthdate, this.url, this.rate, int id}) - : this.id = id ?? _nextId++; - - String get fullName { - if (lastName == null) return firstName; - return '$firstName $lastName'; - } - - Hero clone() => new Hero(firstName, - lastName: lastName, birthdate: birthdate, url: url, rate: rate, id: id); - - @override String toString() => '$fullName (rate: $rate)'; -} - -final List mockHeroes = [ - new Hero('Hercules', - lastName: 'Son of Zeus', - birthdate: new DateTime(1970, 2, 25), - url: 'http://www.imdb.com/title/tt0065832/', - rate: 325), - new Hero('eenie', lastName: 'toe'), - new Hero('Meanie', lastName: 'Toe'), - new Hero('Miny', lastName: 'Toe'), - new Hero('Moe', lastName: 'Toe') -]; diff --git a/public/docs/_examples/template-syntax/dart/lib/hero_detail_component.dart b/public/docs/_examples/template-syntax/dart/lib/hero_detail_component.dart deleted file mode 100644 index 5fd0b1e3cf..0000000000 --- a/public/docs/_examples/template-syntax/dart/lib/hero_detail_component.dart +++ /dev/null @@ -1,82 +0,0 @@ -// #docplaster -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; - -var nextHeroDetailId = 1; - -// #docregion input-output-2 -@Component( -// #enddocregion input-output-2 - selector: 'hero-detail', -// #docregion input-output-2 - // ... - inputs: const ['hero'], - outputs: const ['deleteRequest'], -// #enddocregion input-output-2 - styles: const [ - 'button { margin-left: 8px} div {margin: 8px 0} img {height:24px}' - ], -// #docregion template-1 - template: ''' -
    - - - {{prefix}} {{hero?.fullName}} - - -
    ''' -// #enddocregion template-1 -// #docregion input-output-2 - ) -// #enddocregion input-output-2 -class HeroDetailComponent { - Hero hero = new Hero('Zzzzzzzz'); // default sleeping hero - String heroImageUrl = 'assets/images/hero.png'; - String lineThrough = ''; // PENDING: use null instead? - @Input() String prefix = ''; - - // #docregion deleteRequest - // This component make a request but it can't actually delete a hero. - final deleteRequest = new EventEmitter(); - - void delete() { - deleteRequest.emit(hero); - // #enddocregion deleteRequest - lineThrough = (lineThrough == '') ? 'line-through' : ''; - // #docregion deleteRequest - } - // #enddocregion deleteRequest -} - -@Component( - selector: 'big-hero-detail', - /* - inputs: ['hero'], - outputs: ['deleteRequest'], - */ - template: ''' -
    - -
    {{hero?.fullName}}
    -
    First: {{hero?.firstName}}
    -
    Last: {{hero?.lastName}}
    -
    Birthdate: {{hero?.birthdate | date:'longDate'}}
    - -
    Rate/hr: {{hero?.rate | currency:'EUR'}}
    -
    - -
    ''') -class BigHeroDetailComponent extends HeroDetailComponent { - // #docregion input-output-1 - @Input() Hero hero; - @Output() final deleteRequest = new EventEmitter(); - // #enddocregion input-output-1 - - String get heroImageUrl => 'assets/images/hero.png'; - - @override void delete() { - deleteRequest.emit(hero); - } -} diff --git a/public/docs/_examples/template-syntax/dart/lib/my_click_directive.dart b/public/docs/_examples/template-syntax/dart/lib/my_click_directive.dart deleted file mode 100644 index 0980478f29..0000000000 --- a/public/docs/_examples/template-syntax/dart/lib/my_click_directive.dart +++ /dev/null @@ -1,42 +0,0 @@ -// #docplaster -import 'dart:html'; - -import 'package:angular2/core.dart'; - -@Directive(selector: '[myClick]') -class MyClickDirective { - // #docregion my-click-output-1 - // @Output(alias) [type info] propertyName = ... - @Output('myClick') final EventEmitter clicks = new EventEmitter(); - - // #enddocregion my-click-output-1 - bool _toggle = false; - - MyClickDirective(ElementRef el) { - Element nativeEl = el.nativeElement; - nativeEl.onClick.listen((Event e) { - _toggle = !_toggle; - clicks.emit(_toggle ? 'Click!' : ''); - }); - } -} - -// #docregion my-click-output-2 -@Directive( -// #enddocregion my-click-output-2 - selector: '[myClick2]', -// #docregion my-click-output-2 - // ... - outputs: const ['clicks:myClick']) // propertyName:alias -// #enddocregion my-click-output-2 -class MyClickDirective2 { - final EventEmitter clicks = new EventEmitter(); - bool _toggle = false; - - MyClickDirective2(ElementRef el) { - el.nativeElement.onClick.listen((Event e) { - _toggle = !_toggle; - clicks.emit(_toggle ? 'Click2!' : ''); - }); - } -} diff --git a/public/docs/_examples/template-syntax/dart/pubspec.yaml b/public/docs/_examples/template-syntax/dart/pubspec.yaml deleted file mode 100644 index bc7f1fc9bb..0000000000 --- a/public/docs/_examples/template-syntax/dart/pubspec.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# #docregion -name: template_syntax -description: Template Syntax -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_pipes: 'package:angular2/common.dart#COMMON_PIPES' - platform_directives: - - 'package:angular2/common.dart#COMMON_DIRECTIVES' - - 'package:angular2/common.dart#FORM_DIRECTIVES' - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/template-syntax/dart/web/assets/images/hero.png b/public/docs/_examples/template-syntax/dart/web/assets/images/hero.png deleted file mode 100644 index b60c3ecc30..0000000000 Binary files a/public/docs/_examples/template-syntax/dart/web/assets/images/hero.png and /dev/null differ diff --git a/public/docs/_examples/template-syntax/dart/web/assets/images/ng-logo.png b/public/docs/_examples/template-syntax/dart/web/assets/images/ng-logo.png deleted file mode 100644 index 7929242740..0000000000 Binary files a/public/docs/_examples/template-syntax/dart/web/assets/images/ng-logo.png and /dev/null differ diff --git a/public/docs/_examples/template-syntax/dart/web/assets/images/villain.png b/public/docs/_examples/template-syntax/dart/web/assets/images/villain.png deleted file mode 100644 index d1e71cf00b..0000000000 Binary files a/public/docs/_examples/template-syntax/dart/web/assets/images/villain.png and /dev/null differ diff --git a/public/docs/_examples/template-syntax/dart/web/index.html b/public/docs/_examples/template-syntax/dart/web/index.html deleted file mode 100644 index 3444f9f8f9..0000000000 --- a/public/docs/_examples/template-syntax/dart/web/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Template Syntax - - - - - - - - Loading... - - diff --git a/public/docs/_examples/template-syntax/dart/web/main.dart b/public/docs/_examples/template-syntax/dart/web/main.dart deleted file mode 100644 index 1a5f965ec1..0000000000 --- a/public/docs/_examples/template-syntax/dart/web/main.dart +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -import 'package:angular2/platform/browser.dart'; - -import 'package:template_syntax/app_component.dart'; - -void main() { - bootstrap(AppComponent); -} diff --git a/public/docs/_examples/template-syntax/dart/web/template-syntax.css b/public/docs/_examples/template-syntax/dart/web/template-syntax.css deleted file mode 100644 index c8c0925830..0000000000 --- a/public/docs/_examples/template-syntax/dart/web/template-syntax.css +++ /dev/null @@ -1,12 +0,0 @@ -fieldset {border-style:none} -img {height: 100px;} -.box {border: 1px solid black; padding:3px} -.child-div {margin-left: 1em; font-weight: normal} -.hidden {display: none} -.parent-div {margin-top: 1em; font-weight: bold} -.special {font-weight:bold; font-size: x-large} -.bad {color: red;} -.curly {font-family: "Brush Script MT"} -.toe {margin-left: 1em; font-style: italic;} -little-hero {color:blue; font-size: smaller; background-color: Turquoise } -.to-toc {margin-top: 10px; display: block} \ No newline at end of file diff --git a/public/docs/_examples/template-syntax/e2e-spec.ts b/public/docs/_examples/template-syntax/e2e-spec.ts index 48f69ba051..71f1c58165 100644 --- a/public/docs/_examples/template-syntax/e2e-spec.ts +++ b/public/docs/_examples/template-syntax/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + // Not yet complete describe('Template Syntax', function () { @@ -12,14 +15,14 @@ describe('Template Syntax', function () { }); it('should be able to use interpolation with a calculation', function () { - let theSumEles = element.all(by.cssContainingText('h3~p','The sum of')); + let theSumEles = element.all(by.cssContainingText('h3~p', 'The sum of')); expect(theSumEles.count()).toBe(2); expect(theSumEles.get(0).getText()).toEqual('The sum of 1 + 1 is 2'); expect(theSumEles.get(1).getText()).toEqual('The sum of 1 + 1 is not 4'); }); it('should be able to use class binding syntax', function () { - let specialEle = element(by.cssContainingText('div','Special')); + let specialEle = element(by.cssContainingText('div', 'Special')); expect(specialEle.getAttribute('class')).toMatch('special'); }); @@ -27,4 +30,14 @@ describe('Template Syntax', function () { let specialButtonEle = element(by.cssContainingText('div.special~button', 'button')); expect(specialButtonEle.getAttribute('style')).toMatch('color: red'); }); + + it('should two-way bind to sizer', async () => { + let div = element(by.css('div#two-way-1')); + let incButton = div.element(by.buttonText('+')); + let input = div.element(by.css('input')); + let initSize = await input.getAttribute('value'); + incButton.click(); + expect(input.getAttribute('value')).toEqual((+initSize + 1).toString()); + }); }); + diff --git a/public/docs/_examples/template-syntax/ts/app/app.component.html b/public/docs/_examples/template-syntax/ts/app/app.component.html deleted file mode 100644 index 57f73c4cb2..0000000000 --- a/public/docs/_examples/template-syntax/ts/app/app.component.html +++ /dev/null @@ -1,804 +0,0 @@ - - -

    Template Syntax

    -Interpolation
    -Mental Model
    -Buttons
    -Properties vs. Attributes
    -
    -Property Binding
    - -
    -Event Binding
    - -
    -
    Directives
    - -
    -* prefix and <template>
    -Template reference variables
    -Inputs and outputs
    -Pipes
    -Safe navigation operator ?.
    -Enums
    - - -

    Interpolation

    - - -

    My current hero is {{currentHero.firstName}}

    - - - -

    - {{title}} - -

    - - - - -

    The sum of 1 + 1 is {{1 + 1}}

    - - - - -

    The sum of 1 + 1 is not {{1 + 1 + getVal()}}

    - - -top - - -

    New Mental Model

    - - - - -
    Mental Model
    - - - -

    - -
    - - -
    Mental Model
    - - - -
    -

    - -
    - - - - -
    -

    - -
    - - - -
    - -
    -

    - - - - -
    click me
    - -{{clicked}} -

    - -
    - - - - Hero Name: {{heroName}} -
    -

    - - - - -

    - - -
    Special
    - -

    - - - - -top - - -

    Property vs. Attribute (img examples)

    - - - -

    - - - - - -top - - -

    Buttons

    - - - - -

    - - -

    - - - -top - - -

    Property Binding

    - - - - - - - - -
    [ngClass] binding to the classes property
    - - - - - - - - - - - -
    - - - -
    - - - - - -

    is the interpolated image.

    -

    is the property bound image.

    - -

    "{{title}}" is the interpolated title.

    -

    "" is the property bound title.

    - - - -

    "{{evilTitle}}" is the interpolated evil title.

    -

    "" is the property bound evil title.

    - - -top - - -

    Attribute Binding

    - - - - - - - - - - -
    One-Two
    FiveSix
    - - -
    - - - - -

    - - -
    - - - - - - - - - - -
    - -top - - -

    Class Binding

    - - - -
    Bad curly special
    - - - - -
    Bad curly
    - - - - - -
    The class binding is special
    - - - -
    This one is not so special
    - - -
    This class binding is special too
    - -top - - -

    Style Binding

    - - - - - - - - - - - -top - - -

    Event Binding

    - - - - - - - - - -
    - - - -
    click with myClick
    - - -{{clickMessage}} -
    - - - - - - -
    - - - - - -
    Click me -
    Click me too!
    -
    - -

    - - - -
    - -
    - -

    - - -
    - -
    - -

    - -top - - -

    NgModel (two-way) Binding

    - -

    Result: {{currentHero.firstName}}

    - - - - -without NgModel -
    - - - -[(ngModel)] -
    - - - -bindon-ngModel -
    - - - -(ngModelChange) = "...firstName=$event" -
    - - - -(ngModelChange) = "setUpperCaseFirstName($event)" -
    - -top - - -

    NgClass Binding

    - -

    setClasses returns {{setClasses() | json}}

    - -
    This div is saveable and special
    - -
    - After setClasses(), the classes are "{{classDiv.className}}" -
    - - - -
    This div is special
    - -
    Bad curly special
    -
    Curly special
    - -top - - -

    NgStyle Binding

    - - -
    - This div is x-large. -
    - - -

    Use setStyles() - CSS property names

    -

    setStyles returns {{setStyles() | json}}

    - -
    - This div is italic, normal weight, and extra large (24px). -
    - -

    After setStyles(), the DOM confirms that the styles are - - {{getStyles(styleDiv)}} - . -

    - - - -top - - -

    NgIf Binding

    - - -
    Hello, {{currentHero.firstName}}
    - - - - -
    Hello, {{nullHero.firstName}}
    - - - - - - - - - - -
    Hero Detail removed from DOM (via template) because isActive is false
    - - - - -
    Show with class
    -
    Hide with class
    - - - - -
    Show with style
    -
    Hide with style
    - - -top - - -

    NgSwitch Binding

    - -
    - Eenie - Meanie - Miney - Moe - ??? -
    - -
    -
    Pick a toe
    -
    - You picked ... - - - - - - - Eenie - Meanie - Miney - Moe - other - - - - - - - - - - - - -
    -
    - -top - - -

    NgFor Binding

    - -
    - -
    {{hero.fullName}}
    - -
    -
    - -
    - - - - -
    - -top - -

    NgFor with index

    -

    with semi-colon separator

    -
    - -
    {{i + 1}} - {{hero.fullName}}
    - -
    - -

    with comma separator

    -
    - -
    {{i + 1}} - {{hero.fullName}}
    -
    - -top - -

    NgForTrackBy

    - -

    First hero:

    - -

    without trackBy

    -
    - -
    ({{hero.id}}) {{hero.fullName}}
    - -
    -
    - Hero DOM elements change #{{heroesNoTrackByChangeCount}} without trackBy -
    - -

    with trackBy and semi-colon separator

    -
    - -
    ({{hero.id}}) {{hero.fullName}}
    - -
    -
    - Hero DOM elements change #{{heroesWithTrackByChangeCount}} with trackBy -
    - -

    with trackBy and comma separator

    -
    -
    ({{hero.id}}) {{hero.fullName}}
    -
    - -

    with trackBy and space separator

    -
    -
    ({{hero.id}}) {{hero.fullName}}
    -
    - -

    with *ngForTrackBy

    -
    - -
    ({{hero.id}}) {{hero.fullName}}
    - -
    - -

    with generic trackById function

    -
    - -
    ({{hero.id}}) {{hero.fullName}}
    - -
    - -top - - -

    * prefix and <template>

    - -

    *ngIf expansion

    -

    *ngIf

    - - - - -

    expand to template = "..."

    - - - - -

    expand to <template>

    - - - - -

    *ngFor expansion

    -

    *ngFor

    - - - - - -

    expand to template = "..."

    -
    - - - - -
    - -

    expand to <template>

    -
    - - - - -
    - -top - - -

    Template reference variables

    - - - - - - - - - - - -

    Example Form

    - - -
    - -
    - - -
    - - -
    - - -

    - - - - -top - - -

    Inputs and Outputs

    - - - - - - - - - - - -
    myClick2
    -{{clickMessage2}} - -top - - -

    Pipes

    - - -
    Title through uppercase pipe: {{title | uppercase}}
    - - - - -
    - Title through a pipe chain: - {{title | uppercase | lowercase}} -
    - - - - -
    Birthdate: {{currentHero?.birthdate | date:'longDate'}}
    - - - -
    {{currentHero | json}}
    - - -
    Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}
    - -
    - - {{product.price | currency:'USD':true}} -
    - -top - - -

    Safe navigation operator ?.

    - -
    - - The title is {{title}} - -
    - -
    - - The current hero's name is {{currentHero?.firstName}} - -
    - -
    - - The current hero's name is {{currentHero.firstName}} - -
    - - - - - - -
    The null hero's name is {{nullHero.firstName}}
    - - -
    - -The null hero's name is {{nullHero && nullHero.firstName}} - -
    - -
    - - - The null hero's name is {{nullHero?.firstName}} - -
    - - -top - - - -

    Enums in binding

    - -

    - - The name of the Color.Red enum is {{Color[Color.Red]}}.
    - The current color is {{Color[color]}} and its number is {{color}}.
    - - -

    - -top diff --git a/public/docs/_examples/template-syntax/ts/app/app.component.ts b/public/docs/_examples/template-syntax/ts/app/app.component.ts deleted file mode 100644 index c4e32c74d1..0000000000 --- a/public/docs/_examples/template-syntax/ts/app/app.component.ts +++ /dev/null @@ -1,252 +0,0 @@ -/* tslint:disable:member-ordering forin */ -// #docplaster - -import { AfterViewInit, Component, ElementRef, OnInit, QueryList, ViewChildren } from '@angular/core'; -import { NgForm } from '@angular/common'; - -import { Hero } from './hero'; -import { HeroDetailComponent, BigHeroDetailComponent } from './hero-detail.component'; -import { MyClickDirective, MyClickDirective2 } from './my-click.directive'; - -// Alerter fn: monkey patch during test -export function alerter(msg?: string) { - window.alert(msg); -} - -export enum Color {Red, Green, Blue}; - -/** - * Giant grab bag of stuff to drive the chapter - */ -@Component({ - selector: 'my-app', - templateUrl: 'app/app.component.html', - directives: [ - HeroDetailComponent, BigHeroDetailComponent, - MyClickDirective, MyClickDirective2 - ] -}) -export class AppComponent implements AfterViewInit, OnInit { - - ngOnInit() { - this.refreshHeroes(); - } - - ngAfterViewInit() { - this.detectNgForTrackByEffects(); - } - - actionName = 'Go for it'; - alert = alerter; - badCurly = 'bad curly'; - classes = 'special'; - - callFax(value: string) {this.alert(`Faxing ${value} ...`); } - callPhone(value: string) {this.alert(`Calling ${value} ...`); } - canSave = true; - - Color = Color; - color = Color.Red; - colorToggle() {this.color = (this.color === Color.Red) ? Color.Blue : Color.Red; } - - currentHero = Hero.MockHeroes[0]; - - deleteHero(hero: Hero) { - this.alert('Deleted hero: ' + (hero && hero.firstName)); - } - - // #docregion evil-title - evilTitle = 'Template Syntax'; - // #enddocregion evil-title - - title = 'Template Syntax'; - - // DevMode memoization fields - private priorClasses: {}; - private _priorStyles: {}; - - getStyles(el: Element) { - let styles = window.getComputedStyle(el); - let showStyles = {}; - for (let p in this.setStyles()) { - showStyles[p] = styles[p]; - } - return JSON.stringify(showStyles); - } - - getVal() { return this.val; } - - heroes: Hero[]; - - // heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png'; - // Public Domain terms of use: http://www.wpclipart.com/terms.html - heroImageUrl = 'images/hero.png'; - - // iconUrl = 'https://angular.io/resources/images/logos/standard/shield-large.png'; - clicked = ''; - clickMessage = ''; - clickMessage2 = ''; - iconUrl = 'images/ng-logo.png'; - isActive = false; - isSpecial = true; - isUnchanged = true; - - nullHero: Hero = null; // or undefined - - onCancel(event: KeyboardEvent) { - let evtMsg = event ? ' Event target is ' + (event.target).innerHTML : ''; - this.alert('Canceled.' + evtMsg); - } - - onClickMe(event: KeyboardEvent) { - let evtMsg = event ? ' Event target class is ' + (event.target).className : ''; - this.alert('Click me.' + evtMsg); - } - - onSave(event: KeyboardEvent) { - let evtMsg = event ? ' Event target is ' + (event.target).innerText : ''; - this.alert('Saved.' + evtMsg); - } - - onSubmit(form: NgForm) { - let evtMsg = form.valid ? - ' Form value is ' + JSON.stringify(form.value) : - ' Form is invalid'; - this.alert('Form submitted.' + evtMsg); - } - - product = { - name: 'frimfram', - price: 42 - }; - - // #docregion refresh-heroes - // update this.heroes with fresh set of cloned heroes - refreshHeroes() { - this.heroes = Hero.MockHeroes.map(hero => Hero.clone(hero)); - } - // #enddocregion refresh-heroes - - // #docregion same-as-it-ever-was - private samenessCount = 5; - moreOfTheSame() { this.samenessCount++; }; - get sameAsItEverWas() { - let result: string[] = Array(this.samenessCount); - for ( let i = result.length; i-- > 0; ) { result[i] = 'same as it ever was ...'; } - return result; - // return [1,2,3,4,5].map(id => { - // return {id:id, text: 'same as it ever was ...'}; - // }); - } - // #enddocregion same-as-it-ever-was - - setUpperCaseFirstName(firstName: string) { - // console.log(firstName); - this.currentHero.firstName = firstName.toUpperCase(); - } - - // #docregion setClasses - setClasses() { - let classes = { - saveable: this.canSave, // true - modified: !this.isUnchanged, // false - special: this.isSpecial, // true - }; - // #enddocregion setClasses - // compensate for DevMode (sigh) - if (JSON.stringify(classes) === JSON.stringify(this.priorClasses)) { - return this.priorClasses; - } - this.priorClasses = classes; - // #docregion setClasses - return classes; - } - // #enddocregion setClasses - - - // #docregion setStyles - setStyles() { - let styles = { - // CSS property names - 'font-style': this.canSave ? 'italic' : 'normal', // italic - 'font-weight': !this.isUnchanged ? 'bold' : 'normal', // normal - 'font-size': this.isSpecial ? '24px' : '8px', // 24px - }; - // #enddocregion setStyles - // compensate for DevMode (sigh) - if (JSON.stringify(styles) === JSON.stringify(this._priorStyles)) { - return this._priorStyles; - } - this._priorStyles = styles; - // #docregion setStyles - return styles; - } - // #enddocregion setStyles - - toeChoice = ''; - toeChooser(picker: HTMLFieldSetElement) { - let choices = picker.children; - for (let i = 0; i < choices.length; i++) { - let choice = choices[i]; - if (choice.checked) {return this.toeChoice = choice.value; } - } - } - - - // #docregion trackByHeroes - trackByHeroes(index: number, hero: Hero) { return hero.id; } - // #enddocregion trackByHeroes - - // #docregion trackById - trackById(index: number, item: any): string { return item['id']; } - // #enddocregion trackById - - val = 2; - // villainImageUrl = 'http://www.clker.com/cliparts/u/s/y/L/x/9/villain-man-hi.png' - // Public Domain terms of use http://www.clker.com/disclaimer.html - villainImageUrl = 'images/villain.png'; - - - //////// Detect effects of NgForTrackBy /////////////// - @ViewChildren('noTrackBy') childrenNoTrackBy: QueryList; - @ViewChildren('withTrackBy') childrenWithTrackBy: QueryList; - - private _oldNoTrackBy: HTMLElement[]; - private _oldWithTrackBy: HTMLElement[]; - - heroesNoTrackByChangeCount = 0; - heroesWithTrackByChangeCount = 0; - - private detectNgForTrackByEffects() { - this._oldNoTrackBy = toArray(this.childrenNoTrackBy); - this._oldWithTrackBy = toArray(this.childrenWithTrackBy); - - this.childrenNoTrackBy.changes.subscribe((changes: any) => { - let newNoTrackBy = toArray(changes); - let isSame = this._oldNoTrackBy.every((v: any, i: number) => v === newNoTrackBy[i]); - if (!isSame) { - this._oldNoTrackBy = newNoTrackBy; - this.heroesNoTrackByChangeCount++; - } - }); - - this.childrenWithTrackBy.changes.subscribe((changes: any) => { - let newWithTrackBy = toArray(changes); - let isSame = this._oldWithTrackBy.every((v: any, i: number) => v === newWithTrackBy[i]); - if (!isSame) { - this._oldWithTrackBy = newWithTrackBy; - this.heroesWithTrackByChangeCount++; - } - }); - } - /////////////////// - -} - -// helper to convert viewChildren to an array of HTMLElements -function toArray(viewChildren: QueryList) { - let result: HTMLElement[] = []; - let children = viewChildren.toArray()[0].nativeElement.children; - for (let i = 0; i < children.length; i++) { result.push(children[i]); } - return result; -} diff --git a/public/docs/_examples/template-syntax/ts/app/decorator.directive.ts b/public/docs/_examples/template-syntax/ts/app/decorator.directive.ts deleted file mode 100644 index a7e9c7d93c..0000000000 --- a/public/docs/_examples/template-syntax/ts/app/decorator.directive.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Useful for spying on an element -// for fun; not used (yet) -import { Directive, ElementRef } from '@angular/core'; - -// set the selector for the element type to spy on. -@Directive({selector: 'select'}) -export class DecoratorDirective { - constructor(el: ElementRef){ - console.log(el) - } -} \ No newline at end of file diff --git a/public/docs/_examples/template-syntax/ts/app/hero-detail.component.ts b/public/docs/_examples/template-syntax/ts/app/hero-detail.component.ts deleted file mode 100644 index b613fa63b4..0000000000 --- a/public/docs/_examples/template-syntax/ts/app/hero-detail.component.ts +++ /dev/null @@ -1,78 +0,0 @@ -// #docplaster -import { Component, EventEmitter, Input, Output } from '@angular/core'; - -import { Hero } from './hero'; - -let nextHeroDetailId = 1; - -// #docregion input-output-2 -@Component({ -// #enddocregion input-output-2 - selector: 'hero-detail', - // #docregion input-output-2 - inputs: ['hero'], - outputs: ['deleteRequest'], - // #enddocregion input-output-2 - styles:['button { margin-left: 8px} div {margin: 8px 0} img {height:24px}'], - // #docregion template-1 - template: ` -
    - - - {{prefix}} {{hero?.fullName}} - - -
    ` - // #enddocregion template-1 -// #docregion input-output-2 -}) -// #enddocregion input-output-2 -export class HeroDetailComponent { - -// #docregion deleteRequest - // This component make a request but it can't actually delete a hero. - deleteRequest = new EventEmitter(); - - delete() { - this.deleteRequest.emit(this.hero); - // #enddocregion deleteRequest - this.lineThrough = this.lineThrough ? '' : 'line-through'; - // #docregion deleteRequest - } -// #enddocregion deleteRequest - - hero: Hero = new Hero('','Zzzzzzzz'); // default sleeping hero - // heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png'; - // Public Domain terms of use: http://www.wpclipart.com/terms.html - heroImageUrl = 'images/hero.png'; - lineThrough = ''; - @Input() prefix = ''; -} - -@Component({ - selector: 'big-hero-detail', - template: ` -
    - -
    {{hero?.fullName}}
    -
    First: {{hero?.firstName}}
    -
    Last: {{hero?.lastName}}
    -
    Birthdate: {{hero?.birthdate | date:'longDate'}}
    - -
    Rate/hr: {{hero?.rate | currency:'EUR'}}
    -
    - -
    - ` -}) -export class BigHeroDetailComponent extends HeroDetailComponent { - - // #docregion input-output-1 - @Input() hero: Hero; - @Output() deleteRequest = new EventEmitter(); - // #enddocregion input-output-1 - - delete() { - this.deleteRequest.emit(this.hero); - } -} diff --git a/public/docs/_examples/template-syntax/ts/app/hero.ts b/public/docs/_examples/template-syntax/ts/app/hero.ts deleted file mode 100644 index aca1fd5a72..0000000000 --- a/public/docs/_examples/template-syntax/ts/app/hero.ts +++ /dev/null @@ -1,36 +0,0 @@ -export class Hero { - public id:number - - constructor( - public firstName:string, - public lastName?:string, - public birthdate?:Date, - public url?:string, - public rate:number = 100, - id?:number) { - - this.id = id != null ? id : Hero.nextId++; - } - - static clone({firstName, lastName, birthdate, url, rate, id} : Hero){ - return new Hero (firstName, lastName, birthdate, url, rate, id ); - } - - get fullName() {return `${this.firstName} ${this.lastName}`;} - - static nextId = 1; - - static MockHeroes = [ - new Hero( - 'Hercules', - 'Son of Zeus', - new Date(1970, 1, 25), - 'http://www.imdb.com/title/tt0065832/', - 325), - - new Hero('eenie', 'toe'), - new Hero('Meanie', 'Toe'), - new Hero('Miny', 'Toe'), - new Hero('Moe', 'Toe') - ]; -} \ No newline at end of file diff --git a/public/docs/_examples/template-syntax/ts/app/main.ts b/public/docs/_examples/template-syntax/ts/app/main.ts deleted file mode 100644 index 19551339f8..0000000000 --- a/public/docs/_examples/template-syntax/ts/app/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); \ No newline at end of file diff --git a/public/docs/_examples/template-syntax/ts/app/my-click.directive.ts b/public/docs/_examples/template-syntax/ts/app/my-click.directive.ts deleted file mode 100644 index 4b2b23b5cf..0000000000 --- a/public/docs/_examples/template-syntax/ts/app/my-click.directive.ts +++ /dev/null @@ -1,39 +0,0 @@ -// #docplaster -import { Directive, ElementRef, EventEmitter, Output } from '@angular/core'; - -@Directive({selector:'[myClick]'}) -export class MyClickDirective { - // #docregion my-click-output-1 - @Output('myClick') clicks = new EventEmitter(); // @Output(alias) propertyName = ... - // #enddocregion my-click-output-1 - - constructor(el: ElementRef){ - el.nativeElement - .addEventListener('click', (event:Event) => { - this.toggle = !this.toggle; - this.clicks.emit(this.toggle ? 'Click!' : ''); - }); - } - toggle = false; -} - -// #docregion my-click-output-2 -@Directive({ -// #enddocregion my-click-output-2 - selector:'[myClick2]', -// #docregion my-click-output-2 - outputs:['clicks:myClick'] // propertyName:alias -}) -// #enddocregion my-click-output-2 -export class MyClickDirective2 { - clicks = new EventEmitter(); - - constructor(el: ElementRef){ - el.nativeElement - .addEventListener('click', (event:Event) => { - this.toggle = !this.toggle; - this.clicks.emit(this.toggle ? 'Click2!' : ''); - }); - } - toggle = false; -} diff --git a/public/docs/_examples/template-syntax/ts/images/hero.png b/public/docs/_examples/template-syntax/ts/images/hero.png deleted file mode 100644 index b60c3ecc30..0000000000 Binary files a/public/docs/_examples/template-syntax/ts/images/hero.png and /dev/null differ diff --git a/public/docs/_examples/template-syntax/ts/images/ng-logo.png b/public/docs/_examples/template-syntax/ts/images/ng-logo.png deleted file mode 100644 index 7929242740..0000000000 Binary files a/public/docs/_examples/template-syntax/ts/images/ng-logo.png and /dev/null differ diff --git a/public/docs/_examples/template-syntax/ts/images/villain.png b/public/docs/_examples/template-syntax/ts/images/villain.png deleted file mode 100644 index d1e71cf00b..0000000000 Binary files a/public/docs/_examples/template-syntax/ts/images/villain.png and /dev/null differ diff --git a/public/docs/_examples/template-syntax/ts/index.html b/public/docs/_examples/template-syntax/ts/index.html deleted file mode 100644 index d3a4ec6aa6..0000000000 --- a/public/docs/_examples/template-syntax/ts/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - Template Syntax - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/template-syntax/ts/plnkr.json b/public/docs/_examples/template-syntax/ts/plnkr.json index 05efe8f536..099616ad7c 100644 --- a/public/docs/_examples/template-syntax/ts/plnkr.json +++ b/public/docs/_examples/template-syntax/ts/plnkr.json @@ -1,5 +1,6 @@ { "description": "Template Syntax Collection", + "basePath": "src/", "files":["!**/*.d.ts", "!**/*.js"], "tags": ["template"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/template-syntax/ts/src/app/app.component.css b/public/docs/_examples/template-syntax/ts/src/app/app.component.css new file mode 100644 index 0000000000..23f9667623 --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/app.component.css @@ -0,0 +1,17 @@ +a.to-toc { margin: 30px 0; } +button { font-size: 100%; margin: 0 2px; } +div[clickable] {cursor: pointer; max-width: 200px; margin: 16px 0} +#noTrackByCnt, #withTrackByCnt {color: darkred; max-width: 450px; margin: 4px;} +img {height: 100px;} +.box {border: 1px solid black; padding: 6px; max-width: 450px;} +.child-div {margin-left: 1em; font-weight: normal} +.context {margin-left: 1em;} +.hidden {display: none} +.parent-div {margin-top: 1em; font-weight: bold} +.special {font-weight:bold; font-size: x-large} +.bad {color: red;} +.saveable {color: limegreen;} +.curly, .modified {font-family: "Brush Script MT"} +.toe {margin-left: 1em; font-style: italic;} +little-hero {color:blue; font-size: smaller; background-color: Turquoise } +.to-toc {margin-top: 10px; display: block} diff --git a/public/docs/_examples/template-syntax/ts/src/app/app.component.html b/public/docs/_examples/template-syntax/ts/src/app/app.component.html new file mode 100644 index 0000000000..760fa3a367 --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/app.component.html @@ -0,0 +1,820 @@ + + +

    Template Syntax

    +Interpolation
    +Expression context
    +Statement context
    +Mental Model
    +Buttons
    +Properties vs. Attributes
    +
    +Property Binding
    + +
    +Event Binding
    +Two-way Binding
    +
    +
    Directives
    + +
    +Template reference variables
    +Inputs and outputs
    +Pipes
    +Safe navigation operator ?.
    +Enums
    + + +

    Interpolation

    + + +

    My current hero is {{currentHero.name}}

    + + + +

    + {{title}} + +

    + + + + +

    The sum of 1 + 1 is {{1 + 1}}

    + + + + +

    The sum of 1 + 1 is not {{1 + 1 + getVal()}}

    + + +top + +

    Expression context

    + +

    Component expression context ({{title}}, [hidden]="isUnchanged")

    +
    + + {{title}} + changed + +
    + + +

    Template input variable expression context (let hero)

    + + + +

    Template reference variable expression context (#heroInput)

    +
    + Type something: + + {{heroInput.value}} + +
    + +top + +

    Statement context

    + +

    Component statement context ( (click)="onSave() ) +

    + + + +
    + +

    Template $event statement context

    +
    + + + +
    + +

    Template input variable statement context (let hero)

    + +
    + + + +
    + +

    Template reference variable statement context (#heroForm)

    +
    + +
    ...
    + +
    + +top + + +

    New Mental Model

    + + + + +
    Mental Model
    + + + +

    + +
    + + +
    Mental Model
    + + + +
    +

    + +
    + + + + +
    +

    + +
    + + + +
    + +
    +

    + + + + +
    click me
    + +{{clicked}} +

    + +
    + Hero Name: + + + + {{name}} +
    +

    + + + + +

    + + +
    Special
    + +

    + + + + +top + + +

    Property vs. Attribute (img examples)

    + + + +

    + + + + + +top + + +

    Buttons

    + + + + +

    + + +

    + + + +top + + +

    Property Binding

    + + + + + + + + +
    [ngClass] binding to the classes property
    + + + + + + + + + + + +
    + + + +
    + + + + + +

    is the interpolated image.

    +

    is the property bound image.

    + +

    "{{title}}" is the interpolated title.

    +

    "" is the property bound title.

    + + + + +

    "{{evilTitle}}" is the interpolated evil title.

    +

    "" is the property bound evil title.

    + + +top + + +

    Attribute Binding

    + + + + + + + + + + +
    One-Two
    FiveSix
    + + +
    + + + + +

    + + +
    + + + + + + + +
    + +top + + +

    Class Binding

    + + + +
    Bad curly special
    + + + + +
    Bad curly
    + + + + + +
    The class binding is special
    + + + +
    This one is not so special
    + + +
    This class binding is special too
    + +top + + +

    Style Binding

    + + + + + + + + + + + +top + + +

    Event Binding

    + + + + + + + + + +
    + + + +
    click with myClick
    + + +{{clickMessage}} +
    + + + + + + +
    + + + + + +
    Click me +
    Click me too!
    +
    + + + + +
    + +
    + + + + +
    + +
    + + +top + +

    Two-way Binding

    +
    + + +
    Resizable Text
    + + +
    +
    +
    +

    De-sugared two-way binding

    + + + +
    + +top + + +

    NgModel (two-way) Binding

    + +

    Result: {{currentHero.name}}

    + + + + +without NgModel +
    + + + +[(ngModel)] +
    + + + +bindon-ngModel +
    + + + +(ngModelChange)="...name=$event" +
    + + + +(ngModelChange)="setUppercaseName($event)" + +top + + +

    NgClass Binding

    + +

    currentClasses is {{currentClasses | json}}

    + +
    This div is initially saveable, unchanged, and special
    + + + +
    + | + | + + +

    +
    + This div should be {{ canSave ? "": "not"}} saveable, + {{ isUnchanged ? "unchanged" : "modified" }} and, + {{ isSpecial ? "": "not"}} special after clicking "Refresh".
    +

    + +
    This div is special
    + +
    Bad curly special
    +
    Curly special
    + +top + + +

    NgStyle Binding

    + + +
    + This div is x-large or smaller. +
    + + +

    [ngStyle] binding to currentStyles - CSS property names

    +

    currentStyles is {{currentStyles | json}}

    + +
    + This div is initially italic, normal weight, and extra large (24px). +
    + + + +
    + | + | + + +

    +
    + This div should be {{ canSave ? "italic": "plain"}}, + {{ isUnchanged ? "normal weight" : "bold" }} and, + {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".
    + +top + + +

    NgIf Binding

    + + + + + + +
    Hello, {{currentHero.name}}
    +
    Hello, {{nullHero.name}}
    + + + + +Add {{currentHero.name}} with template + + +
    Hero Detail removed from DOM (via template) because isActive is false
    + + + + + + +
    Show with class
    +
    Hide with class
    + + + + +
    Show with style
    +
    Hide with style
    + + +top + + +

    NgFor Binding

    + +
    + +
    {{hero.name}}
    + +
    +
    + +
    + + + + +
    + +top + +

    *ngFor with index

    +

    with semi-colon separator

    +
    + +
    {{i + 1}} - {{hero.name}}
    + +
    + +

    with comma separator

    +
    + +
    {{i + 1}} - {{hero.name}}
    +
    + +top + +

    *ngFor trackBy

    + + + + +

    without trackBy

    +
    +
    ({{hero.id}}) {{hero.name}}
    + +
    + Hero DOM elements change #{{heroesNoTrackByCount}} without trackBy +
    +
    + +

    with trackBy

    +
    +
    ({{hero.id}}) {{hero.name}}
    + +
    + Hero DOM elements change #{{heroesWithTrackByCount}} with trackBy +
    +
    + +


    + +

    with trackBy and semi-colon separator

    +
    + +
    + ({{hero.id}}) {{hero.name}} +
    + +
    + +

    with trackBy and comma separator

    +
    +
    ({{hero.id}}) {{hero.name}}
    +
    + +

    with trackBy and space separator

    +
    +
    ({{hero.id}}) {{hero.name}}
    +
    + +

    with generic trackById function

    +
    +
    ({{hero.id}}) {{hero.name}}
    +
    + +top + + +

    NgSwitch Binding

    + +

    Pick your favorite hero

    +
    + +
    + + +
    + + + + + +
    Are you as confused as {{currentHero.name}}?
    + + + +
    + + +top + + +

    Template reference variables

    + + + + + + + + + + + + + + + + + + + + +

    Example Form

    + + +top + + +

    Inputs and Outputs

    + + + + + + + + + + + +
    myClick2
    +{{clickMessage2}} + +top + + +

    Pipes

    + + +
    Title through uppercase pipe: {{title | uppercase}}
    + + + + +
    + Title through a pipe chain: + {{title | uppercase | lowercase}} +
    + + + + +
    Birthdate: {{currentHero?.birthdate | date:'longDate'}}
    + + + +
    {{currentHero | json}}
    + + +
    Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}
    + +
    + + {{product.price | currency:'USD':true}} +
    + +top + + +

    Safe navigation operator ?.

    + +
    + + The title is {{title}} + +
    + +
    + + The current hero's name is {{currentHero?.name}} + +
    + +
    + + The current hero's name is {{currentHero.name}} + +
    + + + + + + +
    The null hero's name is {{nullHero.name}}
    + + +
    + +The null hero's name is {{nullHero && nullHero.name}} + +
    + +
    + + + The null hero's name is {{nullHero?.name}} + +
    + +top + + + +

    Enums in binding

    + +

    + + The name of the Color.Red enum is {{Color[Color.Red]}}.
    + The current color is {{Color[color]}} and its number is {{color}}.
    + + +

    + +top diff --git a/public/docs/_examples/template-syntax/ts/src/app/app.component.ts b/public/docs/_examples/template-syntax/ts/src/app/app.component.ts new file mode 100644 index 0000000000..f0fa2a2d23 --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/app.component.ts @@ -0,0 +1,183 @@ +/* tslint:disable:forin member-ordering */ +// #docplaster + +import { AfterViewInit, Component, ElementRef, OnInit, QueryList, ViewChildren } from '@angular/core'; + +import { Hero } from './hero'; + +export enum Color {Red, Green, Blue}; + +/** + * Giant grab bag of stuff to drive the chapter + */ +@Component({ + selector: 'my-app', + templateUrl: './app.component.html', + styleUrls: [ './app.component.css' ] +}) +export class AppComponent implements AfterViewInit, OnInit { + + ngOnInit() { + this.resetHeroes(); + this.setCurrentClasses(); + this.setCurrentStyles(); + } + + ngAfterViewInit() { + // Detect effects of NgForTrackBy + trackChanges(this.heroesNoTrackBy, () => this.heroesNoTrackByCount++); + trackChanges(this.heroesWithTrackBy, () => this.heroesWithTrackByCount++); + } + + @ViewChildren('noTrackBy') heroesNoTrackBy: QueryList; + @ViewChildren('withTrackBy') heroesWithTrackBy: QueryList; + + actionName = 'Go for it'; + badCurly = 'bad curly'; + classes = 'special'; + help = ''; + + alert(msg?: string) { window.alert(msg); } + callFax(value: string) { this.alert(`Faxing ${value} ...`); } + callPhone(value: string) { this.alert(`Calling ${value} ...`); } + canSave = true; + + changeIds() { + this.resetHeroes(); + this.heroes.forEach(h => h.id += 10 * this.heroIdIncrement++); + this.heroesWithTrackByCountReset = -1; + } + + clearTrackByCounts() { + const trackByCountReset = this.heroesWithTrackByCountReset; + this.resetHeroes(); + this.heroesNoTrackByCount = -1; + this.heroesWithTrackByCount = trackByCountReset; + this.heroIdIncrement = 1; + } + + clicked = ''; + clickMessage = ''; + clickMessage2 = ''; + + Color = Color; + color = Color.Red; + colorToggle() {this.color = (this.color === Color.Red) ? Color.Blue : Color.Red; } + + currentHero: Hero; + + deleteHero(hero: Hero) { + this.alert(`Delete ${hero ? hero.name : 'the hero'}.`); + } + + // #docregion evil-title + evilTitle = 'Template Syntax'; + // #enddocregion evil-title + + fontSizePx = 16; + + title = 'Template Syntax'; + + getVal(): number { return 2; } + + name: string = Hero.heroes[0].name; + hero: Hero; // defined to demonstrate template context precedence + heroes: Hero[]; + + // trackBy change counting + heroesNoTrackByCount = 0; + heroesWithTrackByCount = 0; + heroesWithTrackByCountReset = 0; + + heroIdIncrement = 1; + + // heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png'; + // Public Domain terms of use: http://www.wpclipart.com/terms.html + heroImageUrl = 'images/hero.png'; + // villainImageUrl = 'http://www.clker.com/cliparts/u/s/y/L/x/9/villain-man-hi.png' + // Public Domain terms of use http://www.clker.com/disclaimer.html + villainImageUrl = 'images/villain.png'; + + iconUrl = 'images/ng-logo.png'; + isActive = false; + isSpecial = true; + isUnchanged = true; + + get nullHero(): Hero { return null; } + + onClickMe(event: KeyboardEvent) { + let evtMsg = event ? ' Event target class is ' + (event.target).className : ''; + this.alert('Click me.' + evtMsg); + } + + onSave(event: KeyboardEvent) { + let evtMsg = event ? ' Event target is ' + (event.target).innerText : ''; + this.alert('Saved.' + evtMsg); + if (event) { event.stopPropagation(); } + } + + onSubmit() {/* referenced but not used */} + + product = { + name: 'frimfram', + price: 42 + }; + + // updates with fresh set of cloned heroes + resetHeroes() { + this.heroes = Hero.heroes.map(hero => hero.clone()); + this.currentHero = this.heroes[0]; + this.heroesWithTrackByCountReset = 0; + } + + setUppercaseName(name: string) { + this.currentHero.name = name.toUpperCase(); + } + + // #docregion setClasses + currentClasses: {}; + setCurrentClasses() { + // CSS classes: added/removed per current state of component properties + this.currentClasses = { + saveable: this.canSave, + modified: !this.isUnchanged, + special: this.isSpecial + }; + } + // #enddocregion setClasses + + // #docregion setStyles + currentStyles: {}; + setCurrentStyles() { + // CSS styles: set per current state of component properties + this.currentStyles = { + 'font-style': this.canSave ? 'italic' : 'normal', + 'font-weight': !this.isUnchanged ? 'bold' : 'normal', + 'font-size': this.isSpecial ? '24px' : '12px' + }; + } + // #enddocregion setStyles + + // #docregion trackByHeroes + trackByHeroes(index: number, hero: Hero): number { return hero.id; } + // #enddocregion trackByHeroes + + // #docregion trackById + trackById(index: number, item: any): number { return item['id']; } + // #enddocregion trackById +} + +// helper to track changes to viewChildren +function trackChanges(views: QueryList, changed: () => void) { + let oldRefs = views.toArray(); + views.changes.subscribe((changes: QueryList) => { + const changedRefs = changes.toArray(); + // Is every changed ElemRef the same as old and in the same position + const isSame = oldRefs.every((v, i) => v === changedRefs[i]); + if (!isSame) { + oldRefs = changedRefs; + // wait a tick because called after views are constructed + setTimeout(changed, 0); + } + }); +} diff --git a/public/docs/_examples/template-syntax/ts/src/app/app.module.1.ts b/public/docs/_examples/template-syntax/ts/src/app/app.module.1.ts new file mode 100644 index 0000000000..8ea0d3d207 --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/app.module.1.ts @@ -0,0 +1,15 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; // <--- JavaScript import from Angular + +/* Other imports */ + +@NgModule({ + imports: [ + BrowserModule, + FormsModule // <--- import into the NgModule + ], + /* Other module metadata */ +}) +export class AppModule { } diff --git a/public/docs/_examples/template-syntax/ts/src/app/app.module.ts b/public/docs/_examples/template-syntax/ts/src/app/app.module.ts new file mode 100644 index 0000000000..5c2fbed6f1 --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/app.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { BigHeroDetailComponent, HeroDetailComponent } from './hero-detail.component'; +import { ClickDirective, ClickDirective2 } from './click.directive'; +import { HeroFormComponent } from './hero-form.component'; +import { heroSwitchComponents } from './hero-switch.components'; +import { SizerComponent } from './sizer.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule + ], + declarations: [ + AppComponent, + BigHeroDetailComponent, + HeroDetailComponent, + HeroFormComponent, + heroSwitchComponents, + ClickDirective, + ClickDirective2, + SizerComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/template-syntax/ts/src/app/click.directive.ts b/public/docs/_examples/template-syntax/ts/src/app/click.directive.ts new file mode 100644 index 0000000000..09757bfeaf --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/click.directive.ts @@ -0,0 +1,41 @@ +/* tslint:disable use-output-property-decorator */ +// #docplaster +import { Directive, ElementRef, EventEmitter, Output } from '@angular/core'; + +@Directive({selector: '[myClick]'}) +export class ClickDirective { + // #docregion output-myClick + @Output('myClick') clicks = new EventEmitter(); // @Output(alias) propertyName = ... + // #enddocregion output-myClick + + toggle = false; + + constructor(el: ElementRef) { + el.nativeElement + .addEventListener('click', (event: Event) => { + this.toggle = !this.toggle; + this.clicks.emit(this.toggle ? 'Click!' : ''); + }); + } +} + +// #docregion output-myClick2 +@Directive({ + // #enddocregion output-myClick2 + selector: '[myClick2]', + // #docregion output-myClick2 + outputs: ['clicks:myClick'] // propertyName:alias +}) +// #enddocregion output-myClick2 +export class ClickDirective2 { + clicks = new EventEmitter(); + toggle = false; + + constructor(el: ElementRef) { + el.nativeElement + .addEventListener('click', (event: Event) => { + this.toggle = !this.toggle; + this.clicks.emit(this.toggle ? 'Click2!' : ''); + }); + } +} diff --git a/public/docs/_examples/template-syntax/ts/src/app/hero-detail.component.ts b/public/docs/_examples/template-syntax/ts/src/app/hero-detail.component.ts new file mode 100644 index 0000000000..725849d692 --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/hero-detail.component.ts @@ -0,0 +1,80 @@ +/* tslint:disable use-input-property-decorator use-output-property-decorator */ +// #docplaster +import { Component, EventEmitter, Input, Output } from '@angular/core'; + +import { Hero } from './hero'; + +// #docregion input-output-2 +@Component({ +// #enddocregion input-output-2 + selector: 'hero-detail', + // #docregion input-output-2 + inputs: ['hero'], + outputs: ['deleteRequest'], + // #enddocregion input-output-2 + styles: ['button {margin-left: 8px} div {margin: 8px 0} img {height:24px}'], + // #docregion template-1 + template: ` +
    + + + {{prefix}} {{hero?.name}} + + +
    ` + // #enddocregion template-1 +// #docregion input-output-2 +}) +// #enddocregion input-output-2 +export class HeroDetailComponent { + hero: Hero = new Hero(-1, '', 'Zzzzzzzz'); // default sleeping hero + // heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png'; + // Public Domain terms of use: http://www.wpclipart.com/terms.html + heroImageUrl = 'images/hero.png'; + lineThrough = ''; + @Input() prefix = ''; + + // #docregion deleteRequest + // This component make a request but it can't actually delete a hero. + deleteRequest = new EventEmitter(); + + delete() { + this.deleteRequest.emit(this.hero); + // #enddocregion deleteRequest + this.lineThrough = this.lineThrough ? '' : 'line-through'; + // #docregion deleteRequest + } + // #enddocregion deleteRequest +} + +@Component({ + selector: 'big-hero-detail', + template: ` +
    + +
    {{hero?.name}}
    +
    Name: {{hero?.name}}
    +
    Emotion: {{hero?.emotion}}
    +
    Birthdate: {{hero?.birthdate | date:'longDate'}}
    + +
    Rate/hr: {{hero?.rate | currency:'EUR'}}
    +
    + +
    + `, + styles: [` + .detail { border: 1px solid black; padding: 4px; max-width: 450px; } + img { float: left; margin-right: 8px; height: 100px; } + `] +}) +export class BigHeroDetailComponent extends HeroDetailComponent { + + // #docregion input-output-1 + @Input() hero: Hero; + @Output() deleteRequest = new EventEmitter(); + // #enddocregion input-output-1 + + delete() { + this.deleteRequest.emit(this.hero); + } +} diff --git a/public/docs/_examples/template-syntax/ts/src/app/hero-form.component.html b/public/docs/_examples/template-syntax/ts/src/app/hero-form.component.html new file mode 100644 index 0000000000..2182060439 --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/hero-form.component.html @@ -0,0 +1,15 @@ +
    + +
    +
    + +
    + +
    +
    + {{submitMessage}} +
    + +
    diff --git a/public/docs/_examples/template-syntax/ts/src/app/hero-form.component.ts b/public/docs/_examples/template-syntax/ts/src/app/hero-form.component.ts new file mode 100644 index 0000000000..7bdc4a0bba --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/hero-form.component.ts @@ -0,0 +1,30 @@ +import { Component, Input, ViewChild } from '@angular/core'; +import { NgForm } from '@angular/forms'; + +import { Hero } from './hero'; + +@Component({ + selector: 'hero-form', + templateUrl: './hero-form.component.html', + styles: [` + button { margin: 6px 0; } + #heroForm { border: 1px solid black; margin: 20px 0; padding: 8px; max-width: 350px; } + `] +}) +export class HeroFormComponent { + @Input() hero: Hero; + @ViewChild('heroForm') form: NgForm; + + private _submitMessage = ''; + + get submitMessage() { + if (!this.form.valid) { + this._submitMessage = ''; + } + return this._submitMessage; + } + + onSubmit(form: NgForm) { + this._submitMessage = 'Submitted. form value is ' + JSON.stringify(form.value); + } +} diff --git a/public/docs/_examples/template-syntax/ts/src/app/hero-switch.components.ts b/public/docs/_examples/template-syntax/ts/src/app/hero-switch.components.ts new file mode 100644 index 0000000000..a21892e248 --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/hero-switch.components.ts @@ -0,0 +1,42 @@ +import { Component, Input } from '@angular/core'; +import { Hero } from './hero'; + +@Component({ + selector: 'happy-hero', + template: `Wow. You like {{hero.name}}. What a happy hero ... just like you.` +}) +export class HappyHeroComponent { + @Input() hero: Hero; +} + +@Component({ + selector: 'sad-hero', + template: `You like {{hero.name}}? Such a sad hero. Are you sad too?` +}) +export class SadHeroComponent { + @Input() hero: Hero; +} + +@Component({ + selector: 'confused-hero', + template: `Are you as confused as {{hero.name}}?` +}) +export class ConfusedHeroComponent { + @Input() hero: Hero; +} + +@Component({ + selector: 'unknown-hero', + template: `{{message}}` +}) +export class UnknownHeroComponent { + @Input() hero: Hero; + get message() { + return this.hero && this.hero.name ? + `${this.hero.name} is strange and mysterious.` : + 'Are you feeling indecisive?'; + } +} + +export const heroSwitchComponents = + [ HappyHeroComponent, SadHeroComponent, ConfusedHeroComponent, UnknownHeroComponent ]; diff --git a/public/docs/_examples/template-syntax/ts/src/app/hero.ts b/public/docs/_examples/template-syntax/ts/src/app/hero.ts new file mode 100644 index 0000000000..f8cc3b16a6 --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/hero.ts @@ -0,0 +1,34 @@ +export class Hero { + static nextId = 0; + + static heroes: Hero[] = [ + new Hero( + null, + 'Hercules', + 'happy', + new Date(1970, 1, 25), + 'http://www.imdb.com/title/tt0065832/', + 325 + ), + new Hero(1, 'Mr. Nice', 'happy'), + new Hero(2, 'Narco', 'sad' ), + new Hero(3, 'Windstorm', 'confused' ), + new Hero(4, 'Magneta') + ]; + + + constructor( + public id?: number, + public name?: string, + public emotion?: string, + public birthdate?: Date, + public url?: string, + public rate = 100, + ) { + this.id = id ? id : Hero.nextId++; + } + + clone(): Hero { + return Object.assign(new Hero(), this); + } +} diff --git a/public/docs/_examples/template-syntax/ts/src/app/sizer.component.ts b/public/docs/_examples/template-syntax/ts/src/app/sizer.component.ts new file mode 100644 index 0000000000..b6065c8cd1 --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/app/sizer.component.ts @@ -0,0 +1,24 @@ +// #docregion +import { Component, EventEmitter, Input, Output } from '@angular/core'; + +@Component({ + selector: 'my-sizer', + template: ` +
    + + + +
    ` +}) +export class SizerComponent { + @Input() size: number | string; + @Output() sizeChange = new EventEmitter(); + + dec() { this.resize(-1); } + inc() { this.resize(+1); } + + resize(delta: number) { + this.size = Math.min(40, Math.max(8, +this.size + delta)); + this.sizeChange.emit(this.size); + } +} diff --git a/public/docs/_examples/template-syntax/ts/src/images/hero.png b/public/docs/_examples/template-syntax/ts/src/images/hero.png new file mode 100644 index 0000000000..2a128ac367 Binary files /dev/null and b/public/docs/_examples/template-syntax/ts/src/images/hero.png differ diff --git a/public/docs/_examples/template-syntax/ts/src/images/ng-logo.png b/public/docs/_examples/template-syntax/ts/src/images/ng-logo.png new file mode 100644 index 0000000000..1e488b1a49 Binary files /dev/null and b/public/docs/_examples/template-syntax/ts/src/images/ng-logo.png differ diff --git a/public/docs/_examples/template-syntax/ts/src/images/villain.png b/public/docs/_examples/template-syntax/ts/src/images/villain.png new file mode 100644 index 0000000000..26697d1a42 Binary files /dev/null and b/public/docs/_examples/template-syntax/ts/src/images/villain.png differ diff --git a/public/docs/_examples/template-syntax/ts/src/index.html b/public/docs/_examples/template-syntax/ts/src/index.html new file mode 100644 index 0000000000..3e711397cb --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/index.html @@ -0,0 +1,26 @@ + + + + Template Syntax + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/template-syntax/ts/src/main.ts b/public/docs/_examples/template-syntax/ts/src/main.ts new file mode 100644 index 0000000000..311c44b76d --- /dev/null +++ b/public/docs/_examples/template-syntax/ts/src/main.ts @@ -0,0 +1,5 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/template-syntax/ts/template-syntax.css b/public/docs/_examples/template-syntax/ts/template-syntax.css deleted file mode 100644 index c8c0925830..0000000000 --- a/public/docs/_examples/template-syntax/ts/template-syntax.css +++ /dev/null @@ -1,12 +0,0 @@ -fieldset {border-style:none} -img {height: 100px;} -.box {border: 1px solid black; padding:3px} -.child-div {margin-left: 1em; font-weight: normal} -.hidden {display: none} -.parent-div {margin-top: 1em; font-weight: bold} -.special {font-weight:bold; font-size: x-large} -.bad {color: red;} -.curly {font-family: "Brush Script MT"} -.toe {margin-left: 1em; font-style: italic;} -little-hero {color:blue; font-size: smaller; background-color: Turquoise } -.to-toc {margin-top: 10px; display: block} \ No newline at end of file diff --git a/public/docs/_examples/testing/ts/.gitignore b/public/docs/_examples/testing/ts/.gitignore new file mode 100644 index 0000000000..5374943421 --- /dev/null +++ b/public/docs/_examples/testing/ts/.gitignore @@ -0,0 +1 @@ +!src/browser-test-shim.js diff --git a/public/docs/_examples/testing/ts/1st-specs.plnkr.json b/public/docs/_examples/testing/ts/1st-specs.plnkr.json new file mode 100644 index 0000000000..9fe15ddef1 --- /dev/null +++ b/public/docs/_examples/testing/ts/1st-specs.plnkr.json @@ -0,0 +1,14 @@ +{ + "description": "Testing - 1st.specs", + "basePath": "src/", + "files":[ + "browser-test-shim.js", + "styles.css", + + "app/1st.spec.ts", + "1st-specs.html" + ], + "main": "1st-specs.html", + "open": "app/1st.spec.ts", + "tags": ["testing"] +} diff --git a/public/docs/_examples/testing/ts/1st.spec.ts b/public/docs/_examples/testing/ts/1st.spec.ts deleted file mode 100644 index bcac7a1aa7..0000000000 --- a/public/docs/_examples/testing/ts/1st.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -// #docplaster -// #docregion it - it('true is true', () => expect(true).toEqual(true)); - // #enddocregion it - -// #docregion describe - describe('1st tests', () => { - - it('true is true', () => expect(true).toEqual(true)); - - // #enddocregion describe - // #docregion another-test - it('null is not the same thing as undefined', - () => expect(null).not.toEqual(undefined) - ); - // #enddocregion another-test - - // #docregion describe -}); -// #enddocregion describe diff --git a/public/docs/_examples/testing/ts/app-specs.plnkr.json b/public/docs/_examples/testing/ts/app-specs.plnkr.json new file mode 100644 index 0000000000..d97bf82c86 --- /dev/null +++ b/public/docs/_examples/testing/ts/app-specs.plnkr.json @@ -0,0 +1,24 @@ +{ + "description": "Testing - app.specs", + "basePath": "src/", + "files":[ + "browser-test-shim.js", + "systemjs.config.extras.js", + "styles.css", + + "app/**/*.css", + "app/**/*.html", + "app/**/*.ts", + "app/**/*.spec.ts", + + "testing/*.ts", + + "!main.ts", + "!app/bag/*.*", + "!app/1st.spec.ts", + + "app-specs.html" + ], + "main": "app-specs.html", + "tags": ["testing"] +} diff --git a/public/docs/_examples/testing/ts/app/app.component.css b/public/docs/_examples/testing/ts/app/app.component.css deleted file mode 100644 index 137e9be7be..0000000000 --- a/public/docs/_examples/testing/ts/app/app.component.css +++ /dev/null @@ -1,31 +0,0 @@ -/* #docplaster */ -/* #docregion css */ -h1 { - font-size: 1.2em; - color: #999; - margin-bottom: 0; -} -h2 { - font-size: 2em; - margin-top: 0; - padding-top: 0; -} -nav a { - padding: 5px 10px; - text-decoration: none; - margin-top: 10px; - display: inline-block; - background-color: #eee; - border-radius: 4px; -} -nav a:visited, a:link { - color: #607D8B; -} -nav a:hover { - color: #039be5; - background-color: #CFD8DC; -} -nav a.router-link-active { - color: #039be5; -} -/* #enddocregion css */ diff --git a/public/docs/_examples/testing/ts/app/app.component.spec.ts b/public/docs/_examples/testing/ts/app/app.component.spec.ts deleted file mode 100644 index ce17ae744a..0000000000 --- a/public/docs/_examples/testing/ts/app/app.component.spec.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* tslint:disable:no-unused-variable */ -import { AppComponent } from './app.component'; - -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; - -import { - beforeEach, beforeEachProviders, - describe, ddescribe, xdescribe, - expect, it, iit, xit, - async, inject -} from '@angular/core/testing'; - -import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing'; - -import { Hero, HeroService, MockHeroService } from './mock-hero.service'; - -import { Router, MockRouter, - RouterLink, MockRouterLink, - RouterOutlet, MockRouterOutlet} from './mock-router'; - -describe('AppComponent', () => { - let fixture: ComponentFixture; - let comp: AppComponent; - - beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - tcb - .overrideDirective(AppComponent, RouterLink, MockRouterLink) - .overrideDirective(AppComponent, RouterOutlet, MockRouterOutlet) - .overrideProviders(AppComponent, [ - { provide: HeroService, useClass: MockHeroService}, - { provide: Router, useClass: MockRouter}, - ]) - .createAsync(AppComponent) - .then(fix => { - fixture = fix; - comp = fixture.debugElement.componentInstance; - }); - }))); - - it('can instantiate it', () => { - expect(comp).not.toBeNull(); - }); - - it('can get title from template', () => { - fixture.detectChanges(); - let titleEl = fixture.debugElement.query(By.css('h1')).nativeElement; - expect(titleEl).toHaveText(comp.title); - }); - - it('can get RouterLinks from template', () => { - fixture.detectChanges(); - - let links = fixture.debugElement - .queryAll(By.directive(MockRouterLink)) - .map(de => de.injector.get(MockRouterLink) ); - - expect(links.length).toEqual(2, 'should have 2 links'); - expect(links[0].routeParams[0]).toEqual('Dashboard', '1st link should go to Dashboard'); - expect(links[1].routeParams[0]).toEqual('Heroes', '1st link should go to Heroes'); - - let result = links[1].onClick(); - expect(result).toEqual(false, 'click should prevent default browser behavior'); - }); - - it('can click Heroes link in template', () => { - fixture.detectChanges(); - - // Heroes RouterLink DebugElement - let heroesDe = fixture.debugElement - .queryAll(By.directive(MockRouterLink))[1]; - - expect(heroesDe).toBeDefined('should have a 2nd RouterLink'); - - let link = heroesDe.injector.get(MockRouterLink); - - expect(link.navigatedTo).toBeNull('link should not have navigate yet'); - - heroesDe.triggerEventHandler('click', null); - - fixture.detectChanges(); - expect(link.navigatedTo[0]).toEqual('Heroes'); - - }); -}); - diff --git a/public/docs/_examples/testing/ts/app/app.component.ts b/public/docs/_examples/testing/ts/app/app.component.ts deleted file mode 100644 index f2da2da067..0000000000 --- a/public/docs/_examples/testing/ts/app/app.component.ts +++ /dev/null @@ -1,53 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; - -// Can't test with ROUTER_DIRECTIVES yet -// import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated'; - -import { RouteConfig, RouterLink, - RouterOutlet, ROUTER_PROVIDERS } from '@angular/router-deprecated'; - -import { DashboardComponent } from './dashboard.component'; -import { HeroesComponent } from './heroes.component'; -import { HeroDetailComponent } from './hero-detail.component'; -import { HeroService } from './hero.service'; - -import { BAG_DIRECTIVES, BAG_PROVIDERS } from './bag'; - -@Component({ - selector: 'my-app', - template: ` -

    {{title}}

    - - -
    -

    Bag-a-specs

    - -

    External Template Comp

    - -

    Comp With External Template Comp

    - - `, - /* - - */ - styleUrls: ['app/app.component.css'], - directives: [RouterLink, RouterOutlet, BAG_DIRECTIVES], - providers: [ - ROUTER_PROVIDERS, - HeroService, - BAG_PROVIDERS - ] -}) -@RouteConfig([ - { path: '/dashboard', name: 'Dashboard', component: DashboardComponent, useAsDefault: true }, - { path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent }, - { path: '/heroes', name: 'Heroes', component: HeroesComponent } -]) -export class AppComponent { - title = 'Tour of Heroes'; -} diff --git a/public/docs/_examples/testing/ts/app/bad-tests.spec.ts b/public/docs/_examples/testing/ts/app/bad-tests.spec.ts deleted file mode 100644 index 1251185160..0000000000 --- a/public/docs/_examples/testing/ts/app/bad-tests.spec.ts +++ /dev/null @@ -1,165 +0,0 @@ -// Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts -/* tslint:disable:no-unused-variable */ -/** - * Tests that show what goes wrong when the tests are incorrectly written or have a problem - */ -import { - BadTemplateUrlComp, ButtonComp, - ChildChildComp, ChildComp, ChildWithChildComp, - ExternalTemplateComp, - FancyService, MockFancyService, - InputComp, - MyIfComp, MyIfChildComp, MyIfParentComp, - MockChildComp, MockChildChildComp, - ParentComp, - TestProvidersComp, TestViewProvidersComp -} from './bag'; - -import { DebugElement } from '@angular/core'; -import { By } from '@angular/platform-browser'; - -import { - beforeEach, beforeEachProviders, - describe, ddescribe, xdescribe, - expect, it, iit, xit, - async, inject -} from '@angular/core/testing'; - -import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing'; - -import { ViewMetadata } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; - -//////// SPECS ///////////// - -xdescribe('async & inject testing errors', () => { - let originalJasmineIt: any; - let originalJasmineBeforeEach: any; - - let patchJasmineIt = () => { - return new Promise((resolve, reject) => { - originalJasmineIt = jasmine.getEnv().it; - jasmine.getEnv().it = (description: string, fn: Function): jasmine.Spec => { - let done = () => { resolve(); }; - (done).fail = (err: any) => { reject(err); }; - fn(done); - return null; - }; - }); - }; - - let restoreJasmineIt = () => { jasmine.getEnv().it = originalJasmineIt; }; - - let patchJasmineBeforeEach = () => { - return new Promise((resolve, reject) => { - originalJasmineBeforeEach = jasmine.getEnv().beforeEach; - jasmine.getEnv().beforeEach = (fn: any): void => { - let done = () => { resolve(); }; - (done).fail = (err: any) => { reject(err); }; - fn(done); - return null; - }; - }); - }; - - let restoreJasmineBeforeEach = - () => { jasmine.getEnv().beforeEach = originalJasmineBeforeEach; }; - - const shouldNotSucceed = - (done: DoneFn) => () => done.fail( 'Expected an error, but did not get one.'); - - const shouldFail = - (done: DoneFn, emsg: string) => (err: any) => { expect(err).toEqual(emsg); done(); }; - - it('should fail when an asynchronous error is thrown', (done: DoneFn) => { - let itPromise = patchJasmineIt(); - - it('throws an async error', - async(inject([], () => { setTimeout(() => { throw new Error('bar'); }, 0); }))); - - itPromise.then( - shouldNotSucceed(done), - err => { - expect(err).toEqual('bar'); - done(); - }); - restoreJasmineIt(); - }); - - it('should fail when a returned promise is rejected', (done: DoneFn) => { - let itPromise = patchJasmineIt(); - - it('should fail with an error from a promise', async(() => { - return Promise.reject('baz'); - })); - - itPromise.then( - shouldNotSucceed(done), - err => { - expect(err).toEqual('Uncaught (in promise): baz'); - done(); - }); - restoreJasmineIt(); - }); - - it('should fail when an error occurs inside inject', (done: DoneFn) => { - let itPromise = patchJasmineIt(); - - it('throws an error', inject([], () => { throw new Error('foo'); })); - - itPromise.then( - shouldNotSucceed(done), - shouldFail(done, 'foo') - ); - restoreJasmineIt(); - }); - - // TODO(juliemr): reenable this test when we are using a test zone and can capture this error. - it('should fail when an asynchronous error is thrown', (done: DoneFn) => { - let itPromise = patchJasmineIt(); - - it('throws an async error', - async(inject([], () => { setTimeout(() => { throw new Error('bar'); }, 0); }))); - - itPromise.then( - shouldNotSucceed(done), - shouldFail(done, 'bar') - ); - restoreJasmineIt(); - }); - - it('should fail when XHR loading of a template fails', (done: DoneFn) => { - let itPromise = patchJasmineIt(); - - it('should fail with an error from a promise', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - tcb.createAsync(BadTemplateUrlComp); - }))); - - itPromise.then( - shouldNotSucceed(done), - shouldFail(done, 'Uncaught (in promise): Failed to load non-existant.html') - ); - restoreJasmineIt(); - }, 10000); - - describe('using beforeEachProviders', () => { - beforeEachProviders(() => [{ provide: FancyService, useValue: new FancyService() }]); - - beforeEach( - inject([FancyService], (service: FancyService) => { expect(service.value).toEqual('real value'); })); - - describe('nested beforeEachProviders', () => { - - it('should fail when the injector has already been used', () => { - patchJasmineBeforeEach(); - expect(() => { - beforeEachProviders(() => [{ provide: FancyService, useValue: new FancyService() }]); - }) - .toThrowError('beforeEachProviders was called after the injector had been used ' + - 'in a beforeEach or it block. This invalidates the test injector'); - restoreJasmineBeforeEach(); - }); - }); - }); -}); diff --git a/public/docs/_examples/testing/ts/app/bag.spec.ts b/public/docs/_examples/testing/ts/app/bag.spec.ts deleted file mode 100644 index 91e689e8b4..0000000000 --- a/public/docs/_examples/testing/ts/app/bag.spec.ts +++ /dev/null @@ -1,501 +0,0 @@ -// Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts -/* tslint:disable:no-unused-variable */ -import { - BadTemplateUrl, ButtonComp, - ChildChildComp, ChildComp, ChildWithChildComp, - ExternalTemplateComp, - FancyService, MockFancyService, - InputComp, - MyIfComp, MyIfChildComp, MyIfParentComp, - MockChildComp, MockChildChildComp, - ParentComp, - TestProvidersComp, TestViewProvidersComp -} from './bag'; - -import { DebugElement } from '@angular/core'; -import { By } from '@angular/platform-browser'; - -import { - beforeEach, beforeEachProviders, - describe, ddescribe, xdescribe, - expect, it, iit, xit, - async, inject, - fakeAsync, tick, withProviders -} from '@angular/core/testing'; - -import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing'; - -import { ViewMetadata } from '@angular/core'; - -import { Observable } from 'rxjs/Rx'; - -//////// SPECS ///////////// - -/// Verify can use Angular testing's DOM abstraction to access DOM - -describe('angular2 jasmine matchers', () => { - describe('toHaveCssClass', () => { - it('should assert that the CSS class is present', () => { - let el = document.createElement('div'); - el.classList.add('bombasto'); - expect(el).toHaveCssClass('bombasto'); - }); - - it('should assert that the CSS class is not present', () => { - let el = document.createElement('div'); - el.classList.add('bombasto'); - expect(el).not.toHaveCssClass('fatias'); - }); - }); - - describe('toHaveCssStyle', () => { - it('should assert that the CSS style is present', () => { - let el = document.createElement('div'); - expect(el).not.toHaveCssStyle('width'); - - el.style.setProperty('width', '100px'); - expect(el).toHaveCssStyle('width'); - }); - - it('should assert that the styles are matched against the element', () => { - let el = document.createElement('div'); - expect(el).not.toHaveCssStyle({width: '100px', height: '555px'}); - - el.style.setProperty('width', '100px'); - expect(el).toHaveCssStyle({width: '100px'}); - expect(el).not.toHaveCssStyle({width: '100px', height: '555px'}); - - el.style.setProperty('height', '555px'); - expect(el).toHaveCssStyle({height: '555px'}); - expect(el).toHaveCssStyle({width: '100px', height: '555px'}); - }); - }); -}); - -describe('using the async helper', () => { - let actuallyDone = false; - - beforeEach(() => { actuallyDone = false; }); - - afterEach(() => { expect(actuallyDone).toEqual(true); }); - - it('should run normal test', () => { actuallyDone = true; }); - - it('should run normal async test', (done: DoneFn) => { - setTimeout(() => { - actuallyDone = true; - done(); - }, 0); - }); - - it('should run async test with task', - async(() => { setTimeout(() => { actuallyDone = true; }, 0); })); - - it('should run async test with successful promise', async(() => { - let p = new Promise(resolve => { setTimeout(resolve, 10); }); - p.then(() => { actuallyDone = true; }); - })); - - it('should run async test with failed promise', async(() => { - let p = new Promise((resolve, reject) => { setTimeout(reject, 10); }); - p.catch(() => { actuallyDone = true; }); - })); - - it('should run async test with successful Observable', async(() => { - let source = Observable.of(true).delay(10); - source.subscribe( - val => {}, - err => fail(err), - () => { actuallyDone = true; } // completed - ); - })); -}); - -describe('using the test injector with the inject helper', () => { - - describe('setting up Providers with FancyService', () => { - beforeEachProviders(() => [ - { provide: FancyService, useValue: new FancyService() } - ]); - - it('should use FancyService', - inject([FancyService], (service: FancyService) => { - expect(service.value).toEqual('real value'); - })); - - it('test should wait for FancyService.getAsyncValue', - async(inject([FancyService], (service: FancyService) => { - service.getAsyncValue().then( - value => { expect(value).toEqual('async value'); }); - }))); - - it('test should wait for FancyService.getTimeoutValue', - async(inject([FancyService], (service: FancyService) => { - service.getTimeoutValue().then( - value => { expect(value).toEqual('timeout value'); }); - }))); - - it('test should wait for FancyService.getObservableValue', - async(inject([FancyService], (service: FancyService) => { - service.getObservableValue().subscribe( - value => { expect(value).toEqual('observable value'); } - ); - }))); - - it('test should wait for FancyService.getObservableDelayValue', - async(inject([FancyService], (service: FancyService) => { - service.getObservableDelayValue().subscribe( - value => { expect(value).toEqual('observable delay value'); } - ); - }))); - - it('should allow the use of fakeAsync (Experimental)', - fakeAsync(inject([FancyService], (service: FancyService) => { - let value: any; - service.getAsyncValue().then((val: any) => value = val); - tick(); // Trigger JS engine cycle until all promises resolve. - expect(value).toEqual('async value'); - }))); - - describe('using inner beforeEach to inject-and-modify FancyService', () => { - beforeEach(inject([FancyService], (service: FancyService) => { - service.value = 'value modified in beforeEach'; - })); - - it('should use modified providers', - inject([FancyService], (service: FancyService) => { - expect(service.value).toEqual('value modified in beforeEach'); - })); - }); - - describe('using async within beforeEach', () => { - beforeEach(async(inject([FancyService], (service: FancyService) => { - service.getAsyncValue().then(value => { service.value = value; }); - }))); - - it('should use asynchronously modified value ... in synchronous test', - inject([FancyService], (service: FancyService) => { - expect(service.value).toEqual('async value'); })); - }); - }); - - describe('using `withProviders` for per-test provision', () => { - it('should inject test-local FancyService for this test', - // `withProviders`: set up providers at individual test level - withProviders(() => [{ provide: FancyService, useValue: {value: 'fake value' }}]) - - // now inject and test - .inject([FancyService], (service: FancyService) => { - expect(service.value).toEqual('fake value'); - })); - }); -}); - -describe('test component builder', function() { - it('should instantiate a component with valid DOM', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.createAsync(ChildComp).then(fixture => { - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveText('Original Child'); - }); - }))); - - it('should allow changing members of the component', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.createAsync(MyIfComp).then(fixture => { - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveText('MyIf()'); - - fixture.debugElement.componentInstance.showMore = true; - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveText('MyIf(More)'); - }); - }))); - - it('should support clicking a button', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.createAsync(ButtonComp).then(fixture => { - - let comp = fixture.componentInstance; - expect(comp.wasClicked).toEqual(false, 'wasClicked should be false at start'); - - let btn = fixture.debugElement.query(By.css('button')); - // let btn = fixture.debugElement.query(el => el.name === 'button'); // the hard way - - btn.triggerEventHandler('click', null); - // btn.nativeElement.click(); // this often works too ... but not all the time! - expect(comp.wasClicked).toEqual(true, 'wasClicked should be true after click'); - }); - }))); - - it('should support entering text in input box (ngModel)', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - let origName = 'John'; - let newName = 'Sally'; - - tcb.createAsync(InputComp).then(fixture => { - - let comp = fixture.componentInstance; - expect(comp.name).toEqual(origName, `At start name should be ${origName} `); - - let inputBox = fixture.debugElement.query(By.css('input')).nativeElement; - fixture.detectChanges(); - expect(inputBox.value).toEqual(origName, `At start input box value should be ${origName} `); - - inputBox.value = newName; - expect(comp.name).toEqual(origName, - `Name should still be ${origName} after value change, before detectChanges`); - - fixture.detectChanges(); - expect(inputBox.value).toEqual(newName, - `After value change and detectChanges, name should now be ${newName} `); - }); - }))); - - it('should override a template', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.overrideTemplate(MockChildComp, 'Mock') - .createAsync(MockChildComp) - .then(fixture => { - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveText('Mock'); - }); - }))); - - it('should override a view', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.overrideView( - ChildComp, - new ViewMetadata({template: 'Modified {{childBinding}}'}) - ) - .createAsync(ChildComp) - .then(fixture => { - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveText('Modified Child'); - - }); - }))); - - it('should override component directives', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.overrideDirective(ParentComp, ChildComp, MockChildComp) - .createAsync(ParentComp) - .then(fixture => { - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveText('Parent(Mock)'); - - }); - }))); - - - it('should override child component\'s directives', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.overrideDirective(ParentComp, ChildComp, ChildWithChildComp) - .overrideDirective(ChildWithChildComp, ChildChildComp, MockChildChildComp) - .createAsync(ParentComp) - .then(fixture => { - fixture.detectChanges(); - expect(fixture.nativeElement) - .toHaveText('Parent(Original Child(ChildChild Mock))'); - - }); - }))); - - it('should override a provider', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.overrideProviders( - TestProvidersComp, - [{ provide: FancyService, useClass: MockFancyService }] - ) - .createAsync(TestProvidersComp) - .then(fixture => { - fixture.detectChanges(); - expect(fixture.nativeElement) - .toHaveText('injected value: mocked out value'); - }); - }))); - - it('should override a viewProvider', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.overrideViewProviders( - TestViewProvidersComp, - [{ provide: FancyService, useClass: MockFancyService }] - ) - .createAsync(TestViewProvidersComp) - .then(fixture => { - fixture.detectChanges(); - expect(fixture.nativeElement) - .toHaveText('injected value: mocked out value'); - }); - }))); - - it('should allow an external templateUrl', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.createAsync(ExternalTemplateComp) - .then(fixture => { - fixture.detectChanges(); - expect(fixture.nativeElement) - .toHaveText('from external template\n'); - }); - })), 10000); // Long timeout because this test makes an actual XHR. - - describe('(lifecycle hooks w/ MyIfParentComp)', () => { - let fixture: ComponentFixture; - let parent: MyIfParentComp; - let child: MyIfChildComp; - - /** - * Get the MyIfChildComp from parent; fail w/ good message if cannot. - */ - function getChild() { - - let childDe: DebugElement; // DebugElement that should hold the MyIfChildComp - - // The Hard Way: requires detailed knowledge of the parent template - try { - childDe = fixture.debugElement.children[4].children[0]; - } catch (err) { /* we'll report the error */ } - - // DebugElement.queryAll: if we wanted all of many instances: - childDe = fixture.debugElement - .queryAll(function (de) { return de.componentInstance instanceof MyIfChildComp; })[0]; - - // WE'LL USE THIS APPROACH ! - // DebugElement.query: find first instance (if any) - childDe = fixture.debugElement - .query(function (de) { return de.componentInstance instanceof MyIfChildComp; }); - - if (childDe && childDe.componentInstance) { - child = childDe.componentInstance; - } else { - fail('Unable to find MyIfChildComp within MyIfParentComp'); - } - - return child; - } - - // Create MyIfParentComp TCB and component instance before each test (async beforeEach) - beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - tcb.createAsync(MyIfParentComp) - .then(fix => { - fixture = fix; - parent = fixture.debugElement.componentInstance; - }); - }))); - - it('should instantiate parent component', () => { - expect(parent).not.toBeNull('parent component should exist'); - }); - - it('parent component OnInit should NOT be called before first detectChanges()', () => { - expect(parent.ngOnInitCalled).toEqual(false); - }); - - it('parent component OnInit should be called after first detectChanges()', () => { - fixture.detectChanges(); - expect(parent.ngOnInitCalled).toEqual(true); - }); - - it('child component should exist after OnInit', () => { - fixture.detectChanges(); - getChild(); - expect(child instanceof MyIfChildComp).toEqual(true, 'should create child'); - }); - - it('should have called child component\'s OnInit ', () => { - fixture.detectChanges(); - getChild(); - expect(child.ngOnInitCalled).toEqual(true); - }); - - it('child component called OnChanges once', () => { - fixture.detectChanges(); - getChild(); - expect(child.ngOnChangesCounter).toEqual(1); - }); - - it('changed parent value flows to child', () => { - fixture.detectChanges(); - getChild(); - - parent.parentValue = 'foo'; - fixture.detectChanges(); - - expect(child.ngOnChangesCounter).toEqual(2, - 'expected 2 changes: initial value and changed value'); - expect(child.childValue).toEqual('foo', - 'childValue should eq changed parent value'); - }); - - it('changed child value flows to parent', async(() => { - fixture.detectChanges(); - getChild(); - - child.childValue = 'bar'; - - return new Promise(resolve => { - // Wait one JS engine turn! - setTimeout(() => resolve(), 0); - }).then(() => { - fixture.detectChanges(); - - expect(child.ngOnChangesCounter).toEqual(2, - 'expected 2 changes: initial value and changed value'); - expect(parent.parentValue).toEqual('bar', - 'parentValue should eq changed parent value'); - }); - - })); - - it('clicking "Close Child" triggers child OnDestroy', () => { - fixture.detectChanges(); - getChild(); - - let btn = fixture.debugElement.query(By.css('button')); - btn.triggerEventHandler('click', null); - - fixture.detectChanges(); - expect(child.ngOnDestroyCalled).toEqual(true); - }); - - }); -}); - - -//////// Testing Framework Bugs? ///// -import { HeroService } from './hero.service'; -import { Component } from '@angular/core'; - -@Component({ - selector: 'another-comp', - template: `AnotherProvidersComp()`, - providers: [FancyService] // <======= BOOM! if we comment out - // Failed: 'undefined' is not an object (evaluating 'dm.providers.concat') -}) -export class AnotherProvidersComp { - constructor( - private _heroService: HeroService - ) { } -} - -describe('tcb.overrideProviders', () => { - it('Component must have at least one provider else crash', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.overrideProviders( - AnotherProvidersComp, - [{ provide: HeroService, useValue: {}} ] - ) - .createAsync(AnotherProvidersComp); - }))); -}); diff --git a/public/docs/_examples/testing/ts/app/bag.ts b/public/docs/_examples/testing/ts/app/bag.ts deleted file mode 100644 index 94be448e7e..0000000000 --- a/public/docs/_examples/testing/ts/app/bag.ts +++ /dev/null @@ -1,255 +0,0 @@ -// Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts -/* tslint:disable:forin */ -import { Component, EventEmitter, Injectable, Input, Output, Optional, - OnInit, OnChanges, OnDestroy, SimpleChange } from '@angular/core'; - -import { Observable } from 'rxjs/Rx'; - -////////// The App: Services and Components for the tests. ////////////// - -////////// Services /////////////// - -@Injectable() -export class FancyService { - value: string = 'real value'; - - getValue() { return this.value; } - - getAsyncValue() { return Promise.resolve('async value'); } - - getObservableValue() { return Observable.of('observable value'); } - - getTimeoutValue() { - return new Promise((resolve, reject) => { setTimeout(() => {resolve('timeout value'); }, 10); }); - } - - getObservableDelayValue() { return Observable.of('observable delay value').delay(10); } -} - -@Injectable() -export class MockFancyService extends FancyService { - value: string = 'mocked out value'; -} - -//////////// Components ///////////// - -@Component({ - selector: 'button-comp', - template: `` -}) -export class ButtonComp { - wasClicked = false; - clicked() { this.wasClicked = true; } -} - -@Component({ - selector: 'input-comp', - template: `` -}) -export class InputComp { - name = 'John'; -} - -@Component({ - selector: 'child-comp', - template: `Original {{childBinding}}` -}) -export class ChildComp { - childBinding = 'Child'; -} - - -@Component({ - selector: 'child-comp', - template: `Mock` -}) -export class MockChildComp { } - - -@Component({ - selector: 'parent-comp', - template: `Parent()`, - directives: [ChildComp] -}) -export class ParentComp { } - - -@Component({ - selector: 'my-if-comp', - template: `MyIf(More)` -}) -export class MyIfComp { - showMore = false; -} - -@Component({ - selector: 'child-child-comp', - template: 'ChildChild' -}) -export class ChildChildComp { } - - -@Component({ - selector: 'child-comp', - template: `Original {{childBinding}}()`, - directives: [ChildChildComp] -}) -export class ChildWithChildComp { - childBinding = 'Child'; -} - - -@Component({ - selector: 'child-child-comp', - template: `ChildChild Mock` -}) -export class MockChildChildComp { } - - -@Component({ - selector: 'my-service-comp', - template: `injected value: {{fancyService.value}}`, - providers: [FancyService] -}) -export class TestProvidersComp { - constructor(private fancyService: FancyService) {} -} - - -@Component({ - selector: 'my-service-comp', - template: `injected value: {{fancyService.value}}`, - viewProviders: [FancyService] -}) -export class TestViewProvidersComp { - constructor(private fancyService: FancyService) {} -} - -@Component({ - moduleId: module.id, - selector: 'external-template-comp', - templateUrl: 'bag-external-template.html' -}) -export class ExternalTemplateComp { - serviceValue: string; - - constructor(@Optional() private service: FancyService) { } - - ngOnInit() { - if (this.service) { this.serviceValue = this.service.getValue(); } - } -} - -@Component({ - selector: 'comp-w-ext-comp', - template: ` -

    comp-w-ext-comp

    - - `, - directives: [ExternalTemplateComp] -}) -export class CompWithCompWithExternalTemplate { } - -@Component({ - selector: 'bad-template-comp', - templateUrl: 'non-existant.html' -}) -export class BadTemplateUrlComp { } - - -///////// MyIfChildComp //////// -@Component({ - selector: 'my-if-child-comp', - - template: ` -

    MyIfChildComp

    -
    - -
    -

    Change log:

    -
    {{i + 1}} - {{log}}
    ` -}) -export class MyIfChildComp implements OnInit, OnChanges, OnDestroy { - @Input() value = ''; - @Output() valueChange = new EventEmitter(); - - get childValue() { return this.value; } - set childValue(v: string) { - if (this.value === v) { return; } - this.value = v; - this.valueChange.emit(v); - } - - changeLog: string[] = []; - - ngOnInitCalled = false; - ngOnChangesCounter = 0; - ngOnDestroyCalled = false; - - ngOnInit() { - this.ngOnInitCalled = true; - this.changeLog.push('ngOnInit called'); - } - - ngOnDestroy() { - this.ngOnDestroyCalled = true; - this.changeLog.push('ngOnDestroy called'); - } - - ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { - for (let propName in changes) { - this.ngOnChangesCounter += 1; - let prop = changes[propName]; - let cur = JSON.stringify(prop.currentValue); - let prev = JSON.stringify(prop.previousValue); - this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`); - } - } -} - -///////// MyIfParentComp //////// - -@Component({ - selector: 'my-if-parent-comp', - template: ` -

    MyIfParentComp

    - -
    -
    - -
    - `, - directives: [MyIfChildComp] -}) -export class MyIfParentComp implements OnInit { - ngOnInitCalled = false; - parentValue = 'Hello, World'; - showChild = false; - toggleLabel = 'Unknown'; - - ngOnInit() { - this.ngOnInitCalled = true; - this.clicked(); - } - - clicked() { - this.showChild = !this.showChild; - this.toggleLabel = this.showChild ? 'Close' : 'Show'; - } -} - -export const BAG_PROVIDERS = [FancyService]; - -export const BAG_DIRECTIVES = [ - ButtonComp, - ChildChildComp, ChildComp, ChildWithChildComp, - ExternalTemplateComp, CompWithCompWithExternalTemplate, - InputComp, - MyIfComp, MyIfChildComp, MyIfParentComp, - MockChildComp, MockChildChildComp, - ParentComp, - TestProvidersComp, TestViewProvidersComp -]; diff --git a/public/docs/_examples/testing/ts/app/dashboard.component.css b/public/docs/_examples/testing/ts/app/dashboard.component.css deleted file mode 100644 index ce6e963a5f..0000000000 --- a/public/docs/_examples/testing/ts/app/dashboard.component.css +++ /dev/null @@ -1,63 +0,0 @@ -/* #docplaster */ -/* #docregion */ -[class*='col-'] { - float: left; -} -*, *:after, *:before { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -h3 { - text-align: center; margin-bottom: 0; -} -[class*='col-'] { - padding-right: 20px; - padding-bottom: 20px; -} -[class*='col-']:last-of-type { - padding-right: 0; -} -.grid { - margin: 0; -} -.col-1-4 { - width: 25%; -} -.module { - padding: 20px; - text-align: center; - color: #eee; - max-height: 120px; - min-width: 120px; - background-color: #607D8B; - border-radius: 2px; -} -h4 { - position: relative; -} -.module:hover { - background-color: #EEE; - cursor: pointer; - color: #607d8b; -} -.grid-pad { - padding: 10px 0; -} -.grid-pad > [class*='col-']:last-of-type { - padding-right: 20px; -} -@media (max-width: 600px) { - .module { - font-size: 10px; - max-height: 75px; } -} -@media (max-width: 1024px) { - .grid { - margin: 0; - } - .module { - min-width: 60px; - } -} -/* #enddocregion */ diff --git a/public/docs/_examples/testing/ts/app/dashboard.component.html b/public/docs/_examples/testing/ts/app/dashboard.component.html deleted file mode 100644 index 028eab6eb3..0000000000 --- a/public/docs/_examples/testing/ts/app/dashboard.component.html +++ /dev/null @@ -1,11 +0,0 @@ - -

    Top Heroes

    -
    - -
    - -
    -

    {{hero.name}}

    -
    -
    -
    diff --git a/public/docs/_examples/testing/ts/app/dashboard.component.spec.ts b/public/docs/_examples/testing/ts/app/dashboard.component.spec.ts deleted file mode 100644 index 803ea00535..0000000000 --- a/public/docs/_examples/testing/ts/app/dashboard.component.spec.ts +++ /dev/null @@ -1,166 +0,0 @@ -/* tslint:disable:no-unused-variable */ -import { DashboardComponent } from './dashboard.component'; - -import { By } from '@angular/platform-browser'; - -import { - beforeEach, beforeEachProviders, - describe, ddescribe, xdescribe, - expect, it, iit, xit, - async, inject -} from '@angular/core/testing'; - -import { ComponentFixture, TestComponentBuilder } from '@angular/compiler/testing'; - -import { Hero, HeroService, MockHeroService } from './mock-hero.service'; -import { Router, MockRouter } from './mock-router'; - -describe('DashboardComponent', () => { - - //////// WITHOUT ANGULAR INVOLVED /////// - describe('w/o Angular', () => { - let comp: DashboardComponent; - let mockHeroService: MockHeroService; - let router: MockRouter; - - beforeEach(() => { - router = new MockRouter(); - mockHeroService = new MockHeroService(); - comp = new DashboardComponent(router, mockHeroService); - }); - - it('should NOT have heroes before calling OnInit', () => { - expect(comp.heroes.length).toEqual(0, - 'should not have heroes before OnInit'); - }); - - it('should NOT have heroes immediately after OnInit', () => { - comp.ngOnInit(); // ngOnInit -> getHeroes - expect(comp.heroes.length).toEqual(0, - 'should not have heroes until service promise resolves'); - }); - - it('should HAVE heroes after HeroService gets them', (done: DoneFn) => { - comp.ngOnInit(); // ngOnInit -> getHeroes - mockHeroService.lastPromise // the one from getHeroes - .then(() => { - // throw new Error('deliberate error'); // see it fail gracefully - expect(comp.heroes.length).toBeGreaterThan(0, - 'should have heroes after service promise resolves'); - }) - .then(done, done.fail); - }); - - it('should tell ROUTER to navigate by hero id', () => { - let hero: Hero = {id: 42, name: 'Abbracadabra' }; - let spy = spyOn(router, 'navigate').and.callThrough(); - - comp.gotoDetail(hero); - - let linkParams = spy.calls.mostRecent().args[0]; - expect(linkParams[0]).toEqual('HeroDetail', 'should nav to "HeroDetail"'); - expect(linkParams[1].id).toEqual(hero.id, 'should nav to fake hero\'s id'); - }); - - }); - - - ////// WITH ANGULAR TEST INFRASTRUCTURE /////// - describe('using TCB', () => { - let comp: DashboardComponent; - let mockHeroService: MockHeroService; - - beforeEachProviders(() => { - mockHeroService = new MockHeroService(); - return [ - { provide: Router, useClass: MockRouter}, - { provide: MockRouter, useExisting: Router}, - { provide: HeroService, useValue: mockHeroService } - ]; - }); - - it('can instantiate it', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - tcb.createAsync(DashboardComponent); - }))); - - it('should NOT have heroes before OnInit', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - tcb.createAsync(DashboardComponent).then(fixture => { - comp = fixture.debugElement.componentInstance; - - expect(comp.heroes.length).toEqual(0, - 'should not have heroes before OnInit'); - }); - }))); - - it('should NOT have heroes immediately after OnInit', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - tcb.createAsync(DashboardComponent).then(fixture => { - comp = fixture.debugElement.componentInstance; - fixture.detectChanges(); // runs initial lifecycle hooks - - expect(comp.heroes.length).toEqual(0, - 'should not have heroes until service promise resolves'); - }); - }))); - - it('should HAVE heroes after HeroService gets them', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.createAsync(DashboardComponent).then(fixture => { - comp = fixture.debugElement.componentInstance; - fixture.detectChanges(); // runs ngOnInit -> getHeroes - - mockHeroService.lastPromise // the one from getHeroes - .then(() => { - expect(comp.heroes.length).toBeGreaterThan(0, - 'should have heroes after service promise resolves'); - }); - - }); - }))); - - it('should DISPLAY heroes after HeroService gets them', - async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - - tcb.createAsync(DashboardComponent).then(fixture => { - comp = fixture.debugElement.componentInstance; - fixture.detectChanges(); // runs ngOnInit -> getHeroes - - mockHeroService.lastPromise // the one from getHeroes - .then(() => { - - // Find and examine the displayed heroes - fixture.detectChanges(); // update bindings - let heroNames = fixture.debugElement.queryAll(By.css('h4')); - - expect(heroNames.length).toEqual(4, 'should display 4 heroes'); - - // the 4th displayed hero should be the 5th mock hero - expect(heroNames[3].nativeElement) - .toHaveText(mockHeroService.mockHeroes[4].name); - }); - - }); - }))); - - it('should tell ROUTER to navigate by hero id', - async(inject([TestComponentBuilder, Router], - (tcb: TestComponentBuilder, router: MockRouter) => { - - let spy = spyOn(router, 'navigate').and.callThrough(); - - tcb.createAsync(DashboardComponent).then(fixture => { - let hero: Hero = {id: 42, name: 'Abbracadabra' }; - comp = fixture.debugElement.componentInstance; - comp.gotoDetail(hero); - - let linkParams = spy.calls.mostRecent().args[0]; - expect(linkParams[0]).toEqual('HeroDetail', 'should nav to "HeroDetail"'); - expect(linkParams[1].id).toEqual(hero.id, 'should nav to fake hero\'s id'); - - }); - }))); - }); -}); diff --git a/public/docs/_examples/testing/ts/app/dashboard.component.ts b/public/docs/_examples/testing/ts/app/dashboard.component.ts deleted file mode 100644 index 69a9c5cce6..0000000000 --- a/public/docs/_examples/testing/ts/app/dashboard.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -// #docplaster -// #docregion -import { Component, OnInit } from '@angular/core'; -// #docregion import-router -import { Router } from '@angular/router-deprecated'; -// #enddocregion import-router - -import { Hero } from './hero'; -import { HeroService } from './hero.service'; - -@Component({ - selector: 'my-dashboard', - // #docregion template-url - templateUrl: 'app/dashboard.component.html', - // #enddocregion template-url - // #docregion css - styleUrls: ['app/dashboard.component.css'] - // #enddocregion css -}) -// #docregion component -export class DashboardComponent implements OnInit { - - heroes: Hero[] = []; - -// #docregion ctor - constructor( - private _router: Router, - private _heroService: HeroService) { - } -// #enddocregion ctor - - ngOnInit() { - this._heroService.getHeroes() - .then(heroes => this.heroes = heroes.slice(1, 5)); - } - - // #docregion goto-detail - gotoDetail(hero: Hero) { - let link = ['HeroDetail', { id: hero.id }]; - this._router.navigate(link); - } - // #enddocregion goto-detail -} -// #enddocregion diff --git a/public/docs/_examples/testing/ts/app/expect-proper.ts b/public/docs/_examples/testing/ts/app/expect-proper.ts deleted file mode 100644 index 6712b879d1..0000000000 --- a/public/docs/_examples/testing/ts/app/expect-proper.ts +++ /dev/null @@ -1,9 +0,0 @@ -// See https://github.com/angular/angular/issues/9017 -import { expect as expectCore} from '@angular/core/testing'; -import { NgMatchers } from '@angular/platform-browser/testing'; - -export function expect(spy: Function): NgMatchers; -export function expect(actual: any): NgMatchers; -export function expect(actual: any): NgMatchers { - return expectCore(actual) as NgMatchers; -} diff --git a/public/docs/_examples/testing/ts/app/hero-detail.component.html b/public/docs/_examples/testing/ts/app/hero-detail.component.html deleted file mode 100644 index cf96fc2169..0000000000 --- a/public/docs/_examples/testing/ts/app/hero-detail.component.html +++ /dev/null @@ -1,14 +0,0 @@ - - -
    -

    {{hero.name}} details!

    -
    - {{hero.id}}
    -
    - - -
    - - - -
    \ No newline at end of file diff --git a/public/docs/_examples/testing/ts/app/hero-detail.component.ts b/public/docs/_examples/testing/ts/app/hero-detail.component.ts deleted file mode 100644 index 5cc03cff4b..0000000000 --- a/public/docs/_examples/testing/ts/app/hero-detail.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -// #docplaster -// #docregion -// #docregion v2 -// #docregion import-oninit -import { Component, OnInit } from '@angular/core'; -// #enddocregion import-oninit -// #docregion import-route-params -import { RouteParams } from '@angular/router-deprecated'; -// #enddocregion import-route-params - -import { Hero } from './hero'; -// #docregion import-hero-service -import { HeroService } from './hero.service'; -// #enddocregion import-hero-service - -// #docregion extract-template -@Component({ - selector: 'my-hero-detail', - // #docregion template-url - templateUrl: 'app/hero-detail.component.html', - // #enddocregion template-url -// #enddocregion v2 - styleUrls: ['app/hero-detail.component.css'], - inputs: ['hero'] -// #docregion v2 -}) -// #enddocregion extract-template -// #docregion implement -export class HeroDetailComponent implements OnInit { -// #enddocregion implement - hero: Hero; - -// #docregion ctor - constructor( - private _heroService: HeroService, - private _routeParams: RouteParams) { - } -// #enddocregion ctor - -// #docregion ng-oninit - ngOnInit() { - // #docregion get-id - let id = +this._routeParams.get('id'); - // #enddocregion get-id - this._heroService.getHero(id) - .then(hero => this.hero = hero); - } -// #enddocregion ng-oninit - -// #docregion go-back - goBack() { - window.history.back(); - } -// #enddocregion go-back -} -// #enddocregion v2 -// #enddocregion diff --git a/public/docs/_examples/testing/ts/app/hero.service.ts b/public/docs/_examples/testing/ts/app/hero.service.ts deleted file mode 100644 index fd6d5bb128..0000000000 --- a/public/docs/_examples/testing/ts/app/hero.service.ts +++ /dev/null @@ -1,28 +0,0 @@ -// #docplaster -// #docregion -import { Hero } from './hero'; -import { HEROES } from './mock-heroes'; -import { Injectable } from '@angular/core'; - -@Injectable() -export class HeroService { - getHeroes() { - return Promise.resolve(HEROES); - } - - // See the "Take it slow" appendix - getHeroesSlowly() { - return new Promise(resolve => - setTimeout(()=>resolve(HEROES), 2000) // 2 seconds - ); - } - - //#docregion get-hero - getHero(id: number) { - return Promise.resolve(HEROES).then( - heroes => heroes.filter(hero => hero.id === id)[0] - ); - } - //#enddocregion get-hero -} -// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/testing/ts/app/hero.spec.ts b/public/docs/_examples/testing/ts/app/hero.spec.ts deleted file mode 100644 index 78a73ad6b0..0000000000 --- a/public/docs/_examples/testing/ts/app/hero.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -// #docregion -// #docplaster -// #docregion base-hero-spec -import { Hero } from './hero'; - -describe('Hero', () => { - - it('has name', () => { - let hero: Hero = {id: 1, name: 'Super Cat'}; - expect(hero.name).toEqual('Super Cat'); - }); - - it('has id', () => { - let hero: Hero = {id: 1, name: 'Super Cat'}; - expect(hero.id).toEqual(1); - }); - // #enddocregion base-hero-spec - - - /* more tests we could run - - it('can clone itself', () => { - let hero = new Hero(1, 'Super Cat'); - let clone = hero.clone(); - expect(hero).toEqual(clone); - }); - - it('has expected generated id when id not given in the constructor', () => { - Hero.setNextId(100); // reset the `nextId` seed - let hero = new Hero(null, 'Cool Kitty'); - expect(hero.id).toEqual(100); - }); - - it('has expected generated id when id=0 in the constructor', () => { - Hero.setNextId(100); - let hero = new Hero(0, 'Cool Kitty'); - expect(hero.id).toEqual(100); - }) - - it('increments generated id for each new Hero w/o an id', () => { - Hero.setNextId(100); - let hero1 = new Hero(0, 'Cool Kitty'); - let hero2 = new Hero(null, 'Hip Cat'); - expect(hero2.id).toEqual(101); - }); - - */ - // #docregion base-hero-spec -}); -// #enddocregion base-hero-spec diff --git a/public/docs/_examples/testing/ts/app/hero.ts b/public/docs/_examples/testing/ts/app/hero.ts deleted file mode 100644 index 8f7cc205c8..0000000000 --- a/public/docs/_examples/testing/ts/app/hero.ts +++ /dev/null @@ -1,5 +0,0 @@ -// #docregion -export class Hero { - id: number; - name: string; -} diff --git a/public/docs/_examples/testing/ts/app/heroes.component.html b/public/docs/_examples/testing/ts/app/heroes.component.html deleted file mode 100644 index cce1853d30..0000000000 --- a/public/docs/_examples/testing/ts/app/heroes.component.html +++ /dev/null @@ -1,21 +0,0 @@ - - -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    - -
    -

    - - {{selectedHero.name | uppercase}} is my hero - -

    - -
    - - diff --git a/public/docs/_examples/testing/ts/app/heroes.component.ts b/public/docs/_examples/testing/ts/app/heroes.component.ts deleted file mode 100644 index 1e2651f256..0000000000 --- a/public/docs/_examples/testing/ts/app/heroes.component.ts +++ /dev/null @@ -1,50 +0,0 @@ -// #docplaster -// #docregion -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router-deprecated'; - -import { Hero } from './hero'; -import { HeroDetailComponent } from './hero-detail.component'; -import { HeroService } from './hero.service'; - -// #docregion metadata -// #docregion heroes-component-renaming -@Component({ - selector: 'my-heroes', -// #enddocregion heroes-component-renaming - templateUrl: 'app/heroes.component.html', - styleUrls: ['app/heroes.component.css'], - directives: [HeroDetailComponent] -// #docregion heroes-component-renaming -}) -// #enddocregion heroes-component-renaming -// #enddocregion metadata -// #docregion class -// #docregion heroes-component-renaming -export class HeroesComponent implements OnInit { -// #enddocregion heroes-component-renaming - heroes: Hero[]; - selectedHero: Hero; - - constructor( - private _router: Router, - private _heroService: HeroService) { } - - getHeroes() { - this._heroService.getHeroes().then(heroes => this.heroes = heroes); - } - - ngOnInit() { - this.getHeroes(); - } - - onSelect(hero: Hero) { this.selectedHero = hero; } - - gotoDetail() { - this._router.navigate(['HeroDetail', { id: this.selectedHero.id }]); - } -// #docregion heroes-component-renaming -} -// #enddocregion heroes-component-renaming -// #enddocregion class -// #enddocregion diff --git a/public/docs/_examples/testing/ts/app/http-hero.service.spec.ts b/public/docs/_examples/testing/ts/app/http-hero.service.spec.ts deleted file mode 100644 index 0c79f7f3aa..0000000000 --- a/public/docs/_examples/testing/ts/app/http-hero.service.spec.ts +++ /dev/null @@ -1,133 +0,0 @@ -/* tslint:disable:no-unused-variable */ -import { - beforeEach, beforeEachProviders, - describe, ddescribe, xdescribe, - expect, it, iit, xit, - async, inject, withProviders -} from '@angular/core/testing'; - -import { TestComponentBuilder } from '@angular/compiler/testing'; - -import { - MockBackend, - MockConnection } from '@angular/http/testing'; - -import { - Http, HTTP_PROVIDERS, - ConnectionBackend, XHRBackend, - Request, RequestMethod, BaseRequestOptions, RequestOptions, - Response, ResponseOptions, - URLSearchParams -} from '@angular/http'; - -// Add all operators to Observable -import 'rxjs/Rx'; -import { Observable } from 'rxjs/Observable'; - -import { Hero } from './hero'; -import { HeroService } from './http-hero.service'; - -type HeroData = {id: string, name: string} - -const makeHeroData = () => [ - { id: '1', name: 'Windstorm' }, - { id: '2', name: 'Bombasto' }, - { id: '3', name: 'Magneta' }, - { id: '4', name: 'Tornado' } -]; - -// HeroService expects response data like {data: {the-data}} -const makeResponseData = (data: {}) => {return { data }; }; - -//////// SPECS ///////////// -describe('Http-HeroService (mockBackend)', () => { - - beforeEachProviders(() => [ - HTTP_PROVIDERS, - { provide: XHRBackend, useClass: MockBackend } - ]); - - it('can instantiate service when inject service', - withProviders(() => [HeroService]) - .inject([HeroService], (service: HeroService) => { - expect(service instanceof HeroService).toBe(true); - })); - - - it('can instantiate service with "new"', inject([Http], (http: Http) => { - expect(http).not.toBeNull('http should be provided'); - let service = new HeroService(http); - expect(service instanceof HeroService).toBe(true, 'new service should be ok'); - })); - - - it('can provide the mockBackend as XHRBackend', - inject([XHRBackend], (backend: MockBackend) => { - expect(backend).not.toBeNull('backend should be provided'); - })); - - describe('when getHeroes', () => { - let backend: MockBackend; - let service: HeroService; - let fakeHeroes: HeroData[]; - let response: Response; - - - beforeEach(inject([Http, XHRBackend], (http: Http, be: MockBackend) => { - backend = be; - service = new HeroService(http); - fakeHeroes = makeHeroData(); - let options = new ResponseOptions({status: 200, body: {data: fakeHeroes}}); - response = new Response(options); - })); - - it('should have expected fake heroes (then)', async(inject([], () => { - backend.connections.subscribe((c: MockConnection) => c.mockRespond(response)); - - service.getHeroes().toPromise() - // .then(() => Promise.reject('deliberate')) - .then(heroes => { - expect(heroes.length).toEqual(fakeHeroes.length, - 'should have expected no. of heroes'); - }); - }))); - - it('should have expected fake heroes (Observable.do)', async(inject([], () => { - backend.connections.subscribe((c: MockConnection) => c.mockRespond(response)); - - service.getHeroes() - .do(heroes => { - expect(heroes.length).toEqual(fakeHeroes.length, - 'should have expected no. of heroes'); - }) - .toPromise(); - }))); - - - it('should be OK returning no heroes', async(inject([], () => { - let resp = new Response(new ResponseOptions({status: 200, body: {data: []}})); - backend.connections.subscribe((c: MockConnection) => c.mockRespond(resp)); - - service.getHeroes() - .do(heroes => { - expect(heroes.length).toEqual(0, 'should have no heroes'); - }) - .toPromise(); - }))); - - it('should treat 404 as an Observable error', async(inject([], () => { - let resp = new Response(new ResponseOptions({status: 404})); - backend.connections.subscribe((c: MockConnection) => c.mockRespond(resp)); - - service.getHeroes() - .do(heroes => { - fail('should not respond with heroes'); - }) - .catch(err => { - expect(err).toMatch(/Bad response status/, 'should catch bad response status code'); - return Observable.of(null); // failure is the expected test result - }) - .toPromise(); - }))); - }); -}); diff --git a/public/docs/_examples/testing/ts/app/http-hero.service.ts b/public/docs/_examples/testing/ts/app/http-hero.service.ts deleted file mode 100644 index 39b0991f7b..0000000000 --- a/public/docs/_examples/testing/ts/app/http-hero.service.ts +++ /dev/null @@ -1,44 +0,0 @@ -// #docplaster -// #docregion -import {Injectable} from '@angular/core'; -import {Http, Response} from '@angular/http'; -import {Headers, RequestOptions} from '@angular/http'; -import {Hero} from './hero'; -import {Observable} from 'rxjs/Observable'; - -@Injectable() -export class HeroService { - constructor (private http: Http) {} - private _heroesUrl = 'app/heroes'; // URL to web api - getHeroes (): Observable { - return this.http.get(this._heroesUrl) - .map(this.extractData) - // .do(data => console.log(data)) // eyeball results in the console - .catch(this.handleError); - } - - addHero (name: string): Observable { - let body = JSON.stringify({ name }); - let headers = new Headers({ 'Content-Type': 'application/json' }); - let options = new RequestOptions({ headers: headers }); - - return this.http.post(this._heroesUrl, body, options) - .map(this.extractData) - .catch(this.handleError); - } - - private extractData(res: Response) { - if (res.status < 200 || res.status >= 300) { - throw new Error('Bad response status: ' + res.status); - } - let body = res.json(); - return body.data || { }; - } - - private handleError (error: any) { - // In a real world app, we might send the error to remote logging infrastructure - let errMsg = error.message || 'Server error'; - console.error(errMsg); // log to console instead - return Observable.throw(errMsg); - } -} diff --git a/public/docs/_examples/testing/ts/app/main.ts b/public/docs/_examples/testing/ts/app/main.ts deleted file mode 100644 index 5f185788a3..0000000000 --- a/public/docs/_examples/testing/ts/app/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); - diff --git a/public/docs/_examples/testing/ts/app/mock-hero.service.ts b/public/docs/_examples/testing/ts/app/mock-hero.service.ts deleted file mode 100644 index b1538be366..0000000000 --- a/public/docs/_examples/testing/ts/app/mock-hero.service.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { HEROES } from './mock-heroes'; -import { Hero } from './hero'; -import { HeroService } from './hero.service'; - -export { Hero } from './hero'; -export { HeroService } from './hero.service'; - -export class MockHeroService implements HeroService { - - mockHeroes = HEROES.slice(); - lastPromise: Promise; // so we can spy on promise calls - - getHero(id: number) { - return this.lastPromise = Promise.resolve(this.mockHeroes[0]); - } - - getHeroes() { - return this.lastPromise = Promise.resolve(this.mockHeroes); - } - - getHeroesSlowly() { return this.getHeroes(); } -} diff --git a/public/docs/_examples/testing/ts/app/mock-heroes.ts b/public/docs/_examples/testing/ts/app/mock-heroes.ts deleted file mode 100644 index ddd36d7868..0000000000 --- a/public/docs/_examples/testing/ts/app/mock-heroes.ts +++ /dev/null @@ -1,16 +0,0 @@ -// #docregion -import { Hero } from './hero'; - -export var HEROES: Hero[] = [ - {id: 11, name: 'Mr. Nice'}, - {id: 12, name: 'Narco'}, - {id: 13, name: 'Bombasto'}, - {id: 14, name: 'Celeritas'}, - {id: 15, name: 'Magneta'}, - {id: 16, name: 'RubberMan'}, - {id: 17, name: 'Dynama'}, - {id: 18, name: 'Dr IQ'}, - {id: 19, name: 'Magma'}, - {id: 20, name: 'Tornado'} -]; -// #enddocregion diff --git a/public/docs/_examples/testing/ts/app/mock-router.ts b/public/docs/_examples/testing/ts/app/mock-router.ts deleted file mode 100644 index 547629f53d..0000000000 --- a/public/docs/_examples/testing/ts/app/mock-router.ts +++ /dev/null @@ -1,216 +0,0 @@ -export * from '@angular/router-deprecated'; - -import { Directive, DynamicComponentLoader, ViewContainerRef, - Injectable, Optional, Input } from '@angular/core'; - -import { ComponentInstruction, Instruction, - Router, RouterOutlet} from '@angular/router-deprecated'; - -let _resolveToTrue = Promise.resolve(true); - -const NOT_IMPLEMENTED = (what: string) => { - throw new Error (`"${what}" is not implemented`); -}; - - -@Directive({ - selector: '[routerLink]', - host: { - '(click)': 'onClick()', - '[attr.href]': 'visibleHref', - '[class.router-link-active]': 'isRouteActive' - } -}) -export class MockRouterLink { - - isRouteActive = false; - visibleHref: string; // the url displayed on the anchor element. - - @Input('routerLink') routeParams: any[]; - @Input() target: string; - navigatedTo: any[] = null; - - constructor(public router: Router) { } - - onClick() { - this.navigatedTo = null; - - // If no target, or if target is _self, prevent default browser behavior - if (!this.target || typeof this.target !== 'string' || this.target === '_self') { - this.navigatedTo = this.routeParams; - return false; - } - return true; - } -} - -@Directive({selector: 'router-outlet'}) -export class MockRouterOutlet extends RouterOutlet { - name: string = null; - - constructor( - _viewContainerRef: ViewContainerRef, - @Optional() _loader: DynamicComponentLoader, - _parentRouter: Router, - nameAttr: string) { - super(_viewContainerRef, _loader, _parentRouter, nameAttr); - if (nameAttr) { - this.name = nameAttr; - } - } - - /** - * Called by the Router to instantiate a new component during the commit phase of a navigation. - * This method in turn is responsible for calling the `routerOnActivate` hook of its child. - */ - activate(nextInstruction: ComponentInstruction): Promise { NOT_IMPLEMENTED('activate'); return _resolveToTrue; } - - /** - * Called by the {@link Router} during the commit phase of a navigation when an outlet - * reuses a component between different routes. - * This method in turn is responsible for calling the `routerOnReuse` hook of its child. - */ - reuse(nextInstruction: ComponentInstruction): Promise { NOT_IMPLEMENTED('reuse'); return _resolveToTrue; } - - /** - * Called by the {@link Router} when an outlet disposes of a component's contents. - * This method in turn is responsible for calling the `routerOnDeactivate` hook of its child. - */ - deactivate(nextInstruction: ComponentInstruction): Promise { NOT_IMPLEMENTED('deactivate'); return _resolveToTrue; } - - /** - * Called by the {@link Router} during recognition phase of a navigation. - * - * If this resolves to `false`, the given navigation is cancelled. - * - * This method delegates to the child component's `routerCanDeactivate` hook if it exists, - * and otherwise resolves to true. - */ - routerCanDeactivate(nextInstruction: ComponentInstruction): Promise { - NOT_IMPLEMENTED('routerCanDeactivate'); return _resolveToTrue; - } - - /** - * Called by the {@link Router} during recognition phase of a navigation. - * - * If the new child component has a different Type than the existing child component, - * this will resolve to `false`. You can't reuse an old component when the new component - * is of a different Type. - * - * Otherwise, this method delegates to the child component's `routerCanReuse` hook if it exists, - * or resolves to true if the hook is not present. - */ - routerCanReuse(nextInstruction: ComponentInstruction): Promise { NOT_IMPLEMENTED('routerCanReuse'); return _resolveToTrue; } - -} - -@Injectable() -export class MockRouter extends Router { - - mockIsRouteActive = false; - mockRecognizedInstruction: Instruction; - outlet: RouterOutlet = null; - - constructor() { - super(null, null, null, null); - } - - auxRouter(hostComponent: any): Router { return new MockChildRouter(this, hostComponent); } - childRouter(hostComponent: any): Router { return new MockChildRouter(this, hostComponent); } - - commit(instruction: Instruction, _skipLocationChange = false): Promise { - NOT_IMPLEMENTED('commit'); return _resolveToTrue; - } - - deactivate(instruction: Instruction, _skipLocationChange = false): Promise { - NOT_IMPLEMENTED('deactivate'); return _resolveToTrue; - } - - /** - * Generate an `Instruction` based on the provided Route Link DSL. - */ - generate(linkParams: any[]): Instruction { - NOT_IMPLEMENTED('generate'); return null; - } - - isRouteActive(instruction: Instruction): boolean { return this.mockIsRouteActive; } - - /** - * Navigate based on the provided Route Link DSL. It's preferred to navigate with this method - * over `navigateByUrl`. - * - * ### Usage - * - * This method takes an array representing the Route Link DSL: - * ``` - * ['./MyCmp', {param: 3}] - * ``` - * See the {@link RouterLink} directive for more. - */ - navigate(linkParams: any[]): Promise { - return Promise.resolve(linkParams); - } - - /** - * Navigate to a URL. Returns a promise that resolves when navigation is complete. - * It's preferred to navigate with `navigate` instead of this method, since URLs are more brittle. - * - * If the given URL begins with a `/`, router will navigate absolutely. - * If the given URL does not begin with `/`, the router will navigate relative to this component. - */ - navigateByUrl(url: string, _skipLocationChange = false): Promise { - return Promise.resolve(url); - } - - - /** - * Navigate via the provided instruction. Returns a promise that resolves when navigation is - * complete. - */ - navigateByInstruction(instruction: Instruction, _skipLocationChange = false): Promise { - return Promise.resolve(instruction); - } - - /** - * Subscribe to URL updates from the router - */ - subscribe(onNext: (v: any) => void, onError?: (v: any) => void) { - return {onNext, onError}; - } - - /** - * Given a URL, returns an instruction representing the component graph - */ - recognize(url: string): Promise { - return Promise.resolve(this.mockRecognizedInstruction); - } - - registerPrimaryOutlet(outlet: RouterOutlet): Promise { - this.outlet = outlet; - return super.registerPrimaryOutlet(outlet); - } - - unregisterPrimaryOutlet(outlet: RouterOutlet) { - super.unregisterPrimaryOutlet(outlet); - this.outlet = null; - } -} - -class MockChildRouter extends MockRouter { - constructor(parent: MockRouter, hostComponent: any) { - super(); - this.parent = parent; - } - - - navigateByUrl(url: string, _skipLocationChange = false): Promise { - // Delegate navigation to the root router - return this.parent.navigateByUrl(url, _skipLocationChange); - } - - navigateByInstruction(instruction: Instruction, _skipLocationChange = false): - Promise { - // Delegate navigation to the root router - return this.parent.navigateByInstruction(instruction, _skipLocationChange); - } -} diff --git a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.1.ts b/public/docs/_examples/testing/ts/app/my-uppercase.pipe.1.ts deleted file mode 100644 index 94b5bc45ce..0000000000 --- a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.1.ts +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion -import { Pipe, PipeTransform } from '@angular/core'; - -@Pipe({ name: 'my-uppercase' }) -export class MyUppercasePipe implements PipeTransform { - transform(value: string) { - return value; - } -} diff --git a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.spec.ts b/public/docs/_examples/testing/ts/app/my-uppercase.pipe.spec.ts deleted file mode 100644 index 731b2ed965..0000000000 --- a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -// #docregion -// #docplaster -// #docregion base-pipe-spec -import { MyUppercasePipe } from './my-uppercase.pipe'; - -describe('MyUppercasePipe', () => { - let pipe: MyUppercasePipe; - - beforeEach(() => { - pipe = new MyUppercasePipe(); - }); - - // #docregion expectations - it('transforms "abc" to "ABC"', () => { - expect(pipe.transform('abc')).toEqual('ABC'); - }); - - it('transforms "abc def" to "ABC DEF"', () => { - expect(pipe.transform('abc def')).toEqual('ABC DEF'); - }); - - it('leaves "ABC DEF" unchanged', () => { - expect(pipe.transform('ABC DEF')).toEqual('ABC DEF'); - }); - // #enddocregion expectations - // #enddocregion base-pipe-spec - - /* more tests we could run - - it('transforms "abc-def" to "Abc-def"', () => { - expect(pipe.transform('abc-def')).toEqual('Abc-def'); - }); - - it('transforms " abc def" to " Abc Def" (preserves spaces) ', () => { - expect(pipe.transform(' abc def')).toEqual(' Abc Def'); - }); - - */ - // #docregion base-pipe-spec -}); -// #enddocregion base-pipe-spec diff --git a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.ts b/public/docs/_examples/testing/ts/app/my-uppercase.pipe.ts deleted file mode 100644 index 6584f92ef6..0000000000 --- a/public/docs/_examples/testing/ts/app/my-uppercase.pipe.ts +++ /dev/null @@ -1,13 +0,0 @@ -// #docregion -// #docregion depends-on-angular -import { Pipe, PipeTransform } from '@angular/core'; -// #enddocregion depends-on-angular - -@Pipe({ name: 'my-uppercase' }) -export class MyUppercasePipe implements PipeTransform { - // #docregion uppercase - transform(value: string) { - return value.toUpperCase(); - } - // #enddocregion uppercase -} diff --git a/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.spec.ts.not-yet deleted file mode 100644 index 80c210be5d..0000000000 --- a/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.spec.ts.not-yet +++ /dev/null @@ -1,218 +0,0 @@ -///// Boiler Plate //// -import {bind, By, Component, Directive, EventEmitter, FORM_DIRECTIVES} from 'angular2/angular2'; - -// Angular 2 Test Bed -import { -beforeEachProviders, inject, injectAsync, RootTestComponent as RTC, -beforeEach, ddescribe, xdescribe, describe, expect, iit, it, xit // Jasmine wrappers -} from 'angular2/testing'; - -import {dispatchEvent, DoneFn, injectTcb, tick} from '../test-helpers/test-helpers'; - -///// Testing this component //// -import {HeroDetailComponent} from './hero-detail.component'; -import {Hero} from './hero'; - -describe('HeroDetailComponent', () => { - - /////////// Component Tests without DOM interaction ///////////// - describe('(No DOM)', () => { - it('can be created', () => { - let hdc = new HeroDetailComponent(); - expect(hdc instanceof HeroDetailComponent).toEqual(true); // proof of life - }); - - it('onDelete method should raise delete event', (done: DoneFn) => { - let hdc = new HeroDetailComponent(); - - // Listen for the HeroComponent.delete EventEmitter's event - hdc.delete.toRx().subscribe(() => { - console.log('HeroComponent.delete event raised'); - done(); // it must have worked - }, (error: any) => { fail(error); done() }); - - hdc.onDelete(); - }); - - // Disable until toPromise() works again - xit('onDelete method should raise delete event (w/ promise)', (done: DoneFn) => { - - let hdc = new HeroDetailComponent(); - - // Listen for the HeroComponent.delete EventEmitter's event - let p = hdc.delete.toRx() - .toPromise() - .then(() => { - console.log('HeroComponent.delete event raised in promise'); - }) - .then(done, done.fail); - - hdc.delete.toRx() - .subscribe(() => { - console.log('HeroComponent.delete event raised in subscription') - }); - - hdc.onDelete(); - - // toPromise() does not fulfill until emitter is completed by `return()` - hdc.delete.return(); - }); - - it('onUpdate method should modify hero', () => { - let hdc = new HeroDetailComponent(); - hdc.hero = new Hero(42, 'Cat Woman'); - let origNameLength = hdc.hero.name.length; - - hdc.onUpdate(); - expect(hdc.hero.name.length).toBeGreaterThan(origNameLength); - }); - }); - - - /////////// Component tests that check the DOM ///////////// - describe('(DOM)', () => { - // Disable until toPromise() works again - xit('Delete button should raise delete event', injectTcb(tcb => { - - // We only care about the button - let template = ''; - - return tcb - .overrideTemplate(HeroDetailComponent, template) - .createAsync(HeroDetailComponent) - .then((rootTC: RTC) => { - let hdc: HeroDetailComponent = rootTC.debugElement.componentInstance; - - // // USE PROMISE WRAPPING AN OBSERVABLE UNTIL can get `toPromise` working again - // let p = new Promise((resolve) => { - // // Listen for the HeroComponent.delete EventEmitter's event with observable - // hdc.delete.toRx().subscribe((hero: Hero) => { - // console.log('Observable heard HeroComponent.delete event raised'); - // resolve(hero); - // }); - // }) - - //Listen for the HeroComponent.delete EventEmitter's event with promise - let p = > hdc.delete.toRx().toPromise() - .then((hero:Hero) => { - console.log('Promise heard HeroComponent.delete event raised'); - }); - - // trigger the 'click' event on the HeroDetailComponent delete button - let el = rootTC.debugElement.query(By.css('button')); - el.triggerEventHandler('click', null); - - // toPromise() does not fulfill until emitter is completed by `return()` - hdc.delete.return(); - - return p; - }); - - })); - - it('Update button should modify hero', injectTcb(tcb => { - - let template = - `
    - - -
    ` - - return tcb - .overrideTemplate(HeroDetailComponent, template) - .createAsync(HeroDetailComponent) - .then((rootTC: RTC) => { - - let hdc: HeroDetailComponent = rootTC.debugElement.componentInstance; - hdc.hero = new Hero(42, 'Cat Woman'); - let origNameLength = hdc.hero.name.length; - - // trigger the 'click' event on the HeroDetailComponent update button - rootTC.debugElement.query(By.css('#update')) - .triggerEventHandler('click', null); - - expect(hdc.hero.name.length).toBeGreaterThan(origNameLength); - }); - })); - - it('Entering hero name in textbox changes hero', injectTcb(tcb => { - - let hdc: HeroDetailComponent - let template = `` - - return tcb - .overrideTemplate(HeroDetailComponent, template) - .createAsync(HeroDetailComponent) - .then((rootTC: RTC) => { - - hdc = rootTC.debugElement.componentInstance; - - hdc.hero = new Hero(42, 'Cat Woman'); - rootTC.detectChanges(); - - // get the HTML element and change its value in the DOM - var input = rootTC.debugElement.query(By.css('input')).nativeElement; - input.value = "Dog Man" - dispatchEvent(input, 'change'); // event triggers Ng to update model - - rootTC.detectChanges(); - // model update hasn't happened yet, despite `detectChanges` - expect(hdc.hero.name).toEqual('Cat Woman'); - - }) - .then(tick) // must wait a tick for the model update - .then(() => { - expect(hdc.hero.name).toEqual('Dog Man'); - }); - })); - - // Simulates ... - // 1. change a hero - // 2. select a different hero - // 3 re-select the first hero - // 4. confirm that the change is preserved in HTML - // Reveals 2-way binding bug in alpha-36, fixed in pull #3715 for alpha-37 - - it('toggling heroes after modifying name preserves the change on screen', injectTcb(tcb => { - - let hdc: HeroDetailComponent; - let hero1 = new Hero(1, 'Cat Woman'); - let hero2 = new Hero(2, 'Goat Boy'); - let input: HTMLInputElement; - let rootTC: RTC; - let template = `{{hero.id}} - ` - - return tcb - .overrideTemplate(HeroDetailComponent, template) - .createAsync(HeroDetailComponent) - .then((rtc: RTC) => { - rootTC = rtc; - hdc = rootTC.debugElement.componentInstance; - - hdc.hero = hero1; // start with hero1 - rootTC.detectChanges(); - - // get the HTML element and change its value in the DOM - input = rootTC.debugElement.query(By.css('input')).nativeElement; - input.value = "Dog Man" - dispatchEvent(input, 'change'); // event triggers Ng to update model - }) - .then(tick) // must wait a tick for the model update - .then(() => { - expect(hdc.hero.name).toEqual('Dog Man'); - - hdc.hero = hero2 // switch to hero2 - rootTC.detectChanges(); - - hdc.hero = hero1 // switch back to hero1 - rootTC.detectChanges(); - - // model value will be the same changed value (of course) - expect(hdc.hero.name).toEqual('Dog Man'); - - // the view should reflect the same changed value - expect(input.value).toEqual('Dog Man'); - }); - })); - }); -}); diff --git a/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.wrapped-tests.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.wrapped-tests.spec.ts.not-yet deleted file mode 100644 index 319ac93ebf..0000000000 --- a/public/docs/_examples/testing/ts/app/old-specs/hero-detail.component.wrapped-tests.spec.ts.not-yet +++ /dev/null @@ -1,144 +0,0 @@ -///// Boiler Plate //// -import {bind, Component, Directive, EventEmitter, FORM_DIRECTIVES, View} from 'angular2/angular2'; - -// Angular 2 Test Bed -import { - beforeEachProviders, By, DebugElement, RootTestComponent as RTC, - beforeEach, ddescribe, xdescribe, describe, expect, iit, it, xit // Jasmine wrappers -} from 'angular2/testing'; - -import {injectAsync, injectTcb} from '../test-helpers/test-helpers'; - -///// Testing this component //// -import {HeroDetailComponent} from './hero-detail.component'; -import {Hero} from './hero'; - -describe('HeroDetailComponent', () => { - - it('can be created', () => { - let hc = new HeroDetailComponent() - expect(hc instanceof HeroDetailComponent).toEqual(true); // proof of life - }); - - it('parent "currentHero" flows down to HeroDetailComponent', injectTcb( tcb => { - return tcb - .createAsync(TestWrapper) - .then((rootTC:RTC) => { - let hc:HeroDetailComponent = rootTC.componentViewChildren[0].componentInstance; - let hw:TestWrapper = rootTC.componentInstance; - - rootTC.detectChanges(); // trigger view binding - - expect(hw.currentHero).toBe(hc.hero); - }); - })); - - it('delete button should raise delete event for parent component', injectTcb( tcb => { - - return tcb - //.overrideTemplate(HeroDetailComponent, '') - .overrideDirective(TestWrapper, HeroDetailComponent, mockHDC) - .createAsync(TestWrapper) - .then((rootTC:RTC) => { - - let hw:TestWrapper = rootTC.componentInstance; - let hdcElement = rootTC.componentViewChildren[0]; - let hdc:HeroDetailComponent = hdcElement.componentInstance; - - rootTC.detectChanges(); // trigger view binding - - // We can watch the HeroComponent.delete EventEmitter's event - let subscription = hdc.delete.toRx().subscribe(() => { - console.log('HeroComponent.delete event raised'); - subscription.dispose(); - }); - - // We can EITHER invoke HeroComponent delete button handler OR - // trigger the 'click' event on the delete HeroComponent button - // BUT DON'T DO BOTH - - // Trigger event - // FRAGILE because assumes precise knowledge of HeroComponent template - hdcElement - .query(By.css('#delete')) - .triggerEventHandler('click', {}); - - hw.testCallback = () => { - // if wrapper.onDelete is called, HeroComponent.delete event must have been raised - //console.log('HeroWrapper.onDelete called'); - expect(true).toEqual(true); - } - // hc.onDelete(); - }); - }), 500); // needs some time for event to complete; 100ms is not long enough - - it('update button should modify hero', injectTcb( tcb => { - - return tcb - .createAsync(TestWrapper) - .then((rootTC:RTC) => { - - let hc:HeroDetailComponent = rootTC.componentViewChildren[0].componentInstance; - let hw:TestWrapper = rootTC.componentInstance; - let origNameLength = hw.currentHero.name.length; - - rootTC.detectChanges(); // trigger view binding - - // We can EITHER invoke HeroComponent update button handler OR - // trigger the 'click' event on the HeroComponent update button - // BUT DON'T DO BOTH - - // Trigger event - // FRAGILE because assumes precise knowledge of HeroComponent template - rootTC.componentViewChildren[0] - .componentViewChildren[2] - .triggerEventHandler('click', {}); - - // hc.onUpdate(); // Invoke button handler - expect(hw.currentHero.name.length).toBeGreaterThan(origNameLength); - }); - })); - -}); - -///// Test Components //////// - -// TestWrapper is a convenient way to communicate w/ HeroDetailComponent in a test -@Component({selector: 'hero-wrapper'}) -@View({ - template: ``, - directives: [HeroDetailComponent] -}) -class TestWrapper { - currentHero = new Hero(42, 'Cat Woman'); - userName = 'Sally'; - testCallback() {} // monkey-punched in a test - onDelete() { this.testCallback(); } -} - -@View({ - template: ` -
    -

    {{hero.name}} | {{userName}}

    - - -
    {{hero.id}}
    - -
    `, - directives: [FORM_DIRECTIVES] -}) -class mockHDC //extends HeroDetailComponent { } -{ - hero: Hero; - - delete = new EventEmitter(); - - onDelete() { this.delete.next(this.hero) } - - onUpdate() { - if (this.hero) { - this.hero.name += 'x'; - } - } - userName: string; -} \ No newline at end of file diff --git a/public/docs/_examples/testing/ts/app/old-specs/hero.service.ng.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/hero.service.ng.spec.ts.not-yet deleted file mode 100644 index a3e4c0c6a4..0000000000 --- a/public/docs/_examples/testing/ts/app/old-specs/hero.service.ng.spec.ts.not-yet +++ /dev/null @@ -1,198 +0,0 @@ -// Test a service when Angular DI is in play - -// Angular 2 Test Bed -import { - beforeEach, xdescribe, describe, it, xit, // Jasmine wrappers - beforeEachProviders, inject, injectAsync, -} from 'angular2/testing'; - -import {bind} from 'angular2/core'; - -// Service related imports -import {HeroService} from './hero.service'; -import {BackendService} from './backend.service'; -import {Hero} from './hero'; - -////// tests //////////// - -describe('HeroService (with angular DI)', () => { - - beforeEachProviders(() => [HeroService]); - - describe('creation', () => { - - beforeEachProviders( () => [bind(BackendService).toValue(null)] ); - - it('can instantiate the service', - inject([HeroService], (service: HeroService) => { - expect(service).toBeDefined(); - })); - - it('service.heroes is empty', - inject([HeroService], (service: HeroService) => { - expect(service.heroes.length).toEqual(0); - })); - }); - - describe('#refresh', () => { - - describe('when backend provides data', () => { - - beforeEach(() => { - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3,'Baz')]; - }); - - beforeEachProviders(() => - [bind(BackendService).toClass(HappyBackendService)] - ); - - it('refresh promise returns expected # of heroes when fulfilled', - injectAsync([HeroService], (service: HeroService) => { - - return service.refresh().then(heroes => - expect(heroes.length).toEqual(heroData.length) - ); - })); - - it('service.heroes has expected # of heroes when fulfilled', - injectAsync([HeroService], (service: HeroService) => { - - return service.refresh().then(() => - expect(service.heroes.length).toEqual(heroData.length) - ); - })); - - it('service.heroes remains empty until fulfilled', - inject([HeroService], (service: HeroService) => { - - service.refresh(); - - // executed before refresh completes - expect(service.heroes.length).toEqual(0); - })); - - it('service.heroes remains empty when the server returns no data', - injectAsync([HeroService], (service: HeroService) => { - - heroData = []; // simulate no heroes from the backend - - return service.refresh().then(() => - expect(service.heroes.length).toEqual(0) - ); - })); - - it('resets service.heroes w/ original data after re-refresh', - injectAsync([HeroService], (service: HeroService) => { - - let firstHeroes: Hero[]; - let changedName = 'Gerry Mander'; - - return service.refresh().then(heroes => { - firstHeroes = heroes; // remember array reference - - // Changes to cache! Should disappear after refresh - service.heroes[0].name = changedName; - service.heroes.push(new Hero(33, 'Hercules')); - return service.refresh() - }) - .then(() => { - expect(firstHeroes).toBe(service.heroes); // same object - expect(service.heroes.length).toEqual(heroData.length); // no Hercules - expect(service.heroes[0].name).not.toEqual(changedName); // reverted name change - }); - })); - - it('clears service.heroes while waiting for re-refresh', - injectAsync([HeroService], (service: HeroService) => { - - return service.refresh().then(() => { - service.refresh(); - expect(service.heroes.length).toEqual(0); - }); - })); - // the paranoid will verify not only that the array lengths are the same - // but also that the contents are the same. - it('service.heroes has expected heroes when fulfilled (paranoia)', - injectAsync([HeroService], (service: HeroService) => { - - return service.refresh().then(() => { - expect(service.heroes.length).toEqual(heroData.length); - service.heroes.forEach(h => - expect(heroData.some( - // hero instances are not the same objects but - // each hero in result matches an original hero by value - hd => hd.name === h.name && hd.id === h.id) - ) - ); - }); - })); - - }); - - describe('when backend throws an error', () => { - - beforeEachProviders(() => - [bind(BackendService).toClass(FailingBackendService)] - ); - - it('returns failed promise with the server error', - injectAsync([HeroService], (service: HeroService) => { - - return service.refresh() - .then(() => fail('refresh should have failed')) - .catch(err => expect(err).toBe(testError)); - })); - - it('resets heroes array to empty', - injectAsync([HeroService], (service: HeroService) => { - - return service.refresh() - .then(() => fail('refresh should have failed')) - .catch(err => expect(service.heroes.length).toEqual(0)) - })); - }); - - describe('when backend throws an error (spy version)', () => { - - beforeEachProviders(() => [BackendService]); - - beforeEach(inject([BackendService], (backend: BackendService) => - spyOn(backend, 'fetchAllHeroesAsync').and.callFake(() => Promise.reject(testError) - ))); - - it('returns failed promise with the server error', - injectAsync([HeroService], (service: HeroService) => { - - return service.refresh() - .then(() => fail('refresh should have failed')) - .catch(err => expect(err).toBe(testError)); - })); - - it('resets heroes array to empty', - injectAsync([HeroService], (service: HeroService) => { - - return service.refresh() - .then(() => fail('refresh should have failed')) - .catch(err => expect(service.heroes.length).toEqual(0)) - })); - }); - - }); -}); -///////// test helpers ///////// -var service: HeroService; -var heroData: Hero[]; - -class HappyBackendService { - // return a promise for fake heroes that resolves as quickly as possible - fetchAllHeroesAsync = () => - Promise.resolve(heroData.map(h => h.clone())); -} - -var testError = 'BackendService.fetchAllHeroesAsync failed on purpose'; - -class FailingBackendService { - // return a promise that fails as quickly as possible - fetchAllHeroesAsync = () => - Promise.reject(testError); -} diff --git a/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.1.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.1.spec.ts.not-yet deleted file mode 100644 index 89cbc597f8..0000000000 --- a/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.1.spec.ts.not-yet +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Dev Guide steps to hero.service.no-ng.spec - * Try it with unit-tests-4.html - */ - -// The phase of hero-service-spec -// when we're outlining what we want to test -describe('HeroService (test plan)', () => { - - describe('creation', () => { - xit('can instantiate the service'); - xit('service.heroes is empty'); - }); - - describe('#refresh', () => { - - describe('when server provides heroes', () => { - xit('refresh promise returns expected # of heroes when fulfilled'); - xit('service.heroes has expected # of heroes when fulfilled'); - xit('service.heroes remains empty until fulfilled'); - xit('service.heroes remains empty when the server returns no data'); - xit('resets service.heroes w/ original data after re-refresh'); - xit('clears service.heroes while waiting for re-refresh'); - }); - - describe('when the server fails', () => { - xit('returns failed promise with the server error'); - xit('clears service.heroes'); - }); - - }); - -}); - -import {HeroService} from './hero.service'; - -describe('HeroService (beginning tests - 1)', () => { - - describe('creation', () => { - it('can instantiate the service', () => { - let service = new HeroService(null); - expect(service).toBeDefined(); - }); - - it('heroes is empty', () => { - let service = new HeroService(null); - expect(service.heroes.length).toEqual(0); - }); - - }); - -}); - -import {BackendService} from './backend.service'; -import {Hero} from './hero'; - -xdescribe('HeroService (beginning tests - 2 [dont run])', () => { - let heroData:Hero[]; - - // No good! - it('refresh promise returns expected # of heroes when fulfilled', () => { - let service = new HeroService(null); - service.refresh().then(heroes => { - expect(heroes.length).toBeGreaterThan(0); // don’t know how many to expect yet - }); - }); - - // better ... but not async! - it('refresh promise returns expected # of heroes when fulfilled', () => { - - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')]; - - let backend = { - // return a promise for fake heroes that resolves as quickly as possible - fetchAllHeroesAsync: () => Promise.resolve(heroData) - }; - - let service = new HeroService(backend); - service.refresh().then(heroes => { - expect(heroes.length).toEqual(heroData.length); // is it? - expect(heroes.length).not.toEqual(heroData.length); // or is it not? - console.log('** inside callback **'); - }); - - console.log('** end of test **'); - }); - - // better ... but forgot to call done! - it('refresh promise returns expected # of heroes when fulfilled', done => { - - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')]; - - let backend = { - // return a promise for fake heroes that resolves as quickly as possible - fetchAllHeroesAsync: () => Promise.resolve(heroData) - }; - - let service = new HeroService(backend); - service.refresh().then(heroes => { - expect(heroes.length).toEqual(heroData.length); // is it? - expect(heroes.length).not.toEqual(heroData.length); // or is it not? - console.log('** inside callback **'); - }); - - console.log('** end of test **'); - }); -}); - -describe('HeroService (beginning tests - 3 [async])', () => { - - let heroData:Hero[]; - // Now it's proper async! - it('refresh promise returns expected # of heroes when fulfilled', done => { - - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')]; - - let backend = { - // return a promise for fake heroes that resolves as quickly as possible - fetchAllHeroesAsync: () => Promise.resolve(heroData) - }; - - let service = new HeroService(backend); - service.refresh().then(heroes => { - expect(heroes.length).toEqual(heroData.length); // is it? - //expect(heroes.length).not.toEqual(heroData.length); // or is it not? - console.log('** inside callback **'); - done(); - }); - - console.log('** end of test **'); - }); - - // Final before catch - it('refresh promise returns expected # of heroes when fulfilled', done => { - - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')]; - - let backend = { - // return a promise for fake heroes that resolves as quickly as possible - fetchAllHeroesAsync: () => Promise.resolve(heroData) - }; - - let service = new HeroService(backend); - service.refresh().then(heroes => { - expect(heroes.length).toEqual(heroData.length); - }) - .then(done); - }); - - // Final before beforeEach refactoring - it('refresh promise returns expected # of heroes when fulfilled', done => { - - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')]; - - let backend = { - // return a promise for fake heroes that resolves as quickly as possible - fetchAllHeroesAsync: () => Promise.resolve(heroData) - }; - - let service = new HeroService(backend); - service.refresh().then(heroes => { - expect(heroes.length).toEqual(heroData.length); - }) - .then(done, done.fail); - }); - - it('service.heroes remains empty until fulfilled', () => { - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')]; - - let backend = { - // return a promise for fake heroes that resolves as quickly as possible - fetchAllHeroesAsync: () => Promise.resolve(heroData) - }; - - let service = new HeroService(backend); - service.refresh(); - - // executed before refresh completes - expect(service.heroes.length).toEqual(0); - }); -}); - - -describe('HeroService (beginning tests - 4 [beforeEach])', () => { - let heroData:Hero[]; - let service:HeroService; // local to describe so tests can see it - - // before beforEach refactoring - beforeEach(() => { - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3,'Baz')]; - - let backend = { - // return a promise for fake heroes that resolves as quickly as possible - fetchAllHeroesAsync: () => Promise.resolve(heroData) - }; - - service = new HeroService(backend); - }); - - it('refresh promise returns expected # of heroes when fulfilled', done => { - service.refresh().then(heroes => - expect(heroes.length).toEqual(heroData.length) - ) - .then(done, done.fail); - }); - - it('service.heroes remains empty until fulfilled', () => { - service.refresh(); - - // executed before refresh completes - expect(service.heroes.length).toEqual(0); - }); - -}); - -describe('HeroService (beginning tests - 5 [refactored beforeEach])', () => { - - describe('when backend provides data', () => { - beforeEach(() => { - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3,'Baz')]; - service = new HeroService(new HappyBackendService()); - }); - - it('refresh promise returns expected # of heroes when fulfilled', done => { - service.refresh().then(() => - expect(service.heroes.length).toEqual(heroData.length) - ) - .then(done, done.fail); - }); - - it('service.heroes remains empty until fulfilled', () => { - service.refresh(); - - // executed before refresh completes - expect(service.heroes.length).toEqual(0); - }); - }); - -}); - - -///////// test helpers ///////// -var service: HeroService; -var heroData: Hero[]; - -class HappyBackendService { - // return a promise for fake heroes that resolves as quickly as possible - fetchAllHeroesAsync = () => - Promise.resolve(heroData.map(h => h.clone())); -} diff --git a/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.spec.ts.not-yet deleted file mode 100644 index c2deb56c7c..0000000000 --- a/public/docs/_examples/testing/ts/app/old-specs/hero.service.no-ng.spec.ts.not-yet +++ /dev/null @@ -1,150 +0,0 @@ -// Test a service without referencing Angular (no Angular DI) -import {HeroService} from './hero.service'; -import {BackendService} from './backend.service'; -import {Hero} from './hero'; - -////// tests //////////// - -describe('HeroService (no-angular)', () => { - - describe('creation', () => { - it('can instantiate the service', () => { - let service = new HeroService(null); - expect(service).toBeDefined(); - }); - - it('service.heroes is empty', () => { - let service = new HeroService(null); - expect(service.heroes.length).toEqual(0); - }); - }); - - describe('#refresh', () => { - - describe('when backend provides data', () => { - - beforeEach(() => { - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')]; - service = new HeroService(new HappyBackendService()); - }); - - - it('refresh promise returns expected # of heroes when fulfilled', done => { - service.refresh().then(heroes => - expect(heroes.length).toEqual(heroData.length) - ) - .then(done, done.fail); - }); - - it('service.heroes has expected # of heroes when fulfilled', done => { - service.refresh().then(() => - expect(service.heroes.length).toEqual(heroData.length) - ) - .then(done, done.fail); - }); - - it('service.heroes remains empty until fulfilled', () => { - service.refresh(); - - // executed before refresh completes - expect(service.heroes.length).toEqual(0); - }); - - it('service.heroes remains empty when the server returns no data', done => { - heroData = []; // simulate no heroes from the backend - - service.refresh().then(() => - expect(service.heroes.length).toEqual(0) - ) - .then(done, done.fail); - }); - - it('resets service.heroes w/ original data after re-refresh', done => { - let firstHeroes: Hero[]; - let changedName = 'Gerry Mander'; - - service.refresh().then(() => { - firstHeroes = service.heroes; // remember array reference - - // Changes to cache! Should disappear after refresh - service.heroes[0].name = changedName; - service.heroes.push(new Hero(33, 'Hercules')); - return service.refresh() - }) - .then(() => { - expect(firstHeroes).toBe(service.heroes); // same array - expect(service.heroes.length).toEqual(heroData.length); // no Hercules - expect(service.heroes[0].name).not.toEqual(changedName); // reverted name change - }) - .then(done, done.fail); - }); - - it('clears service.heroes while waiting for re-refresh', done => { - service.refresh().then(() => { - service.refresh(); - expect(service.heroes.length).toEqual(0); - }) - .then(done, done.fail); - }); - - // the paranoid will verify not only that the array lengths are the same - // but also that the contents are the same. - it('service.heroes has expected heroes when fulfilled (paranoia)', done => { - service.refresh().then(() => { - expect(service.heroes.length).toEqual(heroData.length); - service.heroes.forEach(h => - expect(heroData.some( - // hero instances are not the same objects but - // each hero in result matches an original hero by value - hd => hd.name === h.name && hd.id === h.id) - ) - ); - }) - .then(done, done.fail); - }); - - }); - - describe('when backend throws an error', () => { - - beforeEach(() => { - service = new HeroService(new FailingBackendService()); - }); - - it('returns failed promise with the server error', done => { - service.refresh() - .then(() => fail('refresh should have failed')) - .catch(err => expect(err).toEqual(testError)) - .then(done, done.fail); - }); - - it('clears service.heroes', done => { - service.refresh() - .then(() => fail('refresh should have failed')) - .catch(err => expect(service.heroes.length).toEqual(0)) - .then(done, done.fail); - }); - - }); - }); -}); - -///////// test helpers ///////// - -var service: HeroService; -var heroData: Hero[]; - -class HappyBackendService { - // return a promise for fake heroes that resolves as quickly as possible - fetchAllHeroesAsync = () => - Promise.resolve(heroData.map(h => h.clone())); -} - -var testError = 'BackendService.fetchAllHeroesAsync failed on purpose'; - -class FailingBackendService { - // return a promise that fails as quickly as possible - // force-cast it to because of TS typing bug. - fetchAllHeroesAsync = () => - >Promise.reject(testError); -} diff --git a/public/docs/_examples/testing/ts/app/old-specs/heroes.component.ng.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/heroes.component.ng.spec.ts.not-yet deleted file mode 100644 index 489745ca2b..0000000000 --- a/public/docs/_examples/testing/ts/app/old-specs/heroes.component.ng.spec.ts.not-yet +++ /dev/null @@ -1,276 +0,0 @@ -///// Angular 2 Test Bed //// -import {bind, By} from 'angular2/angular2'; - -import { - beforeEach, xdescribe, describe, it, xit, // Jasmine wrappers - beforeEachProviders, - injectAsync, - RootTestComponent as RTC, - TestComponentBuilder as TCB -} from 'angular2/testing'; - -import { - expectSelectedHtml, - expectViewChildHtml, - expectViewChildClass, - injectTcb, tick} from '../test-helpers/test-helpers'; - -///// Testing this component //// -import {HeroesComponent} from './heroes.component'; -import {Hero} from './hero'; -import {HeroService} from './hero.service'; -import {User} from './user'; - -let hc: HeroesComponent; -let heroData: Hero[]; // fresh heroes for each test -let mockUser: User; -let service: HeroService; - -// get the promise from the refresh spy; -// casting required because of inadequate d.ts for Jasmine -let refreshPromise = () => (service.refresh).calls.mostRecent().returnValue; - -describe('HeroesComponent (with Angular)', () => { - - beforeEach(() => { - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')]; - mockUser = new User(); - }); - - // Set up DI bindings required by component (and its nested components?) - // else hangs silently forever - beforeEachProviders(() => [ - bind(HeroService).toClass(HappyHeroService), - bind(User).toValue(mockUser) - ]); - - // test-lib bug? first test fails unless this no-op test runs first - it('ignore this test', () => expect(true).toEqual(true)); // hack - - it('can be created and has userName', injectTcb((tcb:TCB) => { - let template = ''; - return tcb - .overrideTemplate(HeroesComponent, template) - .createAsync(HeroesComponent) - .then((rootTC: RTC) => { - hc = rootTC.debugElement.componentInstance; - expect(hc).toBeDefined();// proof of life - expect(hc.userName).toEqual(mockUser.name); - }); - })); - - it('binds view to userName', injectTcb((tcb:TCB) => { - let template = `

    {{userName}}'s Heroes

    `; - return tcb - .overrideTemplate(HeroesComponent, template) - .createAsync(HeroesComponent) - .then((rootTC: RTC) => { - hc = rootTC.debugElement.componentInstance; - - rootTC.detectChanges(); // trigger component property binding - expectSelectedHtml(rootTC, 'h1').toMatch(hc.userName); - expectViewChildHtml(rootTC).toMatch(hc.userName); - }); - })); - - describe('#onInit', () => { - let template = ''; - - it('HeroService.refresh not called immediately', - injectTcb([HeroService], (tcb:TCB, heroService:HeroService) => { - - return tcb - .overrideTemplate(HeroesComponent, template) - .createAsync(HeroesComponent) - .then(() => { - let spy = heroService.refresh; - expect(spy.calls.count()).toEqual(0); - }); - })); - - it('onInit calls HeroService.refresh', - injectTcb([HeroService], (tcb:TCB, heroService:HeroService) => { - - return tcb - .overrideTemplate(HeroesComponent, template) - .createAsync(HeroesComponent) - .then((rootTC: RTC) => { - hc = rootTC.debugElement.componentInstance; - let spy = heroService.refresh; - hc.ngOnInit(); // Angular framework calls when it creates the component - expect(spy.calls.count()).toEqual(1); - }); - })); - - it('onInit is called after the test calls detectChanges', injectTcb((tcb:TCB) => { - - return tcb - .overrideTemplate(HeroesComponent, template) - .createAsync(HeroesComponent) - .then((rootTC: RTC) => { - hc = rootTC.debugElement.componentInstance; - let spy = spyOn(hc, 'onInit').and.callThrough(); - - expect(spy.calls.count()).toEqual(0); - rootTC.detectChanges(); - expect(spy.calls.count()).toEqual(1); - }); - })); - }) - - describe('#heroes', () => { - // focus on the part of the template that displays heroe names - let template = - '
    • {{h.name}}
    '; - - it('binds view to heroes', injectTcb((tcb:TCB) => { - return tcb - .overrideTemplate(HeroesComponent, template) - .createAsync(HeroesComponent) - .then((rootTC: RTC) => { - // trigger {{heroes}} binding - rootTC.detectChanges(); - - // hc.heroes is still empty; need a JS cycle to get the data - return rootTC; - }) - .then((rootTC: RTC) => { - hc = rootTC.debugElement.componentInstance; - // now heroes are available for binding - expect(hc.heroes.length).toEqual(heroData.length); - - rootTC.detectChanges(); // trigger component property binding - - // confirm hero list is displayed by looking for a known hero - expect(rootTC.debugElement.nativeElement.innerHTML).toMatch(heroData[0].name); - }); - })); - - // ... add more tests of component behavior affecting the heroes list - - }); - - describe('#onSelected', () => { - - it('no hero is selected by default', injectHC(hc => { - expect(hc.currentHero).not.toBeDefined(); - })); - - it('sets the "currentHero"', injectHC(hc => { - hc.onSelect(heroData[1]); // select the second hero - expect(hc.currentHero).toEqual(heroData[1]); - })); - - it('no hero is selected after onRefresh() called', injectHC(hc => { - hc.onSelect(heroData[1]); // select the second hero - hc.onRefresh(); - expect(hc.currentHero).not.toBeDefined(); - })); - - // TODO: Remove `withNgClass=true` ONCE BUG IS FIXED - xit('the view of the "currentHero" has the "selected" class (NG2 BUG)', injectHC((hc, rootTC) => { - hc.onSelect(heroData[1]); // select the second hero - - rootTC.detectChanges(); - - // The 3rd ViewChild is 2nd hero; the 1st is for the template - expectViewChildClass(rootTC, 2).toMatch('selected'); - }, true /* true == include ngClass */)); - - it('the view of a non-selected hero does NOT have the "selected" class', injectHC((hc, rootTC) => { - hc.onSelect(heroData[1]); // select the second hero - rootTC.detectChanges(); - // The 4th ViewChild is 3rd hero; the 1st is for the template - expectViewChildClass(rootTC, 4).not.toMatch('selected'); - })); - - }); - - // Most #onDelete tests not re-implemented because - // writing those tests w/in Angular adds little value and - // is far more painful than writing them to run outside Angular - // Only bother with the one test that checks the DOM - describe('#onDeleted', () => { - let template = - '
    • {{h.name}}
    '; - - it('the list view does not contain the "deleted" currentHero', injectTcb((tcb:TCB) => { - return tcb - .overrideTemplate(HeroesComponent, template) - .createAsync(HeroesComponent) - .then((rootTC: RTC) => { - hc = rootTC.debugElement.componentInstance; - // trigger {{heroes}} binding - rootTC.detectChanges(); - return rootTC; // wait for heroes to arrive - }) - .then((rootTC: RTC) => { - hc.currentHero = heroData[1]; - hc.onDelete() - rootTC.detectChanges(); // trigger component property binding - - // confirm hero list is not displayed by looking for removed hero - expect(rootTC.debugElement.nativeElement.innerHTML).not.toMatch(heroData[1].name); - }); - })); - }); -}); - -////// Helpers ////// - -class HappyHeroService { - - constructor() { - spyOn(this, 'refresh').and.callThrough(); - } - - heroes: Hero[]; - - refresh() { - this.heroes = []; - // updates cached heroes after one JavaScript cycle - return new Promise((resolve, reject) => { - this.heroes.push(...heroData); - resolve(this.heroes); - }); - } -} - - -// The same setup for every test in the #onSelected suite -// TODO: Remove `withNgClass` and always include in template ONCE BUG IS FIXED -function injectHC(testFn: (hc: HeroesComponent, rootTC?: RTC) => void, withNgClass:boolean = false) { - - // This is the bad boy: [ngClass]="getSelectedClass(hero)" - let ngClass = withNgClass ? '[ngClass]="getSelectedClass(hero)"' : ''; - - // focus on the part of the template that displays heroes - let template = - `
    • - ({{hero.id}}) {{hero.name}} -
    `; - - return injectTcb((tcb:TCB) => { - let hc: HeroesComponent; - - return tcb - .overrideTemplate(HeroesComponent, template) - .createAsync(HeroesComponent) - .then((rootTC:RTC) => { - hc = rootTC.debugElement.componentInstance; - rootTC.detectChanges();// trigger {{heroes}} binding - return rootTC; - }) - .then((rootTC:RTC) => { // wait a tick until heroes are fetched -console.error("WAS THIS FIXED??"); - // CRASHING HERE IF TEMPLATE HAS '[ngClass]="getSelectedClass(hero)"' - // WITH EXCEPTION: - // "Expression 'getSelectedClass(hero) in null' has changed after it was checked." - - rootTC.detectChanges(); // show the list - testFn(hc, rootTC); - }); - }) -} diff --git a/public/docs/_examples/testing/ts/app/old-specs/heroes.component.no-ng.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/heroes.component.no-ng.spec.ts.not-yet deleted file mode 100644 index b1c1f2cff8..0000000000 --- a/public/docs/_examples/testing/ts/app/old-specs/heroes.component.no-ng.spec.ts.not-yet +++ /dev/null @@ -1,229 +0,0 @@ -import {HeroesComponent} from './heroes.component'; -import {Hero} from './hero'; -import {HeroService} from './hero.service'; -import {User} from './user'; - -describe('HeroesComponent (Test Plan)', () => { - xit('can be created'); - xit('has expected userName'); - - describe('#onInit', () => { - xit('HeroService.refresh not called immediately'); - xit('onInit calls HeroService.refresh'); - }); - - describe('#heroes', () => { - xit('lacks heroes when created'); - xit('has heroes after cache loaded'); - xit('restores heroes after refresh called again'); - - xit('binds view to heroes'); - }); - - describe('#onSelected', () => { - xit('no hero is selected by default'); - xit('sets the "currentHero"'); - xit('no hero is selected after onRefresh() called'); - - xit('the view of the "currentHero" has the "selected" class (NG2 BUG)'); - xit('the view of a non-selected hero does NOT have the "selected" class'); - }); - - describe('#onDelete', () => { - xit('removes the supplied hero (only) from the list'); - xit('removes the currentHero from the list if no hero argument'); - xit('is harmless if no supplied or current hero'); - xit('is harmless if hero not in list'); - xit('is harmless if the list is empty'); - xit('the new currentHero is the one after the removed hero'); - xit('the new currentHero is the one before the removed hero if none after'); - - xit('the list view does not contain the "deleted" currentHero'); - }); -}); - -let hc:HeroesComponent; -let heroData: Hero[]; // fresh heroes for each test -let mockUser: User; -let service: HeroService; - -// get the promise from the refresh spy; -// casting required because of inadequate d.ts for Jasmine -let refreshPromise = () => (service.refresh).calls.mostRecent().returnValue; - -describe('HeroesComponent (no Angular)', () => { - - beforeEach(()=> { - heroData = [new Hero(1, 'Foo'), new Hero(2, 'Bar'), new Hero(3, 'Baz')]; - mockUser = new User(); - }); - - beforeEach(()=> { - service = new HappyHeroService(); - hc = new HeroesComponent(service, mockUser) - }); - - it('can be created', () => { - expect(hc instanceof HeroesComponent).toEqual(true); // proof of life - }); - - it('has expected userName', () => { - expect(hc.userName).toEqual(mockUser.name); - }); - - describe('#onInit', () => { - it('HeroService.refresh not called immediately', () => { - let spy = service.refresh; - expect(spy.calls.count()).toEqual(0); - }); - - it('onInit calls HeroService.refresh', () => { - let spy = service.refresh; - hc.ngOnInit(); // Angular framework calls when it creates the component - expect(spy.calls.count()).toEqual(1); - }); - }) - - describe('#heroes', () => { - - it('lacks heroes when created', () => { - let heroes = hc.heroes; - expect(heroes.length).toEqual(0); // not filled yet - }); - - it('has heroes after cache loaded', done => { - hc.ngOnInit(); // Angular framework calls when it creates the component - - refreshPromise().then(() => { - let heroes = hc.heroes; // now the component has heroes to show - expect(heroes.length).toEqual(heroData.length); - }) - .then(done, done.fail); - }); - - it('restores heroes after refresh called again', done => { - hc.ngOnInit(); // component initialization triggers service - let heroes: Hero[]; - - refreshPromise().then(() => { - heroes = hc.heroes; // now the component has heroes to show - heroes[0].name = 'Wotan'; - heroes.push(new Hero(33, 'Thor')); - hc.onRefresh(); - }) - .then(() => { - heroes = hc.heroes; // get it again (don't reuse old array!) - expect(heroes[0]).not.toEqual('Wotan'); // change reversed - expect(heroes.length).toEqual(heroData.length); // orig num of heroes - }) - .then(done, done.fail); - }); - }); - - describe('#onSelected', () => { - - it('no hero is selected by default', () => { - expect(hc.currentHero).not.toBeDefined(); - }); - - it('sets the "currentHero"', () => { - hc.onSelect(heroData[1]); // select the second hero - expect(hc.currentHero).toEqual(heroData[1]); - }); - - it('no hero is selected after onRefresh() called', () => { - hc.onSelect(heroData[1]); // select the second hero - hc.onRefresh(); - expect(hc.currentHero).not.toBeDefined(); - }); - }); - - - describe('#onDelete', () => { - - // Load the heroes asynchronously before each test - // Getting the async out of the way in the beforeEach - // means tests can be synchronous - // Note: could have cheated and simply plugged hc.heroes with fake data - // that trick would fail if we reimplemented hc.heroes as a readonly property - beforeEach(done => { - hc.ngOnInit(); // Angular framework calls when it creates the component - refreshPromise().then(done, done.fail); - }); - - it('removes the supplied hero (only) from the list', () => { - hc.currentHero = heroData[1]; - let hero = heroData[2]; - hc.onDelete(hero); - - expect(hc.heroes).not.toContain(hero); - expect(hc.heroes).toContain(heroData[1]); // left current in place - expect(hc.heroes.length).toEqual(heroData.length - 1); - }); - - it('removes the currentHero from the list if no hero argument', () => { - hc.currentHero = heroData[1]; - hc.onDelete(); - expect(hc.heroes).not.toContain(heroData[1]); - }); - - it('is harmless if no supplied or current hero', () => { - hc.currentHero = null; - hc.onDelete(); - expect(hc.heroes.length).toEqual(heroData.length); - }); - - it('is harmless if hero not in list', () => { - let hero = heroData[1].clone(); // object reference matters, not id - hc.onDelete(hero); - expect(hc.heroes.length).toEqual(heroData.length); - }); - - // must go async to get hc to clear its heroes list - it('is harmless if the list is empty', done => { - let hero = heroData[1]; - heroData = []; - hc.onRefresh(); - refreshPromise().then(() => { - hc.onDelete(hero); // shouldn't fail - }) - .then(done, done.fail); - }); - - it('the new currentHero is the one after the removed hero', () => { - hc.currentHero = heroData[1]; - let expectedCurrent = heroData[2]; - hc.onDelete(); - expect(hc.currentHero).toBe(expectedCurrent); - }); - - it('the new currentHero is the one before the removed hero if none after', () => { - hc.currentHero = heroData[heroData.length - 1]; // last hero - let expectedCurrent = heroData[heroData.length - 2]; // penultimate hero - hc.onDelete(); - expect(hc.currentHero).toBe(expectedCurrent); - }); - }); - -}); - - -////// Helpers ////// - -class HappyHeroService { - - constructor() { - spyOn(this, 'refresh').and.callThrough(); - } - - heroes: Hero[]; - - refresh() { - this.heroes = []; - // updates cached heroes after one JavaScript cycle - return new Promise((resolve, reject) => { - this.heroes.push(...heroData); - resolve(this.heroes); - }); - } -} diff --git a/public/docs/_examples/testing/ts/app/old-specs/user.spec.ts.not-yet b/public/docs/_examples/testing/ts/app/old-specs/user.spec.ts.not-yet deleted file mode 100644 index f65ac89a5e..0000000000 --- a/public/docs/_examples/testing/ts/app/old-specs/user.spec.ts.not-yet +++ /dev/null @@ -1,18 +0,0 @@ -import {User} from './user'; - -describe('User', () => { - let user:User; - - beforeEach(() => { - user = new User(); - }); - - it('has id === 42', () => { - expect(user.id).toEqual(42); - }); - - it('has an email address', () => { - expect(user.email.length).toBeGreaterThan(0); - }); - -}); \ No newline at end of file diff --git a/public/docs/_examples/testing/ts/bag-specs.plnkr.json b/public/docs/_examples/testing/ts/bag-specs.plnkr.json new file mode 100644 index 0000000000..cd22e10c28 --- /dev/null +++ b/public/docs/_examples/testing/ts/bag-specs.plnkr.json @@ -0,0 +1,21 @@ +{ + "description": "Testing - bag.specs", + "basePath": "src/", + "files":[ + "browser-test-shim.js", + "systemjs.config.extras.js", + "styles.css", + + "app/bag/**/*.html", + "app/bag/**/*.ts", + "app/bag/**/*.spec.ts", + + "!app/bag/bag-main.ts", + + "testing/*.ts", + + "bag-specs.html" + ], + "main": "bag-specs.html", + "tags": ["testing"] +} diff --git a/public/docs/_examples/testing/ts/bag.plnkr.json b/public/docs/_examples/testing/ts/bag.plnkr.json new file mode 100644 index 0000000000..4bb0ac9c5b --- /dev/null +++ b/public/docs/_examples/testing/ts/bag.plnkr.json @@ -0,0 +1,14 @@ +{ + "description": "Running the bag", + "basePath": "src/", + "files":[ + "styles.css", + + "app/bag/bag.ts", + "app/bag/bag-external-template.html", + "app/bag/bag-main.ts", + "bag.html" + ], + "main": "bag.html", + "tags": ["testing"] +} diff --git a/public/docs/_examples/testing/ts/banner-inline-specs.plnkr.json b/public/docs/_examples/testing/ts/banner-inline-specs.plnkr.json new file mode 100644 index 0000000000..77b8c212cf --- /dev/null +++ b/public/docs/_examples/testing/ts/banner-inline-specs.plnkr.json @@ -0,0 +1,15 @@ +{ + "description": "Testing - banner-inline.component.specs", + "basePath": "src/", + "files":[ + "browser-test-shim.js", + "systemjs.config.extras.js", + + "app/banner-inline.component.ts", + "app/banner-inline.component.spec.ts", + "banner-inline-specs.html" + ], + "main": "banner-inline-specs.html", + "open": "app/banner-inline.component.spec.ts", + "tags": ["testing"] +} diff --git a/public/docs/_examples/testing/ts/banner-specs.plnkr.json b/public/docs/_examples/testing/ts/banner-specs.plnkr.json new file mode 100644 index 0000000000..6e5f20bccb --- /dev/null +++ b/public/docs/_examples/testing/ts/banner-specs.plnkr.json @@ -0,0 +1,17 @@ +{ + "description": "Testing - banner.component.specs", + "basePath": "src/", + "files":[ + "browser-test-shim.js", + "systemjs.config.extras.js", + + "app/banner.component.css", + "app/banner.component.html", + "app/banner.component.ts", + "app/banner.component.spec.ts", + "banner-specs.html" + ], + "main": "banner-specs.html", + "open": "app/banner.component.spec.ts", + "tags": ["testing"] +} diff --git a/public/docs/_examples/testing/ts/index.html b/public/docs/_examples/testing/ts/index.html deleted file mode 100644 index bfde80afe3..0000000000 --- a/public/docs/_examples/testing/ts/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - Testing Tour of Heroes - - - - - - - - - - - - - - - - - Loading... - - diff --git a/public/docs/_examples/testing/ts/karma-test-shim.js b/public/docs/_examples/testing/ts/karma-test-shim.js new file mode 100644 index 0000000000..1b8d6acdd4 --- /dev/null +++ b/public/docs/_examples/testing/ts/karma-test-shim.js @@ -0,0 +1,96 @@ +// #docregion +// /*global jasmine, __karma__, window*/ +Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing. + +// Uncomment to get full stacktrace output. Sometimes helpful, usually not. +// Error.stackTraceLimit = Infinity; // + +jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; + +// builtPaths: root paths for output ("built") files +// get from karma.config.js, then prefix with '/src/' (default is 'app/') +var builtPaths = (__karma__.config.builtPaths || ['src/']) + .map(function(p) { return '/base/'+p;}); + +__karma__.loaded = function () { }; + +function isJsFile(path) { + return path.slice(-3) == '.js'; +} + +function isSpecFile(path) { + return /\.spec\.(.*\.)?js$/.test(path); +} + +// Is a "built" file if is JavaScript file in one of the "built" folders +function isBuiltFile(path) { + return isJsFile(path) && + builtPaths.reduce(function(keep, bp) { + return keep || (path.substr(0, bp.length) === bp); + }, false); +} + +var allSpecFiles = Object.keys(window.__karma__.files) + .filter(isSpecFile) + .filter(isBuiltFile); + +System.config({ + baseURL: 'base/src', + // Extend usual application package list with testing folder + packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } }, + + // Assume npm: is set in `paths` in systemjs.config + // Map the angular testing umd bundles + map: { + '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js', + '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js', + '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js', + '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js', + '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js', + '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js', + '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js', + '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js', + }, +}); + +System.import('systemjs.config.js') + .then(importSystemJsExtras) + .then(initTestBed) + .then(initTesting); + +/** Optional SystemJS configuration extras. Keep going w/o it */ +function importSystemJsExtras(){ + return System.import('systemjs.config.extras.js') + .catch(function(reason) { + console.log( + 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.' + ); + console.log(reason); + }); +} + +function initTestBed(){ + return Promise.all([ + System.import('@angular/core/testing'), + System.import('@angular/platform-browser-dynamic/testing') + ]) + + .then(function (providers) { + var coreTesting = providers[0]; + var browserTesting = providers[1]; + + coreTesting.TestBed.initTestEnvironment( + browserTesting.BrowserDynamicTestingModule, + browserTesting.platformBrowserDynamicTesting()); + }) +} + +// Import all spec files and start karma +function initTesting () { + return Promise.all( + allSpecFiles.map(function (moduleName) { + return System.import(moduleName); + }) + ) + .then(__karma__.start, __karma__.error); +} diff --git a/public/docs/_examples/testing/ts/karma.conf.js b/public/docs/_examples/testing/ts/karma.conf.js new file mode 100644 index 0000000000..a00b8add54 --- /dev/null +++ b/public/docs/_examples/testing/ts/karma.conf.js @@ -0,0 +1,98 @@ +// #docregion +module.exports = function(config) { + + var appBase = 'src/'; // transpiled app JS and map files + var appAssets = '/base/app/'; // component assets fetched by Angular's compiler + + // Testing helpers (optional) are conventionally in a folder called `testing` + var testingBase = 'src/testing/'; // transpiled test JS and map files + var testingSrcBase = 'src/testing/'; // test source TS files + + config.set({ + basePath: '', + frameworks: ['jasmine'], + + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter') + ], + + client: { + builtPaths: [appBase, testingBase], // add more spec base paths as needed + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + + customLaunchers: { + // From the CLI. Not used here but interesting + // chrome setup for travis CI using chromium + Chrome_travis_ci: { + base: 'Chrome', + flags: ['--no-sandbox'] + } + }, + + files: [ + // System.js for module loading + 'node_modules/systemjs/dist/system.src.js', + + // Polyfills + 'node_modules/core-js/client/shim.js', + + // zone.js + 'node_modules/zone.js/dist/zone.js', + 'node_modules/zone.js/dist/long-stack-trace-zone.js', + 'node_modules/zone.js/dist/proxy.js', + 'node_modules/zone.js/dist/sync-test.js', + 'node_modules/zone.js/dist/jasmine-patch.js', + 'node_modules/zone.js/dist/async-test.js', + 'node_modules/zone.js/dist/fake-async-test.js', + + // RxJs + { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, + { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false }, + + // Paths loaded via module imports: + // Angular itself + { pattern: 'node_modules/@angular/**/*.js', included: false, watched: false }, + { pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false }, + + { pattern: appBase + '/systemjs.config.js', included: false, watched: false }, + { pattern: appBase + '/systemjs.config.extras.js', included: false, watched: false }, + 'karma-test-shim.js', // optionally extend SystemJS mapping e.g., with barrels + + // transpiled application & spec code paths loaded via module imports + { pattern: appBase + '**/*.js', included: false, watched: true }, + { pattern: testingBase + '**/*.js', included: false, watched: true }, + + + // Asset (HTML & CSS) paths loaded via Angular's component compiler + // (these paths need to be rewritten, see proxies section) + { pattern: appBase + '**/*.html', included: false, watched: true }, + { pattern: appBase + '**/*.css', included: false, watched: true }, + + // Paths for debugging with source maps in dev tools + { pattern: appBase + '**/*.ts', included: false, watched: false }, + { pattern: appBase + '**/*.js.map', included: false, watched: false }, + { pattern: testingSrcBase + '**/*.ts', included: false, watched: false }, + { pattern: testingBase + '**/*.js.map', included: false, watched: false} + ], + + // Proxied base paths for loading assets + proxies: { + // required for modules fetched by SystemJS + '/base/src/node_modules/': '/base/node_modules/' + }, + + exclude: [], + preprocessors: {}, + reporters: ['progress', 'kjhtml'], + + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false + }) +} diff --git a/public/docs/_examples/testing/ts/plnkr.json b/public/docs/_examples/testing/ts/plnkr.json new file mode 100644 index 0000000000..899867159f --- /dev/null +++ b/public/docs/_examples/testing/ts/plnkr.json @@ -0,0 +1,18 @@ +{ + "description": "Heroes Test App", + "basePath": "src/", + "files":[ + "styles.css", + "systemjs.config.extras.js", + + "app/**/*.css", + "app/**/*.html", + "app/**/*.ts", + + "!app/bag/*.*", + + "main.ts", + "index.html" + ], + "tags": ["testing"] +} diff --git a/public/docs/_examples/testing/ts/src/1st-specs.html b/public/docs/_examples/testing/ts/src/1st-specs.html new file mode 100644 index 0000000000..5876a65b9a --- /dev/null +++ b/public/docs/_examples/testing/ts/src/1st-specs.html @@ -0,0 +1,41 @@ + + + + + + + 1st Specs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/testing/ts/src/app-specs.html b/public/docs/_examples/testing/ts/src/app-specs.html new file mode 100644 index 0000000000..7b7292ed7c --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app-specs.html @@ -0,0 +1,56 @@ + + + + + + + Sample App Specs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/testing/ts/src/app/1st.spec.ts b/public/docs/_examples/testing/ts/src/app/1st.spec.ts new file mode 100644 index 0000000000..63f1ab134c --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/1st.spec.ts @@ -0,0 +1,5 @@ +// #docplaster +// #docregion +describe('1st tests', () => { + it('true is true', () => expect(true).toBe(true)); +}); diff --git a/public/docs/_examples/testing/ts/src/app/about.component.spec.ts b/public/docs/_examples/testing/ts/src/app/about.component.spec.ts new file mode 100644 index 0000000000..0909e74434 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/about.component.spec.ts @@ -0,0 +1,27 @@ +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; + +import { AboutComponent } from './about.component'; +import { HighlightDirective } from './shared/highlight.directive'; + +let fixture: ComponentFixture; + +describe('AboutComponent (highlightDirective)', () => { + // #docregion tests + beforeEach(() => { + fixture = TestBed.configureTestingModule({ + declarations: [ AboutComponent, HighlightDirective], + schemas: [ NO_ERRORS_SCHEMA ] + }) + .createComponent(AboutComponent); + fixture.detectChanges(); // initial binding + }); + + it('should have skyblue

    ', () => { + const de = fixture.debugElement.query(By.css('h2')); + const bgColor = de.nativeElement.style.backgroundColor; + expect(bgColor).toBe('skyblue'); + }); + // #enddocregion tests +}); diff --git a/public/docs/_examples/testing/ts/src/app/about.component.ts b/public/docs/_examples/testing/ts/src/app/about.component.ts new file mode 100644 index 0000000000..90e7132b4c --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/about.component.ts @@ -0,0 +1,9 @@ +// #docregion +import { Component } from '@angular/core'; +@Component({ + template: ` +

    About

    + +

    All about this sample

    ` +}) +export class AboutComponent { } diff --git a/public/docs/_examples/testing/ts/src/app/app-routing.module.ts b/public/docs/_examples/testing/ts/src/app/app-routing.module.ts new file mode 100644 index 0000000000..6096a513df --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/app-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { AboutComponent } from './about.component'; + +@NgModule({ + imports: [ + RouterModule.forRoot([ + { path: '', redirectTo: 'dashboard', pathMatch: 'full'}, + { path: 'about', component: AboutComponent }, + { path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule'} + ]) + ], + exports: [ RouterModule ] // re-export the module declarations +}) +export class AppRoutingModule { }; diff --git a/public/docs/_examples/testing/ts/src/app/app.component.html b/public/docs/_examples/testing/ts/src/app/app.component.html new file mode 100644 index 0000000000..232bcebb6d --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/app.component.html @@ -0,0 +1,11 @@ + + + + + + + diff --git a/public/docs/_examples/testing/ts/src/app/app.component.router.spec.ts b/public/docs/_examples/testing/ts/src/app/app.component.router.spec.ts new file mode 100644 index 0000000000..226d6d1ff3 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/app.component.router.spec.ts @@ -0,0 +1,198 @@ +// For more examples: +// https://github.com/angular/angular/blob/master/modules/@angular/router/test/integration.spec.ts + +import { async, ComponentFixture, fakeAsync, TestBed, tick, +} from '@angular/core/testing'; + +import { RouterTestingModule } from '@angular/router/testing'; +import { SpyLocation } from '@angular/common/testing'; + +import { click } from '../testing'; + +// r - for relatively obscure router symbols +import * as r from '@angular/router'; +import { Router, RouterLinkWithHref } from '@angular/router'; + +import { By } from '@angular/platform-browser'; +import { DebugElement, Type } from '@angular/core'; +import { Location } from '@angular/common'; + +import { AppModule } from './app.module'; +import { AppComponent } from './app.component'; +import { AboutComponent } from './about.component'; +import { DashboardHeroComponent } from './dashboard/dashboard-hero.component'; +import { TwainService } from './shared/twain.service'; + +let comp: AppComponent; +let fixture: ComponentFixture; +let page: Page; +let router: Router; +let location: SpyLocation; + +describe('AppComponent & RouterTestingModule', () => { + + beforeEach( async(() => { + TestBed.configureTestingModule({ + imports: [ AppModule, RouterTestingModule ] + }) + .compileComponents(); + })); + + it('should navigate to "Dashboard" immediately', fakeAsync(() => { + createComponent(); + expect(location.path()).toEqual('/dashboard', 'after initialNavigation()'); + expectElementOf(DashboardHeroComponent); + })); + + it('should navigate to "About" on click', fakeAsync(() => { + createComponent(); + click(page.aboutLinkDe); + // page.aboutLinkDe.nativeElement.click(); // ok but fails in phantom + + advance(); + expectPathToBe('/about'); + expectElementOf(AboutComponent); + + page.expectEvents([ + [r.NavigationStart, '/about'], [r.RoutesRecognized, '/about'], + [r.NavigationEnd, '/about'] + ]); + })); + + it('should navigate to "About" w/ browser location URL change', fakeAsync(() => { + createComponent(); + location.simulateHashChange('/about'); + // location.go('/about'); // also works ... except in plunker + advance(); + expectPathToBe('/about'); + expectElementOf(AboutComponent); + })); + + // Can't navigate to lazy loaded modules with this technique + xit('should navigate to "Heroes" on click', fakeAsync(() => { + createComponent(); + page.heroesLinkDe.nativeElement.click(); + advance(); + expectPathToBe('/heroes'); + })); + +}); + + +/////////////// +import { NgModuleFactoryLoader } from '@angular/core'; +import { SpyNgModuleFactoryLoader } from '@angular/router/testing'; + +import { HeroModule } from './hero/hero.module'; // should be lazy loaded +import { HeroListComponent } from './hero/hero-list.component'; + +let loader: SpyNgModuleFactoryLoader; + +///////// Can't get lazy loaded Heroes to work yet +xdescribe('AppComponent & Lazy Loading', () => { + + beforeEach( async(() => { + TestBed.configureTestingModule({ + imports: [ AppModule, RouterTestingModule ] + }) + .compileComponents(); + })); + + beforeEach(fakeAsync(() => { + createComponent(); + loader = TestBed.get(NgModuleFactoryLoader); + loader.stubbedModules = {expected: HeroModule}; + router.resetConfig([{path: 'heroes', loadChildren: 'expected'}]); + })); + + it('dummy', () => expect(true).toBe(true) ); + + + it('should navigate to "Heroes" on click', async(() => { + page.heroesLinkDe.nativeElement.click(); + advance(); + expectPathToBe('/heroes'); + expectElementOf(HeroListComponent); + })); + + xit('can navigate to "Heroes" w/ browser location URL change', fakeAsync(() => { + location.go('/heroes'); + advance(); + expectPathToBe('/heroes'); + expectElementOf(HeroListComponent); + + page.expectEvents([ + [r.NavigationStart, '/heroes'], [r.RoutesRecognized, '/heroes'], + [r.NavigationEnd, '/heroes'] + ]); + })); +}); + +////// Helpers ///////// + +/** Wait a tick, then detect changes */ +function advance(): void { + tick(); + fixture.detectChanges(); +} + +function createComponent() { + fixture = TestBed.createComponent(AppComponent); + comp = fixture.componentInstance; + + const injector = fixture.debugElement.injector; + location = injector.get(Location) as SpyLocation; + router = injector.get(Router); + router.initialNavigation(); + spyOn(injector.get(TwainService), 'getQuote') + .and.returnValue(Promise.resolve('Test Quote')); // fakes it + + advance(); + + page = new Page(); +} + +class Page { + aboutLinkDe: DebugElement; + dashboardLinkDe: DebugElement; + heroesLinkDe: DebugElement; + recordedEvents: any[] = []; + + // for debugging + comp: AppComponent; + location: SpyLocation; + router: Router; + fixture: ComponentFixture; + + expectEvents(pairs: any[]) { + const events = this.recordedEvents; + expect(events.length).toEqual(pairs.length, 'actual/expected events length mismatch'); + for (let i = 0; i < events.length; ++i) { + expect((events[i].constructor).name).toBe(pairs[i][0].name, 'unexpected event name'); + expect((events[i]).url).toBe(pairs[i][1], 'unexpected event url'); + } + } + + constructor() { + router.events.subscribe(e => this.recordedEvents.push(e)); + const links = fixture.debugElement.queryAll(By.directive(RouterLinkWithHref)); + this.aboutLinkDe = links[2]; + this.dashboardLinkDe = links[0]; + this.heroesLinkDe = links[1]; + + // for debugging + this.comp = comp; + this.fixture = fixture; + this.router = router; + } +} + +function expectPathToBe(path: string, expectationFailOutput?: any) { + expect(location.path()).toEqual(path, expectationFailOutput || 'location.path()'); +} + +function expectElementOf(type: Type): any { + const el = fixture.debugElement.query(By.directive(type)); + expect(el).toBeTruthy('expected an element for ' + type.name); + return el; +} diff --git a/public/docs/_examples/testing/ts/src/app/app.component.spec.ts b/public/docs/_examples/testing/ts/src/app/app.component.spec.ts new file mode 100644 index 0000000000..20c40767c0 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/app.component.spec.ts @@ -0,0 +1,148 @@ +// #docplaster +import { async, ComponentFixture, TestBed +} from '@angular/core/testing'; + +import { DebugElement } from '@angular/core'; +import { By } from '@angular/platform-browser'; + + // #docregion setup-schemas + import { NO_ERRORS_SCHEMA } from '@angular/core'; + // #enddocregion setup-schemas + // #docregion setup-stubs-w-imports + import { Component } from '@angular/core'; + // #docregion setup-schemas + import { AppComponent } from './app.component'; + // #enddocregion setup-schemas + import { BannerComponent } from './banner.component'; + import { RouterLinkStubDirective } from '../testing'; + // #docregion setup-schemas + import { RouterOutletStubComponent } from '../testing'; + + // #enddocregion setup-schemas + @Component({selector: 'app-welcome', template: ''}) + class WelcomeStubComponent {} + + // #enddocregion setup-stubs-w-imports + +let comp: AppComponent; +let fixture: ComponentFixture; + +describe('AppComponent & TestModule', () => { + // #docregion setup-stubs, setup-stubs-w-imports + beforeEach( async(() => { + TestBed.configureTestingModule({ + declarations: [ + AppComponent, + BannerComponent, WelcomeStubComponent, + RouterLinkStubDirective, RouterOutletStubComponent + ] + }) + + .compileComponents() + .then(() => { + fixture = TestBed.createComponent(AppComponent); + comp = fixture.componentInstance; + }); + })); + // #enddocregion setup-stubs, setup-stubs-w-imports + tests(); +}); + +//////// Testing w/ NO_ERRORS_SCHEMA ////// +describe('AppComponent & NO_ERRORS_SCHEMA', () => { + // #docregion setup-schemas + beforeEach( async(() => { + TestBed.configureTestingModule({ + declarations: [ AppComponent, RouterLinkStubDirective ], + schemas: [ NO_ERRORS_SCHEMA ] + }) + + .compileComponents() + .then(() => { + fixture = TestBed.createComponent(AppComponent); + comp = fixture.componentInstance; + }); + })); + // #enddocregion setup-schemas + tests(); +}); + +//////// Testing w/ real root module ////// +// Tricky because we are disabling the router and its configuration +// Better to use RouterTestingModule +import { AppModule } from './app.module'; +import { AppRoutingModule } from './app-routing.module'; + +describe('AppComponent & AppModule', () => { + + beforeEach( async(() => { + + TestBed.configureTestingModule({ + imports: [ AppModule ] + }) + + // Get rid of app's Router configuration otherwise many failures. + // Doing so removes Router declarations; add the Router stubs + .overrideModule(AppModule, { + remove: { + imports: [ AppRoutingModule ] + }, + add: { + declarations: [ RouterLinkStubDirective, RouterOutletStubComponent ] + } + }) + + .compileComponents() + + .then(() => { + fixture = TestBed.createComponent(AppComponent); + comp = fixture.componentInstance; + }); + })); + + tests(); +}); + +function tests() { + let links: RouterLinkStubDirective[]; + let linkDes: DebugElement[]; + + // #docregion test-setup + beforeEach(() => { + // trigger initial data binding + fixture.detectChanges(); + + // find DebugElements with an attached RouterLinkStubDirective + linkDes = fixture.debugElement + .queryAll(By.directive(RouterLinkStubDirective)); + + // get the attached link directive instances using the DebugElement injectors + links = linkDes + .map(de => de.injector.get(RouterLinkStubDirective) as RouterLinkStubDirective); + }); + // #enddocregion test-setup + + it('can instantiate it', () => { + expect(comp).not.toBeNull(); + }); + + // #docregion tests + it('can get RouterLinks from template', () => { + expect(links.length).toBe(3, 'should have 3 links'); + expect(links[0].linkParams).toBe('/dashboard', '1st link should go to Dashboard'); + expect(links[1].linkParams).toBe('/heroes', '1st link should go to Heroes'); + }); + + it('can click Heroes link in template', () => { + const heroesLinkDe = linkDes[1]; + const heroesLink = links[1]; + + expect(heroesLink.navigatedTo).toBeNull('link should not have navigated yet'); + + heroesLinkDe.triggerEventHandler('click', null); + fixture.detectChanges(); + + expect(heroesLink.navigatedTo).toBe('/heroes'); + }); + // #enddocregion tests +} diff --git a/public/docs/_examples/testing/ts/src/app/app.component.ts b/public/docs/_examples/testing/ts/src/app/app.component.ts new file mode 100644 index 0000000000..5bd535a113 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/app.component.ts @@ -0,0 +1,7 @@ +// #docregion +import { Component } from '@angular/core'; +@Component({ + selector: 'my-app', + templateUrl: './app.component.html' +}) +export class AppComponent { } diff --git a/public/docs/_examples/testing/ts/src/app/app.module.ts b/public/docs/_examples/testing/ts/src/app/app.module.ts new file mode 100644 index 0000000000..d3c288ad11 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/app.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { AppRoutingModule } from './app-routing.module'; + +import { AboutComponent } from './about.component'; +import { BannerComponent } from './banner.component'; +import { HeroService, + UserService } from './model'; +import { TwainService } from './shared/twain.service'; +import { WelcomeComponent } from './welcome.component'; + + +import { DashboardModule } from './dashboard/dashboard.module'; +import { SharedModule } from './shared/shared.module'; + +@NgModule({ + imports: [ + BrowserModule, + DashboardModule, + AppRoutingModule, + SharedModule + ], + providers: [ HeroService, TwainService, UserService ], + declarations: [ AppComponent, AboutComponent, BannerComponent, WelcomeComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/testing/ts/src/app/bag/async-helper.spec.ts b/public/docs/_examples/testing/ts/src/app/bag/async-helper.spec.ts new file mode 100644 index 0000000000..12c8a4fbbd --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/bag/async-helper.spec.ts @@ -0,0 +1,68 @@ +// tslint:disable-next-line:no-unused-variable +import { async, fakeAsync, tick } from '@angular/core/testing'; + +import { Observable } from 'rxjs/Observable'; + +describe('Angular async helper', () => { + let actuallyDone = false; + + beforeEach(() => { actuallyDone = false; }); + + afterEach(() => { expect(actuallyDone).toBe(true, 'actuallyDone should be true'); }); + + it('should run normal test', () => { actuallyDone = true; }); + + it('should run normal async test', (done: DoneFn) => { + setTimeout(() => { + actuallyDone = true; + done(); + }, 0); + }); + + it('should run async test with task', + async(() => { setTimeout(() => { actuallyDone = true; }, 0); })); + + it('should run async test with successful promise', async(() => { + const p = new Promise(resolve => { setTimeout(resolve, 10); }); + p.then(() => { actuallyDone = true; }); + })); + + it('should run async test with failed promise', async(() => { + const p = new Promise((resolve, reject) => { setTimeout(reject, 10); }); + p.catch(() => { actuallyDone = true; }); + })); + + // Use done. Cannot use setInterval with async or fakeAsync + // See https://github.com/angular/angular/issues/10127 + it('should run async test with successful delayed Observable', (done: any) => { + const source = Observable.of(true).delay(10); + source.subscribe( + val => actuallyDone = true, + err => fail(err), + done + ); + }); + + // Cannot use setInterval from within an async zone test + // See https://github.com/angular/angular/issues/10127 + // xit('should run async test with successful delayed Observable', async(() => { + // const source = Observable.of(true).delay(10); + // source.subscribe( + // val => actuallyDone = true, + // err => fail(err) + // ); + // })); + + // // Fail message: Error: 1 periodic timer(s) still in the queue + // // See https://github.com/angular/angular/issues/10127 + // xit('should run async test with successful delayed Observable', fakeAsync(() => { + // const source = Observable.of(true).delay(10); + // source.subscribe( + // val => actuallyDone = true, + // err => fail(err) + // ); + + // tick(); + // })); + +}); diff --git a/public/docs/_examples/testing/ts/app/bag-external-template.html b/public/docs/_examples/testing/ts/src/app/bag/bag-external-template.html similarity index 100% rename from public/docs/_examples/testing/ts/app/bag-external-template.html rename to public/docs/_examples/testing/ts/src/app/bag/bag-external-template.html diff --git a/public/docs/_examples/testing/ts/src/app/bag/bag-main.ts b/public/docs/_examples/testing/ts/src/app/bag/bag-main.ts new file mode 100644 index 0000000000..27b78200ae --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/bag/bag-main.ts @@ -0,0 +1,5 @@ +// main app entry point +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { BagModule } from './bag'; + +platformBrowserDynamic().bootstrapModule(BagModule); diff --git a/public/docs/_examples/testing/ts/src/app/bag/bag.no-testbed.spec.ts b/public/docs/_examples/testing/ts/src/app/bag/bag.no-testbed.spec.ts new file mode 100644 index 0000000000..f29672ecf6 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/bag/bag.no-testbed.spec.ts @@ -0,0 +1,130 @@ +// #docplaster +import { DependentService, FancyService } from './bag'; + +///////// Fakes ///////// +export class FakeFancyService extends FancyService { + value: string = 'faked value'; +} +//////////////////////// +// #docregion FancyService +// Straight Jasmine - no imports from Angular test libraries + +describe('FancyService without the TestBed', () => { + let service: FancyService; + + beforeEach(() => { service = new FancyService(); }); + + it('#getValue should return real value', () => { + expect(service.getValue()).toBe('real value'); + }); + + it('#getAsyncValue should return async value', (done: DoneFn) => { + service.getAsyncValue().then(value => { + expect(value).toBe('async value'); + done(); + }); + }); + + // #docregion getTimeoutValue + it('#getTimeoutValue should return timeout value', (done: DoneFn) => { + service = new FancyService(); + service.getTimeoutValue().then(value => { + expect(value).toBe('timeout value'); + done(); + }); + }); + // #enddocregion getTimeoutValue + + it('#getObservableValue should return observable value', (done: DoneFn) => { + service.getObservableValue().subscribe(value => { + expect(value).toBe('observable value'); + done(); + }); + }); + +}); +// #enddocregion FancyService + +// DependentService requires injection of a FancyService +// #docregion DependentService +describe('DependentService without the TestBed', () => { + let service: DependentService; + + it('#getValue should return real value by way of the real FancyService', () => { + service = new DependentService(new FancyService()); + expect(service.getValue()).toBe('real value'); + }); + + it('#getValue should return faked value by way of a fakeService', () => { + service = new DependentService(new FakeFancyService()); + expect(service.getValue()).toBe('faked value'); + }); + + it('#getValue should return faked value from a fake object', () => { + const fake = { getValue: () => 'fake value' }; + service = new DependentService(fake as FancyService); + expect(service.getValue()).toBe('fake value'); + }); + + it('#getValue should return stubbed value from a FancyService spy', () => { + const fancy = new FancyService(); + const stubValue = 'stub value'; + const spy = spyOn(fancy, 'getValue').and.returnValue(stubValue); + service = new DependentService(fancy); + + expect(service.getValue()).toBe(stubValue, 'service returned stub value'); + expect(spy.calls.count()).toBe(1, 'stubbed method was called once'); + expect(spy.calls.mostRecent().returnValue).toBe(stubValue); + }); +}); +// #enddocregion DependentService + +// #docregion ReversePipe +import { ReversePipe } from './bag'; + +describe('ReversePipe', () => { + let pipe: ReversePipe; + + beforeEach(() => { pipe = new ReversePipe(); }); + + it('transforms "abc" to "cba"', () => { + expect(pipe.transform('abc')).toBe('cba'); + }); + + it('no change to palindrome: "able was I ere I saw elba"', () => { + const palindrome = 'able was I ere I saw elba'; + expect(pipe.transform(palindrome)).toBe(palindrome); + }); + +}); +// #enddocregion ReversePipe + + +import { ButtonComponent } from './bag'; +// #docregion ButtonComp +describe('ButtonComp', () => { + let comp: ButtonComponent; + beforeEach(() => comp = new ButtonComponent()); + + it('#isOn should be false initially', () => { + expect(comp.isOn).toBe(false); + }); + + it('#clicked() should set #isOn to true', () => { + comp.clicked(); + expect(comp.isOn).toBe(true); + }); + + it('#clicked() should set #message to "is on"', () => { + comp.clicked(); + expect(comp.message).toMatch(/is on/i); + }); + + it('#clicked() should toggle #isOn', () => { + comp.clicked(); + expect(comp.isOn).toBe(true); + comp.clicked(); + expect(comp.isOn).toBe(false); + }); +}); +// #enddocregion ButtonComp diff --git a/public/docs/_examples/testing/ts/src/app/bag/bag.spec.ts b/public/docs/_examples/testing/ts/src/app/bag/bag.spec.ts new file mode 100644 index 0000000000..d6fea7ca94 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/bag/bag.spec.ts @@ -0,0 +1,681 @@ +// #docplaster +import { + BagModule, + BankAccountComponent, BankAccountParentComponent, + ButtonComponent, + Child1Component, Child2Component, Child3Component, + FancyService, + ExternalTemplateComponent, + InputComponent, + IoComponent, IoParentComponent, + MyIfComponent, MyIfChildComponent, MyIfParentComponent, + NeedsContentComponent, ParentComponent, + TestProvidersComponent, TestViewProvidersComponent, + ReversePipeComponent, ShellComponent +} from './bag'; + +import { By } from '@angular/platform-browser'; +import { Component, + DebugElement, + Injectable } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +// Forms symbols imported only for a specific test below +import { NgModel, NgControl } from '@angular/forms'; + +import { async, ComponentFixture, fakeAsync, inject, TestBed, tick +} from '@angular/core/testing'; + +import { addMatchers, newEvent, click } from '../../testing'; + +beforeEach( addMatchers ); + +//////// Service Tests ///////////// +// #docregion FancyService +describe('use inject helper in beforeEach', () => { + let service: FancyService; + + beforeEach(() => { + TestBed.configureTestingModule({ providers: [FancyService] }); + + // `TestBed.get` returns the injectable or an + // alternative object (including null) if the service provider is not found. + // Of course it will be found in this case because we're providing it. + // #docregion testbed-get + service = TestBed.get(FancyService, null); + // #enddocregion testbed-get + }); + + it('should use FancyService', () => { + expect(service.getValue()).toBe('real value'); + }); + + it('should use FancyService', () => { + expect(service.getValue()).toBe('real value'); + }); + + it('test should wait for FancyService.getAsyncValue', async(() => { + service.getAsyncValue().then( + value => expect(value).toBe('async value') + ); + })); + + it('test should wait for FancyService.getTimeoutValue', async(() => { + service.getTimeoutValue().then( + value => expect(value).toBe('timeout value') + ); + })); + + it('test should wait for FancyService.getObservableValue', async(() => { + service.getObservableValue().subscribe( + value => expect(value).toBe('observable value') + ); + })); + + // Must use done. See https://github.com/angular/angular/issues/10127 + it('test should wait for FancyService.getObservableDelayValue', (done: DoneFn) => { + service.getObservableDelayValue().subscribe(value => { + expect(value).toBe('observable delay value'); + done(); + }); + }); + + it('should allow the use of fakeAsync', fakeAsync(() => { + let value: any; + service.getAsyncValue().then((val: any) => value = val); + tick(); // Trigger JS engine cycle until all promises resolve. + expect(value).toBe('async value'); + })); +}); +// #enddocregion FancyService + +describe('use inject within `it`', () => { + // #docregion getTimeoutValue + beforeEach(() => { + TestBed.configureTestingModule({ providers: [FancyService] }); + }); + + // #enddocregion getTimeoutValue + + it('should use modified providers', + inject([FancyService], (service: FancyService) => { + service.setValue('value modified in beforeEach'); + expect(service.getValue()).toBe('value modified in beforeEach'); + }) + ); + + // #docregion getTimeoutValue + it('test should wait for FancyService.getTimeoutValue', + async(inject([FancyService], (service: FancyService) => { + + service.getTimeoutValue().then( + value => expect(value).toBe('timeout value') + ); + }))); + // #enddocregion getTimeoutValue +}); + +describe('using async(inject) within beforeEach', () => { + let serviceValue: string; + + beforeEach(() => { + TestBed.configureTestingModule({ providers: [FancyService] }); + }); + + beforeEach( async(inject([FancyService], (service: FancyService) => { + service.getAsyncValue().then(value => serviceValue = value); + }))); + + it('should use asynchronously modified value ... in synchronous test', () => { + expect(serviceValue).toBe('async value'); + }); +}); + + +/////////// Component Tests ////////////////// + +describe('TestBed Component Tests', () => { + + beforeEach( async(() => { + TestBed + .configureTestingModule({ + imports: [BagModule], + }) + // Compile everything in BagModule + .compileComponents(); + })); + + it('should create a component with inline template', () => { + const fixture = TestBed.createComponent(Child1Component); + fixture.detectChanges(); + + expect(fixture).toHaveText('Child'); + }); + + it('should create a component with external template', () => { + const fixture = TestBed.createComponent(ExternalTemplateComponent); + fixture.detectChanges(); + + expect(fixture).toHaveText('from external template'); + }); + + it('should allow changing members of the component', () => { + const fixture = TestBed.createComponent(MyIfComponent); + + fixture.detectChanges(); + expect(fixture).toHaveText('MyIf()'); + + fixture.componentInstance.showMore = true; + fixture.detectChanges(); + expect(fixture).toHaveText('MyIf(More)'); + }); + + it('should create a nested component bound to inputs/outputs', () => { + const fixture = TestBed.createComponent(IoParentComponent); + + fixture.detectChanges(); + const heroes = fixture.debugElement.queryAll(By.css('.hero')); + expect(heroes.length).toBeGreaterThan(0, 'has heroes'); + + const comp = fixture.componentInstance; + const hero = comp.heroes[0]; + + click(heroes[0]); + fixture.detectChanges(); + + const selected = fixture.debugElement.query(By.css('p')); + expect(selected).toHaveText(hero.name); + }); + + it('can access the instance variable of an `*ngFor` row component', () => { + const fixture = TestBed.createComponent(IoParentComponent); + const comp = fixture.componentInstance; + const heroName = comp.heroes[0].name; // first hero's name + + fixture.detectChanges(); + const ngForRow = fixture.debugElement.query(By.directive(IoComponent)); // first hero ngForRow + + const hero = ngForRow.context['hero']; // the hero object passed into the row + expect(hero.name).toBe(heroName, 'ngRow.context.hero'); + + const rowComp = ngForRow.componentInstance; + // jasmine.any is an "instance-of-type" test. + expect(rowComp).toEqual(jasmine.any(IoComponent), 'component is IoComp'); + expect(rowComp.hero.name).toBe(heroName, 'component.hero'); + }); + + + // #docregion ButtonComp + it('should support clicking a button', () => { + const fixture = TestBed.createComponent(ButtonComponent); + const btn = fixture.debugElement.query(By.css('button')); + const span = fixture.debugElement.query(By.css('span')).nativeElement; + + fixture.detectChanges(); + expect(span.textContent).toMatch(/is off/i, 'before click'); + + click(btn); + fixture.detectChanges(); + expect(span.textContent).toMatch(/is on/i, 'after click'); + }); + // #enddocregion ButtonComp + + // ngModel is async so we must wait for it with promise-based `whenStable` + it('should support entering text in input box (ngModel)', async(() => { + const expectedOrigName = 'John'; + const expectedNewName = 'Sally'; + + const fixture = TestBed.createComponent(InputComponent); + fixture.detectChanges(); + + const comp = fixture.componentInstance; + const input = fixture.debugElement.query(By.css('input')).nativeElement; + + expect(comp.name).toBe(expectedOrigName, + `At start name should be ${expectedOrigName} `); + + // wait until ngModel binds comp.name to input box + fixture.whenStable().then(() => { + expect(input.value).toBe(expectedOrigName, + `After ngModel updates input box, input.value should be ${expectedOrigName} `); + + // simulate user entering new name in input + input.value = expectedNewName; + + // that change doesn't flow to the component immediately + expect(comp.name).toBe(expectedOrigName, + `comp.name should still be ${expectedOrigName} after value change, before binding happens`); + + // dispatch a DOM event so that Angular learns of input value change. + // then wait while ngModel pushes input.box value to comp.name + input.dispatchEvent(newEvent('input')); + return fixture.whenStable(); + }) + .then(() => { + expect(comp.name).toBe(expectedNewName, + `After ngModel updates the model, comp.name should be ${expectedNewName} `); + }); + })); + + // fakeAsync version of ngModel input test enables sync test style + // synchronous `tick` replaces asynchronous promise-base `whenStable` + it('should support entering text in input box (ngModel) - fakeAsync', fakeAsync(() => { + const expectedOrigName = 'John'; + const expectedNewName = 'Sally'; + + const fixture = TestBed.createComponent(InputComponent); + fixture.detectChanges(); + + const comp = fixture.componentInstance; + const input = fixture.debugElement.query(By.css('input')).nativeElement; + + expect(comp.name).toBe(expectedOrigName, + `At start name should be ${expectedOrigName} `); + + // wait until ngModel binds comp.name to input box + tick(); + expect(input.value).toBe(expectedOrigName, + `After ngModel updates input box, input.value should be ${expectedOrigName} `); + + // simulate user entering new name in input + input.value = expectedNewName; + + // that change doesn't flow to the component immediately + expect(comp.name).toBe(expectedOrigName, + `comp.name should still be ${expectedOrigName} after value change, before binding happens`); + + // dispatch a DOM event so that Angular learns of input value change. + // then wait a tick while ngModel pushes input.box value to comp.name + input.dispatchEvent(newEvent('input')); + tick(); + expect(comp.name).toBe(expectedNewName, + `After ngModel updates the model, comp.name should be ${expectedNewName} `); + })); + + // #docregion ReversePipeComp + it('ReversePipeComp should reverse the input text', fakeAsync(() => { + const inputText = 'the quick brown fox.'; + const expectedText = '.xof nworb kciuq eht'; + + const fixture = TestBed.createComponent(ReversePipeComponent); + fixture.detectChanges(); + + const comp = fixture.componentInstance; + const input = fixture.debugElement.query(By.css('input')).nativeElement as HTMLInputElement; + const span = fixture.debugElement.query(By.css('span')).nativeElement as HTMLElement; + + // simulate user entering new name in input + input.value = inputText; + + // dispatch a DOM event so that Angular learns of input value change. + // then wait a tick while ngModel pushes input.box value to comp.text + // and Angular updates the output span + input.dispatchEvent(newEvent('input')); + tick(); + fixture.detectChanges(); + expect(span.textContent).toBe(expectedText, 'output span'); + expect(comp.text).toBe(inputText, 'component.text'); + })); + // #enddocregion ReversePipeComp + + // Use this technique to find attached directives of any kind + it('can examine attached directives and listeners', () => { + const fixture = TestBed.createComponent(InputComponent); + fixture.detectChanges(); + + const inputEl = fixture.debugElement.query(By.css('input')); + + expect(inputEl.providerTokens).toContain(NgModel, 'NgModel directive'); + + const ngControl = inputEl.injector.get(NgControl); + expect(ngControl).toEqual(jasmine.any(NgControl), 'NgControl directive'); + + expect(inputEl.listeners.length).toBeGreaterThan(2, 'several listeners attached'); + }); + + // #docregion dom-attributes + it('BankAccountComponent should set attributes, styles, classes, and properties', () => { + const fixture = TestBed.createComponent(BankAccountParentComponent); + fixture.detectChanges(); + const comp = fixture.componentInstance; + + // the only child is debugElement of the BankAccount component + const el = fixture.debugElement.children[0]; + const childComp = el.componentInstance as BankAccountComponent; + expect(childComp).toEqual(jasmine.any(BankAccountComponent)); + + expect(el.context).toBe(childComp, 'context is the child component'); + + expect(el.attributes['account']).toBe(childComp.id, 'account attribute'); + expect(el.attributes['bank']).toBe(childComp.bank, 'bank attribute'); + + expect(el.classes['closed']).toBe(true, 'closed class'); + expect(el.classes['open']).toBe(false, 'open class'); + + expect(el.styles['color']).toBe(comp.color, 'color style'); + expect(el.styles['width']).toBe(comp.width + 'px', 'width style'); + // #enddocregion dom-attributes + + // Removed on 12/02/2016 when ceased public discussion of the `Renderer`. Revive in future? + // expect(el.properties['customProperty']).toBe(true, 'customProperty'); + + // #docregion dom-attributes + }); + // #enddocregion dom-attributes + + +}); + +describe('TestBed Component Overrides:', () => { + + it('should override ChildComp\'s template', () => { + + const fixture = TestBed.configureTestingModule({ + declarations: [Child1Component], + }) + .overrideComponent(Child1Component, { + set: { template: 'Fake' } + }) + .createComponent(Child1Component); + + fixture.detectChanges(); + expect(fixture).toHaveText('Fake'); + }); + + it('should override TestProvidersComp\'s FancyService provider', () => { + const fixture = TestBed.configureTestingModule({ + declarations: [TestProvidersComponent], + }) + .overrideComponent(TestProvidersComponent, { + remove: { providers: [FancyService]}, + add: { providers: [{ provide: FancyService, useClass: FakeFancyService }] }, + + // Or replace them all (this component has only one provider) + // set: { providers: [{ provide: FancyService, useClass: FakeFancyService }] }, + }) + .createComponent(TestProvidersComponent); + + fixture.detectChanges(); + expect(fixture).toHaveText('injected value: faked value', 'text'); + + // Explore the providerTokens + const tokens = fixture.debugElement.providerTokens; + expect(tokens).toContain(fixture.componentInstance.constructor, 'component ctor'); + expect(tokens).toContain(TestProvidersComponent, 'TestProvidersComp'); + expect(tokens).toContain(FancyService, 'FancyService'); + }); + + it('should override TestViewProvidersComp\'s FancyService viewProvider', () => { + const fixture = TestBed.configureTestingModule({ + declarations: [TestViewProvidersComponent], + }) + .overrideComponent(TestViewProvidersComponent, { + // remove: { viewProviders: [FancyService]}, + // add: { viewProviders: [{ provide: FancyService, useClass: FakeFancyService }] }, + + // Or replace them all (this component has only one viewProvider) + set: { viewProviders: [{ provide: FancyService, useClass: FakeFancyService }] }, + }) + .createComponent(TestViewProvidersComponent); + + fixture.detectChanges(); + expect(fixture).toHaveText('injected value: faked value'); + }); + + it('injected provider should not be same as component\'s provider', () => { + + // TestComponent is parent of TestProvidersComponent + @Component({ template: '' }) + class TestComponent {} + + // 3 levels of FancyService provider: module, TestCompomponent, TestProvidersComponent + const fixture = TestBed.configureTestingModule({ + declarations: [TestComponent, TestProvidersComponent], + providers: [FancyService] + }) + .overrideComponent(TestComponent, { + set: { providers: [{ provide: FancyService, useValue: {} }] } + }) + .overrideComponent(TestProvidersComponent, { + set: { providers: [{ provide: FancyService, useClass: FakeFancyService }] } + }) + .createComponent(TestComponent); + + let testBedProvider: FancyService; + let tcProvider: {}; + let tpcProvider: FakeFancyService; + + // `inject` uses TestBed's injector + inject([FancyService], (s: FancyService) => testBedProvider = s)(); + tcProvider = fixture.debugElement.injector.get(FancyService); + tpcProvider = fixture.debugElement.children[0].injector.get(FancyService) as FakeFancyService; + + expect(testBedProvider).not.toBe(tcProvider, 'testBed/tc not same providers'); + expect(testBedProvider).not.toBe(tpcProvider, 'testBed/tpc not same providers'); + + expect(testBedProvider instanceof FancyService).toBe(true, 'testBedProvider is FancyService'); + expect(tcProvider).toEqual({}, 'tcProvider is {}'); + expect(tpcProvider instanceof FakeFancyService).toBe(true, 'tpcProvider is FakeFancyService'); + }); + + it('can access template local variables as references', () => { + const fixture = TestBed.configureTestingModule({ + declarations: [ShellComponent, NeedsContentComponent, Child1Component, Child2Component, Child3Component], + }) + .overrideComponent(ShellComponent, { + set: { + selector: 'test-shell', + template: ` + + + + + +
    !
    +
    + ` + } + }) + .createComponent(ShellComponent); + + fixture.detectChanges(); + + // NeedsContentComp is the child of ShellComp + const el = fixture.debugElement.children[0]; + const comp = el.componentInstance; + + expect(comp.children.toArray().length).toBe(4, + 'three different child components and an ElementRef with #content'); + + expect(el.references['nc']).toBe(comp, '#nc reference to component'); + + // #docregion custom-predicate + // Filter for DebugElements with a #content reference + const contentRefs = el.queryAll( de => de.references['content']); + // #enddocregion custom-predicate + expect(contentRefs.length).toBe(4, 'elements w/ a #content reference'); + }); + +}); + +describe('Nested (one-deep) component override', () => { + + beforeEach( async(() => { + TestBed.configureTestingModule({ + declarations: [ParentComponent, FakeChildComponent] + }) + .compileComponents(); + })); + + it('ParentComp should use Fake Child component', () => { + const fixture = TestBed.createComponent(ParentComponent); + fixture.detectChanges(); + expect(fixture).toHaveText('Parent(Fake Child)'); + }); +}); + +describe('Nested (two-deep) component override', () => { + + beforeEach( async(() => { + TestBed.configureTestingModule({ + declarations: [ParentComponent, FakeChildWithGrandchildComponent, FakeGrandchildComponent] + }) + .compileComponents(); + })); + + it('should use Fake Grandchild component', () => { + const fixture = TestBed.createComponent(ParentComponent); + fixture.detectChanges(); + expect(fixture).toHaveText('Parent(Fake Child(Fake Grandchild))'); + }); +}); + +describe('Lifecycle hooks w/ MyIfParentComp', () => { + let fixture: ComponentFixture; + let parent: MyIfParentComponent; + let child: MyIfChildComponent; + + beforeEach( async(() => { + TestBed.configureTestingModule({ + imports: [FormsModule], + declarations: [MyIfChildComponent, MyIfParentComponent] + }) + .compileComponents().then(() => { + fixture = TestBed.createComponent(MyIfParentComponent); + parent = fixture.componentInstance; + }); + })); + + it('should instantiate parent component', () => { + expect(parent).not.toBeNull('parent component should exist'); + }); + + it('parent component OnInit should NOT be called before first detectChanges()', () => { + expect(parent.ngOnInitCalled).toBe(false); + }); + + it('parent component OnInit should be called after first detectChanges()', () => { + fixture.detectChanges(); + expect(parent.ngOnInitCalled).toBe(true); + }); + + it('child component should exist after OnInit', () => { + fixture.detectChanges(); + getChild(); + expect(child instanceof MyIfChildComponent).toBe(true, 'should create child'); + }); + + it('should have called child component\'s OnInit ', () => { + fixture.detectChanges(); + getChild(); + expect(child.ngOnInitCalled).toBe(true); + }); + + it('child component called OnChanges once', () => { + fixture.detectChanges(); + getChild(); + expect(child.ngOnChangesCounter).toBe(1); + }); + + it('changed parent value flows to child', () => { + fixture.detectChanges(); + getChild(); + + parent.parentValue = 'foo'; + fixture.detectChanges(); + + expect(child.ngOnChangesCounter).toBe(2, + 'expected 2 changes: initial value and changed value'); + expect(child.childValue).toBe('foo', + 'childValue should eq changed parent value'); + }); + + // must be async test to see child flow to parent + it('changed child value flows to parent', async(() => { + fixture.detectChanges(); + getChild(); + + child.childValue = 'bar'; + + return new Promise(resolve => { + // Wait one JS engine turn! + setTimeout(() => resolve(), 0); + }) + .then(() => { + fixture.detectChanges(); + + expect(child.ngOnChangesCounter).toBe(2, + 'expected 2 changes: initial value and changed value'); + expect(parent.parentValue).toBe('bar', + 'parentValue should eq changed parent value'); + }); + + })); + + it('clicking "Close Child" triggers child OnDestroy', () => { + fixture.detectChanges(); + getChild(); + + const btn = fixture.debugElement.query(By.css('button')); + click(btn); + + fixture.detectChanges(); + expect(child.ngOnDestroyCalled).toBe(true); + }); + + ////// helpers /// + /** + * Get the MyIfChildComp from parent; fail w/ good message if cannot. + */ + function getChild() { + + let childDe: DebugElement; // DebugElement that should hold the MyIfChildComp + + // The Hard Way: requires detailed knowledge of the parent template + try { + childDe = fixture.debugElement.children[4].children[0]; + } catch (err) { /* we'll report the error */ } + + // DebugElement.queryAll: if we wanted all of many instances: + childDe = fixture.debugElement + .queryAll(function (de) { return de.componentInstance instanceof MyIfChildComponent; })[0]; + + // WE'LL USE THIS APPROACH ! + // DebugElement.query: find first instance (if any) + childDe = fixture.debugElement + .query(function (de) { return de.componentInstance instanceof MyIfChildComponent; }); + + if (childDe && childDe.componentInstance) { + child = childDe.componentInstance; + } else { + fail('Unable to find MyIfChildComp within MyIfParentComp'); + } + + return child; + } +}); + +////////// Fakes /////////// + +@Component({ + selector: 'child-1', + template: `Fake Child` +}) +class FakeChildComponent { } + +@Component({ + selector: 'child-1', + template: `Fake Child()` +}) +class FakeChildWithGrandchildComponent { } + +@Component({ + selector: 'grandchild-1', + template: `Fake Grandchild` +}) +class FakeGrandchildComponent { } + +@Injectable() +class FakeFancyService extends FancyService { + value: string = 'faked value'; +} diff --git a/public/docs/_examples/testing/ts/src/app/bag/bag.ts b/public/docs/_examples/testing/ts/src/app/bag/bag.ts new file mode 100644 index 0000000000..cbf1c21136 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/bag/bag.ts @@ -0,0 +1,454 @@ +/* tslint:disable:forin */ +import { Component, ContentChildren, Directive, EventEmitter, + Injectable, Input, Output, Optional, + HostBinding, HostListener, + OnInit, OnChanges, OnDestroy, + Pipe, PipeTransform, + SimpleChange } from '@angular/core'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/delay'; + +////////// The App: Services and Components for the tests. ////////////// + +export class Hero { + name: string; +} + +////////// Services /////////////// +// #docregion FancyService +@Injectable() +export class FancyService { + protected value: string = 'real value'; + + getValue() { return this.value; } + setValue(value: string) { this.value = value; } + + getAsyncValue() { return Promise.resolve('async value'); } + + getObservableValue() { return Observable.of('observable value'); } + + getTimeoutValue() { + return new Promise((resolve) => { + setTimeout(() => { resolve('timeout value'); }, 10); + }); + } + + getObservableDelayValue() { + return Observable.of('observable delay value').delay(10); + } +} +// #enddocregion FancyService + +// #docregion DependentService +@Injectable() +export class DependentService { + constructor(private dependentService: FancyService) { } + getValue() { return this.dependentService.getValue(); } +} +// #enddocregion DependentService + +/////////// Pipe //////////////// +/* + * Reverse the input string. +*/ +// #docregion ReversePipe +@Pipe({ name: 'reverse' }) +export class ReversePipe implements PipeTransform { + transform(s: string) { + let r = ''; + for (let i = s.length; i; ) { r += s[--i]; }; + return r; + } +} +// #enddocregion ReversePipe + +//////////// Components ///////////// +@Component({ + selector: 'bank-account', + template: ` + Bank Name: {{bank}} + Account Id: {{id}} + ` +}) +export class BankAccountComponent { + @Input() bank: string; + @Input('account') id: string; + + // Removed on 12/02/2016 when ceased public discussion of the `Renderer`. Revive in future? + // constructor(private renderer: Renderer, private el: ElementRef ) { + // renderer.setElementProperty(el.nativeElement, 'customProperty', true); + // } +} + +/** A component with attributes, styles, classes, and property setting */ +@Component({ + selector: 'bank-account-parent', + template: ` + + + ` +}) +export class BankAccountParentComponent { + width = 200; + color = 'red'; + isClosed = true; +} + +// #docregion ButtonComp +@Component({ + selector: 'button-comp', + template: ` + + {{message}}` +}) +export class ButtonComponent { + isOn = false; + clicked() { this.isOn = !this.isOn; } + get message() { return `The light is ${this.isOn ? 'On' : 'Off'}`; } +} +// #enddocregion ButtonComp + +@Component({ + selector: 'child-1', + template: `Child-1({{text}})` +}) +export class Child1Component { + @Input() text = 'Original'; +} + +@Component({ + selector: 'child-2', + template: '
    Child-2({{text}})
    ' +}) +export class Child2Component { + @Input() text: string; +} + +@Component({ + selector: 'child-3', + template: '
    Child-3({{text}})
    ' +}) +export class Child3Component { + @Input() text: string; +} + +@Component({ + selector: 'input-comp', + template: `` +}) +export class InputComponent { + name = 'John'; +} + +/* Prefer this metadata syntax */ +// @Directive({ +// selector: 'input[value]', +// host: { +// '[value]': 'value', +// '(input)': 'valueChange.emit($event.target.value)' +// }, +// inputs: ['value'], +// outputs: ['valueChange'] +// }) +// export class InputValueBinderDirective { +// value: any; +// valueChange: EventEmitter = new EventEmitter(); +// } + +// As the style-guide recommends +@Directive({ selector: 'input[value]' }) +export class InputValueBinderDirective { + @HostBinding() + @Input() + value: any; + + @Output() + valueChange: EventEmitter = new EventEmitter(); + + @HostListener('input', ['$event.target.value']) + onInput(value: any) { this.valueChange.emit(value); } +} + +@Component({ + selector: 'input-value-comp', + template: ` + Name: {{name}} + ` +}) +export class InputValueBinderComponent { + name = 'Sally'; // initial value +} + +@Component({ + selector: 'parent-comp', + template: `Parent()` +}) +export class ParentComponent { } + +@Component({ + selector: 'io-comp', + template: `
    Original {{hero.name}}
    ` +}) +export class IoComponent { + @Input() hero: Hero; + @Output() selected = new EventEmitter(); + click() { this.selected.emit(this.hero); } +} + +@Component({ + selector: 'io-parent-comp', + template: ` +

    Click to select a hero

    +

    The selected hero is {{selectedHero.name}}

    + + + ` +}) +export class IoParentComponent { + heroes: Hero[] = [ {name: 'Bob'}, {name: 'Carol'}, {name: 'Ted'}, {name: 'Alice'} ]; + selectedHero: Hero; + onSelect(hero: Hero) { this.selectedHero = hero; } +} + +@Component({ + selector: 'my-if-comp', + template: `MyIf(More)` +}) +export class MyIfComponent { + showMore = false; +} + +@Component({ + selector: 'my-service-comp', + template: `injected value: {{fancyService.value}}`, + providers: [FancyService] +}) +export class TestProvidersComponent { + constructor(private fancyService: FancyService) {} +} + + +@Component({ + selector: 'my-service-comp', + template: `injected value: {{fancyService.value}}`, + viewProviders: [FancyService] +}) +export class TestViewProvidersComponent { + constructor(private fancyService: FancyService) {} +} + +@Component({ + selector: 'external-template-comp', + templateUrl: './bag-external-template.html' +}) +export class ExternalTemplateComponent implements OnInit { + serviceValue: string; + + constructor(@Optional() private service: FancyService) { } + + ngOnInit() { + if (this.service) { this.serviceValue = this.service.getValue(); } + } +} + +@Component({ + selector: 'comp-w-ext-comp', + template: ` +

    comp-w-ext-comp

    + + ` +}) +export class InnerCompWithExternalTemplateComponent { } + +@Component({ + selector: 'bad-template-comp', + templateUrl: './non-existant.html' +}) +export class BadTemplateUrlComponent { } + + + +@Component({selector: 'needs-content', template: ''}) +export class NeedsContentComponent { + // children with #content local variable + @ContentChildren('content') children: any; +} + +///////// MyIfChildComp //////// +@Component({ + selector: 'my-if-child-1', + + template: ` +

    MyIfChildComp

    +
    + +
    +

    Change log:

    +
    {{i + 1}} - {{log}}
    ` +}) +export class MyIfChildComponent implements OnInit, OnChanges, OnDestroy { + @Input() value = ''; + @Output() valueChange = new EventEmitter(); + + get childValue() { return this.value; } + set childValue(v: string) { + if (this.value === v) { return; } + this.value = v; + this.valueChange.emit(v); + } + + changeLog: string[] = []; + + ngOnInitCalled = false; + ngOnChangesCounter = 0; + ngOnDestroyCalled = false; + + ngOnInit() { + this.ngOnInitCalled = true; + this.changeLog.push('ngOnInit called'); + } + + ngOnDestroy() { + this.ngOnDestroyCalled = true; + this.changeLog.push('ngOnDestroy called'); + } + + ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { + for (let propName in changes) { + this.ngOnChangesCounter += 1; + let prop = changes[propName]; + let cur = JSON.stringify(prop.currentValue); + let prev = JSON.stringify(prop.previousValue); + this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`); + } + } +} + +///////// MyIfParentComp //////// + +@Component({ + selector: 'my-if-parent-comp', + template: ` +

    MyIfParentComp

    + +
    +
    + +
    + ` +}) +export class MyIfParentComponent implements OnInit { + ngOnInitCalled = false; + parentValue = 'Hello, World'; + showChild = false; + toggleLabel = 'Unknown'; + + ngOnInit() { + this.ngOnInitCalled = true; + this.clicked(); + } + + clicked() { + this.showChild = !this.showChild; + this.toggleLabel = this.showChild ? 'Close' : 'Show'; + } +} + + +@Component({ + selector: 'reverse-pipe-comp', + template: ` + + {{text | reverse}} + ` +}) +export class ReversePipeComponent { + text = 'my dog has fleas.'; +} + +@Component({template: '
    Replace Me
    '}) +export class ShellComponent { } + +@Component({ + selector: 'bag-comp', + template: ` +

    Specs Bag

    + +
    +

    Input/Output Component

    + +
    +

    External Template Component

    + +
    +

    Component With External Template Component

    + +
    +

    Reverse Pipe

    + +
    +

    InputValueBinder Directive

    + +
    +

    Button Component

    + +
    +

    Needs Content

    + + + + + +
    !
    +
    + ` +}) +export class BagComponent { } +//////// Aggregations //////////// + +export const bagDeclarations = [ + BagComponent, + BankAccountComponent, BankAccountParentComponent, + ButtonComponent, + Child1Component, Child2Component, Child3Component, + ExternalTemplateComponent, InnerCompWithExternalTemplateComponent, + InputComponent, + InputValueBinderDirective, InputValueBinderComponent, + IoComponent, IoParentComponent, + MyIfComponent, MyIfChildComponent, MyIfParentComponent, + NeedsContentComponent, ParentComponent, + TestProvidersComponent, TestViewProvidersComponent, + ReversePipe, ReversePipeComponent, ShellComponent +]; + +export const bagProviders = [DependentService, FancyService]; + +//////////////////// +//////////// +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +@NgModule({ + imports: [BrowserModule, FormsModule], + declarations: bagDeclarations, + providers: bagProviders, + entryComponents: [BagComponent], + bootstrap: [BagComponent] +}) +export class BagModule { } + diff --git a/public/docs/_examples/testing/ts/src/app/banner-inline.component.spec.ts b/public/docs/_examples/testing/ts/src/app/banner-inline.component.spec.ts new file mode 100644 index 0000000000..7f35d6b956 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/banner-inline.component.spec.ts @@ -0,0 +1,55 @@ +// #docplaster +// #docregion imports +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { BannerComponent } from './banner-inline.component'; +// #enddocregion imports + +// #docregion setup +describe('BannerComponent (inline template)', () => { + + let comp: BannerComponent; + let fixture: ComponentFixture; + let de: DebugElement; + let el: HTMLElement; + +// #docregion before-each + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ BannerComponent ], // declare the test component + }); + + fixture = TestBed.createComponent(BannerComponent); + + comp = fixture.componentInstance; // BannerComponent test instance + + // query for the title

    by CSS element selector + de = fixture.debugElement.query(By.css('h1')); + el = de.nativeElement; + }); +// #enddocregion before-each +// #enddocregion setup + + // #docregion test-w-o-detect-changes + it('no title in the DOM until manually call `detectChanges`', () => { + expect(el.textContent).toEqual(''); + }); + // #enddocregion test-w-o-detect-changes + + // #docregion tests + it('should display original title', () => { + fixture.detectChanges(); + expect(el.textContent).toContain(comp.title); + }); + + it('should display a different test title', () => { + comp.title = 'Test Title'; + fixture.detectChanges(); + expect(el.textContent).toContain('Test Title'); + }); + // #enddocregion tests +// #docregion setup +}); +// #enddocregion setup diff --git a/public/docs/_examples/testing/ts/src/app/banner-inline.component.ts b/public/docs/_examples/testing/ts/src/app/banner-inline.component.ts new file mode 100644 index 0000000000..7ec4ef6999 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/banner-inline.component.ts @@ -0,0 +1,11 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-banner', + template: '

    {{title}}

    ' +}) +export class BannerComponent { + title = 'Test Tour of Heroes'; +} + diff --git a/public/docs/_examples/testing/ts/src/app/banner.component.css b/public/docs/_examples/testing/ts/src/app/banner.component.css new file mode 100644 index 0000000000..cd09a55b3c --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/banner.component.css @@ -0,0 +1 @@ +h1 { color: green; font-size: 350%} diff --git a/public/docs/_examples/testing/ts/src/app/banner.component.detect-changes.spec.ts b/public/docs/_examples/testing/ts/src/app/banner.component.detect-changes.spec.ts new file mode 100644 index 0000000000..412f5be586 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/banner.component.detect-changes.spec.ts @@ -0,0 +1,59 @@ +// #docplaster +// #docregion +// #docregion import-async +import { async } from '@angular/core/testing'; +// #enddocregion import-async +// #docregion import-ComponentFixtureAutoDetect +import { ComponentFixtureAutoDetect } from '@angular/core/testing'; +// #enddocregion import-ComponentFixtureAutoDetect +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { BannerComponent } from './banner.component'; + +describe('BannerComponent (AutoChangeDetect)', () => { + let comp: BannerComponent; + let fixture: ComponentFixture; + let de: DebugElement; + let el: HTMLElement; + + beforeEach(async(() => { + // #docregion auto-detect + TestBed.configureTestingModule({ + declarations: [ BannerComponent ], + providers: [ + { provide: ComponentFixtureAutoDetect, useValue: true } + ] + }) + // #enddocregion auto-detect + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BannerComponent); + comp = fixture.componentInstance; + de = fixture.debugElement.query(By.css('h1')); + el = de.nativeElement; + }); + + // #docregion auto-detect-tests + it('should display original title', () => { + // Hooray! No `fixture.detectChanges()` needed + expect(el.textContent).toContain(comp.title); + }); + + it('should still see original title after comp.title change', () => { + const oldTitle = comp.title; + comp.title = 'Test Title'; + // Displayed title is old because Angular didn't hear the change :( + expect(el.textContent).toContain(oldTitle); + }); + + it('should display updated title after detectChanges', () => { + comp.title = 'Test Title'; + fixture.detectChanges(); // detect changes explicitly + expect(el.textContent).toContain(comp.title); + }); + // #enddocregion auto-detect-tests +}); diff --git a/public/docs/_examples/testing/ts/src/app/banner.component.html b/public/docs/_examples/testing/ts/src/app/banner.component.html new file mode 100644 index 0000000000..6213adcb47 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/banner.component.html @@ -0,0 +1 @@ +

    {{title}}

    diff --git a/public/docs/_examples/testing/ts/src/app/banner.component.spec.ts b/public/docs/_examples/testing/ts/src/app/banner.component.spec.ts new file mode 100644 index 0000000000..a564c45c85 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/banner.component.spec.ts @@ -0,0 +1,53 @@ +// #docplaster +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { BannerComponent } from './banner.component'; + +describe('BannerComponent (templateUrl)', () => { + + let comp: BannerComponent; + let fixture: ComponentFixture; + let de: DebugElement; + let el: HTMLElement; + + // #docregion async-before-each + // async beforeEach + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ BannerComponent ], // declare the test component + }) + .compileComponents(); // compile template and css + })); + // #enddocregion async-before-each + + // #docregion sync-before-each + // synchronous beforeEach + beforeEach(() => { + fixture = TestBed.createComponent(BannerComponent); + + comp = fixture.componentInstance; // BannerComponent test instance + + // query for the title

    by CSS element selector + de = fixture.debugElement.query(By.css('h1')); + el = de.nativeElement; + }); + // #enddocregion sync-before-each + + it('no title in the DOM until manually call `detectChanges`', () => { + expect(el.textContent).toEqual(''); + }); + + it('should display original title', () => { + fixture.detectChanges(); + expect(el.textContent).toContain(comp.title); + }); + + it('should display a different test title', () => { + comp.title = 'Test Title'; + fixture.detectChanges(); + expect(el.textContent).toContain('Test Title'); + }); + +}); diff --git a/public/docs/_examples/testing/ts/src/app/banner.component.ts b/public/docs/_examples/testing/ts/src/app/banner.component.ts new file mode 100644 index 0000000000..4355a40867 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/banner.component.ts @@ -0,0 +1,12 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-banner', + templateUrl: './banner.component.html', + styleUrls: ['./banner.component.css'] +}) +export class BannerComponent { + title = 'Test Tour of Heroes'; +} + diff --git a/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.css b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.css new file mode 100644 index 0000000000..eb54d181d8 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.css @@ -0,0 +1,28 @@ +.hero { + padding: 20px; + position: relative; + text-align: center; + color: #eee; + max-height: 120px; + min-width: 120px; + background-color: #607D8B; + border-radius: 2px; +} + +.hero:hover { + background-color: #EEE; + cursor: pointer; + color: #607d8b; +} + +@media (max-width: 600px) { + .hero { + font-size: 10px; + max-height: 75px; } +} + +@media (max-width: 1024px) { + .hero { + min-width: 60px; + } +} diff --git a/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.html b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.html new file mode 100644 index 0000000000..ff49bd17a5 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.html @@ -0,0 +1,4 @@ + +
    + {{hero.name | uppercase}} +
    diff --git a/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.spec.ts b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.spec.ts new file mode 100644 index 0000000000..40c01571e6 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.spec.ts @@ -0,0 +1,124 @@ +import { async, ComponentFixture, TestBed +} from '@angular/core/testing'; + +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { addMatchers, click } from '../../testing'; + +import { Hero } from '../model/hero'; +import { DashboardHeroComponent } from './dashboard-hero.component'; + +beforeEach( addMatchers ); + +describe('DashboardHeroComponent when tested directly', () => { + + let comp: DashboardHeroComponent; + let expectedHero: Hero; + let fixture: ComponentFixture; + let heroEl: DebugElement; + + // #docregion setup, compile-components + // async beforeEach + beforeEach( async(() => { + TestBed.configureTestingModule({ + declarations: [ DashboardHeroComponent ], + }) + .compileComponents(); // compile template and css + })); + // #enddocregion compile-components + + // synchronous beforeEach + beforeEach(() => { + fixture = TestBed.createComponent(DashboardHeroComponent); + comp = fixture.componentInstance; + heroEl = fixture.debugElement.query(By.css('.hero')); // find hero element + + // pretend that it was wired to something that supplied a hero + expectedHero = new Hero(42, 'Test Name'); + comp.hero = expectedHero; + fixture.detectChanges(); // trigger initial data binding + }); + // #enddocregion setup + + // #docregion name-test + it('should display hero name', () => { + const expectedPipedName = expectedHero.name.toUpperCase(); + expect(heroEl.nativeElement.textContent).toContain(expectedPipedName); + }); + // #enddocregion name-test + + // #docregion click-test + it('should raise selected event when clicked', () => { + let selectedHero: Hero; + comp.selected.subscribe((hero: Hero) => selectedHero = hero); + + // #docregion trigger-event-handler + heroEl.triggerEventHandler('click', null); + // #enddocregion trigger-event-handler + expect(selectedHero).toBe(expectedHero); + }); + // #enddocregion click-test + + // #docregion click-test-2 + it('should raise selected event when clicked', () => { + let selectedHero: Hero; + comp.selected.subscribe((hero: Hero) => selectedHero = hero); + + click(heroEl); // triggerEventHandler helper + expect(selectedHero).toBe(expectedHero); + }); + // #enddocregion click-test-2 +}); + +////////////////// + +describe('DashboardHeroComponent when inside a test host', () => { + let testHost: TestHostComponent; + let fixture: ComponentFixture; + let heroEl: DebugElement; + + // #docregion test-host-setup + beforeEach( async(() => { + TestBed.configureTestingModule({ + declarations: [ DashboardHeroComponent, TestHostComponent ], // declare both + }).compileComponents(); + })); + + beforeEach(() => { + // create TestHostComponent instead of DashboardHeroComponent + fixture = TestBed.createComponent(TestHostComponent); + testHost = fixture.componentInstance; + heroEl = fixture.debugElement.query(By.css('.hero')); // find hero + fixture.detectChanges(); // trigger initial data binding + }); + // #enddocregion test-host-setup + + // #docregion test-host-tests + it('should display hero name', () => { + const expectedPipedName = testHost.hero.name.toUpperCase(); + expect(heroEl.nativeElement.textContent).toContain(expectedPipedName); + }); + + it('should raise selected event when clicked', () => { + click(heroEl); + // selected hero should be the same data bound hero + expect(testHost.selectedHero).toBe(testHost.hero); + }); + // #enddocregion test-host-tests +}); + +////// Test Host Component ////// +import { Component } from '@angular/core'; + +// #docregion test-host +@Component({ + template: ` + ` +}) +class TestHostComponent { + hero = new Hero(42, 'Test Name'); + selectedHero: Hero; + onSelected(hero: Hero) { this.selectedHero = hero; } +} +// #enddocregion test-host diff --git a/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.ts b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.ts new file mode 100644 index 0000000000..9f6be16d7d --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard-hero.component.ts @@ -0,0 +1,17 @@ +// #docregion +import { Component, EventEmitter, Input, Output } from '@angular/core'; + +import { Hero } from '../model'; + +// #docregion component +@Component({ + selector: 'dashboard-hero', + templateUrl: './dashboard-hero.component.html', + styleUrls: [ './dashboard-hero.component.css' ] +}) +export class DashboardHeroComponent { + @Input() hero: Hero; + @Output() selected = new EventEmitter(); + click() { this.selected.emit(this.hero); } +} +// #enddocregion component diff --git a/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.css b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.css new file mode 100644 index 0000000000..98130b61c6 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.css @@ -0,0 +1,35 @@ +[class*='col-'] { + float: left; +} +*, *:after, *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +h3 { + text-align: center; margin-bottom: 0; +} +[class*='col-'] { + padding-right: 20px; + padding-bottom: 20px; +} +[class*='col-']:last-of-type { + padding-right: 0; +} +.grid { + margin: 0; +} +.col-1-4 { + width: 25%; +} +.grid-pad { + padding: 10px 0; +} +.grid-pad > [class*='col-']:last-of-type { + padding-right: 20px; +} +@media (max-width: 1024px) { + .grid { + margin: 0; + } +} diff --git a/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.html b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.html new file mode 100644 index 0000000000..b26e16b828 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.html @@ -0,0 +1,9 @@ +

    {{title}}

    + +
    + + + + +
    diff --git a/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.no-testbed.spec.ts b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.no-testbed.spec.ts new file mode 100644 index 0000000000..125e5193b7 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.no-testbed.spec.ts @@ -0,0 +1,57 @@ +import { Router } from '@angular/router'; + +import { DashboardComponent } from './dashboard.component'; +import { Hero } from '../model'; + +import { addMatchers } from '../../testing'; +import { FakeHeroService } from '../model/testing'; + +class FakeRouter { + navigateByUrl(url: string) { return url; } +} + +describe('DashboardComponent: w/o Angular TestBed', () => { + let comp: DashboardComponent; + let heroService: FakeHeroService; + let router: Router; + + beforeEach(() => { + addMatchers(); + router = new FakeRouter() as any as Router; + heroService = new FakeHeroService(); + comp = new DashboardComponent(router, heroService); + }); + + it('should NOT have heroes before calling OnInit', () => { + expect(comp.heroes.length).toBe(0, + 'should not have heroes before OnInit'); + }); + + it('should NOT have heroes immediately after OnInit', () => { + comp.ngOnInit(); // ngOnInit -> getHeroes + expect(comp.heroes.length).toBe(0, + 'should not have heroes until service promise resolves'); + }); + + it('should HAVE heroes after HeroService gets them', (done: DoneFn) => { + comp.ngOnInit(); // ngOnInit -> getHeroes + heroService.lastPromise // the one from getHeroes + .then(() => { + // throw new Error('deliberate error'); // see it fail gracefully + expect(comp.heroes.length).toBeGreaterThan(0, + 'should have heroes after service promise resolves'); + }) + .then(done, done.fail); + }); + + it('should tell ROUTER to navigate by hero id', () => { + const hero = new Hero(42, 'Abbracadabra'); + const spy = spyOn(router, 'navigateByUrl'); + + comp.gotoDetail(hero); + + const navArgs = spy.calls.mostRecent().args[0]; + expect(navArgs).toBe('/heroes/42', 'should nav to HeroDetail for Hero 42'); + }); + +}); diff --git a/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.spec.ts b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.spec.ts new file mode 100644 index 0000000000..0b0f9e213a --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.spec.ts @@ -0,0 +1,147 @@ +// #docplaster +import { async, inject, ComponentFixture, TestBed +} from '@angular/core/testing'; + +import { addMatchers, click } from '../../testing'; +import { HeroService } from '../model'; +import { FakeHeroService } from '../model/testing'; + +import { By } from '@angular/platform-browser'; +import { Router } from '@angular/router'; + +import { DashboardComponent } from './dashboard.component'; +import { DashboardModule } from './dashboard.module'; + +// #docregion router-stub +class RouterStub { + navigateByUrl(url: string) { return url; } +} +// #enddocregion router-stub + +beforeEach ( addMatchers ); + +let comp: DashboardComponent; +let fixture: ComponentFixture; + +//////// Deep //////////////// + +describe('DashboardComponent (deep)', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ DashboardModule ] + }); + }); + + compileAndCreate(); + + tests(clickForDeep); + + function clickForDeep() { + // get first
    DebugElement + const heroEl = fixture.debugElement.query(By.css('.hero')); + click(heroEl); + } +}); + +//////// Shallow //////////////// + +import { NO_ERRORS_SCHEMA } from '@angular/core'; + +describe('DashboardComponent (shallow)', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ DashboardComponent ], + schemas: [NO_ERRORS_SCHEMA] + }); + }); + + compileAndCreate(); + + tests(clickForShallow); + + function clickForShallow() { + // get first DebugElement + const heroEl = fixture.debugElement.query(By.css('dashboard-hero')); + heroEl.triggerEventHandler('selected', comp.heroes[0]); + } +}); + +/** Add TestBed providers, compile, and create DashboardComponent */ +function compileAndCreate() { + // #docregion compile-and-create-body + beforeEach( async(() => { + TestBed.configureTestingModule({ + providers: [ + { provide: HeroService, useClass: FakeHeroService }, + { provide: Router, useClass: RouterStub } + ] + }) + .compileComponents().then(() => { + fixture = TestBed.createComponent(DashboardComponent); + comp = fixture.componentInstance; + }); + // #enddocregion compile-and-create-body + })); +} + +/** + * The (almost) same tests for both. + * Only change: the way that the first hero is clicked + */ +function tests(heroClick: Function) { + + it('should NOT have heroes before ngOnInit', () => { + expect(comp.heroes.length).toBe(0, + 'should not have heroes before ngOnInit'); + }); + + it('should NOT have heroes immediately after ngOnInit', () => { + fixture.detectChanges(); // runs initial lifecycle hooks + + expect(comp.heroes.length).toBe(0, + 'should not have heroes until service promise resolves'); + }); + + describe('after get dashboard heroes', () => { + + // Trigger component so it gets heroes and binds to them + beforeEach( async(() => { + fixture.detectChanges(); // runs ngOnInit -> getHeroes + fixture.whenStable() // No need for the `lastPromise` hack! + .then(() => fixture.detectChanges()); // bind to heroes + })); + + it('should HAVE heroes', () => { + expect(comp.heroes.length).toBeGreaterThan(0, + 'should have heroes after service promise resolves'); + }); + + it('should DISPLAY heroes', () => { + // Find and examine the displayed heroes + // Look for them in the DOM by css class + const heroes = fixture.debugElement.queryAll(By.css('dashboard-hero')); + expect(heroes.length).toBe(4, 'should display 4 heroes'); + }); + + // #docregion navigate-test, inject + it('should tell ROUTER to navigate when hero clicked', + inject([Router], (router: Router) => { // ... + // #enddocregion inject + + const spy = spyOn(router, 'navigateByUrl'); + + heroClick(); // trigger click on first inner
    + + // args passed to router.navigateByUrl() + const navArgs = spy.calls.first().args[0]; + + // expecting to navigate to id of the component's first hero + const id = comp.heroes[0].id; + expect(navArgs).toBe('/heroes/' + id, + 'should nav to HeroDetail for first hero'); + // #docregion inject + })); + // #enddocregion navigate-test, inject + }); +} + diff --git a/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.ts b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.ts new file mode 100644 index 0000000000..3edaa0c0ab --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.component.ts @@ -0,0 +1,40 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +import { Hero, HeroService } from '../model'; + +@Component({ + selector: 'app-dashboard', + templateUrl: './dashboard.component.html', + styleUrls: [ './dashboard.component.css' ] +}) +export class DashboardComponent implements OnInit { + + heroes: Hero[] = []; + + // #docregion ctor + constructor( + private router: Router, + private heroService: HeroService) { + } + // #enddocregion ctor + + ngOnInit() { + this.heroService.getHeroes() + .then(heroes => this.heroes = heroes.slice(1, 5)); + } + + // #docregion goto-detail + gotoDetail(hero: Hero) { + let url = `/heroes/${hero.id}`; + this.router.navigateByUrl(url); + } + // #enddocregion goto-detail + + get title() { + let cnt = this.heroes.length; + return cnt === 0 ? 'No Heroes' : + cnt === 1 ? 'Top Hero' : `Top ${cnt} Heroes`; + } +} diff --git a/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.module.ts b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.module.ts new file mode 100644 index 0000000000..8a70c851a0 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/dashboard/dashboard.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { SharedModule } from '../shared/shared.module'; + +import { DashboardComponent } from './dashboard.component'; +import { DashboardHeroComponent } from './dashboard-hero.component'; + +const routes: Routes = [ + { path: 'dashboard', component: DashboardComponent }, +]; + +@NgModule({ + imports: [ + SharedModule, + RouterModule.forChild(routes) + ], + declarations: [ DashboardComponent, DashboardHeroComponent ] +}) +export class DashboardModule { } diff --git a/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.css b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.css new file mode 100644 index 0000000000..f6139ba274 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.css @@ -0,0 +1,29 @@ +label { + display: inline-block; + width: 3em; + margin: .5em 0; + color: #607D8B; + font-weight: bold; +} +input { + height: 2em; + font-size: 1em; + padding-left: .4em; +} +button { + margin-top: 20px; + font-family: Arial; + background-color: #eee; + border: none; + padding: 5px 10px; + border-radius: 4px; + cursor: pointer; cursor: hand; +} +button:hover { + background-color: #cfd8dc; +} +button:disabled { + background-color: #eee; + color: #ccc; + cursor: auto; +} diff --git a/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.html b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.html new file mode 100644 index 0000000000..7e86a668f6 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.html @@ -0,0 +1,12 @@ + +
    +

    {{hero.name | titlecase}} Details

    +
    + {{hero.id}}
    +
    + + +
    + + +
    diff --git a/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.no-testbed.spec.ts b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.no-testbed.spec.ts new file mode 100644 index 0000000000..422dae6f77 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.no-testbed.spec.ts @@ -0,0 +1,58 @@ +import { HeroDetailComponent } from './hero-detail.component'; +import { Hero } from '../model'; + +import { ActivatedRouteStub } from '../../testing'; + +////////// Tests //////////////////// + +describe('HeroDetailComponent - no TestBed', () => { + let activatedRoute: ActivatedRouteStub; + let comp: HeroDetailComponent; + let expectedHero: Hero; + let hds: any; + let router: any; + + beforeEach((done: any) => { + expectedHero = new Hero(42, 'Bubba'); + activatedRoute = new ActivatedRouteStub(); + activatedRoute.testParams = { id: expectedHero.id }; + + router = jasmine.createSpyObj('router', ['navigate']); + + hds = jasmine.createSpyObj('HeroDetailService', ['getHero', 'saveHero']); + hds.getHero.and.returnValue(Promise.resolve(expectedHero)); + hds.saveHero.and.returnValue(Promise.resolve(expectedHero)); + + comp = new HeroDetailComponent(hds, activatedRoute, router); + comp.ngOnInit(); + + // OnInit calls HDS.getHero; wait for it to get the fake hero + hds.getHero.calls.first().returnValue.then(done); + }); + + it('should expose the hero retrieved from the service', () => { + expect(comp.hero).toBe(expectedHero); + }); + + it('should navigate when click cancel', () => { + comp.cancel(); + expect(router.navigate.calls.any()).toBe(true, 'router.navigate called'); + }); + + it('should save when click save', () => { + comp.save(); + expect(hds.saveHero.calls.any()).toBe(true, 'HeroDetailService.save called'); + expect(router.navigate.calls.any()).toBe(false, 'router.navigate not called yet'); + }); + + it('should navigate when click save resolves', (done: any) => { + comp.save(); + // waits for async save to complete before navigating + hds.saveHero.calls.first().returnValue + .then(() => { + expect(router.navigate.calls.any()).toBe(true, 'router.navigate called'); + done(); + }); + }); + +}); diff --git a/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.spec.ts b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.spec.ts new file mode 100644 index 0000000000..80b6450ac5 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.spec.ts @@ -0,0 +1,364 @@ +// #docplaster +import { + async, ComponentFixture, fakeAsync, inject, TestBed, tick +} from '@angular/core/testing'; + +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { + ActivatedRoute, ActivatedRouteStub, click, newEvent, Router, RouterStub +} from '../../testing'; + +import { Hero } from '../model'; +import { HeroDetailComponent } from './hero-detail.component'; +import { HeroDetailService } from './hero-detail.service'; +import { HeroModule } from './hero.module'; + +////// Testing Vars ////// +let activatedRoute: ActivatedRouteStub; +let comp: HeroDetailComponent; +let fixture: ComponentFixture; +let page: Page; + +////// Tests ////// +describe('HeroDetailComponent', () => { + beforeEach(() => { + activatedRoute = new ActivatedRouteStub(); + }); + describe('with HeroModule setup', heroModuleSetup); + describe('when override its provided HeroDetailService', overrideSetup); + describe('with FormsModule setup', formsModuleSetup); + describe('with SharedModule setup', sharedModuleSetup); +}); + +//////////////////// +function overrideSetup() { + // #docregion hds-spy + class HeroDetailServiceSpy { + testHero = new Hero(42, 'Test Hero'); + + getHero = jasmine.createSpy('getHero').and.callFake( + () => Promise + .resolve(true) + .then(() => Object.assign({}, this.testHero)) + ); + + saveHero = jasmine.createSpy('saveHero').and.callFake( + (hero: Hero) => Promise + .resolve(true) + .then(() => Object.assign(this.testHero, hero)) + ); + } + // #enddocregion hds-spy + + // the `id` value is irrelevant because ignored by service stub + beforeEach(() => activatedRoute.testParams = { id: 99999 } ); + + // #docregion setup-override + beforeEach( async(() => { + TestBed.configureTestingModule({ + imports: [ HeroModule ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: Router, useClass: RouterStub}, + // #enddocregion setup-override + // HeroDetailService at this level is IRRELEVANT! + { provide: HeroDetailService, useValue: {} } + // #docregion setup-override + ] + }) + + // Override component's own provider + // #docregion override-component-method + .overrideComponent(HeroDetailComponent, { + set: { + providers: [ + { provide: HeroDetailService, useClass: HeroDetailServiceSpy } + ] + } + }) + // #enddocregion override-component-method + + .compileComponents(); + })); + // #enddocregion setup-override + + // #docregion override-tests + let hdsSpy: HeroDetailServiceSpy; + + beforeEach( async(() => { + createComponent(); + // get the component's injected HeroDetailServiceSpy + hdsSpy = fixture.debugElement.injector.get(HeroDetailService) as any; + })); + + it('should have called `getHero`', () => { + expect(hdsSpy.getHero.calls.count()).toBe(1, 'getHero called once'); + }); + + it('should display stub hero\'s name', () => { + expect(page.nameDisplay.textContent).toBe(hdsSpy.testHero.name); + }); + + it('should save stub hero change', fakeAsync(() => { + const origName = hdsSpy.testHero.name; + const newName = 'New Name'; + + page.nameInput.value = newName; + page.nameInput.dispatchEvent(newEvent('input')); // tell Angular + + expect(comp.hero.name).toBe(newName, 'component hero has new name'); + expect(hdsSpy.testHero.name).toBe(origName, 'service hero unchanged before save'); + + click(page.saveBtn); + expect(hdsSpy.saveHero.calls.count()).toBe(1, 'saveHero called once'); + + tick(); // wait for async save to complete + expect(hdsSpy.testHero.name).toBe(newName, 'service hero has new name after save'); + expect(page.navSpy.calls.any()).toBe(true, 'router.navigate called'); + })); + // #enddocregion override-tests + + it('fixture injected service is not the component injected service', + inject([HeroDetailService], (service: HeroDetailService) => { + + expect(service).toEqual({}, 'service injected from fixture'); + expect(hdsSpy).toBeTruthy('service injected into component'); + })); +} + +//////////////////// +import { HEROES, FakeHeroService } from '../model/testing'; +import { HeroService } from '../model'; + +const firstHero = HEROES[0]; + +function heroModuleSetup() { + // #docregion setup-hero-module + beforeEach( async(() => { + TestBed.configureTestingModule({ + imports: [ HeroModule ], + // #enddocregion setup-hero-module + // declarations: [ HeroDetailComponent ], // NO! DOUBLE DECLARATION + // #docregion setup-hero-module + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: HeroService, useClass: FakeHeroService }, + { provide: Router, useClass: RouterStub}, + ] + }) + .compileComponents(); + })); + // #enddocregion setup-hero-module + + // #docregion route-good-id + describe('when navigate to existing hero', () => { + let expectedHero: Hero; + + beforeEach( async(() => { + expectedHero = firstHero; + activatedRoute.testParams = { id: expectedHero.id }; + createComponent(); + })); + + // #docregion selected-tests + it('should display that hero\'s name', () => { + expect(page.nameDisplay.textContent).toBe(expectedHero.name); + }); + // #enddocregion route-good-id + + it('should navigate when click cancel', () => { + click(page.cancelBtn); + expect(page.navSpy.calls.any()).toBe(true, 'router.navigate called'); + }); + + it('should save when click save but not navigate immediately', () => { + // Get service injected into component and spy on its`saveHero` method. + // It delegates to fake `HeroService.updateHero` which delivers a safe test result. + const hds = fixture.debugElement.injector.get(HeroDetailService); + const saveSpy = spyOn(hds, 'saveHero').and.callThrough(); + + click(page.saveBtn); + expect(saveSpy.calls.any()).toBe(true, 'HeroDetailService.save called'); + expect(page.navSpy.calls.any()).toBe(false, 'router.navigate not called'); + }); + + it('should navigate when click save and save resolves', fakeAsync(() => { + click(page.saveBtn); + tick(); // wait for async save to complete + expect(page.navSpy.calls.any()).toBe(true, 'router.navigate called'); + })); + + // #docregion title-case-pipe + it('should convert hero name to Title Case', () => { + const inputName = 'quick BROWN fox'; + const titleCaseName = 'Quick Brown Fox'; + + // simulate user entering new name into the input box + page.nameInput.value = inputName; + + // dispatch a DOM event so that Angular learns of input value change. + page.nameInput.dispatchEvent(newEvent('input')); + + // Tell Angular to update the output span through the title pipe + fixture.detectChanges(); + + expect(page.nameDisplay.textContent).toBe(titleCaseName); + }); + // #enddocregion title-case-pipe + // #enddocregion selected-tests + // #docregion route-good-id + }); + // #enddocregion route-good-id + + // #docregion route-no-id + describe('when navigate with no hero id', () => { + beforeEach( async( createComponent )); + + it('should have hero.id === 0', () => { + expect(comp.hero.id).toBe(0); + }); + + it('should display empty hero name', () => { + expect(page.nameDisplay.textContent).toBe(''); + }); + }); + // #enddocregion route-no-id + + // #docregion route-bad-id + describe('when navigate to non-existant hero id', () => { + beforeEach( async(() => { + activatedRoute.testParams = { id: 99999 }; + createComponent(); + })); + + it('should try to navigate back to hero list', () => { + expect(page.gotoSpy.calls.any()).toBe(true, 'comp.gotoList called'); + expect(page.navSpy.calls.any()).toBe(true, 'router.navigate called'); + }); + }); + // #enddocregion route-bad-id + + // Why we must use `fixture.debugElement.injector` in `Page()` + it('cannot use `inject` to get component\'s provided HeroDetailService', () => { + let service: HeroDetailService; + fixture = TestBed.createComponent(HeroDetailComponent); + expect( + // Throws because `inject` only has access to TestBed's injector + // which is an ancestor of the component's injector + inject([HeroDetailService], (hds: HeroDetailService) => service = hds ) + ) + .toThrowError(/No provider for HeroDetailService/); + + // get `HeroDetailService` with component's own injector + service = fixture.debugElement.injector.get(HeroDetailService); + expect(service).toBeDefined('debugElement.injector'); + }); +} + +///////////////////// +import { FormsModule } from '@angular/forms'; +import { TitleCasePipe } from '../shared/title-case.pipe'; + +function formsModuleSetup() { + // #docregion setup-forms-module + beforeEach( async(() => { + TestBed.configureTestingModule({ + imports: [ FormsModule ], + declarations: [ HeroDetailComponent, TitleCasePipe ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: HeroService, useClass: FakeHeroService }, + { provide: Router, useClass: RouterStub}, + ] + }) + .compileComponents(); + })); + // #enddocregion setup-forms-module + + it('should display 1st hero\'s name', fakeAsync(() => { + const expectedHero = firstHero; + activatedRoute.testParams = { id: expectedHero.id }; + createComponent().then(() => { + expect(page.nameDisplay.textContent).toBe(expectedHero.name); + }); + })); +} + +/////////////////////// +import { SharedModule } from '../shared/shared.module'; + +function sharedModuleSetup() { + // #docregion setup-shared-module + beforeEach( async(() => { + TestBed.configureTestingModule({ + imports: [ SharedModule ], + declarations: [ HeroDetailComponent ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: HeroService, useClass: FakeHeroService }, + { provide: Router, useClass: RouterStub}, + ] + }) + .compileComponents(); + })); + // #enddocregion setup-shared-module + + it('should display 1st hero\'s name', fakeAsync(() => { + const expectedHero = firstHero; + activatedRoute.testParams = { id: expectedHero.id }; + createComponent().then(() => { + expect(page.nameDisplay.textContent).toBe(expectedHero.name); + }); + })); +} + +/////////// Helpers ///// + +// #docregion create-component +/** Create the HeroDetailComponent, initialize it, set test variables */ +function createComponent() { + fixture = TestBed.createComponent(HeroDetailComponent); + comp = fixture.componentInstance; + page = new Page(); + + // 1st change detection triggers ngOnInit which gets a hero + fixture.detectChanges(); + return fixture.whenStable().then(() => { + // 2nd change detection displays the async-fetched hero + fixture.detectChanges(); + page.addPageElements(); + }); +} +// #enddocregion create-component + +// #docregion page +class Page { + gotoSpy: jasmine.Spy; + navSpy: jasmine.Spy; + + saveBtn: DebugElement; + cancelBtn: DebugElement; + nameDisplay: HTMLElement; + nameInput: HTMLInputElement; + + constructor() { + const router = TestBed.get(Router); // get router from root injector + this.gotoSpy = spyOn(comp, 'gotoList').and.callThrough(); + this.navSpy = spyOn(router, 'navigate'); + } + + /** Add page elements after hero arrives */ + addPageElements() { + if (comp.hero) { + // have a hero so these elements are now in the DOM + const buttons = fixture.debugElement.queryAll(By.css('button')); + this.saveBtn = buttons[0]; + this.cancelBtn = buttons[1]; + this.nameDisplay = fixture.debugElement.query(By.css('span')).nativeElement; + this.nameInput = fixture.debugElement.query(By.css('input')).nativeElement; + } + } +} +// #enddocregion page diff --git a/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.ts b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.ts new file mode 100644 index 0000000000..25f13b0cd5 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.component.ts @@ -0,0 +1,63 @@ +/* tslint:disable:member-ordering */ +// #docplaster +import { Component, Input, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import 'rxjs/add/operator/map'; + +import { Hero } from '../model'; +import { HeroDetailService } from './hero-detail.service'; + +// #docregion prototype +@Component({ + selector: 'app-hero-detail', + templateUrl: './hero-detail.component.html', + styleUrls: ['./hero-detail.component.css' ], + providers: [ HeroDetailService ] +}) +export class HeroDetailComponent implements OnInit { + // #docregion ctor + constructor( + private heroDetailService: HeroDetailService, + private route: ActivatedRoute, + private router: Router) { + } + // #enddocregion ctor +// #enddocregion prototype + + @Input() hero: Hero; + + // #docregion ng-on-init + ngOnInit(): void { + // get hero when `id` param changes + this.route.params.subscribe(p => this.getHero(p && p['id'])); + } + // #enddocregion ng-on-init + + private getHero(id: string): void { + // when no id or id===0, create new hero + if (!id) { + this.hero = new Hero(); + return; + } + + this.heroDetailService.getHero(id).then(hero => { + if (hero) { + this.hero = hero; + } else { + this.gotoList(); // id not found; navigate to list + } + }); + } + + save(): void { + this.heroDetailService.saveHero(this.hero).then(() => this.gotoList()); + } + + cancel() { this.gotoList(); } + + gotoList() { + this.router.navigate(['../'], {relativeTo: this.route}); + } +// #docregion prototype +} +// #enddocregion prototype diff --git a/public/docs/_examples/testing/ts/src/app/hero/hero-detail.service.ts b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.service.ts new file mode 100644 index 0000000000..6239ae5b80 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/hero/hero-detail.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@angular/core'; + +import { Hero, HeroService } from '../model'; + +// #docregion prototype +@Injectable() +export class HeroDetailService { + constructor(private heroService: HeroService) { } +// #enddocregion prototype + + // Returns a clone which caller may modify safely + getHero(id: number | string): Promise { + if (typeof id === 'string') { + id = parseInt(id as string, 10); + } + return this.heroService.getHero(id).then(hero => { + return hero ? Object.assign({}, hero) : null; // clone or null + }); + } + + saveHero(hero: Hero) { + return this.heroService.updateHero(hero); + } +// #docregion prototype +} +// #enddocregion prototype diff --git a/public/docs/_examples/testing/ts/app/heroes.component.css b/public/docs/_examples/testing/ts/src/app/hero/hero-list.component.css similarity index 100% rename from public/docs/_examples/testing/ts/app/heroes.component.css rename to public/docs/_examples/testing/ts/src/app/hero/hero-list.component.css diff --git a/public/docs/_examples/testing/ts/src/app/hero/hero-list.component.html b/public/docs/_examples/testing/ts/src/app/hero/hero-list.component.html new file mode 100644 index 0000000000..cd37301fd6 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/hero/hero-list.component.html @@ -0,0 +1,8 @@ +

    My Heroes

    +
      +
    • + {{hero.id}} {{hero.name}} +
    • +
    diff --git a/public/docs/_examples/testing/ts/src/app/hero/hero-list.component.spec.ts b/public/docs/_examples/testing/ts/src/app/hero/hero-list.component.spec.ts new file mode 100644 index 0000000000..dbf9d37d71 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/hero/hero-list.component.spec.ts @@ -0,0 +1,139 @@ +import { async, ComponentFixture, fakeAsync, TestBed, tick +} from '@angular/core/testing'; + +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { addMatchers, newEvent, Router, RouterStub +} from '../../testing'; + +import { HEROES, FakeHeroService } from '../model/testing'; + +import { HeroModule } from './hero.module'; +import { HeroListComponent } from './hero-list.component'; +import { HighlightDirective } from '../shared/highlight.directive'; +import { HeroService } from '../model'; + +let comp: HeroListComponent; +let fixture: ComponentFixture; +let page: Page; + +/////// Tests ////// + +describe('HeroListComponent', () => { + + beforeEach( async(() => { + addMatchers(); + TestBed.configureTestingModule({ + imports: [HeroModule], + providers: [ + { provide: HeroService, useClass: FakeHeroService }, + { provide: Router, useClass: RouterStub} + ] + }) + .compileComponents() + .then(createComponent); + })); + + it('should display heroes', () => { + expect(page.heroRows.length).toBeGreaterThan(0); + }); + + it('1st hero should match 1st test hero', () => { + const expectedHero = HEROES[0]; + const actualHero = page.heroRows[0].textContent; + expect(actualHero).toContain(expectedHero.id, 'hero.id'); + expect(actualHero).toContain(expectedHero.name, 'hero.name'); + }); + + it('should select hero on click', fakeAsync(() => { + const expectedHero = HEROES[1]; + const li = page.heroRows[1]; + li.dispatchEvent(newEvent('click')); + tick(); + // `.toEqual` because selectedHero is clone of expectedHero; see FakeHeroService + expect(comp.selectedHero).toEqual(expectedHero); + })); + + it('should navigate to selected hero detail on click', fakeAsync(() => { + const expectedHero = HEROES[1]; + const li = page.heroRows[1]; + li.dispatchEvent(newEvent('click')); + tick(); + + // should have navigated + expect(page.navSpy.calls.any()).toBe(true, 'navigate called'); + + // composed hero detail will be URL like 'heroes/42' + // expect link array with the route path and hero id + // first argument to router.navigate is link array + const navArgs = page.navSpy.calls.first().args[0]; + expect(navArgs[0]).toContain('heroes', 'nav to heroes detail URL'); + expect(navArgs[1]).toBe(expectedHero.id, 'expected hero.id'); + + })); + + it('should find `HighlightDirective` with `By.directive', () => { + // #docregion by + // Can find DebugElement either by css selector or by directive + const h2 = fixture.debugElement.query(By.css('h2')); + const directive = fixture.debugElement.query(By.directive(HighlightDirective)); + // #enddocregion by + expect(h2).toBe(directive); + }); + + it('should color header with `HighlightDirective`', () => { + const h2 = page.highlightDe.nativeElement as HTMLElement; + const bgColor = h2.style.backgroundColor; + + // different browsers report color values differently + const isExpectedColor = bgColor === 'gold' || bgColor === 'rgb(255, 215, 0)'; + expect(isExpectedColor).toBe(true, 'backgroundColor'); + }); + + it('the `HighlightDirective` is among the element\'s providers', () => { + expect(page.highlightDe.providerTokens).toContain(HighlightDirective, 'HighlightDirective'); + }); +}); + +/////////// Helpers ///// + +/** Create the component and set the `page` test variables */ +function createComponent() { + fixture = TestBed.createComponent(HeroListComponent); + comp = fixture.componentInstance; + + // change detection triggers ngOnInit which gets a hero + fixture.detectChanges(); + + return fixture.whenStable().then(() => { + // got the heroes and updated component + // change detection updates the view + fixture.detectChanges(); + page = new Page(); + }); +} + +class Page { + /** Hero line elements */ + heroRows: HTMLLIElement[]; + + /** Highlighted element */ + highlightDe: DebugElement; + + /** Spy on router navigate method */ + navSpy: jasmine.Spy; + + constructor() { + this.heroRows = fixture.debugElement.queryAll(By.css('li')).map(de => de.nativeElement); + + // Find the first element with an attached HighlightDirective + this.highlightDe = fixture.debugElement.query(By.directive(HighlightDirective)); + + // Get the component's injected router and spy on it + const router = fixture.debugElement.injector.get(Router); + this.navSpy = spyOn(router, 'navigate'); + }; +} + + diff --git a/public/docs/_examples/testing/ts/src/app/hero/hero-list.component.ts b/public/docs/_examples/testing/ts/src/app/hero/hero-list.component.ts new file mode 100644 index 0000000000..c61ff23f0e --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/hero/hero-list.component.ts @@ -0,0 +1,27 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +import { Hero, HeroService } from '../model'; + +@Component({ + selector: 'app-heroes', + templateUrl: './hero-list.component.html', + styleUrls: [ './hero-list.component.css' ] +}) +export class HeroListComponent implements OnInit { + heroes: Promise; + selectedHero: Hero; + + constructor( + private router: Router, + private heroService: HeroService) { } + + ngOnInit() { + this.heroes = this.heroService.getHeroes(); + } + + onSelect(hero: Hero) { + this.selectedHero = hero; + this.router.navigate(['../heroes', this.selectedHero.id ]); + } +} diff --git a/public/docs/_examples/testing/ts/src/app/hero/hero-routing.module.ts b/public/docs/_examples/testing/ts/src/app/hero/hero-routing.module.ts new file mode 100644 index 0000000000..59ec14474c --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/hero/hero-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { HeroListComponent } from './hero-list.component'; +import { HeroDetailComponent } from './hero-detail.component'; + +const routes: Routes = [ + { path: '', component: HeroListComponent }, + { path: ':id', component: HeroDetailComponent } +]; + +export const routedComponents = [HeroDetailComponent, HeroListComponent]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class HeroRoutingModule {} diff --git a/public/docs/_examples/testing/ts/src/app/hero/hero.module.ts b/public/docs/_examples/testing/ts/src/app/hero/hero.module.ts new file mode 100644 index 0000000000..dfe33cc199 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/hero/hero.module.ts @@ -0,0 +1,9 @@ +import { NgModule } from '@angular/core'; +import { SharedModule } from '../shared/shared.module'; +import { routedComponents, HeroRoutingModule } from './hero-routing.module'; + +@NgModule({ + imports: [ SharedModule, HeroRoutingModule ], + declarations: [ routedComponents ] +}) +export class HeroModule { } diff --git a/public/docs/_examples/testing/ts/src/app/model/hero.service.ts b/public/docs/_examples/testing/ts/src/app/model/hero.service.ts new file mode 100644 index 0000000000..667d47312b --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/model/hero.service.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@angular/core'; + +import { Hero } from './hero'; +import { HEROES } from './test-heroes'; + +@Injectable() +/** Dummy HeroService. Pretend it makes real http requests */ +export class HeroService { + getHeroes() { + return Promise.resolve(HEROES); + } + + getHero(id: number | string): Promise { + if (typeof id === 'string') { + id = parseInt(id as string, 10); + } + return this.getHeroes().then( + heroes => heroes.find(hero => hero.id === id) + ); + } + + updateHero(hero: Hero): Promise { + return this.getHero(hero.id).then(h => { + if (!h) { + throw new Error(`Hero ${hero.id} not found`); + } + return Object.assign(h, hero); + }); + } +} diff --git a/public/docs/_examples/testing/ts/src/app/model/hero.spec.ts b/public/docs/_examples/testing/ts/src/app/model/hero.spec.ts new file mode 100644 index 0000000000..e8acf913f2 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/model/hero.spec.ts @@ -0,0 +1,20 @@ +// #docregion +import { Hero } from './hero'; + +describe('Hero', () => { + it('has name', () => { + const hero = new Hero(1, 'Super Cat'); + expect(hero.name).toBe('Super Cat'); + }); + + it('has id', () => { + const hero = new Hero(1, 'Super Cat'); + expect(hero.id).toBe(1); + }); + + it('can clone itself', () => { + const hero = new Hero(1, 'Super Cat'); + const clone = hero.clone(); + expect(hero).toEqual(clone); + }); +}); diff --git a/public/docs/_examples/testing/ts/src/app/model/hero.ts b/public/docs/_examples/testing/ts/src/app/model/hero.ts new file mode 100644 index 0000000000..6a98f0dfdc --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/model/hero.ts @@ -0,0 +1,4 @@ +export class Hero { + constructor(public id = 0, public name = '') { } + clone() { return new Hero(this.id, this.name); } +} diff --git a/public/docs/_examples/testing/ts/src/app/model/http-hero.service.spec.ts b/public/docs/_examples/testing/ts/src/app/model/http-hero.service.spec.ts new file mode 100644 index 0000000000..c16b421274 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/model/http-hero.service.spec.ts @@ -0,0 +1,127 @@ +import { + async, inject, TestBed +} from '@angular/core/testing'; + +import { + MockBackend, + MockConnection +} from '@angular/http/testing'; + +import { + HttpModule, Http, XHRBackend, Response, ResponseOptions +} from '@angular/http'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; + +import 'rxjs/add/operator/catch'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/toPromise'; + +import { Hero } from './hero'; +import { HttpHeroService as HeroService } from './http-hero.service'; + +const makeHeroData = () => [ + { id: 1, name: 'Windstorm' }, + { id: 2, name: 'Bombasto' }, + { id: 3, name: 'Magneta' }, + { id: 4, name: 'Tornado' } +] as Hero[]; + +//////// Tests ///////////// +describe('Http-HeroService (mockBackend)', () => { + + beforeEach( async(() => { + TestBed.configureTestingModule({ + imports: [ HttpModule ], + providers: [ + HeroService, + { provide: XHRBackend, useClass: MockBackend } + ] + }) + .compileComponents(); + })); + + it('can instantiate service when inject service', + inject([HeroService], (service: HeroService) => { + expect(service instanceof HeroService).toBe(true); + })); + + + + it('can instantiate service with "new"', inject([Http], (http: Http) => { + expect(http).not.toBeNull('http should be provided'); + let service = new HeroService(http); + expect(service instanceof HeroService).toBe(true, 'new service should be ok'); + })); + + + it('can provide the mockBackend as XHRBackend', + inject([XHRBackend], (backend: MockBackend) => { + expect(backend).not.toBeNull('backend should be provided'); + })); + + describe('when getHeroes', () => { + let backend: MockBackend; + let service: HeroService; + let fakeHeroes: Hero[]; + let response: Response; + + beforeEach(inject([Http, XHRBackend], (http: Http, be: MockBackend) => { + backend = be; + service = new HeroService(http); + fakeHeroes = makeHeroData(); + let options = new ResponseOptions({status: 200, body: {data: fakeHeroes}}); + response = new Response(options); + })); + + it('should have expected fake heroes (then)', async(inject([], () => { + backend.connections.subscribe((c: MockConnection) => c.mockRespond(response)); + + service.getHeroes().toPromise() + // .then(() => Promise.reject('deliberate')) + .then(heroes => { + expect(heroes.length).toBe(fakeHeroes.length, + 'should have expected no. of heroes'); + }); + }))); + + it('should have expected fake heroes (Observable.do)', async(inject([], () => { + backend.connections.subscribe((c: MockConnection) => c.mockRespond(response)); + + service.getHeroes() + .do(heroes => { + expect(heroes.length).toBe(fakeHeroes.length, + 'should have expected no. of heroes'); + }) + .toPromise(); + }))); + + + it('should be OK returning no heroes', async(inject([], () => { + let resp = new Response(new ResponseOptions({status: 200, body: {data: []}})); + backend.connections.subscribe((c: MockConnection) => c.mockRespond(resp)); + + service.getHeroes() + .do(heroes => { + expect(heroes.length).toBe(0, 'should have no heroes'); + }) + .toPromise(); + }))); + + it('should treat 404 as an Observable error', async(inject([], () => { + let resp = new Response(new ResponseOptions({status: 404})); + backend.connections.subscribe((c: MockConnection) => c.mockRespond(resp)); + + service.getHeroes() + .do(heroes => { + fail('should not respond with heroes'); + }) + .catch(err => { + expect(err).toMatch(/Bad response status/, 'should catch bad response status code'); + return Observable.of(null); // failure is the expected test result + }) + .toPromise(); + }))); + }); +}); diff --git a/public/docs/_examples/testing/ts/src/app/model/http-hero.service.ts b/public/docs/_examples/testing/ts/src/app/model/http-hero.service.ts new file mode 100644 index 0000000000..a5fe46b801 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/model/http-hero.service.ts @@ -0,0 +1,68 @@ +// #docplaster +// #docregion +import { Injectable } from '@angular/core'; +import { Http, Response } from '@angular/http'; +import { Headers, RequestOptions } from '@angular/http'; +import { Hero } from './hero'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/throw'; + +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/catch'; +import 'rxjs/add/operator/map'; + +@Injectable() +export class HttpHeroService { + private _heroesUrl = 'app/heroes'; // URL to web api + + constructor (private http: Http) {} + + getHeroes (): Observable { + return this.http.get(this._heroesUrl) + .map(this.extractData) + // .do(data => console.log(data)) // eyeball results in the console + .catch(this.handleError); + } + + getHero(id: number | string) { + return this.http + .get('app/heroes/?id=${id}') + .map((r: Response) => r.json().data as Hero[]); + } + + addHero (name: string): Observable { + let body = JSON.stringify({ name }); + let headers = new Headers({ 'Content-Type': 'application/json' }); + let options = new RequestOptions({ headers: headers }); + + return this.http.post(this._heroesUrl, body, options) + .map(this.extractData) + .catch(this.handleError); + } + + updateHero (hero: Hero): Observable { + let body = JSON.stringify(hero); + let headers = new Headers({ 'Content-Type': 'application/json' }); + let options = new RequestOptions({ headers: headers }); + + return this.http.put(this._heroesUrl, body, options) + .map(this.extractData) + .catch(this.handleError); + } + + private extractData(res: Response) { + if (res.status < 200 || res.status >= 300) { + throw new Error('Bad response status: ' + res.status); + } + let body = res.json(); + return body.data || { }; + } + + private handleError (error: any) { + // In a real world app, we might send the error to remote logging infrastructure + let errMsg = error.message || 'Server error'; + console.error(errMsg); // log to console instead + return Observable.throw(errMsg); + } +} diff --git a/public/docs/_examples/testing/ts/src/app/model/index.ts b/public/docs/_examples/testing/ts/src/app/model/index.ts new file mode 100644 index 0000000000..227004d5be --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/model/index.ts @@ -0,0 +1,7 @@ +// Model barrel +export * from './hero'; +export * from './hero.service'; +export * from './http-hero.service'; +export * from './test-heroes'; + +export * from './user.service'; diff --git a/public/docs/_examples/testing/ts/src/app/model/test-heroes.ts b/public/docs/_examples/testing/ts/src/app/model/test-heroes.ts new file mode 100644 index 0000000000..d40ce5d564 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/model/test-heroes.ts @@ -0,0 +1,11 @@ +// #docregion +import { Hero } from './hero'; + +export var HEROES: Hero[] = [ + new Hero(11, 'Mr. Nice'), + new Hero(12, 'Narco'), + new Hero(13, 'Bombasto'), + new Hero(14, 'Celeritas'), + new Hero(15, 'Magneta'), + new Hero(16, 'RubberMan') +]; diff --git a/public/docs/_examples/testing/ts/src/app/model/testing/fake-hero.service.ts b/public/docs/_examples/testing/ts/src/app/model/testing/fake-hero.service.ts new file mode 100644 index 0000000000..79a865cc44 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/model/testing/fake-hero.service.ts @@ -0,0 +1,41 @@ +// re-export for tester convenience +export { Hero } from '../hero'; +export { HeroService } from '../hero.service'; + +import { Hero } from '../hero'; +import { HeroService } from '../hero.service'; + +export var HEROES: Hero[] = [ + new Hero(41, 'Bob'), + new Hero(42, 'Carol'), + new Hero(43, 'Ted'), + new Hero(44, 'Alice'), + new Hero(45, 'Speedy'), + new Hero(46, 'Stealthy') +]; + +export class FakeHeroService implements HeroService { + + heroes = HEROES.map(h => h.clone()); + lastPromise: Promise; // remember so we can spy on promise calls + + getHero(id: number | string) { + if (typeof id === 'string') { + id = parseInt(id as string, 10); + } + let hero = this.heroes.find(h => h.id === id); + return this.lastPromise = Promise.resolve(hero); + } + + getHeroes() { + return this.lastPromise = Promise.resolve(this.heroes); + } + + updateHero(hero: Hero): Promise { + return this.lastPromise = this.getHero(hero.id).then(h => { + return h ? + Object.assign(h, hero) : + Promise.reject(`Hero ${hero.id} not found`) as any as Promise; + }); + } +} diff --git a/public/docs/_examples/testing/ts/src/app/model/testing/index.ts b/public/docs/_examples/testing/ts/src/app/model/testing/index.ts new file mode 100644 index 0000000000..6da76e67db --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/model/testing/index.ts @@ -0,0 +1 @@ +export * from './fake-hero.service'; diff --git a/public/docs/_examples/testing/ts/src/app/model/user.service.ts b/public/docs/_examples/testing/ts/src/app/model/user.service.ts new file mode 100644 index 0000000000..280efefeec --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/model/user.service.ts @@ -0,0 +1,7 @@ +import { Injectable } from '@angular/core'; + +@Injectable() +export class UserService { + isLoggedIn = true; + user = {name: 'Sam Spade'}; +} diff --git a/public/docs/_examples/testing/ts/src/app/shared/highlight.directive.spec.ts b/public/docs/_examples/testing/ts/src/app/shared/highlight.directive.spec.ts new file mode 100644 index 0000000000..b990f20b69 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/shared/highlight.directive.spec.ts @@ -0,0 +1,104 @@ +import { Component, DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; + +import { HighlightDirective } from './highlight.directive'; +import { newEvent } from '../../testing'; + +// #docregion test-component +@Component({ + template: ` +

    Something Yellow

    +

    The Default (Gray)

    +

    No Highlight

    + ` +}) +class TestComponent { } +// #enddocregion test-component + +describe('HighlightDirective', () => { + + let fixture: ComponentFixture; + let des: DebugElement[]; // the three elements w/ the directive + let bareH2: DebugElement; // the

    w/o the directive + + // #docregion selected-tests + beforeEach(() => { + fixture = TestBed.configureTestingModule({ + declarations: [ HighlightDirective, TestComponent ] + }) + .createComponent(TestComponent); + + fixture.detectChanges(); // initial binding + + // all elements with an attached HighlightDirective + des = fixture.debugElement.queryAll(By.directive(HighlightDirective)); + + // the h2 without the HighlightDirective + bareH2 = fixture.debugElement.query(By.css('h2:not([highlight])')); + }); + + // color tests + it('should have three highlighted elements', () => { + expect(des.length).toBe(3); + }); + + it('should color 1st

    background "yellow"', () => { + const bgColor = des[0].nativeElement.style.backgroundColor; + expect(bgColor).toBe('yellow'); + }); + + it('should color 2nd

    background w/ default color', () => { + const dir = des[1].injector.get(HighlightDirective) as HighlightDirective; + const bgColor = des[1].nativeElement.style.backgroundColor; + expect(bgColor).toBe(dir.defaultColor); + }); + + it('should bind background to value color', () => { + // easier to work with nativeElement + const input = des[2].nativeElement as HTMLInputElement; + expect(input.style.backgroundColor).toBe('cyan', 'initial backgroundColor'); + + // dispatch a DOM event so that Angular responds to the input value change. + input.value = 'green'; + input.dispatchEvent(newEvent('input')); + fixture.detectChanges(); + + expect(input.style.backgroundColor).toBe('green', 'changed backgroundColor'); + }); + + + it('bare

    should not have a customProperty', () => { + expect(bareH2.properties['customProperty']).toBeUndefined(); + }); + // #enddocregion selected-tests + + // Removed on 12/02/2016 when ceased public discussion of the `Renderer`. Revive in future? + // // customProperty tests + // it('all highlighted elements should have a true customProperty', () => { + // const allTrue = des.map(de => !!de.properties['customProperty']).every(v => v === true); + // expect(allTrue).toBe(true); + // }); + + // injected directive + // attached HighlightDirective can be injected + it('can inject `HighlightDirective` in 1st

    ', () => { + const dir = des[0].injector.get(HighlightDirective); + expect(dir).toBeTruthy(); + }); + + it('cannot inject `HighlightDirective` in 3rd

    ', () => { + const dir = bareH2.injector.get(HighlightDirective, null); + expect(dir).toBe(null); + }); + + // DebugElement.providerTokens + // attached HighlightDirective should be listed in the providerTokens + it('should have `HighlightDirective` in 1st

    providerTokens', () => { + expect(des[0].providerTokens).toContain(HighlightDirective); + }); + + it('should not have `HighlightDirective` in 3rd

    providerTokens', () => { + expect(bareH2.providerTokens).not.toContain(HighlightDirective); + }); +}); diff --git a/public/docs/_examples/testing/ts/src/app/shared/highlight.directive.ts b/public/docs/_examples/testing/ts/src/app/shared/highlight.directive.ts new file mode 100644 index 0000000000..20901878c4 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/shared/highlight.directive.ts @@ -0,0 +1,20 @@ +// #docregion +import { Directive, ElementRef, Input, OnChanges } from '@angular/core'; + +@Directive({ selector: '[highlight]' }) +/** Set backgroundColor for the attached element to highlight color + * and set the element's customProperty to true */ +export class HighlightDirective implements OnChanges { + + defaultColor = 'rgb(211, 211, 211)'; // lightgray + + @Input('highlight') bgColor: string; + + constructor(private el: ElementRef) { + el.nativeElement.style.customProperty = true; + } + + ngOnChanges() { + this.el.nativeElement.style.backgroundColor = this.bgColor || this.defaultColor; + } +} diff --git a/public/docs/_examples/testing/ts/src/app/shared/shared.module.ts b/public/docs/_examples/testing/ts/src/app/shared/shared.module.ts new file mode 100644 index 0000000000..17c41c0410 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/shared/shared.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { HighlightDirective } from './highlight.directive'; +import { TitleCasePipe } from './title-case.pipe'; +import { TwainComponent } from './twain.component'; + +@NgModule({ + imports: [ CommonModule ], + exports: [ CommonModule, FormsModule, + HighlightDirective, TitleCasePipe, TwainComponent ], + declarations: [ HighlightDirective, TitleCasePipe, TwainComponent ] +}) +export class SharedModule { } diff --git a/public/docs/_examples/testing/ts/src/app/shared/title-case.pipe.spec.ts b/public/docs/_examples/testing/ts/src/app/shared/title-case.pipe.spec.ts new file mode 100644 index 0000000000..5dfc5d91b0 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/shared/title-case.pipe.spec.ts @@ -0,0 +1,34 @@ +// #docplaster +// #docregion +import { TitleCasePipe } from './title-case.pipe'; + +// #docregion excerpt, mini-excerpt +describe('TitleCasePipe', () => { + // This pipe is a pure, stateless function so no need for BeforeEach + let pipe = new TitleCasePipe(); + + it('transforms "abc" to "Abc"', () => { + expect(pipe.transform('abc')).toBe('Abc'); + }); +// #enddocregion mini-excerpt + + it('transforms "abc def" to "Abc Def"', () => { + expect(pipe.transform('abc def')).toBe('Abc Def'); + }); + + // ... more tests ... +// #enddocregion excerpt + it('leaves "Abc Def" unchanged', () => { + expect(pipe.transform('Abc Def')).toBe('Abc Def'); + }); + + it('transforms "abc-def" to "Abc-def"', () => { + expect(pipe.transform('abc-def')).toBe('Abc-def'); + }); + + it('transforms " abc def" to " Abc Def" (preserves spaces) ', () => { + expect(pipe.transform(' abc def')).toBe(' Abc Def'); + }); +// #docregion excerpt, mini-excerpt +}); +// #enddocregion excerpt, mini-excerpt diff --git a/public/docs/_examples/testing/ts/src/app/shared/title-case.pipe.ts b/public/docs/_examples/testing/ts/src/app/shared/title-case.pipe.ts new file mode 100644 index 0000000000..df2567778d --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/shared/title-case.pipe.ts @@ -0,0 +1,11 @@ +// #docregion +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({name: 'titlecase', pure: false}) +/** Transform to Title Case: uppercase the first letter of the words in a string.*/ +export class TitleCasePipe implements PipeTransform { + transform(input: string): string { + return input.length === 0 ? '' : + input.replace(/\w\S*/g, (txt => txt[0].toUpperCase() + txt.substr(1).toLowerCase() )); + } +} diff --git a/public/docs/_examples/testing/ts/src/app/shared/twain.component.spec.ts b/public/docs/_examples/testing/ts/src/app/shared/twain.component.spec.ts new file mode 100644 index 0000000000..b177c0bfc3 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/shared/twain.component.spec.ts @@ -0,0 +1,92 @@ +// #docplaster +import { async, fakeAsync, ComponentFixture, TestBed, tick } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { TwainService } from './twain.service'; +import { TwainComponent } from './twain.component'; + +describe('TwainComponent', () => { + + let comp: TwainComponent; + let fixture: ComponentFixture; + + let spy: jasmine.Spy; + let de: DebugElement; + let el: HTMLElement; + let twainService: TwainService; // the actually injected service + + const testQuote = 'Test Quote'; + + // #docregion setup + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ TwainComponent ], + providers: [ TwainService ], + }); + + fixture = TestBed.createComponent(TwainComponent); + comp = fixture.componentInstance; + + // TwainService actually injected into the component + twainService = fixture.debugElement.injector.get(TwainService); + + // Setup spy on the `getQuote` method + // #docregion spy + spy = spyOn(twainService, 'getQuote') + .and.returnValue(Promise.resolve(testQuote)); + // #enddocregion spy + + // Get the Twain quote element by CSS selector (e.g., by class name) + de = fixture.debugElement.query(By.css('.twain')); + el = de.nativeElement; + }); + // #enddocregion setup + + // #docregion tests + it('should not show quote before OnInit', () => { + expect(el.textContent).toBe('', 'nothing displayed'); + expect(spy.calls.any()).toBe(false, 'getQuote not yet called'); + }); + + it('should still not show quote after component initialized', () => { + fixture.detectChanges(); + // getQuote service is async => still has not returned with quote + expect(el.textContent).toBe('...', 'no quote yet'); + expect(spy.calls.any()).toBe(true, 'getQuote called'); + }); + + // #docregion async-test + it('should show quote after getQuote promise (async)', async(() => { + fixture.detectChanges(); + + fixture.whenStable().then(() => { // wait for async getQuote + fixture.detectChanges(); // update view with quote + expect(el.textContent).toBe(testQuote); + }); + })); + // #enddocregion async-test + + // #docregion fake-async-test + it('should show quote after getQuote promise (fakeAsync)', fakeAsync(() => { + fixture.detectChanges(); + tick(); // wait for async getQuote + fixture.detectChanges(); // update view with quote + expect(el.textContent).toBe(testQuote); + })); + // #enddocregion fake-async-test + // #enddocregion tests + + // #docregion done-test + it('should show quote after getQuote promise (done)', (done: any) => { + fixture.detectChanges(); + + // get the spy promise and wait for it to resolve + spy.calls.mostRecent().returnValue.then(() => { + fixture.detectChanges(); // update view with quote + expect(el.textContent).toBe(testQuote); + done(); + }); + }); + // #enddocregion done-test +}); diff --git a/public/docs/_examples/testing/ts/src/app/shared/twain.component.timer.spec.ts.no-work b/public/docs/_examples/testing/ts/src/app/shared/twain.component.timer.spec.ts.no-work new file mode 100644 index 0000000000..74dec3e766 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/shared/twain.component.timer.spec.ts.no-work @@ -0,0 +1,116 @@ +// #docplaster +// When AppComponent learns to present quote with intervalTimer +import { async, discardPeriodicTasks, fakeAsync, ComponentFixture, TestBed, tick } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { TwainService } from './model'; +import { TwainComponent } from './twain.component'; + +xdescribe('TwainComponent', () => { + + let comp: TwainComponent; + let fixture: ComponentFixture; + + const quotes = [ + 'Test Quote 1', + 'Test Quote 2', + 'Test Quote 3' + ]; + + let spy: jasmine.Spy; + let twainEl: DebugElement; // the element with the Twain quote + let twainService: TwainService; // the actually injected service + + function getQuote() { return twainEl.nativeElement.textContent; } + + // #docregion setup + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ TwainComponent ], + providers: [ TwainService ], + }); + + fixture = TestBed.createComponent(TwainComponent); + comp = fixture.componentInstance; + + // TwainService actually injected into the component + twainService = fixture.debugElement.injector.get(TwainService); + + // Setup spy on the `getQuote` method + spy = spyOn(twainService, 'getQuote') + .and.returnValues(...quotes.map(q => Promise.resolve(q))); + + // Get the Twain quote element by CSS selector (e.g., by class name) + twainEl = fixture.debugElement.query(By.css('.twain')); + }); + + afterEach(() => { + // destroy component to stop the component timer + fixture.destroy(); + }); + // #enddocregion setup + + // #docregion tests + it('should not show quote before OnInit', () => { + expect(getQuote()).toBe(''); + }); + + it('should still not show quote after component initialized', () => { + // because the getQuote service is async + fixture.detectChanges(); // trigger data binding + expect(getQuote()).toContain('not initialized'); + }); + + // WIP + // If go this way, add jasmine.clock().uninstall(); to afterEach + // it('should show quote after Angular "settles"', async(() => { + // //jasmine.clock().install(); + // fixture.detectChanges(); // trigger data binding + // fixture.whenStable().then(() => { + // fixture.detectChanges(); // update view with the quote + // expect(getQuote()).toBe(quotes[0]); + // }); + // // jasmine.clock().tick(5000); + // // fixture.whenStable().then(() => { + // // fixture.detectChanges(); // update view with the quote + // // expect(getQuote()).toBe(quotes[1]); + // // }); + // })); + + it('should show quote after getQuote promise returns', fakeAsync(() => { + fixture.detectChanges(); // trigger data binding + tick(); // wait for first async getQuote to return + fixture.detectChanges(); // update view with the quote + expect(getQuote()).toBe(quotes[0]); + + // destroy component to stop the component timer before test ends + // else test errors because still have timer in the queue + fixture.destroy(); + })); + + it('should show 2nd quote after 5 seconds pass', fakeAsync(() => { + fixture.detectChanges(); // trigger data binding + tick(5000); // wait for second async getQuote to return + fixture.detectChanges(); // update view with the quote + expect(getQuote()).toBe(quotes[1]); + + // still have intervalTimer queuing requres + // discardPeriodicTasks() else test errors + discardPeriodicTasks(); + })); + + fit('should show 3rd quote after 10 seconds pass', fakeAsync(() => { + fixture.detectChanges(); // trigger data binding + tick(5000); // wait for second async getQuote to return + fixture.detectChanges(); // update view with the 2nd quote + tick(5000); // wait for third async getQuote to return + fixture.detectChanges(); // update view with the 3rd quote + expect(getQuote()).toBe(quotes[2]); + + // still have intervalTimer queuing requres + // discardPeriodicTasks() else test errors + discardPeriodicTasks(); + })); + // #enddocregion tests +}); diff --git a/public/docs/_examples/testing/ts/src/app/shared/twain.component.timer.ts.no-work b/public/docs/_examples/testing/ts/src/app/shared/twain.component.timer.ts.no-work new file mode 100644 index 0000000000..d3dc1f205d --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/shared/twain.component.timer.ts.no-work @@ -0,0 +1,27 @@ +// #docregion +import { Component, OnInit, OnDestroy } from '@angular/core'; + +import { TwainService } from './twain.service'; + +@Component({ + selector: 'twain-quote', + template: '

    {{quote}}

    ' +}) +export class TwainComponent implements OnInit, OnDestroy { + intervalId: number; + quote = '-- not initialized yet --'; + constructor(private twainService: TwainService) { } + + getQuote() { + this.twainService.getQuote().then(quote => this.quote = quote); + } + + ngOnInit(): void { + this.getQuote(); + this.intervalId = window.setInterval(() => this.getQuote(), 5000); + } + + ngOnDestroy(): void { + clearInterval(this.intervalId); + } +} diff --git a/public/docs/_examples/testing/ts/src/app/shared/twain.component.ts b/public/docs/_examples/testing/ts/src/app/shared/twain.component.ts new file mode 100644 index 0000000000..29f24459ab --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/shared/twain.component.ts @@ -0,0 +1,20 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; + +import { TwainService } from './twain.service'; + +// #docregion component +@Component({ + selector: 'twain-quote', + template: '

    {{quote}}

    ' +}) +export class TwainComponent implements OnInit { + intervalId: number; + quote = '...'; + constructor(private twainService: TwainService) { } + + ngOnInit(): void { + this.twainService.getQuote().then(quote => this.quote = quote); + } +} +// #enddocregion component diff --git a/public/docs/_examples/testing/ts/src/app/shared/twain.service.ts b/public/docs/_examples/testing/ts/src/app/shared/twain.service.ts new file mode 100644 index 0000000000..9e394df1ee --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/shared/twain.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@angular/core'; + +const quotes = [ +'Always do right. This will gratify some people and astonish the rest.', +'I have never let my schooling interfere with my education.', +'Don\'t go around saying the world owes you a living. The world owes you nothing. It was here first.', +'Whenever you find yourself on the side of the majority, it is time to pause and reflect.', +'If you tell the truth, you don\'t have to remember anything.', +'Clothes make the man. Naked people have little or no influence on society.', +'It\'s not the size of the dog in the fight, it\'s the size of the fight in the dog.', +'Truth is stranger than fiction, but it is because Fiction is obliged to stick to possibilities; Truth isn\'t.', +'The man who does not read good books has no advantage over the man who cannot read them.', +'Get your facts first, and then you can distort them as much as you please.', +]; + +@Injectable() +export class TwainService { + private next = 0; + + // Imaginary todo: get quotes from a remote quote service + // returns quote after delay simulating server latency + getQuote(): Promise { + return new Promise(resolve => { + setTimeout( () => resolve(this.nextQuote()), 500 ); + }); + } + + private nextQuote() { + if (this.next === quotes.length) { this.next = 0; } + return quotes[ this.next++ ]; + } +} diff --git a/public/docs/_examples/testing/ts/src/app/welcome.component.spec.ts b/public/docs/_examples/testing/ts/src/app/welcome.component.spec.ts new file mode 100644 index 0000000000..e506dda396 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/welcome.component.spec.ts @@ -0,0 +1,108 @@ +// #docplaster +import { ComponentFixture, inject, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { UserService } from './model'; +import { WelcomeComponent } from './welcome.component'; + +describe('WelcomeComponent', () => { + + let comp: WelcomeComponent; + let fixture: ComponentFixture; + let componentUserService: UserService; // the actually injected service + let userService: UserService; // the TestBed injected service + let de: DebugElement; // the DebugElement with the welcome message + let el: HTMLElement; // the DOM element with the welcome message + + let userServiceStub: { + isLoggedIn: boolean; + user: { name: string} + }; + + // #docregion setup + beforeEach(() => { + // stub UserService for test purposes + // #docregion user-service-stub + userServiceStub = { + isLoggedIn: true, + user: { name: 'Test User'} + }; + // #enddocregion user-service-stub + + // #docregion config-test-module + TestBed.configureTestingModule({ + declarations: [ WelcomeComponent ], + // #enddocregion setup + // providers: [ UserService ] // NO! Don't provide the real service! + // Provide a test-double instead + // #docregion setup + providers: [ {provide: UserService, useValue: userServiceStub } ] + }); + // #enddocregion config-test-module + + fixture = TestBed.createComponent(WelcomeComponent); + comp = fixture.componentInstance; + + // #enddocregion setup + // #docregion injected-service + // UserService actually injected into the component + userService = fixture.debugElement.injector.get(UserService); + // #enddocregion injected-service + componentUserService = userService; + // #docregion setup + // #docregion inject-from-testbed + // UserService from the root injector + userService = TestBed.get(UserService); + // #enddocregion inject-from-testbed + + // get the "welcome" element by CSS selector (e.g., by class name) + de = fixture.debugElement.query(By.css('.welcome')); + el = de.nativeElement; + }); + // #enddocregion setup + + // #docregion tests + it('should welcome the user', () => { + fixture.detectChanges(); + const content = el.textContent; + expect(content).toContain('Welcome', '"Welcome ..."'); + expect(content).toContain('Test User', 'expected name'); + }); + + it('should welcome "Bubba"', () => { + userService.user.name = 'Bubba'; // welcome message hasn't been shown yet + fixture.detectChanges(); + expect(el.textContent).toContain('Bubba'); + }); + + it('should request login if not logged in', () => { + userService.isLoggedIn = false; // welcome message hasn't been shown yet + fixture.detectChanges(); + const content = el.textContent; + expect(content).not.toContain('Welcome', 'not welcomed'); + expect(content).toMatch(/log in/i, '"log in"'); + }); + // #enddocregion tests + + // #docregion inject-it + it('should inject the component\'s UserService instance', + inject([UserService], (service: UserService) => { + expect(service).toBe(componentUserService); + })); + // #enddocregion inject-it + + it('TestBed and Component UserService should be the same', () => { + expect(userService === componentUserService).toBe(true); + }); + + // #docregion stub-not-injected + it('stub object and injected UserService should not be the same', () => { + expect(userServiceStub === userService).toBe(false); + + // Changing the stub object has no effect on the injected service + userServiceStub.isLoggedIn = false; + expect(userService.isLoggedIn).toBe(true); + }); + // #enddocregion stub-not-injected +}); diff --git a/public/docs/_examples/testing/ts/src/app/welcome.component.ts b/public/docs/_examples/testing/ts/src/app/welcome.component.ts new file mode 100644 index 0000000000..35958cc5c9 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/app/welcome.component.ts @@ -0,0 +1,18 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; +import { UserService } from './model'; + +@Component({ + selector: 'app-welcome', + template: '

    {{welcome}}

    ' +}) +export class WelcomeComponent implements OnInit { + welcome = '-- not initialized yet --'; + constructor(private userService: UserService) { } + + ngOnInit(): void { + this.welcome = this.userService.isLoggedIn ? + 'Welcome, ' + this.userService.user.name : + 'Please log in.'; + } +} diff --git a/public/docs/_examples/testing/ts/src/bag-specs.html b/public/docs/_examples/testing/ts/src/bag-specs.html new file mode 100644 index 0000000000..89b46f7056 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/bag-specs.html @@ -0,0 +1,42 @@ + + + + + + + Specs Bag + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/testing/ts/src/bag.html b/public/docs/_examples/testing/ts/src/bag.html new file mode 100644 index 0000000000..3e0fcb9025 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/bag.html @@ -0,0 +1,26 @@ + + + + + + Specs Bag + + + + + + + + + + + + + + + + Loading ... + + diff --git a/public/docs/_examples/testing/ts/src/banner-inline-specs.html b/public/docs/_examples/testing/ts/src/banner-inline-specs.html new file mode 100644 index 0000000000..2a512a5647 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/banner-inline-specs.html @@ -0,0 +1,40 @@ + + + + + + + Banner Component (inline template) Specs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/testing/ts/src/banner-specs.html b/public/docs/_examples/testing/ts/src/banner-specs.html new file mode 100644 index 0000000000..d16dd977a4 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/banner-specs.html @@ -0,0 +1,40 @@ + + + + + + + Banner Component Specs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/testing/ts/src/browser-test-shim.js b/public/docs/_examples/testing/ts/src/browser-test-shim.js new file mode 100644 index 0000000000..ee21831e22 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/browser-test-shim.js @@ -0,0 +1,87 @@ +// BROWSER TESTING SHIM +// Keep it in-sync with what karma-test-shim does +// #docregion +/*global jasmine, __karma__, window*/ +(function () { + +Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing. + +// Uncomment to get full stacktrace output. Sometimes helpful, usually not. +// Error.stackTraceLimit = Infinity; // + +jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000; + +var baseURL = document.baseURI; +baseURL = baseURL + baseURL[baseURL.length-1] ? '' : '/'; + +System.config({ + baseURL: baseURL, + // Extend usual application package list with test folder + packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } }, + + // Assume npm: is set in `paths` in systemjs.config + // Map the angular testing umd bundles + map: { + '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js', + '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js', + '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js', + '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js', + '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js', + '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js', + '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js', + '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js', + }, +}); + +System.import('systemjs.config.js') + .then(importSystemJsExtras) + .then(initTestBed) + .then(initTesting); + +/** Optional SystemJS configuration extras. Keep going w/o it */ +function importSystemJsExtras(){ + return System.import('systemjs.config.extras.js') + .catch(function(reason) { + console.log( + 'Note: System.import could not load "systemjs.config.extras.js" where you might have added more configuration. It is an optional file so we will continue without it.' + ); + console.log(reason); + }); +} + +function initTestBed(){ + return Promise.all([ + System.import('@angular/core/testing'), + System.import('@angular/platform-browser-dynamic/testing') + ]) + + .then(function (providers) { + var coreTesting = providers[0]; + var browserTesting = providers[1]; + + coreTesting.TestBed.initTestEnvironment( + browserTesting.BrowserDynamicTestingModule, + browserTesting.platformBrowserDynamicTesting()); + }) +} + +// Import all spec files defined in the html (__spec_files__) +// and start Jasmine testrunner +function initTesting () { + console.log('loading spec files: '+__spec_files__.join(', ')); + return Promise.all( + __spec_files__.map(function(spec) { + return System.import(spec); + }) + ) + // After all imports load, re-execute `window.onload` which + // triggers the Jasmine test-runner start or explain what went wrong + .then(success, console.error.bind(console)); + + function success () { + console.log('Spec files loaded; starting Jasmine testrunner'); + window.onload(); + } +} + +})(); diff --git a/public/docs/_examples/testing/ts/src/index.html b/public/docs/_examples/testing/ts/src/index.html new file mode 100644 index 0000000000..fff2464efc --- /dev/null +++ b/public/docs/_examples/testing/ts/src/index.html @@ -0,0 +1,27 @@ + + + + + + App Under Test + + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/testing/ts/src/main.ts b/public/docs/_examples/testing/ts/src/main.ts new file mode 100644 index 0000000000..fadce2f3c1 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/main.ts @@ -0,0 +1,5 @@ +// main app entry point +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/testing/ts/src/systemjs.config.extras.js b/public/docs/_examples/testing/ts/src/systemjs.config.extras.js new file mode 100644 index 0000000000..218e65715c --- /dev/null +++ b/public/docs/_examples/testing/ts/src/systemjs.config.extras.js @@ -0,0 +1,9 @@ +// #docregion +/** App specific SystemJS configuration */ +System.config({ + packages: { + // barrels + 'app/model': {main:'index.js', defaultExtension:'js'}, + 'app/model/testing': {main:'index.js', defaultExtension:'js'} + } +}); diff --git a/public/docs/_examples/testing/ts/src/testing/index.ts b/public/docs/_examples/testing/ts/src/testing/index.ts new file mode 100644 index 0000000000..e3de5164ca --- /dev/null +++ b/public/docs/_examples/testing/ts/src/testing/index.ts @@ -0,0 +1,43 @@ +import { DebugElement } from '@angular/core'; +import { tick, ComponentFixture } from '@angular/core/testing'; + +export * from './jasmine-matchers'; +export * from './router-stubs'; + +///// Short utilities ///// + +/** Wait a tick, then detect changes */ +export function advance(f: ComponentFixture): void { + tick(); + f.detectChanges(); +} + +/** + * Create custom DOM event the old fashioned way + * + * https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent + * Although officially deprecated, some browsers (phantom) don't accept the preferred "new Event(eventName)" + */ +export function newEvent(eventName: string, bubbles = false, cancelable = false) { + let evt = document.createEvent('CustomEvent'); // MUST be 'CustomEvent' + evt.initCustomEvent(eventName, bubbles, cancelable, null); + return evt; +} + +// See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button +// #docregion click-event +/** Button events to pass to `DebugElement.triggerEventHandler` for RouterLink event handler */ +export const ButtonClickEvents = { + left: { button: 0 }, + right: { button: 2 } +}; + +/** Simulate element click. Defaults to mouse left-button click event. */ +export function click(el: DebugElement | HTMLElement, eventObj: any = ButtonClickEvents.left): void { + if (el instanceof HTMLElement) { + el.click(); + } else { + el.triggerEventHandler('click', eventObj); + } +} +// #enddocregion click-event diff --git a/public/docs/_examples/testing/ts/src/testing/jasmine-matchers.d.ts b/public/docs/_examples/testing/ts/src/testing/jasmine-matchers.d.ts new file mode 100644 index 0000000000..f1c5acf77c --- /dev/null +++ b/public/docs/_examples/testing/ts/src/testing/jasmine-matchers.d.ts @@ -0,0 +1,5 @@ +declare namespace jasmine { + interface Matchers { + toHaveText(actual: any, expectationFailOutput?: any): jasmine.CustomMatcher; + } +} diff --git a/public/docs/_examples/testing/ts/src/testing/jasmine-matchers.ts b/public/docs/_examples/testing/ts/src/testing/jasmine-matchers.ts new file mode 100644 index 0000000000..4cab02e148 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/testing/jasmine-matchers.ts @@ -0,0 +1,45 @@ +/// + +//// Jasmine Custom Matchers //// +// Be sure to extend jasmine-matchers.d.ts when adding matchers + +export function addMatchers(): void { + jasmine.addMatchers({ + toHaveText: toHaveText + }); +} + +function toHaveText(): jasmine.CustomMatcher { + return { + compare: function (actual: any, expectedText: string, expectationFailOutput?: any): jasmine.CustomMatcherResult { + const actualText = elementText(actual); + const pass = actualText.indexOf(expectedText) > -1; + const message = pass ? '' : composeMessage(); + return { pass, message }; + + function composeMessage () { + const a = (actualText.length < 100 ? actualText : actualText.substr(0, 100) + '...'); + const efo = expectationFailOutput ? ` '${expectationFailOutput}'` : ''; + return `Expected element to have text content '${expectedText}' instead of '${a}'${efo}`; + } + } + }; +} + +function elementText(n: any): string { + if (n instanceof Array) { + return n.map(elementText).join(''); + } + + if (n.nodeType === Node.COMMENT_NODE) { + return ''; + } + + if (n.nodeType === Node.ELEMENT_NODE && n.hasChildNodes()) { + return elementText(Array.prototype.slice.call(n.childNodes)); + } + + if (n.nativeElement) { n = n.nativeElement; } + + return n.textContent; +} diff --git a/public/docs/_examples/testing/ts/src/testing/router-stubs.ts b/public/docs/_examples/testing/ts/src/testing/router-stubs.ts new file mode 100644 index 0000000000..75a2858f65 --- /dev/null +++ b/public/docs/_examples/testing/ts/src/testing/router-stubs.ts @@ -0,0 +1,57 @@ + // export for convenience. +export { ActivatedRoute, Router, RouterLink, RouterOutlet} from '@angular/router'; + +import { Component, Directive, Injectable, Input } from '@angular/core'; +import { NavigationExtras } from '@angular/router'; + +// #docregion router-link +@Directive({ + selector: '[routerLink]', + host: { + '(click)': 'onClick()' + } +}) +export class RouterLinkStubDirective { + @Input('routerLink') linkParams: any; + navigatedTo: any = null; + + onClick() { + this.navigatedTo = this.linkParams; + } +} +// #enddocregion router-link + +@Component({selector: 'router-outlet', template: ''}) +export class RouterOutletStubComponent { } + +@Injectable() +export class RouterStub { + navigate(commands: any[], extras?: NavigationExtras) { } +} + + +// Only implements params and part of snapshot.params +// #docregion activated-route-stub +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; + +@Injectable() +export class ActivatedRouteStub { + + // ActivatedRoute.params is Observable + private subject = new BehaviorSubject(this.testParams); + params = this.subject.asObservable(); + + // Test parameters + private _testParams: {}; + get testParams() { return this._testParams; } + set testParams(params: {}) { + this._testParams = params; + this.subject.next(params); + } + + // ActivatedRoute.snapshot.params + get snapshot() { + return { params: this.testParams }; + } +} +// #enddocregion activated-route-stub diff --git a/public/docs/_examples/testing/ts/test-helpers/dom-setup.ts.not-yet b/public/docs/_examples/testing/ts/test-helpers/dom-setup.ts.not-yet deleted file mode 100644 index 5e8f6d03a7..0000000000 --- a/public/docs/_examples/testing/ts/test-helpers/dom-setup.ts.not-yet +++ /dev/null @@ -1,18 +0,0 @@ -/////// MUST IMPORT AND EXECUTE BEFORE TestComponentBuilder TESTS //////////// - -// CRAZY BUG WORKAROUND: -// Must FIRST import and mention something (anything?) from angular -// else this file hangs systemjs for almost a minute -import { bind } from 'angular2/angular2'; -function noop() { return bind; } - -/////// THIS SECTION REALLY SHOULD BE EXECUTED FOR US BY ANGULAR //////////// -// should be in `angular2/test` or `angular2/angular2` but it isn't yet -import {BrowserDomAdapter} from 'angular2/src/core/dom/browser_adapter'; - -if (BrowserDomAdapter) { - // MUST be called before any specs involving the TestComponentBuilder - BrowserDomAdapter.makeCurrent(); -} else { - console.log("BrowserDomAdapter not found; TestComponentBuilder tests will fail"); -} diff --git a/public/docs/_examples/testing/ts/test-helpers/test-helpers.ts.not-yet b/public/docs/_examples/testing/ts/test-helpers/test-helpers.ts.not-yet deleted file mode 100644 index e39f4ae8ee..0000000000 --- a/public/docs/_examples/testing/ts/test-helpers/test-helpers.ts.not-yet +++ /dev/null @@ -1,103 +0,0 @@ -import {FunctionWithParamTokens, injectAsync,RootTestComponent, TestComponentBuilder} from 'angular2/testing'; -import {By} from 'angular2/angular2' - -///////// Should be in testing ///////// - -export type DoneFn = { - fail: (err?:any) => void, - (done?:any): () => void -} - -///////// injectAsync extensions /// - -type PromiseLikeTestFn = (...args:any[]) => PromiseLike; -type PromiseLikeTcbTestFn = (tcb: TestComponentBuilder, ...args:any[]) => PromiseLike; - -/** Run an async component test within Angular test bed using TestComponentBuilder -// Example -// it('async Component test', tcb => { -// // your test here -// // your test here -// // your test here -// return aPromise; -// }); -// -// May precede the test fn with some injectables which will be passed as args AFTER the TestComponentBuilder -// Example: -// it('async Component test w/ injectables', [HeroService], (tcb, service:HeroService) => { -// // your test here -// return aPromise; -// }); -*/ -export function injectTcb(testFn: (tcb: TestComponentBuilder) => PromiseLike): FunctionWithParamTokens; -export function injectTcb(dependencies: any[], testFn: PromiseLikeTcbTestFn): FunctionWithParamTokens; -export function injectTcb(dependencies: any[] | PromiseLikeTcbTestFn, testFn?: PromiseLikeTcbTestFn) { - - if (typeof dependencies === 'function' ){ - testFn = dependencies; - dependencies = []; - } - - return injectAsync([TestComponentBuilder, ...(dependencies)], testFn); -} -///////// inspectors and expectations ///////// - -export function getSelectedHtml(rootTC: RootTestComponent, selector: string) { - var debugElement = rootTC.debugElement.query(By.css(selector)); - return debugElement && debugElement.nativeElement && debugElement.nativeElement.innerHTML; -} - -export function expectSelectedHtml(rootTC: RootTestComponent, selector: string) { - return expect(getSelectedHtml(rootTC, selector)); -} - -export function getSelectedClassName(rootTC: RootTestComponent, selector: string) { - var debugElement = rootTC.debugElement.query(By.css(selector)); - return debugElement && debugElement.nativeElement && debugElement.nativeElement.className; -} - -export function expectSelectedClassName(rootTC: RootTestComponent, selector: string) { - return expect(getSelectedClassName(rootTC, selector)); -} - -export function getViewChildHtml(rootTC: RootTestComponent, elIndex: number = 0) { - let child = rootTC.debugElement.componentViewChildren[elIndex]; - return child && child.nativeElement && child.nativeElement.innerHTML -} - -export function expectViewChildHtml(rootTC: RootTestComponent, elIndex: number = 0) { - return expect(getViewChildHtml(rootTC, elIndex)); -} - -export function expectViewChildClass(rootTC: RootTestComponent, elIndex: number = 0) { - let child = rootTC.debugElement.componentViewChildren[elIndex]; - return expect(child && child.nativeElement && child.nativeElement.className); -} - -export function dispatchEvent(element: Element, eventType: string) { - element.dispatchEvent(new Event(eventType)); -} - -/** Let time pass so that DOM or Ng can react -// returns a promise that returns ("passes through") -// the value resolved in the previous `then` (if any) -// after delaying for [millis] which is zero by default. -// Example (passing along the rootTC w/ no delay): -// ... -// return rootTC; // optional -// }) -// .then(tick) -// .then(rootTC:RTC => { .. do something ..}); -// -// Example (passing along nothing in particular w/ 10ms delay): -// ... -// // don't care if it returns something or not -// }) -// .then(_ => tick(_, 10)) // ten milliseconds pass -// .then(() => { .. do something ..}); -*/ -export function tick(passThru?: any, millis: number = 0){ - return new Promise((resolve, reject) =>{ - setTimeout(() => resolve(passThru), millis); - }); -} \ No newline at end of file diff --git a/public/docs/_examples/testing/ts/test-shim.js b/public/docs/_examples/testing/ts/test-shim.js deleted file mode 100644 index 31e1998e69..0000000000 --- a/public/docs/_examples/testing/ts/test-shim.js +++ /dev/null @@ -1,48 +0,0 @@ -/*global jasmine, __karma__, window*/ - -// Browser testing shim -(function () { - -// Error.stackTraceLimit = Infinity; - -jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; - -// Configure systemjs to use the .js extension for imports from the app folder -System.config({ - packages: { - app: { - format: 'register', - defaultExtension: 'js' - } - } -}); - -// Configure Angular for the browser and with test versions of the platform providers -System.import('angular2/testing') - .then(function (testing) { - return System.import('angular2/platform/testing/browser') - .then(function (providers) { - testing.setBaseTestProviders( - providers.TEST_BROWSER_PLATFORM_PROVIDERS, - providers.TEST_BROWSER_APPLICATION_PROVIDERS - ); - }); - }) - - // Load the spec files (__spec_files__) explicitly - .then(function () { - console.log('loading spec files: '+__spec_files__.join(', ')); - return Promise.all(__spec_files__.map(function(spec) { return System.import(spec);} )); - }) - - // After all imports load, re-execute `window.onload` which - // triggers the Jasmine test-runner start or explain what went wrong - .then(success, console.error.bind(console)); - -function success () { - console.log('Spec files loaded; starting Jasmine testrunner'); - window.onload(); -} - - -})(); diff --git a/public/docs/_examples/testing/ts/tsconfig.1.json b/public/docs/_examples/testing/ts/tsconfig.1.json deleted file mode 100644 index 062cf1bcb4..0000000000 --- a/public/docs/_examples/testing/ts/tsconfig.1.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "module": "system", - "moduleResolution": "node", - "sourceMap": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "removeComments": false, - "noImplicitAny": true, - "suppressImplicitAnyIndexErrors": true - } -} diff --git a/public/docs/_examples/testing/ts/unit-tests-0.html b/public/docs/_examples/testing/ts/unit-tests-0.html deleted file mode 100644 index af7d1b9192..0000000000 --- a/public/docs/_examples/testing/ts/unit-tests-0.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - Ng App Unit Tests - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/testing/ts/unit-tests-1.html b/public/docs/_examples/testing/ts/unit-tests-1.html deleted file mode 100644 index b370ca053a..0000000000 --- a/public/docs/_examples/testing/ts/unit-tests-1.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - Ng App Unit Tests - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/testing/ts/unit-tests-2.html b/public/docs/_examples/testing/ts/unit-tests-2.html deleted file mode 100644 index d47b4d1f60..0000000000 --- a/public/docs/_examples/testing/ts/unit-tests-2.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - Ng App Unit Tests - - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/testing/ts/unit-tests-3.html b/public/docs/_examples/testing/ts/unit-tests-3.html deleted file mode 100644 index 349606bd6d..0000000000 --- a/public/docs/_examples/testing/ts/unit-tests-3.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - Ng App Unit Tests - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/testing/ts/unit-tests-4.html b/public/docs/_examples/testing/ts/unit-tests-4.html deleted file mode 100644 index a3e252fdb0..0000000000 --- a/public/docs/_examples/testing/ts/unit-tests-4.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - Ng App Unit Tests - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/testing/ts/unit-tests-5.html b/public/docs/_examples/testing/ts/unit-tests-5.html deleted file mode 100644 index b95b36760a..0000000000 --- a/public/docs/_examples/testing/ts/unit-tests-5.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - Ng App Unit Tests - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/testing/ts/unit-tests-6.html.not-yet b/public/docs/_examples/testing/ts/unit-tests-6.html.not-yet deleted file mode 100644 index df8e3704ba..0000000000 --- a/public/docs/_examples/testing/ts/unit-tests-6.html.not-yet +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - Ng App Unit Tests - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/docs/_examples/testing/ts/unit-tests-7.html.not-yet b/public/docs/_examples/testing/ts/unit-tests-7.html.not-yet deleted file mode 100644 index d5449711ee..0000000000 --- a/public/docs/_examples/testing/ts/unit-tests-7.html.not-yet +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - Ng App Unit Tests - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/docs/_examples/testing/ts/unit-tests-bag.html b/public/docs/_examples/testing/ts/unit-tests-bag.html deleted file mode 100644 index f373c387e8..0000000000 --- a/public/docs/_examples/testing/ts/unit-tests-bag.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Bag of Unit Tests - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/testing/ts/unit-tests.html.not-yet b/public/docs/_examples/testing/ts/unit-tests.html.not-yet deleted file mode 100644 index f1b8ab444d..0000000000 --- a/public/docs/_examples/testing/ts/unit-tests.html.not-yet +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - Ng App Unit Tests - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/docs/_examples/testing/ts/wallaby.js b/public/docs/_examples/testing/ts/wallaby.js new file mode 100644 index 0000000000..cd31e158fe --- /dev/null +++ b/public/docs/_examples/testing/ts/wallaby.js @@ -0,0 +1,118 @@ +// Configuration for the Wallaby Visual Studio Code testing extension +// https://marketplace.visualstudio.com/items?itemName=WallabyJs.wallaby-vscode +// Note: Wallaby is not open source and costs money + +module.exports = function () { + return { + files: [ + // System.js for module loading + {pattern: 'node_modules/systemjs/dist/system.js', instrument: false}, + {pattern: 'systemjs.config.js', instrument: false}, + {pattern: 'systemjs.config.extras.js', instrument: false}, + + // Polyfills + {pattern: 'node_modules/core-js/client/shim.min.js', instrument: false}, + + // zone.js + {pattern: 'node_modules/zone.js/dist/zone.js', instrument: false}, + {pattern: 'node_modules/zone.js/dist/long-stack-trace-zone.js', instrument: false}, + {pattern: 'node_modules/zone.js/dist/proxy.js', instrument: false}, + {pattern: 'node_modules/zone.js/dist/sync-test.js', instrument: false}, + {pattern: 'node_modules/zone.js/dist/jasmine-patch.js', instrument: false}, + {pattern: 'node_modules/zone.js/dist/async-test.js', instrument: false}, + {pattern: 'node_modules/zone.js/dist/fake-async-test.js', instrument: false}, + + // application (but not specs) loaded via module imports + {pattern: 'app/**/*+(ts|html|css)', load: false}, + {pattern: 'app/**/*.spec.ts', ignore: true}, + + {pattern: 'testing/**/*+(ts|html|css)', load: false}, + ], + + tests: [ + {pattern: 'app/**/*.spec.ts', load: false} + ], + + middleware: function (app, express) { + app.use('/node_modules', express.static(require('path').join(__dirname, 'node_modules'))); + }, + + testFramework: 'jasmine', + + debug: true, + + bootstrap: bootstrap + }; +}; + +// Like karma-test-shim.js +function bootstrap (wallaby) { + wallaby.delayStart(); + + System.config({ + // Extend usual application package list with test folder + packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } }, + + // Assume npm: is set in `paths` in systemjs.config + // Map the angular testing umd bundles + map: { + '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js', + '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js', + '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js', + '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js', + '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js', + '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js', + '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js', + '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js', + }, + }); + + System.import('systemjs.config.js') + .then(importSystemJsExtras) + .then(initTestBed) + .then(initTesting); + + /** Optional SystemJS configuration extras. Keep going w/o it */ + function importSystemJsExtras(){ + return System.import('systemjs.config.extras.js') + .catch(function(reason) { + console.log( + 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.' + ); + console.log(reason); + }); + } + + function initTestBed(){ + return Promise.all([ + System.import('@angular/core/testing'), + System.import('@angular/platform-browser-dynamic/testing') + ]) + + .then(function (providers) { + var coreTesting = providers[0]; + var browserTesting = providers[1]; + + coreTesting.TestBed.initTestEnvironment( + browserTesting.BrowserDynamicTestingModule, + browserTesting.platformBrowserDynamicTesting()); + }) + } + + // Load all spec files and start wallaby + function initTesting () { + return Promise.all( + wallaby.tests.map(function (specFile) { + return System.import(specFile); + }) + ) + .then(function () { + wallaby.start(); + }) + .catch(function (e) { + setTimeout(function () { + throw e; + }, 0); + }); + } +} diff --git a/public/docs/_examples/toh-1/dart-snippets/app_component_snippets_pt1.dart b/public/docs/_examples/toh-1/dart-snippets/app_component_snippets_pt1.dart index b3a4e60eaf..3bfa89762d 100644 --- a/public/docs/_examples/toh-1/dart-snippets/app_component_snippets_pt1.dart +++ b/public/docs/_examples/toh-1/dart-snippets/app_component_snippets_pt1.dart @@ -25,17 +25,13 @@ template: '''
    {{hero.id}}
    -
    +
    ''' // #enddocregion editing-Hero // #docregion app-component-1 class AppComponent { String title = 'Tour of Heroes'; - Hero hero = 'Windstorm'; + var hero = 'Windstorm'; } // #enddocregion app-component-1 - -// #docregion hero-property-1 -Hero hero = new Hero(1, 'Windstorm'); -// #enddocregion hero-property-1 diff --git a/public/docs/_examples/toh-1/dart/lib/app_component.dart b/public/docs/_examples/toh-1/dart/lib/app_component.dart deleted file mode 100644 index 7fa504adbf..0000000000 --- a/public/docs/_examples/toh-1/dart/lib/app_component.dart +++ /dev/null @@ -1,28 +0,0 @@ -// #docregion pt1 -import 'package:angular2/core.dart'; - -// #docregion hero-class-1 -class Hero { - final int id; - String name; - - Hero(this.id, this.name); -} -// #enddocregion hero-class-1 - -@Component( - selector: 'my-app', - template: ''' -

    {{title}}

    -

    {{hero.name}} details!

    -
    {{hero.id}}
    -
    - -
    -
    ''' -) -class AppComponent { - String title = 'Tour of Heroes'; - Hero hero = new Hero(1, 'Windstorm'); -} -// #enddocregion pt1 diff --git a/public/docs/_examples/toh-1/dart/pubspec.yaml b/public/docs/_examples/toh-1/dart/pubspec.yaml deleted file mode 100644 index 8b71851f9a..0000000000 --- a/public/docs/_examples/toh-1/dart/pubspec.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# #docregion -name: angular2_tour_of_heroes -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: - - package:angular2/common.dart#COMMON_DIRECTIVES - platform_pipes: - - package:angular2/common.dart#COMMON_PIPES - entry_points: web/main.dart diff --git a/public/docs/_examples/toh-1/dart/web/index.html b/public/docs/_examples/toh-1/dart/web/index.html deleted file mode 100644 index 3c09e8af9d..0000000000 --- a/public/docs/_examples/toh-1/dart/web/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - Angular 2 Tour of Heroes - - - - - - - - Loading... - - diff --git a/public/docs/_examples/toh-1/dart/web/main.dart b/public/docs/_examples/toh-1/dart/web/main.dart deleted file mode 100644 index 81c22cd91d..0000000000 --- a/public/docs/_examples/toh-1/dart/web/main.dart +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion pt1 -import 'package:angular2/platform/browser.dart'; - -import 'package:angular2_tour_of_heroes/app_component.dart'; - -main() { - bootstrap(AppComponent); -} -// #enddocregion pt1 diff --git a/public/docs/_examples/toh-1/e2e-spec.ts b/public/docs/_examples/toh-1/e2e-spec.ts new file mode 100644 index 0000000000..75f99788a6 --- /dev/null +++ b/public/docs/_examples/toh-1/e2e-spec.ts @@ -0,0 +1,70 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by, ElementFinder } from 'protractor'; +import { promise } from 'selenium-webdriver'; + +const expectedH1 = 'Tour of Heroes'; +const expectedTitle = `Angular ${expectedH1}`; + +class Hero { + id: number; + name: string; + + // Factory method + // Get hero id and name from the given detail element. + static async fromDetail(detail: ElementFinder): Promise { + // Get hero id from the first
    + let _id = await detail.all(by.css('div')).first().getText(); + // Get name from the h2 + let _name = await detail.element(by.css('h2')).getText(); + return { + id: +_id.substr(_id.indexOf(' ') + 1), + name: _name.substr(0, _name.lastIndexOf(' ')) + }; + } +} + +const nameSuffix = 'X'; +function addToHeroName(text: string): promise.Promise { + let input = element(by.css('input')); + return input.sendKeys(text); +} + +describe('Tutorial part 1', () => { + + const expectedHero = { id: 1, name: 'Windstorm' }; + + beforeAll(() => browser.get('')); + + it(`has title '${expectedTitle}'`, () => { + expect(browser.getTitle()).toEqual(expectedTitle); + }); + + it(`has h1 '${expectedH1}'`, () => { + let hText = element(by.css('h1')).getText(); + expect(hText).toEqual(expectedH1, 'h1'); + }); + + it(`shows initial hero details`, async () => { + let page = getPageElts(); + let hero = await Hero.fromDetail(page.heroDetail); + expect(hero.id).toEqual(expectedHero.id); + expect(hero.name).toEqual(expectedHero.name); + }); + + it(`shows updated hero name`, async () => { + addToHeroName(nameSuffix); + let page = getPageElts(); + let hero = await Hero.fromDetail(page.heroDetail); + let newName = expectedHero.name + nameSuffix; + expect(hero.id).toEqual(expectedHero.id); + expect(hero.name).toEqual(newName); + }); + +}); + +function getPageElts() { + return { + heroDetail: element(by.css('my-app')) + }; +} diff --git a/public/docs/_examples/toh-1/ts-snippets/app.component.snippets.pt1.ts b/public/docs/_examples/toh-1/ts-snippets/app.component.snippets.pt1.ts deleted file mode 100644 index a62447ad91..0000000000 --- a/public/docs/_examples/toh-1/ts-snippets/app.component.snippets.pt1.ts +++ /dev/null @@ -1,46 +0,0 @@ -// #docregion show-hero -template: '

    {{title}}

    {{hero}} details!

    ' -// #enddocregion show-hero - -// #docregion show-hero-2 -template: '

    {{title}}

    {{hero.name}} details!

    ' -// #enddocregion show-hero-2 - -// #docregion show-hero-properties -template: '

    {{title}}

    {{hero.name}} details!

    {{hero.id}}
    {{hero.name}}
    ' -// #enddocregion show-hero-properties - -// #docregion multi-line-strings -template:` -

    {{title}}

    -

    {{hero.name}} details!

    -
    {{hero.id}}
    -
    {{hero.name}}
    - ` -// #enddocregion multi-line-strings - -// #docregion editing-Hero -template:` -

    {{title}}

    -

    {{hero.name}} details!

    -
    {{hero.id}}
    -
    - - -
    - ` -// #enddocregion editing-Hero - -// #docregion app-component-1 -export class AppComponent { - title = 'Tour of Heroes'; - hero = 'Windstorm'; -} -// #enddocregion app-component-1 - -// #docregion hero-property-1 -hero: Hero = { - id: 1, - name: 'Windstorm' -}; -// #enddocregion hero-property-1 diff --git a/public/docs/_examples/toh-1/ts/app/app.component.1.ts b/public/docs/_examples/toh-1/ts/app/app.component.1.ts new file mode 100644 index 0000000000..371fe39f90 --- /dev/null +++ b/public/docs/_examples/toh-1/ts/app/app.component.1.ts @@ -0,0 +1,44 @@ +import { Component } from '@angular/core'; + +let t = { +// #docregion show-hero +template: `

    {{title}}

    {{hero}} details!

    ` +// #enddocregion show-hero +}; + +t = { +// #docregion show-hero-2 +template: `

    {{title}}

    {{hero.name}} details!

    ` +// #enddocregion show-hero-2 +}; + +t = { +// #docregion multi-line-strings +template: ` +

    {{title}}

    +

    {{hero.name}} details!

    +
    {{hero.id}}
    +
    {{hero.name}}
    + ` +// #enddocregion multi-line-strings +}; + + +/* +// #docregion name-input +
    + + +
    +// #enddocregion name-input +*/ + +///////////////// + +@Component(t) +// #docregion app-component-1 +export class AppComponent { + title = 'Tour of Heroes'; + hero = 'Windstorm'; +} +// #enddocregion app-component-1 diff --git a/public/docs/_examples/toh-1/ts/app/app.component.ts b/public/docs/_examples/toh-1/ts/app/app.component.ts deleted file mode 100644 index b3cd4e8f55..0000000000 --- a/public/docs/_examples/toh-1/ts/app/app.component.ts +++ /dev/null @@ -1,31 +0,0 @@ -// #docregion pt1 -import { Component } from '@angular/core'; - -// #docregion hero-class-1 -export class Hero { - id: number; - name: string; -} -// #enddocregion hero-class-1 - -@Component({ - selector: 'my-app', - template:` -

    {{title}}

    -

    {{hero.name}} details!

    -
    {{hero.id}}
    -
    - - -
    - ` -}) -export class AppComponent { - title = 'Tour of Heroes'; - hero: Hero = { - id: 1, - name: 'Windstorm' - }; -} - -// #enddocregion pt1 diff --git a/public/docs/_examples/toh-1/ts/app/main.ts b/public/docs/_examples/toh-1/ts/app/main.ts deleted file mode 100644 index dae4ddf676..0000000000 --- a/public/docs/_examples/toh-1/ts/app/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -// #docregion pt1 -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); -// #enddocregion pt1 diff --git a/public/docs/_examples/toh-1/ts/index.html b/public/docs/_examples/toh-1/ts/index.html deleted file mode 100644 index f784483eaa..0000000000 --- a/public/docs/_examples/toh-1/ts/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - Angular 2 Tour of Heroes - - - - - - - - - - - - - - - - Loading... - - diff --git a/public/docs/_examples/toh-1/ts/plnkr.json b/public/docs/_examples/toh-1/ts/plnkr.json index 70479d87e5..ca75131d96 100644 --- a/public/docs/_examples/toh-1/ts/plnkr.json +++ b/public/docs/_examples/toh-1/ts/plnkr.json @@ -1,8 +1,10 @@ { "description": "Tour of Heroes: Part 1", + "basePath": "src/", "files":[ "!**/*.d.ts", - "!**/*.js" + "!**/*.js", + "!**/*.[1].*" ], "tags": ["tutorial", "tour", "heroes"] } diff --git a/public/docs/_examples/toh-1/ts/src/app/app.component.ts b/public/docs/_examples/toh-1/ts/src/app/app.component.ts new file mode 100644 index 0000000000..602781b9ba --- /dev/null +++ b/public/docs/_examples/toh-1/ts/src/app/app.component.ts @@ -0,0 +1,33 @@ +// #docregion +import { Component } from '@angular/core'; + +// #docregion hero-class-1 +export class Hero { + id: number; + name: string; +} +// #enddocregion hero-class-1 + +@Component({ + selector: 'my-app', + // #docregion editing-Hero + template: ` +

    {{title}}

    +

    {{hero.name}} details!

    +
    {{hero.id}}
    +
    + + +
    + ` + // #enddocregion editing-Hero +}) +export class AppComponent { + title = 'Tour of Heroes'; + // #docregion hero-property-1 + hero: Hero = { + id: 1, + name: 'Windstorm' + }; + // #enddocregion hero-property-1 +} diff --git a/public/docs/_examples/toh-1/ts/src/app/app.module.ts b/public/docs/_examples/toh-1/ts/src/app/app.module.ts new file mode 100644 index 0000000000..8e87678efc --- /dev/null +++ b/public/docs/_examples/toh-1/ts/src/app/app.module.ts @@ -0,0 +1,18 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; // <-- NgModel lives here + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule // <-- import the FormsModule before binding with [(ngModel)] + ], + declarations: [ + AppComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/toh-1/ts/src/index.html b/public/docs/_examples/toh-1/ts/src/index.html new file mode 100644 index 0000000000..a217238c6c --- /dev/null +++ b/public/docs/_examples/toh-1/ts/src/index.html @@ -0,0 +1,25 @@ + + + + Angular Tour of Heroes + + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/toh-1/ts/src/main.ts b/public/docs/_examples/toh-1/ts/src/main.ts new file mode 100644 index 0000000000..80ece654a5 --- /dev/null +++ b/public/docs/_examples/toh-1/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); +// #enddocregion diff --git a/public/docs/_examples/toh-2/dart-snippets/app_component_snippets_pt2.dart b/public/docs/_examples/toh-2/dart-snippets/app_component_snippets_pt2.dart index 2e3e2438fd..9f805c5bc5 100644 --- a/public/docs/_examples/toh-2/dart-snippets/app_component_snippets_pt2.dart +++ b/public/docs/_examples/toh-2/dart-snippets/app_component_snippets_pt2.dart @@ -1,5 +1,5 @@ // #docregion ng-for -
  • +
  • {{hero.id}} {{hero.name}}
  • // #enddocregion ng-for @@ -7,14 +7,14 @@ // #docregion heroes-styled

    My Heroes

      -
    • +
    • {{hero.id}} {{hero.name}}
    // #enddocregion heroes-styled // #docregion selectedHero-click -
  • +
  • {{hero.id}} {{hero.name}}
  • // #enddocregion selectedHero-click @@ -53,7 +53,7 @@ final List heroes = mockHeroes; // #enddocregion heroes-template-1 // #docregion heroes-ngfor-1 -
  • +
  • // #enddocregion heroes-ngfor-1 // #docregion class-selected-1 @@ -61,7 +61,7 @@ final List heroes = mockHeroes; // #enddocregion class-selected-1 // #docregion class-selected-2 -
  • {{hero.id}} {{hero.name}} diff --git a/public/docs/_examples/toh-2/dart/lib/app_component.dart b/public/docs/_examples/toh-2/dart/lib/app_component.dart deleted file mode 100644 index 4959afe753..0000000000 --- a/public/docs/_examples/toh-2/dart/lib/app_component.dart +++ /dev/null @@ -1,114 +0,0 @@ -// #docregion pt2 -import 'package:angular2/core.dart'; - -class Hero { - final int id; - String name; - - Hero(this.id, this.name); -} - -@Component( - selector: 'my-app', - template: ''' -

    {{title}}

    -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    -
    -

    {{selectedHero.name}} details!

    -
    {{selectedHero.id}}
    -
    - - -
    -
    - ''', -// #docregion styles-1 - styles: const [ - ''' - .selected { - background-color: #CFD8DC !important; - color: white; - } - .heroes { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 10em; - } - .heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0em; - height: 1.6em; - border-radius: 4px; - } - .heroes li.selected:hover { - color: white; - } - .heroes li:hover { - color: #607D8B; - background-color: #EEE; - left: .1em; - } - .heroes .text { - position: relative; - top: -3px; - } - .heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0em 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0px 0px 4px; - } - ''' - ]) -// #enddocregion styles-1 -class AppComponent { - final String title = 'Tour of Heroes'; - final List heroes = mockHeroes; -// #docregion selected-hero-1 - Hero selectedHero; -// #enddocregion selected-hero-1 - -// #docregion on-select-1 - onSelect(Hero hero) { - selectedHero = hero; - } -// #enddocregion on-select-1 -} -// #enddocregion pt2 - -// #docregion hero-array -final List mockHeroes = [ - new Hero(11, 'Mr. Nice'), - new Hero(12, 'Narco'), - new Hero(13, 'Bombasto'), - new Hero(14, 'Celeritas'), - new Hero(15, 'Magneta'), - new Hero(16, 'RubberMan'), - new Hero(17, 'Dynama'), - new Hero(18, 'Dr IQ'), - new Hero(19, 'Magma'), - new Hero(20, 'Tornado') -]; -// #enddocregion hero-array - -// #enddocregion pt2 diff --git a/public/docs/_examples/toh-2/dart/pubspec.yaml b/public/docs/_examples/toh-2/dart/pubspec.yaml deleted file mode 100644 index 14e92eff11..0000000000 --- a/public/docs/_examples/toh-2/dart/pubspec.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: angular2_tour_of_heroes -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: - - package:angular2/common.dart#COMMON_DIRECTIVES - platform_pipes: - - package:angular2/common.dart#COMMON_PIPES - entry_points: web/main.dart diff --git a/public/docs/_examples/toh-2/dart/web/index.html b/public/docs/_examples/toh-2/dart/web/index.html deleted file mode 100644 index 3c09e8af9d..0000000000 --- a/public/docs/_examples/toh-2/dart/web/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - Angular 2 Tour of Heroes - - - - - - - - Loading... - - diff --git a/public/docs/_examples/toh-2/dart/web/main.dart b/public/docs/_examples/toh-2/dart/web/main.dart deleted file mode 100644 index 129bd9620b..0000000000 --- a/public/docs/_examples/toh-2/dart/web/main.dart +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion pt2 -import 'package:angular2/platform/browser.dart'; - -import 'package:angular2_tour_of_heroes/app_component.dart'; - -main() { - bootstrap(AppComponent); -} -// #enddocregion pt2 diff --git a/public/docs/_examples/toh-2/e2e-spec.ts b/public/docs/_examples/toh-2/e2e-spec.ts new file mode 100644 index 0000000000..34f9fba573 --- /dev/null +++ b/public/docs/_examples/toh-2/e2e-spec.ts @@ -0,0 +1,133 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by, ElementFinder } from 'protractor'; +import { promise } from 'selenium-webdriver'; + +const expectedH1 = 'Tour of Heroes'; +const expectedTitle = `Angular ${expectedH1}`; +const expectedH2 = 'My Heroes'; +const targetHero = { id: 16, name: 'RubberMan' }; +const nameSuffix = 'X'; + +class Hero { + id: number; + name: string; + + // Factory methods + + // Get hero from s formatted as ' '. + static fromString(s: string): Hero { + return { + id: +s.substr(0, s.indexOf(' ')), + name: s.substr(s.indexOf(' ') + 1), + }; + } + + // Get hero id and name from the given detail element. + static async fromDetail(detail: ElementFinder): Promise { + // Get hero id from the first
    + let _id = await detail.all(by.css('div')).first().getText(); + // Get name from the h2 + let _name = await detail.element(by.css('h2')).getText(); + return { + id: +_id.substr(_id.indexOf(' ') + 1), + name: _name.substr(0, _name.lastIndexOf(' ')) + }; + } +} + +describe('Tutorial part 2', () => { + beforeAll(() => browser.get('')); + describe('Initial page', initialPageTests); + describe('Select hero', selectHeroTests); + describe('Update hero', updateHeroTests); +}); + +function initialPageTests() { + it(`has title '${expectedTitle}'`, () => { + expect(browser.getTitle()).toEqual(expectedTitle); + }); + + it(`has h1 '${expectedH1}'`, () => { + expectHeading(1, expectedH1); + }); + + it(`has h2 '${expectedH2}'`, () => { + expectHeading(2, expectedH2); + }); + + it('has the right number of heroes', () => { + let page = getPageElts(); + expect(page.heroes.count()).toEqual(10); + }); + + it('has no selected hero and no hero details', function () { + let page = getPageElts(); + expect(page.selected.isPresent()).toBeFalsy('selected hero'); + expect(page.heroDetail.isPresent()).toBeFalsy('no hero detail'); + }); +} + +function selectHeroTests() { + it(`selects ${targetHero.name} from hero list`, function () { + let hero = element(by.cssContainingText('li span.badge', targetHero.id.toString())); + hero.click(); + // Nothing specific to expect other than lack of exceptions. + }); + + it(`has selected ${targetHero.name}`, function () { + let page = getPageElts(); + let expectedText = `${targetHero.id} ${targetHero.name}`; + expect(page.selected.getText()).toBe(expectedText); + }); + + it('shows selected hero details', async () => { + let page = getPageElts(); + let hero = await Hero.fromDetail(page.heroDetail); + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(targetHero.name); + }); +} + +function updateHeroTests() { + it(`can update hero name`, () => { + addToHeroName(nameSuffix); + // Nothing specific to expect other than lack of exceptions. + }); + + it(`shows updated hero name in details`, async () => { + let page = getPageElts(); + let hero = await Hero.fromDetail(page.heroDetail); + let newName = targetHero.name + nameSuffix; + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(newName); + }); + + it(`shows updated hero name in list`, async () => { + let page = getPageElts(); + let hero = Hero.fromString(await page.selected.getText()); + let newName = targetHero.name + nameSuffix; + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(newName); + }); + +} + +function addToHeroName(text: string): promise.Promise { + let input = element(by.css('input')); + return input.sendKeys(text); +} + +function expectHeading(hLevel: number, expectedText: string): void { + let hTag = `h${hLevel}`; + let hText = element(by.css(hTag)).getText(); + expect(hText).toEqual(expectedText, hTag); +}; + +function getPageElts() { + return { + heroes: element.all(by.css('my-app li')), + selected: element(by.css('my-app li.selected')), + heroDetail: element(by.css('my-app > div, my-app > hero-detail > div')) + }; +} diff --git a/public/docs/_examples/toh-2/ts-snippets/app.component.snippets.pt2.ts b/public/docs/_examples/toh-2/ts-snippets/app.component.snippets.pt2.ts deleted file mode 100644 index 10475a0954..0000000000 --- a/public/docs/_examples/toh-2/ts-snippets/app.component.snippets.pt2.ts +++ /dev/null @@ -1,69 +0,0 @@ -// #docregion ng-for -
  • - {{hero.id}} {{hero.name}} -
  • -// #enddocregion ng-for - -// #docregion heroes-styled -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    -// #enddocregion heroes-styled - -// #docregion selectedHero-click -
  • - {{hero.id}} {{hero.name}} -
  • -// #enddocregion selectedHero-click - -// #docregion selectedHero-details -

    {{selectedHero.name}} details!

    -
    {{selectedHero.id}}
    -
    - - -
    -// #enddocregion selectedHero-details - -// #docregion ng-if -
    -

    {{selectedHero.name}} details!

    -
    {{selectedHero.id}}
    -
    - - -
    -
    -// #enddocregion ng-if - -// #docregion hero-array-1 -public heroes = HEROES; -// #enddocregion hero-array-1 - -// #docregion heroes-template-1 -

    My Heroes

    -
      -
    • - -
    • -
    -// #enddocregion heroes-template-1 - -// #docregion heroes-ngfor-1 -
  • -// #enddocregion heroes-ngfor-1 - -// #docregion class-selected-1 -[class.selected]="hero === selectedHero" -// #enddocregion class-selected-1 - -// #docregion class-selected-2 -
  • - {{hero.id}} {{hero.name}} -
  • -// #enddocregion class-selected-2 diff --git a/public/docs/_examples/toh-2/ts/app/app.component.ts b/public/docs/_examples/toh-2/ts/app/app.component.ts deleted file mode 100644 index 2dee49f08c..0000000000 --- a/public/docs/_examples/toh-2/ts/app/app.component.ts +++ /dev/null @@ -1,110 +0,0 @@ -// #docregion pt2 -import { Component } from '@angular/core'; - -export class Hero { - id: number; - name: string; -} - -@Component({ - selector: 'my-app', - template:` -

    {{title}}

    -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    -
    -

    {{selectedHero.name}} details!

    -
    {{selectedHero.id}}
    -
    - - -
    -
    - `, -// #docregion styles-1 - styles:[` - .selected { - background-color: #CFD8DC !important; - color: white; - } - .heroes { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 15em; - } - .heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; - } - .heroes li.selected:hover { - background-color: #BBD8DC !important; - color: white; - } - .heroes li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; - } - .heroes .text { - position: relative; - top: -3px; - } - .heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; - } - `] -// #enddocregion styles-1 -}) -export class AppComponent { - title = 'Tour of Heroes'; - heroes = HEROES; -// #docregion selected-hero-1 - selectedHero: Hero; -// #enddocregion selected-hero-1 - -// #docregion on-select-1 - onSelect(hero: Hero) { this.selectedHero = hero; } -// #enddocregion on-select-1 -} -// #enddocregion pt2 - -// #docregion hero-array -var HEROES: Hero[] = [ - { "id": 11, "name": "Mr. Nice" }, - { "id": 12, "name": "Narco" }, - { "id": 13, "name": "Bombasto" }, - { "id": 14, "name": "Celeritas" }, - { "id": 15, "name": "Magneta" }, - { "id": 16, "name": "RubberMan" }, - { "id": 17, "name": "Dynama" }, - { "id": 18, "name": "Dr IQ" }, - { "id": 19, "name": "Magma" }, - { "id": 20, "name": "Tornado" } -]; -// #enddocregion hero-array - -// #enddocregion pt2 diff --git a/public/docs/_examples/toh-2/ts/app/main.ts b/public/docs/_examples/toh-2/ts/app/main.ts deleted file mode 100644 index dae4ddf676..0000000000 --- a/public/docs/_examples/toh-2/ts/app/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -// #docregion pt1 -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); -// #enddocregion pt1 diff --git a/public/docs/_examples/toh-2/ts/index.html b/public/docs/_examples/toh-2/ts/index.html deleted file mode 100644 index 485409815c..0000000000 --- a/public/docs/_examples/toh-2/ts/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - Angular 2 Tour of Heros - - - - - - - - - - - - - - - - - Loading... - - diff --git a/public/docs/_examples/toh-2/ts/plnkr.json b/public/docs/_examples/toh-2/ts/plnkr.json index 61add17a65..08c7b9581a 100644 --- a/public/docs/_examples/toh-2/ts/plnkr.json +++ b/public/docs/_examples/toh-2/ts/plnkr.json @@ -1,8 +1,10 @@ { "description": "Tour of Heroes: Part 2", + "basePath": "src/", "files":[ "!**/*.d.ts", - "!**/*.js" + "!**/*.js", + "!**/*.[1].*" ], "tags": ["tutorial", "tour", "heroes"] } diff --git a/public/docs/_examples/toh-2/ts/src/app/app.component.1.html b/public/docs/_examples/toh-2/ts/src/app/app.component.1.html new file mode 100644 index 0000000000..86f8228723 --- /dev/null +++ b/public/docs/_examples/toh-2/ts/src/app/app.component.1.html @@ -0,0 +1,69 @@ + +
  • + {{hero.id}} {{hero.name}} +
  • + + + +

    My Heroes

    +
      +
    • + {{hero.id}} {{hero.name}} +
    • +
    + + + +
  • + ... +
  • + + + +

    {{selectedHero.name}} details!

    +
    {{selectedHero.id}}
    +
    + + +
    + + + +
    +

    {{selectedHero.name}} details!

    +
    {{selectedHero.id}}
    +
    + + +
    +
    + + + +heroes = HEROES; + + + +

    My Heroes

    +
      +
    • + +
    • +
    + + + +
  • + + + +[class.selected]="hero === selectedHero" + + + +
  • + {{hero.id}} {{hero.name}} +
  • + diff --git a/public/docs/_examples/toh-2/ts/src/app/app.component.ts b/public/docs/_examples/toh-2/ts/src/app/app.component.ts new file mode 100644 index 0000000000..3e7c86f150 --- /dev/null +++ b/public/docs/_examples/toh-2/ts/src/app/app.component.ts @@ -0,0 +1,109 @@ +// #docregion +import { Component } from '@angular/core'; + +export class Hero { + id: number; + name: string; +} + +// #docregion hero-array +const HEROES: Hero[] = [ + { id: 11, name: 'Mr. Nice' }, + { id: 12, name: 'Narco' }, + { id: 13, name: 'Bombasto' }, + { id: 14, name: 'Celeritas' }, + { id: 15, name: 'Magneta' }, + { id: 16, name: 'RubberMan' }, + { id: 17, name: 'Dynama' }, + { id: 18, name: 'Dr IQ' }, + { id: 19, name: 'Magma' }, + { id: 20, name: 'Tornado' } +]; +// #enddocregion hero-array + +@Component({ + selector: 'my-app', + template: ` +

    {{title}}

    +

    My Heroes

    +
      +
    • + {{hero.id}} {{hero.name}} +
    • +
    +
    +

    {{selectedHero.name}} details!

    +
    {{selectedHero.id}}
    +
    + + +
    +
    + `, + // #docregion styles + styles: [` + .selected { + background-color: #CFD8DC !important; + color: white; + } + .heroes { + margin: 0 0 2em 0; + list-style-type: none; + padding: 0; + width: 15em; + } + .heroes li { + cursor: pointer; + position: relative; + left: 0; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; + } + .heroes li.selected:hover { + background-color: #BBD8DC !important; + color: white; + } + .heroes li:hover { + color: #607D8B; + background-color: #DDD; + left: .1em; + } + .heroes .text { + position: relative; + top: -3px; + } + .heroes .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0 0 4px; + } + `] + // #enddocregion styles +}) +export class AppComponent { + title = 'Tour of Heroes'; + heroes = HEROES; + // #docregion selected-hero + selectedHero: Hero; + // #enddocregion selected-hero + + // #docregion on-select + onSelect(hero: Hero): void { + this.selectedHero = hero; + } + // #enddocregion on-select +} diff --git a/public/docs/_examples/toh-2/ts/src/app/app.module.ts b/public/docs/_examples/toh-2/ts/src/app/app.module.ts new file mode 100644 index 0000000000..4c0b77ea48 --- /dev/null +++ b/public/docs/_examples/toh-2/ts/src/app/app.module.ts @@ -0,0 +1,18 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule + ], + declarations: [ + AppComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/toh-2/ts/src/index.html b/public/docs/_examples/toh-2/ts/src/index.html new file mode 100644 index 0000000000..a217238c6c --- /dev/null +++ b/public/docs/_examples/toh-2/ts/src/index.html @@ -0,0 +1,25 @@ + + + + Angular Tour of Heroes + + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/toh-2/ts/src/main.ts b/public/docs/_examples/toh-2/ts/src/main.ts new file mode 100644 index 0000000000..80ece654a5 --- /dev/null +++ b/public/docs/_examples/toh-2/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); +// #enddocregion diff --git a/public/docs/_examples/toh-3/dart/lib/app_component.dart b/public/docs/_examples/toh-3/dart/lib/app_component.dart deleted file mode 100644 index 774f8e68f6..0000000000 --- a/public/docs/_examples/toh-3/dart/lib/app_component.dart +++ /dev/null @@ -1,102 +0,0 @@ -//#docregion -import 'package:angular2/core.dart'; - -// #docregion hero-import -import 'hero.dart'; -// #enddocregion hero-import -// #docregion hero-detail-import -import 'hero_detail_component.dart'; -// #enddocregion hero-detail-import - -@Component( - selector: 'my-app', -// #docregion hero-detail-template - template: ''' -

    {{title}}

    -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    - - ''', -// #enddocregion hero-detail-template - styles: const [''' - .selected { - background-color: #CFD8DC !important; - color: white; - } - .heroes { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 10em; - } - .heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0em; - height: 1.6em; - border-radius: 4px; - } - .heroes li.selected:hover { - color: white; - } - .heroes li:hover { - color: #607D8B; - background-color: #EEE; - left: .1em; - } - .heroes .text { - position: relative; - top: -3px; - } - .heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0em 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0px 0px 4px; - } - ''' - ], -// #docregion directives - directives: const [ - HeroDetailComponent - ]) -// #enddocregion directives -class AppComponent { - final String title = 'Tour of Heroes'; - final List heroes = mockHeroes; - Hero selectedHero; - - onSelect(Hero hero) { - selectedHero = hero; - } -} - -final List mockHeroes = [ - new Hero(11, 'Mr. Nice'), - new Hero(12, 'Narco'), - new Hero(13, 'Bombasto'), - new Hero(14, 'Celeritas'), - new Hero(15, 'Magneta'), - new Hero(16, 'RubberMan'), - new Hero(17, 'Dynama'), - new Hero(18, 'Dr IQ'), - new Hero(19, 'Magma'), - new Hero(20, 'Tornado') -]; diff --git a/public/docs/_examples/toh-3/dart/lib/hero.dart b/public/docs/_examples/toh-3/dart/lib/hero.dart deleted file mode 100644 index 71eb336b9c..0000000000 --- a/public/docs/_examples/toh-3/dart/lib/hero.dart +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -class Hero { - final int id; - String name; - - Hero(this.id, this.name); -} -// #enddocregion diff --git a/public/docs/_examples/toh-3/dart/lib/hero_detail_component.dart b/public/docs/_examples/toh-3/dart/lib/hero_detail_component.dart deleted file mode 100644 index e8481c5261..0000000000 --- a/public/docs/_examples/toh-3/dart/lib/hero_detail_component.dart +++ /dev/null @@ -1,39 +0,0 @@ -// #docplaster -// #docregion -// #docregion v1 -import 'package:angular2/core.dart'; - -// #enddocregion v1 -// #docregion hero-import -import 'hero.dart'; -// #enddocregion hero-import - -// #docregion v1 -@Component( - selector: 'my-hero-detail', -// #enddocregion v1 - // #docregion template - template: ''' -
    -

    {{hero.name}} details!

    -
    {{hero.id}}
    -
    - - -
    -
    - ''' - // #enddocregion template -// #docregion v1 - ) -class HeroDetailComponent { -// #enddocregion v1 -// #docregion inputs - @Input() -// #docregion hero - Hero hero; -// #enddocregion hero -// #enddocregion inputs -// #docregion v1 -} -// #enddocregion v1 diff --git a/public/docs/_examples/toh-3/dart/pubspec.yaml b/public/docs/_examples/toh-3/dart/pubspec.yaml deleted file mode 100644 index 14e92eff11..0000000000 --- a/public/docs/_examples/toh-3/dart/pubspec.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: angular2_tour_of_heroes -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: - - package:angular2/common.dart#COMMON_DIRECTIVES - platform_pipes: - - package:angular2/common.dart#COMMON_PIPES - entry_points: web/main.dart diff --git a/public/docs/_examples/toh-3/dart/web/index.html b/public/docs/_examples/toh-3/dart/web/index.html deleted file mode 100644 index 3c09e8af9d..0000000000 --- a/public/docs/_examples/toh-3/dart/web/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - Angular 2 Tour of Heroes - - - - - - - - Loading... - - diff --git a/public/docs/_examples/toh-3/dart/web/main.dart b/public/docs/_examples/toh-3/dart/web/main.dart deleted file mode 100644 index 81c22cd91d..0000000000 --- a/public/docs/_examples/toh-3/dart/web/main.dart +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion pt1 -import 'package:angular2/platform/browser.dart'; - -import 'package:angular2_tour_of_heroes/app_component.dart'; - -main() { - bootstrap(AppComponent); -} -// #enddocregion pt1 diff --git a/public/docs/_examples/toh-3/e2e-spec.ts b/public/docs/_examples/toh-3/e2e-spec.ts new file mode 100644 index 0000000000..842716c5fc --- /dev/null +++ b/public/docs/_examples/toh-3/e2e-spec.ts @@ -0,0 +1,133 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by, ElementFinder } from 'protractor'; +import { promise } from 'selenium-webdriver'; + +const expectedH1 = 'Tour of Heroes'; +const expectedTitle = `Angular ${expectedH1}`; +const expectedH2 = 'My Heroes'; +const targetHero = { id: 16, name: 'RubberMan' }; +const nameSuffix = 'X'; + +class Hero { + id: number; + name: string; + + // Factory methods + + // Get hero from s formatted as ' '. + static fromString(s: string): Hero { + return { + id: +s.substr(0, s.indexOf(' ')), + name: s.substr(s.indexOf(' ') + 1), + }; + } + + // Get hero id and name from the given detail element. + static async fromDetail(detail: ElementFinder): Promise { + // Get hero id from the first
    + let _id = await detail.all(by.css('div')).first().getText(); + // Get name from the h2 + let _name = await detail.element(by.css('h2')).getText(); + return { + id: +_id.substr(_id.indexOf(' ') + 1), + name: _name.substr(0, _name.lastIndexOf(' ')) + }; + } +} + +describe('Tutorial part 3', () => { + beforeAll(() => browser.get('')); + describe('Initial page', initialPageTests); + describe('Select hero', selectHeroTests); + describe('Update hero', updateHeroTests); +}); + +function initialPageTests() { + it(`has title '${expectedTitle}'`, () => { + expect(browser.getTitle()).toEqual(expectedTitle); + }); + + it(`has h1 '${expectedH1}'`, () => { + expectHeading(1, expectedH1); + }); + + it(`has h2 '${expectedH2}'`, () => { + expectHeading(2, expectedH2); + }); + + it('has the right number of heroes', () => { + let page = getPageElts(); + expect(page.heroes.count()).toEqual(10); + }); + + it('has no selected hero and no hero details', function () { + let page = getPageElts(); + expect(page.selected.isPresent()).toBeFalsy('selected hero'); + expect(page.heroDetail.isPresent()).toBeFalsy('no hero detail'); + }); +} + +function selectHeroTests() { + it(`selects ${targetHero.name} from hero list`, function () { + let hero = element(by.cssContainingText('li span.badge', targetHero.id.toString())); + hero.click(); + // Nothing specific to expect other than lack of exceptions. + }); + + it(`has selected ${targetHero.name}`, function () { + let page = getPageElts(); + let expectedText = `${targetHero.id} ${targetHero.name}`; + expect(page.selected.getText()).toBe(expectedText); + }); + + it('shows selected hero details', async () => { + let page = getPageElts(); + let hero = await Hero.fromDetail(page.heroDetail); + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(targetHero.name); + }); +} + +function updateHeroTests() { + it(`can update hero name`, () => { + addToHeroName(nameSuffix); + // Nothing specific to expect other than lack of exceptions. + }); + + it(`shows updated hero name in details`, async () => { + let page = getPageElts(); + let hero = await Hero.fromDetail(page.heroDetail); + let newName = targetHero.name + nameSuffix; + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(newName); + }); + + it(`shows updated hero name in list`, async () => { + let page = getPageElts(); + let hero = Hero.fromString(await page.selected.getText()); + let newName = targetHero.name + nameSuffix; + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(newName); + }); + +} + +function addToHeroName(text: string): promise.Promise { + let input = element(by.css('input')); + return input.sendKeys(text); +} + +function expectHeading(hLevel: number, expectedText: string): void { + let hTag = `h${hLevel}`; + let hText = element(by.css(hTag)).getText(); + expect(hText).toEqual(expectedText, hTag); +}; + +function getPageElts() { + return { + heroes: element.all(by.css('my-app li')), + selected: element(by.css('my-app li.selected')), + heroDetail: element(by.css('my-app > div, my-app > hero-detail > div')) + }; +} diff --git a/public/docs/_examples/toh-3/ts/app/app.component.1.html b/public/docs/_examples/toh-3/ts/app/app.component.1.html new file mode 100644 index 0000000000..bab9dda877 --- /dev/null +++ b/public/docs/_examples/toh-3/ts/app/app.component.1.html @@ -0,0 +1,12 @@ +

    {{title}}

    +

    My Heroes

    +
      +
    • + {{hero.id}} {{hero.name}} +
    • +
    + + + diff --git a/public/docs/_examples/toh-3/ts/app/app.component.ts b/public/docs/_examples/toh-3/ts/app/app.component.ts deleted file mode 100644 index 9fc4f99910..0000000000 --- a/public/docs/_examples/toh-3/ts/app/app.component.ts +++ /dev/null @@ -1,99 +0,0 @@ -//#docregion -import { Component } from '@angular/core'; - -// #docregion hero-import -import { Hero } from './hero'; -// #enddocregion hero-import -// #docregion hero-detail-import -import { HeroDetailComponent } from './hero-detail.component'; -// #enddocregion hero-detail-import - -@Component({ - selector: 'my-app', -// #docregion hero-detail-template - template:` -

    {{title}}

    -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    - - `, -// #enddocregion hero-detail-template - styles:[` - .selected { - background-color: #CFD8DC !important; - color: white; - } - .heroes { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 15em; - } - .heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; - } - .heroes li.selected:hover { - background-color: #BBD8DC !important; - color: white; - } - .heroes li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; - } - .heroes .text { - position: relative; - top: -3px; - } - .heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; - } - `], -// #docregion directives - directives: [HeroDetailComponent] -// #enddocregion directives -}) -export class AppComponent { - title = 'Tour of Heroes'; - heroes = HEROES; - selectedHero: Hero; - - onSelect(hero: Hero) { this.selectedHero = hero; } -} - -var HEROES: Hero[] = [ - { "id": 11, "name": "Mr. Nice" }, - { "id": 12, "name": "Narco" }, - { "id": 13, "name": "Bombasto" }, - { "id": 14, "name": "Celeritas" }, - { "id": 15, "name": "Magneta" }, - { "id": 16, "name": "RubberMan" }, - { "id": 17, "name": "Dynama" }, - { "id": 18, "name": "Dr IQ" }, - { "id": 19, "name": "Magma" }, - { "id": 20, "name": "Tornado" } -]; diff --git a/public/docs/_examples/toh-3/ts/app/hero-detail.component.1.ts b/public/docs/_examples/toh-3/ts/app/hero-detail.component.1.ts new file mode 100644 index 0000000000..fec477fbd7 --- /dev/null +++ b/public/docs/_examples/toh-3/ts/app/hero-detail.component.1.ts @@ -0,0 +1,35 @@ +// #docplaster +// #docregion v1 +import { Component } from '@angular/core'; + +// #enddocregion v1 +// #docregion hero-import +import { Hero } from './hero'; +// #enddocregion hero-import + +// #docregion v1 +@Component({ + selector: 'hero-detail', +// #enddocregion v1 + // #docregion template + template: ` +
    +

    {{hero.name}} details!

    +
    {{hero.id}}
    +
    + + +
    +
    + ` + // #enddocregion template +// #docregion v1 +}) +export class HeroDetailComponent { +// #enddocregion v1 +// #docregion hero + hero: Hero; +// #enddocregion hero +// #docregion v1 +} +// #enddocregion v1 diff --git a/public/docs/_examples/toh-3/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-3/ts/app/hero-detail.component.ts deleted file mode 100644 index 1192359265..0000000000 --- a/public/docs/_examples/toh-3/ts/app/hero-detail.component.ts +++ /dev/null @@ -1,39 +0,0 @@ -// #docplaster -// #docregion -// #docregion v1 -import { Component, Input } from '@angular/core'; - -// #enddocregion v1 -// #docregion hero-import -import { Hero } from './hero'; -// #enddocregion hero-import - -// #docregion v1 -@Component({ - selector: 'my-hero-detail', -// #enddocregion v1 - // #docregion template - template: ` -
    -

    {{hero.name}} details!

    -
    {{hero.id}}
    -
    - - -
    -
    - ` - // #enddocregion template -// #docregion v1 -}) -export class HeroDetailComponent { -// #enddocregion v1 -// #docregion hero-input - @Input() -// #docregion hero - hero: Hero; -// #enddocregion hero -// #enddocregion hero-input -// #docregion v1 -} -// #enddocregion v1 diff --git a/public/docs/_examples/toh-3/ts/app/main.ts b/public/docs/_examples/toh-3/ts/app/main.ts deleted file mode 100644 index dae4ddf676..0000000000 --- a/public/docs/_examples/toh-3/ts/app/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -// #docregion pt1 -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); -// #enddocregion pt1 diff --git a/public/docs/_examples/toh-3/ts/index.html b/public/docs/_examples/toh-3/ts/index.html deleted file mode 100644 index e9c099696b..0000000000 --- a/public/docs/_examples/toh-3/ts/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - Angular 2 Tour of Heroes - - - - - - - - - - - - - - - - - Loading... - - diff --git a/public/docs/_examples/toh-3/ts/plnkr.json b/public/docs/_examples/toh-3/ts/plnkr.json index b6e424dda7..829715877e 100644 --- a/public/docs/_examples/toh-3/ts/plnkr.json +++ b/public/docs/_examples/toh-3/ts/plnkr.json @@ -1,8 +1,10 @@ { "description": "Tour of Heroes: Part 3", + "basePath": "src/", "files":[ "!**/*.d.ts", - "!**/*.js" + "!**/*.js", + "!**/*.[1].*" ], "tags": ["tutorial", "tour", "heroes"] } diff --git a/public/docs/_examples/toh-3/ts/src/app/app.component.ts b/public/docs/_examples/toh-3/ts/src/app/app.component.ts new file mode 100644 index 0000000000..3e242914aa --- /dev/null +++ b/public/docs/_examples/toh-3/ts/src/app/app.component.ts @@ -0,0 +1,95 @@ +// #docregion +import { Component } from '@angular/core'; + +// #docregion hero-import +import { Hero } from './hero'; +// #enddocregion hero-import + +const HEROES: Hero[] = [ + { id: 11, name: 'Mr. Nice' }, + { id: 12, name: 'Narco' }, + { id: 13, name: 'Bombasto' }, + { id: 14, name: 'Celeritas' }, + { id: 15, name: 'Magneta' }, + { id: 16, name: 'RubberMan' }, + { id: 17, name: 'Dynama' }, + { id: 18, name: 'Dr IQ' }, + { id: 19, name: 'Magma' }, + { id: 20, name: 'Tornado' } +]; + +@Component({ + selector: 'my-app', +// #docregion hero-detail-template + template: ` +

    {{title}}

    +

    My Heroes

    +
      +
    • + {{hero.id}} {{hero.name}} +
    • +
    + + `, +// #enddocregion hero-detail-template + styles: [` + .selected { + background-color: #CFD8DC !important; + color: white; + } + .heroes { + margin: 0 0 2em 0; + list-style-type: none; + padding: 0; + width: 15em; + } + .heroes li { + cursor: pointer; + position: relative; + left: 0; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; + } + .heroes li.selected:hover { + background-color: #BBD8DC !important; + color: white; + } + .heroes li:hover { + color: #607D8B; + background-color: #DDD; + left: .1em; + } + .heroes .text { + position: relative; + top: -3px; + } + .heroes .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0 0 4px; + } + `] +}) +export class AppComponent { + title = 'Tour of Heroes'; + heroes = HEROES; + selectedHero: Hero; + + onSelect(hero: Hero): void { + this.selectedHero = hero; + } +} diff --git a/public/docs/_examples/toh-3/ts/src/app/app.module.ts b/public/docs/_examples/toh-3/ts/src/app/app.module.ts new file mode 100644 index 0000000000..e04b8d304b --- /dev/null +++ b/public/docs/_examples/toh-3/ts/src/app/app.module.ts @@ -0,0 +1,24 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +// #docregion hero-detail-import +import { HeroDetailComponent } from './hero-detail.component'; +// #enddocregion hero-detail-import + +@NgModule({ + imports: [ + BrowserModule, + FormsModule + ], +// #docregion declarations + declarations: [ + AppComponent, + HeroDetailComponent + ], +// #enddocregion declarations + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/toh-3/ts/src/app/hero-detail.component.ts b/public/docs/_examples/toh-3/ts/src/app/hero-detail.component.ts new file mode 100644 index 0000000000..45a1a1e7e1 --- /dev/null +++ b/public/docs/_examples/toh-3/ts/src/app/hero-detail.component.ts @@ -0,0 +1,29 @@ +// #docregion +// #docregion import-input +import { Component, Input } from '@angular/core'; +// #enddocregion import-input + +import { Hero } from './hero'; +// #docregion template +@Component({ + selector: 'hero-detail', + template: ` +
    +

    {{hero.name}} details!

    +
    {{hero.id}}
    +
    + + +
    +
    + ` +}) +// #enddocregion template +// #docregion class +export class HeroDetailComponent { +// #docregion hero + @Input() hero: Hero; +// #enddocregion hero +} +// #enddocregion class + diff --git a/public/docs/_examples/toh-3/ts/app/hero.ts b/public/docs/_examples/toh-3/ts/src/app/hero.ts similarity index 100% rename from public/docs/_examples/toh-3/ts/app/hero.ts rename to public/docs/_examples/toh-3/ts/src/app/hero.ts diff --git a/public/docs/_examples/toh-3/ts/src/index.html b/public/docs/_examples/toh-3/ts/src/index.html new file mode 100644 index 0000000000..a217238c6c --- /dev/null +++ b/public/docs/_examples/toh-3/ts/src/index.html @@ -0,0 +1,25 @@ + + + + Angular Tour of Heroes + + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/toh-3/ts/src/main.ts b/public/docs/_examples/toh-3/ts/src/main.ts new file mode 100644 index 0000000000..aa939b3241 --- /dev/null +++ b/public/docs/_examples/toh-3/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion pt1 +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); +// #enddocregion pt1 diff --git a/public/docs/_examples/toh-4/dart/lib/app_component.dart b/public/docs/_examples/toh-4/dart/lib/app_component.dart deleted file mode 100644 index 145030d300..0000000000 --- a/public/docs/_examples/toh-4/dart/lib/app_component.dart +++ /dev/null @@ -1,106 +0,0 @@ -// #docplaster -// #docregion -import 'dart:async'; - -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'hero_detail_component.dart'; -// #docregion hero-service-import -import 'hero_service.dart'; - -// #enddocregion hero-service-import - -@Component( - selector: 'my-app', - template: ''' -

    {{title}}

    -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    - - ''', - styles: const [ - ''' - .selected { - background-color: #CFD8DC !important; - color: white; - } - .heroes { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 10em; - } - .heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0em; - height: 1.6em; - border-radius: 4px; - } - .heroes li.selected:hover { - color: white; - } - .heroes li:hover { - color: #607D8B; - background-color: #EEE; - left: .1em; - } - .heroes .text { - position: relative; - top: -3px; - } - .heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0em 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0px 0px 4px; - } - ''' - ], - directives: const [ - HeroDetailComponent - ], - providers: const [ - HeroService - ]) -class AppComponent implements OnInit { - String title = 'Tour of Heroes'; - List heroes; - Hero selectedHero; - - final HeroService _heroService; - - AppComponent(this._heroService); - -// #docregion get-heroes - getHeroes() async { - heroes = await _heroService.getHeroes(); - } -// #enddocregion get-heroes - - ngOnInit() { - getHeroes(); - } - - onSelect(Hero hero) { - selectedHero = hero; - } -} diff --git a/public/docs/_examples/toh-4/dart/lib/app_component_1.dart b/public/docs/_examples/toh-4/dart/lib/app_component_1.dart deleted file mode 100644 index 7f23cf89fd..0000000000 --- a/public/docs/_examples/toh-4/dart/lib/app_component_1.dart +++ /dev/null @@ -1,64 +0,0 @@ -// #docplaster -// #docregion on-init -import 'package:angular2/core.dart'; - -// #enddocregion on-init -import 'hero.dart'; -import 'hero_detail_component.dart'; -// #docregion hero-service-import -import 'hero_service_1.dart'; -// #enddocregion hero-service-import - -// Testable but never shown -@Component( - selector: 'my-app', - template: ''' -
    - {{hero.name}} -
    - - ''', - directives: const [HeroDetailComponent], - // #docregion providers - providers: const [HeroService]) -// #enddocregion providers -// #docregion on-init -class AppComponent implements OnInit { - // #enddocregion on-init - String title = 'Tour of Heroes'; - // #docregion heroes-prop - List heroes; - // #enddocregion heroes-prop - Hero selectedHero; - - // #docregion new-service - HeroService heroService = new HeroService(); // don't do this - // #enddocregion new-service - // #docregion ctor - final HeroService _heroService; - AppComponent(this._heroService); - // #enddocregion ctor - // #docregion getHeroes - getHeroes() { - //#docregion get-heroes - heroes = _heroService.getHeroes(); - // #enddocregion get-heroes - } - // #enddocregion getHeroes - - // #docregion ng-on-init - // #docregion on-init - ngOnInit() { - // #enddocregion on-init - getHeroes(); - // #docregion on-init - } - // #enddocregion on-init - // #enddocregion ng-on-init - - onSelect(Hero hero) { - selectedHero = hero; - } - // #docregion on-init -} -// #enddocregion on-init diff --git a/public/docs/_examples/toh-4/dart/lib/hero.dart b/public/docs/_examples/toh-4/dart/lib/hero.dart deleted file mode 100644 index 828f8cebab..0000000000 --- a/public/docs/_examples/toh-4/dart/lib/hero.dart +++ /dev/null @@ -1,6 +0,0 @@ -class Hero { - final int id; - String name; - - Hero(this.id, this.name); -} diff --git a/public/docs/_examples/toh-4/dart/lib/hero_detail_component.dart b/public/docs/_examples/toh-4/dart/lib/hero_detail_component.dart deleted file mode 100644 index 8a6144ddfb..0000000000 --- a/public/docs/_examples/toh-4/dart/lib/hero_detail_component.dart +++ /dev/null @@ -1,21 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'hero.dart'; - -@Component( - selector: 'my-hero-detail', - template: ''' -
    -

    {{hero.name}} details!

    -
    {{hero.id}}
    -
    - - -
    -
    - ''', - inputs: const ['hero']) -class HeroDetailComponent { - Hero hero; -} diff --git a/public/docs/_examples/toh-4/dart/lib/hero_service.dart b/public/docs/_examples/toh-4/dart/lib/hero_service.dart deleted file mode 100644 index f3f4f85233..0000000000 --- a/public/docs/_examples/toh-4/dart/lib/hero_service.dart +++ /dev/null @@ -1,26 +0,0 @@ -// #docplaster -// #docregion -// #docregion just-get-heroes -import 'dart:async'; - -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'mock_heroes.dart'; - -@Injectable() -class HeroService { - // #docregion get-heroes - Future> getHeroes() async => mockHeroes; - // #enddocregion get-heroes - // #enddocregion just-get-heroes - // See the "Take it slow" appendix - // #docregion get-heroes-slowly - Future> getHeroesSlowly() { - return new Future.delayed(const Duration(seconds: 2), () => mockHeroes); - } - // #enddocregion get-heroes-slowly - // #docregion just-get-heroes -} -// #enddocregion just-get-heroes -// #enddocregion diff --git a/public/docs/_examples/toh-4/dart/lib/hero_service_1.dart b/public/docs/_examples/toh-4/dart/lib/hero_service_1.dart deleted file mode 100644 index c95aeea7f8..0000000000 --- a/public/docs/_examples/toh-4/dart/lib/hero_service_1.dart +++ /dev/null @@ -1,28 +0,0 @@ -// #docplaster -// #docregion final -// #docregion empty-class -import 'package:angular2/core.dart'; - -// #enddocregion empty-class -import 'hero.dart'; -import 'mock_heroes.dart'; - -// #docregion getHeroes-stub -@Injectable() -class HeroService { -// #enddocregion getHeroes-stub -// #enddocregion empty-class -// #enddocregion final - /* -// #docregion getHeroes-stub - List getHeroes() {} -// #enddocregion getHeroes-stub - */ -// #docregion final - List getHeroes() => mockHeroes; -// #docregion empty-class -// #docregion getHeroes-stub -} -// #enddocregion getHeroes-stub -// #enddocregion empty-class -// #enddocregion final diff --git a/public/docs/_examples/toh-4/dart/lib/mock_heroes.dart b/public/docs/_examples/toh-4/dart/lib/mock_heroes.dart deleted file mode 100644 index 645aa56c25..0000000000 --- a/public/docs/_examples/toh-4/dart/lib/mock_heroes.dart +++ /dev/null @@ -1,16 +0,0 @@ -// #docregion -import 'hero.dart'; - -final List mockHeroes = [ - new Hero(11, 'Mr. Nice'), - new Hero(12, 'Narco'), - new Hero(13, 'Bombasto'), - new Hero(14, 'Celeritas'), - new Hero(15, 'Magneta'), - new Hero(16, 'RubberMan'), - new Hero(17, 'Dynama'), - new Hero(18, 'Dr IQ'), - new Hero(19, 'Magma'), - new Hero(20, 'Tornado') -]; -// #enddocregion diff --git a/public/docs/_examples/toh-4/dart/pubspec.yaml b/public/docs/_examples/toh-4/dart/pubspec.yaml deleted file mode 100644 index 14e92eff11..0000000000 --- a/public/docs/_examples/toh-4/dart/pubspec.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: angular2_tour_of_heroes -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: - - package:angular2/common.dart#COMMON_DIRECTIVES - platform_pipes: - - package:angular2/common.dart#COMMON_PIPES - entry_points: web/main.dart diff --git a/public/docs/_examples/toh-4/dart/web/index.html b/public/docs/_examples/toh-4/dart/web/index.html deleted file mode 100644 index 059daeed4c..0000000000 --- a/public/docs/_examples/toh-4/dart/web/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - Loading... - - diff --git a/public/docs/_examples/toh-4/dart/web/main.dart b/public/docs/_examples/toh-4/dart/web/main.dart deleted file mode 100644 index 81c22cd91d..0000000000 --- a/public/docs/_examples/toh-4/dart/web/main.dart +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion pt1 -import 'package:angular2/platform/browser.dart'; - -import 'package:angular2_tour_of_heroes/app_component.dart'; - -main() { - bootstrap(AppComponent); -} -// #enddocregion pt1 diff --git a/public/docs/_examples/toh-4/dart/web/main_1.dart b/public/docs/_examples/toh-4/dart/web/main_1.dart deleted file mode 100644 index 7d3d59c77d..0000000000 --- a/public/docs/_examples/toh-4/dart/web/main_1.dart +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion pt1 -import 'package:angular2/platform/browser.dart'; - -import 'package:angular2_tour_of_heroes/app_component_1.dart'; - -main() { - bootstrap(AppComponent); -} -// #enddocregion pt1 diff --git a/public/docs/_examples/toh-4/e2e-spec.ts b/public/docs/_examples/toh-4/e2e-spec.ts new file mode 100644 index 0000000000..d6a223dd12 --- /dev/null +++ b/public/docs/_examples/toh-4/e2e-spec.ts @@ -0,0 +1,133 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by, ElementFinder } from 'protractor'; +import { promise } from 'selenium-webdriver'; + +const expectedH1 = 'Tour of Heroes'; +const expectedTitle = `Angular ${expectedH1}`; +const expectedH2 = 'My Heroes'; +const targetHero = { id: 16, name: 'RubberMan' }; +const nameSuffix = 'X'; + +class Hero { + id: number; + name: string; + + // Factory methods + + // Get hero from s formatted as ' '. + static fromString(s: string): Hero { + return { + id: +s.substr(0, s.indexOf(' ')), + name: s.substr(s.indexOf(' ') + 1), + }; + } + + // Get hero id and name from the given detail element. + static async fromDetail(detail: ElementFinder): Promise { + // Get hero id from the first
    + let _id = await detail.all(by.css('div')).first().getText(); + // Get name from the h2 + let _name = await detail.element(by.css('h2')).getText(); + return { + id: +_id.substr(_id.indexOf(' ') + 1), + name: _name.substr(0, _name.lastIndexOf(' ')) + }; + } +} + +describe('Tutorial part 4', () => { + beforeAll(() => browser.get('')); + describe('Initial page', initialPageTests); + describe('Select hero', selectHeroTests); + describe('Update hero', updateHeroTests); +}); + +function initialPageTests() { + it(`has title '${expectedTitle}'`, () => { + expect(browser.getTitle()).toEqual(expectedTitle); + }); + + it(`has h1 '${expectedH1}'`, () => { + expectHeading(1, expectedH1); + }); + + it(`has h2 '${expectedH2}'`, () => { + expectHeading(2, expectedH2); + }); + + it('has the right number of heroes', () => { + let page = getPageElts(); + expect(page.heroes.count()).toEqual(10); + }); + + it('has no selected hero and no hero details', function () { + let page = getPageElts(); + expect(page.selected.isPresent()).toBeFalsy('selected hero'); + expect(page.heroDetail.isPresent()).toBeFalsy('no hero detail'); + }); +} + +function selectHeroTests() { + it(`selects ${targetHero.name} from hero list`, function () { + let hero = element(by.cssContainingText('li span.badge', targetHero.id.toString())); + hero.click(); + // Nothing specific to expect other than lack of exceptions. + }); + + it(`has selected ${targetHero.name}`, function () { + let page = getPageElts(); + let expectedText = `${targetHero.id} ${targetHero.name}`; + expect(page.selected.getText()).toBe(expectedText); + }); + + it('shows selected hero details', async () => { + let page = getPageElts(); + let hero = await Hero.fromDetail(page.heroDetail); + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(targetHero.name); + }); +} + +function updateHeroTests() { + it(`can update hero name`, () => { + addToHeroName(nameSuffix); + // Nothing specific to expect other than lack of exceptions. + }); + + it(`shows updated hero name in details`, async () => { + let page = getPageElts(); + let hero = await Hero.fromDetail(page.heroDetail); + let newName = targetHero.name + nameSuffix; + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(newName); + }); + + it(`shows updated hero name in list`, async () => { + let page = getPageElts(); + let hero = Hero.fromString(await page.selected.getText()); + let newName = targetHero.name + nameSuffix; + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(newName); + }); + +} + +function addToHeroName(text: string): promise.Promise { + let input = element(by.css('input')); + return input.sendKeys(text); +} + +function expectHeading(hLevel: number, expectedText: string): void { + let hTag = `h${hLevel}`; + let hText = element(by.css(hTag)).getText(); + expect(hText).toEqual(expectedText, hTag); +}; + +function getPageElts() { + return { + heroes: element.all(by.css('my-app li')), + selected: element(by.css('my-app li.selected')), + heroDetail: element(by.css('my-app > div, my-app > hero-detail > div')) + }; +} diff --git a/public/docs/_examples/toh-4/ts/app/app.component.1.ts b/public/docs/_examples/toh-4/ts/app/app.component.1.ts deleted file mode 100644 index 42558a8a4b..0000000000 --- a/public/docs/_examples/toh-4/ts/app/app.component.1.ts +++ /dev/null @@ -1,65 +0,0 @@ -// #docplaster -// #docregion on-init -import { OnInit } from '@angular/core'; - -// #enddocregion on-init -import { Component } from '@angular/core'; - -import { Hero } from './hero'; -import { HeroDetailComponent } from './hero-detail.component'; -// #docregion hero-service-import -import { HeroService } from './hero.service.1'; -// #enddocregion hero-service-import - -// Testable but never shown -@Component({ - selector: 'my-app', - template: ` -
    - {{hero.name}} -
    - - `, - directives: [HeroDetailComponent], - // #docregion providers - providers: [HeroService] - // #enddocregion providers -}) -// #docregion on-init -export class AppComponent implements OnInit { - // #enddocregion on-init - title = 'Tour of Heroes'; - // #docregion heroes-prop - heroes: Hero[]; - // #enddocregion heroes-prop - selectedHero: Hero; - - // #docregion new-service - heroService = new HeroService(); // don't do this - // #enddocregion new-service - // #docregion ctor - constructor(private heroService: HeroService) { } - // #enddocregion ctor - // #docregion getHeroes - getHeroes() { - //#docregion get-heroes - this.heroes = this.heroService.getHeroes(); - // #enddocregion get-heroes - } - // #enddocregion getHeroes - - // #docregion ng-on-init - // #docregion on-init - ngOnInit() { - // #enddocregion on-init - this.getHeroes(); - // #docregion on-init - } - // #enddocregion on-init - // #enddocregion ng-on-init - - onSelect(hero: Hero) { this.selectedHero = hero; } - // #docregion on-init -} -// #enddocregion on-init -// #enddocregion diff --git a/public/docs/_examples/toh-4/ts/app/app.component.ts b/public/docs/_examples/toh-4/ts/app/app.component.ts deleted file mode 100644 index 7ca63ee237..0000000000 --- a/public/docs/_examples/toh-4/ts/app/app.component.ts +++ /dev/null @@ -1,97 +0,0 @@ -// #docplaster -// #docregion -import { Component, OnInit } from '@angular/core'; - -import { Hero } from './hero'; -import { HeroDetailComponent } from './hero-detail.component'; -// #docregion hero-service-import -import { HeroService } from './hero.service'; -// #enddocregion hero-service-import - -@Component({ - selector: 'my-app', - // #docregion template - template:` -

    {{title}}

    -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    - - `, - // #enddocregion template - styles: [` - .selected { - background-color: #CFD8DC !important; - color: white; - } - .heroes { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 15em; - } - .heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; - } - .heroes li.selected:hover { - background-color: #BBD8DC !important; - color: white; - } - .heroes li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; - } - .heroes .text { - position: relative; - top: -3px; - } - .heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; - } - `], - directives: [HeroDetailComponent], - providers: [HeroService] -}) -export class AppComponent implements OnInit { - title = 'Tour of Heroes'; - heroes: Hero[]; - selectedHero: Hero; - - constructor(private heroService: HeroService) { } - -// #docregion get-heroes - getHeroes() { - this.heroService.getHeroes().then(heroes => this.heroes = heroes); - } -// #enddocregion get-heroes - - ngOnInit() { - this.getHeroes(); - } - - onSelect(hero: Hero) { this.selectedHero = hero; } -} diff --git a/public/docs/_examples/toh-4/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-4/ts/app/hero-detail.component.ts deleted file mode 100644 index 80d6ca020c..0000000000 --- a/public/docs/_examples/toh-4/ts/app/hero-detail.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -// #docregion -import { Component, Input } from '@angular/core'; -import { Hero } from './hero'; - -@Component({ - selector: 'my-hero-detail', - template: ` -
    -

    {{hero.name}} details

    -
    - {{hero.id}} -
    -
    - - -
    -
    - ` -}) -export class HeroDetailComponent { - @Input() hero: Hero; -} diff --git a/public/docs/_examples/toh-4/ts/app/hero.service.1.ts b/public/docs/_examples/toh-4/ts/app/hero.service.1.ts deleted file mode 100644 index 1374cb25fd..0000000000 --- a/public/docs/_examples/toh-4/ts/app/hero.service.1.ts +++ /dev/null @@ -1,23 +0,0 @@ -// #docplaster -// #docregion -// #docregion empty-class -import { Injectable } from '@angular/core'; - -// #enddocregion empty-class -import { HEROES } from './mock-heroes'; - -// #docregion empty-class -// #docregion getHeroes-stub -@Injectable() -export class HeroService { -// #enddocregion empty-class - getHeroes() { -// #enddocregion getHeroes-stub - return HEROES; -// #docregion getHeroes-stub - } -// #docregion empty-class -} -// #enddocregion getHeroes-stub -// #enddocregion empty-class -// #enddocregion diff --git a/public/docs/_examples/toh-4/ts/app/hero.service.ts b/public/docs/_examples/toh-4/ts/app/hero.service.ts deleted file mode 100644 index 943c8fe2d9..0000000000 --- a/public/docs/_examples/toh-4/ts/app/hero.service.ts +++ /dev/null @@ -1,28 +0,0 @@ -// #docplaster -// #docregion -// #docregion just-get-heroes -import { Injectable } from '@angular/core'; - -import { Hero } from './hero'; -import { HEROES } from './mock-heroes'; - -@Injectable() -export class HeroService { - // #docregion get-heroes - getHeroes() { - return Promise.resolve(HEROES); - } - // #enddocregion get-heroes - // #enddocregion just-get-heroes - // See the "Take it slow" appendix - // #docregion get-heroes-slowly - getHeroesSlowly() { - return new Promise(resolve => - setTimeout(()=>resolve(HEROES), 2000) // 2 seconds - ); - } - // #enddocregion get-heroes-slowly - // #docregion just-get-heroes -} -// #enddocregion just-get-heroes -// #enddocregion diff --git a/public/docs/_examples/toh-4/ts/app/main.1.ts b/public/docs/_examples/toh-4/ts/app/main.1.ts deleted file mode 100644 index f8cf0497d6..0000000000 --- a/public/docs/_examples/toh-4/ts/app/main.1.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component.1'; - -bootstrap(AppComponent); diff --git a/public/docs/_examples/toh-4/ts/app/main.ts b/public/docs/_examples/toh-4/ts/app/main.ts deleted file mode 100644 index 42dbeb9f7d..0000000000 --- a/public/docs/_examples/toh-4/ts/app/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); diff --git a/public/docs/_examples/toh-4/ts/app/mock-heroes.ts b/public/docs/_examples/toh-4/ts/app/mock-heroes.ts deleted file mode 100644 index ddd36d7868..0000000000 --- a/public/docs/_examples/toh-4/ts/app/mock-heroes.ts +++ /dev/null @@ -1,16 +0,0 @@ -// #docregion -import { Hero } from './hero'; - -export var HEROES: Hero[] = [ - {id: 11, name: 'Mr. Nice'}, - {id: 12, name: 'Narco'}, - {id: 13, name: 'Bombasto'}, - {id: 14, name: 'Celeritas'}, - {id: 15, name: 'Magneta'}, - {id: 16, name: 'RubberMan'}, - {id: 17, name: 'Dynama'}, - {id: 18, name: 'Dr IQ'}, - {id: 19, name: 'Magma'}, - {id: 20, name: 'Tornado'} -]; -// #enddocregion diff --git a/public/docs/_examples/toh-4/ts/index.html b/public/docs/_examples/toh-4/ts/index.html deleted file mode 100644 index e9c099696b..0000000000 --- a/public/docs/_examples/toh-4/ts/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - Angular 2 Tour of Heroes - - - - - - - - - - - - - - - - - Loading... - - diff --git a/public/docs/_examples/toh-4/ts/plnkr.json b/public/docs/_examples/toh-4/ts/plnkr.json index cb495e519e..95987d95ce 100644 --- a/public/docs/_examples/toh-4/ts/plnkr.json +++ b/public/docs/_examples/toh-4/ts/plnkr.json @@ -1,9 +1,10 @@ { "description": "Tour of Heroes: Part 4", + "basePath": "src/", "files":[ "!**/*.d.ts", "!**/*.js", - "!**/*.[1].*" + "!**/*.[1,2].*" ], "tags": ["tutorial", "tour", "heroes"] } diff --git a/public/docs/_examples/toh-4/ts/src/app/app.component.1.ts b/public/docs/_examples/toh-4/ts/src/app/app.component.1.ts new file mode 100644 index 0000000000..cfddbab537 --- /dev/null +++ b/public/docs/_examples/toh-4/ts/src/app/app.component.1.ts @@ -0,0 +1,65 @@ +// #docplaster +// #docregion on-init +import { OnInit } from '@angular/core'; + +// #enddocregion on-init +import { Component } from '@angular/core'; + +import { Hero } from './hero'; +// #docregion hero-service-import +import { HeroService } from './hero.service.2'; +// #enddocregion hero-service-import + +// Testable but never shown +@Component({ + selector: 'my-app', + template: ` +
    + {{hero.name}} +
    + + `, + // #docregion providers + providers: [HeroService] + // #enddocregion providers +}) +// #docregion on-init +export class AppComponent implements OnInit { + // #enddocregion on-init + title = 'Tour of Heroes'; + // #docregion heroes-prop + heroes: Hero[]; + // #enddocregion heroes-prop + selectedHero: Hero; + + /* + // #docregion new-service + heroService = new HeroService(); // don't do this + // #enddocregion new-service + */ + // #docregion ctor + constructor(private heroService: HeroService) { } + // #enddocregion ctor + // #docregion getHeroes + getHeroes(): void { + // #docregion get-heroes + this.heroes = this.heroService.getHeroes(); + // #enddocregion get-heroes + } + // #enddocregion getHeroes + + // #docregion ng-on-init + // #docregion on-init + ngOnInit(): void { + // #enddocregion on-init + this.getHeroes(); + // #docregion on-init + } + // #enddocregion on-init + // #enddocregion ng-on-init + + onSelect(hero: Hero): void { + this.selectedHero = hero; + } + // #docregion on-init +} diff --git a/public/docs/_examples/toh-4/ts/src/app/app.component.ts b/public/docs/_examples/toh-4/ts/src/app/app.component.ts new file mode 100644 index 0000000000..0d57acb5b0 --- /dev/null +++ b/public/docs/_examples/toh-4/ts/src/app/app.component.ts @@ -0,0 +1,97 @@ +// #docplaster +// #docregion +import { Component, OnInit } from '@angular/core'; + +import { Hero } from './hero'; +// #docregion hero-service-import +import { HeroService } from './hero.service'; +// #enddocregion hero-service-import + +@Component({ + selector: 'my-app', + // #docregion template + template: ` +

    {{title}}

    +

    My Heroes

    +
      +
    • + {{hero.id}} {{hero.name}} +
    • +
    + + `, + // #enddocregion template + styles: [` + .selected { + background-color: #CFD8DC !important; + color: white; + } + .heroes { + margin: 0 0 2em 0; + list-style-type: none; + padding: 0; + width: 15em; + } + .heroes li { + cursor: pointer; + position: relative; + left: 0; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; + } + .heroes li.selected:hover { + background-color: #BBD8DC !important; + color: white; + } + .heroes li:hover { + color: #607D8B; + background-color: #DDD; + left: .1em; + } + .heroes .text { + position: relative; + top: -3px; + } + .heroes .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0 0 4px; + } + `], + providers: [HeroService] +}) +export class AppComponent implements OnInit { + title = 'Tour of Heroes'; + heroes: Hero[]; + selectedHero: Hero; + + constructor(private heroService: HeroService) { } + +// #docregion get-heroes + getHeroes(): void { + this.heroService.getHeroes().then(heroes => this.heroes = heroes); + } +// #enddocregion get-heroes + + ngOnInit(): void { + this.getHeroes(); + } + + onSelect(hero: Hero): void { + this.selectedHero = hero; + } +} diff --git a/public/docs/_examples/toh-4/ts/src/app/app.module.ts b/public/docs/_examples/toh-4/ts/src/app/app.module.ts new file mode 100644 index 0000000000..3df186c62a --- /dev/null +++ b/public/docs/_examples/toh-4/ts/src/app/app.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { HeroDetailComponent } from './hero-detail.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule + ], + declarations: [ + AppComponent, + HeroDetailComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/toh-4/ts/src/app/hero-detail.component.ts b/public/docs/_examples/toh-4/ts/src/app/hero-detail.component.ts new file mode 100644 index 0000000000..865fb98da7 --- /dev/null +++ b/public/docs/_examples/toh-4/ts/src/app/hero-detail.component.ts @@ -0,0 +1,22 @@ +// #docregion +import { Component, Input } from '@angular/core'; +import { Hero } from './hero'; + +@Component({ + selector: 'hero-detail', + template: ` +
    +

    {{hero.name}} details!

    +
    + {{hero.id}} +
    +
    + + +
    +
    + ` +}) +export class HeroDetailComponent { + @Input() hero: Hero; +} diff --git a/public/docs/_examples/toh-4/ts/src/app/hero.service.1.ts b/public/docs/_examples/toh-4/ts/src/app/hero.service.1.ts new file mode 100644 index 0000000000..2366215259 --- /dev/null +++ b/public/docs/_examples/toh-4/ts/src/app/hero.service.1.ts @@ -0,0 +1,24 @@ +// #docplaster +// #docregion +// #docregion empty-class, full +import { Injectable } from '@angular/core'; + +// #enddocregion empty-class +import { Hero } from './hero'; +import { HEROES } from './mock-heroes'; + +// #docregion empty-class, getHeroes-stub +@Injectable() +export class HeroService { + // #enddocregion empty-class, getHeroes-stub, full + /* + // #docregion getHeroes-stub + getHeroes(): void {} // stub + // #enddocregion getHeroes-stub + */ + // #docregion full + getHeroes(): Hero[] { + return HEROES; + } + // #docregion empty-class, getHeroes-stub +} diff --git a/public/docs/_examples/toh-4/ts/src/app/hero.service.2.ts b/public/docs/_examples/toh-4/ts/src/app/hero.service.2.ts new file mode 100644 index 0000000000..d14fe02410 --- /dev/null +++ b/public/docs/_examples/toh-4/ts/src/app/hero.service.2.ts @@ -0,0 +1,13 @@ +// #docregion +import { Injectable } from '@angular/core'; + +import { Hero } from './hero'; +import { HEROES } from './mock-heroes'; + +@Injectable() +export class HeroService { + + getHeroes(): Hero[] { + return HEROES; + } +} diff --git a/public/docs/_examples/toh-4/ts/src/app/hero.service.ts b/public/docs/_examples/toh-4/ts/src/app/hero.service.ts new file mode 100644 index 0000000000..03a1c10a4a --- /dev/null +++ b/public/docs/_examples/toh-4/ts/src/app/hero.service.ts @@ -0,0 +1,29 @@ +// #docplaster +// #docregion +// #docregion just-get-heroes +import { Injectable } from '@angular/core'; + +import { Hero } from './hero'; +import { HEROES } from './mock-heroes'; + +@Injectable() +export class HeroService { + // #docregion get-heroes + getHeroes(): Promise { + return Promise.resolve(HEROES); + } + // #enddocregion get-heroes, just-get-heroes + // #enddocregion + + // See the "Take it slow" appendix + // #docregion get-heroes-slowly + getHeroesSlowly(): Promise { + return new Promise(resolve => { + // Simulate server latency with 2 second delay + setTimeout(() => resolve(this.getHeroes()), 2000); + }); + } + // #enddocregion get-heroes-slowly + // #docregion + // #docregion just-get-heroes +} diff --git a/public/docs/_examples/toh-4/ts/app/hero.ts b/public/docs/_examples/toh-4/ts/src/app/hero.ts similarity index 100% rename from public/docs/_examples/toh-4/ts/app/hero.ts rename to public/docs/_examples/toh-4/ts/src/app/hero.ts diff --git a/public/docs/_examples/toh-4/ts/src/app/mock-heroes.ts b/public/docs/_examples/toh-4/ts/src/app/mock-heroes.ts new file mode 100644 index 0000000000..6f7c5d83a0 --- /dev/null +++ b/public/docs/_examples/toh-4/ts/src/app/mock-heroes.ts @@ -0,0 +1,15 @@ +// #docregion +import { Hero } from './hero'; + +export const HEROES: Hero[] = [ + {id: 11, name: 'Mr. Nice'}, + {id: 12, name: 'Narco'}, + {id: 13, name: 'Bombasto'}, + {id: 14, name: 'Celeritas'}, + {id: 15, name: 'Magneta'}, + {id: 16, name: 'RubberMan'}, + {id: 17, name: 'Dynama'}, + {id: 18, name: 'Dr IQ'}, + {id: 19, name: 'Magma'}, + {id: 20, name: 'Tornado'} +]; diff --git a/public/docs/_examples/toh-4/ts/src/index.html b/public/docs/_examples/toh-4/ts/src/index.html new file mode 100644 index 0000000000..a217238c6c --- /dev/null +++ b/public/docs/_examples/toh-4/ts/src/index.html @@ -0,0 +1,25 @@ + + + + Angular Tour of Heroes + + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/toh-4/ts/src/main.1.ts b/public/docs/_examples/toh-4/ts/src/main.1.ts new file mode 100644 index 0000000000..f22933ba8e --- /dev/null +++ b/public/docs/_examples/toh-4/ts/src/main.1.ts @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/toh-4/ts/src/main.ts b/public/docs/_examples/toh-4/ts/src/main.ts new file mode 100644 index 0000000000..f22933ba8e --- /dev/null +++ b/public/docs/_examples/toh-4/ts/src/main.ts @@ -0,0 +1,4 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/toh-5/dart/example-config.json b/public/docs/_examples/toh-5/dart/example-config.json deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/public/docs/_examples/toh-5/dart/lib/app_component.css b/public/docs/_examples/toh-5/dart/lib/app_component.css deleted file mode 100644 index 137e9be7be..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/app_component.css +++ /dev/null @@ -1,31 +0,0 @@ -/* #docplaster */ -/* #docregion css */ -h1 { - font-size: 1.2em; - color: #999; - margin-bottom: 0; -} -h2 { - font-size: 2em; - margin-top: 0; - padding-top: 0; -} -nav a { - padding: 5px 10px; - text-decoration: none; - margin-top: 10px; - display: inline-block; - background-color: #eee; - border-radius: 4px; -} -nav a:visited, a:link { - color: #607D8B; -} -nav a:hover { - color: #039be5; - background-color: #CFD8DC; -} -nav a.router-link-active { - color: #039be5; -} -/* #enddocregion css */ diff --git a/public/docs/_examples/toh-5/dart/lib/app_component.dart b/public/docs/_examples/toh-5/dart/lib/app_component.dart deleted file mode 100644 index 60ebd7c9bc..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/app_component.dart +++ /dev/null @@ -1,46 +0,0 @@ -// #docplaster -// #docregion -import 'package:angular2/core.dart'; -import 'package:angular2/router.dart'; - -import 'package:angular2_tour_of_heroes/heroes_component.dart'; -import 'package:angular2_tour_of_heroes/hero_service.dart'; -import 'package:angular2_tour_of_heroes/dashboard_component.dart'; -// #docregion hero-detail-import -import 'package:angular2_tour_of_heroes/hero_detail_component.dart'; -// #enddocregion hero-detail-import - -@Component( - selector: 'my-app', - // #docregion template - template: ''' -

    {{title}}

    - - ''', - // #enddocregion template - // #docregion style-urls - styleUrls: const ['app_component.css'], - // #enddocregion style-urls - directives: const [ROUTER_DIRECTIVES], - providers: const [HeroService, ROUTER_PROVIDERS]) -@RouteConfig(const [ -// #docregion dashboard-route - const Route( - path: '/dashboard', - name: 'Dashboard', - component: DashboardComponent, - useAsDefault: true), -// #enddocregion dashboard-route -// #docregion hero-detail-route - const Route( - path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent), -// #enddocregion hero-detail-route - const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent) -]) -class AppComponent { - String title = 'Tour of Heroes'; -} -// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/app_component_1.dart b/public/docs/_examples/toh-5/dart/lib/app_component_1.dart deleted file mode 100644 index da03cbbee0..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/app_component_1.dart +++ /dev/null @@ -1,26 +0,0 @@ -// #docplaster -// #docregion -import 'package:angular2/core.dart'; -// #enddocregion -import 'package:angular2/router.dart'; // for testing only -// #docregion - -import 'hero_service.dart'; -import 'heroes_component.dart'; - -@Component( - selector: 'my-app', - template: ''' -

    {{title}}

    - ''', - directives: const [HeroesComponent], - providers: const [ -// #enddocregion - ROUTER_PROVIDERS, -// #docregion - HeroService - ]) -class AppComponent { - String title = 'Tour of Heroes'; -} -// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/app_component_2.dart b/public/docs/_examples/toh-5/dart/lib/app_component_2.dart deleted file mode 100644 index a677520d91..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/app_component_2.dart +++ /dev/null @@ -1,32 +0,0 @@ -// #docplaster -// #docregion -import 'package:angular2/core.dart'; -// #docregion import-router -import 'package:angular2/router.dart'; -// #enddocregion import-router - -import 'hero_service.dart'; -import 'heroes_component.dart'; - -@Component( - selector: 'my-app', -// #docregion template - template: ''' -

    {{title}}

    - Heroes - ''', -// #enddocregion template - // #docregion directives-and-providers - directives: const [ROUTER_DIRECTIVES], - providers: const [ROUTER_PROVIDERS, HeroService] - // #enddocregion directives-and-providers -) -// #docregion route-config -@RouteConfig(const [ - const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent) -]) -// #enddocregion route-config -class AppComponent { - String title = 'Tour of Heroes'; -} -// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.css b/public/docs/_examples/toh-5/dart/lib/dashboard_component.css deleted file mode 100644 index ce6e963a5f..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/dashboard_component.css +++ /dev/null @@ -1,63 +0,0 @@ -/* #docplaster */ -/* #docregion */ -[class*='col-'] { - float: left; -} -*, *:after, *:before { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -h3 { - text-align: center; margin-bottom: 0; -} -[class*='col-'] { - padding-right: 20px; - padding-bottom: 20px; -} -[class*='col-']:last-of-type { - padding-right: 0; -} -.grid { - margin: 0; -} -.col-1-4 { - width: 25%; -} -.module { - padding: 20px; - text-align: center; - color: #eee; - max-height: 120px; - min-width: 120px; - background-color: #607D8B; - border-radius: 2px; -} -h4 { - position: relative; -} -.module:hover { - background-color: #EEE; - cursor: pointer; - color: #607d8b; -} -.grid-pad { - padding: 10px 0; -} -.grid-pad > [class*='col-']:last-of-type { - padding-right: 20px; -} -@media (max-width: 600px) { - .module { - font-size: 10px; - max-height: 75px; } -} -@media (max-width: 1024px) { - .grid { - margin: 0; - } - .module { - min-width: 60px; - } -} -/* #enddocregion */ diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart b/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart deleted file mode 100644 index 76335c54c4..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart +++ /dev/null @@ -1,43 +0,0 @@ -// #docplaster -// #docregion -import 'package:angular2/core.dart'; -// #docregion import-router -import 'package:angular2/router.dart'; -// #enddocregion import-router - -import 'hero.dart'; -import 'hero_service.dart'; - -@Component( - selector: 'my-dashboard', - // #docregion template-url - templateUrl: 'dashboard_component.html', - // #enddocregion template-url - // #docregion css - styleUrls: const ['dashboard_component.css'] - // #enddocregion css -) -// #docregion component -class DashboardComponent implements OnInit { - List heroes; -// #docregion ctor - final Router _router; - final HeroService _heroService; - - DashboardComponent(this._heroService, this._router); -// #enddocregion ctor - - ngOnInit() async => - heroes = (await _heroService.getHeroes()).getRange(1, 5).toList(); - - // #docregion goto-detail - gotoDetail(Hero hero) { - var link = [ - 'HeroDetail', - {'id': hero.id.toString()} - ]; - _router.navigate(link); - } -// #enddocregion goto-detail -} -// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.html b/public/docs/_examples/toh-5/dart/lib/dashboard_component.html deleted file mode 100644 index b05b58c180..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/dashboard_component.html +++ /dev/null @@ -1,11 +0,0 @@ - -

    Top Heroes

    -
    - -
    - -
    -

    {{hero.name}}

    -
    -
    -
    diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component_1.dart b/public/docs/_examples/toh-5/dart/lib/dashboard_component_1.dart deleted file mode 100644 index 5324624d1f..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/dashboard_component_1.dart +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -@Component( - selector: 'my-dashboard', - template: '

    My Dashboard

    ' -) -class DashboardComponent {} diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart b/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart deleted file mode 100644 index fa1dd9a41e..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart +++ /dev/null @@ -1,25 +0,0 @@ -// #docplaster -// #docregion imports -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'hero_service.dart'; -// #enddocregion imports - -// #docregion component -@Component( - selector: 'my-dashboard', - templateUrl: 'dashboard_component.html' -) -class DashboardComponent implements OnInit { - List heroes; - final HeroService _heroService; - - DashboardComponent(this._heroService); - - ngOnInit() async => - heroes = (await _heroService.getHeroes()).getRange(1, 5).toList(); - - gotoDetail(){ /* not implemented yet */} -} -// #enddocregion component diff --git a/public/docs/_examples/toh-5/dart/lib/hero.dart b/public/docs/_examples/toh-5/dart/lib/hero.dart deleted file mode 100644 index d62b733142..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/hero.dart +++ /dev/null @@ -1,6 +0,0 @@ -class Hero { - final int id; - String name; - - Hero(this.id, this.name); -} \ No newline at end of file diff --git a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.css b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.css deleted file mode 100644 index ab2437efd8..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.css +++ /dev/null @@ -1,30 +0,0 @@ -/* #docregion */ -label { - display: inline-block; - width: 3em; - margin: .5em 0; - color: #607D8B; - font-weight: bold; -} -input { - height: 2em; - font-size: 1em; - padding-left: .4em; -} -button { - margin-top: 20px; - font-family: Arial; - background-color: #eee; - border: none; - padding: 5px 10px; - border-radius: 4px; - cursor: pointer; cursor: hand; -} -button:hover { - background-color: #cfd8dc; -} -button:disabled { - background-color: #eee; - color: #ccc; - cursor: auto; -} diff --git a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart deleted file mode 100644 index ec143efb62..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart +++ /dev/null @@ -1,56 +0,0 @@ -// #docplaster -// #docregion -// #docregion v2 -import 'dart:html'; - -// #docregion import-oninit -import 'package:angular2/core.dart'; -// #enddocregion import-oninit -// #docregion import-route-params -import 'package:angular2/router.dart'; -// #enddocregion import-route-params - -import 'hero.dart'; -// #docregion import-hero-service -import 'hero_service.dart'; -// #enddocregion import-hero-service - -// #docregion extract-template -@Component( - selector: 'my-hero-detail', - // #docregion template-url - templateUrl: 'hero_detail_component.html', - // #enddocregion template-url -// #enddocregion v2 - styleUrls: const ['hero_detail_component.css'] -// #docregion v2 -) -// #enddocregion extract-template -// #docregion implement -class HeroDetailComponent implements OnInit { -// #enddocregion implement - Hero hero; -// #docregion ctor - final HeroService _heroService; - final RouteParams _routeParams; - - HeroDetailComponent(this._heroService, this._routeParams); -// #enddocregion ctor - -// #docregion ng-oninit - ngOnInit() async { - // #docregion get-id - var id = int.parse(_routeParams.get('id')); - // #enddocregion get-id - hero = await (_heroService.getHero(id)); - } -// #enddocregion ng-oninit - -// #docregion go-back - goBack() { - window.history.back(); - } -// #enddocregion go-back -} -// #enddocregion v2 -// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.html b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.html deleted file mode 100644 index 9b2adf5c1e..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.html +++ /dev/null @@ -1,14 +0,0 @@ - - -
    -

    {{hero.name}} details!

    -
    - {{hero.id}}
    -
    - - -
    - - - -
    \ No newline at end of file diff --git a/public/docs/_examples/toh-5/dart/lib/hero_service.dart b/public/docs/_examples/toh-5/dart/lib/hero_service.dart deleted file mode 100644 index 97490fd5fa..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/hero_service.dart +++ /dev/null @@ -1,27 +0,0 @@ -// #docplaster - -// #docregion -import 'dart:async'; - -import 'package:angular2/core.dart'; - -import 'hero.dart'; -import 'mock_heroes.dart'; - -@Injectable() -class HeroService { - Future> getHeroes() async => HEROES; - - // See the "Take it slow" appendix - Future> getHeroesSlowly() { - return new Future>.delayed( - const Duration(seconds: 2), () => HEROES // 2 seconds - ); - } - -//#docregion get-hero - Future getHero(int id) async => - HEROES.where((hero) => hero.id == id).first; -//#enddocregion get-hero -} -// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/heroes_component.css b/public/docs/_examples/toh-5/dart/lib/heroes_component.css deleted file mode 100644 index d939ab565d..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/heroes_component.css +++ /dev/null @@ -1,59 +0,0 @@ -.selected { - background-color: #CFD8DC !important; - color: white; -} -.heroes { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 10em; -} -.heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; -} -.heroes li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; -} -.heroes li.selected:hover { - background-color: #BBD8DC !important; - color: white; -} -.heroes .text { - position: relative; - top: -3px; -} -.heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; -} -button { - font-family: Arial; - background-color: #eee; - border: none; - padding: 5px 10px; - border-radius: 4px; - cursor: pointer; - cursor: hand; -} -button:hover { - background-color: #cfd8dc; -} diff --git a/public/docs/_examples/toh-5/dart/lib/heroes_component.dart b/public/docs/_examples/toh-5/dart/lib/heroes_component.dart deleted file mode 100644 index d615756952..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/heroes_component.dart +++ /dev/null @@ -1,51 +0,0 @@ -// #docplaster -// #docregion -import 'dart:async'; - -import 'package:angular2/core.dart'; -import 'package:angular2/router.dart'; - -import 'hero.dart'; -import 'hero_detail_component.dart'; -import 'hero_service.dart'; - -// #docregion metadata -// #docregion heroes-component-renaming -@Component( - selector: 'my-heroes', -// #enddocregion heroes-component-renaming - templateUrl: 'heroes_component.html', - styleUrls: const ['heroes_component.css'], - directives: const [HeroDetailComponent] -// #docregion heroes-component-renaming -) -// #enddocregion heroes-component-renaming -// #enddocregion metadata -// #docregion class -// #docregion heroes-component-renaming -class HeroesComponent implements OnInit { -// #enddocregion heroes-component-renaming - final Router _router; - final HeroService _heroService; - List heroes; - Hero selectedHero; - - HeroesComponent(this._heroService, this._router); - - Future getHeroes() async { - heroes = await _heroService.getHeroes(); - } - - void ngOnInit() { - getHeroes(); - } - - void onSelect(Hero hero) { selectedHero = hero; } - - Future gotoDetail() => - _router.navigate(['HeroDetail', {'id': selectedHero.id.toString()}]); -// #docregion heroes-component-renaming -} -// #enddocregion heroes-component-renaming -// #enddocregion class -// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/heroes_component.html b/public/docs/_examples/toh-5/dart/lib/heroes_component.html deleted file mode 100644 index d103743706..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/heroes_component.html +++ /dev/null @@ -1,21 +0,0 @@ - - -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    - -
    -

    - - {{selectedHero.name | uppercase}} is my hero - -

    - -
    - - diff --git a/public/docs/_examples/toh-5/dart/lib/mock_heroes.dart b/public/docs/_examples/toh-5/dart/lib/mock_heroes.dart deleted file mode 100644 index b96c17ff61..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/mock_heroes.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'hero.dart'; - -final List HEROES = [ - new Hero(11, 'Mr. Nice'), - new Hero(12, 'Narco'), - new Hero(13, 'Bombasto'), - new Hero(14, 'Celeritas'), - new Hero(15, 'Magneta'), - new Hero(16, 'RubberMan'), - new Hero(17, 'Dynama'), - new Hero(18, 'Dr IQ'), - new Hero(19, 'Magma'), - new Hero(20, 'Tornado') -]; diff --git a/public/docs/_examples/toh-5/dart/pubspec.yaml b/public/docs/_examples/toh-5/dart/pubspec.yaml deleted file mode 100644 index 1cc1f689e9..0000000000 --- a/public/docs/_examples/toh-5/dart/pubspec.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# #docregion -name: angular2_tour_of_heroes -description: Tour of Heroes 5 -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: - - package:angular2/common.dart#COMMON_DIRECTIVES - platform_pipes: - - package:angular2/common.dart#COMMON_PIPES - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/toh-5/dart/web/index.html b/public/docs/_examples/toh-5/dart/web/index.html deleted file mode 100644 index 0d2d000077..0000000000 --- a/public/docs/_examples/toh-5/dart/web/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - Angular 2 Tour of Heroes - - - - - - - - - - - - - Loading... - - diff --git a/public/docs/_examples/toh-5/dart/web/main.dart b/public/docs/_examples/toh-5/dart/web/main.dart deleted file mode 100644 index 314d6f0b65..0000000000 --- a/public/docs/_examples/toh-5/dart/web/main.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:angular2/platform/browser.dart'; - -import 'package:angular2_tour_of_heroes/app_component.dart'; - -main() { - bootstrap(AppComponent); -} diff --git a/public/docs/_examples/toh-5/e2e-spec.ts b/public/docs/_examples/toh-5/e2e-spec.ts index 4266a2b5ce..a49f2ddb62 100644 --- a/public/docs/_examples/toh-5/e2e-spec.ts +++ b/public/docs/_examples/toh-5/e2e-spec.ts @@ -1,112 +1,190 @@ -/// -describe('Tutorial', function () { +'use strict'; // necessary for es6 output in node - beforeAll(function () { - browser.get(''); - }); +import { browser, element, by, ElementFinder } from 'protractor'; +import { promise } from 'selenium-webdriver'; + +const expectedH1 = 'Tour of Heroes'; +const expectedTitle = `Angular ${expectedH1}`; +const targetHero = { id: 15, name: 'Magneta' }; +const targetHeroDashboardIndex = 3; +const nameSuffix = 'X'; +const newHeroName = targetHero.name + nameSuffix; + +class Hero { + id: number; + name: string; + + // Factory methods + + // Get hero from s formatted as ' '. + static fromString(s: string): Hero { + return { + id: +s.substr(0, s.indexOf(' ')), + name: s.substr(s.indexOf(' ') + 1), + }; + } - function getPageStruct() { - let hrefEles = element.all(by.css('my-app a')); + // Get hero id and name from the given detail element. + static async fromDetail(detail: ElementFinder): Promise { + // Get hero id from the first
    + let _id = await detail.all(by.css('div')).first().getText(); + // Get name from the h2 + let _name = await detail.element(by.css('h2')).getText(); + return { + id: +_id.substr(_id.indexOf(' ') + 1), + name: _name.substr(0, _name.lastIndexOf(' ')) + }; + } +} + +describe('Tutorial part 5', () => { + + beforeAll(() => browser.get('')); + + function getPageElts() { + let navElts = element.all(by.css('my-app nav a')); return { - hrefs: hrefEles, - myDashboardHref: hrefEles.get(0), - myDashboardParent: element(by.css('my-app my-dashboard')), - topHeroes: element.all(by.css('my-app my-dashboard .module.hero')), + navElts: navElts, + + myDashboardHref: navElts.get(0), + myDashboard: element(by.css('my-app my-dashboard')), + topHeroes: element.all(by.css('my-app my-dashboard > div h4')), - myHeroesHref: hrefEles.get(1), - myHeroesParent: element(by.css('my-app my-heroes')), + myHeroesHref: navElts.get(1), + myHeroes: element(by.css('my-app my-heroes')), allHeroes: element.all(by.css('my-app my-heroes li')), + selectedHero: element(by.css('my-app li.selected')), + selectedHeroSubview: element(by.css('my-app my-heroes > div')), - heroDetail: element(by.css('my-app my-hero-detail')) - } + heroDetail: element(by.css('my-app hero-detail > div')) + }; } - it('should be able to see the start screen', function () { - let page = getPageStruct(); - expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices'); - expect(page.myDashboardHref.getText()).toEqual("Dashboard"); - expect(page.myHeroesHref.getText()).toEqual("Heroes"); - }); + describe('Initial page', () => { - it('should be able to see dashboard choices', function () { - let page = getPageStruct(); - expect(page.topHeroes.count()).toBe(4, "should be 4 dashboard hero choices"); - }); + it(`has title '${expectedTitle}'`, () => { + expect(browser.getTitle()).toEqual(expectedTitle); + }); - it('should be able to toggle the views', function () { - let page = getPageStruct(); + it(`has h1 '${expectedH1}'`, () => { + expectHeading(1, expectedH1); + }); + + const expectedViewNames = ['Dashboard', 'Heroes']; + it(`has views ${expectedViewNames}`, () => { + let viewNames = getPageElts().navElts.map((el: ElementFinder) => el.getText()); + expect(viewNames).toEqual(expectedViewNames); + }); - expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes'); - page.myHeroesHref.click().then(function() { - expect(page.myDashboardParent.isPresent()).toBe(false, 'should no longer see dashboard element'); - expect(page.allHeroes.count()).toBeGreaterThan(4, "should be more than 4 heroes shown"); - return page.myDashboardHref.click(); - }).then(function() { - expect(page.myDashboardParent.isPresent()).toBe(true, 'should once again see the dashboard element'); + it('has dashboard as the active view', () => { + let page = getPageElts(); + expect(page.myDashboard.isPresent()).toBeTruthy(); }); }); - it('should be able to edit details from "Dashboard" view', function () { - let page = getPageStruct(); - expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available'); - let heroEle = page.topHeroes.get(3); - let heroDescrEle = heroEle.element(by.css('h4')); - let heroDescr: string; - return heroDescrEle.getText().then(function(text) { - heroDescr = text; - return heroEle.click(); - }).then(function() { - return editDetails(page, heroDescr, '-foo'); - }).then(function() { - expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be back'); - expect(heroDescrEle.getText()).toEqual(heroDescr + '-foo'); + describe('Dashboard tests', () => { + + beforeAll(() => browser.get('')); + + it('has top heroes', () => { + let page = getPageElts(); + expect(page.topHeroes.count()).toEqual(4); }); - }); - it('should be able to edit details from "Heroes" view', function () { - let page = getPageStruct(); - expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be present'); - let viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details')); - let heroEle: protractor.ElementFinder; - let heroDescr: string; - page.myHeroesHref.click().then(function() { - expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present'); - expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present'); - expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should not yet be present'); - heroEle = page.allHeroes.get(2); - return heroEle.getText(); - }).then(function(text) { - // remove leading 'id' from the element - heroDescr = text.substr(text.indexOf(' ')+1); - return heroEle.click(); - }).then(function() { - expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible'); - return viewDetailsButtonEle.click(); - }).then(function() { - return editDetails(page, heroDescr, '-bar'); - }).then(function() { - expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be back'); - expect(heroEle.getText()).toContain(heroDescr + '-bar'); - expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should again NOT be present'); + it(`selects and routes to ${targetHero.name} details`, dashboardSelectTargetHero); + + it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView); + + it(`saves and shows ${newHeroName} in Dashboard`, () => { + element(by.buttonText('Back')).click(); + let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex); + expect(targetHeroElt.getText()).toEqual(newHeroName); }); + }); - function editDetails(page: any, origValue: string, textToAdd: string) { - expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present'); - expect(page.myHeroesParent.isPresent()).toBe(false, 'myHeroes element should NOT be present'); - expect(page.heroDetail.isDisplayed()).toBe(true, 'should be able to see hero-details'); - let inputEle = page.heroDetail.element(by.css('input')); - expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box'); - let backButtonEle = page.heroDetail.element(by.css('button')); - expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button'); - let detailTextEle = page.heroDetail.element(by.css('div h2')); - expect(detailTextEle.getText()).toContain(origValue); - return sendKeys(inputEle, textToAdd).then(function () { - expect(detailTextEle.getText()).toContain(origValue + textToAdd); - return backButtonEle.click(); + describe('Heroes tests', () => { + + beforeAll(() => browser.get('')); + + it('can switch to Heroes view', () => { + getPageElts().myHeroesHref.click(); + let page = getPageElts(); + expect(page.myHeroes.isPresent()).toBeTruthy(); + expect(page.allHeroes.count()).toEqual(10, 'number of heroes'); + }); + + it(`selects and shows ${targetHero.name} as selected in list`, () => { + getHeroLiEltById(targetHero.id).click(); + let expectedText = `${targetHero.id} ${targetHero.name}`; + expect(getPageElts().selectedHero.getText()).toBe(expectedText); + }); + + it('shows selected hero subview', async () => { + let page = getPageElts(); + let title = page.selectedHeroSubview.element(by.css('h2')).getText(); + let expectedTitle = `${targetHero.name.toUpperCase()} is my hero`; + expect(title).toEqual(expectedTitle); + }); + + it('can route to hero details', async () => { + element(by.buttonText('View Details')).click(); + + let page = getPageElts(); + expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail'); + let hero = await Hero.fromDetail(page.heroDetail); + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(targetHero.name); }); + + it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView); + + it(`shows ${newHeroName} in Heroes list`, () => { + element(by.buttonText('Back')).click(); + let expectedText = `${targetHero.id} ${newHeroName}`; + expect(getHeroLiEltById(targetHero.id).getText()).toEqual(expectedText); + }); + + }); + + async function dashboardSelectTargetHero() { + let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex); + expect(targetHeroElt.getText()).toEqual(targetHero.name); + targetHeroElt.click(); + + let page = getPageElts(); + expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail'); + let hero = await Hero.fromDetail(page.heroDetail); + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(targetHero.name); + } + + async function updateHeroNameInDetailView() { + // Assumes that the current view is the hero details view. + addToHeroName(nameSuffix); + + let page = getPageElts(); + let hero = await Hero.fromDetail(page.heroDetail); + expect(hero.id).toEqual(targetHero.id); + expect(hero.name).toEqual(newHeroName); } }); + +function addToHeroName(text: string): promise.Promise { + let input = element(by.css('input')); + return input.sendKeys(text); +} + +function expectHeading(hLevel: number, expectedText: string): void { + let hTag = `h${hLevel}`; + let hText = element(by.css(hTag)).getText(); + expect(hText).toEqual(expectedText, hTag); +}; + +function getHeroLiEltById(id: number) { + let spanForId = element(by.cssContainingText('li span.badge', id.toString())); + return spanForId.element(by.xpath('..')); +} diff --git a/public/docs/_examples/toh-5/ts/app/app.component.1.ts b/public/docs/_examples/toh-5/ts/app/app.component.1.ts deleted file mode 100644 index b35870af20..0000000000 --- a/public/docs/_examples/toh-5/ts/app/app.component.1.ts +++ /dev/null @@ -1,31 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; - -import { HeroService } from './hero.service'; -import { HeroesComponent } from './heroes.component'; -// #enddocregion - -// For testing only -import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated'; - -// #docregion - -@Component({ - selector: 'my-app', - template: ` -

    {{title}}

    - - `, - directives: [HeroesComponent], - providers: [ -// #enddocregion - ROUTER_PROVIDERS, -// #docregion - HeroService - ] -}) -export class AppComponent { - title = 'Tour of Heroes'; -} -// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/app/app.component.2.ts b/public/docs/_examples/toh-5/ts/app/app.component.2.ts deleted file mode 100644 index ca3f60efba..0000000000 --- a/public/docs/_examples/toh-5/ts/app/app.component.2.ts +++ /dev/null @@ -1,40 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; -// #docregion import-router -import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated'; -// #enddocregion import-router - -import { HeroService } from './hero.service'; -import { HeroesComponent } from './heroes.component'; - -@Component({ - selector: 'my-app', -// #docregion template - template: ` -

    {{title}}

    - Heroes - - `, -// #enddocregion template -// #docregion directives-and-providers - directives: [ROUTER_DIRECTIVES], - providers: [ - ROUTER_PROVIDERS, - HeroService - ] - // #enddocregion directives-and-providers -}) -// #docregion route-config -@RouteConfig([ - { - path: '/heroes', - name: 'Heroes', - component: HeroesComponent - } -]) -// #enddocregion route-config -export class AppComponent { - title = 'Tour of Heroes'; -} -// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/app/app.component.css b/public/docs/_examples/toh-5/ts/app/app.component.css deleted file mode 100644 index 137e9be7be..0000000000 --- a/public/docs/_examples/toh-5/ts/app/app.component.css +++ /dev/null @@ -1,31 +0,0 @@ -/* #docplaster */ -/* #docregion css */ -h1 { - font-size: 1.2em; - color: #999; - margin-bottom: 0; -} -h2 { - font-size: 2em; - margin-top: 0; - padding-top: 0; -} -nav a { - padding: 5px 10px; - text-decoration: none; - margin-top: 10px; - display: inline-block; - background-color: #eee; - border-radius: 4px; -} -nav a:visited, a:link { - color: #607D8B; -} -nav a:hover { - color: #039be5; - background-color: #CFD8DC; -} -nav a.router-link-active { - color: #039be5; -} -/* #enddocregion css */ diff --git a/public/docs/_examples/toh-5/ts/app/app.component.ts b/public/docs/_examples/toh-5/ts/app/app.component.ts deleted file mode 100644 index 8d26ea6d90..0000000000 --- a/public/docs/_examples/toh-5/ts/app/app.component.ts +++ /dev/null @@ -1,59 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; -import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated'; - -import { DashboardComponent } from './dashboard.component'; -import { HeroesComponent } from './heroes.component'; -// #docregion hero-detail-import -import { HeroDetailComponent } from './hero-detail.component'; -// #enddocregion hero-detail-import -import { HeroService } from './hero.service'; - -@Component({ - selector: 'my-app', -// #docregion template - template: ` -

    {{title}}

    - - - `, -// #enddocregion template -// #docregion style-urls - styleUrls: ['app/app.component.css'], -// #enddocregion style-urls - directives: [ROUTER_DIRECTIVES], - providers: [ - ROUTER_PROVIDERS, - HeroService - ] -}) -@RouteConfig([ -// #docregion dashboard-route - { - path: '/dashboard', - name: 'Dashboard', - component: DashboardComponent, - useAsDefault: true - }, -// #enddocregion dashboard-route -// #docregion hero-detail-route - { - path: '/detail/:id', - name: 'HeroDetail', - component: HeroDetailComponent - }, -// #enddocregion hero-detail-route - { - path: '/heroes', - name: 'Heroes', - component: HeroesComponent - } -]) -export class AppComponent { - title = 'Tour of Heroes'; -} -// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts b/public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts deleted file mode 100644 index 3825a7625c..0000000000 --- a/public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts +++ /dev/null @@ -1,27 +0,0 @@ -// #docplaster -// #docregion imports -import { Component, OnInit } from '@angular/core'; - -import { Hero } from './hero'; -import { HeroService } from './hero.service'; -// #enddocregion imports - -@Component({ - selector: 'my-dashboard', - templateUrl: 'app/dashboard.component.html' -}) -// #docregion component -export class DashboardComponent implements OnInit { - - heroes: Hero[] = []; - - constructor(private heroService: HeroService) { } - - ngOnInit() { - this.heroService.getHeroes() - .then(heroes => this.heroes = heroes.slice(1,5)); - } - - gotoDetail(){ /* not implemented yet */} -} -// #enddocregion component diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.css b/public/docs/_examples/toh-5/ts/app/dashboard.component.css deleted file mode 100644 index ce6e963a5f..0000000000 --- a/public/docs/_examples/toh-5/ts/app/dashboard.component.css +++ /dev/null @@ -1,63 +0,0 @@ -/* #docplaster */ -/* #docregion */ -[class*='col-'] { - float: left; -} -*, *:after, *:before { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -h3 { - text-align: center; margin-bottom: 0; -} -[class*='col-'] { - padding-right: 20px; - padding-bottom: 20px; -} -[class*='col-']:last-of-type { - padding-right: 0; -} -.grid { - margin: 0; -} -.col-1-4 { - width: 25%; -} -.module { - padding: 20px; - text-align: center; - color: #eee; - max-height: 120px; - min-width: 120px; - background-color: #607D8B; - border-radius: 2px; -} -h4 { - position: relative; -} -.module:hover { - background-color: #EEE; - cursor: pointer; - color: #607d8b; -} -.grid-pad { - padding: 10px 0; -} -.grid-pad > [class*='col-']:last-of-type { - padding-right: 20px; -} -@media (max-width: 600px) { - .module { - font-size: 10px; - max-height: 75px; } -} -@media (max-width: 1024px) { - .grid { - margin: 0; - } - .module { - min-width: 60px; - } -} -/* #enddocregion */ diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.html b/public/docs/_examples/toh-5/ts/app/dashboard.component.html deleted file mode 100644 index 028eab6eb3..0000000000 --- a/public/docs/_examples/toh-5/ts/app/dashboard.component.html +++ /dev/null @@ -1,11 +0,0 @@ - -

    Top Heroes

    -
    - -
    - -
    -

    {{hero.name}}

    -
    -
    -
    diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.ts b/public/docs/_examples/toh-5/ts/app/dashboard.component.ts deleted file mode 100644 index 64489ff312..0000000000 --- a/public/docs/_examples/toh-5/ts/app/dashboard.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -// #docplaster -// #docregion -import { Component, OnInit } from '@angular/core'; -// #docregion import-router -import { Router } from '@angular/router-deprecated'; -// #enddocregion import-router - -import { Hero } from './hero'; -import { HeroService } from './hero.service'; - -@Component({ - selector: 'my-dashboard', - // #docregion template-url - templateUrl: 'app/dashboard.component.html', - // #enddocregion template-url - // #docregion css - styleUrls: ['app/dashboard.component.css'] - // #enddocregion css -}) -// #docregion component -export class DashboardComponent implements OnInit { - - heroes: Hero[] = []; - -// #docregion ctor - constructor( - private router: Router, - private heroService: HeroService) { - } -// #enddocregion ctor - - ngOnInit() { - this.heroService.getHeroes() - .then(heroes => this.heroes = heroes.slice(1,5)); - } - - // #docregion goto-detail - gotoDetail(hero: Hero) { - let link = ['HeroDetail', { id: hero.id }]; - this.router.navigate(link); - } - // #enddocregion goto-detail -} -// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/hero-detail.component.html b/public/docs/_examples/toh-5/ts/app/hero-detail.component.html deleted file mode 100644 index cf96fc2169..0000000000 --- a/public/docs/_examples/toh-5/ts/app/hero-detail.component.html +++ /dev/null @@ -1,14 +0,0 @@ - - -
    -

    {{hero.name}} details!

    -
    - {{hero.id}}
    -
    - - -
    - - - -
    \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts deleted file mode 100644 index 08af69c69c..0000000000 --- a/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -// #docplaster -// #docregion -// #docregion v2 -// #docregion import-oninit -import { Component, OnInit } from '@angular/core'; -// #enddocregion import-oninit -// #docregion import-route-params -import { RouteParams } from '@angular/router-deprecated'; -// #enddocregion import-route-params - -import { Hero } from './hero'; -// #docregion import-hero-service -import { HeroService } from './hero.service'; -// #enddocregion import-hero-service - -// #docregion extract-template -@Component({ - selector: 'my-hero-detail', - // #docregion template-url - templateUrl: 'app/hero-detail.component.html', - // #enddocregion template-url -// #enddocregion v2 - styleUrls: ['app/hero-detail.component.css'] -// #docregion v2 -}) -// #enddocregion extract-template -// #docregion implement -export class HeroDetailComponent implements OnInit { -// #enddocregion implement - hero: Hero; - -// #docregion ctor - constructor( - private heroService: HeroService, - private routeParams: RouteParams) { - } -// #enddocregion ctor - -// #docregion ng-oninit - ngOnInit() { - // #docregion get-id - let id = +this.routeParams.get('id'); - // #enddocregion get-id - this.heroService.getHero(id) - .then(hero => this.hero = hero); - } -// #enddocregion ng-oninit - -// #docregion go-back - goBack() { - window.history.back(); - } -// #enddocregion go-back -} -// #enddocregion v2 -// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/app/hero.service.ts b/public/docs/_examples/toh-5/ts/app/hero.service.ts deleted file mode 100644 index efc348509b..0000000000 --- a/public/docs/_examples/toh-5/ts/app/hero.service.ts +++ /dev/null @@ -1,27 +0,0 @@ -// #docplaster -// #docregion -import { Hero } from './hero'; -import { HEROES } from './mock-heroes'; -import { Injectable } from '@angular/core'; - -@Injectable() -export class HeroService { - getHeroes() { - return Promise.resolve(HEROES); - } - - // See the "Take it slow" appendix - getHeroesSlowly() { - return new Promise(resolve => - setTimeout(()=>resolve(HEROES), 2000) // 2 seconds - ); - } - - //#docregion get-hero - getHero(id: number) { - return this.getHeroes() - .then(heroes => heroes.filter(hero => hero.id === id)[0]); - } - //#enddocregion get-hero -} -// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/heroes.component.css b/public/docs/_examples/toh-5/ts/app/heroes.component.css deleted file mode 100644 index 35e45af98d..0000000000 --- a/public/docs/_examples/toh-5/ts/app/heroes.component.css +++ /dev/null @@ -1,59 +0,0 @@ -.selected { - background-color: #CFD8DC !important; - color: white; -} -.heroes { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 15em; -} -.heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; -} -.heroes li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; -} -.heroes li.selected:hover { - background-color: #BBD8DC !important; - color: white; -} -.heroes .text { - position: relative; - top: -3px; -} -.heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; -} -button { - font-family: Arial; - background-color: #eee; - border: none; - padding: 5px 10px; - border-radius: 4px; - cursor: pointer; - cursor: hand; -} -button:hover { - background-color: #cfd8dc; -} diff --git a/public/docs/_examples/toh-5/ts/app/heroes.component.html b/public/docs/_examples/toh-5/ts/app/heroes.component.html deleted file mode 100644 index cce1853d30..0000000000 --- a/public/docs/_examples/toh-5/ts/app/heroes.component.html +++ /dev/null @@ -1,21 +0,0 @@ - - -

    My Heroes

    -
      -
    • - {{hero.id}} {{hero.name}} -
    • -
    - -
    -

    - - {{selectedHero.name | uppercase}} is my hero - -

    - -
    - - diff --git a/public/docs/_examples/toh-5/ts/app/heroes.component.ts b/public/docs/_examples/toh-5/ts/app/heroes.component.ts deleted file mode 100644 index 300f3065e0..0000000000 --- a/public/docs/_examples/toh-5/ts/app/heroes.component.ts +++ /dev/null @@ -1,48 +0,0 @@ -// #docplaster -// #docregion -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router-deprecated'; - -import { Hero } from './hero'; -import { HeroService } from './hero.service'; - -// #docregion metadata -// #docregion heroes-component-renaming -@Component({ - selector: 'my-heroes', -// #enddocregion heroes-component-renaming - templateUrl: 'app/heroes.component.html', - styleUrls: ['app/heroes.component.css'] -// #docregion heroes-component-renaming -}) -// #enddocregion heroes-component-renaming -// #enddocregion metadata -// #docregion class -// #docregion heroes-component-renaming -export class HeroesComponent implements OnInit { -// #enddocregion heroes-component-renaming - heroes: Hero[]; - selectedHero: Hero; - - constructor( - private router: Router, - private heroService: HeroService) { } - - getHeroes() { - this.heroService.getHeroes().then(heroes => this.heroes = heroes); - } - - ngOnInit() { - this.getHeroes(); - } - - onSelect(hero: Hero) { this.selectedHero = hero; } - - gotoDetail() { - this.router.navigate(['HeroDetail', { id: this.selectedHero.id }]); - } -// #docregion heroes-component-renaming -} -// #enddocregion heroes-component-renaming -// #enddocregion class -// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/app/main.ts b/public/docs/_examples/toh-5/ts/app/main.ts deleted file mode 100644 index ad256f0823..0000000000 --- a/public/docs/_examples/toh-5/ts/app/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); diff --git a/public/docs/_examples/toh-5/ts/app/mock-heroes.ts b/public/docs/_examples/toh-5/ts/app/mock-heroes.ts deleted file mode 100644 index ddd36d7868..0000000000 --- a/public/docs/_examples/toh-5/ts/app/mock-heroes.ts +++ /dev/null @@ -1,16 +0,0 @@ -// #docregion -import { Hero } from './hero'; - -export var HEROES: Hero[] = [ - {id: 11, name: 'Mr. Nice'}, - {id: 12, name: 'Narco'}, - {id: 13, name: 'Bombasto'}, - {id: 14, name: 'Celeritas'}, - {id: 15, name: 'Magneta'}, - {id: 16, name: 'RubberMan'}, - {id: 17, name: 'Dynama'}, - {id: 18, name: 'Dr IQ'}, - {id: 19, name: 'Magma'}, - {id: 20, name: 'Tornado'} -]; -// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/index.html b/public/docs/_examples/toh-5/ts/index.html deleted file mode 100644 index 93fa8d4889..0000000000 --- a/public/docs/_examples/toh-5/ts/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - Angular 2 Tour of Heroes - - - - - - - - - - - - - - - - - - - - - - Loading... - - diff --git a/public/docs/_examples/toh-5/ts/plnkr.json b/public/docs/_examples/toh-5/ts/plnkr.json index 019630c28f..db4b15d160 100644 --- a/public/docs/_examples/toh-5/ts/plnkr.json +++ b/public/docs/_examples/toh-5/ts/plnkr.json @@ -1,9 +1,10 @@ { "description": "Tour of Heroes: Part 5", + "basePath": "src/", "files":[ "!**/*.d.ts", "!**/*.js", - "!**/*.[1,2].*" + "!**/*.[1,2,3].*" ], "tags": ["tutorial", "tour", "heroes", "router"] } diff --git a/public/docs/_examples/toh-5/ts/src/app/app-routing.module.ts b/public/docs/_examples/toh-5/ts/src/app/app-routing.module.ts new file mode 100644 index 0000000000..dfd957782b --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/app-routing.module.ts @@ -0,0 +1,20 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { DashboardComponent } from './dashboard.component'; +import { HeroesComponent } from './heroes.component'; +import { HeroDetailComponent } from './hero-detail.component'; + +const routes: Routes = [ + { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, + { path: 'dashboard', component: DashboardComponent }, + { path: 'detail/:id', component: HeroDetailComponent }, + { path: 'heroes', component: HeroesComponent } +]; + +@NgModule({ + imports: [ RouterModule.forRoot(routes) ], + exports: [ RouterModule ] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/toh-5/ts/src/app/app.component.1.ts b/public/docs/_examples/toh-5/ts/src/app/app.component.1.ts new file mode 100644 index 0000000000..c9f5db9712 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/app.component.1.ts @@ -0,0 +1,42 @@ +// #docplaster +// #docregion , v2 +import { Component } from '@angular/core'; + +// #enddocregion v2 +@Component({ + selector: 'my-app', + template: ` +

    {{title}}

    + + ` +}) +// #enddocregion +// #docregion v2 +@Component({ + selector: 'my-app', + // #docregion template-v2 + template: ` +

    {{title}}

    + Heroes + + ` + // #enddocregion template-v2 +}) +// #enddocregion +@Component({ + selector: 'my-app', + // #docregion template-v3 + template: ` +

    {{title}}

    + + + ` + // #enddocregion template-v3 +}) +// #docregion , v2 +export class AppComponent { + title = 'Tour of Heroes'; +} diff --git a/public/docs/_examples/toh-5/ts/src/app/app.component.css b/public/docs/_examples/toh-5/ts/src/app/app.component.css new file mode 100644 index 0000000000..071e665767 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/app.component.css @@ -0,0 +1,29 @@ +/* #docregion */ +h1 { + font-size: 1.2em; + color: #999; + margin-bottom: 0; +} +h2 { + font-size: 2em; + margin-top: 0; + padding-top: 0; +} +nav a { + padding: 5px 10px; + text-decoration: none; + margin-top: 10px; + display: inline-block; + background-color: #eee; + border-radius: 4px; +} +nav a:visited, a:link { + color: #607D8B; +} +nav a:hover { + color: #039be5; + background-color: #CFD8DC; +} +nav a.active { + color: #039be5; +} diff --git a/public/docs/_examples/toh-5/ts/src/app/app.component.ts b/public/docs/_examples/toh-5/ts/src/app/app.component.ts new file mode 100644 index 0000000000..96bc3fe694 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/app.component.ts @@ -0,0 +1,22 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + // #docregion template + template: ` +

    {{title}}

    + + + `, + // #enddocregion template + // #docregion styleUrls + styleUrls: ['./app.component.css'], + // #enddocregion styleUrls +}) +export class AppComponent { + title = 'Tour of Heroes'; +} diff --git a/public/docs/_examples/toh-5/ts/src/app/app.module.1.ts b/public/docs/_examples/toh-5/ts/src/app/app.module.1.ts new file mode 100644 index 0000000000..e1cda9b620 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/app.module.1.ts @@ -0,0 +1,28 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { HeroDetailComponent } from './hero-detail.component'; +import { HeroesComponent } from './heroes.component'; +import { HeroService } from './hero.service'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule + ], + declarations: [ + AppComponent, + HeroDetailComponent, + HeroesComponent + ], + providers: [ + HeroService + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { +} +// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/src/app/app.module.2.ts b/public/docs/_examples/toh-5/ts/src/app/app.module.2.ts new file mode 100644 index 0000000000..00876570f3 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/app.module.2.ts @@ -0,0 +1,48 @@ +// #docplaster +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroDetailComponent } from './hero-detail.component'; +import { HeroesComponent } from './heroes.component'; +import { HeroService } from './hero.service'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + RouterModule.forRoot([ + { + path: 'heroes', + component: HeroesComponent + } + ]) + ], + declarations: [ + AppComponent, + HeroDetailComponent, + HeroesComponent + ], + providers: [ + HeroService + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { +} +// #enddocregion +/* +// #docregion heroes, routing +import { RouterModule } from '@angular/router'; + +RouterModule.forRoot([ + { + path: 'heroes', + component: HeroesComponent + } +]) +// #enddocregion heroes, routing +*/ diff --git a/public/docs/_examples/toh-5/ts/src/app/app.module.3.ts b/public/docs/_examples/toh-5/ts/src/app/app.module.3.ts new file mode 100644 index 0000000000..306d9958f0 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/app.module.3.ts @@ -0,0 +1,58 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HeroDetailComponent } from './hero-detail.component'; +import { DashboardComponent } from './dashboard.component'; +import { HeroesComponent } from './heroes.component'; +import { HeroService } from './hero.service'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + RouterModule.forRoot([ + // #docregion redirect + { + path: '', + redirectTo: '/dashboard', + pathMatch: 'full' + }, + // #enddocregion redirect + // #docregion dashboard + { + path: 'dashboard', + component: DashboardComponent + }, + // #enddocregion dashboard + // #docregion hero-detail + { + path: 'detail/:id', + component: HeroDetailComponent + }, + // #enddocregion hero-detail + // #docregion heroes, routing + { + path: 'heroes', + component: HeroesComponent + } + // #enddocregion heroes, routing + ]) + ], + declarations: [ + AppComponent, + DashboardComponent, + HeroDetailComponent, + HeroesComponent + ], + providers: [ + HeroService + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { +} +// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/src/app/app.module.ts b/public/docs/_examples/toh-5/ts/src/app/app.module.ts new file mode 100644 index 0000000000..b376d69aba --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/app.module.ts @@ -0,0 +1,35 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; + +import { AppComponent } from './app.component'; +import { DashboardComponent } from './dashboard.component'; +import { HeroDetailComponent } from './hero-detail.component'; +import { HeroesComponent } from './heroes.component'; +import { HeroService } from './hero.service'; + +// #docregion routing-module +import { AppRoutingModule } from './app-routing.module'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + AppRoutingModule + ], +// #enddocregion routing-module + // #docregion dashboard + declarations: [ + AppComponent, + DashboardComponent, + HeroDetailComponent, + HeroesComponent + ], + // #enddocregion dashboard + providers: [ HeroService ], + bootstrap: [ AppComponent ] +// #docregion routing-module +}) +export class AppModule { } +// #enddocregion routing-module diff --git a/public/docs/_examples/toh-5/ts/src/app/dashboard.component.1.html b/public/docs/_examples/toh-5/ts/src/app/dashboard.component.1.html new file mode 100644 index 0000000000..0c556b8de0 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/dashboard.component.1.html @@ -0,0 +1,9 @@ + +

    Top Heroes

    +
    +
    +
    +

    {{hero.name}}

    +
    +
    +
    diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.1.ts b/public/docs/_examples/toh-5/ts/src/app/dashboard.component.1.ts similarity index 99% rename from public/docs/_examples/toh-5/ts/app/dashboard.component.1.ts rename to public/docs/_examples/toh-5/ts/src/app/dashboard.component.1.ts index 430a30ebbe..3c92b205c8 100644 --- a/public/docs/_examples/toh-5/ts/app/dashboard.component.1.ts +++ b/public/docs/_examples/toh-5/ts/src/app/dashboard.component.1.ts @@ -6,4 +6,3 @@ import { Component } from '@angular/core'; template: '

    My Dashboard

    ' }) export class DashboardComponent { } - diff --git a/public/docs/_examples/toh-5/ts/src/app/dashboard.component.css b/public/docs/_examples/toh-5/ts/src/app/dashboard.component.css new file mode 100644 index 0000000000..dc7fb7ce06 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/dashboard.component.css @@ -0,0 +1,62 @@ +/* #docregion */ +[class*='col-'] { + float: left; + padding-right: 20px; + padding-bottom: 20px; +} +[class*='col-']:last-of-type { + padding-right: 0; +} +a { + text-decoration: none; +} +*, *:after, *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +h3 { + text-align: center; margin-bottom: 0; +} +h4 { + position: relative; +} +.grid { + margin: 0; +} +.col-1-4 { + width: 25%; +} +.module { + padding: 20px; + text-align: center; + color: #eee; + max-height: 120px; + min-width: 120px; + background-color: #607D8B; + border-radius: 2px; +} +.module:hover { + background-color: #EEE; + cursor: pointer; + color: #607d8b; +} +.grid-pad { + padding: 10px 0; +} +.grid-pad > [class*='col-']:last-of-type { + padding-right: 20px; +} +@media (max-width: 600px) { + .module { + font-size: 10px; + max-height: 75px; } +} +@media (max-width: 1024px) { + .grid { + margin: 0; + } + .module { + min-width: 60px; + } +} diff --git a/public/docs/_examples/toh-5/ts/src/app/dashboard.component.html b/public/docs/_examples/toh-5/ts/src/app/dashboard.component.html new file mode 100644 index 0000000000..49e77c460c --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/dashboard.component.html @@ -0,0 +1,11 @@ + +

    Top Heroes

    + diff --git a/public/docs/_examples/toh-5/ts/src/app/dashboard.component.ts b/public/docs/_examples/toh-5/ts/src/app/dashboard.component.ts new file mode 100644 index 0000000000..416cf8868e --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/dashboard.component.ts @@ -0,0 +1,33 @@ +// #docplaster +// #docregion , imports +import { Component, OnInit } from '@angular/core'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; +// #enddocregion imports + +// #docregion metadata +@Component({ + selector: 'my-dashboard', + templateUrl: './dashboard.component.html', + // #enddocregion metadata + // #docregion css + styleUrls: [ './dashboard.component.css' ] + // #enddocregion css + // #docregion metadata +}) +// #enddocregion metadata +// #docregion class +export class DashboardComponent implements OnInit { + + heroes: Hero[] = []; + + // #docregion ctor + constructor(private heroService: HeroService) { } + // #enddocregion ctor + + ngOnInit(): void { + this.heroService.getHeroes() + .then(heroes => this.heroes = heroes.slice(1, 5)); + } +} diff --git a/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.1.ts b/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.1.ts new file mode 100644 index 0000000000..2f5081bdce --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.1.ts @@ -0,0 +1,29 @@ +// Imports in comments cause problems when the app is executed +// (some error about 'traceur' missing). Hence this separate file +// is solely for containing the transitory state of the imports. + +// #docregion added-imports +// Keep the Input import for now, you'll remove it later: +import { Component, Input, OnInit } from '@angular/core'; +import { ActivatedRoute, Params } from '@angular/router'; +import { Location } from '@angular/common'; + +import { HeroService } from './hero.service'; +// #enddocregion added-imports + +// Bogus code below this point. It is only here to make lint happy. +import { Hero } from './hero'; + +@Component({}) +export class HeroDetailComponent implements OnInit { + @Input() hero: Hero; + bogus: Params; + + constructor( + private heroService: HeroService, + private route: ActivatedRoute, + private location: Location + ) {} + + ngOnInit() {} +} diff --git a/public/docs/_examples/testing/ts/app/hero-detail.component.css b/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.css similarity index 100% rename from public/docs/_examples/testing/ts/app/hero-detail.component.css rename to public/docs/_examples/toh-5/ts/src/app/hero-detail.component.css diff --git a/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.html b/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.html new file mode 100644 index 0000000000..8f2ff9d90c --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.html @@ -0,0 +1,14 @@ + + +
    +

    {{hero.name}} details!

    +
    + {{hero.id}}
    +
    + + +
    + + + +
    diff --git a/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.ts b/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.ts new file mode 100644 index 0000000000..222b6705d7 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.ts @@ -0,0 +1,46 @@ +// #docplaster +// #docregion , v2, rxjs-import +import 'rxjs/add/operator/switchMap'; +// #enddocregion rxjs-import +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Params } from '@angular/router'; +import { Location } from '@angular/common'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; +// #docregion metadata +@Component({ + selector: 'hero-detail', + templateUrl: './hero-detail.component.html', + // #enddocregion metadata, v2 + styleUrls: [ './hero-detail.component.css' ] + // #docregion metadata, v2 +}) +// #enddocregion metadata +// #docregion implement +export class HeroDetailComponent implements OnInit { +// #enddocregion implement + hero: Hero; + + // #docregion ctor + constructor( + private heroService: HeroService, + private route: ActivatedRoute, + private location: Location + ) {} + // #enddocregion ctor + + // #docregion ngOnInit + ngOnInit(): void { + this.route.params + .switchMap((params: Params) => this.heroService.getHero(+params['id'])) + .subscribe(hero => this.hero = hero); + } + // #enddocregion ngOnInit + + // #docregion goBack + goBack(): void { + this.location.back(); + } +// #enddocregion goBack +} diff --git a/public/docs/_examples/toh-5/ts/src/app/hero.service.ts b/public/docs/_examples/toh-5/ts/src/app/hero.service.ts new file mode 100644 index 0000000000..ee5a684762 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/hero.service.ts @@ -0,0 +1,26 @@ +// #docplaster +// #docregion +import { Hero } from './hero'; +import { HEROES } from './mock-heroes'; +import { Injectable } from '@angular/core'; + +@Injectable() +export class HeroService { + getHeroes(): Promise { + return Promise.resolve(HEROES); + } + + getHeroesSlowly(): Promise { + return new Promise(resolve => { + // Simulate server latency with 2 second delay + setTimeout(() => resolve(this.getHeroes()), 2000); + }); + } + + // #docregion getHero + getHero(id: number): Promise { + return this.getHeroes() + .then(heroes => heroes.find(hero => hero.id === id)); + } + // #enddocregion getHero +} diff --git a/public/docs/_examples/toh-5/ts/app/hero.ts b/public/docs/_examples/toh-5/ts/src/app/hero.ts similarity index 100% rename from public/docs/_examples/toh-5/ts/app/hero.ts rename to public/docs/_examples/toh-5/ts/src/app/hero.ts diff --git a/public/docs/_examples/toh-5/ts/src/app/heroes.component.css b/public/docs/_examples/toh-5/ts/src/app/heroes.component.css new file mode 100644 index 0000000000..b49fa0a419 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/heroes.component.css @@ -0,0 +1,60 @@ +/* #docregion */ +.selected { + background-color: #CFD8DC !important; + color: white; +} +.heroes { + margin: 0 0 2em 0; + list-style-type: none; + padding: 0; + width: 15em; +} +.heroes li { + cursor: pointer; + position: relative; + left: 0; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; +} +.heroes li:hover { + color: #607D8B; + background-color: #DDD; + left: .1em; +} +.heroes li.selected:hover { + background-color: #BBD8DC !important; + color: white; +} +.heroes .text { + position: relative; + top: -3px; +} +.heroes .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0 0 4px; +} +button { + font-family: Arial; + background-color: #eee; + border: none; + padding: 5px 10px; + border-radius: 4px; + cursor: pointer; + cursor: hand; +} +button:hover { + background-color: #cfd8dc; +} diff --git a/public/docs/_examples/toh-5/ts/src/app/heroes.component.html b/public/docs/_examples/toh-5/ts/src/app/heroes.component.html new file mode 100644 index 0000000000..db41c4692e --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/heroes.component.html @@ -0,0 +1,19 @@ + + +

    My Heroes

    +
      +
    • + {{hero.id}} {{hero.name}} +
    • +
    + +
    +

    + + {{selectedHero.name | uppercase}} is my hero + +

    + +
    diff --git a/public/docs/_examples/toh-5/ts/src/app/heroes.component.ts b/public/docs/_examples/toh-5/ts/src/app/heroes.component.ts new file mode 100644 index 0000000000..def615e6b9 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/heroes.component.ts @@ -0,0 +1,46 @@ +// #docplaster +// #docregion +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +// #docregion renaming, metadata +@Component({ + selector: 'my-heroes', + // #enddocregion renaming + templateUrl: './heroes.component.html', + styleUrls: [ './heroes.component.css' ] + // #docregion renaming +}) +// #enddocregion metadata +// #docregion class +export class HeroesComponent implements OnInit { + // #enddocregion renaming + heroes: Hero[]; + selectedHero: Hero; + + constructor( + private router: Router, + private heroService: HeroService) { } + + getHeroes(): void { + this.heroService.getHeroes().then(heroes => this.heroes = heroes); + } + + ngOnInit(): void { + this.getHeroes(); + } + + onSelect(hero: Hero): void { + this.selectedHero = hero; + } + + // #docregion gotoDetail + gotoDetail(): void { + this.router.navigate(['/detail', this.selectedHero.id]); + } + // #enddocregion gotoDetail + // #docregion renaming +} diff --git a/public/docs/_examples/toh-5/ts/src/app/mock-heroes.ts b/public/docs/_examples/toh-5/ts/src/app/mock-heroes.ts new file mode 100644 index 0000000000..69afde3d34 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/app/mock-heroes.ts @@ -0,0 +1,15 @@ +// #docregion +import { Hero } from './hero'; + +export var HEROES: Hero[] = [ + {id: 11, name: 'Mr. Nice'}, + {id: 12, name: 'Narco'}, + {id: 13, name: 'Bombasto'}, + {id: 14, name: 'Celeritas'}, + {id: 15, name: 'Magneta'}, + {id: 16, name: 'RubberMan'}, + {id: 17, name: 'Dynama'}, + {id: 18, name: 'Dr IQ'}, + {id: 19, name: 'Magma'}, + {id: 20, name: 'Tornado'} +]; diff --git a/public/docs/_examples/toh-5/ts/src/index.html b/public/docs/_examples/toh-5/ts/src/index.html new file mode 100644 index 0000000000..cbacc9b83b --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/index.html @@ -0,0 +1,33 @@ + + + + + + + + Angular Tour of Heroes + + + + + + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/toh-5/ts/src/main.ts b/public/docs/_examples/toh-5/ts/src/main.ts new file mode 100644 index 0000000000..505f60b35b --- /dev/null +++ b/public/docs/_examples/toh-5/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +// main entry point +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/toh-5/ts/styles.1.css b/public/docs/_examples/toh-5/ts/styles.1.css deleted file mode 100644 index 5b77b74d1c..0000000000 --- a/public/docs/_examples/toh-5/ts/styles.1.css +++ /dev/null @@ -1,34 +0,0 @@ -/* #docregion */ -h2 { - color: #444; - font-family: Arial, Helvetica, sans-serif; - font-weight: lighter; -} -body { - margin: 2em; -} -body, input[text], button { - color: #888; - font-family: Cambria, Georgia; -} -button { - font-family: Arial; - background-color: #eee; - border: none; - padding: 5px 10px; - border-radius: 4px; - cursor: pointer; - cursor: hand; -} -button:hover { - background-color: #cfd8dc; -} -button:disabled { - background-color: #eee; - color: #aaa; - cursor: auto; -} -/* everywhere else */ -* { - font-family: Arial, Helvetica, sans-serif; -} diff --git a/public/docs/_examples/toh-6/e2e-spec.ts b/public/docs/_examples/toh-6/e2e-spec.ts index bec10800b4..80d9660263 100644 --- a/public/docs/_examples/toh-6/e2e-spec.ts +++ b/public/docs/_examples/toh-6/e2e-spec.ts @@ -1,224 +1,283 @@ -/// -describe('TOH Http Chapter', function () { +'use strict'; // necessary for es6 output in node - beforeEach(function () { - browser.get(''); - }); +import { browser, element, by, ElementFinder, ElementArrayFinder } from 'protractor'; +import { promise } from 'selenium-webdriver'; + +const expectedH1 = 'Tour of Heroes'; +const expectedTitle = `Angular ${expectedH1}`; +const targetHero = { id: 15, name: 'Magneta' }; +const targetHeroDashboardIndex = 3; +const nameSuffix = 'X'; +const newHeroName = targetHero.name + nameSuffix; + +class Hero { + id: number; + name: string; - function getPageStruct() { - let hrefEles = element.all(by.css('my-app a')); + // Factory methods + // Hero from string formatted as ' '. + static fromString(s: string): Hero { return { - hrefs: hrefEles, - myDashboardHref: hrefEles.get(0), - myDashboardParent: element(by.css('my-app my-dashboard')), - topHeroes: element.all(by.css('my-app my-dashboard .module.hero')), + id: +s.substr(0, s.indexOf(' ')), + name: s.substr(s.indexOf(' ') + 1), + }; + } - myHeroesHref: hrefEles.get(1), - myHeroesParent: element(by.css('my-app my-heroes')), - allHeroes: element.all(by.css('my-app my-heroes li .hero-element')), + // Hero from hero list
  • element. + static async fromLi(li: ElementFinder): Promise { + let strings = await li.all(by.xpath('span')).getText(); + return { id: +strings[0], name: strings[1] }; + } - firstDeleteButton: element.all(by.buttonText('Delete')).get(0), + // Hero id and name from the given detail element. + static async fromDetail(detail: ElementFinder): Promise { + // Get hero id from the first
    + let _id = await detail.all(by.css('div')).first().getText(); + // Get name from the h2 + let _name = await detail.element(by.css('h2')).getText(); + return { + id: +_id.substr(_id.indexOf(' ') + 1), + name: _name.substr(0, _name.lastIndexOf(' ')) + }; + } +} - addButton: element.all(by.buttonText('Add New Hero')).get(0), +describe('Tutorial part 6', () => { - heroDetail: element(by.css('my-app my-hero-detail')) + beforeAll(() => browser.get('')); + + function getPageElts() { + let navElts = element.all(by.css('my-app nav a')); + + return { + navElts: navElts, + + myDashboardHref: navElts.get(0), + myDashboard: element(by.css('my-app my-dashboard')), + topHeroes: element.all(by.css('my-app my-dashboard > div h4')), + + myHeroesHref: navElts.get(1), + myHeroes: element(by.css('my-app my-heroes')), + allHeroes: element.all(by.css('my-app my-heroes li')), + selectedHero: element(by.css('my-app li.selected')), + selectedHeroSubview: element(by.css('my-app my-heroes > div:last-child')), + + heroDetail: element(by.css('my-app hero-detail > div')), + + searchBox: element(by.css('#search-box')), + searchResults: element.all(by.css('.search-result')) }; } - it('should be able to add a hero from the "Heroes" view', function(){ - let page = getPageStruct(); - let heroCount: webdriver.promise.Promise; + describe('Initial page', () => { - page.myHeroesHref.click().then(function() { - browser.waitForAngular(); - heroCount = page.allHeroes.count(); - expect(heroCount).toBe(10, 'should show 10'); - }).then(function() { - return page.addButton.click(); - }).then(function(){ - return save(page,'','The New Hero'); - }).then(function(){ - browser.waitForAngular(); + it(`has title '${expectedTitle}'`, () => { + expect(browser.getTitle()).toEqual(expectedTitle); + }); - heroCount = page.allHeroes.count(); - expect(heroCount).toBe(11, 'should show 11'); + it(`has h1 '${expectedH1}'`, () => { + expectHeading(1, expectedH1); + }); - let newHero = element(by.xpath('//span[@class="hero-element" and contains(text(),"The New Hero")]')); - expect(newHero).toBeDefined(); + const expectedViewNames = ['Dashboard', 'Heroes']; + it(`has views ${expectedViewNames}`, () => { + let viewNames = getPageElts().navElts.map((el: ElementFinder) => el.getText()); + expect(viewNames).toEqual(expectedViewNames); }); - }); - it('should be able to delete hero from "Heroes" view', function(){ - let page = getPageStruct(); - let heroCount: webdriver.promise.Promise; - - page.myHeroesHref.click().then(function() { - browser.waitForAngular(); - heroCount = page.allHeroes.count(); - expect(heroCount).toBe(10, 'should show 10'); - }).then(function() { - return page.firstDeleteButton.click(); - }).then(function(){ - browser.waitForAngular(); - heroCount = page.allHeroes.count(); - expect(heroCount).toBe(9, 'should show 9'); + it('has dashboard as the active view', () => { + let page = getPageElts(); + expect(page.myDashboard.isPresent()).toBeTruthy(); }); + }); - it('should be able to save details from "Dashboard" view', function () { - let page = getPageStruct(); - expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available'); - let heroEle = page.topHeroes.get(2); - let heroDescrEle = heroEle.element(by.css('h4')); - let heroDescr: string; - - return heroDescrEle.getText().then(function(text) { - heroDescr = text; - return heroEle.click(); - }).then(function() { - return save(page, heroDescr, '-foo'); - }) - .then(function(){ - return page.myDashboardHref.click(); - }) - .then(function() { - expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be back'); - expect(heroDescrEle.getText()).toEqual(heroDescr + '-foo'); + describe('Dashboard tests', () => { + + beforeAll(() => browser.get('')); + + it('has top heroes', () => { + let page = getPageElts(); + expect(page.topHeroes.count()).toEqual(4); }); - }); - it('should be able to save details from "Heroes" view', function () { - let page = getPageStruct(); - - let viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details')); - let heroEle: protractor.ElementFinder, heroDescr: string; - - page.myHeroesHref.click().then(function() { - expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present'); - expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present'); - expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should not yet be present'); - heroEle = page.allHeroes.get(0); - return heroEle.getText(); - }).then(function(text) { - // remove leading 'id' from the element - heroDescr = text.substr(text.indexOf(' ') + 1); - return heroEle.click(); - }).then(function() { - expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible'); - return viewDetailsButtonEle.click(); - }).then(function() { - return save(page, heroDescr, '-bar'); - }) - .then(function(){ - return page.myHeroesHref.click(); - }) - .then(function() { - expect(heroEle.getText()).toContain(heroDescr + '-bar'); + it(`selects and routes to ${targetHero.name} details`, dashboardSelectTargetHero); + + it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView); + + it(`cancels and shows ${targetHero.name} in Dashboard`, () => { + element(by.buttonText('Back')).click(); + browser.waitForAngular(); // seems necessary to gets tests to past for toh-6 + + let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex); + expect(targetHeroElt.getText()).toEqual(targetHero.name); }); - }); - function save(page: any, origValue: string, textToAdd: string) { - let inputEle = page.heroDetail.element(by.css('input')); - expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box'); - let saveButtonEle = page.heroDetail.element(by.buttonText('Save')); - let backButtonEle = page.heroDetail.element(by.buttonText('Back')); - expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button'); - let detailTextEle = page.heroDetail.element(by.css('div h2')); - expect(detailTextEle.getText()).toContain(origValue); - return sendKeys(inputEle, textToAdd).then(function () { - expect(detailTextEle.getText()).toContain(origValue + textToAdd); - return saveButtonEle.click(); + it(`selects and routes to ${targetHero.name} details`, dashboardSelectTargetHero); + + it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView); + + it(`saves and shows ${newHeroName} in Dashboard`, () => { + element(by.buttonText('Save')).click(); + browser.waitForAngular(); // seems necessary to gets tests to past for toh-6 + + let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex); + expect(targetHeroElt.getText()).toEqual(newHeroName); }); - } - it('should be able to see the start screen', function () { - let page = getPageStruct(); - expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices'); - expect(page.myDashboardHref.getText()).toEqual('Dashboard'); - expect(page.myHeroesHref.getText()).toEqual('Heroes'); }); - it('should be able to see dashboard choices', function () { - let page = getPageStruct(); - expect(page.topHeroes.count()).toBe(4, 'should be 4 dashboard hero choices'); - }); + describe('Heroes tests', () => { - it('should be able to toggle the views', function () { - let page = getPageStruct(); + beforeAll(() => browser.get('')); - expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes'); - page.myHeroesHref.click().then(function() { - expect(page.myDashboardParent.isPresent()).toBe(false, 'should no longer see dashboard element'); - expect(page.allHeroes.count()).toBeGreaterThan(4, 'should be more than 4 heroes shown'); - return page.myDashboardHref.click(); - }).then(function() { - expect(page.myDashboardParent.isPresent()).toBe(true, 'should once again see the dashboard element'); + it('can switch to Heroes view', () => { + getPageElts().myHeroesHref.click(); + let page = getPageElts(); + expect(page.myHeroes.isPresent()).toBeTruthy(); + expect(page.allHeroes.count()).toEqual(10, 'number of heroes'); }); - }); + it(`selects and shows ${targetHero.name} as selected in list`, () => { + getHeroLiEltById(targetHero.id).click(); + expect(Hero.fromLi(getPageElts().selectedHero)).toEqual(targetHero); + }); - it('should be able to edit details from "Dashboard" view', function () { - let page = getPageStruct(); - expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available'); - let heroEle = page.topHeroes.get(3); - let heroDescrEle = heroEle.element(by.css('h4')); - let heroDescr: string; - return heroDescrEle.getText().then(function(text) { - heroDescr = text; - return heroEle.click(); - }).then(function() { - return editDetails(page, heroDescr, '-foo'); - }).then(function() { - expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be back'); - expect(heroDescrEle.getText()).toEqual(heroDescr + '-foo'); + it('shows selected hero subview', () => { + let page = getPageElts(); + let title = page.selectedHeroSubview.element(by.css('h2')).getText(); + let expectedTitle = `${targetHero.name.toUpperCase()} is my hero`; + expect(title).toEqual(expectedTitle); }); - }); - it('should be able to edit details from "Heroes" view', function () { - let page = getPageStruct(); - expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be present'); - let viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details')); - let heroEle: protractor.ElementFinder, heroDescr: string; - page.myHeroesHref.click().then(function() { - expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present'); - expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present'); - expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should not yet be present'); - heroEle = page.allHeroes.get(2); - return heroEle.getText(); - }).then(function(text) { - // remove leading 'id' from the element - heroDescr = text.substr(text.indexOf(' ') + 1); - return heroEle.click(); - }).then(function() { - expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible'); - return viewDetailsButtonEle.click(); - }).then(function() { - return editDetails(page, heroDescr, '-bar'); - }).then(function() { - expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be back'); - expect(heroEle.getText()).toContain(heroDescr + '-bar'); - expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should again NOT be present'); + it('can route to hero details', () => { + element(by.buttonText('View Details')).click(); + + let page = getPageElts(); + expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail'); + let hero = Hero.fromDetail(page.heroDetail); + expect(hero).toEqual(targetHero); + }); + + it(`updates hero name (${newHeroName}) in details view`, updateHeroNameInDetailView); + + it(`shows ${newHeroName} in Heroes list`, () => { + element(by.buttonText('Save')).click(); + browser.waitForAngular(); // seems necessary to gets tests to past for toh-6 + let expectedHero = {id: targetHero.id, name: newHeroName}; + expect(Hero.fromLi(getHeroLiEltById(targetHero.id))).toEqual(expectedHero); + }); + + it(`deletes ${newHeroName} from Heroes list`, async () => { + const heroesBefore = await toHeroArray(getPageElts().allHeroes); + const li = getHeroLiEltById(targetHero.id); + li.element(by.buttonText('x')).click(); + + const page = getPageElts(); + expect(page.myHeroes.isPresent()).toBeTruthy(); + expect(page.allHeroes.count()).toEqual(9, 'number of heroes'); + const heroesAfter = await toHeroArray(page.allHeroes); + const expectedHeroes = heroesBefore.filter(h => h.name !== newHeroName); + expect(heroesAfter).toEqual(expectedHeroes); + expect(page.selectedHeroSubview.isPresent()).toBeFalsy(); + }); + + it(`adds back ${targetHero.name}`, async () => { + const newHeroName = 'Alice'; + const heroesBefore = await toHeroArray(getPageElts().allHeroes); + const numHeroes = heroesBefore.length; + + element(by.css('input')).sendKeys(newHeroName); + element(by.buttonText('Add')).click(); + + let page = getPageElts(); + let heroesAfter = await toHeroArray(page.allHeroes); + expect(heroesAfter.length).toEqual(numHeroes + 1, 'number of heroes'); + + expect(heroesAfter.slice(0, numHeroes)).toEqual(heroesBefore, 'Old heroes are still there'); + + const maxId = heroesBefore[heroesBefore.length - 1].id; + expect(heroesAfter[numHeroes]).toEqual({id: maxId + 1, name: newHeroName}); }); }); - function editDetails(page: any, origValue: string, textToAdd: string) { - expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present'); - expect(page.myHeroesParent.isPresent()).toBe(false, 'myHeroes element should NOT be present'); - expect(page.heroDetail.isDisplayed()).toBe(true, 'should be able to see hero-details'); - let inputEle = page.heroDetail.element(by.css('input')); - expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box'); - let buttons = page.heroDetail.all(by.css('button')); - let backButtonEle = buttons.get(0); - let saveButtonEle = buttons.get(1); - expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button'); - expect(saveButtonEle.isDisplayed()).toBe(true, 'should be able to see the save button'); - let detailTextEle = page.heroDetail.element(by.css('div h2')); - expect(detailTextEle.getText()).toContain(origValue); - return sendKeys(inputEle, textToAdd).then(function () { - expect(detailTextEle.getText()).toContain(origValue + textToAdd); - return saveButtonEle.click(); + describe('Progressive hero search', () => { + + beforeAll(() => browser.get('')); + + it(`searches for 'Ma'`, async () => { + getPageElts().searchBox.sendKeys('Ma'); + browser.sleep(1000); + expect(getPageElts().searchResults.count()).toBe(4); }); + + it(`continues search with 'g'`, async () => { + getPageElts().searchBox.sendKeys('g'); + browser.sleep(1000); + expect(getPageElts().searchResults.count()).toBe(2); + }); + + it(`continues search with 'n' and gets ${targetHero.name}`, async () => { + getPageElts().searchBox.sendKeys('n'); + browser.sleep(1000); + let page = getPageElts(); + expect(page.searchResults.count()).toBe(1); + let hero = page.searchResults.get(0); + expect(hero.getText()).toEqual(targetHero.name); + }); + + it(`navigates to ${targetHero.name} details view`, async () => { + let hero = getPageElts().searchResults.get(0); + expect(hero.getText()).toEqual(targetHero.name); + hero.click(); + + let page = getPageElts(); + expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail'); + expect(Hero.fromDetail(page.heroDetail)).toEqual(targetHero); + }); + }); + + function dashboardSelectTargetHero() { + let targetHeroElt = getPageElts().topHeroes.get(targetHeroDashboardIndex); + expect(targetHeroElt.getText()).toEqual(targetHero.name); + targetHeroElt.click(); + browser.waitForAngular(); // seems necessary to gets tests to past for toh-6 + + let page = getPageElts(); + expect(page.heroDetail.isPresent()).toBeTruthy('shows hero detail'); + let hero = Hero.fromDetail(page.heroDetail); + expect(hero).toEqual(targetHero); + } + + async function updateHeroNameInDetailView() { + // Assumes that the current view is the hero details view. + addToHeroName(nameSuffix); + + let hero = await Hero.fromDetail(getPageElts().heroDetail); + expect(hero).toEqual({id: targetHero.id, name: newHeroName}); } }); + +function addToHeroName(text: string): promise.Promise { + let input = element(by.css('input')); + return input.sendKeys(text); +} + +function expectHeading(hLevel: number, expectedText: string): void { + let hTag = `h${hLevel}`; + let hText = element(by.css(hTag)).getText(); + expect(hText).toEqual(expectedText, hTag); +}; + +function getHeroLiEltById(id: number): ElementFinder { + let spanForId = element(by.cssContainingText('li span.badge', id.toString())); + return spanForId.element(by.xpath('..')); +} + +async function toHeroArray(allHeroes: ElementArrayFinder): Promise { + let promisedHeroes = await allHeroes.map(Hero.fromLi); + // The cast is necessary to get around issuing with the signature of Promise.all() + return > Promise.all(promisedHeroes); +} diff --git a/public/docs/_examples/toh-6/ts/.gitignore b/public/docs/_examples/toh-6/ts/.gitignore index 2cb7d2a2e9..804879d44a 100644 --- a/public/docs/_examples/toh-6/ts/.gitignore +++ b/public/docs/_examples/toh-6/ts/.gitignore @@ -1 +1,8 @@ +aot/**/*.ts +**/*.ngfactory.ts +**/*.ngsummary.json +**/*.metadata.json **/*.js +dist +!app/tsconfig.json +!rollup-config.js diff --git a/public/docs/_examples/toh-6/ts/aot/index.html b/public/docs/_examples/toh-6/ts/aot/index.html new file mode 100644 index 0000000000..cb8ecc4461 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/aot/index.html @@ -0,0 +1,19 @@ + + + + + + Angular Tour of Heroes + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/toh-6/ts/aot/styles.css b/public/docs/_examples/toh-6/ts/aot/styles.css new file mode 100644 index 0000000000..d81835d0cd --- /dev/null +++ b/public/docs/_examples/toh-6/ts/aot/styles.css @@ -0,0 +1,116 @@ +/* #docregion , quickstart, toh */ +/* Master Styles */ +h1 { + color: #369; + font-family: Arial, Helvetica, sans-serif; + font-size: 250%; +} +h2, h3 { + color: #444; + font-family: Arial, Helvetica, sans-serif; + font-weight: lighter; +} +body { + margin: 2em; +} +/* #enddocregion quickstart */ +body, input[text], button { + color: #888; + font-family: Cambria, Georgia; +} +/* #enddocregion toh */ +a { + cursor: pointer; + cursor: hand; +} +button { + font-family: Arial; + background-color: #eee; + border: none; + padding: 5px 10px; + border-radius: 4px; + cursor: pointer; + cursor: hand; +} +button:hover { + background-color: #cfd8dc; +} +button:disabled { + background-color: #eee; + color: #aaa; + cursor: auto; +} + +/* Navigation link styles */ +nav a { + padding: 5px 10px; + text-decoration: none; + margin-right: 10px; + margin-top: 10px; + display: inline-block; + background-color: #eee; + border-radius: 4px; +} +nav a:visited, a:link { + color: #607D8B; +} +nav a:hover { + color: #039be5; + background-color: #CFD8DC; +} +nav a.active { + color: #039be5; +} + +/* items class */ +.items { + margin: 0 0 2em 0; + list-style-type: none; + padding: 0; + width: 24em; +} +.items li { + cursor: pointer; + position: relative; + left: 0; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; +} +.items li:hover { + color: #607D8B; + background-color: #DDD; + left: .1em; +} +.items li.selected { + background-color: #CFD8DC; + color: white; +} +.items li.selected:hover { + background-color: #BBD8DC; +} +.items .text { + position: relative; + top: -3px; +} +.items .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0 0 4px; +} +/* #docregion toh */ +/* everywhere else */ +* { + font-family: Arial, Helvetica, sans-serif; +} diff --git a/public/docs/_examples/toh-6/ts/app/app.component.css b/public/docs/_examples/toh-6/ts/app/app.component.css deleted file mode 100644 index 137e9be7be..0000000000 --- a/public/docs/_examples/toh-6/ts/app/app.component.css +++ /dev/null @@ -1,31 +0,0 @@ -/* #docplaster */ -/* #docregion css */ -h1 { - font-size: 1.2em; - color: #999; - margin-bottom: 0; -} -h2 { - font-size: 2em; - margin-top: 0; - padding-top: 0; -} -nav a { - padding: 5px 10px; - text-decoration: none; - margin-top: 10px; - display: inline-block; - background-color: #eee; - border-radius: 4px; -} -nav a:visited, a:link { - color: #607D8B; -} -nav a:hover { - color: #039be5; - background-color: #CFD8DC; -} -nav a.router-link-active { - color: #039be5; -} -/* #enddocregion css */ diff --git a/public/docs/_examples/toh-6/ts/app/app.component.ts b/public/docs/_examples/toh-6/ts/app/app.component.ts deleted file mode 100644 index 22317d4403..0000000000 --- a/public/docs/_examples/toh-6/ts/app/app.component.ts +++ /dev/null @@ -1,36 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; -import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated'; - -import { DashboardComponent } from './dashboard.component'; -import { HeroesComponent } from './heroes.component'; -import { HeroDetailComponent } from './hero-detail.component'; -import { HeroService } from './hero.service'; - -@Component({ - selector: 'my-app', - - template: ` -

    {{title}}

    - - - `, - styleUrls: ['app/app.component.css'], - directives: [ROUTER_DIRECTIVES], - providers: [ - ROUTER_PROVIDERS, - HeroService, - ] -}) -@RouteConfig([ - { path: '/dashboard', name: 'Dashboard', component: DashboardComponent, useAsDefault: true }, - { path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent }, - { path: '/heroes', name: 'Heroes', component: HeroesComponent } -]) -export class AppComponent { - title = 'Tour of Heroes'; -} diff --git a/public/docs/_examples/toh-6/ts/app/dashboard.component.css b/public/docs/_examples/toh-6/ts/app/dashboard.component.css deleted file mode 100644 index ce6e963a5f..0000000000 --- a/public/docs/_examples/toh-6/ts/app/dashboard.component.css +++ /dev/null @@ -1,63 +0,0 @@ -/* #docplaster */ -/* #docregion */ -[class*='col-'] { - float: left; -} -*, *:after, *:before { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -h3 { - text-align: center; margin-bottom: 0; -} -[class*='col-'] { - padding-right: 20px; - padding-bottom: 20px; -} -[class*='col-']:last-of-type { - padding-right: 0; -} -.grid { - margin: 0; -} -.col-1-4 { - width: 25%; -} -.module { - padding: 20px; - text-align: center; - color: #eee; - max-height: 120px; - min-width: 120px; - background-color: #607D8B; - border-radius: 2px; -} -h4 { - position: relative; -} -.module:hover { - background-color: #EEE; - cursor: pointer; - color: #607d8b; -} -.grid-pad { - padding: 10px 0; -} -.grid-pad > [class*='col-']:last-of-type { - padding-right: 20px; -} -@media (max-width: 600px) { - .module { - font-size: 10px; - max-height: 75px; } -} -@media (max-width: 1024px) { - .grid { - margin: 0; - } - .module { - min-width: 60px; - } -} -/* #enddocregion */ diff --git a/public/docs/_examples/toh-6/ts/app/dashboard.component.html b/public/docs/_examples/toh-6/ts/app/dashboard.component.html deleted file mode 100644 index 028eab6eb3..0000000000 --- a/public/docs/_examples/toh-6/ts/app/dashboard.component.html +++ /dev/null @@ -1,11 +0,0 @@ - -

    Top Heroes

    -
    - -
    - -
    -

    {{hero.name}}

    -
    -
    -
    diff --git a/public/docs/_examples/toh-6/ts/app/dashboard.component.ts b/public/docs/_examples/toh-6/ts/app/dashboard.component.ts deleted file mode 100644 index 988d51fee9..0000000000 --- a/public/docs/_examples/toh-6/ts/app/dashboard.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -// #docplaster -// #docregion -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router-deprecated'; - -import { Hero } from './hero'; -import { HeroService } from './hero.service'; - -@Component({ - selector: 'my-dashboard', - templateUrl: 'app/dashboard.component.html', - styleUrls: ['app/dashboard.component.css'] -}) -export class DashboardComponent implements OnInit { - - heroes: Hero[] = []; - - constructor( - private router: Router, - private heroService: HeroService) { - } - - ngOnInit() { - this.heroService.getHeroes() - .then(heroes => this.heroes = heroes.slice(1,5)); - } - - gotoDetail(hero: Hero) { - let link = ['HeroDetail', { id: hero.id }]; - this.router.navigate(link); - } -} diff --git a/public/docs/_examples/toh-6/ts/app/hero-detail.component.html b/public/docs/_examples/toh-6/ts/app/hero-detail.component.html deleted file mode 100644 index f532eb0109..0000000000 --- a/public/docs/_examples/toh-6/ts/app/hero-detail.component.html +++ /dev/null @@ -1,13 +0,0 @@ - - -
    -

    {{hero.name}} details!

    -
    - {{hero.id}}
    -
    - - -
    - - -
    \ No newline at end of file diff --git a/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts deleted file mode 100644 index 73ea334fc2..0000000000 --- a/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -// #docplaster -// #docregion -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { RouteParams } from '@angular/router-deprecated'; - -import { Hero } from './hero'; -import { HeroService } from './hero.service'; - -@Component({ - selector: 'my-hero-detail', - templateUrl: 'app/hero-detail.component.html', - styleUrls: ['app/hero-detail.component.css'] -}) -export class HeroDetailComponent implements OnInit { - @Input() hero: Hero; - @Output() close = new EventEmitter(); - error: any; - navigated = false; // true if navigated here - - constructor( - private heroService: HeroService, - private routeParams: RouteParams) { - } - - // #docregion ngOnInit - ngOnInit() { - if (this.routeParams.get('id') !== null) { - let id = +this.routeParams.get('id'); - this.navigated = true; - this.heroService.getHero(id) - .then(hero => this.hero = hero); - } else { - this.navigated = false; - this.hero = new Hero(); - } - } - // #enddocregion ngOnInit - // #docregion save - save() { - this.heroService - .save(this.hero) - .then(hero => { - this.hero = hero; // saved hero, w/ id if new - this.goBack(hero); - }) - .catch(error => this.error = error); // TODO: Display error message - } - // #enddocregion save - // #docregion goback - goBack(savedHero: Hero = null) { - this.close.emit(savedHero); - if (this.navigated) { window.history.back(); } - } - // #enddocregion goback -} - diff --git a/public/docs/_examples/toh-6/ts/app/hero.service.ts b/public/docs/_examples/toh-6/ts/app/hero.service.ts deleted file mode 100644 index fa1e1ac4e4..0000000000 --- a/public/docs/_examples/toh-6/ts/app/hero.service.ts +++ /dev/null @@ -1,99 +0,0 @@ -// #docplaster -// #docregion -import { Injectable } from '@angular/core'; -import { Headers, Http } from '@angular/http'; - -// #docregion rxjs -import 'rxjs/add/operator/toPromise'; -// #enddocregion rxjs - -import { Hero } from './hero'; - -@Injectable() -export class HeroService { - - private heroesUrl = 'app/heroes'; // URL to web api - - constructor(private http: Http) { } - - // #docregion get-heroes - getHeroes(): Promise { - return this.http.get(this.heroesUrl) - // #docregion to-promise - .toPromise() - // #enddocregion to-promise - // #docregion to-data - .then(response => response.json().data) - // #enddocregion to-data - // #docregion catch - .catch(this.handleError); - // #enddocregion catch - } - // #enddocregion get-heroes - - getHero(id: number) { - return this.getHeroes() - .then(heroes => heroes.filter(hero => hero.id === id)[0]); - } - - // #docregion save - save(hero: Hero): Promise { - if (hero.id) { - return this.put(hero); - } - return this.post(hero); - } - // #enddocregion save - - // #docregion delete-hero - delete(hero: Hero) { - let headers = new Headers(); - headers.append('Content-Type', 'application/json'); - - let url = `${this.heroesUrl}/${hero.id}`; - - return this.http - .delete(url, headers) - .toPromise() - .catch(this.handleError); - } - // #enddocregion delete-hero - - // #docregion post-hero - // Add new Hero - private post(hero: Hero): Promise { - let headers = new Headers({ - 'Content-Type': 'application/json'}); - - return this.http - .post(this.heroesUrl, JSON.stringify(hero), {headers: headers}) - .toPromise() - .then(res => res.json().data) - .catch(this.handleError); - } - // #enddocregion post-hero - - // #docregion put-hero - // Update existing Hero - private put(hero: Hero) { - let headers = new Headers(); - headers.append('Content-Type', 'application/json'); - - let url = `${this.heroesUrl}/${hero.id}`; - - return this.http - .put(url, JSON.stringify(hero), {headers: headers}) - .toPromise() - .then(() => hero) - .catch(this.handleError); - } - // #enddocregion put-hero - - // #docregion error-handler - private handleError(error: any) { - console.error('An error occurred', error); - return Promise.reject(error.message || error); - } - // #enddocregion error-handler -} -// #enddocregion diff --git a/public/docs/_examples/toh-6/ts/app/heroes.component.css b/public/docs/_examples/toh-6/ts/app/heroes.component.css deleted file mode 100644 index 35e45af98d..0000000000 --- a/public/docs/_examples/toh-6/ts/app/heroes.component.css +++ /dev/null @@ -1,59 +0,0 @@ -.selected { - background-color: #CFD8DC !important; - color: white; -} -.heroes { - margin: 0 0 2em 0; - list-style-type: none; - padding: 0; - width: 15em; -} -.heroes li { - cursor: pointer; - position: relative; - left: 0; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; -} -.heroes li:hover { - color: #607D8B; - background-color: #DDD; - left: .1em; -} -.heroes li.selected:hover { - background-color: #BBD8DC !important; - color: white; -} -.heroes .text { - position: relative; - top: -3px; -} -.heroes .badge { - display: inline-block; - font-size: small; - color: white; - padding: 0.8em 0.7em 0 0.7em; - background-color: #607D8B; - line-height: 1em; - position: relative; - left: -1px; - top: -4px; - height: 1.8em; - margin-right: .8em; - border-radius: 4px 0 0 4px; -} -button { - font-family: Arial; - background-color: #eee; - border: none; - padding: 5px 10px; - border-radius: 4px; - cursor: pointer; - cursor: hand; -} -button:hover { - background-color: #cfd8dc; -} diff --git a/public/docs/_examples/toh-6/ts/app/heroes.component.html b/public/docs/_examples/toh-6/ts/app/heroes.component.html deleted file mode 100644 index 705c67677f..0000000000 --- a/public/docs/_examples/toh-6/ts/app/heroes.component.html +++ /dev/null @@ -1,26 +0,0 @@ - -

    My Heroes

    -
      -
    • - - {{hero.id}} {{hero.name}} - - - - -
    • -
    - - - -
    - -
    - - -
    -

    - {{selectedHero.name | uppercase}} is my hero -

    - -
    diff --git a/public/docs/_examples/toh-6/ts/app/heroes.component.ts b/public/docs/_examples/toh-6/ts/app/heroes.component.ts deleted file mode 100644 index df3f26c69b..0000000000 --- a/public/docs/_examples/toh-6/ts/app/heroes.component.ts +++ /dev/null @@ -1,71 +0,0 @@ -// #docregion -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router-deprecated'; - -import { Hero } from './hero'; -import { HeroService } from './hero.service'; -// #docregion hero-detail-component -import { HeroDetailComponent } from './hero-detail.component'; - -@Component({ - selector: 'my-heroes', - templateUrl: 'app/heroes.component.html', - styleUrls: ['app/heroes.component.css'], - directives: [HeroDetailComponent] -}) -// #enddocregion hero-detail-component -export class HeroesComponent implements OnInit { - heroes: Hero[]; - selectedHero: Hero; - addingHero = false; - error: any; - - constructor( - private router: Router, - private heroService: HeroService) { } - - getHeroes() { - this.heroService - .getHeroes() - .then(heroes => this.heroes = heroes) - .catch(error => this.error = error); // TODO: Display error message - } - - // #docregion add - addHero() { - this.addingHero = true; - this.selectedHero = null; - } - - close(savedHero: Hero) { - this.addingHero = false; - if (savedHero) { this.getHeroes(); } - } - // #enddocregion add - - // #docregion delete - delete(hero: Hero, event: any) { - event.stopPropagation(); - this.heroService - .delete(hero) - .then(res => { - this.heroes = this.heroes.filter(h => h !== hero); - if (this.selectedHero === hero) { this.selectedHero = null; } - }) - .catch(error => this.error = error); // TODO: Display error message - } - // #enddocregion delete - - ngOnInit() { - this.getHeroes(); - } - - onSelect(hero: Hero) { - this.selectedHero = hero; - this.addingHero = false; - } - - gotoDetail() { - this.router.navigate(['HeroDetail', { id: this.selectedHero.id }]); - } -} diff --git a/public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts b/public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts deleted file mode 100644 index 791b6ae2c5..0000000000 --- a/public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts +++ /dev/null @@ -1,18 +0,0 @@ -// #docregion -export class InMemoryDataService { - createDb() { - let heroes = [ - {id: 11, name: 'Mr. Nice'}, - {id: 12, name: 'Narco'}, - {id: 13, name: 'Bombasto'}, - {id: 14, name: 'Celeritas'}, - {id: 15, name: 'Magneta'}, - {id: 16, name: 'RubberMan'}, - {id: 17, name: 'Dynama'}, - {id: 18, name: 'Dr IQ'}, - {id: 19, name: 'Magma'}, - {id: 20, name: 'Tornado'} - ]; - return {heroes}; - } -} diff --git a/public/docs/_examples/toh-6/ts/app/main.ts b/public/docs/_examples/toh-6/ts/app/main.ts deleted file mode 100644 index 958b9a8c69..0000000000 --- a/public/docs/_examples/toh-6/ts/app/main.ts +++ /dev/null @@ -1,28 +0,0 @@ -// #docplaster -// #docregion final -// Imports for loading & configuring the in-memory web api -import { XHRBackend } from '@angular/http'; - -import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api'; -import { InMemoryDataService } from './in-memory-data.service'; - -// The usual bootstrapping imports -// #docregion v1 -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { HTTP_PROVIDERS } from '@angular/http'; - -import { AppComponent } from './app.component'; - -// #enddocregion v1, final -/* -// #docregion v1 -bootstrap(AppComponent, [ HTTP_PROVIDERS ]); -// #enddocregion v1 - */ -// #docregion final -bootstrap(AppComponent, [ - HTTP_PROVIDERS, - { provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server - { provide: SEED_DATA, useClass: InMemoryDataService } // in-mem server data -]); -// #enddocregion final diff --git a/public/docs/_examples/toh-6/ts/bs-config.aot.json b/public/docs/_examples/toh-6/ts/bs-config.aot.json new file mode 100644 index 0000000000..e59a7403a0 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/bs-config.aot.json @@ -0,0 +1,14 @@ +{ + "open": false, + "logLevel": "silent", + "port": 8080, + "server": { + "baseDir": "aot", + "routes": { + "/node_modules": "node_modules" + }, + "middleware": { + "0": null + } + } +} diff --git a/public/docs/_examples/toh-6/ts/copy-dist-files.js b/public/docs/_examples/toh-6/ts/copy-dist-files.js new file mode 100644 index 0000000000..080864e99c --- /dev/null +++ b/public/docs/_examples/toh-6/ts/copy-dist-files.js @@ -0,0 +1,12 @@ +// #docregion +var fs = require('fs'); +var resources = [ + 'node_modules/core-js/client/shim.min.js', + 'node_modules/zone.js/dist/zone.min.js', + 'src/styles.css' +]; +resources.map(function(f) { + var path = f.split('/'); + var t = 'aot/' + path[path.length-1]; + fs.createReadStream(f).pipe(fs.createWriteStream(t)); +}); diff --git a/public/docs/_examples/toh-6/ts/index.html b/public/docs/_examples/toh-6/ts/index.html deleted file mode 100644 index b84f744a78..0000000000 --- a/public/docs/_examples/toh-6/ts/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - Angular 2 Tour of Heroes - - - - - - - - - - - - - - - - - - Loading... - - diff --git a/public/docs/_examples/toh-6/ts/plnkr.json b/public/docs/_examples/toh-6/ts/plnkr.json index 777d9ad1f1..d355bc9ff2 100644 --- a/public/docs/_examples/toh-6/ts/plnkr.json +++ b/public/docs/_examples/toh-6/ts/plnkr.json @@ -1,5 +1,6 @@ { "description": "Tour of Heroes: Part 6", + "basePath": "src/", "files":[ "!**/*.d.ts", "!**/*.js", diff --git a/public/docs/_examples/toh-6/ts/rollup-config.js b/public/docs/_examples/toh-6/ts/rollup-config.js new file mode 100644 index 0000000000..5689edcff4 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/rollup-config.js @@ -0,0 +1,30 @@ +// #docregion +import rollup from 'rollup' +import nodeResolve from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs'; +import uglify from 'rollup-plugin-uglify' + +//paths are relative to the execution path +export default { + entry: 'src/main-aot.js', + dest: 'aot/dist/build.js', // output a single application bundle + sourceMap: true, + sourceMapFile: 'aot/dist/build.js.map', + format: 'iife', + onwarn: function(warning) { + // Skip certain warnings + + // should intercept ... but doesn't in some rollup versions + if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; } + + // console.warn everything else + console.warn( warning.message ); + }, + plugins: [ + nodeResolve({jsnext: true, module: true}), + commonjs({ + include: ['node_modules/rxjs/**'] + }), + uglify() + ] +} diff --git a/public/docs/_examples/toh-6/ts/sample.css b/public/docs/_examples/toh-6/ts/sample.css deleted file mode 100644 index 042f0494f6..0000000000 --- a/public/docs/_examples/toh-6/ts/sample.css +++ /dev/null @@ -1,8 +0,0 @@ -button.delete-button{ - float:right; - background-color: gray !important; - color:white; -} - - - diff --git a/public/docs/_examples/toh-6/ts/src/app/app-routing.module.ts b/public/docs/_examples/toh-6/ts/src/app/app-routing.module.ts new file mode 100644 index 0000000000..bc070f6c31 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/app-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { DashboardComponent } from './dashboard.component'; +import { HeroesComponent } from './heroes.component'; +import { HeroDetailComponent } from './hero-detail.component'; + +const routes: Routes = [ + { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, + { path: 'dashboard', component: DashboardComponent }, + { path: 'detail/:id', component: HeroDetailComponent }, + { path: 'heroes', component: HeroesComponent } +]; + +@NgModule({ + imports: [ RouterModule.forRoot(routes) ], + exports: [ RouterModule ] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/toh-6/ts/src/app/app.component.css b/public/docs/_examples/toh-6/ts/src/app/app.component.css new file mode 100644 index 0000000000..071e665767 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/app.component.css @@ -0,0 +1,29 @@ +/* #docregion */ +h1 { + font-size: 1.2em; + color: #999; + margin-bottom: 0; +} +h2 { + font-size: 2em; + margin-top: 0; + padding-top: 0; +} +nav a { + padding: 5px 10px; + text-decoration: none; + margin-top: 10px; + display: inline-block; + background-color: #eee; + border-radius: 4px; +} +nav a:visited, a:link { + color: #607D8B; +} +nav a:hover { + color: #039be5; + background-color: #CFD8DC; +} +nav a.active { + color: #039be5; +} diff --git a/public/docs/_examples/toh-6/ts/src/app/app.component.ts b/public/docs/_examples/toh-6/ts/src/app/app.component.ts new file mode 100644 index 0000000000..a9fe05a9a8 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/app.component.ts @@ -0,0 +1,19 @@ +// #docplaster +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` +

    {{title}}

    + + + `, + styleUrls: ['./app.component.css'] +}) +export class AppComponent { + title = 'Tour of Heroes'; +} diff --git a/public/docs/_examples/toh-6/ts/src/app/app.module.ts b/public/docs/_examples/toh-6/ts/src/app/app.module.ts new file mode 100644 index 0000000000..58eeb10c54 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/app.module.ts @@ -0,0 +1,52 @@ +// #docplaster +// #docregion +// #docregion v1, v2 +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +import { AppRoutingModule } from './app-routing.module'; + +// #enddocregion v1 +// Imports for loading & configuring the in-memory web api +import { InMemoryWebApiModule } from 'angular-in-memory-web-api'; +import { InMemoryDataService } from './in-memory-data.service'; + +// #docregion v1 +import { AppComponent } from './app.component'; +import { DashboardComponent } from './dashboard.component'; +import { HeroesComponent } from './heroes.component'; +import { HeroDetailComponent } from './hero-detail.component'; +import { HeroService } from './hero.service'; +// #enddocregion v1, v2 +import { HeroSearchComponent } from './hero-search.component'; +// #docregion v1, v2 + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HttpModule, + // #enddocregion v1 + // #docregion in-mem-web-api + InMemoryWebApiModule.forRoot(InMemoryDataService), + // #enddocregion in-mem-web-api + // #docregion v1 + AppRoutingModule + ], + // #docregion search + declarations: [ + AppComponent, + DashboardComponent, + HeroDetailComponent, + HeroesComponent, + // #enddocregion v1, v2 + HeroSearchComponent + // #docregion v1, v2 + ], + // #enddocregion search + providers: [ HeroService ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/toh-6/ts/src/app/dashboard.component.css b/public/docs/_examples/toh-6/ts/src/app/dashboard.component.css new file mode 100644 index 0000000000..dc7fb7ce06 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/dashboard.component.css @@ -0,0 +1,62 @@ +/* #docregion */ +[class*='col-'] { + float: left; + padding-right: 20px; + padding-bottom: 20px; +} +[class*='col-']:last-of-type { + padding-right: 0; +} +a { + text-decoration: none; +} +*, *:after, *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +h3 { + text-align: center; margin-bottom: 0; +} +h4 { + position: relative; +} +.grid { + margin: 0; +} +.col-1-4 { + width: 25%; +} +.module { + padding: 20px; + text-align: center; + color: #eee; + max-height: 120px; + min-width: 120px; + background-color: #607D8B; + border-radius: 2px; +} +.module:hover { + background-color: #EEE; + cursor: pointer; + color: #607d8b; +} +.grid-pad { + padding: 10px 0; +} +.grid-pad > [class*='col-']:last-of-type { + padding-right: 20px; +} +@media (max-width: 600px) { + .module { + font-size: 10px; + max-height: 75px; } +} +@media (max-width: 1024px) { + .grid { + margin: 0; + } + .module { + min-width: 60px; + } +} diff --git a/public/docs/_examples/toh-6/ts/src/app/dashboard.component.html b/public/docs/_examples/toh-6/ts/src/app/dashboard.component.html new file mode 100644 index 0000000000..db8546ccd2 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/dashboard.component.html @@ -0,0 +1,10 @@ + +

    Top Heroes

    + + diff --git a/public/docs/_examples/toh-6/ts/src/app/dashboard.component.ts b/public/docs/_examples/toh-6/ts/src/app/dashboard.component.ts new file mode 100644 index 0000000000..9960aa77d4 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/dashboard.component.ts @@ -0,0 +1,22 @@ +// #docregion , search +import { Component, OnInit } from '@angular/core'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +@Component({ + selector: 'my-dashboard', + templateUrl: './dashboard.component.html', + styleUrls: [ './dashboard.component.css' ] +}) +// #enddocregion search +export class DashboardComponent implements OnInit { + heroes: Hero[] = []; + + constructor(private heroService: HeroService) { } + + ngOnInit(): void { + this.heroService.getHeroes() + .then(heroes => this.heroes = heroes.slice(1, 5)); + } +} diff --git a/public/docs/_examples/toh-5/ts/app/hero-detail.component.css b/public/docs/_examples/toh-6/ts/src/app/hero-detail.component.css similarity index 100% rename from public/docs/_examples/toh-5/ts/app/hero-detail.component.css rename to public/docs/_examples/toh-6/ts/src/app/hero-detail.component.css diff --git a/public/docs/_examples/toh-6/ts/src/app/hero-detail.component.html b/public/docs/_examples/toh-6/ts/src/app/hero-detail.component.html new file mode 100644 index 0000000000..32fe6d4391 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/hero-detail.component.html @@ -0,0 +1,14 @@ + +
    +

    {{hero.name}} details!

    +
    + {{hero.id}}
    +
    + + +
    + + + + +
    diff --git a/public/docs/_examples/toh-6/ts/src/app/hero-detail.component.ts b/public/docs/_examples/toh-6/ts/src/app/hero-detail.component.ts new file mode 100644 index 0000000000..6224f10ac1 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/hero-detail.component.ts @@ -0,0 +1,40 @@ +// #docregion +import 'rxjs/add/operator/switchMap'; +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Params } from '@angular/router'; +import { Location } from '@angular/common'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +@Component({ + selector: 'hero-detail', + templateUrl: './hero-detail.component.html', + styleUrls: [ './hero-detail.component.css' ] +}) +export class HeroDetailComponent implements OnInit { + hero: Hero; + + constructor( + private heroService: HeroService, + private route: ActivatedRoute, + private location: Location + ) {} + + ngOnInit(): void { + this.route.params + .switchMap((params: Params) => this.heroService.getHero(+params['id'])) + .subscribe(hero => this.hero = hero); + } + + // #docregion save + save(): void { + this.heroService.update(this.hero) + .then(() => this.goBack()); + } + // #enddocregion save + + goBack(): void { + this.location.back(); + } +} diff --git a/public/docs/_examples/toh-6/ts/src/app/hero-search.component.css b/public/docs/_examples/toh-6/ts/src/app/hero-search.component.css new file mode 100644 index 0000000000..9bf8d13457 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/hero-search.component.css @@ -0,0 +1,21 @@ +/* #docregion */ +.search-result{ + border-bottom: 1px solid gray; + border-left: 1px solid gray; + border-right: 1px solid gray; + width:195px; + height: 16px; + padding: 5px; + background-color: white; + cursor: pointer; +} + +.search-result:hover { + color: #eee; + background-color: #607D8B; +} + +#search-box{ + width: 200px; + height: 20px; +} diff --git a/public/docs/_examples/toh-6/ts/src/app/hero-search.component.html b/public/docs/_examples/toh-6/ts/src/app/hero-search.component.html new file mode 100644 index 0000000000..08c0560c5b --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/hero-search.component.html @@ -0,0 +1,11 @@ + +
    +

    Hero Search

    + +
    +
    + {{hero.name}} +
    +
    +
    diff --git a/public/docs/_examples/toh-6/ts/src/app/hero-search.component.ts b/public/docs/_examples/toh-6/ts/src/app/hero-search.component.ts new file mode 100644 index 0000000000..8b2d32f06b --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/hero-search.component.ts @@ -0,0 +1,69 @@ +// #docplaster +// #docregion +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +// #docregion rxjs-imports +import { Observable } from 'rxjs/Observable'; +import { Subject } from 'rxjs/Subject'; + +// Observable class extensions +import 'rxjs/add/observable/of'; + +// Observable operators +import 'rxjs/add/operator/catch'; +import 'rxjs/add/operator/debounceTime'; +import 'rxjs/add/operator/distinctUntilChanged'; +// #enddocregion rxjs-imports + +import { HeroSearchService } from './hero-search.service'; +import { Hero } from './hero'; + +@Component({ + selector: 'hero-search', + templateUrl: './hero-search.component.html', + styleUrls: [ './hero-search.component.css' ], + providers: [HeroSearchService] +}) +export class HeroSearchComponent implements OnInit { + // #docregion search + heroes: Observable; + // #enddocregion search + // #docregion searchTerms + private searchTerms = new Subject(); + // #enddocregion searchTerms + + constructor( + private heroSearchService: HeroSearchService, + private router: Router) {} + // #docregion searchTerms + + // Push a search term into the observable stream. + search(term: string): void { + this.searchTerms.next(term); + } + // #enddocregion searchTerms + // #docregion search + + ngOnInit(): void { + this.heroes = this.searchTerms + .debounceTime(300) // wait 300ms after each keystroke before considering the term + .distinctUntilChanged() // ignore if next search term is same as previous + .switchMap(term => term // switch to new observable each time the term changes + // return the http search observable + ? this.heroSearchService.search(term) + // or the observable of empty heroes if there was no search term + : Observable.of([])) + .catch(error => { + // TODO: add real error handling + console.log(error); + return Observable.of([]); + }); + } + // #enddocregion search + + gotoDetail(hero: Hero): void { + let link = ['/detail', hero.id]; + this.router.navigate(link); + } +} diff --git a/public/docs/_examples/toh-6/ts/src/app/hero-search.service.ts b/public/docs/_examples/toh-6/ts/src/app/hero-search.service.ts new file mode 100644 index 0000000000..d24e0fba41 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/hero-search.service.ts @@ -0,0 +1,20 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { Http } from '@angular/http'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/map'; + +import { Hero } from './hero'; + +@Injectable() +export class HeroSearchService { + + constructor(private http: Http) {} + + search(term: string): Observable { + return this.http + .get(`app/heroes/?name=${term}`) + .map(response => response.json().data as Hero[]); + } +} diff --git a/public/docs/_examples/toh-6/ts/src/app/hero.service.ts b/public/docs/_examples/toh-6/ts/src/app/hero.service.ts new file mode 100644 index 0000000000..29fe5c2e0e --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/hero.service.ts @@ -0,0 +1,87 @@ +// #docplaster +// #docregion , imports +import { Injectable } from '@angular/core'; +import { Headers, Http } from '@angular/http'; + +// #docregion rxjs +import 'rxjs/add/operator/toPromise'; +// #enddocregion rxjs + +import { Hero } from './hero'; +// #enddocregion imports + +@Injectable() +export class HeroService { + + // #docregion update + private headers = new Headers({'Content-Type': 'application/json'}); + // #enddocregion update + // #docregion getHeroes + private heroesUrl = 'api/heroes'; // URL to web api + + constructor(private http: Http) { } + + getHeroes(): Promise { + return this.http.get(this.heroesUrl) + // #docregion to-promise + .toPromise() + // #enddocregion to-promise + // #docregion to-data + .then(response => response.json().data as Hero[]) + // #enddocregion to-data + // #docregion catch + .catch(this.handleError); + // #enddocregion catch + } + + // #enddocregion getHeroes + + // #docregion getHero + getHero(id: number): Promise { + const url = `${this.heroesUrl}/${id}`; + return this.http.get(url) + .toPromise() + .then(response => response.json().data as Hero) + .catch(this.handleError); + } + // #enddocregion getHero + + // #docregion delete + delete(id: number): Promise { + const url = `${this.heroesUrl}/${id}`; + return this.http.delete(url, {headers: this.headers}) + .toPromise() + .then(() => null) + .catch(this.handleError); + } + // #enddocregion delete + + // #docregion create + create(name: string): Promise { + return this.http + .post(this.heroesUrl, JSON.stringify({name: name}), {headers: this.headers}) + .toPromise() + .then(res => res.json().data as Hero) + .catch(this.handleError); + } + // #enddocregion create + // #docregion update + + update(hero: Hero): Promise { + const url = `${this.heroesUrl}/${hero.id}`; + return this.http + .put(url, JSON.stringify(hero), {headers: this.headers}) + .toPromise() + .then(() => hero) + .catch(this.handleError); + } + // #enddocregion update + + // #docregion getHeroes, handleError + private handleError(error: any): Promise { + console.error('An error occurred', error); // for demo purposes only + return Promise.reject(error.message || error); + } + // #enddocregion getHeroes, handleError +} + diff --git a/public/docs/_examples/toh-6/ts/app/hero.ts b/public/docs/_examples/toh-6/ts/src/app/hero.ts similarity index 100% rename from public/docs/_examples/toh-6/ts/app/hero.ts rename to public/docs/_examples/toh-6/ts/src/app/hero.ts diff --git a/public/docs/_examples/toh-6/ts/src/app/heroes.component.css b/public/docs/_examples/toh-6/ts/src/app/heroes.component.css new file mode 100644 index 0000000000..d2c958a911 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/heroes.component.css @@ -0,0 +1,68 @@ +/* #docregion */ +.selected { + background-color: #CFD8DC !important; + color: white; +} +.heroes { + margin: 0 0 2em 0; + list-style-type: none; + padding: 0; + width: 15em; +} +.heroes li { + cursor: pointer; + position: relative; + left: 0; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; +} +.heroes li:hover { + color: #607D8B; + background-color: #DDD; + left: .1em; +} +.heroes li.selected:hover { + background-color: #BBD8DC !important; + color: white; +} +.heroes .text { + position: relative; + top: -3px; +} +.heroes .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0 0 4px; +} +button { + font-family: Arial; + background-color: #eee; + border: none; + padding: 5px 10px; + border-radius: 4px; + cursor: pointer; + cursor: hand; +} +button:hover { + background-color: #cfd8dc; +} +/* #docregion additions */ +button.delete { + float:right; + margin-top: 2px; + margin-right: .8em; + background-color: gray !important; + color:white; +} diff --git a/public/docs/_examples/toh-6/ts/src/app/heroes.component.html b/public/docs/_examples/toh-6/ts/src/app/heroes.component.html new file mode 100644 index 0000000000..392d241d52 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/heroes.component.html @@ -0,0 +1,29 @@ + +

    My Heroes

    + +
    + + +
    + +
      + +
    • + {{hero.id}} + {{hero.name}} + + + +
    • + +
    +
    +

    + {{selectedHero.name | uppercase}} is my hero +

    + +
    diff --git a/public/docs/_examples/toh-6/ts/src/app/heroes.component.ts b/public/docs/_examples/toh-6/ts/src/app/heroes.component.ts new file mode 100644 index 0000000000..6350b803c4 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/heroes.component.ts @@ -0,0 +1,61 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +@Component({ + selector: 'my-heroes', + templateUrl: './heroes.component.html', + styleUrls: [ './heroes.component.css' ] +}) +export class HeroesComponent implements OnInit { + heroes: Hero[]; + selectedHero: Hero; + + constructor( + private heroService: HeroService, + private router: Router) { } + + getHeroes(): void { + this.heroService + .getHeroes() + .then(heroes => this.heroes = heroes); + } + + // #docregion add + add(name: string): void { + name = name.trim(); + if (!name) { return; } + this.heroService.create(name) + .then(hero => { + this.heroes.push(hero); + this.selectedHero = null; + }); + } + // #enddocregion add + + // #docregion delete + delete(hero: Hero): void { + this.heroService + .delete(hero.id) + .then(() => { + this.heroes = this.heroes.filter(h => h !== hero); + if (this.selectedHero === hero) { this.selectedHero = null; } + }); + } + // #enddocregion delete + + ngOnInit(): void { + this.getHeroes(); + } + + onSelect(hero: Hero): void { + this.selectedHero = hero; + } + + gotoDetail(): void { + this.router.navigate(['/detail', this.selectedHero.id]); + } +} diff --git a/public/docs/_examples/toh-6/ts/src/app/in-memory-data.service.ts b/public/docs/_examples/toh-6/ts/src/app/in-memory-data.service.ts new file mode 100644 index 0000000000..c915955e22 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/app/in-memory-data.service.ts @@ -0,0 +1,19 @@ +// #docregion , init +import { InMemoryDbService } from 'angular-in-memory-web-api'; +export class InMemoryDataService implements InMemoryDbService { + createDb() { + let heroes = [ + {id: 11, name: 'Mr. Nice'}, + {id: 12, name: 'Narco'}, + {id: 13, name: 'Bombasto'}, + {id: 14, name: 'Celeritas'}, + {id: 15, name: 'Magneta'}, + {id: 16, name: 'RubberMan'}, + {id: 17, name: 'Dynama'}, + {id: 18, name: 'Dr IQ'}, + {id: 19, name: 'Magma'}, + {id: 20, name: 'Tornado'} + ]; + return {heroes}; + } +} diff --git a/public/docs/_examples/toh-6/ts/src/index.html b/public/docs/_examples/toh-6/ts/src/index.html new file mode 100644 index 0000000000..18977969bb --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/index.html @@ -0,0 +1,26 @@ + + + + + + Angular Tour of Heroes + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/toh-6/ts/src/main-aot.ts b/public/docs/_examples/toh-6/ts/src/main-aot.ts new file mode 100644 index 0000000000..bd2ca604a3 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/main-aot.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowser } from '@angular/platform-browser'; + +import { AppModuleNgFactory } from '../aot/src/app/app.module.ngfactory'; + +platformBrowser().bootstrapModuleFactory(AppModuleNgFactory); diff --git a/public/docs/_examples/toh-6/ts/src/main.ts b/public/docs/_examples/toh-6/ts/src/main.ts new file mode 100644 index 0000000000..f332d1d245 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/toh-6/ts/src/tsconfig.1.json b/public/docs/_examples/toh-6/ts/src/tsconfig.1.json new file mode 100644 index 0000000000..fb3d43db90 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/src/tsconfig.1.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ "es2015", "dom" ], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true + } +} \ No newline at end of file diff --git a/public/docs/_examples/toh-6/ts/tsconfig-aot.json b/public/docs/_examples/toh-6/ts/tsconfig-aot.json new file mode 100644 index 0000000000..fe1e6df520 --- /dev/null +++ b/public/docs/_examples/toh-6/ts/tsconfig-aot.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "es2015", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es2015", "dom"], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "../../node_modules/@types/" + ] + }, + + "files": [ + "src/app/app.module.ts", + "src/main-aot.ts" + ], + + "angularCompilerOptions": { + "genDir": "aot", + "skipMetadataEmit" : true + } +} diff --git a/public/docs/_examples/tsconfig.json b/public/docs/_examples/tsconfig.json index fd1d10190d..51ea56dc7f 100644 --- a/public/docs/_examples/tsconfig.json +++ b/public/docs/_examples/tsconfig.json @@ -1,13 +1,24 @@ +// this tsconfig is used for protractor tests +// see _boilerplate/tsconfig.json for the tsconfig used in examples { "compilerOptions": { - "target": "es5", + "target": "es6", "module": "commonjs", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "removeComments": false, + "lib": ["es2015", "dom"], "noImplicitAny": true, - "suppressImplicitAnyIndexErrors": true - } + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "node_modules/@types" + ] + }, + "files": [ + "protractor-helpers.ts" + ], + "include": [ + "*/e2e-spec.ts" + ] } diff --git a/public/docs/_examples/typings.json b/public/docs/_examples/typings.json deleted file mode 100644 index 7e0e18568d..0000000000 --- a/public/docs/_examples/typings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "globalDependencies": { - "core-js": "registry:dt/core-js#0.0.0+20160317120654", - "jasmine": "registry:dt/jasmine#2.2.0+20160505161446", - "node": "registry:dt/node#4.0.0+20160509154515" - } -} diff --git a/public/docs/_examples/universal/ts/.gitignore b/public/docs/_examples/universal/ts/.gitignore new file mode 100644 index 0000000000..62993511f8 --- /dev/null +++ b/public/docs/_examples/universal/ts/.gitignore @@ -0,0 +1,8 @@ +aot/**/*.ts +**/*.ngfactory.ts +**/*.ngsummary.json +**/*.metadata.json +**/*.js +dist +!app/tsconfig.json +!/*.js diff --git a/public/docs/_examples/universal/ts/bs-config.aot.js b/public/docs/_examples/universal/ts/bs-config.aot.js new file mode 100644 index 0000000000..7bb795b9e2 --- /dev/null +++ b/public/docs/_examples/universal/ts/bs-config.aot.js @@ -0,0 +1,18 @@ +module.exports = { + port: 3100, + server: { + baseDir: "src", + routes: { + "/node_modules": "node_modules" + }, + middleware: { + // overrides the fallback middleware to use index-aot + 1: require('connect-history-api-fallback')({ index: '/index-aot.html' }) + } + } + // ,"snippetOptions": { + // "rule": { + // "match": "/dummy/" // disable browsersync by giving it an invalid injection target + // } + // } +}; diff --git a/public/docs/_examples/universal/ts/bs-config.uni.js b/public/docs/_examples/universal/ts/bs-config.uni.js new file mode 100644 index 0000000000..e15de19940 --- /dev/null +++ b/public/docs/_examples/universal/ts/bs-config.uni.js @@ -0,0 +1,41 @@ +module.exports = function(bs) { + + return { + "open": true, + "port": 3200, + "server": { + "baseDir": "aot", + "routes": { + "/node_modules": "node_modules" + }, + "middleware": [ + testMiddleware + ] + } + }; + +}; + +function testMiddleware (req, res, next) { + + var routes = []; //['/', '/dashboard', '/heroes']; + var prefixRoutes = ['/detail/', '/styles.css']; + var url = req.originalUrl; + + if (routes.indexOf(url) >= 0 || prefixRoutes.some(function(r) { return url.startsWith(r); })) { + console.log('test handling ' + url); + res.setHeader('Content-Type', 'text/css'); + res.end("this should be css"); + return; + } + + console.log('test skipping ' + url); + // var parsed = require("url").parse(req.url); + // if (parsed.pathname.match(/\.less$/)) { + // return less(parsed.pathname).then(function (o) { + // res.setHeader('Content-Type', 'text/css'); + // res.end(o.css); + // }); + // } + next(); +} diff --git a/public/docs/_examples/server-communication/dart/example-config.json b/public/docs/_examples/universal/ts/example-config.json similarity index 100% rename from public/docs/_examples/server-communication/dart/example-config.json rename to public/docs/_examples/universal/ts/example-config.json diff --git a/public/docs/_examples/universal/ts/package.steve.json b/public/docs/_examples/universal/ts/package.steve.json new file mode 100644 index 0000000000..15ef45e849 --- /dev/null +++ b/public/docs/_examples/universal/ts/package.steve.json @@ -0,0 +1,62 @@ +{ + "name": "toh-universal", + "version": "1.0.0", + "description": "Tour-of-Heroes application with ng-universal server-side rendering", + "scripts": { + "build": "tsc -p src/", + "build:watch": "tsc -w", + "build:aot": "webpack --config webpack.config.aot.js", + "build:uni": "webpack --config webpack.config.uni.js", + + "serve": "lite-server -c=bs-config.json", + "serve:aot": "lite-server -c=bs-config.aot.js", + "serve:uni": "node src/dist/server.js", + "serve:uni2": "lite-server -c bs-config.uni.js", + + "prestart": "npm run build", + "start": "concurrently \"npm run build:watch\" \"npm run serve\"", + + "lint": "tslint ./src/**/*.ts -t verbose", + "ngc": "ngc", + "clean": "rimraf src/dist && rimraf src/app/*.js* && rimraf src/uni/*.js* && rimraf src/main.js*" + }, + "keywords": [], + "author": "", + "license": "MIT", + "dependencies": { + "@angular/common": "angular/common-builds", + "@angular/compiler": "angular/compiler-builds", + "@angular/compiler-cli": "angular/compiler-cli-builds", + "@angular/core": "angular/core-builds", + "@angular/forms": "angular/forms-builds", + "@angular/http": "angular/http-builds", + "@angular/platform-browser": "angular/platform-browser-builds", + "@angular/platform-browser-dynamic": "angular/platform-browser-dynamic-builds", + "@angular/platform-server": "angular/platform-server-builds", + "@angular/router": "angular/router-builds", + + "angular-in-memory-web-api": "^0.3.1", + "systemjs": "0.19.40", + "core-js": "^2.4.1", + "rxjs": "5.1.1", + "zone.js": "^0.7.7" + }, + "devDependencies": { + "concurrently": "^3.2.0", + "lite-server": "^2.2.2", + "typescript": "~2.1.6", + + "canonical-path": "0.0.2", + "tslint": "^3.15.1", + "lodash": "^4.16.4", + "rimraf": "^2.5.4", + + "@types/node": "^6.0.46", + + "@ngtools/webpack": "^1.2.11", + "@types/express": "^4.0.35", + "raw-loader": "^0.5.1", + "webpack": "^2.2.1" + }, + "repository": {} +} diff --git a/public/docs/_examples/universal/ts/src/app/app-routing.module.ts b/public/docs/_examples/universal/ts/src/app/app-routing.module.ts new file mode 100644 index 0000000000..bc070f6c31 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/app-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { DashboardComponent } from './dashboard.component'; +import { HeroesComponent } from './heroes.component'; +import { HeroDetailComponent } from './hero-detail.component'; + +const routes: Routes = [ + { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, + { path: 'dashboard', component: DashboardComponent }, + { path: 'detail/:id', component: HeroDetailComponent }, + { path: 'heroes', component: HeroesComponent } +]; + +@NgModule({ + imports: [ RouterModule.forRoot(routes) ], + exports: [ RouterModule ] +}) +export class AppRoutingModule {} diff --git a/public/docs/_examples/universal/ts/src/app/app.component.css b/public/docs/_examples/universal/ts/src/app/app.component.css new file mode 100644 index 0000000000..071e665767 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/app.component.css @@ -0,0 +1,29 @@ +/* #docregion */ +h1 { + font-size: 1.2em; + color: #999; + margin-bottom: 0; +} +h2 { + font-size: 2em; + margin-top: 0; + padding-top: 0; +} +nav a { + padding: 5px 10px; + text-decoration: none; + margin-top: 10px; + display: inline-block; + background-color: #eee; + border-radius: 4px; +} +nav a:visited, a:link { + color: #607D8B; +} +nav a:hover { + color: #039be5; + background-color: #CFD8DC; +} +nav a.active { + color: #039be5; +} diff --git a/public/docs/_examples/universal/ts/src/app/app.component.ts b/public/docs/_examples/universal/ts/src/app/app.component.ts new file mode 100644 index 0000000000..a9fe05a9a8 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/app.component.ts @@ -0,0 +1,19 @@ +// #docplaster +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` +

    {{title}}

    + + + `, + styleUrls: ['./app.component.css'] +}) +export class AppComponent { + title = 'Tour of Heroes'; +} diff --git a/public/docs/_examples/universal/ts/src/app/app.module.ts b/public/docs/_examples/universal/ts/src/app/app.module.ts new file mode 100644 index 0000000000..e078044928 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/app.module.ts @@ -0,0 +1,54 @@ +// #docplaster +// #docregion +// #docregion v1, v2 +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +import { AppRoutingModule } from './app-routing.module'; + +// #enddocregion v1 +// Imports for loading & configuring the in-memory web api +import { InMemoryWebApiModule } from 'angular-in-memory-web-api'; +import { InMemoryDataService } from './in-memory-data.service'; + +// #docregion v1 +import { AppComponent } from './app.component'; +import { DashboardComponent } from './dashboard.component'; +import { HeroesComponent } from './heroes.component'; +import { HeroDetailComponent } from './hero-detail.component'; +import { HeroService } from './hero.service'; +// #enddocregion v1, v2 +import { HeroSearchComponent } from './hero-search.component'; +// #docregion v1, v2 + +@NgModule({ + imports: [ + BrowserModule.withServerTransition({ + appId: 'toh-universal' + }), + FormsModule, + HttpModule, + // #enddocregion v1 + // #docregion in-mem-web-api + InMemoryWebApiModule.forRoot(InMemoryDataService), + // #enddocregion in-mem-web-api + // #docregion v1 + AppRoutingModule + ], + // #docregion search + declarations: [ + AppComponent, + DashboardComponent, + HeroDetailComponent, + HeroesComponent, + // #enddocregion v1, v2 + HeroSearchComponent + // #docregion v1, v2 + ], + // #enddocregion search + providers: [ HeroService ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/universal/ts/src/app/dashboard.component.css b/public/docs/_examples/universal/ts/src/app/dashboard.component.css new file mode 100644 index 0000000000..dc7fb7ce06 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/dashboard.component.css @@ -0,0 +1,62 @@ +/* #docregion */ +[class*='col-'] { + float: left; + padding-right: 20px; + padding-bottom: 20px; +} +[class*='col-']:last-of-type { + padding-right: 0; +} +a { + text-decoration: none; +} +*, *:after, *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +h3 { + text-align: center; margin-bottom: 0; +} +h4 { + position: relative; +} +.grid { + margin: 0; +} +.col-1-4 { + width: 25%; +} +.module { + padding: 20px; + text-align: center; + color: #eee; + max-height: 120px; + min-width: 120px; + background-color: #607D8B; + border-radius: 2px; +} +.module:hover { + background-color: #EEE; + cursor: pointer; + color: #607d8b; +} +.grid-pad { + padding: 10px 0; +} +.grid-pad > [class*='col-']:last-of-type { + padding-right: 20px; +} +@media (max-width: 600px) { + .module { + font-size: 10px; + max-height: 75px; } +} +@media (max-width: 1024px) { + .grid { + margin: 0; + } + .module { + min-width: 60px; + } +} diff --git a/public/docs/_examples/universal/ts/src/app/dashboard.component.html b/public/docs/_examples/universal/ts/src/app/dashboard.component.html new file mode 100644 index 0000000000..db8546ccd2 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/dashboard.component.html @@ -0,0 +1,10 @@ + +

    Top Heroes

    + + diff --git a/public/docs/_examples/universal/ts/src/app/dashboard.component.ts b/public/docs/_examples/universal/ts/src/app/dashboard.component.ts new file mode 100644 index 0000000000..9960aa77d4 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/dashboard.component.ts @@ -0,0 +1,22 @@ +// #docregion , search +import { Component, OnInit } from '@angular/core'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +@Component({ + selector: 'my-dashboard', + templateUrl: './dashboard.component.html', + styleUrls: [ './dashboard.component.css' ] +}) +// #enddocregion search +export class DashboardComponent implements OnInit { + heroes: Hero[] = []; + + constructor(private heroService: HeroService) { } + + ngOnInit(): void { + this.heroService.getHeroes() + .then(heroes => this.heroes = heroes.slice(1, 5)); + } +} diff --git a/public/docs/_examples/toh-6/ts/app/hero-detail.component.css b/public/docs/_examples/universal/ts/src/app/hero-detail.component.css similarity index 100% rename from public/docs/_examples/toh-6/ts/app/hero-detail.component.css rename to public/docs/_examples/universal/ts/src/app/hero-detail.component.css diff --git a/public/docs/_examples/universal/ts/src/app/hero-detail.component.html b/public/docs/_examples/universal/ts/src/app/hero-detail.component.html new file mode 100644 index 0000000000..32fe6d4391 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/hero-detail.component.html @@ -0,0 +1,14 @@ + +
    +

    {{hero.name}} details!

    +
    + {{hero.id}}
    +
    + + +
    + + + + +
    diff --git a/public/docs/_examples/universal/ts/src/app/hero-detail.component.ts b/public/docs/_examples/universal/ts/src/app/hero-detail.component.ts new file mode 100644 index 0000000000..b3bbbd2f3d --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/hero-detail.component.ts @@ -0,0 +1,40 @@ +// #docregion +import 'rxjs/add/operator/switchMap'; +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Params } from '@angular/router'; +import { Location } from '@angular/common'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +@Component({ + selector: 'my-hero-detail', + templateUrl: './hero-detail.component.html', + styleUrls: [ './hero-detail.component.css' ] +}) +export class HeroDetailComponent implements OnInit { + hero: Hero; + + constructor( + private heroService: HeroService, + private route: ActivatedRoute, + private location: Location + ) {} + + ngOnInit(): void { + this.route.params + .switchMap((params: Params) => this.heroService.getHero(+params['id'])) + .subscribe(hero => this.hero = hero); + } + + // #docregion save + save(): void { + this.heroService.update(this.hero) + .then(() => this.goBack()); + } + // #enddocregion save + + goBack(): void { + this.location.back(); + } +} diff --git a/public/docs/_examples/universal/ts/src/app/hero-search.component.css b/public/docs/_examples/universal/ts/src/app/hero-search.component.css new file mode 100644 index 0000000000..9bf8d13457 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/hero-search.component.css @@ -0,0 +1,21 @@ +/* #docregion */ +.search-result{ + border-bottom: 1px solid gray; + border-left: 1px solid gray; + border-right: 1px solid gray; + width:195px; + height: 16px; + padding: 5px; + background-color: white; + cursor: pointer; +} + +.search-result:hover { + color: #eee; + background-color: #607D8B; +} + +#search-box{ + width: 200px; + height: 20px; +} diff --git a/public/docs/_examples/universal/ts/src/app/hero-search.component.html b/public/docs/_examples/universal/ts/src/app/hero-search.component.html new file mode 100644 index 0000000000..08c0560c5b --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/hero-search.component.html @@ -0,0 +1,11 @@ + +
    +

    Hero Search

    + +
    +
    + {{hero.name}} +
    +
    +
    diff --git a/public/docs/_examples/universal/ts/src/app/hero-search.component.ts b/public/docs/_examples/universal/ts/src/app/hero-search.component.ts new file mode 100644 index 0000000000..8b2d32f06b --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/hero-search.component.ts @@ -0,0 +1,69 @@ +// #docplaster +// #docregion +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +// #docregion rxjs-imports +import { Observable } from 'rxjs/Observable'; +import { Subject } from 'rxjs/Subject'; + +// Observable class extensions +import 'rxjs/add/observable/of'; + +// Observable operators +import 'rxjs/add/operator/catch'; +import 'rxjs/add/operator/debounceTime'; +import 'rxjs/add/operator/distinctUntilChanged'; +// #enddocregion rxjs-imports + +import { HeroSearchService } from './hero-search.service'; +import { Hero } from './hero'; + +@Component({ + selector: 'hero-search', + templateUrl: './hero-search.component.html', + styleUrls: [ './hero-search.component.css' ], + providers: [HeroSearchService] +}) +export class HeroSearchComponent implements OnInit { + // #docregion search + heroes: Observable; + // #enddocregion search + // #docregion searchTerms + private searchTerms = new Subject(); + // #enddocregion searchTerms + + constructor( + private heroSearchService: HeroSearchService, + private router: Router) {} + // #docregion searchTerms + + // Push a search term into the observable stream. + search(term: string): void { + this.searchTerms.next(term); + } + // #enddocregion searchTerms + // #docregion search + + ngOnInit(): void { + this.heroes = this.searchTerms + .debounceTime(300) // wait 300ms after each keystroke before considering the term + .distinctUntilChanged() // ignore if next search term is same as previous + .switchMap(term => term // switch to new observable each time the term changes + // return the http search observable + ? this.heroSearchService.search(term) + // or the observable of empty heroes if there was no search term + : Observable.of([])) + .catch(error => { + // TODO: add real error handling + console.log(error); + return Observable.of([]); + }); + } + // #enddocregion search + + gotoDetail(hero: Hero): void { + let link = ['/detail', hero.id]; + this.router.navigate(link); + } +} diff --git a/public/docs/_examples/universal/ts/src/app/hero-search.service.ts b/public/docs/_examples/universal/ts/src/app/hero-search.service.ts new file mode 100644 index 0000000000..d24e0fba41 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/hero-search.service.ts @@ -0,0 +1,20 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { Http } from '@angular/http'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/map'; + +import { Hero } from './hero'; + +@Injectable() +export class HeroSearchService { + + constructor(private http: Http) {} + + search(term: string): Observable { + return this.http + .get(`app/heroes/?name=${term}`) + .map(response => response.json().data as Hero[]); + } +} diff --git a/public/docs/_examples/universal/ts/src/app/hero.service.ts b/public/docs/_examples/universal/ts/src/app/hero.service.ts new file mode 100644 index 0000000000..18af476123 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/hero.service.ts @@ -0,0 +1,87 @@ +// #docplaster +// #docregion , imports +import { Injectable } from '@angular/core'; +import { Headers, Http } from '@angular/http'; + +// #docregion rxjs +import 'rxjs/add/operator/toPromise'; +// #enddocregion rxjs + +import { Hero } from './hero'; +// #enddocregion imports + +@Injectable() +export class HeroService { + + // #docregion update + private headers = new Headers({'Content-Type': 'application/json'}); + // #enddocregion update + // #docregion getHeroes + private heroesUrl = 'api/heroes'; // URL to web api + + constructor(private http: Http) { } + + getHeroes(): Promise { + return this.http.get(this.heroesUrl) + // #docregion to-promise + .toPromise() + // #enddocregion to-promise + // #docregion to-data + .then(response => response.json().data as Hero[]) + // #enddocregion to-data + // #docregion catch + .catch(this.handleError); + // #enddocregion catch + } + + // #enddocregion getHeroes + + // #docregion getHero + getHero(id: number): Promise { + const url = `${this.heroesUrl}/${id}`; + return this.http.get(url) + .toPromise() + .then(response => response.json().data as Hero) + .catch(this.handleError); + } + // #enddocregion getHero + + // #docregion delete + delete(id: number): Promise { + const url = `${this.heroesUrl}/${id}`; + return this.http.delete(url, {headers: this.headers}) + .toPromise() + .then(() => null) + .catch(this.handleError); + } + // #enddocregion delete + + // #docregion create + create(name: string): Promise { + return this.http + .post(this.heroesUrl, JSON.stringify({name: name}), {headers: this.headers}) + .toPromise() + .then(res => res.json().data) + .catch(this.handleError); + } + // #enddocregion create + // #docregion update + + update(hero: Hero): Promise { + const url = `${this.heroesUrl}/${hero.id}`; + return this.http + .put(url, JSON.stringify(hero), {headers: this.headers}) + .toPromise() + .then(() => hero) + .catch(this.handleError); + } + // #enddocregion update + + // #docregion getHeroes, handleError + private handleError(error: any): Promise { + console.error('An error occurred', error); // for demo purposes only + return Promise.reject(error.message || error); + } + // #enddocregion getHeroes, handleError +} + diff --git a/public/docs/_examples/universal/ts/src/app/hero.ts b/public/docs/_examples/universal/ts/src/app/hero.ts new file mode 100644 index 0000000000..e3eac516da --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/hero.ts @@ -0,0 +1,4 @@ +export class Hero { + id: number; + name: string; +} diff --git a/public/docs/_examples/universal/ts/src/app/heroes.component.css b/public/docs/_examples/universal/ts/src/app/heroes.component.css new file mode 100644 index 0000000000..d2c958a911 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/heroes.component.css @@ -0,0 +1,68 @@ +/* #docregion */ +.selected { + background-color: #CFD8DC !important; + color: white; +} +.heroes { + margin: 0 0 2em 0; + list-style-type: none; + padding: 0; + width: 15em; +} +.heroes li { + cursor: pointer; + position: relative; + left: 0; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; +} +.heroes li:hover { + color: #607D8B; + background-color: #DDD; + left: .1em; +} +.heroes li.selected:hover { + background-color: #BBD8DC !important; + color: white; +} +.heroes .text { + position: relative; + top: -3px; +} +.heroes .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0 0 4px; +} +button { + font-family: Arial; + background-color: #eee; + border: none; + padding: 5px 10px; + border-radius: 4px; + cursor: pointer; + cursor: hand; +} +button:hover { + background-color: #cfd8dc; +} +/* #docregion additions */ +button.delete { + float:right; + margin-top: 2px; + margin-right: .8em; + background-color: gray !important; + color:white; +} diff --git a/public/docs/_examples/universal/ts/src/app/heroes.component.html b/public/docs/_examples/universal/ts/src/app/heroes.component.html new file mode 100644 index 0000000000..392d241d52 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/heroes.component.html @@ -0,0 +1,29 @@ + +

    My Heroes

    + +
    + + +
    + +
      + +
    • + {{hero.id}} + {{hero.name}} + + + +
    • + +
    +
    +

    + {{selectedHero.name | uppercase}} is my hero +

    + +
    diff --git a/public/docs/_examples/universal/ts/src/app/heroes.component.ts b/public/docs/_examples/universal/ts/src/app/heroes.component.ts new file mode 100644 index 0000000000..6350b803c4 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/heroes.component.ts @@ -0,0 +1,61 @@ +// #docregion +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +@Component({ + selector: 'my-heroes', + templateUrl: './heroes.component.html', + styleUrls: [ './heroes.component.css' ] +}) +export class HeroesComponent implements OnInit { + heroes: Hero[]; + selectedHero: Hero; + + constructor( + private heroService: HeroService, + private router: Router) { } + + getHeroes(): void { + this.heroService + .getHeroes() + .then(heroes => this.heroes = heroes); + } + + // #docregion add + add(name: string): void { + name = name.trim(); + if (!name) { return; } + this.heroService.create(name) + .then(hero => { + this.heroes.push(hero); + this.selectedHero = null; + }); + } + // #enddocregion add + + // #docregion delete + delete(hero: Hero): void { + this.heroService + .delete(hero.id) + .then(() => { + this.heroes = this.heroes.filter(h => h !== hero); + if (this.selectedHero === hero) { this.selectedHero = null; } + }); + } + // #enddocregion delete + + ngOnInit(): void { + this.getHeroes(); + } + + onSelect(hero: Hero): void { + this.selectedHero = hero; + } + + gotoDetail(): void { + this.router.navigate(['/detail', this.selectedHero.id]); + } +} diff --git a/public/docs/_examples/universal/ts/src/app/in-memory-data.service.ts b/public/docs/_examples/universal/ts/src/app/in-memory-data.service.ts new file mode 100644 index 0000000000..c915955e22 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/app/in-memory-data.service.ts @@ -0,0 +1,19 @@ +// #docregion , init +import { InMemoryDbService } from 'angular-in-memory-web-api'; +export class InMemoryDataService implements InMemoryDbService { + createDb() { + let heroes = [ + {id: 11, name: 'Mr. Nice'}, + {id: 12, name: 'Narco'}, + {id: 13, name: 'Bombasto'}, + {id: 14, name: 'Celeritas'}, + {id: 15, name: 'Magneta'}, + {id: 16, name: 'RubberMan'}, + {id: 17, name: 'Dynama'}, + {id: 18, name: 'Dr IQ'}, + {id: 19, name: 'Magma'}, + {id: 20, name: 'Tornado'} + ]; + return {heroes}; + } +} diff --git a/public/docs/_examples/universal/ts/src/index-aot.html b/public/docs/_examples/universal/ts/src/index-aot.html new file mode 100644 index 0000000000..096bfbb512 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/index-aot.html @@ -0,0 +1,18 @@ + + + + + Angular Tour of Heroes + + + + + + + + Loading... + + + + + diff --git a/public/docs/_examples/universal/ts/src/index.html b/public/docs/_examples/universal/ts/src/index.html new file mode 100644 index 0000000000..727b1fc833 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/index.html @@ -0,0 +1,26 @@ + + + + + + Angular Universal Tour of Heroes + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/universal/ts/src/main-aot.ts b/public/docs/_examples/universal/ts/src/main-aot.ts new file mode 100644 index 0000000000..fcb35dc9dc --- /dev/null +++ b/public/docs/_examples/universal/ts/src/main-aot.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowser } from '@angular/platform-browser'; +import { AppModuleNgFactory } from '../aot/src/app/app.module.ngfactory'; + +platformBrowser().bootstrapModuleFactory(AppModuleNgFactory); diff --git a/public/docs/_examples/universal/ts/src/main.ts b/public/docs/_examples/universal/ts/src/main.ts new file mode 100644 index 0000000000..f332d1d245 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/main.ts @@ -0,0 +1,6 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/universal/ts/src/uni/app.server.ts b/public/docs/_examples/universal/ts/src/uni/app.server.ts new file mode 100644 index 0000000000..585470cd09 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/uni/app.server.ts @@ -0,0 +1,21 @@ +import { NgModule } from '@angular/core'; +import { APP_BASE_HREF } from '@angular/common'; +import { ServerModule } from '@angular/platform-server'; +import { AppComponent } from '../app/app.component'; +import { AppModule } from '../app/app.module'; + +@NgModule({ + imports: [ + ServerModule, + AppModule + ], + bootstrap: [ + AppComponent + ], + providers: [ + {provide: APP_BASE_HREF, useValue: '/'} + // { provide: NgModuleFactoryLoader, useClass: ServerRouterLoader } + ] +}) +export class AppServerModule { +} diff --git a/public/docs/_examples/universal/ts/src/uni/server-aot.ts b/public/docs/_examples/universal/ts/src/uni/server-aot.ts new file mode 100644 index 0000000000..38eb3f6b33 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/uni/server-aot.ts @@ -0,0 +1,40 @@ +import 'zone.js/dist/zone-node'; +import { enableProdMode } from '@angular/core'; +// import { AppServerModule } from './app.server'; +import { AppServerModuleNgFactory } from '../../aot/src/uni/app.server.ngfactory'; +import * as express from 'express'; +import { ngUniversalEngine } from './universal-engine'; + +enableProdMode(); + +const server = express(); + +// set our angular engine as the handler for html files, so it will be used to render them. +server.engine('html', ngUniversalEngine({ + bootstrap: [AppServerModuleNgFactory] +})); + +// set default view directory +server.set('views', 'src'); + +// handle requests for routes in the app. ngExpressEngine does the rendering. +server.get(['/', '/dashboard', '/heroes', '/detail/:id'], (req, res) => { + res.render('index-aot.html', {req}); +}); + +// handle requests for static files +server.get(['/*.js', '/*.css'], (req, res, next) => { + let fileName: string = req.originalUrl; + console.log(fileName); + let root = fileName.startsWith('/node_modules/') ? '.' : 'src'; + res.sendFile(fileName, { root: root }, function (err) { + if (err) { + next(err); + } + }); +}); + +// start the server +server.listen(3200, () => { + console.log('listening on port 3200...'); +}); diff --git a/public/docs/_examples/universal/ts/src/uni/universal-engine.ts b/public/docs/_examples/universal/ts/src/uni/universal-engine.ts new file mode 100644 index 0000000000..3c0ac6b528 --- /dev/null +++ b/public/docs/_examples/universal/ts/src/uni/universal-engine.ts @@ -0,0 +1,38 @@ +/** + * Express/Connect middleware for rendering pages using Angular Universal + */ +import * as fs from 'fs'; +import { renderModuleFactory } from '@angular/platform-server'; + +const templateCache = {}; // cache for page templates +const outputCache = {}; // cache for rendered pages + +export function ngUniversalEngine(setupOptions: any) { + + return function (filePath: string, options: { req: Request }, callback: (err: Error, html: string) => void) { + let url: string = options.req.url; + let html: string = outputCache[url]; + if (html) { + // return already-built page for this url + console.log('from cache: ' + url); + callback(null, html); + return; + } + + console.log('building: ' + url); + if (!templateCache[filePath]) { + let file = fs.readFileSync(filePath); + templateCache[filePath] = file.toString(); + } + + // render the page via angular platform-server + let appModuleFactory = setupOptions.bootstrap[0]; + renderModuleFactory(appModuleFactory, { + document: templateCache[filePath], + url: url + }).then(str => { + outputCache[url] = str; + callback(null, str); + }); + }; +} diff --git a/public/docs/_examples/universal/ts/tsconfig-aot.json b/public/docs/_examples/universal/ts/tsconfig-aot.json new file mode 100644 index 0000000000..023bf2fb68 --- /dev/null +++ b/public/docs/_examples/universal/ts/tsconfig-aot.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "es2015", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es2015", "dom"], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "node_modules/@types/" + ] + }, + + "files": [ + "src/app/app.module.ts", + "src/main-aot.ts" + ], + + "angularCompilerOptions": { + "genDir": "aot", + "entryModule": "./src/app/app.module#AppModule", + "skipMetadataEmit" : true + } +} diff --git a/public/docs/_examples/universal/ts/tsconfig-uni.json b/public/docs/_examples/universal/ts/tsconfig-uni.json new file mode 100644 index 0000000000..fcb6a7c92d --- /dev/null +++ b/public/docs/_examples/universal/ts/tsconfig-uni.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "es2015", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es2015", "dom"], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "../../node_modules/@types/" + ] + }, + + "files": [ + "src/uni/app.server.ts", + "src/uni/server-aot.ts" + ], + + "angularCompilerOptions": { + "genDir": "aot", + "entryModule": "./src/app/app.module#AppModule", + "skipMetadataEmit" : true + } +} diff --git a/public/docs/_examples/universal/ts/tsconfig.json b/public/docs/_examples/universal/ts/tsconfig.json new file mode 100644 index 0000000000..58307adfe0 --- /dev/null +++ b/public/docs/_examples/universal/ts/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ "es2015", "dom" ], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "../../../node_modules/@types/" + ] + }, + "compileOnSave": true, + "exclude": [ + "node_modules/*" + ] +} diff --git a/public/docs/_examples/universal/ts/webpack.config.aot.js b/public/docs/_examples/universal/ts/webpack.config.aot.js new file mode 100644 index 0000000000..f16ce50294 --- /dev/null +++ b/public/docs/_examples/universal/ts/webpack.config.aot.js @@ -0,0 +1,30 @@ +const ngtools = require('@ngtools/webpack'); +const webpack = require('webpack'); + +module.exports = { + devtool: 'source-map', + entry: { + main: './src/main-aot.ts' + }, + resolve: { + extensions: ['.ts', '.js'] + }, + target: 'node', + output: { + path: 'src/dist', + filename: 'build.js' + }, + plugins: [ + new ngtools.AotPlugin({ + tsConfigPath: './tsconfig-aot.json' + }), + new webpack.optimize.UglifyJsPlugin({ sourceMap: true }) + ], + module: { + rules: [ + { test: /\.css$/, loader: 'raw-loader' }, + { test: /\.html$/, loader: 'raw-loader' }, + { test: /\.ts$/, loader: '@ngtools/webpack' } + ] + } +} diff --git a/public/docs/_examples/universal/ts/webpack.config.uni.js b/public/docs/_examples/universal/ts/webpack.config.uni.js new file mode 100644 index 0000000000..1ccccb6f1a --- /dev/null +++ b/public/docs/_examples/universal/ts/webpack.config.uni.js @@ -0,0 +1,30 @@ +const ngtools = require('@ngtools/webpack'); +const webpack = require('webpack'); + +module.exports = { + devtool: 'source-map', + entry: { + main: ['./src/uni/app.server.ts', './src/uni/server-aot.ts'] + }, + resolve: { + extensions: ['.ts', '.js'] + }, + target: 'node', + output: { + path: 'src/dist', + filename: 'server.js' + }, + plugins: [ + new ngtools.AotPlugin({ + tsConfigPath: './tsconfig-uni.json' + }), + new webpack.optimize.UglifyJsPlugin({ sourceMap: true }) + ], + module: { + rules: [ + { test: /\.css$/, loader: 'raw-loader' }, + { test: /\.html$/, loader: 'raw-loader' }, + { test: /\.ts$/, loader: '@ngtools/webpack' } + ] + } +} diff --git a/public/docs/_examples/upgrade-adapter/e2e-spec.ts b/public/docs/_examples/upgrade-adapter/e2e-spec.ts deleted file mode 100644 index eb4706137c..0000000000 --- a/public/docs/_examples/upgrade-adapter/e2e-spec.ts +++ /dev/null @@ -1,198 +0,0 @@ -/// -describe('Upgrade Tests', function () { - - // Protractor doesn't support the UpgradeAdapter's asynchronous - // bootstrap with Angular 1 at the moment. Get around it by - // waiting for an element to get `ng-scope` class. - function waitForNg1AsyncBootstrap() { - browser.ignoreSynchronization = true; - browser.driver.wait(function() { - return element(by.css('.ng-scope')).isPresent(); - }, 5000); - } - - describe('NG1 Auto-bootstrap', function() { - - beforeAll(function () { - browser.get('/index-ng-app.html'); - setProtractorToNg1Mode(); - }); - - it('bootstraps as expected', function () { - expect(element(by.css('#message')).getText()).toEqual('Hello world'); - }); - - }); - - describe('NG1 JavaScript Bootstrap', function() { - - beforeAll(function () { - browser.get('/index-bootstrap.html'); - setProtractorToNg1Mode(); - }); - - it('bootstraps as expected', function () { - expect(element(by.css('#message')).getText()).toEqual('Hello world'); - }); - - }); - - describe('NG1-2 Hybrid Bootstrap', function() { - - beforeAll(function () { - browser.get('/index-1-2-hybrid-bootstrap.html'); - setProtractorToNg1Mode(); - }); - - it('bootstraps as expected', function () { - expect(element(by.css('#message')).getText()).toEqual('Hello world'); - }); - - }); - - describe('NG1-2 Hybrid Bootstrap with Shared UpgradeAdapter', function() { - - beforeAll(function () { - browser.get('/index-1-2-hybrid-shared-adapter-bootstrap.html'); - setProtractorToNg1Mode(); - }); - - it('bootstraps as expected', function () { - expect(element(by.css('#message')).getText()).toEqual('Hello world'); - }); - - }); - - describe('Upgraded static component', function() { - - beforeAll(function () { - browser.get('/index-upgrade-static.html'); - setProtractorToNg1Mode(); - waitForNg1AsyncBootstrap(); - }); - - it('renders', function () { - expect(element(by.css('h2')).getText()).toEqual('Windstorm details!'); - }); - - }); - - - describe('Upgraded component with IO', function() { - - beforeAll(function () { - browser.get('/index-upgrade-io.html'); - setProtractorToNg1Mode(); - waitForNg1AsyncBootstrap(); - }); - - it('has inputs', function () { - expect(element(by.css('h2')).getText()).toEqual('Windstorm details!'); - }); - - it('has outputs', function () { - element(by.buttonText('Delete')).click(); - expect(element(by.css('h2')).getText()).toEqual('Ex-Windstorm details!'); - }); - - }); - - - describe('Downgraded static component', function() { - - beforeAll(function () { - browser.get('/index-downgrade-static.html'); - setProtractorToNg1Mode(); - waitForNg1AsyncBootstrap(); - }); - - it('renders', function () { - expect(element(by.css('h2')).getText()).toEqual('Windstorm details!'); - }); - - }); - - describe('Downgraded component with IO', function() { - - beforeAll(function () { - browser.get('/index-downgrade-io.html'); - setProtractorToNg1Mode(); - waitForNg1AsyncBootstrap(); - }); - - it('has inputs', function () { - expect(element.all(by.css('h2')).first().getText()).toEqual('Windstorm details!'); - }); - - it('has outputs', function () { - element.all(by.buttonText('Delete')).first().click(); - expect(element.all(by.css('h2')).first().getText()).toEqual('Ex-Windstorm details!'); - }); - - it('supports ng-repeat', function () { - expect(element.all(by.css('hero-detail')).count()).toBe(3); - }); - - }); - - - describe('Downgraded component with content projection', function() { - - beforeAll(function () { - browser.get('/index-1-to-2-projection.html'); - setProtractorToNg1Mode(); - waitForNg1AsyncBootstrap(); - }); - - it('can be transcluded into', function () { - expect(element(by.css('hero-detail')).getText()).toContain('Specific powers of controlling winds'); - }); - - }); - - - describe('Upgraded component with transclusion', function() { - - beforeAll(function () { - browser.get('/index-2-to-1-transclusion.html'); - setProtractorToNg1Mode(); - waitForNg1AsyncBootstrap(); - }); - - it('can be projected into', function () { - expect(element(by.css('hero-detail')).getText()).toContain('Specific powers of controlling winds'); - }); - - }); - - - describe('Upgrading NG1 Providers', function() { - - beforeAll(function () { - browser.get('/index-1-to-2-providers.html'); - setProtractorToNg1Mode(); - waitForNg1AsyncBootstrap(); - }); - - it('works', function () { - expect(element(by.css('h2')).getText()).toBe('1: Windstorm'); - }); - - }); - - - describe('Downgrading NG2 Providers', function() { - - beforeAll(function () { - browser.get('/index-2-to-1-providers.html'); - setProtractorToNg1Mode(); - waitForNg1AsyncBootstrap(); - }); - - it('works', function () { - expect(element(by.css('h2')).getText()).toBe('1: Windstorm'); - }); - - }); - -}); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-bootstrap/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-bootstrap/app.module.ts deleted file mode 100644 index 2e2b7b5b54..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-bootstrap/app.module.ts +++ /dev/null @@ -1,18 +0,0 @@ -declare var angular:any; - -// #docregion bootstrap -import { UpgradeAdapter } from '@angular/upgrade'; - -// #enddocregion bootstrap - -angular.module('heroApp', []) - .controller('MainCtrl', function() { - this.message = 'Hello world'; - }); - -// #docregion bootstrap - -const upgradeAdapter = new UpgradeAdapter(); - -upgradeAdapter.bootstrap(document.body, ['heroApp'], {strictDi: true}); -// #enddocregion bootstrap diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/app.module.ts deleted file mode 100644 index f7e1ba4b13..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/app.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -// #docregion bootstrap -import { upgradeAdapter } from './upgrade_adapter'; - -// #enddocregion bootstrap - -declare var angular:any; - -angular.module('heroApp', []) - .controller('MainCtrl', function() { - this.message = 'Hello world'; - }); - -// #docregion bootstrap - -upgradeAdapter.bootstrap(document.body, ['heroApp'], {strictDi: true}); -// #enddocregion bootstrap diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/upgrade_adapter.ts deleted file mode 100644 index f6066f9109..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-2-hybrid-shared-adapter-bootstrap/upgrade_adapter.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-bootstrap/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-bootstrap/app.module.ts deleted file mode 100644 index c4b56a5ca6..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-bootstrap/app.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -declare var angular:any; - -angular.module('heroApp', []) - .controller('MainCtrl', function() { - this.message = 'Hello world'; - }); - -document.addEventListener('DOMContentLoaded', function() { - // #docregion bootstrap - angular.bootstrap(document.body, ['heroApp'], {strictDi: true}); - // #enddocregion bootstrap -}); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-ng-app/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-ng-app/app.module.ts deleted file mode 100644 index 427c605de3..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-ng-app/app.module.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare var angular:any; - -angular.module('heroApp', []) - .controller('MainCtrl', function() { - this.message = 'Hello world'; - }); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-projection/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-projection/app.module.ts deleted file mode 100644 index 2534ebd99a..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-projection/app.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { UpgradeAdapter } from '@angular/upgrade'; - -import { MainController } from './main.controller'; -import { HeroDetailComponent } from './hero-detail.component'; - -declare var angular:any; -const upgradeAdapter = new UpgradeAdapter(); - -angular.module('heroApp', []) - .controller('MainController', MainController) - .directive('heroDetail', upgradeAdapter.downgradeNg2Component(HeroDetailComponent)); - -upgradeAdapter.bootstrap( - document.querySelector('hero-app'), - ['heroApp'], - {strictDi: true} -); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/app.module.ts deleted file mode 100644 index a38d87d6f5..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/app.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { HeroDetailComponent } from './hero-detail.component'; -import { HeroesService } from './heroes.service'; -import { upgradeAdapter } from './upgrade_adapter'; - -declare var angular:any; - -// #docregion register -angular.module('heroApp', []) - .service('heroes', HeroesService) - .directive('heroDetail', - upgradeAdapter.downgradeNg2Component(HeroDetailComponent)); - -upgradeAdapter.upgradeNg1Provider('heroes'); - -// #enddocregion register - -upgradeAdapter.bootstrap( - document.querySelector('hero-app'), - ['heroApp'], - {strictDi: true} -); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/hero-detail.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/hero-detail.component.ts deleted file mode 100644 index fa1c26a9fa..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/hero-detail.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -// #docregion -import { Component, Inject } from '@angular/core'; -import { HeroesService } from './heroes.service'; -import { Hero } from '../hero'; - -@Component({ - selector: 'hero-detail', - template: ` -

    {{hero.id}}: {{hero.name}}

    - ` -}) -export class HeroDetailComponent { - hero:Hero; - constructor(@Inject('heroes') heroes:HeroesService) { - this.hero = heroes.get()[0]; - } -} diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/upgrade_adapter.ts deleted file mode 100644 index f6066f9109..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/upgrade_adapter.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/app.module.ts deleted file mode 100644 index 657c4d25cc..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/app.module.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { heroDetailComponent } from './hero-detail.component'; -import { Heroes } from './heroes'; -import { upgradeAdapter } from './upgrade_adapter'; - -declare var angular:any; - -// #docregion register -upgradeAdapter.addProvider(Heroes); - -angular.module('heroApp', []) - .factory('heroes', upgradeAdapter.downgradeNg2Provider(Heroes)) - .component('heroDetail', heroDetailComponent) -// #enddocregion register - -upgradeAdapter.bootstrap( - document.querySelector('hero-app'), - ['heroApp'], - {strictDi: true} -); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/hero-detail.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/hero-detail.component.ts deleted file mode 100644 index d736117ce0..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/hero-detail.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Heroes } from './heroes'; - -// #docregion -export const heroDetailComponent = { - template: ` -

    {{$ctrl.hero.id}}: {{$ctrl.hero.name}}

    - `, - controller: ['heroes', function(heroes:Heroes) { - this.hero = heroes.get()[0]; - }] -}; diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/upgrade_adapter.ts deleted file mode 100644 index f6066f9109..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/upgrade_adapter.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/app.module.ts deleted file mode 100644 index ab16d3a24d..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/app.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { UpgradeAdapter } from '@angular/upgrade'; -import { ContainerComponent } from './container.component'; -import { heroDetailComponent } from './hero-detail.component'; -import { upgradeAdapter } from './upgrade_adapter'; - -declare var angular:any; - -angular.module('heroApp', []) - .directive('myContainer', upgradeAdapter.downgradeNg2Component(ContainerComponent)) - .component('heroDetail', heroDetailComponent) - -upgradeAdapter.bootstrap( - document.querySelector('hero-app'), - ['heroApp'], - {strictDi: true} -); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/container.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/container.component.ts deleted file mode 100644 index a468898e5f..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/container.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { upgradeAdapter } from './upgrade_adapter'; -import { Hero } from '../hero'; - -const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail'); - -@Component({ - selector: 'my-container', - template: ` - - -

    {{hero.description}}

    -
    - `, - directives: [HeroDetail] -}) -export class ContainerComponent { - hero = new Hero(1, 'Windstorm', 'Specific powers of controlling winds'); -} diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/hero-detail.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/hero-detail.component.ts deleted file mode 100644 index a8f842781d..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/hero-detail.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -export const heroDetailComponent = { - bindings: { - hero: '=' - }, - template: ` -

    {{$ctrl.hero.name}}

    -
    - -
    - ` -}; diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/upgrade_adapter.ts deleted file mode 100644 index f6066f9109..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-transclusion/upgrade_adapter.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/app.module.ts deleted file mode 100644 index d9af4e0104..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/app.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { MainController } from './main.controller'; -// #docregion downgradecomponent -import { HeroDetailComponent } from './hero-detail.component'; - -// #enddocregion downgradecomponent -import { UpgradeAdapter } from '@angular/upgrade'; - -const upgradeAdapter = new UpgradeAdapter(); - -// #docregion downgradecomponent - -angular.module('heroApp', []) - .controller('MainController', MainController) - .directive('heroDetail', upgradeAdapter.downgradeNg2Component(HeroDetailComponent)); - -// #enddocregion downgradecomponent - -upgradeAdapter.bootstrap( - document.querySelector('hero-app'), - ['heroApp'], - {strictDi: true} -); -// #enddocregion bootstrap diff --git a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/hero-detail.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/hero-detail.component.ts deleted file mode 100644 index 12879ac980..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/hero-detail.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -// #docregion -import { Component, EventEmitter, Input, Output } from '@angular/core'; -import {Hero} from '../hero'; - -@Component({ - selector: 'hero-detail', - template: ` -

    {{hero.name}} details!

    -
    {{hero.id}}
    - - ` -}) -export class HeroDetailComponent { - @Input() hero:Hero - @Output() deleted = new EventEmitter(); - onDelete() { - this.deleted.emit(this.hero); - } -} diff --git a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-static/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/downgrade-static/app.module.ts deleted file mode 100644 index 44935340f0..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-static/app.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -// #docregion downgradecomponent -import { HeroDetailComponent } from './hero-detail.component'; - -// #enddocregion downgradecomponent -import { UpgradeAdapter } from '@angular/upgrade'; - -const upgradeAdapter = new UpgradeAdapter(); - -// #docregion downgradecomponent - -angular.module('heroApp', []) - .directive('heroDetail', upgradeAdapter.downgradeNg2Component(HeroDetailComponent)); - -// #enddocregion downgradecomponent - -upgradeAdapter.bootstrap( - document.querySelector('hero-app'), - ['heroApp'], - {strictDi: true} -); -// #enddocregion bootstrap diff --git a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-static/hero-detail.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/downgrade-static/hero-detail.component.ts deleted file mode 100644 index cbcadfbd5a..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-static/hero-detail.component.ts +++ /dev/null @@ -1,13 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -@Component({ - selector: 'hero-detail', - template: ` -

    Windstorm details!

    -
    1
    - ` -}) -export class HeroDetailComponent { - -} diff --git a/public/docs/_examples/upgrade-adapter/ts/app/hero.ts b/public/docs/_examples/upgrade-adapter/ts/app/hero.ts deleted file mode 100644 index 172d393139..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/hero.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class Hero { - constructor(public id:number, - public name:string, - public description?:string) { } -} diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/app.module.ts deleted file mode 100644 index dd2df20bdf..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/app.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { heroDetail } from './hero-detail.component'; -import { ContainerComponent } from './container.component'; -import { upgradeAdapter } from './upgrade_adapter'; - - -declare var angular:any; - -angular.module('heroApp', []) - .component('heroDetail', heroDetail) - .directive('myContainer', upgradeAdapter.downgradeNg2Component(ContainerComponent)); - -upgradeAdapter.bootstrap( - document.querySelector('hero-app'), - ['heroApp'], - {strictDi: true} -); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/container.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/container.component.ts deleted file mode 100644 index 692e3f206f..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/container.component.ts +++ /dev/null @@ -1,23 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { upgradeAdapter } from './upgrade_adapter'; -import { Hero } from '../hero'; - -const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail'); - -@Component({ - selector: 'my-container', - template: ` -

    Tour of Heroes

    - - - `, - directives: [HeroDetail] -}) -export class ContainerComponent { - hero = new Hero(1, 'Windstorm'); - heroDeleted(hero:Hero) { - hero.name = 'Ex-' + hero.name; - } -} diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/hero-detail.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/hero-detail.component.ts deleted file mode 100644 index 3295fe9382..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/hero-detail.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -// #docregion -export const heroDetail = { - bindings: { - hero: '=', - deleted: '&' - }, - template: ` -

    {{$ctrl.hero.name}} details!

    -
    {{$ctrl.hero.id}}
    - - `, - controller: function() { - this.onDelete = () => { - this.deleted(this.hero); - }; - } -}; diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/upgrade_adapter.ts deleted file mode 100644 index f6066f9109..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-io/upgrade_adapter.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/app.module.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/app.module.ts deleted file mode 100644 index dd2df20bdf..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/app.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { heroDetail } from './hero-detail.component'; -import { ContainerComponent } from './container.component'; -import { upgradeAdapter } from './upgrade_adapter'; - - -declare var angular:any; - -angular.module('heroApp', []) - .component('heroDetail', heroDetail) - .directive('myContainer', upgradeAdapter.downgradeNg2Component(ContainerComponent)); - -upgradeAdapter.bootstrap( - document.querySelector('hero-app'), - ['heroApp'], - {strictDi: true} -); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/container.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/container.component.ts deleted file mode 100644 index ca8a93dd26..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/container.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { upgradeAdapter } from './upgrade_adapter'; - -const HeroDetail = upgradeAdapter.upgradeNg1Component('heroDetail'); - -@Component({ - selector: 'my-container', - template: ` -

    Tour of Heroes

    - - `, - directives: [HeroDetail] -}) -export class ContainerComponent { - -} diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/hero-detail.component.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/hero-detail.component.ts deleted file mode 100644 index 862c904bbc..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/hero-detail.component.ts +++ /dev/null @@ -1,9 +0,0 @@ -// #docregion -export const heroDetail = { - template: ` -

    Windstorm details!

    -
    1
    - `, - controller: function() { - } -}; diff --git a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/upgrade_adapter.ts b/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/upgrade_adapter.ts deleted file mode 100644 index f6066f9109..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/app/upgrade-static/upgrade_adapter.ts +++ /dev/null @@ -1,3 +0,0 @@ -// #docregion -import { UpgradeAdapter } from '@angular/upgrade'; -export const upgradeAdapter = new UpgradeAdapter(); diff --git a/public/docs/_examples/upgrade-adapter/ts/example-config.json b/public/docs/_examples/upgrade-adapter/ts/example-config.json deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/public/docs/_examples/upgrade-adapter/ts/index-1-2-hybrid-bootstrap.html b/public/docs/_examples/upgrade-adapter/ts/index-1-2-hybrid-bootstrap.html deleted file mode 100644 index ff5481a40d..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/index-1-2-hybrid-bootstrap.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - Angular 2 Upgrade - - - - - - - - - - - - - - - - - - - -
    {{ mainCtrl.message }}
    - - diff --git a/public/docs/_examples/upgrade-adapter/ts/index-1-2-hybrid-shared-adapter-bootstrap.html b/public/docs/_examples/upgrade-adapter/ts/index-1-2-hybrid-shared-adapter-bootstrap.html deleted file mode 100644 index 14dfb6ebb4..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/index-1-2-hybrid-shared-adapter-bootstrap.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - Angular 2 Upgrade - - - - - - - - - - - - - - - - - - - -
    {{ mainCtrl.message }}
    - - diff --git a/public/docs/_examples/upgrade-adapter/ts/index-1-to-2-projection.html b/public/docs/_examples/upgrade-adapter/ts/index-1-to-2-projection.html deleted file mode 100644 index 03299b89e3..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/index-1-to-2-projection.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - Angular 2 Upgrade - - - - - - - - - - - - - - - - - - - - - -
    - - -

    {{mainCtrl.hero.description}}

    -
    -
    - -
    - - diff --git a/public/docs/_examples/upgrade-adapter/ts/index-1-to-2-providers.html b/public/docs/_examples/upgrade-adapter/ts/index-1-to-2-providers.html deleted file mode 100644 index 266b8af6a0..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/index-1-to-2-providers.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - Angular 2 Upgrade - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/upgrade-adapter/ts/index-2-to-1-providers.html b/public/docs/_examples/upgrade-adapter/ts/index-2-to-1-providers.html deleted file mode 100644 index 9ddd676460..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/index-2-to-1-providers.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - Angular 2 Upgrade - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/upgrade-adapter/ts/index-2-to-1-transclusion.html b/public/docs/_examples/upgrade-adapter/ts/index-2-to-1-transclusion.html deleted file mode 100644 index 5f1a4de61c..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/index-2-to-1-transclusion.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - Angular 2 Upgrade - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/upgrade-adapter/ts/index-downgrade-static.html b/public/docs/_examples/upgrade-adapter/ts/index-downgrade-static.html deleted file mode 100644 index 5193b95c5f..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/index-downgrade-static.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - Angular 2 Upgrade - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/upgrade-adapter/ts/index-upgrade-io.html b/public/docs/_examples/upgrade-adapter/ts/index-upgrade-io.html deleted file mode 100644 index 345cdbeaa6..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/index-upgrade-io.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - Angular 2 Upgrade - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/upgrade-adapter/ts/index-upgrade-static.html b/public/docs/_examples/upgrade-adapter/ts/index-upgrade-static.html deleted file mode 100644 index 3d60cbbff2..0000000000 --- a/public/docs/_examples/upgrade-adapter/ts/index-upgrade-static.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - Angular 2 Upgrade - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/upgrade-module/e2e-spec.ts b/public/docs/_examples/upgrade-module/e2e-spec.ts new file mode 100644 index 0000000000..0c45fb78b8 --- /dev/null +++ b/public/docs/_examples/upgrade-module/e2e-spec.ts @@ -0,0 +1,182 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; +import { setProtractorToHybridMode } from '../protractor-helpers'; + +describe('Upgrade Tests', function () { + + beforeAll(function () { + setProtractorToHybridMode(); + }); + + describe('AngularJS Auto-bootstrap', function() { + + beforeAll(function () { + browser.get('/index-ng-app.html'); + }); + + it('bootstraps as expected', function () { + expect(element(by.css('#message')).getText()).toEqual('Hello world'); + }); + + }); + + describe('AngularJS JavaScript Bootstrap', function() { + + beforeAll(function () { + browser.get('/index-bootstrap.html'); + }); + + it('bootstraps as expected', function () { + expect(element(by.css('#message')).getText()).toEqual('Hello world'); + }); + + }); + + describe('AngularJS-Angular Hybrid Bootstrap', function() { + + beforeAll(function () { + browser.get('/index-ajs-a-hybrid-bootstrap.html'); + }); + + it('bootstraps as expected', function () { + expect(element(by.css('#message')).getText()).toEqual('Hello world'); + }); + + }); + + describe('Upgraded static component', function() { + + beforeAll(function () { + browser.get('/index-upgrade-static.html'); + }); + + it('renders', function () { + expect(element(by.css('h2')).getText()).toEqual('Windstorm details!'); + }); + + }); + + + describe('Upgraded component with IO', function() { + + beforeAll(function () { + browser.get('/index-upgrade-io.html'); + }); + + it('has inputs', function () { + expect(element(by.css('h2')).getText()).toEqual('Windstorm details!'); + }); + + it('has outputs', function () { + element(by.buttonText('Delete')).click(); + expect(element(by.css('h2')).getText()).toEqual('Ex-Windstorm details!'); + }); + + }); + + + describe('Downgraded static component', function() { + + beforeAll(function () { + browser.get('/index-downgrade-static.html'); + }); + + it('renders', function () { + expect(element(by.css('h2')).getText()).toEqual('Windstorm details!'); + }); + + }); + + describe('Downgraded component with IO', function() { + + beforeAll(function () { + browser.get('/index-downgrade-io.html'); + }); + + it('has inputs', function () { + expect(element.all(by.css('h2')).first().getText()).toEqual('Windstorm details!'); + }); + + it('has outputs', function () { + element.all(by.buttonText('Delete')).first().click(); + expect(element.all(by.css('h2')).first().getText()).toEqual('Ex-Windstorm details!'); + }); + + it('supports ng-repeat', function () { + expect(element.all(by.css('hero-detail')).count()).toBe(3); + }); + + }); + + + describe('Downgraded component with content projection', function() { + + beforeAll(function () { + browser.get('/index-ajs-to-a-projection.html'); + }); + + it('can be transcluded into', function () { + expect(element(by.css('hero-detail')).getText()).toContain('Specific powers of controlling winds'); + }); + + }); + + + describe('Upgraded component with transclusion', function() { + + beforeAll(function () { + browser.get('/index-a-to-ajs-transclusion.html'); + }); + + it('can be projected into', function () { + expect(element(by.css('hero-detail')).getText()).toContain('Specific powers of controlling winds'); + }); + + }); + + + describe('Upgrading AngularJS Providers', function() { + + beforeAll(function () { + browser.get('/index-ajs-to-a-providers.html'); + }); + + it('works', function () { + expect(element(by.css('h2')).getText()).toBe('1: Windstorm'); + }); + + }); + + + describe('Downgrading Angular Providers', function() { + + beforeAll(function () { + browser.get('/index-a-to-ajs-providers.html'); + }); + + it('works', function () { + expect(element(by.css('h2')).getText()).toBe('1: Windstorm'); + }); + + }); + + describe('Dividing routes', function() { + + beforeAll(function () { + browser.get('/index-divide-routes.html'); + }); + + it('allows ng1 routes', function () { + browser.get('/index-divide-routes.html#/villain'); + expect(element(by.css('h2')).getText()).toBe('Mr. Nice - No More Mr. Nice Guy'); + }); + + it('allows ng2 routes', function () { + browser.get('/index-divide-routes.html#/hero'); + expect(element(by.css('h2')).getText()).toBe('Windstorm - Specific powers of controlling winds'); + }); + + }); + +}); diff --git a/public/docs/_examples/upgrade-module/ts/.gitignore b/public/docs/_examples/upgrade-module/ts/.gitignore new file mode 100644 index 0000000000..7f5c313a3e --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/.gitignore @@ -0,0 +1,7 @@ +**/*.js +aot/**/* +!aot/bs-config.json +!aot/index.html +!copy-dist-files.js +!rollup-config.js +!systemjs.config.1.js diff --git a/public/docs/_examples/template-syntax/dart/example-config.json b/public/docs/_examples/upgrade-module/ts/example-config.json similarity index 100% rename from public/docs/_examples/template-syntax/dart/example-config.json rename to public/docs/_examples/upgrade-module/ts/example-config.json diff --git a/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-providers/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-providers/app.module.ts new file mode 100644 index 0000000000..91235a1485 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-providers/app.module.ts @@ -0,0 +1,34 @@ +declare var angular: angular.IAngularStatic; +import { NgModule } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule } from '@angular/upgrade/static'; + +import { heroDetailComponent } from './hero-detail.component'; + +// #docregion ngmodule +import { Heroes } from './heroes'; + +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule + ], + providers: [ Heroes ] +}) +export class AppModule { + ngDoBootstrap() {} +} +// #enddocregion ngmodule +// #docregion register +import { downgradeInjectable } from '@angular/upgrade/static'; + +angular.module('heroApp', []) + .factory('heroes', downgradeInjectable(Heroes)) + .component('heroDetail', heroDetailComponent); +// #enddocregion register + +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true}); +}); diff --git a/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-providers/hero-detail.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-providers/hero-detail.component.ts new file mode 100644 index 0000000000..dd7aa10d79 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-providers/hero-detail.component.ts @@ -0,0 +1,11 @@ +import { Heroes } from './heroes'; + +// #docregion +export const heroDetailComponent = { + template: ` +

    {{$ctrl.hero.id}}: {{$ctrl.hero.name}}

    + `, + controller: ['heroes', function(heroes: Heroes) { + this.hero = heroes.get()[0]; + }] +}; diff --git a/public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/heroes.ts b/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-providers/heroes.ts similarity index 100% rename from public/docs/_examples/upgrade-adapter/ts/app/2-to-1-providers/heroes.ts rename to public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-providers/heroes.ts diff --git a/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-transclusion/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-transclusion/app.module.ts new file mode 100644 index 0000000000..599e711b5e --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-transclusion/app.module.ts @@ -0,0 +1,39 @@ +declare var angular: angular.IAngularStatic; +import { NgModule } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static'; + +import { heroDetail, HeroDetailDirective } from './hero-detail.component'; +import { ContainerComponent } from './container.component'; + +// #docregion heroupgrade +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule + ], + declarations: [ + ContainerComponent, + HeroDetailDirective + ], + entryComponents: [ + ContainerComponent + ] +}) +export class AppModule { + ngDoBootstrap() {} +} +// #enddocregion heroupgrade + +angular.module('heroApp', []) + .component('heroDetail', heroDetail) + .directive( + 'myContainer', + downgradeComponent({component: ContainerComponent}) as angular.IDirectiveFactory + ); + +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true}); +}); diff --git a/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-transclusion/container.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-transclusion/container.component.ts new file mode 100644 index 0000000000..1b740d6554 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-transclusion/container.component.ts @@ -0,0 +1,16 @@ +// #docregion +import { Component } from '@angular/core'; +import { Hero } from '../hero'; + +@Component({ + selector: 'my-container', + template: ` + + +

    {{hero.description}}

    +
    + ` +}) +export class ContainerComponent { + hero = new Hero(1, 'Windstorm', 'Specific powers of controlling winds'); +} diff --git a/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-transclusion/hero-detail.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-transclusion/hero-detail.component.ts new file mode 100644 index 0000000000..a1bec385e0 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/a-to-ajs-transclusion/hero-detail.component.ts @@ -0,0 +1,28 @@ +// #docregion +export const heroDetail = { + bindings: { + hero: '=' + }, + template: ` +

    {{$ctrl.hero.name}}

    +
    + +
    + ` +}; +// #enddocregion + +import { Directive, ElementRef, Injector, Input } from '@angular/core'; +import { UpgradeComponent } from '@angular/upgrade/static'; +import { Hero } from '../hero'; + +@Directive({ + selector: 'hero-detail' +}) +export class HeroDetailDirective extends UpgradeComponent { + @Input() hero: Hero; + + constructor(elementRef: ElementRef, injector: Injector) { + super('heroDetail', elementRef, injector); + } +} diff --git a/public/docs/_examples/upgrade-module/ts/src/app/ajs-a-hybrid-bootstrap/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/ajs-a-hybrid-bootstrap/app.module.ts new file mode 100644 index 0000000000..7a6b82cf92 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/ajs-a-hybrid-bootstrap/app.module.ts @@ -0,0 +1,29 @@ +declare var angular: angular.IAngularStatic; +// #docregion ngmodule +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule } from '@angular/upgrade/static'; + +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule + ] +}) +export class AppModule { + ngDoBootstrap() {} +} +// #enddocregion ngmodule +angular.module('heroApp', []) + .controller('MainCtrl', function() { + this.message = 'Hello world'; + }); + +// #docregion bootstrap +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true}); +}); +// #enddocregion bootstrap diff --git a/public/docs/_examples/upgrade-module/ts/src/app/ajs-bootstrap/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/ajs-bootstrap/app.module.ts new file mode 100644 index 0000000000..639b780d1b --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/ajs-bootstrap/app.module.ts @@ -0,0 +1,10 @@ +angular.module('heroApp', []) + .controller('MainCtrl', function() { + this.message = 'Hello world'; + }); + +document.addEventListener('DOMContentLoaded', function() { + // #docregion bootstrap + angular.bootstrap(document.body, ['heroApp'], {strictDi: true}); + // #enddocregion bootstrap +}); diff --git a/public/docs/_examples/upgrade-module/ts/src/app/ajs-ng-app/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/ajs-ng-app/app.module.ts new file mode 100644 index 0000000000..904f7578b8 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/ajs-ng-app/app.module.ts @@ -0,0 +1,4 @@ +angular.module('heroApp', []) + .controller('MainCtrl', function() { + this.message = 'Hello world'; + }); diff --git a/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-projection/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-projection/app.module.ts new file mode 100644 index 0000000000..080f80f0ef --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-projection/app.module.ts @@ -0,0 +1,36 @@ +declare var angular: angular.IAngularStatic; +import { NgModule } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static'; + +import { MainController } from './main.controller'; +import { HeroDetailComponent } from './hero-detail.component'; + +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule + ], + declarations: [ + HeroDetailComponent + ], + entryComponents: [ + HeroDetailComponent + ] +}) +export class AppModule { + ngDoBootstrap() {} +} + +angular.module('heroApp', []) + .controller('MainController', MainController) + .directive('heroDetail', downgradeComponent({ + component: HeroDetailComponent, + inputs: ['hero'] + }) as angular.IDirectiveFactory); + +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true}); +}); diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-projection/hero-detail.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-projection/hero-detail.component.ts similarity index 100% rename from public/docs/_examples/upgrade-adapter/ts/app/1-to-2-projection/hero-detail.component.ts rename to public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-projection/hero-detail.component.ts diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-projection/main.controller.ts b/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-projection/main.controller.ts similarity index 100% rename from public/docs/_examples/upgrade-adapter/ts/app/1-to-2-projection/main.controller.ts rename to public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-projection/main.controller.ts diff --git a/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-providers/ajs-upgraded-providers.ts b/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-providers/ajs-upgraded-providers.ts new file mode 100644 index 0000000000..52d4e74a1f --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-providers/ajs-upgraded-providers.ts @@ -0,0 +1,12 @@ +// #docregion +import { HeroesService } from './heroes.service'; + +export function heroesServiceFactory(i: any) { + return i.get('heroes'); +} + +export const heroesServiceProvider = { + provide: HeroesService, + useFactory: heroesServiceFactory, + deps: ['$injector'] +}; diff --git a/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-providers/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-providers/app.module.ts new file mode 100644 index 0000000000..4e0eca003a --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-providers/app.module.ts @@ -0,0 +1,44 @@ +declare var angular: angular.IAngularStatic; +import { NgModule } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static'; + +import { HeroDetailComponent } from './hero-detail.component'; +import { HeroesService } from './heroes.service'; +// #docregion register +import { heroesServiceProvider } from './ajs-upgraded-providers'; + +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule + ], + providers: [ + heroesServiceProvider + ], + // #enddocregion register + declarations: [ + HeroDetailComponent + ], + entryComponents: [ + HeroDetailComponent + ] +// #docregion register +}) +export class AppModule { + ngDoBootstrap() {} +} +// #enddocregion register + +angular.module('heroApp', []) + .service('heroes', HeroesService) + .directive( + 'heroDetail', + downgradeComponent({component: HeroDetailComponent}) as angular.IDirectiveFactory + ); + +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true}); +}); diff --git a/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-providers/hero-detail.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-providers/hero-detail.component.ts new file mode 100644 index 0000000000..b02f85b99a --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-providers/hero-detail.component.ts @@ -0,0 +1,17 @@ +// #docregion +import { Component } from '@angular/core'; +import { HeroesService } from './heroes.service'; +import { Hero } from '../hero'; + +@Component({ + selector: 'hero-detail', + template: ` +

    {{hero.id}}: {{hero.name}}

    + ` +}) +export class HeroDetailComponent { + hero: Hero; + constructor(heroes: HeroesService) { + this.hero = heroes.get()[0]; + } +} diff --git a/public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/heroes.service.ts b/public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-providers/heroes.service.ts similarity index 100% rename from public/docs/_examples/upgrade-adapter/ts/app/1-to-2-providers/heroes.service.ts rename to public/docs/_examples/upgrade-module/ts/src/app/ajs-to-a-providers/heroes.service.ts diff --git a/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/app.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/app.component.ts new file mode 100644 index 0000000000..1fae3f84c6 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/app.component.ts @@ -0,0 +1,11 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + template: ` + +
    + `, +}) +export class AppComponent { } diff --git a/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/app.module.ts new file mode 100644 index 0000000000..7d85a23c94 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/app.module.ts @@ -0,0 +1,62 @@ +// #docregion +declare var angular: angular.IAngularStatic; +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule } from '@angular/upgrade/static'; + +import { HeroModule } from './hero.module'; + +// #docregion router-config +import { HashLocationStrategy, LocationStrategy } from '@angular/common'; +import { RouterModule, UrlHandlingStrategy, UrlTree } from '@angular/router'; +import { AppComponent } from './app.component'; + +class HybridUrlHandlingStrategy implements UrlHandlingStrategy { + // use only process the `/hero` url + shouldProcessUrl(url: UrlTree) { return url.toString().startsWith('/hero'); } + extract(url: UrlTree) { return url; } + merge(url: UrlTree, whole: UrlTree) { return url; } +} + +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule, + HeroModule, + RouterModule.forRoot([]) + ], + providers: [ + // use hash location strategy + { provide: LocationStrategy, useClass: HashLocationStrategy }, + // use custom url handling strategy + { provide: UrlHandlingStrategy, useClass: HybridUrlHandlingStrategy } + ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +// #enddocregion router-config + +import { Villain } from '../villain'; + +export const villainDetail = { + template: ` +

    Villain detail

    +

    {{$ctrl.villain.name}} - {{$ctrl.villain.description}}

    + `, + controller: function() { + this.villain = new Villain(1, 'Mr. Nice', 'No More Mr. Nice Guy'); + } +}; + +angular.module('heroApp', ['ngRoute']) + .component('villainDetail', villainDetail) + .config(['$locationProvider', '$routeProvider', + function config($locationProvider: angular.ILocationProvider, + $routeProvider: angular.route.IRouteProvider) { + // #docregion ajs-route + $routeProvider + .when('/villain', { template: '' }); + // #enddocregion ajs-route + } + ]); diff --git a/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/hero.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/hero.module.ts new file mode 100644 index 0000000000..33099d0a9f --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/hero.module.ts @@ -0,0 +1,32 @@ +// #docregion +import { Component } from '@angular/core'; +import { Hero } from '../hero'; + +@Component({ + template: ` +

    Hero detail

    +

    {{hero.name}} - {{hero.description}}

    + ` +}) +export class HeroDetailComponent { + hero = new Hero(1, 'Windstorm', 'Specific powers of controlling winds'); +} + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; + +@NgModule({ + imports: [ + CommonModule, + // #docregion a-route + RouterModule.forChild([ + { path: 'hero', children: [ + { path: '', component: HeroDetailComponent }, + ] }, + ]) + // #enddocregion a-route + ], + declarations: [ HeroDetailComponent ] +}) +export class HeroModule {} diff --git a/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/main.ts b/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/main.ts new file mode 100644 index 0000000000..9b4d37ebc3 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/divide-routes/main.ts @@ -0,0 +1,10 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { UpgradeModule } from '@angular/upgrade/static'; + +import { AppModule } from './app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true}); +}); diff --git a/public/docs/_examples/upgrade-module/ts/src/app/downgrade-io/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/downgrade-io/app.module.ts new file mode 100644 index 0000000000..1e836cfc9d --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/downgrade-io/app.module.ts @@ -0,0 +1,43 @@ +declare var angular: angular.IAngularStatic; +import { NgModule } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static'; + +import { MainController } from './main.controller'; + +// #docregion downgradecomponent +import { HeroDetailComponent } from './hero-detail.component'; + +// #enddocregion downgradecomponent +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule + ], + declarations: [ + HeroDetailComponent + ], + entryComponents: [ + HeroDetailComponent + ] +}) +export class AppModule { + ngDoBootstrap() {} +} +// #docregion downgradecomponent + +angular.module('heroApp', []) + .controller('MainController', MainController) + .directive('heroDetail', downgradeComponent({ + component: HeroDetailComponent, + inputs: ['hero'], + outputs: ['deleted'] + }) as angular.IDirectiveFactory); + +// #enddocregion downgradecomponent + +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true}); +}); diff --git a/public/docs/_examples/upgrade-module/ts/src/app/downgrade-io/hero-detail.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/downgrade-io/hero-detail.component.ts new file mode 100644 index 0000000000..94082813fd --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/downgrade-io/hero-detail.component.ts @@ -0,0 +1,19 @@ +// #docregion +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Hero } from '../hero'; + +@Component({ + selector: 'hero-detail', + template: ` +

    {{hero.name}} details!

    +
    {{hero.id}}
    + + ` +}) +export class HeroDetailComponent { + @Input() hero: Hero; + @Output() deleted = new EventEmitter(); + onDelete() { + this.deleted.emit(this.hero); + } +} diff --git a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/main.controller.ts b/public/docs/_examples/upgrade-module/ts/src/app/downgrade-io/main.controller.ts similarity index 87% rename from public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/main.controller.ts rename to public/docs/_examples/upgrade-module/ts/src/app/downgrade-io/main.controller.ts index 2ce02c8792..d50272073f 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/downgrade-io/main.controller.ts +++ b/public/docs/_examples/upgrade-module/ts/src/app/downgrade-io/main.controller.ts @@ -5,8 +5,8 @@ export class MainController { heroes = [ new Hero(2, 'Superman'), new Hero(3, 'Spiderman') - ] - onDelete(hero:Hero) { + ]; + onDelete(hero: Hero) { hero.name = 'Ex-' + hero.name; } } diff --git a/public/docs/_examples/upgrade-module/ts/src/app/downgrade-static/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/downgrade-static/app.module.ts new file mode 100644 index 0000000000..4d621d2f03 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/downgrade-static/app.module.ts @@ -0,0 +1,42 @@ +declare var angular: angular.IAngularStatic; +import { NgModule } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule } from '@angular/upgrade/static'; + +// #docregion downgradecomponent, ngmodule +import { HeroDetailComponent } from './hero-detail.component'; + +// #enddocregion downgradecomponent +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule + ], + declarations: [ + HeroDetailComponent + ], + entryComponents: [ + HeroDetailComponent + ] +}) +export class AppModule { + ngDoBootstrap() {} +} +// #enddocregion ngmodule +// #docregion downgradecomponent + +import { downgradeComponent } from '@angular/upgrade/static'; + +angular.module('heroApp', []) + .directive( + 'heroDetail', + downgradeComponent({component: HeroDetailComponent}) as angular.IDirectiveFactory + ); + +// #enddocregion downgradecomponent + +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true}); +}); diff --git a/public/docs/_examples/upgrade-module/ts/src/app/downgrade-static/hero-detail.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/downgrade-static/hero-detail.component.ts new file mode 100644 index 0000000000..df4a705f37 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/downgrade-static/hero-detail.component.ts @@ -0,0 +1,11 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'hero-detail', + template: ` +

    Windstorm details!

    +
    1
    + ` +}) +export class HeroDetailComponent { } diff --git a/public/docs/_examples/upgrade-adapter/ts/app/hero-detail.directive.ts b/public/docs/_examples/upgrade-module/ts/src/app/hero-detail.directive.ts similarity index 98% rename from public/docs/_examples/upgrade-adapter/ts/app/hero-detail.directive.ts rename to public/docs/_examples/upgrade-module/ts/src/app/hero-detail.directive.ts index 8f595ba38f..e1b14d2dfc 100644 --- a/public/docs/_examples/upgrade-adapter/ts/app/hero-detail.directive.ts +++ b/public/docs/_examples/upgrade-module/ts/src/app/hero-detail.directive.ts @@ -18,5 +18,5 @@ export function heroDetailDirective() { }; }, controllerAs: 'ctrl' - } + }; } diff --git a/public/docs/_examples/upgrade-module/ts/src/app/hero.ts b/public/docs/_examples/upgrade-module/ts/src/app/hero.ts new file mode 100644 index 0000000000..5dcb5664eb --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/hero.ts @@ -0,0 +1,5 @@ +export class Hero { + constructor(public id: number, + public name: string, + public description?: string) { } +} diff --git a/public/docs/_examples/upgrade-module/ts/src/app/upgrade-io/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-io/app.module.ts new file mode 100644 index 0000000000..599e711b5e --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-io/app.module.ts @@ -0,0 +1,39 @@ +declare var angular: angular.IAngularStatic; +import { NgModule } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static'; + +import { heroDetail, HeroDetailDirective } from './hero-detail.component'; +import { ContainerComponent } from './container.component'; + +// #docregion heroupgrade +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule + ], + declarations: [ + ContainerComponent, + HeroDetailDirective + ], + entryComponents: [ + ContainerComponent + ] +}) +export class AppModule { + ngDoBootstrap() {} +} +// #enddocregion heroupgrade + +angular.module('heroApp', []) + .component('heroDetail', heroDetail) + .directive( + 'myContainer', + downgradeComponent({component: ContainerComponent}) as angular.IDirectiveFactory + ); + +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true}); +}); diff --git a/public/docs/_examples/upgrade-module/ts/src/app/upgrade-io/container.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-io/container.component.ts new file mode 100644 index 0000000000..8d76085174 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-io/container.component.ts @@ -0,0 +1,19 @@ +// #docregion +import { Component } from '@angular/core'; +import { Hero } from '../hero'; + +@Component({ + selector: 'my-container', + template: ` +

    Tour of Heroes

    + + + ` +}) +export class ContainerComponent { + hero = new Hero(1, 'Windstorm'); + heroDeleted(hero: Hero) { + hero.name = 'Ex-' + hero.name; + } +} diff --git a/public/docs/_examples/upgrade-module/ts/src/app/upgrade-io/hero-detail.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-io/hero-detail.component.ts new file mode 100644 index 0000000000..90c3273010 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-io/hero-detail.component.ts @@ -0,0 +1,37 @@ +// #docregion +// #docregion hero-detail-io +export const heroDetail = { + bindings: { + hero: '<', + deleted: '&' + }, + template: ` +

    {{$ctrl.hero.name}} details!

    +
    {{$ctrl.hero.id}}
    + + `, + controller: function() { + this.onDelete = () => { + this.deleted(this.hero); + }; + } +}; +// #enddocregion hero-detail-io + +// #docregion hero-detail-io-upgrade +import { Directive, ElementRef, Injector, Input, Output, EventEmitter } from '@angular/core'; +import { UpgradeComponent } from '@angular/upgrade/static'; +import { Hero } from '../hero'; + +@Directive({ + selector: 'hero-detail' +}) +export class HeroDetailDirective extends UpgradeComponent { + @Input() hero: Hero; + @Output() deleted: EventEmitter; + + constructor(elementRef: ElementRef, injector: Injector) { + super('heroDetail', elementRef, injector); + } +} +// #enddocregion hero-detail-io-upgrade diff --git a/public/docs/_examples/upgrade-module/ts/src/app/upgrade-static/app.module.ts b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-static/app.module.ts new file mode 100644 index 0000000000..401963c35e --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-static/app.module.ts @@ -0,0 +1,41 @@ +declare var angular: angular.IAngularStatic; +import { NgModule } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static'; + +import { heroDetail, HeroDetailDirective } from './hero-detail.component'; +import { ContainerComponent } from './container.component'; + +// #docregion hero-detail-upgrade +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule + ], + declarations: [ + HeroDetailDirective, + // #enddocregion hero-detail-upgrade + ContainerComponent + ], + entryComponents: [ + ContainerComponent + // #docregion hero-detail-upgrade + ] +}) +export class AppModule { + ngDoBootstrap() {} +} +// #enddocregion hero-detail-upgrade + +angular.module('heroApp', []) + .component('heroDetail', heroDetail) + .directive( + 'myContainer', + downgradeComponent({component: ContainerComponent}) as angular.IDirectiveFactory + ); + +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.body, ['heroApp'], {strictDi: true}); +}); diff --git a/public/docs/_examples/upgrade-module/ts/src/app/upgrade-static/container.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-static/container.component.ts new file mode 100644 index 0000000000..c28e5ea42d --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-static/container.component.ts @@ -0,0 +1,11 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-container', + template: ` +

    Tour of Heroes

    + + ` +}) +export class ContainerComponent { } diff --git a/public/docs/_examples/upgrade-module/ts/src/app/upgrade-static/hero-detail.component.ts b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-static/hero-detail.component.ts new file mode 100644 index 0000000000..02ddd293eb --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/upgrade-static/hero-detail.component.ts @@ -0,0 +1,25 @@ +// #docregion +// #docregion hero-detail +export const heroDetail = { + template: ` +

    Windstorm details!

    +
    1
    + `, + controller: function() { + } +}; +// #enddocregion hero-detail + +// #docregion hero-detail-upgrade +import { Directive, ElementRef, Injector } from '@angular/core'; +import { UpgradeComponent } from '@angular/upgrade/static'; + +@Directive({ + selector: 'hero-detail' +}) +export class HeroDetailDirective extends UpgradeComponent { + constructor(elementRef: ElementRef, injector: Injector) { + super('heroDetail', elementRef, injector); + } +} +// #enddocregion hero-detail-upgrade diff --git a/public/docs/_examples/upgrade-module/ts/src/app/villain.ts b/public/docs/_examples/upgrade-module/ts/src/app/villain.ts new file mode 100644 index 0000000000..ef3d014f11 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/app/villain.ts @@ -0,0 +1,5 @@ +export class Villain { + constructor(public id: number, + public name: string, + public description?: string) { } +} diff --git a/public/docs/_examples/upgrade-module/ts/src/index-a-to-ajs-providers.html b/public/docs/_examples/upgrade-module/ts/src/index-a-to-ajs-providers.html new file mode 100644 index 0000000000..693655a53c --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/index-a-to-ajs-providers.html @@ -0,0 +1,31 @@ + + + + Angular Upgrade + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/upgrade-module/ts/src/index-a-to-ajs-transclusion.html b/public/docs/_examples/upgrade-module/ts/src/index-a-to-ajs-transclusion.html new file mode 100644 index 0000000000..43bc09c64b --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/index-a-to-ajs-transclusion.html @@ -0,0 +1,30 @@ + + + + Angular Upgrade + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/upgrade-module/ts/src/index-ajs-a-hybrid-bootstrap.html b/public/docs/_examples/upgrade-module/ts/src/index-ajs-a-hybrid-bootstrap.html new file mode 100644 index 0000000000..1115e931f5 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/index-ajs-a-hybrid-bootstrap.html @@ -0,0 +1,28 @@ + + + + Angular Upgrade + + + + + + + + + + + + + + + + + + +
    {{ mainCtrl.message }}
    + + diff --git a/public/docs/_examples/upgrade-module/ts/src/index-ajs-to-a-projection.html b/public/docs/_examples/upgrade-module/ts/src/index-ajs-to-a-projection.html new file mode 100644 index 0000000000..3456957077 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/index-ajs-to-a-projection.html @@ -0,0 +1,37 @@ + + + + Angular Upgrade + + + + + + + + + + + + + + + + + + + + +
    + + +

    {{mainCtrl.hero.description}}

    +
    +
    + +
    + + diff --git a/public/docs/_examples/upgrade-module/ts/src/index-ajs-to-a-providers.html b/public/docs/_examples/upgrade-module/ts/src/index-ajs-to-a-providers.html new file mode 100644 index 0000000000..7d1f2b7a05 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/index-ajs-to-a-providers.html @@ -0,0 +1,31 @@ + + + + Angular Upgrade + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/upgrade-adapter/ts/index-bootstrap.html b/public/docs/_examples/upgrade-module/ts/src/index-bootstrap.html similarity index 77% rename from public/docs/_examples/upgrade-adapter/ts/index-bootstrap.html rename to public/docs/_examples/upgrade-module/ts/src/index-bootstrap.html index 430dfbde80..bc4614e562 100644 --- a/public/docs/_examples/upgrade-adapter/ts/index-bootstrap.html +++ b/public/docs/_examples/upgrade-module/ts/src/index-bootstrap.html @@ -2,8 +2,9 @@ + - + diff --git a/public/docs/_examples/upgrade-module/ts/src/index-divide-routes.html b/public/docs/_examples/upgrade-module/ts/src/index-divide-routes.html new file mode 100644 index 0000000000..ee9a56ab36 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/index-divide-routes.html @@ -0,0 +1,31 @@ + + + + Angular 2 Upgrade + + + + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/upgrade-adapter/ts/index-downgrade-io.html b/public/docs/_examples/upgrade-module/ts/src/index-downgrade-io.html similarity index 81% rename from public/docs/_examples/upgrade-adapter/ts/index-downgrade-io.html rename to public/docs/_examples/upgrade-module/ts/src/index-downgrade-io.html index 744a0ca5c1..71e55db355 100644 --- a/public/docs/_examples/upgrade-adapter/ts/index-downgrade-io.html +++ b/public/docs/_examples/upgrade-module/ts/src/index-downgrade-io.html @@ -1,24 +1,21 @@ - Angular 2 Upgrade + Angular Upgrade + - + - - - + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/upgrade-adapter/ts/index-ng-app.html b/public/docs/_examples/upgrade-module/ts/src/index-ng-app.html similarity index 80% rename from public/docs/_examples/upgrade-adapter/ts/index-ng-app.html rename to public/docs/_examples/upgrade-module/ts/src/index-ng-app.html index 2b793fe949..0bd661faae 100644 --- a/public/docs/_examples/upgrade-adapter/ts/index-ng-app.html +++ b/public/docs/_examples/upgrade-module/ts/src/index-ng-app.html @@ -2,8 +2,9 @@ + - + diff --git a/public/docs/_examples/upgrade-module/ts/src/index-upgrade-io.html b/public/docs/_examples/upgrade-module/ts/src/index-upgrade-io.html new file mode 100644 index 0000000000..2dca0d44d4 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/index-upgrade-io.html @@ -0,0 +1,30 @@ + + + + Angular Upgrade + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/upgrade-module/ts/src/index-upgrade-static.html b/public/docs/_examples/upgrade-module/ts/src/index-upgrade-static.html new file mode 100644 index 0000000000..9134cfbc32 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/index-upgrade-static.html @@ -0,0 +1,30 @@ + + + + Angular Upgrade + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/upgrade-module/ts/src/systemjs.config.1.js b/public/docs/_examples/upgrade-module/ts/src/systemjs.config.1.js new file mode 100644 index 0000000000..a8c57d1792 --- /dev/null +++ b/public/docs/_examples/upgrade-module/ts/src/systemjs.config.1.js @@ -0,0 +1,43 @@ +/** + * System configuration for Angular samples + * Adjust as necessary for your application needs. + */ +(function (global) { + System.config({ + paths: { + // paths serve as alias + 'npm:': 'node_modules/' + }, + // map tells the System loader where to look for things + map: { + // our app is within the app folder + app: 'app', + // angular bundles + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + // #docregion upgrade-static-umd + '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js', + // #enddocregion upgrade-static-umd + + // other libraries + 'rxjs': 'npm:rxjs', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' + }, + // packages tells the System loader how to load when no filename and/or no extension + packages: { + app: { + main: './main.js', + defaultExtension: 'js' + }, + rxjs: { + defaultExtension: 'js' + } + } + }); +})(this); diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/README.md b/public/docs/_examples/upgrade-phonecat-1-typescript/README.md index dafa67ece9..f3433b901a 100644 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/README.md +++ b/public/docs/_examples/upgrade-phonecat-1-typescript/README.md @@ -3,18 +3,15 @@ structure. The following changes from vanilla Phonecat are applied: -* The TypeScript config file shown in the guide is `tsconfig.ng1.json` instead +* The TypeScript config file shown in the guide is `tsconfig.ajs.json` instead of the default, because we don't want to enable `noImplicitAny` for migration. -* Karma config for unit tests is in karma.conf.ng1.js because the boilerplate - Karma config is not compatible with the way Angular 1 tests need to be run. +* Karma config for unit tests is in karma.conf.ajs.js because the boilerplate + Karma config is not compatible with the way AngularJS tests need to be run. The shell script run-unit-tests.sh can be used to run the unit tests. -* Instead of using Bower, Angular 1 and its dependencies are fetched from a CDN - in index.html and karma.conf.ng1.js. +* Instead of using Bower, AngularJS and its dependencies are fetched from a CDN + in index.html and karma.conf.ajs.js. * E2E tests have been moved to the parent directory, where `gulp run-e2e-tests` can discover and run them along with all the other examples. -* Angular 1 typings (from DefinitelyTyped) are added to typings-ng1 so that - TypeScript can recognize Angular 1 code. (typings.json comes from boilerplate - so we can't add them there). * Most of the phone JSON and image data removed in the interest of keeping repo weight down. Keeping enough to retain testability of the app. diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/e2e-spec.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/e2e-spec.ts index ced4fbfbd5..4598a7f6dc 100644 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/e2e-spec.ts +++ b/public/docs/_examples/upgrade-phonecat-1-typescript/e2e-spec.ts @@ -1,5 +1,7 @@ -/// -'use strict'; +'use strict'; // necessary for es6 output in node + +import { browser, element, by, ElementFinder } from 'protractor'; +import { setProtractorToNg1Mode } from '../protractor-helpers'; // Angular E2E Testing Guide: // https://docs.angularjs.org/guide/e2e-testing @@ -43,7 +45,7 @@ describe('PhoneCat Application', function() { let phoneNameColumn = element.all(by.repeater('phone in $ctrl.phones').column('phone.name')); function getNames() { - return phoneNameColumn.map(function(elem) { + return phoneNameColumn.map(function(elem: ElementFinder) { return elem.getText(); }); } diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/.gitignore b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/.gitignore new file mode 100644 index 0000000000..448efbe632 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/.gitignore @@ -0,0 +1 @@ +!karma.conf.ajs.js diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/app.animations.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/app.animations.ts index 4af94f3d37..f0739b6405 100644 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/app.animations.ts +++ b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/app.animations.ts @@ -9,7 +9,7 @@ angular. }; function animateIn(element: JQuery, className: string, done: () => void) { - if (className !== 'selected') return; + if (className !== 'selected') { return; } element.css({ display: 'block', @@ -21,12 +21,12 @@ angular. }, done); return function animateInEnd(wasCanceled: boolean) { - if (wasCanceled) element.stop(); + if (wasCanceled) { element.stop(); } }; } function animateOut(element: JQuery, className: string, done: () => void) { - if (className !== 'selected') return; + if (className !== 'selected') { return; } element.css({ position: 'absolute', @@ -37,7 +37,7 @@ angular. }, done); return function animateOutEnd(wasCanceled: boolean) { - if (wasCanceled) element.stop(); + if (wasCanceled) { element.stop(); } }; } }); diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/app.config.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/app.config.ts index 57f37b9d1f..1d16f67fbe 100644 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/app.config.ts +++ b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/app.config.ts @@ -1,7 +1,7 @@ // #docregion angular. module('phonecatApp'). - config(['$locationProvider' ,'$routeProvider', + config(['$locationProvider', '$routeProvider', function config($locationProvider: angular.ILocationProvider, $routeProvider: angular.route.IRouteProvider) { $locationProvider.hashPrefix('!'); diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/core/checkmark/checkmark.filter.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/core/checkmark/checkmark.filter.ts index b140bd6a84..3114dc9681 100644 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/core/checkmark/checkmark.filter.ts +++ b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/core/checkmark/checkmark.filter.ts @@ -1,5 +1,4 @@ // #docregion - angular. module('core'). filter('checkmark', function() { diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/core/phone/phone.service.spec.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/core/phone/phone.service.spec.ts index 3b6962dd59..312036d71d 100644 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/core/phone/phone.service.spec.ts +++ b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/core/phone/phone.service.spec.ts @@ -1,8 +1,8 @@ 'use strict'; describe('Phone', () => { - let $httpBackend:angular.IHttpBackendService; - let Phone:any; + let $httpBackend: angular.IHttpBackendService; + let Phone: any; let phonesData = [ {name: 'Phone X'}, {name: 'Phone Y'}, @@ -18,7 +18,7 @@ describe('Phone', () => { beforeEach(angular.mock.module('core.phone')); // Instantiate the service and "train" `$httpBackend` before each test - beforeEach(inject(function(_$httpBackend_:angular.IHttpBackendService, _Phone_:any) { + beforeEach(inject(function(_$httpBackend_: angular.IHttpBackendService, _Phone_: any) { $httpBackend = _$httpBackend_; $httpBackend.expectGET('phones/phones.json').respond(phonesData); @@ -32,7 +32,7 @@ describe('Phone', () => { }); it('should fetch the phones data from `/phones/phones.json`', () => { - var phones = Phone.query(); + let phones = Phone.query(); expect(phones).toEqual([]); diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/phone-detail/phone-detail.component.spec.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/phone-detail/phone-detail.component.spec.ts index 15ff4a2464..0998b638f0 100644 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/phone-detail/phone-detail.component.spec.ts +++ b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/app/phone-detail/phone-detail.component.spec.ts @@ -6,7 +6,7 @@ describe('phoneDetail', () => { // Test the controller describe('PhoneDetailController', () => { - let $httpBackend: angular.IHttpBackendService + let $httpBackend: angular.IHttpBackendService; let ctrl: any; let xyzPhoneData = { name: 'phone xyz', diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/example-config.json b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/example-config.json index e69de29bb2..a8781b9a31 100644 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/example-config.json +++ b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/example-config.json @@ -0,0 +1,4 @@ +{ + "build": "build:upgrade", + "run": "serve:upgrade" +} diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/karma.conf.ng1.js b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/karma.conf.ajs.js similarity index 100% rename from public/docs/_examples/upgrade-phonecat-1-typescript/ts/karma.conf.ng1.js rename to public/docs/_examples/upgrade-phonecat-1-typescript/ts/karma.conf.ajs.js diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/run-unit-tests.sh b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/run-unit-tests.sh index 00a5abb7bc..239e5ff7d7 100755 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/run-unit-tests.sh +++ b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/run-unit-tests.sh @@ -1,7 +1,7 @@ -## The boilerplate Karma configuration won't work with Angular 1 tests since +## The boilerplate Karma configuration won't work with AngularJS tests since ## a specific loading configuration is needed for them. -## We keep one in karma.conf.ng1.js. This scripts runs the ng1 tests with +## We keep one in karma.conf.ajs.js. This scripts runs the AngularJS tests with ## that config. PATH=$(npm bin):$PATH -tsc && karma start karma.conf.ng1.js +tsc && karma start karma.conf.ajs.js diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/tsconfig.ng1.json b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/tsconfig.ajs.json similarity index 100% rename from public/docs/_examples/upgrade-phonecat-1-typescript/ts/tsconfig.ng1.json rename to public/docs/_examples/upgrade-phonecat-1-typescript/ts/tsconfig.ajs.json diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/tsconfig.json b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/tsconfig.json new file mode 100644 index 0000000000..be11d1eb49 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ "es2015", "dom" ], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "../../node_modules/@types/" + ] + }, + "compileOnSave": true, + "exclude": [ + "node_modules/*", + "**/*-aot.ts", + "aot/**/*" + ] +} diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-animate/index.d.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-animate/index.d.ts deleted file mode 100644 index c720d9293a..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-animate/index.d.ts +++ /dev/null @@ -1,294 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/f0b2681b481397d0c03557ac2ac4d70c1c61c464/angularjs/angular-animate.d.ts -declare module "angular-animate" { - var _: string; - export = _; -} - -/** - * ngAnimate module (angular-animate.js) - */ -declare namespace angular.animate { - interface IAnimateFactory { - (...args: any[]): IAnimateCallbackObject; - } - - interface IAnimateCallbackObject { - eventFn?: (element: IAugmentedJQuery, doneFunction: Function, options: IAnimationOptions) => any; - setClass?: (element: IAugmentedJQuery, addedClasses: string, removedClasses: string, doneFunction: Function, options: IAnimationOptions) => any; - addClass?: (element: IAugmentedJQuery, addedClasses: string, doneFunction: Function, options: IAnimationOptions) => any; - removeClass?: (element: IAugmentedJQuery, removedClasses: string, doneFunction: Function, options: IAnimationOptions) => any; - enter?: (element: IAugmentedJQuery, doneFunction: Function, options: IAnimationOptions) => any; - leave?: (element: IAugmentedJQuery, doneFunction: Function, options: IAnimationOptions) => any; - move?: (element: IAugmentedJQuery, doneFunction: Function, options: IAnimationOptions) => any; - animate?: (element: IAugmentedJQuery, fromStyles: string, toStyles: string, doneFunction: Function, options: IAnimationOptions) => any; - } - - interface IAnimationPromise extends IPromise {} - - /** - * AnimateService - * see http://docs.angularjs.org/api/ngAnimate/service/$animate - */ - interface IAnimateService { - /** - * Sets up an event listener to fire whenever the animation event has fired on the given element or among any of its children. - * - * @param event the animation event that will be captured (e.g. enter, leave, move, addClass, removeClass, etc...) - * @param container the container element that will capture each of the animation events that are fired on itself as well as among its children - * @param callback the callback function that will be fired when the listener is triggered - */ - on(event: string, container: JQuery, callback: Function): void; - - /** - * Deregisters an event listener based on the event which has been associated with the provided element. - * - * @param event the animation event (e.g. enter, leave, move, addClass, removeClass, etc...) - * @param container the container element the event listener was placed on - * @param callback the callback function that was registered as the listener - */ - off(event: string, container?: JQuery, callback?: Function): void; - - /** - * Associates the provided element with a host parent element to allow the element to be animated even if it exists outside of the DOM structure of the Angular application. - * - * @param element the external element that will be pinned - * @param parentElement the host parent element that will be associated with the external element - */ - pin(element: JQuery, parentElement: JQuery): void; - - /** - * Globally enables / disables animations. - * - * @param element If provided then the element will be used to represent the enable/disable operation. - * @param value If provided then set the animation on or off. - * @returns current animation state - */ - enabled(element: JQuery, value?: boolean): boolean; - enabled(value: boolean): boolean; - - /** - * Cancels the provided animation. - */ - cancel(animationPromise: IAnimationPromise): void; - - /** - * Performs an inline animation on the element. - * - * @param element the element that will be the focus of the animation - * @param from a collection of CSS styles that will be applied to the element at the start of the animation - * @param to a collection of CSS styles that the element will animate towards - * @param className an optional CSS class that will be added to the element for the duration of the animation (the default class is 'ng-inline-animate') - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - animate(element: JQuery, from: any, to: any, className?: string, options?: IAnimationOptions): IAnimationPromise; - - /** - * Appends the element to the parentElement element that resides in the document and then runs the enter animation. - * - * @param element the element that will be the focus of the enter animation - * @param parentElement the parent element of the element that will be the focus of the enter animation - * @param afterElement the sibling element (which is the previous element) of the element that will be the focus of the enter animation - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - enter(element: JQuery, parentElement: JQuery, afterElement?: JQuery, options?: IAnimationOptions): IAnimationPromise; - - /** - * Runs the leave animation operation and, upon completion, removes the element from the DOM. - * - * @param element the element that will be the focus of the leave animation - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - leave(element: JQuery, options?: IAnimationOptions): IAnimationPromise; - - /** - * Fires the move DOM operation. Just before the animation starts, the animate service will either append - * it into the parentElement container or add the element directly after the afterElement element if present. - * Then the move animation will be run. - * - * @param element the element that will be the focus of the move animation - * @param parentElement the parent element of the element that will be the focus of the move animation - * @param afterElement the sibling element (which is the previous element) of the element that will be the focus of the move animation - * @returns the animation callback promise - */ - move(element: JQuery, parentElement: JQuery, afterElement?: JQuery): IAnimationPromise; - - /** - * Triggers a custom animation event based off the className variable and then attaches the className - * value to the element as a CSS class. - * - * @param element the element that will be animated - * @param className the CSS class that will be added to the element and then animated - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - addClass(element: JQuery, className: string, options?: IAnimationOptions): IAnimationPromise; - - /** - * Triggers a custom animation event based off the className variable and then removes the CSS class - * provided by the className value from the element. - * - * @param element the element that will be animated - * @param className the CSS class that will be animated and then removed from the element - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - removeClass(element: JQuery, className: string, options?: IAnimationOptions): IAnimationPromise; - - /** - * Adds and/or removes the given CSS classes to and from the element. Once complete, the done() callback - * will be fired (if provided). - * - * @param element the element which will have its CSS classes changed removed from it - * @param add the CSS classes which will be added to the element - * @param remove the CSS class which will be removed from the element CSS classes have been set on the element - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - setClass(element: JQuery, add: string, remove: string, options?: IAnimationOptions): IAnimationPromise; - } - - /** - * AnimateProvider - * see http://docs.angularjs.org/api/ngAnimate/provider/$animateProvider - */ - interface IAnimateProvider { - /** - * Registers a new injectable animation factory function. - * - * @param name The name of the animation. - * @param factory The factory function that will be executed to return the animation object. - */ - register(name: string, factory: IAnimateFactory): void; - - /** - * Gets and/or sets the CSS class expression that is checked when performing an animation. - * - * @param expression The className expression which will be checked against all animations. - * @returns The current CSS className expression value. If null then there is no expression value. - */ - classNameFilter(expression?: RegExp): RegExp; - } - - /** - * Angular Animation Options - * see https://docs.angularjs.org/api/ngAnimate/#applying-directive-specific-styles-to-an-animation - */ - interface IAnimationOptions { - /** - * The ending CSS styles (a key/value object) that will be applied across the animation via a CSS transition. - */ - to?: Object; - - /** - * The starting CSS styles (a key/value object) that will be applied at the start of the animation. - */ - from?: Object; - - /** - * The DOM event (e.g. enter, leave, move). When used, a generated CSS class of ng-EVENT and - * ng-EVENT-active will be applied to the element during the animation. Multiple events can be provided when - * spaces are used as a separator. (Note that this will not perform any DOM operation.) - */ - event?: string; - - /** - * The CSS easing value that will be applied to the transition or keyframe animation (or both). - */ - easing?: string; - - /** - * The raw CSS transition style that will be used (e.g. 1s linear all). - */ - transition?: string; - - /** - * The raw CSS keyframe animation style that will be used (e.g. 1s my_animation linear). - */ - keyframe?: string; - - /** - * A space separated list of CSS classes that will be added to the element and spread across the animation. - */ - addClass?: string; - - /** - * A space separated list of CSS classes that will be removed from the element and spread across - * the animation. - */ - removeClass?: string; - - /** - * A number value representing the total duration of the transition and/or keyframe (note that a value - * of 1 is 1000ms). If a value of 0 is provided then the animation will be skipped entirely. - */ - duration?: number; - - /** - * A number value representing the total delay of the transition and/or keyframe (note that a value of - * 1 is 1000ms). If a value of true is used then whatever delay value is detected from the CSS classes will be - * mirrored on the elements styles (e.g. by setting delay true then the style value of the element will be - * transition-delay: DETECTED_VALUE). Using true is useful when you want the CSS classes and inline styles to - * all share the same CSS delay value. - */ - delay?: number; - - /** - * A numeric time value representing the delay between successively animated elements (Click here to - * learn how CSS-based staggering works in ngAnimate.) - */ - stagger?: number; - - /** - * The numeric index representing the stagger item (e.g. a value of 5 is equal to the sixth item - * in the stagger; therefore when a stagger option value of 0.1 is used then there will be a stagger delay of 600ms) - * applyClassesEarly - Whether or not the classes being added or removed will be used when detecting the animation. - * This is set by $animate when enter/leave/move animations are fired to ensure that the CSS classes are resolved in time. - * (Note that this will prevent any transitions from occuring on the classes being added and removed.) - */ - staggerIndex?: number; - } - - interface IAnimateCssRunner { - /** - * Starts the animation - * - * @returns The animation runner with a done function for supplying a callback. - */ - start(): IAnimateCssRunnerStart; - - /** - * Ends (aborts) the animation - */ - end(): void; - } - - interface IAnimateCssRunnerStart extends IPromise { - /** - * Allows you to add done callbacks to the running animation - * - * @param callbackFn: the callback function to be run - */ - done(callbackFn: (animationFinished: boolean) => void): void; - } - - /** - * AnimateCssService - * see http://docs.angularjs.org/api/ngAnimate/service/$animateCss - */ - interface IAnimateCssService { - (element: JQuery, animateCssOptions: IAnimationOptions): IAnimateCssRunner; - } -} - -declare module angular { - interface IModule { - animation(name: string, animationFactory: angular.animate.IAnimateFactory): IModule; - animation(name: string, inlineAnnotatedFunction: any[]): IModule; - animation(object: Object): IModule; - } - -} \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-animate/typings.json b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-animate/typings.json deleted file mode 100644 index ea2467c89a..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-animate/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/f0b2681b481397d0c03557ac2ac4d70c1c61c464/angularjs/angular-animate.d.ts", - "raw": "registry:dt/angular-animate#1.5.0+20160407085121", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/f0b2681b481397d0c03557ac2ac4d70c1c61c464/angularjs/angular-animate.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-mocks/index.d.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-mocks/index.d.ts deleted file mode 100644 index fd6e92534b..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-mocks/index.d.ts +++ /dev/null @@ -1,339 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/5b7257019ae959533341a715b339d2562bbf9b85/angularjs/angular-mocks.d.ts -declare module "angular-mocks/ngMock" { - var _: string; - export = _; -} - -declare module "angular-mocks/ngMockE2E" { - var _: string; - export = _; -} - -declare module "angular-mocks/ngAnimateMock" { - var _: string; - export = _; -} - -/////////////////////////////////////////////////////////////////////////////// -// ngMock module (angular-mocks.js) -/////////////////////////////////////////////////////////////////////////////// -declare namespace angular { - - /////////////////////////////////////////////////////////////////////////// - // AngularStatic - // We reopen it to add the MockStatic definition - /////////////////////////////////////////////////////////////////////////// - interface IAngularStatic { - mock: IMockStatic; - } - - // see https://docs.angularjs.org/api/ngMock/function/angular.mock.inject - interface IInjectStatic { - (...fns: Function[]): any; - (...inlineAnnotatedConstructor: any[]): any; // this overload is undocumented, but works - strictDi(val?: boolean): void; - } - - interface IMockStatic { - // see https://docs.angularjs.org/api/ngMock/function/angular.mock.dump - dump(obj: any): string; - - inject: IInjectStatic - - // see https://docs.angularjs.org/api/ngMock/function/angular.mock.module - module: { - (...modules: any[]): any; - sharedInjector(): void; - } - - // see https://docs.angularjs.org/api/ngMock/type/angular.mock.TzDate - TzDate(offset: number, timestamp: number): Date; - TzDate(offset: number, timestamp: string): Date; - } - - /////////////////////////////////////////////////////////////////////////// - // ExceptionHandlerService - // see https://docs.angularjs.org/api/ngMock/service/$exceptionHandler - // see https://docs.angularjs.org/api/ngMock/provider/$exceptionHandlerProvider - /////////////////////////////////////////////////////////////////////////// - interface IExceptionHandlerProvider extends IServiceProvider { - mode(mode: string): void; - } - - /////////////////////////////////////////////////////////////////////////// - // TimeoutService - // see https://docs.angularjs.org/api/ngMock/service/$timeout - // Augments the original service - /////////////////////////////////////////////////////////////////////////// - interface ITimeoutService { - flush(delay?: number): void; - flushNext(expectedDelay?: number): void; - verifyNoPendingTasks(): void; - } - - /////////////////////////////////////////////////////////////////////////// - // IntervalService - // see https://docs.angularjs.org/api/ngMock/service/$interval - // Augments the original service - /////////////////////////////////////////////////////////////////////////// - interface IIntervalService { - flush(millis?: number): number; - } - - /////////////////////////////////////////////////////////////////////////// - // LogService - // see https://docs.angularjs.org/api/ngMock/service/$log - // Augments the original service - /////////////////////////////////////////////////////////////////////////// - interface ILogService { - assertEmpty(): void; - reset(): void; - } - - interface ILogCall { - logs: string[]; - } - - /////////////////////////////////////////////////////////////////////////// - // ControllerService mock - // see https://docs.angularjs.org/api/ngMock/service/$controller - // This interface extends http://docs.angularjs.org/api/ng.$controller - /////////////////////////////////////////////////////////////////////////// - interface IControllerService { - // Although the documentation doesn't state this, locals are optional - (controllerConstructor: new (...args: any[]) => T, locals?: any, bindings?: any): T; - (controllerConstructor: Function, locals?: any, bindings?: any): T; - (controllerName: string, locals?: any, bindings?: any): T; - } - - /////////////////////////////////////////////////////////////////////////// - // ComponentControllerService - // see https://docs.angularjs.org/api/ngMock/service/$componentController - /////////////////////////////////////////////////////////////////////////// - interface IComponentControllerService { - // TBinding is an interface exposed by a component as per John Papa's style guide - // https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#accessible-members-up-top - (componentName: string, locals: { $scope: IScope, [key: string]: any }, bindings?: TBinding, ident?: string): T; - } - - - /////////////////////////////////////////////////////////////////////////// - // HttpBackendService - // see https://docs.angularjs.org/api/ngMock/service/$httpBackend - /////////////////////////////////////////////////////////////////////////// - interface IHttpBackendService { - /** - * Flushes all pending requests using the trained responses. - * @param count Number of responses to flush (in the order they arrived). If undefined, all pending requests will be flushed. - */ - flush(count?: number): void; - - /** - * Resets all request expectations, but preserves all backend definitions. - */ - resetExpectations(): void; - - /** - * Verifies that all of the requests defined via the expect api were made. If any of the requests were not made, verifyNoOutstandingExpectation throws an exception. - */ - verifyNoOutstandingExpectation(): void; - - /** - * Verifies that there are no outstanding requests that need to be flushed. - */ - verifyNoOutstandingRequest(): void; - - /** - * Creates a new request expectation. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param method HTTP method. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - expect(method: string, url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)) :mock.IRequestHandler; - - /** - * Creates a new request expectation for DELETE requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url is as expected. - * @param headers HTTP headers object to be compared with the HTTP headers in the request. - */ - expectDELETE(url: string | RegExp | ((url: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new request expectation for GET requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object to be compared with the HTTP headers in the request. - */ - expectGET(url: string | RegExp | ((url: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new request expectation for HEAD requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object to be compared with the HTTP headers in the request. - */ - expectHEAD(url: string | RegExp | ((url: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new request expectation for JSONP requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - */ - expectJSONP(url: string | RegExp | ((url: string) => boolean)): mock.IRequestHandler; - - /** - * Creates a new request expectation for PATCH requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - expectPATCH(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new request expectation for POST requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - expectPOST(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new request expectation for PUT requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - expectPUT(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new backend definition. - * Returns an object with respond method that controls how a matched request is handled. - * @param method HTTP method. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - when(method: string, url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for DELETE requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenDELETE(url: string | RegExp | ((url: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for GET requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenGET(url: string | RegExp | ((url: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for HEAD requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenHEAD(url: string | RegExp | ((url: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for JSONP requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenJSONP(url: string | RegExp | ((url: string) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for PATCH requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenPATCH(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for POST requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenPOST(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for PUT requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenPUT(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - } - - export module mock { - // returned interface by the the mocked HttpBackendService expect/when methods - interface IRequestHandler { - - /** - * Controls the response for a matched request using a function to construct the response. - * Returns the RequestHandler object for possible overrides. - * @param func Function that receives the request HTTP method, url, data, and headers and returns an array containing response status (number), data, headers, and status text. - */ - respond(func: ((method: string, url: string, data: string | Object, headers: Object) => [number, string | Object, Object, string])): IRequestHandler; - - /** - * Controls the response for a matched request using supplied static data to construct the response. - * Returns the RequestHandler object for possible overrides. - * @param status HTTP status code to add to the response. - * @param data Data to add to the response. - * @param headers Headers object to add to the response. - * @param responseText Response text to add to the response. - */ - respond(status: number, data: string | Object, headers?: Object, responseText?: string): IRequestHandler; - - /** - * Controls the response for a matched request using the HTTP status code 200 and supplied static data to construct the response. - * Returns the RequestHandler object for possible overrides. - * @param data Data to add to the response. - * @param headers Headers object to add to the response. - * @param responseText Response text to add to the response. - */ - respond(data: string | Object, headers?: Object, responseText?: string): IRequestHandler; - - // Available when ngMockE2E is loaded - /** - * Any request matching a backend definition or expectation with passThrough handler will be passed through to the real backend (an XHR request will be made to the server.) - */ - passThrough(): IRequestHandler; - } - - } - -} - -/////////////////////////////////////////////////////////////////////////////// -// functions attached to global object (window) -/////////////////////////////////////////////////////////////////////////////// -//Use `angular.mock.module` instead of `module`, as `module` conflicts with commonjs. -//declare var module: (...modules: any[]) => any; -declare var inject: angular.IInjectStatic; \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-mocks/typings.json b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-mocks/typings.json deleted file mode 100644 index 4e51b0e278..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-mocks/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/5b7257019ae959533341a715b339d2562bbf9b85/angularjs/angular-mocks.d.ts", - "raw": "registry:dt/angular-mocks#1.3.0+20160425155016", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/5b7257019ae959533341a715b339d2562bbf9b85/angularjs/angular-mocks.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-resource/index.d.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-resource/index.d.ts deleted file mode 100644 index 3735f9430c..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-resource/index.d.ts +++ /dev/null @@ -1,191 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/e684481e0cd360db62fd6213ca7248245315e8a2/angularjs/angular-resource.d.ts -declare module 'angular-resource' { - var _: string; - export = _; -} - -/////////////////////////////////////////////////////////////////////////////// -// ngResource module (angular-resource.js) -/////////////////////////////////////////////////////////////////////////////// -declare namespace angular.resource { - - /** - * Currently supported options for the $resource factory options argument. - */ - interface IResourceOptions { - /** - * If true then the trailing slashes from any calculated URL will be stripped (defaults to true) - */ - stripTrailingSlashes?: boolean; - /** - * If true, the request made by a "non-instance" call will be cancelled (if not already completed) by calling - * $cancelRequest() on the call's return value. This can be overwritten per action. (Defaults to false.) - */ - cancellable?: boolean; - } - - - /////////////////////////////////////////////////////////////////////////// - // ResourceService - // see http://docs.angularjs.org/api/ngResource.$resource - // Most part of the following definitions were achieved by analyzing the - // actual implementation, since the documentation doesn't seem to cover - // that deeply. - /////////////////////////////////////////////////////////////////////////// - interface IResourceService { - (url: string, paramDefaults?: any, - /** example: {update: { method: 'PUT' }, delete: deleteDescriptor } - where deleteDescriptor : IActionDescriptor */ - actions?: any, options?: IResourceOptions): IResourceClass>; - (url: string, paramDefaults?: any, - /** example: {update: { method: 'PUT' }, delete: deleteDescriptor } - where deleteDescriptor : IActionDescriptor */ - actions?: any, options?: IResourceOptions): U; - (url: string, paramDefaults?: any, - /** example: {update: { method: 'PUT' }, delete: deleteDescriptor } - where deleteDescriptor : IActionDescriptor */ - actions?: any, options?: IResourceOptions): IResourceClass; - } - - // Just a reference to facilitate describing new actions - interface IActionDescriptor { - method: string; - params?: any; - url?: string; - isArray?: boolean; - transformRequest?: angular.IHttpRequestTransformer | angular.IHttpRequestTransformer[]; - transformResponse?: angular.IHttpResponseTransformer | angular.IHttpResponseTransformer[]; - headers?: any; - cache?: boolean | angular.ICacheObject; - /** - * Note: In contrast to $http.config, promises are not supported in $resource, because the same value - * would be used for multiple requests. If you are looking for a way to cancel requests, you should - * use the cancellable option. - */ - timeout?: number - cancellable?: boolean; - withCredentials?: boolean; - responseType?: string; - interceptor?: IHttpInterceptor; - } - - // Allow specify more resource methods - // No need to add duplicates for all four overloads. - interface IResourceMethod { - (): T; - (params: Object): T; - (success: Function, error?: Function): T; - (params: Object, success: Function, error?: Function): T; - (params: Object, data: Object, success?: Function, error?: Function): T; - } - - // Allow specify resource moethod which returns the array - // No need to add duplicates for all four overloads. - interface IResourceArrayMethod { - (): IResourceArray; - (params: Object): IResourceArray; - (success: Function, error?: Function): IResourceArray; - (params: Object, success: Function, error?: Function): IResourceArray; - (params: Object, data: Object, success?: Function, error?: Function): IResourceArray; - } - - // Baseclass for everyresource with default actions. - // If you define your new actions for the resource, you will need - // to extend this interface and typecast the ResourceClass to it. - // - // In case of passing the first argument as anything but a function, - // it's gonna be considered data if the action method is POST, PUT or - // PATCH (in other words, methods with body). Otherwise, it's going - // to be considered as parameters to the request. - // https://github.com/angular/angular.js/blob/v1.2.0/src/ngResource/resource.js#L461-L465 - // - // Only those methods with an HTTP body do have 'data' as first parameter: - // https://github.com/angular/angular.js/blob/v1.2.0/src/ngResource/resource.js#L463 - // More specifically, those methods are POST, PUT and PATCH: - // https://github.com/angular/angular.js/blob/v1.2.0/src/ngResource/resource.js#L432 - // - // Also, static calls always return the IResource (or IResourceArray) retrieved - // https://github.com/angular/angular.js/blob/v1.2.0/src/ngResource/resource.js#L538-L549 - interface IResourceClass { - new(dataOrParams? : any) : T; - get: IResourceMethod; - - query: IResourceArrayMethod; - - save: IResourceMethod; - - remove: IResourceMethod; - - delete: IResourceMethod; - } - - // Instance calls always return the the promise of the request which retrieved the object - // https://github.com/angular/angular.js/blob/v1.2.0/src/ngResource/resource.js#L538-L546 - interface IResource { - $get(): angular.IPromise; - $get(params?: Object, success?: Function, error?: Function): angular.IPromise; - $get(success: Function, error?: Function): angular.IPromise; - - $query(): angular.IPromise>; - $query(params?: Object, success?: Function, error?: Function): angular.IPromise>; - $query(success: Function, error?: Function): angular.IPromise>; - - $save(): angular.IPromise; - $save(params?: Object, success?: Function, error?: Function): angular.IPromise; - $save(success: Function, error?: Function): angular.IPromise; - - $remove(): angular.IPromise; - $remove(params?: Object, success?: Function, error?: Function): angular.IPromise; - $remove(success: Function, error?: Function): angular.IPromise; - - $delete(): angular.IPromise; - $delete(params?: Object, success?: Function, error?: Function): angular.IPromise; - $delete(success: Function, error?: Function): angular.IPromise; - - $cancelRequest(): void; - - /** the promise of the original server interaction that created this instance. **/ - $promise : angular.IPromise; - $resolved : boolean; - toJSON(): T; - } - - /** - * Really just a regular Array object with $promise and $resolve attached to it - */ - interface IResourceArray extends Array> { - /** the promise of the original server interaction that created this collection. **/ - $promise : angular.IPromise>; - $resolved : boolean; - } - - /** when creating a resource factory via IModule.factory */ - interface IResourceServiceFactoryFunction { - ($resource: angular.resource.IResourceService): IResourceClass; - >($resource: angular.resource.IResourceService): U; - } - - // IResourceServiceProvider used to configure global settings - interface IResourceServiceProvider extends angular.IServiceProvider { - - defaults: IResourceOptions; - } - -} - -/** extensions to base ng based on using angular-resource */ -declare namespace angular { - - interface IModule { - /** creating a resource service factory */ - factory(name: string, resourceServiceFactoryFunction: angular.resource.IResourceServiceFactoryFunction): IModule; - } -} - -interface Array -{ - /** the promise of the original server interaction that created this collection. **/ - $promise : angular.IPromise>; - $resolved : boolean; -} \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-resource/typings.json b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-resource/typings.json deleted file mode 100644 index b60eafd673..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-resource/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/e684481e0cd360db62fd6213ca7248245315e8a2/angularjs/angular-resource.d.ts", - "raw": "registry:dt/angular-resource#1.5.0+20160412142209", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/e684481e0cd360db62fd6213ca7248245315e8a2/angularjs/angular-resource.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-route/index.d.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-route/index.d.ts deleted file mode 100644 index 5fad393d0a..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-route/index.d.ts +++ /dev/null @@ -1,154 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/angularjs/angular-route.d.ts -declare module "angular-route" { - var _: string; - export = _; -} - -/////////////////////////////////////////////////////////////////////////////// -// ngRoute module (angular-route.js) -/////////////////////////////////////////////////////////////////////////////// -declare namespace angular.route { - - /////////////////////////////////////////////////////////////////////////// - // RouteParamsService - // see http://docs.angularjs.org/api/ngRoute.$routeParams - /////////////////////////////////////////////////////////////////////////// - interface IRouteParamsService { - [key: string]: any; - } - - /////////////////////////////////////////////////////////////////////////// - // RouteService - // see http://docs.angularjs.org/api/ngRoute.$route - // see http://docs.angularjs.org/api/ngRoute.$routeProvider - /////////////////////////////////////////////////////////////////////////// - interface IRouteService { - reload(): void; - routes: any; - - // May not always be available. For instance, current will not be available - // to a controller that was not initialized as a result of a route maching. - current?: ICurrentRoute; - - /** - * Causes $route service to update the current URL, replacing current route parameters with those specified in newParams. - * Provided property names that match the route's path segment definitions will be interpolated into the - * location's path, while remaining properties will be treated as query params. - * - * @param newParams Object. mapping of URL parameter names to values - */ - updateParams(newParams:{[key:string]:string}): void; - - } - - type InlineAnnotatedFunction = Function|Array - - /** - * see http://docs.angularjs.org/api/ngRoute/provider/$routeProvider#when for API documentation - */ - interface IRoute { - /** - * {(string|function()=} - * Controller fn that should be associated with newly created scope or the name of a registered controller if passed as a string. - */ - controller?: string|InlineAnnotatedFunction; - /** - * A controller alias name. If present the controller will be published to scope under the controllerAs name. - */ - controllerAs?: string; - /** - * Undocumented? - */ - name?: string; - /** - * {string=|function()=} - * Html template as a string or a function that returns an html template as a string which should be used by ngView or ngInclude directives. This property takes precedence over templateUrl. - * - * If template is a function, it will be called with the following parameters: - * - * {Array.} - route parameters extracted from the current $location.path() by applying the current route - */ - template?: string|{($routeParams?: angular.route.IRouteParamsService) : string;} - /** - * {string=|function()=} - * Path or function that returns a path to an html template that should be used by ngView. - * - * If templateUrl is a function, it will be called with the following parameters: - * - * {Array.} - route parameters extracted from the current $location.path() by applying the current route - */ - templateUrl?: string|{ ($routeParams?: angular.route.IRouteParamsService): string; } - /** - * {Object.=} - An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated. If all the promises are resolved successfully, the values of the resolved promises are injected and $routeChangeSuccess event is fired. If any of the promises are rejected the $routeChangeError event is fired. The map object is: - * - * - key - {string}: a name of a dependency to be injected into the controller. - * - factory - {string|function}: If string then it is an alias for a service. Otherwise if function, then it is injected and the return value is treated as the dependency. If the result is a promise, it is resolved before its value is injected into the controller. Be aware that ngRoute.$routeParams will still refer to the previous route within these resolve functions. Use $route.current.params to access the new route parameters, instead. - */ - resolve?: {[key: string]: any}; - /** - * {(string|function())=} - * Value to update $location path with and trigger route redirection. - * - * If redirectTo is a function, it will be called with the following parameters: - * - * - {Object.} - route parameters extracted from the current $location.path() by applying the current route templateUrl. - * - {string} - current $location.path() - * - {Object} - current $location.search() - * - The custom redirectTo function is expected to return a string which will be used to update $location.path() and $location.search(). - */ - redirectTo?: string|{($routeParams?: angular.route.IRouteParamsService, $locationPath?: string, $locationSearch?: any) : string}; - /** - * Reload route when only $location.search() or $location.hash() changes. - * - * This option defaults to true. If the option is set to false and url in the browser changes, then $routeUpdate event is broadcasted on the root scope. - */ - reloadOnSearch?: boolean; - /** - * Match routes without being case sensitive - * - * This option defaults to false. If the option is set to true, then the particular route can be matched without being case sensitive - */ - caseInsensitiveMatch?: boolean; - } - - // see http://docs.angularjs.org/api/ng.$route#current - interface ICurrentRoute extends IRoute { - locals: { - [index: string]: any; - $scope: IScope; - $template: string; - }; - - params: any; - } - - interface IRouteProvider extends IServiceProvider { - /** - * Match routes without being case sensitive - * - * This option defaults to false. If the option is set to true, then the particular route can be matched without being case sensitive - */ - caseInsensitiveMatch?: boolean; - /** - * Sets route definition that will be used on route change when no other route definition is matched. - * - * @params Mapping information to be assigned to $route.current. - */ - otherwise(params: IRoute): IRouteProvider; - /** - * Adds a new route definition to the $route service. - * - * @param path Route path (matched against $location.path). If $location.path contains redundant trailing slash or is missing one, the route will still match and the $location.path will be updated to add or drop the trailing slash to exactly match the route definition. - * - * - path can contain named groups starting with a colon: e.g. :name. All characters up to the next slash are matched and stored in $routeParams under the given name when the route matches. - * - path can contain named groups starting with a colon and ending with a star: e.g.:name*. All characters are eagerly stored in $routeParams under the given name when the route matches. - * - path can contain optional named groups with a question mark: e.g.:name?. - * - * For example, routes like /color/:color/largecode/:largecode*\/edit will match /color/brown/largecode/code/with/slashes/edit and extract: color: brown and largecode: code/with/slashes. - * - * @param route Mapping information to be assigned to $route.current on route match. - */ - when(path: string, route: IRoute): IRouteProvider; - } -} \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-route/typings.json b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-route/typings.json deleted file mode 100644 index 4c4677f34f..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular-route/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/angularjs/angular-route.d.ts", - "raw": "registry:dt/angular-route#1.3.0+20160317120654", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/angularjs/angular-route.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular/index.d.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular/index.d.ts deleted file mode 100644 index dfde81e26b..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular/index.d.ts +++ /dev/null @@ -1,1953 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/b76dd8a7f95b71696982befbb7589940d27e940b/angularjs/angular.d.ts -declare var angular: angular.IAngularStatic; - -// Support for painless dependency injection -interface Function { - $inject?: string[]; -} - -// Collapse angular into ng -import ng = angular; -// Support AMD require -declare module 'angular' { - export = angular; -} - -/////////////////////////////////////////////////////////////////////////////// -// ng module (angular.js) -/////////////////////////////////////////////////////////////////////////////// -declare namespace angular { - - // not directly implemented, but ensures that constructed class implements $get - interface IServiceProviderClass { - new (...args: any[]): IServiceProvider; - } - - interface IServiceProviderFactory { - (...args: any[]): IServiceProvider; - } - - // All service providers extend this interface - interface IServiceProvider { - $get: any; - } - - interface IAngularBootstrapConfig { - strictDi?: boolean; - debugInfoEnabled?: boolean; - } - - /////////////////////////////////////////////////////////////////////////// - // AngularStatic - // see http://docs.angularjs.org/api - /////////////////////////////////////////////////////////////////////////// - interface IAngularStatic { - bind(context: any, fn: Function, ...args: any[]): Function; - - /** - * Use this function to manually start up angular application. - * - * @param element DOM element which is the root of angular application. - * @param modules An array of modules to load into the application. - * Each item in the array should be the name of a predefined module or a (DI annotated) - * function that will be invoked by the injector as a config block. - * @param config an object for defining configuration options for the application. The following keys are supported: - * - `strictDi`: disable automatic function annotation for the application. This is meant to assist in finding bugs which break minified code. - */ - bootstrap(element: string|Element|JQuery|Document, modules?: (string|Function|any[])[], config?: IAngularBootstrapConfig): auto.IInjectorService; - - /** - * Creates a deep copy of source, which should be an object or an array. - * - * - If no destination is supplied, a copy of the object or array is created. - * - If a destination is provided, all of its elements (for array) or properties (for objects) are deleted and then all elements/properties from the source are copied to it. - * - If source is not an object or array (inc. null and undefined), source is returned. - * - If source is identical to 'destination' an exception will be thrown. - * - * @param source The source that will be used to make a copy. Can be any type, including primitives, null, and undefined. - * @param destination Destination into which the source is copied. If provided, must be of the same type as source. - */ - copy(source: T, destination?: T): T; - - /** - * Wraps a raw DOM element or HTML string as a jQuery element. - * - * If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite." - */ - element: IAugmentedJQueryStatic; - equals(value1: any, value2: any): boolean; - extend(destination: any, ...sources: any[]): any; - - /** - * Invokes the iterator function once for each item in obj collection, which can be either an object or an array. The iterator function is invoked with iterator(value, key), where value is the value of an object property or an array element and key is the object property key or array element index. Specifying a context for the function is optional. - * - * It is worth noting that .forEach does not iterate over inherited properties because it filters using the hasOwnProperty method. - * - * @param obj Object to iterate over. - * @param iterator Iterator function. - * @param context Object to become context (this) for the iterator function. - */ - forEach(obj: T[], iterator: (value: T, key: number) => any, context?: any): any; - /** - * Invokes the iterator function once for each item in obj collection, which can be either an object or an array. The iterator function is invoked with iterator(value, key), where value is the value of an object property or an array element and key is the object property key or array element index. Specifying a context for the function is optional. - * - * It is worth noting that .forEach does not iterate over inherited properties because it filters using the hasOwnProperty method. - * - * @param obj Object to iterate over. - * @param iterator Iterator function. - * @param context Object to become context (this) for the iterator function. - */ - forEach(obj: { [index: string]: T; }, iterator: (value: T, key: string) => any, context?: any): any; - /** - * Invokes the iterator function once for each item in obj collection, which can be either an object or an array. The iterator function is invoked with iterator(value, key), where value is the value of an object property or an array element and key is the object property key or array element index. Specifying a context for the function is optional. - * - * It is worth noting that .forEach does not iterate over inherited properties because it filters using the hasOwnProperty method. - * - * @param obj Object to iterate over. - * @param iterator Iterator function. - * @param context Object to become context (this) for the iterator function. - */ - forEach(obj: any, iterator: (value: any, key: any) => any, context?: any): any; - - fromJson(json: string): any; - identity(arg?: T): T; - injector(modules?: any[], strictDi?: boolean): auto.IInjectorService; - isArray(value: any): boolean; - isDate(value: any): boolean; - isDefined(value: any): boolean; - isElement(value: any): boolean; - isFunction(value: any): boolean; - isNumber(value: any): boolean; - isObject(value: any): boolean; - isString(value: any): boolean; - isUndefined(value: any): boolean; - lowercase(str: string): string; - - /** - * Deeply extends the destination object dst by copying own enumerable properties from the src object(s) to dst. You can specify multiple src objects. If you want to preserve original objects, you can do so by passing an empty object as the target: var object = angular.merge({}, object1, object2). - * - * Unlike extend(), merge() recursively descends into object properties of source objects, performing a deep copy. - * - * @param dst Destination object. - * @param src Source object(s). - */ - merge(dst: any, ...src: any[]): any; - - /** - * The angular.module is a global place for creating, registering and retrieving Angular modules. All modules (angular core or 3rd party) that should be available to an application must be registered using this mechanism. - * - * When passed two or more arguments, a new module is created. If passed only one argument, an existing module (the name passed as the first argument to module) is retrieved. - * - * @param name The name of the module to create or retrieve. - * @param requires The names of modules this module depends on. If specified then new module is being created. If unspecified then the module is being retrieved for further configuration. - * @param configFn Optional configuration function for the module. - */ - module( - name: string, - requires?: string[], - configFn?: Function): IModule; - - noop(...args: any[]): void; - reloadWithDebugInfo(): void; - toJson(obj: any, pretty?: boolean): string; - uppercase(str: string): string; - version: { - full: string; - major: number; - minor: number; - dot: number; - codeName: string; - }; - - /** - * If window.name contains prefix NG_DEFER_BOOTSTRAP! when angular.bootstrap is called, the bootstrap process will be paused until angular.resumeBootstrap() is called. - * @param extraModules An optional array of modules that should be added to the original list of modules that the app was about to be bootstrapped with. - */ - resumeBootstrap?(extraModules?: string[]): ng.auto.IInjectorService; - } - - /////////////////////////////////////////////////////////////////////////// - // Module - // see http://docs.angularjs.org/api/angular.Module - /////////////////////////////////////////////////////////////////////////// - interface IModule { - /** - * Use this method to register a component. - * - * @param name The name of the component. - * @param options A definition object passed into the component. - */ - component(name: string, options: IComponentOptions): IModule; - /** - * Use this method to register work which needs to be performed on module loading. - * - * @param configFn Execute this function on module load. Useful for service configuration. - */ - config(configFn: Function): IModule; - /** - * Use this method to register work which needs to be performed on module loading. - * - * @param inlineAnnotatedFunction Execute this function on module load. Useful for service configuration. - */ - config(inlineAnnotatedFunction: any[]): IModule; - config(object: Object): IModule; - /** - * Register a constant service, such as a string, a number, an array, an object or a function, with the $injector. Unlike value it can be injected into a module configuration function (see config) and it cannot be overridden by an Angular decorator. - * - * @param name The name of the constant. - * @param value The constant value. - */ - constant(name: string, value: T): IModule; - constant(object: Object): IModule; - /** - * The $controller service is used by Angular to create new controllers. - * - * This provider allows controller registration via the register method. - * - * @param name Controller name, or an object map of controllers where the keys are the names and the values are the constructors. - * @param controllerConstructor Controller constructor fn (optionally decorated with DI annotations in the array notation). - */ - controller(name: string, controllerConstructor: Function): IModule; - /** - * The $controller service is used by Angular to create new controllers. - * - * This provider allows controller registration via the register method. - * - * @param name Controller name, or an object map of controllers where the keys are the names and the values are the constructors. - * @param controllerConstructor Controller constructor fn (optionally decorated with DI annotations in the array notation). - */ - controller(name: string, inlineAnnotatedConstructor: any[]): IModule; - controller(object: Object): IModule; - /** - * Register a new directive with the compiler. - * - * @param name Name of the directive in camel-case (i.e. ngBind which will match as ng-bind) - * @param directiveFactory An injectable directive factory function. - */ - directive(name: string, directiveFactory: IDirectiveFactory): IModule; - /** - * Register a new directive with the compiler. - * - * @param name Name of the directive in camel-case (i.e. ngBind which will match as ng-bind) - * @param directiveFactory An injectable directive factory function. - */ - directive(name: string, inlineAnnotatedFunction: any[]): IModule; - directive(object: Object): IModule; - /** - * Register a service factory, which will be called to return the service instance. This is short for registering a service where its provider consists of only a $get property, which is the given service factory function. You should use $provide.factory(getFn) if you do not need to configure your service in a provider. - * - * @param name The name of the instance. - * @param $getFn The $getFn for the instance creation. Internally this is a short hand for $provide.provider(name, {$get: $getFn}). - */ - factory(name: string, $getFn: Function): IModule; - /** - * Register a service factory, which will be called to return the service instance. This is short for registering a service where its provider consists of only a $get property, which is the given service factory function. You should use $provide.factory(getFn) if you do not need to configure your service in a provider. - * - * @param name The name of the instance. - * @param inlineAnnotatedFunction The $getFn for the instance creation. Internally this is a short hand for $provide.provider(name, {$get: $getFn}). - */ - factory(name: string, inlineAnnotatedFunction: any[]): IModule; - factory(object: Object): IModule; - filter(name: string, filterFactoryFunction: Function): IModule; - filter(name: string, inlineAnnotatedFunction: any[]): IModule; - filter(object: Object): IModule; - provider(name: string, serviceProviderFactory: IServiceProviderFactory): IModule; - provider(name: string, serviceProviderConstructor: IServiceProviderClass): IModule; - provider(name: string, inlineAnnotatedConstructor: any[]): IModule; - provider(name: string, providerObject: IServiceProvider): IModule; - provider(object: Object): IModule; - /** - * Run blocks are the closest thing in Angular to the main method. A run block is the code which needs to run to kickstart the application. It is executed after all of the service have been configured and the injector has been created. Run blocks typically contain code which is hard to unit-test, and for this reason should be declared in isolated modules, so that they can be ignored in the unit-tests. - */ - run(initializationFunction: Function): IModule; - /** - * Run blocks are the closest thing in Angular to the main method. A run block is the code which needs to run to kickstart the application. It is executed after all of the service have been configured and the injector has been created. Run blocks typically contain code which is hard to unit-test, and for this reason should be declared in isolated modules, so that they can be ignored in the unit-tests. - */ - run(inlineAnnotatedFunction: any[]): IModule; - /** - * Register a service constructor, which will be invoked with new to create the service instance. This is short for registering a service where its provider's $get property is a factory function that returns an instance instantiated by the injector from the service constructor function. - * - * @param name The name of the instance. - * @param serviceConstructor An injectable class (constructor function) that will be instantiated. - */ - service(name: string, serviceConstructor: Function): IModule; - /** - * Register a service constructor, which will be invoked with new to create the service instance. This is short for registering a service where its provider's $get property is a factory function that returns an instance instantiated by the injector from the service constructor function. - * - * @param name The name of the instance. - * @param inlineAnnotatedConstructor An injectable class (constructor function) that will be instantiated. - */ - service(name: string, inlineAnnotatedConstructor: any[]): IModule; - service(object: Object): IModule; - /** - * Register a value service with the $injector, such as a string, a number, an array, an object or a function. This is short for registering a service where its provider's $get property is a factory function that takes no arguments and returns the value service. - - Value services are similar to constant services, except that they cannot be injected into a module configuration function (see config) but they can be overridden by an Angular decorator. - * - * @param name The name of the instance. - * @param value The value. - */ - value(name: string, value: T): IModule; - value(object: Object): IModule; - - /** - * Register a service decorator with the $injector. A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service. - * @param name The name of the service to decorate - * @param decorator This function will be invoked when the service needs to be instantiated and should return the decorated service instance. The function is called using the injector.invoke method and is therefore fully injectable. Local injection arguments: $delegate - The original service instance, which can be monkey patched, configured, decorated or delegated to. - */ - decorator(name:string, decoratorConstructor: Function): IModule; - decorator(name:string, inlineAnnotatedConstructor: any[]): IModule; - - // Properties - name: string; - requires: string[]; - } - - /////////////////////////////////////////////////////////////////////////// - // Attributes - // see http://docs.angularjs.org/api/ng.$compile.directive.Attributes - /////////////////////////////////////////////////////////////////////////// - interface IAttributes { - /** - * this is necessary to be able to access the scoped attributes. it's not very elegant - * because you have to use attrs['foo'] instead of attrs.foo but I don't know of a better way - * this should really be limited to return string but it creates this problem: http://stackoverflow.com/q/17201854/165656 - */ - [name: string]: any; - - /** - * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with x- or data-) to its normalized, camelCase form. - * - * Also there is special case for Moz prefix starting with upper case letter. - * - * For further information check out the guide on @see https://docs.angularjs.org/guide/directive#matching-directives - */ - $normalize(name: string): string; - - /** - * Adds the CSS class value specified by the classVal parameter to the - * element. If animations are enabled then an animation will be triggered - * for the class addition. - */ - $addClass(classVal: string): void; - - /** - * Removes the CSS class value specified by the classVal parameter from the - * element. If animations are enabled then an animation will be triggered for - * the class removal. - */ - $removeClass(classVal: string): void; - - /** - * Adds and removes the appropriate CSS class values to the element based on the difference between - * the new and old CSS class values (specified as newClasses and oldClasses). - */ - $updateClass(newClasses: string, oldClasses: string): void; - - /** - * Set DOM element attribute value. - */ - $set(key: string, value: any): void; - - /** - * Observes an interpolated attribute. - * The observer function will be invoked once during the next $digest - * following compilation. The observer is then invoked whenever the - * interpolated value changes. - */ - $observe(name: string, fn: (value?: T) => any): Function; - - /** - * A map of DOM element attribute names to the normalized name. This is needed - * to do reverse lookup from normalized name back to actual name. - */ - $attr: Object; - } - - /** - * form.FormController - type in module ng - * see https://docs.angularjs.org/api/ng/type/form.FormController - */ - interface IFormController { - - /** - * Indexer which should return ng.INgModelController for most properties but cannot because of "All named properties must be assignable to string indexer type" constraint - see https://github.com/Microsoft/TypeScript/issues/272 - */ - [name: string]: any; - - $pristine: boolean; - $dirty: boolean; - $valid: boolean; - $invalid: boolean; - $submitted: boolean; - $error: any; - $pending: any; - $addControl(control: INgModelController | IFormController): void; - $removeControl(control: INgModelController | IFormController): void; - $setValidity(validationErrorKey: string, isValid: boolean, control: INgModelController | IFormController): void; - $setDirty(): void; - $setPristine(): void; - $commitViewValue(): void; - $rollbackViewValue(): void; - $setSubmitted(): void; - $setUntouched(): void; - } - - /////////////////////////////////////////////////////////////////////////// - // NgModelController - // see http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController - /////////////////////////////////////////////////////////////////////////// - interface INgModelController { - $render(): void; - $setValidity(validationErrorKey: string, isValid: boolean): void; - // Documentation states viewValue and modelValue to be a string but other - // types do work and it's common to use them. - $setViewValue(value: any, trigger?: string): void; - $setPristine(): void; - $setDirty(): void; - $validate(): void; - $setTouched(): void; - $setUntouched(): void; - $rollbackViewValue(): void; - $commitViewValue(): void; - $isEmpty(value: any): boolean; - - $viewValue: any; - - $modelValue: any; - - $parsers: IModelParser[]; - $formatters: IModelFormatter[]; - $viewChangeListeners: IModelViewChangeListener[]; - $error: any; - $name: string; - - $touched: boolean; - $untouched: boolean; - - $validators: IModelValidators; - $asyncValidators: IAsyncModelValidators; - - $pending: any; - $pristine: boolean; - $dirty: boolean; - $valid: boolean; - $invalid: boolean; - } - - //Allows tuning how model updates are done. - //https://docs.angularjs.org/api/ng/directive/ngModelOptions - interface INgModelOptions { - updateOn?: string; - debounce?: any; - allowInvalid?: boolean; - getterSetter?: boolean; - timezone?: string; - } - - interface IModelValidators { - /** - * viewValue is any because it can be an object that is called in the view like $viewValue.name:$viewValue.subName - */ - [index: string]: (modelValue: any, viewValue: any) => boolean; - } - - interface IAsyncModelValidators { - [index: string]: (modelValue: any, viewValue: any) => IPromise; - } - - interface IModelParser { - (value: any): any; - } - - interface IModelFormatter { - (value: any): any; - } - - interface IModelViewChangeListener { - (): void; - } - - /** - * $rootScope - $rootScopeProvider - service in module ng - * see https://docs.angularjs.org/api/ng/type/$rootScope.Scope and https://docs.angularjs.org/api/ng/service/$rootScope - */ - interface IRootScopeService { - [index: string]: any; - - $apply(): any; - $apply(exp: string): any; - $apply(exp: (scope: IScope) => any): any; - - $applyAsync(): any; - $applyAsync(exp: string): any; - $applyAsync(exp: (scope: IScope) => any): any; - - /** - * Dispatches an event name downwards to all child scopes (and their children) notifying the registered $rootScope.Scope listeners. - * - * The event life cycle starts at the scope on which $broadcast was called. All listeners listening for name event on this scope get notified. Afterwards, the event propagates to all direct and indirect scopes of the current scope and calls all registered listeners along the way. The event cannot be canceled. - * - * Any exception emitted from the listeners will be passed onto the $exceptionHandler service. - * - * @param name Event name to broadcast. - * @param args Optional one or more arguments which will be passed onto the event listeners. - */ - $broadcast(name: string, ...args: any[]): IAngularEvent; - $destroy(): void; - $digest(): void; - /** - * Dispatches an event name upwards through the scope hierarchy notifying the registered $rootScope.Scope listeners. - * - * The event life cycle starts at the scope on which $emit was called. All listeners listening for name event on this scope get notified. Afterwards, the event traverses upwards toward the root scope and calls all registered listeners along the way. The event will stop propagating if one of the listeners cancels it. - * - * Any exception emitted from the listeners will be passed onto the $exceptionHandler service. - * - * @param name Event name to emit. - * @param args Optional one or more arguments which will be passed onto the event listeners. - */ - $emit(name: string, ...args: any[]): IAngularEvent; - - $eval(): any; - $eval(expression: string, locals?: Object): any; - $eval(expression: (scope: IScope) => any, locals?: Object): any; - - $evalAsync(): void; - $evalAsync(expression: string): void; - $evalAsync(expression: (scope: IScope) => any): void; - - // Defaults to false by the implementation checking strategy - $new(isolate?: boolean, parent?: IScope): IScope; - - /** - * Listens on events of a given type. See $emit for discussion of event life cycle. - * - * The event listener function format is: function(event, args...). - * - * @param name Event name to listen on. - * @param listener Function to call when the event is emitted. - */ - $on(name: string, listener: (event: IAngularEvent, ...args: any[]) => any): () => void; - - $watch(watchExpression: string, listener?: string, objectEquality?: boolean): () => void; - $watch(watchExpression: string, listener?: (newValue: T, oldValue: T, scope: IScope) => any, objectEquality?: boolean): () => void; - $watch(watchExpression: (scope: IScope) => any, listener?: string, objectEquality?: boolean): () => void; - $watch(watchExpression: (scope: IScope) => T, listener?: (newValue: T, oldValue: T, scope: IScope) => any, objectEquality?: boolean): () => void; - - $watchCollection(watchExpression: string, listener: (newValue: T, oldValue: T, scope: IScope) => any): () => void; - $watchCollection(watchExpression: (scope: IScope) => T, listener: (newValue: T, oldValue: T, scope: IScope) => any): () => void; - - $watchGroup(watchExpressions: any[], listener: (newValue: any, oldValue: any, scope: IScope) => any): () => void; - $watchGroup(watchExpressions: { (scope: IScope): any }[], listener: (newValue: any, oldValue: any, scope: IScope) => any): () => void; - - $parent: IScope; - $root: IRootScopeService; - $id: number; - - // Hidden members - $$isolateBindings: any; - $$phase: any; - } - - interface IScope extends IRootScopeService { } - - /** - * $scope for ngRepeat directive. - * see https://docs.angularjs.org/api/ng/directive/ngRepeat - */ - interface IRepeatScope extends IScope { - - /** - * iterator offset of the repeated element (0..length-1). - */ - $index: number; - - /** - * true if the repeated element is first in the iterator. - */ - $first: boolean; - - /** - * true if the repeated element is between the first and last in the iterator. - */ - $middle: boolean; - - /** - * true if the repeated element is last in the iterator. - */ - $last: boolean; - - /** - * true if the iterator position $index is even (otherwise false). - */ - $even: boolean; - - /** - * true if the iterator position $index is odd (otherwise false). - */ - $odd: boolean; - - } - - interface IAngularEvent { - /** - * the scope on which the event was $emit-ed or $broadcast-ed. - */ - targetScope: IScope; - /** - * the scope that is currently handling the event. Once the event propagates through the scope hierarchy, this property is set to null. - */ - currentScope: IScope; - /** - * name of the event. - */ - name: string; - /** - * calling stopPropagation function will cancel further event propagation (available only for events that were $emit-ed). - */ - stopPropagation?: Function; - /** - * calling preventDefault sets defaultPrevented flag to true. - */ - preventDefault: Function; - /** - * true if preventDefault was called. - */ - defaultPrevented: boolean; - } - - /////////////////////////////////////////////////////////////////////////// - // WindowService - // see http://docs.angularjs.org/api/ng.$window - /////////////////////////////////////////////////////////////////////////// - interface IWindowService extends Window { - [key: string]: any; - } - - /////////////////////////////////////////////////////////////////////////// - // TimeoutService - // see http://docs.angularjs.org/api/ng.$timeout - /////////////////////////////////////////////////////////////////////////// - interface ITimeoutService { - (delay?: number, invokeApply?: boolean): IPromise; - (fn: (...args: any[]) => T, delay?: number, invokeApply?: boolean, ...args: any[]): IPromise; - cancel(promise?: IPromise): boolean; - } - - /////////////////////////////////////////////////////////////////////////// - // IntervalService - // see http://docs.angularjs.org/api/ng.$interval - /////////////////////////////////////////////////////////////////////////// - interface IIntervalService { - (func: Function, delay: number, count?: number, invokeApply?: boolean, ...args: any[]): IPromise; - cancel(promise: IPromise): boolean; - } - - /** - * $filter - $filterProvider - service in module ng - * - * Filters are used for formatting data displayed to the user. - * - * see https://docs.angularjs.org/api/ng/service/$filter - */ - interface IFilterService { - (name: 'filter'): IFilterFilter; - (name: 'currency'): IFilterCurrency; - (name: 'number'): IFilterNumber; - (name: 'date'): IFilterDate; - (name: 'json'): IFilterJson; - (name: 'lowercase'): IFilterLowercase; - (name: 'uppercase'): IFilterUppercase; - (name: 'limitTo'): IFilterLimitTo; - (name: 'orderBy'): IFilterOrderBy; - /** - * Usage: - * $filter(name); - * - * @param name Name of the filter function to retrieve - */ - (name: string): T; - } - - interface IFilterFilter { - (array: T[], expression: string | IFilterFilterPatternObject | IFilterFilterPredicateFunc, comparator?: IFilterFilterComparatorFunc|boolean): T[]; - } - - interface IFilterFilterPatternObject { - [name: string]: any; - } - - interface IFilterFilterPredicateFunc { - (value: T, index: number, array: T[]): boolean; - } - - interface IFilterFilterComparatorFunc { - (actual: T, expected: T): boolean; - } - - interface IFilterCurrency { - /** - * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default symbol for current locale is used. - * @param amount Input to filter. - * @param symbol Currency symbol or identifier to be displayed. - * @param fractionSize Number of decimal places to round the amount to, defaults to default max fraction size for current locale - * @return Formatted number - */ - (amount: number, symbol?: string, fractionSize?: number): string; - } - - interface IFilterNumber { - /** - * Formats a number as text. - * @param number Number to format. - * @param fractionSize Number of decimal places to round the number to. If this is not provided then the fraction size is computed from the current locale's number formatting pattern. In the case of the default locale, it will be 3. - * @return Number rounded to decimalPlaces and places a “,” after each third digit. - */ - (value: number|string, fractionSize?: number|string): string; - } - - interface IFilterDate { - /** - * Formats date to a string based on the requested format. - * - * @param date Date to format either as Date object, milliseconds (string or number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is specified in the string input, the time is considered to be in the local timezone. - * @param format Formatting rules (see Description). If not specified, mediumDate is used. - * @param timezone Timezone to be used for formatting. It understands UTC/GMT and the continental US time zone abbreviations, but for general use, use a time zone offset, for example, '+0430' (4 hours, 30 minutes east of the Greenwich meridian) If not specified, the timezone of the browser will be used. - * @return Formatted string or the input if input is not recognized as date/millis. - */ - (date: Date | number | string, format?: string, timezone?: string): string; - } - - interface IFilterJson { - /** - * Allows you to convert a JavaScript object into JSON string. - * @param object Any JavaScript object (including arrays and primitive types) to filter. - * @param spacing The number of spaces to use per indentation, defaults to 2. - * @return JSON string. - */ - (object: any, spacing?: number): string; - } - - interface IFilterLowercase { - /** - * Converts string to lowercase. - */ - (value: string): string; - } - - interface IFilterUppercase { - /** - * Converts string to uppercase. - */ - (value: string): string; - } - - interface IFilterLimitTo { - /** - * Creates a new array containing only a specified number of elements. The elements are taken from either the beginning or the end of the source array, string or number, as specified by the value and sign (positive or negative) of limit. - * @param input Source array to be limited. - * @param limit The length of the returned array. If the limit number is positive, limit number of items from the beginning of the source array/string are copied. If the number is negative, limit number of items from the end of the source array are copied. The limit will be trimmed if it exceeds array.length. If limit is undefined, the input will be returned unchanged. - * @param begin Index at which to begin limitation. As a negative index, begin indicates an offset from the end of input. Defaults to 0. - * @return A new sub-array of length limit or less if input array had less than limit elements. - */ - (input: T[], limit: string|number, begin?: string|number): T[]; - /** - * Creates a new string containing only a specified number of elements. The elements are taken from either the beginning or the end of the source string or number, as specified by the value and sign (positive or negative) of limit. If a number is used as input, it is converted to a string. - * @param input Source string or number to be limited. - * @param limit The length of the returned string. If the limit number is positive, limit number of items from the beginning of the source string are copied. If the number is negative, limit number of items from the end of the source string are copied. The limit will be trimmed if it exceeds input.length. If limit is undefined, the input will be returned unchanged. - * @param begin Index at which to begin limitation. As a negative index, begin indicates an offset from the end of input. Defaults to 0. - * @return A new substring of length limit or less if input had less than limit elements. - */ - (input: string|number, limit: string|number, begin?: string|number): string; - } - - interface IFilterOrderBy { - /** - * Orders a specified array by the expression predicate. It is ordered alphabetically for strings and numerically for numbers. Note: if you notice numbers are not being sorted as expected, make sure they are actually being saved as numbers and not strings. - * @param array The array to sort. - * @param expression A predicate to be used by the comparator to determine the order of elements. - * @param reverse Reverse the order of the array. - * @return Reverse the order of the array. - */ - (array: T[], expression: string|((value: T) => any)|(((value: T) => any)|string)[], reverse?: boolean): T[]; - } - - /** - * $filterProvider - $filter - provider in module ng - * - * Filters are just functions which transform input to an output. However filters need to be Dependency Injected. To achieve this a filter definition consists of a factory function which is annotated with dependencies and is responsible for creating a filter function. - * - * see https://docs.angularjs.org/api/ng/provider/$filterProvider - */ - interface IFilterProvider extends IServiceProvider { - /** - * register(name); - * - * @param name Name of the filter function, or an object map of filters where the keys are the filter names and the values are the filter factories. Note: Filter names must be valid angular Expressions identifiers, such as uppercase or orderBy. Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace your filters, then you can use capitalization (myappSubsectionFilterx) or underscores (myapp_subsection_filterx). - */ - register(name: string | {}): IServiceProvider; - } - - /////////////////////////////////////////////////////////////////////////// - // LocaleService - // see http://docs.angularjs.org/api/ng.$locale - /////////////////////////////////////////////////////////////////////////// - interface ILocaleService { - id: string; - - // These are not documented - // Check angular's i18n files for exemples - NUMBER_FORMATS: ILocaleNumberFormatDescriptor; - DATETIME_FORMATS: ILocaleDateTimeFormatDescriptor; - pluralCat: (num: any) => string; - } - - interface ILocaleNumberFormatDescriptor { - DECIMAL_SEP: string; - GROUP_SEP: string; - PATTERNS: ILocaleNumberPatternDescriptor[]; - CURRENCY_SYM: string; - } - - interface ILocaleNumberPatternDescriptor { - minInt: number; - minFrac: number; - maxFrac: number; - posPre: string; - posSuf: string; - negPre: string; - negSuf: string; - gSize: number; - lgSize: number; - } - - interface ILocaleDateTimeFormatDescriptor { - MONTH: string[]; - SHORTMONTH: string[]; - DAY: string[]; - SHORTDAY: string[]; - AMPMS: string[]; - medium: string; - short: string; - fullDate: string; - longDate: string; - mediumDate: string; - shortDate: string; - mediumTime: string; - shortTime: string; - } - - /////////////////////////////////////////////////////////////////////////// - // LogService - // see http://docs.angularjs.org/api/ng.$log - // see http://docs.angularjs.org/api/ng.$logProvider - /////////////////////////////////////////////////////////////////////////// - interface ILogService { - debug: ILogCall; - error: ILogCall; - info: ILogCall; - log: ILogCall; - warn: ILogCall; - } - - interface ILogProvider extends IServiceProvider { - debugEnabled(): boolean; - debugEnabled(enabled: boolean): ILogProvider; - } - - // We define this as separate interface so we can reopen it later for - // the ngMock module. - interface ILogCall { - (...args: any[]): void; - } - - /////////////////////////////////////////////////////////////////////////// - // ParseService - // see http://docs.angularjs.org/api/ng.$parse - // see http://docs.angularjs.org/api/ng.$parseProvider - /////////////////////////////////////////////////////////////////////////// - interface IParseService { - (expression: string): ICompiledExpression; - } - - interface IParseProvider { - logPromiseWarnings(): boolean; - logPromiseWarnings(value: boolean): IParseProvider; - - unwrapPromises(): boolean; - unwrapPromises(value: boolean): IParseProvider; - } - - interface ICompiledExpression { - (context: any, locals?: any): any; - - literal: boolean; - constant: boolean; - - // If value is not provided, undefined is gonna be used since the implementation - // does not check the parameter. Let's force a value for consistency. If consumer - // whants to undefine it, pass the undefined value explicitly. - assign(context: any, value: any): any; - } - - /** - * $location - $locationProvider - service in module ng - * see https://docs.angularjs.org/api/ng/service/$location - */ - interface ILocationService { - absUrl(): string; - hash(): string; - hash(newHash: string): ILocationService; - host(): string; - - /** - * Return path of current url - */ - path(): string; - - /** - * Change path when called with parameter and return $location. - * Note: Path should always begin with forward slash (/), this method will add the forward slash if it is missing. - * - * @param path New path - */ - path(path: string): ILocationService; - - port(): number; - protocol(): string; - replace(): ILocationService; - - /** - * Return search part (as object) of current url - */ - search(): any; - - /** - * Change search part when called with parameter and return $location. - * - * @param search When called with a single argument the method acts as a setter, setting the search component of $location to the specified value. - * - * If the argument is a hash object containing an array of values, these values will be encoded as duplicate search parameters in the url. - */ - search(search: any): ILocationService; - - /** - * Change search part when called with parameter and return $location. - * - * @param search New search params - * @param paramValue If search is a string or a Number, then paramValue will override only a single search property. If paramValue is null, the property specified via the first argument will be deleted. If paramValue is an array, it will override the property of the search component of $location specified via the first argument. If paramValue is true, the property specified via the first argument will be added with no value nor trailing equal sign. - */ - search(search: string, paramValue: string|number|string[]|boolean): ILocationService; - - state(): any; - state(state: any): ILocationService; - url(): string; - url(url: string): ILocationService; - } - - interface ILocationProvider extends IServiceProvider { - hashPrefix(): string; - hashPrefix(prefix: string): ILocationProvider; - html5Mode(): boolean; - - // Documentation states that parameter is string, but - // implementation tests it as boolean, which makes more sense - // since this is a toggler - html5Mode(active: boolean): ILocationProvider; - html5Mode(mode: { enabled?: boolean; requireBase?: boolean; rewriteLinks?: boolean; }): ILocationProvider; - } - - /////////////////////////////////////////////////////////////////////////// - // DocumentService - // see http://docs.angularjs.org/api/ng.$document - /////////////////////////////////////////////////////////////////////////// - interface IDocumentService extends IAugmentedJQuery {} - - /////////////////////////////////////////////////////////////////////////// - // ExceptionHandlerService - // see http://docs.angularjs.org/api/ng.$exceptionHandler - /////////////////////////////////////////////////////////////////////////// - interface IExceptionHandlerService { - (exception: Error, cause?: string): void; - } - - /////////////////////////////////////////////////////////////////////////// - // RootElementService - // see http://docs.angularjs.org/api/ng.$rootElement - /////////////////////////////////////////////////////////////////////////// - interface IRootElementService extends JQuery {} - - interface IQResolveReject { - (): void; - (value: T): void; - } - /** - * $q - service in module ng - * A promise/deferred implementation inspired by Kris Kowal's Q. - * See http://docs.angularjs.org/api/ng/service/$q - */ - interface IQService { - new (resolver: (resolve: IQResolveReject) => any): IPromise; - new (resolver: (resolve: IQResolveReject, reject: IQResolveReject) => any): IPromise; - (resolver: (resolve: IQResolveReject) => any): IPromise; - (resolver: (resolve: IQResolveReject, reject: IQResolveReject) => any): IPromise; - - /** - * Combines multiple promises into a single promise that is resolved when all of the input promises are resolved. - * - * Returns a single promise that will be resolved with an array of values, each value corresponding to the promise at the same index in the promises array. If any of the promises is resolved with a rejection, this resulting promise will be rejected with the same rejection value. - * - * @param promises An array of promises. - */ - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise, T8 | IPromise, T9 | IPromise, T10 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise, T8 | IPromise, T9 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise, T8 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7, T8]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise]): IPromise<[T1, T2, T3, T4, T5]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise ]): IPromise<[T1, T2, T3, T4]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise]): IPromise<[T1, T2, T3]>; - all(values: [T1 | IPromise, T2 | IPromise]): IPromise<[T1, T2]>; - all(promises: IPromise[]): IPromise; - /** - * Combines multiple promises into a single promise that is resolved when all of the input promises are resolved. - * - * Returns a single promise that will be resolved with a hash of values, each value corresponding to the promise at the same key in the promises hash. If any of the promises is resolved with a rejection, this resulting promise will be rejected with the same rejection value. - * - * @param promises A hash of promises. - */ - all(promises: { [id: string]: IPromise; }): IPromise<{ [id: string]: any; }>; - all(promises: { [id: string]: IPromise; }): IPromise; - /** - * Creates a Deferred object which represents a task which will finish in the future. - */ - defer(): IDeferred; - /** - * Creates a promise that is resolved as rejected with the specified reason. This api should be used to forward rejection in a chain of promises. If you are dealing with the last promise in a promise chain, you don't need to worry about it. - * - * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of reject as the throw keyword in JavaScript. This also means that if you "catch" an error via a promise error callback and you want to forward the error to the promise derived from the current promise, you have to "rethrow" the error by returning a rejection constructed via reject. - * - * @param reason Constant, message, exception or an object representing the rejection reason. - */ - reject(reason?: any): IPromise; - /** - * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. - * - * @param value Value or a promise - */ - resolve(value: IPromise|T): IPromise; - /** - * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. - */ - resolve(): IPromise; - /** - * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. - * - * @param value Value or a promise - */ - when(value: IPromise|T): IPromise; - /** - * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. - */ - when(): IPromise; - } - - interface IPromise { - /** - * Regardless of when the promise was or will be resolved or rejected, then calls one of the success or error callbacks asynchronously as soon as the result is available. The callbacks are called with a single argument: the result or rejection reason. Additionally, the notify callback may be called zero or more times to provide a progress indication, before the promise is resolved or rejected. - * The successCallBack may return IPromise for when a $q.reject() needs to be returned - * This method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback. It also notifies via the return value of the notifyCallback method. The promise can not be resolved or rejected from the notifyCallback method. - */ - then(successCallback: (promiseValue: T) => IPromise|TResult, errorCallback?: (reason: any) => any, notifyCallback?: (state: any) => any): IPromise; - - /** - * Shorthand for promise.then(null, errorCallback) - */ - catch(onRejected: (reason: any) => IPromise|TResult): IPromise; - - /** - * Allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful to release resources or do some clean-up that needs to be done whether the promise was rejected or resolved. See the full specification for more information. - * - * Because finally is a reserved word in JavaScript and reserved keywords are not supported as property names by ES3, you'll need to invoke the method like promise['finally'](callback) to make your code IE8 and Android 2.x compatible. - */ - finally(finallyCallback: () => any): IPromise; - } - - interface IDeferred { - resolve(value?: T|IPromise): void; - reject(reason?: any): void; - notify(state?: any): void; - promise: IPromise; - } - - /////////////////////////////////////////////////////////////////////////// - // AnchorScrollService - // see http://docs.angularjs.org/api/ng.$anchorScroll - /////////////////////////////////////////////////////////////////////////// - interface IAnchorScrollService { - (): void; - (hash: string): void; - yOffset: any; - } - - interface IAnchorScrollProvider extends IServiceProvider { - disableAutoScrolling(): void; - } - - /** - * $cacheFactory - service in module ng - * - * Factory that constructs Cache objects and gives access to them. - * - * see https://docs.angularjs.org/api/ng/service/$cacheFactory - */ - interface ICacheFactoryService { - /** - * Factory that constructs Cache objects and gives access to them. - * - * @param cacheId Name or id of the newly created cache. - * @param optionsMap Options object that specifies the cache behavior. Properties: - * - * capacity — turns the cache into LRU cache. - */ - (cacheId: string, optionsMap?: { capacity?: number; }): ICacheObject; - - /** - * Get information about all the caches that have been created. - * @returns key-value map of cacheId to the result of calling cache#info - */ - info(): any; - - /** - * Get access to a cache object by the cacheId used when it was created. - * - * @param cacheId Name or id of a cache to access. - */ - get(cacheId: string): ICacheObject; - } - - /** - * $cacheFactory.Cache - type in module ng - * - * A cache object used to store and retrieve data, primarily used by $http and the script directive to cache templates and other data. - * - * see https://docs.angularjs.org/api/ng/type/$cacheFactory.Cache - */ - interface ICacheObject { - /** - * Retrieve information regarding a particular Cache. - */ - info(): { - /** - * the id of the cache instance - */ - id: string; - - /** - * the number of entries kept in the cache instance - */ - size: number; - - //...: any additional properties from the options object when creating the cache. - }; - - /** - * Inserts a named entry into the Cache object to be retrieved later, and incrementing the size of the cache if the key was not already present in the cache. If behaving like an LRU cache, it will also remove stale entries from the set. - * - * It will not insert undefined values into the cache. - * - * @param key the key under which the cached data is stored. - * @param value the value to store alongside the key. If it is undefined, the key will not be stored. - */ - put(key: string, value?: T): T; - - /** - * Retrieves named data stored in the Cache object. - * - * @param key the key of the data to be retrieved - */ - get(key: string): T; - - /** - * Removes an entry from the Cache object. - * - * @param key the key of the entry to be removed - */ - remove(key: string): void; - - /** - * Clears the cache object of any entries. - */ - removeAll(): void; - - /** - * Destroys the Cache object entirely, removing it from the $cacheFactory set. - */ - destroy(): void; - } - - /////////////////////////////////////////////////////////////////////////// - // CompileService - // see http://docs.angularjs.org/api/ng.$compile - // see http://docs.angularjs.org/api/ng.$compileProvider - /////////////////////////////////////////////////////////////////////////// - interface ICompileService { - (element: string, transclude?: ITranscludeFunction, maxPriority?: number): ITemplateLinkingFunction; - (element: Element, transclude?: ITranscludeFunction, maxPriority?: number): ITemplateLinkingFunction; - (element: JQuery, transclude?: ITranscludeFunction, maxPriority?: number): ITemplateLinkingFunction; - } - - interface ICompileProvider extends IServiceProvider { - directive(name: string, directiveFactory: Function): ICompileProvider; - directive(directivesMap: Object, directiveFactory: Function): ICompileProvider; - directive(name: string, inlineAnnotatedFunction: any[]): ICompileProvider; - directive(directivesMap: Object, inlineAnnotatedFunction: any[]): ICompileProvider; - - // Undocumented, but it is there... - directive(directivesMap: any): ICompileProvider; - - component(name: string, options: IComponentOptions): ICompileProvider; - - aHrefSanitizationWhitelist(): RegExp; - aHrefSanitizationWhitelist(regexp: RegExp): ICompileProvider; - - imgSrcSanitizationWhitelist(): RegExp; - imgSrcSanitizationWhitelist(regexp: RegExp): ICompileProvider; - - debugInfoEnabled(enabled?: boolean): any; - } - - interface ICloneAttachFunction { - // Let's hint but not force cloneAttachFn's signature - (clonedElement?: JQuery, scope?: IScope): any; - } - - // This corresponds to the "publicLinkFn" returned by $compile. - interface ITemplateLinkingFunction { - (scope: IScope, cloneAttachFn?: ICloneAttachFunction): IAugmentedJQuery; - } - - // This corresponds to $transclude (and also the transclude function passed to link). - interface ITranscludeFunction { - // If the scope is provided, then the cloneAttachFn must be as well. - (scope: IScope, cloneAttachFn: ICloneAttachFunction): IAugmentedJQuery; - // If one argument is provided, then it's assumed to be the cloneAttachFn. - (cloneAttachFn?: ICloneAttachFunction): IAugmentedJQuery; - } - - /////////////////////////////////////////////////////////////////////////// - // ControllerService - // see http://docs.angularjs.org/api/ng.$controller - // see http://docs.angularjs.org/api/ng.$controllerProvider - /////////////////////////////////////////////////////////////////////////// - interface IControllerService { - // Although the documentation doesn't state this, locals are optional - (controllerConstructor: new (...args: any[]) => T, locals?: any, later?: boolean, ident?: string): T; - (controllerConstructor: Function, locals?: any, later?: boolean, ident?: string): T; - (controllerName: string, locals?: any, later?: boolean, ident?: string): T; - } - - interface IControllerProvider extends IServiceProvider { - register(name: string, controllerConstructor: Function): void; - register(name: string, dependencyAnnotatedConstructor: any[]): void; - allowGlobals(): void; - } - - /** - * xhrFactory - * Replace or decorate this service to create your own custom XMLHttpRequest objects. - * see https://docs.angularjs.org/api/ng/service/$xhrFactory - */ - interface IXhrFactory { - (method: string, url: string): T; - } - - /** - * HttpService - * see http://docs.angularjs.org/api/ng/service/$http - */ - interface IHttpService { - /** - * Object describing the request to be made and how it should be processed. - */ - (config: IRequestConfig): IHttpPromise; - - /** - * Shortcut method to perform GET request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param config Optional configuration object - */ - get(url: string, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform DELETE request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param config Optional configuration object - */ - delete(url: string, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform HEAD request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param config Optional configuration object - */ - head(url: string, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform JSONP request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param config Optional configuration object - */ - jsonp(url: string, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform POST request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param data Request content - * @param config Optional configuration object - */ - post(url: string, data: any, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform PUT request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param data Request content - * @param config Optional configuration object - */ - put(url: string, data: any, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform PATCH request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param data Request content - * @param config Optional configuration object - */ - patch(url: string, data: any, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Runtime equivalent of the $httpProvider.defaults property. Allows configuration of default headers, withCredentials as well as request and response transformations. - */ - defaults: IHttpProviderDefaults; - - /** - * Array of config objects for currently pending requests. This is primarily meant to be used for debugging purposes. - */ - pendingRequests: IRequestConfig[]; - } - - /** - * Object describing the request to be made and how it should be processed. - * see http://docs.angularjs.org/api/ng/service/$http#usage - */ - interface IRequestShortcutConfig extends IHttpProviderDefaults { - /** - * {Object.} - * Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified. - */ - params?: any; - - /** - * {string|Object} - * Data to be sent as the request message data. - */ - data?: any; - - /** - * Timeout in milliseconds, or promise that should abort the request when resolved. - */ - timeout?: number|IPromise; - - /** - * See [XMLHttpRequest.responseType]https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype - */ - responseType?: string; - } - - /** - * Object describing the request to be made and how it should be processed. - * see http://docs.angularjs.org/api/ng/service/$http#usage - */ - interface IRequestConfig extends IRequestShortcutConfig { - /** - * HTTP method (e.g. 'GET', 'POST', etc) - */ - method: string; - /** - * Absolute or relative URL of the resource that is being requested. - */ - url: string; - } - - interface IHttpHeadersGetter { - (): { [name: string]: string; }; - (headerName: string): string; - } - - interface IHttpPromiseCallback { - (data: T, status: number, headers: IHttpHeadersGetter, config: IRequestConfig): void; - } - - interface IHttpPromiseCallbackArg { - data?: T; - status?: number; - headers?: IHttpHeadersGetter; - config?: IRequestConfig; - statusText?: string; - } - - interface IHttpPromise extends IPromise> { - /** - * The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. - * If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error. - * @deprecated - */ - success?(callback: IHttpPromiseCallback): IHttpPromise; - /** - * The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. - * If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error. - * @deprecated - */ - error?(callback: IHttpPromiseCallback): IHttpPromise; - } - - // See the jsdoc for transformData() at https://github.com/angular/angular.js/blob/master/src/ng/http.js#L228 - interface IHttpRequestTransformer { - (data: any, headersGetter: IHttpHeadersGetter): any; - } - - // The definition of fields are the same as IHttpPromiseCallbackArg - interface IHttpResponseTransformer { - (data: any, headersGetter: IHttpHeadersGetter, status: number): any; - } - - type HttpHeaderType = {[requestType: string]:string|((config:IRequestConfig) => string)}; - - interface IHttpRequestConfigHeaders { - [requestType: string]: any; - common?: any; - get?: any; - post?: any; - put?: any; - patch?: any; - } - - /** - * Object that controls the defaults for $http provider. Not all fields of IRequestShortcutConfig can be configured - * via defaults and the docs do not say which. The following is based on the inspection of the source code. - * https://docs.angularjs.org/api/ng/service/$http#defaults - * https://docs.angularjs.org/api/ng/service/$http#usage - * https://docs.angularjs.org/api/ng/provider/$httpProvider The properties section - */ - interface IHttpProviderDefaults { - /** - * {boolean|Cache} - * If true, a default $http cache will be used to cache the GET request, otherwise if a cache instance built with $cacheFactory, this cache will be used for caching. - */ - cache?: any; - - /** - * Transform function or an array of such functions. The transform function takes the http request body and - * headers and returns its transformed (typically serialized) version. - * @see {@link https://docs.angularjs.org/api/ng/service/$http#transforming-requests-and-responses} - */ - transformRequest?: IHttpRequestTransformer |IHttpRequestTransformer[]; - - /** - * Transform function or an array of such functions. The transform function takes the http response body and - * headers and returns its transformed (typically deserialized) version. - */ - transformResponse?: IHttpResponseTransformer | IHttpResponseTransformer[]; - - /** - * Map of strings or functions which return strings representing HTTP headers to send to the server. If the - * return value of a function is null, the header will not be sent. - * The key of the map is the request verb in lower case. The "common" key applies to all requests. - * @see {@link https://docs.angularjs.org/api/ng/service/$http#setting-http-headers} - */ - headers?: IHttpRequestConfigHeaders; - - /** Name of HTTP header to populate with the XSRF token. */ - xsrfHeaderName?: string; - - /** Name of cookie containing the XSRF token. */ - xsrfCookieName?: string; - - /** - * whether to to set the withCredentials flag on the XHR object. See [requests with credentials]https://developer.mozilla.org/en/http_access_control#section_5 for more information. - */ - withCredentials?: boolean; - - /** - * A function used to the prepare string representation of request parameters (specified as an object). If - * specified as string, it is interpreted as a function registered with the $injector. Defaults to - * $httpParamSerializer. - */ - paramSerializer?: string | ((obj: any) => string); - } - - interface IHttpInterceptor { - request?: (config: IRequestConfig) => IRequestConfig|IPromise; - requestError?: (rejection: any) => any; - response?: (response: IHttpPromiseCallbackArg) => IPromise>|IHttpPromiseCallbackArg; - responseError?: (rejection: any) => any; - } - - interface IHttpInterceptorFactory { - (...args: any[]): IHttpInterceptor; - } - - interface IHttpProvider extends IServiceProvider { - defaults: IHttpProviderDefaults; - - /** - * Register service factories (names or implementations) for interceptors which are called before and after - * each request. - */ - interceptors: (string|IHttpInterceptorFactory|(string|IHttpInterceptorFactory)[])[]; - useApplyAsync(): boolean; - useApplyAsync(value: boolean): IHttpProvider; - - /** - * - * @param {boolean=} value If true, `$http` will return a normal promise without the `success` and `error` methods. - * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining. - * otherwise, returns the current configured value. - */ - useLegacyPromiseExtensions(value:boolean) : boolean | IHttpProvider; - } - - /////////////////////////////////////////////////////////////////////////// - // HttpBackendService - // see http://docs.angularjs.org/api/ng.$httpBackend - // You should never need to use this service directly. - /////////////////////////////////////////////////////////////////////////// - interface IHttpBackendService { - // XXX Perhaps define callback signature in the future - (method: string, url: string, post?: any, callback?: Function, headers?: any, timeout?: number, withCredentials?: boolean): void; - } - - /////////////////////////////////////////////////////////////////////////// - // InterpolateService - // see http://docs.angularjs.org/api/ng.$interpolate - // see http://docs.angularjs.org/api/ng.$interpolateProvider - /////////////////////////////////////////////////////////////////////////// - interface IInterpolateService { - (text: string, mustHaveExpression?: boolean, trustedContext?: string, allOrNothing?: boolean): IInterpolationFunction; - endSymbol(): string; - startSymbol(): string; - } - - interface IInterpolationFunction { - (context: any): string; - } - - interface IInterpolateProvider extends IServiceProvider { - startSymbol(): string; - startSymbol(value: string): IInterpolateProvider; - endSymbol(): string; - endSymbol(value: string): IInterpolateProvider; - } - - /////////////////////////////////////////////////////////////////////////// - // TemplateCacheService - // see http://docs.angularjs.org/api/ng.$templateCache - /////////////////////////////////////////////////////////////////////////// - interface ITemplateCacheService extends ICacheObject {} - - /////////////////////////////////////////////////////////////////////////// - // SCEService - // see http://docs.angularjs.org/api/ng.$sce - /////////////////////////////////////////////////////////////////////////// - interface ISCEService { - getTrusted(type: string, mayBeTrusted: any): any; - getTrustedCss(value: any): any; - getTrustedHtml(value: any): any; - getTrustedJs(value: any): any; - getTrustedResourceUrl(value: any): any; - getTrustedUrl(value: any): any; - parse(type: string, expression: string): (context: any, locals: any) => any; - parseAsCss(expression: string): (context: any, locals: any) => any; - parseAsHtml(expression: string): (context: any, locals: any) => any; - parseAsJs(expression: string): (context: any, locals: any) => any; - parseAsResourceUrl(expression: string): (context: any, locals: any) => any; - parseAsUrl(expression: string): (context: any, locals: any) => any; - trustAs(type: string, value: any): any; - trustAsHtml(value: any): any; - trustAsJs(value: any): any; - trustAsResourceUrl(value: any): any; - trustAsUrl(value: any): any; - isEnabled(): boolean; - } - - /////////////////////////////////////////////////////////////////////////// - // SCEProvider - // see http://docs.angularjs.org/api/ng.$sceProvider - /////////////////////////////////////////////////////////////////////////// - interface ISCEProvider extends IServiceProvider { - enabled(value: boolean): void; - } - - /////////////////////////////////////////////////////////////////////////// - // SCEDelegateService - // see http://docs.angularjs.org/api/ng.$sceDelegate - /////////////////////////////////////////////////////////////////////////// - interface ISCEDelegateService { - getTrusted(type: string, mayBeTrusted: any): any; - trustAs(type: string, value: any): any; - valueOf(value: any): any; - } - - - /////////////////////////////////////////////////////////////////////////// - // SCEDelegateProvider - // see http://docs.angularjs.org/api/ng.$sceDelegateProvider - /////////////////////////////////////////////////////////////////////////// - interface ISCEDelegateProvider extends IServiceProvider { - resourceUrlBlacklist(blacklist: any[]): void; - resourceUrlWhitelist(whitelist: any[]): void; - resourceUrlBlacklist(): any[]; - resourceUrlWhitelist(): any[]; - } - - /** - * $templateRequest service - * see http://docs.angularjs.org/api/ng/service/$templateRequest - */ - interface ITemplateRequestService { - /** - * Downloads a template using $http and, upon success, stores the - * contents inside of $templateCache. - * - * If the HTTP request fails or the response data of the HTTP request is - * empty then a $compile error will be thrown (unless - * {ignoreRequestError} is set to true). - * - * @param tpl The template URL. - * @param ignoreRequestError Whether or not to ignore the exception - * when the request fails or the template is - * empty. - * - * @return A promise whose value is the template content. - */ - (tpl: string, ignoreRequestError?: boolean): IPromise; - /** - * total amount of pending template requests being downloaded. - * @type {number} - */ - totalPendingRequests: number; - } - - /////////////////////////////////////////////////////////////////////////// - // Component - // see http://angularjs.blogspot.com.br/2015/11/angularjs-15-beta2-and-14-releases.html - // and http://toddmotto.com/exploring-the-angular-1-5-component-method/ - /////////////////////////////////////////////////////////////////////////// - /** - * Runtime representation a type that a Component or other object is instances of. - * - * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by - * the `MyCustomComponent` constructor function. - */ - interface Type extends Function { - } - - /** - * `RouteDefinition` defines a route within a {@link RouteConfig} decorator. - * - * Supported keys: - * - `path` or `aux` (requires exactly one of these) - * - `component`, `loader`, `redirectTo` (requires exactly one of these) - * - `name` or `as` (optional) (requires exactly one of these) - * - `data` (optional) - * - * See also {@link Route}, {@link AsyncRoute}, {@link AuxRoute}, and {@link Redirect}. - */ - interface RouteDefinition { - path?: string; - aux?: string; - component?: Type | ComponentDefinition | string; - loader?: Function; - redirectTo?: any[]; - as?: string; - name?: string; - data?: any; - useAsDefault?: boolean; - } - - /** - * Represents either a component type (`type` is `component`) or a loader function - * (`type` is `loader`). - * - * See also {@link RouteDefinition}. - */ - interface ComponentDefinition { - type: string; - loader?: Function; - component?: Type; - } - - /** - * Component definition object (a simplified directive definition object) - */ - interface IComponentOptions { - /** - * Controller constructor function that should be associated with newly created scope or the name of a registered - * controller if passed as a string. Empty function by default. - * Use the array form to define dependencies (necessary if strictDi is enabled and you require dependency injection) - */ - controller?: string | Function | (string | Function)[]; - /** - * An identifier name for a reference to the controller. If present, the controller will be published to scope under - * the controllerAs name. If not present, this will default to be the same as the component name. - * @default "$ctrl" - */ - controllerAs?: string; - /** - * html template as a string or a function that returns an html template as a string which should be used as the - * contents of this component. Empty string by default. - * If template is a function, then it is injected with the following locals: - * $element - Current element - * $attrs - Current attributes object for the element - * Use the array form to define dependencies (necessary if strictDi is enabled and you require dependency injection) - */ - template?: string | Function | (string | Function)[]; - /** - * path or function that returns a path to an html template that should be used as the contents of this component. - * If templateUrl is a function, then it is injected with the following locals: - * $element - Current element - * $attrs - Current attributes object for the element - * Use the array form to define dependencies (necessary if strictDi is enabled and you require dependency injection) - */ - templateUrl?: string | Function | (string | Function)[]; - /** - * Define DOM attribute binding to component properties. Component properties are always bound to the component - * controller and not to the scope. - */ - bindings?: {[binding: string]: string}; - /** - * Whether transclusion is enabled. Enabled by default. - */ - transclude?: boolean | string | {[slot: string]: string}; - require?: string | string[] | {[controller: string]: string}; - } - - interface IComponentTemplateFn { - ( $element?: IAugmentedJQuery, $attrs?: IAttributes ): string; - } - - /////////////////////////////////////////////////////////////////////////// - // Directive - // see http://docs.angularjs.org/api/ng.$compileProvider#directive - // and http://docs.angularjs.org/guide/directive - /////////////////////////////////////////////////////////////////////////// - - interface IDirectiveFactory { - (...args: any[]): IDirective; - } - - interface IDirectiveLinkFn { - ( - scope: IScope, - instanceElement: IAugmentedJQuery, - instanceAttributes: IAttributes, - controller: {}, - transclude: ITranscludeFunction - ): void; - } - - interface IDirectivePrePost { - pre?: IDirectiveLinkFn; - post?: IDirectiveLinkFn; - } - - interface IDirectiveCompileFn { - ( - templateElement: IAugmentedJQuery, - templateAttributes: IAttributes, - /** - * @deprecated - * Note: The transclude function that is passed to the compile function is deprecated, - * as it e.g. does not know about the right outer scope. Please use the transclude function - * that is passed to the link function instead. - */ - transclude: ITranscludeFunction - ): IDirectivePrePost; - } - - interface IDirective { - compile?: IDirectiveCompileFn; - controller?: any; - controllerAs?: string; - /** - * @deprecated - * Deprecation warning: although bindings for non-ES6 class controllers are currently bound to this before - * the controller constructor is called, this use is now deprecated. Please place initialization code that - * relies upon bindings inside a $onInit method on the controller, instead. - */ - bindToController?: boolean | Object; - link?: IDirectiveLinkFn | IDirectivePrePost; - multiElement?: boolean; - name?: string; - priority?: number; - /** - * @deprecated - */ - replace?: boolean; - require?: string | string[] | {[controller: string]: string}; - restrict?: string; - scope?: boolean | Object; - template?: string | Function; - templateNamespace?: string; - templateUrl?: string | Function; - terminal?: boolean; - transclude?: boolean | string | {[slot: string]: string}; - } - - /** - * angular.element - * when calling angular.element, angular returns a jQuery object, - * augmented with additional methods like e.g. scope. - * see: http://docs.angularjs.org/api/angular.element - */ - interface IAugmentedJQueryStatic extends JQueryStatic { - (selector: string, context?: any): IAugmentedJQuery; - (element: Element): IAugmentedJQuery; - (object: {}): IAugmentedJQuery; - (elementArray: Element[]): IAugmentedJQuery; - (object: JQuery): IAugmentedJQuery; - (func: Function): IAugmentedJQuery; - (array: any[]): IAugmentedJQuery; - (): IAugmentedJQuery; - } - - interface IAugmentedJQuery extends JQuery { - // TODO: events, how to define? - //$destroy - - find(selector: string): IAugmentedJQuery; - find(element: any): IAugmentedJQuery; - find(obj: JQuery): IAugmentedJQuery; - controller(): any; - controller(name: string): any; - injector(): any; - scope(): IScope; - - /** - * Overload for custom scope interfaces - */ - scope(): T; - isolateScope(): IScope; - - inheritedData(key: string, value: any): JQuery; - inheritedData(obj: { [key: string]: any; }): JQuery; - inheritedData(key?: string): any; - } - - /////////////////////////////////////////////////////////////////////////// - // AUTO module (angular.js) - /////////////////////////////////////////////////////////////////////////// - export module auto { - - /////////////////////////////////////////////////////////////////////// - // InjectorService - // see http://docs.angularjs.org/api/AUTO.$injector - /////////////////////////////////////////////////////////////////////// - interface IInjectorService { - annotate(fn: Function, strictDi?: boolean): string[]; - annotate(inlineAnnotatedFunction: any[]): string[]; - get(name: string, caller?: string): T; - get(name: '$anchorScroll'): IAnchorScrollService - get(name: '$cacheFactory'): ICacheFactoryService - get(name: '$compile'): ICompileService - get(name: '$controller'): IControllerService - get(name: '$document'): IDocumentService - get(name: '$exceptionHandler'): IExceptionHandlerService - get(name: '$filter'): IFilterService - get(name: '$http'): IHttpService - get(name: '$httpBackend'): IHttpBackendService - get(name: '$httpParamSerializer'): IHttpParamSerializer - get(name: '$httpParamSerializerJQLike'): IHttpParamSerializer - get(name: '$interpolate'): IInterpolateService - get(name: '$interval'): IIntervalService - get(name: '$locale'): ILocaleService - get(name: '$location'): ILocationService - get(name: '$log'): ILogService - get(name: '$parse'): IParseService - get(name: '$q'): IQService - get(name: '$rootElement'): IRootElementService - get(name: '$rootScope'): IRootScopeService - get(name: '$sce'): ISCEService - get(name: '$sceDelegate'): ISCEDelegateService - get(name: '$templateCache'): ITemplateCacheService - get(name: '$templateRequest'): ITemplateRequestService - get(name: '$timeout'): ITimeoutService - get(name: '$window'): IWindowService - get(name: '$xhrFactory'): IXhrFactory - has(name: string): boolean; - instantiate(typeConstructor: Function, locals?: any): T; - invoke(inlineAnnotatedFunction: any[]): any; - invoke(func: Function, context?: any, locals?: any): any; - strictDi: boolean; - } - - /////////////////////////////////////////////////////////////////////// - // ProvideService - // see http://docs.angularjs.org/api/AUTO.$provide - /////////////////////////////////////////////////////////////////////// - interface IProvideService { - // Documentation says it returns the registered instance, but actual - // implementation does not return anything. - // constant(name: string, value: any): any; - /** - * Register a constant service, such as a string, a number, an array, an object or a function, with the $injector. Unlike value it can be injected into a module configuration function (see config) and it cannot be overridden by an Angular decorator. - * - * @param name The name of the constant. - * @param value The constant value. - */ - constant(name: string, value: any): void; - - /** - * Register a service decorator with the $injector. A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service. - * - * @param name The name of the service to decorate. - * @param decorator This function will be invoked when the service needs to be instantiated and should return the decorated service instance. The function is called using the injector.invoke method and is therefore fully injectable. Local injection arguments: - * - * $delegate - The original service instance, which can be monkey patched, configured, decorated or delegated to. - */ - decorator(name: string, decorator: Function): void; - /** - * Register a service decorator with the $injector. A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service. - * - * @param name The name of the service to decorate. - * @param inlineAnnotatedFunction This function will be invoked when the service needs to be instantiated and should return the decorated service instance. The function is called using the injector.invoke method and is therefore fully injectable. Local injection arguments: - * - * $delegate - The original service instance, which can be monkey patched, configured, decorated or delegated to. - */ - decorator(name: string, inlineAnnotatedFunction: any[]): void; - factory(name: string, serviceFactoryFunction: Function): IServiceProvider; - factory(name: string, inlineAnnotatedFunction: any[]): IServiceProvider; - provider(name: string, provider: IServiceProvider): IServiceProvider; - provider(name: string, serviceProviderConstructor: Function): IServiceProvider; - service(name: string, constructor: Function): IServiceProvider; - service(name: string, inlineAnnotatedFunction: any[]): IServiceProvider; - value(name: string, value: any): IServiceProvider; - } - - } - - /** - * $http params serializer that converts objects to strings - * see https://docs.angularjs.org/api/ng/service/$httpParamSerializer - */ - interface IHttpParamSerializer { - (obj: Object): string; - } -} \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular/typings.json b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular/typings.json deleted file mode 100644 index c974311fa7..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/angular/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/b76dd8a7f95b71696982befbb7589940d27e940b/angularjs/angular.d.ts", - "raw": "registry:dt/angular#1.5.0+20160517064839", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/b76dd8a7f95b71696982befbb7589940d27e940b/angularjs/angular.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/jquery/index.d.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/jquery/index.d.ts deleted file mode 100644 index b4208b3b82..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/jquery/index.d.ts +++ /dev/null @@ -1,3199 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/4cdfbe96b666eec5e1defbb519a62abf04e96764/jquery/jquery.d.ts -interface JQueryAjaxSettings { - /** - * The content type sent in the request header that tells the server what kind of response it will accept in return. If the accepts setting needs modification, it is recommended to do so once in the $.ajaxSetup() method. - */ - accepts?: any; - /** - * By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success(). - */ - async?: boolean; - /** - * A pre-request callback function that can be used to modify the jqXHR (in jQuery 1.4.x, XMLHTTPRequest) object before it is sent. Use this to set custom headers, etc. The jqXHR and settings objects are passed as arguments. This is an Ajax Event. Returning false in the beforeSend function will cancel the request. As of jQuery 1.5, the beforeSend option will be called regardless of the type of request. - */ - beforeSend? (jqXHR: JQueryXHR, settings: JQueryAjaxSettings): any; - /** - * If set to false, it will force requested pages not to be cached by the browser. Note: Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters. The parameter is not needed for other types of requests, except in IE8 when a POST is made to a URL that has already been requested by a GET. - */ - cache?: boolean; - /** - * A function to be called when the request finishes (after success and error callbacks are executed). The function gets passed two arguments: The jqXHR (in jQuery 1.4.x, XMLHTTPRequest) object and a string categorizing the status of the request ("success", "notmodified", "error", "timeout", "abort", or "parsererror"). As of jQuery 1.5, the complete setting can accept an array of functions. Each function will be called in turn. This is an Ajax Event. - */ - complete? (jqXHR: JQueryXHR, textStatus: string): any; - /** - * An object of string/regular-expression pairs that determine how jQuery will parse the response, given its content type. (version added: 1.5) - */ - contents?: { [key: string]: any; }; - //According to jQuery.ajax source code, ajax's option actually allows contentType to set to "false" - // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/742 - /** - * When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent). The W3C XMLHttpRequest specification dictates that the charset is always UTF-8; specifying another charset will not force the browser to change the encoding. - */ - contentType?: any; - /** - * This object will be made the context of all Ajax-related callbacks. By default, the context is an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax). - */ - context?: any; - /** - * An object containing dataType-to-dataType converters. Each converter's value is a function that returns the transformed value of the response. (version added: 1.5) - */ - converters?: { [key: string]: any; }; - /** - * If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain. (version added: 1.5) - */ - crossDomain?: boolean; - /** - * Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests. See processData option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key based on the value of the traditional setting (described below). - */ - data?: any; - /** - * A function to be used to handle the raw response data of XMLHttpRequest.This is a pre-filtering function to sanitize the response. You should return the sanitized data. The function accepts two arguments: The raw data returned from the server and the 'dataType' parameter. - */ - dataFilter? (data: any, ty: any): any; - /** - * The type of data that you're expecting back from the server. If none is specified, jQuery will try to infer it based on the MIME type of the response (an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string). - */ - dataType?: string; - /** - * A function to be called if the request fails. The function receives three arguments: The jqXHR (in jQuery 1.4.x, XMLHttpRequest) object, a string describing the type of error that occurred and an optional exception object, if one occurred. Possible values for the second argument (besides null) are "timeout", "error", "abort", and "parsererror". When an HTTP error occurs, errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error." As of jQuery 1.5, the error setting can accept an array of functions. Each function will be called in turn. Note: This handler is not called for cross-domain script and cross-domain JSONP requests. This is an Ajax Event. - */ - error? (jqXHR: JQueryXHR, textStatus: string, errorThrown: string): any; - /** - * Whether to trigger global Ajax event handlers for this request. The default is true. Set to false to prevent the global handlers like ajaxStart or ajaxStop from being triggered. This can be used to control various Ajax Events. - */ - global?: boolean; - /** - * An object of additional header key/value pairs to send along with requests using the XMLHttpRequest transport. The header X-Requested-With: XMLHttpRequest is always added, but its default XMLHttpRequest value can be changed here. Values in the headers setting can also be overwritten from within the beforeSend function. (version added: 1.5) - */ - headers?: { [key: string]: any; }; - /** - * Allow the request to be successful only if the response has changed since the last request. This is done by checking the Last-Modified header. Default value is false, ignoring the header. In jQuery 1.4 this technique also checks the 'etag' specified by the server to catch unmodified data. - */ - ifModified?: boolean; - /** - * Allow the current environment to be recognized as "local," (e.g. the filesystem), even if jQuery does not recognize it as such by default. The following protocols are currently recognized as local: file, *-extension, and widget. If the isLocal setting needs modification, it is recommended to do so once in the $.ajaxSetup() method. (version added: 1.5.1) - */ - isLocal?: boolean; - /** - * Override the callback function name in a jsonp request. This value will be used instead of 'callback' in the 'callback=?' part of the query string in the url. So {jsonp:'onJSONPLoad'} would result in 'onJSONPLoad=?' passed to the server. As of jQuery 1.5, setting the jsonp option to false prevents jQuery from adding the "?callback" string to the URL or attempting to use "=?" for transformation. In this case, you should also explicitly set the jsonpCallback setting. For example, { jsonp: false, jsonpCallback: "callbackName" } - */ - jsonp?: any; - /** - * Specify the callback function name for a JSONP request. This value will be used instead of the random name automatically generated by jQuery. It is preferable to let jQuery generate a unique name as it'll make it easier to manage the requests and provide callbacks and error handling. You may want to specify the callback when you want to enable better browser caching of GET requests. As of jQuery 1.5, you can also use a function for this setting, in which case the value of jsonpCallback is set to the return value of that function. - */ - jsonpCallback?: any; - /** - * The HTTP method to use for the request (e.g. "POST", "GET", "PUT"). (version added: 1.9.0) - */ - method?: string; - /** - * A mime type to override the XHR mime type. (version added: 1.5.1) - */ - mimeType?: string; - /** - * A password to be used with XMLHttpRequest in response to an HTTP access authentication request. - */ - password?: string; - /** - * By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded". If you want to send a DOMDocument, or other non-processed data, set this option to false. - */ - processData?: boolean; - /** - * Only applies when the "script" transport is used (e.g., cross-domain requests with "jsonp" or "script" dataType and "GET" type). Sets the charset attribute on the script tag used in the request. Used when the character set on the local page is not the same as the one on the remote script. - */ - scriptCharset?: string; - /** - * An object of numeric HTTP codes and functions to be called when the response has the corresponding code. f the request is successful, the status code functions take the same parameters as the success callback; if it results in an error (including 3xx redirect), they take the same parameters as the error callback. (version added: 1.5) - */ - statusCode?: { [key: string]: any; }; - /** - * A function to be called if the request succeeds. The function gets passed three arguments: The data returned from the server, formatted according to the dataType parameter; a string describing the status; and the jqXHR (in jQuery 1.4.x, XMLHttpRequest) object. As of jQuery 1.5, the success setting can accept an array of functions. Each function will be called in turn. This is an Ajax Event. - */ - success? (data: any, textStatus: string, jqXHR: JQueryXHR): any; - /** - * Set a timeout (in milliseconds) for the request. This will override any global timeout set with $.ajaxSetup(). The timeout period starts at the point the $.ajax call is made; if several other requests are in progress and the browser has no connections available, it is possible for a request to time out before it can be sent. In jQuery 1.4.x and below, the XMLHttpRequest object will be in an invalid state if the request times out; accessing any object members may throw an exception. In Firefox 3.0+ only, script and JSONP requests cannot be cancelled by a timeout; the script will run even if it arrives after the timeout period. - */ - timeout?: number; - /** - * Set this to true if you wish to use the traditional style of param serialization. - */ - traditional?: boolean; - /** - * The type of request to make ("POST" or "GET"), default is "GET". Note: Other HTTP request methods, such as PUT and DELETE, can also be used here, but they are not supported by all browsers. - */ - type?: string; - /** - * A string containing the URL to which the request is sent. - */ - url?: string; - /** - * A username to be used with XMLHttpRequest in response to an HTTP access authentication request. - */ - username?: string; - /** - * Callback for creating the XMLHttpRequest object. Defaults to the ActiveXObject when available (IE), the XMLHttpRequest otherwise. Override to provide your own implementation for XMLHttpRequest or enhancements to the factory. - */ - xhr?: any; - /** - * An object of fieldName-fieldValue pairs to set on the native XHR object. For example, you can use it to set withCredentials to true for cross-domain requests if needed. In jQuery 1.5, the withCredentials property was not propagated to the native XHR and thus CORS requests requiring it would ignore this flag. For this reason, we recommend using jQuery 1.5.1+ should you require the use of it. (version added: 1.5.1) - */ - xhrFields?: { [key: string]: any; }; -} - -/** - * Interface for the jqXHR object - */ -interface JQueryXHR extends XMLHttpRequest, JQueryPromise { - /** - * The .overrideMimeType() method may be used in the beforeSend() callback function, for example, to modify the response content-type header. As of jQuery 1.5.1, the jqXHR object also contains the overrideMimeType() method (it was available in jQuery 1.4.x, as well, but was temporarily removed in jQuery 1.5). - */ - overrideMimeType(mimeType: string): any; - /** - * Cancel the request. - * - * @param statusText A string passed as the textStatus parameter for the done callback. Default value: "canceled" - */ - abort(statusText?: string): void; - /** - * Incorporates the functionality of the .done() and .fail() methods, allowing (as of jQuery 1.8) the underlying Promise to be manipulated. Refer to deferred.then() for implementation details. - */ - then(doneCallback: (data: any, textStatus: string, jqXHR: JQueryXHR) => R, failCallback?: (jqXHR: JQueryXHR, textStatus: string, errorThrown: any) => void): JQueryPromise; - /** - * Property containing the parsed response if the response Content-Type is json - */ - responseJSON?: any; - /** - * A function to be called if the request fails. - */ - error(xhr: JQueryXHR, textStatus: string, errorThrown: string): void; -} - -/** - * Interface for the JQuery callback - */ -interface JQueryCallback { - /** - * Add a callback or a collection of callbacks to a callback list. - * - * @param callbacks A function, or array of functions, that are to be added to the callback list. - */ - add(callbacks: Function): JQueryCallback; - /** - * Add a callback or a collection of callbacks to a callback list. - * - * @param callbacks A function, or array of functions, that are to be added to the callback list. - */ - add(callbacks: Function[]): JQueryCallback; - - /** - * Disable a callback list from doing anything more. - */ - disable(): JQueryCallback; - - /** - * Determine if the callbacks list has been disabled. - */ - disabled(): boolean; - - /** - * Remove all of the callbacks from a list. - */ - empty(): JQueryCallback; - - /** - * Call all of the callbacks with the given arguments - * - * @param arguments The argument or list of arguments to pass back to the callback list. - */ - fire(...arguments: any[]): JQueryCallback; - - /** - * Determine if the callbacks have already been called at least once. - */ - fired(): boolean; - - /** - * Call all callbacks in a list with the given context and arguments. - * - * @param context A reference to the context in which the callbacks in the list should be fired. - * @param arguments An argument, or array of arguments, to pass to the callbacks in the list. - */ - fireWith(context?: any, args?: any[]): JQueryCallback; - - /** - * Determine whether a supplied callback is in a list - * - * @param callback The callback to search for. - */ - has(callback: Function): boolean; - - /** - * Lock a callback list in its current state. - */ - lock(): JQueryCallback; - - /** - * Determine if the callbacks list has been locked. - */ - locked(): boolean; - - /** - * Remove a callback or a collection of callbacks from a callback list. - * - * @param callbacks A function, or array of functions, that are to be removed from the callback list. - */ - remove(callbacks: Function): JQueryCallback; - /** - * Remove a callback or a collection of callbacks from a callback list. - * - * @param callbacks A function, or array of functions, that are to be removed from the callback list. - */ - remove(callbacks: Function[]): JQueryCallback; -} - -/** - * Allows jQuery Promises to interop with non-jQuery promises - */ -interface JQueryGenericPromise { - /** - * Add handlers to be called when the Deferred object is resolved, rejected, or still in progress. - * - * @param doneFilter A function that is called when the Deferred is resolved. - * @param failFilter An optional function that is called when the Deferred is rejected. - */ - then(doneFilter: (value?: T, ...values: any[]) => U|JQueryPromise, failFilter?: (...reasons: any[]) => any, progressFilter?: (...progression: any[]) => any): JQueryPromise; - - /** - * Add handlers to be called when the Deferred object is resolved, rejected, or still in progress. - * - * @param doneFilter A function that is called when the Deferred is resolved. - * @param failFilter An optional function that is called when the Deferred is rejected. - */ - then(doneFilter: (value?: T, ...values: any[]) => void, failFilter?: (...reasons: any[]) => any, progressFilter?: (...progression: any[]) => any): JQueryPromise; -} - -/** - * Interface for the JQuery promise/deferred callbacks - */ -interface JQueryPromiseCallback { - (value?: T, ...args: any[]): void; -} - -interface JQueryPromiseOperator { - (callback1: JQueryPromiseCallback|JQueryPromiseCallback[], ...callbacksN: Array|JQueryPromiseCallback[]>): JQueryPromise; -} - -/** - * Interface for the JQuery promise, part of callbacks - */ -interface JQueryPromise extends JQueryGenericPromise { - /** - * Determine the current state of a Deferred object. - */ - state(): string; - /** - * Add handlers to be called when the Deferred object is either resolved or rejected. - * - * @param alwaysCallbacks1 A function, or array of functions, that is called when the Deferred is resolved or rejected. - * @param alwaysCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved or rejected. - */ - always(alwaysCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...alwaysCallbacksN: Array|JQueryPromiseCallback[]>): JQueryPromise; - /** - * Add handlers to be called when the Deferred object is resolved. - * - * @param doneCallbacks1 A function, or array of functions, that are called when the Deferred is resolved. - * @param doneCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved. - */ - done(doneCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...doneCallbackN: Array|JQueryPromiseCallback[]>): JQueryPromise; - /** - * Add handlers to be called when the Deferred object is rejected. - * - * @param failCallbacks1 A function, or array of functions, that are called when the Deferred is rejected. - * @param failCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is rejected. - */ - fail(failCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...failCallbacksN: Array|JQueryPromiseCallback[]>): JQueryPromise; - /** - * Add handlers to be called when the Deferred object generates progress notifications. - * - * @param progressCallbacks A function, or array of functions, to be called when the Deferred generates progress notifications. - */ - progress(progressCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...progressCallbackN: Array|JQueryPromiseCallback[]>): JQueryPromise; - - // Deprecated - given no typings - pipe(doneFilter?: (x: any) => any, failFilter?: (x: any) => any, progressFilter?: (x: any) => any): JQueryPromise; -} - -/** - * Interface for the JQuery deferred, part of callbacks - */ -interface JQueryDeferred extends JQueryGenericPromise { - /** - * Determine the current state of a Deferred object. - */ - state(): string; - /** - * Add handlers to be called when the Deferred object is either resolved or rejected. - * - * @param alwaysCallbacks1 A function, or array of functions, that is called when the Deferred is resolved or rejected. - * @param alwaysCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved or rejected. - */ - always(alwaysCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...alwaysCallbacksN: Array|JQueryPromiseCallback[]>): JQueryDeferred; - /** - * Add handlers to be called when the Deferred object is resolved. - * - * @param doneCallbacks1 A function, or array of functions, that are called when the Deferred is resolved. - * @param doneCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved. - */ - done(doneCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...doneCallbackN: Array|JQueryPromiseCallback[]>): JQueryDeferred; - /** - * Add handlers to be called when the Deferred object is rejected. - * - * @param failCallbacks1 A function, or array of functions, that are called when the Deferred is rejected. - * @param failCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is rejected. - */ - fail(failCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...failCallbacksN: Array|JQueryPromiseCallback[]>): JQueryDeferred; - /** - * Add handlers to be called when the Deferred object generates progress notifications. - * - * @param progressCallbacks A function, or array of functions, to be called when the Deferred generates progress notifications. - */ - progress(progressCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...progressCallbackN: Array|JQueryPromiseCallback[]>): JQueryDeferred; - - /** - * Call the progressCallbacks on a Deferred object with the given args. - * - * @param args Optional arguments that are passed to the progressCallbacks. - */ - notify(value?: any, ...args: any[]): JQueryDeferred; - - /** - * Call the progressCallbacks on a Deferred object with the given context and args. - * - * @param context Context passed to the progressCallbacks as the this object. - * @param args Optional arguments that are passed to the progressCallbacks. - */ - notifyWith(context: any, value?: any[]): JQueryDeferred; - - /** - * Reject a Deferred object and call any failCallbacks with the given args. - * - * @param args Optional arguments that are passed to the failCallbacks. - */ - reject(value?: any, ...args: any[]): JQueryDeferred; - /** - * Reject a Deferred object and call any failCallbacks with the given context and args. - * - * @param context Context passed to the failCallbacks as the this object. - * @param args An optional array of arguments that are passed to the failCallbacks. - */ - rejectWith(context: any, value?: any[]): JQueryDeferred; - - /** - * Resolve a Deferred object and call any doneCallbacks with the given args. - * - * @param value First argument passed to doneCallbacks. - * @param args Optional subsequent arguments that are passed to the doneCallbacks. - */ - resolve(value?: T, ...args: any[]): JQueryDeferred; - - /** - * Resolve a Deferred object and call any doneCallbacks with the given context and args. - * - * @param context Context passed to the doneCallbacks as the this object. - * @param args An optional array of arguments that are passed to the doneCallbacks. - */ - resolveWith(context: any, value?: T[]): JQueryDeferred; - - /** - * Return a Deferred's Promise object. - * - * @param target Object onto which the promise methods have to be attached - */ - promise(target?: any): JQueryPromise; - - // Deprecated - given no typings - pipe(doneFilter?: (x: any) => any, failFilter?: (x: any) => any, progressFilter?: (x: any) => any): JQueryPromise; -} - -/** - * Interface of the JQuery extension of the W3C event object - */ -interface BaseJQueryEventObject extends Event { - data: any; - delegateTarget: Element; - isDefaultPrevented(): boolean; - isImmediatePropagationStopped(): boolean; - isPropagationStopped(): boolean; - namespace: string; - originalEvent: Event; - preventDefault(): any; - relatedTarget: Element; - result: any; - stopImmediatePropagation(): void; - stopPropagation(): void; - target: Element; - pageX: number; - pageY: number; - which: number; - metaKey: boolean; -} - -interface JQueryInputEventObject extends BaseJQueryEventObject { - altKey: boolean; - ctrlKey: boolean; - metaKey: boolean; - shiftKey: boolean; -} - -interface JQueryMouseEventObject extends JQueryInputEventObject { - button: number; - clientX: number; - clientY: number; - offsetX: number; - offsetY: number; - pageX: number; - pageY: number; - screenX: number; - screenY: number; -} - -interface JQueryKeyEventObject extends JQueryInputEventObject { - char: any; - charCode: number; - key: any; - keyCode: number; -} - -interface JQueryEventObject extends BaseJQueryEventObject, JQueryInputEventObject, JQueryMouseEventObject, JQueryKeyEventObject{ -} - -/* - Collection of properties of the current browser -*/ - -interface JQuerySupport { - ajax?: boolean; - boxModel?: boolean; - changeBubbles?: boolean; - checkClone?: boolean; - checkOn?: boolean; - cors?: boolean; - cssFloat?: boolean; - hrefNormalized?: boolean; - htmlSerialize?: boolean; - leadingWhitespace?: boolean; - noCloneChecked?: boolean; - noCloneEvent?: boolean; - opacity?: boolean; - optDisabled?: boolean; - optSelected?: boolean; - scriptEval? (): boolean; - style?: boolean; - submitBubbles?: boolean; - tbody?: boolean; -} - -interface JQueryParam { - /** - * Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request. - * - * @param obj An array or object to serialize. - */ - (obj: any): string; - - /** - * Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request. - * - * @param obj An array or object to serialize. - * @param traditional A Boolean indicating whether to perform a traditional "shallow" serialization. - */ - (obj: any, traditional: boolean): string; -} - -/** - * The interface used to construct jQuery events (with $.Event). It is - * defined separately instead of inline in JQueryStatic to allow - * overriding the construction function with specific strings - * returning specific event objects. - */ -interface JQueryEventConstructor { - (name: string, eventProperties?: any): JQueryEventObject; - new (name: string, eventProperties?: any): JQueryEventObject; -} - -/** - * The interface used to specify coordinates. - */ -interface JQueryCoordinates { - left: number; - top: number; -} - -/** - * Elements in the array returned by serializeArray() - */ -interface JQuerySerializeArrayElement { - name: string; - value: string; -} - -interface JQueryAnimationOptions { - /** - * A string or number determining how long the animation will run. - */ - duration?: any; - /** - * A string indicating which easing function to use for the transition. - */ - easing?: string; - /** - * A function to call once the animation is complete. - */ - complete?: Function; - /** - * A function to be called for each animated property of each animated element. This function provides an opportunity to modify the Tween object to change the value of the property before it is set. - */ - step?: (now: number, tween: any) => any; - /** - * A function to be called after each step of the animation, only once per animated element regardless of the number of animated properties. (version added: 1.8) - */ - progress?: (animation: JQueryPromise, progress: number, remainingMs: number) => any; - /** - * A function to call when the animation begins. (version added: 1.8) - */ - start?: (animation: JQueryPromise) => any; - /** - * A function to be called when the animation completes (its Promise object is resolved). (version added: 1.8) - */ - done?: (animation: JQueryPromise, jumpedToEnd: boolean) => any; - /** - * A function to be called when the animation fails to complete (its Promise object is rejected). (version added: 1.8) - */ - fail?: (animation: JQueryPromise, jumpedToEnd: boolean) => any; - /** - * A function to be called when the animation completes or stops without completing (its Promise object is either resolved or rejected). (version added: 1.8) - */ - always?: (animation: JQueryPromise, jumpedToEnd: boolean) => any; - /** - * A Boolean indicating whether to place the animation in the effects queue. If false, the animation will begin immediately. As of jQuery 1.7, the queue option can also accept a string, in which case the animation is added to the queue represented by that string. When a custom queue name is used the animation does not automatically start; you must call .dequeue("queuename") to start it. - */ - queue?: any; - /** - * A map of one or more of the CSS properties defined by the properties argument and their corresponding easing functions. (version added: 1.4) - */ - specialEasing?: Object; -} - -interface JQueryEasingFunction { - ( percent: number ): number; -} - -interface JQueryEasingFunctions { - [ name: string ]: JQueryEasingFunction; - linear: JQueryEasingFunction; - swing: JQueryEasingFunction; -} - -/** - * Static members of jQuery (those on $ and jQuery themselves) - */ -interface JQueryStatic { - - /** - * Perform an asynchronous HTTP (Ajax) request. - * - * @param settings A set of key/value pairs that configure the Ajax request. All settings are optional. A default can be set for any option with $.ajaxSetup(). - */ - ajax(settings: JQueryAjaxSettings): JQueryXHR; - /** - * Perform an asynchronous HTTP (Ajax) request. - * - * @param url A string containing the URL to which the request is sent. - * @param settings A set of key/value pairs that configure the Ajax request. All settings are optional. A default can be set for any option with $.ajaxSetup(). - */ - ajax(url: string, settings?: JQueryAjaxSettings): JQueryXHR; - - /** - * Handle custom Ajax options or modify existing options before each request is sent and before they are processed by $.ajax(). - * - * @param dataTypes An optional string containing one or more space-separated dataTypes - * @param handler A handler to set default values for future Ajax requests. - */ - ajaxPrefilter(dataTypes: string, handler: (opts: any, originalOpts: JQueryAjaxSettings, jqXHR: JQueryXHR) => any): void; - /** - * Handle custom Ajax options or modify existing options before each request is sent and before they are processed by $.ajax(). - * - * @param handler A handler to set default values for future Ajax requests. - */ - ajaxPrefilter(handler: (opts: any, originalOpts: JQueryAjaxSettings, jqXHR: JQueryXHR) => any): void; - - ajaxSettings: JQueryAjaxSettings; - - /** - * Set default values for future Ajax requests. Its use is not recommended. - * - * @param options A set of key/value pairs that configure the default Ajax request. All options are optional. - */ - ajaxSetup(options: JQueryAjaxSettings): void; - - /** - * Load data from the server using a HTTP GET request. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, or html). - */ - get(url: string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - /** - * Load data from the server using a HTTP GET request. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param success A callback function that is executed if the request succeeds. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, or html). - */ - get(url: string, data?: Object|string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - /** - * Load data from the server using a HTTP GET request. - * - * @param settings The JQueryAjaxSettings to be used for the request - */ - get(settings : JQueryAjaxSettings): JQueryXHR; - /** - * Load JSON-encoded data from the server using a GET HTTP request. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. - */ - getJSON(url: string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any): JQueryXHR; - /** - * Load JSON-encoded data from the server using a GET HTTP request. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param success A callback function that is executed if the request succeeds. - */ - getJSON(url: string, data?: Object|string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any): JQueryXHR; - /** - * Load a JavaScript file from the server using a GET HTTP request, then execute it. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. - */ - getScript(url: string, success?: (script: string, textStatus: string, jqXHR: JQueryXHR) => any): JQueryXHR; - - /** - * Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request. - */ - param: JQueryParam; - - /** - * Load data from the server using a HTTP POST request. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. Required if dataType is provided, but can be null in that case. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, text, html). - */ - post(url: string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - /** - * Load data from the server using a HTTP POST request. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param success A callback function that is executed if the request succeeds. Required if dataType is provided, but can be null in that case. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, text, html). - */ - post(url: string, data?: Object|string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - /** - * Load data from the server using a HTTP POST request. - * - * @param settings The JQueryAjaxSettings to be used for the request - */ - post(settings : JQueryAjaxSettings): JQueryXHR; - /** - * A multi-purpose callbacks list object that provides a powerful way to manage callback lists. - * - * @param flags An optional list of space-separated flags that change how the callback list behaves. - */ - Callbacks(flags?: string): JQueryCallback; - - /** - * Holds or releases the execution of jQuery's ready event. - * - * @param hold Indicates whether the ready hold is being requested or released - */ - holdReady(hold: boolean): void; - - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param selector A string containing a selector expression - * @param context A DOM Element, Document, or jQuery to use as context - */ - (selector: string, context?: Element|JQuery): JQuery; - - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param element A DOM element to wrap in a jQuery object. - */ - (element: Element): JQuery; - - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param elementArray An array containing a set of DOM elements to wrap in a jQuery object. - */ - (elementArray: Element[]): JQuery; - - /** - * Binds a function to be executed when the DOM has finished loading. - * - * @param callback A function to execute after the DOM is ready. - */ - (callback: (jQueryAlias?: JQueryStatic) => any): JQuery; - - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param object A plain object to wrap in a jQuery object. - */ - (object: {}): JQuery; - - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param object An existing jQuery object to clone. - */ - (object: JQuery): JQuery; - - /** - * Specify a function to execute when the DOM is fully loaded. - */ - (): JQuery; - - /** - * Creates DOM elements on the fly from the provided string of raw HTML. - * - * @param html A string of HTML to create on the fly. Note that this parses HTML, not XML. - * @param ownerDocument A document in which the new elements will be created. - */ - (html: string, ownerDocument?: Document): JQuery; - - /** - * Creates DOM elements on the fly from the provided string of raw HTML. - * - * @param html A string defining a single, standalone, HTML element (e.g.
    or
    ). - * @param attributes An object of attributes, events, and methods to call on the newly-created element. - */ - (html: string, attributes: Object): JQuery; - - /** - * Relinquish jQuery's control of the $ variable. - * - * @param removeAll A Boolean indicating whether to remove all jQuery variables from the global scope (including jQuery itself). - */ - noConflict(removeAll?: boolean): JQueryStatic; - - /** - * Provides a way to execute callback functions based on one or more objects, usually Deferred objects that represent asynchronous events. - * - * @param deferreds One or more Deferred objects, or plain JavaScript objects. - */ - when(...deferreds: Array/* as JQueryDeferred */>): JQueryPromise; - - /** - * Hook directly into jQuery to override how particular CSS properties are retrieved or set, normalize CSS property naming, or create custom properties. - */ - cssHooks: { [key: string]: any; }; - cssNumber: any; - - /** - * Store arbitrary data associated with the specified element. Returns the value that was set. - * - * @param element The DOM element to associate with the data. - * @param key A string naming the piece of data to set. - * @param value The new data value. - */ - data(element: Element, key: string, value: T): T; - /** - * Returns value at named data store for the element, as set by jQuery.data(element, name, value), or the full data store for the element. - * - * @param element The DOM element to associate with the data. - * @param key A string naming the piece of data to set. - */ - data(element: Element, key: string): any; - /** - * Returns value at named data store for the element, as set by jQuery.data(element, name, value), or the full data store for the element. - * - * @param element The DOM element to associate with the data. - */ - data(element: Element): any; - - /** - * Execute the next function on the queue for the matched element. - * - * @param element A DOM element from which to remove and execute a queued function. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - dequeue(element: Element, queueName?: string): void; - - /** - * Determine whether an element has any jQuery data associated with it. - * - * @param element A DOM element to be checked for data. - */ - hasData(element: Element): boolean; - - /** - * Show the queue of functions to be executed on the matched element. - * - * @param element A DOM element to inspect for an attached queue. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - queue(element: Element, queueName?: string): any[]; - /** - * Manipulate the queue of functions to be executed on the matched element. - * - * @param element A DOM element where the array of queued functions is attached. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param newQueue An array of functions to replace the current queue contents. - */ - queue(element: Element, queueName: string, newQueue: Function[]): JQuery; - /** - * Manipulate the queue of functions to be executed on the matched element. - * - * @param element A DOM element on which to add a queued function. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param callback The new function to add to the queue. - */ - queue(element: Element, queueName: string, callback: Function): JQuery; - - /** - * Remove a previously-stored piece of data. - * - * @param element A DOM element from which to remove data. - * @param name A string naming the piece of data to remove. - */ - removeData(element: Element, name?: string): JQuery; - - /** - * A constructor function that returns a chainable utility object with methods to register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function. - * - * @param beforeStart A function that is called just before the constructor returns. - */ - Deferred(beforeStart?: (deferred: JQueryDeferred) => any): JQueryDeferred; - - /** - * Effects - */ - - easing: JQueryEasingFunctions; - - fx: { - tick: () => void; - /** - * The rate (in milliseconds) at which animations fire. - */ - interval: number; - stop: () => void; - speeds: { slow: number; fast: number; }; - /** - * Globally disable all animations. - */ - off: boolean; - step: any; - }; - - /** - * Takes a function and returns a new one that will always have a particular context. - * - * @param fnction The function whose context will be changed. - * @param context The object to which the context (this) of the function should be set. - * @param additionalArguments Any number of arguments to be passed to the function referenced in the function argument. - */ - proxy(fnction: (...args: any[]) => any, context: Object, ...additionalArguments: any[]): any; - /** - * Takes a function and returns a new one that will always have a particular context. - * - * @param context The object to which the context (this) of the function should be set. - * @param name The name of the function whose context will be changed (should be a property of the context object). - * @param additionalArguments Any number of arguments to be passed to the function named in the name argument. - */ - proxy(context: Object, name: string, ...additionalArguments: any[]): any; - - Event: JQueryEventConstructor; - - /** - * Takes a string and throws an exception containing it. - * - * @param message The message to send out. - */ - error(message: any): JQuery; - - expr: any; - fn: any; //TODO: Decide how we want to type this - - isReady: boolean; - - // Properties - support: JQuerySupport; - - /** - * Check to see if a DOM element is a descendant of another DOM element. - * - * @param container The DOM element that may contain the other element. - * @param contained The DOM element that may be contained by (a descendant of) the other element. - */ - contains(container: Element, contained: Element): boolean; - - /** - * A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties. - * - * @param collection The object or array to iterate over. - * @param callback The function that will be executed on every object. - */ - each( - collection: T[], - callback: (indexInArray: number, valueOfElement: T) => any - ): any; - - /** - * A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties. - * - * @param collection The object or array to iterate over. - * @param callback The function that will be executed on every object. - */ - each( - collection: any, - callback: (indexInArray: any, valueOfElement: any) => any - ): any; - - /** - * Merge the contents of two or more objects together into the first object. - * - * @param target An object that will receive the new properties if additional objects are passed in or that will extend the jQuery namespace if it is the sole argument. - * @param object1 An object containing additional properties to merge in. - * @param objectN Additional objects containing properties to merge in. - */ - extend(target: any, object1?: any, ...objectN: any[]): any; - /** - * Merge the contents of two or more objects together into the first object. - * - * @param deep If true, the merge becomes recursive (aka. deep copy). - * @param target The object to extend. It will receive the new properties. - * @param object1 An object containing additional properties to merge in. - * @param objectN Additional objects containing properties to merge in. - */ - extend(deep: boolean, target: any, object1?: any, ...objectN: any[]): any; - - /** - * Execute some JavaScript code globally. - * - * @param code The JavaScript code to execute. - */ - globalEval(code: string): any; - - /** - * Finds the elements of an array which satisfy a filter function. The original array is not affected. - * - * @param array The array to search through. - * @param func The function to process each item against. The first argument to the function is the item, and the second argument is the index. The function should return a Boolean value. this will be the global window object. - * @param invert If "invert" is false, or not provided, then the function returns an array consisting of all elements for which "callback" returns true. If "invert" is true, then the function returns an array consisting of all elements for which "callback" returns false. - */ - grep(array: T[], func: (elementOfArray: T, indexInArray: number) => boolean, invert?: boolean): T[]; - - /** - * Search for a specified value within an array and return its index (or -1 if not found). - * - * @param value The value to search for. - * @param array An array through which to search. - * @param fromIndex he index of the array at which to begin the search. The default is 0, which will search the whole array. - */ - inArray(value: T, array: T[], fromIndex?: number): number; - - /** - * Determine whether the argument is an array. - * - * @param obj Object to test whether or not it is an array. - */ - isArray(obj: any): boolean; - /** - * Check to see if an object is empty (contains no enumerable properties). - * - * @param obj The object that will be checked to see if it's empty. - */ - isEmptyObject(obj: any): boolean; - /** - * Determine if the argument passed is a Javascript function object. - * - * @param obj Object to test whether or not it is a function. - */ - isFunction(obj: any): boolean; - /** - * Determines whether its argument is a number. - * - * @param obj The value to be tested. - */ - isNumeric(value: any): boolean; - /** - * Check to see if an object is a plain object (created using "{}" or "new Object"). - * - * @param obj The object that will be checked to see if it's a plain object. - */ - isPlainObject(obj: any): boolean; - /** - * Determine whether the argument is a window. - * - * @param obj Object to test whether or not it is a window. - */ - isWindow(obj: any): boolean; - /** - * Check to see if a DOM node is within an XML document (or is an XML document). - * - * @param node he DOM node that will be checked to see if it's in an XML document. - */ - isXMLDoc(node: Node): boolean; - - /** - * Convert an array-like object into a true JavaScript array. - * - * @param obj Any object to turn into a native Array. - */ - makeArray(obj: any): any[]; - - /** - * Translate all items in an array or object to new array of items. - * - * @param array The Array to translate. - * @param callback The function to process each item against. The first argument to the function is the array item, the second argument is the index in array The function can return any value. Within the function, this refers to the global (window) object. - */ - map(array: T[], callback: (elementOfArray: T, indexInArray: number) => U): U[]; - /** - * Translate all items in an array or object to new array of items. - * - * @param arrayOrObject The Array or Object to translate. - * @param callback The function to process each item against. The first argument to the function is the value; the second argument is the index or key of the array or object property. The function can return any value to add to the array. A returned array will be flattened into the resulting array. Within the function, this refers to the global (window) object. - */ - map(arrayOrObject: any, callback: (value: any, indexOrKey: any) => any): any; - - /** - * Merge the contents of two arrays together into the first array. - * - * @param first The first array to merge, the elements of second added. - * @param second The second array to merge into the first, unaltered. - */ - merge(first: T[], second: T[]): T[]; - - /** - * An empty function. - */ - noop(): any; - - /** - * Return a number representing the current time. - */ - now(): number; - - /** - * Takes a well-formed JSON string and returns the resulting JavaScript object. - * - * @param json The JSON string to parse. - */ - parseJSON(json: string): any; - - /** - * Parses a string into an XML document. - * - * @param data a well-formed XML string to be parsed - */ - parseXML(data: string): XMLDocument; - - /** - * Remove the whitespace from the beginning and end of a string. - * - * @param str Remove the whitespace from the beginning and end of a string. - */ - trim(str: string): string; - - /** - * Determine the internal JavaScript [[Class]] of an object. - * - * @param obj Object to get the internal JavaScript [[Class]] of. - */ - type(obj: any): string; - - /** - * Sorts an array of DOM elements, in place, with the duplicates removed. Note that this only works on arrays of DOM elements, not strings or numbers. - * - * @param array The Array of DOM elements. - */ - unique(array: Element[]): Element[]; - - /** - * Parses a string into an array of DOM nodes. - * - * @param data HTML string to be parsed - * @param context DOM element to serve as the context in which the HTML fragment will be created - * @param keepScripts A Boolean indicating whether to include scripts passed in the HTML string - */ - parseHTML(data: string, context?: HTMLElement, keepScripts?: boolean): any[]; - - /** - * Parses a string into an array of DOM nodes. - * - * @param data HTML string to be parsed - * @param context DOM element to serve as the context in which the HTML fragment will be created - * @param keepScripts A Boolean indicating whether to include scripts passed in the HTML string - */ - parseHTML(data: string, context?: Document, keepScripts?: boolean): any[]; -} - -/** - * The jQuery instance members - */ -interface JQuery { - /** - * Register a handler to be called when Ajax requests complete. This is an AjaxEvent. - * - * @param handler The function to be invoked. - */ - ajaxComplete(handler: (event: JQueryEventObject, XMLHttpRequest: XMLHttpRequest, ajaxOptions: any) => any): JQuery; - /** - * Register a handler to be called when Ajax requests complete with an error. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxError(handler: (event: JQueryEventObject, jqXHR: JQueryXHR, ajaxSettings: JQueryAjaxSettings, thrownError: any) => any): JQuery; - /** - * Attach a function to be executed before an Ajax request is sent. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxSend(handler: (event: JQueryEventObject, jqXHR: JQueryXHR, ajaxOptions: JQueryAjaxSettings) => any): JQuery; - /** - * Register a handler to be called when the first Ajax request begins. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxStart(handler: () => any): JQuery; - /** - * Register a handler to be called when all Ajax requests have completed. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxStop(handler: () => any): JQuery; - /** - * Attach a function to be executed whenever an Ajax request completes successfully. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxSuccess(handler: (event: JQueryEventObject, XMLHttpRequest: XMLHttpRequest, ajaxOptions: JQueryAjaxSettings) => any): JQuery; - - /** - * Load data from the server and place the returned HTML into the matched element. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param complete A callback function that is executed when the request completes. - */ - load(url: string, data?: string|Object, complete?: (responseText: string, textStatus: string, XMLHttpRequest: XMLHttpRequest) => any): JQuery; - - /** - * Encode a set of form elements as a string for submission. - */ - serialize(): string; - /** - * Encode a set of form elements as an array of names and values. - */ - serializeArray(): JQuerySerializeArrayElement[]; - - /** - * Adds the specified class(es) to each of the set of matched elements. - * - * @param className One or more space-separated classes to be added to the class attribute of each matched element. - */ - addClass(className: string): JQuery; - /** - * Adds the specified class(es) to each of the set of matched elements. - * - * @param function A function returning one or more space-separated class names to be added to the existing class name(s). Receives the index position of the element in the set and the existing class name(s) as arguments. Within the function, this refers to the current element in the set. - */ - addClass(func: (index: number, className: string) => string): JQuery; - - /** - * Add the previous set of elements on the stack to the current set, optionally filtered by a selector. - */ - addBack(selector?: string): JQuery; - - /** - * Get the value of an attribute for the first element in the set of matched elements. - * - * @param attributeName The name of the attribute to get. - */ - attr(attributeName: string): string; - /** - * Set one or more attributes for the set of matched elements. - * - * @param attributeName The name of the attribute to set. - * @param value A value to set for the attribute. - */ - attr(attributeName: string, value: string|number): JQuery; - /** - * Set one or more attributes for the set of matched elements. - * - * @param attributeName The name of the attribute to set. - * @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old attribute value as arguments. - */ - attr(attributeName: string, func: (index: number, attr: string) => string|number): JQuery; - /** - * Set one or more attributes for the set of matched elements. - * - * @param attributes An object of attribute-value pairs to set. - */ - attr(attributes: Object): JQuery; - - /** - * Determine whether any of the matched elements are assigned the given class. - * - * @param className The class name to search for. - */ - hasClass(className: string): boolean; - - /** - * Get the HTML contents of the first element in the set of matched elements. - */ - html(): string; - /** - * Set the HTML contents of each element in the set of matched elements. - * - * @param htmlString A string of HTML to set as the content of each matched element. - */ - html(htmlString: string): JQuery; - /** - * Set the HTML contents of each element in the set of matched elements. - * - * @param func A function returning the HTML content to set. Receives the index position of the element in the set and the old HTML value as arguments. jQuery empties the element before calling the function; use the oldhtml argument to reference the previous content. Within the function, this refers to the current element in the set. - */ - html(func: (index: number, oldhtml: string) => string): JQuery; - /** - * Set the HTML contents of each element in the set of matched elements. - * - * @param func A function returning the HTML content to set. Receives the index position of the element in the set and the old HTML value as arguments. jQuery empties the element before calling the function; use the oldhtml argument to reference the previous content. Within the function, this refers to the current element in the set. - */ - - /** - * Get the value of a property for the first element in the set of matched elements. - * - * @param propertyName The name of the property to get. - */ - prop(propertyName: string): any; - /** - * Set one or more properties for the set of matched elements. - * - * @param propertyName The name of the property to set. - * @param value A value to set for the property. - */ - prop(propertyName: string, value: string|number|boolean): JQuery; - /** - * Set one or more properties for the set of matched elements. - * - * @param properties An object of property-value pairs to set. - */ - prop(properties: Object): JQuery; - /** - * Set one or more properties for the set of matched elements. - * - * @param propertyName The name of the property to set. - * @param func A function returning the value to set. Receives the index position of the element in the set and the old property value as arguments. Within the function, the keyword this refers to the current element. - */ - prop(propertyName: string, func: (index: number, oldPropertyValue: any) => any): JQuery; - - /** - * Remove an attribute from each element in the set of matched elements. - * - * @param attributeName An attribute to remove; as of version 1.7, it can be a space-separated list of attributes. - */ - removeAttr(attributeName: string): JQuery; - - /** - * Remove a single class, multiple classes, or all classes from each element in the set of matched elements. - * - * @param className One or more space-separated classes to be removed from the class attribute of each matched element. - */ - removeClass(className?: string): JQuery; - /** - * Remove a single class, multiple classes, or all classes from each element in the set of matched elements. - * - * @param function A function returning one or more space-separated class names to be removed. Receives the index position of the element in the set and the old class value as arguments. - */ - removeClass(func: (index: number, className: string) => string): JQuery; - - /** - * Remove a property for the set of matched elements. - * - * @param propertyName The name of the property to remove. - */ - removeProp(propertyName: string): JQuery; - - /** - * Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument. - * - * @param className One or more class names (separated by spaces) to be toggled for each element in the matched set. - * @param swtch A Boolean (not just truthy/falsy) value to determine whether the class should be added or removed. - */ - toggleClass(className: string, swtch?: boolean): JQuery; - /** - * Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument. - * - * @param swtch A boolean value to determine whether the class should be added or removed. - */ - toggleClass(swtch?: boolean): JQuery; - /** - * Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument. - * - * @param func A function that returns class names to be toggled in the class attribute of each element in the matched set. Receives the index position of the element in the set, the old class value, and the switch as arguments. - * @param swtch A boolean value to determine whether the class should be added or removed. - */ - toggleClass(func: (index: number, className: string, swtch: boolean) => string, swtch?: boolean): JQuery; - - /** - * Get the current value of the first element in the set of matched elements. - */ - val(): any; - /** - * Set the value of each element in the set of matched elements. - * - * @param value A string of text, an array of strings or number corresponding to the value of each matched element to set as selected/checked. - */ - val(value: string|string[]|number): JQuery; - /** - * Set the value of each element in the set of matched elements. - * - * @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments. - */ - val(func: (index: number, value: string) => string): JQuery; - - - /** - * Get the value of style properties for the first element in the set of matched elements. - * - * @param propertyName A CSS property. - */ - css(propertyName: string): string; - /** - * Set one or more CSS properties for the set of matched elements. - * - * @param propertyName A CSS property name. - * @param value A value to set for the property. - */ - css(propertyName: string, value: string|number): JQuery; - /** - * Set one or more CSS properties for the set of matched elements. - * - * @param propertyName A CSS property name. - * @param value A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments. - */ - css(propertyName: string, value: (index: number, value: string) => string|number): JQuery; - /** - * Set one or more CSS properties for the set of matched elements. - * - * @param properties An object of property-value pairs to set. - */ - css(properties: Object): JQuery; - - /** - * Get the current computed height for the first element in the set of matched elements. - */ - height(): number; - /** - * Set the CSS height of every matched element. - * - * @param value An integer representing the number of pixels, or an integer with an optional unit of measure appended (as a string). - */ - height(value: number|string): JQuery; - /** - * Set the CSS height of every matched element. - * - * @param func A function returning the height to set. Receives the index position of the element in the set and the old height as arguments. Within the function, this refers to the current element in the set. - */ - height(func: (index: number, height: number) => number|string): JQuery; - - /** - * Get the current computed height for the first element in the set of matched elements, including padding but not border. - */ - innerHeight(): number; - - /** - * Sets the inner height on elements in the set of matched elements, including padding but not border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - innerHeight(height: number|string): JQuery; - - /** - * Get the current computed width for the first element in the set of matched elements, including padding but not border. - */ - innerWidth(): number; - - /** - * Sets the inner width on elements in the set of matched elements, including padding but not border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - innerWidth(width: number|string): JQuery; - - /** - * Get the current coordinates of the first element in the set of matched elements, relative to the document. - */ - offset(): JQueryCoordinates; - /** - * An object containing the properties top and left, which are integers indicating the new top and left coordinates for the elements. - * - * @param coordinates An object containing the properties top and left, which are integers indicating the new top and left coordinates for the elements. - */ - offset(coordinates: JQueryCoordinates): JQuery; - /** - * An object containing the properties top and left, which are integers indicating the new top and left coordinates for the elements. - * - * @param func A function to return the coordinates to set. Receives the index of the element in the collection as the first argument and the current coordinates as the second argument. The function should return an object with the new top and left properties. - */ - offset(func: (index: number, coords: JQueryCoordinates) => JQueryCoordinates): JQuery; - - /** - * Get the current computed height for the first element in the set of matched elements, including padding, border, and optionally margin. Returns an integer (without "px") representation of the value or null if called on an empty set of elements. - * - * @param includeMargin A Boolean indicating whether to include the element's margin in the calculation. - */ - outerHeight(includeMargin?: boolean): number; - - /** - * Sets the outer height on elements in the set of matched elements, including padding and border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - outerHeight(height: number|string): JQuery; - - /** - * Get the current computed width for the first element in the set of matched elements, including padding and border. - * - * @param includeMargin A Boolean indicating whether to include the element's margin in the calculation. - */ - outerWidth(includeMargin?: boolean): number; - - /** - * Sets the outer width on elements in the set of matched elements, including padding and border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - outerWidth(width: number|string): JQuery; - - /** - * Get the current coordinates of the first element in the set of matched elements, relative to the offset parent. - */ - position(): JQueryCoordinates; - - /** - * Get the current horizontal position of the scroll bar for the first element in the set of matched elements or set the horizontal position of the scroll bar for every matched element. - */ - scrollLeft(): number; - /** - * Set the current horizontal position of the scroll bar for each of the set of matched elements. - * - * @param value An integer indicating the new position to set the scroll bar to. - */ - scrollLeft(value: number): JQuery; - - /** - * Get the current vertical position of the scroll bar for the first element in the set of matched elements or set the vertical position of the scroll bar for every matched element. - */ - scrollTop(): number; - /** - * Set the current vertical position of the scroll bar for each of the set of matched elements. - * - * @param value An integer indicating the new position to set the scroll bar to. - */ - scrollTop(value: number): JQuery; - - /** - * Get the current computed width for the first element in the set of matched elements. - */ - width(): number; - /** - * Set the CSS width of each element in the set of matched elements. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - width(value: number|string): JQuery; - /** - * Set the CSS width of each element in the set of matched elements. - * - * @param func A function returning the width to set. Receives the index position of the element in the set and the old width as arguments. Within the function, this refers to the current element in the set. - */ - width(func: (index: number, width: number) => number|string): JQuery; - - /** - * Remove from the queue all items that have not yet been run. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - clearQueue(queueName?: string): JQuery; - - /** - * Store arbitrary data associated with the matched elements. - * - * @param key A string naming the piece of data to set. - * @param value The new data value; it can be any Javascript type including Array or Object. - */ - data(key: string, value: any): JQuery; - /** - * Return the value at the named data store for the first element in the jQuery collection, as set by data(name, value) or by an HTML5 data-* attribute. - * - * @param key Name of the data stored. - */ - data(key: string): any; - /** - * Store arbitrary data associated with the matched elements. - * - * @param obj An object of key-value pairs of data to update. - */ - data(obj: { [key: string]: any; }): JQuery; - /** - * Return the value at the named data store for the first element in the jQuery collection, as set by data(name, value) or by an HTML5 data-* attribute. - */ - data(): any; - - /** - * Execute the next function on the queue for the matched elements. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - dequeue(queueName?: string): JQuery; - - /** - * Remove a previously-stored piece of data. - * - * @param name A string naming the piece of data to delete or space-separated string naming the pieces of data to delete. - */ - removeData(name: string): JQuery; - /** - * Remove a previously-stored piece of data. - * - * @param list An array of strings naming the pieces of data to delete. - */ - removeData(list: string[]): JQuery; - /** - * Remove all previously-stored piece of data. - */ - removeData(): JQuery; - - /** - * Return a Promise object to observe when all actions of a certain type bound to the collection, queued or not, have finished. - * - * @param type The type of queue that needs to be observed. (default: fx) - * @param target Object onto which the promise methods have to be attached - */ - promise(type?: string, target?: Object): JQueryPromise; - - /** - * Perform a custom animation of a set of CSS properties. - * - * @param properties An object of CSS properties and values that the animation will move toward. - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - animate(properties: Object, duration?: string|number, complete?: Function): JQuery; - /** - * Perform a custom animation of a set of CSS properties. - * - * @param properties An object of CSS properties and values that the animation will move toward. - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. (default: swing) - * @param complete A function to call once the animation is complete. - */ - animate(properties: Object, duration?: string|number, easing?: string, complete?: Function): JQuery; - /** - * Perform a custom animation of a set of CSS properties. - * - * @param properties An object of CSS properties and values that the animation will move toward. - * @param options A map of additional options to pass to the method. - */ - animate(properties: Object, options: JQueryAnimationOptions): JQuery; - - /** - * Set a timer to delay execution of subsequent items in the queue. - * - * @param duration An integer indicating the number of milliseconds to delay execution of the next item in the queue. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - delay(duration: number, queueName?: string): JQuery; - - /** - * Display the matched elements by fading them to opaque. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - fadeIn(duration?: number|string, complete?: Function): JQuery; - /** - * Display the matched elements by fading them to opaque. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeIn(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display the matched elements by fading them to opaque. - * - * @param options A map of additional options to pass to the method. - */ - fadeIn(options: JQueryAnimationOptions): JQuery; - - /** - * Hide the matched elements by fading them to transparent. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - fadeOut(duration?: number|string, complete?: Function): JQuery; - /** - * Hide the matched elements by fading them to transparent. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeOut(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Hide the matched elements by fading them to transparent. - * - * @param options A map of additional options to pass to the method. - */ - fadeOut(options: JQueryAnimationOptions): JQuery; - - /** - * Adjust the opacity of the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param opacity A number between 0 and 1 denoting the target opacity. - * @param complete A function to call once the animation is complete. - */ - fadeTo(duration: string|number, opacity: number, complete?: Function): JQuery; - /** - * Adjust the opacity of the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param opacity A number between 0 and 1 denoting the target opacity. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeTo(duration: string|number, opacity: number, easing?: string, complete?: Function): JQuery; - - /** - * Display or hide the matched elements by animating their opacity. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - fadeToggle(duration?: number|string, complete?: Function): JQuery; - /** - * Display or hide the matched elements by animating their opacity. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeToggle(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display or hide the matched elements by animating their opacity. - * - * @param options A map of additional options to pass to the method. - */ - fadeToggle(options: JQueryAnimationOptions): JQuery; - - /** - * Stop the currently-running animation, remove all queued animations, and complete all animations for the matched elements. - * - * @param queue The name of the queue in which to stop animations. - */ - finish(queue?: string): JQuery; - - /** - * Hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - hide(duration?: number|string, complete?: Function): JQuery; - /** - * Hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - hide(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Hide the matched elements. - * - * @param options A map of additional options to pass to the method. - */ - hide(options: JQueryAnimationOptions): JQuery; - - /** - * Display the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - show(duration?: number|string, complete?: Function): JQuery; - /** - * Display the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - show(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display the matched elements. - * - * @param options A map of additional options to pass to the method. - */ - show(options: JQueryAnimationOptions): JQuery; - - /** - * Display the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - slideDown(duration?: number|string, complete?: Function): JQuery; - /** - * Display the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - slideDown(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display the matched elements with a sliding motion. - * - * @param options A map of additional options to pass to the method. - */ - slideDown(options: JQueryAnimationOptions): JQuery; - - /** - * Display or hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - slideToggle(duration?: number|string, complete?: Function): JQuery; - /** - * Display or hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - slideToggle(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display or hide the matched elements with a sliding motion. - * - * @param options A map of additional options to pass to the method. - */ - slideToggle(options: JQueryAnimationOptions): JQuery; - - /** - * Hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - slideUp(duration?: number|string, complete?: Function): JQuery; - /** - * Hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - slideUp(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Hide the matched elements with a sliding motion. - * - * @param options A map of additional options to pass to the method. - */ - slideUp(options: JQueryAnimationOptions): JQuery; - - /** - * Stop the currently-running animation on the matched elements. - * - * @param clearQueue A Boolean indicating whether to remove queued animation as well. Defaults to false. - * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately. Defaults to false. - */ - stop(clearQueue?: boolean, jumpToEnd?: boolean): JQuery; - /** - * Stop the currently-running animation on the matched elements. - * - * @param queue The name of the queue in which to stop animations. - * @param clearQueue A Boolean indicating whether to remove queued animation as well. Defaults to false. - * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately. Defaults to false. - */ - stop(queue?: string, clearQueue?: boolean, jumpToEnd?: boolean): JQuery; - - /** - * Display or hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - toggle(duration?: number|string, complete?: Function): JQuery; - /** - * Display or hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - toggle(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display or hide the matched elements. - * - * @param options A map of additional options to pass to the method. - */ - toggle(options: JQueryAnimationOptions): JQuery; - /** - * Display or hide the matched elements. - * - * @param showOrHide A Boolean indicating whether to show or hide the elements. - */ - toggle(showOrHide: boolean): JQuery; - - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - bind(eventType: string, eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param handler A function to execute each time the event is triggered. - */ - bind(eventType: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param eventData An object containing data that will be passed to the event handler. - * @param preventBubble Setting the third argument to false will attach a function that prevents the default action from occurring and stops the event from bubbling. The default is true. - */ - bind(eventType: string, eventData: any, preventBubble: boolean): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param preventBubble Setting the third argument to false will attach a function that prevents the default action from occurring and stops the event from bubbling. The default is true. - */ - bind(eventType: string, preventBubble: boolean): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param events An object containing one or more DOM event types and functions to execute for them. - */ - bind(events: any): JQuery; - - /** - * Trigger the "blur" event on an element - */ - blur(): JQuery; - /** - * Bind an event handler to the "blur" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - blur(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "blur" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - blur(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "change" event on an element. - */ - change(): JQuery; - /** - * Bind an event handler to the "change" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - change(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "change" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - change(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "click" event on an element. - */ - click(): JQuery; - /** - * Bind an event handler to the "click" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - */ - click(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "click" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - click(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "dblclick" event on an element. - */ - dblclick(): JQuery; - /** - * Bind an event handler to the "dblclick" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - dblclick(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "dblclick" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - dblclick(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - delegate(selector: any, eventType: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - delegate(selector: any, eventType: string, eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "focus" event on an element. - */ - focus(): JQuery; - /** - * Bind an event handler to the "focus" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - focus(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "focus" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - focus(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "focusin" event on an element. - */ - focusin(): JQuery; - /** - * Bind an event handler to the "focusin" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - focusin(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "focusin" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - focusin(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "focusout" event on an element. - */ - focusout(): JQuery; - /** - * Bind an event handler to the "focusout" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - focusout(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "focusout" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - focusout(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Bind two handlers to the matched elements, to be executed when the mouse pointer enters and leaves the elements. - * - * @param handlerIn A function to execute when the mouse pointer enters the element. - * @param handlerOut A function to execute when the mouse pointer leaves the element. - */ - hover(handlerIn: (eventObject: JQueryEventObject) => any, handlerOut: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind a single handler to the matched elements, to be executed when the mouse pointer enters or leaves the elements. - * - * @param handlerInOut A function to execute when the mouse pointer enters or leaves the element. - */ - hover(handlerInOut: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "keydown" event on an element. - */ - keydown(): JQuery; - /** - * Bind an event handler to the "keydown" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - keydown(handler: (eventObject: JQueryKeyEventObject) => any): JQuery; - /** - * Bind an event handler to the "keydown" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - keydown(eventData?: any, handler?: (eventObject: JQueryKeyEventObject) => any): JQuery; - - /** - * Trigger the "keypress" event on an element. - */ - keypress(): JQuery; - /** - * Bind an event handler to the "keypress" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - keypress(handler: (eventObject: JQueryKeyEventObject) => any): JQuery; - /** - * Bind an event handler to the "keypress" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - keypress(eventData?: any, handler?: (eventObject: JQueryKeyEventObject) => any): JQuery; - - /** - * Trigger the "keyup" event on an element. - */ - keyup(): JQuery; - /** - * Bind an event handler to the "keyup" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - keyup(handler: (eventObject: JQueryKeyEventObject) => any): JQuery; - /** - * Bind an event handler to the "keyup" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - keyup(eventData?: any, handler?: (eventObject: JQueryKeyEventObject) => any): JQuery; - - /** - * Bind an event handler to the "load" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - load(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "load" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - load(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "mousedown" event on an element. - */ - mousedown(): JQuery; - /** - * Bind an event handler to the "mousedown" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mousedown(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mousedown" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mousedown(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseenter" event on an element. - */ - mouseenter(): JQuery; - /** - * Bind an event handler to be fired when the mouse enters an element. - * - * @param handler A function to execute when the event is triggered. - */ - mouseenter(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to be fired when the mouse enters an element. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseenter(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseleave" event on an element. - */ - mouseleave(): JQuery; - /** - * Bind an event handler to be fired when the mouse leaves an element. - * - * @param handler A function to execute when the event is triggered. - */ - mouseleave(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to be fired when the mouse leaves an element. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseleave(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mousemove" event on an element. - */ - mousemove(): JQuery; - /** - * Bind an event handler to the "mousemove" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mousemove(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mousemove" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mousemove(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseout" event on an element. - */ - mouseout(): JQuery; - /** - * Bind an event handler to the "mouseout" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mouseout(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mouseout" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseout(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseover" event on an element. - */ - mouseover(): JQuery; - /** - * Bind an event handler to the "mouseover" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mouseover(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mouseover" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseover(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseup" event on an element. - */ - mouseup(): JQuery; - /** - * Bind an event handler to the "mouseup" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mouseup(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mouseup" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseup(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Remove an event handler. - */ - off(): JQuery; - /** - * Remove an event handler. - * - * @param events One or more space-separated event types and optional namespaces, or just namespaces, such as "click", "keydown.myPlugin", or ".myPlugin". - * @param selector A selector which should match the one originally passed to .on() when attaching event handlers. - * @param handler A handler function previously attached for the event(s), or the special value false. - */ - off(events: string, selector?: string, handler?: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove an event handler. - * - * @param events One or more space-separated event types and optional namespaces, or just namespaces, such as "click", "keydown.myPlugin", or ".myPlugin". - * @param handler A handler function previously attached for the event(s), or the special value false. Takes handler with extra args that can be attached with on(). - */ - off(events: string, handler: (eventObject: JQueryEventObject, ...args: any[]) => any): JQuery; - /** - * Remove an event handler. - * - * @param events One or more space-separated event types and optional namespaces, or just namespaces, such as "click", "keydown.myPlugin", or ".myPlugin". - * @param handler A handler function previously attached for the event(s), or the special value false. - */ - off(events: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove an event handler. - * - * @param events An object where the string keys represent one or more space-separated event types and optional namespaces, and the values represent handler functions previously attached for the event(s). - * @param selector A selector which should match the one originally passed to .on() when attaching event handlers. - */ - off(events: { [key: string]: any; }, selector?: string): JQuery; - - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. Rest parameter args is for optional parameters passed to jQuery.trigger(). Note that the actual parameters on the event handler function must be marked as optional (? syntax). - */ - on(events: string, handler: (eventObject: JQueryEventObject, ...args: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param data Data to be passed to the handler in event.data when an event is triggered. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - on(events: string, data : any, handler: (eventObject: JQueryEventObject, ...args: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - on(events: string, selector: string, handler: (eventObject: JQueryEventObject, ...eventData: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event is triggered. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - on(events: string, selector: string, data: any, handler: (eventObject: JQueryEventObject, ...eventData: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param selector A selector string to filter the descendants of the selected elements that will call the handler. If the selector is null or omitted, the handler is always called when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - on(events: { [key: string]: any; }, selector?: string, data?: any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - on(events: { [key: string]: any; }, data?: any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names. - * @param handler A function to execute at the time the event is triggered. - */ - one(events: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names. - * @param data An object containing data that will be passed to the event handler. - * @param handler A function to execute at the time the event is triggered. - */ - one(events: string, data: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - one(events: string, selector: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event is triggered. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - one(events: string, selector: string, data: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param selector A selector string to filter the descendants of the selected elements that will call the handler. If the selector is null or omitted, the handler is always called when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - one(events: { [key: string]: any; }, selector?: string, data?: any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - one(events: { [key: string]: any; }, data?: any): JQuery; - - - /** - * Specify a function to execute when the DOM is fully loaded. - * - * @param handler A function to execute after the DOM is ready. - */ - ready(handler: (jQueryAlias?: JQueryStatic) => any): JQuery; - - /** - * Trigger the "resize" event on an element. - */ - resize(): JQuery; - /** - * Bind an event handler to the "resize" JavaScript event. - * - * @param handler A function to execute each time the event is triggered. - */ - resize(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "resize" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - resize(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "scroll" event on an element. - */ - scroll(): JQuery; - /** - * Bind an event handler to the "scroll" JavaScript event. - * - * @param handler A function to execute each time the event is triggered. - */ - scroll(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "scroll" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - scroll(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "select" event on an element. - */ - select(): JQuery; - /** - * Bind an event handler to the "select" JavaScript event. - * - * @param handler A function to execute each time the event is triggered. - */ - select(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "select" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - select(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "submit" event on an element. - */ - submit(): JQuery; - /** - * Bind an event handler to the "submit" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - submit(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "submit" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - submit(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Execute all handlers and behaviors attached to the matched elements for the given event type. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param extraParameters Additional parameters to pass along to the event handler. - */ - trigger(eventType: string, extraParameters?: any[]|Object): JQuery; - /** - * Execute all handlers and behaviors attached to the matched elements for the given event type. - * - * @param event A jQuery.Event object. - * @param extraParameters Additional parameters to pass along to the event handler. - */ - trigger(event: JQueryEventObject, extraParameters?: any[]|Object): JQuery; - - /** - * Execute all handlers attached to an element for an event. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param extraParameters An array of additional parameters to pass along to the event handler. - */ - triggerHandler(eventType: string, ...extraParameters: any[]): Object; - - /** - * Execute all handlers attached to an element for an event. - * - * @param event A jQuery.Event object. - * @param extraParameters An array of additional parameters to pass along to the event handler. - */ - triggerHandler(event: JQueryEventObject, ...extraParameters: any[]): Object; - - /** - * Remove a previously-attached event handler from the elements. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param handler The function that is to be no longer executed. - */ - unbind(eventType?: string, handler?: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove a previously-attached event handler from the elements. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param fls Unbinds the corresponding 'return false' function that was bound using .bind( eventType, false ). - */ - unbind(eventType: string, fls: boolean): JQuery; - /** - * Remove a previously-attached event handler from the elements. - * - * @param evt A JavaScript event object as passed to an event handler. - */ - unbind(evt: any): JQuery; - - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - */ - undelegate(): JQuery; - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - * - * @param selector A selector which will be used to filter the event results. - * @param eventType A string containing a JavaScript event type, such as "click" or "keydown" - * @param handler A function to execute at the time the event is triggered. - */ - undelegate(selector: string, eventType: string, handler?: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - * - * @param selector A selector which will be used to filter the event results. - * @param events An object of one or more event types and previously bound functions to unbind from them. - */ - undelegate(selector: string, events: Object): JQuery; - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - * - * @param namespace A string containing a namespace to unbind all events from. - */ - undelegate(namespace: string): JQuery; - - /** - * Bind an event handler to the "unload" JavaScript event. (DEPRECATED from v1.8) - * - * @param handler A function to execute when the event is triggered. - */ - unload(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "unload" JavaScript event. (DEPRECATED from v1.8) - * - * @param eventData A plain object of data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - unload(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * The DOM node context originally passed to jQuery(); if none was passed then context will likely be the document. (DEPRECATED from v1.10) - */ - context: Element; - - jquery: string; - - /** - * Bind an event handler to the "error" JavaScript event. (DEPRECATED from v1.8) - * - * @param handler A function to execute when the event is triggered. - */ - error(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "error" JavaScript event. (DEPRECATED from v1.8) - * - * @param eventData A plain object of data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - error(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Add a collection of DOM elements onto the jQuery stack. - * - * @param elements An array of elements to push onto the stack and make into a new jQuery object. - */ - pushStack(elements: any[]): JQuery; - /** - * Add a collection of DOM elements onto the jQuery stack. - * - * @param elements An array of elements to push onto the stack and make into a new jQuery object. - * @param name The name of a jQuery method that generated the array of elements. - * @param arguments The arguments that were passed in to the jQuery method (for serialization). - */ - pushStack(elements: any[], name: string, arguments: any[]): JQuery; - - /** - * Insert content, specified by the parameter, after each element in the set of matched elements. - * - * param content1 HTML string, DOM element, array of elements, or jQuery object to insert after each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert after each element in the set of matched elements. - */ - after(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, after each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert after each element in the set of matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - after(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Insert content, specified by the parameter, to the end of each element in the set of matched elements. - * - * param content1 DOM element, array of elements, HTML string, or jQuery object to insert at the end of each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert at the end of each element in the set of matched elements. - */ - append(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, to the end of each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert at the end of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set. - */ - append(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Insert every element in the set of matched elements to the end of the target. - * - * @param target A selector, element, HTML string, array of elements, or jQuery object; the matched set of elements will be inserted at the end of the element(s) specified by this parameter. - */ - appendTo(target: JQuery|any[]|Element|string): JQuery; - - /** - * Insert content, specified by the parameter, before each element in the set of matched elements. - * - * param content1 HTML string, DOM element, array of elements, or jQuery object to insert before each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert before each element in the set of matched elements. - */ - before(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, before each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert before each element in the set of matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - before(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Create a deep copy of the set of matched elements. - * - * param withDataAndEvents A Boolean indicating whether event handlers and data should be copied along with the elements. The default value is false. - * param deepWithDataAndEvents A Boolean indicating whether event handlers and data for all children of the cloned element should be copied. By default its value matches the first argument's value (which defaults to false). - */ - clone(withDataAndEvents?: boolean, deepWithDataAndEvents?: boolean): JQuery; - - /** - * Remove the set of matched elements from the DOM. - * - * param selector A selector expression that filters the set of matched elements to be removed. - */ - detach(selector?: string): JQuery; - - /** - * Remove all child nodes of the set of matched elements from the DOM. - */ - empty(): JQuery; - - /** - * Insert every element in the set of matched elements after the target. - * - * param target A selector, element, array of elements, HTML string, or jQuery object; the matched set of elements will be inserted after the element(s) specified by this parameter. - */ - insertAfter(target: JQuery|any[]|Element|Text|string): JQuery; - - /** - * Insert every element in the set of matched elements before the target. - * - * param target A selector, element, array of elements, HTML string, or jQuery object; the matched set of elements will be inserted before the element(s) specified by this parameter. - */ - insertBefore(target: JQuery|any[]|Element|Text|string): JQuery; - - /** - * Insert content, specified by the parameter, to the beginning of each element in the set of matched elements. - * - * param content1 DOM element, array of elements, HTML string, or jQuery object to insert at the beginning of each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert at the beginning of each element in the set of matched elements. - */ - prepend(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, to the beginning of each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert at the beginning of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set. - */ - prepend(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Insert every element in the set of matched elements to the beginning of the target. - * - * @param target A selector, element, HTML string, array of elements, or jQuery object; the matched set of elements will be inserted at the beginning of the element(s) specified by this parameter. - */ - prependTo(target: JQuery|any[]|Element|string): JQuery; - - /** - * Remove the set of matched elements from the DOM. - * - * @param selector A selector expression that filters the set of matched elements to be removed. - */ - remove(selector?: string): JQuery; - - /** - * Replace each target element with the set of matched elements. - * - * @param target A selector string, jQuery object, DOM element, or array of elements indicating which element(s) to replace. - */ - replaceAll(target: JQuery|any[]|Element|string): JQuery; - - /** - * Replace each element in the set of matched elements with the provided new content and return the set of elements that was removed. - * - * param newContent The content to insert. May be an HTML string, DOM element, array of DOM elements, or jQuery object. - */ - replaceWith(newContent: JQuery|any[]|Element|Text|string): JQuery; - /** - * Replace each element in the set of matched elements with the provided new content and return the set of elements that was removed. - * - * param func A function that returns content with which to replace the set of matched elements. - */ - replaceWith(func: () => Element|JQuery): JQuery; - - /** - * Get the combined text contents of each element in the set of matched elements, including their descendants. - */ - text(): string; - /** - * Set the content of each element in the set of matched elements to the specified text. - * - * @param text The text to set as the content of each matched element. When Number or Boolean is supplied, it will be converted to a String representation. - */ - text(text: string|number|boolean): JQuery; - /** - * Set the content of each element in the set of matched elements to the specified text. - * - * @param func A function returning the text content to set. Receives the index position of the element in the set and the old text value as arguments. - */ - text(func: (index: number, text: string) => string): JQuery; - - /** - * Retrieve all the elements contained in the jQuery set, as an array. - */ - toArray(): any[]; - - /** - * Remove the parents of the set of matched elements from the DOM, leaving the matched elements in their place. - */ - unwrap(): JQuery; - - /** - * Wrap an HTML structure around each element in the set of matched elements. - * - * @param wrappingElement A selector, element, HTML string, or jQuery object specifying the structure to wrap around the matched elements. - */ - wrap(wrappingElement: JQuery|Element|string): JQuery; - /** - * Wrap an HTML structure around each element in the set of matched elements. - * - * @param func A callback function returning the HTML content or jQuery object to wrap around the matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - wrap(func: (index: number) => string|JQuery): JQuery; - - /** - * Wrap an HTML structure around all elements in the set of matched elements. - * - * @param wrappingElement A selector, element, HTML string, or jQuery object specifying the structure to wrap around the matched elements. - */ - wrapAll(wrappingElement: JQuery|Element|string): JQuery; - wrapAll(func: (index: number) => string): JQuery; - - /** - * Wrap an HTML structure around the content of each element in the set of matched elements. - * - * @param wrappingElement An HTML snippet, selector expression, jQuery object, or DOM element specifying the structure to wrap around the content of the matched elements. - */ - wrapInner(wrappingElement: JQuery|Element|string): JQuery; - /** - * Wrap an HTML structure around the content of each element in the set of matched elements. - * - * @param func A callback function which generates a structure to wrap around the content of the matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - wrapInner(func: (index: number) => string): JQuery; - - /** - * Iterate over a jQuery object, executing a function for each matched element. - * - * @param func A function to execute for each matched element. - */ - each(func: (index: number, elem: Element) => any): JQuery; - - /** - * Retrieve one of the elements matched by the jQuery object. - * - * @param index A zero-based integer indicating which element to retrieve. - */ - get(index: number): HTMLElement; - /** - * Retrieve the elements matched by the jQuery object. - */ - get(): any[]; - - /** - * Search for a given element from among the matched elements. - */ - index(): number; - /** - * Search for a given element from among the matched elements. - * - * @param selector A selector representing a jQuery collection in which to look for an element. - */ - index(selector: string|JQuery|Element): number; - - /** - * The number of elements in the jQuery object. - */ - length: number; - /** - * A selector representing selector passed to jQuery(), if any, when creating the original set. - * version deprecated: 1.7, removed: 1.9 - */ - selector: string; - [index: string]: any; - [index: number]: HTMLElement; - - /** - * Add elements to the set of matched elements. - * - * @param selector A string representing a selector expression to find additional elements to add to the set of matched elements. - * @param context The point in the document at which the selector should begin matching; similar to the context argument of the $(selector, context) method. - */ - add(selector: string, context?: Element): JQuery; - /** - * Add elements to the set of matched elements. - * - * @param elements One or more elements to add to the set of matched elements. - */ - add(...elements: Element[]): JQuery; - /** - * Add elements to the set of matched elements. - * - * @param html An HTML fragment to add to the set of matched elements. - */ - add(html: string): JQuery; - /** - * Add elements to the set of matched elements. - * - * @param obj An existing jQuery object to add to the set of matched elements. - */ - add(obj: JQuery): JQuery; - - /** - * Get the children of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - children(selector?: string): JQuery; - - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param selector A string containing a selector expression to match elements against. - */ - closest(selector: string): JQuery; - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param selector A string containing a selector expression to match elements against. - * @param context A DOM element within which a matching element may be found. If no context is passed in then the context of the jQuery set will be used instead. - */ - closest(selector: string, context?: Element): JQuery; - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param obj A jQuery object to match elements against. - */ - closest(obj: JQuery): JQuery; - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param element An element to match elements against. - */ - closest(element: Element): JQuery; - - /** - * Get an array of all the elements and selectors matched against the current element up through the DOM tree. - * - * @param selectors An array or string containing a selector expression to match elements against (can also be a jQuery object). - * @param context A DOM element within which a matching element may be found. If no context is passed in then the context of the jQuery set will be used instead. - */ - closest(selectors: any, context?: Element): any[]; - - /** - * Get the children of each element in the set of matched elements, including text and comment nodes. - */ - contents(): JQuery; - - /** - * End the most recent filtering operation in the current chain and return the set of matched elements to its previous state. - */ - end(): JQuery; - - /** - * Reduce the set of matched elements to the one at the specified index. - * - * @param index An integer indicating the 0-based position of the element. OR An integer indicating the position of the element, counting backwards from the last element in the set. - * - */ - eq(index: number): JQuery; - - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param selector A string containing a selector expression to match the current set of elements against. - */ - filter(selector: string): JQuery; - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param func A function used as a test for each element in the set. this is the current DOM element. - */ - filter(func: (index: number, element: Element) => any): JQuery; - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param element An element to match the current set of elements against. - */ - filter(element: Element): JQuery; - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param obj An existing jQuery object to match the current set of elements against. - */ - filter(obj: JQuery): JQuery; - - /** - * Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element. - * - * @param selector A string containing a selector expression to match elements against. - */ - find(selector: string): JQuery; - /** - * Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element. - * - * @param element An element to match elements against. - */ - find(element: Element): JQuery; - /** - * Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element. - * - * @param obj A jQuery object to match elements against. - */ - find(obj: JQuery): JQuery; - - /** - * Reduce the set of matched elements to the first in the set. - */ - first(): JQuery; - - /** - * Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element. - * - * @param selector A string containing a selector expression to match elements against. - */ - has(selector: string): JQuery; - /** - * Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element. - * - * @param contained A DOM element to match elements against. - */ - has(contained: Element): JQuery; - - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param selector A string containing a selector expression to match elements against. - */ - is(selector: string): boolean; - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param func A function used as a test for the set of elements. It accepts one argument, index, which is the element's index in the jQuery collection.Within the function, this refers to the current DOM element. - */ - is(func: (index: number, element: Element) => boolean): boolean; - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param obj An existing jQuery object to match the current set of elements against. - */ - is(obj: JQuery): boolean; - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param elements One or more elements to match the current set of elements against. - */ - is(elements: any): boolean; - - /** - * Reduce the set of matched elements to the final one in the set. - */ - last(): JQuery; - - /** - * Pass each element in the current matched set through a function, producing a new jQuery object containing the return values. - * - * @param callback A function object that will be invoked for each element in the current set. - */ - map(callback: (index: number, domElement: Element) => any): JQuery; - - /** - * Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - next(selector?: string): JQuery; - - /** - * Get all following siblings of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - nextAll(selector?: string): JQuery; - - /** - * Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed. - * - * @param selector A string containing a selector expression to indicate where to stop matching following sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - nextUntil(selector?: string, filter?: string): JQuery; - /** - * Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed. - * - * @param element A DOM node or jQuery object indicating where to stop matching following sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - nextUntil(element?: Element, filter?: string): JQuery; - /** - * Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed. - * - * @param obj A DOM node or jQuery object indicating where to stop matching following sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - nextUntil(obj?: JQuery, filter?: string): JQuery; - - /** - * Remove elements from the set of matched elements. - * - * @param selector A string containing a selector expression to match elements against. - */ - not(selector: string): JQuery; - /** - * Remove elements from the set of matched elements. - * - * @param func A function used as a test for each element in the set. this is the current DOM element. - */ - not(func: (index: number, element: Element) => boolean): JQuery; - /** - * Remove elements from the set of matched elements. - * - * @param elements One or more DOM elements to remove from the matched set. - */ - not(elements: Element|Element[]): JQuery; - /** - * Remove elements from the set of matched elements. - * - * @param obj An existing jQuery object to match the current set of elements against. - */ - not(obj: JQuery): JQuery; - - /** - * Get the closest ancestor element that is positioned. - */ - offsetParent(): JQuery; - - /** - * Get the parent of each element in the current set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - parent(selector?: string): JQuery; - - /** - * Get the ancestors of each element in the current set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - parents(selector?: string): JQuery; - - /** - * Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param selector A string containing a selector expression to indicate where to stop matching ancestor elements. - * @param filter A string containing a selector expression to match elements against. - */ - parentsUntil(selector?: string, filter?: string): JQuery; - /** - * Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param element A DOM node or jQuery object indicating where to stop matching ancestor elements. - * @param filter A string containing a selector expression to match elements against. - */ - parentsUntil(element?: Element, filter?: string): JQuery; - /** - * Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param obj A DOM node or jQuery object indicating where to stop matching ancestor elements. - * @param filter A string containing a selector expression to match elements against. - */ - parentsUntil(obj?: JQuery, filter?: string): JQuery; - - /** - * Get the immediately preceding sibling of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - prev(selector?: string): JQuery; - - /** - * Get all preceding siblings of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - prevAll(selector?: string): JQuery; - - /** - * Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param selector A string containing a selector expression to indicate where to stop matching preceding sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - prevUntil(selector?: string, filter?: string): JQuery; - /** - * Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param element A DOM node or jQuery object indicating where to stop matching preceding sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - prevUntil(element?: Element, filter?: string): JQuery; - /** - * Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param obj A DOM node or jQuery object indicating where to stop matching preceding sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - prevUntil(obj?: JQuery, filter?: string): JQuery; - - /** - * Get the siblings of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - siblings(selector?: string): JQuery; - - /** - * Reduce the set of matched elements to a subset specified by a range of indices. - * - * @param start An integer indicating the 0-based position at which the elements begin to be selected. If negative, it indicates an offset from the end of the set. - * @param end An integer indicating the 0-based position at which the elements stop being selected. If negative, it indicates an offset from the end of the set. If omitted, the range continues until the end of the set. - */ - slice(start: number, end?: number): JQuery; - - /** - * Show the queue of functions to be executed on the matched elements. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - queue(queueName?: string): any[]; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param newQueue An array of functions to replace the current queue contents. - */ - queue(newQueue: Function[]): JQuery; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param callback The new function to add to the queue, with a function to call that will dequeue the next item. - */ - queue(callback: Function): JQuery; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param newQueue An array of functions to replace the current queue contents. - */ - queue(queueName: string, newQueue: Function[]): JQuery; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param callback The new function to add to the queue, with a function to call that will dequeue the next item. - */ - queue(queueName: string, callback: Function): JQuery; -} -declare module "jquery" { - export = $; -} -declare var jQuery: JQueryStatic; -declare var $: JQueryStatic; \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/jquery/typings.json b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/jquery/typings.json deleted file mode 100644 index 0af7c54b42..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/globals/jquery/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/4cdfbe96b666eec5e1defbb519a62abf04e96764/jquery/jquery.d.ts", - "raw": "registry:dt/jquery#1.10.0+20160417213236", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/4cdfbe96b666eec5e1defbb519a62abf04e96764/jquery/jquery.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/index.d.ts b/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/index.d.ts deleted file mode 100644 index 7b1af70fde..0000000000 --- a/public/docs/_examples/upgrade-phonecat-1-typescript/ts/typings-ng1/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/// -/// -/// -/// -/// -/// diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/README.md b/public/docs/_examples/upgrade-phonecat-2-hybrid/README.md index 31fd100e68..b005739148 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/README.md +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/README.md @@ -3,20 +3,17 @@ structure. The following changes from vanilla Phonecat are applied: -* Karma config for unit tests is in karma.conf.ng1.js because the boilerplate - Karma config is not compatible with the way Angular 1 tests need to be run. +* Karma config for unit tests is in karma.conf.ajs.js because the boilerplate + Karma config is not compatible with the way AngularJS tests need to be run. The shell script run-unit-tests.sh can be used to run the unit tests. -* There's a `package.ng1.json`, which is not used to run anything but only to +* There's a `package.ajs.json`, which is not used to run anything but only to show an example of changing the PhoneCat http-server root path. * Also for the Karma shim, there is a `karma-test-shim.1.js` file which isn't used but is shown in the test appendix. -* Instead of using Bower, Angular 1 and its dependencies are fetched from a CDN - in index.html and karma.conf.ng1.js. +* Instead of using Bower, AngularJS and its dependencies are fetched from a CDN + in index.html and karma.conf.ajs.js. * E2E tests have been moved to the parent directory, where `run-e2e-tests` can discover and run them along with all the other examples. -* Angular 1 typings (from DefinitelyTyped) are added to typings-ng1 so that - TypeScript can recognize Angular 1 code. (typings.json comes from boilerplate - so we can't add them there). * Most of the phone JSON and image data removed in the interest of keeping repo weight down. Keeping enough to retain testability of the app. diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/e2e-spec.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/e2e-spec.ts index 6ff865ac8c..2ec8e37977 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/e2e-spec.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/e2e-spec.ts @@ -1,13 +1,15 @@ -/// -'use strict'; +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; +import { setProtractorToHybridMode } from '../protractor-helpers'; // Angular E2E Testing Guide: // https://docs.angularjs.org/guide/e2e-testing describe('PhoneCat Application', function() { - beforeAll(function() { - setProtractorToNg1Mode(); + beforeAll(function () { + setProtractorToHybridMode(); }); it('should redirect `index.html` to `index.html#!/phones', function() { @@ -27,11 +29,11 @@ describe('PhoneCat Application', function() { expect(phoneList.count()).toBe(20); - sendKeys(query, 'nexus'); + query.sendKeys('nexus'); expect(phoneList.count()).toBe(1); query.clear(); - sendKeys(query, 'motorola'); + query.sendKeys('motorola'); expect(phoneList.count()).toBe(8); }); @@ -47,7 +49,7 @@ describe('PhoneCat Application', function() { }); } - sendKeys(queryField, 'tablet'); // Let's narrow the dataset to make the assertions shorter + queryField.sendKeys('tablet'); // Let's narrow the dataset to make the assertions shorter expect(getNames()).toEqual([ 'Motorola XOOM\u2122 with Wi-Fi', @@ -64,10 +66,10 @@ describe('PhoneCat Application', function() { it('should render phone specific links', function() { let query = element(by.css('input')); - sendKeys(query, 'nexus'); + query.sendKeys('nexus'); element.all(by.css('.phones li a')).first().click(); - browser.refresh(); // Not sure why this is needed but it is. The route change works fine. + browser.sleep(200); // Not sure why this is needed but it is. The route change works fine. expect(browser.getLocationAbsUrl()).toBe('/phones/nexus-s'); }); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/.gitignore b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/.gitignore new file mode 100644 index 0000000000..927d62d641 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/.gitignore @@ -0,0 +1,8 @@ +aot/**/* +!aot/index.html +dist +!app/tsconfig.json +!rollup-config.js +!karma.conf.ajs.js +!copy-dist-files.js +!systemjs.config.1.js diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/aot/index.html b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/aot/index.html new file mode 100644 index 0000000000..fdc9584928 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/aot/index.html @@ -0,0 +1,40 @@ + + + + + + + + + Google Phone Gallery + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + + diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/ajs-upgraded-providers.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/ajs-upgraded-providers.ts new file mode 100644 index 0000000000..f6e1654d74 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/ajs-upgraded-providers.ts @@ -0,0 +1,14 @@ +// #docregion +export abstract class RouteParams { + [key: string]: string; +} + +export function routeParamsFactory(i: any) { + return i.get('$routeParams'); +} + +export const routeParamsProvider = { + provide: RouteParams, + useFactory: routeParamsFactory, + deps: ['$injector'] +}; diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.animations.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.animations.ts index 4af94f3d37..f0739b6405 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.animations.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.animations.ts @@ -9,7 +9,7 @@ angular. }; function animateIn(element: JQuery, className: string, done: () => void) { - if (className !== 'selected') return; + if (className !== 'selected') { return; } element.css({ display: 'block', @@ -21,12 +21,12 @@ angular. }, done); return function animateInEnd(wasCanceled: boolean) { - if (wasCanceled) element.stop(); + if (wasCanceled) { element.stop(); } }; } function animateOut(element: JQuery, className: string, done: () => void) { - if (className !== 'selected') return; + if (className !== 'selected') { return; } element.css({ position: 'absolute', @@ -37,7 +37,7 @@ angular. }, done); return function animateOutEnd(wasCanceled: boolean) { - if (wasCanceled) element.stop(); + if (wasCanceled) { element.stop(); } }; } }); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.config.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.config.ts index 72bbb2de49..458ed94250 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.config.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.config.ts @@ -2,8 +2,8 @@ angular. module('phonecatApp'). - config(['$locationProvider' ,'$routeProvider', - function config($locationProvider:angular.ILocationProvider, + config(['$locationProvider', '$routeProvider', + function config($locationProvider: angular.ILocationProvider, $routeProvider: angular.route.IRouteProvider) { $locationProvider.hashPrefix('!'); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.module.ajs.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.module.ajs.ts new file mode 100644 index 0000000000..089c3c7d85 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.module.ajs.ts @@ -0,0 +1,11 @@ +// #docregion +'use strict'; + +// Define the `phonecatApp` AngularJS module +angular.module('phonecatApp', [ + 'ngAnimate', + 'ngRoute', + 'core', + 'phoneDetail', + 'phoneList', +]); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.module.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.module.ts index ab6d353eeb..ea570e3cbf 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.module.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/app.module.ts @@ -1,10 +1,73 @@ -'use strict'; +// #docplaster +// #docregion bare +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +// #enddocregion bare +// #docregion upgrademodule +import { UpgradeModule } from '@angular/upgrade/static'; +// #enddocregion upgrademodule +// #docregion httpmodule +import { HttpModule } from '@angular/http'; +// #enddocregion httpmodule +// #docregion phonelist +import { FormsModule } from '@angular/forms'; +// #enddocregion phonelist +// #docregion phone +import { Phone } from './core/phone/phone.service'; +// #enddocregion phone +// #docregion checkmarkpipe +import { CheckmarkPipe } from './core/checkmark/checkmark.pipe'; +// #enddocregion checkmarkpipe +// #docregion phonelist +import { PhoneListComponent } from './phone-list/phone-list.component'; +// #enddocregion phonelist +// #docregion routeparams +import { routeParamsProvider } from './ajs-upgraded-providers'; +// #enddocregion routeparams +// #docregion phonedetail +import { PhoneDetailComponent } from './phone-detail/phone-detail.component'; +// #enddocregion phonedetail -// Define the `phonecatApp` module -angular.module('phonecatApp', [ - 'ngAnimate', - 'ngRoute', - 'core', - 'phoneDetail', - 'phoneList', -]); +// #docregion bare, upgrademodule, httpmodule, phone, phonelist, phonedetail, checkmarkpipe + +@NgModule({ + imports: [ + BrowserModule, + // #enddocregion bare + UpgradeModule, + // #enddocregion upgrademodule + HttpModule, + // #enddocregion httpmodule, phone + FormsModule, + // #docregion bare, upgrademodule, httpmodule, phone + ], + // #enddocregion bare, upgrademodule, httpmodule, phone + declarations: [ + PhoneListComponent, + // #enddocregion phonelist + PhoneDetailComponent, + // #enddocregion phonedetail + CheckmarkPipe + // #docregion phonelist, phonedetail + ], + entryComponents: [ + PhoneListComponent, + // #enddocregion phonelist + PhoneDetailComponent + ], + // #docregion phone, routeparams + providers: [ + Phone, + // #enddocregion phone + routeParamsProvider + // #docregion phone + ] + // #enddocregion routeparams +// #docregion bare, upgrademodule, httpmodule, phonelist +}) +export class AppModule { + // #enddocregion bare + ngDoBootstrap() {} + // #docregion bare +} +// #enddocregion bare, upgrademodule, httpmodule, phone, phonelist, phonedetail, checkmarkpipe diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.spec.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.spec.ts index 5b9ad15f32..f7485ec2ba 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.spec.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.spec.ts @@ -1,22 +1,11 @@ // #docregion -import { - describe, - beforeEachProviders, - it, - inject, - expect -} from '@angular/core/testing'; import { CheckmarkPipe } from './checkmark.pipe'; describe('CheckmarkPipe', function() { - beforeEachProviders(() => [CheckmarkPipe]); - - it('should convert boolean values to unicode checkmark or cross', - inject([CheckmarkPipe], function(checkmarkPipe: CheckmarkPipe) { - expect(checkmarkPipe.transform(true)).toBe('\u2713'); - expect(checkmarkPipe.transform(false)).toBe('\u2718'); - }) - ); - + it('should convert boolean values to unicode checkmark or cross', function () { + const checkmarkPipe = new CheckmarkPipe(); + expect(checkmarkPipe.transform(true)).toBe('\u2713'); + expect(checkmarkPipe.transform(false)).toBe('\u2718'); + }); }); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.ts index e79b99fc80..888017e15c 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/checkmark/checkmark.pipe.ts @@ -3,9 +3,7 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({name: 'checkmark'}) export class CheckmarkPipe implements PipeTransform { - transform(input: boolean) { return input ? '\u2713' : '\u2718'; } - } diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.spec.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.spec.ts index 9fe842a4e4..a0c1655c20 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.spec.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.spec.ts @@ -1,11 +1,5 @@ // #docregion -import { - describe, - beforeEach, - beforeEachProviders, - it, - inject -} from '@angular/core/testing'; +import { inject, TestBed } from '@angular/core/testing'; import { Http, BaseRequestOptions, @@ -16,37 +10,36 @@ import { MockBackend, MockConnection } from '@angular/http/testing'; import { Phone, PhoneData } from './phone.service'; describe('Phone', function() { - let phone:Phone; - let phonesData:PhoneData[] = [ + let phone: Phone; + let phonesData: PhoneData[] = [ {name: 'Phone X', snippet: '', images: []}, {name: 'Phone Y', snippet: '', images: []}, {name: 'Phone Z', snippet: '', images: []} ]; - let mockBackend:MockBackend; + let mockBackend: MockBackend; - beforeEachProviders(() => [ - Phone, - MockBackend, - BaseRequestOptions, - { provide: Http, - useFactory: (backend: MockBackend, options: BaseRequestOptions) => - new Http(backend, options), - deps: [MockBackend, BaseRequestOptions] - } - ]); + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + Phone, + MockBackend, + BaseRequestOptions, + { provide: Http, + useFactory: (backend: MockBackend, options: BaseRequestOptions) => new Http(backend, options), + deps: [MockBackend, BaseRequestOptions] + } + ] + }); + }); - beforeEach(inject([MockBackend, Phone], - (_mockBackend_:MockBackend, _phone_:Phone) => { + beforeEach(inject([MockBackend, Phone], (_mockBackend_: MockBackend, _phone_: Phone) => { mockBackend = _mockBackend_; phone = _phone_; })); - it('should fetch the phones data from `/phones/phones.json`', - (done: () => void) => { + it('should fetch the phones data from `/phones/phones.json`', (done: () => void) => { mockBackend.connections.subscribe((conn: MockConnection) => { - conn.mockRespond(new Response(new ResponseOptions({ - body: JSON.stringify(phonesData) - }))); + conn.mockRespond(new Response(new ResponseOptions({body: JSON.stringify(phonesData)}))); }); phone.query().subscribe(result => { expect(result).toEqual(phonesData); @@ -55,3 +48,4 @@ describe('Phone', function() { }); }); + diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.ts index b19eea598d..c4673475fb 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/core/phone/phone.service.ts @@ -3,6 +3,11 @@ import { Injectable } from '@angular/core'; import { Http, Response } from '@angular/http'; import { Observable } from 'rxjs/Rx'; +// #docregion downgrade-injectable +declare var angular: angular.IAngularStatic; +import { downgradeInjectable } from '@angular/upgrade/static'; +// #enddocregion downgrade-injectable + import 'rxjs/add/operator/map'; // #docregion phonedata-interface @@ -14,10 +19,10 @@ export interface PhoneData { // #enddocregion phonedata-interface // #docregion fullclass -// #docregion classdef +// #docregion classdef, downgrade-injectable @Injectable() export class Phone { -// #enddocregion classdef +// #enddocregion classdef, downgrade-injectable constructor(private http: Http) { } query(): Observable { return this.http.get(`phones/phones.json`) @@ -27,7 +32,11 @@ export class Phone { return this.http.get(`phones/${id}.json`) .map((res: Response) => res.json()); } -// #docregion classdef +// #docregion classdef, downgrade-injectable } // #enddocregion classdef // #enddocregion fullclass + +angular.module('core.phone') + .factory('phone', downgradeInjectable(Phone)); +// #enddocregion downgrade-injectable diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/dell-venue.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/dell-venue.0.jpg new file mode 100644 index 0000000000..b4cb4eb25f Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/dell-venue.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/droid-2-global-by-motorola.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/droid-2-global-by-motorola.0.jpg new file mode 100644 index 0000000000..60700a2ab3 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/droid-2-global-by-motorola.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/droid-pro-by-motorola.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/droid-pro-by-motorola.0.jpg new file mode 100644 index 0000000000..c7710de986 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/droid-pro-by-motorola.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/lg-axis.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/lg-axis.0.jpg new file mode 100644 index 0000000000..55e5a23bb2 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/lg-axis.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg new file mode 100644 index 0000000000..e452ae7e7c Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg new file mode 100644 index 0000000000..21e4b8d741 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg new file mode 100644 index 0000000000..c7c5e3ba0c Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-galaxy-tab.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-galaxy-tab.0.jpg new file mode 100644 index 0000000000..3750377ad9 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-galaxy-tab.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-gem.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-gem.0.jpg new file mode 100644 index 0000000000..0d5024a026 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-gem.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg new file mode 100644 index 0000000000..11b8f860cb Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg new file mode 100644 index 0000000000..11b8f860cb Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-transform.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-transform.0.jpg new file mode 100644 index 0000000000..0e3107caf5 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/samsung-transform.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/sanyo-zio.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/sanyo-zio.0.jpg new file mode 100644 index 0000000000..9eeb9b96ed Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/sanyo-zio.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/t-mobile-g2.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/t-mobile-g2.0.jpg new file mode 100644 index 0000000000..6b6c09e058 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/t-mobile-g2.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg new file mode 100644 index 0000000000..beba1f6827 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/main-aot.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/main-aot.ts new file mode 100644 index 0000000000..23a741c684 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/main-aot.ts @@ -0,0 +1,10 @@ +// #docregion +import { platformBrowser } from '@angular/platform-browser'; +import { UpgradeModule } from '@angular/upgrade/static'; + +import { AppModuleNgFactory } from '../aot/app/app.module.ngfactory'; + +platformBrowser().bootstrapModuleFactory(AppModuleNgFactory).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.documentElement, ['phonecatApp']); +}); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/main.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/main.ts index 5ca4771a27..886e8ffac8 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/main.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/main.ts @@ -1,61 +1,11 @@ -// #docregion import-adapter -import { UpgradeAdapter } from '@angular/upgrade'; -// #enddocregion import-adapter -// #docregion import-http -import { HTTP_PROVIDERS } from '@angular/http'; -// #enddocregion import-http -// #docregion phone-service -import { Phone } from './core/phone/phone.service'; - -// #enddocregion phone-service -// #docregion phone-list -import { PhoneListComponent } from './phone-list/phone-list.component'; - -// #enddocregion phone-list -// #docregion phone-detail -import { PhoneDetailComponent } from './phone-detail/phone-detail.component'; - -// #enddocregion phone-detail -// #docregion init-adapter -let upgradeAdapter = new UpgradeAdapter(); -// #enddocregion init-adapter - -// #docregion add-http -upgradeAdapter.addProvider(HTTP_PROVIDERS); -// #enddocregion add-http -// #docregion phone-service - -upgradeAdapter.addProvider(Phone); - -// #enddocregion phone-service -// #docregion routeparams -upgradeAdapter.upgradeNg1Provider('$routeParams'); -// #enddocregion routeparams - -// #docregion phone-service - -angular.module('core.phone') - .factory('phone', upgradeAdapter.downgradeNg2Provider(Phone)); -// #enddocregion phone-service -// #docregion phone-list - -angular.module('phoneList') - .directive( - 'phoneList', - - upgradeAdapter.downgradeNg2Component(PhoneListComponent) - ); -// #enddocregion phone-list -// #docregion phone-detail +// #docregion bootstrap +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { UpgradeModule } from '@angular/upgrade/static'; -angular.module('phoneDetail') - .directive( - 'phoneDetail', - - upgradeAdapter.downgradeNg2Component(PhoneDetailComponent) - ); -// #enddocregion phone-detail +import { AppModule } from './app.module'; -// #docregion bootstrap -upgradeAdapter.bootstrap(document.documentElement, ['phonecatApp']); +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.documentElement, ['phonecatApp']); +}); // #enddocregion bootstrap diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ajs.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ajs.ts new file mode 100644 index 0000000000..80282858c4 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ajs.ts @@ -0,0 +1,28 @@ +// #docregion +declare var angular: angular.IAngularStatic; +import { Phone, PhoneData } from '../core/phone/phone.service'; + +class PhoneDetailController { + phone: PhoneData; + mainImageUrl: string; + + static $inject = ['$routeParams', 'phone']; + constructor($routeParams: angular.route.IRouteParamsService, phone: Phone) { + let phoneId = $routeParams['phoneId']; + phone.get(phoneId).subscribe(data => { + this.phone = data; + this.setImage(data.images[0]); + }); + } + + setImage(imageUrl: string) { + this.mainImageUrl = imageUrl; + } +} + +angular. + module('phoneDetail'). + component('phoneDetail', { + templateUrl: 'phone-detail/phone-detail.template.html', + controller: PhoneDetailController + }); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ng1.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ng1.ts deleted file mode 100644 index b458343ece..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ng1.ts +++ /dev/null @@ -1,27 +0,0 @@ -// #docregion -import { Phone, PhoneData } from '../core/phone/phone.service'; - -class PhoneDetailController { - phone: PhoneData; - mainImageUrl: string; - - static $inject = ['$routeParams', 'phone']; - constructor($routeParams: angular.route.IRouteParamsService, phone: Phone) { - let phoneId = $routeParams['phoneId']; - phone.get(phoneId).subscribe(data => { - this.phone = data; - this.setImage(data.images[0]); - }); - } - - setImage(imageUrl: string) { - this.mainImageUrl = imageUrl; - } -} - -angular. - module('phoneDetail'). - component('phoneDetail', { - templateUrl: 'phone-detail/phone-detail.template.html', - controller: PhoneDetailController - }); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.spec.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.spec.ts index 67809b486a..e3b9143a94 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.spec.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.spec.ts @@ -1,52 +1,59 @@ // #docregion -import { HTTP_PROVIDERS } from '@angular/http'; +// #docregion activatedroute +import { ActivatedRoute } from '@angular/router'; + +// #enddocregion activatedroute import { Observable } from 'rxjs/Rx'; -import { - describe, - beforeEachProviders, - inject, - it, - expect -} from '@angular/core/testing'; -import { - TestComponentBuilder, - ComponentFixture -} from '@angular/compiler/testing'; +import { async, TestBed } from '@angular/core/testing'; import { PhoneDetailComponent } from './phone-detail.component'; import { Phone, PhoneData } from '../core/phone/phone.service'; +import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe'; -function xyzPhoneData():PhoneData { +function xyzPhoneData(): PhoneData { return { name: 'phone xyz', snippet: '', images: ['image/url1.png', 'image/url2.png'] - } + }; } -class MockPhone extends Phone { - get(id: string):Observable { +class MockPhone { + get(id: string): Observable { return Observable.of(xyzPhoneData()); } } +// #docregion activatedroute + +class ActivatedRouteMock { + constructor(public snapshot: any) {} +} + +// #enddocregion activatedroute + describe('PhoneDetailComponent', () => { - beforeEachProviders(() => [ - { provide: Phone, useClass: MockPhone }, - { provide: '$routeParams', useValue: {phoneId: 'xyz'}}, - HTTP_PROVIDERS - ]); - - it('should fetch phone detail', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb.createAsync(PhoneDetailComponent) - .then((fixture: ComponentFixture) => { - fixture.detectChanges(); - let compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1')).toHaveText(xyzPhoneData().name); - }); + // #docregion activatedroute + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CheckmarkPipe, PhoneDetailComponent ], + providers: [ + { provide: Phone, useClass: MockPhone }, + { provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) } + ] + }) + .compileComponents(); })); + // #enddocregion activatedroute + + it('should fetch phone detail', () => { + const fixture = TestBed.createComponent(PhoneDetailComponent); + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name); + }); }); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ts index 3f42ba3044..aa20ebb801 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-detail/phone-detail.component.ts @@ -1,28 +1,28 @@ // #docplaster +// #docregion +declare var angular: angular.IAngularStatic; +import { downgradeComponent } from '@angular/upgrade/static'; + // #docregion initialclass -import { Component, Inject } from '@angular/core'; +import { Component } from '@angular/core'; + import { Phone, PhoneData } from '../core/phone/phone.service'; // #enddocregion initialclass -// #docregion checkmark-pipe -import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe'; +import { RouteParams } from '../ajs-upgraded-providers'; // #docregion initialclass @Component({ selector: 'phone-detail', - templateUrl: 'phone-detail/phone-detail.template.html', + templateUrl: './phone-detail.template.html', // #enddocregion initialclass - pipes: [ CheckmarkPipe ] // #docregion initialclass }) -// #enddocregion checkmark-pipe -export class PhoneDetailComponent{ +export class PhoneDetailComponent { phone: PhoneData; mainImageUrl: string; - constructor(@Inject('$routeParams') - $routeParams: angular.route.IRouteParamsService, - phone: Phone) { - phone.get($routeParams['phoneId']).subscribe(phone => { + constructor(routeParams: RouteParams, phone: Phone) { + phone.get(routeParams['phoneId']).subscribe(phone => { this.phone = phone; this.setImage(phone.images[0]); }); @@ -33,3 +33,9 @@ export class PhoneDetailComponent{ } } // #enddocregion initialclass + +angular.module('phoneDetail') + .directive( + 'phoneDetail', + downgradeComponent({component: PhoneDetailComponent}) as angular.IDirectiveFactory + ); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ajs.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ajs.ts new file mode 100644 index 0000000000..81eac1cd81 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ajs.ts @@ -0,0 +1,24 @@ +// #docregion +declare var angular: angular.IAngularStatic; +import { Phone, PhoneData } from '../core/phone/phone.service'; + +class PhoneListController { + phones: PhoneData[]; + orderProp: string; + + static $inject = ['phone']; + constructor(phone: Phone) { + phone.query().subscribe(phones => { + this.phones = phones; + }); + this.orderProp = 'age'; + } + +} + +angular. + module('phoneList'). + component('phoneList', { + templateUrl: 'app/phone-list/phone-list.template.html', + controller: PhoneListController + }); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ng1.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ng1.ts deleted file mode 100644 index 6b36772a72..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ng1.ts +++ /dev/null @@ -1,23 +0,0 @@ -// #docregion -import { Phone, PhoneData } from '../core/phone/phone.service'; - -class PhoneListController { - phones: PhoneData[]; - orderProp: string; - - static $inject = ['phone']; - constructor(phone: Phone) { - phone.query().subscribe(phones => { - this.phones = phones; - }); - this.orderProp = 'age'; - } - -} - -angular. - module('phoneList'). - component('phoneList', { - templateUrl: 'app/phone-list/phone-list.template.html', - controller: PhoneListController - }); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.spec.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.spec.ts index d050615923..2bb9d2b62f 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.spec.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.spec.ts @@ -1,66 +1,66 @@ +/* tslint:disable */ // #docregion -import { HTTP_PROVIDERS } from '@angular/http'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs/Rx'; -import { - describe, - beforeEachProviders, - inject, - it, - expect -} from '@angular/core/testing'; -import { - TestComponentBuilder, - ComponentFixture -} from '@angular/compiler/testing'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { SpyLocation } from '@angular/common/testing'; import { PhoneListComponent } from './phone-list.component'; import { Phone, PhoneData } from '../core/phone/phone.service'; -class MockPhone extends Phone { - query():Observable { - console.log('mocking here'); - return Observable.of( - [ - {name: 'Nexus S', snippet: '', images: []}, - {name: 'Motorola DROID', snippet: '', images: []} - ] - ) +class ActivatedRouteMock { + constructor(public snapshot: any) {} +} + +class MockPhone { + query(): Observable { + return Observable.of([ + {name: 'Nexus S', snippet: '', images: []}, + {name: 'Motorola DROID', snippet: '', images: []} + ]); } } -describe('PhoneList', () => { +let fixture: ComponentFixture; - beforeEachProviders(() => [ - { provide: Phone, useClass: MockPhone }, - HTTP_PROVIDERS - ]); +describe('PhoneList', () => { - it('should create "phones" model with 2 phones fetched from xhr', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb.createAsync(PhoneListComponent) - .then((fixture: ComponentFixture) => { - fixture.detectChanges(); - let compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2); - expect( - compiled.querySelector('.phone-list-item:nth-child(1)').textContent - ).toContain('Motorola DROID'); - expect( - compiled.querySelector('.phone-list-item:nth-child(2)').textContent - ).toContain('Nexus S'); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PhoneListComponent ], + providers: [ + { provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) }, + { provide: Location, useClass: SpyLocation }, + { provide: Phone, useClass: MockPhone }, + ], + schemas: [ NO_ERRORS_SCHEMA ] + }) + .compileComponents(); })); - it('should set the default value of orderProp model', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb.createAsync(PhoneListComponent) - .then((fixture: ComponentFixture) => { - fixture.detectChanges(); - let compiled = fixture.debugElement.nativeElement; - expect( - compiled.querySelector('select option:last-child').selected - ).toBe(true); - }); - })); + beforeEach(() => { + fixture = TestBed.createComponent(PhoneListComponent); + }); + + it('should create "phones" model with 2 phones fetched from xhr', () => { + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2); + expect( + compiled.querySelector('.phone-list-item:nth-child(1)').textContent + ).toContain('Motorola DROID'); + expect( + compiled.querySelector('.phone-list-item:nth-child(2)').textContent + ).toContain('Nexus S'); + }); + + xit('should set the default value of orderProp model', () => { + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect( + compiled.querySelector('select option:last-child').selected + ).toBe(true); + }); }); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ts index a8b16c123f..1f51c6faa2 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ts +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/app/phone-list/phone-list.component.ts @@ -1,15 +1,22 @@ -// #docplaster +// #docregion downgrade-component +declare var angular: angular.IAngularStatic; +import { downgradeComponent } from '@angular/upgrade/static'; + +// #enddocregion downgrade-component + // #docregion initialclass import { Component } from '@angular/core'; import { Phone, PhoneData } from '../core/phone/phone.service'; +// #docregion downgrade-component @Component({ selector: 'phone-list', - templateUrl: 'phone-list/phone-list.template.html' + templateUrl: 'phone-list.template.html' }) export class PhoneListComponent { + // #enddocregion downgrade-component phones: PhoneData[]; - query:string; + query: string; orderProp: string; constructor(phone: Phone) { @@ -21,7 +28,7 @@ export class PhoneListComponent { // #enddocregion initialclass // #docregion getphones - getPhones():PhoneData[] { + getPhones(): PhoneData[] { return this.sortPhones(this.filterPhones(this.phones)); } @@ -37,22 +44,29 @@ export class PhoneListComponent { } private sortPhones(phones: PhoneData[]) { - if (phones && this.orderProp) { - return phones - .slice(0) // Make a copy - .sort((a, b) => { - if (a[this.orderProp] < b[this.orderProp]) { - return -1; - } else if ([b[this.orderProp] < a[this.orderProp]]) { - return 1; - } else { - return 0; - } - }); - } - return phones; + if (phones && this.orderProp) { + return phones + .slice(0) // Make a copy + .sort((a, b) => { + if (a[this.orderProp] < b[this.orderProp]) { + return -1; + } else if ([b[this.orderProp] < a[this.orderProp]]) { + return 1; + } else { + return 0; + } + }); + } + return phones; } // #enddocregion getphones - // #docregion initialclass + // #docregion initialclass, downgrade-component } // #enddocregion initialclass + +angular.module('phoneList') + .directive( + 'phoneList', + downgradeComponent({component: PhoneListComponent}) as angular.IDirectiveFactory + ); +// #enddocregion downgrade-component diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/bs-config.aot.json b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/bs-config.aot.json new file mode 100644 index 0000000000..e59a7403a0 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/bs-config.aot.json @@ -0,0 +1,14 @@ +{ + "open": false, + "logLevel": "silent", + "port": 8080, + "server": { + "baseDir": "aot", + "routes": { + "/node_modules": "node_modules" + }, + "middleware": { + "0": null + } + } +} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/copy-dist-files.js b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/copy-dist-files.js new file mode 100644 index 0000000000..a857af085c --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/copy-dist-files.js @@ -0,0 +1,25 @@ +// #docregion +var fsExtra = require('fs-extra'); +var resources = [ + // polyfills + 'node_modules/core-js/client/shim.min.js', + 'node_modules/zone.js/dist/zone.min.js', + // css + 'app/app.css', + 'app/app.animations.css', + // images and json files + 'app/img/', + 'app/phones/', + // app files + 'app/app.module.ajs.js', + 'app/app.config.js', + 'app/app.animations.js', + 'app/core/core.module.js', + 'app/core/phone/phone.module.js', + 'app/phone-list/phone-list.module.js', + 'app/phone-detail/phone-detail.module.js' +]; +resources.map(function(sourcePath) { + var destPath = `aot/${sourcePath}`; + fsExtra.copySync(sourcePath, destPath); +}); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/example-config.json b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/example-config.json index e69de29bb2..401c14f835 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/example-config.json +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/example-config.json @@ -0,0 +1,5 @@ +{ + "build": "build:upgrade", + "run": "serve:upgrade", + "unittesting": true +} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/index.html b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/index.html index 393d465911..f747e641e0 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/index.html +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/index.html @@ -17,7 +17,7 @@ - + @@ -25,19 +25,18 @@ - + - - + - + diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js index bf17063954..19fcc89fe9 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma-test-shim.1.js @@ -1,21 +1,25 @@ // #docregion // /*global jasmine, __karma__, window*/ -Error.stackTraceLimit = Infinity; +Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing. + +// Uncomment to get full stacktrace output. Sometimes helpful, usually not. +// Error.stackTraceLimit = Infinity; // + jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; -__karma__.loaded = function () { -}; +var builtPath = '/base/app/'; + +__karma__.loaded = function () { }; function isJsFile(path) { return path.slice(-3) == '.js'; } function isSpecFile(path) { - return /\.spec\.js$/.test(path); + return /\.spec\.(.*\.)?js$/.test(path); } function isBuiltFile(path) { - var builtPath = '/base/app/'; return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath); } @@ -25,31 +29,61 @@ var allSpecFiles = Object.keys(window.__karma__.files) System.config({ baseURL: '/base', - packageWithIndex: true // sadly, we can't use umd packages (yet?) + // Extend usual application package list with test folder + packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } }, + + // Assume npm: is set in `paths` in systemjs.config + // Map the angular testing umd bundles + map: { + '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js', + '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js', + '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js', + '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js', + '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js', + '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js', + '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js', + '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js', + }, }); System.import('systemjs.config.js') - .then(function () { - return Promise.all([ - System.import('@angular/core/testing'), - System.import('@angular/platform-browser-dynamic/testing') - ]) - }) - .then(function (providers) { - var testing = providers[0]; - var testingBrowser = providers[1]; + .then(importSystemJsExtras) + .then(initTestBed) + .then(initTesting); + +/** Optional SystemJS configuration extras. Keep going w/o it */ +function importSystemJsExtras(){ + return System.import('systemjs.config.extras.js') + .catch(function(reason) { + console.log( + 'Warning: System.import could not load the optional "systemjs.config.extras.js". Did you omit it by accident? Continuing without it.' + ); + console.log(reason); + }); +} - testing.setBaseTestProviders( - testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, - testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS); +function initTestBed(){ + return Promise.all([ + System.import('@angular/core/testing'), + System.import('@angular/platform-browser-dynamic/testing') + ]) + .then(function (providers) { + var coreTesting = providers[0]; + var browserTesting = providers[1]; + + coreTesting.TestBed.initTestEnvironment( + browserTesting.BrowserDynamicTestingModule, + browserTesting.platformBrowserDynamicTesting()); }) - .then(function() { - // Finally, load all spec files. - // This will run the tests directly. - return Promise.all( - allSpecFiles.map(function (moduleName) { - return System.import(moduleName); - })); - }) +} + +// Import all spec files and start karma +function initTesting () { + return Promise.all( + allSpecFiles.map(function (moduleName) { + return System.import(moduleName); + }) + ) .then(__karma__.start, __karma__.error); +} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ajs.js b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ajs.js new file mode 100644 index 0000000000..a52abf73ce --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ajs.js @@ -0,0 +1,73 @@ +//jshint strict: false +module.exports = function(config) { + config.set({ + + // #docregion basepath + basePath: './', + // #enddocregion basepath + + files: [ + 'https://code.angularjs.org/1.5.5/angular.js', + 'https://code.angularjs.org/1.5.5/angular-animate.js', + 'https://code.angularjs.org/1.5.5/angular-resource.js', + 'https://code.angularjs.org/1.5.5/angular-route.js', + 'https://code.angularjs.org/1.5.5/angular-mocks.js', + + // #docregion files + // System.js for module loading + 'node_modules/systemjs/dist/system.src.js', + + // Polyfills + 'node_modules/core-js/client/shim.js', + + // zone.js + 'node_modules/zone.js/dist/zone.js', + 'node_modules/zone.js/dist/long-stack-trace-zone.js', + 'node_modules/zone.js/dist/proxy.js', + 'node_modules/zone.js/dist/sync-test.js', + 'node_modules/zone.js/dist/jasmine-patch.js', + 'node_modules/zone.js/dist/async-test.js', + 'node_modules/zone.js/dist/fake-async-test.js', + + // RxJs. + { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, + { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false }, + + // Angular itself and the testing library + {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false}, + {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false}, + + {pattern: 'systemjs.config.js', included: false, watched: false}, + 'karma-test-shim.js', + + {pattern: 'app/**/*.module.js', included: false, watched: true}, + {pattern: 'app/*!(.module|.spec).js', included: false, watched: true}, + {pattern: 'app/!(bower_components)/**/*!(.module|.spec).js', included: false, watched: true}, + {pattern: 'app/**/*.spec.js', included: false, watched: true}, + + {pattern: '**/*.html', included: false, watched: true}, + // #enddocregion files + ], + + // #docregion html + // proxied base paths for loading assets + proxies: { + // required for component assets fetched by Angular's compiler + "/phone-detail": '/base/app/phone-detail', + "/phone-list": '/base/app/phone-list' + }, + // #enddocregion html + + autoWatch: true, + + frameworks: ['jasmine'], + + browsers: ['Chrome'], + + plugins: [ + 'karma-chrome-launcher', + 'karma-jasmine' + ] + + }); +}; diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ng1.js b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ng1.js deleted file mode 100644 index 7156e025ce..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/karma.conf.ng1.js +++ /dev/null @@ -1,72 +0,0 @@ -//jshint strict: false -module.exports = function(config) { - config.set({ - - // #docregion basepath - basePath: './', - // #enddocregion basepath - - files: [ - 'https://code.angularjs.org/1.5.5/angular.js', - 'https://code.angularjs.org/1.5.5/angular-animate.js', - 'https://code.angularjs.org/1.5.5/angular-resource.js', - 'https://code.angularjs.org/1.5.5/angular-route.js', - 'https://code.angularjs.org/1.5.5/angular-mocks.js', - - // #docregion files - // System.js for module loading - 'node_modules/systemjs/dist/system.src.js', - - // Polyfills - 'node_modules/core-js/client/shim.js', - - // Reflect and Zone.js - 'node_modules/reflect-metadata/Reflect.js', - 'node_modules/zone.js/dist/zone.js', - 'node_modules/zone.js/dist/jasmine-patch.js', - 'node_modules/zone.js/dist/async-test.js', - 'node_modules/zone.js/dist/fake-async-test.js', - - // RxJs. - { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, - { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false }, - - // Angular 2 itself and the testing library - {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false}, - {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false}, - - {pattern: 'systemjs.config.js', included: false, watched: false}, - 'karma-test-shim.js', - - {pattern: 'app/**/*.module.js', included: false, watched: true}, - {pattern: 'app/*!(.module|.spec).js', included: false, watched: true}, - {pattern: 'app/!(bower_components)/**/*!(.module|.spec).js', included: false, watched: true}, - {pattern: 'app/**/*.spec.js', included: false, watched: true}, - - {pattern: '**/*.html', included: false, watched: true}, - // #enddocregion files - ], - - // #docregion html - // proxied base paths for loading assets - proxies: { - // required for component assets fetched by Angular's compiler - "/phone-detail": '/base/app/phone-detail', - "/phone-list": '/base/app/phone-list' - }, - // #enddocregion html - - autoWatch: true, - - frameworks: ['jasmine'], - - browsers: ['Chrome', 'Firefox'], - - plugins: [ - 'karma-chrome-launcher', - 'karma-firefox-launcher', - 'karma-jasmine' - ] - - }); -}; diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/package.ng1.json b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/package.ajs.json similarity index 100% rename from public/docs/_examples/upgrade-phonecat-2-hybrid/ts/package.ng1.json rename to public/docs/_examples/upgrade-phonecat-2-hybrid/ts/package.ajs.json diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/rollup-config.js b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/rollup-config.js new file mode 100644 index 0000000000..aeb227689c --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/rollup-config.js @@ -0,0 +1,21 @@ +// #docregion +import rollup from 'rollup' +import nodeResolve from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs'; +import uglify from 'rollup-plugin-uglify' + +//paths are relative to the execution path +export default { + entry: 'app/main-aot.js', + dest: 'aot/dist/build.js', // output a single application bundle + sourceMap: true, + sourceMapFile: 'aot/dist/build.js.map', + format: 'iife', + plugins: [ + nodeResolve({jsnext: true, module: true}), + commonjs({ + include: ['node_modules/rxjs/**'] + }), + uglify() + ] +} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/run-unit-tests.sh b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/run-unit-tests.sh index 00a5abb7bc..239e5ff7d7 100755 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/run-unit-tests.sh +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/run-unit-tests.sh @@ -1,7 +1,7 @@ -## The boilerplate Karma configuration won't work with Angular 1 tests since +## The boilerplate Karma configuration won't work with AngularJS tests since ## a specific loading configuration is needed for them. -## We keep one in karma.conf.ng1.js. This scripts runs the ng1 tests with +## We keep one in karma.conf.ajs.js. This scripts runs the AngularJS tests with ## that config. PATH=$(npm bin):$PATH -tsc && karma start karma.conf.ng1.js +tsc && karma start karma.conf.ajs.js diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/systemjs.config.1.js b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/systemjs.config.1.js index 3a455980bb..8197c44a89 100644 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/systemjs.config.1.js +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/systemjs.config.1.js @@ -1,58 +1,50 @@ /** - * System configuration for Angular 2 samples + * System configuration for Angular samples * Adjust as necessary for your application needs. */ -(function(global) { - - // map tells the System loader where to look for things +(function (global) { // #docregion paths - var map = { - 'app': '/app', // 'dist', - - '@angular': '/node_modules/@angular', - 'angular2-in-memory-web-api': '/node_modules/angular2-in-memory-web-api', - 'rxjs': '/node_modules/rxjs' - }; - - var packages = { - '/app': { main: 'main.js', defaultExtension: 'js' }, - 'rxjs': { defaultExtension: 'js' }, - 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, - }; - // #enddocregion paths - - var ngPackageNames = [ - 'common', - 'compiler', - 'core', - 'http', - 'platform-browser', - 'platform-browser-dynamic', - 'router', - 'router-deprecated', - 'upgrade', - ]; - - // Individual files (~300 requests): - function packIndex(pkgName) { - packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; - } - - // Bundled (~40 requests): - function packUmd(pkgName) { - packages['@angular/'+pkgName] = { main: pkgName + '.umd.js', defaultExtension: 'js' }; - }; - - var setPackageConfig = System.packageWithIndex ? packIndex : packUmd; - - // Add package entries for angular packages - ngPackageNames.forEach(setPackageConfig); - - var config = { - map: map, - packages: packages - } - - System.config(config); - + System.config({ + paths: { + // paths serve as alias + 'npm:': '/node_modules/' + }, + map: { + app: '/app', + // #enddocregion paths + // angular bundles + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + // #docregion paths + '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js', + // #enddocregion paths + + // other libraries + 'rxjs': 'npm:rxjs', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api', + // #docregion paths + }, + // #enddocregion paths + // packages tells the System loader how to load when no filename and/or no extension + packages: { + 'app': { + main: './main.js', + defaultExtension: 'js' + }, + rxjs: { + defaultExtension: 'js' + }, + 'angular-in-memory-web-api': { + main: './index.js', + defaultExtension: 'js' + } + } + }); })(this); diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/tsconfig-aot.json b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/tsconfig-aot.json new file mode 100644 index 0000000000..58f9de3309 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/tsconfig-aot.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "es2015", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es2015", "dom"], + "removeComments": false, + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "../../node_modules/@types/" + ] + }, + + "files": [ + "app/app.module.ts", + "app/main-aot.ts" + ], + + "angularCompilerOptions": { + "genDir": "aot", + "skipMetadataEmit" : true + } +} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/tsconfig.json b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/tsconfig.json new file mode 100644 index 0000000000..f267800f14 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ "es2015", "dom" ], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "../../node_modules/@types/" + ] + }, + "compileOnSave": true, + "exclude": [ + "node_modules/*", + "**/*-aot.ts" + ] +} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-animate/index.d.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-animate/index.d.ts deleted file mode 100644 index c720d9293a..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-animate/index.d.ts +++ /dev/null @@ -1,294 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/f0b2681b481397d0c03557ac2ac4d70c1c61c464/angularjs/angular-animate.d.ts -declare module "angular-animate" { - var _: string; - export = _; -} - -/** - * ngAnimate module (angular-animate.js) - */ -declare namespace angular.animate { - interface IAnimateFactory { - (...args: any[]): IAnimateCallbackObject; - } - - interface IAnimateCallbackObject { - eventFn?: (element: IAugmentedJQuery, doneFunction: Function, options: IAnimationOptions) => any; - setClass?: (element: IAugmentedJQuery, addedClasses: string, removedClasses: string, doneFunction: Function, options: IAnimationOptions) => any; - addClass?: (element: IAugmentedJQuery, addedClasses: string, doneFunction: Function, options: IAnimationOptions) => any; - removeClass?: (element: IAugmentedJQuery, removedClasses: string, doneFunction: Function, options: IAnimationOptions) => any; - enter?: (element: IAugmentedJQuery, doneFunction: Function, options: IAnimationOptions) => any; - leave?: (element: IAugmentedJQuery, doneFunction: Function, options: IAnimationOptions) => any; - move?: (element: IAugmentedJQuery, doneFunction: Function, options: IAnimationOptions) => any; - animate?: (element: IAugmentedJQuery, fromStyles: string, toStyles: string, doneFunction: Function, options: IAnimationOptions) => any; - } - - interface IAnimationPromise extends IPromise {} - - /** - * AnimateService - * see http://docs.angularjs.org/api/ngAnimate/service/$animate - */ - interface IAnimateService { - /** - * Sets up an event listener to fire whenever the animation event has fired on the given element or among any of its children. - * - * @param event the animation event that will be captured (e.g. enter, leave, move, addClass, removeClass, etc...) - * @param container the container element that will capture each of the animation events that are fired on itself as well as among its children - * @param callback the callback function that will be fired when the listener is triggered - */ - on(event: string, container: JQuery, callback: Function): void; - - /** - * Deregisters an event listener based on the event which has been associated with the provided element. - * - * @param event the animation event (e.g. enter, leave, move, addClass, removeClass, etc...) - * @param container the container element the event listener was placed on - * @param callback the callback function that was registered as the listener - */ - off(event: string, container?: JQuery, callback?: Function): void; - - /** - * Associates the provided element with a host parent element to allow the element to be animated even if it exists outside of the DOM structure of the Angular application. - * - * @param element the external element that will be pinned - * @param parentElement the host parent element that will be associated with the external element - */ - pin(element: JQuery, parentElement: JQuery): void; - - /** - * Globally enables / disables animations. - * - * @param element If provided then the element will be used to represent the enable/disable operation. - * @param value If provided then set the animation on or off. - * @returns current animation state - */ - enabled(element: JQuery, value?: boolean): boolean; - enabled(value: boolean): boolean; - - /** - * Cancels the provided animation. - */ - cancel(animationPromise: IAnimationPromise): void; - - /** - * Performs an inline animation on the element. - * - * @param element the element that will be the focus of the animation - * @param from a collection of CSS styles that will be applied to the element at the start of the animation - * @param to a collection of CSS styles that the element will animate towards - * @param className an optional CSS class that will be added to the element for the duration of the animation (the default class is 'ng-inline-animate') - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - animate(element: JQuery, from: any, to: any, className?: string, options?: IAnimationOptions): IAnimationPromise; - - /** - * Appends the element to the parentElement element that resides in the document and then runs the enter animation. - * - * @param element the element that will be the focus of the enter animation - * @param parentElement the parent element of the element that will be the focus of the enter animation - * @param afterElement the sibling element (which is the previous element) of the element that will be the focus of the enter animation - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - enter(element: JQuery, parentElement: JQuery, afterElement?: JQuery, options?: IAnimationOptions): IAnimationPromise; - - /** - * Runs the leave animation operation and, upon completion, removes the element from the DOM. - * - * @param element the element that will be the focus of the leave animation - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - leave(element: JQuery, options?: IAnimationOptions): IAnimationPromise; - - /** - * Fires the move DOM operation. Just before the animation starts, the animate service will either append - * it into the parentElement container or add the element directly after the afterElement element if present. - * Then the move animation will be run. - * - * @param element the element that will be the focus of the move animation - * @param parentElement the parent element of the element that will be the focus of the move animation - * @param afterElement the sibling element (which is the previous element) of the element that will be the focus of the move animation - * @returns the animation callback promise - */ - move(element: JQuery, parentElement: JQuery, afterElement?: JQuery): IAnimationPromise; - - /** - * Triggers a custom animation event based off the className variable and then attaches the className - * value to the element as a CSS class. - * - * @param element the element that will be animated - * @param className the CSS class that will be added to the element and then animated - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - addClass(element: JQuery, className: string, options?: IAnimationOptions): IAnimationPromise; - - /** - * Triggers a custom animation event based off the className variable and then removes the CSS class - * provided by the className value from the element. - * - * @param element the element that will be animated - * @param className the CSS class that will be animated and then removed from the element - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - removeClass(element: JQuery, className: string, options?: IAnimationOptions): IAnimationPromise; - - /** - * Adds and/or removes the given CSS classes to and from the element. Once complete, the done() callback - * will be fired (if provided). - * - * @param element the element which will have its CSS classes changed removed from it - * @param add the CSS classes which will be added to the element - * @param remove the CSS class which will be removed from the element CSS classes have been set on the element - * @param options an optional collection of styles that will be picked up by the CSS transition/animation - * @returns the animation callback promise - */ - setClass(element: JQuery, add: string, remove: string, options?: IAnimationOptions): IAnimationPromise; - } - - /** - * AnimateProvider - * see http://docs.angularjs.org/api/ngAnimate/provider/$animateProvider - */ - interface IAnimateProvider { - /** - * Registers a new injectable animation factory function. - * - * @param name The name of the animation. - * @param factory The factory function that will be executed to return the animation object. - */ - register(name: string, factory: IAnimateFactory): void; - - /** - * Gets and/or sets the CSS class expression that is checked when performing an animation. - * - * @param expression The className expression which will be checked against all animations. - * @returns The current CSS className expression value. If null then there is no expression value. - */ - classNameFilter(expression?: RegExp): RegExp; - } - - /** - * Angular Animation Options - * see https://docs.angularjs.org/api/ngAnimate/#applying-directive-specific-styles-to-an-animation - */ - interface IAnimationOptions { - /** - * The ending CSS styles (a key/value object) that will be applied across the animation via a CSS transition. - */ - to?: Object; - - /** - * The starting CSS styles (a key/value object) that will be applied at the start of the animation. - */ - from?: Object; - - /** - * The DOM event (e.g. enter, leave, move). When used, a generated CSS class of ng-EVENT and - * ng-EVENT-active will be applied to the element during the animation. Multiple events can be provided when - * spaces are used as a separator. (Note that this will not perform any DOM operation.) - */ - event?: string; - - /** - * The CSS easing value that will be applied to the transition or keyframe animation (or both). - */ - easing?: string; - - /** - * The raw CSS transition style that will be used (e.g. 1s linear all). - */ - transition?: string; - - /** - * The raw CSS keyframe animation style that will be used (e.g. 1s my_animation linear). - */ - keyframe?: string; - - /** - * A space separated list of CSS classes that will be added to the element and spread across the animation. - */ - addClass?: string; - - /** - * A space separated list of CSS classes that will be removed from the element and spread across - * the animation. - */ - removeClass?: string; - - /** - * A number value representing the total duration of the transition and/or keyframe (note that a value - * of 1 is 1000ms). If a value of 0 is provided then the animation will be skipped entirely. - */ - duration?: number; - - /** - * A number value representing the total delay of the transition and/or keyframe (note that a value of - * 1 is 1000ms). If a value of true is used then whatever delay value is detected from the CSS classes will be - * mirrored on the elements styles (e.g. by setting delay true then the style value of the element will be - * transition-delay: DETECTED_VALUE). Using true is useful when you want the CSS classes and inline styles to - * all share the same CSS delay value. - */ - delay?: number; - - /** - * A numeric time value representing the delay between successively animated elements (Click here to - * learn how CSS-based staggering works in ngAnimate.) - */ - stagger?: number; - - /** - * The numeric index representing the stagger item (e.g. a value of 5 is equal to the sixth item - * in the stagger; therefore when a stagger option value of 0.1 is used then there will be a stagger delay of 600ms) - * applyClassesEarly - Whether or not the classes being added or removed will be used when detecting the animation. - * This is set by $animate when enter/leave/move animations are fired to ensure that the CSS classes are resolved in time. - * (Note that this will prevent any transitions from occuring on the classes being added and removed.) - */ - staggerIndex?: number; - } - - interface IAnimateCssRunner { - /** - * Starts the animation - * - * @returns The animation runner with a done function for supplying a callback. - */ - start(): IAnimateCssRunnerStart; - - /** - * Ends (aborts) the animation - */ - end(): void; - } - - interface IAnimateCssRunnerStart extends IPromise { - /** - * Allows you to add done callbacks to the running animation - * - * @param callbackFn: the callback function to be run - */ - done(callbackFn: (animationFinished: boolean) => void): void; - } - - /** - * AnimateCssService - * see http://docs.angularjs.org/api/ngAnimate/service/$animateCss - */ - interface IAnimateCssService { - (element: JQuery, animateCssOptions: IAnimationOptions): IAnimateCssRunner; - } -} - -declare module angular { - interface IModule { - animation(name: string, animationFactory: angular.animate.IAnimateFactory): IModule; - animation(name: string, inlineAnnotatedFunction: any[]): IModule; - animation(object: Object): IModule; - } - -} \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-animate/typings.json b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-animate/typings.json deleted file mode 100644 index ea2467c89a..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-animate/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/f0b2681b481397d0c03557ac2ac4d70c1c61c464/angularjs/angular-animate.d.ts", - "raw": "registry:dt/angular-animate#1.5.0+20160407085121", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/f0b2681b481397d0c03557ac2ac4d70c1c61c464/angularjs/angular-animate.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-mocks/index.d.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-mocks/index.d.ts deleted file mode 100644 index fd6e92534b..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-mocks/index.d.ts +++ /dev/null @@ -1,339 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/5b7257019ae959533341a715b339d2562bbf9b85/angularjs/angular-mocks.d.ts -declare module "angular-mocks/ngMock" { - var _: string; - export = _; -} - -declare module "angular-mocks/ngMockE2E" { - var _: string; - export = _; -} - -declare module "angular-mocks/ngAnimateMock" { - var _: string; - export = _; -} - -/////////////////////////////////////////////////////////////////////////////// -// ngMock module (angular-mocks.js) -/////////////////////////////////////////////////////////////////////////////// -declare namespace angular { - - /////////////////////////////////////////////////////////////////////////// - // AngularStatic - // We reopen it to add the MockStatic definition - /////////////////////////////////////////////////////////////////////////// - interface IAngularStatic { - mock: IMockStatic; - } - - // see https://docs.angularjs.org/api/ngMock/function/angular.mock.inject - interface IInjectStatic { - (...fns: Function[]): any; - (...inlineAnnotatedConstructor: any[]): any; // this overload is undocumented, but works - strictDi(val?: boolean): void; - } - - interface IMockStatic { - // see https://docs.angularjs.org/api/ngMock/function/angular.mock.dump - dump(obj: any): string; - - inject: IInjectStatic - - // see https://docs.angularjs.org/api/ngMock/function/angular.mock.module - module: { - (...modules: any[]): any; - sharedInjector(): void; - } - - // see https://docs.angularjs.org/api/ngMock/type/angular.mock.TzDate - TzDate(offset: number, timestamp: number): Date; - TzDate(offset: number, timestamp: string): Date; - } - - /////////////////////////////////////////////////////////////////////////// - // ExceptionHandlerService - // see https://docs.angularjs.org/api/ngMock/service/$exceptionHandler - // see https://docs.angularjs.org/api/ngMock/provider/$exceptionHandlerProvider - /////////////////////////////////////////////////////////////////////////// - interface IExceptionHandlerProvider extends IServiceProvider { - mode(mode: string): void; - } - - /////////////////////////////////////////////////////////////////////////// - // TimeoutService - // see https://docs.angularjs.org/api/ngMock/service/$timeout - // Augments the original service - /////////////////////////////////////////////////////////////////////////// - interface ITimeoutService { - flush(delay?: number): void; - flushNext(expectedDelay?: number): void; - verifyNoPendingTasks(): void; - } - - /////////////////////////////////////////////////////////////////////////// - // IntervalService - // see https://docs.angularjs.org/api/ngMock/service/$interval - // Augments the original service - /////////////////////////////////////////////////////////////////////////// - interface IIntervalService { - flush(millis?: number): number; - } - - /////////////////////////////////////////////////////////////////////////// - // LogService - // see https://docs.angularjs.org/api/ngMock/service/$log - // Augments the original service - /////////////////////////////////////////////////////////////////////////// - interface ILogService { - assertEmpty(): void; - reset(): void; - } - - interface ILogCall { - logs: string[]; - } - - /////////////////////////////////////////////////////////////////////////// - // ControllerService mock - // see https://docs.angularjs.org/api/ngMock/service/$controller - // This interface extends http://docs.angularjs.org/api/ng.$controller - /////////////////////////////////////////////////////////////////////////// - interface IControllerService { - // Although the documentation doesn't state this, locals are optional - (controllerConstructor: new (...args: any[]) => T, locals?: any, bindings?: any): T; - (controllerConstructor: Function, locals?: any, bindings?: any): T; - (controllerName: string, locals?: any, bindings?: any): T; - } - - /////////////////////////////////////////////////////////////////////////// - // ComponentControllerService - // see https://docs.angularjs.org/api/ngMock/service/$componentController - /////////////////////////////////////////////////////////////////////////// - interface IComponentControllerService { - // TBinding is an interface exposed by a component as per John Papa's style guide - // https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#accessible-members-up-top - (componentName: string, locals: { $scope: IScope, [key: string]: any }, bindings?: TBinding, ident?: string): T; - } - - - /////////////////////////////////////////////////////////////////////////// - // HttpBackendService - // see https://docs.angularjs.org/api/ngMock/service/$httpBackend - /////////////////////////////////////////////////////////////////////////// - interface IHttpBackendService { - /** - * Flushes all pending requests using the trained responses. - * @param count Number of responses to flush (in the order they arrived). If undefined, all pending requests will be flushed. - */ - flush(count?: number): void; - - /** - * Resets all request expectations, but preserves all backend definitions. - */ - resetExpectations(): void; - - /** - * Verifies that all of the requests defined via the expect api were made. If any of the requests were not made, verifyNoOutstandingExpectation throws an exception. - */ - verifyNoOutstandingExpectation(): void; - - /** - * Verifies that there are no outstanding requests that need to be flushed. - */ - verifyNoOutstandingRequest(): void; - - /** - * Creates a new request expectation. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param method HTTP method. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - expect(method: string, url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)) :mock.IRequestHandler; - - /** - * Creates a new request expectation for DELETE requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url is as expected. - * @param headers HTTP headers object to be compared with the HTTP headers in the request. - */ - expectDELETE(url: string | RegExp | ((url: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new request expectation for GET requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object to be compared with the HTTP headers in the request. - */ - expectGET(url: string | RegExp | ((url: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new request expectation for HEAD requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object to be compared with the HTTP headers in the request. - */ - expectHEAD(url: string | RegExp | ((url: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new request expectation for JSONP requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - */ - expectJSONP(url: string | RegExp | ((url: string) => boolean)): mock.IRequestHandler; - - /** - * Creates a new request expectation for PATCH requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - expectPATCH(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new request expectation for POST requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - expectPOST(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new request expectation for PUT requests. - * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - expectPUT(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object): mock.IRequestHandler; - - /** - * Creates a new backend definition. - * Returns an object with respond method that controls how a matched request is handled. - * @param method HTTP method. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - when(method: string, url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for DELETE requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenDELETE(url: string | RegExp | ((url: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for GET requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenGET(url: string | RegExp | ((url: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for HEAD requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenHEAD(url: string | RegExp | ((url: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for JSONP requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenJSONP(url: string | RegExp | ((url: string) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for PATCH requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenPATCH(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for POST requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenPOST(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - - /** - * Creates a new backend definition for PUT requests. - * Returns an object with respond method that controls how a matched request is handled. - * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. - * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. - * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. - */ - whenPUT(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; - } - - export module mock { - // returned interface by the the mocked HttpBackendService expect/when methods - interface IRequestHandler { - - /** - * Controls the response for a matched request using a function to construct the response. - * Returns the RequestHandler object for possible overrides. - * @param func Function that receives the request HTTP method, url, data, and headers and returns an array containing response status (number), data, headers, and status text. - */ - respond(func: ((method: string, url: string, data: string | Object, headers: Object) => [number, string | Object, Object, string])): IRequestHandler; - - /** - * Controls the response for a matched request using supplied static data to construct the response. - * Returns the RequestHandler object for possible overrides. - * @param status HTTP status code to add to the response. - * @param data Data to add to the response. - * @param headers Headers object to add to the response. - * @param responseText Response text to add to the response. - */ - respond(status: number, data: string | Object, headers?: Object, responseText?: string): IRequestHandler; - - /** - * Controls the response for a matched request using the HTTP status code 200 and supplied static data to construct the response. - * Returns the RequestHandler object for possible overrides. - * @param data Data to add to the response. - * @param headers Headers object to add to the response. - * @param responseText Response text to add to the response. - */ - respond(data: string | Object, headers?: Object, responseText?: string): IRequestHandler; - - // Available when ngMockE2E is loaded - /** - * Any request matching a backend definition or expectation with passThrough handler will be passed through to the real backend (an XHR request will be made to the server.) - */ - passThrough(): IRequestHandler; - } - - } - -} - -/////////////////////////////////////////////////////////////////////////////// -// functions attached to global object (window) -/////////////////////////////////////////////////////////////////////////////// -//Use `angular.mock.module` instead of `module`, as `module` conflicts with commonjs. -//declare var module: (...modules: any[]) => any; -declare var inject: angular.IInjectStatic; \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-mocks/typings.json b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-mocks/typings.json deleted file mode 100644 index 4e51b0e278..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-mocks/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/5b7257019ae959533341a715b339d2562bbf9b85/angularjs/angular-mocks.d.ts", - "raw": "registry:dt/angular-mocks#1.3.0+20160425155016", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/5b7257019ae959533341a715b339d2562bbf9b85/angularjs/angular-mocks.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-resource/index.d.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-resource/index.d.ts deleted file mode 100644 index 3735f9430c..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-resource/index.d.ts +++ /dev/null @@ -1,191 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/e684481e0cd360db62fd6213ca7248245315e8a2/angularjs/angular-resource.d.ts -declare module 'angular-resource' { - var _: string; - export = _; -} - -/////////////////////////////////////////////////////////////////////////////// -// ngResource module (angular-resource.js) -/////////////////////////////////////////////////////////////////////////////// -declare namespace angular.resource { - - /** - * Currently supported options for the $resource factory options argument. - */ - interface IResourceOptions { - /** - * If true then the trailing slashes from any calculated URL will be stripped (defaults to true) - */ - stripTrailingSlashes?: boolean; - /** - * If true, the request made by a "non-instance" call will be cancelled (if not already completed) by calling - * $cancelRequest() on the call's return value. This can be overwritten per action. (Defaults to false.) - */ - cancellable?: boolean; - } - - - /////////////////////////////////////////////////////////////////////////// - // ResourceService - // see http://docs.angularjs.org/api/ngResource.$resource - // Most part of the following definitions were achieved by analyzing the - // actual implementation, since the documentation doesn't seem to cover - // that deeply. - /////////////////////////////////////////////////////////////////////////// - interface IResourceService { - (url: string, paramDefaults?: any, - /** example: {update: { method: 'PUT' }, delete: deleteDescriptor } - where deleteDescriptor : IActionDescriptor */ - actions?: any, options?: IResourceOptions): IResourceClass>; - (url: string, paramDefaults?: any, - /** example: {update: { method: 'PUT' }, delete: deleteDescriptor } - where deleteDescriptor : IActionDescriptor */ - actions?: any, options?: IResourceOptions): U; - (url: string, paramDefaults?: any, - /** example: {update: { method: 'PUT' }, delete: deleteDescriptor } - where deleteDescriptor : IActionDescriptor */ - actions?: any, options?: IResourceOptions): IResourceClass; - } - - // Just a reference to facilitate describing new actions - interface IActionDescriptor { - method: string; - params?: any; - url?: string; - isArray?: boolean; - transformRequest?: angular.IHttpRequestTransformer | angular.IHttpRequestTransformer[]; - transformResponse?: angular.IHttpResponseTransformer | angular.IHttpResponseTransformer[]; - headers?: any; - cache?: boolean | angular.ICacheObject; - /** - * Note: In contrast to $http.config, promises are not supported in $resource, because the same value - * would be used for multiple requests. If you are looking for a way to cancel requests, you should - * use the cancellable option. - */ - timeout?: number - cancellable?: boolean; - withCredentials?: boolean; - responseType?: string; - interceptor?: IHttpInterceptor; - } - - // Allow specify more resource methods - // No need to add duplicates for all four overloads. - interface IResourceMethod { - (): T; - (params: Object): T; - (success: Function, error?: Function): T; - (params: Object, success: Function, error?: Function): T; - (params: Object, data: Object, success?: Function, error?: Function): T; - } - - // Allow specify resource moethod which returns the array - // No need to add duplicates for all four overloads. - interface IResourceArrayMethod { - (): IResourceArray; - (params: Object): IResourceArray; - (success: Function, error?: Function): IResourceArray; - (params: Object, success: Function, error?: Function): IResourceArray; - (params: Object, data: Object, success?: Function, error?: Function): IResourceArray; - } - - // Baseclass for everyresource with default actions. - // If you define your new actions for the resource, you will need - // to extend this interface and typecast the ResourceClass to it. - // - // In case of passing the first argument as anything but a function, - // it's gonna be considered data if the action method is POST, PUT or - // PATCH (in other words, methods with body). Otherwise, it's going - // to be considered as parameters to the request. - // https://github.com/angular/angular.js/blob/v1.2.0/src/ngResource/resource.js#L461-L465 - // - // Only those methods with an HTTP body do have 'data' as first parameter: - // https://github.com/angular/angular.js/blob/v1.2.0/src/ngResource/resource.js#L463 - // More specifically, those methods are POST, PUT and PATCH: - // https://github.com/angular/angular.js/blob/v1.2.0/src/ngResource/resource.js#L432 - // - // Also, static calls always return the IResource (or IResourceArray) retrieved - // https://github.com/angular/angular.js/blob/v1.2.0/src/ngResource/resource.js#L538-L549 - interface IResourceClass { - new(dataOrParams? : any) : T; - get: IResourceMethod; - - query: IResourceArrayMethod; - - save: IResourceMethod; - - remove: IResourceMethod; - - delete: IResourceMethod; - } - - // Instance calls always return the the promise of the request which retrieved the object - // https://github.com/angular/angular.js/blob/v1.2.0/src/ngResource/resource.js#L538-L546 - interface IResource { - $get(): angular.IPromise; - $get(params?: Object, success?: Function, error?: Function): angular.IPromise; - $get(success: Function, error?: Function): angular.IPromise; - - $query(): angular.IPromise>; - $query(params?: Object, success?: Function, error?: Function): angular.IPromise>; - $query(success: Function, error?: Function): angular.IPromise>; - - $save(): angular.IPromise; - $save(params?: Object, success?: Function, error?: Function): angular.IPromise; - $save(success: Function, error?: Function): angular.IPromise; - - $remove(): angular.IPromise; - $remove(params?: Object, success?: Function, error?: Function): angular.IPromise; - $remove(success: Function, error?: Function): angular.IPromise; - - $delete(): angular.IPromise; - $delete(params?: Object, success?: Function, error?: Function): angular.IPromise; - $delete(success: Function, error?: Function): angular.IPromise; - - $cancelRequest(): void; - - /** the promise of the original server interaction that created this instance. **/ - $promise : angular.IPromise; - $resolved : boolean; - toJSON(): T; - } - - /** - * Really just a regular Array object with $promise and $resolve attached to it - */ - interface IResourceArray extends Array> { - /** the promise of the original server interaction that created this collection. **/ - $promise : angular.IPromise>; - $resolved : boolean; - } - - /** when creating a resource factory via IModule.factory */ - interface IResourceServiceFactoryFunction { - ($resource: angular.resource.IResourceService): IResourceClass; - >($resource: angular.resource.IResourceService): U; - } - - // IResourceServiceProvider used to configure global settings - interface IResourceServiceProvider extends angular.IServiceProvider { - - defaults: IResourceOptions; - } - -} - -/** extensions to base ng based on using angular-resource */ -declare namespace angular { - - interface IModule { - /** creating a resource service factory */ - factory(name: string, resourceServiceFactoryFunction: angular.resource.IResourceServiceFactoryFunction): IModule; - } -} - -interface Array -{ - /** the promise of the original server interaction that created this collection. **/ - $promise : angular.IPromise>; - $resolved : boolean; -} \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-resource/typings.json b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-resource/typings.json deleted file mode 100644 index b60eafd673..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-resource/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/e684481e0cd360db62fd6213ca7248245315e8a2/angularjs/angular-resource.d.ts", - "raw": "registry:dt/angular-resource#1.5.0+20160412142209", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/e684481e0cd360db62fd6213ca7248245315e8a2/angularjs/angular-resource.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-route/index.d.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-route/index.d.ts deleted file mode 100644 index 5fad393d0a..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-route/index.d.ts +++ /dev/null @@ -1,154 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/angularjs/angular-route.d.ts -declare module "angular-route" { - var _: string; - export = _; -} - -/////////////////////////////////////////////////////////////////////////////// -// ngRoute module (angular-route.js) -/////////////////////////////////////////////////////////////////////////////// -declare namespace angular.route { - - /////////////////////////////////////////////////////////////////////////// - // RouteParamsService - // see http://docs.angularjs.org/api/ngRoute.$routeParams - /////////////////////////////////////////////////////////////////////////// - interface IRouteParamsService { - [key: string]: any; - } - - /////////////////////////////////////////////////////////////////////////// - // RouteService - // see http://docs.angularjs.org/api/ngRoute.$route - // see http://docs.angularjs.org/api/ngRoute.$routeProvider - /////////////////////////////////////////////////////////////////////////// - interface IRouteService { - reload(): void; - routes: any; - - // May not always be available. For instance, current will not be available - // to a controller that was not initialized as a result of a route maching. - current?: ICurrentRoute; - - /** - * Causes $route service to update the current URL, replacing current route parameters with those specified in newParams. - * Provided property names that match the route's path segment definitions will be interpolated into the - * location's path, while remaining properties will be treated as query params. - * - * @param newParams Object. mapping of URL parameter names to values - */ - updateParams(newParams:{[key:string]:string}): void; - - } - - type InlineAnnotatedFunction = Function|Array - - /** - * see http://docs.angularjs.org/api/ngRoute/provider/$routeProvider#when for API documentation - */ - interface IRoute { - /** - * {(string|function()=} - * Controller fn that should be associated with newly created scope or the name of a registered controller if passed as a string. - */ - controller?: string|InlineAnnotatedFunction; - /** - * A controller alias name. If present the controller will be published to scope under the controllerAs name. - */ - controllerAs?: string; - /** - * Undocumented? - */ - name?: string; - /** - * {string=|function()=} - * Html template as a string or a function that returns an html template as a string which should be used by ngView or ngInclude directives. This property takes precedence over templateUrl. - * - * If template is a function, it will be called with the following parameters: - * - * {Array.} - route parameters extracted from the current $location.path() by applying the current route - */ - template?: string|{($routeParams?: angular.route.IRouteParamsService) : string;} - /** - * {string=|function()=} - * Path or function that returns a path to an html template that should be used by ngView. - * - * If templateUrl is a function, it will be called with the following parameters: - * - * {Array.} - route parameters extracted from the current $location.path() by applying the current route - */ - templateUrl?: string|{ ($routeParams?: angular.route.IRouteParamsService): string; } - /** - * {Object.=} - An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated. If all the promises are resolved successfully, the values of the resolved promises are injected and $routeChangeSuccess event is fired. If any of the promises are rejected the $routeChangeError event is fired. The map object is: - * - * - key - {string}: a name of a dependency to be injected into the controller. - * - factory - {string|function}: If string then it is an alias for a service. Otherwise if function, then it is injected and the return value is treated as the dependency. If the result is a promise, it is resolved before its value is injected into the controller. Be aware that ngRoute.$routeParams will still refer to the previous route within these resolve functions. Use $route.current.params to access the new route parameters, instead. - */ - resolve?: {[key: string]: any}; - /** - * {(string|function())=} - * Value to update $location path with and trigger route redirection. - * - * If redirectTo is a function, it will be called with the following parameters: - * - * - {Object.} - route parameters extracted from the current $location.path() by applying the current route templateUrl. - * - {string} - current $location.path() - * - {Object} - current $location.search() - * - The custom redirectTo function is expected to return a string which will be used to update $location.path() and $location.search(). - */ - redirectTo?: string|{($routeParams?: angular.route.IRouteParamsService, $locationPath?: string, $locationSearch?: any) : string}; - /** - * Reload route when only $location.search() or $location.hash() changes. - * - * This option defaults to true. If the option is set to false and url in the browser changes, then $routeUpdate event is broadcasted on the root scope. - */ - reloadOnSearch?: boolean; - /** - * Match routes without being case sensitive - * - * This option defaults to false. If the option is set to true, then the particular route can be matched without being case sensitive - */ - caseInsensitiveMatch?: boolean; - } - - // see http://docs.angularjs.org/api/ng.$route#current - interface ICurrentRoute extends IRoute { - locals: { - [index: string]: any; - $scope: IScope; - $template: string; - }; - - params: any; - } - - interface IRouteProvider extends IServiceProvider { - /** - * Match routes without being case sensitive - * - * This option defaults to false. If the option is set to true, then the particular route can be matched without being case sensitive - */ - caseInsensitiveMatch?: boolean; - /** - * Sets route definition that will be used on route change when no other route definition is matched. - * - * @params Mapping information to be assigned to $route.current. - */ - otherwise(params: IRoute): IRouteProvider; - /** - * Adds a new route definition to the $route service. - * - * @param path Route path (matched against $location.path). If $location.path contains redundant trailing slash or is missing one, the route will still match and the $location.path will be updated to add or drop the trailing slash to exactly match the route definition. - * - * - path can contain named groups starting with a colon: e.g. :name. All characters up to the next slash are matched and stored in $routeParams under the given name when the route matches. - * - path can contain named groups starting with a colon and ending with a star: e.g.:name*. All characters are eagerly stored in $routeParams under the given name when the route matches. - * - path can contain optional named groups with a question mark: e.g.:name?. - * - * For example, routes like /color/:color/largecode/:largecode*\/edit will match /color/brown/largecode/code/with/slashes/edit and extract: color: brown and largecode: code/with/slashes. - * - * @param route Mapping information to be assigned to $route.current on route match. - */ - when(path: string, route: IRoute): IRouteProvider; - } -} \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-route/typings.json b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-route/typings.json deleted file mode 100644 index 4c4677f34f..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular-route/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/angularjs/angular-route.d.ts", - "raw": "registry:dt/angular-route#1.3.0+20160317120654", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/angularjs/angular-route.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular/index.d.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular/index.d.ts deleted file mode 100644 index dfde81e26b..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular/index.d.ts +++ /dev/null @@ -1,1953 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/b76dd8a7f95b71696982befbb7589940d27e940b/angularjs/angular.d.ts -declare var angular: angular.IAngularStatic; - -// Support for painless dependency injection -interface Function { - $inject?: string[]; -} - -// Collapse angular into ng -import ng = angular; -// Support AMD require -declare module 'angular' { - export = angular; -} - -/////////////////////////////////////////////////////////////////////////////// -// ng module (angular.js) -/////////////////////////////////////////////////////////////////////////////// -declare namespace angular { - - // not directly implemented, but ensures that constructed class implements $get - interface IServiceProviderClass { - new (...args: any[]): IServiceProvider; - } - - interface IServiceProviderFactory { - (...args: any[]): IServiceProvider; - } - - // All service providers extend this interface - interface IServiceProvider { - $get: any; - } - - interface IAngularBootstrapConfig { - strictDi?: boolean; - debugInfoEnabled?: boolean; - } - - /////////////////////////////////////////////////////////////////////////// - // AngularStatic - // see http://docs.angularjs.org/api - /////////////////////////////////////////////////////////////////////////// - interface IAngularStatic { - bind(context: any, fn: Function, ...args: any[]): Function; - - /** - * Use this function to manually start up angular application. - * - * @param element DOM element which is the root of angular application. - * @param modules An array of modules to load into the application. - * Each item in the array should be the name of a predefined module or a (DI annotated) - * function that will be invoked by the injector as a config block. - * @param config an object for defining configuration options for the application. The following keys are supported: - * - `strictDi`: disable automatic function annotation for the application. This is meant to assist in finding bugs which break minified code. - */ - bootstrap(element: string|Element|JQuery|Document, modules?: (string|Function|any[])[], config?: IAngularBootstrapConfig): auto.IInjectorService; - - /** - * Creates a deep copy of source, which should be an object or an array. - * - * - If no destination is supplied, a copy of the object or array is created. - * - If a destination is provided, all of its elements (for array) or properties (for objects) are deleted and then all elements/properties from the source are copied to it. - * - If source is not an object or array (inc. null and undefined), source is returned. - * - If source is identical to 'destination' an exception will be thrown. - * - * @param source The source that will be used to make a copy. Can be any type, including primitives, null, and undefined. - * @param destination Destination into which the source is copied. If provided, must be of the same type as source. - */ - copy(source: T, destination?: T): T; - - /** - * Wraps a raw DOM element or HTML string as a jQuery element. - * - * If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite." - */ - element: IAugmentedJQueryStatic; - equals(value1: any, value2: any): boolean; - extend(destination: any, ...sources: any[]): any; - - /** - * Invokes the iterator function once for each item in obj collection, which can be either an object or an array. The iterator function is invoked with iterator(value, key), where value is the value of an object property or an array element and key is the object property key or array element index. Specifying a context for the function is optional. - * - * It is worth noting that .forEach does not iterate over inherited properties because it filters using the hasOwnProperty method. - * - * @param obj Object to iterate over. - * @param iterator Iterator function. - * @param context Object to become context (this) for the iterator function. - */ - forEach(obj: T[], iterator: (value: T, key: number) => any, context?: any): any; - /** - * Invokes the iterator function once for each item in obj collection, which can be either an object or an array. The iterator function is invoked with iterator(value, key), where value is the value of an object property or an array element and key is the object property key or array element index. Specifying a context for the function is optional. - * - * It is worth noting that .forEach does not iterate over inherited properties because it filters using the hasOwnProperty method. - * - * @param obj Object to iterate over. - * @param iterator Iterator function. - * @param context Object to become context (this) for the iterator function. - */ - forEach(obj: { [index: string]: T; }, iterator: (value: T, key: string) => any, context?: any): any; - /** - * Invokes the iterator function once for each item in obj collection, which can be either an object or an array. The iterator function is invoked with iterator(value, key), where value is the value of an object property or an array element and key is the object property key or array element index. Specifying a context for the function is optional. - * - * It is worth noting that .forEach does not iterate over inherited properties because it filters using the hasOwnProperty method. - * - * @param obj Object to iterate over. - * @param iterator Iterator function. - * @param context Object to become context (this) for the iterator function. - */ - forEach(obj: any, iterator: (value: any, key: any) => any, context?: any): any; - - fromJson(json: string): any; - identity(arg?: T): T; - injector(modules?: any[], strictDi?: boolean): auto.IInjectorService; - isArray(value: any): boolean; - isDate(value: any): boolean; - isDefined(value: any): boolean; - isElement(value: any): boolean; - isFunction(value: any): boolean; - isNumber(value: any): boolean; - isObject(value: any): boolean; - isString(value: any): boolean; - isUndefined(value: any): boolean; - lowercase(str: string): string; - - /** - * Deeply extends the destination object dst by copying own enumerable properties from the src object(s) to dst. You can specify multiple src objects. If you want to preserve original objects, you can do so by passing an empty object as the target: var object = angular.merge({}, object1, object2). - * - * Unlike extend(), merge() recursively descends into object properties of source objects, performing a deep copy. - * - * @param dst Destination object. - * @param src Source object(s). - */ - merge(dst: any, ...src: any[]): any; - - /** - * The angular.module is a global place for creating, registering and retrieving Angular modules. All modules (angular core or 3rd party) that should be available to an application must be registered using this mechanism. - * - * When passed two or more arguments, a new module is created. If passed only one argument, an existing module (the name passed as the first argument to module) is retrieved. - * - * @param name The name of the module to create or retrieve. - * @param requires The names of modules this module depends on. If specified then new module is being created. If unspecified then the module is being retrieved for further configuration. - * @param configFn Optional configuration function for the module. - */ - module( - name: string, - requires?: string[], - configFn?: Function): IModule; - - noop(...args: any[]): void; - reloadWithDebugInfo(): void; - toJson(obj: any, pretty?: boolean): string; - uppercase(str: string): string; - version: { - full: string; - major: number; - minor: number; - dot: number; - codeName: string; - }; - - /** - * If window.name contains prefix NG_DEFER_BOOTSTRAP! when angular.bootstrap is called, the bootstrap process will be paused until angular.resumeBootstrap() is called. - * @param extraModules An optional array of modules that should be added to the original list of modules that the app was about to be bootstrapped with. - */ - resumeBootstrap?(extraModules?: string[]): ng.auto.IInjectorService; - } - - /////////////////////////////////////////////////////////////////////////// - // Module - // see http://docs.angularjs.org/api/angular.Module - /////////////////////////////////////////////////////////////////////////// - interface IModule { - /** - * Use this method to register a component. - * - * @param name The name of the component. - * @param options A definition object passed into the component. - */ - component(name: string, options: IComponentOptions): IModule; - /** - * Use this method to register work which needs to be performed on module loading. - * - * @param configFn Execute this function on module load. Useful for service configuration. - */ - config(configFn: Function): IModule; - /** - * Use this method to register work which needs to be performed on module loading. - * - * @param inlineAnnotatedFunction Execute this function on module load. Useful for service configuration. - */ - config(inlineAnnotatedFunction: any[]): IModule; - config(object: Object): IModule; - /** - * Register a constant service, such as a string, a number, an array, an object or a function, with the $injector. Unlike value it can be injected into a module configuration function (see config) and it cannot be overridden by an Angular decorator. - * - * @param name The name of the constant. - * @param value The constant value. - */ - constant(name: string, value: T): IModule; - constant(object: Object): IModule; - /** - * The $controller service is used by Angular to create new controllers. - * - * This provider allows controller registration via the register method. - * - * @param name Controller name, or an object map of controllers where the keys are the names and the values are the constructors. - * @param controllerConstructor Controller constructor fn (optionally decorated with DI annotations in the array notation). - */ - controller(name: string, controllerConstructor: Function): IModule; - /** - * The $controller service is used by Angular to create new controllers. - * - * This provider allows controller registration via the register method. - * - * @param name Controller name, or an object map of controllers where the keys are the names and the values are the constructors. - * @param controllerConstructor Controller constructor fn (optionally decorated with DI annotations in the array notation). - */ - controller(name: string, inlineAnnotatedConstructor: any[]): IModule; - controller(object: Object): IModule; - /** - * Register a new directive with the compiler. - * - * @param name Name of the directive in camel-case (i.e. ngBind which will match as ng-bind) - * @param directiveFactory An injectable directive factory function. - */ - directive(name: string, directiveFactory: IDirectiveFactory): IModule; - /** - * Register a new directive with the compiler. - * - * @param name Name of the directive in camel-case (i.e. ngBind which will match as ng-bind) - * @param directiveFactory An injectable directive factory function. - */ - directive(name: string, inlineAnnotatedFunction: any[]): IModule; - directive(object: Object): IModule; - /** - * Register a service factory, which will be called to return the service instance. This is short for registering a service where its provider consists of only a $get property, which is the given service factory function. You should use $provide.factory(getFn) if you do not need to configure your service in a provider. - * - * @param name The name of the instance. - * @param $getFn The $getFn for the instance creation. Internally this is a short hand for $provide.provider(name, {$get: $getFn}). - */ - factory(name: string, $getFn: Function): IModule; - /** - * Register a service factory, which will be called to return the service instance. This is short for registering a service where its provider consists of only a $get property, which is the given service factory function. You should use $provide.factory(getFn) if you do not need to configure your service in a provider. - * - * @param name The name of the instance. - * @param inlineAnnotatedFunction The $getFn for the instance creation. Internally this is a short hand for $provide.provider(name, {$get: $getFn}). - */ - factory(name: string, inlineAnnotatedFunction: any[]): IModule; - factory(object: Object): IModule; - filter(name: string, filterFactoryFunction: Function): IModule; - filter(name: string, inlineAnnotatedFunction: any[]): IModule; - filter(object: Object): IModule; - provider(name: string, serviceProviderFactory: IServiceProviderFactory): IModule; - provider(name: string, serviceProviderConstructor: IServiceProviderClass): IModule; - provider(name: string, inlineAnnotatedConstructor: any[]): IModule; - provider(name: string, providerObject: IServiceProvider): IModule; - provider(object: Object): IModule; - /** - * Run blocks are the closest thing in Angular to the main method. A run block is the code which needs to run to kickstart the application. It is executed after all of the service have been configured and the injector has been created. Run blocks typically contain code which is hard to unit-test, and for this reason should be declared in isolated modules, so that they can be ignored in the unit-tests. - */ - run(initializationFunction: Function): IModule; - /** - * Run blocks are the closest thing in Angular to the main method. A run block is the code which needs to run to kickstart the application. It is executed after all of the service have been configured and the injector has been created. Run blocks typically contain code which is hard to unit-test, and for this reason should be declared in isolated modules, so that they can be ignored in the unit-tests. - */ - run(inlineAnnotatedFunction: any[]): IModule; - /** - * Register a service constructor, which will be invoked with new to create the service instance. This is short for registering a service where its provider's $get property is a factory function that returns an instance instantiated by the injector from the service constructor function. - * - * @param name The name of the instance. - * @param serviceConstructor An injectable class (constructor function) that will be instantiated. - */ - service(name: string, serviceConstructor: Function): IModule; - /** - * Register a service constructor, which will be invoked with new to create the service instance. This is short for registering a service where its provider's $get property is a factory function that returns an instance instantiated by the injector from the service constructor function. - * - * @param name The name of the instance. - * @param inlineAnnotatedConstructor An injectable class (constructor function) that will be instantiated. - */ - service(name: string, inlineAnnotatedConstructor: any[]): IModule; - service(object: Object): IModule; - /** - * Register a value service with the $injector, such as a string, a number, an array, an object or a function. This is short for registering a service where its provider's $get property is a factory function that takes no arguments and returns the value service. - - Value services are similar to constant services, except that they cannot be injected into a module configuration function (see config) but they can be overridden by an Angular decorator. - * - * @param name The name of the instance. - * @param value The value. - */ - value(name: string, value: T): IModule; - value(object: Object): IModule; - - /** - * Register a service decorator with the $injector. A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service. - * @param name The name of the service to decorate - * @param decorator This function will be invoked when the service needs to be instantiated and should return the decorated service instance. The function is called using the injector.invoke method and is therefore fully injectable. Local injection arguments: $delegate - The original service instance, which can be monkey patched, configured, decorated or delegated to. - */ - decorator(name:string, decoratorConstructor: Function): IModule; - decorator(name:string, inlineAnnotatedConstructor: any[]): IModule; - - // Properties - name: string; - requires: string[]; - } - - /////////////////////////////////////////////////////////////////////////// - // Attributes - // see http://docs.angularjs.org/api/ng.$compile.directive.Attributes - /////////////////////////////////////////////////////////////////////////// - interface IAttributes { - /** - * this is necessary to be able to access the scoped attributes. it's not very elegant - * because you have to use attrs['foo'] instead of attrs.foo but I don't know of a better way - * this should really be limited to return string but it creates this problem: http://stackoverflow.com/q/17201854/165656 - */ - [name: string]: any; - - /** - * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with x- or data-) to its normalized, camelCase form. - * - * Also there is special case for Moz prefix starting with upper case letter. - * - * For further information check out the guide on @see https://docs.angularjs.org/guide/directive#matching-directives - */ - $normalize(name: string): string; - - /** - * Adds the CSS class value specified by the classVal parameter to the - * element. If animations are enabled then an animation will be triggered - * for the class addition. - */ - $addClass(classVal: string): void; - - /** - * Removes the CSS class value specified by the classVal parameter from the - * element. If animations are enabled then an animation will be triggered for - * the class removal. - */ - $removeClass(classVal: string): void; - - /** - * Adds and removes the appropriate CSS class values to the element based on the difference between - * the new and old CSS class values (specified as newClasses and oldClasses). - */ - $updateClass(newClasses: string, oldClasses: string): void; - - /** - * Set DOM element attribute value. - */ - $set(key: string, value: any): void; - - /** - * Observes an interpolated attribute. - * The observer function will be invoked once during the next $digest - * following compilation. The observer is then invoked whenever the - * interpolated value changes. - */ - $observe(name: string, fn: (value?: T) => any): Function; - - /** - * A map of DOM element attribute names to the normalized name. This is needed - * to do reverse lookup from normalized name back to actual name. - */ - $attr: Object; - } - - /** - * form.FormController - type in module ng - * see https://docs.angularjs.org/api/ng/type/form.FormController - */ - interface IFormController { - - /** - * Indexer which should return ng.INgModelController for most properties but cannot because of "All named properties must be assignable to string indexer type" constraint - see https://github.com/Microsoft/TypeScript/issues/272 - */ - [name: string]: any; - - $pristine: boolean; - $dirty: boolean; - $valid: boolean; - $invalid: boolean; - $submitted: boolean; - $error: any; - $pending: any; - $addControl(control: INgModelController | IFormController): void; - $removeControl(control: INgModelController | IFormController): void; - $setValidity(validationErrorKey: string, isValid: boolean, control: INgModelController | IFormController): void; - $setDirty(): void; - $setPristine(): void; - $commitViewValue(): void; - $rollbackViewValue(): void; - $setSubmitted(): void; - $setUntouched(): void; - } - - /////////////////////////////////////////////////////////////////////////// - // NgModelController - // see http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController - /////////////////////////////////////////////////////////////////////////// - interface INgModelController { - $render(): void; - $setValidity(validationErrorKey: string, isValid: boolean): void; - // Documentation states viewValue and modelValue to be a string but other - // types do work and it's common to use them. - $setViewValue(value: any, trigger?: string): void; - $setPristine(): void; - $setDirty(): void; - $validate(): void; - $setTouched(): void; - $setUntouched(): void; - $rollbackViewValue(): void; - $commitViewValue(): void; - $isEmpty(value: any): boolean; - - $viewValue: any; - - $modelValue: any; - - $parsers: IModelParser[]; - $formatters: IModelFormatter[]; - $viewChangeListeners: IModelViewChangeListener[]; - $error: any; - $name: string; - - $touched: boolean; - $untouched: boolean; - - $validators: IModelValidators; - $asyncValidators: IAsyncModelValidators; - - $pending: any; - $pristine: boolean; - $dirty: boolean; - $valid: boolean; - $invalid: boolean; - } - - //Allows tuning how model updates are done. - //https://docs.angularjs.org/api/ng/directive/ngModelOptions - interface INgModelOptions { - updateOn?: string; - debounce?: any; - allowInvalid?: boolean; - getterSetter?: boolean; - timezone?: string; - } - - interface IModelValidators { - /** - * viewValue is any because it can be an object that is called in the view like $viewValue.name:$viewValue.subName - */ - [index: string]: (modelValue: any, viewValue: any) => boolean; - } - - interface IAsyncModelValidators { - [index: string]: (modelValue: any, viewValue: any) => IPromise; - } - - interface IModelParser { - (value: any): any; - } - - interface IModelFormatter { - (value: any): any; - } - - interface IModelViewChangeListener { - (): void; - } - - /** - * $rootScope - $rootScopeProvider - service in module ng - * see https://docs.angularjs.org/api/ng/type/$rootScope.Scope and https://docs.angularjs.org/api/ng/service/$rootScope - */ - interface IRootScopeService { - [index: string]: any; - - $apply(): any; - $apply(exp: string): any; - $apply(exp: (scope: IScope) => any): any; - - $applyAsync(): any; - $applyAsync(exp: string): any; - $applyAsync(exp: (scope: IScope) => any): any; - - /** - * Dispatches an event name downwards to all child scopes (and their children) notifying the registered $rootScope.Scope listeners. - * - * The event life cycle starts at the scope on which $broadcast was called. All listeners listening for name event on this scope get notified. Afterwards, the event propagates to all direct and indirect scopes of the current scope and calls all registered listeners along the way. The event cannot be canceled. - * - * Any exception emitted from the listeners will be passed onto the $exceptionHandler service. - * - * @param name Event name to broadcast. - * @param args Optional one or more arguments which will be passed onto the event listeners. - */ - $broadcast(name: string, ...args: any[]): IAngularEvent; - $destroy(): void; - $digest(): void; - /** - * Dispatches an event name upwards through the scope hierarchy notifying the registered $rootScope.Scope listeners. - * - * The event life cycle starts at the scope on which $emit was called. All listeners listening for name event on this scope get notified. Afterwards, the event traverses upwards toward the root scope and calls all registered listeners along the way. The event will stop propagating if one of the listeners cancels it. - * - * Any exception emitted from the listeners will be passed onto the $exceptionHandler service. - * - * @param name Event name to emit. - * @param args Optional one or more arguments which will be passed onto the event listeners. - */ - $emit(name: string, ...args: any[]): IAngularEvent; - - $eval(): any; - $eval(expression: string, locals?: Object): any; - $eval(expression: (scope: IScope) => any, locals?: Object): any; - - $evalAsync(): void; - $evalAsync(expression: string): void; - $evalAsync(expression: (scope: IScope) => any): void; - - // Defaults to false by the implementation checking strategy - $new(isolate?: boolean, parent?: IScope): IScope; - - /** - * Listens on events of a given type. See $emit for discussion of event life cycle. - * - * The event listener function format is: function(event, args...). - * - * @param name Event name to listen on. - * @param listener Function to call when the event is emitted. - */ - $on(name: string, listener: (event: IAngularEvent, ...args: any[]) => any): () => void; - - $watch(watchExpression: string, listener?: string, objectEquality?: boolean): () => void; - $watch(watchExpression: string, listener?: (newValue: T, oldValue: T, scope: IScope) => any, objectEquality?: boolean): () => void; - $watch(watchExpression: (scope: IScope) => any, listener?: string, objectEquality?: boolean): () => void; - $watch(watchExpression: (scope: IScope) => T, listener?: (newValue: T, oldValue: T, scope: IScope) => any, objectEquality?: boolean): () => void; - - $watchCollection(watchExpression: string, listener: (newValue: T, oldValue: T, scope: IScope) => any): () => void; - $watchCollection(watchExpression: (scope: IScope) => T, listener: (newValue: T, oldValue: T, scope: IScope) => any): () => void; - - $watchGroup(watchExpressions: any[], listener: (newValue: any, oldValue: any, scope: IScope) => any): () => void; - $watchGroup(watchExpressions: { (scope: IScope): any }[], listener: (newValue: any, oldValue: any, scope: IScope) => any): () => void; - - $parent: IScope; - $root: IRootScopeService; - $id: number; - - // Hidden members - $$isolateBindings: any; - $$phase: any; - } - - interface IScope extends IRootScopeService { } - - /** - * $scope for ngRepeat directive. - * see https://docs.angularjs.org/api/ng/directive/ngRepeat - */ - interface IRepeatScope extends IScope { - - /** - * iterator offset of the repeated element (0..length-1). - */ - $index: number; - - /** - * true if the repeated element is first in the iterator. - */ - $first: boolean; - - /** - * true if the repeated element is between the first and last in the iterator. - */ - $middle: boolean; - - /** - * true if the repeated element is last in the iterator. - */ - $last: boolean; - - /** - * true if the iterator position $index is even (otherwise false). - */ - $even: boolean; - - /** - * true if the iterator position $index is odd (otherwise false). - */ - $odd: boolean; - - } - - interface IAngularEvent { - /** - * the scope on which the event was $emit-ed or $broadcast-ed. - */ - targetScope: IScope; - /** - * the scope that is currently handling the event. Once the event propagates through the scope hierarchy, this property is set to null. - */ - currentScope: IScope; - /** - * name of the event. - */ - name: string; - /** - * calling stopPropagation function will cancel further event propagation (available only for events that were $emit-ed). - */ - stopPropagation?: Function; - /** - * calling preventDefault sets defaultPrevented flag to true. - */ - preventDefault: Function; - /** - * true if preventDefault was called. - */ - defaultPrevented: boolean; - } - - /////////////////////////////////////////////////////////////////////////// - // WindowService - // see http://docs.angularjs.org/api/ng.$window - /////////////////////////////////////////////////////////////////////////// - interface IWindowService extends Window { - [key: string]: any; - } - - /////////////////////////////////////////////////////////////////////////// - // TimeoutService - // see http://docs.angularjs.org/api/ng.$timeout - /////////////////////////////////////////////////////////////////////////// - interface ITimeoutService { - (delay?: number, invokeApply?: boolean): IPromise; - (fn: (...args: any[]) => T, delay?: number, invokeApply?: boolean, ...args: any[]): IPromise; - cancel(promise?: IPromise): boolean; - } - - /////////////////////////////////////////////////////////////////////////// - // IntervalService - // see http://docs.angularjs.org/api/ng.$interval - /////////////////////////////////////////////////////////////////////////// - interface IIntervalService { - (func: Function, delay: number, count?: number, invokeApply?: boolean, ...args: any[]): IPromise; - cancel(promise: IPromise): boolean; - } - - /** - * $filter - $filterProvider - service in module ng - * - * Filters are used for formatting data displayed to the user. - * - * see https://docs.angularjs.org/api/ng/service/$filter - */ - interface IFilterService { - (name: 'filter'): IFilterFilter; - (name: 'currency'): IFilterCurrency; - (name: 'number'): IFilterNumber; - (name: 'date'): IFilterDate; - (name: 'json'): IFilterJson; - (name: 'lowercase'): IFilterLowercase; - (name: 'uppercase'): IFilterUppercase; - (name: 'limitTo'): IFilterLimitTo; - (name: 'orderBy'): IFilterOrderBy; - /** - * Usage: - * $filter(name); - * - * @param name Name of the filter function to retrieve - */ - (name: string): T; - } - - interface IFilterFilter { - (array: T[], expression: string | IFilterFilterPatternObject | IFilterFilterPredicateFunc, comparator?: IFilterFilterComparatorFunc|boolean): T[]; - } - - interface IFilterFilterPatternObject { - [name: string]: any; - } - - interface IFilterFilterPredicateFunc { - (value: T, index: number, array: T[]): boolean; - } - - interface IFilterFilterComparatorFunc { - (actual: T, expected: T): boolean; - } - - interface IFilterCurrency { - /** - * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default symbol for current locale is used. - * @param amount Input to filter. - * @param symbol Currency symbol or identifier to be displayed. - * @param fractionSize Number of decimal places to round the amount to, defaults to default max fraction size for current locale - * @return Formatted number - */ - (amount: number, symbol?: string, fractionSize?: number): string; - } - - interface IFilterNumber { - /** - * Formats a number as text. - * @param number Number to format. - * @param fractionSize Number of decimal places to round the number to. If this is not provided then the fraction size is computed from the current locale's number formatting pattern. In the case of the default locale, it will be 3. - * @return Number rounded to decimalPlaces and places a “,” after each third digit. - */ - (value: number|string, fractionSize?: number|string): string; - } - - interface IFilterDate { - /** - * Formats date to a string based on the requested format. - * - * @param date Date to format either as Date object, milliseconds (string or number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is specified in the string input, the time is considered to be in the local timezone. - * @param format Formatting rules (see Description). If not specified, mediumDate is used. - * @param timezone Timezone to be used for formatting. It understands UTC/GMT and the continental US time zone abbreviations, but for general use, use a time zone offset, for example, '+0430' (4 hours, 30 minutes east of the Greenwich meridian) If not specified, the timezone of the browser will be used. - * @return Formatted string or the input if input is not recognized as date/millis. - */ - (date: Date | number | string, format?: string, timezone?: string): string; - } - - interface IFilterJson { - /** - * Allows you to convert a JavaScript object into JSON string. - * @param object Any JavaScript object (including arrays and primitive types) to filter. - * @param spacing The number of spaces to use per indentation, defaults to 2. - * @return JSON string. - */ - (object: any, spacing?: number): string; - } - - interface IFilterLowercase { - /** - * Converts string to lowercase. - */ - (value: string): string; - } - - interface IFilterUppercase { - /** - * Converts string to uppercase. - */ - (value: string): string; - } - - interface IFilterLimitTo { - /** - * Creates a new array containing only a specified number of elements. The elements are taken from either the beginning or the end of the source array, string or number, as specified by the value and sign (positive or negative) of limit. - * @param input Source array to be limited. - * @param limit The length of the returned array. If the limit number is positive, limit number of items from the beginning of the source array/string are copied. If the number is negative, limit number of items from the end of the source array are copied. The limit will be trimmed if it exceeds array.length. If limit is undefined, the input will be returned unchanged. - * @param begin Index at which to begin limitation. As a negative index, begin indicates an offset from the end of input. Defaults to 0. - * @return A new sub-array of length limit or less if input array had less than limit elements. - */ - (input: T[], limit: string|number, begin?: string|number): T[]; - /** - * Creates a new string containing only a specified number of elements. The elements are taken from either the beginning or the end of the source string or number, as specified by the value and sign (positive or negative) of limit. If a number is used as input, it is converted to a string. - * @param input Source string or number to be limited. - * @param limit The length of the returned string. If the limit number is positive, limit number of items from the beginning of the source string are copied. If the number is negative, limit number of items from the end of the source string are copied. The limit will be trimmed if it exceeds input.length. If limit is undefined, the input will be returned unchanged. - * @param begin Index at which to begin limitation. As a negative index, begin indicates an offset from the end of input. Defaults to 0. - * @return A new substring of length limit or less if input had less than limit elements. - */ - (input: string|number, limit: string|number, begin?: string|number): string; - } - - interface IFilterOrderBy { - /** - * Orders a specified array by the expression predicate. It is ordered alphabetically for strings and numerically for numbers. Note: if you notice numbers are not being sorted as expected, make sure they are actually being saved as numbers and not strings. - * @param array The array to sort. - * @param expression A predicate to be used by the comparator to determine the order of elements. - * @param reverse Reverse the order of the array. - * @return Reverse the order of the array. - */ - (array: T[], expression: string|((value: T) => any)|(((value: T) => any)|string)[], reverse?: boolean): T[]; - } - - /** - * $filterProvider - $filter - provider in module ng - * - * Filters are just functions which transform input to an output. However filters need to be Dependency Injected. To achieve this a filter definition consists of a factory function which is annotated with dependencies and is responsible for creating a filter function. - * - * see https://docs.angularjs.org/api/ng/provider/$filterProvider - */ - interface IFilterProvider extends IServiceProvider { - /** - * register(name); - * - * @param name Name of the filter function, or an object map of filters where the keys are the filter names and the values are the filter factories. Note: Filter names must be valid angular Expressions identifiers, such as uppercase or orderBy. Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace your filters, then you can use capitalization (myappSubsectionFilterx) or underscores (myapp_subsection_filterx). - */ - register(name: string | {}): IServiceProvider; - } - - /////////////////////////////////////////////////////////////////////////// - // LocaleService - // see http://docs.angularjs.org/api/ng.$locale - /////////////////////////////////////////////////////////////////////////// - interface ILocaleService { - id: string; - - // These are not documented - // Check angular's i18n files for exemples - NUMBER_FORMATS: ILocaleNumberFormatDescriptor; - DATETIME_FORMATS: ILocaleDateTimeFormatDescriptor; - pluralCat: (num: any) => string; - } - - interface ILocaleNumberFormatDescriptor { - DECIMAL_SEP: string; - GROUP_SEP: string; - PATTERNS: ILocaleNumberPatternDescriptor[]; - CURRENCY_SYM: string; - } - - interface ILocaleNumberPatternDescriptor { - minInt: number; - minFrac: number; - maxFrac: number; - posPre: string; - posSuf: string; - negPre: string; - negSuf: string; - gSize: number; - lgSize: number; - } - - interface ILocaleDateTimeFormatDescriptor { - MONTH: string[]; - SHORTMONTH: string[]; - DAY: string[]; - SHORTDAY: string[]; - AMPMS: string[]; - medium: string; - short: string; - fullDate: string; - longDate: string; - mediumDate: string; - shortDate: string; - mediumTime: string; - shortTime: string; - } - - /////////////////////////////////////////////////////////////////////////// - // LogService - // see http://docs.angularjs.org/api/ng.$log - // see http://docs.angularjs.org/api/ng.$logProvider - /////////////////////////////////////////////////////////////////////////// - interface ILogService { - debug: ILogCall; - error: ILogCall; - info: ILogCall; - log: ILogCall; - warn: ILogCall; - } - - interface ILogProvider extends IServiceProvider { - debugEnabled(): boolean; - debugEnabled(enabled: boolean): ILogProvider; - } - - // We define this as separate interface so we can reopen it later for - // the ngMock module. - interface ILogCall { - (...args: any[]): void; - } - - /////////////////////////////////////////////////////////////////////////// - // ParseService - // see http://docs.angularjs.org/api/ng.$parse - // see http://docs.angularjs.org/api/ng.$parseProvider - /////////////////////////////////////////////////////////////////////////// - interface IParseService { - (expression: string): ICompiledExpression; - } - - interface IParseProvider { - logPromiseWarnings(): boolean; - logPromiseWarnings(value: boolean): IParseProvider; - - unwrapPromises(): boolean; - unwrapPromises(value: boolean): IParseProvider; - } - - interface ICompiledExpression { - (context: any, locals?: any): any; - - literal: boolean; - constant: boolean; - - // If value is not provided, undefined is gonna be used since the implementation - // does not check the parameter. Let's force a value for consistency. If consumer - // whants to undefine it, pass the undefined value explicitly. - assign(context: any, value: any): any; - } - - /** - * $location - $locationProvider - service in module ng - * see https://docs.angularjs.org/api/ng/service/$location - */ - interface ILocationService { - absUrl(): string; - hash(): string; - hash(newHash: string): ILocationService; - host(): string; - - /** - * Return path of current url - */ - path(): string; - - /** - * Change path when called with parameter and return $location. - * Note: Path should always begin with forward slash (/), this method will add the forward slash if it is missing. - * - * @param path New path - */ - path(path: string): ILocationService; - - port(): number; - protocol(): string; - replace(): ILocationService; - - /** - * Return search part (as object) of current url - */ - search(): any; - - /** - * Change search part when called with parameter and return $location. - * - * @param search When called with a single argument the method acts as a setter, setting the search component of $location to the specified value. - * - * If the argument is a hash object containing an array of values, these values will be encoded as duplicate search parameters in the url. - */ - search(search: any): ILocationService; - - /** - * Change search part when called with parameter and return $location. - * - * @param search New search params - * @param paramValue If search is a string or a Number, then paramValue will override only a single search property. If paramValue is null, the property specified via the first argument will be deleted. If paramValue is an array, it will override the property of the search component of $location specified via the first argument. If paramValue is true, the property specified via the first argument will be added with no value nor trailing equal sign. - */ - search(search: string, paramValue: string|number|string[]|boolean): ILocationService; - - state(): any; - state(state: any): ILocationService; - url(): string; - url(url: string): ILocationService; - } - - interface ILocationProvider extends IServiceProvider { - hashPrefix(): string; - hashPrefix(prefix: string): ILocationProvider; - html5Mode(): boolean; - - // Documentation states that parameter is string, but - // implementation tests it as boolean, which makes more sense - // since this is a toggler - html5Mode(active: boolean): ILocationProvider; - html5Mode(mode: { enabled?: boolean; requireBase?: boolean; rewriteLinks?: boolean; }): ILocationProvider; - } - - /////////////////////////////////////////////////////////////////////////// - // DocumentService - // see http://docs.angularjs.org/api/ng.$document - /////////////////////////////////////////////////////////////////////////// - interface IDocumentService extends IAugmentedJQuery {} - - /////////////////////////////////////////////////////////////////////////// - // ExceptionHandlerService - // see http://docs.angularjs.org/api/ng.$exceptionHandler - /////////////////////////////////////////////////////////////////////////// - interface IExceptionHandlerService { - (exception: Error, cause?: string): void; - } - - /////////////////////////////////////////////////////////////////////////// - // RootElementService - // see http://docs.angularjs.org/api/ng.$rootElement - /////////////////////////////////////////////////////////////////////////// - interface IRootElementService extends JQuery {} - - interface IQResolveReject { - (): void; - (value: T): void; - } - /** - * $q - service in module ng - * A promise/deferred implementation inspired by Kris Kowal's Q. - * See http://docs.angularjs.org/api/ng/service/$q - */ - interface IQService { - new (resolver: (resolve: IQResolveReject) => any): IPromise; - new (resolver: (resolve: IQResolveReject, reject: IQResolveReject) => any): IPromise; - (resolver: (resolve: IQResolveReject) => any): IPromise; - (resolver: (resolve: IQResolveReject, reject: IQResolveReject) => any): IPromise; - - /** - * Combines multiple promises into a single promise that is resolved when all of the input promises are resolved. - * - * Returns a single promise that will be resolved with an array of values, each value corresponding to the promise at the same index in the promises array. If any of the promises is resolved with a rejection, this resulting promise will be rejected with the same rejection value. - * - * @param promises An array of promises. - */ - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise, T8 | IPromise, T9 | IPromise, T10 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise, T8 | IPromise, T9 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise, T8 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7, T8]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise]): IPromise<[T1, T2, T3, T4, T5]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise ]): IPromise<[T1, T2, T3, T4]>; - all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise]): IPromise<[T1, T2, T3]>; - all(values: [T1 | IPromise, T2 | IPromise]): IPromise<[T1, T2]>; - all(promises: IPromise[]): IPromise; - /** - * Combines multiple promises into a single promise that is resolved when all of the input promises are resolved. - * - * Returns a single promise that will be resolved with a hash of values, each value corresponding to the promise at the same key in the promises hash. If any of the promises is resolved with a rejection, this resulting promise will be rejected with the same rejection value. - * - * @param promises A hash of promises. - */ - all(promises: { [id: string]: IPromise; }): IPromise<{ [id: string]: any; }>; - all(promises: { [id: string]: IPromise; }): IPromise; - /** - * Creates a Deferred object which represents a task which will finish in the future. - */ - defer(): IDeferred; - /** - * Creates a promise that is resolved as rejected with the specified reason. This api should be used to forward rejection in a chain of promises. If you are dealing with the last promise in a promise chain, you don't need to worry about it. - * - * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of reject as the throw keyword in JavaScript. This also means that if you "catch" an error via a promise error callback and you want to forward the error to the promise derived from the current promise, you have to "rethrow" the error by returning a rejection constructed via reject. - * - * @param reason Constant, message, exception or an object representing the rejection reason. - */ - reject(reason?: any): IPromise; - /** - * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. - * - * @param value Value or a promise - */ - resolve(value: IPromise|T): IPromise; - /** - * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. - */ - resolve(): IPromise; - /** - * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. - * - * @param value Value or a promise - */ - when(value: IPromise|T): IPromise; - /** - * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. - */ - when(): IPromise; - } - - interface IPromise { - /** - * Regardless of when the promise was or will be resolved or rejected, then calls one of the success or error callbacks asynchronously as soon as the result is available. The callbacks are called with a single argument: the result or rejection reason. Additionally, the notify callback may be called zero or more times to provide a progress indication, before the promise is resolved or rejected. - * The successCallBack may return IPromise for when a $q.reject() needs to be returned - * This method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback. It also notifies via the return value of the notifyCallback method. The promise can not be resolved or rejected from the notifyCallback method. - */ - then(successCallback: (promiseValue: T) => IPromise|TResult, errorCallback?: (reason: any) => any, notifyCallback?: (state: any) => any): IPromise; - - /** - * Shorthand for promise.then(null, errorCallback) - */ - catch(onRejected: (reason: any) => IPromise|TResult): IPromise; - - /** - * Allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful to release resources or do some clean-up that needs to be done whether the promise was rejected or resolved. See the full specification for more information. - * - * Because finally is a reserved word in JavaScript and reserved keywords are not supported as property names by ES3, you'll need to invoke the method like promise['finally'](callback) to make your code IE8 and Android 2.x compatible. - */ - finally(finallyCallback: () => any): IPromise; - } - - interface IDeferred { - resolve(value?: T|IPromise): void; - reject(reason?: any): void; - notify(state?: any): void; - promise: IPromise; - } - - /////////////////////////////////////////////////////////////////////////// - // AnchorScrollService - // see http://docs.angularjs.org/api/ng.$anchorScroll - /////////////////////////////////////////////////////////////////////////// - interface IAnchorScrollService { - (): void; - (hash: string): void; - yOffset: any; - } - - interface IAnchorScrollProvider extends IServiceProvider { - disableAutoScrolling(): void; - } - - /** - * $cacheFactory - service in module ng - * - * Factory that constructs Cache objects and gives access to them. - * - * see https://docs.angularjs.org/api/ng/service/$cacheFactory - */ - interface ICacheFactoryService { - /** - * Factory that constructs Cache objects and gives access to them. - * - * @param cacheId Name or id of the newly created cache. - * @param optionsMap Options object that specifies the cache behavior. Properties: - * - * capacity — turns the cache into LRU cache. - */ - (cacheId: string, optionsMap?: { capacity?: number; }): ICacheObject; - - /** - * Get information about all the caches that have been created. - * @returns key-value map of cacheId to the result of calling cache#info - */ - info(): any; - - /** - * Get access to a cache object by the cacheId used when it was created. - * - * @param cacheId Name or id of a cache to access. - */ - get(cacheId: string): ICacheObject; - } - - /** - * $cacheFactory.Cache - type in module ng - * - * A cache object used to store and retrieve data, primarily used by $http and the script directive to cache templates and other data. - * - * see https://docs.angularjs.org/api/ng/type/$cacheFactory.Cache - */ - interface ICacheObject { - /** - * Retrieve information regarding a particular Cache. - */ - info(): { - /** - * the id of the cache instance - */ - id: string; - - /** - * the number of entries kept in the cache instance - */ - size: number; - - //...: any additional properties from the options object when creating the cache. - }; - - /** - * Inserts a named entry into the Cache object to be retrieved later, and incrementing the size of the cache if the key was not already present in the cache. If behaving like an LRU cache, it will also remove stale entries from the set. - * - * It will not insert undefined values into the cache. - * - * @param key the key under which the cached data is stored. - * @param value the value to store alongside the key. If it is undefined, the key will not be stored. - */ - put(key: string, value?: T): T; - - /** - * Retrieves named data stored in the Cache object. - * - * @param key the key of the data to be retrieved - */ - get(key: string): T; - - /** - * Removes an entry from the Cache object. - * - * @param key the key of the entry to be removed - */ - remove(key: string): void; - - /** - * Clears the cache object of any entries. - */ - removeAll(): void; - - /** - * Destroys the Cache object entirely, removing it from the $cacheFactory set. - */ - destroy(): void; - } - - /////////////////////////////////////////////////////////////////////////// - // CompileService - // see http://docs.angularjs.org/api/ng.$compile - // see http://docs.angularjs.org/api/ng.$compileProvider - /////////////////////////////////////////////////////////////////////////// - interface ICompileService { - (element: string, transclude?: ITranscludeFunction, maxPriority?: number): ITemplateLinkingFunction; - (element: Element, transclude?: ITranscludeFunction, maxPriority?: number): ITemplateLinkingFunction; - (element: JQuery, transclude?: ITranscludeFunction, maxPriority?: number): ITemplateLinkingFunction; - } - - interface ICompileProvider extends IServiceProvider { - directive(name: string, directiveFactory: Function): ICompileProvider; - directive(directivesMap: Object, directiveFactory: Function): ICompileProvider; - directive(name: string, inlineAnnotatedFunction: any[]): ICompileProvider; - directive(directivesMap: Object, inlineAnnotatedFunction: any[]): ICompileProvider; - - // Undocumented, but it is there... - directive(directivesMap: any): ICompileProvider; - - component(name: string, options: IComponentOptions): ICompileProvider; - - aHrefSanitizationWhitelist(): RegExp; - aHrefSanitizationWhitelist(regexp: RegExp): ICompileProvider; - - imgSrcSanitizationWhitelist(): RegExp; - imgSrcSanitizationWhitelist(regexp: RegExp): ICompileProvider; - - debugInfoEnabled(enabled?: boolean): any; - } - - interface ICloneAttachFunction { - // Let's hint but not force cloneAttachFn's signature - (clonedElement?: JQuery, scope?: IScope): any; - } - - // This corresponds to the "publicLinkFn" returned by $compile. - interface ITemplateLinkingFunction { - (scope: IScope, cloneAttachFn?: ICloneAttachFunction): IAugmentedJQuery; - } - - // This corresponds to $transclude (and also the transclude function passed to link). - interface ITranscludeFunction { - // If the scope is provided, then the cloneAttachFn must be as well. - (scope: IScope, cloneAttachFn: ICloneAttachFunction): IAugmentedJQuery; - // If one argument is provided, then it's assumed to be the cloneAttachFn. - (cloneAttachFn?: ICloneAttachFunction): IAugmentedJQuery; - } - - /////////////////////////////////////////////////////////////////////////// - // ControllerService - // see http://docs.angularjs.org/api/ng.$controller - // see http://docs.angularjs.org/api/ng.$controllerProvider - /////////////////////////////////////////////////////////////////////////// - interface IControllerService { - // Although the documentation doesn't state this, locals are optional - (controllerConstructor: new (...args: any[]) => T, locals?: any, later?: boolean, ident?: string): T; - (controllerConstructor: Function, locals?: any, later?: boolean, ident?: string): T; - (controllerName: string, locals?: any, later?: boolean, ident?: string): T; - } - - interface IControllerProvider extends IServiceProvider { - register(name: string, controllerConstructor: Function): void; - register(name: string, dependencyAnnotatedConstructor: any[]): void; - allowGlobals(): void; - } - - /** - * xhrFactory - * Replace or decorate this service to create your own custom XMLHttpRequest objects. - * see https://docs.angularjs.org/api/ng/service/$xhrFactory - */ - interface IXhrFactory { - (method: string, url: string): T; - } - - /** - * HttpService - * see http://docs.angularjs.org/api/ng/service/$http - */ - interface IHttpService { - /** - * Object describing the request to be made and how it should be processed. - */ - (config: IRequestConfig): IHttpPromise; - - /** - * Shortcut method to perform GET request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param config Optional configuration object - */ - get(url: string, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform DELETE request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param config Optional configuration object - */ - delete(url: string, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform HEAD request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param config Optional configuration object - */ - head(url: string, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform JSONP request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param config Optional configuration object - */ - jsonp(url: string, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform POST request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param data Request content - * @param config Optional configuration object - */ - post(url: string, data: any, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform PUT request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param data Request content - * @param config Optional configuration object - */ - put(url: string, data: any, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Shortcut method to perform PATCH request. - * - * @param url Relative or absolute URL specifying the destination of the request - * @param data Request content - * @param config Optional configuration object - */ - patch(url: string, data: any, config?: IRequestShortcutConfig): IHttpPromise; - - /** - * Runtime equivalent of the $httpProvider.defaults property. Allows configuration of default headers, withCredentials as well as request and response transformations. - */ - defaults: IHttpProviderDefaults; - - /** - * Array of config objects for currently pending requests. This is primarily meant to be used for debugging purposes. - */ - pendingRequests: IRequestConfig[]; - } - - /** - * Object describing the request to be made and how it should be processed. - * see http://docs.angularjs.org/api/ng/service/$http#usage - */ - interface IRequestShortcutConfig extends IHttpProviderDefaults { - /** - * {Object.} - * Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified. - */ - params?: any; - - /** - * {string|Object} - * Data to be sent as the request message data. - */ - data?: any; - - /** - * Timeout in milliseconds, or promise that should abort the request when resolved. - */ - timeout?: number|IPromise; - - /** - * See [XMLHttpRequest.responseType]https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype - */ - responseType?: string; - } - - /** - * Object describing the request to be made and how it should be processed. - * see http://docs.angularjs.org/api/ng/service/$http#usage - */ - interface IRequestConfig extends IRequestShortcutConfig { - /** - * HTTP method (e.g. 'GET', 'POST', etc) - */ - method: string; - /** - * Absolute or relative URL of the resource that is being requested. - */ - url: string; - } - - interface IHttpHeadersGetter { - (): { [name: string]: string; }; - (headerName: string): string; - } - - interface IHttpPromiseCallback { - (data: T, status: number, headers: IHttpHeadersGetter, config: IRequestConfig): void; - } - - interface IHttpPromiseCallbackArg { - data?: T; - status?: number; - headers?: IHttpHeadersGetter; - config?: IRequestConfig; - statusText?: string; - } - - interface IHttpPromise extends IPromise> { - /** - * The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. - * If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error. - * @deprecated - */ - success?(callback: IHttpPromiseCallback): IHttpPromise; - /** - * The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. - * If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error. - * @deprecated - */ - error?(callback: IHttpPromiseCallback): IHttpPromise; - } - - // See the jsdoc for transformData() at https://github.com/angular/angular.js/blob/master/src/ng/http.js#L228 - interface IHttpRequestTransformer { - (data: any, headersGetter: IHttpHeadersGetter): any; - } - - // The definition of fields are the same as IHttpPromiseCallbackArg - interface IHttpResponseTransformer { - (data: any, headersGetter: IHttpHeadersGetter, status: number): any; - } - - type HttpHeaderType = {[requestType: string]:string|((config:IRequestConfig) => string)}; - - interface IHttpRequestConfigHeaders { - [requestType: string]: any; - common?: any; - get?: any; - post?: any; - put?: any; - patch?: any; - } - - /** - * Object that controls the defaults for $http provider. Not all fields of IRequestShortcutConfig can be configured - * via defaults and the docs do not say which. The following is based on the inspection of the source code. - * https://docs.angularjs.org/api/ng/service/$http#defaults - * https://docs.angularjs.org/api/ng/service/$http#usage - * https://docs.angularjs.org/api/ng/provider/$httpProvider The properties section - */ - interface IHttpProviderDefaults { - /** - * {boolean|Cache} - * If true, a default $http cache will be used to cache the GET request, otherwise if a cache instance built with $cacheFactory, this cache will be used for caching. - */ - cache?: any; - - /** - * Transform function or an array of such functions. The transform function takes the http request body and - * headers and returns its transformed (typically serialized) version. - * @see {@link https://docs.angularjs.org/api/ng/service/$http#transforming-requests-and-responses} - */ - transformRequest?: IHttpRequestTransformer |IHttpRequestTransformer[]; - - /** - * Transform function or an array of such functions. The transform function takes the http response body and - * headers and returns its transformed (typically deserialized) version. - */ - transformResponse?: IHttpResponseTransformer | IHttpResponseTransformer[]; - - /** - * Map of strings or functions which return strings representing HTTP headers to send to the server. If the - * return value of a function is null, the header will not be sent. - * The key of the map is the request verb in lower case. The "common" key applies to all requests. - * @see {@link https://docs.angularjs.org/api/ng/service/$http#setting-http-headers} - */ - headers?: IHttpRequestConfigHeaders; - - /** Name of HTTP header to populate with the XSRF token. */ - xsrfHeaderName?: string; - - /** Name of cookie containing the XSRF token. */ - xsrfCookieName?: string; - - /** - * whether to to set the withCredentials flag on the XHR object. See [requests with credentials]https://developer.mozilla.org/en/http_access_control#section_5 for more information. - */ - withCredentials?: boolean; - - /** - * A function used to the prepare string representation of request parameters (specified as an object). If - * specified as string, it is interpreted as a function registered with the $injector. Defaults to - * $httpParamSerializer. - */ - paramSerializer?: string | ((obj: any) => string); - } - - interface IHttpInterceptor { - request?: (config: IRequestConfig) => IRequestConfig|IPromise; - requestError?: (rejection: any) => any; - response?: (response: IHttpPromiseCallbackArg) => IPromise>|IHttpPromiseCallbackArg; - responseError?: (rejection: any) => any; - } - - interface IHttpInterceptorFactory { - (...args: any[]): IHttpInterceptor; - } - - interface IHttpProvider extends IServiceProvider { - defaults: IHttpProviderDefaults; - - /** - * Register service factories (names or implementations) for interceptors which are called before and after - * each request. - */ - interceptors: (string|IHttpInterceptorFactory|(string|IHttpInterceptorFactory)[])[]; - useApplyAsync(): boolean; - useApplyAsync(value: boolean): IHttpProvider; - - /** - * - * @param {boolean=} value If true, `$http` will return a normal promise without the `success` and `error` methods. - * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining. - * otherwise, returns the current configured value. - */ - useLegacyPromiseExtensions(value:boolean) : boolean | IHttpProvider; - } - - /////////////////////////////////////////////////////////////////////////// - // HttpBackendService - // see http://docs.angularjs.org/api/ng.$httpBackend - // You should never need to use this service directly. - /////////////////////////////////////////////////////////////////////////// - interface IHttpBackendService { - // XXX Perhaps define callback signature in the future - (method: string, url: string, post?: any, callback?: Function, headers?: any, timeout?: number, withCredentials?: boolean): void; - } - - /////////////////////////////////////////////////////////////////////////// - // InterpolateService - // see http://docs.angularjs.org/api/ng.$interpolate - // see http://docs.angularjs.org/api/ng.$interpolateProvider - /////////////////////////////////////////////////////////////////////////// - interface IInterpolateService { - (text: string, mustHaveExpression?: boolean, trustedContext?: string, allOrNothing?: boolean): IInterpolationFunction; - endSymbol(): string; - startSymbol(): string; - } - - interface IInterpolationFunction { - (context: any): string; - } - - interface IInterpolateProvider extends IServiceProvider { - startSymbol(): string; - startSymbol(value: string): IInterpolateProvider; - endSymbol(): string; - endSymbol(value: string): IInterpolateProvider; - } - - /////////////////////////////////////////////////////////////////////////// - // TemplateCacheService - // see http://docs.angularjs.org/api/ng.$templateCache - /////////////////////////////////////////////////////////////////////////// - interface ITemplateCacheService extends ICacheObject {} - - /////////////////////////////////////////////////////////////////////////// - // SCEService - // see http://docs.angularjs.org/api/ng.$sce - /////////////////////////////////////////////////////////////////////////// - interface ISCEService { - getTrusted(type: string, mayBeTrusted: any): any; - getTrustedCss(value: any): any; - getTrustedHtml(value: any): any; - getTrustedJs(value: any): any; - getTrustedResourceUrl(value: any): any; - getTrustedUrl(value: any): any; - parse(type: string, expression: string): (context: any, locals: any) => any; - parseAsCss(expression: string): (context: any, locals: any) => any; - parseAsHtml(expression: string): (context: any, locals: any) => any; - parseAsJs(expression: string): (context: any, locals: any) => any; - parseAsResourceUrl(expression: string): (context: any, locals: any) => any; - parseAsUrl(expression: string): (context: any, locals: any) => any; - trustAs(type: string, value: any): any; - trustAsHtml(value: any): any; - trustAsJs(value: any): any; - trustAsResourceUrl(value: any): any; - trustAsUrl(value: any): any; - isEnabled(): boolean; - } - - /////////////////////////////////////////////////////////////////////////// - // SCEProvider - // see http://docs.angularjs.org/api/ng.$sceProvider - /////////////////////////////////////////////////////////////////////////// - interface ISCEProvider extends IServiceProvider { - enabled(value: boolean): void; - } - - /////////////////////////////////////////////////////////////////////////// - // SCEDelegateService - // see http://docs.angularjs.org/api/ng.$sceDelegate - /////////////////////////////////////////////////////////////////////////// - interface ISCEDelegateService { - getTrusted(type: string, mayBeTrusted: any): any; - trustAs(type: string, value: any): any; - valueOf(value: any): any; - } - - - /////////////////////////////////////////////////////////////////////////// - // SCEDelegateProvider - // see http://docs.angularjs.org/api/ng.$sceDelegateProvider - /////////////////////////////////////////////////////////////////////////// - interface ISCEDelegateProvider extends IServiceProvider { - resourceUrlBlacklist(blacklist: any[]): void; - resourceUrlWhitelist(whitelist: any[]): void; - resourceUrlBlacklist(): any[]; - resourceUrlWhitelist(): any[]; - } - - /** - * $templateRequest service - * see http://docs.angularjs.org/api/ng/service/$templateRequest - */ - interface ITemplateRequestService { - /** - * Downloads a template using $http and, upon success, stores the - * contents inside of $templateCache. - * - * If the HTTP request fails or the response data of the HTTP request is - * empty then a $compile error will be thrown (unless - * {ignoreRequestError} is set to true). - * - * @param tpl The template URL. - * @param ignoreRequestError Whether or not to ignore the exception - * when the request fails or the template is - * empty. - * - * @return A promise whose value is the template content. - */ - (tpl: string, ignoreRequestError?: boolean): IPromise; - /** - * total amount of pending template requests being downloaded. - * @type {number} - */ - totalPendingRequests: number; - } - - /////////////////////////////////////////////////////////////////////////// - // Component - // see http://angularjs.blogspot.com.br/2015/11/angularjs-15-beta2-and-14-releases.html - // and http://toddmotto.com/exploring-the-angular-1-5-component-method/ - /////////////////////////////////////////////////////////////////////////// - /** - * Runtime representation a type that a Component or other object is instances of. - * - * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by - * the `MyCustomComponent` constructor function. - */ - interface Type extends Function { - } - - /** - * `RouteDefinition` defines a route within a {@link RouteConfig} decorator. - * - * Supported keys: - * - `path` or `aux` (requires exactly one of these) - * - `component`, `loader`, `redirectTo` (requires exactly one of these) - * - `name` or `as` (optional) (requires exactly one of these) - * - `data` (optional) - * - * See also {@link Route}, {@link AsyncRoute}, {@link AuxRoute}, and {@link Redirect}. - */ - interface RouteDefinition { - path?: string; - aux?: string; - component?: Type | ComponentDefinition | string; - loader?: Function; - redirectTo?: any[]; - as?: string; - name?: string; - data?: any; - useAsDefault?: boolean; - } - - /** - * Represents either a component type (`type` is `component`) or a loader function - * (`type` is `loader`). - * - * See also {@link RouteDefinition}. - */ - interface ComponentDefinition { - type: string; - loader?: Function; - component?: Type; - } - - /** - * Component definition object (a simplified directive definition object) - */ - interface IComponentOptions { - /** - * Controller constructor function that should be associated with newly created scope or the name of a registered - * controller if passed as a string. Empty function by default. - * Use the array form to define dependencies (necessary if strictDi is enabled and you require dependency injection) - */ - controller?: string | Function | (string | Function)[]; - /** - * An identifier name for a reference to the controller. If present, the controller will be published to scope under - * the controllerAs name. If not present, this will default to be the same as the component name. - * @default "$ctrl" - */ - controllerAs?: string; - /** - * html template as a string or a function that returns an html template as a string which should be used as the - * contents of this component. Empty string by default. - * If template is a function, then it is injected with the following locals: - * $element - Current element - * $attrs - Current attributes object for the element - * Use the array form to define dependencies (necessary if strictDi is enabled and you require dependency injection) - */ - template?: string | Function | (string | Function)[]; - /** - * path or function that returns a path to an html template that should be used as the contents of this component. - * If templateUrl is a function, then it is injected with the following locals: - * $element - Current element - * $attrs - Current attributes object for the element - * Use the array form to define dependencies (necessary if strictDi is enabled and you require dependency injection) - */ - templateUrl?: string | Function | (string | Function)[]; - /** - * Define DOM attribute binding to component properties. Component properties are always bound to the component - * controller and not to the scope. - */ - bindings?: {[binding: string]: string}; - /** - * Whether transclusion is enabled. Enabled by default. - */ - transclude?: boolean | string | {[slot: string]: string}; - require?: string | string[] | {[controller: string]: string}; - } - - interface IComponentTemplateFn { - ( $element?: IAugmentedJQuery, $attrs?: IAttributes ): string; - } - - /////////////////////////////////////////////////////////////////////////// - // Directive - // see http://docs.angularjs.org/api/ng.$compileProvider#directive - // and http://docs.angularjs.org/guide/directive - /////////////////////////////////////////////////////////////////////////// - - interface IDirectiveFactory { - (...args: any[]): IDirective; - } - - interface IDirectiveLinkFn { - ( - scope: IScope, - instanceElement: IAugmentedJQuery, - instanceAttributes: IAttributes, - controller: {}, - transclude: ITranscludeFunction - ): void; - } - - interface IDirectivePrePost { - pre?: IDirectiveLinkFn; - post?: IDirectiveLinkFn; - } - - interface IDirectiveCompileFn { - ( - templateElement: IAugmentedJQuery, - templateAttributes: IAttributes, - /** - * @deprecated - * Note: The transclude function that is passed to the compile function is deprecated, - * as it e.g. does not know about the right outer scope. Please use the transclude function - * that is passed to the link function instead. - */ - transclude: ITranscludeFunction - ): IDirectivePrePost; - } - - interface IDirective { - compile?: IDirectiveCompileFn; - controller?: any; - controllerAs?: string; - /** - * @deprecated - * Deprecation warning: although bindings for non-ES6 class controllers are currently bound to this before - * the controller constructor is called, this use is now deprecated. Please place initialization code that - * relies upon bindings inside a $onInit method on the controller, instead. - */ - bindToController?: boolean | Object; - link?: IDirectiveLinkFn | IDirectivePrePost; - multiElement?: boolean; - name?: string; - priority?: number; - /** - * @deprecated - */ - replace?: boolean; - require?: string | string[] | {[controller: string]: string}; - restrict?: string; - scope?: boolean | Object; - template?: string | Function; - templateNamespace?: string; - templateUrl?: string | Function; - terminal?: boolean; - transclude?: boolean | string | {[slot: string]: string}; - } - - /** - * angular.element - * when calling angular.element, angular returns a jQuery object, - * augmented with additional methods like e.g. scope. - * see: http://docs.angularjs.org/api/angular.element - */ - interface IAugmentedJQueryStatic extends JQueryStatic { - (selector: string, context?: any): IAugmentedJQuery; - (element: Element): IAugmentedJQuery; - (object: {}): IAugmentedJQuery; - (elementArray: Element[]): IAugmentedJQuery; - (object: JQuery): IAugmentedJQuery; - (func: Function): IAugmentedJQuery; - (array: any[]): IAugmentedJQuery; - (): IAugmentedJQuery; - } - - interface IAugmentedJQuery extends JQuery { - // TODO: events, how to define? - //$destroy - - find(selector: string): IAugmentedJQuery; - find(element: any): IAugmentedJQuery; - find(obj: JQuery): IAugmentedJQuery; - controller(): any; - controller(name: string): any; - injector(): any; - scope(): IScope; - - /** - * Overload for custom scope interfaces - */ - scope(): T; - isolateScope(): IScope; - - inheritedData(key: string, value: any): JQuery; - inheritedData(obj: { [key: string]: any; }): JQuery; - inheritedData(key?: string): any; - } - - /////////////////////////////////////////////////////////////////////////// - // AUTO module (angular.js) - /////////////////////////////////////////////////////////////////////////// - export module auto { - - /////////////////////////////////////////////////////////////////////// - // InjectorService - // see http://docs.angularjs.org/api/AUTO.$injector - /////////////////////////////////////////////////////////////////////// - interface IInjectorService { - annotate(fn: Function, strictDi?: boolean): string[]; - annotate(inlineAnnotatedFunction: any[]): string[]; - get(name: string, caller?: string): T; - get(name: '$anchorScroll'): IAnchorScrollService - get(name: '$cacheFactory'): ICacheFactoryService - get(name: '$compile'): ICompileService - get(name: '$controller'): IControllerService - get(name: '$document'): IDocumentService - get(name: '$exceptionHandler'): IExceptionHandlerService - get(name: '$filter'): IFilterService - get(name: '$http'): IHttpService - get(name: '$httpBackend'): IHttpBackendService - get(name: '$httpParamSerializer'): IHttpParamSerializer - get(name: '$httpParamSerializerJQLike'): IHttpParamSerializer - get(name: '$interpolate'): IInterpolateService - get(name: '$interval'): IIntervalService - get(name: '$locale'): ILocaleService - get(name: '$location'): ILocationService - get(name: '$log'): ILogService - get(name: '$parse'): IParseService - get(name: '$q'): IQService - get(name: '$rootElement'): IRootElementService - get(name: '$rootScope'): IRootScopeService - get(name: '$sce'): ISCEService - get(name: '$sceDelegate'): ISCEDelegateService - get(name: '$templateCache'): ITemplateCacheService - get(name: '$templateRequest'): ITemplateRequestService - get(name: '$timeout'): ITimeoutService - get(name: '$window'): IWindowService - get(name: '$xhrFactory'): IXhrFactory - has(name: string): boolean; - instantiate(typeConstructor: Function, locals?: any): T; - invoke(inlineAnnotatedFunction: any[]): any; - invoke(func: Function, context?: any, locals?: any): any; - strictDi: boolean; - } - - /////////////////////////////////////////////////////////////////////// - // ProvideService - // see http://docs.angularjs.org/api/AUTO.$provide - /////////////////////////////////////////////////////////////////////// - interface IProvideService { - // Documentation says it returns the registered instance, but actual - // implementation does not return anything. - // constant(name: string, value: any): any; - /** - * Register a constant service, such as a string, a number, an array, an object or a function, with the $injector. Unlike value it can be injected into a module configuration function (see config) and it cannot be overridden by an Angular decorator. - * - * @param name The name of the constant. - * @param value The constant value. - */ - constant(name: string, value: any): void; - - /** - * Register a service decorator with the $injector. A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service. - * - * @param name The name of the service to decorate. - * @param decorator This function will be invoked when the service needs to be instantiated and should return the decorated service instance. The function is called using the injector.invoke method and is therefore fully injectable. Local injection arguments: - * - * $delegate - The original service instance, which can be monkey patched, configured, decorated or delegated to. - */ - decorator(name: string, decorator: Function): void; - /** - * Register a service decorator with the $injector. A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service. - * - * @param name The name of the service to decorate. - * @param inlineAnnotatedFunction This function will be invoked when the service needs to be instantiated and should return the decorated service instance. The function is called using the injector.invoke method and is therefore fully injectable. Local injection arguments: - * - * $delegate - The original service instance, which can be monkey patched, configured, decorated or delegated to. - */ - decorator(name: string, inlineAnnotatedFunction: any[]): void; - factory(name: string, serviceFactoryFunction: Function): IServiceProvider; - factory(name: string, inlineAnnotatedFunction: any[]): IServiceProvider; - provider(name: string, provider: IServiceProvider): IServiceProvider; - provider(name: string, serviceProviderConstructor: Function): IServiceProvider; - service(name: string, constructor: Function): IServiceProvider; - service(name: string, inlineAnnotatedFunction: any[]): IServiceProvider; - value(name: string, value: any): IServiceProvider; - } - - } - - /** - * $http params serializer that converts objects to strings - * see https://docs.angularjs.org/api/ng/service/$httpParamSerializer - */ - interface IHttpParamSerializer { - (obj: Object): string; - } -} \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular/typings.json b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular/typings.json deleted file mode 100644 index c974311fa7..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/angular/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/b76dd8a7f95b71696982befbb7589940d27e940b/angularjs/angular.d.ts", - "raw": "registry:dt/angular#1.5.0+20160517064839", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/b76dd8a7f95b71696982befbb7589940d27e940b/angularjs/angular.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/jquery/index.d.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/jquery/index.d.ts deleted file mode 100644 index b4208b3b82..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/jquery/index.d.ts +++ /dev/null @@ -1,3199 +0,0 @@ -// Generated by typings -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/4cdfbe96b666eec5e1defbb519a62abf04e96764/jquery/jquery.d.ts -interface JQueryAjaxSettings { - /** - * The content type sent in the request header that tells the server what kind of response it will accept in return. If the accepts setting needs modification, it is recommended to do so once in the $.ajaxSetup() method. - */ - accepts?: any; - /** - * By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success(). - */ - async?: boolean; - /** - * A pre-request callback function that can be used to modify the jqXHR (in jQuery 1.4.x, XMLHTTPRequest) object before it is sent. Use this to set custom headers, etc. The jqXHR and settings objects are passed as arguments. This is an Ajax Event. Returning false in the beforeSend function will cancel the request. As of jQuery 1.5, the beforeSend option will be called regardless of the type of request. - */ - beforeSend? (jqXHR: JQueryXHR, settings: JQueryAjaxSettings): any; - /** - * If set to false, it will force requested pages not to be cached by the browser. Note: Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters. The parameter is not needed for other types of requests, except in IE8 when a POST is made to a URL that has already been requested by a GET. - */ - cache?: boolean; - /** - * A function to be called when the request finishes (after success and error callbacks are executed). The function gets passed two arguments: The jqXHR (in jQuery 1.4.x, XMLHTTPRequest) object and a string categorizing the status of the request ("success", "notmodified", "error", "timeout", "abort", or "parsererror"). As of jQuery 1.5, the complete setting can accept an array of functions. Each function will be called in turn. This is an Ajax Event. - */ - complete? (jqXHR: JQueryXHR, textStatus: string): any; - /** - * An object of string/regular-expression pairs that determine how jQuery will parse the response, given its content type. (version added: 1.5) - */ - contents?: { [key: string]: any; }; - //According to jQuery.ajax source code, ajax's option actually allows contentType to set to "false" - // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/742 - /** - * When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent). The W3C XMLHttpRequest specification dictates that the charset is always UTF-8; specifying another charset will not force the browser to change the encoding. - */ - contentType?: any; - /** - * This object will be made the context of all Ajax-related callbacks. By default, the context is an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax). - */ - context?: any; - /** - * An object containing dataType-to-dataType converters. Each converter's value is a function that returns the transformed value of the response. (version added: 1.5) - */ - converters?: { [key: string]: any; }; - /** - * If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain. (version added: 1.5) - */ - crossDomain?: boolean; - /** - * Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests. See processData option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key based on the value of the traditional setting (described below). - */ - data?: any; - /** - * A function to be used to handle the raw response data of XMLHttpRequest.This is a pre-filtering function to sanitize the response. You should return the sanitized data. The function accepts two arguments: The raw data returned from the server and the 'dataType' parameter. - */ - dataFilter? (data: any, ty: any): any; - /** - * The type of data that you're expecting back from the server. If none is specified, jQuery will try to infer it based on the MIME type of the response (an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string). - */ - dataType?: string; - /** - * A function to be called if the request fails. The function receives three arguments: The jqXHR (in jQuery 1.4.x, XMLHttpRequest) object, a string describing the type of error that occurred and an optional exception object, if one occurred. Possible values for the second argument (besides null) are "timeout", "error", "abort", and "parsererror". When an HTTP error occurs, errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error." As of jQuery 1.5, the error setting can accept an array of functions. Each function will be called in turn. Note: This handler is not called for cross-domain script and cross-domain JSONP requests. This is an Ajax Event. - */ - error? (jqXHR: JQueryXHR, textStatus: string, errorThrown: string): any; - /** - * Whether to trigger global Ajax event handlers for this request. The default is true. Set to false to prevent the global handlers like ajaxStart or ajaxStop from being triggered. This can be used to control various Ajax Events. - */ - global?: boolean; - /** - * An object of additional header key/value pairs to send along with requests using the XMLHttpRequest transport. The header X-Requested-With: XMLHttpRequest is always added, but its default XMLHttpRequest value can be changed here. Values in the headers setting can also be overwritten from within the beforeSend function. (version added: 1.5) - */ - headers?: { [key: string]: any; }; - /** - * Allow the request to be successful only if the response has changed since the last request. This is done by checking the Last-Modified header. Default value is false, ignoring the header. In jQuery 1.4 this technique also checks the 'etag' specified by the server to catch unmodified data. - */ - ifModified?: boolean; - /** - * Allow the current environment to be recognized as "local," (e.g. the filesystem), even if jQuery does not recognize it as such by default. The following protocols are currently recognized as local: file, *-extension, and widget. If the isLocal setting needs modification, it is recommended to do so once in the $.ajaxSetup() method. (version added: 1.5.1) - */ - isLocal?: boolean; - /** - * Override the callback function name in a jsonp request. This value will be used instead of 'callback' in the 'callback=?' part of the query string in the url. So {jsonp:'onJSONPLoad'} would result in 'onJSONPLoad=?' passed to the server. As of jQuery 1.5, setting the jsonp option to false prevents jQuery from adding the "?callback" string to the URL or attempting to use "=?" for transformation. In this case, you should also explicitly set the jsonpCallback setting. For example, { jsonp: false, jsonpCallback: "callbackName" } - */ - jsonp?: any; - /** - * Specify the callback function name for a JSONP request. This value will be used instead of the random name automatically generated by jQuery. It is preferable to let jQuery generate a unique name as it'll make it easier to manage the requests and provide callbacks and error handling. You may want to specify the callback when you want to enable better browser caching of GET requests. As of jQuery 1.5, you can also use a function for this setting, in which case the value of jsonpCallback is set to the return value of that function. - */ - jsonpCallback?: any; - /** - * The HTTP method to use for the request (e.g. "POST", "GET", "PUT"). (version added: 1.9.0) - */ - method?: string; - /** - * A mime type to override the XHR mime type. (version added: 1.5.1) - */ - mimeType?: string; - /** - * A password to be used with XMLHttpRequest in response to an HTTP access authentication request. - */ - password?: string; - /** - * By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded". If you want to send a DOMDocument, or other non-processed data, set this option to false. - */ - processData?: boolean; - /** - * Only applies when the "script" transport is used (e.g., cross-domain requests with "jsonp" or "script" dataType and "GET" type). Sets the charset attribute on the script tag used in the request. Used when the character set on the local page is not the same as the one on the remote script. - */ - scriptCharset?: string; - /** - * An object of numeric HTTP codes and functions to be called when the response has the corresponding code. f the request is successful, the status code functions take the same parameters as the success callback; if it results in an error (including 3xx redirect), they take the same parameters as the error callback. (version added: 1.5) - */ - statusCode?: { [key: string]: any; }; - /** - * A function to be called if the request succeeds. The function gets passed three arguments: The data returned from the server, formatted according to the dataType parameter; a string describing the status; and the jqXHR (in jQuery 1.4.x, XMLHttpRequest) object. As of jQuery 1.5, the success setting can accept an array of functions. Each function will be called in turn. This is an Ajax Event. - */ - success? (data: any, textStatus: string, jqXHR: JQueryXHR): any; - /** - * Set a timeout (in milliseconds) for the request. This will override any global timeout set with $.ajaxSetup(). The timeout period starts at the point the $.ajax call is made; if several other requests are in progress and the browser has no connections available, it is possible for a request to time out before it can be sent. In jQuery 1.4.x and below, the XMLHttpRequest object will be in an invalid state if the request times out; accessing any object members may throw an exception. In Firefox 3.0+ only, script and JSONP requests cannot be cancelled by a timeout; the script will run even if it arrives after the timeout period. - */ - timeout?: number; - /** - * Set this to true if you wish to use the traditional style of param serialization. - */ - traditional?: boolean; - /** - * The type of request to make ("POST" or "GET"), default is "GET". Note: Other HTTP request methods, such as PUT and DELETE, can also be used here, but they are not supported by all browsers. - */ - type?: string; - /** - * A string containing the URL to which the request is sent. - */ - url?: string; - /** - * A username to be used with XMLHttpRequest in response to an HTTP access authentication request. - */ - username?: string; - /** - * Callback for creating the XMLHttpRequest object. Defaults to the ActiveXObject when available (IE), the XMLHttpRequest otherwise. Override to provide your own implementation for XMLHttpRequest or enhancements to the factory. - */ - xhr?: any; - /** - * An object of fieldName-fieldValue pairs to set on the native XHR object. For example, you can use it to set withCredentials to true for cross-domain requests if needed. In jQuery 1.5, the withCredentials property was not propagated to the native XHR and thus CORS requests requiring it would ignore this flag. For this reason, we recommend using jQuery 1.5.1+ should you require the use of it. (version added: 1.5.1) - */ - xhrFields?: { [key: string]: any; }; -} - -/** - * Interface for the jqXHR object - */ -interface JQueryXHR extends XMLHttpRequest, JQueryPromise { - /** - * The .overrideMimeType() method may be used in the beforeSend() callback function, for example, to modify the response content-type header. As of jQuery 1.5.1, the jqXHR object also contains the overrideMimeType() method (it was available in jQuery 1.4.x, as well, but was temporarily removed in jQuery 1.5). - */ - overrideMimeType(mimeType: string): any; - /** - * Cancel the request. - * - * @param statusText A string passed as the textStatus parameter for the done callback. Default value: "canceled" - */ - abort(statusText?: string): void; - /** - * Incorporates the functionality of the .done() and .fail() methods, allowing (as of jQuery 1.8) the underlying Promise to be manipulated. Refer to deferred.then() for implementation details. - */ - then(doneCallback: (data: any, textStatus: string, jqXHR: JQueryXHR) => R, failCallback?: (jqXHR: JQueryXHR, textStatus: string, errorThrown: any) => void): JQueryPromise; - /** - * Property containing the parsed response if the response Content-Type is json - */ - responseJSON?: any; - /** - * A function to be called if the request fails. - */ - error(xhr: JQueryXHR, textStatus: string, errorThrown: string): void; -} - -/** - * Interface for the JQuery callback - */ -interface JQueryCallback { - /** - * Add a callback or a collection of callbacks to a callback list. - * - * @param callbacks A function, or array of functions, that are to be added to the callback list. - */ - add(callbacks: Function): JQueryCallback; - /** - * Add a callback or a collection of callbacks to a callback list. - * - * @param callbacks A function, or array of functions, that are to be added to the callback list. - */ - add(callbacks: Function[]): JQueryCallback; - - /** - * Disable a callback list from doing anything more. - */ - disable(): JQueryCallback; - - /** - * Determine if the callbacks list has been disabled. - */ - disabled(): boolean; - - /** - * Remove all of the callbacks from a list. - */ - empty(): JQueryCallback; - - /** - * Call all of the callbacks with the given arguments - * - * @param arguments The argument or list of arguments to pass back to the callback list. - */ - fire(...arguments: any[]): JQueryCallback; - - /** - * Determine if the callbacks have already been called at least once. - */ - fired(): boolean; - - /** - * Call all callbacks in a list with the given context and arguments. - * - * @param context A reference to the context in which the callbacks in the list should be fired. - * @param arguments An argument, or array of arguments, to pass to the callbacks in the list. - */ - fireWith(context?: any, args?: any[]): JQueryCallback; - - /** - * Determine whether a supplied callback is in a list - * - * @param callback The callback to search for. - */ - has(callback: Function): boolean; - - /** - * Lock a callback list in its current state. - */ - lock(): JQueryCallback; - - /** - * Determine if the callbacks list has been locked. - */ - locked(): boolean; - - /** - * Remove a callback or a collection of callbacks from a callback list. - * - * @param callbacks A function, or array of functions, that are to be removed from the callback list. - */ - remove(callbacks: Function): JQueryCallback; - /** - * Remove a callback or a collection of callbacks from a callback list. - * - * @param callbacks A function, or array of functions, that are to be removed from the callback list. - */ - remove(callbacks: Function[]): JQueryCallback; -} - -/** - * Allows jQuery Promises to interop with non-jQuery promises - */ -interface JQueryGenericPromise { - /** - * Add handlers to be called when the Deferred object is resolved, rejected, or still in progress. - * - * @param doneFilter A function that is called when the Deferred is resolved. - * @param failFilter An optional function that is called when the Deferred is rejected. - */ - then(doneFilter: (value?: T, ...values: any[]) => U|JQueryPromise, failFilter?: (...reasons: any[]) => any, progressFilter?: (...progression: any[]) => any): JQueryPromise; - - /** - * Add handlers to be called when the Deferred object is resolved, rejected, or still in progress. - * - * @param doneFilter A function that is called when the Deferred is resolved. - * @param failFilter An optional function that is called when the Deferred is rejected. - */ - then(doneFilter: (value?: T, ...values: any[]) => void, failFilter?: (...reasons: any[]) => any, progressFilter?: (...progression: any[]) => any): JQueryPromise; -} - -/** - * Interface for the JQuery promise/deferred callbacks - */ -interface JQueryPromiseCallback { - (value?: T, ...args: any[]): void; -} - -interface JQueryPromiseOperator { - (callback1: JQueryPromiseCallback|JQueryPromiseCallback[], ...callbacksN: Array|JQueryPromiseCallback[]>): JQueryPromise; -} - -/** - * Interface for the JQuery promise, part of callbacks - */ -interface JQueryPromise extends JQueryGenericPromise { - /** - * Determine the current state of a Deferred object. - */ - state(): string; - /** - * Add handlers to be called when the Deferred object is either resolved or rejected. - * - * @param alwaysCallbacks1 A function, or array of functions, that is called when the Deferred is resolved or rejected. - * @param alwaysCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved or rejected. - */ - always(alwaysCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...alwaysCallbacksN: Array|JQueryPromiseCallback[]>): JQueryPromise; - /** - * Add handlers to be called when the Deferred object is resolved. - * - * @param doneCallbacks1 A function, or array of functions, that are called when the Deferred is resolved. - * @param doneCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved. - */ - done(doneCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...doneCallbackN: Array|JQueryPromiseCallback[]>): JQueryPromise; - /** - * Add handlers to be called when the Deferred object is rejected. - * - * @param failCallbacks1 A function, or array of functions, that are called when the Deferred is rejected. - * @param failCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is rejected. - */ - fail(failCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...failCallbacksN: Array|JQueryPromiseCallback[]>): JQueryPromise; - /** - * Add handlers to be called when the Deferred object generates progress notifications. - * - * @param progressCallbacks A function, or array of functions, to be called when the Deferred generates progress notifications. - */ - progress(progressCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...progressCallbackN: Array|JQueryPromiseCallback[]>): JQueryPromise; - - // Deprecated - given no typings - pipe(doneFilter?: (x: any) => any, failFilter?: (x: any) => any, progressFilter?: (x: any) => any): JQueryPromise; -} - -/** - * Interface for the JQuery deferred, part of callbacks - */ -interface JQueryDeferred extends JQueryGenericPromise { - /** - * Determine the current state of a Deferred object. - */ - state(): string; - /** - * Add handlers to be called when the Deferred object is either resolved or rejected. - * - * @param alwaysCallbacks1 A function, or array of functions, that is called when the Deferred is resolved or rejected. - * @param alwaysCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved or rejected. - */ - always(alwaysCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...alwaysCallbacksN: Array|JQueryPromiseCallback[]>): JQueryDeferred; - /** - * Add handlers to be called when the Deferred object is resolved. - * - * @param doneCallbacks1 A function, or array of functions, that are called when the Deferred is resolved. - * @param doneCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is resolved. - */ - done(doneCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...doneCallbackN: Array|JQueryPromiseCallback[]>): JQueryDeferred; - /** - * Add handlers to be called when the Deferred object is rejected. - * - * @param failCallbacks1 A function, or array of functions, that are called when the Deferred is rejected. - * @param failCallbacks2 Optional additional functions, or arrays of functions, that are called when the Deferred is rejected. - */ - fail(failCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...failCallbacksN: Array|JQueryPromiseCallback[]>): JQueryDeferred; - /** - * Add handlers to be called when the Deferred object generates progress notifications. - * - * @param progressCallbacks A function, or array of functions, to be called when the Deferred generates progress notifications. - */ - progress(progressCallback1?: JQueryPromiseCallback|JQueryPromiseCallback[], ...progressCallbackN: Array|JQueryPromiseCallback[]>): JQueryDeferred; - - /** - * Call the progressCallbacks on a Deferred object with the given args. - * - * @param args Optional arguments that are passed to the progressCallbacks. - */ - notify(value?: any, ...args: any[]): JQueryDeferred; - - /** - * Call the progressCallbacks on a Deferred object with the given context and args. - * - * @param context Context passed to the progressCallbacks as the this object. - * @param args Optional arguments that are passed to the progressCallbacks. - */ - notifyWith(context: any, value?: any[]): JQueryDeferred; - - /** - * Reject a Deferred object and call any failCallbacks with the given args. - * - * @param args Optional arguments that are passed to the failCallbacks. - */ - reject(value?: any, ...args: any[]): JQueryDeferred; - /** - * Reject a Deferred object and call any failCallbacks with the given context and args. - * - * @param context Context passed to the failCallbacks as the this object. - * @param args An optional array of arguments that are passed to the failCallbacks. - */ - rejectWith(context: any, value?: any[]): JQueryDeferred; - - /** - * Resolve a Deferred object and call any doneCallbacks with the given args. - * - * @param value First argument passed to doneCallbacks. - * @param args Optional subsequent arguments that are passed to the doneCallbacks. - */ - resolve(value?: T, ...args: any[]): JQueryDeferred; - - /** - * Resolve a Deferred object and call any doneCallbacks with the given context and args. - * - * @param context Context passed to the doneCallbacks as the this object. - * @param args An optional array of arguments that are passed to the doneCallbacks. - */ - resolveWith(context: any, value?: T[]): JQueryDeferred; - - /** - * Return a Deferred's Promise object. - * - * @param target Object onto which the promise methods have to be attached - */ - promise(target?: any): JQueryPromise; - - // Deprecated - given no typings - pipe(doneFilter?: (x: any) => any, failFilter?: (x: any) => any, progressFilter?: (x: any) => any): JQueryPromise; -} - -/** - * Interface of the JQuery extension of the W3C event object - */ -interface BaseJQueryEventObject extends Event { - data: any; - delegateTarget: Element; - isDefaultPrevented(): boolean; - isImmediatePropagationStopped(): boolean; - isPropagationStopped(): boolean; - namespace: string; - originalEvent: Event; - preventDefault(): any; - relatedTarget: Element; - result: any; - stopImmediatePropagation(): void; - stopPropagation(): void; - target: Element; - pageX: number; - pageY: number; - which: number; - metaKey: boolean; -} - -interface JQueryInputEventObject extends BaseJQueryEventObject { - altKey: boolean; - ctrlKey: boolean; - metaKey: boolean; - shiftKey: boolean; -} - -interface JQueryMouseEventObject extends JQueryInputEventObject { - button: number; - clientX: number; - clientY: number; - offsetX: number; - offsetY: number; - pageX: number; - pageY: number; - screenX: number; - screenY: number; -} - -interface JQueryKeyEventObject extends JQueryInputEventObject { - char: any; - charCode: number; - key: any; - keyCode: number; -} - -interface JQueryEventObject extends BaseJQueryEventObject, JQueryInputEventObject, JQueryMouseEventObject, JQueryKeyEventObject{ -} - -/* - Collection of properties of the current browser -*/ - -interface JQuerySupport { - ajax?: boolean; - boxModel?: boolean; - changeBubbles?: boolean; - checkClone?: boolean; - checkOn?: boolean; - cors?: boolean; - cssFloat?: boolean; - hrefNormalized?: boolean; - htmlSerialize?: boolean; - leadingWhitespace?: boolean; - noCloneChecked?: boolean; - noCloneEvent?: boolean; - opacity?: boolean; - optDisabled?: boolean; - optSelected?: boolean; - scriptEval? (): boolean; - style?: boolean; - submitBubbles?: boolean; - tbody?: boolean; -} - -interface JQueryParam { - /** - * Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request. - * - * @param obj An array or object to serialize. - */ - (obj: any): string; - - /** - * Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request. - * - * @param obj An array or object to serialize. - * @param traditional A Boolean indicating whether to perform a traditional "shallow" serialization. - */ - (obj: any, traditional: boolean): string; -} - -/** - * The interface used to construct jQuery events (with $.Event). It is - * defined separately instead of inline in JQueryStatic to allow - * overriding the construction function with specific strings - * returning specific event objects. - */ -interface JQueryEventConstructor { - (name: string, eventProperties?: any): JQueryEventObject; - new (name: string, eventProperties?: any): JQueryEventObject; -} - -/** - * The interface used to specify coordinates. - */ -interface JQueryCoordinates { - left: number; - top: number; -} - -/** - * Elements in the array returned by serializeArray() - */ -interface JQuerySerializeArrayElement { - name: string; - value: string; -} - -interface JQueryAnimationOptions { - /** - * A string or number determining how long the animation will run. - */ - duration?: any; - /** - * A string indicating which easing function to use for the transition. - */ - easing?: string; - /** - * A function to call once the animation is complete. - */ - complete?: Function; - /** - * A function to be called for each animated property of each animated element. This function provides an opportunity to modify the Tween object to change the value of the property before it is set. - */ - step?: (now: number, tween: any) => any; - /** - * A function to be called after each step of the animation, only once per animated element regardless of the number of animated properties. (version added: 1.8) - */ - progress?: (animation: JQueryPromise, progress: number, remainingMs: number) => any; - /** - * A function to call when the animation begins. (version added: 1.8) - */ - start?: (animation: JQueryPromise) => any; - /** - * A function to be called when the animation completes (its Promise object is resolved). (version added: 1.8) - */ - done?: (animation: JQueryPromise, jumpedToEnd: boolean) => any; - /** - * A function to be called when the animation fails to complete (its Promise object is rejected). (version added: 1.8) - */ - fail?: (animation: JQueryPromise, jumpedToEnd: boolean) => any; - /** - * A function to be called when the animation completes or stops without completing (its Promise object is either resolved or rejected). (version added: 1.8) - */ - always?: (animation: JQueryPromise, jumpedToEnd: boolean) => any; - /** - * A Boolean indicating whether to place the animation in the effects queue. If false, the animation will begin immediately. As of jQuery 1.7, the queue option can also accept a string, in which case the animation is added to the queue represented by that string. When a custom queue name is used the animation does not automatically start; you must call .dequeue("queuename") to start it. - */ - queue?: any; - /** - * A map of one or more of the CSS properties defined by the properties argument and their corresponding easing functions. (version added: 1.4) - */ - specialEasing?: Object; -} - -interface JQueryEasingFunction { - ( percent: number ): number; -} - -interface JQueryEasingFunctions { - [ name: string ]: JQueryEasingFunction; - linear: JQueryEasingFunction; - swing: JQueryEasingFunction; -} - -/** - * Static members of jQuery (those on $ and jQuery themselves) - */ -interface JQueryStatic { - - /** - * Perform an asynchronous HTTP (Ajax) request. - * - * @param settings A set of key/value pairs that configure the Ajax request. All settings are optional. A default can be set for any option with $.ajaxSetup(). - */ - ajax(settings: JQueryAjaxSettings): JQueryXHR; - /** - * Perform an asynchronous HTTP (Ajax) request. - * - * @param url A string containing the URL to which the request is sent. - * @param settings A set of key/value pairs that configure the Ajax request. All settings are optional. A default can be set for any option with $.ajaxSetup(). - */ - ajax(url: string, settings?: JQueryAjaxSettings): JQueryXHR; - - /** - * Handle custom Ajax options or modify existing options before each request is sent and before they are processed by $.ajax(). - * - * @param dataTypes An optional string containing one or more space-separated dataTypes - * @param handler A handler to set default values for future Ajax requests. - */ - ajaxPrefilter(dataTypes: string, handler: (opts: any, originalOpts: JQueryAjaxSettings, jqXHR: JQueryXHR) => any): void; - /** - * Handle custom Ajax options or modify existing options before each request is sent and before they are processed by $.ajax(). - * - * @param handler A handler to set default values for future Ajax requests. - */ - ajaxPrefilter(handler: (opts: any, originalOpts: JQueryAjaxSettings, jqXHR: JQueryXHR) => any): void; - - ajaxSettings: JQueryAjaxSettings; - - /** - * Set default values for future Ajax requests. Its use is not recommended. - * - * @param options A set of key/value pairs that configure the default Ajax request. All options are optional. - */ - ajaxSetup(options: JQueryAjaxSettings): void; - - /** - * Load data from the server using a HTTP GET request. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, or html). - */ - get(url: string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - /** - * Load data from the server using a HTTP GET request. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param success A callback function that is executed if the request succeeds. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, or html). - */ - get(url: string, data?: Object|string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - /** - * Load data from the server using a HTTP GET request. - * - * @param settings The JQueryAjaxSettings to be used for the request - */ - get(settings : JQueryAjaxSettings): JQueryXHR; - /** - * Load JSON-encoded data from the server using a GET HTTP request. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. - */ - getJSON(url: string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any): JQueryXHR; - /** - * Load JSON-encoded data from the server using a GET HTTP request. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param success A callback function that is executed if the request succeeds. - */ - getJSON(url: string, data?: Object|string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any): JQueryXHR; - /** - * Load a JavaScript file from the server using a GET HTTP request, then execute it. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. - */ - getScript(url: string, success?: (script: string, textStatus: string, jqXHR: JQueryXHR) => any): JQueryXHR; - - /** - * Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request. - */ - param: JQueryParam; - - /** - * Load data from the server using a HTTP POST request. - * - * @param url A string containing the URL to which the request is sent. - * @param success A callback function that is executed if the request succeeds. Required if dataType is provided, but can be null in that case. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, text, html). - */ - post(url: string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - /** - * Load data from the server using a HTTP POST request. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param success A callback function that is executed if the request succeeds. Required if dataType is provided, but can be null in that case. - * @param dataType The type of data expected from the server. Default: Intelligent Guess (xml, json, script, text, html). - */ - post(url: string, data?: Object|string, success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any, dataType?: string): JQueryXHR; - /** - * Load data from the server using a HTTP POST request. - * - * @param settings The JQueryAjaxSettings to be used for the request - */ - post(settings : JQueryAjaxSettings): JQueryXHR; - /** - * A multi-purpose callbacks list object that provides a powerful way to manage callback lists. - * - * @param flags An optional list of space-separated flags that change how the callback list behaves. - */ - Callbacks(flags?: string): JQueryCallback; - - /** - * Holds or releases the execution of jQuery's ready event. - * - * @param hold Indicates whether the ready hold is being requested or released - */ - holdReady(hold: boolean): void; - - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param selector A string containing a selector expression - * @param context A DOM Element, Document, or jQuery to use as context - */ - (selector: string, context?: Element|JQuery): JQuery; - - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param element A DOM element to wrap in a jQuery object. - */ - (element: Element): JQuery; - - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param elementArray An array containing a set of DOM elements to wrap in a jQuery object. - */ - (elementArray: Element[]): JQuery; - - /** - * Binds a function to be executed when the DOM has finished loading. - * - * @param callback A function to execute after the DOM is ready. - */ - (callback: (jQueryAlias?: JQueryStatic) => any): JQuery; - - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param object A plain object to wrap in a jQuery object. - */ - (object: {}): JQuery; - - /** - * Accepts a string containing a CSS selector which is then used to match a set of elements. - * - * @param object An existing jQuery object to clone. - */ - (object: JQuery): JQuery; - - /** - * Specify a function to execute when the DOM is fully loaded. - */ - (): JQuery; - - /** - * Creates DOM elements on the fly from the provided string of raw HTML. - * - * @param html A string of HTML to create on the fly. Note that this parses HTML, not XML. - * @param ownerDocument A document in which the new elements will be created. - */ - (html: string, ownerDocument?: Document): JQuery; - - /** - * Creates DOM elements on the fly from the provided string of raw HTML. - * - * @param html A string defining a single, standalone, HTML element (e.g.
    or
    ). - * @param attributes An object of attributes, events, and methods to call on the newly-created element. - */ - (html: string, attributes: Object): JQuery; - - /** - * Relinquish jQuery's control of the $ variable. - * - * @param removeAll A Boolean indicating whether to remove all jQuery variables from the global scope (including jQuery itself). - */ - noConflict(removeAll?: boolean): JQueryStatic; - - /** - * Provides a way to execute callback functions based on one or more objects, usually Deferred objects that represent asynchronous events. - * - * @param deferreds One or more Deferred objects, or plain JavaScript objects. - */ - when(...deferreds: Array/* as JQueryDeferred */>): JQueryPromise; - - /** - * Hook directly into jQuery to override how particular CSS properties are retrieved or set, normalize CSS property naming, or create custom properties. - */ - cssHooks: { [key: string]: any; }; - cssNumber: any; - - /** - * Store arbitrary data associated with the specified element. Returns the value that was set. - * - * @param element The DOM element to associate with the data. - * @param key A string naming the piece of data to set. - * @param value The new data value. - */ - data(element: Element, key: string, value: T): T; - /** - * Returns value at named data store for the element, as set by jQuery.data(element, name, value), or the full data store for the element. - * - * @param element The DOM element to associate with the data. - * @param key A string naming the piece of data to set. - */ - data(element: Element, key: string): any; - /** - * Returns value at named data store for the element, as set by jQuery.data(element, name, value), or the full data store for the element. - * - * @param element The DOM element to associate with the data. - */ - data(element: Element): any; - - /** - * Execute the next function on the queue for the matched element. - * - * @param element A DOM element from which to remove and execute a queued function. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - dequeue(element: Element, queueName?: string): void; - - /** - * Determine whether an element has any jQuery data associated with it. - * - * @param element A DOM element to be checked for data. - */ - hasData(element: Element): boolean; - - /** - * Show the queue of functions to be executed on the matched element. - * - * @param element A DOM element to inspect for an attached queue. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - queue(element: Element, queueName?: string): any[]; - /** - * Manipulate the queue of functions to be executed on the matched element. - * - * @param element A DOM element where the array of queued functions is attached. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param newQueue An array of functions to replace the current queue contents. - */ - queue(element: Element, queueName: string, newQueue: Function[]): JQuery; - /** - * Manipulate the queue of functions to be executed on the matched element. - * - * @param element A DOM element on which to add a queued function. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param callback The new function to add to the queue. - */ - queue(element: Element, queueName: string, callback: Function): JQuery; - - /** - * Remove a previously-stored piece of data. - * - * @param element A DOM element from which to remove data. - * @param name A string naming the piece of data to remove. - */ - removeData(element: Element, name?: string): JQuery; - - /** - * A constructor function that returns a chainable utility object with methods to register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function. - * - * @param beforeStart A function that is called just before the constructor returns. - */ - Deferred(beforeStart?: (deferred: JQueryDeferred) => any): JQueryDeferred; - - /** - * Effects - */ - - easing: JQueryEasingFunctions; - - fx: { - tick: () => void; - /** - * The rate (in milliseconds) at which animations fire. - */ - interval: number; - stop: () => void; - speeds: { slow: number; fast: number; }; - /** - * Globally disable all animations. - */ - off: boolean; - step: any; - }; - - /** - * Takes a function and returns a new one that will always have a particular context. - * - * @param fnction The function whose context will be changed. - * @param context The object to which the context (this) of the function should be set. - * @param additionalArguments Any number of arguments to be passed to the function referenced in the function argument. - */ - proxy(fnction: (...args: any[]) => any, context: Object, ...additionalArguments: any[]): any; - /** - * Takes a function and returns a new one that will always have a particular context. - * - * @param context The object to which the context (this) of the function should be set. - * @param name The name of the function whose context will be changed (should be a property of the context object). - * @param additionalArguments Any number of arguments to be passed to the function named in the name argument. - */ - proxy(context: Object, name: string, ...additionalArguments: any[]): any; - - Event: JQueryEventConstructor; - - /** - * Takes a string and throws an exception containing it. - * - * @param message The message to send out. - */ - error(message: any): JQuery; - - expr: any; - fn: any; //TODO: Decide how we want to type this - - isReady: boolean; - - // Properties - support: JQuerySupport; - - /** - * Check to see if a DOM element is a descendant of another DOM element. - * - * @param container The DOM element that may contain the other element. - * @param contained The DOM element that may be contained by (a descendant of) the other element. - */ - contains(container: Element, contained: Element): boolean; - - /** - * A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties. - * - * @param collection The object or array to iterate over. - * @param callback The function that will be executed on every object. - */ - each( - collection: T[], - callback: (indexInArray: number, valueOfElement: T) => any - ): any; - - /** - * A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties. - * - * @param collection The object or array to iterate over. - * @param callback The function that will be executed on every object. - */ - each( - collection: any, - callback: (indexInArray: any, valueOfElement: any) => any - ): any; - - /** - * Merge the contents of two or more objects together into the first object. - * - * @param target An object that will receive the new properties if additional objects are passed in or that will extend the jQuery namespace if it is the sole argument. - * @param object1 An object containing additional properties to merge in. - * @param objectN Additional objects containing properties to merge in. - */ - extend(target: any, object1?: any, ...objectN: any[]): any; - /** - * Merge the contents of two or more objects together into the first object. - * - * @param deep If true, the merge becomes recursive (aka. deep copy). - * @param target The object to extend. It will receive the new properties. - * @param object1 An object containing additional properties to merge in. - * @param objectN Additional objects containing properties to merge in. - */ - extend(deep: boolean, target: any, object1?: any, ...objectN: any[]): any; - - /** - * Execute some JavaScript code globally. - * - * @param code The JavaScript code to execute. - */ - globalEval(code: string): any; - - /** - * Finds the elements of an array which satisfy a filter function. The original array is not affected. - * - * @param array The array to search through. - * @param func The function to process each item against. The first argument to the function is the item, and the second argument is the index. The function should return a Boolean value. this will be the global window object. - * @param invert If "invert" is false, or not provided, then the function returns an array consisting of all elements for which "callback" returns true. If "invert" is true, then the function returns an array consisting of all elements for which "callback" returns false. - */ - grep(array: T[], func: (elementOfArray: T, indexInArray: number) => boolean, invert?: boolean): T[]; - - /** - * Search for a specified value within an array and return its index (or -1 if not found). - * - * @param value The value to search for. - * @param array An array through which to search. - * @param fromIndex he index of the array at which to begin the search. The default is 0, which will search the whole array. - */ - inArray(value: T, array: T[], fromIndex?: number): number; - - /** - * Determine whether the argument is an array. - * - * @param obj Object to test whether or not it is an array. - */ - isArray(obj: any): boolean; - /** - * Check to see if an object is empty (contains no enumerable properties). - * - * @param obj The object that will be checked to see if it's empty. - */ - isEmptyObject(obj: any): boolean; - /** - * Determine if the argument passed is a Javascript function object. - * - * @param obj Object to test whether or not it is a function. - */ - isFunction(obj: any): boolean; - /** - * Determines whether its argument is a number. - * - * @param obj The value to be tested. - */ - isNumeric(value: any): boolean; - /** - * Check to see if an object is a plain object (created using "{}" or "new Object"). - * - * @param obj The object that will be checked to see if it's a plain object. - */ - isPlainObject(obj: any): boolean; - /** - * Determine whether the argument is a window. - * - * @param obj Object to test whether or not it is a window. - */ - isWindow(obj: any): boolean; - /** - * Check to see if a DOM node is within an XML document (or is an XML document). - * - * @param node he DOM node that will be checked to see if it's in an XML document. - */ - isXMLDoc(node: Node): boolean; - - /** - * Convert an array-like object into a true JavaScript array. - * - * @param obj Any object to turn into a native Array. - */ - makeArray(obj: any): any[]; - - /** - * Translate all items in an array or object to new array of items. - * - * @param array The Array to translate. - * @param callback The function to process each item against. The first argument to the function is the array item, the second argument is the index in array The function can return any value. Within the function, this refers to the global (window) object. - */ - map(array: T[], callback: (elementOfArray: T, indexInArray: number) => U): U[]; - /** - * Translate all items in an array or object to new array of items. - * - * @param arrayOrObject The Array or Object to translate. - * @param callback The function to process each item against. The first argument to the function is the value; the second argument is the index or key of the array or object property. The function can return any value to add to the array. A returned array will be flattened into the resulting array. Within the function, this refers to the global (window) object. - */ - map(arrayOrObject: any, callback: (value: any, indexOrKey: any) => any): any; - - /** - * Merge the contents of two arrays together into the first array. - * - * @param first The first array to merge, the elements of second added. - * @param second The second array to merge into the first, unaltered. - */ - merge(first: T[], second: T[]): T[]; - - /** - * An empty function. - */ - noop(): any; - - /** - * Return a number representing the current time. - */ - now(): number; - - /** - * Takes a well-formed JSON string and returns the resulting JavaScript object. - * - * @param json The JSON string to parse. - */ - parseJSON(json: string): any; - - /** - * Parses a string into an XML document. - * - * @param data a well-formed XML string to be parsed - */ - parseXML(data: string): XMLDocument; - - /** - * Remove the whitespace from the beginning and end of a string. - * - * @param str Remove the whitespace from the beginning and end of a string. - */ - trim(str: string): string; - - /** - * Determine the internal JavaScript [[Class]] of an object. - * - * @param obj Object to get the internal JavaScript [[Class]] of. - */ - type(obj: any): string; - - /** - * Sorts an array of DOM elements, in place, with the duplicates removed. Note that this only works on arrays of DOM elements, not strings or numbers. - * - * @param array The Array of DOM elements. - */ - unique(array: Element[]): Element[]; - - /** - * Parses a string into an array of DOM nodes. - * - * @param data HTML string to be parsed - * @param context DOM element to serve as the context in which the HTML fragment will be created - * @param keepScripts A Boolean indicating whether to include scripts passed in the HTML string - */ - parseHTML(data: string, context?: HTMLElement, keepScripts?: boolean): any[]; - - /** - * Parses a string into an array of DOM nodes. - * - * @param data HTML string to be parsed - * @param context DOM element to serve as the context in which the HTML fragment will be created - * @param keepScripts A Boolean indicating whether to include scripts passed in the HTML string - */ - parseHTML(data: string, context?: Document, keepScripts?: boolean): any[]; -} - -/** - * The jQuery instance members - */ -interface JQuery { - /** - * Register a handler to be called when Ajax requests complete. This is an AjaxEvent. - * - * @param handler The function to be invoked. - */ - ajaxComplete(handler: (event: JQueryEventObject, XMLHttpRequest: XMLHttpRequest, ajaxOptions: any) => any): JQuery; - /** - * Register a handler to be called when Ajax requests complete with an error. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxError(handler: (event: JQueryEventObject, jqXHR: JQueryXHR, ajaxSettings: JQueryAjaxSettings, thrownError: any) => any): JQuery; - /** - * Attach a function to be executed before an Ajax request is sent. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxSend(handler: (event: JQueryEventObject, jqXHR: JQueryXHR, ajaxOptions: JQueryAjaxSettings) => any): JQuery; - /** - * Register a handler to be called when the first Ajax request begins. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxStart(handler: () => any): JQuery; - /** - * Register a handler to be called when all Ajax requests have completed. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxStop(handler: () => any): JQuery; - /** - * Attach a function to be executed whenever an Ajax request completes successfully. This is an Ajax Event. - * - * @param handler The function to be invoked. - */ - ajaxSuccess(handler: (event: JQueryEventObject, XMLHttpRequest: XMLHttpRequest, ajaxOptions: JQueryAjaxSettings) => any): JQuery; - - /** - * Load data from the server and place the returned HTML into the matched element. - * - * @param url A string containing the URL to which the request is sent. - * @param data A plain object or string that is sent to the server with the request. - * @param complete A callback function that is executed when the request completes. - */ - load(url: string, data?: string|Object, complete?: (responseText: string, textStatus: string, XMLHttpRequest: XMLHttpRequest) => any): JQuery; - - /** - * Encode a set of form elements as a string for submission. - */ - serialize(): string; - /** - * Encode a set of form elements as an array of names and values. - */ - serializeArray(): JQuerySerializeArrayElement[]; - - /** - * Adds the specified class(es) to each of the set of matched elements. - * - * @param className One or more space-separated classes to be added to the class attribute of each matched element. - */ - addClass(className: string): JQuery; - /** - * Adds the specified class(es) to each of the set of matched elements. - * - * @param function A function returning one or more space-separated class names to be added to the existing class name(s). Receives the index position of the element in the set and the existing class name(s) as arguments. Within the function, this refers to the current element in the set. - */ - addClass(func: (index: number, className: string) => string): JQuery; - - /** - * Add the previous set of elements on the stack to the current set, optionally filtered by a selector. - */ - addBack(selector?: string): JQuery; - - /** - * Get the value of an attribute for the first element in the set of matched elements. - * - * @param attributeName The name of the attribute to get. - */ - attr(attributeName: string): string; - /** - * Set one or more attributes for the set of matched elements. - * - * @param attributeName The name of the attribute to set. - * @param value A value to set for the attribute. - */ - attr(attributeName: string, value: string|number): JQuery; - /** - * Set one or more attributes for the set of matched elements. - * - * @param attributeName The name of the attribute to set. - * @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old attribute value as arguments. - */ - attr(attributeName: string, func: (index: number, attr: string) => string|number): JQuery; - /** - * Set one or more attributes for the set of matched elements. - * - * @param attributes An object of attribute-value pairs to set. - */ - attr(attributes: Object): JQuery; - - /** - * Determine whether any of the matched elements are assigned the given class. - * - * @param className The class name to search for. - */ - hasClass(className: string): boolean; - - /** - * Get the HTML contents of the first element in the set of matched elements. - */ - html(): string; - /** - * Set the HTML contents of each element in the set of matched elements. - * - * @param htmlString A string of HTML to set as the content of each matched element. - */ - html(htmlString: string): JQuery; - /** - * Set the HTML contents of each element in the set of matched elements. - * - * @param func A function returning the HTML content to set. Receives the index position of the element in the set and the old HTML value as arguments. jQuery empties the element before calling the function; use the oldhtml argument to reference the previous content. Within the function, this refers to the current element in the set. - */ - html(func: (index: number, oldhtml: string) => string): JQuery; - /** - * Set the HTML contents of each element in the set of matched elements. - * - * @param func A function returning the HTML content to set. Receives the index position of the element in the set and the old HTML value as arguments. jQuery empties the element before calling the function; use the oldhtml argument to reference the previous content. Within the function, this refers to the current element in the set. - */ - - /** - * Get the value of a property for the first element in the set of matched elements. - * - * @param propertyName The name of the property to get. - */ - prop(propertyName: string): any; - /** - * Set one or more properties for the set of matched elements. - * - * @param propertyName The name of the property to set. - * @param value A value to set for the property. - */ - prop(propertyName: string, value: string|number|boolean): JQuery; - /** - * Set one or more properties for the set of matched elements. - * - * @param properties An object of property-value pairs to set. - */ - prop(properties: Object): JQuery; - /** - * Set one or more properties for the set of matched elements. - * - * @param propertyName The name of the property to set. - * @param func A function returning the value to set. Receives the index position of the element in the set and the old property value as arguments. Within the function, the keyword this refers to the current element. - */ - prop(propertyName: string, func: (index: number, oldPropertyValue: any) => any): JQuery; - - /** - * Remove an attribute from each element in the set of matched elements. - * - * @param attributeName An attribute to remove; as of version 1.7, it can be a space-separated list of attributes. - */ - removeAttr(attributeName: string): JQuery; - - /** - * Remove a single class, multiple classes, or all classes from each element in the set of matched elements. - * - * @param className One or more space-separated classes to be removed from the class attribute of each matched element. - */ - removeClass(className?: string): JQuery; - /** - * Remove a single class, multiple classes, or all classes from each element in the set of matched elements. - * - * @param function A function returning one or more space-separated class names to be removed. Receives the index position of the element in the set and the old class value as arguments. - */ - removeClass(func: (index: number, className: string) => string): JQuery; - - /** - * Remove a property for the set of matched elements. - * - * @param propertyName The name of the property to remove. - */ - removeProp(propertyName: string): JQuery; - - /** - * Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument. - * - * @param className One or more class names (separated by spaces) to be toggled for each element in the matched set. - * @param swtch A Boolean (not just truthy/falsy) value to determine whether the class should be added or removed. - */ - toggleClass(className: string, swtch?: boolean): JQuery; - /** - * Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument. - * - * @param swtch A boolean value to determine whether the class should be added or removed. - */ - toggleClass(swtch?: boolean): JQuery; - /** - * Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument. - * - * @param func A function that returns class names to be toggled in the class attribute of each element in the matched set. Receives the index position of the element in the set, the old class value, and the switch as arguments. - * @param swtch A boolean value to determine whether the class should be added or removed. - */ - toggleClass(func: (index: number, className: string, swtch: boolean) => string, swtch?: boolean): JQuery; - - /** - * Get the current value of the first element in the set of matched elements. - */ - val(): any; - /** - * Set the value of each element in the set of matched elements. - * - * @param value A string of text, an array of strings or number corresponding to the value of each matched element to set as selected/checked. - */ - val(value: string|string[]|number): JQuery; - /** - * Set the value of each element in the set of matched elements. - * - * @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments. - */ - val(func: (index: number, value: string) => string): JQuery; - - - /** - * Get the value of style properties for the first element in the set of matched elements. - * - * @param propertyName A CSS property. - */ - css(propertyName: string): string; - /** - * Set one or more CSS properties for the set of matched elements. - * - * @param propertyName A CSS property name. - * @param value A value to set for the property. - */ - css(propertyName: string, value: string|number): JQuery; - /** - * Set one or more CSS properties for the set of matched elements. - * - * @param propertyName A CSS property name. - * @param value A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments. - */ - css(propertyName: string, value: (index: number, value: string) => string|number): JQuery; - /** - * Set one or more CSS properties for the set of matched elements. - * - * @param properties An object of property-value pairs to set. - */ - css(properties: Object): JQuery; - - /** - * Get the current computed height for the first element in the set of matched elements. - */ - height(): number; - /** - * Set the CSS height of every matched element. - * - * @param value An integer representing the number of pixels, or an integer with an optional unit of measure appended (as a string). - */ - height(value: number|string): JQuery; - /** - * Set the CSS height of every matched element. - * - * @param func A function returning the height to set. Receives the index position of the element in the set and the old height as arguments. Within the function, this refers to the current element in the set. - */ - height(func: (index: number, height: number) => number|string): JQuery; - - /** - * Get the current computed height for the first element in the set of matched elements, including padding but not border. - */ - innerHeight(): number; - - /** - * Sets the inner height on elements in the set of matched elements, including padding but not border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - innerHeight(height: number|string): JQuery; - - /** - * Get the current computed width for the first element in the set of matched elements, including padding but not border. - */ - innerWidth(): number; - - /** - * Sets the inner width on elements in the set of matched elements, including padding but not border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - innerWidth(width: number|string): JQuery; - - /** - * Get the current coordinates of the first element in the set of matched elements, relative to the document. - */ - offset(): JQueryCoordinates; - /** - * An object containing the properties top and left, which are integers indicating the new top and left coordinates for the elements. - * - * @param coordinates An object containing the properties top and left, which are integers indicating the new top and left coordinates for the elements. - */ - offset(coordinates: JQueryCoordinates): JQuery; - /** - * An object containing the properties top and left, which are integers indicating the new top and left coordinates for the elements. - * - * @param func A function to return the coordinates to set. Receives the index of the element in the collection as the first argument and the current coordinates as the second argument. The function should return an object with the new top and left properties. - */ - offset(func: (index: number, coords: JQueryCoordinates) => JQueryCoordinates): JQuery; - - /** - * Get the current computed height for the first element in the set of matched elements, including padding, border, and optionally margin. Returns an integer (without "px") representation of the value or null if called on an empty set of elements. - * - * @param includeMargin A Boolean indicating whether to include the element's margin in the calculation. - */ - outerHeight(includeMargin?: boolean): number; - - /** - * Sets the outer height on elements in the set of matched elements, including padding and border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - outerHeight(height: number|string): JQuery; - - /** - * Get the current computed width for the first element in the set of matched elements, including padding and border. - * - * @param includeMargin A Boolean indicating whether to include the element's margin in the calculation. - */ - outerWidth(includeMargin?: boolean): number; - - /** - * Sets the outer width on elements in the set of matched elements, including padding and border. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - outerWidth(width: number|string): JQuery; - - /** - * Get the current coordinates of the first element in the set of matched elements, relative to the offset parent. - */ - position(): JQueryCoordinates; - - /** - * Get the current horizontal position of the scroll bar for the first element in the set of matched elements or set the horizontal position of the scroll bar for every matched element. - */ - scrollLeft(): number; - /** - * Set the current horizontal position of the scroll bar for each of the set of matched elements. - * - * @param value An integer indicating the new position to set the scroll bar to. - */ - scrollLeft(value: number): JQuery; - - /** - * Get the current vertical position of the scroll bar for the first element in the set of matched elements or set the vertical position of the scroll bar for every matched element. - */ - scrollTop(): number; - /** - * Set the current vertical position of the scroll bar for each of the set of matched elements. - * - * @param value An integer indicating the new position to set the scroll bar to. - */ - scrollTop(value: number): JQuery; - - /** - * Get the current computed width for the first element in the set of matched elements. - */ - width(): number; - /** - * Set the CSS width of each element in the set of matched elements. - * - * @param value An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string). - */ - width(value: number|string): JQuery; - /** - * Set the CSS width of each element in the set of matched elements. - * - * @param func A function returning the width to set. Receives the index position of the element in the set and the old width as arguments. Within the function, this refers to the current element in the set. - */ - width(func: (index: number, width: number) => number|string): JQuery; - - /** - * Remove from the queue all items that have not yet been run. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - clearQueue(queueName?: string): JQuery; - - /** - * Store arbitrary data associated with the matched elements. - * - * @param key A string naming the piece of data to set. - * @param value The new data value; it can be any Javascript type including Array or Object. - */ - data(key: string, value: any): JQuery; - /** - * Return the value at the named data store for the first element in the jQuery collection, as set by data(name, value) or by an HTML5 data-* attribute. - * - * @param key Name of the data stored. - */ - data(key: string): any; - /** - * Store arbitrary data associated with the matched elements. - * - * @param obj An object of key-value pairs of data to update. - */ - data(obj: { [key: string]: any; }): JQuery; - /** - * Return the value at the named data store for the first element in the jQuery collection, as set by data(name, value) or by an HTML5 data-* attribute. - */ - data(): any; - - /** - * Execute the next function on the queue for the matched elements. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - dequeue(queueName?: string): JQuery; - - /** - * Remove a previously-stored piece of data. - * - * @param name A string naming the piece of data to delete or space-separated string naming the pieces of data to delete. - */ - removeData(name: string): JQuery; - /** - * Remove a previously-stored piece of data. - * - * @param list An array of strings naming the pieces of data to delete. - */ - removeData(list: string[]): JQuery; - /** - * Remove all previously-stored piece of data. - */ - removeData(): JQuery; - - /** - * Return a Promise object to observe when all actions of a certain type bound to the collection, queued or not, have finished. - * - * @param type The type of queue that needs to be observed. (default: fx) - * @param target Object onto which the promise methods have to be attached - */ - promise(type?: string, target?: Object): JQueryPromise; - - /** - * Perform a custom animation of a set of CSS properties. - * - * @param properties An object of CSS properties and values that the animation will move toward. - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - animate(properties: Object, duration?: string|number, complete?: Function): JQuery; - /** - * Perform a custom animation of a set of CSS properties. - * - * @param properties An object of CSS properties and values that the animation will move toward. - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. (default: swing) - * @param complete A function to call once the animation is complete. - */ - animate(properties: Object, duration?: string|number, easing?: string, complete?: Function): JQuery; - /** - * Perform a custom animation of a set of CSS properties. - * - * @param properties An object of CSS properties and values that the animation will move toward. - * @param options A map of additional options to pass to the method. - */ - animate(properties: Object, options: JQueryAnimationOptions): JQuery; - - /** - * Set a timer to delay execution of subsequent items in the queue. - * - * @param duration An integer indicating the number of milliseconds to delay execution of the next item in the queue. - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - delay(duration: number, queueName?: string): JQuery; - - /** - * Display the matched elements by fading them to opaque. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - fadeIn(duration?: number|string, complete?: Function): JQuery; - /** - * Display the matched elements by fading them to opaque. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeIn(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display the matched elements by fading them to opaque. - * - * @param options A map of additional options to pass to the method. - */ - fadeIn(options: JQueryAnimationOptions): JQuery; - - /** - * Hide the matched elements by fading them to transparent. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - fadeOut(duration?: number|string, complete?: Function): JQuery; - /** - * Hide the matched elements by fading them to transparent. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeOut(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Hide the matched elements by fading them to transparent. - * - * @param options A map of additional options to pass to the method. - */ - fadeOut(options: JQueryAnimationOptions): JQuery; - - /** - * Adjust the opacity of the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param opacity A number between 0 and 1 denoting the target opacity. - * @param complete A function to call once the animation is complete. - */ - fadeTo(duration: string|number, opacity: number, complete?: Function): JQuery; - /** - * Adjust the opacity of the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param opacity A number between 0 and 1 denoting the target opacity. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeTo(duration: string|number, opacity: number, easing?: string, complete?: Function): JQuery; - - /** - * Display or hide the matched elements by animating their opacity. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - fadeToggle(duration?: number|string, complete?: Function): JQuery; - /** - * Display or hide the matched elements by animating their opacity. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - fadeToggle(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display or hide the matched elements by animating their opacity. - * - * @param options A map of additional options to pass to the method. - */ - fadeToggle(options: JQueryAnimationOptions): JQuery; - - /** - * Stop the currently-running animation, remove all queued animations, and complete all animations for the matched elements. - * - * @param queue The name of the queue in which to stop animations. - */ - finish(queue?: string): JQuery; - - /** - * Hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - hide(duration?: number|string, complete?: Function): JQuery; - /** - * Hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - hide(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Hide the matched elements. - * - * @param options A map of additional options to pass to the method. - */ - hide(options: JQueryAnimationOptions): JQuery; - - /** - * Display the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - show(duration?: number|string, complete?: Function): JQuery; - /** - * Display the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - show(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display the matched elements. - * - * @param options A map of additional options to pass to the method. - */ - show(options: JQueryAnimationOptions): JQuery; - - /** - * Display the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - slideDown(duration?: number|string, complete?: Function): JQuery; - /** - * Display the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - slideDown(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display the matched elements with a sliding motion. - * - * @param options A map of additional options to pass to the method. - */ - slideDown(options: JQueryAnimationOptions): JQuery; - - /** - * Display or hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - slideToggle(duration?: number|string, complete?: Function): JQuery; - /** - * Display or hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - slideToggle(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display or hide the matched elements with a sliding motion. - * - * @param options A map of additional options to pass to the method. - */ - slideToggle(options: JQueryAnimationOptions): JQuery; - - /** - * Hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - slideUp(duration?: number|string, complete?: Function): JQuery; - /** - * Hide the matched elements with a sliding motion. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - slideUp(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Hide the matched elements with a sliding motion. - * - * @param options A map of additional options to pass to the method. - */ - slideUp(options: JQueryAnimationOptions): JQuery; - - /** - * Stop the currently-running animation on the matched elements. - * - * @param clearQueue A Boolean indicating whether to remove queued animation as well. Defaults to false. - * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately. Defaults to false. - */ - stop(clearQueue?: boolean, jumpToEnd?: boolean): JQuery; - /** - * Stop the currently-running animation on the matched elements. - * - * @param queue The name of the queue in which to stop animations. - * @param clearQueue A Boolean indicating whether to remove queued animation as well. Defaults to false. - * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately. Defaults to false. - */ - stop(queue?: string, clearQueue?: boolean, jumpToEnd?: boolean): JQuery; - - /** - * Display or hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param complete A function to call once the animation is complete. - */ - toggle(duration?: number|string, complete?: Function): JQuery; - /** - * Display or hide the matched elements. - * - * @param duration A string or number determining how long the animation will run. - * @param easing A string indicating which easing function to use for the transition. - * @param complete A function to call once the animation is complete. - */ - toggle(duration?: number|string, easing?: string, complete?: Function): JQuery; - /** - * Display or hide the matched elements. - * - * @param options A map of additional options to pass to the method. - */ - toggle(options: JQueryAnimationOptions): JQuery; - /** - * Display or hide the matched elements. - * - * @param showOrHide A Boolean indicating whether to show or hide the elements. - */ - toggle(showOrHide: boolean): JQuery; - - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - bind(eventType: string, eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param handler A function to execute each time the event is triggered. - */ - bind(eventType: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param eventData An object containing data that will be passed to the event handler. - * @param preventBubble Setting the third argument to false will attach a function that prevents the default action from occurring and stops the event from bubbling. The default is true. - */ - bind(eventType: string, eventData: any, preventBubble: boolean): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param eventType A string containing one or more DOM event types, such as "click" or "submit," or custom event names. - * @param preventBubble Setting the third argument to false will attach a function that prevents the default action from occurring and stops the event from bubbling. The default is true. - */ - bind(eventType: string, preventBubble: boolean): JQuery; - /** - * Attach a handler to an event for the elements. - * - * @param events An object containing one or more DOM event types and functions to execute for them. - */ - bind(events: any): JQuery; - - /** - * Trigger the "blur" event on an element - */ - blur(): JQuery; - /** - * Bind an event handler to the "blur" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - blur(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "blur" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - blur(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "change" event on an element. - */ - change(): JQuery; - /** - * Bind an event handler to the "change" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - change(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "change" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - change(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "click" event on an element. - */ - click(): JQuery; - /** - * Bind an event handler to the "click" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - */ - click(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "click" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - click(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "dblclick" event on an element. - */ - dblclick(): JQuery; - /** - * Bind an event handler to the "dblclick" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - dblclick(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "dblclick" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - dblclick(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - delegate(selector: any, eventType: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - delegate(selector: any, eventType: string, eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "focus" event on an element. - */ - focus(): JQuery; - /** - * Bind an event handler to the "focus" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - focus(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "focus" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - focus(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "focusin" event on an element. - */ - focusin(): JQuery; - /** - * Bind an event handler to the "focusin" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - focusin(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "focusin" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - focusin(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "focusout" event on an element. - */ - focusout(): JQuery; - /** - * Bind an event handler to the "focusout" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - focusout(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "focusout" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - focusout(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Bind two handlers to the matched elements, to be executed when the mouse pointer enters and leaves the elements. - * - * @param handlerIn A function to execute when the mouse pointer enters the element. - * @param handlerOut A function to execute when the mouse pointer leaves the element. - */ - hover(handlerIn: (eventObject: JQueryEventObject) => any, handlerOut: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind a single handler to the matched elements, to be executed when the mouse pointer enters or leaves the elements. - * - * @param handlerInOut A function to execute when the mouse pointer enters or leaves the element. - */ - hover(handlerInOut: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "keydown" event on an element. - */ - keydown(): JQuery; - /** - * Bind an event handler to the "keydown" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - keydown(handler: (eventObject: JQueryKeyEventObject) => any): JQuery; - /** - * Bind an event handler to the "keydown" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - keydown(eventData?: any, handler?: (eventObject: JQueryKeyEventObject) => any): JQuery; - - /** - * Trigger the "keypress" event on an element. - */ - keypress(): JQuery; - /** - * Bind an event handler to the "keypress" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - keypress(handler: (eventObject: JQueryKeyEventObject) => any): JQuery; - /** - * Bind an event handler to the "keypress" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - keypress(eventData?: any, handler?: (eventObject: JQueryKeyEventObject) => any): JQuery; - - /** - * Trigger the "keyup" event on an element. - */ - keyup(): JQuery; - /** - * Bind an event handler to the "keyup" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - keyup(handler: (eventObject: JQueryKeyEventObject) => any): JQuery; - /** - * Bind an event handler to the "keyup" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - keyup(eventData?: any, handler?: (eventObject: JQueryKeyEventObject) => any): JQuery; - - /** - * Bind an event handler to the "load" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - load(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "load" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - load(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "mousedown" event on an element. - */ - mousedown(): JQuery; - /** - * Bind an event handler to the "mousedown" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mousedown(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mousedown" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mousedown(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseenter" event on an element. - */ - mouseenter(): JQuery; - /** - * Bind an event handler to be fired when the mouse enters an element. - * - * @param handler A function to execute when the event is triggered. - */ - mouseenter(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to be fired when the mouse enters an element. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseenter(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseleave" event on an element. - */ - mouseleave(): JQuery; - /** - * Bind an event handler to be fired when the mouse leaves an element. - * - * @param handler A function to execute when the event is triggered. - */ - mouseleave(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to be fired when the mouse leaves an element. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseleave(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mousemove" event on an element. - */ - mousemove(): JQuery; - /** - * Bind an event handler to the "mousemove" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mousemove(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mousemove" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mousemove(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseout" event on an element. - */ - mouseout(): JQuery; - /** - * Bind an event handler to the "mouseout" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mouseout(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mouseout" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseout(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseover" event on an element. - */ - mouseover(): JQuery; - /** - * Bind an event handler to the "mouseover" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mouseover(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mouseover" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseover(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Trigger the "mouseup" event on an element. - */ - mouseup(): JQuery; - /** - * Bind an event handler to the "mouseup" JavaScript event. - * - * @param handler A function to execute when the event is triggered. - */ - mouseup(handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - /** - * Bind an event handler to the "mouseup" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - mouseup(eventData: Object, handler: (eventObject: JQueryMouseEventObject) => any): JQuery; - - /** - * Remove an event handler. - */ - off(): JQuery; - /** - * Remove an event handler. - * - * @param events One or more space-separated event types and optional namespaces, or just namespaces, such as "click", "keydown.myPlugin", or ".myPlugin". - * @param selector A selector which should match the one originally passed to .on() when attaching event handlers. - * @param handler A handler function previously attached for the event(s), or the special value false. - */ - off(events: string, selector?: string, handler?: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove an event handler. - * - * @param events One or more space-separated event types and optional namespaces, or just namespaces, such as "click", "keydown.myPlugin", or ".myPlugin". - * @param handler A handler function previously attached for the event(s), or the special value false. Takes handler with extra args that can be attached with on(). - */ - off(events: string, handler: (eventObject: JQueryEventObject, ...args: any[]) => any): JQuery; - /** - * Remove an event handler. - * - * @param events One or more space-separated event types and optional namespaces, or just namespaces, such as "click", "keydown.myPlugin", or ".myPlugin". - * @param handler A handler function previously attached for the event(s), or the special value false. - */ - off(events: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove an event handler. - * - * @param events An object where the string keys represent one or more space-separated event types and optional namespaces, and the values represent handler functions previously attached for the event(s). - * @param selector A selector which should match the one originally passed to .on() when attaching event handlers. - */ - off(events: { [key: string]: any; }, selector?: string): JQuery; - - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. Rest parameter args is for optional parameters passed to jQuery.trigger(). Note that the actual parameters on the event handler function must be marked as optional (? syntax). - */ - on(events: string, handler: (eventObject: JQueryEventObject, ...args: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param data Data to be passed to the handler in event.data when an event is triggered. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - on(events: string, data : any, handler: (eventObject: JQueryEventObject, ...args: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - on(events: string, selector: string, handler: (eventObject: JQueryEventObject, ...eventData: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event is triggered. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - on(events: string, selector: string, data: any, handler: (eventObject: JQueryEventObject, ...eventData: any[]) => any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param selector A selector string to filter the descendants of the selected elements that will call the handler. If the selector is null or omitted, the handler is always called when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - on(events: { [key: string]: any; }, selector?: string, data?: any): JQuery; - /** - * Attach an event handler function for one or more events to the selected elements. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - on(events: { [key: string]: any; }, data?: any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names. - * @param handler A function to execute at the time the event is triggered. - */ - one(events: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names. - * @param data An object containing data that will be passed to the event handler. - * @param handler A function to execute at the time the event is triggered. - */ - one(events: string, data: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - one(events: string, selector: string, handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin". - * @param selector A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event is triggered. - * @param handler A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false. - */ - one(events: string, selector: string, data: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param selector A selector string to filter the descendants of the selected elements that will call the handler. If the selector is null or omitted, the handler is always called when it reaches the selected element. - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - one(events: { [key: string]: any; }, selector?: string, data?: any): JQuery; - - /** - * Attach a handler to an event for the elements. The handler is executed at most once per element per event type. - * - * @param events An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s). - * @param data Data to be passed to the handler in event.data when an event occurs. - */ - one(events: { [key: string]: any; }, data?: any): JQuery; - - - /** - * Specify a function to execute when the DOM is fully loaded. - * - * @param handler A function to execute after the DOM is ready. - */ - ready(handler: (jQueryAlias?: JQueryStatic) => any): JQuery; - - /** - * Trigger the "resize" event on an element. - */ - resize(): JQuery; - /** - * Bind an event handler to the "resize" JavaScript event. - * - * @param handler A function to execute each time the event is triggered. - */ - resize(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "resize" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - resize(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "scroll" event on an element. - */ - scroll(): JQuery; - /** - * Bind an event handler to the "scroll" JavaScript event. - * - * @param handler A function to execute each time the event is triggered. - */ - scroll(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "scroll" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - scroll(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "select" event on an element. - */ - select(): JQuery; - /** - * Bind an event handler to the "select" JavaScript event. - * - * @param handler A function to execute each time the event is triggered. - */ - select(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "select" JavaScript event. - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - select(eventData: Object, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Trigger the "submit" event on an element. - */ - submit(): JQuery; - /** - * Bind an event handler to the "submit" JavaScript event - * - * @param handler A function to execute each time the event is triggered. - */ - submit(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "submit" JavaScript event - * - * @param eventData An object containing data that will be passed to the event handler. - * @param handler A function to execute each time the event is triggered. - */ - submit(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Execute all handlers and behaviors attached to the matched elements for the given event type. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param extraParameters Additional parameters to pass along to the event handler. - */ - trigger(eventType: string, extraParameters?: any[]|Object): JQuery; - /** - * Execute all handlers and behaviors attached to the matched elements for the given event type. - * - * @param event A jQuery.Event object. - * @param extraParameters Additional parameters to pass along to the event handler. - */ - trigger(event: JQueryEventObject, extraParameters?: any[]|Object): JQuery; - - /** - * Execute all handlers attached to an element for an event. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param extraParameters An array of additional parameters to pass along to the event handler. - */ - triggerHandler(eventType: string, ...extraParameters: any[]): Object; - - /** - * Execute all handlers attached to an element for an event. - * - * @param event A jQuery.Event object. - * @param extraParameters An array of additional parameters to pass along to the event handler. - */ - triggerHandler(event: JQueryEventObject, ...extraParameters: any[]): Object; - - /** - * Remove a previously-attached event handler from the elements. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param handler The function that is to be no longer executed. - */ - unbind(eventType?: string, handler?: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove a previously-attached event handler from the elements. - * - * @param eventType A string containing a JavaScript event type, such as click or submit. - * @param fls Unbinds the corresponding 'return false' function that was bound using .bind( eventType, false ). - */ - unbind(eventType: string, fls: boolean): JQuery; - /** - * Remove a previously-attached event handler from the elements. - * - * @param evt A JavaScript event object as passed to an event handler. - */ - unbind(evt: any): JQuery; - - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - */ - undelegate(): JQuery; - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - * - * @param selector A selector which will be used to filter the event results. - * @param eventType A string containing a JavaScript event type, such as "click" or "keydown" - * @param handler A function to execute at the time the event is triggered. - */ - undelegate(selector: string, eventType: string, handler?: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - * - * @param selector A selector which will be used to filter the event results. - * @param events An object of one or more event types and previously bound functions to unbind from them. - */ - undelegate(selector: string, events: Object): JQuery; - /** - * Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements. - * - * @param namespace A string containing a namespace to unbind all events from. - */ - undelegate(namespace: string): JQuery; - - /** - * Bind an event handler to the "unload" JavaScript event. (DEPRECATED from v1.8) - * - * @param handler A function to execute when the event is triggered. - */ - unload(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "unload" JavaScript event. (DEPRECATED from v1.8) - * - * @param eventData A plain object of data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - unload(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * The DOM node context originally passed to jQuery(); if none was passed then context will likely be the document. (DEPRECATED from v1.10) - */ - context: Element; - - jquery: string; - - /** - * Bind an event handler to the "error" JavaScript event. (DEPRECATED from v1.8) - * - * @param handler A function to execute when the event is triggered. - */ - error(handler: (eventObject: JQueryEventObject) => any): JQuery; - /** - * Bind an event handler to the "error" JavaScript event. (DEPRECATED from v1.8) - * - * @param eventData A plain object of data that will be passed to the event handler. - * @param handler A function to execute when the event is triggered. - */ - error(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery; - - /** - * Add a collection of DOM elements onto the jQuery stack. - * - * @param elements An array of elements to push onto the stack and make into a new jQuery object. - */ - pushStack(elements: any[]): JQuery; - /** - * Add a collection of DOM elements onto the jQuery stack. - * - * @param elements An array of elements to push onto the stack and make into a new jQuery object. - * @param name The name of a jQuery method that generated the array of elements. - * @param arguments The arguments that were passed in to the jQuery method (for serialization). - */ - pushStack(elements: any[], name: string, arguments: any[]): JQuery; - - /** - * Insert content, specified by the parameter, after each element in the set of matched elements. - * - * param content1 HTML string, DOM element, array of elements, or jQuery object to insert after each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert after each element in the set of matched elements. - */ - after(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, after each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert after each element in the set of matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - after(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Insert content, specified by the parameter, to the end of each element in the set of matched elements. - * - * param content1 DOM element, array of elements, HTML string, or jQuery object to insert at the end of each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert at the end of each element in the set of matched elements. - */ - append(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, to the end of each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert at the end of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set. - */ - append(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Insert every element in the set of matched elements to the end of the target. - * - * @param target A selector, element, HTML string, array of elements, or jQuery object; the matched set of elements will be inserted at the end of the element(s) specified by this parameter. - */ - appendTo(target: JQuery|any[]|Element|string): JQuery; - - /** - * Insert content, specified by the parameter, before each element in the set of matched elements. - * - * param content1 HTML string, DOM element, array of elements, or jQuery object to insert before each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert before each element in the set of matched elements. - */ - before(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, before each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert before each element in the set of matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - before(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Create a deep copy of the set of matched elements. - * - * param withDataAndEvents A Boolean indicating whether event handlers and data should be copied along with the elements. The default value is false. - * param deepWithDataAndEvents A Boolean indicating whether event handlers and data for all children of the cloned element should be copied. By default its value matches the first argument's value (which defaults to false). - */ - clone(withDataAndEvents?: boolean, deepWithDataAndEvents?: boolean): JQuery; - - /** - * Remove the set of matched elements from the DOM. - * - * param selector A selector expression that filters the set of matched elements to be removed. - */ - detach(selector?: string): JQuery; - - /** - * Remove all child nodes of the set of matched elements from the DOM. - */ - empty(): JQuery; - - /** - * Insert every element in the set of matched elements after the target. - * - * param target A selector, element, array of elements, HTML string, or jQuery object; the matched set of elements will be inserted after the element(s) specified by this parameter. - */ - insertAfter(target: JQuery|any[]|Element|Text|string): JQuery; - - /** - * Insert every element in the set of matched elements before the target. - * - * param target A selector, element, array of elements, HTML string, or jQuery object; the matched set of elements will be inserted before the element(s) specified by this parameter. - */ - insertBefore(target: JQuery|any[]|Element|Text|string): JQuery; - - /** - * Insert content, specified by the parameter, to the beginning of each element in the set of matched elements. - * - * param content1 DOM element, array of elements, HTML string, or jQuery object to insert at the beginning of each element in the set of matched elements. - * param content2 One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert at the beginning of each element in the set of matched elements. - */ - prepend(content1: JQuery|any[]|Element|Text|string, ...content2: any[]): JQuery; - /** - * Insert content, specified by the parameter, to the beginning of each element in the set of matched elements. - * - * param func A function that returns an HTML string, DOM element(s), or jQuery object to insert at the beginning of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set. - */ - prepend(func: (index: number, html: string) => string|Element|JQuery): JQuery; - - /** - * Insert every element in the set of matched elements to the beginning of the target. - * - * @param target A selector, element, HTML string, array of elements, or jQuery object; the matched set of elements will be inserted at the beginning of the element(s) specified by this parameter. - */ - prependTo(target: JQuery|any[]|Element|string): JQuery; - - /** - * Remove the set of matched elements from the DOM. - * - * @param selector A selector expression that filters the set of matched elements to be removed. - */ - remove(selector?: string): JQuery; - - /** - * Replace each target element with the set of matched elements. - * - * @param target A selector string, jQuery object, DOM element, or array of elements indicating which element(s) to replace. - */ - replaceAll(target: JQuery|any[]|Element|string): JQuery; - - /** - * Replace each element in the set of matched elements with the provided new content and return the set of elements that was removed. - * - * param newContent The content to insert. May be an HTML string, DOM element, array of DOM elements, or jQuery object. - */ - replaceWith(newContent: JQuery|any[]|Element|Text|string): JQuery; - /** - * Replace each element in the set of matched elements with the provided new content and return the set of elements that was removed. - * - * param func A function that returns content with which to replace the set of matched elements. - */ - replaceWith(func: () => Element|JQuery): JQuery; - - /** - * Get the combined text contents of each element in the set of matched elements, including their descendants. - */ - text(): string; - /** - * Set the content of each element in the set of matched elements to the specified text. - * - * @param text The text to set as the content of each matched element. When Number or Boolean is supplied, it will be converted to a String representation. - */ - text(text: string|number|boolean): JQuery; - /** - * Set the content of each element in the set of matched elements to the specified text. - * - * @param func A function returning the text content to set. Receives the index position of the element in the set and the old text value as arguments. - */ - text(func: (index: number, text: string) => string): JQuery; - - /** - * Retrieve all the elements contained in the jQuery set, as an array. - */ - toArray(): any[]; - - /** - * Remove the parents of the set of matched elements from the DOM, leaving the matched elements in their place. - */ - unwrap(): JQuery; - - /** - * Wrap an HTML structure around each element in the set of matched elements. - * - * @param wrappingElement A selector, element, HTML string, or jQuery object specifying the structure to wrap around the matched elements. - */ - wrap(wrappingElement: JQuery|Element|string): JQuery; - /** - * Wrap an HTML structure around each element in the set of matched elements. - * - * @param func A callback function returning the HTML content or jQuery object to wrap around the matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - wrap(func: (index: number) => string|JQuery): JQuery; - - /** - * Wrap an HTML structure around all elements in the set of matched elements. - * - * @param wrappingElement A selector, element, HTML string, or jQuery object specifying the structure to wrap around the matched elements. - */ - wrapAll(wrappingElement: JQuery|Element|string): JQuery; - wrapAll(func: (index: number) => string): JQuery; - - /** - * Wrap an HTML structure around the content of each element in the set of matched elements. - * - * @param wrappingElement An HTML snippet, selector expression, jQuery object, or DOM element specifying the structure to wrap around the content of the matched elements. - */ - wrapInner(wrappingElement: JQuery|Element|string): JQuery; - /** - * Wrap an HTML structure around the content of each element in the set of matched elements. - * - * @param func A callback function which generates a structure to wrap around the content of the matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set. - */ - wrapInner(func: (index: number) => string): JQuery; - - /** - * Iterate over a jQuery object, executing a function for each matched element. - * - * @param func A function to execute for each matched element. - */ - each(func: (index: number, elem: Element) => any): JQuery; - - /** - * Retrieve one of the elements matched by the jQuery object. - * - * @param index A zero-based integer indicating which element to retrieve. - */ - get(index: number): HTMLElement; - /** - * Retrieve the elements matched by the jQuery object. - */ - get(): any[]; - - /** - * Search for a given element from among the matched elements. - */ - index(): number; - /** - * Search for a given element from among the matched elements. - * - * @param selector A selector representing a jQuery collection in which to look for an element. - */ - index(selector: string|JQuery|Element): number; - - /** - * The number of elements in the jQuery object. - */ - length: number; - /** - * A selector representing selector passed to jQuery(), if any, when creating the original set. - * version deprecated: 1.7, removed: 1.9 - */ - selector: string; - [index: string]: any; - [index: number]: HTMLElement; - - /** - * Add elements to the set of matched elements. - * - * @param selector A string representing a selector expression to find additional elements to add to the set of matched elements. - * @param context The point in the document at which the selector should begin matching; similar to the context argument of the $(selector, context) method. - */ - add(selector: string, context?: Element): JQuery; - /** - * Add elements to the set of matched elements. - * - * @param elements One or more elements to add to the set of matched elements. - */ - add(...elements: Element[]): JQuery; - /** - * Add elements to the set of matched elements. - * - * @param html An HTML fragment to add to the set of matched elements. - */ - add(html: string): JQuery; - /** - * Add elements to the set of matched elements. - * - * @param obj An existing jQuery object to add to the set of matched elements. - */ - add(obj: JQuery): JQuery; - - /** - * Get the children of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - children(selector?: string): JQuery; - - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param selector A string containing a selector expression to match elements against. - */ - closest(selector: string): JQuery; - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param selector A string containing a selector expression to match elements against. - * @param context A DOM element within which a matching element may be found. If no context is passed in then the context of the jQuery set will be used instead. - */ - closest(selector: string, context?: Element): JQuery; - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param obj A jQuery object to match elements against. - */ - closest(obj: JQuery): JQuery; - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * - * @param element An element to match elements against. - */ - closest(element: Element): JQuery; - - /** - * Get an array of all the elements and selectors matched against the current element up through the DOM tree. - * - * @param selectors An array or string containing a selector expression to match elements against (can also be a jQuery object). - * @param context A DOM element within which a matching element may be found. If no context is passed in then the context of the jQuery set will be used instead. - */ - closest(selectors: any, context?: Element): any[]; - - /** - * Get the children of each element in the set of matched elements, including text and comment nodes. - */ - contents(): JQuery; - - /** - * End the most recent filtering operation in the current chain and return the set of matched elements to its previous state. - */ - end(): JQuery; - - /** - * Reduce the set of matched elements to the one at the specified index. - * - * @param index An integer indicating the 0-based position of the element. OR An integer indicating the position of the element, counting backwards from the last element in the set. - * - */ - eq(index: number): JQuery; - - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param selector A string containing a selector expression to match the current set of elements against. - */ - filter(selector: string): JQuery; - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param func A function used as a test for each element in the set. this is the current DOM element. - */ - filter(func: (index: number, element: Element) => any): JQuery; - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param element An element to match the current set of elements against. - */ - filter(element: Element): JQuery; - /** - * Reduce the set of matched elements to those that match the selector or pass the function's test. - * - * @param obj An existing jQuery object to match the current set of elements against. - */ - filter(obj: JQuery): JQuery; - - /** - * Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element. - * - * @param selector A string containing a selector expression to match elements against. - */ - find(selector: string): JQuery; - /** - * Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element. - * - * @param element An element to match elements against. - */ - find(element: Element): JQuery; - /** - * Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element. - * - * @param obj A jQuery object to match elements against. - */ - find(obj: JQuery): JQuery; - - /** - * Reduce the set of matched elements to the first in the set. - */ - first(): JQuery; - - /** - * Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element. - * - * @param selector A string containing a selector expression to match elements against. - */ - has(selector: string): JQuery; - /** - * Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element. - * - * @param contained A DOM element to match elements against. - */ - has(contained: Element): JQuery; - - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param selector A string containing a selector expression to match elements against. - */ - is(selector: string): boolean; - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param func A function used as a test for the set of elements. It accepts one argument, index, which is the element's index in the jQuery collection.Within the function, this refers to the current DOM element. - */ - is(func: (index: number, element: Element) => boolean): boolean; - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param obj An existing jQuery object to match the current set of elements against. - */ - is(obj: JQuery): boolean; - /** - * Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments. - * - * @param elements One or more elements to match the current set of elements against. - */ - is(elements: any): boolean; - - /** - * Reduce the set of matched elements to the final one in the set. - */ - last(): JQuery; - - /** - * Pass each element in the current matched set through a function, producing a new jQuery object containing the return values. - * - * @param callback A function object that will be invoked for each element in the current set. - */ - map(callback: (index: number, domElement: Element) => any): JQuery; - - /** - * Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - next(selector?: string): JQuery; - - /** - * Get all following siblings of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - nextAll(selector?: string): JQuery; - - /** - * Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed. - * - * @param selector A string containing a selector expression to indicate where to stop matching following sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - nextUntil(selector?: string, filter?: string): JQuery; - /** - * Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed. - * - * @param element A DOM node or jQuery object indicating where to stop matching following sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - nextUntil(element?: Element, filter?: string): JQuery; - /** - * Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed. - * - * @param obj A DOM node or jQuery object indicating where to stop matching following sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - nextUntil(obj?: JQuery, filter?: string): JQuery; - - /** - * Remove elements from the set of matched elements. - * - * @param selector A string containing a selector expression to match elements against. - */ - not(selector: string): JQuery; - /** - * Remove elements from the set of matched elements. - * - * @param func A function used as a test for each element in the set. this is the current DOM element. - */ - not(func: (index: number, element: Element) => boolean): JQuery; - /** - * Remove elements from the set of matched elements. - * - * @param elements One or more DOM elements to remove from the matched set. - */ - not(elements: Element|Element[]): JQuery; - /** - * Remove elements from the set of matched elements. - * - * @param obj An existing jQuery object to match the current set of elements against. - */ - not(obj: JQuery): JQuery; - - /** - * Get the closest ancestor element that is positioned. - */ - offsetParent(): JQuery; - - /** - * Get the parent of each element in the current set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - parent(selector?: string): JQuery; - - /** - * Get the ancestors of each element in the current set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - parents(selector?: string): JQuery; - - /** - * Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param selector A string containing a selector expression to indicate where to stop matching ancestor elements. - * @param filter A string containing a selector expression to match elements against. - */ - parentsUntil(selector?: string, filter?: string): JQuery; - /** - * Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param element A DOM node or jQuery object indicating where to stop matching ancestor elements. - * @param filter A string containing a selector expression to match elements against. - */ - parentsUntil(element?: Element, filter?: string): JQuery; - /** - * Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param obj A DOM node or jQuery object indicating where to stop matching ancestor elements. - * @param filter A string containing a selector expression to match elements against. - */ - parentsUntil(obj?: JQuery, filter?: string): JQuery; - - /** - * Get the immediately preceding sibling of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - prev(selector?: string): JQuery; - - /** - * Get all preceding siblings of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - prevAll(selector?: string): JQuery; - - /** - * Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param selector A string containing a selector expression to indicate where to stop matching preceding sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - prevUntil(selector?: string, filter?: string): JQuery; - /** - * Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param element A DOM node or jQuery object indicating where to stop matching preceding sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - prevUntil(element?: Element, filter?: string): JQuery; - /** - * Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object. - * - * @param obj A DOM node or jQuery object indicating where to stop matching preceding sibling elements. - * @param filter A string containing a selector expression to match elements against. - */ - prevUntil(obj?: JQuery, filter?: string): JQuery; - - /** - * Get the siblings of each element in the set of matched elements, optionally filtered by a selector. - * - * @param selector A string containing a selector expression to match elements against. - */ - siblings(selector?: string): JQuery; - - /** - * Reduce the set of matched elements to a subset specified by a range of indices. - * - * @param start An integer indicating the 0-based position at which the elements begin to be selected. If negative, it indicates an offset from the end of the set. - * @param end An integer indicating the 0-based position at which the elements stop being selected. If negative, it indicates an offset from the end of the set. If omitted, the range continues until the end of the set. - */ - slice(start: number, end?: number): JQuery; - - /** - * Show the queue of functions to be executed on the matched elements. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - */ - queue(queueName?: string): any[]; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param newQueue An array of functions to replace the current queue contents. - */ - queue(newQueue: Function[]): JQuery; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param callback The new function to add to the queue, with a function to call that will dequeue the next item. - */ - queue(callback: Function): JQuery; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param newQueue An array of functions to replace the current queue contents. - */ - queue(queueName: string, newQueue: Function[]): JQuery; - /** - * Manipulate the queue of functions to be executed, once for each matched element. - * - * @param queueName A string containing the name of the queue. Defaults to fx, the standard effects queue. - * @param callback The new function to add to the queue, with a function to call that will dequeue the next item. - */ - queue(queueName: string, callback: Function): JQuery; -} -declare module "jquery" { - export = $; -} -declare var jQuery: JQueryStatic; -declare var $: JQueryStatic; \ No newline at end of file diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/jquery/typings.json b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/jquery/typings.json deleted file mode 100644 index 0af7c54b42..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/globals/jquery/typings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "resolution": "main", - "tree": { - "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/4cdfbe96b666eec5e1defbb519a62abf04e96764/jquery/jquery.d.ts", - "raw": "registry:dt/jquery#1.10.0+20160417213236", - "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/4cdfbe96b666eec5e1defbb519a62abf04e96764/jquery/jquery.d.ts" - } -} diff --git a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/index.d.ts b/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/index.d.ts deleted file mode 100644 index 7b1af70fde..0000000000 --- a/public/docs/_examples/upgrade-phonecat-2-hybrid/ts/typings-ng1/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/// -/// -/// -/// -/// -/// diff --git a/public/docs/_examples/upgrade-phonecat-3-final/e2e-spec.ts b/public/docs/_examples/upgrade-phonecat-3-final/e2e-spec.ts deleted file mode 100644 index 3622210403..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/e2e-spec.ts +++ /dev/null @@ -1,112 +0,0 @@ -/// -'use strict'; - -// Angular E2E Testing Guide: -// https://docs.angularjs.org/guide/e2e-testing - -describe('PhoneCat Application', function() { - - // #docregion redirect - it('should redirect `index.html` to `index.html#!/phones', function() { - browser.get('index.html'); - browser.waitForAngular(); - browser.getCurrentUrl().then(function(url) { - expect(url.endsWith('/phones')).toBe(true); - }); - }); - // #enddocregion redirect - - describe('View: Phone list', function() { - - beforeEach(function() { - browser.get('index.html#!/phones'); - }); - - it('should filter the phone list as a user types into the search box', function() { - let phoneList = element.all(by.css('.phones li')); - let query = element(by.css('input')); - - expect(phoneList.count()).toBe(20); - - sendKeys(query, 'nexus'); - expect(phoneList.count()).toBe(1); - - query.clear(); - sendKeys(query, 'motorola'); - expect(phoneList.count()).toBe(8); - }); - - it('should be possible to control phone order via the drop-down menu', function() { - let queryField = element(by.css('input')); - let orderSelect = element(by.css('select')); - let nameOption = orderSelect.element(by.css('option[value="name"]')); - let phoneNameColumn = element.all(by.css('.phones .name')); - - function getNames() { - return phoneNameColumn.map(function(elem) { - return elem.getText(); - }); - } - - sendKeys(queryField, 'tablet'); // Let's narrow the dataset to make the assertions shorter - - expect(getNames()).toEqual([ - 'Motorola XOOM\u2122 with Wi-Fi', - 'MOTOROLA XOOM\u2122' - ]); - - nameOption.click(); - - expect(getNames()).toEqual([ - 'MOTOROLA XOOM\u2122', - 'Motorola XOOM\u2122 with Wi-Fi' - ]); - }); - - // #docregion links - it('should render phone specific links', function() { - let query = element(by.css('input')); - // https://github.com/angular/protractor/issues/2019 - let str = 'nexus'; - for (let i = 0; i < str.length; i++) { - query.sendKeys(str.charAt(i)); - } - element.all(by.css('.phones li a')).first().click(); - browser.getCurrentUrl().then(function(url) { - expect(url.endsWith('/phones/nexus-s')).toBe(true); - }); - }); - // #enddocregion links - - }); - - describe('View: Phone detail', function() { - - beforeEach(function() { - browser.get('index.html#!/phones/nexus-s'); - }); - - it('should display the `nexus-s` page', function() { - expect(element(by.css('h1')).getText()).toBe('Nexus S'); - }); - - it('should display the first phone image as the main phone image', function() { - let mainImage = element(by.css('img.phone.selected')); - - expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/); - }); - - it('should swap the main image when clicking on a thumbnail image', function() { - let mainImage = element(by.css('img.phone.selected')); - let thumbnails = element.all(by.css('.phone-thumbs img')); - - thumbnails.get(2).click(); - expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.2.jpg/); - - thumbnails.get(0).click(); - expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/); - }); - - }); - -}); diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.component.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.component.ts deleted file mode 100644 index 8f7ebd2ef4..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.component.ts +++ /dev/null @@ -1,18 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; -import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated'; -import { PhoneListComponent } from './phone-list/phone-list.component'; -import { PhoneDetailComponent } from './phone-detail/phone-detail.component'; - -@RouteConfig([ - {path:'/phones', name: 'Phones', component: PhoneListComponent}, - {path:'/phones/:phoneId', name: 'Phone', component: PhoneDetailComponent}, - {path:'/', redirectTo: ['Phones']} -]) -@Component({ - selector: 'phonecat-app', - template: '', - directives: [ROUTER_DIRECTIVES] -}) -export class AppComponent { -} diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.spec.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.spec.ts deleted file mode 100644 index b3a1c59a8d..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { - describe, - beforeEachProviders, - it, - inject, - expect -} from '@angular/core/testing'; -import { CheckmarkPipe } from './checkmark.pipe'; - -describe('CheckmarkPipe', function() { - - beforeEachProviders(() => [CheckmarkPipe]); - - it('should convert boolean values to unicode checkmark or cross', - inject([CheckmarkPipe], function(checkmarkPipe: CheckmarkPipe) { - expect(checkmarkPipe.transform(true)).toBe('\u2713'); - expect(checkmarkPipe.transform(false)).toBe('\u2718'); - }) - ); - -}); diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.ts deleted file mode 100644 index e79b99fc80..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/checkmark/checkmark.pipe.ts +++ /dev/null @@ -1,11 +0,0 @@ -// #docregion -import { Pipe, PipeTransform } from '@angular/core'; - -@Pipe({name: 'checkmark'}) -export class CheckmarkPipe implements PipeTransform { - - transform(input: boolean) { - return input ? '\u2713' : '\u2718'; - } - -} diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.spec.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.spec.ts deleted file mode 100644 index ab664dc4c8..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.spec.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { - describe, - beforeEach, - beforeEachProviders, - it, - inject -} from '@angular/core/testing'; -import { - Http, - BaseRequestOptions, - ResponseOptions, - Response -} from '@angular/http'; -import { MockBackend, MockConnection } from '@angular/http/testing'; -import { Phone, PhoneData } from './phone.service'; - -describe('Phone', function() { - let phone:Phone; - let phonesData:PhoneData[] = [ - {name: 'Phone X', snippet: '', images: []}, - {name: 'Phone Y', snippet: '', images: []}, - {name: 'Phone Z', snippet: '', images: []} - ]; - let mockBackend:MockBackend; - - beforeEachProviders(() => [ - Phone, - MockBackend, - BaseRequestOptions, - { provide: Http, - useFactory: (backend: MockBackend, options: BaseRequestOptions) => new Http(backend, options), - deps: [MockBackend, BaseRequestOptions] - } - ]); - - beforeEach(inject([MockBackend, Phone], (_mockBackend_:MockBackend, _phone_:Phone) => { - mockBackend = _mockBackend_; - phone = _phone_; - })); - - it('should fetch the phones data from `/phones/phones.json`', (done: () => void) => { - mockBackend.connections.subscribe((conn: MockConnection) => { - conn.mockRespond(new Response(new ResponseOptions({body: JSON.stringify(phonesData)}))); - }); - phone.query().subscribe(result => { - expect(result).toEqual(phonesData); - done(); - }); - }); - -}); diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.ts deleted file mode 100644 index b19eea598d..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/core/phone/phone.service.ts +++ /dev/null @@ -1,33 +0,0 @@ -// #docregion -import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; -import { Observable } from 'rxjs/Rx'; - -import 'rxjs/add/operator/map'; - -// #docregion phonedata-interface -export interface PhoneData { - name: string; - snippet: string; - images: string[]; -} -// #enddocregion phonedata-interface - -// #docregion fullclass -// #docregion classdef -@Injectable() -export class Phone { -// #enddocregion classdef - constructor(private http: Http) { } - query(): Observable { - return this.http.get(`phones/phones.json`) - .map((res: Response) => res.json()); - } - get(id: string): Observable { - return this.http.get(`phones/${id}.json`) - .map((res: Response) => res.json()); - } -// #docregion classdef -} -// #enddocregion classdef -// #enddocregion fullclass diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/main.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/main.ts deleted file mode 100644 index f59e9c7afd..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/main.ts +++ /dev/null @@ -1,23 +0,0 @@ -// #docregion -// #docregion imports -import { - LocationStrategy, - HashLocationStrategy, - APP_BASE_HREF -} from '@angular/common'; -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { HTTP_PROVIDERS } from '@angular/http'; -import { ROUTER_PROVIDERS } from '@angular/router-deprecated'; -import { Phone } from './core/phone/phone.service'; -import { AppComponent } from './app.component'; -// #enddocregion imports - -// #docregion bootstrap -bootstrap(AppComponent, [ - HTTP_PROVIDERS, - ROUTER_PROVIDERS, - { provide: APP_BASE_HREF, useValue: '!' }, - { provide: LocationStrategy, useClass: HashLocationStrategy }, - Phone -]); -// #enddocregion bootstrap diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.spec.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.spec.ts deleted file mode 100644 index c553df3d29..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.spec.ts +++ /dev/null @@ -1,59 +0,0 @@ -// #docregion -import { HTTP_PROVIDERS } from '@angular/http'; -// #docregion routeparams -import { RouteParams } from '@angular/router-deprecated'; - -// #enddocregion routeparams -import { Observable } from 'rxjs/Rx'; - -import { - describe, - beforeEachProviders, - inject, - it, - expect -} from '@angular/core/testing'; -import { - TestComponentBuilder, - ComponentFixture -} from '@angular/compiler/testing'; - -import { PhoneDetailComponent } from './phone-detail.component'; -import { Phone, PhoneData } from '../core/phone/phone.service'; - -function xyzPhoneData():PhoneData { - return { - name: 'phone xyz', - snippet: '', - images: ['image/url1.png', 'image/url2.png'] - } -} - -class MockPhone extends Phone { - get(id: string):Observable { - return Observable.of(xyzPhoneData()); - } -} - -describe('PhoneDetailComponent', () => { - - // #docregion routeparams - - beforeEachProviders(() => [ - { provide: Phone, useClass: MockPhone }, - { provide: RouteParams, useValue: new RouteParams({phoneId: 'xyz'})}, - HTTP_PROVIDERS - ]); - // #enddocregion routeparams - - it('should fetch phone detail', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb.createAsync(PhoneDetailComponent) - .then((fixture: ComponentFixture) => { - fixture.detectChanges(); - let compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1')).toHaveText(xyzPhoneData().name); - }); - })); - -}); diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.ts deleted file mode 100644 index 5e29057023..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -// #docplaster -// #docregion -import { Component } from '@angular/core'; -import { RouteParams } from '@angular/router-deprecated'; -import { Phone, PhoneData } from '../core/phone/phone.service'; -import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe'; - -@Component({ - selector: 'phone-detail', - templateUrl: 'phone-detail/phone-detail.template.html', - pipes: [ CheckmarkPipe ] -}) -export class PhoneDetailComponent{ - phone: PhoneData; - mainImageUrl: string; - - constructor(routeParams: RouteParams, phone: Phone) { - phone.get(routeParams.get('phoneId')).subscribe(phone => { - this.phone = phone; - this.setImage(phone.images[0]); - }); - } - - setImage(imageUrl: string) { - this.mainImageUrl = imageUrl; - } -} diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.spec.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.spec.ts deleted file mode 100644 index bfdde7e1fc..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.spec.ts +++ /dev/null @@ -1,82 +0,0 @@ -// #docregion routestuff -import { ApplicationRef } from '@angular/core'; -import { LocationStrategy, HashLocationStrategy } from '@angular/common'; -import { HTTP_PROVIDERS } from '@angular/http'; -import { - ROUTER_PROVIDERS, - ROUTER_PRIMARY_COMPONENT -} from '@angular/router-deprecated'; -import { Observable } from 'rxjs/Rx'; -import { - describe, - beforeEachProviders, - inject, - it, - expect, - MockApplicationRef -} from '@angular/core/testing'; -import { MockLocationStrategy } from '@angular/common/testing'; -import { - TestComponentBuilder, - ComponentFixture -} from '@angular/compiler/testing'; - -import { AppComponent } from '../app.component'; -import { PhoneListComponent } from './phone-list.component'; -import { Phone, PhoneData } from '../core/phone/phone.service'; - -// #enddocregion routestuff - - -class MockPhone extends Phone { - query():Observable { - return Observable.of([ - {name: 'Nexus S', snippet: '', images: []}, - {name: 'Motorola DROID', snippet: '', images: []} - ]) - } -} - -describe('PhoneList', () => { - - // #docregion routestuff - - beforeEachProviders(() => [ - { provide: Phone, useClass: MockPhone}, - HTTP_PROVIDERS, - ROUTER_PROVIDERS, - { provide: ApplicationRef, useClass: MockApplicationRef }, - { provide: ROUTER_PRIMARY_COMPONENT, useValue: AppComponent }, - { provide: LocationStrategy, useClass: MockLocationStrategy}, - ]); - // #enddocregion routestuff - - it('should create "phones" model with 2 phones fetched from xhr', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb.createAsync(PhoneListComponent) - .then((fixture: ComponentFixture) => { - fixture.detectChanges(); - let compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2); - expect( - compiled.querySelector('.phone-list-item:nth-child(1)').textContent - ).toContain('Motorola DROID'); - expect( - compiled.querySelector('.phone-list-item:nth-child(2)').textContent - ).toContain('Nexus S'); - }); - })); - - it('should set the default value of orderProp model', - inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { - return tcb.createAsync(PhoneListComponent) - .then((fixture: ComponentFixture) => { - fixture.detectChanges(); - let compiled = fixture.debugElement.nativeElement; - expect( - compiled.querySelector('select option:last-child').selected - ).toBe(true); - }); - })); - -}); diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.ts b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.ts deleted file mode 100644 index 1ea6219031..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.component.ts +++ /dev/null @@ -1,61 +0,0 @@ -// #docplaster -// #docregion top -import { Component } from '@angular/core'; -import { RouterLink } from '@angular/router-deprecated'; -import { Phone, PhoneData } from '../core/phone/phone.service'; - -@Component({ - selector: 'phone-list', - templateUrl: 'phone-list/phone-list.template.html', - directives: [ RouterLink ] -}) -// #enddocregion top -export class PhoneListComponent { - phones: PhoneData[]; - query:string; - orderProp: string; - - constructor(phone: Phone) { - phone.query().subscribe(phones => { - this.phones = phones; - }); - this.orderProp = 'age'; - } - // #enddocregion initialclass - - // #docregion getphones - getPhones():PhoneData[] { - return this.sortPhones(this.filterPhones(this.phones)); - } - - private filterPhones(phones: PhoneData[]) { - if (phones && this.query) { - return phones.filter(phone => { - let name = phone.name.toLowerCase(); - let snippet = phone.snippet.toLowerCase(); - return name.indexOf(this.query) >= 0 || snippet.indexOf(this.query) >= 0; - }); - } - return phones; - } - - private sortPhones(phones: PhoneData[]) { - if (phones && this.orderProp) { - return phones - .slice(0) // Make a copy - .sort((a, b) => { - if (a[this.orderProp] < b[this.orderProp]) { - return -1; - } else if ([b[this.orderProp] < a[this.orderProp]]) { - return 1; - } else { - return 0; - } - }); - } - return phones; - } - // #enddocregion getphones - // #docregion initialclass -} -// #enddocregion initialclass diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.template.html b/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.template.html deleted file mode 100644 index 9846664768..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-list/phone-list.template.html +++ /dev/null @@ -1,40 +0,0 @@ -
    -
    -
    - - - -

    - Search: - -

    - -

    - Sort by: - -

    - - -
    -
    - - - - - - -
    -
    -
    diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/example-config.json b/public/docs/_examples/upgrade-phonecat-3-final/ts/example-config.json deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/index.html b/public/docs/_examples/upgrade-phonecat-3-final/ts/index.html deleted file mode 100644 index 1b4174131e..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/index.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - Google Phone Gallery - - - - - - - - - - - - - - - - - - - - diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/karma.conf.ng1.js b/public/docs/_examples/upgrade-phonecat-3-final/ts/karma.conf.ng1.js deleted file mode 100644 index 7156e025ce..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/karma.conf.ng1.js +++ /dev/null @@ -1,72 +0,0 @@ -//jshint strict: false -module.exports = function(config) { - config.set({ - - // #docregion basepath - basePath: './', - // #enddocregion basepath - - files: [ - 'https://code.angularjs.org/1.5.5/angular.js', - 'https://code.angularjs.org/1.5.5/angular-animate.js', - 'https://code.angularjs.org/1.5.5/angular-resource.js', - 'https://code.angularjs.org/1.5.5/angular-route.js', - 'https://code.angularjs.org/1.5.5/angular-mocks.js', - - // #docregion files - // System.js for module loading - 'node_modules/systemjs/dist/system.src.js', - - // Polyfills - 'node_modules/core-js/client/shim.js', - - // Reflect and Zone.js - 'node_modules/reflect-metadata/Reflect.js', - 'node_modules/zone.js/dist/zone.js', - 'node_modules/zone.js/dist/jasmine-patch.js', - 'node_modules/zone.js/dist/async-test.js', - 'node_modules/zone.js/dist/fake-async-test.js', - - // RxJs. - { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, - { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false }, - - // Angular 2 itself and the testing library - {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false}, - {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false}, - - {pattern: 'systemjs.config.js', included: false, watched: false}, - 'karma-test-shim.js', - - {pattern: 'app/**/*.module.js', included: false, watched: true}, - {pattern: 'app/*!(.module|.spec).js', included: false, watched: true}, - {pattern: 'app/!(bower_components)/**/*!(.module|.spec).js', included: false, watched: true}, - {pattern: 'app/**/*.spec.js', included: false, watched: true}, - - {pattern: '**/*.html', included: false, watched: true}, - // #enddocregion files - ], - - // #docregion html - // proxied base paths for loading assets - proxies: { - // required for component assets fetched by Angular's compiler - "/phone-detail": '/base/app/phone-detail', - "/phone-list": '/base/app/phone-list' - }, - // #enddocregion html - - autoWatch: true, - - frameworks: ['jasmine'], - - browsers: ['Chrome', 'Firefox'], - - plugins: [ - 'karma-chrome-launcher', - 'karma-firefox-launcher', - 'karma-jasmine' - ] - - }); -}; diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/systemjs.config.1.js b/public/docs/_examples/upgrade-phonecat-3-final/ts/systemjs.config.1.js deleted file mode 100644 index 3a455980bb..0000000000 --- a/public/docs/_examples/upgrade-phonecat-3-final/ts/systemjs.config.1.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * System configuration for Angular 2 samples - * Adjust as necessary for your application needs. - */ -(function(global) { - - // map tells the System loader where to look for things - // #docregion paths - var map = { - 'app': '/app', // 'dist', - - '@angular': '/node_modules/@angular', - 'angular2-in-memory-web-api': '/node_modules/angular2-in-memory-web-api', - 'rxjs': '/node_modules/rxjs' - }; - - var packages = { - '/app': { main: 'main.js', defaultExtension: 'js' }, - 'rxjs': { defaultExtension: 'js' }, - 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' }, - }; - // #enddocregion paths - - var ngPackageNames = [ - 'common', - 'compiler', - 'core', - 'http', - 'platform-browser', - 'platform-browser-dynamic', - 'router', - 'router-deprecated', - 'upgrade', - ]; - - // Individual files (~300 requests): - function packIndex(pkgName) { - packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; - } - - // Bundled (~40 requests): - function packUmd(pkgName) { - packages['@angular/'+pkgName] = { main: pkgName + '.umd.js', defaultExtension: 'js' }; - }; - - var setPackageConfig = System.packageWithIndex ? packIndex : packUmd; - - // Add package entries for angular packages - ngPackageNames.forEach(setPackageConfig); - - var config = { - map: map, - packages: packages - } - - System.config(config); - -})(this); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/README.md b/public/docs/_examples/upgrade-phonecat-3-router/README.md new file mode 100644 index 0000000000..4f8e4928af --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/README.md @@ -0,0 +1,34 @@ +This is the Angular Phonecat application adjusted to fit our boilerplate project +structure. + +The following changes from vanilla Phonecat are applied: + +* Karma config for unit tests is in karma.conf.ng1.js because the boilerplate + Karma config is not compatible with the way Angular 1 tests need to be run. + The shell script run-unit-tests.sh can be used to run the unit tests. +* There's a `package.ng1.json`, which is not used to run anything but only to + show an example of changing the PhoneCat http-server root path. +* Also for the Karma shim, there is a `karma-test-shim.1.js` file which isn't + used but is shown in the test appendix. +* Instead of using Bower, Angular 1 and its dependencies are fetched from a CDN + in index.html and karma.conf.ng1.js. +* E2E tests have been moved to the parent directory, where `run-e2e-tests` can + discover and run them along with all the other examples. +* Most of the phone JSON and image data removed in the interest of keeping + repo weight down. Keeping enough to retain testability of the app. + +## Running the app + +Start like any example + + npm run start + +## Running unit tests + + ./run-unit-tests.sh + +## Running E2E tests + +Like for any example (at the project root): + + gulp run-e2e-tests --filter=phonecat-2 diff --git a/public/docs/_examples/upgrade-phonecat-3-router/e2e-spec.ts b/public/docs/_examples/upgrade-phonecat-3-router/e2e-spec.ts new file mode 100644 index 0000000000..2ec8e37977 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/e2e-spec.ts @@ -0,0 +1,107 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; +import { setProtractorToHybridMode } from '../protractor-helpers'; + +// Angular E2E Testing Guide: +// https://docs.angularjs.org/guide/e2e-testing + +describe('PhoneCat Application', function() { + + beforeAll(function () { + setProtractorToHybridMode(); + }); + + it('should redirect `index.html` to `index.html#!/phones', function() { + browser.get('index.html'); + expect(browser.getLocationAbsUrl()).toBe('/phones'); + }); + + describe('View: Phone list', function() { + + beforeEach(function() { + browser.get('index.html#!/phones'); + }); + + it('should filter the phone list as a user types into the search box', function() { + let phoneList = element.all(by.css('.phones li')); + let query = element(by.css('input')); + + expect(phoneList.count()).toBe(20); + + query.sendKeys('nexus'); + expect(phoneList.count()).toBe(1); + + query.clear(); + query.sendKeys('motorola'); + expect(phoneList.count()).toBe(8); + }); + + it('should be possible to control phone order via the drop-down menu', function() { + let queryField = element(by.css('input')); + let orderSelect = element(by.css('select')); + let nameOption = orderSelect.element(by.css('option[value="name"]')); + let phoneNameColumn = element.all(by.css('.phones .name')); + + function getNames() { + return phoneNameColumn.map(function(elem) { + return elem.getText(); + }); + } + + queryField.sendKeys('tablet'); // Let's narrow the dataset to make the assertions shorter + + expect(getNames()).toEqual([ + 'Motorola XOOM\u2122 with Wi-Fi', + 'MOTOROLA XOOM\u2122' + ]); + + nameOption.click(); + + expect(getNames()).toEqual([ + 'MOTOROLA XOOM\u2122', + 'Motorola XOOM\u2122 with Wi-Fi' + ]); + }); + + it('should render phone specific links', function() { + let query = element(by.css('input')); + query.sendKeys('nexus'); + + element.all(by.css('.phones li a')).first().click(); + browser.sleep(200); // Not sure why this is needed but it is. The route change works fine. + expect(browser.getLocationAbsUrl()).toBe('/phones/nexus-s'); + }); + + }); + + describe('View: Phone detail', function() { + + beforeEach(function() { + browser.get('index.html#!/phones/nexus-s'); + }); + + it('should display the `nexus-s` page', function() { + expect(element(by.css('h1')).getText()).toBe('Nexus S'); + }); + + it('should display the first phone image as the main phone image', function() { + let mainImage = element(by.css('img.phone.selected')); + + expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/); + }); + + it('should swap the main image when clicking on a thumbnail image', function() { + let mainImage = element(by.css('img.phone.selected')); + let thumbnails = element.all(by.css('.phone-thumbs img')); + + thumbnails.get(2).click(); + expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.2.jpg/); + + thumbnails.get(0).click(); + expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/); + }); + + }); + +}); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/.gitignore b/public/docs/_examples/upgrade-phonecat-3-router/ts/.gitignore new file mode 100644 index 0000000000..7f5c313a3e --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/.gitignore @@ -0,0 +1,7 @@ +**/*.js +aot/**/* +!aot/bs-config.json +!aot/index.html +!copy-dist-files.js +!rollup-config.js +!systemjs.config.1.js diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/aot/bs-config.json b/public/docs/_examples/upgrade-phonecat-3-router/ts/aot/bs-config.json new file mode 100644 index 0000000000..7c85d6eddd --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/aot/bs-config.json @@ -0,0 +1,5 @@ +{ + "port": 8000, + "files": ["./aot/**/*.{html,htm,css,js}"], + "server": { "baseDir": "./aot" } +} diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/aot/index.html b/public/docs/_examples/upgrade-phonecat-3-router/ts/aot/index.html new file mode 100644 index 0000000000..0d6cf5946e --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/aot/index.html @@ -0,0 +1,38 @@ + + + + + + + + + Google Phone Gallery + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/ajs-upgraded-providers.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/ajs-upgraded-providers.ts new file mode 100644 index 0000000000..f6e1654d74 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/ajs-upgraded-providers.ts @@ -0,0 +1,14 @@ +// #docregion +export abstract class RouteParams { + [key: string]: string; +} + +export function routeParamsFactory(i: any) { + return i.get('$routeParams'); +} + +export const routeParamsProvider = { + provide: RouteParams, + useFactory: routeParamsFactory, + deps: ['$injector'] +}; diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app-routing.module.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app-routing.module.ts new file mode 100644 index 0000000000..0485b1848d --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app-routing.module.ts @@ -0,0 +1,30 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { Routes, RouterModule, UrlHandlingStrategy, UrlTree } from '@angular/router'; +import { APP_BASE_HREF, HashLocationStrategy, LocationStrategy } from '@angular/common'; + +import { PhoneListComponent } from './phone-list/phone-list.component'; + +export class Ng1Ng2UrlHandlingStrategy implements UrlHandlingStrategy { + shouldProcessUrl(url: UrlTree) { + return url.toString() === '/' || url.toString() === '/phones'; + } + extract(url: UrlTree) { return url; } + merge(url: UrlTree, whole: UrlTree) { return url; } +} + +const routes: Routes = [ + { path: '', redirectTo: 'phones', pathMatch: 'full' }, + { path: 'phones', component: PhoneListComponent } +]; + +@NgModule({ + imports: [ RouterModule.forRoot(routes) ], + exports: [ RouterModule ], + providers: [ + { provide: APP_BASE_HREF, useValue: '!' }, + { provide: LocationStrategy, useClass: HashLocationStrategy }, + { provide: UrlHandlingStrategy, useClass: Ng1Ng2UrlHandlingStrategy } + ] +}) +export class AppRoutingModule { } diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.animations.css b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.animations.css new file mode 100644 index 0000000000..175320b509 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.animations.css @@ -0,0 +1,67 @@ +/* Animate `ngRepeat` in `phoneList` component */ +.phone-list-item.ng-enter, +.phone-list-item.ng-leave, +.phone-list-item.ng-move { + overflow: hidden; + transition: 0.5s linear all; +} + +.phone-list-item.ng-enter, +.phone-list-item.ng-leave.ng-leave-active, +.phone-list-item.ng-move { + height: 0; + margin-bottom: 0; + opacity: 0; + padding-bottom: 0; + padding-top: 0; +} + +.phone-list-item.ng-enter.ng-enter-active, +.phone-list-item.ng-leave, +.phone-list-item.ng-move.ng-move-active { + height: 120px; + margin-bottom: 20px; + opacity: 1; + padding-bottom: 4px; + padding-top: 15px; +} + +/* Animate view transitions with `ngView` */ +.view-container { + position: relative; +} + +.view-frame { + margin-top: 20px; +} + +.view-frame.ng-enter, +.view-frame.ng-leave { + background: white; + left: 0; + position: absolute; + right: 0; + top: 0; +} + +.view-frame.ng-enter { + animation: 1s fade-in; + z-index: 100; +} + +.view-frame.ng-leave { + animation: 1s fade-out; + z-index: 99; +} + +@keyframes fade-in { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes fade-out { + from { opacity: 1; } + to { opacity: 0; } +} + +/* Older browsers might need vendor-prefixes for keyframes and animation! */ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.animations.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.animations.ts new file mode 100644 index 0000000000..f0739b6405 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.animations.ts @@ -0,0 +1,43 @@ +'use strict'; + +angular. + module('phonecatApp'). + animation('.phone', function phoneAnimationFactory() { + return { + addClass: animateIn, + removeClass: animateOut + }; + + function animateIn(element: JQuery, className: string, done: () => void) { + if (className !== 'selected') { return; } + + element.css({ + display: 'block', + position: 'absolute', + top: 500, + left: 0 + }).animate({ + top: 0 + }, done); + + return function animateInEnd(wasCanceled: boolean) { + if (wasCanceled) { element.stop(); } + }; + } + + function animateOut(element: JQuery, className: string, done: () => void) { + if (className !== 'selected') { return; } + + element.css({ + position: 'absolute', + top: 0, + left: 0 + }).animate({ + top: -500 + }, done); + + return function animateOutEnd(wasCanceled: boolean) { + if (wasCanceled) { element.stop(); } + }; + } + }); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.component.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.component.ts new file mode 100644 index 0000000000..6ecd19ab80 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.component.ts @@ -0,0 +1,13 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'phonecat-app', + template: ` + +
    +
    +
    + ` +}) +export class AppComponent { } diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.config.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.config.ts new file mode 100644 index 0000000000..51a5d82422 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.config.ts @@ -0,0 +1,16 @@ +'use strict'; + +angular. + module('phonecatApp'). + config(['$locationProvider', '$routeProvider', + function config($locationProvider: angular.ILocationProvider, + $routeProvider: angular.route.IRouteProvider) { + $locationProvider.hashPrefix('!'); + // #docregion ajs-routes + $routeProvider + .when('/phones/:phoneId', { + template: '' + }); + // #enddocregion ajs-routes + } + ]); diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.css b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.css similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/app.css rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.css diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.module.ajs.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.module.ajs.ts new file mode 100644 index 0000000000..e493137966 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.module.ajs.ts @@ -0,0 +1,11 @@ +// #docregion +'use strict'; + +// Define the `phonecatApp` Angular 1 module +angular.module('phonecatApp', [ + 'ngAnimate', + 'ngRoute', + 'core', + 'phoneDetail', + 'phoneList', +]); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.module.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.module.ts new file mode 100644 index 0000000000..e0bb64f4e4 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/app.module.ts @@ -0,0 +1,42 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule } from '@angular/upgrade/static'; +import { HttpModule } from '@angular/http'; +import { FormsModule } from '@angular/forms'; + +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { Phone } from './core/phone/phone.service'; +import { CheckmarkPipe } from './core/checkmark/checkmark.pipe'; +import { PhoneListComponent } from './phone-list/phone-list.component'; +import { PhoneDetailComponent } from './phone-detail/phone-detail.component'; +import { routeParamsProvider } from './ajs-upgraded-providers'; + +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule, + HttpModule, + FormsModule, + AppRoutingModule + ], + declarations: [ + AppComponent, + PhoneListComponent, + PhoneDetailComponent, + CheckmarkPipe + ], + entryComponents: [ + PhoneListComponent, + PhoneDetailComponent + ], + providers: [ + Phone, + routeParamsProvider + ], + // #docregion bootstrap + bootstrap: [ AppComponent ] +}) +export class AppModule { } +// #enddocregion bootstrap diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/checkmark/checkmark.pipe.spec.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/checkmark/checkmark.pipe.spec.ts new file mode 100644 index 0000000000..f7485ec2ba --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/checkmark/checkmark.pipe.spec.ts @@ -0,0 +1,11 @@ +// #docregion +import { CheckmarkPipe } from './checkmark.pipe'; + +describe('CheckmarkPipe', function() { + + it('should convert boolean values to unicode checkmark or cross', function () { + const checkmarkPipe = new CheckmarkPipe(); + expect(checkmarkPipe.transform(true)).toBe('\u2713'); + expect(checkmarkPipe.transform(false)).toBe('\u2718'); + }); +}); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/checkmark/checkmark.pipe.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/checkmark/checkmark.pipe.ts new file mode 100644 index 0000000000..888017e15c --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/checkmark/checkmark.pipe.ts @@ -0,0 +1,9 @@ +// #docregion +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({name: 'checkmark'}) +export class CheckmarkPipe implements PipeTransform { + transform(input: boolean) { + return input ? '\u2713' : '\u2718'; + } +} diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/core.module.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/core.module.ts new file mode 100644 index 0000000000..84a91dc7a6 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/core.module.ts @@ -0,0 +1,4 @@ +'use strict'; + +// Define the `core` module +angular.module('core', ['core.phone']); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/phone/phone.module.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/phone/phone.module.ts new file mode 100644 index 0000000000..0b6b348899 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/phone/phone.module.ts @@ -0,0 +1,4 @@ +'use strict'; + +// Define the `core.phone` module +angular.module('core.phone', ['ngResource']); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/phone/phone.service.spec.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/phone/phone.service.spec.ts new file mode 100644 index 0000000000..a0c1655c20 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/phone/phone.service.spec.ts @@ -0,0 +1,51 @@ +// #docregion +import { inject, TestBed } from '@angular/core/testing'; +import { + Http, + BaseRequestOptions, + ResponseOptions, + Response +} from '@angular/http'; +import { MockBackend, MockConnection } from '@angular/http/testing'; +import { Phone, PhoneData } from './phone.service'; + +describe('Phone', function() { + let phone: Phone; + let phonesData: PhoneData[] = [ + {name: 'Phone X', snippet: '', images: []}, + {name: 'Phone Y', snippet: '', images: []}, + {name: 'Phone Z', snippet: '', images: []} + ]; + let mockBackend: MockBackend; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + Phone, + MockBackend, + BaseRequestOptions, + { provide: Http, + useFactory: (backend: MockBackend, options: BaseRequestOptions) => new Http(backend, options), + deps: [MockBackend, BaseRequestOptions] + } + ] + }); + }); + + beforeEach(inject([MockBackend, Phone], (_mockBackend_: MockBackend, _phone_: Phone) => { + mockBackend = _mockBackend_; + phone = _phone_; + })); + + it('should fetch the phones data from `/phones/phones.json`', (done: () => void) => { + mockBackend.connections.subscribe((conn: MockConnection) => { + conn.mockRespond(new Response(new ResponseOptions({body: JSON.stringify(phonesData)}))); + }); + phone.query().subscribe(result => { + expect(result).toEqual(phonesData); + done(); + }); + }); + +}); + diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/phone/phone.service.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/phone/phone.service.ts new file mode 100644 index 0000000000..ccbd1fdd72 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/core/phone/phone.service.ts @@ -0,0 +1,32 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { Http, Response } from '@angular/http'; +import { Observable } from 'rxjs/Rx'; + +declare var angular: angular.IAngularStatic; +import { downgradeInjectable } from '@angular/upgrade/static'; + +import 'rxjs/add/operator/map'; + +export interface PhoneData { + name: string; + snippet: string; + images: string[]; +} + +@Injectable() +export class Phone { + constructor(private http: Http) { } + query(): Observable { + return this.http.get(`phones/phones.json`) + .map((res: Response) => res.json()); + } + get(id: string): Observable { + return this.http.get(`phones/${id}.json`) + .map((res: Response) => res.json()); + } +} + +angular.module('core.phone') + .factory('phone', downgradeInjectable(Phone)); + diff --git a/public/docs/_examples/homepage-hello-world/ts/systemjs.config.1.js b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/.gitkeep similarity index 100% rename from public/docs/_examples/homepage-hello-world/ts/systemjs.config.1.js rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/.gitkeep diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-streak-7.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-streak-7.0.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-streak-7.0.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-streak-7.0.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-streak-7.1.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-streak-7.1.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-streak-7.1.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-streak-7.1.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-streak-7.2.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-streak-7.2.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-streak-7.2.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-streak-7.2.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-streak-7.3.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-streak-7.3.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-streak-7.3.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-streak-7.3.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-streak-7.4.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-streak-7.4.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/dell-streak-7.4.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-streak-7.4.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-venue.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-venue.0.jpg new file mode 100644 index 0000000000..b4cb4eb25f Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/dell-venue.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/droid-2-global-by-motorola.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/droid-2-global-by-motorola.0.jpg new file mode 100644 index 0000000000..60700a2ab3 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/droid-2-global-by-motorola.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/droid-pro-by-motorola.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/droid-pro-by-motorola.0.jpg new file mode 100644 index 0000000000..c7710de986 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/droid-pro-by-motorola.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/lg-axis.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/lg-axis.0.jpg new file mode 100644 index 0000000000..55e5a23bb2 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/lg-axis.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-atrix-4g.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-atrix-4g.0.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-atrix-4g.0.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-atrix-4g.0.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-atrix-4g.1.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-atrix-4g.1.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-atrix-4g.1.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-atrix-4g.1.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-atrix-4g.2.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-atrix-4g.2.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-atrix-4g.2.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-atrix-4g.2.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-atrix-4g.3.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-atrix-4g.3.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-atrix-4g.3.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-atrix-4g.3.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg new file mode 100644 index 0000000000..e452ae7e7c Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg new file mode 100644 index 0000000000..21e4b8d741 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg new file mode 100644 index 0000000000..c7c5e3ba0c Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.0.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.0.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.0.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.1.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.1.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.1.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.1.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.2.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.2.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.2.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.2.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.3.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.3.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.3.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.3.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.4.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.4.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.4.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.4.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.5.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.5.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom-with-wi-fi.5.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom-with-wi-fi.5.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom.0.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom.0.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom.0.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom.1.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom.1.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom.1.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom.1.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom.2.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom.2.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/motorola-xoom.2.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/motorola-xoom.2.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/nexus-s.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/nexus-s.0.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/nexus-s.0.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/nexus-s.0.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/nexus-s.1.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/nexus-s.1.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/nexus-s.1.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/nexus-s.1.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/nexus-s.2.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/nexus-s.2.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/nexus-s.2.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/nexus-s.2.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/nexus-s.3.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/nexus-s.3.jpg similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/img/phones/nexus-s.3.jpg rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/nexus-s.3.jpg diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-galaxy-tab.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-galaxy-tab.0.jpg new file mode 100644 index 0000000000..3750377ad9 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-galaxy-tab.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-gem.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-gem.0.jpg new file mode 100644 index 0000000000..0d5024a026 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-gem.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg new file mode 100644 index 0000000000..11b8f860cb Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg new file mode 100644 index 0000000000..11b8f860cb Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-transform.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-transform.0.jpg new file mode 100644 index 0000000000..0e3107caf5 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/samsung-transform.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/sanyo-zio.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/sanyo-zio.0.jpg new file mode 100644 index 0000000000..9eeb9b96ed Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/sanyo-zio.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/t-mobile-g2.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/t-mobile-g2.0.jpg new file mode 100644 index 0000000000..6b6c09e058 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/t-mobile-g2.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg new file mode 100644 index 0000000000..beba1f6827 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/main-aot.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/main-aot.ts new file mode 100644 index 0000000000..23a741c684 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/main-aot.ts @@ -0,0 +1,10 @@ +// #docregion +import { platformBrowser } from '@angular/platform-browser'; +import { UpgradeModule } from '@angular/upgrade/static'; + +import { AppModuleNgFactory } from '../aot/app/app.module.ngfactory'; + +platformBrowser().bootstrapModuleFactory(AppModuleNgFactory).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.documentElement, ['phonecatApp']); +}); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/main.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/main.ts new file mode 100644 index 0000000000..51b8e4d2a8 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/main.ts @@ -0,0 +1,10 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { UpgradeModule } from '@angular/upgrade/static'; + +import { AppModule } from './app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => { + const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; + upgrade.bootstrap(document.documentElement, ['phonecatApp']); +}); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-detail/phone-detail.component.spec.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-detail/phone-detail.component.spec.ts new file mode 100644 index 0000000000..e3b9143a94 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-detail/phone-detail.component.spec.ts @@ -0,0 +1,59 @@ +// #docregion +// #docregion activatedroute +import { ActivatedRoute } from '@angular/router'; + +// #enddocregion activatedroute +import { Observable } from 'rxjs/Rx'; + +import { async, TestBed } from '@angular/core/testing'; + +import { PhoneDetailComponent } from './phone-detail.component'; +import { Phone, PhoneData } from '../core/phone/phone.service'; +import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe'; + +function xyzPhoneData(): PhoneData { + return { + name: 'phone xyz', + snippet: '', + images: ['image/url1.png', 'image/url2.png'] + }; +} + +class MockPhone { + get(id: string): Observable { + return Observable.of(xyzPhoneData()); + } +} + +// #docregion activatedroute + +class ActivatedRouteMock { + constructor(public snapshot: any) {} +} + +// #enddocregion activatedroute + +describe('PhoneDetailComponent', () => { + + // #docregion activatedroute + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CheckmarkPipe, PhoneDetailComponent ], + providers: [ + { provide: Phone, useClass: MockPhone }, + { provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) } + ] + }) + .compileComponents(); + })); + // #enddocregion activatedroute + + it('should fetch phone detail', () => { + const fixture = TestBed.createComponent(PhoneDetailComponent); + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name); + }); + +}); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-detail/phone-detail.component.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-detail/phone-detail.component.ts new file mode 100644 index 0000000000..32a3d40790 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-detail/phone-detail.component.ts @@ -0,0 +1,33 @@ +// #docplaster +// #docregion +declare var angular: angular.IAngularStatic; +import { downgradeComponent } from '@angular/upgrade/static'; +import { Component } from '@angular/core'; + +import { Phone, PhoneData } from '../core/phone/phone.service'; +import { RouteParams } from '../ajs-upgraded-providers'; + +@Component({ + templateUrl: 'phone-detail.template.html', +}) +export class PhoneDetailComponent { + phone: PhoneData; + mainImageUrl: string; + + constructor(routeParams: RouteParams, phone: Phone) { + phone.get(routeParams['phoneId']).subscribe(phone => { + this.phone = phone; + this.setImage(phone.images[0]); + }); + } + + setImage(imageUrl: string) { + this.mainImageUrl = imageUrl; + } +} + +angular.module('phoneDetail') + .directive( + 'phoneDetail', + downgradeComponent({component: PhoneDetailComponent}) as angular.IDirectiveFactory + ); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-detail/phone-detail.module.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-detail/phone-detail.module.ts new file mode 100644 index 0000000000..fd7cb3b920 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-detail/phone-detail.module.ts @@ -0,0 +1,7 @@ +'use strict'; + +// Define the `phoneDetail` module +angular.module('phoneDetail', [ + 'ngRoute', + 'core.phone' +]); diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.template.html b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-detail/phone-detail.template.html similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/phone-detail/phone-detail.template.html rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-detail/phone-detail.template.html diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.component.spec.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.component.spec.ts new file mode 100644 index 0000000000..2bb9d2b62f --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.component.spec.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +// #docregion +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { Observable } from 'rxjs/Rx'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { SpyLocation } from '@angular/common/testing'; + +import { PhoneListComponent } from './phone-list.component'; +import { Phone, PhoneData } from '../core/phone/phone.service'; + +class ActivatedRouteMock { + constructor(public snapshot: any) {} +} + +class MockPhone { + query(): Observable { + return Observable.of([ + {name: 'Nexus S', snippet: '', images: []}, + {name: 'Motorola DROID', snippet: '', images: []} + ]); + } +} + +let fixture: ComponentFixture; + +describe('PhoneList', () => { + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PhoneListComponent ], + providers: [ + { provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) }, + { provide: Location, useClass: SpyLocation }, + { provide: Phone, useClass: MockPhone }, + ], + schemas: [ NO_ERRORS_SCHEMA ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PhoneListComponent); + }); + + it('should create "phones" model with 2 phones fetched from xhr', () => { + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2); + expect( + compiled.querySelector('.phone-list-item:nth-child(1)').textContent + ).toContain('Motorola DROID'); + expect( + compiled.querySelector('.phone-list-item:nth-child(2)').textContent + ).toContain('Nexus S'); + }); + + xit('should set the default value of orderProp model', () => { + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect( + compiled.querySelector('select option:last-child').selected + ).toBe(true); + }); + +}); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.component.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.component.ts new file mode 100644 index 0000000000..40f522bec8 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.component.ts @@ -0,0 +1,60 @@ +// #docregion +declare var angular: angular.IAngularStatic; +import { downgradeComponent } from '@angular/upgrade/static'; + +import { Component } from '@angular/core'; +import { Phone, PhoneData } from '../core/phone/phone.service'; + +@Component({ + templateUrl: 'phone-list.template.html' +}) +export class PhoneListComponent { + phones: PhoneData[]; + query: string; + orderProp: string; + + constructor(phone: Phone) { + phone.query().subscribe(phones => { + this.phones = phones; + }); + this.orderProp = 'age'; + } + + getPhones(): PhoneData[] { + return this.sortPhones(this.filterPhones(this.phones)); + } + + private filterPhones(phones: PhoneData[]) { + if (phones && this.query) { + return phones.filter(phone => { + let name = phone.name.toLowerCase(); + let snippet = phone.snippet.toLowerCase(); + return name.indexOf(this.query) >= 0 || snippet.indexOf(this.query) >= 0; + }); + } + return phones; + } + + private sortPhones(phones: PhoneData[]) { + if (phones && this.orderProp) { + return phones + .slice(0) // Make a copy + .sort((a, b) => { + if (a[this.orderProp] < b[this.orderProp]) { + return -1; + } else if ([b[this.orderProp] < a[this.orderProp]]) { + return 1; + } else { + return 0; + } + }); + } + return phones; + } +} + +angular.module('phoneList') + .directive( + 'phoneList', + downgradeComponent({component: PhoneListComponent}) as angular.IDirectiveFactory + ); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.module.ts b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.module.ts new file mode 100644 index 0000000000..8ade7c5b88 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.module.ts @@ -0,0 +1,4 @@ +'use strict'; + +// Define the `phoneList` module +angular.module('phoneList', ['core.phone']); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.template.html b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.template.html new file mode 100644 index 0000000000..2678d384c2 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phone-list/phone-list.template.html @@ -0,0 +1,38 @@ +
    +
    +
    + + +

    + Search: + +

    + +

    + Sort by: + +

    + +
    +
    + + + + + + +
    +
    +
    diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/dell-streak-7.json b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/dell-streak-7.json similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/dell-streak-7.json rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/dell-streak-7.json diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/motorola-atrix-4g.json b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/motorola-atrix-4g.json similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/motorola-atrix-4g.json rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/motorola-atrix-4g.json diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/motorola-xoom-with-wi-fi.json b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/motorola-xoom-with-wi-fi.json similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/motorola-xoom-with-wi-fi.json rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/motorola-xoom-with-wi-fi.json diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/motorola-xoom.json b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/motorola-xoom.json similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/motorola-xoom.json rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/motorola-xoom.json diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/nexus-s.json b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/nexus-s.json similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/nexus-s.json rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/nexus-s.json diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/phones.json b/public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/phones.json similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/app/phones/phones.json rename to public/docs/_examples/upgrade-phonecat-3-router/ts/app/phones/phones.json diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/bs-config.aot.json b/public/docs/_examples/upgrade-phonecat-3-router/ts/bs-config.aot.json new file mode 100644 index 0000000000..e59a7403a0 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/bs-config.aot.json @@ -0,0 +1,14 @@ +{ + "open": false, + "logLevel": "silent", + "port": 8080, + "server": { + "baseDir": "aot", + "routes": { + "/node_modules": "node_modules" + }, + "middleware": { + "0": null + } + } +} diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/copy-dist-files.js b/public/docs/_examples/upgrade-phonecat-3-router/ts/copy-dist-files.js new file mode 100644 index 0000000000..a857af085c --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/copy-dist-files.js @@ -0,0 +1,25 @@ +// #docregion +var fsExtra = require('fs-extra'); +var resources = [ + // polyfills + 'node_modules/core-js/client/shim.min.js', + 'node_modules/zone.js/dist/zone.min.js', + // css + 'app/app.css', + 'app/app.animations.css', + // images and json files + 'app/img/', + 'app/phones/', + // app files + 'app/app.module.ajs.js', + 'app/app.config.js', + 'app/app.animations.js', + 'app/core/core.module.js', + 'app/core/phone/phone.module.js', + 'app/phone-list/phone-list.module.js', + 'app/phone-detail/phone-detail.module.js' +]; +resources.map(function(sourcePath) { + var destPath = `aot/${sourcePath}`; + fsExtra.copySync(sourcePath, destPath); +}); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/example-config.json b/public/docs/_examples/upgrade-phonecat-3-router/ts/example-config.json new file mode 100644 index 0000000000..401c14f835 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/example-config.json @@ -0,0 +1,5 @@ +{ + "build": "build:upgrade", + "run": "serve:upgrade", + "unittesting": true +} diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/index.html b/public/docs/_examples/upgrade-phonecat-3-router/ts/index.html new file mode 100644 index 0000000000..572c80d315 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/index.html @@ -0,0 +1,44 @@ + + + + + + + + + Google Phone Gallery + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/rollup-config.js b/public/docs/_examples/upgrade-phonecat-3-router/ts/rollup-config.js new file mode 100644 index 0000000000..aeb227689c --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/rollup-config.js @@ -0,0 +1,21 @@ +// #docregion +import rollup from 'rollup' +import nodeResolve from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs'; +import uglify from 'rollup-plugin-uglify' + +//paths are relative to the execution path +export default { + entry: 'app/main-aot.js', + dest: 'aot/dist/build.js', // output a single application bundle + sourceMap: true, + sourceMapFile: 'aot/dist/build.js.map', + format: 'iife', + plugins: [ + nodeResolve({jsnext: true, module: true}), + commonjs({ + include: ['node_modules/rxjs/**'] + }), + uglify() + ] +} diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/systemjs.config.1.js b/public/docs/_examples/upgrade-phonecat-3-router/ts/systemjs.config.1.js new file mode 100644 index 0000000000..b801d42bad --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/systemjs.config.1.js @@ -0,0 +1,48 @@ +/** + * System configuration for Angular samples + * Adjust as necessary for your application needs. + */ +(function (global) { + // #docregion paths + System.config({ + paths: { + // paths serve as alias + 'npm:': '/node_modules/' + }, + map: { + app: '/app', + // #enddocregion paths + // angular bundles + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js', + '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js', + + // other libraries + 'rxjs': 'npm:rxjs', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api', + // #docregion paths + }, + // #enddocregion paths + // packages tells the System loader how to load when no filename and/or no extension + packages: { + 'app': { + main: './main.js', + defaultExtension: 'js' + }, + rxjs: { + defaultExtension: 'js' + }, + 'angular-in-memory-web-api': { + main: './index.js', + defaultExtension: 'js' + } + } + }); +})(this); diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/tsconfig-aot.json b/public/docs/_examples/upgrade-phonecat-3-router/ts/tsconfig-aot.json new file mode 100644 index 0000000000..58f9de3309 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/tsconfig-aot.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "es2015", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es2015", "dom"], + "removeComments": false, + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "../../node_modules/@types/" + ] + }, + + "files": [ + "app/app.module.ts", + "app/main-aot.ts" + ], + + "angularCompilerOptions": { + "genDir": "aot", + "skipMetadataEmit" : true + } +} diff --git a/public/docs/_examples/upgrade-phonecat-3-router/ts/tsconfig.json b/public/docs/_examples/upgrade-phonecat-3-router/ts/tsconfig.json new file mode 100644 index 0000000000..f267800f14 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-3-router/ts/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ "es2015", "dom" ], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "../../node_modules/@types/" + ] + }, + "compileOnSave": true, + "exclude": [ + "node_modules/*", + "**/*-aot.ts" + ] +} diff --git a/public/docs/_examples/upgrade-phonecat-3-final/README.md b/public/docs/_examples/upgrade-phonecat-4-final/README.md similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/README.md rename to public/docs/_examples/upgrade-phonecat-4-final/README.md diff --git a/public/docs/_examples/upgrade-phonecat-4-final/e2e-spec.ts b/public/docs/_examples/upgrade-phonecat-4-final/e2e-spec.ts new file mode 100644 index 0000000000..6f47c54d02 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/e2e-spec.ts @@ -0,0 +1,109 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + +// Angular E2E Testing Guide: +// https://docs.angularjs.org/guide/e2e-testing + +describe('PhoneCat Application', function() { + + // #docregion redirect + it('should redirect `index.html` to `index.html#!/phones', function() { + browser.get('index.html'); + browser.waitForAngular(); + browser.getCurrentUrl().then(function(url: string) { + expect(url.endsWith('/phones')).toBe(true); + }); + }); + // #enddocregion redirect + + describe('View: Phone list', function() { + + beforeEach(function() { + browser.get('index.html#!/phones'); + }); + + it('should filter the phone list as a user types into the search box', function() { + let phoneList = element.all(by.css('.phones li')); + let query = element(by.css('input')); + + expect(phoneList.count()).toBe(20); + + query.sendKeys('nexus'); + expect(phoneList.count()).toBe(1); + + query.clear(); + query.sendKeys('motorola'); + expect(phoneList.count()).toBe(8); + }); + + it('should be possible to control phone order via the drop-down menu', function() { + let queryField = element(by.css('input')); + let orderSelect = element(by.css('select')); + let nameOption = orderSelect.element(by.css('option[value="name"]')); + let phoneNameColumn = element.all(by.css('.phones .name')); + + function getNames() { + return phoneNameColumn.map(function(elem) { + return elem.getText(); + }); + } + + queryField.sendKeys('tablet'); // Let's narrow the dataset to make the assertions shorter + + expect(getNames()).toEqual([ + 'Motorola XOOM\u2122 with Wi-Fi', + 'MOTOROLA XOOM\u2122' + ]); + + nameOption.click(); + + expect(getNames()).toEqual([ + 'MOTOROLA XOOM\u2122', + 'Motorola XOOM\u2122 with Wi-Fi' + ]); + }); + + // #docregion links + it('should render phone specific links', function() { + let query = element(by.css('input')); + query.sendKeys('nexus'); + element.all(by.css('.phones li a')).first().click(); + browser.getCurrentUrl().then(function(url: string) { + expect(url.endsWith('/phones/nexus-s')).toBe(true); + }); + }); + // #enddocregion links + + }); + + describe('View: Phone detail', function() { + + beforeEach(function() { + browser.get('index.html#!/phones/nexus-s'); + }); + + it('should display the `nexus-s` page', function() { + expect(element(by.css('h1')).getText()).toBe('Nexus S'); + }); + + it('should display the first phone image as the main phone image', function() { + let mainImage = element(by.css('img.phone.selected')); + + expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/); + }); + + it('should swap the main image when clicking on a thumbnail image', function() { + let mainImage = element(by.css('img.phone.selected')); + let thumbnails = element.all(by.css('.phone-thumbs img')); + + thumbnails.get(2).click(); + expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.2.jpg/); + + thumbnails.get(0).click(); + expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/); + }); + + }); + +}); diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app-routing.module.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app-routing.module.ts new file mode 100644 index 0000000000..f64d82e253 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app-routing.module.ts @@ -0,0 +1,23 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { APP_BASE_HREF, HashLocationStrategy, LocationStrategy } from '@angular/common'; + +import { PhoneDetailComponent } from './phone-detail/phone-detail.component'; +import { PhoneListComponent } from './phone-list/phone-list.component'; + +const routes: Routes = [ + { path: '', redirectTo: 'phones', pathMatch: 'full' }, + { path: 'phones', component: PhoneListComponent }, + { path: 'phones/:phoneId', component: PhoneDetailComponent } +]; + +@NgModule({ + imports: [ RouterModule.forRoot(routes) ], + exports: [ RouterModule ], + providers: [ + { provide: APP_BASE_HREF, useValue: '!' }, + { provide: LocationStrategy, useClass: HashLocationStrategy }, + ] +}) +export class AppRoutingModule { } diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app.component.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app.component.ts new file mode 100644 index 0000000000..c476614121 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app.component.ts @@ -0,0 +1,8 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'phonecat-app', + template: '' +}) +export class AppComponent { } diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app.css b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app.css new file mode 100644 index 0000000000..f4b45b02a5 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app.css @@ -0,0 +1,93 @@ +body { + padding: 20px; +} + +h1 { + border-bottom: 1px solid gray; + margin-top: 0; +} + +/* View: Phone list */ +.phones { + list-style: none; +} + +.phones li { + clear: both; + height: 115px; + padding-top: 15px; +} + +.thumb { + float: left; + height: 100px; + margin: -0.5em 1em 1.5em 0; + padding-bottom: 1em; + width: 100px; +} + +/* View: Phone detail */ +.phone { + background-color: white; + display: none; + float: left; + height: 400px; + margin-bottom: 2em; + margin-right: 3em; + padding: 2em; + width: 400px; +} + +.phone:first-child { + display: block; +} + +.phone-images { + background-color: white; + float: left; + height: 450px; + overflow: hidden; + position: relative; + width: 450px; +} + +.phone-thumbs { + list-style: none; + margin: 0; +} + +.phone-thumbs img { + height: 100px; + padding: 1em; + width: 100px; +} + +.phone-thumbs li { + background-color: white; + border: 1px solid black; + cursor: pointer; + display: inline-block; + margin: 1em; +} + +.specs { + clear: both; + list-style: none; + margin: 0; + padding: 0; +} + +.specs dt { + font-weight: bold; +} + +.specs > li { + display: inline-block; + vertical-align: top; + width: 200px; +} + +.specs > li > span { + font-size: 1.2em; + font-weight: bold; +} diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app.module.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app.module.ts new file mode 100644 index 0000000000..607ecab8c9 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/app.module.ts @@ -0,0 +1,34 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { CheckmarkPipe } from './core/checkmark/checkmark.pipe'; +import { Phone } from './core/phone/phone.service'; +import { PhoneDetailComponent } from './phone-detail/phone-detail.component'; +import { PhoneListComponent } from './phone-list/phone-list.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HttpModule, + AppRoutingModule + ], + declarations: [ + AppComponent, + PhoneListComponent, + CheckmarkPipe, + PhoneDetailComponent + ], + providers: [ + Phone + ], + // #docregion bootstrap + bootstrap: [ AppComponent ] + // #enddocregion bootstrap +}) +export class AppModule {} diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/checkmark/checkmark.pipe.spec.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/checkmark/checkmark.pipe.spec.ts new file mode 100644 index 0000000000..75150500a6 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/checkmark/checkmark.pipe.spec.ts @@ -0,0 +1,10 @@ +import { CheckmarkPipe } from './checkmark.pipe'; + +describe('CheckmarkPipe', function() { + + it('should convert boolean values to unicode checkmark or cross', function () { + const checkmarkPipe = new CheckmarkPipe(); + expect(checkmarkPipe.transform(true)).toBe('\u2713'); + expect(checkmarkPipe.transform(false)).toBe('\u2718'); + }); +}); diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/checkmark/checkmark.pipe.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/checkmark/checkmark.pipe.ts new file mode 100644 index 0000000000..888017e15c --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/checkmark/checkmark.pipe.ts @@ -0,0 +1,9 @@ +// #docregion +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({name: 'checkmark'}) +export class CheckmarkPipe implements PipeTransform { + transform(input: boolean) { + return input ? '\u2713' : '\u2718'; + } +} diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/phone/phone.service.spec.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/phone/phone.service.spec.ts new file mode 100644 index 0000000000..e3a422965b --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/phone/phone.service.spec.ts @@ -0,0 +1,49 @@ +import { inject, TestBed } from '@angular/core/testing'; +import { + Http, + BaseRequestOptions, + ResponseOptions, + Response +} from '@angular/http'; +import { MockBackend, MockConnection } from '@angular/http/testing'; +import { Phone, PhoneData } from './phone.service'; + +describe('Phone', function() { + let phone: Phone; + let phonesData: PhoneData[] = [ + {name: 'Phone X', snippet: '', images: []}, + {name: 'Phone Y', snippet: '', images: []}, + {name: 'Phone Z', snippet: '', images: []} + ]; + let mockBackend: MockBackend; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + Phone, + MockBackend, + BaseRequestOptions, + { provide: Http, + useFactory: (backend: MockBackend, options: BaseRequestOptions) => new Http(backend, options), + deps: [MockBackend, BaseRequestOptions] + } + ] + }); + }); + + beforeEach(inject([MockBackend, Phone], (_mockBackend_: MockBackend, _phone_: Phone) => { + mockBackend = _mockBackend_; + phone = _phone_; + })); + + it('should fetch the phones data from `/phones/phones.json`', (done: () => void) => { + mockBackend.connections.subscribe((conn: MockConnection) => { + conn.mockRespond(new Response(new ResponseOptions({body: JSON.stringify(phonesData)}))); + }); + phone.query().subscribe(result => { + expect(result).toEqual(phonesData); + done(); + }); + }); + +}); diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/phone/phone.service.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/phone/phone.service.ts new file mode 100644 index 0000000000..83a837afb7 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/core/phone/phone.service.ts @@ -0,0 +1,25 @@ +// #docregion +import { Injectable } from '@angular/core'; +import { Http, Response } from '@angular/http'; +import { Observable } from 'rxjs/Rx'; + +import 'rxjs/add/operator/map'; + +export interface PhoneData { + name: string; + snippet: string; + images: string[]; +} + +@Injectable() +export class Phone { + constructor(private http: Http) { } + query(): Observable { + return this.http.get(`phones/phones.json`) + .map((res: Response) => res.json()); + } + get(id: string): Observable { + return this.http.get(`phones/${id}.json`) + .map((res: Response) => res.json()); + } +} diff --git a/public/docs/_examples/homepage-tabs/ts/systemjs.config.1.js b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/.gitkeep similarity index 100% rename from public/docs/_examples/homepage-tabs/ts/systemjs.config.1.js rename to public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/.gitkeep diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.0.jpg new file mode 100644 index 0000000000..7ce0dce4ee Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.1.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.1.jpg new file mode 100644 index 0000000000..ed8cad89fb Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.1.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.2.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.2.jpg new file mode 100644 index 0000000000..c83529e0f9 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.2.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.3.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.3.jpg new file mode 100644 index 0000000000..cd2c30280d Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.3.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.4.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.4.jpg new file mode 100644 index 0000000000..b4d8472da8 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-streak-7.4.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-venue.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-venue.0.jpg new file mode 100644 index 0000000000..b4cb4eb25f Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/dell-venue.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/droid-2-global-by-motorola.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/droid-2-global-by-motorola.0.jpg new file mode 100644 index 0000000000..60700a2ab3 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/droid-2-global-by-motorola.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/droid-pro-by-motorola.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/droid-pro-by-motorola.0.jpg new file mode 100644 index 0000000000..c7710de986 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/droid-pro-by-motorola.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/lg-axis.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/lg-axis.0.jpg new file mode 100644 index 0000000000..55e5a23bb2 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/lg-axis.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.0.jpg new file mode 100644 index 0000000000..2446159e93 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.1.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.1.jpg new file mode 100644 index 0000000000..867f207459 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.1.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.2.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.2.jpg new file mode 100644 index 0000000000..27d78338c4 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.2.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.3.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.3.jpg new file mode 100644 index 0000000000..29459a68a4 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-atrix-4g.3.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg new file mode 100644 index 0000000000..e452ae7e7c Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-bravo-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg new file mode 100644 index 0000000000..21e4b8d741 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-charm-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg new file mode 100644 index 0000000000..c7c5e3ba0c Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-defy-with-motoblur.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.0.jpg new file mode 100644 index 0000000000..a6c993291e Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.1.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.1.jpg new file mode 100644 index 0000000000..400b89e2df Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.1.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.2.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.2.jpg new file mode 100644 index 0000000000..86b55d28dd Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.2.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.3.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.3.jpg new file mode 100644 index 0000000000..85ec293ae5 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.3.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.4.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.4.jpg new file mode 100644 index 0000000000..75ef1464cb Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.4.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.5.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.5.jpg new file mode 100644 index 0000000000..4d42db4330 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom-with-wi-fi.5.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom.0.jpg new file mode 100644 index 0000000000..bf6954bbd5 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom.1.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom.1.jpg new file mode 100644 index 0000000000..659688a47d Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom.1.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom.2.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom.2.jpg new file mode 100644 index 0000000000..ce0ff1002e Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/motorola-xoom.2.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.0.jpg new file mode 100644 index 0000000000..0952bc79c2 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.1.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.1.jpg new file mode 100644 index 0000000000..f33004dd7f Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.1.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.2.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.2.jpg new file mode 100644 index 0000000000..c5c63621f1 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.2.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.3.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.3.jpg new file mode 100644 index 0000000000..e51f75b0ed Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/nexus-s.3.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-galaxy-tab.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-galaxy-tab.0.jpg new file mode 100644 index 0000000000..3750377ad9 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-galaxy-tab.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-gem.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-gem.0.jpg new file mode 100644 index 0000000000..0d5024a026 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-gem.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg new file mode 100644 index 0000000000..11b8f860cb Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg new file mode 100644 index 0000000000..11b8f860cb Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-transform.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-transform.0.jpg new file mode 100644 index 0000000000..0e3107caf5 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/samsung-transform.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/sanyo-zio.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/sanyo-zio.0.jpg new file mode 100644 index 0000000000..9eeb9b96ed Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/sanyo-zio.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/t-mobile-g2.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/t-mobile-g2.0.jpg new file mode 100644 index 0000000000..6b6c09e058 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/t-mobile-g2.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg new file mode 100644 index 0000000000..beba1f6827 Binary files /dev/null and b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/img/phones/t-mobile-mytouch-4g.0.jpg differ diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/main.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/main.ts new file mode 100644 index 0000000000..08be7a99ba --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/main.ts @@ -0,0 +1,10 @@ +// #docregion +// #docregion imports +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app.module'; +// #enddocregion imports + +// #docregion bootstrap +platformBrowserDynamic().bootstrapModule(AppModule); +// #enddocregion bootstrap diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-detail/phone-detail.component.spec.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-detail/phone-detail.component.spec.ts new file mode 100644 index 0000000000..e3b9143a94 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-detail/phone-detail.component.spec.ts @@ -0,0 +1,59 @@ +// #docregion +// #docregion activatedroute +import { ActivatedRoute } from '@angular/router'; + +// #enddocregion activatedroute +import { Observable } from 'rxjs/Rx'; + +import { async, TestBed } from '@angular/core/testing'; + +import { PhoneDetailComponent } from './phone-detail.component'; +import { Phone, PhoneData } from '../core/phone/phone.service'; +import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe'; + +function xyzPhoneData(): PhoneData { + return { + name: 'phone xyz', + snippet: '', + images: ['image/url1.png', 'image/url2.png'] + }; +} + +class MockPhone { + get(id: string): Observable { + return Observable.of(xyzPhoneData()); + } +} + +// #docregion activatedroute + +class ActivatedRouteMock { + constructor(public snapshot: any) {} +} + +// #enddocregion activatedroute + +describe('PhoneDetailComponent', () => { + + // #docregion activatedroute + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CheckmarkPipe, PhoneDetailComponent ], + providers: [ + { provide: Phone, useClass: MockPhone }, + { provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) } + ] + }) + .compileComponents(); + })); + // #enddocregion activatedroute + + it('should fetch phone detail', () => { + const fixture = TestBed.createComponent(PhoneDetailComponent); + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name); + }); + +}); diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-detail/phone-detail.component.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-detail/phone-detail.component.ts new file mode 100644 index 0000000000..dd47f746f6 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-detail/phone-detail.component.ts @@ -0,0 +1,27 @@ +// #docplaster +// #docregion +import { Component } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; + +import { Phone, PhoneData } from '../core/phone/phone.service'; + +@Component({ + selector: 'phone-detail', + templateUrl: './phone-detail.template.html' +}) +export class PhoneDetailComponent { + phone: PhoneData; + mainImageUrl: string; + + constructor(activatedRoute: ActivatedRoute, phone: Phone) { + phone.get(activatedRoute.snapshot.params['phoneId']) + .subscribe((p: PhoneData) => { + this.phone = p; + this.setImage(p.images[0]); + }); + } + + setImage(imageUrl: string) { + this.mainImageUrl = imageUrl; + } +} diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-detail/phone-detail.template.html b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-detail/phone-detail.template.html new file mode 100644 index 0000000000..46a96d66c3 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-detail/phone-detail.template.html @@ -0,0 +1,120 @@ + +
    +
    + +
    + +

    {{phone.name}}

    + +

    {{phone.description}}

    + +
      +
    • + +
    • +
    + +
      +
    • + Availability and Networks +
      +
      Availability
      +
      {{availability}}
      +
      +
    • +
    • + Battery +
      +
      Type
      +
      {{phone.battery?.type}}
      +
      Talk Time
      +
      {{phone.battery?.talkTime}}
      +
      Standby time (max)
      +
      {{phone.battery?.standbyTime}}
      +
      +
    • +
    • + Storage and Memory +
      +
      RAM
      +
      {{phone.storage?.ram}}
      +
      Internal Storage
      +
      {{phone.storage?.flash}}
      +
      +
    • +
    • + Connectivity +
      +
      Network Support
      +
      {{phone.connectivity?.cell}}
      +
      WiFi
      +
      {{phone.connectivity?.wifi}}
      +
      Bluetooth
      +
      {{phone.connectivity?.bluetooth}}
      +
      Infrared
      +
      {{phone.connectivity?.infrared | checkmark}}
      +
      GPS
      +
      {{phone.connectivity?.gps | checkmark}}
      +
      +
    • +
    • + Android +
      +
      OS Version
      +
      {{phone.android?.os}}
      +
      UI
      +
      {{phone.android?.ui}}
      +
      +
    • +
    • + Size and Weight +
      +
      Dimensions
      +
      {{dim}}
      +
      Weight
      +
      {{phone.sizeAndWeight?.weight}}
      +
      +
    • +
    • + Display +
      +
      Screen size
      +
      {{phone.display?.screenSize}}
      +
      Screen resolution
      +
      {{phone.display?.screenResolution}}
      +
      Touch screen
      +
      {{phone.display?.touchScreen | checkmark}}
      +
      +
    • +
    • + Hardware +
      +
      CPU
      +
      {{phone.hardware?.cpu}}
      +
      USB
      +
      {{phone.hardware?.usb}}
      +
      Audio / headphone jack
      +
      {{phone.hardware?.audioJack}}
      +
      FM Radio
      +
      {{phone.hardware?.fmRadio | checkmark}}
      +
      Accelerometer
      +
      {{phone.hardware?.accelerometer | checkmark}}
      +
      +
    • +
    • + Camera +
      +
      Primary
      +
      {{phone.camera?.primary}}
      +
      Features
      +
      {{phone.camera?.features?.join(', ')}}
      +
      +
    • +
    • + Additional Features +
      {{phone.additionalFeatures}}
      +
    • +
    +
    diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-list/phone-list.component.spec.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-list/phone-list.component.spec.ts new file mode 100644 index 0000000000..834c93df8f --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-list/phone-list.component.spec.ts @@ -0,0 +1,71 @@ +/* tslint:disable */ +// #docregion routestuff +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { Observable } from 'rxjs/Rx'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { SpyLocation } from '@angular/common/testing'; + +import { PhoneListComponent } from './phone-list.component'; +import { Phone, PhoneData } from '../core/phone/phone.service'; + +// #enddocregion routestuff + +class ActivatedRouteMock { + constructor(public snapshot: any) {} +} + +class MockPhone { + query(): Observable { + return Observable.of([ + {name: 'Nexus S', snippet: '', images: []}, + {name: 'Motorola DROID', snippet: '', images: []} + ]); + } +} + +let fixture: ComponentFixture; + +describe('PhoneList', () => { + + // #docregion routestuff + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PhoneListComponent ], + providers: [ + { provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) }, + { provide: Location, useClass: SpyLocation }, + { provide: Phone, useClass: MockPhone }, + ], + schemas: [ NO_ERRORS_SCHEMA ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PhoneListComponent); + }); + // #enddocregion routestuff + + it('should create "phones" model with 2 phones fetched from xhr', () => { + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2); + expect( + compiled.querySelector('.phone-list-item:nth-child(1)').textContent + ).toContain('Motorola DROID'); + expect( + compiled.querySelector('.phone-list-item:nth-child(2)').textContent + ).toContain('Nexus S'); + }); + + xit('should set the default value of orderProp model', () => { + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect( + compiled.querySelector('select option:last-child').selected + ).toBe(true); + }); + +}); diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-list/phone-list.component.ts b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-list/phone-list.component.ts new file mode 100644 index 0000000000..6cfd172027 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-list/phone-list.component.ts @@ -0,0 +1,53 @@ +// #docregion +import { Component } from '@angular/core'; + +import { Phone, PhoneData } from '../core/phone/phone.service'; + +@Component({ + selector: 'phone-list', + templateUrl: './phone-list.template.html', +}) +export class PhoneListComponent { + phones: PhoneData[]; + query: string; + orderProp: string; + + constructor(phone: Phone) { + phone.query().subscribe(phones => { + this.phones = phones; + }); + this.orderProp = 'age'; + } + + getPhones(): PhoneData[] { + return this.sortPhones(this.filterPhones(this.phones)); + } + + private filterPhones(phones: PhoneData[]) { + if (phones && this.query) { + return phones.filter(phone => { + let name = phone.name.toLowerCase(); + let snippet = phone.snippet.toLowerCase(); + return name.indexOf(this.query) >= 0 || snippet.indexOf(this.query) >= 0; + }); + } + return phones; + } + + private sortPhones(phones: PhoneData[]) { + if (phones && this.orderProp) { + return phones + .slice(0) // Make a copy + .sort((a, b) => { + if (a[this.orderProp] < b[this.orderProp]) { + return -1; + } else if ([b[this.orderProp] < a[this.orderProp]]) { + return 1; + } else { + return 0; + } + }); + } + return phones; + } +} diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-list/phone-list.template.html b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-list/phone-list.template.html new file mode 100644 index 0000000000..b4a994b297 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phone-list/phone-list.template.html @@ -0,0 +1,40 @@ +
    +
    +
    + + + +

    + Search: + +

    + +

    + Sort by: + +

    + + +
    +
    + + + + + + +
    +
    +
    diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/dell-streak-7.json b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/dell-streak-7.json new file mode 100644 index 0000000000..a32eb6ff98 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/dell-streak-7.json @@ -0,0 +1,64 @@ +{ + "additionalFeatures": "Front Facing 1.3MP Camera", + "android": { + "os": "Android 2.2", + "ui": "Dell Stage" + }, + "availability": [ + "T-Mobile" + ], + "battery": { + "standbyTime": "", + "talkTime": "", + "type": "Lithium Ion (Li-Ion) (2780 mAH)" + }, + "camera": { + "features": [ + "Flash", + "Video" + ], + "primary": "5.0 megapixels" + }, + "connectivity": { + "bluetooth": "Bluetooth 2.1", + "cell": "T-mobile HSPA+ @ 2100/1900/AWS/850 MHz", + "gps": true, + "infrared": false, + "wifi": "802.11 b/g" + }, + "description": "Introducing Dell\u2122 Streak 7. Share photos, videos and movies together. It\u2019s small enough to carry around, big enough to gather around. Android\u2122 2.2-based tablet with over-the-air upgrade capability for future OS releases. A vibrant 7-inch, multitouch display with full Adobe\u00ae Flash 10.1 pre-installed. Includes a 1.3 MP front-facing camera for face-to-face chats on popular services such as Qik or Skype. 16 GB of internal storage, plus Wi-Fi, Bluetooth and built-in GPS keeps you in touch with the world around you. Connect on your terms. Save with 2-year contract or flexibility with prepaid pay-as-you-go plans", + "display": { + "screenResolution": "WVGA (800 x 480)", + "screenSize": "7.0 inches", + "touchScreen": true + }, + "hardware": { + "accelerometer": true, + "audioJack": "3.5mm", + "cpu": "nVidia Tegra T20", + "fmRadio": false, + "physicalKeyboard": false, + "usb": "USB 2.0" + }, + "id": "dell-streak-7", + "images": [ + "img/phones/dell-streak-7.0.jpg", + "img/phones/dell-streak-7.1.jpg", + "img/phones/dell-streak-7.2.jpg", + "img/phones/dell-streak-7.3.jpg", + "img/phones/dell-streak-7.4.jpg" + ], + "name": "Dell Streak 7", + "sizeAndWeight": { + "dimensions": [ + "199.9 mm (w)", + "119.8 mm (h)", + "12.4 mm (d)" + ], + "weight": "450.0 grams" + }, + "storage": { + "flash": "16000MB", + "ram": "512MB" + } +} diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/motorola-atrix-4g.json b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/motorola-atrix-4g.json new file mode 100644 index 0000000000..ccca00e3b2 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/motorola-atrix-4g.json @@ -0,0 +1,62 @@ +{ + "additionalFeatures": "", + "android": { + "os": "Android 2.2", + "ui": "MOTOBLUR" + }, + "availability": [ + "AT&T" + ], + "battery": { + "standbyTime": "400 hours", + "talkTime": "5 hours", + "type": "Lithium Ion (Li-Ion) (1930 mAH)" + }, + "camera": { + "features": [ + "" + ], + "primary": "" + }, + "connectivity": { + "bluetooth": "Bluetooth 2.1", + "cell": "WCDMA 850/1900/2100, GSM 850/900/1800/1900, HSDPA 14Mbps (Category 10) Edge Class 12, GPRS Class 12, eCompass, AGPS", + "gps": true, + "infrared": false, + "wifi": "802.11 a/b/g/n" + }, + "description": "MOTOROLA ATRIX 4G gives you dual-core processing power and the revolutionary webtop application. With webtop and a compatible Motorola docking station, sold separately, you can surf the Internet with a full Firefox browser, create and edit docs, or access multimedia on a large screen almost anywhere.", + "display": { + "screenResolution": "QHD (960 x 540)", + "screenSize": "4.0 inches", + "touchScreen": true + }, + "hardware": { + "accelerometer": true, + "audioJack": "3.5mm", + "cpu": "1 GHz Dual Core", + "fmRadio": false, + "physicalKeyboard": false, + "usb": "USB 2.0" + }, + "id": "motorola-atrix-4g", + "images": [ + "img/phones/motorola-atrix-4g.0.jpg", + "img/phones/motorola-atrix-4g.1.jpg", + "img/phones/motorola-atrix-4g.2.jpg", + "img/phones/motorola-atrix-4g.3.jpg" + ], + "name": "MOTOROLA ATRIX\u2122 4G", + "sizeAndWeight": { + "dimensions": [ + "63.5 mm (w)", + "117.75 mm (h)", + "10.95 mm (d)" + ], + "weight": "135.0 grams" + }, + "storage": { + "flash": "", + "ram": "" + } +} diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/motorola-xoom-with-wi-fi.json b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/motorola-xoom-with-wi-fi.json new file mode 100644 index 0000000000..4ba9c8d5b5 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/motorola-xoom-with-wi-fi.json @@ -0,0 +1,65 @@ +{ + "additionalFeatures": "Sensors: proximity, ambient light, barometer, gyroscope", + "android": { + "os": "Android 3.0", + "ui": "Honeycomb" + }, + "availability": [ + "" + ], + "battery": { + "standbyTime": "336 hours", + "talkTime": "24 hours", + "type": "Other ( mAH)" + }, + "camera": { + "features": [ + "Flash", + "Video" + ], + "primary": "5.0 megapixels" + }, + "connectivity": { + "bluetooth": "Bluetooth 2.1", + "cell": "", + "gps": true, + "infrared": false, + "wifi": "802.11 b/g/n" + }, + "description": "Motorola XOOM with Wi-Fi has a super-powerful dual-core processor and Android\u2122 3.0 (Honeycomb) \u2014 the Android platform designed specifically for tablets. With its 10.1-inch HD widescreen display, you\u2019ll enjoy HD video in a thin, light, powerful and upgradeable tablet.", + "display": { + "screenResolution": "WXGA (1200 x 800)", + "screenSize": "10.1 inches", + "touchScreen": true + }, + "hardware": { + "accelerometer": true, + "audioJack": "3.5mm", + "cpu": "1 GHz Dual Core Tegra 2", + "fmRadio": false, + "physicalKeyboard": false, + "usb": "USB 2.0" + }, + "id": "motorola-xoom-with-wi-fi", + "images": [ + "img/phones/motorola-xoom-with-wi-fi.0.jpg", + "img/phones/motorola-xoom-with-wi-fi.1.jpg", + "img/phones/motorola-xoom-with-wi-fi.2.jpg", + "img/phones/motorola-xoom-with-wi-fi.3.jpg", + "img/phones/motorola-xoom-with-wi-fi.4.jpg", + "img/phones/motorola-xoom-with-wi-fi.5.jpg" + ], + "name": "Motorola XOOM\u2122 with Wi-Fi", + "sizeAndWeight": { + "dimensions": [ + "249.1 mm (w)", + "167.8 mm (h)", + "12.9 mm (d)" + ], + "weight": "708.0 grams" + }, + "storage": { + "flash": "32000MB", + "ram": "1000MB" + } +} diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/motorola-xoom.json b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/motorola-xoom.json new file mode 100644 index 0000000000..f0f0c8711d --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/motorola-xoom.json @@ -0,0 +1,62 @@ +{ + "additionalFeatures": "Front-facing camera. Sensors: proximity, ambient light, barometer, gyroscope.", + "android": { + "os": "Android 3.0", + "ui": "Android" + }, + "availability": [ + "Verizon" + ], + "battery": { + "standbyTime": "336 hours", + "talkTime": "24 hours", + "type": "Other (3250 mAH)" + }, + "camera": { + "features": [ + "Flash", + "Video" + ], + "primary": "5.0 megapixels" + }, + "connectivity": { + "bluetooth": "Bluetooth 2.1", + "cell": "CDMA 800 /1900 LTE 700, Rx diversity in all bands", + "gps": true, + "infrared": false, + "wifi": "802.11 a/b/g/n" + }, + "description": "MOTOROLA XOOM has a super-powerful dual-core processor and Android\u2122 3.0 (Honeycomb) \u2014 the Android platform designed specifically for tablets. With its 10.1-inch HD widescreen display, you\u2019ll enjoy HD video in a thin, light, powerful and upgradeable tablet.", + "display": { + "screenResolution": "WXGA (1200 x 800)", + "screenSize": "10.1 inches", + "touchScreen": true + }, + "hardware": { + "accelerometer": true, + "audioJack": "3.5mm", + "cpu": "1 GHz Dual Core Tegra 2", + "fmRadio": false, + "physicalKeyboard": false, + "usb": "USB 2.0" + }, + "id": "motorola-xoom", + "images": [ + "img/phones/motorola-xoom.0.jpg", + "img/phones/motorola-xoom.1.jpg", + "img/phones/motorola-xoom.2.jpg" + ], + "name": "MOTOROLA XOOM\u2122", + "sizeAndWeight": { + "dimensions": [ + "249.0 mm (w)", + "168.0 mm (h)", + "12.7 mm (d)" + ], + "weight": "726.0 grams" + }, + "storage": { + "flash": "32000MB", + "ram": "1000MB" + } +} diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/nexus-s.json b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/nexus-s.json new file mode 100644 index 0000000000..5e712e2ff8 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/nexus-s.json @@ -0,0 +1,69 @@ +{ + "additionalFeatures": "Contour Display, Near Field Communications (NFC), Three-axis gyroscope, Anti-fingerprint display coating, Internet Calling support (VoIP/SIP)", + "android": { + "os": "Android 2.3", + "ui": "Android" + }, + "availability": [ + "M1,", + "O2,", + "Orange,", + "Singtel,", + "StarHub,", + "T-Mobile,", + "Vodafone" + ], + "battery": { + "standbyTime": "428 hours", + "talkTime": "6 hours", + "type": "Lithium Ion (Li-Ion) (1500 mAH)" + }, + "camera": { + "features": [ + "Flash", + "Video" + ], + "primary": "5.0 megapixels" + }, + "connectivity": { + "bluetooth": "Bluetooth 2.1", + "cell": "Quad-band GSM: 850, 900, 1800, 1900\r\nTri-band HSPA: 900, 2100, 1700\r\nHSPA type: HSDPA (7.2Mbps) HSUPA (5.76Mbps)", + "gps": true, + "infrared": false, + "wifi": "802.11 b/g/n" + }, + "description": "Nexus S is the next generation of Nexus devices, co-developed by Google and Samsung. The latest Android platform (Gingerbread), paired with a 1 GHz Hummingbird processor and 16GB of memory, makes Nexus S one of the fastest phones on the market. It comes pre-installed with the best of Google apps and enabled with new and popular features like true multi-tasking, Wi-Fi hotspot, Internet Calling, NFC support, and full web browsing. With this device, users will also be the first to receive software upgrades and new Google mobile apps as soon as they become available. For more details, visit http://www.google.com/nexus.", + "display": { + "screenResolution": "WVGA (800 x 480)", + "screenSize": "4.0 inches", + "touchScreen": true + }, + "hardware": { + "accelerometer": true, + "audioJack": "3.5mm", + "cpu": "1GHz Cortex A8 (Hummingbird) processor", + "fmRadio": false, + "physicalKeyboard": false, + "usb": "USB 2.0" + }, + "id": "nexus-s", + "images": [ + "img/phones/nexus-s.0.jpg", + "img/phones/nexus-s.1.jpg", + "img/phones/nexus-s.2.jpg", + "img/phones/nexus-s.3.jpg" + ], + "name": "Nexus S", + "sizeAndWeight": { + "dimensions": [ + "63.0 mm (w)", + "123.9 mm (h)", + "10.88 mm (d)" + ], + "weight": "129.0 grams" + }, + "storage": { + "flash": "16384MB", + "ram": "512MB" + } +} diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/phones.json b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/phones.json new file mode 100644 index 0000000000..339b94fbb5 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/app/phones/phones.json @@ -0,0 +1,155 @@ +[ + { + "age": 0, + "id": "motorola-xoom-with-wi-fi", + "imageUrl": "img/phones/motorola-xoom-with-wi-fi.0.jpg", + "name": "Motorola XOOM\u2122 with Wi-Fi", + "snippet": "The Next, Next Generation\r\n\r\nExperience the future with Motorola XOOM with Wi-Fi, the world's first tablet powered by Android 3.0 (Honeycomb)." + }, + { + "age": 1, + "id": "motorola-xoom", + "imageUrl": "img/phones/motorola-xoom.0.jpg", + "name": "MOTOROLA XOOM\u2122", + "snippet": "The Next, Next Generation\n\nExperience the future with MOTOROLA XOOM, the world's first tablet powered by Android 3.0 (Honeycomb)." + }, + { + "age": 2, + "carrier": "AT&T", + "id": "motorola-atrix-4g", + "imageUrl": "img/phones/motorola-atrix-4g.0.jpg", + "name": "MOTOROLA ATRIX\u2122 4G", + "snippet": "MOTOROLA ATRIX 4G the world's most powerful smartphone." + }, + { + "age": 3, + "id": "dell-streak-7", + "imageUrl": "img/phones/dell-streak-7.0.jpg", + "name": "Dell Streak 7", + "snippet": "Introducing Dell\u2122 Streak 7. Share photos, videos and movies together. It\u2019s small enough to carry around, big enough to gather around." + }, + { + "age": 4, + "carrier": "Cellular South", + "id": "samsung-gem", + "imageUrl": "img/phones/samsung-gem.0.jpg", + "name": "Samsung Gem\u2122", + "snippet": "The Samsung Gem\u2122 brings you everything that you would expect and more from a touch display smart phone \u2013 more apps, more features and a more affordable price." + }, + { + "age": 5, + "carrier": "Dell", + "id": "dell-venue", + "imageUrl": "img/phones/dell-venue.0.jpg", + "name": "Dell Venue", + "snippet": "The Dell Venue; Your Personal Express Lane to Everything" + }, + { + "age": 6, + "carrier": "Best Buy", + "id": "nexus-s", + "imageUrl": "img/phones/nexus-s.0.jpg", + "name": "Nexus S", + "snippet": "Fast just got faster with Nexus S. A pure Google experience, Nexus S is the first phone to run Gingerbread (Android 2.3), the fastest version of Android yet." + }, + { + "age": 7, + "carrier": "Cellular South", + "id": "lg-axis", + "imageUrl": "img/phones/lg-axis.0.jpg", + "name": "LG Axis", + "snippet": "Android Powered, Google Maps Navigation, 5 Customizable Home Screens" + }, + { + "age": 8, + "id": "samsung-galaxy-tab", + "imageUrl": "img/phones/samsung-galaxy-tab.0.jpg", + "name": "Samsung Galaxy Tab\u2122", + "snippet": "Feel Free to Tab\u2122. The Samsung Galaxy Tab\u2122 brings you an ultra-mobile entertainment experience through its 7\u201d display, high-power processor and Adobe\u00ae Flash\u00ae Player compatibility." + }, + { + "age": 9, + "carrier": "Cellular South", + "id": "samsung-showcase-a-galaxy-s-phone", + "imageUrl": "img/phones/samsung-showcase-a-galaxy-s-phone.0.jpg", + "name": "Samsung Showcase\u2122 a Galaxy S\u2122 phone", + "snippet": "The Samsung Showcase\u2122 delivers a cinema quality experience like you\u2019ve never seen before. Its innovative 4\u201d touch display technology provides rich picture brilliance, even outdoors" + }, + { + "age": 10, + "carrier": "Verizon", + "id": "droid-2-global-by-motorola", + "imageUrl": "img/phones/droid-2-global-by-motorola.0.jpg", + "name": "DROID\u2122 2 Global by Motorola", + "snippet": "The first smartphone with a 1.2 GHz processor and global capabilities." + }, + { + "age": 11, + "carrier": "Verizon", + "id": "droid-pro-by-motorola", + "imageUrl": "img/phones/droid-pro-by-motorola.0.jpg", + "name": "DROID\u2122 Pro by Motorola", + "snippet": "The next generation of DOES." + }, + { + "age": 12, + "carrier": "AT&T", + "id": "motorola-bravo-with-motoblur", + "imageUrl": "img/phones/motorola-bravo-with-motoblur.0.jpg", + "name": "MOTOROLA BRAVO\u2122 with MOTOBLUR\u2122", + "snippet": "An experience to cheer about." + }, + { + "age": 13, + "carrier": "T-Mobile", + "id": "motorola-defy-with-motoblur", + "imageUrl": "img/phones/motorola-defy-with-motoblur.0.jpg", + "name": "Motorola DEFY\u2122 with MOTOBLUR\u2122", + "snippet": "Are you ready for everything life throws your way?" + }, + { + "age": 14, + "carrier": "T-Mobile", + "id": "t-mobile-mytouch-4g", + "imageUrl": "img/phones/t-mobile-mytouch-4g.0.jpg", + "name": "T-Mobile myTouch 4G", + "snippet": "The T-Mobile myTouch 4G is a premium smartphone designed to deliver blazing fast 4G speeds so that you can video chat from practically anywhere, with or without Wi-Fi." + }, + { + "age": 15, + "carrier": "US Cellular", + "id": "samsung-mesmerize-a-galaxy-s-phone", + "imageUrl": "img/phones/samsung-mesmerize-a-galaxy-s-phone.0.jpg", + "name": "Samsung Mesmerize\u2122 a Galaxy S\u2122 phone", + "snippet": "The Samsung Mesmerize\u2122 delivers a cinema quality experience like you\u2019ve never seen before. Its innovative 4\u201d touch display technology provides rich picture brilliance,even outdoors" + }, + { + "age": 16, + "carrier": "Sprint", + "id": "sanyo-zio", + "imageUrl": "img/phones/sanyo-zio.0.jpg", + "name": "SANYO ZIO", + "snippet": "The Sanyo Zio by Kyocera is an Android smartphone with a combination of ultra-sleek styling, strong performance and unprecedented value." + }, + { + "age": 17, + "id": "samsung-transform", + "imageUrl": "img/phones/samsung-transform.0.jpg", + "name": "Samsung Transform\u2122", + "snippet": "The Samsung Transform\u2122 brings you a fun way to customize your Android powered touch screen phone to just the way you like it through your favorite themed \u201cSprint ID Service Pack\u201d." + }, + { + "age": 18, + "id": "t-mobile-g2", + "imageUrl": "img/phones/t-mobile-g2.0.jpg", + "name": "T-Mobile G2", + "snippet": "The T-Mobile G2 with Google is the first smartphone built for 4G speeds on T-Mobile's new network. Get the information you need, faster than you ever thought possible." + }, + { + "age": 19, + "id": "motorola-charm-with-motoblur", + "imageUrl": "img/phones/motorola-charm-with-motoblur.0.jpg", + "name": "Motorola CHARM\u2122 with MOTOBLUR\u2122", + "snippet": "Motorola CHARM fits easily in your pocket or palm. Includes MOTOBLUR service." + } +] diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/example-config.json b/public/docs/_examples/upgrade-phonecat-4-final/ts/example-config.json new file mode 100644 index 0000000000..401c14f835 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/example-config.json @@ -0,0 +1,5 @@ +{ + "build": "build:upgrade", + "run": "serve:upgrade", + "unittesting": true +} diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/index.html b/public/docs/_examples/upgrade-phonecat-4-final/ts/index.html new file mode 100644 index 0000000000..fee59370e6 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/index.html @@ -0,0 +1,36 @@ + + + + + + + + + + Google Phone Gallery + + + + + + + + + + + + + + + + + + + diff --git a/public/docs/_examples/upgrade-phonecat-3-final/ts/run-unit-tests.sh b/public/docs/_examples/upgrade-phonecat-4-final/ts/run-unit-tests.sh old mode 100755 new mode 100644 similarity index 100% rename from public/docs/_examples/upgrade-phonecat-3-final/ts/run-unit-tests.sh rename to public/docs/_examples/upgrade-phonecat-4-final/ts/run-unit-tests.sh diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/systemjs.config.1.js b/public/docs/_examples/upgrade-phonecat-4-final/ts/systemjs.config.1.js new file mode 100644 index 0000000000..c48bb7ca39 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/systemjs.config.1.js @@ -0,0 +1,55 @@ +/** + * System configuration for Angular samples + * Adjust as necessary for your application needs. + */ +(function (global) { + // #docregion paths + System.config({ + paths: { + // paths serve as alias + 'npm:': '/node_modules/' + }, + map: { + 'ng-loader': '../src/systemjs-angular-loader.js', + app: '/app', + // #enddocregion paths + // angular bundles + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js', + '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js', + + // other libraries + 'rxjs': 'npm:rxjs', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api', + // #docregion paths + }, + // #enddocregion paths + // packages tells the System loader how to load when no filename and/or no extension + packages: { + 'app': { + main: './main.js', + defaultExtension: 'js', + meta: { + './*.js': { + loader: 'ng-loader' + } + } + }, + rxjs: { + defaultExtension: 'js' + }, + 'angular-in-memory-web-api': { + main: './index.js', + defaultExtension: 'js' + } + } + }); +})(this); diff --git a/public/docs/_examples/upgrade-phonecat-4-final/ts/tsconfig.json b/public/docs/_examples/upgrade-phonecat-4-final/ts/tsconfig.json new file mode 100644 index 0000000000..f267800f14 --- /dev/null +++ b/public/docs/_examples/upgrade-phonecat-4-final/ts/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ "es2015", "dom" ], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true, + "typeRoots": [ + "../../node_modules/@types/" + ] + }, + "compileOnSave": true, + "exclude": [ + "node_modules/*", + "**/*-aot.ts" + ] +} diff --git a/public/docs/_examples/user-input/dart/.docsync.json b/public/docs/_examples/user-input/dart/.docsync.json deleted file mode 100644 index 7538cfa2a0..0000000000 --- a/public/docs/_examples/user-input/dart/.docsync.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "User input", - "docHref": "https://angular.io/docs/dart/latest/guide/user-input.html" -} diff --git a/public/docs/_examples/user-input/dart/example-config.json b/public/docs/_examples/user-input/dart/example-config.json deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/public/docs/_examples/user-input/dart/lib/app_component.dart b/public/docs/_examples/user-input/dart/lib/app_component.dart deleted file mode 100644 index d86db43cb0..0000000000 --- a/public/docs/_examples/user-input/dart/lib/app_component.dart +++ /dev/null @@ -1,23 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -import 'click_me_component.dart'; -import 'click_me_component_2.dart'; -import 'keyup_components.dart'; -import 'little_tour_component.dart'; -import 'loop_back_component.dart'; - -@Component( - selector: 'my-app', - templateUrl: 'app_component.html', - directives: const [ - ClickMeComponent, - ClickMeComponent2, - KeyUpComponentV1, - KeyUpComponentV2, - KeyUpComponentV3, - KeyUpComponentV4, - LoopBackComponent, - LittleTourComponent - ]) -class AppComponent {} diff --git a/public/docs/_examples/user-input/dart/lib/app_component.html b/public/docs/_examples/user-input/dart/lib/app_component.html deleted file mode 100644 index ecda463827..0000000000 --- a/public/docs/_examples/user-input/dart/lib/app_component.html +++ /dev/null @@ -1,28 +0,0 @@ - -

    - -

    - -

    - -

    - -

    Give me some keys!

    -
    - -

    keyup loop-back component

    -
    -

    - -

    Give me some more keys!

    -
    - -

    Type away! Press [enter] when done.

    -
    - -

    Type away! Press [enter] or click elsewhere when done.

    -
    - -

    Little Tour of Heroes

    -

    Add a new hero

    -
    diff --git a/public/docs/_examples/user-input/dart/lib/click_me_component.dart b/public/docs/_examples/user-input/dart/lib/click_me_component.dart deleted file mode 100644 index c1c7e19f93..0000000000 --- a/public/docs/_examples/user-input/dart/lib/click_me_component.dart +++ /dev/null @@ -1,19 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -// #docregion click-me-component -@Component( - selector: 'click-me', - template: ''' - // #docregion click-me-button - - // #enddocregion click-me-button - {{clickMessage}}''') -class ClickMeComponent { - String clickMessage = ''; - - onClickMe() { - clickMessage = 'You are my hero!'; - } -} -// #enddocregion click-me-component diff --git a/public/docs/_examples/user-input/dart/lib/click_me_component_2.dart b/public/docs/_examples/user-input/dart/lib/click_me_component_2.dart deleted file mode 100644 index 8047b2280a..0000000000 --- a/public/docs/_examples/user-input/dart/lib/click_me_component_2.dart +++ /dev/null @@ -1,17 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -@Component( - selector: 'click-me2', - template: ''' - {{clickMessage}}''') -class ClickMeComponent2 { - String clickMessage = ''; - int clicks = 1; - - onClickMe2(dynamic event) { - var evtMsg = - event != null ? ' Event target is ' + event.target.tagName : ''; - clickMessage = ('Click #${clicks++}. ${evtMsg}'); - } -} diff --git a/public/docs/_examples/user-input/dart/lib/keyup_components.dart b/public/docs/_examples/user-input/dart/lib/keyup_components.dart deleted file mode 100644 index c38a51e9a3..0000000000 --- a/public/docs/_examples/user-input/dart/lib/keyup_components.dart +++ /dev/null @@ -1,83 +0,0 @@ -// #docplaster -// #docregion -import 'dart:html'; - -import 'package:angular2/core.dart'; - -// #docregion key-up-component-1 -@Component( - selector: 'key-up1', -// #docregion key-up-component-1-template - template: ''' - -

    {{values}}

    - ''' -// #enddocregion key-up-component-1-template - ) -// #docregion key-up-component-1-class, key-up-component-1-class-no-type -class KeyUpComponentV1 { - String values = ''; - - // #enddocregion key-up-component-1-class, key-up-component-1-class-no-type - /* - // #docregion key-up-component-1-class-no-type - onKey(dynamic event) { - values += event.target.value + ' | '; - } - // #enddocregion key-up-component-1-class-no-type - */ - // #docregion key-up-component-1-class - onKey(KeyboardEvent event) { - InputElement el = event.target; - values += '${el.value} | '; - } -// #docregion key-up-component-1-class-no-type -} -// #enddocregion key-up-component-1,key-up-component-1-class, key-up-component-1-class-no-type - -////////////////////////////////////////// - -// #docregion key-up-component-2 -@Component( - selector: 'key-up2', - template: ''' - -

    {{values}}

    - ''') -class KeyUpComponentV2 { - String values = ''; - onKey(value) { - values += '$value | '; - } -} -// #enddocregion key-up-component-2 - -////////////////////////////////////////// - -// #docregion key-up-component-3 -@Component( - selector: 'key-up3', - template: ''' - -

    {{values}}

    - ''') -class KeyUpComponentV3 { - String values = ''; -} -// #enddocregion key-up-component-3 - -////////////////////////////////////////// - -// #docregion key-up-component-4 -@Component( - selector: 'key-up4', - template: ''' - -

    {{values}}

    - ''') -class KeyUpComponentV4 { - String values = ''; -} -// #enddocregion key-up-component-4 diff --git a/public/docs/_examples/user-input/dart/lib/little_tour_component.dart b/public/docs/_examples/user-input/dart/lib/little_tour_component.dart deleted file mode 100644 index 4e8f066a0a..0000000000 --- a/public/docs/_examples/user-input/dart/lib/little_tour_component.dart +++ /dev/null @@ -1,25 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -// #docregion little-tour -@Component( - selector: 'little-tour', - template: ''' - - - - -
    • {{hero}}
    - ''') -class LittleTourComponent { - List heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado']; - - void addHero(String newHero) { - if (newHero?.length > 0) { - heroes.add(newHero); - } - } -} -// #enddocregion little-tour diff --git a/public/docs/_examples/user-input/dart/lib/loop_back_component.dart b/public/docs/_examples/user-input/dart/lib/loop_back_component.dart deleted file mode 100644 index f2ceb75d11..0000000000 --- a/public/docs/_examples/user-input/dart/lib/loop_back_component.dart +++ /dev/null @@ -1,12 +0,0 @@ -// #docregion -import 'package:angular2/core.dart'; - -// #docregion loop-back-component -@Component( - selector: 'loop-back', - template: ''' - -

    {{box.value}}

    - ''') -class LoopBackComponent {} -// #enddocregion loop-back-component diff --git a/public/docs/_examples/user-input/dart/pubspec.yaml b/public/docs/_examples/user-input/dart/pubspec.yaml deleted file mode 100644 index 6c18ff599b..0000000000 --- a/public/docs/_examples/user-input/dart/pubspec.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# #docregion -name: user_input -description: User input example -version: 0.0.1 -environment: - sdk: '>=1.13.0 <2.0.0' -dependencies: - angular2: 2.0.0-beta.17 - browser: ^0.10.0 - dart_to_js_script_rewriter: ^1.0.1 -transformers: -- angular2: - platform_directives: 'package:angular2/common.dart#CORE_DIRECTIVES' - entry_points: web/main.dart -- dart_to_js_script_rewriter diff --git a/public/docs/_examples/user-input/dart/web/index.html b/public/docs/_examples/user-input/dart/web/index.html deleted file mode 100644 index 6081616684..0000000000 --- a/public/docs/_examples/user-input/dart/web/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - User Input - - - - - - - - Loading... - - diff --git a/public/docs/_examples/user-input/dart/web/main.dart b/public/docs/_examples/user-input/dart/web/main.dart deleted file mode 100644 index fc77aef43b..0000000000 --- a/public/docs/_examples/user-input/dart/web/main.dart +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion -import 'package:angular2/platform/browser.dart'; - -import 'package:user_input/app_component.dart'; - -main() { - bootstrap(AppComponent); -} diff --git a/public/docs/_examples/user-input/e2e-spec.ts b/public/docs/_examples/user-input/e2e-spec.ts index 22f8d96f63..3f178382c7 100644 --- a/public/docs/_examples/user-input/e2e-spec.ts +++ b/public/docs/_examples/user-input/e2e-spec.ts @@ -1,4 +1,7 @@ -/// +'use strict'; // necessary for es6 output in node + +import { browser, element, by, protractor } from 'protractor'; + describe('User Input Tests', function () { beforeAll(function () { @@ -20,7 +23,7 @@ describe('User Input Tests', function () { expect(mainEle.getText()).not.toContain('Event target is '); buttonEle.click().then(function() { expect(mainEle.getText()).toContain('Event target is BUTTON'); - }) + }); }); it('should support the keyup event ', function () { @@ -28,9 +31,8 @@ describe('User Input Tests', function () { let inputEle = mainEle.element(by.css('input')); let outputTextEle = mainEle.element(by.css('p')); expect(outputTextEle.getText()).toEqual(''); - return sendKeys(inputEle,'abc').then(function() { - expect(outputTextEle.getText()).toEqual('a | ab | abc |'); - }); + inputEle.sendKeys('abc'); + expect(outputTextEle.getText()).toEqual('a | ab | abc |'); }); it('should support user input from a local template let (loopback)', function () { @@ -38,9 +40,8 @@ describe('User Input Tests', function () { let inputEle = mainEle.element(by.css('input')); let outputTextEle = mainEle.element(by.css('p')); expect(outputTextEle.getText()).toEqual(''); - return sendKeys(inputEle,'abc').then(function() { - expect(outputTextEle.getText()).toEqual('abc'); - }); + inputEle.sendKeys('abc'); + expect(outputTextEle.getText()).toEqual('abc'); }); it('should be able to combine click event with a local template var', function () { @@ -48,22 +49,20 @@ describe('User Input Tests', function () { let inputEle = mainEle.element(by.css('input')); let outputTextEle = mainEle.element(by.css('p')); expect(outputTextEle.getText()).toEqual(''); - return sendKeys(inputEle,'abc').then(function() { - expect(outputTextEle.getText()).toEqual('a | ab | abc |'); - }); + inputEle.sendKeys('abc'); + expect(outputTextEle.getText()).toEqual('a | ab | abc |'); }); - it('should be able to filter key events', function () { + it('should be able to filter key events', () => { let mainEle = element(by.css('key-up3')); let inputEle = mainEle.element(by.css('input')); let outputTextEle = mainEle.element(by.css('p')); expect(outputTextEle.getText()).toEqual(''); - return sendKeys(inputEle,'abc').then(function() { - expect(outputTextEle.getText()).toEqual('', 'should be blank - have not sent enter yet'); - return sendKeys(inputEle, protractor.Key.ENTER); - }).then(function() { - expect(outputTextEle.getText()).toEqual('abc'); - }); + inputEle.sendKeys('abc'); + expect(outputTextEle.getText()).toEqual('', 'should be blank - have not sent enter yet'); + // broken atm, see https://github.com/angular/angular/issues/9419 + inputEle.sendKeys(protractor.Key.ENTER); + expect(outputTextEle.getText()).toEqual('abc'); }); it('should be able to filter blur events', function () { @@ -72,11 +71,10 @@ describe('User Input Tests', function () { let inputEle = mainEle.element(by.css('input')); let outputTextEle = mainEle.element(by.css('p')); expect(outputTextEle.getText()).toEqual(''); - return sendKeys(inputEle,'abc').then(function() { - expect(outputTextEle.getText()).toEqual('', 'should be blank - have not sent enter yet'); - // change the focus - return prevInputEle.click(); - }).then(function() { + inputEle.sendKeys('abc'); + expect(outputTextEle.getText()).toEqual('', 'should be blank - have not sent enter yet'); + // change the focus + prevInputEle.click().then(function() { expect(outputTextEle.getText()).toEqual('abc'); }); }); @@ -88,10 +86,9 @@ describe('User Input Tests', function () { let heroEles = mainEle.all(by.css('li')); let numHeroes: number; expect(heroEles.count()).toBeGreaterThan(0); - heroEles.count().then(function(count) { + heroEles.count().then(function(count: number) { numHeroes = count; - return sendKeys(inputEle, 'abc'); - }).then(function() { + inputEle.sendKeys('abc'); return addButtonEle.click(); }).then(function() { expect(heroEles.count()).toEqual(numHeroes + 1, 'should be one more hero added'); diff --git a/public/docs/_examples/user-input/ts/app/app.component.ts b/public/docs/_examples/user-input/ts/app/app.component.ts deleted file mode 100644 index 2b6754f2aa..0000000000 --- a/public/docs/_examples/user-input/ts/app/app.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -import { ClickMeComponent } from './click-me.component'; -import { ClickMeComponent2 } from './click-me2.component'; - -import { LoopbackComponent } from './loop-back.component'; - -import { KeyUpComponent_v1, - KeyUpComponent_v2, - KeyUpComponent_v3, - KeyUpComponent_v4 } from './keyup.components'; - -import { LittleTourComponent } from './little-tour.component'; - -@Component({ - selector: 'my-app', - templateUrl: 'app/app.component.html', - directives: [ - ClickMeComponent, ClickMeComponent2, - LoopbackComponent, - KeyUpComponent_v1, KeyUpComponent_v2, KeyUpComponent_v3, KeyUpComponent_v4, - LittleTourComponent - ] -}) -export class AppComponent { } diff --git a/public/docs/_examples/user-input/ts/app/click-me2.component.ts b/public/docs/_examples/user-input/ts/app/click-me2.component.ts deleted file mode 100644 index b444e3594e..0000000000 --- a/public/docs/_examples/user-input/ts/app/click-me2.component.ts +++ /dev/null @@ -1,18 +0,0 @@ -// #docregion -import { Component } from '@angular/core'; - -@Component({ - selector: 'click-me2', - template: ` - - {{clickMessage}}` -}) -export class ClickMeComponent2 { - clickMessage = ''; - clicks = 1; - - onClickMe2(event:any){ - let evtMsg = event ? ' Event target is '+ event.target.tagName : ''; - this.clickMessage = (`Click #${this.clicks++}. ${evtMsg}`) - } -} diff --git a/public/docs/_examples/user-input/ts/app/main.ts b/public/docs/_examples/user-input/ts/app/main.ts deleted file mode 100644 index 42dbeb9f7d..0000000000 --- a/public/docs/_examples/user-input/ts/app/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; - -import { AppComponent } from './app.component'; - -bootstrap(AppComponent); diff --git a/public/docs/_examples/user-input/ts/index.html b/public/docs/_examples/user-input/ts/index.html deleted file mode 100644 index f72530d64f..0000000000 --- a/public/docs/_examples/user-input/ts/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - User Input - - - - - - - - - - - - - - - - - - Loading... - - - diff --git a/public/docs/_examples/user-input/ts/plnkr.json b/public/docs/_examples/user-input/ts/plnkr.json index 4c260fcf9a..dd8f063d37 100644 --- a/public/docs/_examples/user-input/ts/plnkr.json +++ b/public/docs/_examples/user-input/ts/plnkr.json @@ -1,8 +1,9 @@ { "description": "User Input", + "basePath": "src/", "files": [ "!**/*.d.ts", "!**/*.js" ], "tags": ["input"] -} \ No newline at end of file +} diff --git a/public/docs/_examples/user-input/ts/app/app.component.html b/public/docs/_examples/user-input/ts/src/app/app.component.html similarity index 100% rename from public/docs/_examples/user-input/ts/app/app.component.html rename to public/docs/_examples/user-input/ts/src/app/app.component.html diff --git a/public/docs/_examples/user-input/ts/src/app/app.component.ts b/public/docs/_examples/user-input/ts/src/app/app.component.ts new file mode 100644 index 0000000000..5f885d5105 --- /dev/null +++ b/public/docs/_examples/user-input/ts/src/app/app.component.ts @@ -0,0 +1,8 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'my-app', + templateUrl: './app.component.html' +}) +export class AppComponent { } diff --git a/public/docs/_examples/user-input/ts/src/app/app.module.ts b/public/docs/_examples/user-input/ts/src/app/app.module.ts new file mode 100644 index 0000000000..41f13f9f11 --- /dev/null +++ b/public/docs/_examples/user-input/ts/src/app/app.module.ts @@ -0,0 +1,37 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; +import { ClickMeComponent } from './click-me.component'; +import { ClickMe2Component } from './click-me2.component'; +import { + KeyUpComponent_v1, + KeyUpComponent_v2, + KeyUpComponent_v3, + KeyUpComponent_v4 +} from './keyup.components'; +import { LittleTourComponent } from './little-tour.component'; +import { LoopbackComponent } from './loop-back.component'; + + +@NgModule({ + imports: [ + BrowserModule + ], + declarations: [ + AppComponent, + ClickMeComponent, + ClickMe2Component, + KeyUpComponent_v1, + KeyUpComponent_v2, + KeyUpComponent_v3, + KeyUpComponent_v4, + LittleTourComponent, + LoopbackComponent + ], + providers: [ + + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/user-input/ts/app/click-me.component.ts b/public/docs/_examples/user-input/ts/src/app/click-me.component.ts similarity index 89% rename from public/docs/_examples/user-input/ts/app/click-me.component.ts rename to public/docs/_examples/user-input/ts/src/app/click-me.component.ts index 20e77ad427..45a4ca7e70 100644 --- a/public/docs/_examples/user-input/ts/app/click-me.component.ts +++ b/public/docs/_examples/user-input/ts/src/app/click-me.component.ts @@ -17,8 +17,8 @@ import { Component } from '@angular/core'; export class ClickMeComponent { clickMessage = ''; - onClickMe(){ - this.clickMessage ='You are my hero!'; + onClickMe() { + this.clickMessage = 'You are my hero!'; } } // #enddocregion click-me-component diff --git a/public/docs/_examples/user-input/ts/src/app/click-me2.component.ts b/public/docs/_examples/user-input/ts/src/app/click-me2.component.ts new file mode 100644 index 0000000000..1e35731a82 --- /dev/null +++ b/public/docs/_examples/user-input/ts/src/app/click-me2.component.ts @@ -0,0 +1,18 @@ +// #docregion +import { Component } from '@angular/core'; + +@Component({ + selector: 'click-me2', + template: ` + + {{clickMessage}}` +}) +export class ClickMe2Component { + clickMessage = ''; + clicks = 1; + + onClickMe2(event: any) { + let evtMsg = event ? ' Event target is ' + event.target.tagName : ''; + this.clickMessage = (`Click #${this.clicks++}. ${evtMsg}`); + } +} diff --git a/public/docs/_examples/user-input/ts/app/keyup.components.ts b/public/docs/_examples/user-input/ts/src/app/keyup.components.ts similarity index 76% rename from public/docs/_examples/user-input/ts/app/keyup.components.ts rename to public/docs/_examples/user-input/ts/src/app/keyup.components.ts index c4acf742f5..94ed1ae423 100644 --- a/public/docs/_examples/user-input/ts/app/keyup.components.ts +++ b/public/docs/_examples/user-input/ts/src/app/keyup.components.ts @@ -1,3 +1,4 @@ +/* tslint:disable:class-name component-class-suffix */ // #docplaster // #docregion import { Component } from '@angular/core'; @@ -14,20 +15,19 @@ import { Component } from '@angular/core'; }) // #docregion key-up-component-1-class, key-up-component-1-class-no-type export class KeyUpComponent_v1 { - values=''; + values = ''; // #enddocregion key-up-component-1-class, key-up-component-1-class-no-type /* // #docregion key-up-component-1-class-no-type - // without strong typing - onKey(event:any) { + onKey(event: any) { // without type info this.values += event.target.value + ' | '; } // #enddocregion key-up-component-1-class-no-type */ // #docregion key-up-component-1-class - // with strong typing - onKey(event:KeyboardEvent) { + + onKey(event: KeyboardEvent) { // with type info this.values += (event.target).value + ' | '; } // #docregion key-up-component-1-class-no-type @@ -45,30 +45,29 @@ export class KeyUpComponent_v1 { ` }) export class KeyUpComponent_v2 { - values=''; - onKey(value:string) { + values = ''; + onKey(value: string) { this.values += value + ' | '; } } // #enddocregion key-up-component-2 - ////////////////////////////////////////// // #docregion key-up-component-3 @Component({ selector: 'key-up3', template: ` - -

    {{values}}

    + +

    {{value}}

    ` }) export class KeyUpComponent_v3 { - values=''; + value = ''; + onEnter(value: string) { this.value = value; } } // #enddocregion key-up-component-3 - ////////////////////////////////////////// // #docregion key-up-component-4 @@ -76,13 +75,14 @@ export class KeyUpComponent_v3 { selector: 'key-up4', template: ` + (keyup.enter)="update(box.value)" + (blur)="update(box.value)"> -

    {{values}}

    +

    {{value}}

    ` }) export class KeyUpComponent_v4 { - values=''; + value = ''; + update(value: string) { this.value = value; } } // #enddocregion key-up-component-4 diff --git a/public/docs/_examples/user-input/ts/app/little-tour.component.ts b/public/docs/_examples/user-input/ts/src/app/little-tour.component.ts similarity index 75% rename from public/docs/_examples/user-input/ts/app/little-tour.component.ts rename to public/docs/_examples/user-input/ts/src/app/little-tour.component.ts index f48abe3518..5862f033d6 100644 --- a/public/docs/_examples/user-input/ts/app/little-tour.component.ts +++ b/public/docs/_examples/user-input/ts/src/app/little-tour.component.ts @@ -9,14 +9,14 @@ import { Component } from '@angular/core'; (keyup.enter)="addHero(newHero.value)" (blur)="addHero(newHero.value); newHero.value='' "> - +
    • {{hero}}
    ` }) export class LittleTourComponent { - heroes=['Windstorm', 'Bombasto', 'Magneta', 'Tornado']; - addHero(newHero:string) { + heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado']; + addHero(newHero: string) { if (newHero) { this.heroes.push(newHero); } diff --git a/public/docs/_examples/user-input/ts/app/loop-back.component.ts b/public/docs/_examples/user-input/ts/src/app/loop-back.component.ts similarity index 94% rename from public/docs/_examples/user-input/ts/app/loop-back.component.ts rename to public/docs/_examples/user-input/ts/src/app/loop-back.component.ts index f7c15f36bf..6c9dad1da8 100644 --- a/public/docs/_examples/user-input/ts/app/loop-back.component.ts +++ b/public/docs/_examples/user-input/ts/src/app/loop-back.component.ts @@ -3,7 +3,7 @@ import { Component } from '@angular/core'; // #docregion loop-back-component @Component({ selector: 'loop-back', - template:` + template: `

    {{box.value}}

    ` diff --git a/public/docs/_examples/user-input/ts/src/index.html b/public/docs/_examples/user-input/ts/src/index.html new file mode 100644 index 0000000000..9728814107 --- /dev/null +++ b/public/docs/_examples/user-input/ts/src/index.html @@ -0,0 +1,27 @@ + + + + User Input + + + + + + + + + + + + + + + + + + Loading... + + + diff --git a/public/docs/_examples/user-input/ts/src/main.ts b/public/docs/_examples/user-input/ts/src/main.ts new file mode 100644 index 0000000000..311c44b76d --- /dev/null +++ b/public/docs/_examples/user-input/ts/src/main.ts @@ -0,0 +1,5 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/public/docs/_examples/user-input/dart/web/user-input-styles.css b/public/docs/_examples/user-input/ts/src/user-input-styles.css similarity index 100% rename from public/docs/_examples/user-input/dart/web/user-input-styles.css rename to public/docs/_examples/user-input/ts/src/user-input-styles.css diff --git a/public/docs/_examples/user-input/ts/user-input-styles.css b/public/docs/_examples/user-input/ts/user-input-styles.css deleted file mode 100644 index b2133e5103..0000000000 --- a/public/docs/_examples/user-input/ts/user-input-styles.css +++ /dev/null @@ -1,9 +0,0 @@ -fieldset {border-style:none} -img {height: 100px;} -.box {border: 1px solid black; padding:3px} -.child-div {margin-left: 1em; font-weight: normal} -.hidden {display: none} -.parent-div {margin-top: 1em; font-weight: bold} -.special {font-weight:bold;} -.toe {margin-left: 1em; font-style: italic;} -little-hero {color:blue; font-size: smaller; background-color: Turquoise } \ No newline at end of file diff --git a/public/docs/_examples/wallaby.js b/public/docs/_examples/wallaby.js deleted file mode 100644 index 28053a11fe..0000000000 --- a/public/docs/_examples/wallaby.js +++ /dev/null @@ -1,77 +0,0 @@ -// Configuration for the Wallaby Visual Studio Code testing extension -// https://marketplace.visualstudio.com/items?itemName=WallabyJs.wallaby-vscode -// Note: Wallaby is not open source and costs money - -module.exports = function () { - - return { - files: [ - // System.js for module loading - {pattern: 'node_modules/systemjs/dist/system.js', instrument: false}, - {pattern: 'systemjs.config.js', instrument: false}, - - // Polyfills - {pattern: 'node_modules/core-js/client/shim.min.js', instrument: false}, - - // Reflect, Zone.js, and test shims - // Rx.js, Angular 2 itself, and the testing library not here because loaded by systemjs - {pattern: 'node_modules/reflect-metadata/Reflect.js', instrument: false}, - {pattern: 'node_modules/zone.js/dist/zone.js', instrument: false}, - {pattern: 'node_modules/zone.js/dist/jasmine-patch.js', instrument: false}, - {pattern: 'node_modules/zone.js/dist/async-test.js', instrument: false}, - {pattern: 'node_modules/zone.js/dist/fake-async-test.js', instrument: false}, - - {pattern: 'app/**/*+(ts|html|css)', load: false}, - {pattern: 'app/**/*.spec.ts', ignore: true} - ], - - tests: [ - {pattern: 'app/**/*.spec.ts', load: false} - ], - - middleware: function (app, express) { - app.use('/node_modules', express.static(require('path').join(__dirname, 'node_modules'))); - }, - - testFramework: 'jasmine', - - debug: true, - - bootstrap: function (wallaby) { - wallaby.delayStart(); - - System.config({ - packageWithIndex: true // sadly, we can't use umd packages (yet?) - }); - - System.import('systemjs.config.js') - .then(function () { - return Promise.all([ - System.import('@angular/core/testing'), - System.import('@angular/platform-browser-dynamic/testing') - ]) - }) - .then(function (providers) { - var testing = providers[0]; - var testingBrowser = providers[1]; - - testing.setBaseTestProviders( - testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, - testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS); - - // Load all spec files - return Promise.all(wallaby.tests.map(function (specFile) { - return System.import(specFile); - })); - }) - .then(function () { - wallaby.start(); - }) - .catch(function (e) { - setTimeout(function () { - throw e; - }, 0); - }); - } - }; -}; diff --git a/public/docs/_examples/webpack/e2e-spec.ts b/public/docs/_examples/webpack/e2e-spec.ts new file mode 100644 index 0000000000..9bca9810eb --- /dev/null +++ b/public/docs/_examples/webpack/e2e-spec.ts @@ -0,0 +1,21 @@ +'use strict'; // necessary for es6 output in node + +import { browser, element, by } from 'protractor'; + +describe('QuickStart E2E Tests', function () { + + let expectedMsg = 'Hello from Angular App with Webpack'; + + beforeEach(function () { + browser.get(''); + }); + + it(`should display: ${expectedMsg}`, function () { + expect(element(by.css('h1')).getText()).toEqual(expectedMsg); + }); + + it('should display an image', function () { + expect(element(by.css('img')).isPresent()).toBe(true); + }); + +}); diff --git a/public/docs/_examples/webpack/ts-snippets/webpack.config.snippets.ts b/public/docs/_examples/webpack/ts-snippets/webpack.config.snippets.ts deleted file mode 100644 index 3211e5e2db..0000000000 --- a/public/docs/_examples/webpack/ts-snippets/webpack.config.snippets.ts +++ /dev/null @@ -1,59 +0,0 @@ -/* tslint:disable */ -// #docregion one-entry -entry: { - app: 'src/app.ts' -} -// #enddocregion one-entry - -// #docregion app-example -import { Component } from '@angular/core'; - -@Component({ - ... -}) -export class AppComponent {} -// #enddocregion app-example - -// #docregion one-output -output: { - filename: 'app.js' -} -// #enddocregion one-output - -// #docregion two-entries -entry: { - app: 'src/app.ts', - vendor: 'src/vendor.ts' -}, - -output: { - filename: '[name].js' -} -// #enddocregion two-entries - -// #docregion loaders -loaders: [ - { - test: /\.ts$/ - loaders: 'ts' - }, - { - test: /\.css$/ - loaders: 'style!css' - } -] -// #enddocregion loaders - -// #docregion imports -// #docregion single-import -import { AppComponent } from './app.component.ts'; -// #enddocregion single-import -import 'uiframework/dist/uiframework.css'; -// #enddocregion imports - -// #docregion plugins -plugins: [ - new webpack.optimize.UglifyJsPlugin() -] -// #enddocregion plugins -// #enddocregion diff --git a/public/docs/_examples/webpack/ts/config/karma-test-shim.js b/public/docs/_examples/webpack/ts/config/karma-test-shim.js index 27fa731f5a..2ea37fbd72 100644 --- a/public/docs/_examples/webpack/ts/config/karma-test-shim.js +++ b/public/docs/_examples/webpack/ts/config/karma-test-shim.js @@ -2,10 +2,12 @@ Error.stackTraceLimit = Infinity; require('core-js/es6'); -require('reflect-metadata'); +require('core-js/es7/reflect'); require('zone.js/dist/zone'); require('zone.js/dist/long-stack-trace-zone'); +require('zone.js/dist/proxy'); +require('zone.js/dist/sync-test'); require('zone.js/dist/jasmine-patch'); require('zone.js/dist/async-test'); require('zone.js/dist/fake-async-test'); @@ -17,7 +19,4 @@ appContext.keys().forEach(appContext); var testing = require('@angular/core/testing'); var browser = require('@angular/platform-browser-dynamic/testing'); -testing.setBaseTestProviders( - browser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, - browser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS -); +testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting()); diff --git a/public/docs/_examples/webpack/ts/config/karma.conf.js b/public/docs/_examples/webpack/ts/config/karma.conf.js index 3e2e34072f..7bbb4617db 100644 --- a/public/docs/_examples/webpack/ts/config/karma.conf.js +++ b/public/docs/_examples/webpack/ts/config/karma.conf.js @@ -25,12 +25,12 @@ module.exports = function (config) { noInfo: true }, - reporters: ['progress'], + reporters: ['kjhtml'], port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: false, - browsers: ['PhantomJS'], + browsers: ['Chrome'], singleRun: true }; diff --git a/public/docs/_examples/webpack/ts/config/webpack.common.js b/public/docs/_examples/webpack/ts/config/webpack.common.js index 07e74adc65..28be240e04 100644 --- a/public/docs/_examples/webpack/ts/config/webpack.common.js +++ b/public/docs/_examples/webpack/ts/config/webpack.common.js @@ -1,3 +1,4 @@ +// #docplaster // #docregion var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); @@ -5,44 +6,52 @@ var ExtractTextPlugin = require('extract-text-webpack-plugin'); var helpers = require('./helpers'); module.exports = { - // #docregion entries + // #docregion entries, one-entry, two-entries entry: { + // #enddocregion one-entry, two-entries 'polyfills': './src/polyfills.ts', + // #docregion two-entries 'vendor': './src/vendor.ts', + // #docregion one-entry 'app': './src/main.ts' }, - // #enddocregion + // #enddocregion entries, one-entry, two-entries // #docregion resolve resolve: { - extensions: ['', '.js', '.ts'] + extensions: ['.ts', '.js'] }, // #enddocregion resolve // #docregion loaders module: { - loaders: [ + rules: [ { test: /\.ts$/, - loader: 'ts' + loaders: [ + { + loader: 'awesome-typescript-loader', + options: { configFileName: helpers.root('src', 'tsconfig.json') } + } , 'angular2-template-loader' + ] }, { test: /\.html$/, - loader: 'html' + loader: 'html-loader' }, { test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, - loader: 'file?name=assets/[name].[hash].[ext]' + loader: 'file-loader?name=assets/[name].[hash].[ext]' }, { test: /\.css$/, exclude: helpers.root('src', 'app'), - loader: ExtractTextPlugin.extract('style', 'css?sourceMap') + loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader?sourceMap' }) }, { test: /\.css$/, include: helpers.root('src', 'app'), - loader: 'raw' + loader: 'raw-loader' } ] }, @@ -50,6 +59,14 @@ module.exports = { // #docregion plugins plugins: [ + // Workaround for angular/angular#11580 + new webpack.ContextReplacementPlugin( + // The (\\|\/) piece accounts for path separators in *nix and Windows + /angular(\\|\/)core(\\|\/)@angular/, + helpers.root('./src'), // location of your src + {} // a map of your routes + ), + new webpack.optimize.CommonsChunkPlugin({ name: ['app', 'vendor', 'polyfills'] }), diff --git a/public/docs/_examples/webpack/ts/config/webpack.dev.js b/public/docs/_examples/webpack/ts/config/webpack.dev.js index c1484a0caa..57d29560a0 100644 --- a/public/docs/_examples/webpack/ts/config/webpack.dev.js +++ b/public/docs/_examples/webpack/ts/config/webpack.dev.js @@ -6,21 +6,21 @@ var helpers = require('./helpers'); module.exports = webpackMerge(commonConfig, { devtool: 'cheap-module-eval-source-map', - + output: { path: helpers.root('dist'), - publicPath: 'http://localhost:8080/', + publicPath: '/', filename: '[name].js', chunkFilename: '[id].chunk.js' }, - + plugins: [ new ExtractTextPlugin('[name].css') ], - + devServer: { historyApiFallback: true, stats: 'minimal' } }); -// #enddocregion \ No newline at end of file +// #enddocregion diff --git a/public/docs/_examples/webpack/ts/config/webpack.prod.js b/public/docs/_examples/webpack/ts/config/webpack.prod.js index 0e897cb35a..d6c70119bc 100644 --- a/public/docs/_examples/webpack/ts/config/webpack.prod.js +++ b/public/docs/_examples/webpack/ts/config/webpack.prod.js @@ -17,20 +17,25 @@ module.exports = webpackMerge(commonConfig, { chunkFilename: '[id].[hash].chunk.js' }, - htmlLoader: { - minimize: false // workaround for ng2 - }, - plugins: [ - new webpack.NoErrorsPlugin(), - new webpack.optimize.DedupePlugin(), - new webpack.optimize.UglifyJsPlugin(), + new webpack.NoEmitOnErrorsPlugin(), + new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618 + mangle: { + keep_fnames: true + } + }), new ExtractTextPlugin('[name].[hash].css'), new webpack.DefinePlugin({ 'process.env': { 'ENV': JSON.stringify(ENV) } + }), + new webpack.LoaderOptionsPlugin({ + htmlLoader: { + minimize: false // workaround for ng2 + } }) ] }); + // #enddocregion diff --git a/public/docs/_examples/webpack/ts/config/webpack.test.js b/public/docs/_examples/webpack/ts/config/webpack.test.js index 5c24d4e81e..e668504c67 100644 --- a/public/docs/_examples/webpack/ts/config/webpack.test.js +++ b/public/docs/_examples/webpack/ts/config/webpack.test.js @@ -1,31 +1,55 @@ // #docregion +var webpack = require('webpack'); +var helpers = require('./helpers'); + module.exports = { devtool: 'inline-source-map', resolve: { - extensions: ['', '.ts', '.js'] + extensions: ['.ts', '.js'] }, module: { - loaders: [ + rules: [ { test: /\.ts$/, - loader: 'ts' + loaders: [ + { + loader: 'awesome-typescript-loader', + options: { configFileName: helpers.root('src', 'tsconfig.json') } + } , 'angular2-template-loader' + ] }, { test: /\.html$/, - loader: 'html' + loader: 'html-loader' }, { test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, - loader: 'null' + loader: 'null-loader' + }, + { + test: /\.css$/, + exclude: helpers.root('src', 'app'), + loader: 'null-loader' }, { test: /\.css$/, - loader: 'null' + include: helpers.root('src', 'app'), + loader: 'raw-loader' } ] - } + }, + + plugins: [ + new webpack.ContextReplacementPlugin( + // The (\\|\/) piece accounts for path separators in *nix and Windows + /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/, + helpers.root('./src'), // location of your src + {} // a map of your routes + ) + ] } + // #enddocregion diff --git a/public/docs/_examples/webpack/ts/example-config.json b/public/docs/_examples/webpack/ts/example-config.json index e69de29bb2..e405d0c01a 100644 --- a/public/docs/_examples/webpack/ts/example-config.json +++ b/public/docs/_examples/webpack/ts/example-config.json @@ -0,0 +1,4 @@ +{ + "build": "build:webpack", + "run": "serve:cli" +} diff --git a/public/docs/_examples/webpack/ts/package.webpack.json b/public/docs/_examples/webpack/ts/package.webpack.json index 0e58f8680c..8f9e3954c2 100644 --- a/public/docs/_examples/webpack/ts/package.webpack.json +++ b/public/docs/_examples/webpack/ts/package.webpack.json @@ -1,49 +1,49 @@ { "name": "angular2-webpack", "version": "1.0.0", - "description": "A webpack starter for angular 2", + "description": "A webpack starter for Angular", "scripts": { "start": "webpack-dev-server --inline --progress --port 8080", "test": "karma start", - "build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail", - "postinstall": "typings install" + "build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail" }, "license": "MIT", "dependencies": { - "@angular/common": "2.0.0-rc.1", - "@angular/compiler": "2.0.0-rc.1", - "@angular/core": "2.0.0-rc.1", - "@angular/http": "2.0.0-rc.1", - "@angular/platform-browser": "2.0.0-rc.1", - "@angular/platform-browser-dynamic": "2.0.0-rc.1", - "@angular/router-deprecated": "2.0.0-rc.1", - "core-js": "^2.4.0", - "reflect-metadata": "0.1.2", - "rxjs": "5.0.0-beta.6", - "zone.js": "0.6.12" + "@angular/common": "~4.0.0", + "@angular/compiler": "~4.0.0", + "@angular/core": "~4.0.0", + "@angular/forms": "~4.0.0", + "@angular/http": "~4.0.0", + "@angular/platform-browser": "~4.0.0", + "@angular/platform-browser-dynamic": "~4.0.0", + "@angular/router": "~4.0.0", + "core-js": "^2.4.1", + "rxjs": "5.0.1", + "zone.js": "^0.8.4" }, "devDependencies": { - "css-loader": "^0.23.1", - "extract-text-webpack-plugin": "^1.0.1", - "file-loader": "^0.8.5", + "@types/node": "^6.0.45", + "@types/jasmine": "2.5.36", + "angular2-template-loader": "^0.6.0", + "awesome-typescript-loader": "^3.0.4", + "css-loader": "^0.26.1", + "extract-text-webpack-plugin": "2.0.0-beta.5", + "file-loader": "^0.9.0", "html-loader": "^0.4.3", - "html-webpack-plugin": "^2.15.0", + "html-webpack-plugin": "^2.16.1", "jasmine-core": "^2.4.1", - "karma": "^0.13.22", - "karma-jasmine": "^0.3.8", - "karma-phantomjs-launcher": "^1.0.0", + "karma": "^1.2.0", + "karma-chrome-launcher": "^2.0.0", + "karma-jasmine": "^1.0.2", "karma-sourcemap-loader": "^0.3.7", - "karma-webpack": "^1.7.0", + "karma-webpack": "^2.0.1", "null-loader": "^0.1.1", - "phantomjs-prebuilt": "^2.1.7", "raw-loader": "^0.5.1", "rimraf": "^2.5.2", "style-loader": "^0.13.1", - "ts-loader": "^0.8.1", - "typescript": "^1.8.9", - "typings": "^1.0.4", - "webpack": "^1.12.14", - "webpack-dev-server": "^1.14.1", - "webpack-merge": "^0.9.0" + "typescript": "~2.0.10", + "webpack": "2.2.1", + "webpack-dev-server": "2.4.1", + "webpack-merge": "^3.0.0" } } diff --git a/public/docs/_examples/webpack/ts/public/images/angular.png b/public/docs/_examples/webpack/ts/public/images/angular.png deleted file mode 100644 index a1d9790bc3..0000000000 Binary files a/public/docs/_examples/webpack/ts/public/images/angular.png and /dev/null differ diff --git a/public/docs/_examples/webpack/ts/src/app/app.component.html b/public/docs/_examples/webpack/ts/src/app/app.component.html index a333a7a72f..9e60cd2ad5 100644 --- a/public/docs/_examples/webpack/ts/src/app/app.component.html +++ b/public/docs/_examples/webpack/ts/src/app/app.component.html @@ -1,7 +1,7 @@
    -

    Hello from Angular 2 App with Webpack

    +

    Hello from Angular App with Webpack

    - +
    diff --git a/public/docs/_examples/webpack/ts/src/app/app.component.spec.ts b/public/docs/_examples/webpack/ts/src/app/app.component.spec.ts index c2e85fd099..a6512a11e7 100644 --- a/public/docs/_examples/webpack/ts/src/app/app.component.spec.ts +++ b/public/docs/_examples/webpack/ts/src/app/app.component.spec.ts @@ -1,22 +1,16 @@ // #docregion -import { - it, - inject, - describe, - beforeEachProviders, - expect -} from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { AppComponent } from './app.component'; describe('App', () => { - beforeEachProviders(() => [ - AppComponent - ]); + beforeEach(() => { + TestBed.configureTestingModule({ declarations: [AppComponent]}); + }); - it ('should work', inject([AppComponent], (app: AppComponent) => { - // Add real test here - expect(2).toBe(2); - })); + it ('should work', () => { + let fixture = TestBed.createComponent(AppComponent); + expect(fixture.componentInstance instanceof AppComponent).toBe(true, 'should create AppComponent'); + }); }); // #enddocregion diff --git a/public/docs/_examples/webpack/ts/src/app/app.component.ts b/public/docs/_examples/webpack/ts/src/app/app.component.ts index 590e5008ec..2c5eac0147 100644 --- a/public/docs/_examples/webpack/ts/src/app/app.component.ts +++ b/public/docs/_examples/webpack/ts/src/app/app.component.ts @@ -1,12 +1,16 @@ +// #docplaster // #docregion +// #docregion component import { Component } from '@angular/core'; -import '../../public/css/styles.css'; +// #enddocregion component +import '../assets/css/styles.css'; +// #docregion component @Component({ selector: 'my-app', - template: require('./app.component.html'), - styles: [require('./app.component.css')] + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'] }) export class AppComponent { } // #enddocregion diff --git a/public/docs/_examples/webpack/ts/src/app/app.module.ts b/public/docs/_examples/webpack/ts/src/app/app.module.ts new file mode 100644 index 0000000000..362f3401fa --- /dev/null +++ b/public/docs/_examples/webpack/ts/src/app/app.module.ts @@ -0,0 +1,16 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; + +@NgModule({ + imports: [ + BrowserModule + ], + declarations: [ + AppComponent + ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } diff --git a/public/docs/_examples/webpack/ts/public/css/styles.css b/public/docs/_examples/webpack/ts/src/assets/css/styles.css similarity index 100% rename from public/docs/_examples/webpack/ts/public/css/styles.css rename to public/docs/_examples/webpack/ts/src/assets/css/styles.css diff --git a/public/docs/_examples/webpack/ts/src/assets/images/angular.png b/public/docs/_examples/webpack/ts/src/assets/images/angular.png new file mode 100644 index 0000000000..c510293918 Binary files /dev/null and b/public/docs/_examples/webpack/ts/src/assets/images/angular.png differ diff --git a/public/docs/_examples/webpack/ts/src/main.ts b/public/docs/_examples/webpack/ts/src/main.ts index 8ea0ea84ce..e1d8cbc0fe 100644 --- a/public/docs/_examples/webpack/ts/src/main.ts +++ b/public/docs/_examples/webpack/ts/src/main.ts @@ -1,8 +1,8 @@ // #docregion -import { bootstrap } from '@angular/platform-browser-dynamic'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { enableProdMode } from '@angular/core'; -import { AppComponent } from './app/app.component'; +import { AppModule } from './app/app.module'; // #docregion enable-prod if (process.env.ENV === 'production') { @@ -10,5 +10,5 @@ if (process.env.ENV === 'production') { } // #enddocregion enable-prod -bootstrap(AppComponent, []); +platformBrowserDynamic().bootstrapModule(AppModule); // #enddocregion diff --git a/public/docs/_examples/webpack/ts/src/polyfills.ts b/public/docs/_examples/webpack/ts/src/polyfills.ts index 5de11fb502..118acd2b0c 100644 --- a/public/docs/_examples/webpack/ts/src/polyfills.ts +++ b/public/docs/_examples/webpack/ts/src/polyfills.ts @@ -1,15 +1,12 @@ // #docregion import 'core-js/es6'; -import 'reflect-metadata'; +import 'core-js/es7/reflect'; require('zone.js/dist/zone'); if (process.env.ENV === 'production') { // Production - } else { - // Development - + // Development and test Error['stackTraceLimit'] = Infinity; - require('zone.js/dist/long-stack-trace-zone'); } diff --git a/public/docs/_examples/webpack/ts/src/tsconfig.1.json b/public/docs/_examples/webpack/ts/src/tsconfig.1.json new file mode 100644 index 0000000000..544e895bce --- /dev/null +++ b/public/docs/_examples/webpack/ts/src/tsconfig.1.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es2015", "dom"], + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true + } +} \ No newline at end of file diff --git a/public/docs/_examples/webpack/ts/src/vendor.ts b/public/docs/_examples/webpack/ts/src/vendor.ts index 1a45c91d46..8ffd09240a 100644 --- a/public/docs/_examples/webpack/ts/src/vendor.ts +++ b/public/docs/_examples/webpack/ts/src/vendor.ts @@ -1,11 +1,11 @@ // #docregion -// Angular 2 +// Angular import '@angular/platform-browser'; import '@angular/platform-browser-dynamic'; import '@angular/core'; import '@angular/common'; import '@angular/http'; -import '@angular/router-deprecated'; +import '@angular/router'; // RxJS import 'rxjs'; diff --git a/public/docs/_examples/webpack/ts/tsconfig.1.json b/public/docs/_examples/webpack/ts/tsconfig.1.json deleted file mode 100644 index 302417ff3d..0000000000 --- a/public/docs/_examples/webpack/ts/tsconfig.1.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "moduleResolution": "node", - "sourceMap": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "removeComments": false, - "noImplicitAny": true, - "suppressImplicitAnyIndexErrors": true - }, - "exclude": [ - "node_modules", - "typings/main", - "typings/main.d.ts" - ] -} diff --git a/public/docs/_examples/webpack/ts/typings.1.json b/public/docs/_examples/webpack/ts/typings.1.json deleted file mode 100644 index 7e0e18568d..0000000000 --- a/public/docs/_examples/webpack/ts/typings.1.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "globalDependencies": { - "core-js": "registry:dt/core-js#0.0.0+20160317120654", - "jasmine": "registry:dt/jasmine#2.2.0+20160505161446", - "node": "registry:dt/node#4.0.0+20160509154515" - } -} diff --git a/public/docs/_examples/webpack/ts/zipper.json b/public/docs/_examples/webpack/ts/zipper.json new file mode 100644 index 0000000000..73ea46a406 --- /dev/null +++ b/public/docs/_examples/webpack/ts/zipper.json @@ -0,0 +1,12 @@ +{ + "files":[ + "!**/*.d.ts", + "!**/*.js", + "!**/*.[0-9].*", + "config/**/*", + "webpack.config.js", + "karma.webpack.conf.js" + ], + "removeSystemJsConfig": true, + "type": "webpack" +} diff --git a/public/docs/_includes/_hover-card.jade b/public/docs/_includes/_hover-card.jade new file mode 100644 index 0000000000..a76f9948c2 --- /dev/null +++ b/public/docs/_includes/_hover-card.jade @@ -0,0 +1,12 @@ +- var hasIcon = icon ? 'has-icon' : '' +- var iconNumber = number ? number : '' +a(class="hover-card is-button #{hasIcon}" href="#{url}" md-button) + if icon + span(class="hover-card-icon #{icon}") #{iconNumber} + + h3 #{name} + + if cta + p #{cta} + else + p View #{name} Docs diff --git a/public/docs/_includes/_see-addr-bar.jade b/public/docs/_includes/_see-addr-bar.jade new file mode 100644 index 0000000000..523b72f67a --- /dev/null +++ b/public/docs/_includes/_see-addr-bar.jade @@ -0,0 +1,11 @@ +table + tr + td + :marked + To see the URL changes in the browser address bar of the live example, + open it again in the Plunker editor by clicking the icon in the upper right, + then pop out the preview window by clicking the blue 'X' button in the upper right corner. + td + img(src='/resources/images/devguide/plunker-switch-to-editor-button.png' width="200px" height="70px" alt="pop out the window" align="right" ) + br + img(src='/resources/images/devguide/plunker-separate-window-button.png' width="200px" height="47px" alt="pop out the window" align="right" ) diff --git a/public/docs/_includes/_side-nav.jade b/public/docs/_includes/_side-nav.jade index d1b8bbb5f7..cf73ed27d0 100644 --- a/public/docs/_includes/_side-nav.jade +++ b/public/docs/_includes/_side-nav.jade @@ -37,56 +37,83 @@ - var basics = sections('guide', function(item) { return item.basics; }); - var guide = sections('guide', function(item) { return !item.basics; }); - var qs = sections('', function(item) { return item.slug === 'quickstart'; })[0] || {}; +- var cliqs = sections('', function(item) { return item.slug === 'cli-quickstart'; })[0] || {}; - var reference = sections('', function(item) { return item.reference; }); - var anyItemSelected = function(items) { - var selectedCount = items.filter(function(item) { return !!item.class; }).length; -- return selectedCount > 0 ? 'is-nav-title-selected' : ''; +- return selectedCount > 0 ? 'is-selected' : ''; - } - var isQuickstartSelected = function() { - var splitted = cur.split('/'); - var bit = splitted[splitted.length - 1].replace('.html', ''); -- return bit === 'quickstart' ? 'is-nav-title-selected' : ''; +- return bit === 'quickstart' ? 'is-selected' : ''; +-} +- var isCLIQuickstartSelected = function() { +- var split = cur.split('/'); +- var bit = split[split.length - 1].replace('.html', ''); +- return bit === 'cli-quickstart' ? 'is-selected' : ''; -} - var isApiReferenceSelected = function() { - var splitted = cur.split('/'); - var bit = splitted[splitted.length - 2]; -- return bit === 'api' ? 'is-nav-title-selected' : ''; +- return bit === 'api' ? 'is-selected' : ''; -} - var isCollapsed = function(titleStyle) { -- return titleStyle === 'is-nav-title-selected' ? '' : 'is-hidden'; +- return titleStyle === 'is-selected' ? '' : 'is-hidden'; - } -nav.side-nav.l-pinned-left.l-layer-4.l-offset-nav +- var language = current.path[1] || 'ts' +- if (language !== 'ts' || language !== 'js' || language !== 'dart') { language = 'ts'; } + + +nav(class="sidenav l-pinned-left l-layer-4 l-offset-nav" data-swiftype-index="false" ng-class="appCtrl.showDocsNav ? 'is-visible' : ''") // SEARCH BAR - header.side-nav-search.st-input-wrapper - form.st-input-inner + header.sidenav-search.st-input-wrapper + .st-input-inner label(for="search-io" class="is-hidden") Search Docs - input(type="search" id="search-io" placeholder="SEARCH DOCS...") + input(type="text" class="st-default-search-input" placeholder="SEARCH DOCS...") button(class="mobile-trigger button" aria-label="View Docs Menu" ng-click="appCtrl.toggleDocsMenu($event)" md-button) Docs - div(class="side-nav-secondary" ng-class="appCtrl.showDocsNav ? 'is-visible' : ''") - .nav-blocks + ul(class="sidenav-links") + li.sidenav-section.no-border + a(class="nav-title" href="/docs/#{current.path[1]}/latest/") Docs Home + + // CORE DOCUMENTATION + li.sidenav-section-divider + h3 Core Documentation + + li.sidenav-section a(class="nav-title #{isQuickstartSelected(cur)}" href="#{qs.href}" title="#{qs.tooltip}") Quickstart - .nav-blocks - a(class="nav-title #{anyItemSelected(tutorial)}" href="#{tutorial[0].href}" title="#{tutorial[0].tooltip}") Tutorial - img(class="inline-arrow-down-svg" src="/resources/images/icons/ic_keyboard_arrow_down_black_24px.svg") - .nav-ordered-lists(class="#{isCollapsed(anyItemSelected(tutorial))}") - ul - each item, index in tutorial - li(class="nav-list-item #{item.class}"): a(href="#{item.href}" title="#{item.tooltip}") #{index + 1}. #{item.navTitle} + li.sidenav-section + a(class="nav-title #{isCLIQuickstartSelected(cur)}" href="#{cliqs.href}" title="#{cliqs.tooltip}") CLI Quickstart + - .nav-blocks - a(class="nav-title #{anyItemSelected(basics)}" href="#{basics[0].href}" title="#{basics[0].tooltip}") Basics + li.sidenav-section + a(class="nav-title is-parent #{anyItemSelected(basics)}" href="#{basics[0].href}" title="#{basics[0].tooltip}") Guide img(class="inline-arrow-down-svg" src="/resources/images/icons/ic_keyboard_arrow_down_black_24px.svg") .nav-ordered-lists(class="#{isCollapsed(anyItemSelected(basics))}") ul each item, index in basics li(class="nav-list-item #{item.class}"): a(href="#{item.href}" title="#{item.tooltip}") #{index + 1}. #{item.navTitle} + li.sidenav-section.no-border + a(class="nav-title #{isApiReferenceSelected()}" href="#{reference[0].href}" title="#{reference[0].tooltip}") API Reference + + // ADVANCED DOCUMENATION + li.sidenav-section-divider + h3 Additional Documentation + + li.sidenav-section + a(class="nav-title is-parent #{anyItemSelected(tutorial)}" href="#{tutorial[0].href}" title="#{tutorial[0].tooltip}") Tutorial + img(class="inline-arrow-down-svg" src="/resources/images/icons/ic_keyboard_arrow_down_black_24px.svg") + .nav-ordered-lists(class="#{isCollapsed(anyItemSelected(tutorial))}") + ul + each item, index in tutorial + li(class="nav-list-item #{item.class}"): a(href="#{item.href}" title="#{item.tooltip}") #{index + 1}. #{item.navTitle} - .nav-blocks - a(class="nav-title #{anyItemSelected(guide)}" href="#{guide[0].href}" title="#{guide[0].tooltip}") Developer Guide + li.sidenav-section + a(class="nav-title is-parent #{anyItemSelected(guide)}" href="#{guide[0].href}" title="#{guide[0].tooltip}") Advanced img(class="inline-arrow-down-svg" src="/resources/images/icons/ic_keyboard_arrow_down_black_24px.svg") .nav-unordered-lists(class="#{isCollapsed(anyItemSelected(guide))}") @@ -94,8 +121,8 @@ nav.side-nav.l-pinned-left.l-layer-4.l-offset-nav each item in guide li(class="nav-list-item #{item.class}"): a(href="#{item.href}" title="#{item.tooltip}") #{item.navTitle} - .nav-blocks - a(class="nav-title #{anyItemSelected(cookbook)}" href="#{cookbook[0].href}" title="#{cookbook[0].tooltip}") Cookbook + li.sidenav-section + a(class="nav-title is-parent #{anyItemSelected(cookbook)}" href="#{cookbook[0].href}" title="#{cookbook[0].tooltip}") Cookbook img(class="inline-arrow-down-svg" src="/resources/images/icons/ic_keyboard_arrow_down_black_24px.svg") .nav-unordered-lists(class="#{isCollapsed(anyItemSelected(cookbook))}") @@ -103,16 +130,20 @@ nav.side-nav.l-pinned-left.l-layer-4.l-offset-nav each item in cookbook li(class="nav-list-item #{item.class}"): a(href="#{item.href}" title="#{item.tooltip}") #{item.navTitle} - .nav-blocks - a(class="nav-title #{isApiReferenceSelected()}" href="#{reference[0].href}" title="#{reference[0].tooltip}") API Reference + + + + if current.path[0] == "docs" + != partial("../../_includes/_version-dropdown") + script. // Could put in appCtrl but only needed here and clear here (function scrollToSelectedLink() { - var sideNav = document.getElementsByClassName('side-nav')[0]; + var sideNav = document.getElementsByClassName('sidenav')[0]; var link = sideNav.getElementsByClassName('is-selected')[0]; if(link && link.offsetTop > window.innerHeight){ sideNav.scrollTop = link.offsetTop - (window.innerHeight/2); //alert("offsetTop: " + link.offsetTop + " side-nav top is " + sideNav.scrollTop); } - })() \ No newline at end of file + })() diff --git a/public/docs/_includes/_ts-temp.jade b/public/docs/_includes/_ts-temp.jade index b4a6b8ad8a..7c162672f4 100644 --- a/public/docs/_includes/_ts-temp.jade +++ b/public/docs/_includes/_ts-temp.jade @@ -8,26 +8,9 @@ if language == 'js' if language == 'ts' - lang = 'TypeScript' -- var page = '' -if current.path[4] - - var page = current.path[4] + '.html' - +- var page = current.path[4] ? current.path[4] + '.html' : '' +- if (page === 'index.html') page = '' - var path = '/docs/ts/latest/'+ current.path[3] + '/' + page - -- var name = 'it' -- var secondaryPath = public.docs[current.path[1]][current.path[2]][current.path[3]] -if secondaryPath - - var data = secondaryPath._data - - var listType = data._listtype - - var items = listType == 'api' ? secondaryPath : data - - for item, slug in items - if slug == current.path[4] - - name = 'the ' + item.title + ' chapter' - -p. - This chapter is not yet available in #{lang}. - We recommend reading the TypeScript version. -a(href=path, class='md-primary md-button md-ink-ripple'). - Read !{name} in TypeScript -// != partial(path) \ No newline at end of file +:marked + This page is not yet available in #{lang}. + We recommend reading [it in TypeScript](!{path}). \ No newline at end of file diff --git a/public/docs/_includes/styleguide/_code-examples.jade b/public/docs/_includes/styleguide/_code-examples.jade index 8291c74e59..c92cb84cd9 100644 --- a/public/docs/_includes/styleguide/_code-examples.jade +++ b/public/docs/_includes/styleguide/_code-examples.jade @@ -45,14 +45,14 @@ include ../../../_includes/_util-fns #### Example: code-example(format="linenums" language="js"). - +makeExample('styleguide/js/index.html', null, 'index.html') + +makeExample('styleguide/js/src/index.html', null, 'index.html') :marked - This will read the *_examples/styleguide/js/index.html* file and include it + This will read the *_examples/styleguide/js/src/index.html* file and include it with the heading 'index.html'. Note that the file will be properly escaped and color coded according to the extension on the file ( html in this case). - +makeExample('styleguide/js/index.html', null, 'index.html') + +makeExample('styleguide/js/src/index.html', null, 'index.html') :marked The second parameter with a value of 'null' will be described later in this document. @@ -69,12 +69,12 @@ include ../../../_includes/_util-fns #### Example: code-example(format="linenums" language="js"). - +makeTabs('styleguide/js/index.html, styleguide/js/spec.js', null, 'index.html,unit test') + +makeTabs('styleguide/js/src/index.html, styleguide/js/spec.js', null, 'index.html,unit test') :marked This will create two tabs, each with its own title and appropriately color coded. - +makeTabs('styleguide/js/index.html, styleguide/js/spec.js', null, 'index.html,unit test') + +makeTabs('styleguide/js/src/index.html, styleguide/js/spec.js', null, 'index.html,unit test') :marked @@ -116,7 +116,7 @@ include ../../../_includes/_util-fns selector: 'my-app', // #enddocregion component // #docregion view - template: '

    My First Angular 2 App

    ' + template: '

    My First Angular App

    ' }) // #enddocregion view // #docregion class @@ -143,7 +143,7 @@ include ../../../_includes/_util-fns // #enddocregion twoparts, import @Component({ selector: 'my-app', - template: '

    My first Angular 2 App

    ' + template: '

    My first Angular App

    ' }) class AppComponent { } @@ -160,7 +160,6 @@ include ../../../_includes/_util-fns code-example(format="linenums" language="html"). <!-- #docregion --> ... - <script src="https://code.angularjs.org/2.0.0-beta.7/angular2.sfx.dev.js"></script> <script src="app.js"></script> ... @@ -183,13 +182,13 @@ include ../../../_includes/_util-fns #### Example code-example(format="linenums" language="js"). - +makeExample('styleguide/js/app.js', 'class-w-annotations', "Extracted region") + +makeExample('styleguide/js/src/app.js', 'class-w-annotations', "Extracted region") :marked is a request to include just the `class-w-annotations` region from the `app.js` file in the `_examples/styleguide` folder and results in the following: - +makeExample('styleguide/js/app.js', 'class-w-annotations', "Extracted region") + +makeExample('styleguide/js/src/app.js', 'class-w-annotations', "Extracted region") :marked @@ -209,7 +208,7 @@ include ../../../_includes/_util-fns #### Example code-example(format="linenums" language="js" escape="none"). - +makeExample('styleguide/js/index.html', null, 'index.html', {pnk: /script (src=.*&quot;)/g}) + +makeExample('styleguide/js/src/index.html', null, 'index.html', {pnk: /script (src=.*&quot;)/g}) :marked Which will mark all of the quoted contents of each `script` tag within the index.html file in pink. @@ -218,20 +217,20 @@ include ../../../_includes/_util-fns Note that expression replacement occurs AFTER the fragment has been included and html escaped. This means that your regular expression must use escaped html text; i.e. the '&quot' in the regex above. - +makeExample('styleguide/js/index.html', null, 'index.html', {pnk: /script (src=.*")/g}) + +makeExample('styleguide/js/src/index.html', null, 'src/index.html', {pnk: /script (src=.*")/g}) :marked A more complicated example might be: code-example(format="linenums" language="js"). - var stylePattern = { pnk: /script (src=.*&quot;)/g, otl: /(\S*my-app.*$)/m }; - +makeExample('styleguide/js/index.html', null, 'index.html', stylePattern ) + +makeExample('styleguide/js/src/index.html', null, 'index.html', stylePattern ) :marked Which applies multiple styles and uses an intermediate javascript object as opposed to a literal. - var stylePattern = { pnk: /script (src=.*")/g, otl: /(\S*my-app.*$)/m }; - +makeExample('styleguide/js/index.html', null, 'index.html', stylePattern ) + +makeExample('styleguide/js/src/index.html', null, 'index.html', stylePattern ) :marked `makeTabs` support for `stylePatterns` is slightly different from the `makeExample` mixin in that you can also @@ -240,10 +239,10 @@ include ../../../_includes/_util-fns code-example(format="linenums" language="js"). -var stylePatterns = [{ pnk: /script (src=.*&quot;)/g }, {pnk: /(result)/ }]; - +makeTabs('styleguide/js/index.html, styleguide/js/spec.js', null, 'index.html,unit test', stylePatterns) + +makeTabs('styleguide/js/src/index.html, styleguide/js/spec.js', null, 'index.html,unit test', stylePatterns) -var stylePatterns = [{ pnk: /script (src=.*")/g }, {pnk: /(result)/ }]; - +makeTabs('styleguide/js/index.html, styleguide/js/spec.js', null, 'index.html,unit test', stylePatterns) + +makeTabs('styleguide/js/src/index.html, styleguide/js/spec.js', null, 'index.html,unit test', stylePatterns) :marked @@ -285,19 +284,9 @@ include ../../../_includes/_util-fns Styling selected portions of the json is also supported. code-example(format="" language="js"). - +makeJson('styleguide/package.1.json', {paths: 'dependencies'}, "package.json dependencies", { pnk: [/(\S*traceur.*)/, /(\Sangular2.*)/, /(\Ssystem.*)/ ]}) + +makeJson('styleguide/package.1.json', {paths: 'dependencies'}, "package.json dependencies", { pnk: [/(\S*zone.*)/, /(\Score-js.*)/, /(\Ssystem.*)/ ]}) - +makeJson('styleguide/package.1.json', {paths: 'dependencies'}, "package.json dependencies", { pnk: [/(\S*traceur.*)/, /(\Sangular2.*)/, /(\Ssystem.*)/ ]}) - - :marked - As well as styling across multiple lines. - - code-example(format="" language="js"). - - var styles = { pnk: /(^.*dependencies[\s\S]* \})/gm }; - +makeJson('styleguide/package.1.json', {paths: 'name, version, dependencies '}, "Foo", styles ) - - - var styles = { pnk: /(^.*dependencies[\s\S]* \})/gm }; - +makeJson('styleguide/package.1.json', {paths: 'name, version, dependencies '}, "Foo", styles ) + +makeJson('styleguide/package.1.json', {paths: 'dependencies'}, "package.json dependencies", { pnk: [/(\S*zone.*)/, /(\Score-js.*)/, /(\Ssystem.*)/ ]}) :marked ### Inline code and code examples provided directly i.e. not from an example file. @@ -308,10 +297,10 @@ include ../../../_includes/_util-fns This style has several named attributes #### code-example attributes - - *name:* Name displayed in Tab (required for tabs) - - *language:* javascript, html, etc. - - *escape:* html (escapes html, woot!) - - *format:* linenums (or linenums:4 specify starting line) + * *name:* Name displayed in Tab (required for tabs) + * *language:* javascript, html, etc. + * *escape:* html (escapes html, woot!) + * *format:* linenums (or linenums:4 specify starting line) #### Example @@ -394,20 +383,20 @@ include ../../../_includes/_util-fns #### Example code-example(). - +makeExample('styleguide/js/app.js', "class-w-annotations")(format="linenums:15") + +makeExample('styleguide/js/src/app.js', "class-w-annotations")(format="linenums:15") :marked Starts the numbering of the example at line 15. - +makeExample('styleguide/js/app.js', "class-w-annotations")(format="linenums:15") + +makeExample('styleguide/js/src/app.js', "class-w-annotations")(format="linenums:15") :marked Or to suppress line numbering completely you can use code-example(). - +makeExample('styleguide/js/app.js', 'class-w-annotations')(format=".") + +makeExample('styleguide/js/src/app.js', 'class-w-annotations')(format=".") - +makeExample('styleguide/js/app.js', 'class-w-annotations')(format=".") + +makeExample('styleguide/js/src/app.js', 'class-w-annotations')(format=".") :marked @@ -422,7 +411,7 @@ include ../../../_includes/_util-fns .alert.is-important. The '@example' and '@exampleTabs' inline tags MUST always appear at the beginning of a line. - Example files referenced by inline tags are all assumed to be in the 'modules/angular2' folder in the angular/angular repo. + Example files referenced by inline tags are all assumed to be in the 'modules/@angular' folder in the angular/angular repo. :marked #### @example inline tag parameters diff --git a/public/docs/_includes/styleguide/_images.jade b/public/docs/_includes/styleguide/_images.jade new file mode 100644 index 0000000000..9643229235 --- /dev/null +++ b/public/docs/_includes/styleguide/_images.jade @@ -0,0 +1,10 @@ +#sg-images.showcase.shadow-1 + header.showcase-header + h2 Images + p. + To maintain visual consistency across documentation chapters, please follow the best + practices for authors outlined in the Image + Guide. + p. + The browser background template used for outlining screenshots is here. diff --git a/public/docs/_includes/styleguide/_styleguide.jade b/public/docs/_includes/styleguide/_styleguide.jade index b4db92940a..36684a8841 100644 --- a/public/docs/_includes/styleguide/_styleguide.jade +++ b/public/docs/_includes/styleguide/_styleguide.jade @@ -1,10 +1,11 @@ .grid-fluid .c10 - != partial("_layouts") - != partial("_code-examples") - != partial("_alerts") - != partial("_callouts") - != partial("_tables") - != partial("_aside") + include _layouts + include _code-examples + include _alerts + include _callouts + include _tables + include _aside + include _images -//!= partial("_jump-nav") +//include _jump-nav diff --git a/public/docs/_includes/styleguide/_tables.jade b/public/docs/_includes/styleguide/_tables.jade index bc370e5250..738a8dc873 100644 --- a/public/docs/_includes/styleguide/_tables.jade +++ b/public/docs/_includes/styleguide/_tables.jade @@ -15,15 +15,15 @@ th Task th Speed tr - td Angular 1.3 + td AngularJS v.1.3 td Routing td fast tr - td Angular 1.4 + td AngularJS v.1.4 td Routing td faster tr - td Angular 2 + td Angular td Routing td fastest :) @@ -35,6 +35,6 @@ th Task th Speed tr - td Angular 1.3 + td AngularJS v.1.3 td Routing td fast diff --git a/public/docs/_layout-dart-api.jade b/public/docs/_layout-dart-api.jade new file mode 100644 index 0000000000..cded545a26 --- /dev/null +++ b/public/docs/_layout-dart-api.jade @@ -0,0 +1,52 @@ +//- WARNING: _layout.jade and _layout-dart-api.jade should match in terms of content +//- except that one uses Harp partial/yield and the other uses Jade extends/include. +if jade2ng + .side-nav--offset + link(rel="stylesheet" href="/assets/css/vendor/dartdoc/bootstrap.min.css") + link(rel="stylesheet" href="/assets/css/vendor/dartdoc/styles.css") + include ../_includes/_hero + include ../_includes/_banner + .l-content-small.grid-fluid.docs-content + block main-content +else + doctype + html(lang="en" ng-app="angularIOApp" itemscope itemtype="http://schema.org/Framework") + // template: public/docs/_layout-dart-api + head + include ../_includes/_head-include + link(rel="stylesheet" href="/resources/css/vendor/dartdoc/bootstrap.min.css") + link(rel="stylesheet" href="/resources/css/vendor/dartdoc/styles.css") + block head-extra + + block var-def + body(class="l-offset-nav l-offset-side-nav" ng-controller="AppCtrl as appCtrl") + include ../_includes/_main-nav + if current.path[2] + include _includes/_side-nav + include ../_includes/_hero + include ../_includes/_banner + + if current.path[3] == 'api' + if current.path[4] == 'index' + block main-content + else + article(class="l-content-small grid-fluid docs-content") + block main-content + else if current.path.indexOf('cheatsheet') > 0 + block main-content + else + if current.path[3] == 'index' || current.path[3] == 'styleguide' + article(class="l-content-small grid-fluid docs-content") + block main-content + else + article(class="l-content-small grid-fluid docs-content") + div(class="c10") + .showcase + .showcase-content + block main-content + if (current.path[3] == 'guide' || current.path[3] == 'tutorial') && current.path[4] + include ../_includes/_next-item + + include ../_includes/_footer + include ../_includes/_scripts-include + include ../_includes/_scripts-minimum \ No newline at end of file diff --git a/public/docs/_layout.jade b/public/docs/_layout.jade index e277180fa0..a59a28af1d 100644 --- a/public/docs/_layout.jade +++ b/public/docs/_layout.jade @@ -1,35 +1,64 @@ -doctype -html(lang="en" ng-app="angularIOApp" itemscope itemtype="http://schema.org/Framework") - head - != partial("../_includes/_head-include") +//- WARNING: _layout.jade and _layout-dart-api.jade should match in terms of content +//- except that one uses Harp partial/yield and the other uses Jade extends/include. - body(class="l-offset-nav l-offset-side-nav" ng-controller="AppCtrl as appCtrl") - != partial("../_includes/_main-nav") - if current.path[2] - != partial("_includes/_side-nav") +- function tsApiHrefToDart(match, hrefApi, dontcare1, urlRest) { +- // Simple argument values: +- // hrefApi: href="../api/ +- // urlRest: core/index/ViewChild-var.html" +- // console.log(`got match on ${match}, 1: ${hrefApi}, 3: ${urlRest}`); +- var matches = urlRest.match(/^(\w*)\/index\/(\w*)-(\w*)(\.html")$/); +- // console.log(`urlRest matches ${matches}`); +- if (!matches) return match; // leave unchanged +- var i = 1; // matches[0] corresponds to the fully matched result +- var libName = matches[i++]; +- var apiPageEntryName = matches[i++]; +- var apiEntryKind = matches[i++]; +- var suffix = matches[i++]; +- return hrefApi + 'angular2.' + libName + '/' + apiPageEntryName + '-class' + suffix; +- } + +if jade2ng + .side-nav--offset != partial("../_includes/_hero") != partial("../_includes/_banner") - - if current.path[3] == 'api' - if current.path[4] == 'index' - != yield - else - article(class="l-content-small grid-fluid docs-content") - != yield - else if current.path.indexOf('cheatsheet') > 0 + .l-content-small.grid-fluid.docs-content != yield - else - if current.path[3] == 'index' || current.path[3] == 'styleguide' - article(class="l-content-small grid-fluid docs-content") +else + doctype + html(lang="en" ng-app="angularIOApp" itemscope itemtype="http://schema.org/Framework") + // template: public/docs/_layout + head + != partial("../_includes/_head-include") + block head-extra + + //- + body(class="l-offset-nav l-offset-side-nav" ng-controller="AppCtrl as appCtrl") + != partial("../_includes/_main-nav") + if current.path[2] + != partial("_includes/_side-nav") + != partial("../_includes/_hero") + != partial("../_includes/_banner") + + if current.path[3] == 'api' + if current.path[4] == 'index' != yield + else + article(class="l-content-small grid-fluid docs-content") + != yield + else if current.path.indexOf('cheatsheet') > 0 + != yield else - article(class="l-content-small grid-fluid docs-content") - div(class="c10") - .showcase - .showcase-content - != yield - if (current.path[3] == 'guide' || current.path[3] == 'tutorial') && current.path[4] - != partial("../_includes/_next-item") + if current.path[3] == 'index' || current.path[3] == 'styleguide' + article(class="l-content-small grid-fluid docs-content") + != yield + else + - var isDart = current.path[1] === 'dart'; + - var regex = /(href=\"(\.?\.\/)*api\/)(.*")/g; + article(class="l-content-small grid-fluid docs-content") + != !isDart ? yield : yield.replace(regex, tsApiHrefToDart) + if (current.path[3] == 'guide' || current.path[3] == 'tutorial') && current.path[4] + != partial("../_includes/_next-item") - != partial("../_includes/_footer") - != partial("../_includes/_scripts-include") \ No newline at end of file + != partial("../_includes/_footer") + != partial("../_includes/_scripts-include") + != partial("../_includes/_scripts-minimum") \ No newline at end of file diff --git a/public/docs/dart/latest/_data.json b/public/docs/dart/latest/_data.json deleted file mode 100644 index 861e707ff1..0000000000 --- a/public/docs/dart/latest/_data.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "index": { - "icon": "home", - "title": "Angular Docs", - "menuTitle": "Docs Home", - "banner": "Welcome to angular.io/dart! The current Angular 2 release is beta.17. Consult the Change Log about recent enhancements, fixes, and breaking changes." - }, - - "quickstart": { - "icon": "query-builder", - "title": "5 Min Quickstart", - "description": "Get up and running with Angular 2" - }, - - "tutorial": { - "icon": "list", - "title": "Tutorial", - "banner": "Angular 2 is currently in Beta." - }, - - "guide": { - "icon": "list", - "title": "Developer Guides", - "banner": "Angular 2 is currently in Beta." - }, - - "cookbook": { - "icon": "list", - "title": "Cookbook", - "banner": "How to solve common implementation challenges." - }, - - "api/": { - "icon": "book", - "title": "API Preview", - "reference": true - }, - - "cheatsheet": { - "title": "Angular Cheat Sheet", - "intro": "A quick guide to Angular syntax.", - "reference": false - }, - - "glossary": { - "title": "Glossary", - "intro": "Brief definitions of the most important words in the Angular 2 vocabulary", - "reference": false - }, - - "resources": { - "icon": "play-circle-fill", - "title": "Angular Resources", - "banner": "Angular 2 is currently in Beta.", - "resources": true - }, - - "help": { - "icon": "chat", - "title": "Help & Support", - "resources": true - }, - - "styleguide": { - "title": "Docs Style Guide", - "intro": "Design & Layout Patterns For Documentation" - } -} diff --git a/public/docs/dart/latest/_util-fns.jade b/public/docs/dart/latest/_util-fns.jade deleted file mode 100644 index 5d54cf117d..0000000000 --- a/public/docs/dart/latest/_util-fns.jade +++ /dev/null @@ -1,67 +0,0 @@ -include ../../../_includes/_util-fns - -//- See the _util-fns file included above for a description of the use of these variables. -- var _docsFor = 'dart'; -- var _decorator = 'annotation'; -- var _Array = 'List'; -- var _array = 'list'; -- var _a = 'an'; -- var _an = 'a'; -- var _priv = '_'; -- var _Lang = 'Dart'; -- var _Promise = 'Future'; -- var _FutureUrl = 'https://api.dartlang.org/dart_async/Future.html'; -- var _PromiseLinked = '' + _Promise + ''; -- var _Observable = 'Stream'; -- var _liveLink = 'sample repo'; -- var _truthy = 'true'; -- var _falsey = 'false'; -- var _appDir = 'lib'; -- var _indexHtmlDir = 'web'; -- var _mainDir = 'web'; - -mixin liveExampleLink(linkText, exampleUrlPartName) - - var text = linkText || 'live example'; - - var ex = exampleUrlPartName || getExampleName(); - - var href = 'http://angular-examples.github.io/' + ex; - a(href='#{href}' target="_blank")= text - -mixin liveExampleLink2(linkText, exampleUrlPartName) - - var srcText = attributes.srcText || 'view source'; - - var ex = exampleUrlPartName || attributes.example || getExampleName(); - - var href = 'http://github.com/angular-examples/' + ex; - span #[+liveExampleLink(linkText, ex)] (#[a(href='#{href}' target="_blank") #{srcText}]) - -- var adjustTsExamplePathForDart = function(_path) { -- if(!_path) return _path; -- var path = _path.trim(); -- var folder = getFolder(path); -- var extn = getExtn(path); -- // if(extn == 'dart') return path; -- var baseName = getBaseFileName(path) || path; // TODO: have getBaseFileName() return path -- var baseNameNoExt = baseName.substr(0,baseName.length - (extn.length + 1)); -- var inWebFolder = baseNameNoExt.match(/^(main|index)(\.\d)?$/); -- // Adjust the folder path, e.g., ts -> dart -- folder = folder.replace(/(^|\/)ts($|\/)/, '$1dart$2').replace(/(^|\/)app($|\/)/, inWebFolder ? '$1web$2' : '$1lib$2'); -- // Special case not handled above: e.g., index.html -> web/index.html -- if(baseNameNoExt.match(/^(index|styles)(\.\d)?$/) && !folder.match(/web$/)) folder = (folder ? folder + '/' : '') + 'web'; -- // In file name, replace special characters with underscore -- baseNameNoExt = baseNameNoExt.replace(/[\-\.]/g, '_'); -- // Adjust the file extension -- if(extn == 'ts') extn = 'dart'; -- return (folder ? folder + '/' : '') + baseNameNoExt + (extn ? '.' + extn : ''); -- }; - -- var adjustTsExampleTitleForDart = function(_title) { -- if(!_title || !adjustTsExamplePathForDart) return _title; -- var title = _title.trim(); -- // Assume title is a path if it ends with an extension like '.foo', -- // optionally followed by some comment in parentheses. -- var matches = title.match(/(.*\.\w+)($|\s*\([\w ]+\)$)/); -- if(matches && matches.length == 3) { -- // e.g. matches == ['abc.ts (excerpt)', 'abc.ts', ' (excerpt)'] -- var path = adjustTsExamplePathForDart(matches[1]); -- title = path + matches[2]; -- } -- return title; -- } diff --git a/public/docs/dart/latest/api/_data.json b/public/docs/dart/latest/api/_data.json deleted file mode 100644 index 4b375156fc..0000000000 --- a/public/docs/dart/latest/api/_data.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "index" : { - "title" : "API 2.0 Preview" - } -} \ No newline at end of file diff --git a/public/docs/dart/latest/api/index.jade b/public/docs/dart/latest/api/index.jade deleted file mode 100644 index c0b081114d..0000000000 --- a/public/docs/dart/latest/api/index.jade +++ /dev/null @@ -1,10 +0,0 @@ -.l-main-section - h2 Beta - - p. - The proposed Angular 2 API does not yet have Dart-specific documentation. - However, because the Dart and JavaScript APIs are generated from the same source, - you might find the JavaScript API docs helpful: - - p.text-center - Angular 2 API Preview (JavaScript) diff --git a/public/docs/dart/latest/cheatsheet.jade b/public/docs/dart/latest/cheatsheet.jade deleted file mode 100644 index 694e02b0d2..0000000000 --- a/public/docs/dart/latest/cheatsheet.jade +++ /dev/null @@ -1,7 +0,0 @@ -- var base = current.path[4] ? '.' : './guide'; -.banner.grid-fluid - p.text-body.c10 This cheat sheet is provisional and may change. Angular 2 is currently in Beta. - -article(class="l-content-small grid-fluid docs-content") - .cheatsheet - ngio-cheatsheet(src= base + '/cheatsheet.json') diff --git a/public/docs/dart/latest/cookbook/_data.json b/public/docs/dart/latest/cookbook/_data.json deleted file mode 100644 index 9b2545ec5e..0000000000 --- a/public/docs/dart/latest/cookbook/_data.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "index": { - "title": "Cookbook", - "navTitle": "Overview", - "intro": "A collection of recipes for common Angular application scenarios" - }, - - "a1-a2-quick-reference": { - "title": "Angular 1 to 2 Quick Reference", - "navTitle": "Angular 1 to 2 Quick Ref", - "intro": "Learn how Angular 1 concepts and techniques map to Angular 2", - "hide": true - }, - - "component-communication": { - "title": "Component Interaction", - "intro": "Share information between different directives and components" - }, - - "component-relative-paths": { - "title": "Component-relative Paths", - "intro": "Use relative URLs for component templates and styles.", - "hide": true - }, - - "dependency-injection": { - "title": "Dependency Injection", - "intro": "Techniques for Dependency Injection", - "hide": true - }, - - "dynamic-forms": { - "title": "Dynamic Form", - "intro": "Render dynamic forms with NgFormModel", - "hide": true - }, - - "set-document-title": { - "title": "Set the Document Title", - "intro": "Setting the document or window title using the Title service." - }, - - "ts-to-js": { - "title": "TypeScript to JavaScript", - "intro": "Convert Angular 2 TypeScript examples into ES5 JavaScript", - "hide": true - } -} diff --git a/public/docs/dart/latest/cookbook/a1-a2-quick-reference.jade b/public/docs/dart/latest/cookbook/a1-a2-quick-reference.jade deleted file mode 100644 index 6778b6af28..0000000000 --- a/public/docs/dart/latest/cookbook/a1-a2-quick-reference.jade +++ /dev/null @@ -1 +0,0 @@ -!= partial("../../../_includes/_ts-temp") diff --git a/public/docs/dart/latest/cookbook/component-communication.jade b/public/docs/dart/latest/cookbook/component-communication.jade deleted file mode 100644 index 6778b6af28..0000000000 --- a/public/docs/dart/latest/cookbook/component-communication.jade +++ /dev/null @@ -1 +0,0 @@ -!= partial("../../../_includes/_ts-temp") diff --git a/public/docs/dart/latest/cookbook/component-relative-paths.jade b/public/docs/dart/latest/cookbook/component-relative-paths.jade deleted file mode 100644 index 6778b6af28..0000000000 --- a/public/docs/dart/latest/cookbook/component-relative-paths.jade +++ /dev/null @@ -1 +0,0 @@ -!= partial("../../../_includes/_ts-temp") diff --git a/public/docs/dart/latest/cookbook/dependency-injection.jade b/public/docs/dart/latest/cookbook/dependency-injection.jade deleted file mode 100644 index f8df2a84a6..0000000000 --- a/public/docs/dart/latest/cookbook/dependency-injection.jade +++ /dev/null @@ -1 +0,0 @@ -!= partial("../../../_includes/_ts-temp") \ No newline at end of file diff --git a/public/docs/dart/latest/cookbook/dynamic-form.jade b/public/docs/dart/latest/cookbook/dynamic-form.jade deleted file mode 100644 index f8df2a84a6..0000000000 --- a/public/docs/dart/latest/cookbook/dynamic-form.jade +++ /dev/null @@ -1 +0,0 @@ -!= partial("../../../_includes/_ts-temp") \ No newline at end of file diff --git a/public/docs/dart/latest/cookbook/index.jade b/public/docs/dart/latest/cookbook/index.jade deleted file mode 100644 index 6778b6af28..0000000000 --- a/public/docs/dart/latest/cookbook/index.jade +++ /dev/null @@ -1 +0,0 @@ -!= partial("../../../_includes/_ts-temp") diff --git a/public/docs/dart/latest/cookbook/set-document-title.jade b/public/docs/dart/latest/cookbook/set-document-title.jade deleted file mode 100644 index f8df2a84a6..0000000000 --- a/public/docs/dart/latest/cookbook/set-document-title.jade +++ /dev/null @@ -1 +0,0 @@ -!= partial("../../../_includes/_ts-temp") \ No newline at end of file diff --git a/public/docs/dart/latest/cookbook/ts-to-js.jade b/public/docs/dart/latest/cookbook/ts-to-js.jade deleted file mode 100644 index f8df2a84a6..0000000000 --- a/public/docs/dart/latest/cookbook/ts-to-js.jade +++ /dev/null @@ -1 +0,0 @@ -!= partial("../../../_includes/_ts-temp") \ No newline at end of file diff --git a/public/docs/dart/latest/glossary.jade b/public/docs/dart/latest/glossary.jade deleted file mode 100644 index ec8bdf04f3..0000000000 --- a/public/docs/dart/latest/glossary.jade +++ /dev/null @@ -1,33 +0,0 @@ -include _util-fns -// From ts/glossary.jade, the folder ts/latest/_fragments is generated which contains a bunch of partial files. -// These partials comprise the glossary,a subset of these partials should be used to generate the glossary for -// __dart__ under BASICS. -!=partial('../../ts/latest/_fragments/glossary-intro') -!=partial('../../ts/latest/_fragments/glossary-a-2') -!=partial('../../ts/latest/_fragments/glossary-b-c') -!=partial('../../ts/latest/_fragments/glossary-d1') -!=partial('../../ts/latest/_fragments/glossary-d2') -!=partial('../../ts/latest/_fragments/glossary-e1') -!=partial('../../ts/latest/_fragments/glossary-e2') -!=partial('../../ts/latest/_fragments/glossary-f-l') -!=partial('../../ts/latest/_fragments/glossary-m1') -//!=partial('../../ts/latest/_fragments/glossary-m2') not needed in dart -!=partial('../../ts/latest/_fragments/glossary-n-s') -!=partial('../../ts/latest/_fragments/glossary-t1') -//!=partial('../../ts/latest/_fragments/glossary-t2') notneeded in dart -!=partial('../../ts/latest/_fragments/glossary-u-z') - -// NOTE: (ericjim): I am almost certain these lines are doing nothing, -// so instead I use `!=partial` to include the glossary fragments. -//+includeShared('{ts}', 'intro') -//+includeShared('{ts}', 'a2') -//+includeShared('{ts}', 'b-c') -//+includeShared('{ts}', 'd1') -//+includeShared('{ts}', 'd2') -//+includeShared('{ts}', 'e1') -//+includeShared('{ts}', 'e2') -//+includeShared('{ts}', 'f-l') -//+includeShared('{ts}', 'm1') -//+includeShared('{ts}', 'n-s') -//+includeShared('{ts}', 't1') -//+includeShared('{ts}', 'u-z') diff --git a/public/docs/dart/latest/guide/_data.json b/public/docs/dart/latest/guide/_data.json deleted file mode 100644 index eed8cf36a4..0000000000 --- a/public/docs/dart/latest/guide/_data.json +++ /dev/null @@ -1,148 +0,0 @@ -{ - "index": { - "title": "Documentation Overview", - "navTitle": "Overview", - "description": "How to read and use this documentation", - "nextable": true, - "basics": true - }, - - "architecture": { - "title": "Architecture Overview", - "navTitle": "Architecture", - "intro": "The basic building blocks of Angular 2 applications", - "nextable": true, - "basics": true - }, - - "displaying-data": { - "title": "Displaying Data", - "intro": "Interpolation and other forms of property binding help us show app data in the UI.", - "nextable": true, - "basics": true - }, - - "user-input": { - "title": "User Input", - "intro": "User input triggers DOM events. We listen to those events with event bindings that funnel updated values back into our components and models.", - "nextable": true, - "basics": true - }, - - "forms": { - "title": "Forms", - "intro": "A form creates a cohesive, effective, and compelling data entry experience. An Angular form coordinates a set of data-bound user controls, tracks changes, validates input, and presents errors.", - "nextable": true, - "basics": true - }, - - "dependency-injection": { - "title": "Dependency Injection", - "intro": "Angular's dependency injection system creates and delivers dependent services \"just-in-time\".", - "nextable": true, - "basics": true - }, - - "template-syntax": { - "title": "Template Syntax", - "intro": "Learn how to write templates that display data and consume user events with the help of data binding.", - "nextable": true, - "basics": true - }, - - "cheatsheet": { - "title": "Angular Cheat Sheet", - "intro": "A quick guide to Angular syntax.", - "nextable": true, - "basics": true - }, - - "style-guide": { - "title": "Style Guide", - "intro": "Write Angular 2 with style.", - "basics": true - }, - - "attribute-directives": { - "title": "Attribute Directives", - "intro": "Attribute directives attach behavior to elements." - }, - - "component-styles": { - "title": "Component Styles", - "intro": "Learn how to apply CSS styles to components." - }, - - "hierarchical-dependency-injection": { - "title": "Hierarchical Dependency Injectors", - "navTitle": "Hierarchical Injectors", - "intro": "Angular's hierarchical dependency injection system supports nested injectors in parallel with the component tree." - }, - - "server-communication": { - "title": "HTTP Client", - "intro": "Talk to a remote server with an HTTP Client." - }, - - "lifecycle-hooks": { - "title": "Lifecycle Hooks", - "intro": "Angular calls lifecycle hook methods on directives and components as it creates, changes, and destroys them." - }, - - "npm-packages": { - "title": "Npm Packages", - "intro": "Details of the recommended npm packages and the different kinds of package dependencies", - "hide": true - }, - - "pipes": { - "title": "Pipes", - "intro": "Pipes transform displayed values within a template." - }, - - "router-deprecated": { - "title": "Router (Deprecated Beta)", - "intro": "The deprecated Beta Router." - }, - - "router": { - "title": "Routing & Navigation", - "intro": "Discover the basics of screen navigation with the Angular 2 router.", - "hide": true - }, - - "structural-directives": { - "title": "Structural Directives", - "intro": "Angular has a powerful template engine that lets us easily manipulate the DOM structure of our elements." - }, - - "testing": { - "title": "Testing", - "intro": "Techniques and practices for testing an Angular 2 app", - "hide": true - }, - - "typescript-configuration": { - "title": "TypeScript Configuration", - "intro": "TypeScript configuration for Angular 2 developers", - "hide": true - }, - - "upgrade": { - "title": "Upgrading from 1.x", - "intro": "Angular 1 applications can be incrementally upgraded to Angular 2.", - "hide": true - }, - - "webpack": { - "title": "Webpack: an introduction", - "intro": "Create your Angular 2 applications with a Webpack based tooling", - "hide": true - }, - - "glossary": { - "title": "Glossary", - "intro": "Brief definitions of the most important words in the Angular 2 vocabulary", - "basics": true - } -} diff --git a/public/docs/dart/latest/guide/architecture.jade b/public/docs/dart/latest/guide/architecture.jade deleted file mode 100644 index 2c6f1b04bc..0000000000 --- a/public/docs/dart/latest/guide/architecture.jade +++ /dev/null @@ -1,451 +0,0 @@ -include ../_util-fns - -:marked - Angular 2 is a framework to help us build client applications in HTML and - either JavaScript or a language (like Dart or TypeScript) that compiles to JavaScript. - Angular 2 for Dart is published as the `angular2` package, which - (like many other Dart packages) is available via the Pub tool. - - With Angular, we write applications by composing HTML *templates* with Angularized markup, - writing *component* classes to manage those templates, adding application logic in *services*, - and handing the top root component to Angular's *bootstrapper*. - - Angular takes over, presenting our application content in a browser and responding to user interactions - according to the instructions we provided. - - -:marked - Of course there is more to it than this. - We're cruising at high altitude in this overview. - We're looking for landmarks. We should expect the object below to be fuzzy and obscured by occasional clouds. - Details become more clear and precise when we land in the chapters themselves. -
    - -:marked - An Angular 2 for Dart application rests on seven main building blocks: - 1. [Components](#component) - 1. [Templates](#template) - 1. [Metadata](#metadata) - 1. [Data binding](#data-binding) - 1. [Directives](#directive) - 1. [Services](#service) - 1. [Dependency injection](#dependency-injection) - -figure - img(src="/resources/images/devguide/architecture/overview.png" alt="overview" style="margin-left:-40px;" width="700") -:marked - Learn these seven and we're on our way. - -.l-main-section - -:marked - ## Components -figure - img(src="/resources/images/devguide/architecture/hero-component.png" alt="Component" align="left" style="width:200px; margin-left:-40px;margin-right:10px" ) -:marked - A **component** controls a patch of screen real estate that we could call a *view*. - A set of navigation links, a list of heroes, a hero editor ... - they're all views controlled by components. - - We define a component's application logic — what it does to support the view — inside a class. - The class interacts with the view through an API of properties and methods. - - - A `HeroListComponent`, for example, might have a `heroes` property that returns an array of heroes - that it acquired from a service. - It might have a `selectHero()` method that sets a `selectedHero` property when the user clicks to choose a hero from that list. - The component might be a class like this: - -+makeExample('architecture/dart/lib/hero_list_component.dart', 'class', 'lib/hero_list_component.dart') -:marked - Angular creates, updates, and destroys components as the user moves through the application. - The developer can take action at each moment in this lifecycle through optional lifecycle hooks. - - -.l-sub-section - :marked - We may wonder who is calling the component's constructor? Who provides the service parameter? - For the moment, have faith that Angular will call the constructor and deliver an - appropriate `HeroService` when we need it. - -.l-main-section - -:marked - ## Templates -figure - img(src="/resources/images/devguide/architecture/template.png" alt="Template" align="left" style="width:200px; margin-left:-40px;margin-right:10px" ) -:marked - We define a component's view with its companion **template**. A template is a form of HTML - that tells Angular how to render the component. - - A template looks like regular HTML much of the time ... and then it gets a bit strange. Here is a - template for our `HeroListComponent`: -+makeExample('architecture/dart/lib/hero_list_component.html', null, 'lib/hero_list_component.html') -:marked - This template features typical HTML elements like `

    ` and `
    `. - But what are `*ngFor`, {‌{hero.name}}, `(click)`, `[hero]`, and ``? - They're examples of Angular's template syntax. - We'll grow accustomed to that syntax and may even learn to love it. - - Take a look at the last line, - which has the `` tag. - That tag adds a custom element representing a component we haven't seen yet, - a `HeroDetailComponent`. - - The `HeroDetailComponent` is a *different* component than the `HeroListComponent` we've seen. - The `HeroDetailComponent` (code not shown) presents facts about a particular hero, the - hero that the user selects from the list presented by the `HeroListComponent`. - The `HeroDetailComponent` is a **child** of the `HeroListComponent`. - -figure - img(src="/resources/images/devguide/architecture/component-tree.png" alt="Metadata" align="left" style="width:300px; margin-left:-40px;margin-right:10px" ) -:marked - Notice how `` rests comfortably among native HTML elements. - We can and _will_ mix our custom components with native HTML in the same layouts. - - In this manner we'll compose complex component trees to build out our richly featured application. -
    - -.l-main-section - -:marked - ## Metadata -figure - img(src="/resources/images/devguide/architecture/metadata.png" alt="Metadata" align="left" style="width:150px; margin-left:-40px;margin-right:10px" ) -:marked -

    Metadata tells Angular how to process a class.

    -
    -:marked - [Looking back at the code](#component-code) for `HeroListComponent`, we see that it's just a class. - There is no evidence of a framework, no "Angular" in it at all. - - In fact, it really is *just a class*. It's not a component until we *tell Angular about it*. - - We tell Angular that `HeroListComponent` is a component by attaching **metadata** to the class. - - In Dart, we attach metadata by using an **annotation**. - Here's some metadata for `HeroListComponent`: - -+makeExample('architecture/dart/lib/hero_list_component.dart', 'metadata', 'lib/hero_list_component.dart') -:marked - Here we see the `@Component` annotation, which (no surprise) identifies the class - immediately below it as a component class. - - Annotations often have configuration parameters. - The `@Component` annotation takes parameters to provide the - information Angular needs to create and present the component and its view. - - Here we see a few of the possible `@Component` parameters: - - * `selector`: A CSS selector that tells Angular to create and insert an instance of this component - where it finds a `` tag in *parent* HTML. - For example, if an app's HTML contains ``, then - Angular inserts an instance of the `HeroListComponent` view between those tags. - - * `templateUrl`: The address of this component's template, which we showed [above](#the-template). - - * `directives`: An array of the components or directives that *this* template requires. - We saw in the last line of our template that we expect Angular to insert a `HeroDetailComponent` - in the space indicated by `` tags. - Angular will do so only if we mention the `HeroDetailComponent` in this `directives` array. - - * `providers`: An array of **dependency injection providers** for services that the component requires. - This is one way to tell Angular that our component's constructor requires a `HeroService` - so it can get the list of heroes to display. We'll get to dependency injection later. -figure - img(src="/resources/images/devguide/architecture/template-metadata-component.png" alt="Metadata" align="left" style="height:200px; margin-left:-40px;margin-right:10px" ) - -:marked - At runtime, Angular discovers the metadata specified by the `@Component` - annotation. That's how Angular learns how to do "the right thing". - - The template, metadata, and component together describe the view. - - We apply other metadata annotations in a similar fashion to guide Angular behavior. - `@Injectable`, `@Input`, `@Output`, and `@RouterConfig` are a few of the more popular annotations - we'll master as our Angular knowledge grows. -
    -:marked - The architectural takeaway is that we must add metadata to our code - so that Angular knows what to do. - -.l-main-section - -:marked - ## Data binding - Without a framework, we would be responsible for pushing data values into the HTML controls and turning user responses - into actions and value updates. Writing such push/pull logic by hand is tedious, error-prone, and a nightmare to - read as any experienced jQuery programmer can attest. -figure - img(src="/resources/images/devguide/architecture/databinding.png" alt="Data Binding" style="width:220px; float:left; margin-left:-40px;margin-right:20px" ) -:marked - Angular supports **data binding**, - a mechanism for coordinating parts of a template with parts of a component. - We add binding markup to the template HTML to tell Angular how to connect both sides. - - There are four forms of data binding syntax. Each form has a direction — to the DOM, from the DOM, or in both directions — - as indicated by the arrows in the diagram. -
    -:marked - We saw three forms of data binding in our [example](#template) template: -+makeExample('architecture/dart/lib/hero_list_component_1.html', 'binding')(format=".") -:marked - * The {‌{hero.name}} [interpolation](displaying-data.html#interpolation) - displays the component's `hero.name` property value within the `
    ` tags. - - * The `[hero]` property binding - passes the value of `selectedHero` from - the parent `HeroListComponent` to the `hero` property of the child `HeroDetailComponent`. - - * The `(click)` [event binding](user-input.html#click) calls the component's `selectHero` method when the user clicks a hero's name. - - **Two-way data binding** is an important fourth form - that combines property and event binding in a single notation, using the `ngModel` directive. - We didn't have a two-way binding in the `HeroListComponent` template; - here's an example from the `HeroDetailComponent` template: - -+makeExample('architecture/dart/lib/hero_detail_component.html', 'ng-model', 'lib/hero_detail_component.html (excerpt)')(format=".") -:marked - In two-way binding, a data property value flows to the input box from the component as with property binding. - The user's changes also flow back to the component, resetting the property to the latest value, - as with event binding. - - Angular processes *all* data bindings once per JavaScript event cycle, - depth-first from the root of the application component tree. - -figure - img(src="/resources/images/devguide/architecture/component-databinding.png" alt="Data Binding" style="float:left; width:300px; margin-left:-40px;margin-right:10px" ) -:marked - We don't know all the details yet, - but it's clear from these examples that data binding plays an important role in communication - between a template and its component. -
    -figure - img(src="/resources/images/devguide/architecture/parent-child-binding.png" alt="Parent/Child binding" style="float:left; width:300px; margin-left:-40px;margin-right:10px" ) -:marked - Data binding is also important for communication between parent and child components. -
    - -.l-main-section - -:marked - ## Directives -figure - img(src="/resources/images/devguide/architecture/directive.png" alt="Parent child" style="float:left; width:150px; margin-left:-40px;margin-right:10px" ) -:marked - Angular templates are *dynamic*. When Angular renders them, it transforms the DOM - according to the instructions given by **directives**. - - A directive is a class with directive metadata. In Dart we apply the `@Directive` annotation - to attach metadata to the class. -
    -:marked - We already met one form of directive: the component. A component is a *directive-with-a-template*; - a `@Component` annotation is actually a `@Directive` annotation extended with template-oriented features. - -.l-sub-section - :marked - While **a component is technically a directive**, - components are so distinctive and central to Angular applications that we chose - to separate components from directives in this architectural overview. -:marked - Two *other* kinds of directives exist: _structural_ and _attribute_ directives. - - They tend to appear within an element tag like attributes, - sometimes by name but more often as the target of an assignment or a binding. - - **Structural** directives alter layout by adding, removing, and replacing elements in DOM. - - Our [example](#template) template uses two built-in structural directives: -+makeExample('architecture/dart/lib/hero_list_component_1.html', 'structural')(format=".") -:marked - * [`*ngFor`](displaying-data.html#ng-for) tells Angular to stamp out one `
    ` per hero in the `heroes` list. - * [`*ngIf`](displaying-data.html#ng-if) includes the `HeroDetail` component only if a selected hero exists. - -.l-sub-section - :marked - In Dart, **the only value that is true is the boolean value `true`**; all - other values are false. JavaScript and TypeScript, in contrast, treat values - such as 1 and most non-null objects as true. For this reason, the JavaScript - and TypeScript versions of this app can use just `selectedHero` as the value - of the `*ngIf` expression. The Dart version must use a boolean operator such - as `!=` instead. - -:marked - **Attribute** directives alter the appearance or behavior of an existing element. - In templates they look like regular HTML attributes, hence the name. - - The `ngModel` directive, which implements two-way data binding, is - an example of an attribute directive. `ngModel` modifies the behavior of - an existing element (typically an ``) - by setting its display value property and responding to change events. - -+makeExample('architecture/dart/lib/hero_detail_component.html', 'ng-model')(format=".") -:marked - Angular ships with a small number of other directives that either alter the layout structure - (for example, `ngSwitch`) - or modify aspects of DOM elements and components - (for example, `ngStyle` and `ngClass`). - - - Of course, we can also write our own directives. Components such as - `HeroListComponent` are one kind of custom directive. - - -.l-main-section - -:marked - ## Services -figure - img(src="/resources/images/devguide/architecture/service.png" alt="Service" style="float:left; margin-left:-40px;margin-right:10px" ) -:marked - _Services_ is a broad category encompassing any value, function, or feature that our application needs. - - Almost anything can be a service. - A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well. -
    -:marked - Examples include: - * logging service - * data service - * message bus - * tax calculator - * application configuration - - There is nothing specifically _Angular_ about services. Angular itself has no definition of a service. - There is no service base class, and no place to register a service. - - Yet services are fundamental to any Angular application. Our components are big consumers of services. - - We prefer our component classes lean. Our components don't fetch data from the server, - they don't validate user input, and they don't log directly to console. They delegate such tasks to services. - - A component's job is to enable the user experience and nothing more. It mediates between the view (rendered by the template) - and the application logic (which often includes some notion of a _model_). - A good component presents properties and methods for data binding. - It delegates everything nontrivial to services. - - Angular doesn't *enforce* these principles. - It won't complain if we write a "kitchen sink" component with 3000 lines. - - Angular does help us *follow* these principles by making it easy to factor our - application logic into services and make those services available to components through *dependency injection*. - -.l-main-section - -:marked - ## Dependency injection -figure - img(src="/resources/images/devguide/architecture/dependency-injection.png" alt="Service" style="float:left; width:200px; margin-left:-40px;margin-right:10px" ) -:marked - Dependency injection is a way to supply a new instance of a class - with the fully-formed dependencies it requires. Most dependencies are services. - Angular uses dependency injection to provide new components with the services they need. -
    -:marked - Angular can tell which services a component needs by looking at the types of its constructor parameters. - For example, the constructor of our `HeroListComponent` needs a `HeroService`: -+makeExample('architecture/dart/lib/hero_list_component.dart', 'ctor', 'lib/hero_list_component.dart (excerpt)')(format='.') -:marked - When Angular creates a component, it first asks an **injector** for - the services that the component requires. - - An injector maintains a container of service instances that it has previously created. - If a requested service instance is not in the container, the injector makes one and adds it to the container - before returning the service to Angular. - When all requested services have been resolved and returned, - Angular can call the component's constructor with those services as arguments. - This is what we mean by *dependency injection*. - - The process of `HeroService` injection looks a bit like this: -figure - img(src="/resources/images/devguide/architecture/injector-injects.png" alt="Service" ) -:marked - If the injector doesn't have a `HeroService`, how does it know how to make one? - - In brief, we must have previously registered a **provider** of the `HeroService` with the injector. - A provider is something that can create or return a service, typically the service class itself. - - We can register providers at any level of the application component tree. - We often do so at the root when we bootstrap the application so that - the same instance of a service is available everywhere. -+makeExample('architecture/dart/web/main.dart', 'bootstrap', 'web/main.dart (excerpt)')(format='.') -:marked - Alternatively, we might register at a component level: -+makeExample('architecture/dart/lib/hero_list_component.dart', 'providers', 'lib/hero_list_component.dart (excerpt)')(format='.') -:marked - Registering at a component level means we get a new instance of the - service with each new instance of that component. - - - - Points to remember about dependency injection: - - * Dependency injection is wired into the Angular framework and used everywhere. - - * The *injector* is the main mechanism. - * An injector maintains a *container* of service instances that it created. - * An injector can create a new service instance from a *provider*. - - * A *provider* is a recipe for creating a service. - - * We register *providers* with injectors. - - -.l-main-section -:marked - ## Other stuff - - We've learned just a bit about the seven main building blocks of an Angular application: - 1. [Components](#component) - 1. [Templates](#template) - 1. [Metadata](#metadata) - 1. [Data binding](#data-binding) - 1. [Directives](#directive) - 1. [Services](#service) - 1. [Dependency injection](#dependency-injection) - - That's a foundation for everything else in an Angular application, - and it's more than enough to get going. - But it doesn't include everything we'll need or want to know. - - Here is a brief, alphabetical list of other important Angular features and services. - Most of them are covered in this Developers Guide (or soon will be). - - >**Animations:** A forthcoming animation library makes it easy for developers to animate component behavior - without deep knowledge of animation techniques or CSS. - - >**Bootstrap:** A method to configure and launch the root application component. - - >**Change detection:** Learn how Angular decides that a component property value has changed and - when to update the screen. - Learn how it uses **zones** to intercept asynchronous activity and run its change detection strategies. - - >**Component router:** With the component Router service, users can navigate a multi-screen application - in a familiar web browsing style using URLs. - - >**Events:** The DOM raises events. So can components and services. Angular offers mechanisms for - publishing and subscribing to events including an implementation of the [RxJS Observable](https://github.com/zenparsing/es-observable) proposal. - - >**[Forms](forms.html):** Support complex data entry scenarios with HTML-based validation and dirty checking. - - >**HTTP:** Communicate with a server to get data, save data, and invoke server-side actions with this Angular HTTP client. - - >**Lifecycle hooks:** We can tap into key moments in the lifetime of a component, from its creation to its destruction, - by implementing the lifecycle hook interfaces. - - >**Pipes:** Services that transform values for display. - We can put pipes in our templates to improve the user experience. Consider - this `currency` pipe expression: -
    -code-example(language="javascript" linenumbers="."). - price | currency:'USD':true' -
    -:marked - >It displays a price of "42.33" as `$42.33`. - - >**Testing:** Angular provides a - [testing library](https://pub.dartlang.org/packages/angular2_testing) - to run unit tests on our application parts as they interact with the Angular framework. diff --git a/public/docs/dart/latest/guide/attribute-directives.jade b/public/docs/dart/latest/guide/attribute-directives.jade deleted file mode 100644 index 350cd60b88..0000000000 --- a/public/docs/dart/latest/guide/attribute-directives.jade +++ /dev/null @@ -1,9 +0,0 @@ -extends ../../../ts/latest/guide/attribute-directives.jade - -block includes - include ../_util-fns - -block highlight-directive-1 - :marked - We begin by importing the Angular `core`. - Then we define the directive metadata by means of the `@Directive` annotation. diff --git a/public/docs/dart/latest/guide/cheatsheet.jade b/public/docs/dart/latest/guide/cheatsheet.jade deleted file mode 100644 index ff8cc6085c..0000000000 --- a/public/docs/dart/latest/guide/cheatsheet.jade +++ /dev/null @@ -1 +0,0 @@ -!= partial("../cheatsheet") diff --git a/public/docs/dart/latest/guide/component-styles.jade b/public/docs/dart/latest/guide/component-styles.jade deleted file mode 100644 index 71507a7d01..0000000000 --- a/public/docs/dart/latest/guide/component-styles.jade +++ /dev/null @@ -1,36 +0,0 @@ -extends ../../../ts/latest/guide/component-styles.jade - -block includes - include ../_util-fns - -//- TODO: consider adding material equivalent to TS Appendices 1 & 2 if relevant. - -block style-url - :marked - Note that the URLs in `styleUrls` are relative to the component. - -block module-bundlers - //- TODO: determine if an equivalent of the TS material is relevant for Dart. - //- Leaving empty for now. - -block css-import-url - :marked - In *this* case the URL is relative to the CSS file into which we are importing. - .alert.is-important - :marked - URLs are currently not interpreted in this way, see - [issue 8518](href="https://github.com/angular/angular/issues/8518"). - Until this issue is fixed, absolute package-reference style URLs must - be given as is illustrated below. - -block module-id - p. - Thankfully, this is the default interpretation of relative URLs in - Angular2 for Dart: - +makeExample('component-styles/ts/app/quest-summary.component.ts', 'urls')(format='.') - :marked - Note that special measures must be taken in Angular2 for TypeScript, if - relative URLs are to have the same interpretation. See - [here](../../../ts/latest/guide/component-styles.html#!#relative-urls) - for details. - diff --git a/public/docs/dart/latest/guide/dependency-injection.jade b/public/docs/dart/latest/guide/dependency-injection.jade deleted file mode 100644 index 0f991c5673..0000000000 --- a/public/docs/dart/latest/guide/dependency-injection.jade +++ /dev/null @@ -1,133 +0,0 @@ -extends ../../../ts/latest/guide/dependency-injection.jade - -block includes - include ../_util-fns - - var _thisDot = ''; - -block ctor-syntax - .l-sub-section - :marked - We also leveraged Dart's constructor syntax for declaring parameters and - initializing properties simultaneously. - -block service-in-its-own-file - //- N/A - -block one-class-per-file-ts-tradeoffs - //- N/A - -block injectable-not-always-needed-in-ts - //- The [Angular 2 Dart Transformer](https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer) - //- generates static code to replace the use of dart:mirrors. It requires that types be - //- identified as targets for static code generation. Generally this is achieved - //- by marking the class as @Injectable (though there are other mechanisms). - -block ts-any-decorator-will-do - //- N/A - -block always-include-paren - :marked - Always write `@Injectable()`, not just `@Injectable`. - A metadata annotation must be either a reference to a - compile-time constant variable or a call to a constant - constructor such as `Injectable()`. - - If we forget the parentheses, the analyzer will complain: - "Annotation creation must have arguments". If we try to run the - app anyway, it won't work, and the console will say - "expression must be a compile-time constant". - -block real-logger - .l-sub-section - :marked - A real implementation would probably use the - [logging package](https://pub.dartlang.org/packages/logging). - -block optional-logger - //- TBC. - -block provider-ctor-args - - var _secondParam = 'named parameter, such as useClass' - :marked - We supply two arguments (or more) to the `Provider` constructor. - -block dart-diff-const-metadata - .callout.is-helpful - header Dart difference: Constants in metadata - :marked - In Dart, the value of a metadata annotation must be a compile-time constant. - For that reason, we can't call functions to get values - to use within an annotation. - Instead, we use constant literals or constant constructors. - For example, a TypeScript program will use the - object literal `{ provide: Logger, useClass: BetterLogger }`. - A Dart annotation would instead use the constant value `const Provider(Logger, useClass: BetterLogger)`. - -block dart-diff-const-metadata-ctor - .callout.is-helpful - header Dart difference: Constants in metadata - :marked - Because Dart annotations must be compile-time constants, - `useValue` is often used with string or list literals. - However, `useValue` works with any constant object. - - To create a class that can provide constant objects, - ensure all its instance variables are `final`, - and give it a `const` constructor. - - Create a constant instance of the class by using `const` instead of `new`. - -// - var stylePattern = { otl: /(useValue.*\))/gm }; -// +makeExample('dependency-injection/dart/lib/providers_component.dart','providers-9','', stylePattern)(format='.') - -block non-class-dep-eg - span string, list, map, or maybe a function. - -block config-obj-maps - | . They can be - | Map - | literals - -block what-should-we-use-as-token - :marked - But what should we use as the token? - While we _could_ use **[Map][]**, we _should not_ because (like - `String`) `Map` is too general. Our app might depend on several maps, each - for a different purpose. - - [Map]: https://api.dartlang.org/stable/dart-core/Map-class.html - - .callout.is-helpful - header Dart difference: Interfaces are valid tokens - :marked - In TypeScript, interfaces don't work as provider tokens. - Dart doesn't have this limitation; - every class implicitly defines an interface, - so interface names are just class names. - `Map` is a *valid* token even though it's the name of an abstract class; - it's just *unsuitable* as a token because it's too general. - -block dart-map-alternative - :marked - As an alternative to using a configuration `Map`, we can define - a custom configuration class: - - +makeExample('dependency-injection/ts/app/app.config.ts','config-alt','app/app-config.ts (alternative config)')(format='.') - - :marked - Defining a configuration class has a few benefits. One key benefit - is strong static checking: we'll be warned early if we misspell a property - name or assign it a value of the wrong type. - The Dart [cascade notation][cascade] (`..`) provides a convenient means of initializing - a configuration object. - - If we use cascades, the configuration object can't be declared `const` and - we can't use a [value provider](#value-provider). - A solution is to use a [factory provider](#factory-provider). - We illustrate this next. We also show how to provide and inject the - configuration object in our top-level `AppComponent`: - - [cascade]: https://www.dartlang.org/docs/dart-up-and-running/ch02.html#cascade - - +makeExcerpt('lib/app_component.dart','providers') - +makeExcerpt('lib/app_component.dart','ctor') diff --git a/public/docs/dart/latest/guide/displaying-data.jade b/public/docs/dart/latest/guide/displaying-data.jade deleted file mode 100644 index 6e8b96f3c3..0000000000 --- a/public/docs/dart/latest/guide/displaying-data.jade +++ /dev/null @@ -1,257 +0,0 @@ -include ../_util-fns - -:marked - We typically display data in Angular by binding controls in an HTML template - to properties of an Angular component. - - In this chapter, we'll create a component with a list of heroes. Each hero has a name. - We'll display the list of hero names and - conditionally show a selected hero in a detail area below the list. - - The final UI looks like this: - -figure.image-display - img(src="/resources/images/devguide/displaying-data/final.png" alt="Final UI") - - - -.l-main-section -:marked - ## Showing component properties with interpolation - The easiest way to display a component property - is to bind the property name through interpolation. - With interpolation, we put the property name in the view template, enclosed in double curly braces: `{{myHero}}`. - - Let's build a small illustrative example together. - - - Create a new project folder (`displaying`) and create 3 files: - `pubspec.yaml`, `web/index.html`, and `web/main.dart`. - Put these contents in the files: - -- var stylePattern = [{ otl: /(platform_directives.*$)/gm }, null, null]; -+makeTabs('displaying-data/dart/pubspec.yaml, displaying-data/dart/web/index.html, displaying-data/dart/web/main.dart', ',,final', 'pubspec.yaml, web/index.html, web/main.dart', stylePattern) - -:marked - All of this code should look familiar from the - [QuickStart](../quickstart.html), - except for the `platform_directives` entry in `pubspec.yaml` - and the imports in `main.dart`. - - In `pubspec.yaml`, the `platform_directives` entry lets us use - core directives, such as the `ngFor` directive that we'll soon add to our app. - - In `main.dart`, importing `app_component.dart` lets us implement part - of the app in a different Dart file. The QuickStart version of `main.dart` - imported `core.dart`, but we don't need that import here because - this version of `main.dart` is so basic: it only bootstraps the app, - and doesn't implement any components or other injectable types. - - So that the code can run, - let's create a stub for the `` component. - - Create a new directory called `lib`. - In it, put a file called `app_component.dart` - with the following code: - -+makeExample('displaying-data/dart/lib/app_component_1.dart', null, 'lib/app_component.dart') - -:marked - We defined a component with two properties: `title` and `myHero`. - The template displays the two component properties using double curly brace - interpolation: - -+makeExample('displaying-data/dart/lib/app_component_1.dart', 'template')(format=".") - -:marked - Angular automatically pulls the value of the `title` and `myHero` properties from the component and - inserts those values into the browser. Angular updates the display - when these properties change. - - -.l-sub-section - :marked - More precisely, the redisplay occurs after some kind of asynchronous event related to - the view such as a keystroke, a timer completion, or an async `XHR` response. - We don't have those in this sample. - But then the properties aren't changing on their own either. For the moment we must operate on faith. -:marked - Notice that we haven't called **new** to create an instance of the `AppComponent` class. - Angular is creating an instance for us. How? - - Notice the CSS `selector` in the `@Component` decorator that specifies an element named "my-app". - Remember back in QuickStart that we added the `` element to the body of our `index.html` file: -+makeExample('displaying-data/dart/web/index.html', 'my-app')(format=".") - - -:marked - When we bootstrap with the `AppComponent` class (in `main.dart`), Angular looks for a `` - in the `index.html`, finds it, instantiates an instance of `AppComponent`, and renders it - inside the `` tag. - - Try running the app. It should display the title and hero name: -figure.image-display - img(src="/resources/images/devguide/displaying-data/title-and-hero.png" alt="Title and Hero") -// TODO: Here the TS version says "Let's review some of the choices we made and consider alternatives." However, it's unclear where this review ends. Clarify the structure in the TS, and make sure this is the best place for the Dart version of this section. - -#performance.l-sub-section - :marked - ### Template inline or template file? - - We can store our component's template in one of two places. - We can define it *inline* using the `template` property, as we do here. - Or we can define the template in a separate HTML file and link to it in - the component metadata using the `@Component` decorator's `templateUrl` property. - - The choice between inline and separate HTML is a matter of taste, - circumstances, and organization policy. - Here we're using inline HTML because the template is small, and the demo - is simpler without the additional HTML file. - - In either style, the template data bindings have the same access to the component's properties. - - - -.l-main-section -:marked - ## Showing a list property with ***ngFor** - - We want to display a list of heroes. We begin by adding a list of hero names to the component and redefine `myHero` to be the first name in the list. -+makeExample('displaying-data/dart/lib/app_component_2.dart', 'mock-heroes', 'lib/app_component.dart (excerpt)')(format=".") - -:marked - Now we use the Angular `ngFor` "repeater" directive in the template to display - each item in the `heroes` list. - -+makeExample('displaying-data/dart/lib/app_component_2.dart', 'template','lib/app_component.dart (excerpt)')(format=".") - - -:marked - Our presentation is the familiar HTML unordered list with `
      ` and `
    • ` tags. Let's focus on the `
    • ` tag. -+makeExample('displaying-data/dart/lib/app_component_2.dart', 'li-repeater')(format=".") - -:marked - We added a somewhat mysterious `*ngFor` to the `
    • ` element. - That's the Angular "repeater" directive. - Its presence on the `
    • ` tag marks that `
    • ` element (and its children) as the "repeater template". - -.alert.is-important - :marked - Don't forget the leading asterisk (\*) in `*ngFor`. It is an essential part of the syntax. - Learn more about this and `ngFor` in the [Template Syntax](./template-syntax.html#ngFor) chapter. - -:marked - Notice the `hero` in the `ngFor` double-quoted instruction; - it is an example of a [template input variable](./template-syntax.html#ngForMicrosyntax). - - Angular duplicates the `
    • ` for each item in the list, setting the `hero` variable - to the item (the hero) in the current iteration. Angular uses that variable as the - context for the interpolation in the double curly braces. - -.l-sub-section - :marked - We happened to give `ngFor` a list to display. - In fact, `ngFor` can repeat items for any [Iterable](https://api.dartlang.org/stable/dart-core/Iterable-class.html) object. - -:marked - Now the heroes appear in an unordered list. - -figure.image-display - img(src="/resources/images/devguide/displaying-data/hero-names-list.png" alt="After ngfor") - -.callout.is-important - header Did the app break? - :marked - If the app stops working after adding `*ngFor`, - make sure `pubspec.yaml` has the [correct **platform_directives** entry](#platform_directives). - A missing or incorrect `platform_directives` entry results in template parse errors. - -.l-main-section -:marked - ## Creating a class for the data - - We are defining our data directly inside our component. - That's fine for a demo but certainly isn't a best practice. It's not even a good practice. - Although we won't do anything about that in this chapter, we'll make a mental note to fix this down the road. - - At the moment, we're binding to a list of strings. We do that occasionally in real applications, but - most of the time we're binding to more specialized objects. - - Let's turn our list of hero names into a list of `Hero` objects. For that we'll need a `Hero` class. - - Create a new file in the `lib/` folder called `hero.dart` with the following code. -+makeExample('displaying-data/dart/lib/hero.dart',null,'lib/hero.dart') - -:marked - We've defined a class with a constructor, a string description, and two properties: `id` and `name`. - -.l-main-section -:marked - ## Using the Hero class - Let's make the `heroes` property in our component return a list of these Hero objects. -- var stylePattern = { otl: /(import.*$)|(final)|(new Hero.*$)/gm }; -+makeExample('displaying-data/dart/lib/app_component_3.dart', 'heroes', 'app_component.dart (excerpt)', stylePattern)(format=".") - -:marked - We'll have to update the template. - At the moment it displays the string value of the `Hero` object. - Let's fix that so we display only the hero's `name` property. -- var stylePattern = { otl: /(myHero\.name)|(hero\.name)/gm }; -+makeExample('displaying-data/dart/lib/app_component_3.dart', 'template','app_component.dart (template)', stylePattern)(format=".") - - -:marked - Our display looks the same, but now we know much better what a hero really is. - - -.l-main-section -:marked - ## Conditional display with NgIf - - Sometimes the app should display a view or a portion of a view only under specific circumstances. - - In our example, we'd like to display a message if we have a large number of heroes — say, more than 3. - - The Angular `ngIf` directive inserts or removes an element based on a boolean condition. - We can see it in action by adding the following paragraph at the bottom of the template: -+makeExample('displaying-data/dart/lib/app_component.dart', 'message') -.alert.is-important - :marked - Don't forget the leading asterisk (\*) in `*ngIf`. It is an essential part of the syntax. - Learn more about this and `ngIf` in the [Template Syntax](./template-syntax.html#ngIf) chapter. - -:marked - The [template expression](./template-syntax.html#template-expressions) inside the double quotes - looks much like Dart, and it _is_ much like Dart. - When the component's list of heroes has more than 3 items, Angular adds the paragraph to the DOM and the message appears. - If there are 3 or fewer items, Angular omits the paragraph, so no message appears. - -.alert.is-helpful - :marked - Angular isn't showing and hiding the message. It is adding and removing the paragraph element from the DOM. - That hardly matters here. But it would matter a great deal, from a performance perspective, if - we were conditionally including or excluding a big chunk of HTML with many data bindings. - -:marked - Try it out. Because the list has four items, the message should appear. - Go back into `app_component.dart` and delete or comment out one of the elements from the hero list. - The browser should refresh automatically and the message should disappear. - -.l-main-section -:marked - ## Summary - Now we know how to use: - - **interpolation** with double curly braces to display a component property - - **`ngFor`** to display a list of items - - a Dart class to shape the **model data** for our component and display properties of that model - - **`ngIf`** to conditionally display a chunk of HTML based on a boolean expression - - Here's our final code: - -+makeTabs(`displaying-data/dart/lib/app_component.dart, - displaying-data/dart/lib/hero.dart, - displaying-data/dart/pubspec.yaml, - displaying-data/dart/web/index.html, - displaying-data/dart/web/main.dart`, - ',,,,final', - 'lib/app_component.dart, lib/hero.dart, pubspec.yaml, web/index.html, web/main.dart') diff --git a/public/docs/dart/latest/guide/forms.jade b/public/docs/dart/latest/guide/forms.jade deleted file mode 100644 index e78d9c19eb..0000000000 --- a/public/docs/dart/latest/guide/forms.jade +++ /dev/null @@ -1,660 +0,0 @@ -include ../_util-fns - - -:marked - We’ve all used a form to log in, submit a help request, place an order, book a flight, - schedule a meeting, and perform countless other data entry tasks. - Forms are the mainstay of business applications. - - Any seasoned web developer can slap together an HTML form with all the right tags. - It's more challenging to create a cohesive data entry experience that guides the - user efficiently and effectively through the workflow behind the form. - - *That* takes design skills that are, to be frank, well out of scope for this chapter. - - It also takes framework support for - **two-way data binding, change tracking, validation, and error handling** - ... which we shall cover in this chapter on Angular forms. - - We will build a simple form from scratch, one step at a time. Along the way we'll learn: - - - How to build an Angular form with a component and template - - - The `ngModel` two-way data binding syntax for reading and writing values to input controls - - - The `ngControl` directive to track the change state and validity of form controls - - - The special CSS classes that `ngControl` adds to form controls and how to use them to provide strong visual feedback - - - How to display validation errors to users and enable/disable form controls - - - How to share information across controls with template reference variables - -.l-main-section -:marked - ## Template-driven forms - - Many of us will build forms by writing templates in the Angular - template syntax - - with the form-specific directives and techniques described in this chapter. - -.l-sub-section - :marked - That's not the only way to create a form but it's the way we'll cover in this chapter. -:marked - We can build almost any form we need with an Angular template—login forms, contact forms, pretty much any business form. - We can lay out the controls creatively, bind them to data, specify validation rules and display validation errors, - conditionally enable or disable specific controls, trigger built-in visual feedback, and much more. - - It will be pretty easy because Angular handles many of the repetitive, boilerplate tasks we'd - otherwise wrestle with ourselves. - - We'll discuss and learn to build a template-driven form that looks like this: - -figure.image-display - img(src="/resources/images/devguide/forms/hero-form-1.png" width="400px" alt="Clean Form") - -:marked - Here at the *Hero Employment Agency* we use this form to maintain personal information about the - heroes in our stable. Every hero needs a job. It's our company mission to match the right hero with the right crisis! - - Two of the three fields on this form are required. Required fields have a green bar on the left to make them easy to spot. - - If we delete the hero name, the form displays a validation error in an attention-grabbing style: - -figure.image-display - img(src="/resources/images/devguide/forms/hero-form-2.png" width="400px" alt="Invalid, Name Required") - -:marked - Note that the submit button is disabled, and the "required" bar to the left of the input control changed from green to red. - -.l-sub-section - :marked - We'll customize the colors and location of the "required" bar with standard CSS. - -:marked - We'll build this form in small steps: - - 1. Create the `Hero` model class. - 1. Create the component that controls the form. - 1. Create a template with the initial form layout. - 1. Add the **ngModel** directive to each form input control. - 1. Add the **ngControl** directive to each form input control. - 1. Add custom CSS to provide visual feedback. - 1. Show and hide validation error messages. - 1. Handle form submission with **ngSubmit**. - 1. Change the form's display after submission. - -:marked - ## Setup - Create a new project folder (`angular2_forms`) and create 3 files: - `pubspec.yaml`, `web/index.html`, and `web/main.dart`. - (These files should be familiar from the - [QuickStart](../quickstart.html).) Put these contents in the files: - -+makeTabs('forms/dart/pubspec.yaml, forms/dart/web/index.html, forms/dart/web/main.dart', ',initial,', 'pubspec.yaml, web/index.html, web/main.dart') - -.l-sub-section - :marked - Note the `platform_directives` entry in `pubspec.yaml`. - It imports core directives and, more importantly for this chapter, - **form directives**. - -:marked - So that the code can run, - let's create a stub for the `` component. - - Create a new directory called `lib`. - In it, put a file called `hero_form_component.dart` - with the following code: - -+makeExample('forms/dart/lib/hero_form_component_initial.dart', null, 'lib/hero_form_component.dart') - -:marked - The app should now run, but it won't do anything interesting. - Let's add some data. - - - ## Create the Hero model class - - As users enter form data, we'll capture their changes and update an instance of a model. - We can't lay out the form until we know what the model looks like. - - A model can be as simple as a "property bag" that holds facts about a thing of application importance. - That describes well our `Hero` class with its three required fields (`id`, `name`, `power`) - and one optional field (`alterEgo`). - - In the `lib` directory, add a file called `hero.dart` - with the following code: - -+makeExample('forms/dart/lib/hero.dart', 'all', 'lib/hero.dart') - -:marked - It's an anemic model with few requirements and no behavior. Perfect for our demo. - - The `alterEgo` is optional, so the constructor lets us omit it: note the - `[]` in `[this.alterEgo]`. - - We can create a new hero like this: - -+makeExample('forms/dart/lib/hero.dart', 'newhero')(format=".") - -:marked - -.l-main-section -:marked - ## Create a form component - - An Angular form has two parts: an HTML-based template and a code-based component to handle data and user interactions. - - We begin with the component because it states, in brief, what the Hero editor can do. - - Edit `hero_form_component.dart`, replacing all of its contents - with the following code: - -+makeExample('forms/dart/lib/hero_form_component.dart', null, 'lib/hero_form_component.dart') - -:marked - There’s nothing special about this component, nothing form-specific, - nothing to distinguish it from any component we've written before. - - Understanding this component requires only the Angular 2 concepts covered in previous chapters. - - 1. The code imports a standard set of symbols from the Angular library. - - 1. The `@Component` selector value of "hero-form" means we can drop this form in a parent template with a `` tag. - - 1. The `templateUrl` property points to a separate file for template HTML called `hero_form_component.html`. - - 1. We defined dummy data for `model` and `powers`, as befits a demo. - Down the road, we can inject a data service to get and save real data - or perhaps expose these properties as inputs and outputs - for binding to a - parent component. None of this concerns us now, and these future changes won't affect our form. - - 1. We threw in a `diagnostic` property to return a - string describing our model. - It'll help us see what we're doing during our development; we've left ourselves a cleanup note to discard it later. - - Why isn't the template inline in the component file? - - Inline templates can be nice when they are short, - but most form templates aren't short. Dart files generally aren't the best place to - write (or read) large stretches of HTML, and few editors are much help with files that have a mix of HTML and code. - It's also nice to have short files with a clear and obvious purpose. - - We made a good choice to put the HTML template elsewhere. Let's write it. - - - - - -.l-main-section -:marked - ## Create an initial HTML form template - - Create a new file under `lib` called `hero_form_component.html`, - and put the following template code in it: - -+makeExample('forms/dart/lib/hero_form_component_initial.html', null, 'lib/hero_form_component.html') - -:marked - That is plain old HTML 5. We're presenting two of the `Hero` fields, `name` and `alterEgo`, and - opening them up for user input in input boxes. - - The Name `` control has the HTML5 `required` attribute; - the Alter Ego `` control does not because `alterEgo` is optional. - - We've got a Submit button at the bottom with some classes on it. - - **We are not using Angular yet**. There are no bindings. No extra directives. Just layout. - - - The `container`,`form-group`, `form-control`, and `btn` classes are [Bootstrap](http://getbootstrap.com/) CSS. Purely cosmetic. - We're using Bootstrap to gussy up our form. - Hey, what's a form without a little style! - -.callout.is-important - header Angular forms do not require a style library - :marked - Angular makes no use of the `container`, `form-group`, `form-control`, and `btn` classes or - the styles of any external library. Angular apps can use any CSS library - ... or none at all. - -:marked - Let's add the stylesheet. - - 1. Download the Bootstrap stylesheet from - https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css, - and put it in the `web` directory. - - 2. Edit `web/index.html`, adding a link to `bootstrap.min.css`: - -- var stylePattern = { otl: /(<link rel.*$)/gm }; -+makeExample('forms/dart/web/index.html', 'bootstrap-and-script', 'web/index.html (excerpt)', stylePattern)(format=".") - - [PENDING: runnable now? Remind about pub get? remind them to look in the browser console] - - -.l-main-section -:marked - ## Add powers with ***ngFor** - Our hero must choose one super power from a fixed list of Agency-approved powers. - We maintain that list internally (in `HeroFormComponent`). - - We'll add a `select` to our - form and bind the options to the `powers` list using `ngFor`, - a technique used before in [Displaying Data](./displaying-data.html). - - Add the following HTML *immediately below* the Alter Ego group. -+makeExample('forms/dart/lib/hero_form_component_ngmodel_ngfor.html', 'powers', 'lib/hero_form_component.html (excerpt)')(format=".") - -:marked - This code repeats the `