Compare commits

..

35 Commits

Author SHA1 Message Date
f5b7f2b9a5 docs: add changelog for 5.0.0-rc.9 2017-10-30 21:09:14 -07:00
509f392ab0 release: cut the 5.0.0-rc.9 release 2017-10-30 21:07:37 -07:00
cf5fce8d5e build: update rollup lint rule from bad merge (#20047)
PR Close #20047
2017-10-30 23:45:06 -04:00
f1248b69e6 refactor: make all rollup config ES5 compatible (#20028)
So they can be required by other Node scripts.

PR Close #20028
2017-10-30 23:28:18 -04:00
4498dddbe3 build: add lint rule for global flags in rollup config (#20028)
We now verify that every imports is part of the globals defined in the files rollup.config.js.

PR Close #20028
2017-10-30 23:28:11 -04:00
812786f44e fix: add missing globals from each rollup configuration (#20028)
PR Close #20028
2017-10-30 23:11:42 -04:00
de24d54517 fix(compiler): report errors properly in G3 in certain conditions (#20041)
Condition: static analysis error, given:
- noResolve:true
- generateCodeForLibraries: false
- CompilerHost.getSourceFile throws on non existent files

All of these are true in G3.
PR Close #20041
2017-10-30 23:07:37 -04:00
c295aeeca2 build: add release as a valid commit message subject (#19955)
PR Close #19955
2017-10-30 21:23:48 -04:00
a8add78fe1 build: temporarily increase the commit msg limit to 120
Right now HEAD and 5.0.x have a branch deviation and therefore
all the commits between both branches are being compared. There
exists a problematic commit which has a commit message that is
longer than 100 commits. This patch will temporarily increase
the limit to 120 so that CI passes. Once master is resumed to
being the primary development branch (once 5.0.0 is out) then
the the msg limit will be set back to 100.
2017-10-30 21:23:43 -04:00
e3a16ed02d fix(compiler): reexport less symbols in .ngfactory.ts files (#19884)
* don't reexport symbols that the user already reexported
* never reexport symbols that are part of arguments of non simple function calls

Fixes #19883

PR Close #19884
2017-10-30 21:19:44 -04:00
fd37f3fbab fix(compiler): always use relative paths to refer to generated code
Previously we generated imports like `@angular/material/index.ngfactory`,
which doesn’t make sense as we don’t ship generated code on npm

Closes #20031
2017-10-30 20:00:48 -04:00
85e95cc32b docs: add changelog for 5.0.0-rc.8 2017-10-27 23:31:35 -07:00
de71ba74bb release: cut the 5.0.0-rc.8 release 2017-10-27 23:31:27 -07:00
a01c877534 docs: ensure examples get rxjs ^5.5.0 (#19985)
This change coincidentally updates other packages that were in `package.json`
because it regenerates `yarn.lock`. This too should be fine.

PR Close #19985
2017-10-27 22:28:21 -07:00
2d508a3ef0 fix(compiler-cli): avoid producing source mappings for host views (#19965)
The host view doesn't map back to user code so the template compiler
produces a blank `url` for them.

PR Close #19965
2017-10-27 22:28:14 -07:00
4285b6c3e3 fix(platform-server): add missing packages to the UMD global rollup config
This adds the proper bindings for calling angular packages from platform-server in the UMD.
This was not a problem for universal apps that dont use UMD.

Fixes 19899
2017-10-27 22:27:43 -07:00
5542517b9c docs: add changelog for 5.0.0-rc.7 2017-10-26 19:03:14 -07:00
fef3539608 release: cut the 5.0.0-rc.7 release 2017-10-26 19:01:34 -07:00
f4d5729cb3 fix(compiler): make watch mode work on windows (#19953)
Fixes #19951
PR Close #19953
2017-10-26 21:52:35 -04:00
d343bf7885 fix(compiler): recover from structural errors in watch mode (#19953)
This also changes the compiler so that we throw less often
on structural changes and produce a meaningful state
in the `ng.Program` in case of errors.

Related to #19951

PR Close #19953
2017-10-26 21:52:25 -04:00
9ce7f0e538 fix(compiler): translate emit diagnostics with noEmitOnError: true. (#19953)
This prevents errors reported against `.ngfactory.ts` files show up
as the result of running `ngc`.

Closes #19935
PR Close #19953
2017-10-26 21:52:16 -04:00
4a23df3909 fix(compiler): don’t store invalid state when using listLazyRoutes (#19953)
Previously, `listLazyRoute` would store invalid information in a compiler
internal cache, which lead to incorrect paths that were used during emit.
This commit fixes this.

PR Close #19953
2017-10-26 21:51:43 -04:00
14016c781f fix(service-worker): fix improper call of Observable.merge (#19962)
Observable.merge was called using .call() as if it were an operator
and not an Observable factory. This removes the .call() and uses
the factory properly.

PR Close #19962
2017-10-26 18:16:20 -04:00
47caebfe86 fix(service-worker): don't block initialization on registration (#19936)
Importing ServiceWorkerModule.register() will schedule registration of
the Service Worker inside an APP_INITIALIZER. Previously, the Promise
returned by navigator.serviceWorker.register() was returned from the
initializer function. This has the unwanted side effect of blocking
initialization until the SW is registered. Even worse, if the SW script
fails to load, this can cause the app initialization to fail.

The solution is to not return the registration promise from the
initializer function, essentially decoupling registration from the rest
of the initialization flow.

This change is not unit testable as there are no mocks/adapters yet for
navigator.serviceWorker. A future integration test should cover this case
with better fidelity.

PR Close #19936
2017-10-26 16:10:17 -04:00
5cfd9c6020 fix(service-worker): listen for messages on the right event source (#19954)
Currently, the SwUpdate service doesn't receive messages from the SW.
This is because it attempts to subscribe to the 'message' event on
ServiceWorkerRegistration, when really messages are emitted by the
ServiceWorkerContainer.

This change moves to listening on ServiceWorkerContainer and changes
the mocks to reflect the way the browser actually works.

PR Close #19954
2017-10-26 16:10:07 -04:00
47bc6f105d docs: add changelog for 5.0.0-rc.6 2017-10-25 14:34:42 -07:00
40fa2593a9 release: cut the 5.0.0-rc.6 release 2017-10-25 14:32:11 -07:00
680bcf7b8a build: update to rxjs@5.5.2 (#19931)
PR Close #19931
2017-10-25 15:32:01 -04:00
ef08330341 fix(compiler): automatically set emitDecoratorMetadata when "annotationsAs": "static fields” (#19927)
This is a workaround for https://github.com/angular/tsickle/issues/635.

Fixes #19916
PR Close #19927
2017-10-25 14:26:28 -04:00
6cc042e2ba fix(compiler-cli): produce correct paths for windows output (#19915)
The path mapping was broken for Windows by fc0b1d5b61.
Fixed the path mapping and put code in place to make such a problem
to sneek by again.

PR Close #19915
2017-10-24 19:21:18 -04:00
9b26455740 fix(compiler-cli): only use error collector when needed. (#19912)
The error collector changes behavior of the metadata resolver
in ways that haven't been fully hardened. This changes limits
its use to the lazy route detection and the language service.

Issue: #19906

PR Close #19912
2017-10-24 19:21:13 -04:00
18bce5987c fix(compiler): don’t type check templates with skipTemplateCodegen (#19909)
This change is needed to prevent users’ builds from breaking.

If a user sets `fullTemlateTypeCheck` to true, we will
continue to check the templates even when `skipTemplateCodegen` is true
as well.

Related to #19906

PR Close #19909
2017-10-24 19:21:03 -04:00
f1108fea76 docs: add changelog for 5.0.0-rc.5 2017-10-23 23:28:28 -07:00
64b3e3e41a release: cut the 5.0.0-rc.5 release 2017-10-23 23:27:15 -07:00
a82f863e24 fix(compiler-cli): report all diagnostic error messages (#19886)
This fixes a problem introduced in 8d45fefc31
which modified how diagnostic error messages are reported for structural
metadata errors causing some of the diagnostics to be lost.

PR Close #19886
2017-10-24 00:57:41 -04:00
1201 changed files with 19071 additions and 26439 deletions

18
.bazelrc Normal file
View File

@ -0,0 +1,18 @@
# Make compilation fast, by keeping a few copies of the compilers
# running as daemons, and cache SourceFile AST's to reduce parse time.
build --strategy=TypeScriptCompile=worker
build --strategy=AngularTemplateCompile=worker
# Don't create bazel-* symlinks in the WORKSPACE directory.
# These require .gitignore and may scare users.
# Also, it's a workaround for https://github.com/bazelbuild/rules_typescript/issues/12
# which affects the common case of having `tsconfig.json` in the WORKSPACE directory.
#
# Instead, you should run `bazel info bazel-bin` to find out where the outputs went.
build --symlink_prefix=/
# Performance: avoid stat'ing input files
build --watchfs
# Don't print all the .d.ts output locations after builds
build --show_result=0

View File

@ -7,25 +7,17 @@
# To validate changes, use an online parser, eg. # To validate changes, use an online parser, eg.
# http://yaml-online-parser.appspot.com/ # http://yaml-online-parser.appspot.com/
# Variables
## IMPORTANT
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
var_1: &docker_image angular/ngcontainer:0.0.8
var_2: &cache_key angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.0.8
# Settings common to each job # Settings common to each job
anchor_1: &job_defaults anchor_1: &job_defaults
working_directory: ~/ng working_directory: ~/ng
docker: docker:
- image: *docker_image - image: angular/ngcontainer:0.0.2
# After checkout, rebase on top of master. # After checkout, rebase on top of master.
# Similar to travis behavior, but not quite the same. # Similar to travis behavior, but not quite the same.
# See https://discuss.circleci.com/t/1662 # See https://discuss.circleci.com/t/1662
anchor_2: &post_checkout anchor_2: &post_checkout
post: git pull --ff-only origin "refs/pull/${CIRCLE_PULL_REQUEST//*pull\//}/merge" post: git pull --ff-only origin "refs/pull/${CI_PULL_REQUEST//*pull\//}/merge"
version: 2 version: 2
jobs: jobs:
@ -34,13 +26,8 @@ jobs:
steps: steps:
- checkout: - checkout:
<<: *post_checkout <<: *post_checkout
# Check BUILD.bazel formatting before we have a node_modules directory
# Then we don't need any exclude pattern to avoid checking those files
- run: 'buildifier -mode=check $(find . -type f \( -name BUILD.bazel -or -name BUILD \)) ||
(echo "BUILD files not formatted. Please run ''yarn buildifier''" ; exit 1)'
- restore_cache: - restore_cache:
key: *cache_key key: angular-{{ .Branch }}-{{ checksum "yarn.lock" }}
- run: yarn install --frozen-lockfile --non-interactive - run: yarn install --frozen-lockfile --non-interactive
- run: ./node_modules/.bin/gulp lint - run: ./node_modules/.bin/gulp lint
@ -51,17 +38,13 @@ jobs:
- checkout: - checkout:
<<: *post_checkout <<: *post_checkout
- restore_cache: - restore_cache:
key: *cache_key key: angular-{{ .Branch }}-{{ checksum "yarn.lock" }}
- run: bazel info release
- run: bazel run @yarn//:yarn - run: bazel run @yarn//:yarn
# Use bazel query so that we explicitly ask for all buildable targets to be built as well - run: bazel build packages/...
# This avoids waiting for a build command to finish before running the first test - run: bazel test @angular//...
# See https://github.com/bazelbuild/bazel/issues/4257
- run: bazel query --output=label '//packages/... union @angular//...' | xargs bazel test --config=ci
- save_cache: - save_cache:
key: *cache_key key: angular-{{ .Branch }}-{{ checksum "yarn.lock" }}
paths: paths:
- "node_modules" - "node_modules"

2
.nvmrc
View File

@ -1 +1 @@
8.9 6.9.5

View File

@ -22,9 +22,11 @@
# petebacondarwin - Pete Bacon Darwin # petebacondarwin - Pete Bacon Darwin
# pkozlowski-opensource - Pawel Kozlowski # pkozlowski-opensource - Pawel Kozlowski
# robwormald - Rob Wormald # robwormald - Rob Wormald
# tbosch - Tobias Bosch
# tinayuangao - Tina Gao # tinayuangao - Tina Gao
# vicb - Victor Berchet # vicb - Victor Berchet
# vikerman - Vikram Subramanian # vikerman - Vikram Subramanian
# wardbell - Ward Bell
version: 2 version: 2
@ -43,7 +45,6 @@ groups:
include: include:
- "*" - "*"
exclude: exclude:
- ".circleci/*"
- "aio/*" - "aio/*"
- "integration/*" - "integration/*"
- "modules/*" - "modules/*"
@ -73,7 +74,6 @@ groups:
users: users:
- alexeagle #primary - alexeagle #primary
- chuckjaz - chuckjaz
- IgorMinar
- vikerman #fallback - vikerman #fallback
build-and-ci: build-and-ci:
@ -100,6 +100,7 @@ groups:
users: users:
- alexeagle - alexeagle
- mhevery - mhevery
- tbosch
- vicb - vicb
- IgorMinar #fallback - IgorMinar #fallback
@ -108,7 +109,8 @@ groups:
files: files:
- "packages/core/*" - "packages/core/*"
users: users:
- chuckjaz #primary - tbosch #primary
- chuckjaz
- mhevery - mhevery
- vicb - vicb
- IgorMinar #fallback - IgorMinar #fallback
@ -130,7 +132,7 @@ groups:
- "packages/compiler/src/i18n/*" - "packages/compiler/src/i18n/*"
users: users:
- vicb #primary - vicb #primary
- chuckjaz - tbosch
- IgorMinar #fallback - IgorMinar #fallback
- mhevery #fallback - mhevery #fallback
@ -139,8 +141,9 @@ groups:
files: files:
- "packages/compiler/*" - "packages/compiler/*"
users: users:
- chuckjaz #primary - tbosch #primary
- vicb - vicb
- chuckjaz
- mhevery - mhevery
- IgorMinar #fallback - IgorMinar #fallback
@ -165,6 +168,7 @@ groups:
- alexeagle - alexeagle
- chuckjaz - chuckjaz
- vicb - vicb
- tbosch
- IgorMinar #fallback - IgorMinar #fallback
- mhevery #fallback - mhevery #fallback
@ -208,7 +212,7 @@ groups:
- "packages/language-service/*" - "packages/language-service/*"
users: users:
- chuckjaz #primary - chuckjaz #primary
# needs secondary - tbosch #secondary
- vicb - vicb
- IgorMinar #fallback - IgorMinar #fallback
- mhevery #fallback - mhevery #fallback
@ -238,8 +242,8 @@ groups:
files: files:
- "packages/platform-browser/*" - "packages/platform-browser/*"
users: users:
- vicb #primary - tbosch #primary
# needs secondary - vicb #secondary
- IgorMinar #fallback - IgorMinar #fallback
- mhevery #fallback - mhevery #fallback
@ -249,9 +253,9 @@ groups:
- "packages/platform-server/*" - "packages/platform-server/*"
users: users:
- vikerman #primary - vikerman #primary
# needs secondary
- alxhub - alxhub
- vicb - vicb
- tbosch
- IgorMinar #fallback - IgorMinar #fallback
- mhevery #fallback - mhevery #fallback
@ -261,7 +265,7 @@ groups:
- "packages/platform-webworker/*" - "packages/platform-webworker/*"
users: users:
- vicb #primary - vicb #primary
# needs secondary - tbosch #secondary
- IgorMinar #fallback - IgorMinar #fallback
- mhevery #fallback - mhevery #fallback
@ -280,7 +284,7 @@ groups:
files: files:
- "packages/benchpress/*" - "packages/benchpress/*"
users: users:
# needs primary - tbosch #primary
# needs secondary # needs secondary
- IgorMinar #fallback - IgorMinar #fallback
- mhevery #fallback - mhevery #fallback
@ -311,6 +315,7 @@ groups:
- juleskremer #primary - juleskremer #primary
- Foxandxss - Foxandxss
- stephenfluin - stephenfluin
- wardbell
- petebacondarwin - petebacondarwin
- gkalpak - gkalpak
- IgorMinar #fallback - IgorMinar #fallback

View File

@ -2,7 +2,7 @@ language: node_js
sudo: false sudo: false
dist: trusty dist: trusty
node_js: node_js:
- '8.9.1' - '6.9.5'
addons: addons:
# firefox: "38.0" # firefox: "38.0"

View File

@ -1,5 +1,4 @@
package(default_visibility = ["//visibility:public"]) package(default_visibility = ["//visibility:public"])
exports_files(["tsconfig.json"]) exports_files(["tsconfig.json"])
# This rule belongs in node_modules/BUILD # This rule belongs in node_modules/BUILD
@ -12,25 +11,17 @@ filegroup(
# bazel query "deps(:node_modules)" | wc -l # bazel query "deps(:node_modules)" | wc -l
# This won't scale in the general case. # This won't scale in the general case.
# TODO(alexeagle): figure out what to do # TODO(alexeagle): figure out what to do
srcs = glob(["/".join([ srcs = glob(["/".join(["node_modules", pkg, "**", ext]) for pkg in [
"node_modules",
pkg,
"**",
ext,
]) for pkg in [
"jasmine", "jasmine",
"typescript", "typescript",
"zone.js", "zone.js",
"tsutils", "rxjs",
"@types/jasmine", "@types",
"@types/node",
"@types/source-map",
"tsickle", "tsickle",
"hammerjs", "hammerjs",
"protobufjs", "protobufjs",
"bytebuffer", "bytebuffer",
"reflect-metadata", "reflect-metadata",
"source-map-support",
"minimist", "minimist",
] for ext in [ ] for ext in [
"*.js", "*.js",

File diff suppressed because it is too large Load Diff

View File

@ -69,22 +69,21 @@ You can file new issues by filling out our [new issue form](https://github.com/a
### <a name="submit-pr"></a> Submitting a Pull Request (PR) ### <a name="submit-pr"></a> Submitting a Pull Request (PR)
Before you submit your Pull Request (PR) consider the following guidelines: Before you submit your Pull Request (PR) consider the following guidelines:
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR * Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR
that relates to your submission. You don't want to duplicate effort. that relates to your submission. You don't want to duplicate effort.
1. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs. * Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
We cannot accept code without this. We cannot accept code without this.
1. Fork the angular/angular repo. * Make your changes in a new git branch:
1. Make your changes in a new git branch:
```shell ```shell
git checkout -b my-fix-branch master git checkout -b my-fix-branch master
``` ```
1. Create your patch, **including appropriate test cases**. * Create your patch, **including appropriate test cases**.
1. Follow our [Coding Rules](#rules). * Follow our [Coding Rules](#rules).
1. Run the full Angular test suite, as described in the [developer documentation][dev-doc], * Run the full Angular test suite, as described in the [developer documentation][dev-doc],
and ensure that all tests pass. and ensure that all tests pass.
1. Commit your changes using a descriptive commit message that follows our * Commit your changes using a descriptive commit message that follows our
[commit message conventions](#commit). Adherence to these conventions [commit message conventions](#commit). Adherence to these conventions
is necessary because release notes are automatically generated from these messages. is necessary because release notes are automatically generated from these messages.
@ -93,13 +92,13 @@ Before you submit your Pull Request (PR) consider the following guidelines:
``` ```
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files. Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
1. Push your branch to GitHub: * Push your branch to GitHub:
```shell ```shell
git push origin my-fix-branch git push origin my-fix-branch
``` ```
1. In GitHub, send a pull request to `angular:master`. * In GitHub, send a pull request to `angular:master`.
* If we suggest changes then: * If we suggest changes then:
* Make the required updates. * Make the required updates.
* Re-run the Angular test suites to ensure tests are still passing. * Re-run the Angular test suites to ensure tests are still passing.

View File

@ -5,51 +5,20 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository( git_repository(
name = "build_bazel_rules_nodejs", name = "build_bazel_rules_nodejs",
remote = "https://github.com/bazelbuild/rules_nodejs.git", remote = "https://github.com/bazelbuild/rules_nodejs.git",
tag = "0.3.1", # TODO(alexeagle): use the correct tag here.
commit = "2c6243df53fd33fdab283ebdd01582e4eb815db8",
) )
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories") load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")
check_bazel_version("0.8.1")
node_repositories(package_json = ["//:package.json"]) node_repositories(package_json = ["//:package.json"])
git_repository( local_repository(
name = "build_bazel_rules_typescript", name = "build_bazel_rules_typescript",
remote = "https://github.com/bazelbuild/rules_typescript.git", path = "node_modules/@bazel/typescript",
tag = "0.6.0",
) )
load("@build_bazel_rules_typescript//:defs.bzl", "ts_repositories")
ts_repositories()
local_repository( local_repository(
name = "angular", name = "angular",
path = "packages/bazel", path = "packages/bazel",
) )
local_repository(
name = "rxjs",
path = "node_modules/rxjs/src",
)
git_repository(
name = "com_github_bazelbuild_buildtools",
remote = "https://github.com/bazelbuild/buildtools.git",
# Note, this commit matches the version of buildifier in angular/ngcontainer
# If you change this, also check if it matches the version in the angular/ngcontainer
# version in /.circleci/config.yml
commit = "b3b620e8bcff18ed3378cd3f35ebeb7016d71f71",
)
http_archive(
name = "io_bazel_rules_go",
url = "https://github.com/bazelbuild/rules_go/releases/download/0.7.1/rules_go-0.7.1.tar.gz",
sha256 = "341d5eacef704415386974bc82a1783a8b7ffbff2ab6ba02375e1ca20d9b031c",
)
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()

View File

@ -74,7 +74,8 @@ aot-compiler/**/*.factory.d.ts
!styleguide/src/systemjs.custom.js !styleguide/src/systemjs.custom.js
# universal # universal
!universal/webpack.server.config.js !universal/webpack.config.client.js
!universal/webpack.config.universal.js
# plunkers # plunkers
*plnkr.no-link.html *plnkr.no-link.html

View File

@ -1,62 +0,0 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "angular.io-example"
},
"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",
// #docregion styles
"styles": [
"styles.css"
],
// #enddocregion styles
"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",
"exclude": "**/node_modules/**"
},
{
"project": "src/tsconfig.spec.json",
"exclude": "**/node_modules/**"
},
{
"project": "e2e/tsconfig.e2e.json",
"exclude": "**/node_modules/**"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "css",
"component": {}
}
}

View File

@ -5,6 +5,9 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>AngularJS to Angular Quick Reference</title> <title>AngularJS to Angular Quick Reference</title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- #docregion style -->
<link rel="stylesheet" href="styles.css">
<!-- #enddocregion style -->
</head> </head>
<body> <body>

View File

@ -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();
});
});
});

View File

@ -0,0 +1,4 @@
{
"build": "build:aot",
"projectType": "systemjs"
}

View File

@ -0,0 +1,33 @@
// #docregion
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: true,
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

View File

@ -0,0 +1,7 @@
<!-- #docregion -->
<button (click)="toggleHeading()">Toggle Heading</button>
<h1 *ngIf="showHeading">Hello Angular</h1>
<h3>List of Heroes</h3>
<div *ngFor="let hero of heroes">{{hero}}</div>

View File

@ -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;
}
}

View File

@ -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 { }

View File

@ -0,0 +1,24 @@
<!-- #docregion -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Ahead of time compilation (JIT)</title>
<base href="/">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<!-- #docregion jit -->
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('main-jit.js').catch(function(err){ console.error(err); });
</script>
<!-- #enddocregion jit -->
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>

View File

@ -0,0 +1,20 @@
<!-- #docregion -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Ahead of time compilation</title>
<base href="/">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
<!-- #docregion bundle -->
<script src="build.js"></script>
<!-- #enddocregion bundle -->
</html>

View File

@ -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);

View File

@ -0,0 +1,6 @@
// #docregion
import { platformBrowser } from '@angular/platform-browser';
import { AppModuleNgFactory } from './app/app.module.ngfactory';
console.log('Running AOT compiled');
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

View File

@ -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.ts"
],
"angularCompilerOptions": {
"annotationsAs": "decorators",
"genDir": ".",
"skipMetadataEmit" : true
}
}

View File

@ -1,10 +1,9 @@
<hr> <hr>
<h4>{{hero.name}} Detail</h4> <h4>{{hero.name}} Detail</h4>
<div>Id: {{hero.id}}</div> <div>Id: {{hero.id}}</div>
<label>Name: <div>Name:
<!-- #docregion ngModel --> <!-- #docregion ngModel -->
<input [(ngModel)]="hero.name"> <input [(ngModel)]="hero.name">
<!-- #enddocregion ngModel --> <!-- #enddocregion ngModel -->
</label> </div>
<br /> <div>Power:<input [(ngModel)]="hero.power"></div>
<label>Power: <input [(ngModel)]="hero.power"></label>

View File

@ -7,7 +7,7 @@ import { TaxRateService } from './tax-rate.service';
selector: 'app-sales-tax', selector: 'app-sales-tax',
template: ` template: `
<h2>Sales Tax Calculator</h2> <h2>Sales Tax Calculator</h2>
<label>Amount: <input #amountBox (change)="0"></label> Amount: <input #amountBox (change)="0">
<div *ngIf="amountBox.value"> <div *ngIf="amountBox.value">
The sales tax is The sales tax is

View File

@ -4,7 +4,7 @@
"files":[ "files":[
"!**/*.d.ts", "!**/*.d.ts",
"!**/*.js", "!**/*.js",
"!app/*.[0,1,2,3].*" "!app/*.[1,2,3].*"
], ],
"tags": ["attribute", "directive"] "tags": ["attribute", "directive"]
} }

View File

@ -1,14 +1,14 @@
<!-- #docregion --> <!-- #docregion -->
<h1>My First Attribute Directive</h1> <h1>My First Attribute Directive</h1>
<!-- #docregion applied --> <!-- #docregion applied -->
<p appHighlight>Highlight me!</p> <p appHightlight>Highlight me!</p>
<!-- #enddocregion applied, --> <!-- #enddocregion applied, -->
<!-- #docregion color-1 --> <!-- #docregion color-1 -->
<p appHighlight highlightColor="yellow">Highlighted in yellow</p> <p appHightlight highlightColor="yellow">Highlighted in yellow</p>
<p appHighlight [highlightColor]="'orange'">Highlighted in orange</p> <p appHightlight [highlightColor]="'orange'">Highlighted in orange</p>
<!-- #enddocregion color-1 --> <!-- #enddocregion color-1 -->
<!-- #docregion color-2 --> <!-- #docregion color-2 -->
<p appHighlight [highlightColor]="color">Highlighted with parent component's color</p> <p appHightlight [highlightColor]="color">Highlighted with parent component's color</p>
<!-- #enddocregion color-2 --> <!-- #enddocregion color-2 -->

View File

@ -1,9 +0,0 @@
// #docregion
import { Directive } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor() { }
}

View File

@ -1,10 +1,8 @@
/* tslint:disable:no-unused-variable */ /* tslint:disable:no-unused-variable */
// #docregion // #docregion
import { Directive, ElementRef } from '@angular/core'; import { Directive, ElementRef, Input } from '@angular/core';
@Directive({ @Directive({ selector: '[appHighlight]' })
selector: '[appHighlight]'
})
export class HighlightDirective { export class HighlightDirective {
constructor(el: ElementRef) { constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow'; el.nativeElement.style.backgroundColor = 'yellow';

View File

@ -1,10 +1,7 @@
/* tslint:disable:no-unused-variable member-ordering */ /* tslint:disable:no-unused-variable member-ordering */
// #docplaster // #docplaster
// #docregion imports,
import { Directive, ElementRef, HostListener } from '@angular/core';
// #enddocregion imports,
import { Input } from '@angular/core';
// #docregion // #docregion
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({ @Directive({
selector: '[appHighlight]' selector: '[appHighlight]'
@ -38,7 +35,7 @@ export class HighlightDirective {
// #enddocregion color // #enddocregion color
// #docregion color-2 // #docregion color-2
@Input() appHighlight: string; @Input() myHighlight: string;
// #enddocregion color-2 // #enddocregion color-2
} }

View File

@ -1,7 +1,6 @@
/* tslint:disable:member-ordering */ /* tslint:disable:member-ordering */
// #docregion, imports // #docregion
import { Directive, ElementRef, HostListener, Input } from '@angular/core'; import { Directive, ElementRef, HostListener, Input } from '@angular/core';
// #enddocregion imports
@Directive({ @Directive({
selector: '[appHighlight]' selector: '[appHighlight]'

View File

@ -1,5 +1,7 @@
/* tslint:disable:member-ordering */ /* tslint:disable:member-ordering */
// #docregion imports,
import { Directive, ElementRef, HostListener, Input } from '@angular/core'; import { Directive, ElementRef, HostListener, Input } from '@angular/core';
// #enddocregion imports
@Directive({ @Directive({
selector: '[appHighlight]' selector: '[appHighlight]'

View File

@ -13,7 +13,7 @@ describe('Component Style Tests', function () {
let externalH1 = element(by.css('body > h1')); let externalH1 = element(by.css('body > h1'));
// Note: sometimes webdriver returns the fontWeight as "normal", // Note: sometimes webdriver returns the fontWeight as "normal",
// other times as "400", both of which are equal in CSS terms. // othertimes as "400", both of which are equal in CSS terms.
expect(componentH1.getCssValue('fontWeight')).toMatch(/normal|400/); expect(componentH1.getCssValue('fontWeight')).toMatch(/normal|400/);
expect(externalH1.getCssValue('fontWeight')).not.toMatch(/normal|400/); expect(externalH1.getCssValue('fontWeight')).not.toMatch(/normal|400/);
}); });

View File

@ -4,8 +4,7 @@
"files": [ "files": [
"!**/*.d.ts", "!**/*.d.ts",
"!**/*.js", "!**/*.js",
"!**/*.native.*", "!**/*.native.*"
"!**/*.[1].*"
], ],
"tags": ["CSS"] "tags": ["CSS"]
} }

View File

@ -1,3 +0,0 @@
h1 {
font-weight: normal;
}

View File

@ -1,25 +0,0 @@
import { Component, HostBinding } from '@angular/core';
import { Hero } from './hero';
// #docregion
@Component({
selector: 'app-root',
template: `
<h1>Tour of Heroes</h1>
<app-hero-main [hero]="hero"></app-hero-main>
`,
styleUrls: ['./hero-app.component.css']
})
export class HeroAppComponent {
// #enddocregion
hero = new Hero(
'Human Torch',
['Mister Fantastic', 'Invisible Woman', 'Thing']
);
@HostBinding('class') get themeClass() {
return 'theme-light';
}
// #docregion
}
// #enddocregion

View File

@ -6,8 +6,7 @@ import { Hero } from './hero';
selector: 'app-root', selector: 'app-root',
template: ` template: `
<h1>Tour of Heroes</h1> <h1>Tour of Heroes</h1>
<app-hero-main [hero]="hero"></app-hero-main> <app-hero-main [hero]=hero></app-hero-main>`,
`,
styles: ['h1 { font-weight: normal; }'] styles: ['h1 { font-weight: normal; }']
}) })
export class HeroAppComponent { export class HeroAppComponent {

View File

@ -4,8 +4,7 @@
"files":[ "files":[
"!**/*.d.ts", "!**/*.d.ts",
"!**/*.js", "!**/*.js",
"!**/*.[0,1,2].*", "!**/*.[1,2].*"
"!**/dummy.module.ts"
], ],
"tags": ["dependency", "di"] "tags": ["dependency", "di"]
} }

View File

@ -1,10 +0,0 @@
/*
Must put this interface in its own file instead of app.config.ts
or else TypeScript gives a (bogus) warning:
WARNING in ./src/app/... .ts
"export 'AppConfig' was not found in './app.config'
*/
export interface AppConfig {
apiEndpoint: string;
title: string;
}

View File

@ -1,3 +1,5 @@
// Early versions
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';

View File

@ -1,6 +1,7 @@
// #docregion // #docregion
// #docregion imports // #docregion imports
import { Component, Inject } from '@angular/core'; import { Component } from '@angular/core';
import { Inject } from '@angular/core';
import { APP_CONFIG, AppConfig } from './app.config'; import { APP_CONFIG, AppConfig } from './app.config';
// #enddocregion imports // #enddocregion imports
@ -22,5 +23,3 @@ export class AppComponent {
} }
// #enddocregion ctor // #enddocregion ctor
} }
// #enddocregion

View File

@ -4,6 +4,7 @@
import { Component, Inject } from '@angular/core'; import { Component, Inject } from '@angular/core';
import { APP_CONFIG, AppConfig } from './app.config'; import { APP_CONFIG, AppConfig } from './app.config';
import { Logger } from './logger.service';
import { UserService } from './user.service'; import { UserService } from './user.service';
// #enddocregion imports // #enddocregion imports
@ -22,7 +23,8 @@ import { UserService } from './user.service';
<app-heroes id="authorized" *ngIf="isAuthorized"></app-heroes> <app-heroes id="authorized" *ngIf="isAuthorized"></app-heroes>
<app-heroes id="unauthorized" *ngIf="!isAuthorized"></app-heroes> <app-heroes id="unauthorized" *ngIf="!isAuthorized"></app-heroes>
<app-providers></app-providers> <app-providers></app-providers>
` `,
providers: [Logger]
}) })
export class AppComponent { export class AppComponent {
title: string; title: string;

View File

@ -1,13 +1,15 @@
import { AppConfig } from './app-config';
export { AppConfig } from './app-config';
// #docregion token // #docregion token
import { InjectionToken } from '@angular/core'; import { InjectionToken } from '@angular/core';
export const APP_CONFIG = new InjectionToken<AppConfig>('app.config'); export let APP_CONFIG = new InjectionToken<AppConfig>('app.config');
// #enddocregion token // #enddocregion token
// #docregion config // #docregion config
export interface AppConfig {
apiEndpoint: string;
title: string;
}
export const HERO_DI_CONFIG: AppConfig = { export const HERO_DI_CONFIG: AppConfig = {
apiEndpoint: 'api.heroes.com', apiEndpoint: 'api.heroes.com',
title: 'Dependency Injection' title: 'Dependency Injection'

View File

@ -1,24 +1,32 @@
// #docplaster
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { APP_CONFIG, HERO_DI_CONFIG } from './app.config';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { CarComponent } from './car/car.component'; import { CarComponent } from './car/car.component';
import { HeroesComponent } from './heroes/heroes.component'; import { HeroesComponent } from './heroes/heroes.component';
import { HeroListComponent } from './heroes/hero-list.component'; import { HeroListComponent } from './heroes/hero-list.component';
import { InjectorComponent } from './injector.component'; import { InjectorComponent } from './injector.component';
import { Logger } from './logger.service';
import { TestComponent } from './test.component'; import { TestComponent } from './test.component';
import { APP_CONFIG, HERO_DI_CONFIG } from './app.config';
import { UserService } from './user.service'; import { UserService } from './user.service';
import {
import { ProvidersModule } from './providers.module'; ProvidersComponent,
Provider1Component,
Provider3Component,
Provider4Component,
Provider5Component,
Provider6aComponent,
Provider6bComponent,
Provider7Component,
Provider8Component,
Provider9Component,
Provider10Component,
} from './providers.component';
// #docregion ngmodule // #docregion ngmodule
@NgModule({ @NgModule({
imports: [ imports: [
BrowserModule, BrowserModule
ProvidersModule
], ],
declarations: [ declarations: [
AppComponent, AppComponent,
@ -27,19 +35,26 @@ import { ProvidersModule } from './providers.module';
// #enddocregion ngmodule // #enddocregion ngmodule
HeroListComponent, HeroListComponent,
InjectorComponent, InjectorComponent,
TestComponent TestComponent,
ProvidersComponent,
Provider1Component,
Provider3Component,
Provider4Component,
Provider5Component,
Provider6aComponent,
Provider6bComponent,
Provider7Component,
Provider8Component,
Provider9Component,
Provider10Component,
// #docregion ngmodule // #docregion ngmodule
], ],
// #docregion providers, providers-2 // #docregion ngmodule-providers
providers: [ providers: [
// #enddocregion providers
Logger,
// #docregion providers
UserService, UserService,
{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG } { provide: APP_CONFIG, useValue: HERO_DI_CONFIG }
], ],
// #enddocregion providers, providers-2 // #enddocregion ngmodule-providers
exports: [ CarComponent, HeroesComponent ],
bootstrap: [ AppComponent ] bootstrap: [ AppComponent ]
}) })
export class AppModule { } export class AppModule { }

View File

@ -1,25 +0,0 @@
/// Dummy modules to satisfy Angular Language Service
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AppModule } from './app.module';
////////
import { AppComponent as AppComponent1 } from './app.component.1';
@NgModule({
imports: [ CommonModule, AppModule ],
declarations: [ AppComponent1 ]
})
export class DummyModule1 {}
/////////
import { AppComponent as AppComponent2 } from './app.component.2';
@NgModule({
imports: [ CommonModule, AppModule ],
declarations: [ AppComponent2 ]
})
export class DummyModule2 {}

View File

@ -1,35 +0,0 @@
/// Dummy modules to satisfy Angular Language Service
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
////////
import { HeroListComponent as HeroListComponent1 } from './hero-list.component.1';
@NgModule({
imports: [ CommonModule ],
declarations: [ HeroListComponent1 ],
exports: [ HeroListComponent1 ]
})
export class DummyModule1 {}
/////////
import { HeroListComponent as HeroListComponent2 } from './hero-list.component.2';
@NgModule({
imports: [ CommonModule ],
declarations: [ HeroListComponent2 ]
})
export class DummyModule2 {}
/////////
import { HeroesComponent as HeroesComponent1 } from './heroes.component.1';
@NgModule({
imports: [ CommonModule, DummyModule1 ],
declarations: [ HeroesComponent1 ]
})
export class DummyModule3 {}

View File

@ -1,5 +1,6 @@
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { HEROES } from './mock-heroes'; import { HEROES } from './mock-heroes';
@Component({ @Component({
@ -10,8 +11,6 @@ import { HEROES } from './mock-heroes';
</div> </div>
` `
}) })
// #docregion class
export class HeroListComponent { export class HeroListComponent {
heroes = HEROES; heroes = HEROES;
} }
// #enddocregion class

View File

@ -1,6 +1,7 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Hero } from './hero'; import { Hero } from './hero';
// #enddocregion // #enddocregion
import { HeroService } from './hero.service.1'; import { HeroService } from './hero.service.1';

View File

@ -1,6 +1,7 @@
/* tslint:disable:one-line */ /* tslint:disable:one-line */
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Hero } from './hero'; import { Hero } from './hero';
import { HeroService } from './hero.service'; import { HeroService } from './hero.service';

View File

@ -1,6 +0,0 @@
import { Injectable } from '@angular/core';
@Injectable()
export class HeroService {
constructor() { }
}

View File

@ -1,5 +1,6 @@
// #docregion // #docregion
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes'; import { HEROES } from './mock-heroes';
@Injectable() @Injectable()

View File

@ -1,5 +1,6 @@
// #docregion // #docregion
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes'; import { HEROES } from './mock-heroes';
import { Logger } from '../logger.service'; import { Logger } from '../logger.service';

View File

@ -1,5 +1,6 @@
// #docregion // #docregion
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes'; import { HEROES } from './mock-heroes';
import { Logger } from '../logger.service'; import { Logger } from '../logger.service';

View File

@ -1,14 +1,17 @@
// #docplaster // #docplaster
// #docregion, v1 // #docregion full, v1
import { Component } from '@angular/core'; import { Component } from '@angular/core';
// #enddocregion v1 // #enddocregion v1
import { HeroService } from './hero.service';
// #docregion v1 import { HeroService } from './hero.service';
// #enddocregion full
// #docregion full, v1
@Component({ @Component({
selector: 'app-heroes', selector: 'app-heroes',
// #enddocregion v1 // #enddocregion v1
providers: [ HeroService ], providers: [HeroService],
// #docregion v1 // #docregion v1
template: ` template: `
<h2>Heroes</h2> <h2>Heroes</h2>

View File

@ -1,13 +1,14 @@
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { heroServiceProvider } from './hero.service.provider'; import { heroServiceProvider } from './hero.service.provider';
@Component({ @Component({
selector: 'app-heroes', selector: 'app-heroes',
providers: [ heroServiceProvider ],
template: ` template: `
<h2>Heroes</h2> <h2>Heroes</h2>
<app-hero-list></app-hero-list> <app-hero-list></app-hero-list>
` `,
providers: [heroServiceProvider]
}) })
export class HeroesComponent { } export class HeroesComponent { }

View File

@ -1,12 +1,9 @@
/* /* tslint:disable:one-line:check-open-brace*/
* A collection of demo components showing different ways to provide services // Examples of provider arrays
* in @Component metadata // #docplaster
*/
import { Component, Inject, Injectable, OnInit } from '@angular/core'; import { Component, Inject, Injectable, OnInit } from '@angular/core';
import { import { APP_CONFIG, AppConfig,
APP_CONFIG,
AppConfig,
HERO_DI_CONFIG } from './app.config'; HERO_DI_CONFIG } from './app.config';
import { HeroService } from './heroes/hero.service'; import { HeroService } from './heroes/hero.service';
@ -14,8 +11,9 @@ import { heroServiceProvider } from './heroes/hero.service.provider';
import { Logger } from './logger.service'; import { Logger } from './logger.service';
import { UserService } from './user.service'; import { UserService } from './user.service';
const template = '{{log}}'; let template = '{{log}}';
//////////////////////////////////////////
@Component({ @Component({
selector: 'provider-1', selector: 'provider-1',
template: template, template: template,
@ -32,7 +30,6 @@ export class Provider1Component {
} }
////////////////////////////////////////// //////////////////////////////////////////
@Component({ @Component({
selector: 'provider-3', selector: 'provider-3',
template: template, template: template,
@ -50,7 +47,7 @@ export class Provider3Component {
} }
////////////////////////////////////////// //////////////////////////////////////////
export class BetterLogger extends Logger {} class BetterLogger extends Logger {}
@Component({ @Component({
selector: 'provider-4', selector: 'provider-4',
@ -69,10 +66,9 @@ export class Provider4Component {
} }
////////////////////////////////////////// //////////////////////////////////////////
// #docregion EvenBetterLogger // #docregion EvenBetterLogger
@Injectable() @Injectable()
export class EvenBetterLogger extends Logger { class EvenBetterLogger extends Logger {
constructor(private userService: UserService) { super(); } constructor(private userService: UserService) { super(); }
log(message: string) { log(message: string) {
@ -100,10 +96,8 @@ export class Provider5Component {
} }
////////////////////////////////////////// //////////////////////////////////////////
class NewLogger extends Logger {}
export class NewLogger extends Logger {} class OldLogger {
export class OldLogger {
logs: string[] = []; logs: string[] = [];
log(message: string) { log(message: string) {
throw new Error('Should not call the old logger!'); throw new Error('Should not call the old logger!');
@ -155,14 +149,11 @@ export class Provider6bComponent {
} }
////////////////////////////////////////// //////////////////////////////////////////
// #docregion silent-logger // #docregion silent-logger
// An object in the shape of the logger service // An object in the shape of the logger service
export function SilentLoggerFn() {} let silentLogger = {
const silentLogger = {
logs: ['Silent logger says "Shhhhh!". Provided via "useValue"'], logs: ['Silent logger says "Shhhhh!". Provided via "useValue"'],
log: SilentLoggerFn log: () => {}
}; };
// #enddocregion silent-logger // #enddocregion silent-logger
@ -181,7 +172,6 @@ export class Provider7Component {
this.log = logger.logs[0]; this.log = logger.logs[0];
} }
} }
///////////////// /////////////////
@Component({ @Component({
@ -199,7 +189,6 @@ export class Provider8Component {
} }
///////////////// /////////////////
@Component({ @Component({
selector: 'provider-9', selector: 'provider-9',
template: template, template: template,
@ -229,7 +218,6 @@ export class Provider9Component implements OnInit {
this.log = 'APP_CONFIG Application title is ' + this.config.title; this.log = 'APP_CONFIG Application title is ' + this.config.title;
} }
} }
////////////////////////////////////////// //////////////////////////////////////////
// Sample providers 1 to 7 illustrate a required logger dependency. // Sample providers 1 to 7 illustrate a required logger dependency.
// Optional logger, can be null // Optional logger, can be null
@ -260,7 +248,6 @@ export class Provider10Component implements OnInit {
} }
///////////////// /////////////////
@Component({ @Component({
selector: 'app-providers', selector: 'app-providers',
template: ` template: `

View File

@ -1,33 +0,0 @@
import { NgModule } from '@angular/core';
import {
Provider1Component,
Provider3Component,
Provider4Component,
Provider5Component,
Provider6aComponent,
Provider6bComponent,
Provider7Component,
Provider8Component,
Provider9Component,
Provider10Component,
ProvidersComponent,
} from './providers.component';
@NgModule({
declarations: [
Provider1Component,
Provider3Component,
Provider4Component,
Provider5Component,
Provider6aComponent,
Provider6bComponent,
Provider7Component,
Provider8Component,
Provider9Component,
Provider10Component,
ProvidersComponent,
],
exports: [ ProvidersComponent ]
})
export class ProvidersModule {}

View File

@ -4,7 +4,6 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Hero } from './heroes/hero';
import { HeroService } from './heroes/hero.service'; import { HeroService } from './heroes/hero.service';
import { HeroListComponent } from './heroes/hero-list.component'; import { HeroListComponent } from './heroes/hero-list.component';
@ -23,13 +22,12 @@ export class TestComponent {
function runTests() { function runTests() {
// #docregion spec // #docregion spec
const expectedHeroes = [{name: 'A'}, {name: 'B'}] let expectedHeroes = [{name: 'A'}, {name: 'B'}]
const mockService = <HeroService> {getHeroes: () => expectedHeroes } let mockService = <HeroService> {getHeroes: () => expectedHeroes }
it('should have heroes when HeroListComponent created', () => { it('should have heroes when HeroListComponent created', () => {
// Pass the mock to the constructor as the Angular injector would let hlc = new HeroListComponent(mockService);
const component = new HeroListComponent(mockService); expect(hlc.heroes.length).toEqual(expectedHeroes.length);
expect(component.heroes.length).toEqual(expectedHeroes.length);
}); });
// #enddocregion spec // #enddocregion spec

View File

@ -0,0 +1,15 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>Simple Deployment</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>
`
})
export class AppComponent { }

View File

@ -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 { }

View File

@ -0,0 +1,9 @@
// #docregion
import { Component } from '@angular/core';
@Component({
template: `
<h2>CRISIS CENTER</h2>
<p>Get your crisis here</p>`
})
export class CrisisListComponent { }

View File

@ -0,0 +1,10 @@
// #docregion
import { Component } from '@angular/core';
@Component({
template: `
<h2>HEROES</h2>
<p>Get your heroes here</p>
`
})
export class HeroListComponent { }

View File

@ -0,0 +1,38 @@
<!-- #docregion -->
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Doesn't load from node_modules! -->
<!-- Set the base href -->
<base href="/">
<title>Simple Deployment</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<!-- #docregion node-module-scripts -->
<!-- Polyfills -->
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
<!-- Update these package versions as needed -->
<script src="https://unpkg.com/zone.js@0.8.4?main=browser"></script>
<script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script>
<!-- #enddocregion node-module-scripts -->
<!-- #docregion systemjs-config -->
<!-- This SystemJS configuration loads umd packages from the web -->
<script src="systemjs.config.server.js"></script>
<!-- #enddocregion systemjs-config -->
<script>
System.import('main.js')
.catch(function(err){ console.error(err); });
</script>
</head>
<body>
<my-app></my-app>
</body>
</html>

View File

@ -1,12 +1,15 @@
// #docregion // #docregion
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module'; import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) { // #docregion enableProdMode
import { enableProdMode } from '@angular/core';
// Enable production mode unless running locally
if (!/localhost/.test(document.location.host)) {
enableProdMode(); enableProdMode();
} }
// #enddocregion enableProdMode
platformBrowserDynamic().bootstrapModule(AppModule); platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -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);

View File

@ -1 +0,0 @@
<app-hero-form></app-hero-form>

View File

@ -3,7 +3,6 @@ import { Component } from '@angular/core';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
templateUrl: './app.component.html', template: '<app-hero-form></app-hero-form>'
styleUrls: ['./app.component.css']
}) })
export class AppComponent { } export class AppComponent { }

View File

@ -4,7 +4,7 @@ import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { HeroFormComponent } from './hero-form/hero-form.component'; import { HeroFormComponent } from './hero-form.component';
@NgModule({ @NgModule({
imports: [ imports: [
@ -15,7 +15,6 @@ import { HeroFormComponent } from './hero-form/hero-form.component';
AppComponent, AppComponent,
HeroFormComponent HeroFormComponent
], ],
providers: [],
bootstrap: [ AppComponent ] bootstrap: [ AppComponent ]
}) })
export class AppModule { } export class AppModule { }

View File

@ -2,12 +2,11 @@
// #docregion , v1, final // #docregion , v1, final
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Hero } from '../hero'; import { Hero } from './hero';
@Component({ @Component({
selector: 'app-hero-form', selector: 'app-hero-form',
templateUrl: './hero-form.component.html', templateUrl: './hero-form.component.html'
styleUrls: ['./hero-form.component.css']
}) })
export class HeroFormComponent { export class HeroFormComponent {

View File

@ -1 +0,0 @@
@import url('https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css');

View File

@ -1,7 +0,0 @@
// #docregion import-locale-extra
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';
import localeFrExtra from '@angular/common/locales/extra/fr';
registerLocaleData(localeFr, 'fr-FR', localeFrExtra);
// #enddocregion import-locale-extra

View File

@ -1,13 +0,0 @@
// #docregion
import { LOCALE_ID, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from '../src/app/app.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
providers: [ { provide: LOCALE_ID, useValue: 'fr' } ],
bootstrap: [ AppComponent ]
})
export class AppModule { }

View File

@ -1,22 +0,0 @@
// #docregion
import { enableProdMode, TRANSLATIONS, TRANSLATIONS_FORMAT } 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();
}
// use the require method provided by webpack
declare const require;
// we use the webpack raw-loader to return the content as a string
const translations = require(`raw-loader!./locale/messages.fr.xlf`);
platformBrowserDynamic().bootstrapModule(AppModule, {
providers: [
{provide: TRANSLATIONS, useValue: translations},
{provide: TRANSLATIONS_FORMAT, useValue: 'xlf'}
]
});

View File

@ -1,13 +0,0 @@
// #docregion
import { MissingTranslationStrategy } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
// ...
platformBrowserDynamic().bootstrapModule(AppModule, {
missingTranslation: MissingTranslationStrategy.Error,
providers: [
// ...
]
});

View File

@ -1,73 +0,0 @@
<!-- The `messages.fr.xlf` after translation for documentation purposes -->
<!-- #docregion -->
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<!-- #docregion translated-hello-before -->
<trans-unit id="introductionHeader" datatype="html">
<source>Hello i18n!</source>
<note priority="1" from="description">An introduction header for this sample</note>
<note priority="1" from="meaning">User welcome</note>
</trans-unit>
<!-- #enddocregion translated-hello-before -->
<!-- #docregion translated-hello -->
<!-- #docregion custom-id -->
<trans-unit id="introductionHeader" datatype="html">
<!-- #enddocregion custom-id -->
<source>Hello i18n!</source>
<target>Bonjour i18n !</target>
<note priority="1" from="description">An introduction header for this sample</note>
<note priority="1" from="meaning">User welcome</note>
</trans-unit>
<!-- #enddocregion translated-hello -->
<!-- #docregion translated-other-nodes -->
<!-- #docregion generated-id -->
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
<!-- #enddocregion generated-id -->
<source>I don&apos;t output any element</source>
<target>Je n'affiche aucun élément</target>
</trans-unit>
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
<source>Angular logo</source>
<target>Logo d'Angular</target>
</trans-unit>
<!-- #enddocregion translated-other-nodes -->
<!-- #docregion translated-plural -->
<trans-unit id="5a134dee893586d02bffc9611056b9cadf9abfad" datatype="html">
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
<target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes} }</target>
</trans-unit>
<!-- #enddocregion translated-plural -->
<!-- #docregion translated-select -->
<!-- #docregion translate-select-1 -->
<trans-unit id="52515023fc70c216ef291086c1962ff135a9fe13" datatype="html">
<source>The author is <x id="ICU" equiv-text="{gender, select, m {...} f {...} o {...}}"/></source>
<target>L'auteur est <x id="ICU" equiv-text="{gender, select, m {...} f {...} o {...}}"/></target>
</trans-unit>
<!-- #enddocregion translate-select-1 -->
<!-- #docregion translate-select-2 -->
<trans-unit id="4e6fd3f2bb3477e8ad2088f03257f6e1b8b515a5" datatype="html">
<source>{VAR_SELECT, select, m {male} f {female} o {other} }</source>
<target>{VAR_SELECT, select, m {un homme} f {une femme} o {autre} }</target>
</trans-unit>
<!-- #enddocregion translate-select-2 -->
<!-- #enddocregion translated-select -->
<!-- #docregion translate-nested -->
<!-- #docregion translate-nested-1 -->
<trans-unit id="f7a55c9ef7c5b37147825a9041263305063e63e9" datatype="html">
<source>Updated: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></source>
<target>Mis à jour: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></target>
</trans-unit>
<!-- #enddocregion translate-nested-1 -->
<!-- #docregion translate-nested-2 -->
<trans-unit id="80b5ac44661751e191225c0b1e000bceeeccb52c" datatype="html">
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago by {VAR_SELECT, select, m {male} f {female} o {other} }} }</source>
<target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes par {VAR_SELECT, select, m {un homme} f {une femme} o {autre} }} }</target>
</trans-unit>
<!-- #enddocregion translate-nested-2 -->
<!-- #enddocregion translate-nested -->
</body>
</file>
</xliff>

View File

@ -0,0 +1,36 @@
'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');
});
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');
});
it('should display the nested expression', function() {
expect(element.all(by.css('span')).get(2).getText()).toBe('Aquí tenemos: 3 mujeres');
});
});

View File

@ -1,45 +0,0 @@
import { browser, element, by } from 'protractor';
describe('i18n E2E Tests', () => {
beforeEach(function () {
browser.get('');
});
it('should display i18n translated welcome: Bonjour !', function () {
expect(element(by.css('h1')).getText()).toEqual('Bonjour i18n !');
});
it('should display the node texts without elements', function () {
expect(element(by.css('app-root')).getText()).toContain(`Je n'affiche aucun élément`);
});
it('should display the translated title attribute', function () {
const title = element(by.css('img')).getAttribute('title');
expect(title).toBe(`Logo d'Angular`);
});
it('should display the ICU plural expression', function () {
expect(element.all(by.css('span')).get(0).getText()).toBe(`Mis à jour à l'instant`);
});
it('should display the ICU select expression', function () {
const selectIcuExp = element.all(by.css('span')).get(1);
expect(selectIcuExp.getText()).toBe(`L'auteur est une femme`);
element.all(by.css('button')).get(2).click();
expect(selectIcuExp.getText()).toBe(`L'auteur est un homme`);
});
it('should display the nested expression', function() {
const nestedExp = element.all(by.css('span')).get(2);
const incBtn = element.all(by.css('button')).get(0);
expect(nestedExp.getText()).toBe(`Mis à jour: à l'instant`);
incBtn.click();
expect(nestedExp.getText()).toBe(`Mis à jour: il y a une minute`);
incBtn.click();
incBtn.click();
element.all(by.css('button')).get(4).click();
expect(nestedExp.getText()).toBe(`Mis à jour: il y a 3 minutes par autre`);
});
});

View File

@ -1,3 +0,0 @@
{
"projectType": "i18n"
}

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="introductionHeader" datatype="html">
<source>
Hello i18n!
</source>
<target/>
<note priority="1" from="description">An introduction header for this sample</note>
<note priority="1" from="meaning">User welcome</note>
</trans-unit>
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
<source>I don&apos;t output any element</source>
<target/>
</trans-unit>
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
<source>Angular logo</source>
<target/>
</trans-unit>
<trans-unit id="6e22e74e8cbd3095560cfe08993c4fdfa3c50eb0" datatype="html">
<source/>
<target/>
</trans-unit>
<trans-unit id="61cafedb85466ab789b3ae817bba1a545468ee1c" datatype="html">
<source>The hero is <x id="ICU"/></source>
<target/>
</trans-unit>
<trans-unit id="14c7055d67771a3b7b6888d282ac092896be06b6" datatype="html">
<source/>
<target/>
</trans-unit>
<trans-unit id="2cf9a08c5b6e3612572a2a36dd46563013848382" datatype="html">
<source>Here we have: <x id="ICU"/></source>
<target/>
</trans-unit>
<trans-unit id="db1b921b55301ce3957e382090729562002da036" datatype="html">
<source/>
<target/>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -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"]
}

View File

@ -29,3 +29,4 @@
<!--#docregion i18n-title--> <!--#docregion i18n-title-->
<img [src]="logo" title="Angular logo"> <img [src]="logo" title="Angular logo">
<!--#enddocregion i18n-title--> <!--#enddocregion i18n-title-->
Contact GitHub API Training Shop Blog About

View File

@ -17,19 +17,19 @@
<br> <br>
<button (click)="inc(1)">+</button> <button (click)="inc(-1)">-</button> <button (click)="inc(1)">+</button> <button (click)="inc(-1)">-</button>
<!--#docregion i18n-plural--> <!--#docregion i18n-plural-->
<span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago}}</span> <span i18n>{wolves, plural, =0 {no wolves} =1 {one wolf} =2 {two wolves} other {a wolf pack}}</span>
<!--#enddocregion i18n-plural--> <!--#enddocregion i18n-plural-->
({{minutes}}) ({{wolves}})
<br><br> <br><br>
<button (click)="male()">&#9794;</button> <button (click)="female()">&#9792;</button> <button (click)="other()">&#9895;</button> <button (click)="male()">&#9794;</button> <button (click)="female()">&#9792;</button>
<!--#docregion i18n-select--> <!--#docregion i18n-select-->
<span i18n>The author is {gender, select, m {male} f {female} o {other}}</span> <span i18n>The hero is {gender, select, m {male} f {female}}</span>
<!--#enddocregion i18n-select--> <!--#enddocregion i18n-select-->
<br><br> <br><br>
<!--#docregion i18n-nested--> <!--#docregion i18n-nested-->
<span i18n>Updated: {minutes, plural, <span i18n>Here we have: {count, plural,
=0 {just now} =0 {no one}
=1 {one minute ago} =1 {one {gender, select, male {man} female {woman}}}
other {{{minutes}} minutes ago by {gender, select, m {male} f {female} o {other}}}} other {{{heroes.length}} {gender, select, male {men} female {women}}}
</span> }</span>
<!--#enddocregion i18n-nested--> <!--#enddocregion i18n-nested-->

View File

@ -2,20 +2,20 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
@Component({ @Component({
selector: 'app-root', selector: 'my-app',
templateUrl: './app.component.html' templateUrl: './app.component.html'
}) })
export class AppComponent { export class AppComponent {
minutes = 0; wolves = 0;
gender = 'f'; gender = 'f';
fly = true; fly = true;
logo = 'https://angular.io/assets/images/logos/angular/angular.png'; logo = 'https://angular.io/assets/images/logos/angular/angular.png';
count = 3;
heroes: string[] = ['Magneta', 'Celeritas', 'Dynama']; heroes: string[] = ['Magneta', 'Celeritas', 'Dynama'];
inc(i: number) { inc(i: number) {
this.minutes = Math.min(5, Math.max(0, this.minutes + i)); this.wolves = Math.min(5, Math.max(0, this.wolves + i));
} }
male() { this.gender = 'm'; } male() { this.gender = 'm'; }
female() { this.gender = 'f'; } female() { this.gender = 'f'; }
other() { this.gender = 'o'; }
} }

View File

@ -2,6 +2,5 @@
import { registerLocaleData } from '@angular/common'; import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr'; import localeFr from '@angular/common/locales/fr';
// the second parameter 'fr' is optional registerLocaleData(localeFr);
registerLocaleData(localeFr, 'fr');
// #enddocregion import-locale // #enddocregion import-locale

View File

@ -0,0 +1,7 @@
// #docregion import-locale-extra
import { registerLocaleData } from '@angular/common';
import localeEnGB from '@angular/common/locales/en-GB';
import localeEnGBExtra from '@angular/common/locales/extra/en-GB';
registerLocaleData(localeEnGB, localeEnGBExtra);
// #enddocregion import-locale-extra

View File

@ -9,4 +9,5 @@ import { AppComponent } from './app.component';
declarations: [ AppComponent ], declarations: [ AppComponent ],
bootstrap: [ AppComponent ] bootstrap: [ AppComponent ]
}) })
export class AppModule { } export class AppModule { }

View File

@ -0,0 +1,41 @@
// #docplaster
// #docregion without-missing-translation
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID, MissingTranslationStrategy, StaticProvider } from '@angular/core';
import { CompilerConfig } from '@angular/compiler';
export function getTranslationProviders(): Promise<StaticProvider[]> {
// 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: StaticProvider[] = [];
// 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`;
// #docregion missing-translation
return getTranslationsWithSystemJs(translationFile)
.then( (translations: string ) => [
{ provide: TRANSLATIONS, useValue: translations },
{ provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
{ provide: LOCALE_ID, useValue: locale },
// #enddocregion without-missing-translation
{ provide: CompilerConfig, useValue: new CompilerConfig({ missingTranslation: MissingTranslationStrategy.Error }) }
// #docregion without-missing-translation
])
.catch(() => noProviders); // ignore if file not found
// #enddocregion missing-translation
}
declare var System: any;
function getTranslationsWithSystemJs(file: string) {
return System.import(file + '!text'); // relies on text plugin
}
// #enddocregion without-missing-translation

View File

@ -1,14 +1,39 @@
<!-- #docregion -->
<!DOCTYPE html> <!DOCTYPE html>
<!-- #docregion -->
<html> <html>
<head> <head>
<base href="/">
<title>Angular i18n example</title> <title>Angular i18n example</title>
<base href="/">
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<!-- #docregion i18n -->
<script>
// Get the locale id somehow
document.locale = 'es';
// Map to the text plugin
System.config({
map: {
text: 'systemjs-text-plugin.js'
}
});
// Launch the app
System.import('main.js').catch(function(err){ console.error(err); });
</script>
<!-- #enddocregion i18n -->
</head> </head>
<body> <body>
<app-root>Loading...</app-root> <my-app>Loading...</my-app>
</body> </body>
</html> </html>
<!-- #enddocregion -->

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="introductionHeader" datatype="html">
<source>Hello i18n!</source>
<target>¡Hola i18n!</target>
<note priority="1" from="description">An introduction header for this sample</note>
<note priority="1" from="meaning">User welcome</note>
</trans-unit>
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
<source>I don&apos;t output any element</source>
<target>No genero ningún elemento</target>
</trans-unit>
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
<source>Angular logo</source>
<target>Logo de Angular</target>
</trans-unit>
<trans-unit id="6e22e74e8cbd3095560cfe08993c4fdfa3c50eb0" datatype="html">
<source/>
<target>{wolves, plural, =0 {ningún lobo} =1 {un lobo} =2 {dos lobos} other {una horda de lobos}}</target>
</trans-unit>
<trans-unit id="61cafedb85466ab789b3ae817bba1a545468ee1c" datatype="html">
<source>The hero is <x id="ICU"/></source>
<target>El heroe es <x id="ICU"/></target>
</trans-unit>
<trans-unit id="14c7055d67771a3b7b6888d282ac092896be06b6" datatype="html">
<source/>
<target>{gender, select, m {hombre} f {mujer}}</target>
</trans-unit>
<trans-unit id="2cf9a08c5b6e3612572a2a36dd46563013848382" datatype="html">
<source>Here we have: <x id="ICU"/></source>
<target>Aquí tenemos: <x id="ICU"/></target>
</trans-unit>
<trans-unit id="db1b921b55301ce3957e382090729562002da036" datatype="html">
<source/>
<target>
{count, plural,
=0 { nadie }
=1 {{gender, select, m {un hombre} f {una mujer}}}
other {{{heroes.length}} {gender, select, m {hombres} f {mujeres}}}
}
</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -0,0 +1,80 @@
<!-- The `messages.es.xlf` after translation for documentation purposes -->
<!-- #docregion -->
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<!-- #docregion translated-hello -->
<!-- #docregion custom-id -->
<trans-unit id="introductionHeader" datatype="html">
<!-- #enddocregion custom-id -->
<source>Hello i18n!</source>
<target>¡Hola i18n!</target>
<note priority="1" from="description">An introduction header for this sample</note>
<note priority="1" from="meaning">User welcome</note>
</trans-unit>
<!-- #enddocregion translated-hello -->
<!-- #docregion translated-other-nodes -->
<!-- #docregion generated-id -->
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
<!-- #enddocregion generated-id -->
<source>I don&apos;t output any element</source>
<target>No genero ningún elemento</target>
</trans-unit>
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
<source>Angular logo</source>
<target>Logo de Angular</target>
</trans-unit>
<!-- #enddocregion translated-other-nodes -->
<!-- #docregion translated-plural -->
<trans-unit id="6e22e74e8cbd3095560cfe08993c4fdfa3c50eb0" datatype="html">
<source/>
<target>{wolves, plural, =0 {ningún lobo} =1 {un lobo} =2 {dos lobos} other {una horda de lobos}}</target>
</trans-unit>
<!-- #enddocregion translated-plural -->
<!-- #docregion translated-select -->
<!-- #docregion translate-select-1 -->
<trans-unit id="61cafedb85466ab789b3ae817bba1a545468ee1c" datatype="html">
<source>The hero is <x id="ICU"/></source>
<target>El heroe es <x id="ICU"/></target>
</trans-unit>
<!-- #enddocregion translate-select-1 -->
<!-- #docregion translate-select-2 -->
<trans-unit id="14c7055d67771a3b7b6888d282ac092896be06b6" datatype="html">
<source/>
<target>{gender, select, m {hombre} f {mujer}}</target>
</trans-unit>
<!-- #enddocregion translate-select-2 -->
<!-- #enddocregion translated-select -->
<trans-unit id="db04527df562d12c8607eab2b5723ef6e2066ba0" datatype="html">
<source>Here we have: <x id="ICU"/></source>
<target/>
</trans-unit>
<trans-unit id="000058be4e6f08b685d1d0a70f9da68067df7379" datatype="html">
<source/>
<target/>
</trans-unit>
<!-- #docregion translate-nested -->
<!-- #docregion translate-nested-1 -->
<trans-unit id="2cf9a08c5b6e3612572a2a36dd46563013848382" datatype="html">
<source>Here we have: <x id="ICU"/></source>
<target>Aquí tenemos: <x id="ICU"/></target>
</trans-unit>
<!-- #enddocregion translate-nested-1 -->
<!-- #docregion translate-nested-2 -->
<trans-unit id="db1b921b55301ce3957e382090729562002da036" datatype="html">
<source/>
<target>
{count, plural,
=0 { nadie }
=1 {{gender, select, m {un hombre} f {una mujer}}}
other {{{heroes.length}} {gender, select, m {hombres} f {mujeres}}}
}
</target>
</trans-unit>
<!-- #enddocregion translate-nested-2 -->
<!-- #enddocregion translate-nested -->
</body>
</file>
</xliff>

View File

@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="introductionHeader" datatype="html">
<source>
Hello i18n!
</source>
<target>
Bonjour i18n !
</target>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">4</context>
</context-group>
<note priority="1" from="description">An introduction header for this sample</note>
<note priority="1" from="meaning">User welcome</note>
</trans-unit>
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
<source>I don&apos;t output any element</source>
<target>Je n'affiche aucun élément</target>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">10</context>
</context-group>
</trans-unit>
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
<source>Angular logo</source>
<target>Logo d'Angular</target>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">16</context>
</context-group>
</trans-unit>
<trans-unit id="d69f6b42305f49332026fef24b40227f02e34594" datatype="html">
<source>Updated <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></source>
<target>Mis à jour <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></target>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">21</context>
</context-group>
</trans-unit>
<trans-unit id="5a134dee893586d02bffc9611056b9cadf9abfad" datatype="html">
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
<target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes} }</target>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">21</context>
</context-group>
</trans-unit>
<trans-unit id="52515023fc70c216ef291086c1962ff135a9fe13" datatype="html">
<source>The author is <x id="ICU" equiv-text="{gender, select, m {...} f {...} o {...}}"/></source>
<target>L'auteur est <x id="ICU" equiv-text="{gender, select, m {...} f {...} o {...}}"/></target>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">27</context>
</context-group>
</trans-unit>
<trans-unit id="4e6fd3f2bb3477e8ad2088f03257f6e1b8b515a5" datatype="html">
<source>{VAR_SELECT, select, m {male} f {female} o {other} }</source>
<target>{VAR_SELECT, select, m {un homme} f {une femme} o {autre} }</target>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">27</context>
</context-group>
</trans-unit>
<trans-unit id="f7a55c9ef7c5b37147825a9041263305063e63e9" datatype="html">
<source>Updated: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/>
</source>
<target>Mis à jour: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/>
</target>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">31</context>
</context-group>
</trans-unit>
<trans-unit id="80b5ac44661751e191225c0b1e000bceeeccb52c" datatype="html">
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago by {VAR_SELECT, select, m {male} f {female} o {other} }} }</source>
<target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes par {VAR_SELECT, select, m {un homme} f {une femme} o {autre} }} }</target>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">31</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -1,75 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="introductionHeader" datatype="html">
<source>
Hello i18n!
</source>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">4</context>
</context-group>
<note priority="1" from="description">An introduction header for this sample</note>
<note priority="1" from="meaning">User welcome</note>
</trans-unit>
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
<source>I don&apos;t output any element</source>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">10</context>
</context-group>
</trans-unit>
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
<source>Angular logo</source>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">16</context>
</context-group>
</trans-unit>
<trans-unit id="d69f6b42305f49332026fef24b40227f02e34594" datatype="html">
<source>Updated <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></source>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">21</context>
</context-group>
</trans-unit>
<trans-unit id="5a134dee893586d02bffc9611056b9cadf9abfad" datatype="html">
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">21</context>
</context-group>
</trans-unit>
<trans-unit id="52515023fc70c216ef291086c1962ff135a9fe13" datatype="html">
<source>The author is <x id="ICU" equiv-text="{gender, select, m {...} f {...} o {...}}"/></source>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">27</context>
</context-group>
</trans-unit>
<trans-unit id="4e6fd3f2bb3477e8ad2088f03257f6e1b8b515a5" datatype="html">
<source>{VAR_SELECT, select, m {male} f {female} o {other} }</source>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">27</context>
</context-group>
</trans-unit>
<trans-unit id="f7a55c9ef7c5b37147825a9041263305063e63e9" datatype="html">
<source>Updated: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/>
</source>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">31</context>
</context-group>
</trans-unit>
<trans-unit id="80b5ac44661751e191225c0b1e000bceeeccb52c" datatype="html">
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago by {VAR_SELECT, select, m {male} f {female} o {other} }} }</source>
<context-group purpose="location">
<context context-type="sourcefile">app\app.component.ts</context>
<context context-type="linenumber">31</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -0,0 +1,6 @@
// #docregion
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -1,12 +1,10 @@
// #docregion // #docregion
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { getTranslationProviders } from './app/i18n-providers';
import { AppModule } from './app/app.module'; import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) { getTranslationProviders().then(providers => {
enableProdMode(); const options = { providers };
} platformBrowserDynamic().bootstrapModule(AppModule, options);
});
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -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});';
}

View File

@ -1,11 +0,0 @@
{
"files":[
"!dist/",
"!**/*.d.ts",
"!src/**/*.js",
"!doc-files/**/*",
"**/*.xlf"
],
"removeSystemJsConfig": true,
"type": "i18n"
}

Some files were not shown because too many files have changed in this diff Show More