Compare commits

...

189 Commits
7.2.4 ... 7.2.8

Author SHA1 Message Date
903d28fe86 release: cut the v7.2.8 release 2019-03-06 09:58:26 -08:00
6945f7978e build(docs-infra): ivy prebuild script should not run ngcc for all formats (#29122)
Currently when building AIO with Ivy, we run Ngcc and transform
all found formats. This potentially slows down the build (and
therefore the "test_aio_local_ivy" job). Since it's not necessary
to build all formats, and we only need "fesm5" and "fesm2015",
we can explicitly specify the required formats.

**Note**: Currently this does not have any big effect, because Angular
Material does not ship ES2015/ES5 files. The change primarily just
suppresses the Ngcc messages for Material not providing ES2015/ES5
entry-points.

Technically if new non-Ivy packages are added to AIO, this
speeds up the build as we don't build the unused formats.

PR Close #29122
2019-03-05 16:11:05 -08:00
27afe01910 ci(docs-infra): "test_aio_local_ivy" job should attach ivy package output (#29122)
Currently the "test_docs_examples_ivy" job attaches
the legacy package output, while we can also attach
the Ivy NPM package output. We don't need Ngcc to downlevel
the Angular packages in order to build AIO with Ivy.

PR Close #29122
2019-03-05 16:11:05 -08:00
36b6110e7d docs: order upcoming events in chronological order (#29115)
Related to https://github.com/angular/angular/pull/29095#issuecomment-469386472.

PR Close #29115
2019-03-05 09:51:10 -08:00
24a1e146da refactor(language-service): clean up imports language-service and misspellings in public API (#29097)
PR Close #29097
2019-03-05 09:46:47 -08:00
2256920292 docs(router): align examples in interfaces docs (#29093)
* Use exclusively `TeamComponent` class for examples, as currently there are at least 3 different component classes being used, one of which is actually as a type argument for a `Resolve<T>` implementation.
PR Close #29093
2019-03-05 09:45:53 -08:00
2a25ac2ac9 fix(router): removed obsolete TODO comment (#29085)
PR Close #29085
2019-03-05 09:44:41 -08:00
56693339c2 fix(service-worker): detect new version even if files are identical to an old one (#26006)
Previously, if an app version contained the same files as an older
version (e.g. making a change, then rolling it back), the SW would not
detect it as the latest version (and update clients).

This commit fixes it by adding a `timestamp` field in `ngsw.json`, which
makes each build unique (with sufficiently high probability).

Fixes #24338

PR Close #26006
2019-03-05 09:41:45 -08:00
c976b88dcf docs: fix and add decorator api doc (#28986) (#29112)
PR Close #28986

PR Close #29112
2019-03-04 17:51:42 -08:00
3e08794abf ci: print sauce-connect log output on timeout (#29105)
Currently when `sauce-connect` times out after 2min, we just
print a message saying that the SauceLabs tunnel didn't establish
within 2min. In order to make debugging easier, we now print the
full log file output on failure.

PR Close #29105
2019-03-04 13:37:41 -08:00
b598e884f6 fix(service-worker): ignore passive mixed content requests (#25994)
Although [passive mixed content][1] requests (like images) only produce
a warning without a ServiceWorker, fetching it via a ServiceWorker
results in an error. See
https://github.com/angular/angular/issues/23012#issuecomment-376430187
for more details.

This commit makes the ServiceWorker ignore such requests and let them be
handled by the browser directly to avoid breaking apps that would work
without the ServiceWorker.

[1]: https://developers.google.com/web/fundamentals/security/prevent-mixed-content/what-is-mixed-content#passive_mixed_content

Fixes #23012

PR Close #25994
2019-03-04 11:51:06 -08:00
cf916a03d3 docs(core): tidy up the description of resolveComponentResources() (#28055) (#28736)
There were a number of typos and some of the sentences did not
read well.

PR Close #28055

PR Close #28736
2019-03-04 10:36:27 -08:00
ee6498f37e refactor(compiler): remove unnecessary ! operators from lexer (#28055) (#28736)
When we added the strict null checks, the lexer had some `!`
operators added to prevent the compilation from failing.

This commit resolves this problem correctly and removes the
hacks.

Also the comment

```
// Note: this is always lowercase!
```

has been removed as it is no longer true.

See #24571

PR Close #28055

PR Close #28736
2019-03-04 10:36:27 -08:00
1a0b2ff4fb refactor(compiler): use options argument for parsers (#28055) (#28736)
This commit consolidates the options that can modify the
parsing of text (e.g. HTML, Angular templates, CSS, i18n)
into an AST for further processing into a single `options`
hash.

This makes the code cleaner and more readable, but also
enables us to support further options to parsing without
triggering wide ranging changes to code that should not
be affected by these new options.  Specifically, it will let
us pass information about the placement of a template
that is being parsed in its containing file, which is essential
for accurate SourceMap processing.

PR Close #28055

PR Close #28736
2019-03-04 10:36:27 -08:00
dfb331cd18 docs: fix minor typo (#29100)
tradition -> traditional
PR Close #29100
2019-03-04 10:15:38 -08:00
11c926ce47 docs: add AngularConnect announcement for after ng-conf (#29096)
PR Close #29096
2019-03-04 10:14:42 -08:00
a0119b1144 docs(docs-infra): update where we are presenting (#29095)
PR Close #29095
2019-03-04 10:13:54 -08:00
c938fb4619 build: update to bazel 0.23 2019-03-01 15:40:50 -08:00
2f49a23d64 test(animations): fix unit-based delays within the animation DSL (#28993)
Closes #24291

PR Close #28993
2019-03-01 15:16:49 -08:00
c6eaaf5b3d docs: add how to create a minimal repo in bug report template (#29022)
PR Close #29022
2019-03-01 10:15:30 -08:00
5e38ec8acc ci(docs-infra): disable failing ivy jit systemjs examples (#29046)
As a side effect of 09b34bae8655d4251516655c317b150c46cd3653,
we fixed that the docs systemjs examples currently do not run
with Ivy in JIT mode. This now uncovered new failures with the JIT
resource loading. e.g.

```
zone.js:665 Unhandled Promise rejection: Component 'PhoneListComponent' is not resolved:
 - templateUrl: ./phone-list.template.html
Did you run and wait for 'resolveComponentResources()'? ; Zone: <root> ; Task: Promise.then ; Value: Error: Component 'PhoneListComponent' is not resolved:
 - templateUrl: ./phone-list.template.html
Did you run and wait for 'resolveComponentResources()'?
    at Function.get (directive.ts:54)
    at getComponentDef (definition.ts:648)
    at verifyDeclarationsHaveDefinitions (module.ts:185)
    at Array.forEach (<anonymous>)
    at verifySemanticsOfNgModuleDef (module.ts:159)
    at Function.get (module.ts:132)
    at getInjectorDef (defs.ts:181)
    at R3Injector.processInjectorType (r3_injector.ts:230)
    at eval (r3_injector.ts:114)
    at eval (r3_injector.ts:451) Error: Component 'PhoneListComponent' is not resolved:
```

We temporarily disable these two failing SystemJS examples by adding them to the
`fixmeIvyExamples` list.

PR Close #29046
2019-02-28 17:08:52 -08:00
0cd5964f67 ci: increase parallelism for "test_docs_examples" jobs (#29046)
Currently the docs example tests (`test_docs_examples_ivy`
and `test_docs_examples`) are the culprits for a slow-down
in our overall CI turnaround. We need to increase parallelism
in order to make our CI turnaround more _acceptable_. This is
temporary and the long-term goal is to move these tests to Bazel
with remote build execution.

References #28940

PR Close #29046
2019-02-28 17:08:52 -08:00
f3938a6a2b ci: "test_docs_examples_ivy" should attach ivy package output (#29046)
Currently the "test_docs_examples_ivy" job attaches
the legacy package output, while we can also attach
the Ivy NPM package output. We don't need Ngcc to downlevel
the Angular packages in order to run the docs examples with Ivy.

PR Close #29046
2019-02-28 17:08:52 -08:00
3baa74449c build(docs-infra): examples should not run ngcc for all formats (#29046)
Currently when adding the example boilerplate to all
examples with Ivy enabled, we run Ngcc and transform
all found formats. This potentially slows down the build and
is not necessary as we only need the "fesm5" and "fesm2015" bundles.

PR Close #29046
2019-02-28 17:08:52 -08:00
df4e97c81e build: remove accidentally pushed bazel-out symlink (#29046)
https://github.com/angular/angular/pull/29019 accidentally
committed/pushed the bazel-out symlink. This removes the symlink
git "marker" from the patch branch.

PR Close #29046
2019-02-28 17:08:52 -08:00
d629f2c6a8 build(bazel): revert back to non-vendored yarn in node_repositories() (#29034)
Resolves Windows issue https://github.com/bazelbuild/rules_nodejs/issues/588

PR Close #29034
2019-02-28 10:52:24 -08:00
6ee47d5e76 ci: speed up publish_artifacts CircleCI job for PRs (#29028)
PR Close #29028
2019-02-28 10:39:19 -08:00
9226b421e8 style: enforce buildifier lint rules (#29019)
PR Close #29019
2019-02-28 02:57:35 -08:00
b06847f43d refactor: Consistently use index access on index signature types. (#28937)
This change helps highlight certain misoptimizations with Closure
compiler. It is also stylistically preferable to consistently use index
access on index sig types.

Roughly, when one sees '.foo' they know it is always checked for typos
in the prop name by the type system (unless 'any'), while "['foo']" is
always not.

Once all angular repos are conforming this will become a tsetse.info
check, enforced by bazel.

PR Close #28937
2019-02-28 02:52:19 -08:00
a54a752147 build: add VSCode extension recommendations (#28784)
Previously, the VSCode settings for the workspace specified the
`clang-format.executable` setting to configure auto-formatting to use
`clang-format`. Yet, this setting has no effect without the extension
that provides that configuration option namely [xaver.clang-format][1]).
For people that didn't have the extension installed, VSCode would use
the default formatters, resulting in vastly different file fomatting.

This commit adds a set of [rcommended workspace extensions][2], to help
people get the right extensions when checking out the repository.

The recommended extensions are:
- [gkalpak.aio-docs-utils][3]:
  Utilities to aid in authoring/viewing Angular documentation source
  code. Currently, mainly aid in working with
  `{@example}`/`<code-example>` tags.
- [ms-vscode.vscode-typescript-tslint-plugin][4]:
  Add auto-linting for TS files using `tslint` while editing.
- [xaver.clang-format][1]:
  Add auto-formatting for JS/TS files using `clang-format`.

[1]: https://marketplace.visualstudio.com/items?itemName=xaver.clang-format
[2]: http://go.microsoft.com/fwlink/?LinkId=827846
[3]: https://marketplace.visualstudio.com/items?itemName=gkalpak.aio-docs-utils
[4]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-tslint-plugin

PR Close #28784
2019-02-28 02:47:21 -08:00
d00a2e8920 build: update VSCode settings to limit auto-formatting on save to JS/TS files (#28784)
Previously, auto-formatting on save was enabled for all file types,
which meant also using default VSCode formatting settings for files
where this was not desirable - for example HTML files (such as
angular.io and docs examples templates) and JSON files (such as Firebase
configurations).
This was problematic for the following reasons:
- Unlike with JS/TS files, the formatting of other file types is not
  checked/enforced on CI.
- Formatting is subject to default VSCode settings and everyone's local
  VSCode settings overrides.
- Especially for docs examples files, changing the layout might require
  updating the wording in corresponding guides (e.g. when referring to
  line-numbers).

If we decide that we do want to lint those other file types as well
(which sounds like a good idea), we should do it in a way that ensures
consistent formatting and check the formatting on CI.

PR Close #28784
2019-02-28 02:47:15 -08:00
86981b395d fix(animations): ensure position and display styles are handled outside of keyframes/web-animations (#28911)
When web-animations and/or CSS keyframes are used for animations certain
CSS style values (such as `display` and `position`) may be ignored by a
keyframe-based animation. Angular should special-case these styles to
ensure that they get applied as inline styles throughout the duration of
the animation.

Closes #24923
Closes #25635

Jira Issue: FW-1091
Jira Issue: FW-1092

PR Close #28911
2019-02-27 11:57:31 -08:00
feec963106 style: format (#28995)
PR Close #28995
2019-02-27 08:47:27 -08:00
09fc669b4f build(bazel): allow a user to control a subset of angularCompilerOption in their tsconfig file when using ng_module (#28995)
PR Close #28995
2019-02-27 08:47:27 -08:00
cb339b87f3 release: cut the v7.2.7 release 2019-02-26 16:20:57 -08:00
fdcf877f83 fix(core): traverse and sanitize content of unsafe elements (#28804)
In the past, the sanitizer would remove unsafe elements, but still
traverse and sanitize (and potentially preserve) their content. This was
problematic in the case of `<style></style>` tags, whose content would
be converted to HTML text nodes.

In order to fix this, the sanitizer's behavior was changed in #25879 to
ignore the content of _all_ unsafe elements. While this fixed the
problem with `<style></style>` tags, it unnecessarily removed the
contents for _any_ unsafe element. This was an unneeded breaking change.

This commit partially restores the old sanitizer behavior (namely
traversing content of unsafe elements), but introduces a list of
elements whose content should not be traversed if the elements
themselves are considered unsafe. Currently, this list contains `style`,
`script` and `template`.

Related to #25879 and #26007.

Fixes #28427

PR Close #28804
2019-02-26 13:32:10 -08:00
5b5b9897c9 ci: add workspace prereq job to saucelabs_tests (#28973)
Port of https://github.com/angular/angular/pull/28939, followup to https://github.com/angular/angular/pull/28965.

PR Close #28973
2019-02-26 08:40:44 -08:00
0e7365724e docs: re-phrase note in architecture guide for clarity (#28543)
PR Close #28543
2019-02-26 08:39:17 -08:00
4ef1a3cd97 docs: add Leonardo Zizzamia to GDE resources (#25935)
PR Close #25935
2019-02-25 14:07:56 -08:00
38b5ed05ea docs: add Nebular to UI Components section in resources (#28838)
PR Close #28838
2019-02-25 12:54:58 -08:00
642c015f23 docs: modify the descendant spelling and remove multiple times parent's word (#27886)
PR Close #27886
2019-02-25 12:54:29 -08:00
0977d95802 docs(core): export the ...Decorator interfaces to ensure they are documented (#28836) (#28961)
If an interface is not exported publicly from its package, then the doc-gen
does not see it, and so cannot include it in the generated documentation.

This was the case for a number of `...Decorator` interfaces, such as
`PipeDecorator` and `InputDecorator.

This commit adds these interfaces to the public export to fix this problem.

PR Close #28836

PR Close #28961
2019-02-25 12:53:50 -08:00
d374787db6 ci: add bazel_repository_cache to CircleCI workspace (#28935) (#28965)
PR Close #28935

PR Close #28965
2019-02-25 10:24:34 -08:00
a634deb885 ci: rename install job to setup (#28935) (#28965)
Followup to https://github.com/angular/angular/pull/28928#pullrequestreview-207023800

PR Close #28935

PR Close #28965
2019-02-25 10:24:34 -08:00
bcbd7ed8f0 ci: share data between jobs using workspaces (#28928) (#28965)
PR Close #28928

PR Close #28965
2019-02-25 10:24:34 -08:00
f7de2be3f3 docs: add FancyGrid to resources page (#28949)
PR Close #28949
2019-02-25 10:23:34 -08:00
1e97d511c7 docs: add Human Coders trainings in resources.json (#28840)
PR Close #28840
2019-02-25 10:23:01 -08:00
7e1e00c21e docs: add ngVikings 2019 to events page (#28501)
PR Close #28501
2019-02-25 10:22:28 -08:00
481f4b7412 docs: Updated TOH Heros documentation (#28347)
Updated the TOH Heros documentation to specify that the ng cli now generates 4 files
PR Close #28347
2019-02-25 10:21:45 -08:00
4bc0084e5a docs(router): reword relativeLinkResolution docs to not mention version numbers (#26991)
PR Close #26991
2019-02-22 14:35:55 -08:00
b6864494a1 fix(bazel): pin browser repositories using @npm_bazel_karma//:browser_repositories.bzl in bazel schematics (#28896)
PR Close #28896
2019-02-22 12:19:00 -08:00
0021437ee1 build: fixes (#28896)
PR Close #28896
2019-02-22 12:19:00 -08:00
d91ecd2c8b build: update to rules_typescript 0.25.1 (#28896)
* build_bazel_rules_typescript renamed to npm_bazel_typescript
* build_bazel_rules_karma renamed to npm_bazel_karma
* browser_repositories.bzl removed and now using @npm_bazel_karma//:browser_repositories.bzl
* includes some fixes for future ts_library devmode es2015 support but some failure still remain when devmode is es2015 so this PR keeps it as es5 using the bazelOptions.devmodeTargetOverride tsconfig setting

PR Close #28896
2019-02-22 12:18:59 -08:00
d0018e6bf6 fix(language-service): Fix completions for input/output with alias (#28904)
This PR fixes a bug in autocompletion for @Input/@Output decorator with
an alias. The current implementation ignores the alias.

Credit for this work is attributed to @edgardmessias
The original work fixed the bug, but was lacking test.

PR Close #27959

PR Close #28904
2019-02-22 12:02:18 -08:00
587ca854cc docs: clarify documentation about listening to progress events (#28892)
PR Close #28892
2019-02-22 10:50:43 -08:00
8b9f03d9fa ci: run saucelabs legacy tests every hour (#28903)
Initially when we introduced the cronjob for Saucelabs,
we specified that the tests should run every 4h. Since the
caretaker needs more recent results when merging PRs
or before creating a release, we should run the saucelabs
tests every hour. This still ensures that PRs are not
affected by Saucelabs flakiness or incidents, and
the caretaker can also react better to real browser
failures (and isn't blocked on a 4h time frame)

PR Close #28903
2019-02-22 09:52:06 -08:00
40f1f94fe0 refactor: remove unused and duplicate CSS properties from styleguide examples (#28252)
PR Close #28252
2019-02-22 09:51:36 -08:00
2270467d60 docs: fix ngSwitch example (#28899)
docs: fix ngSwitch example

remove the predix "app-" from the confuse emotion ngSwitchCase.
PR Close #28899
2019-02-22 08:54:00 -08:00
8efda5b353 feat(docs-infra): add meta[name]=Description to angular.io's index.html (#28916)
This change makes angular.io more user and SEO friendly according to web.dev.

See: https://web.dev/discoverable/write-descriptive-text

PR Close #28916
2019-02-21 23:27:29 -08:00
7b7f2d9c1b fix(docs-infra): add [lang] attribute to index.html of angular.io (#28916)
It's the right thing to do, and improves accessiblity.

See: https://dequeuniversity.com/rules/axe/3.1/html-has-lang?application=lighthouse

PR Close #28916
2019-02-21 23:27:28 -08:00
c469e25cf2 fix(docs-infra): set the default html title to 'Angular' (#28916)
This removes the annoying flicker while the app is loading.

Also: it's just Angular.

PR Close #28916
2019-02-21 23:27:28 -08:00
a21cde2960 style(docs-infra): reformat using vscode html formatter (#28916)
Makes it easier to keep on editing and reformatting the file.

PR Close #28916
2019-02-21 23:27:28 -08:00
9b774348b3 ci: update circleci post checkout to v2 syntax (#28472)
The `post` key is part of the CircleCI 1.0 syntax is not available in the 2.0 syntax.

PR Close #28472
2019-02-21 22:18:22 -08:00
ce219ccfa2 docs(common): update docs for HttpClient methods (#26143)
PR Close #26143
2019-02-21 20:56:13 -08:00
53bbb01047 build(bazel): cleanup the jasmine bootstrap code (#28906)
PR Close #28906
2019-02-21 17:59:18 -08:00
c6741bf36a build: no //package/bazel/src/api-extractor on the patch branch (#28901)
PR Close #28901
2019-02-21 17:54:04 -08:00
cc06bf50f3 build: Add .bzl/BUILD files to @angular/bazel package (#28901)
It's now possible to use it as a hybrid package in latest rules_nodejs, so no WORKSPACE dep is needed

PR Close #28901
2019-02-21 17:53:56 -08:00
21e78ad022 build: no //package/bazel/src/api-extractor on the patch branch (#28901)
PR Close #28901
2019-02-21 16:34:37 -08:00
05e855092b build: Add .bzl/BUILD files to @angular/bazel package (#28901)
It's now possible to use it as a hybrid package in latest rules_nodejs, so no WORKSPACE dep is needed

PR Close #28901
2019-02-21 16:34:37 -08:00
2817764433 ci: make yarn globally available and independent of $BASH_ENV (#28889)
Previously, our yarn (which overwrote the pre-installed yarn on the
docker image) was only available through `$BASH_ENV` (as an exported
function). This caused it to be undefined for commands executed in other
shells (e.g. via Node.js' `child_process.spawn()` unless explicitly
configuring it to run with `bash`).

This commit fixes this by making our yarn version available globally via
a symlink (`/usr/local/bin/yarn`).

(This was accidentally broken in #28839.)

PR Close #28889
2019-02-21 12:37:53 -08:00
145639d0f8 docs: edit resources description (#28764)
PR Close #28764
2019-02-21 12:34:06 -08:00
3eb327b67b build(bazel): do not build rxjs from source under Bazel (#28869)
PR Close #28869
2019-02-21 08:05:25 -08:00
be6af26dc1 ci: run saucelabs unit tests as cronjob (#28787)
We no longer want to run Saucelabs for every PR/commit because
Saucelabs has been very flaky recently and it blocks most of the
PRs with a flaky failing state that we cannot fix most of the time due
to upstream Saucelabs failures/incidents. Since real browsers tests
rarely catch browser-specific failures (same as in Material), we should
only run Saucelabs in a cronjob on the upstream branches. This still
ensures/guarantees our browser compatibility, but makes our CI
more stable and the PR workflow more productive.

PR Close #28787
2019-02-20 16:47:31 -08:00
637e81e9bb build: remove legacy-unit-tests-local job (#28703)
Since all unit tests are now run with Bazel, we can remove
the local legacy unit tests job. We still need to keep the
Saucelabs legacy job until we can run all of these web
unit tests with Saucelabs and Bazel.

PR Close #28703
2019-02-20 16:31:50 -08:00
abc3cbb33f build: run example unit tests with bazel (#28703)
With #28402 we updated the `examples` package to be
built and tested with Bazel. This PR was only intended
for the e2e integration tests, and there still seem to be
a few unit tests that need to be migrated to Bazel until
we can remove the legacy local unit tests job.

PR Close #28703
2019-02-20 16:31:50 -08:00
27eb8f2723 build: update deps in ./scripts/release/post-check
The versions were off and @angular/http dep was missing.
2019-02-20 13:14:33 -08:00
81671cea9a release: cut the v7.2.6 release 2019-02-20 12:15:47 -08:00
843fc7df9f Revert "feat(router): add hash-based navigation option to setUpLocationSync (#28609)"
This reverts commit fc895ba189.

This is change is a feature and doesn't belong on the patch branch.
2019-02-20 12:07:16 -08:00
cfe4732e41 fix(docs-infra): prevent extra space at the bottom of the page in Chrome (#28864)
The supposedly visually hidden `mat-icon` creates unnecessary space at
the bottom of the page (below the footer) in recent Chrome versions.
This didn't happen before and it still doesn't happen in other browsers
(Firefox, Edge, IE).

This commit fixes it by wrapping the icon in a visually hidden `div`
container, which doesn't have other styles (such as `mat-icon` does)
that could affect the layout of the page.

Fixes #28858

PR Close #28864
2019-02-20 09:20:38 -08:00
48cabb44c7 build: use vendored yarn under Bazel (#28839)
PR Close #28839
2019-02-20 09:19:05 -08:00
9d0db2fe4b ci: Vendor yarn into our repo (#28839)
This avoids a dynamic dependency on fetching a package from the internet in our CI.
We have observed that this is not 100% reliable.

PR Close #28839
2019-02-20 09:19:05 -08:00
069146e7f3 ci: exclude **/third_party/** from google3 check (#28870)
this pattern is being excluded in copybara. see cl/234807990.

PR Close #28870
2019-02-20 09:17:21 -08:00
fc895ba189 feat(router): add hash-based navigation option to setUpLocationSync (#28609)
The `setUpLocationSync` function in @angular/router/upgrade didn't previously let you sync hash-based navigations. With this change, you can now pass an option to `setUpLocationSync` that will make sure location changes run in Angular in hash-based apps.

Fixes #24429 #21995

PR Close #28609
2019-02-19 16:20:36 -08:00
9a51528072 docs: add Sharon DiOrio to contributors (#28671)
PR Close #28671
2019-02-19 16:15:01 -08:00
7fc38d4947 docs: fix wrong filename in text (#28832)
This should be `ngsw.json` not `ngsw-config.json` as the latter is only the src file that gets then compiled into the `ngsw.json` and placed into the `dist` folder
PR Close #28832
2019-02-19 13:34:10 -08:00
b1f84ec78f style: reformat aio/content/marketing/contributors.json with clang-format (#28500)
without this change, it's difficult to edit this file for anyone who has IDE configured for angular/angular development.

PR Close #28500
2019-02-19 13:01:19 -08:00
f351e8a5b1 docs: add Stanimira Vlaeva to contributors (#28500)
PR Close #28500
2019-02-19 13:01:19 -08:00
ff2c342356 docs(common): fix a typo in a debounce requests example header (#28829)
Remove the extra parenthesis from a debounce requests example.

There are no associated issues.

PR Close #28829
2019-02-19 12:59:22 -08:00
01b05b3f7c docs(platform-browser): fix a grammatical error in the BrowserModule documentation (#28808)
The browser module is not included by defaults, it is included by default. Default should be singular.

There is no associated issue.
PR Close #28808
2019-02-19 12:54:53 -08:00
3b78f9eb0f build(compiler-cli): upgrade chokidar to latest version (#28797)
Fixes #28771

PR Close #28797
2019-02-19 12:54:12 -08:00
f6ca619343 test: bazel integration test should use angular npm packages (#28762)
PR Close #28762
2019-02-19 12:53:20 -08:00
ab69c31fc5 fix(compiler-cli): incorrect bundled metadata for static class member call expressions (#28762)
Currently if developers use call expressions in their static
class members ([like we do in Angular](https://github.com/angular/angular/blob/master/packages/core/src/change_detection/differs/keyvalue_differs.ts#L121)),
the metadata that is generated for flat modules is invalid. This
is because the metadata bundler logic currently does not handle
call expressions in static class members and the symbol references
are not rewritten to avoid relative paths in the bundle.

Static class members using a call expression are not relevant for
the ViewEngine AOT compilation, but it is problematic that the
bundled metadata references modules using their original relative
path. This means that the bundled metadata is no longer encapsulated
and depends on other emitted files to be emitted in the proper place.

These incorrect relative paths can now cause issues where NGC
looks for the referenced symbols in the incorrect path. e.g.

```
src/
 | lib/
    | index.ts -> References the call expression using `../../di`
```

Now the metadata looks like that:

```
node_modules/
  | @angular/
  -- | core/
  -- -- | core.metadata.json -> Says that the call expr. is in `../../di`.
  | di/
```

Now if NGC tries to use the metadata files and create the summary files,
NGC resolves the call expression to the `node_modules/di` module. Since
the "unexpected" module does not contain the desired symbol, NGC will
error out.

We should fix this by ensuring that we don't ship corrupted metadata
to NPM which contains relative references that can cause such
failures (other imports can be affected as well; it depends on what
modules the developer has installed and how we import our call
expressions).

Fixes #28741.

PR Close #28762
2019-02-19 12:53:20 -08:00
38de40c9ec docs: clarify process surrounding merge label (#28837)
In the TRIAGE_AND_LABELS doc, it was not clear that the merge label
may be applied by the author before the PR is green (as a sort of
auto-submit). After the label is applied, it is still up to the
caretaker to determine that the PR is acceptable before merging.
This commit adds that clarification.

PR Close #28837
2019-02-19 12:43:21 -08:00
53352c40c3 ci: combine "define_env_vars" and "download_yarn" anchor (#28788)
As discussed in https://github.com/angular/angular/pull/28546#discussion_r254068014, we want to combine the
`define_env_vars` and `download_yarn` anchor since downloading Yarn depends on setting up the
environment variables. In addition this simplifies our setup and reduces code-duplication.

PR Close #28788
2019-02-19 12:41:51 -08:00
dd3cab6eb1 build(docs-infra): improve caching configuration for Firebase hosting (#28785)
This will hopefully improve(/fix?) the errors discussed in #28114.
See there for a more detailed discussion.

PR Close #28785
2019-02-19 12:38:51 -08:00
ea1a3d3603 build: fix validate-commit-message on Windows (#28780)
Previously, the `validate-commit-message` gulp task was using the
`git log ... ^r1 r2` syntax to list commits between the base branch and
the current head. This didn't work as expected on Windows, because `^`
is the escape character. As a result, the command was equivalent to
`git log ... r1 r2` on Windows, which essentially logs all commits
reachable from either `r1` or `r2`.

This commit fixes it by switching to git's
[double-dot range notation][1] (`r1..r2`), which is an alias for the
`^r1 r2` syntax and works correctly on all platforms.

[1]: https://git-scm.com/docs/gitrevisions#_dotted_range_notations

Fixes #16830

PR Close #28780
2019-02-19 12:37:58 -08:00
cf1b436010 build: stop execution on error in validate-commit-message (#28780)
Stop execution when an error happens in `validate-commit-message` gulp
task and ensure the error message is printed at the bottom.

Fixes #16829

PR Close #28780
2019-02-19 12:37:58 -08:00
cdcbb53a2d docs: capitalize karma (#28775)
PR Close #28775
2019-02-19 12:36:22 -08:00
db2db6e7f5 docs: clarify behavior of dependency injection at root injector (#28753)
PR Close #28753
2019-02-19 12:33:49 -08:00
1df6b16263 ci: add gkalpak and filipesilva to fw-dev-infra (#28807)
PR Close #28807
2019-02-19 12:31:29 -08:00
f4871212b7 ci: add /aio/content/images/bios/** to @angular/fw-docs-marketing group (#28835)
we previously missed it.

PR Close #28835
2019-02-19 12:30:38 -08:00
2a23eca917 docs: display the beginning label in interpolation guide example (#28602)
Updating the doc to add the beginning label.

I'm not sure if this was the way it was intended, but it looked strange with just an ending </label> tag.

PR Close #28602
2019-02-19 12:24:46 -08:00
b5da4c6676 docs(aio): add Keilla Fernandes to GDE resources (#28437)
PR Close #28437
2019-02-19 11:24:15 -08:00
b8c2f3b93f docs: warn that directives don't support namespaces (#25855)
PR Close #25855
2019-02-19 11:01:56 -08:00
75cf86e70f ci: add /packages/* to the @angular/fw-dev-infra CODEOWNERS group (#28745)
It was previously missing which is a bug.

PR Close #28745
2019-02-16 20:58:48 -08:00
bf25165354 build(bazel): specify tsconfig-test dependency (#28696)
PR Close #28696
2019-02-16 20:57:34 -08:00
a2ba4448da release: cut the v release 2019-02-15 21:13:21 +00:00
ac6b2b4dc3 build: convert examples package to bazel (#28733)
* build: switch example e2e tests to bazel

* No longer builds the example e2e tests using "tsc". The examples are now built with Bazel and can therefore be built with Ivy by using the `--define=compile=aot` switch.
* No longer runs the example e2e tests using the protractor CLI. example e2e tests are executed with the Bazel protractor rule and can therefore run incrementally.

* test: disable failing ivy example e2e tests

*Note for patch branch:* We had to disable more examples in Ivy because
the patch branch does not contain all Ivy/ngtsc fixes.
2019-02-14 15:25:00 -08:00
b6dffa9763 docs: incorporate review feedback (#26827)
PR Close #26827
2019-02-14 19:33:15 +00:00
54b57def58 docs: update HttpInterceptor API docs (#26827)
PR Close #26827
2019-02-14 19:33:15 +00:00
e2b3cc8118 build: remove unused rollup.config.js files (#28646)
Since we build and publish the individual packages
using Bazel and `build.sh` has been removed, we can
safely remove the `rollup.config.js` files which are no
longer needed because the `ng_package` bazel rule
automatically handles the rollup settings and globals.

PR Close #28646
2019-02-14 19:29:22 +00:00
5e701a2c88 build(bazel): rollback to chromium 69 (latest version that still works on OSX) (#28698)
PR Close #28698
2019-02-13 19:18:28 -08:00
27a3df146d build(bazel): pin chromium to 72.0.3636 and chrome-driver to 2.46 on all platforms (#28698)
PR Close #28698
2019-02-13 19:18:28 -08:00
8cce7efbb2 build(bazel): pin chrome driver to 2.45 and use newer chrome in linux to fix test in CI (#28698)
PR Close #28698
2019-02-13 19:18:28 -08:00
d225c3a6e3 build(bazel): temporarily pin browser versions while upstream is fixed as work-around for #28681 (#28698)
PR Close #28698
2019-02-13 19:18:27 -08:00
b23582d57e docs(animations): fixed some grammar (#28708)
PR Close #28708
2019-02-13 19:14:58 -08:00
d3c6e512a3 build: update jquery to latest (#28719)
Versions less than 3.0.0 have security vulnerabilities

PR Close #28719
2019-02-13 19:14:11 -08:00
a873fab10c docs-infra: backporting #28592, #28463, #28650, #28688, #28663 (#28714)
* ci(docs-infra): run docs examples tests in production mode (#28592)

PR Close #28592

* docs: remove quickstart example and copy tsconfig.1.json into TS config guide (#28592)

This example has long been replaced by the cli-quickstart, but was never deleted.

PR Close #28592

* docs: enable E2E test for setup example (#28592)

This guide is not being shown publicly, and its test is currently being ignored.
Instead of deleting this test and guide, it may be repurposed in the future for a local development guide.

PR Close #28592

* docs: ignore progression filenames from compilation (#28592)

PR Close #28592

* docs: remove unused StringSafeDatePipe from AngularJS Quick Ref example (#28592)

PR Close #28592

* docs: make parent finder functions compatible with AoT (#28592)

PR Close #28592

* docs: make toggleImage arguments optional in AngularJS quick reference (#28592)

PR Close #28592

* docs: add insert remove component to AppModule for animations example (#28592)

PR Close #28592

* docs: ignore component for app compilation for displaying data example (#28592)

PR Close #28592

* docs: ignore files from app compilation for ngmodule-faq example (#28592)

PR Close #28592

* docs: ignore initial components for app compilation in router example (#28592)

PR Close #28592

* docs: remove unused files in styleguide example (#28592)

PR Close #28592

* docs: make method arguments optional in template syntax example (#28592)

PR Close #28592

* docs: add more files to be ignored during app compilation (#28592)

PR Close #28592

* docs: run component-interaction and DI in JiT mode (#28592)

PR Close #28592

* docs: re-enable E2E tests for Http guide (#28592)

PR Close #28592

* ci(docs-infra): test docs examples with Ivy (#28463)

PR Close #28463

* fix(docs-infra): add progression files to exclude list for docs examples (#28650)

Also disables Http guide under Ivy tests with documented error

PR Close #28650

* fix(docs-infra): fix filtering in run-example-e2e.js (#28663)

PR Close #28663

* test(ivy): enable more docs examples e2e tests (#28688)

PR Close #28688
2019-02-13 16:42:39 -08:00
ecef0dd65e Revert "test(ivy): enable more docs examples e2e tests (#28688)" (#28712)
This reverts commit 1cc74eaece.
2019-02-13 15:43:16 -08:00
1cc74eaece ci: fix bad merge 2019-02-13 14:58:22 -08:00
e2b3be87cb build(bazel): update to rules_nodejs 0.18.6 (#28699)
PR Close #28699
2019-02-13 12:13:09 -08:00
3ca6c928f9 docs(router): change slideInDownAnimation into slideInAnimation (#28640)
In the Routing & Navigation there is a typo - slideInDownAnimation, but it should be slideInAnimation

PR Close #28572

PR Close #28640
2019-02-13 12:03:46 -08:00
5933d16f3e build: fix web_worker images example not working (#28562)
The web_worker images example is currently not really usable
because the rendered button that can be used to upload
an "image" to the demo is currently not working. This is because
the HTML markup for the `file-field` is not matching what `materialize-css`
expects. See: https://materializecss.com/text-inputs.html

PR Close #28562
2019-02-13 12:01:55 -08:00
0f839bcfd0 build: playground examples do not explicitly specify "ng_module" assets (#28562)
Currently all playground examples are built with NGC, and most
of the HTML resources are automatically inlined. Surprisingly NGC
is able to resolve the relative component assets even though these
aren't specified in the `assets`. This seems to work because NGC
resolves the files in the execroot where the files are present
(if Bazel doesn't use sandboxing).

Issue is tracked with TOOL-667

PR Close #28562
2019-02-13 12:01:55 -08:00
edda94edfa build: fix web_worker playground examples using external resources (#28562)
The `web_workers/images` example is not being tested by any e2e
spec and therefore it's technically not necessary to fix that it uses
external resources, though in order to ensure that the Bazel builds
are hermetic and that we can eventually add e2e specs for the
web_worker/image example, we should avoid any use of external
resources.

We remove the `web-animations` polyfill in the `web_workers/animations`
example because we should try to vendor as few as possible deps. Also
the animations API is already supported by browsers we run the e2e tests
against (note here: `web_workers/animations` is currently also disabled)

PR Close #28562
2019-02-13 12:01:55 -08:00
b5e36eaa3e docs: add di-related api doc (#27731)
PR Close #27731
2019-02-13 11:59:32 -08:00
08a1f51704 build: remove legacy e2e tests job (#28697)
Now that all e2e integration tests within `modules/` have been
migrated to Bazel, we can remove the legacy e2e tests job.

PR Close #28697
2019-02-13 11:54:37 -08:00
9690e36f78 build: update instructions to run benchmark tests (#28697)
* Updates the instructions on how to run the benchmark tests.
* Removes the unused `favicon.ico` file and the corresponding Bazel filegroup

PR Close #28697
2019-02-13 11:54:36 -08:00
68e741227b build: convert largeform benchmarks to bazel (#28697)
Switches the `largeform` benchmarks to Bazel.
This is the last remaining e2e test within `modules/`.

PR Close #28697
2019-02-13 11:54:36 -08:00
50a2327520 build: run largetable benchmark tests with bazel (#28697)
PR Close #28697
2019-02-13 11:54:36 -08:00
b07346c8e3 build: serve largetable benchmark tests with bazel (#28697)
PR Close #28697
2019-02-13 11:54:36 -08:00
8e95849751 build: fix routing playground example using external resource (#28697)
Currently the "routing" playground example fails the e2e tests
because it tries to load the OpenSans font using an external
HTTP request. External http requests are not allowed (unless
explicitly enabled) within Bazel in order to ensure that
all targets are built and tested in a hermetic way.

In order to work around this issue in a Bazel idiomatic way,
we just vendor the fonts in the "third_party" folder. Note
that we can technically also enable internet for the RBE
host platform, but it's not a best practice for hermeticity.

The following syntax would allow us to enable internet for
RBE (stated here for tracking)

```
properties: {
  name: "dockerNetwork"
  value: "standard"
}
```

PR Close #28697
2019-02-13 11:54:36 -08:00
cd143f67af build: disable failing ivy playground example e2e tests (#28697)
With ed1ba88ffd9d0fc266808413fa517e7a31943bc8 we switched the
examples to run with Bazel. This means that we can now also run the
e2e tests for these examples against Ivy. All playground e2e tests,
**except** the `web_worker` examples, successfully run with Ivy.

The failing webworker e2e tests have been temporarily disabled with
`fixmeIvy` and need to be investigated in a follow-up.

PR Close #28697
2019-02-13 11:54:36 -08:00
dd85351162 build: re-enable upgrade playground example (#28697)
The `upgrade` playground example has been disabled for a
long time because Protractor initially didn't support running
hybrid apps. Now that we use a more recent version of Protractor
that handles hybrid apps (also automatically), we can re-enable
this long-standing disabled test.

Additionally the e2e test logic was outdated and failed because a
CSS selector did not match the template of the upgrade example.
With this change, the CSS selector has been updated to match the
example's template, and also the test has been updated slightly
to also ensure that content projection works.

PR Close #28697
2019-02-13 11:54:36 -08:00
c1c68889de build: run playground e2e examples with bazel (#28697)
PR Close #28697
2019-02-13 11:54:36 -08:00
866f4be782 build: fix "person_management" playground example (#28697)
Currently when someone serves the "person_management" playground
example, there will be runtime exceptions by `@angular/forms` if
someone clicks on one of the two buttons rendered in the example.

This happens because the example is outdated and the input elements
using `ngModel` do not specify a proper "name" while being inside of
a `<form>` element. A name is required inside of a form. The failure
is not specific to Ivy and is not covered by any test because the e2e
tests for this example are just asserting that the page properly loads
(the error only shows up one of the buttons has been clicked)

This is the reason why these errors were never visibile to the e2e tests.
Though in order to make this example work, we should this fix these failures
so that the example can work as expected.

```
FullNameComponent.html:7 ERROR Error: If ngModel is used within a form tag, either the name attribute must be set or the form
      control must be defined as 'standalone' in ngModelOptions.

      Example 1: <input [(ngModel)]="person.firstName" name="first">
      Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">
    at Function.TemplateDrivenErrors.missingNameException (template_driven_errors.ts:40)
    at NgModel._checkName (ng_model.ts:319)
    at NgModel._checkForErrors (ng_model.ts:302)
    at NgModel.ngOnChanges (ng_model.ts:215)
    at Object.checkAndUpdateDirectiveInline (provider.ts:208)
    at checkAndUpdateNodeInline (view.ts:429)
    at checkAndUpdateNode (view.ts:389)
    at debugCheckAndUpdateNode (services.ts:431)
    at debugCheckDirectivesFn (services.ts:392)
    at Object.eval [as updateDirectives] (FullNameComponent.html:7)
```

PR Close #28697
2019-02-13 11:54:36 -08:00
80e4019c83 build: switch playground examples to bazel (#28697)
Currently all playground examples are built with `tsc`
and served with the `gulp serve` task. In order to be able
to test these examples easily with Ivy, we now build and
serve the examples using Bazel. This allows us to expand our
Ivy test coverage and additionally it allows us to move forward
with the overall Bazel migration. Building & serving individual
examples is now very easy and doesn't involve building everything
inside of `/modules`.

PR Close #28697
2019-02-13 11:54:36 -08:00
d9f3316021 build: fix bazel protractor tests not capturing console output (#28697)
Currently we depend on the "rules_webtesting" version that is
installed by "rules_typescript//:package.bzl". This version of
the webtesting rules comes with a very old version of Chromium
and the `chromedriver` that does not support capturing console
errors properly (with stack traces). Since we have a few e2e
tests that depend on console output (e.g. playground/src/source-map),
we need to make sure that these tests can pass upon Bazel
migration.

**Note for patch version**: Technically this commit is no longer updating
the `rules_webtesting` version because a different PR/commit already updated
the version transitively in `master & patch` and reverted 0094b99176264b27582ab620565632788cab66c5
partially, so in order to keep master and patch in sync, we should not update the
version of `rules_webtesting`.

PR Close #28697
2019-02-13 11:54:36 -08:00
424a3b95aa ci: corrected left over merge marker 2019-02-13 10:50:36 -08:00
7e883c2319 ci: corrected left over merge marker 2019-02-13 10:41:55 -08:00
6a7fd70ddf test(ivy): enable more docs examples e2e tests (#28688)
PR Close #28688
2019-02-13 09:54:29 -08:00
73f9db53c2 ci: downgrade to sauce-connect v4.5.1 (#28659)
We currently face a lot of flakiness with our
Saucelabs CI jobs. These randomly exceed the 10min
CircleCI no-output limit because something throws
off `sauce-connect` in a long-lasting loop where
it tries to connect to some of their Saucelabs
servers. The initial assumption from the Saucelabs
team was that we might have some invalid firewall
rules, but this does not answer why this happens
_randomly_, so the latest update from the support
is that there have been some changes in the latest
version of `sauce-connect` version that **could**
cause this flakiness.

I've manually did multiple test runs and was only
able to reproduce the issues with v4.5.3 (latest
version), so it might be worth downgrading to
v4.5.1. This is also what the Saucelabs support
proposed us to do (though it's not guaranteed that
v4.5.1 is unaffected by the same issue)

PR Close #28659
2019-02-12 17:23:38 -08:00
2bf526bbfb docs: add a README for third_party usage (#28651)
PR Close #28651
2019-02-12 09:54:44 -08:00
8bd7d5befc docs: clarify library types integration (#28410)
PR Close #28410
2019-02-11 17:13:45 +00:00
aa163bea93 refactor(compiler): allow disabling external symbol factory reexports (#28594)
Currently external static symbols which are referenced by AOT
compiler generated code, will be re-exported in the corresponding
`.ngfactory` files.

This way of handling the symbol resolution has been introduced in
favor of avoding dynamically generated module dependencies. This
behavior therefore avoids any strict dependency failures.

Read more about a particular scenario here: https://github.com/angular/angular/issues/25644#issuecomment-458354439

Now with `ngtsc`, this behavior has changed since `ngtsc` just
introduces these module dependencies in order to properly reference
the external symbol from its original location (also eliminating the need
for factories). Similarly we should provide a way to use the same
behavior with `ngc` because the downside of using the re-exported symbol
resolution is that user-code transformations (e.g. the `ngInjectableDef`
metadata which is added to the user source code), can resolve external
symbols to previous factory symbol re-exports. This is a critical issue
because it means that the actual JIT code references factory files in order
to access external symbols. This means that the generated output cannot
shipped to NPM without shipping the referenced factory files.

A specific example has been reported here: https://github.com/angular/angular/issues/25644#issue-353554070

PR Close #28594
2019-02-11 17:12:51 +00:00
2f73c554c9 build: fix invalid bazel target referenced by benchmarks (#28626)
PR Close #28626
2019-02-08 15:13:53 -08:00
fb2d15fda1 build: remove outdated polymer tree benchmark (#28568)
The "tree/polymer_leaves" benchmark has no benchmark tests, nor do we install
Polymer anywhere. Polymer was previously installed through `bower`, but since
we removed bower, there is no easy way to run this benchmark with Polymer.

Considering that there are no benchmark tests, nor we have an easy way to
install/vendor Polymer, we should just remove this benchmark app.

This is also based on the assumption that we want to remove the
Polymer benchmarks anyway: see: 8a05199fb9

PR Close #28568
2019-02-08 13:42:03 -08:00
018507fa02 build: run tree benchmark tests with bazel (#28568)
PR Close #28568
2019-02-08 13:42:00 -08:00
95bb72d322 build: serve benchmark tree examples with bazel (#28568)
PR Close #28568
2019-02-08 13:40:10 -08:00
ce6e6c3f81 build: unable to run perf bazel e2e tests on windows (#28568)
Currently it's not possible to run the benchmark e2e tests with Bazel on Windows
because the logic that imports the `perf_util`'s is not using a proper Bazel script
manifest path. A script manifest path should not start with `./angular/`, but rather
with the workspace name (which is in our case `angular/`)

PR Close #28568
2019-02-08 13:37:37 -08:00
e4b1bdbfa0 ci: do not install firebase-tools without cache (#28615)
Currently we install `firebase-tools` manually in the
integration tests run script. This is problematic
because it means that we cannot cache `firebase-tools`
properly and Yarn might time out downloading this
dependency. We can safely move this to the top level
`package.json` since Bazel now has a `.bazelignore` and
since we have a cache that works for PRs (with fallback
caching).

Note that the `.bazelignore` is relevant here because
`firebase-tools` has been mainly moved to the bash
script because it broke some Bazel calls.

See 4f0cae0676.

PR Close #28615
2019-02-08 10:23:20 -08:00
6477c9e04a docs(core): fixed code snippets (#28619)
PR Close #28619
2019-02-08 09:27:24 -08:00
3f380b3b78 test(upgrade): change flaky test to not be affected by other tests (#28617)
It seems that in some cases (especially on CI), global state is not
cleaned up properly causing a specific test to fail.
See #28045 and #28181 for more context.

This PR restores the global state for the affected test. This partly
defeat the purpose of the test, but is better than having flakes on CI.

Fixes #28614

PR Close #28617
2019-02-08 09:27:03 -08:00
c4c0e9dbc5 docs: update merge label meaning (#28574)
PR Close #28574
2019-02-08 09:25:05 -08:00
4ddf57c58d ci: add all required statuses to the requiredStatuses list for angular-robot (#28613)
Somehow the current list ommits quite a few important targets. Especially the cla and google3.

This changes adds all the statuses that must always be present and green for this agregate state expised as "ci/angular: merge status" to be green.

PR Close #28613
2019-02-08 09:20:29 -08:00
624f01c311 docs(core): fixed typo (#28618)
PR Close #28618
2019-02-08 09:19:40 -08:00
6a713521e3 docs(aio): add Happy Angular Podcast to resources (#28407)
PR Close #28407
2019-02-07 21:57:08 -08:00
57a5ba3438 ci: use fallback caches (#28545)
This PR adds fallback cache hits for partial cache restoration.

PR Close #28545
2019-02-07 16:45:54 -08:00
1b6fb5bc19 refactor(common): Remove deprecated FileType (#28583)
FileType objects are deprecated. They are not required for specifying valid file types for rule attributes, a list of strings can be used instead.

PR Close #28583
2019-02-07 16:45:23 -08:00
bd9da268c1 docs: update HttpHeader documentation (#26233)
PR Close #26233
2019-02-07 16:42:13 -08:00
1e58a2194f fix(router): redirect to root url when returned as UrlTree from guard (#28271)
When a UrlTree of root url was returned by a guard as a redirection, the
navigation was not processed. The issue came from the error handler which
incorrectly marked the router as already navigated.

Fixes #27845

PR Close #28271
2019-02-06 21:23:33 -08:00
da81c9cb54 build(docs-infra): use pinned dependencies when possible in ng-packages-installer (#28510)
Previously, `ng-packages-installer` would replace the version ranges for
all dependencies that were peer dependencies of an Angular package with
the version range used in the Angular package. This effectively meant
that the pinned version (from `yarn.lock`) for that dependency was
ignored (even if the pinned version satisfied the new version range).

This commit reduces non-determinism in CI jobs using the locally built
Angular packages by always using pinned versions of dependencies for
Angular package peer dependencies if possible.

For example, assuming the following versions for the RxJS dependency:

- **aio/package.json**: `rxjs: ^6.3.0`
- **aio/yarn.lock**: `rxjs@^6.3.0: 6.3.3`
- **@angular/core#peerDependencies**: `rxjs: ^6.0.0`

...the following versions would be used with `ng-packages-installer`:

- Before this commit:
  - **aio/package.json**: `rxjs: ^6.0.0`
  - **node_modules/rxjs/**: `6.4.0` (latest version satisfying `^6.0.0`)
- After this commit:
  - **aio/package.json**: `rxjs: ^6.3.0`
  - **node_modules/rxjs/**: `6.3.3` (because it satisfies `^6.0.0`)

PR Close #28510
2019-02-06 21:23:03 -08:00
ef6d26d4fa build(docs-infra): keep other dependencies pinned when installing local Angular packages (#28510)
`ng-packages-installer` can be used to replace Angular packages with
locally built ones (from `dist/packages-dist/`) along with their peer
dependencies.

Previously, in order to achieve this, `yarn install` was called with the
`--no-lockfile` option, which resulted in installing the latest versions
of all dependencies (including transitive ones) permitted by the
corresponding version ranges in `package.json` files. As a result, newly
released versions would be picked, resulting in unexpected,
non-deterministic breakages in CI.

This commit calls `yarn install` with the `--pure-lockfile` option
instead. As a result, only the Angular packages (for which the locally
built ones are used) and their peer dependencies are unpinned; the
pinned versions from `yarn.lock` are used for all other (direct and
transitive) dependencies.

While this does not eliminate non-determinism across builds, it
significantly reduces it.

PR Close #28510
2019-02-06 21:23:03 -08:00
13bc1cd853 perf(docs-infra): avoid unnecessary I/O operation in ng-packages-installer (#28510)
PR Close #28510
2019-02-06 21:23:03 -08:00
1fa1379318 refactor(docs-infra): format package.json for readability in ng-packages-installer (#28510)
PR Close #28510
2019-02-06 21:23:03 -08:00
d9efacc07e build(docs-infra): remove unnecessary workaround for RxJS in ng-packages-installer (#28510)
Since b43f8bc7d, RxJS does not need to be patched any more in the
top-level `node_modules/`, so we don't need to special-case RxJS in
`ng-package-installer` and use `node_modules/rxjs/`.

PR Close #28510
2019-02-06 21:23:03 -08:00
47f5b5f2d4 docs(service-worker): note about isStable/setInterval (#28102)
The docs don't mention that the app will never be stable if a `setInterval` is running somewhere, and that it will prevent the servcie worker to be registered too.

PR Close #28102
2019-02-06 15:13:20 -05:00
019fe77f64 docs(core): document isStable traps (#28102)
PR Close #28102
2019-02-06 15:13:19 -05:00
a0e3a8e0f7 build: fix revert issue with bitmap.ts (#28576)
PR Close #28576
2019-02-06 15:09:34 -05:00
8908156eae build: switch to typescript's es2015 typings (#28570)
Note that this allows Angular to depend on the entirety of the ES2015 API, not just our restricted subset.
This change is needed because our copy of the subset was out-of-date, and prevents us using ES2015 target in dev mode.

This is a subset of #27738

PR Close #28570
2019-02-06 14:17:56 -05:00
2ee265fb1f build: update to rules_typescript 0.23.2 and rules_nodejs 0.16.8 (#28567)
PR Close #28567
2019-02-06 14:12:42 -05:00
116512b06d ci(docs-infra): ensure aio_monitoring failure notifications do not depend on earlier steps (#28555)
Previously, in order for the `aio_monitoring` failure notifications to
work, the steps up to `define_env_vars` should have succeeded. This
meant that any failures in earlier steps would not send notifications.

This commit fixes it by making the notification step independent of the
`define_env_vars` step.

PR Close #28555
2019-02-06 06:22:00 -08:00
1d841973eb ci: save the cache in build-npm-packages job instead of test (#28555)
In most cases, it doesn't make a difference, because the cache does
already exist and is not saved. In the few cases where the dependencies
change (and the cache needs to be updated), it makes more sense to save
the cache in the `build-npm-packages` job, because most jobs depend on
it and thus will be able to take advantage of the updated cache right
away.

This seems to be an oversight in b26ac1c22.

PR Close #28555
2019-02-06 06:22:00 -08:00
3694e1a38c ci: run the yarn_install step when necessary (#28555)
PR Close #28555
2019-02-06 06:22:00 -08:00
88d8813ccc refactor: use steps consistently in CircleCI config (#28555)
PR Close #28555
2019-02-06 06:22:00 -08:00
49bfb63442 ci(docs-infra): fix download_yarn in aio_monitoring (#28555)
The `download_yarn` step depends on the `CI_YARN_VERSION` environment
variable and thus has to be run after the `define_env_vars` step.
Accidentally broken in [#28546][1].

[1]: https://github.com/angular/angular/pull/28546/files#diff-1d37e48f9ceff6d8030570cd36286a61R447

PR Close #28555
2019-02-06 06:21:59 -08:00
48848c9ca4 build: add some debug info for yarn installs (#28553)
PR Close #28553
2019-02-06 06:21:01 -08:00
a1f1ea993d build: update yarn to v1.13.0 (#28546)
Currently our version of Yarn is installed through
the "circleci/node" docker image. This is problematic
because in order to be able to update Yarn, we always
need to update the docker image to a version that
comes with the desired Yarn version. Sometimes there
is no docker image with the desired latest Yarn version,
and therefore we cannot easily update the Yarn version.

Additionally updating the docker image also means that
we need to update our version of NodeJS, as well as the
version of `openssl` might have changed (meaning that
our encrypted credential files may not be decodable with
the new version of `openssl`)

PR Close #28546
2019-02-06 06:20:50 -08:00
be8a403bc9 feat(aio): show developer survey 2019 (#28552)
PR Close #28552
2019-02-06 02:33:39 -05:00
c378402af4 build: fix failing compiler-cli tests on windows (#28550)
Note that this fixes `compiler-cli` tests within `compiler-cli/test`,
but there seem to be remaining `ngcc` tests within `compiler-cli/src`
which aren't working on Windows. This is out-of-scope for this commit.

PR Close #28550
2019-02-05 23:47:33 -05:00
91ce8c17ff build: support running ngtsc tests on windows (#28550)
Currently the "ngtsc` testing helpers resolve the `fake_core` NPM
package using the `TEST_SRCDIR` variable. This is problematic on Windows
where Bazel runfiles are not symlinked into the runfiles directory.
In order to properly resolve the NPM Bazel tree artifact, we use the
`resolveTreeNpmArtifact` runfile helper that properly resolves the artifact
properly on all platforms.

PR Close #28550
2019-02-05 23:47:33 -05:00
786be967fd build: support running compiler-cli tests on windows (#28550)
In order to support running "compiler-cli" tests that use the "test_support.ts"
utilities on Windows with Bazel, we need to imporve the logic that resolves NPM
packages and symlinks them into a temporary directory.

A more Bazel idiomatic and windows compatible way of resolving Bazel runfiles
is to use the "RUNFILES_MANIFEST" if present. This ensures that the NPM
packages can be also symlinked on Windows, and tests can execute properly
on Windows. Read more about why this is needed here:

* https://github.com/bazelbuild/bazel/issues/3726#issue-257062364

PR Close #28550
2019-02-05 23:47:33 -05:00
e88d5e0df2 build: remove unused "test.sh" leftover code in compiler-cli (#28550)
Since we recently removed the `test.sh` script, and now run
all tests with Bazel, we can remove the unused logic that makes
compiler-cli tests pass in non-Bazel.

This cleans up the tests, and also makes it easier to write tests
without worrying about two ways of the Angular package output
(Bazel `ng_package` rules vs. old `build.sh` logic of building)

PR Close #28550
2019-02-05 23:47:33 -05:00
f39f01e00b build: remove unused "test.sh" leftover code in language-service (#28550)
Since we recently removed the `test.sh` script, and now run all
tests with Bazel, we can remove the unused logic that makes language-service
tests pass in non-Bazel.

This cleans up the tests, and also makes it easier to write tests
without worrying about two ways of the Angular package output
(Bazel `ng_package` rules vs. old `build.sh` logic of building)

PR Close #28550
2019-02-05 23:47:32 -05:00
ce750e6f5b fix(compiler-cli): diagnostics should respect "newLine" compiler option (#28550)
PR Close #28550
2019-02-05 23:47:32 -05:00
beba944843 fix(docs-infra): avoid a race-condition with navigating forward/back and immediately reloading (#28368)
This can result in an inconsistent state

PR Close #28368
2019-02-05 23:44:57 -05:00
50981cbb1f fix(docs-infra): remove the try catch in the test of the browser's capacities (#28368)
PR Close #28368
2019-02-05 23:44:56 -05:00
76e40eed35 feat(docs-infra): add debouncing in storing scroll position (#28368)
There is no debouncing when we store the scroll Position.
Currently, we have a message in the console after a while:
>Throttling history state changes to prevent the browser from hanging
see: https://bugs.chromium.org/p/chromium/issues/detail?id=786211 for more informations

PR Close #28368
2019-02-05 23:44:56 -05:00
d491a20f3b fix(router): set href when routerLink is used on an 'area' element (#28441)
closes #28401

PR Close #28441
2019-02-05 23:28:41 -05:00
730 changed files with 148639 additions and 9246 deletions

View File

@ -1,4 +1,6 @@
node_modules
dist
aio/content
aio/node_modules
aio/tools/examples/shared/node_modules
integration/bazel

View File

@ -33,7 +33,7 @@ test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test
# eventually a surprising failure with auto-discovery of the C++ toolchain in
# MacOS High Sierra.
# See https://github.com/bazelbuild/bazel/issues/4603
build --symlink_prefix=dist/
build --symlink_prefix=/
# Performance: avoid stat'ing input files
build --watchfs

View File

@ -23,13 +23,31 @@ var_2: &browsers_docker_image circleci/node:10.12-browsers
# cache changes. For example:
# 1) yarn lock file changes --> cached "node_modules" are different.
# 2) bazel repository definitions change --> cached bazel repositories are different.
var_3: &cache_key v2-angular-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-node-10.12
# **NOTE 1 **: If you change the cache key prefix, also sync the restore_cache fallback to match.
# **NOTE 2 **: Keep the static part of the cache key as prefix to enable correct fallbacks.
# See https://circleci.com/docs/2.0/caching/#restoring-cache for how prefixes work in CircleCI.
var_3: &cache_key v3-angular-node-10.12-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
# Define common ENV vars
var_4: &define_env_vars
# Initializes the CI environment by setting up common environment variables.
var_4: &init_environment
run:
name: Define environment variables
command: ./.circleci/env.sh
name: Initializing environment (setting up variables, overwriting Yarn)
# Overwrite the yarn installed in the docker container with our own version.
command: |
./.circleci/env.sh
ourYarn=$(realpath ./third_party/github.com/yarnpkg/yarn/releases/download/v1.13.0/bin/yarn.js)
sudo chmod a+x $ourYarn
sudo ln -fs $ourYarn /usr/local/bin/yarn
echo "Yarn version: $(yarn --version)"
# Add GitHub to known hosts.
mkdir -p ~/.ssh
echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts
# use git+ssh instead of https
git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true
git config --global gc.auto 0 || true
var_5: &setup_bazel_remote_execution
run:
@ -49,7 +67,23 @@ var_6: &job_defaults
# Similar to travis behavior, but not quite the same.
# See https://discuss.circleci.com/t/1662
var_7: &post_checkout
post: git pull --ff-only origin "refs/pull/${CI_PULL_REQUEST//*pull\//}/merge"
run:
name: Post checkout step
command: >
if [[ -n "${CIRCLE_PR_NUMBER}" ]]; then
# Fetch the head and merge commits for this PR.
git fetch origin +refs/pull/$CIRCLE_PR_NUMBER/head:pr/$CIRCLE_PR_NUMBER/head
git fetch origin +refs/pull/$CIRCLE_PR_NUMBER/merge:pr/$CIRCLE_PR_NUMBER/merge
# Checkout the merged PR for testing as CircleCI will just use the PR head otherwise.
git checkout -qf pr/$CIRCLE_PR_NUMBER/merge
# Reset the merge commit into its PR head.
git reset pr/$CIRCLE_PR_NUMBER/head
# Commit the merge changes into the head of the PR.
# This way we keep the last commit message.
git config user.name "angular-ci"
git config user.email "angular-ci"
git commit . --amend --no-edit
fi
var_8: &yarn_install
run:
@ -67,17 +101,63 @@ var_9: &setup_circleci_bazel_config
name: Setting up CircleCI bazel configuration
command: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
var_10: &restore_cache
restore_cache:
keys:
- *cache_key
# This fallback should be the cache_key without variables.
- v3-angular-node-10.12-
# Branch filter that can be specified for jobs that should only run on publish branches
# (e.g. master or the patch branch)
var_12: &publish_branches_filter
branches:
only:
- master
# e.g. 7.0.x, 7.1.x, etc.
- /\d+\.\d+\.x/
# Workspace initially persisted by the `install` job, and then enhanced by `test_aio` and
# `build-npm-packages`.
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
# https://circleci.com/blog/deep-diving-into-circleci-workspaces/
var_13: &attach_workspace
attach_workspace:
at: ~/
version: 2
jobs:
setup:
<<: *job_defaults
steps:
- checkout
- *post_checkout
# This cache is saved in the build-npm-packages so that Bazel cache is also included.
- *restore_cache
- *init_environment
- *yarn_install
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
# Make the bazel directories and add a file to them if they don't exist already so that
# persist_to_workspace does not fail.
- run: |
if [ ! -d ~/bazel_repository_cache ]; then
mkdir ~/bazel_repository_cache
touch ~/bazel_repository_cache/MARKER
fi
# Persist any changes at this point to be reused by further jobs.
# **NOTE 1 **: Folders persisted here should be kept in sync with `var_13: &attach_workspace`.
# **NOTE 2 **: To add new content to the workspace, always persist on the same root.
- persist_to_workspace:
root: ~/
paths:
- ./ng
- ./bazel_repository_cache
lint:
<<: *job_defaults
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *yarn_install
- *attach_workspace
- *init_environment
- run: 'yarn bazel:format -mode=check ||
(echo "BUILD files not formatted. Please run ''yarn bazel:format''" ; exit 1)'
@ -85,19 +165,15 @@ jobs:
- run: 'yarn bazel:lint ||
(echo -e "\n.bzl files have lint errors. Please run ''yarn bazel:lint-fix''"; exit 1)'
- run: ./node_modules/.bin/gulp lint
- run: yarn gulp lint
test:
<<: *job_defaults
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *attach_workspace
- *init_environment
- *setup_circleci_bazel_config
- *yarn_install
# Setup remote execution and run RBE-compatible tests.
- *setup_bazel_remote_execution
@ -106,24 +182,14 @@ jobs:
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- run: yarn bazel test //... --build_tag_filters=-ivy-only,local --test_tag_filters=-ivy-only,local
- save_cache:
key: *cache_key
paths:
- "node_modules"
- "~/bazel_repository_cache"
# Temporary job to test what will happen when we flip the Ivy flag to true
test_ivy_aot:
<<: *job_defaults
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *attach_workspace
- *init_environment
- *setup_circleci_bazel_config
- *yarn_install
- *setup_bazel_remote_execution
# We need to explicitly specify the --symlink_prefix option because otherwise we would
@ -156,11 +222,8 @@ jobs:
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *attach_workspace
- *init_environment
# Build aio
- run: yarn --cwd aio build --progress=false
# Lint the code
@ -184,11 +247,8 @@ jobs:
# Needed because before deploying the deploy-production script runs the PWA score tests.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *attach_workspace
- *init_environment
# Deploy angular.io to production (if necessary)
- run: setPublicVar CI_STABLE_BRANCH "$(npm info @angular/core dist-tags.latest | sed -r 's/^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$/\1.x/')"
- run: yarn --cwd aio deploy-production
@ -199,13 +259,8 @@ jobs:
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
- *attach_workspace
- *init_environment
# Build aio (with local Angular packages)
- run: yarn --cwd aio build-local --progress=false
# Run PWA-score tests
@ -219,26 +274,22 @@ jobs:
test_aio_local_ivy:
<<: *job_defaults
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
- *attach_workspace
- *init_environment
# Rename the Ivy packages dist folder to "dist/packages-dist" as the AIO
# package installer picks up the locally built packages from that location.
# *Note*: We could also adjust the packages installer, but given we won't have
# two different folders of Angular distributions in the future, it's likely not
# worth the efforts to change the AIO packages installer.
- run: mv dist/packages-dist-ivy-aot dist/packages-dist
# Build aio with Ivy (using local Angular packages)
- run: yarn --cwd aio build-with-ivy --progress=false
test_aio_tools:
<<: *job_defaults
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
- *attach_workspace
- *init_environment
# Install
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
- run: yarn --cwd aio extract-cli-command-docs
@ -251,17 +302,13 @@ jobs:
docker:
# Needed because the example e2e tests depend on Chrome.
- image: *browsers_docker_image
parallelism: 3
# We increase the parallelism here to five while the "test_docs_examples" job runs with
# a parallelism of four. This is necessary because this job also need to run NGCC which
# takes up more time and we don't want these jobs to impact the overall CI turnaround.
parallelism: 5
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
# Install root
- *yarn_install
- *attach_workspace
- *init_environment
# Install aio
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
# Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
@ -269,18 +316,36 @@ jobs:
# with either "0", "1" or "2" as node index. This can be passed to the "--shard" argument.
- run: yarn --cwd aio example-e2e --setup --local --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
test_docs_examples_ivy:
<<: *job_defaults
docker:
# Needed because the example e2e tests depend on Chrome.
- image: *browsers_docker_image
parallelism: 4
steps:
- *attach_workspace
- *init_environment
# Install aio
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
# Rename the Ivy packages dist folder to "dist/packages-dist" as the AIO
# package installer picks up the locally built packages from that location.
# *Note*: We could also adjust the packages installer, but given we won't have
# two different folders of Angular distributions in the future, we should keep
# the packages installer unchanged.
- run: mv dist/packages-dist-ivy-aot dist/packages-dist
# Run examples tests with ivy. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
# Since the parallelism is set to "3", there will be three parallel CircleCI containers
# with either "0", "1" or "2" as node index. This can be passed to the "--shard" argument.
- run: yarn --cwd aio example-e2e --setup --local --ivy --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
aio_preview:
<<: *job_defaults
environment:
AIO_SNAPSHOT_ARTIFACT_PATH: &aio_preview_artifact_path 'aio/tmp/snapshot.tgz'
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *yarn_install
- *attach_workspace
- *init_environment
- run: ./aio/scripts/build-artifacts.sh $AIO_SNAPSHOT_ARTIFACT_PATH $CI_PULL_REQUEST $CI_COMMIT
- store_artifacts:
path: *aio_preview_artifact_path
@ -296,12 +361,9 @@ jobs:
# Needed because the test-preview script runs e2e tests and the PWA score test with Chrome.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- run: yarn install --cwd aio --frozen-lockfile --non-interactive
- *attach_workspace
- *init_environment
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
- run:
name: Wait for preview and run tests
command: node aio/scripts/test-preview.js $CI_PULL_REQUEST $CI_COMMIT $CI_AIO_MIN_PWA_SCORE
@ -319,47 +381,44 @@ jobs:
<<: *job_defaults
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *attach_workspace
- *init_environment
- *setup_circleci_bazel_config
- *yarn_install
- *setup_bazel_remote_execution
- run: scripts/build-packages-dist.sh
# Save the npm packages from //packages/... for other workflow jobs to read
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
- persist_to_workspace:
root: dist
root: ~/
paths:
- packages-dist
- ng/dist/packages-dist
# Save dependencies and bazel repository cache to use on subsequent runs.
- save_cache:
key: *cache_key
paths:
- "node_modules"
- "aio/node_modules"
- "~/bazel_repository_cache"
# Build the ivy npm packages.
build-ivy-npm-packages:
<<: *job_defaults
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *attach_workspace
- *init_environment
- *setup_circleci_bazel_config
- *yarn_install
- *setup_bazel_remote_execution
- run: scripts/build-ivy-npm-packages.sh
# Save the npm packages from //packages/... for other workflow jobs to read
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
- persist_to_workspace:
root: dist
root: ~/
paths:
- packages-dist-ivy-aot
- ng/dist/packages-dist-ivy-aot
# We run the integration tests outside of Bazel for now.
# They are a separate workflow job so that they can be easily re-run.
@ -378,13 +437,8 @@ jobs:
# on a 4G worker so we use a larger machine here too.
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
- *attach_workspace
- *init_environment
# Runs the integration tests in parallel across multiple CircleCI container instances. The
# amount of container nodes for this job is controlled by the "parallelism" option.
- run: ./integration/run_tests.sh ${CIRCLE_NODE_INDEX} ${CIRCLE_NODE_TOTAL}
@ -394,21 +448,20 @@ jobs:
publish_snapshot:
<<: *job_defaults
steps:
- checkout:
<<: *post_checkout
- *define_env_vars
# See below - ideally this job should not trigger for non-upstream builds.
# But since it does, we have to check this condition.
- run:
name: Skip this job for Pull Requests and Fork builds
# Note, `|| true` on the end makes this step always exit 0
command: '[[
"$CI_PULL_REQUEST" != "false"
|| "$CI_REPO_OWNER" != "angular"
|| "$CI_REPO_NAME" != "angular"
]] && circleci step halt || true'
- attach_workspace:
at: dist
# Note: Using `CIRCLE_*` env variables (instead of those defined in `env.sh` so that this
# step can be run before `init_environment`.
command: >
if [[ -n "${CIRCLE_PR_NUMBER}" ]] ||
[[ "$CIRCLE_PROJECT_USERNAME" != "angular" ]] ||
[[ "$CIRCLE_PROJECT_REPONAME" != "angular" ]]; then
circleci step halt
fi
- *attach_workspace
- *init_environment
# CircleCI has a config setting to force SSH for all github connections
# This is not compatible with our mechanism of using a Personal Access Token
# Clear the global setting
@ -425,35 +478,18 @@ jobs:
# which does not load the browser through the Bazel webtesting rules.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *attach_workspace
- *init_environment
- run:
name: Run tests against the deployed apps
command: ./aio/scripts/test-production.sh $CI_AIO_MIN_PWA_SCORE
- run:
name: Notify caretaker about failure
command: 'curl --request POST --header "Content-Type: application/json" --data "{\"text\":\":x: \`$CIRCLE_JOB\` job failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}" $CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL'
# `$SLACK_CARETAKER_WEBHOOK_URL` is a secret env var defined in CircleCI project settings.
# The URL comes from https://angular-team.slack.com/apps/A0F7VRE7N-circleci.
command: 'curl --request POST --header "Content-Type: application/json" --data "{\"text\":\":x: \`$CIRCLE_JOB\` job failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}" $SLACK_CARETAKER_WEBHOOK_URL'
when: on_fail
legacy-unit-tests-local:
<<: *job_defaults
docker:
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *yarn_install
- run: yarn tsc -p packages
- run: yarn tsc -p packages/examples
- run: yarn tsc -p modules
- run: yarn karma start ./karma-js.conf.js --single-run --browsers=ChromeNoSandbox
legacy-unit-tests-saucelabs:
<<: *job_defaults
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
@ -461,12 +497,8 @@ jobs:
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *yarn_install
- *attach_workspace
- *init_environment
- run:
name: Preparing environment for running tests on Saucelabs.
command: |
@ -477,7 +509,6 @@ jobs:
command: ./scripts/saucelabs/start-tunnel.sh
background: true
- run: yarn tsc -p packages
- run: yarn tsc -p packages/examples
- run: yarn tsc -p modules
# Waits for the Saucelabs tunnel to be ready. This ensures that we don't run tests
# too early without Saucelabs not being ready.
@ -485,43 +516,11 @@ jobs:
- run: yarn karma start ./karma-js.conf.js --single-run --browsers=${KARMA_JS_BROWSERS}
- run: ./scripts/saucelabs/stop-tunnel.sh
legacy-e2e-tests:
<<: *job_defaults
docker:
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
- *setup_bazel_remote_execution
- attach_workspace:
at: dist
# Build the e2e tests using the existing Bazel "packages-dist" output that has been
# attached to this job. This avoids multiple rebuilds across various CI jobs.
- run: ./scripts/build-e2e-tests.sh --use-existing-packages-dist
- run:
name: Starting servers for e2e tests
command: yarn gulp serve serve-examples
background: true
- run: NODE_PATH=$NODE_PATH:./dist/all yarn protractor ./protractor-e2e.conf.js --bundles=true
- run: NODE_PATH=$NODE_PATH:./dist/all yarn protractor ./protractor-examples-e2e.conf.js --bundles=true
- run: NODE_PATH=$NODE_PATH:./dist/all yarn protractor ./protractor-perf.conf.js --bundles=true --dryrun
legacy-misc-tests:
<<: *job_defaults
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *yarn_install
- attach_workspace:
at: dist
- *attach_workspace
- *init_environment
- run: yarn gulp check-cycle
# TODO: disabled because the Bazel packages-dist does not seem to have map files for
# the ESM5/ES2015 output. See: https://github.com/angular/angular/issues/27966
@ -531,32 +530,46 @@ workflows:
version: 2
default_workflow:
jobs:
- lint
- test
- test_ivy_aot
- build-npm-packages
- test_aio
- legacy-unit-tests-local
- legacy-unit-tests-saucelabs
- setup
- lint:
requires:
- setup
- test:
requires:
- setup
- test_ivy_aot:
requires:
- setup
- build-npm-packages:
requires:
- setup
- test_aio:
requires:
- setup
- deploy_aio:
requires:
- test_aio
- legacy-e2e-tests:
requires:
- build-npm-packages
- legacy-misc-tests:
requires:
- build-npm-packages
- test_aio_local:
requires:
- build-npm-packages
# - test_aio_local_ivy:
# requires:
# - build-ivy-npm-packages
- test_aio_tools:
requires:
- build-npm-packages
- test_docs_examples:
requires:
- build-npm-packages
# - test_docs_examples_ivy:
# requires:
# - build-ivy-npm-packages
- aio_preview:
requires:
- setup
# Only run on PR builds. (There can be no previews for non-PR builds.)
filters:
branches:
@ -581,20 +594,34 @@ workflows:
- test_aio_local
# - test_aio_local_ivy
- test_docs_examples
# Get the artifacts to publish from the build-npm-packages job
# - test_docs_examples_ivy
# Get the artifacts to publish from the build-packages-dist job
# since the publishing script expects the legacy outputs layout.
- build-npm-packages
- legacy-e2e-tests
- legacy-misc-tests
- legacy-unit-tests-local
- legacy-unit-tests-saucelabs
saucelabs_tests:
jobs:
- setup
- legacy-unit-tests-saucelabs:
requires:
- setup
triggers:
- schedule:
# Runs the Saucelabs legacy tests every hour. We still want to run Saucelabs
# frequently as the caretaker needs up-to-date results when merging PRs or creating
# a new release. Also we primarily moved the Saucelabs job into a cronjob that doesn't
# run for PRs, in order to ensure that PRs are not affected by Saucelabs flakiness or
# incidents. This is still guaranteed (even if we run the job every hour).
cron: "0 * * * *"
filters: *publish_branches_filter
aio_monitoring:
jobs:
- aio_monitoring
triggers:
- schedule:
# Runs AIO monitoring job at 00:00AM every day.
cron: "0 0 * * *"
filters:
branches:

View File

@ -1,8 +1,9 @@
#!/usr/bin/env bash
# Variables
readonly envHelpersPath="`dirname $0`/env-helpers.inc.sh";
readonly getCommitRangePath="`dirname $0`/get-commit-range.js";
readonly projectDir=$(realpath "$(dirname ${BASH_SOURCE[0]})/..")
readonly envHelpersPath="$projectDir/.circleci/env-helpers.inc.sh";
readonly getCommitRangePath="$projectDir/.circleci/get-commit-range.js";
# Load helpers and make them available everywhere (through `$BASH_ENV`).
source $envHelpersPath;
@ -14,7 +15,7 @@ echo "source $envHelpersPath;" >> $BASH_ENV;
####################################################################################################
# See https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables for more info.
####################################################################################################
setPublicVar PROJECT_ROOT "$(pwd)";
setPublicVar PROJECT_ROOT "$projectDir";
setPublicVar CI_AIO_MIN_PWA_SCORE "95";
# This is the branch being built; e.g. `pull/12345` for PR builds.
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
@ -38,8 +39,6 @@ setPublicVar CI_REPO_OWNER "$CIRCLE_PROJECT_USERNAME";
####################################################################################################
setSecretVar CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN "$AIO_DEPLOY_TOKEN";
setSecretVar CI_SECRET_PAYLOAD_FIREBASE_TOKEN "$ANGULAR_PAYLOAD_TOKEN";
# Defined in https://angular-team.slack.com/apps/A0F7VRE7N-circleci.
setSecretVar CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL "$SLACK_CARETAKER_WEBHOOK_URL";
####################################################################################################
@ -55,6 +54,7 @@ else
setPublicVar SAUCE_USERNAME "angular-ci";
setSecretVar SAUCE_ACCESS_KEY "9b988f434ff8-fbca-8aa4-4ae3-35442987";
fi
setPublicVar SAUCE_LOG_FILE /tmp/angular/sauce-connect.log
setPublicVar SAUCE_READY_FILE /tmp/angular/sauce-connect-ready-file.lock
setPublicVar SAUCE_PID_FILE /tmp/angular/sauce-connect-pid-file.lock
setPublicVar SAUCE_TUNNEL_IDENTIFIER "angular-${CIRCLE_BUILD_NUM}-${CIRCLE_NODE_INDEX}"

4
.github/CODEOWNERS vendored
View File

@ -313,6 +313,8 @@
# ===========================================================
#
# - alexeagle
# - filipesilva
# - gkalpak
# - IgorMinar
@ -729,6 +731,7 @@ testing/** @angular/fw-test
# ================================================
/aio/content/marketing/** @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/bios/** @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/images/marketing/** @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/navigation.json @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
/aio/content/license.md @angular/fw-docs-marketing @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
@ -744,6 +747,7 @@ testing/** @angular/fw-test
/.circleci/** @angular/fw-dev-infra
/.github/** @angular/fw-dev-infra
/docs/BAZEL.md @angular/fw-dev-infra
/packages/* @angular/fw-dev-infra
/scripts/** @angular/fw-dev-infra
/third_party/** @angular/fw-dev-infra
/tools/** @angular/fw-dev-infra

View File

@ -37,7 +37,9 @@ Please create and share minimal reproduction of the issue starting with this tem
<!-- ✍️--> https://stackblitz.com/...
<!--
If StackBlitz is not suitable for reproduction of your issue, please create a minimal GitHub repository with the reproduction of the issue. Share the link to the repo below along with step-by-step instructions to reproduce the problem, as well as expected and actual behavior.
If StackBlitz is not suitable for reproduction of your issue, please create a minimal GitHub repository with the reproduction of the issue.
A good way to make a minimal reproduction is to create a new app via `ng new repro-app` and add the minimum possible code to show the problem.
Share the link to the repo below along with step-by-step instructions to reproduce the problem, as well as expected and actual behavior.
Issues that don't have enough info and can't be reproduced will be closed.

View File

@ -56,9 +56,9 @@ merge:
- "**/.gitkeep"
- "**/yarn.lock"
- "**/package.json"
- "**/third_party/**"
- "**/tsconfig-build.json"
- "**/tsconfig.json"
- "**/rollup.config.js"
- "**/BUILD.bazel"
- "**/*.md"
- "packages/**/integrationtest/**"
@ -103,6 +103,11 @@ merge:
requiredStatuses:
- "ci/circleci: build"
- "ci/circleci: lint"
- "ci/circleci: publish_snapshot"
- "ci/angular: size"
- "cla/google"
- "google3"
# the comment that will be added when the merge label is added despite failing checks, leave empty or set to false to disable
# {{MERGE_LABEL}} will be replaced by the value of the mergeLabel option

11
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"gkalpak.aio-docs-utils",
"ms-vscode.vscode-typescript-tslint-plugin",
"xaver.clang-format",
],
}

12
.vscode/settings.json vendored
View File

@ -1,4 +1,13 @@
{
"[javascript]": {
"editor.formatOnSave": true,
},
"[typescript]": {
"editor.formatOnSave": true,
},
// Please install https://marketplace.visualstudio.com/items?itemName=xaver.clang-format to take advantage of `clang-format` in VSCode.
// (See https://clang.llvm.org/docs/ClangFormat.html for more info `clang-format`.)
"clang-format.executable": "${workspaceRoot}/node_modules/.bin/clang-format",
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
@ -12,4 +21,5 @@
"**/bazel-out": true,
"**/dist": true,
},
}
"git.ignoreLimitWarning": true,
}

View File

@ -1,7 +1,5 @@
package(default_visibility = ["//visibility:public"])
load("@build_bazel_rules_nodejs//:defs.bzl", "node_modules_filegroup")
exports_files([
"tsconfig.json",
"LICENSE",

View File

@ -1,3 +1,50 @@
<a name="7.2.8"></a>
## [7.2.8](https://github.com/angular/angular/compare/7.2.7...7.2.8) (2019-03-06)
### Bug Fixes
* **animations:** ensure `position` and `display` styles are handled outside of keyframes/web-animations ([#28911](https://github.com/angular/angular/issues/28911)) ([86981b3](https://github.com/angular/angular/commit/86981b3)), closes [#24923](https://github.com/angular/angular/issues/24923) [#25635](https://github.com/angular/angular/issues/25635)
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([2a25ac2](https://github.com/angular/angular/commit/2a25ac2))
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([5669333](https://github.com/angular/angular/commit/5669333)), closes [#24338](https://github.com/angular/angular/issues/24338)
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([b598e88](https://github.com/angular/angular/commit/b598e88)), closes [/github.com/angular/angular/issues/23012#issuecomment-376430187](https://github.com//github.com/angular/angular/issues/23012/issues/issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
<a name="7.2.7"></a>
## [7.2.7](https://github.com/angular/angular/compare/7.2.6...7.2.7) (2019-02-27)
### Bug Fixes
* **bazel:** pin browser repositories using [@npm](https://github.com/npm)_bazel_karma//:browser_repositories.bzl in bazel schematics ([#28896](https://github.com/angular/angular/issues/28896)) ([b686449](https://github.com/angular/angular/commit/b686449))
* **core:** traverse and sanitize content of unsafe elements ([#28804](https://github.com/angular/angular/issues/28804)) ([fdcf877](https://github.com/angular/angular/commit/fdcf877)), closes [#25879](https://github.com/angular/angular/issues/25879) [#25879](https://github.com/angular/angular/issues/25879) [#26007](https://github.com/angular/angular/issues/26007) [#28427](https://github.com/angular/angular/issues/28427)
* **language-service:** Fix completions for input/output with alias ([#28904](https://github.com/angular/angular/issues/28904)) ([d0018e6](https://github.com/angular/angular/commit/d0018e6)), closes [#27959](https://github.com/angular/angular/issues/27959)
<a name="7.2.6"></a>
## [7.2.6](https://github.com/angular/angular/compare/7.2.5...7.2.6) (2019-02-20)
### Bug Fixes
* **compiler-cli:** incorrect bundled metadata for static class member call expressions ([#28762](https://github.com/angular/angular/issues/28762)) ([ab69c31](https://github.com/angular/angular/commit/ab69c31)), closes [/github.com/angular/angular/blob/master/packages/core/src/change_detection/differs/keyvalue_differs.ts#L121](https://github.com//github.com/angular/angular/blob/master/packages/core/src/change_detection/differs/keyvalue_differs.ts/issues/L121) [#28741](https://github.com/angular/angular/issues/28741)
<a name="7.2.5"></a>
## [7.2.5](https://github.com/angular/angular/compare/7.2.4...7.2.5) (2019-02-15)
### Bug Fixes
* **compiler-cli:** diagnostics should respect "newLine" compiler option ([#28550](https://github.com/angular/angular/issues/28550)) ([ce750e6](https://github.com/angular/angular/commit/ce750e6))
* **router:** redirect to root url when returned as UrlTree from guard ([#28271](https://github.com/angular/angular/issues/28271)) ([1e58a21](https://github.com/angular/angular/commit/1e58a21)), closes [#27845](https://github.com/angular/angular/issues/27845)
* **router:** set href when routerLink is used on an 'area' element ([#28441](https://github.com/angular/angular/issues/28441)) ([d491a20](https://github.com/angular/angular/commit/d491a20)), closes [#28401](https://github.com/angular/angular/issues/28401)
<a name="7.2.4"></a>
## [7.2.4](https://github.com/angular/angular/compare/7.2.3...7.2.4) (2019-02-06)

126
WORKSPACE
View File

@ -1,17 +1,6 @@
workspace(name = "angular")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load(
"//packages/bazel:package.bzl",
"rules_angular_dependencies",
"rules_angular_dev_dependencies",
)
http_archive(
name = "io_bazel_rules_go",
sha256 = "b7a62250a3a73277ade0ce306d22f122365b513f5402222403e507f2f997d421",
url = "https://github.com/bazelbuild/rules_go/releases/download/0.16.3/rules_go-0.16.3.tar.gz",
)
# Uncomment for local bazel rules development
#local_repository(
@ -19,59 +8,45 @@ http_archive(
# path = "../rules_nodejs",
#)
#local_repository(
# name = "build_bazel_rules_typescript",
# name = "npm_bazel_typescript",
# path = "../rules_typescript",
#)
# Angular Bazel users will call this function
rules_angular_dependencies()
# Install transitive deps of rules_nodejs
load("@build_bazel_rules_nodejs//:package.bzl", "rules_nodejs_dependencies")
rules_nodejs_dependencies()
# These are the dependencies only for us
rules_angular_dev_dependencies()
# Install transitive deps of rules_typescript
load("@build_bazel_rules_typescript//:package.bzl", "rules_typescript_dependencies")
rules_typescript_dependencies()
#
# Point Bazel to WORKSPACEs that live in subdirectories
#
# Fetch rules_nodejs so we can install our npm dependencies
http_archive(
name = "rxjs",
sha256 = "72b0b4e517f43358f554c125e40e39f67688cd2738a8998b4a266981ed32f403",
strip_prefix = "package/src",
url = "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz",
name = "build_bazel_rules_nodejs",
sha256 = "1416d03823fed624b49a0abbd9979f7c63bbedfd37890ddecedd2fe25cccebc6",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.18.6/rules_nodejs-0.18.6.tar.gz"],
)
# Point to the integration test workspace just so that Bazel doesn't descend into it
# when expanding the //... pattern
# Use a mock @npm repository while we are building angular from source
# downstream. Angular will get its npm dependencies with in @ngdeps which
# is setup in ng_setup_workspace().
# TODO(gregmagolan): remove @ngdeps once angular is no longer build from source
# downstream and have build use @npm for npm dependencies
local_repository(
name = "bazel_integration_test",
path = "integration/bazel",
name = "npm",
path = "tools/npm_workspace",
)
#
# Load and install our dependencies downloaded above.
#
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
# Check the bazel version and download npm dependencies
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
# Bazel version must be at least v0.21.0 because:
# - 0.21.0 Using --incompatible_strict_action_env flag fixes cache when running `yarn bazel`
# (see https://github.com/angular/angular/issues/27514#issuecomment-451438271)
check_bazel_version("0.21.0", """
check_bazel_version(
message = """
You no longer need to install Bazel on your machine.
Angular has a dependency on the @bazel/bazel package which supplies it.
Try running `yarn bazel` instead.
(If you did run that, check that you've got a fresh `yarn install`)
""")
""",
minimum_bazel_version = "0.21.0",
)
# Setup the Node.js toolchain
node_repositories(
node_version = "10.9.0",
package_json = ["//:package.json"],
@ -79,41 +54,48 @@ node_repositories(
yarn_version = "1.12.1",
)
local_repository(
name = "npm",
path = "tools/npm_workspace",
)
load("@io_bazel_rules_go//go:def.bzl", "go_register_toolchains", "go_rules_dependencies")
go_rules_dependencies()
go_register_toolchains()
load("@io_bazel_rules_webtesting//web:repositories.bzl", "browser_repositories", "web_test_repositories")
web_test_repositories()
browser_repositories(
chromium = True,
firefox = True,
)
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
ts_setup_workspace()
load("@angular//:index.bzl", "ng_setup_workspace")
# Setup the angular toolchain which installs npm dependencies into @ngdeps
load("//tools:ng_setup_workspace.bzl", "ng_setup_workspace")
ng_setup_workspace()
##################################
# Skylark documentation generation
# Install all bazel dependencies of the @ngdeps npm packages
load("@ngdeps//:install_bazel_dependencies.bzl", "install_bazel_dependencies")
install_bazel_dependencies()
# Load angular dependencies
load("//packages/bazel:package.bzl", "rules_angular_dev_dependencies")
rules_angular_dev_dependencies()
# Load karma dependencies
load("@npm_bazel_karma//:package.bzl", "rules_karma_dependencies")
rules_karma_dependencies()
# Setup the rules_webtesting toolchain
load("@io_bazel_rules_webtesting//web:repositories.bzl", "web_test_repositories")
web_test_repositories()
# Temporary work-around for https://github.com/angular/angular/issues/28681
# TODO(gregmagolan): go back to @io_bazel_rules_webtesting browser_repositories
load("@npm_bazel_karma//:browser_repositories.bzl", "browser_repositories")
browser_repositories()
# Setup the rules_typescript tooolchain
load("@npm_bazel_typescript//:defs.bzl", "ts_setup_workspace")
ts_setup_workspace()
# Setup the rules_sass toolchain
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")
sass_repositories()
# Setup the skydoc toolchain
load("@io_bazel_skydoc//skylark:skylark.bzl", "skydoc_repositories")
skydoc_repositories()

2
aio/.gitignore vendored
View File

@ -26,11 +26,13 @@
!.vscode/extensions.json
# misc
/.firebase/
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
debug.log
firebase-debug.log
npm-debug.log
testem.log
/typings

View File

@ -57,7 +57,9 @@ dist/
# aot
**/*.ngsummary.json
upgrade-module/tsconfig-aot.json
!rollup-config.js
upgrade-module/rollup-config.js
aot-compiler/**/*.d.ts
aot-compiler/**/*.factory.d.ts
upgrade-phonecat-2-hybrid/aot/**/*
@ -84,5 +86,9 @@ upgrade-phonecat-2-hybrid/aot/**/*
*stackblitz.no-link.html
# ngUpgrade testing
upgrade-phonecat-1-typescript/tsconfig-aot.json
upgrade-phonecat-1-typescript/rollup-config.js
upgrade-phonecat-3-final/tsconfig-aot.json
upgrade-phonecat-3-final/rollup-config.js
!upgrade-phonecat-*/**/karma.conf.js
!upgrade-phonecat-*/**/karma-test-shim.js

View File

@ -20,7 +20,7 @@ export class AppComponent {
movies: IMovie[] = [];
showImage = true;
title = 'AngularJS to Angular Quick Ref Cookbook';
toggleImage(event: UIEvent) {
toggleImage(event?: UIEvent) {
this.showImage = !this.showImage;
this.eventType = (event && event.type) || 'not provided';
}

View File

@ -1,14 +0,0 @@
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

View File

@ -19,6 +19,7 @@ import { HeroListAutoCalcPageComponent } from './hero-list-auto-page.component';
import { HeroListAutoComponent } from './hero-list-auto.component';
import { HomeComponent } from './home.component';
import { AboutComponent } from './about.component';
import { InsertRemoveComponent } from './insert-remove.component';
@NgModule({
@ -56,6 +57,7 @@ import { AboutComponent } from './about.component';
HeroListAutoCalcPageComponent,
HeroListAutoComponent,
HomeComponent,
InsertRemoveComponent,
AboutComponent
],
bootstrap: [AppComponent]

View File

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

View File

@ -0,0 +1,3 @@
<!-- #docregion unsupported -->
<p app:Highlight>This is invalid</p>
<!-- #enddocregion unsupported -->

View File

@ -0,0 +1,11 @@
{
"e2e": [
{
"cmd": "yarn",
"args": [
"e2e",
"--no-webdriver-update"
]
}
]
}

View File

@ -19,20 +19,20 @@ const DifferentParent = Parent;
// #enddocregion provide-the-parent
// The `parentType` defaults to `Parent` when omitting the second parameter.
// #docregion provide-the-parent
const provideParent =
export function provideParent
// #enddocregion provide-parent, provide-the-parent
// #docregion provide-parent
(component: any, parentType?: any) => {
(component: any, parentType?: any) {
return { provide: parentType || Parent, useExisting: forwardRef(() => component) };
};
}
// #enddocregion provide-parent
// Simpler syntax version that always provides the component in the name of `Parent`.
const provideTheParent =
export function provideTheParent
// #docregion provide-the-parent
(component: any) => {
(component: any) {
return { provide: Parent, useExisting: forwardRef(() => component) };
};
}
// #enddocregion provide-the-parent

View File

@ -0,0 +1,11 @@
{
"e2e": [
{
"cmd": "yarn",
"args": [
"e2e",
"--no-webdriver-update"
]
}
]
}

View File

@ -28,10 +28,7 @@ let checkLogForMessage = (message: string) => {
expect(page.logList.getText()).toContain(message);
};
// TODO(i): temorarily disable these tests because angular-in-memory-web-api is not compatible with rxjs v6 yet
// and we don't have the backwards compatibility package yet.
// Reenable after rxjs v6 compatibility package is out or angular-in-memory-web-api is compatible with rxjs v6
xdescribe('Http Tests', function() {
describe('Http Tests', function() {
beforeEach(() => {
browser.get('');
});

View File

@ -1,3 +1,12 @@
{
"projectType": "i18n"
}
"projectType": "i18n",
"e2e": [
{
"cmd": "yarn",
"args": [
"e2e",
"--no-webdriver-update"
]
}
]
}

View File

@ -50,9 +50,10 @@
<div (keyup)="0">
<h4>Template context: template reference variables (#customerInput):</h4>
<label>Type something:
<!-- #docregion template-reference-variable -->
<input #customerInput>{{customerInput.value}}</label>
<label>Type something:
<input #customerInput>{{customerInput.value}}
</label>
<!-- #enddocregion template-reference-variable -->
</div>

View File

@ -13,8 +13,8 @@ import { AppComponent } from './app.component';
// #enddocregion
*/
// #docregion
import { HighlightDirective } from './highlight.directive';
import { TitleComponent } from './title.component';
import { HighlightDirective } from './highlight.directive.1';
import { TitleComponent } from './title.component.1';
import { UserService } from './user.service';
/* Routing Module */

View File

@ -1,10 +0,0 @@
// #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 : '';
}
}

View File

@ -1,20 +0,0 @@
// #docplaster
// 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';
// Highlight the host element or any InputElement in blue
@Directive({ selector: '[highlight], input' })
export class ContactHighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'powderblue';
// #enddocregion
console.log(`* Contact highlight called for ${el.nativeElement.tagName}`);
// #docregion
}
}
// #enddocregion

View File

@ -1,14 +0,0 @@
// #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}`);
}
}

View File

@ -8,7 +8,7 @@ import { UserService } from './user.service';
@Component({
selector: 'app-title',
templateUrl: './title.component.html'
templateUrl: './title.component.1.html'
})
export class TitleComponent {
title = 'Angular Modules';

View File

@ -1,8 +0,0 @@
{
"server": {
"baseDir": "src",
"routes": {
"/node_modules": "node_modules"
}
}
}

View File

@ -1,8 +0,0 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `<h1>Hello {{name}}</h1>`
})
export class AppComponent { name = 'Angular'; }

View File

@ -1,11 +0,0 @@
// #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

@ -1,31 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Angular Quickstart</title>
<base href="/">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {color:#369;font-family: Arial,Helvetica,sans-serif;}
</style>
<!-- Polyfills -->
<!-- #docregion polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<!-- #enddocregion polyfills -->
<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>
<script>
System.import('main.js').catch(function(err){ console.error(err); });
</script>
</head>
<body>
<!-- #docregion my-app-->
<my-app>Loading AppComponent content here ...</my-app>
<!-- #enddocregion my-app-->
</body>
</html>

View File

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

View File

@ -1,13 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "es2015", "dom" ],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}

View File

@ -1,11 +0,0 @@
{
"description": "QuickStart",
"files": [
"src/app/app.component.ts",
"src/app/app.module.ts",
"src/main.ts",
"src/index.html"
],
"file": "src/app/app.component.ts",
"tags": ["quickstart"]
}

View File

@ -4,7 +4,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-crisis-list',
templateUrl: './crisis-list.component.html',
styleUrls: ['./crisis-list.component.css']
templateUrl: './crisis-list.component.1.html',
styleUrls: ['./crisis-list.component.1.css']
})
export class CrisisListComponent { }

View File

@ -4,7 +4,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
styleUrls: ['./hero-list.component.css']
templateUrl: './hero-list.component.1.html',
styleUrls: ['./hero-list.component.1.css']
})
export class HeroListComponent { }

View File

@ -1,17 +0,0 @@
'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);
});
});

View File

@ -152,7 +152,7 @@
<div [ngSwitch]="hero?.emotion">
<app-happy-hero *ngSwitchCase="'happy'" [hero]="hero"></app-happy-hero>
<app-sad-hero *ngSwitchCase="'sad'" [hero]="hero"></app-sad-hero>
<app-confused-hero *ngSwitchCase="'app-confused'" [hero]="hero"></app-confused-hero>
<app-confused-hero *ngSwitchCase="'confused'" [hero]="hero"></app-confused-hero>
<app-unknown-hero *ngSwitchDefault [hero]="hero"></app-unknown-hero>
</div>
<!-- #enddocregion built-in, ngswitch -->

View File

@ -1,3 +1,2 @@
// #docregion
export * from './spinner.component';
export * from './spinner.service';

View File

@ -1,16 +0,0 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { SpinnerService } from './spinner.service';
@Component({
selector: 'toh-spinner',
template: '<div>spinner</div>'
})
export class SpinnerComponent implements OnDestroy, OnInit {
constructor(private spinnerService: SpinnerService) { }
ngOnInit() { }
ngOnDestroy() { }
}

View File

@ -1,3 +1,2 @@
// #docregion
export * from './toast.component';
export * from './toast.service';

View File

@ -1,13 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { ToastService } from './toast.service';
@Component({
selector: 'toh-toast',
template: '<div>toast</div>'
})
export class ToastComponent implements OnInit {
constructor(toastService: ToastService) { }
ngOnInit() { }
}

View File

@ -1,13 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { ToastService } from '../../core';
@Component({
selector: 'toh-toast',
template: '<div>toast</div>'
})
export class ToastComponent implements OnInit {
constructor(toastService: ToastService) { }
ngOnInit() { }
}

View File

@ -32,8 +32,6 @@
height: 56px;
padding: 0 16px 0 72px;
padding-left: 8px;
background-color: #673AB7;
background: #0033FF;
background-color: #222;
}

View File

@ -1,6 +1,5 @@
/*#docregion*/
.spinner {
position: absolute;
left: 7em;
top: 20em;
position: absolute;

View File

@ -32,8 +32,6 @@
height: 56px;
padding: 0 16px 0 72px;
padding-left: 8px;
background-color: #673AB7;
background: #0033FF;
background-color: #222;
}

View File

@ -4,4 +4,7 @@ import { Component } from '@angular/core';
selector: 'sg-app',
templateUrl: './app.component.html'
})
export class AppComponent { }
export class AppComponent {
doSomething() {}
}

View File

@ -4,4 +4,7 @@ import { Component } from '@angular/core';
selector: 'sg-app',
templateUrl: './app.component.html'
})
export class AppComponent { }
export class AppComponent {
onSavedTheDay(event$: any) { }
}

View File

@ -66,7 +66,7 @@ export class AppComponent implements AfterViewInit, OnInit {
currentHero: Hero;
deleteHero(hero: Hero) {
deleteHero(hero?: Hero) {
this.alert(`Delete ${hero ? hero.name : 'the hero'}.`);
}
@ -105,18 +105,18 @@ export class AppComponent implements AfterViewInit, OnInit {
get nullHero(): Hero { return null; }
onClickMe(event: KeyboardEvent) {
onClickMe(event?: KeyboardEvent) {
let evtMsg = event ? ' Event target class is ' + (<HTMLElement>event.target).className : '';
this.alert('Click me.' + evtMsg);
}
onSave(event: KeyboardEvent) {
onSave(event?: KeyboardEvent) {
let evtMsg = event ? ' Event target is ' + (<HTMLElement>event.target).textContent : '';
this.alert('Saved.' + evtMsg);
if (event) { event.stopPropagation(); }
}
onSubmit() {/* referenced but not used */}
onSubmit(data: any) {/* referenced but not used */}
product = {
name: 'frimfram',

View File

@ -1,6 +1,6 @@
# Introduction to modules
Angular apps are modular and Angular has its own modularity system called *NgModules*.
Angular apps are modular and Angular has its own modularity system called *NgModules*.
NgModules are containers for a cohesive block of code dedicated to an application domain, a workflow, or a closely related set of capabilities. They can contain components, service providers, and other code files whose scope is defined by the containing NgModule. They can import functionality that is exported from other NgModules, and export selected functionality for use by other NgModules.
Every Angular app has at least one NgModule class, [the *root module*](guide/bootstrapping), which is conventionally named `AppModule` and resides in a file named `app.module.ts`. You launch your app by *bootstrapping* the root NgModule.
@ -27,7 +27,7 @@ Here's a simple root NgModule definition.
<div class="alert is-helpful">
The `export` property of `AppComponent` is included here for illustration; it isn't actually necessary in this example. A root NgModule has no reason to *export* anything because other modules don't need to *import* the root NgModule.
`AppComponent` is included in the `exports` list here for illustration; it isn't actually necessary in this example. A root NgModule has no reason to *export* anything because other modules don't need to *import* the root NgModule.
</div>
@ -89,7 +89,7 @@ For example, import Angular's `Component` decorator from the `@angular/core` lib
<code-example path="architecture/src/app/app.component.ts" region="import" linenums="false"></code-example>
You also import NgModules from Angular *libraries* using JavaScript import statements.
You also import NgModules from Angular *libraries* using JavaScript import statements.
For example, the following code imports the `BrowserModule` NgModule from the `platform-browser` library.
<code-example path="architecture/src/app/mini-app.ts" region="import-browser-module" linenums="false"></code-example>

View File

@ -41,6 +41,10 @@ when the user hovers over that element. You can apply it like this:
{@a write-directive}
Please note that directives _do not_ support namespaces.
<code-example path="attribute-directives/src/app/app.component.avoid.html" linenums="false" header="src/app/app.component.avoid.html (unsupported)" region="unsupported"></code-example>
### Write the directive code
Create the directive class file in a terminal window with the CLI command [`ng generate directive`](cli/generate).

View File

@ -52,16 +52,16 @@ When all dependencies are in place, `AppComponent` displays the user information
## Limit service scope to a component subtree
An Angular application has multiple injectors, arranged in a tree hierarchy that parallels the component tree.
Each injector creates a singleton instance of a dependency.
An Angular application has multiple injectors, arranged in a tree hierarchy that parallels the component tree.
Each injector creates a singleton instance of a dependency.
That same instance is injected wherever that injector provides that service.
A particular service can be provided and created at any level of the injector hierarchy,
which means that there can be multiple instances of a service if it is provided by multiple injectors.
Dependencies provided by the root injector can be injected into *any* component *anywhere* in the application.
In some cases, you might want to restrict service availability to a particular region of the application.
Dependencies provided by the root injector can be injected into *any* component *anywhere* in the application.
In some cases, you might want to restrict service availability to a particular region of the application.
For instance, you might want to let users explicitly opt in to use a service,
rather than letting the root injector provide it automatically.
rather than letting the root injector provide it automatically.
You can limit the scope of an injected service to a *branch* of the application hierarchy
by providing that service *at the sub-root component for that branch*.
@ -146,34 +146,34 @@ and confirm that the three `HeroBioComponent` instances have their own cached he
When a class requires a dependency, that dependency is added to the constructor as a parameter.
When Angular needs to instantiate the class, it calls upon the DI framework to supply the dependency.
By default, the DI framework searches for a provider in the injector hierarchy,
starting at the component's local injector of the component, and if necessary bubbling up
starting at the component's local injector of the component, and if necessary bubbling up
through the injector tree until it reaches the root injector.
* The first injector configured with a provider supplies the dependency (a service instance or value) to the constructor.
* The first injector configured with a provider supplies the dependency (a service instance or value) to the constructor.
* If no provider is found in the root injector, the DI framework returns null to the constructor.
* If no provider is found in the root injector, the DI framework throws an error.
There are a number of options for modifying the default search behavior, using _parameter decorators_
on the service-valued parameters of a class constructor.
on the service-valued parameters of a class constructor.
{@a optional}
### Make a dependency `@Optional` and limit search with `@Host`
Dependencies can be registered at any level in the component hierarchy.
When a component requests a dependency, Angular starts with that component's injector
and walks up the injector tree until it finds the first suitable provider.
Dependencies can be registered at any level in the component hierarchy.
When a component requests a dependency, Angular starts with that component's injector
and walks up the injector tree until it finds the first suitable provider.
Angular throws an error if it can't find the dependency during that walk.
In some cases, you need to limit the search or accommodate a missing dependency.
You can modify Angular's search behavior with the `@Host` and `@Optional` qualifying
decorators on a service-valued parameter of the component's constructor.
decorators on a service-valued parameter of the component's constructor.
* The `@Optional` property decorator tells Angular to return null when it can't find the dependency.
* The `@Host` property decorator stops the upward search at the *host component*.
The host component is typically the component requesting the dependency.
However, when this component is projected into a *parent* component,
* The `@Host` property decorator stops the upward search at the *host component*.
The host component is typically the component requesting the dependency.
However, when this component is projected into a *parent* component,
that parent component becomes the host. The following example covers this second case.
These decorators can be used individually or together, as shown in the example.
@ -238,8 +238,8 @@ Here's `HeroBiosAndContactsComponent` in action.
If you comment out the `@Host()` decorator, Angular walks up the injector ancestor tree
until it finds the logger at the `AppComponent` level.
The logger logic kicks in and the hero display updates
until it finds the logger at the `AppComponent` level.
The logger logic kicks in and the hero display updates
with the "!!!" marker to indicate that the logger was found.
<figure>
@ -254,7 +254,7 @@ the app throws an exception when it cannot find the required logger at the host
### Supply a custom provider with `@Inject`
Using a custom provider allows you to provide a concrete implementation for implicit dependencies, such as built-in browser APIs. The following example uses an `InjectionToken` to provide the [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) browser API as a dependency in the `BrowserStorageService`.
Using a custom provider allows you to provide a concrete implementation for implicit dependencies, such as built-in browser APIs. The following example uses an `InjectionToken` to provide the [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) browser API as a dependency in the `BrowserStorageService`.
<code-example path="dependency-injection-in-action/src/app/storage.service.ts" header="src/app/storage.service.ts">
@ -262,6 +262,8 @@ Using a custom provider allows you to provide a concrete implementation for impl
The `factory` function returns the `localStorage` property that is attached to the browser window object. The `Inject` decorator is a constructor parameter used to specify a custom provider of a dependency. This custom provider can now be overridden during testing with a mock API of `localStorage` instead of interactive with real browser APIs.
{@a skip}
### Modify the provider search with `@Self` and `@SkipSelf`
Providers can also be scoped by injector through constructor parameter decorators. The following example overrides the `BROWSER_STORAGE` token in the `Component` class `providers` with the `sessionStorage` browser API. The same `BrowserStorageService` is injected twice in the constructor, decorated with `@Self` and `@SkipSelf` to define which injector handles the provider dependency.
@ -291,7 +293,7 @@ The directive sets the background to a highlight color when the user mouses over
DOM element to which the directive is applied.
Angular sets the constructor's `el` parameter to the injected `ElementRef`.
(An `ElementRef` is a wrapper around a DOM element,
(An `ElementRef` is a wrapper around a DOM element,
whose `nativeElement` property exposes the DOM element for the directive to manipulate.)
The sample code applies the directive's `myHighlight` attribute to two `<div>` tags,
@ -332,7 +334,7 @@ Angular asks the injector for the service associated with `LoggerService`
and assigns the returned value to the `logger` parameter.
If the injector has already cached an instance of the service associated with the token,
it provides that instance.
it provides that instance.
If it doesn't, it needs to make one using the provider associated with the token.
<div class="alert is-helpful">
@ -346,7 +348,7 @@ If the search fails, the injector throws an error&mdash;unless the request was [
A new injector has no providers.
Angular initializes the injectors it creates with a set of preferred providers.
You have to configure providers for your own app-specific dependencies.
You have to configure providers for your own app-specific dependencies.
{@a defining-providers}
@ -355,7 +357,7 @@ You have to configure providers for your own app-specific dependencies.
### Defining providers
A dependency can't always be created by the default method of instantiating a class.
You learned about some other methods in [Dependency Providers](guide/dependency-injection-providers).
You learned about some other methods in [Dependency Providers](guide/dependency-injection-providers).
The following `HeroOfTheMonthComponent` example demonstrates many of the alternatives and why you need them.
It's visually simple: a few properties and the logs produced by a logger.
@ -364,7 +366,7 @@ It's visually simple: a few properties and the logs produced by a logger.
</figure>
The code behind it customizes how and where the DI framework provides dependencies.
The use cases illustrate different ways to use the [*provide* object literal](guide/dependency-injection-providers#provide) to associate a definition object with a DI token.
The use cases illustrate different ways to use the [*provide* object literal](guide/dependency-injection-providers#provide) to associate a definition object with a DI token.
<code-example path="dependency-injection-in-action/src/app/hero-of-the-month.component.ts" region="hero-of-the-month" header="hero-of-the-month.component.ts">
@ -389,13 +391,13 @@ The `HeroOfTheMonthComponent` example has two value providers.
</code-example>
* The first provides an existing instance of the `Hero` class to use for the `Hero` token, rather than
requiring the injector to create a new instance with `new` or use its own cached instance.
requiring the injector to create a new instance with `new` or use its own cached instance.
Here, the token is the class itself.
* The second specifies a literal string resource to use for the `TITLE` token.
The `TITLE` provider token is *not* a class, but is instead a
special kind of provider lookup key called an [injection token](guide/dependency-injection-in-action#injection-token), represented by
an `InjectionToken` instance.
an `InjectionToken` instance.
You can use an injection token for any kind of provider but it's particularly
helpful when the dependency is a simple value like a string, a number, or a function.
@ -414,12 +416,12 @@ Other types of providers can create their values *lazily*; that is, when they're
{@a useclass}
#### Class providers: `useClass`
#### Class providers: `useClass`
The `useClass` provider key lets you create and return a new instance of the specified class.
You can use this type of provider to substitute an *alternative implementation*
for a common or default class.
for a common or default class.
The alternative implementation could, for example, implement a different strategy,
extend the default class, or emulate the behavior of the real class in a test case.
@ -502,7 +504,7 @@ This is illustrated in the following image, which displays the logging date.
{@a usefactory}
#### Factory providers: `useFactory`
#### Factory providers: `useFactory`
The `useFactory` provider key lets you create a dependency object by calling a factory function,
as in the following example.
@ -537,7 +539,7 @@ the passed-in state value and the injected services `Hero` and `HeroService`.
The provider factory function (returned by `runnersUpFactory()`) returns the actual dependency object,
the string of names.
* The function takes a winning `Hero` and a `HeroService` as arguments.
* The function takes a winning `Hero` and a `HeroService` as arguments.
Angular supplies these arguments from injected values identified by
the two *tokens* in the `deps` array.
@ -588,7 +590,7 @@ But they did neither.
`MinimalLogger` is used only as a dependency injection token.
When you use a class this way, it's called a *class interface*.
As mentioned in [DI Providers](guide/dependency-injection-providers#interface-not-valid-token),
an interface is not a valid DI token because it is a TypeScript artifact that doesn't exist at run time.
Use this abstract class interface to get the strong typing of an interface,
@ -609,7 +611,7 @@ The `MinimalLogger` transpiles to this unoptimized, pre-minified JavaScript for
</code-example>
Notice that it doesn't have any members. It never grows no matter how many members you add to the class,
as long as those members are typed but not implemented.
as long as those members are typed but not implemented.
Look again at the TypeScript `MinimalLogger` class to confirm that it has no implementation.
@ -736,7 +738,7 @@ Break the circularity with `forwardRef`.
</code-example>
<!--- Waiting for good examples
<!--- Waiting for good examples
{@a directive-level-providers}
@ -744,15 +746,15 @@ Break the circularity with `forwardRef`.
## Element-level providers
A component is a specialization of directive, and the `@Component()` decorator inherits the `providers` property from `@Directive`. The injector is at the element level, so a provider configured with any element-level injector is available to any component, directive, or pipe attached to the same element.
A component is a specialization of directive, and the `@Component()` decorator inherits the `providers` property from `@Directive`. The injector is at the element level, so a provider configured with any element-level injector is available to any component, directive, or pipe attached to the same element.
Here's a live example that implements a custom form control, taking advantage of an injector that is shared by a component and a directive on the same element.
https://stackblitz.com/edit/basic-form-control
The component, `custom-control`, configures a provider for the DI token `NG_VALUE_ACCESSOR`.
The component, `custom-control`, configures a provider for the DI token `NG_VALUE_ACCESSOR`.
In the template, the `FormControlName` directive is instantiated along with the custom component.
It can inject the `NG_VALUE_ACCESSOR` dependency because they share the same injector.
It can inject the `NG_VALUE_ACCESSOR` dependency because they share the same injector.
(Notice that this example also makes use of `forwardRef()` to resolve a circularity in the definitions.)
### Sharing a service among components
@ -784,4 +786,3 @@ If you want to show only one of them, use the directive to make sure __??of what
`<hero-overview heroCache></hero-overview>`
--->

View File

@ -182,8 +182,7 @@ Child modules and component injectors are independent of each other, and create
Thanks to [injector inheritance](guide/hierarchical-dependency-injection),
you can still inject application-wide services into these components.
A component's injector is a child of its parent component's injector,
and a descendent of its parent's parent's injector, and so on all the way back to the application's _root_ injector. Angular can inject a service provided by any injector in that lineage.
A component's injector is a child of its parent component's injector, and inherits from all ancestor injectors all the way back to the application's _root_ injector. Angular can inject a service provided by any injector in that lineage.
For example, Angular can inject `HeroListComponent` with both the `HeroService` provided in `HeroComponent` and the `UserService` provided in `AppModule`.

View File

@ -149,7 +149,7 @@ In either style, the template data bindings have the same access to the componen
Although this example uses variable assignment to initialize the components, you could instead declare and initialize the properties using a constructor:
<code-example path="displaying-data/src/app/app-ctor.component.ts" linenums="false" region="class">
<code-example path="displaying-data/src/app/app-ctor.component.1.ts" linenums="false" region="class">
</code-example>

View File

@ -42,7 +42,7 @@ Learn more about dependency resolution through the injector hierarchy:
*NgModule-level* providers can be specified with `@NgModule()` `providers` metadata option, or in the `@Injectable()` `providedIn` option (with some module other than the root `AppModule`).
Use the `@NgModule()` `provides` option if a module is [lazy loaded](guide/lazy-loading-ngmodules). The module's own injector is configured with the provider when that module is loaded, and Angular can inject the corresponding services in any class it creates in that module. If you use the `@Injectable()` option `providedIn: MyLazyloadModule`, the provider could be shaken out at compile time, if it is not used anywhere else in the app.
Use the `@NgModule()` `providers` option if a module is [lazy loaded](guide/lazy-loading-ngmodules). The module's own injector is configured with the provider when that module is loaded, and Angular can inject the corresponding services in any class it creates in that module. If you use the `@Injectable()` option `providedIn: MyLazyloadModule`, the provider could be shaken out at compile time, if it is not used anywhere else in the app.
* Learn more about [tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).

View File

@ -476,7 +476,7 @@ That's easy to implement with RxJS operators, as shown in this excerpt.
<code-example
path="http/src/app/package-search/package-search.component.ts"
region="debounce"
header="app/package-search/package-search.component.ts (excerpt))">
header="app/package-search/package-search.component.ts (excerpt)">
</code-example>
The `searchText$` is the sequence of search-box values coming from the user.
@ -865,6 +865,9 @@ with the `reportProgress` option set true to enable tracking of progress events.
Every progress event triggers change detection, so only turn them on if you truly intend to report progress in the UI.
When using [`HttpClient#request()`](api/common/http/HttpClient#request) with an HTTP method, configure with
[`observe: 'events'`](api/common/http/HttpClient#request) to see all events, including the progress of transfers.
</div>
Next, pass this request object to the `HttpClient.request()` method, which

View File

@ -896,11 +896,11 @@ Replace the contents of each component with the sample HTML below.
<code-tabs>
<code-pane header="src/app/crisis-list/crisis-list.component.html" path="router/src/app/crisis-list/crisis-list.component.html">
<code-pane header="src/app/crisis-list/crisis-list.component.html" path="router/src/app/crisis-list/crisis-list.component.1.html">
</code-pane>
<code-pane header="src/app/hero-list/hero-list.component.html" path="router/src/app/hero-list/hero-list.component.html" region="template">
<code-pane header="src/app/hero-list/hero-list.component.html" path="router/src/app/hero-list/hero-list.component.1.html" region="template">
</code-pane>
@ -972,7 +972,7 @@ Be sure it is the _last_ route in the configuration.
To test this feature, add a button with a `RouterLink` to the `HeroListComponent` template and set the link to `"/sidekicks"`.
<code-example path="router/src/app/hero-list/hero-list.component.html" linenums="false" header="src/app/hero-list/hero-list.component.html (excerpt)">
<code-example path="router/src/app/hero-list/hero-list.component.1.html" linenums="false" header="src/app/hero-list/hero-list.component.html (excerpt)">
</code-example>
@ -1239,11 +1239,11 @@ Here are the files discussed in this milestone.
</code-pane>
<code-pane header="hero-list/hero-list.component.html" path="router/src/app/hero-list/hero-list.component.html">
<code-pane header="hero-list/hero-list.component.html" path="router/src/app/hero-list/hero-list.component.1.html">
</code-pane>
<code-pane header="crisis-list/crisis-list.component.html" path="router/src/app/crisis-list/crisis-list.component.html">
<code-pane header="crisis-list/crisis-list.component.html" path="router/src/app/crisis-list/crisis-list.component.1.html">
</code-pane>
@ -2242,10 +2242,10 @@ This file does the following:
You could also create more transitions for other routes. This trigger is sufficient for the current milestone.
Back in the `AppComponent`, import the `RouterOutlet` token from the `@angular/router` package and the `slideInDownAnimation` from
Back in the `AppComponent`, import the `RouterOutlet` token from the `@angular/router` package and the `slideInAnimation` from
`'./animations.ts`.
Add an `animations` array to the `@Component` metadata's that contains the `slideInDownAnimation`.
Add an `animations` array to the `@Component` metadata's that contains the `slideInAnimation`.
<code-example path="router/src/app/app.component.2.ts" linenums="false" header="src/app/app.component.ts (animations)" region="animation-imports">

View File

@ -50,6 +50,9 @@ script will never be registered with the browser.
You can avoid that by waiting for the app to stabilize first, before starting to poll for updates
(as shown in the example above).
Note that this is true for any kind of polling done by your application.
Check the {@link ApplicationRef#isStable isStable} documentation for more information.
</div>
### Forcing update activation

View File

@ -301,7 +301,7 @@ an administrator ever needs to deactivate the service worker quickly.
### Fail-safe
To deactivate the service worker, remove or rename the
`ngsw-config.json` file. When the service worker's request
`ngsw.json` file. When the service worker's request
for `ngsw.json` returns a `404`, then the service worker
removes all of its caches and de-registers itself,
essentially self-destructing.

View File

@ -23,7 +23,7 @@ Just run the [`ng test`](cli/test) CLI command:
</code-example>
The `ng test` command builds the app in _watch mode_,
and launches the [karma test runner](https://karma-runner.github.io).
and launches the [Karma test runner](https://karma-runner.github.io).
The console output looks a bit like this:
@ -55,15 +55,15 @@ The tests run again, the browser refreshes, and the new test results appear.
#### Configuration
The CLI takes care of Jasmine and karma configuration for you.
The CLI takes care of Jasmine and Karma configuration for you.
You can fine-tune many options by editing the `karma.conf.js` and
the `test.ts` files in the `src/` folder.
The `karma.conf.js` file is a partial karma configuration file.
The `karma.conf.js` file is a partial Karma configuration file.
The CLI constructs the full runtime configuration in memory, based on application structure specified in the `angular.json` file, supplemented by `karma.conf.js`.
Search the web for more details about Jasmine and karma configuration.
Search the web for more details about Jasmine and Karma configuration.
#### Other test frameworks
@ -428,7 +428,7 @@ to extract the setup variables that it needs.
Many developers feel this approach is cleaner and more explicit than the
traditional `beforeEach()` style.
Although this testing guide follows the tradition style and
Although this testing guide follows the traditional style and
the default [CLI schematics](https://github.com/angular/angular-cli)
generate test files with `beforeEach()` and `TestBed`,
feel free to adopt _this alternative approach_ in your own projects.
@ -2650,10 +2650,10 @@ It takes two arguments: the component type to override (`HeroDetailComponent`) a
The [override metadata object](#metadata-override-object) is a generic defined as follows:
<code-example format="." language="javascript">
type MetadataOverride<T> = {
add?: Partial<T>;
remove?: Partial<T>;
set?: Partial<T>;
type MetadataOverride&lt;T&gt; = {
add?: Partial&lt;T&gt;;
remove?: Partial&lt;T&gt;;
set?: Partial&lt;T&gt;;
};
</code-example>
@ -2816,7 +2816,7 @@ Consider adding component tests such as this one:
Debug specs in the browser in the same way that you debug an application.
1. Reveal the karma browser window (hidden earlier).
1. Reveal the Karma browser window (hidden earlier).
1. Click the **DEBUG** button; it opens a new browser tab and re-runs the tests.
1. Open the browser's “Developer Tools” (`Ctrl-Shift-I` on windows; `Command-Option-I` in OSX).
1. Pick the "sources" section.
@ -3008,10 +3008,10 @@ appropriate to the method, that is, the parameter of an `@NgModule`,
`@Component`, `@Directive`, or `@Pipe`.
<code-example format="." language="javascript">
type MetadataOverride<T> = {
add?: Partial<T>;
remove?: Partial<T>;
set?: Partial<T>;
type MetadataOverride&lt;T&gt; = {
add?: Partial&lt;T&gt;;
remove?: Partial&lt;T&gt;;
set?: Partial&lt;T&gt;;
};
</code-example>

View File

@ -34,7 +34,21 @@ For details about `tsconfig.json`, see the official
The [Setup](guide/setup) guide uses the following `tsconfig.json`:
<code-example path="quickstart/src/tsconfig.1.json" header="tsconfig.json" linenums="false"></code-example>
<code-example lang="json" header="tsconfig.json" linenums="false">
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "es2015", "dom" ],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}
</code-example>
This file contains options and flags that are essential for Angular applications.

View File

@ -17,9 +17,6 @@ For an example, see [Angular Material](https://material.angular.io/) docs.
Library packages often include typings in `.d.ts` files; see examples in `node_modules/@angular/material`. If your library's package does not include typings and your IDE complains, you may need to install the library's associated `@types/<lib_name>` package.
To configure a library that does not include typings in the same package, install the related `@types` package with npm.
TypeScript looks for types in the `node_modules/@types` folder by default, so you don't have to add each type package individually.
For example, suppose you have a library named `d3`:
<code-example format="." language="bash">
@ -27,15 +24,8 @@ npm install d3 --save
npm install @types/d3 --save-dev
</code-example>
Types defined in the library need to be added to the TypeScript configuration for the project that uses it.
* Add the library to the "types" array in `src/tsconfig.app.json`.
```
"types":[
"d3"
]
```
Types defined in a `@types/` package for a library installed into the workspace are automatically added to the TypeScript configuration for the project that uses that library.
TypeScript looks for types in the `node_modules/@types` folder by default, so you don't have to add each type package individually.
If a library doesn't have typings available at `@types/`, you can still use it by manually adding typings for it.
To do this:

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -21,10 +21,10 @@
"linkUrl": "https://angularmix.com/"
},
{
"startDate": "2018-08-15",
"endDate": "2018-11-06",
"message": "Join us for Angular Connect<br/>November 6th-7th, 2018",
"startDate": "2019-05-03",
"endDate": "2019-09-18",
"message": "Join us for Angular Connect<br/>September 19th-20th, 2019",
"imageUrl": "generated/images/marketing/home/angular-connect.png",
"linkUrl": "https://angularconnect.com/"
"linkUrl": "https://www.angularconnect.com/?utm_source=angular.io&utm_medium=referral"
}
]

View File

@ -7,7 +7,6 @@
"bio": "Miško Hevery is the creator of AngularJS framework. He has passion for making complex things simple. He currently works at Google, but has previously worked at Adobe, Sun Microsystems, Intel, and Xerox, where he became an expert in building web applications in web related technologies such as Java, JavaScript, Flex and ActionScript.",
"group": "Angular"
},
"igor": {
"name": "Igor Minar",
"picture": "igor-minar.jpg",
@ -16,7 +15,6 @@
"bio": "Igor is a software engineer at Google. He is a lead on the Angular project, practitioner of test driven development, open source enthusiast, hacker. In his free time, Igor enjoys spending time with his wife and two kids, doing outdoor activities (including but not limited to sports, gardening and building retaining walls).",
"group": "Angular"
},
"naomi": {
"name": "Naomi Black",
"picture": "naomi.jpg",
@ -25,7 +23,6 @@
"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.",
"group": "Angular"
},
"brad": {
"name": "Brad Green",
"picture": "brad-green.jpg",
@ -34,7 +31,6 @@
"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.",
"group": "Angular"
},
"juleskremer": {
"name": "Jules Kremer",
"picture": "juleskremer.jpg",
@ -43,7 +39,6 @@
"bio": "Jules is Head of Angular Developer Relations at Google. When not working with developers, Jules is often bending into pretzel-like shapes, creating paths through thick jungle with a machete or drinking really awesome beer.",
"group": "Angular"
},
"jelbourn": {
"name": "Jeremy Elbourn",
"picture": "jelbourn.jpg",
@ -52,7 +47,6 @@
"bio": "Angular Material Team Lead. FE Engineer @ Google specializing in AngularJS, component design, and the cleanest of code.",
"group": "Angular"
},
"pete": {
"name": "Pete Bacon Darwin",
"picture": "pete.jpg",
@ -61,7 +55,6 @@
"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.",
"group": "Angular"
},
"stephenfluin": {
"name": "Stephen Fluin",
"picture": "stephenfluin.jpg",
@ -70,7 +63,6 @@
"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.",
"group": "Angular"
},
"robwormald": {
"name": "Rob Wormald",
"picture": "rob-wormald.jpg",
@ -79,7 +71,6 @@
"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.",
"group": "Angular"
},
"tobias": {
"name": "Tobias Bosch",
"picture": "tobias.jpg",
@ -88,7 +79,6 @@
"bio": "Tobias Bosch is a software engineer at Google. He is part of the Angular core team and works on Angular.",
"group": "Angular"
},
"rado": {
"name": "Rado Kirov",
"picture": "rado.jpg",
@ -97,7 +87,6 @@
"bio": "Rado has been on the Angular Core team since Summer 2014. Before Angular, he worked on the Adsense serving stack, responsible for serving billions of ads daily. Being passionate about open source, he made contributions to Angular as a Google-20% project, before making the fulltime jump. He is a recovering academic; ask him about error-correcting codes from algebraic curves (or don't).",
"group": "Angular"
},
"alexeagle": {
"name": "Alex Eagle",
"picture": "alex-eagle.jpg",
@ -106,7 +95,6 @@
"bio": "Alex works on language tooling for JavaScript and TypeScript. Previously Alex spent five years in Google's developer testing tools. He has developed systems including Google's continuous integration service, capturing build&test failures, and explaining them to developers. Before Google, Alex worked at startups including Opower, and consulted for large government IT. In his 20% time, he created the Error-Prone static analysis tool, which detects common Java programming mistakes and reports them as compile errors.",
"group": "Angular"
},
"martinprobst": {
"name": "Martin Probst",
"picture": "martin-probst.jpg",
@ -115,7 +103,6 @@
"bio": "Martin is a software engineer at Google in the AngularJS team. He holds a MSc in Software Engineering from HPI in Potsdam, Germany. Before joining the AngularJS team at Google, he worked at a database startup in the Netherlands, at EMC, at SAP, and as a freelancer. In his free time, he likes to cook and sail, not necessarily at the same time.",
"group": "Angular"
},
"julieralph": {
"name": "Julie Ralph",
"picture": "julie-ralph.jpg",
@ -124,7 +111,6 @@
"bio": "Julie Ralph works as a Software Engineer in Test at Google in Seattle and is the lead developer on the Angular end-to-end testing framework Protractor.",
"group": "Angular"
},
"alexrickabaugh": {
"name": "Alex Rickabaugh",
"picture": "alex-rickabaugh.jpg",
@ -133,7 +119,6 @@
"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.",
"group": "Angular"
},
"matias": {
"name": "Matias Niemela",
"picture": "matias.jpg",
@ -142,7 +127,6 @@
"bio": "Matias Niemela is a fullstack web developer who has been programming & building websites for over 10 years, and a core team member of AngularJS for two years. In the spring of 2015 Matias joined Angular full time at Google. In his free time Matias loves to build complex things and is always up for public speaking, travelling and tweaking his current Vim setup.",
"group": "Angular"
},
"hansl": {
"name": "Hans Larsen",
"picture": "hansl.jpg",
@ -151,7 +135,6 @@
"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.",
"group": "Angular"
},
"kara": {
"name": "Kara Erickson",
"picture": "kara-erickson.jpg",
@ -160,7 +143,6 @@
"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.",
"group": "Angular"
},
"chuckj": {
"name": "Chuck Jazdzewski",
"picture": "chuckj.jpg",
@ -169,7 +151,6 @@
"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.",
"group": "Angular"
},
"vikram": {
"name": "Vikram Subramanian",
"picture": "vikram.jpg",
@ -177,7 +158,6 @@
"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.",
"group": "Angular"
},
"maxsills": {
"name": "Max Sills",
"picture": "max-sills.jpg",
@ -186,7 +166,6 @@
"bio": "Max Sills is Angular's Open Source lawyer.",
"group": "Angular"
},
"pawel": {
"name": "Pawel Kozlowski",
"picture": "pawel.jpg",
@ -194,7 +173,6 @@
"bio": "Open source hacker, AngularJS book author, AngularUI lead developer. Pawel is an software-development addict who believes in free, open source software. He is a core contributor to the AngularJS framework, AngularUI, Karma-runner and several other projects. He is the co-author of the \"Mastering Web Application Development with AngularJS\" book. When not coding, Pawel can be spotted speaking at various software development conferences.",
"group": "Angular"
},
"paulgschwendtner": {
"name": "Paul Gschwendtner",
"picture": "devversion.jpg",
@ -203,7 +181,6 @@
"bio": "Paul is a 17-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.",
"group": "Angular"
},
"elad": {
"name": "Elad Bezalel",
"picture": "eladbezalel.jpg",
@ -211,7 +188,6 @@
"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.",
"group": "Angular"
},
"marclaval": {
"name": "Marc Laval",
"picture": "marclaval.jpg",
@ -220,7 +196,6 @@
"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.",
"group": "Angular"
},
"wardbell": {
"name": "Ward Bell",
"picture": "wardbell.jpg",
@ -229,7 +204,6 @@
"bio": "Ward is an all-around developer with JavaScript, Node.js®, 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.",
"group": "Angular"
},
"martinstaffa": {
"name": "Martin Staffa",
"picture": "martinstaffa.jpg",
@ -237,7 +211,6 @@
"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.",
"group": "Angular"
},
"filipesilva": {
"name": "Filipe Silva",
"picture": "filipe-silva.jpg",
@ -246,7 +219,6 @@
"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.",
"group": "Angular"
},
"andrewseguin": {
"name": "Andrew Seguin",
"picture": "andrewseguin.jpg",
@ -254,7 +226,6 @@
"bio": "Andrew is an engineer on the Angular Material team working on bringing material components to the world. When hes not obsessing over pixels and design, he is probably off somewhere having adventures with his wife and daughters.",
"group": "Angular"
},
"jesusrodriguez": {
"name": "Jesús Rodríguez",
"picture": "jesus-rodriguez.jpg",
@ -263,7 +234,6 @@
"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.",
"group": "Angular"
},
"crisbeto": {
"name": "Kristiyan Kostadinov",
"picture": "crisbeto.jpg",
@ -271,7 +241,6 @@
"bio": "Kristiyan is a front-end developer, passionate open-source contributor and a core team member on Angular Material.",
"group": "Angular"
},
"gkalpak": {
"name": "Georgios Kalpakas",
"picture": "gkalpak.jpg",
@ -286,14 +255,12 @@
"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.",
"group": "Angular"
},
"jasonaden": {
"name": "Jason Aden",
"picture": "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.).",
"group": "Angular"
},
"jeffwhelpley": {
"name": "Jeff Whelpley",
"picture": "jeffwhelpley.jpg",
@ -302,7 +269,6 @@
"bio": "Jeff Whelpley is a Google Developer Expert and the CTO of GetHuman. He is the co-organizer of the Angular Boston meetup group, co-creator of Angular Universal, former host of AngularAir and frequent speaker at Angular events.",
"group": "GDE"
},
"pascalprecht": {
"name": "Pascal Precht",
"picture": "pascalprecht.jpg",
@ -310,7 +276,6 @@
"bio": "Pascal is a software engineer, author and Google Developer Expert for the Angular team. He loves contributing to open source and is the creator of the popular angular-translate module. In his spare time hes fiddling with EDM production.",
"group": "GDE"
},
"deborah": {
"name": "Deborah Kurata",
"picture": "deborah.jpg",
@ -319,7 +284,6 @@
"bio": "Deborah is a software developer, author, and Google Developer Expert. She is author of several Pluralsight courses including: 'Angular 2: Getting Started' and Angular Routing",
"group": "GDE"
},
"alyssa": {
"name": "Alyssa Nicoll",
"picture": "mickey_mouse.jpg",
@ -328,7 +292,6 @@
"bio": "I am an energetic, über passionate GDE and Web Dev. I have some Front-End and Angular courses on Egghead.io and Code School. I love to learn new things and share them with others. I Scuba Dive and have a toothless dog named 'Gummy'. My DM is always open, come talk sometime.",
"group": "GDE"
},
"ralph": {
"name": "Ralph Wang",
"picture": "ralph.jpg",
@ -336,7 +299,6 @@
"bio": "Ralph(Zhicheng Wang) is a senior consultant at ThoughtWorks 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 immersed in the excitement of the arrival of the baby.",
"group": "GDE"
},
"wassim": {
"name": "Wassim Chegham",
"picture": "wassim.jpg",
@ -345,7 +307,6 @@
"bio": "Wassim (aka manekinekko on Twitter/Github) is a Developer Advocate at SFEIR, in Web technologies (Angular, Polymer, PWA, Web Components...). He is also a Developer Expert in Web technologies nominated by Google. He enjoys writing technical articles, meeting developers at events, speaking at conferences and contributing to open source projects. Wassim loves the Web Platform and works hard to move it forward.",
"group": "GDE"
},
"chrisnoring": {
"name": "Christoffer Noring",
"picture": "chrisnoring.jpg",
@ -354,7 +315,6 @@
"bio": "Chris is a Full Stack Developer at McKinsey. A Google Developer Expert in Web Technologies and Angular. He is also a Nativescript Developer Expert. He is one of the organizers of the Angular conference ngVikings and an author of the book RxJS 5 Ultimate",
"group": "GDE"
},
"jorgeucano": {
"name": "Jorge Cano",
"picture": "jorgeucano.jpg",
@ -363,7 +323,6 @@
"bio": "Jorge is a Full Stack Developer in ByteDefault, a professor for several courses related to JavaScript, a speaker, and an author of technical articles and the book \"Entendiendo Angular.\" He is a Google Developer Expert in web technologies (nominated by Google) and a NativeScript Developer Expert (nominated by Telerik).",
"group": "GDE"
},
"toddmotto": {
"name": "Todd Motto",
"picture": "toddmotto.jpg",
@ -372,7 +331,6 @@
"bio": "Owner and trainer at Ultimate Angular. Lives in England, UK. Has a love for teaching, OSS and speaking at conferences. Google Developer Expert for Web Technologies and Angular.",
"group": "GDE"
},
"michaelprentice": {
"name": "Michael Prentice",
"picture": "michaelprentice.jpg",
@ -381,7 +339,6 @@
"bio": "Lead for AngularJS Material. Owner and consultant at DevIntent. Ex-Angular GDE. Founder of the Google Developers Group (GDG) community on the Space Coast of Florida, USA.",
"group": "Angular"
},
"mikebrocchi": {
"name": "Mike Brocchi",
"picture": "mike-brocchi.jpg",
@ -389,7 +346,6 @@
"bio": "Mike is a core team member of the Angular CLI team, a GDE and is also an instructor at egghead. Mike is passionate about helping others by writing code as well as teaching.",
"group": "Angular"
},
"manfredsteyer": {
"name": "Manfred Steyer",
"picture": "steyer.jpg",
@ -398,7 +354,6 @@
"bio": "Trainer and Consultant with focus on Angular. Writes for O'Reilly, the German Java Magazine and Heise. Regularly speaks at conferences.",
"group": "GDE"
},
"maximsalnikov": {
"name": "Maxim Salnikov",
"picture": "maximsalnikov.jpg",
@ -407,7 +362,6 @@
"bio": "Oslo-based web front-end engineer, a Google Developer Expert in Angular, Web technologies and IoT. Active public speaker & trainer for the developer events. Leader of Norways largest meetups dedicated to web front-end and mobile development. Founder of ngVikings and Mobile Era conferences. Progressive Web Apps advocate.",
"group": "GDE"
},
"jeremywilken": {
"name": "Jeremy Wilken",
"picture": "jeremywilken.jpg",
@ -416,7 +370,6 @@
"bio": "Based in Austin Texas, Jeremy is an application architect and homebrewer. He is a Google Developer Expert in Web Technologies and Angular, with a focus on speaking and training and author of Angular in Action and Ionic in Action.",
"group": "GDE"
},
"minko": {
"name": "Minko Gechev",
"picture": "minko.jpg",
@ -425,7 +378,6 @@
"bio": "Software engineer who enjoys theoretical computer science and its practical applications. Speaker, author of the book 'Switching to Angular', codelyzer, Guess.js, and the Go linter revive. Working for faster and more reliable software.",
"group": "Angular"
},
"uri": {
"name": "Uri Shaked",
"picture": "urish.jpg",
@ -434,7 +386,6 @@
"bio": "Uri Shaked is a Google Developer Expert for Web Technologies. He regularly writes about Web and IoT related technologies in his medium blog, and speaks about these topics in conferences and meetup around the world. Among his interests are reverse engineering, hardware hacking, building 3d-printed robots and games, playing music and Salsa dancing.",
"group": "GDE"
},
"eusoj": {
"name": "Josue Gutierrez",
"picture": "josue.jpg",
@ -443,7 +394,6 @@
"bio": "Based in Mexico, Josue has been web developer since the last 10 years, he is part of the Google Developer Expert Program, passionate about teaching and building communities",
"group": "GDE"
},
"SanderElias": {
"name": "Sander Elias",
"picture": "sanderelias.jpg",
@ -452,7 +402,6 @@
"bio": "Sander is a versed developer with over 4 decades of practice under his belt. He is also an Google Developer Expert for web, specializing in Angular. Organizer of meetups and conferences. Helping out others wherever he can. When he is not breathing code, he is fiddling around with IOT, photography, science and anything that might vaguely is gadget-like! Thinks he a master of the grill, but in reality you probably don't get a food-poisoning ;) Also, and actually the most important thing to him, he is a father of 4, and has the most patient girlfriend in the universe.",
"group": "GDE"
},
"filipbech": {
"name": "Filip Bruun Bech-Larsen",
"picture": "filipbech.jpg",
@ -461,7 +410,6 @@
"bio": "Filip is a Frontend developer from Denmark. He works at IMPACT, delivering large-scale, high-performance e-commerce to international clients - most often build in Angular. He runs the local Angular usergroup - ngAarhus, and gives talks/workshops around and beyond the country of Denmark.",
"group": "GDE"
},
"ocombe": {
"name": "Olivier Combe",
"picture": "ocombe.jpg",
@ -469,7 +417,6 @@
"bio": "Olivier is a passionate front-end engineer who loves interacting with the community by doing open source projects (ocLazyLoad, ngx-translate…), being a panelist at Angular-Air, giving talks or just chatting on Twitter and Slack. Hes a member of the Angular Core team and works on i18n.",
"group": "Angular"
},
"cironunes": {
"name": "Ciro Nunes",
"picture": "cironunes.jpg",
@ -477,7 +424,6 @@
"bio": "Ciro is the Lead Front-end Engineer of CrossEngage and Google Developer Expert in Web Technologies.",
"group": "GDE"
},
"elecash": {
"name": "Raúl Jiménez",
"picture": "raul.jpg",
@ -485,7 +431,6 @@
"bio": "Raul works as a CEO and Front-end Architect at Byte Default for companies around the world helping them to build high-performance web apps. In his spare time he's usually working on Videogular, involved in local meetups, speaking at conferences and contributing to open source projects.",
"group": "GDE"
},
"simpulton": {
"name": "Lukas Ruebbelke",
"picture": "lukas.jpg",
@ -493,7 +438,6 @@
"bio": "Developer. Hacker. Community backer. Author and blogger. Console logger.",
"group": "GDE"
},
"christianweyer": {
"name": "Christian Weyer",
"picture": "christianweyer.jpg",
@ -502,7 +446,6 @@
"bio": "Co-founder and CTO of Thinktecture AG, as well as Google GDE and Microsoft MVP. Since two decades active as an engaged and passionate speaker on several software conferences and events all over the world. Some people call him 'Mr. Cross-Platform'.",
"group": "GDE"
},
"shaireznik": {
"name": "Shai Reznik",
"picture": "shaireznik.jpg",
@ -511,7 +454,6 @@
"bio": "Teaches Angular at HiRez.io the most entertaining online courses on the web. An experienced developer, consultant and speaker also known for his unusual crazy Angular talks such as ng-wat, ng-show, ng-rap, etc. Shai is also the organizer of the largest JavaScript group in Israel and a professional Improv performer.",
"group": "GDE"
},
"danwahlin": {
"name": "Dan Wahlin",
"picture": "danwahlin.jpg",
@ -520,7 +462,6 @@
"bio": "Dan Wahlin founded Wahlin Consulting which provides consulting and onsite/online training services on Web technologies such as JavaScript, Angular, TypeScript, Node.js, C#, ASP.NET Core, Web API, and Docker. Hes also published many developer courses on Pluralsight.com and Udemy.com. Dan is a Google GDE, Docker Captain, and Microsoft MVP and Regional Director and speaks at conferences and user groups around the world. Dan has written several books on Web technologies, hundreds of technical articles and blog posts (https://blog.codewithdan.com) and runs the 'Code with Dan Web Weekly Newsletter' - a great way to stay up on the latest technologies. Follow Dan on Twitter @DanWahlin.",
"group": "GDE"
},
"joeeames": {
"name": "Joe Eames",
"picture": "joeeames.jpg",
@ -529,7 +470,6 @@
"bio": "Joe Eames is a developer and educator. He publishes course on Angular and JavaScript on Pluralsight.com. He is an organizer of ng-conf, a Google Developer Expert in Angular, gives lots of talks & workshops, and loves all things web.",
"group": "GDE"
},
"willmendesneto": {
"name": "Wilson Mendes",
"picture": "willmendesneto.jpg",
@ -538,7 +478,6 @@
"bio": "GDE (Google Developer Expert) Angular and Web Technologies, GDG Salvador organizer, passionate about technology and active in communities with a focus on web development, including Angular, JavaScript, HTML5, CSS3, Workflow, web performance, security and Internet of things. Participates in events organization, speaker at conferences in Brazil and other countries and contributes to several open source projects.",
"group": "GDE"
},
"jecelynyeen": {
"name": "Jecelyn Yeen",
"picture": "jecelynyeen.jpg",
@ -547,7 +486,6 @@
"bio": "GDE (Google Developer Expert) Angular and Web Technologies, Women Who Code KL Director, Jecelyn specializes in professional application development with technologies, including Angular, HTML5, Typescript, JavaScript, CSS, C#, NodeJs, Cloud and ASP.NET.",
"group": "GDE"
},
"vincirufus": {
"name": "Vinci Rufus",
"picture": "vincirufus.jpg",
@ -556,7 +494,6 @@
"bio": "Director of Experience Technology at SapientRazorfish. Consults various brands on their frontend and mobile web architecture. A speaker at various forums and mentor at Launchpad Accelerator and ngGirls India. Spends free time playing with Angular, Preact, web-components ",
"group": "GDE"
},
"thierrychatel": {
"name": "Thierry Chatel",
"picture": "thierrychatel.jpg",
@ -565,7 +502,6 @@
"bio": "Thierry is a senior consultant and trainer, specialized on Angular, and a Google Developer Expert.",
"group": "GDE"
},
"gerardsans": {
"name": "Gerard Sans",
"picture": "gerardsans.jpg",
@ -574,7 +510,6 @@
"bio": "Gerard is very excited about the future of the Web and JavaScript. Always happy Computer Science Engineer and humble Google Developer Expert. He loves to share his learnings by giving talks, trainings and writing about cool technologies. He loves running AngularZone and GraphQL London, mentoring students and giving back to the community.",
"group": "GDE"
},
"amcdnl": {
"name": "Austin McDaniel",
"picture": "amcdnl.jpeg",
@ -583,7 +518,6 @@
"bio": "Austin is an software architect with a passion for JavaScript and Angular. Austin loves to share his experiences with other like-minded developers by giving talks, blogging, podcasting and open-sourcing.",
"group": "Angular"
},
"nirkaufman": {
"name": "Nir Kaufman",
"picture": "nirkaufman.jpg",
@ -592,7 +526,6 @@
"bio": "Nir is a Principal Frontend Consultant & Head of the Angular department at 500Tech, Google Developer Expert and community leader. He organizes the largest Angular meetup group in Israel (Angular-IL), talks and teaches about front-end technologies around the world. He is also the author of two books about Angular and the founder of the 'Frontend Band'.",
"group": "GDE"
},
"achautard": {
"name": "Alain Chautard",
"picture": "alainchautard.png",
@ -601,7 +534,6 @@
"bio": "Alain Chautard is a Google Developer Expert in Web Technologies / Angular. He started working with Angular JS in 2011. Since then he has worked with all Angular versions on a daily basis, both as a developer and as a technical trainer. He is the organizer of the Sacramento Angular Meetup group, co-organizer of the Google Developer Group chapter in Sacramento, California, and published author of the Packt video course 'Getting Started with Angular'",
"group": "GDE"
},
"coryrylan": {
"name": "Cory Rylan",
"picture": "cory-rylan.jpg",
@ -610,7 +542,6 @@
"bio": "Cory is a full time front end web developer. He works full time building responsive web applications and progressive web apps. When not building web apps he is busy teaching Angular and other web technologies in workshops and conferences. He loves the web and is optimistic of the places it can take us.",
"group": "GDE"
},
"mhartington": {
"name": "Mike Hartington",
"picture": "mhartington.png",
@ -619,7 +550,6 @@
"bio": "Mike is a Developer Advocate for the Ionic Framework and a GDE in Angular. He spends most of his time making fast PWAs and exploring emerging web standards. When not behind a keyboard, you'll probably find him with a guitar and beer.",
"group": "GDE"
},
"juristr": {
"name": "Juri Strumpflohner",
"picture": "juristr.jpg",
@ -628,7 +558,6 @@
"bio": "Juri is a software engineer and freelance trainer and consultant currently mostly focusing on the frontend side using JavaScript, TypeScript and Angular. He has a passion for teaching and sharing his knowledge and experiences with others. This mostly happens by writing tech articles for his personal blog, by creating video courses for Egghead.io, during on-site workshops at companies or by speaking at conferences. In his free time he enjoys practicing Yoseikan Budo, a martial art where he currently owns the 3rd DAN black belt.",
"group": "GDE"
},
"mashhoodr": {
"name": "Mashhood Rastgar",
"picture": "mashhood.jpg",
@ -637,7 +566,6 @@
"bio": "Mashhood is the principal technical consultant at Recurship and a Google Developer Expert. He works with different startups in US and EU to helps them crawl through the technical maze and quickly build amazing products focused around the problems they are trying to solve. He specializes in using the latest web technologies available to execute the best possible solutions.",
"group": "GDE"
},
"kimmaida": {
"name": "Kim Maida",
"picture": "kimmaida.jpg",
@ -646,7 +574,6 @@
"bio": "Kim is an an Angular consultant, developer, speaker, writer, and Google Developer Expert. She is passionate about learning from and sharing knowledge with other developers through blogging, speaking, workshops, and open source.",
"group": "GDE"
},
"elanaolson": {
"name": "Elana Olson",
"picture": "elanaolson.jpg",
@ -654,7 +581,6 @@
"bio": "Elana is a Developer Relations intern on the Angular team at Google. She is working on migration paths from AngularJS to Angular and would love to chat about your experience with upgrading.",
"group": "Angular"
},
"kevinyang": {
"name": "Kevin Yang",
"picture": "kevinyang.jpg",
@ -663,7 +589,6 @@
"bio": "Kevin is a Angular Taiwan, Angular Girls Taiwan community organzier. He loves sharing knowledge with other developers through blogging, speaking, workshops.",
"group": "GDE"
},
"sajee": {
"name": "Sajeetharan Sinnathurai",
"picture": "sajee.jpg",
@ -672,7 +597,6 @@
"bio": "Sajeetharan is a Developer, Top contributor on stackoverflow for #Angular, ng-SriLanka organizer. He makes use of his extensive knowledge over the past years to contribute to community to make the world a better place.",
"group": "GDE"
},
"lacolaco": {
"name": "Suguru Inatomi",
"picture": "lacolaco.jpg",
@ -681,7 +605,6 @@
"bio": "Suguru is a community-loving Frontend developer and a lead of Angular Japan User Group. He organizes the largest Angular event in Japan (ng-japan). And he is a contributor to Angular by sending patches, writing, speaking, and localizing resources in Japanese.",
"group": "GDE"
},
"katerina": {
"name": "Katerina Skroumpelou",
"picture": "katerina.jpg",
@ -690,7 +613,6 @@
"bio": "Katerina is a front end software engineer, a conference speaker and AngularAthens meetup organizer. She is obsessed with sharing knowledge about things she loves. She is also trying to support diversity in the community. She lives with her cat in Athens.",
"group": "GDE"
},
"blove": {
"name": "Brian Love",
"picture": "brian-love.jpg",
@ -706,5 +628,36 @@
"website": "https://nrwl.io/",
"bio": "Jeff is an Angular Consultant at nrwl.io where he helps enterprise teams succeed with Angular. Prior to founding Nrwl, Jeff was one of the earliest members of the Angular Core Team at Google, and contributed to many of the early state management and performance efforts of AngularJS and Angular.",
"group": "GDE"
},
"keilla": {
"name": "Keilla Menezes Fernandes",
"picture": "keilla.jpg",
"twitter": "keillamenezes_",
"bio": "I am Senior Software Development Consultant in ThoughtWorks and GDE in Angular. Graduated in Computer Science from Federal University of Bahia, I have been worked with software development for more than 11 years. Since 2017, I started with Angular Framework and I went deep into front-end ecosystem and became more specialized in this area. I participate in a computer science community, Campinas Front-end, that promotes events in this area. In the end of 2016, I started to do technical talks. The passion for science is the engine that drives me to seek answers to the problems that computing aims to solve. Besides that, sharing knowledge and experiences is the path I choose to democratize the technology for all.",
"group": "GDE"
},
"mira": {
"name": "Stanimira Vlaeva",
"picture": "mira.jpg",
"twitter": "StanimiraVlaeva",
"website": "https://github.com/sis0k0",
"bio": "Software engineer on the NativeScript team at Progress, focused on NativeScript Angular, NativeScript schematics, and integrating webpack in the {N} build system. Co-organizing the Angular Sofia meetup. Speaking about Angular things at conferences here and there.",
"group": "GDE"
},
"sharondio": {
"name": "Sharon DiOrio",
"picture": "sharon.jpg",
"twitter": "sharondio",
"website": "https://medium.com/@sharondio",
"bio": "Sharon is a mother to four teenagers, wife of a USMC veteran/police officer, and lead front-end engineer for an educational non-profit in Boston. In her spare time, she is the \"Head Instigator\" of the Angular-Boston Meetup and an active member of the Boston meetups community. She occasionally speaks on Angular and related topics at technology conferences across the country. She has a Bachelor of Fine Arts from SMU and a Masters with honors from RTFM.",
"group": "GDE"
},
"leonardozizzamia": {
"name": "Leonardo Zizzamia",
"picture": "leonardo.jpg",
"twitter": "zizzamia",
"website": "https://medium.com/@zizzamia",
"bio": "Leonardo is a Senior Software Engineer at Coinbase. He is deeply passionate about web performance and most recently developed Perfume.js to help companies prioritize roadmaps and business, through performance analytics. From 2018, co-organizer of the Angular San Francisco Meetup group and NGRome Conference.",
"group": "GDE"
}
}
}

View File

@ -13,17 +13,23 @@
</tr>
</thead>
<tbody>
<!-- ngAtlanta 2019 -->
<!-- ng-conf 2019-->
<tr>
<th><a href="https://ng-atl.org/" title="ngAtlanta">ngAtlanta</a></th>
<td>Atlanta, Georgia</td>
<td>January 9 - 12, 2019</td>
<th><a href="https://ng-conf.org/" title="ng-conf">ng-conf</a></th>
<td>Salt Lake City, Utah</td>
<td>May 1-3, 2019</td>
</tr>
<!-- ng-India 2019-->
<!-- ngVikings 2019-->
<tr>
<th><a href="https://www.ng-ind.com/" title="ng-India">ng-India</a></th>
<td>Gurgaon, India</td>
<td>February 23, 2019</td>
<th><a href="https://ngvikings.org/" title="ngVikings">ngVikings</a></th>
<td>Copenhagen, Denmark</td>
<td>May 26 (workshops), 27-28 (conference), 2019</td>
</tr>
<!-- AngularConnect 2019-->
<tr>
<th><a href="https://www.angularconnect.com/?utm_source=angular.io&utm_medium=referral" title="AngularConnect">AngularConnect</a></th>
<td>London, UK</td>
<td>September 19-20, 2019</td>
</tr>
</tbody>
</table>
@ -38,18 +44,30 @@
</tr>
</thead>
<tbody>
<!-- ng-India 2019-->
<tr>
<th><a href="https://www.ng-ind.com/" title="ng-India">ng-India</a></th>
<td>Gurgaon, India</td>
<td>February 23, 2019</td>
</tr>
<!-- ngAtlanta 2019 -->
<tr>
<th><a href="https://ng-atl.org/" title="ngAtlanta">ngAtlanta</a></th>
<td>Atlanta, Georgia</td>
<td>January 9-12, 2019</td>
</tr>
<!-- AngularConnect-->
<tr>
<th><a href="https://past.angularconnect.com/2018" title="AngularConnect">AngularConnect</a></th>
<td>London, United Kingdom</td>
<td>November 5-7, 2018</td>
</tr>
<!-- ReactiveConf -->
<tr>
<th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th>
<td>Prague, Czech Republic</td>
<td>October 29-31, 2018</td>
</tr>
<!-- AngularConnect-->
<tr>
<th><a href="http://angularconnect.com" title="AngularConnect">AngularConnect</a></th>
<td>London, United Kingdom</td>
<td>November 5-7, 2018</td>
</tr>
<!-- AngularMix -->
<tr>
<th><a href="https://angularmix.com/" title="AngularMix">AngularMix</a></th>

View File

@ -65,6 +65,13 @@
"title": "AngularAir",
"url": "https://angularair.com/"
},
"sdlkfjsldfkz": {
"desc": "A weekly German podcast for Angular on the go",
"logo": "",
"rev": true,
"title": "Happy Angular Podcast",
"url": "https://happy-angular.de/"
},
"sldkfjsldjf": {
"desc": "The live broadcast podcast all about JavaScript",
"logo": "",
@ -408,6 +415,12 @@
"rev": true,
"title": "ag-Grid",
"url": "https://www.ag-grid.com/best-angular-2-data-grid/"
},
"fancygrid": {
"desc": "Angular grid library with charts integration and server communication for Enterprise.",
"rev": true,
"title": "FancyGrid",
"url": "https://fancygrid.com/docs/getting-started/angular"
},
"jqwidgets": {
"desc": "Angular UI Components including data grid, tree grid, pivot grid, scheduler, charts, editors and other multi-purpose components",
@ -459,6 +472,12 @@
"rev": true,
"title": "Alyle UI",
"url": "https://alyle-ui.firebaseapp.com/"
},
"nebular": {
"desc": "Theme System, UI Components, Auth and Security for your next Angular application.",
"rev": true,
"title": "Nebular",
"url": "https://akveo.github.io/nebular/"
}
}
}
@ -812,6 +831,12 @@
"title": "Formation JavaScript (French)",
"url": "https://formationjavascript.com/formation-angular/"
},
"humancoders-angular": {
"desc": "Angular trainings delivered by Human Coders (France)",
"rev": true,
"title": "Formation Angular (French)",
"url": "https://www.humancoders.com/formations/angular"
},
"wao": {
"desc": "Onsite Angular Training delivered by We Are One Sàrl in Switzerland",
"logo": "https://weareone.ch/wordpress/wao-content/uploads/2014/12/logo_200_2x.png",

View File

@ -13,7 +13,7 @@ Using the Angular CLI, generate a new component named `heroes`.
</code-example>
The CLI creates a new folder, `src/app/heroes/`, and generates
the three files of the `HeroesComponent`.
the four files of the `HeroesComponent`.
The `HeroesComponent` class file is as follows:

View File

@ -120,12 +120,25 @@
],
"headers": [
{
"source": "/",
// All paths (URLs without a file extension).
"source": "**/!(*.*)",
"headers": [
{
"key": "Link",
"value": "</generated/navigation.json>;rel=preload;as=fetch,</generated/docs/index.json>;rel=preload;as=fetch"
}
{"key": "Cache-Control", "value": "no-cache"},
{"key": "Link", "value": "</generated/navigation.json>;rel=preload;as=fetch,</generated/docs/index.json>;rel=preload;as=fetch"}
]
},
{
// Images, fonts, (non-hashed) CSS/JS files.
"source": "**/*.@(gif|jpg|jpeg|png|svg|webp|js|css|eot|otf|ttf|ttc|woff|woff2)",
"headers": [
{"key": "Cache-Control", "value": "max-age=86400"} // 1 day
]
},
{
// Hashed CSS/JS files...
"source": "**/*.+([0-9a-f]).@(css|js)",
"headers": [
{"key": "Cache-Control", "value": "max-age=2592000"} // 30 days
]
}
]

View File

@ -17,7 +17,7 @@
"build": "yarn ~~build",
"prebuild-local": "yarn setup-local",
"build-local": "yarn ~~build",
"prebuild-with-ivy": "yarn setup-local && yarn ivy-ngcc",
"prebuild-with-ivy": "yarn setup-local && yarn ivy-ngcc --formats fesm2015 fesm5",
"build-with-ivy": "node scripts/build-with-ivy",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js b5e796a03",
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
@ -57,6 +57,7 @@
"preserve-and-sync": "yarn docs",
"serve-and-sync": "run-p \"start\" \"docs-watch --watch-only\"",
"boilerplate:add": "node ./tools/examples/example-boilerplate add",
"boilerplate:add:ivy": "yarn boilerplate:add --ivy",
"boilerplate:remove": "node ./tools/examples/example-boilerplate remove",
"boilerplate:test": "node tools/examples/test.js",
"generate-stackblitz": "node ./tools/stackblitz-builder/generateStackblitz",
@ -73,7 +74,7 @@
},
"engines": {
"node": ">=10.9.0 <11.0.0",
"yarn": ">=1.10.1 <1.14.0"
"yarn": ">=1.12.1 <=1.14.0"
},
"private": true,
"dependencies": {
@ -104,6 +105,7 @@
"@types/jasmine": "^2.5.52",
"@types/jasminewd2": "^2.0.4",
"@types/node": "~6.0.60",
"@yarnpkg/lockfile": "^1.1.0",
"archiver": "^1.3.0",
"canonical-path": "1.0.0",
"chalk": "^2.1.0",
@ -166,4 +168,4 @@
"xregexp": "^4.0.0",
"yargs": "^7.0.2"
}
}
}

View File

@ -6,15 +6,11 @@
<mat-toolbar color="primary" class="app-toolbar no-print" [class.transitioning]="isTransitioning">
<mat-toolbar-row class="notification-container">
<aio-notification
notificationId="angular-v6-announcement"
expirationDate="2018-07-01"
[dismissOnContentClick]="true"
(dismissed)="notificationDismissed()">
<a href="https://blog.angular.io/version-6-0-0-of-angular-now-available-cc56b0efa7a4">
<aio-notification notificationId="survey-february-2019" expirationDate="2019-03-01" [dismissOnContentClick]="true" (dismissed)="notificationDismissed()">
<a href="http://bit.ly/angular-survey-2019">
<mat-icon class="icon" svgIcon="insert_comment" aria-label="Announcement"></mat-icon>
<span class="message">Version 6 of Angular Now Available!</span>
<span class="action-button">Learn More</span>
<span class="message">Help Angular by taking a <b>1 minute survey</b>!</span>
<span class="action-button">Go to survey</span>
</a>
</aio-notification>
</mat-toolbar-row>
@ -54,12 +50,7 @@
<main class="sidenav-content" [id]="pageId" role="main">
<aio-mode-banner [mode]="deployment.mode" [version]="versionInfo"></aio-mode-banner>
<aio-doc-viewer [class.no-animations]="isStarting"
[doc]="currentDocument"
(docReady)="onDocReady()"
(docRemoved)="onDocRemoved()"
(docInserted)="onDocInserted()"
(docRendered)="onDocRendered()">
<aio-doc-viewer [class.no-animations]="isStarting" [doc]="currentDocument" (docReady)="onDocReady()" (docRemoved)="onDocRemoved()" (docInserted)="onDocInserted()" (docRendered)="onDocRendered()">
</aio-doc-viewer>
<aio-dt *ngIf="dtOn" [(doc)]="currentDocument"></aio-dt>
</main>
@ -71,7 +62,7 @@
</div>
<footer class="no-print">
<aio-footer [nodes]="footerNodes" [versionInfo]="versionInfo" ></aio-footer>
<aio-footer [nodes]="footerNodes" [versionInfo]="versionInfo"></aio-footer>
</footer>
<!--
@ -80,4 +71,6 @@
material icons on other pages are displayed correctly in offline mode.
(Note: Instantiate lazily to avoid affecting the initial rendering.)
-->
<mat-icon class="cdk-visually-hidden" *ngIf="!isStarting">&nbsp;</mat-icon>
<div class="cdk-visually-hidden" *ngIf="!isStarting">
<mat-icon>&nbsp;</mat-icon>
</div>

View File

@ -169,13 +169,6 @@ describe('AppComponent', () => {
expect(component.tocMaxHeight).toMatch(/^\d+\.\d{2}$/);
});
it('should update `scrollService.updateScrollPositonInHistory()`', () => {
const scrollService = fixture.debugElement.injector.get<ScrollService>(ScrollService);
spyOn(scrollService, 'updateScrollPositionInHistory');
component.onScroll();
expect(scrollService.updateScrollPositionInHistory).toHaveBeenCalled();
});
});
describe('SideNav', () => {

View File

@ -339,9 +339,6 @@ export class AppComponent implements OnInit {
// Dynamically change height of table of contents container
@HostListener('window:scroll')
onScroll() {
this.scrollService.updateScrollPositionInHistory();
if (!this.tocMaxHeightOffset) {
// Must wait until `mat-toolbar` is measurable.
const el = this.hostElement.nativeElement as Element;

View File

@ -34,11 +34,6 @@ describe('ScrollService', () => {
'viewportScroller',
['getScrollPosition', 'scrollToPosition']);
beforeEach(() => {
spyOn(window, 'scrollBy');
});
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
ScrollService,
@ -52,8 +47,24 @@ describe('ScrollService', () => {
document = injector.get(DOCUMENT);
scrollService = injector.get(ScrollService);
location = injector.get(Location);
spyOn(window, 'scrollBy');
});
it('should debounce `updateScrollPositonInHistory()` after 500ms', fakeAsync(() => {
const updateScrollPositionInHistorySpy = spyOn(scrollService, 'updateScrollPositionInHistory');
window.dispatchEvent(new Event('scroll'));
tick(249);
window.dispatchEvent(new Event('scroll'));
tick(249);
window.dispatchEvent(new Event('scroll'));
tick(249);
expect(updateScrollPositionInHistorySpy).not.toHaveBeenCalled();
tick(1);
expect(updateScrollPositionInHistorySpy).toHaveBeenCalledTimes(1);
}));
it('should set `scrollRestoration` to `manual` if supported', () => {
if (scrollService.supportManualScrollRestoration) {
expect(window.history.scrollRestoration).toBe('manual');

View File

@ -2,6 +2,7 @@ import { Injectable, Inject } from '@angular/core';
import { Location, PlatformLocation, ViewportScroller } from '@angular/common';
import { DOCUMENT } from '@angular/common';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
export const topMargin = 16;
/**
@ -45,12 +46,11 @@ export class ScrollService {
// On resize, the toolbar might change height, so "invalidate" the top offset.
fromEvent(window, 'resize').subscribe(() => this._topOffset = null);
try {
this.supportManualScrollRestoration = !!window && !!window.scrollTo && 'scrollX' in window
&& 'scrollY' in window && !!history && !!history.scrollRestoration;
} catch {
this.supportManualScrollRestoration = false;
}
fromEvent(window, 'scroll')
.pipe(debounceTime(250)).subscribe(() => this.updateScrollPositionInHistory());
this.supportManualScrollRestoration = !!window && 'scrollTo' in window && 'scrollX' in window
&& 'scrollY' in window && !!history && 'scrollRestoration' in history;
// Change scroll restoration strategy to `manual` if it's supported
if (this.supportManualScrollRestoration) {
@ -62,6 +62,9 @@ export class ScrollService {
if (event.type === 'hashchange') {
this.scrollToPosition();
} else {
// Navigating with forward/back, we have to remove the position from the session storage in order to avoid a
// race-condition
this.removeStoredScrollPosition();
// The popstate event is always triggered by doing a browser action such as a click on the back or forward button.
// It can be follow by a event of type `hashchange`.
this.popStateFired = true;

View File

@ -1,22 +1,21 @@
<!doctype html>
<html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Angular Docs</title>
<title>Angular</title>
<meta name="Description" content="Angular is a platform for building mobile and desktop web applications.
Join the community of millions of developers who build compeling user interfaces with Angular.">
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="search" type="application/opensearchdescription+xml" href="assets/opensearch.xml">
<link rel="icon" type="image/x-icon" href="assets/images/favicons/favicon.ico">
<link rel="icon" type="image/png" href="assets/images/favicons/favicon-32x32.png"
sizes="32x32">
<link rel="icon" type="image/png" href="assets/images/favicons/favicon-194x194.png"
sizes="194x194">
<link rel="icon" type="image/png" href="assets/images/favicons/favicon-96x96.png"
sizes="96x96">
<link rel="icon" type="image/png" href="assets/images/favicons/favicon-16x16.png"
sizes="16x16">
<link rel="icon" type="image/png" href="assets/images/favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="assets/images/favicons/favicon-194x194.png" sizes="194x194">
<link rel="icon" type="image/png" href="assets/images/favicons/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="assets/images/favicons/favicon-16x16.png" sizes="16x16">
<link rel="apple-touch-icon" sizes="144x144" href="assets/images/favicons/favicon-144x144.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/images/favicons/favicon-144x144.png">
@ -39,39 +38,41 @@
<!-- Google Analytics -->
<script>
// Note this is a customised version of the GA tracking snippet
// See the comments below for more info
(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;
~i.name.indexOf('NG_DEFER_BOOTSTRAP')|| // only load library if not running e2e tests
m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
// Note this is a customised version of the GA tracking snippet
// See the comments below for more info
(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;
~i.name.indexOf('NG_DEFER_BOOTSTRAP') || // only load library if not running e2e tests
m.parentNode.insertBefore(a, m)
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
</script>
<!-- End Google Analytics -->
<script>
// Report fatal errors to Google Analytics
window.onerror = function() {
ga('send', 'exception', {exDescription: formatError.apply(null, arguments), exFatal: true});
window.onerror = function () {
ga('send', 'exception', { exDescription: formatError.apply(null, arguments), exFatal: true });
function formatError(msg, url, line, col, e) {
var stack;
msg = msg.replace(/^Error: /, '');
if (e) {
stack = e.stack
// strip the leading "Error: " from the stack trace
.replace(/^Error: /, '')
// strip the message from the stack trace, if present
.replace(msg + '\n', '')
// strip leading spaces
.replace(/^ +/gm, '')
// strip all leading "at " for each frame
.replace(/^at /gm, '')
// replace long urls with just the last segment: `filename:line:column`
.replace(/(?: \(|@)http.+\/([^/)]+)\)?(?:\n|$)/gm, '@$1\n')
// replace "eval code" in Edge
.replace(/ *\(eval code(:\d+:\d+)\)(?:\n|$)/gm, '@???$1\n')
// strip the leading "Error: " from the stack trace
.replace(/^Error: /, '')
// strip the message from the stack trace, if present
.replace(msg + '\n', '')
// strip leading spaces
.replace(/^ +/gm, '')
// strip all leading "at " for each frame
.replace(/^at /gm, '')
// replace long urls with just the last segment: `filename:line:column`
.replace(/(?: \(|@)http.+\/([^/)]+)\)?(?:\n|$)/gm, '@$1\n')
// replace "eval code" in Edge
.replace(/ *\(eval code(:\d+:\d+)\)(?:\n|$)/gm, '@???$1\n')
} else {
line = line || '?';
col = col || '?';
@ -85,6 +86,7 @@
<script nomodule src="generated/ie-polyfills.min.js"></script>
</head>
<body>
<aio-shell></aio-shell>
@ -104,4 +106,5 @@
</h2>
</noscript>
</body>
</html>

View File

@ -138,9 +138,7 @@ aio-toc.embedded {
}
a {
font-size: inherit;
color: lighten($darkgray, 10);
display:table-cell;
overflow: visible;
font-size: 12px;
display: table-cell;

View File

@ -78,23 +78,43 @@ BOILERPLATE_PATHS.universal = [
'package.json'
];
BOILERPLATE_PATHS.ivy = {
systemjs: [
'rollup-config.js',
'tsconfig-aot.json'
],
cli: [
'src/tsconfig.app.json'
]
};
const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
class ExampleBoilerPlate {
/**
* Add boilerplate files to all the examples
*/
add() {
add(ivy = false) {
// Get all the examples folders, indicated by those that contain a `example-config.json` file
const exampleFolders = this.getFoldersContaining(EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, 'node_modules');
if (!fs.existsSync(SHARED_NODE_MODULES_PATH)) {
throw new Error(`The shared node_modules folder for the examples (${SHARED_NODE_MODULES_PATH}) is missing.\n` +
`Perhaps you need to run "yarn example-use-npm" or "yarn example-use-local" to install the dependencies?`);
}
if (ivy) {
// We only need the "fesm5" bundles as the CLI webpack build does not need
// any other formats for building and serving. Ngcc currently only updates
// the module typings if we specified an "es2015" format. This means that
// we also need to build with "fesm2015" in order to get updated typings
// which are needed for compilation.
shelljs.exec(`yarn --cwd ${SHARED_PATH} ivy-ngcc --formats fesm2015 fesm5`);
}
exampleFolders.forEach(exampleFolder => {
const exampleConfig = this.loadJsonFile(path.resolve(exampleFolder, EXAMPLE_CONFIG_FILENAME));
if (!fs.existsSync(SHARED_NODE_MODULES_PATH)) {
throw new Error(`The shared node_modules folder for the examples (${SHARED_NODE_MODULES_PATH}) is missing.\n` +
`Perhaps you need to run "yarn example-use-npm" or "yarn example-use-local" to install the dependencies?`);
}
// Link the node modules - requires admin access (on Windows) because it adds symlinks
const destinationNodeModules = path.resolve(exampleFolder, 'node_modules');
fs.ensureSymlinkSync(SHARED_NODE_MODULES_PATH, destinationNodeModules);
@ -107,6 +127,12 @@ class ExampleBoilerPlate {
// Copy the boilerplate common files
BOILERPLATE_PATHS.common.forEach(filePath => this.copyFile(BOILERPLATE_COMMON_BASE_PATH, exampleFolder, filePath));
// Copy Ivy specific files
if (ivy && BOILERPLATE_PATHS.ivy[boilerPlateType]) {
const ivyBoilerPlateBasePath = path.resolve(BOILERPLATE_BASE_PATH, 'ivy', boilerPlateType);
BOILERPLATE_PATHS.ivy[boilerPlateType].forEach(filePath => this.copyFile(ivyBoilerPlateBasePath, exampleFolder, filePath));
}
});
}
@ -114,13 +140,13 @@ class ExampleBoilerPlate {
* Remove all the boilerplate files from all the examples
*/
remove() {
shelljs.exec('git clean -xdfq', {cwd: EXAMPLES_BASE_PATH});
shelljs.exec('git clean -xdfq', { cwd: EXAMPLES_BASE_PATH });
}
main() {
yargs
.usage('$0 <cmd> [args]')
.command('add', 'add the boilerplate to each example', () => this.add())
.command('add', 'add the boilerplate to each example', (yrgs) => this.add(yrgs.argv.ivy))
.command('remove', 'remove the boilerplate from each example', () => this.remove())
.demandCommand(1, 'Please supply a command from the list above')
.argv;
@ -144,7 +170,7 @@ class ExampleBoilerPlate {
}
loadJsonFile(filePath) {
return fs.readJsonSync(filePath, {throws: false}) || {};
return fs.readJsonSync(filePath, { throws: false }) || {};
}
normalizePath(filePath) {

View File

@ -15,11 +15,32 @@ const PROTRACTOR_CONFIG_FILENAME = path.join(__dirname, './shared/protractor.con
const SJS_SPEC_FILENAME = 'e2e-spec.ts';
const CLI_SPEC_FILENAME = 'e2e/src/app.e2e-spec.ts';
const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
const IGNORED_EXAMPLES = [ // temporary ignores
'quickstart',
'setup',
const IGNORED_EXAMPLES = [
// temporary ignores
];
const fixmeIvyExamples = [
// fixmeIvy('unknown') version value goes undefined when clicking Major button after clicking
// Minor button twice
'component-interaction',
// fixmeIvy('unknown') failed content projection and applied styles
'component-styles',
// fixmeIvy('unknown') ERROR Error: Unable to find context associated with [object
// HTMLInputElement]
'http',
// fixmeIvy('unknown') app fails at runtime due to missing external service (goog is undefined)
'i18n',
// fixmeIvy('unknown') JIT app fails with external resources not loaded.
'upgrade-phonecat-2-hybrid',
// fixmeIvy('unknown') JIT app fails with external resources not loaded.
'upgrade-phonecat-3-final',
];
if (argv.ivy) {
IGNORED_EXAMPLES.push(...fixmeIvyExamples);
}
/**
* Run Protractor End-to-End Tests for Doc Samples
*
@ -44,30 +65,30 @@ function runE2e() {
// Run setup.
console.log('runE2e: setup boilerplate');
const installPackagesCommand = `example-use-${argv.local ? 'local' : 'npm'}`;
const addBoilerplateCommand = 'boilerplate:add';
shelljs.exec(`yarn ${installPackagesCommand}`, { cwd: AIO_PATH });
shelljs.exec(`yarn ${addBoilerplateCommand}`, { cwd: AIO_PATH });
const addBoilerplateCommand = `boilerplate:add${argv.ivy ? ':ivy' : ''}`;
shelljs.exec(`yarn ${installPackagesCommand}`, {cwd: AIO_PATH});
shelljs.exec(`yarn ${addBoilerplateCommand}`, {cwd: AIO_PATH});
}
const outputFile = path.join(AIO_PATH, './protractor-results.txt');
return Promise.resolve()
.then(() => findAndRunE2eTests(argv.filter, outputFile, argv.shard))
.then((status) => {
reportStatus(status, outputFile);
if (status.failed.length > 0) {
return Promise.reject('Some test suites failed');
}
}).catch(function (e) {
console.log(e);
process.exitCode = 1;
});
.then(() => findAndRunE2eTests(argv.filter, outputFile, argv.shard))
.then((status) => {
reportStatus(status, outputFile);
if (status.failed.length > 0) {
return Promise.reject('Some test suites failed');
}
})
.catch(function(e) {
console.log(e);
process.exitCode = 1;
});
}
// Finds all of the *e2e-spec.tests under the examples folder along with the corresponding apps
// that they should run under. Then run each app/spec collection sequentially.
function findAndRunE2eTests(filter, outputFile, shard) {
const shardParts = shard ? shard.split('/') : [0, 1];
const shardModulo = parseInt(shardParts[0], 10);
const shardDivider = parseInt(shardParts[1], 10);
@ -79,45 +100,48 @@ function findAndRunE2eTests(filter, outputFile, shard) {
fs.writeFileSync(outputFile, header);
// Run the tests sequentially.
const status = { passed: [], failed: [] };
const status = {passed: [], failed: []};
return getE2eSpecs(EXAMPLES_PATH, filter)
.then(e2eSpecPaths => {
console.log('All e2e specs:');
logSpecs(e2eSpecPaths);
.then(e2eSpecPaths => {
console.log('All e2e specs:');
logSpecs(e2eSpecPaths);
Object.keys(e2eSpecPaths).forEach(key => {
const value = e2eSpecPaths[key];
e2eSpecPaths[key] = value.filter((p, index) => index % shardDivider === shardModulo);
});
console.log(`E2e specs for shard ${shardParts.join('/')}:`);
logSpecs(e2eSpecPaths);
return e2eSpecPaths.systemjs.reduce((promise, specPath) => {
return promise.then(() => {
const examplePath = path.dirname(specPath);
return runE2eTestsSystemJS(examplePath, outputFile).then(ok => {
const arr = ok ? status.passed : status.failed;
arr.push(examplePath);
});
Object.keys(e2eSpecPaths).forEach(key => {
const value = e2eSpecPaths[key];
e2eSpecPaths[key] = value.filter((p, index) => index % shardDivider === shardModulo);
});
}, Promise.resolve())
.then(() => {
return e2eSpecPaths.cli.reduce((promise, specPath) => {
return promise.then(() => {
return runE2eTestsCLI(specPath, outputFile).then(ok => {
const arr = ok ? status.passed : status.failed;
arr.push(specPath);
console.log(`E2e specs for shard ${shardParts.join('/')}:`);
logSpecs(e2eSpecPaths);
return e2eSpecPaths.systemjs
.reduce(
(promise, specPath) => {
return promise.then(() => {
const examplePath = path.dirname(specPath);
return runE2eTestsSystemJS(examplePath, outputFile).then(ok => {
const arr = ok ? status.passed : status.failed;
arr.push(examplePath);
});
});
},
Promise.resolve())
.then(() => {
return e2eSpecPaths.cli.reduce((promise, specPath) => {
return promise.then(() => {
return runE2eTestsCLI(specPath, outputFile).then(ok => {
const arr = ok ? status.passed : status.failed;
arr.push(specPath);
});
});
}, Promise.resolve());
});
});
}, Promise.resolve());
})
.then(() => {
const stopTime = new Date().getTime();
status.elapsedTime = (stopTime - startTime) / 1000;
return status;
});
})
.then(() => {
const stopTime = new Date().getTime();
status.elapsedTime = (stopTime - startTime) / 1000;
return status;
});
}
// Start the example in appDir; then run protractor with the specified
@ -127,8 +151,8 @@ function findAndRunE2eTests(filter, outputFile, shard) {
function runE2eTestsSystemJS(appDir, outputFile) {
const config = loadExampleConfig(appDir);
const appBuildSpawnInfo = spawnExt('yarn', [config.build], { cwd: appDir });
const appRunSpawnInfo = spawnExt('yarn', [config.run, '-s'], { cwd: appDir }, true);
const appBuildSpawnInfo = spawnExt('yarn', [config.build], {cwd: appDir});
const appRunSpawnInfo = spawnExt('yarn', [config.run, '-s'], {cwd: appDir}, true);
let run = runProtractorSystemJS(appBuildSpawnInfo.promise, appDir, appRunSpawnInfo, outputFile);
@ -141,40 +165,40 @@ function runE2eTestsSystemJS(appDir, outputFile) {
function runProtractorSystemJS(prepPromise, appDir, appRunSpawnInfo, outputFile) {
const specFilename = path.resolve(`${appDir}/${SJS_SPEC_FILENAME}`);
return prepPromise
.catch(function () {
const emsg = `Application at ${appDir} failed to transpile.\n\n`;
console.log(emsg);
fs.appendFileSync(outputFile, emsg);
return Promise.reject(emsg);
})
.then(function () {
let transpileError = false;
.catch(function() {
const emsg = `Application at ${appDir} failed to transpile.\n\n`;
console.log(emsg);
fs.appendFileSync(outputFile, emsg);
return Promise.reject(emsg);
})
.then(function() {
let transpileError = false;
// Start protractor.
console.log(`\n\n=========== Running aio example tests for: ${appDir}`);
const spawnInfo = spawnExt('yarn', ['protractor',
PROTRACTOR_CONFIG_FILENAME,
`--specs=${specFilename}`,
'--params.appDir=' + appDir,
'--params.outputFile=' + outputFile
], { cwd: SHARED_PATH });
// Start protractor.
console.log(`\n\n=========== Running aio example tests for: ${appDir}`);
const spawnInfo = spawnExt(
'yarn',
[
'protractor', PROTRACTOR_CONFIG_FILENAME, `--specs=${specFilename}`,
'--params.appDir=' + appDir, '--params.outputFile=' + outputFile
],
{cwd: SHARED_PATH});
spawnInfo.proc.stderr.on('data', function (data) {
transpileError = transpileError || /npm ERR! Exit status 100/.test(data.toString());
});
return spawnInfo.promise.catch(function () {
if (transpileError) {
const emsg = `${specFilename} failed to transpile.\n\n`;
console.log(emsg);
fs.appendFileSync(outputFile, emsg);
}
return Promise.reject();
});
})
.then(
function () { return finish(appRunSpawnInfo.proc.pid, true); },
function () { return finish(appRunSpawnInfo.proc.pid, false); }
);
spawnInfo.proc.stderr.on('data', function(data) {
transpileError = transpileError || /npm ERR! Exit status 100/.test(data.toString());
});
return spawnInfo.promise.catch(function() {
if (transpileError) {
const emsg = `${specFilename} failed to transpile.\n\n`;
console.log(emsg);
fs.appendFileSync(outputFile, emsg);
}
return Promise.reject();
});
})
.then(
function() { return finish(appRunSpawnInfo.proc.pid, true); },
function() { return finish(appRunSpawnInfo.proc.pid, false); });
}
function finish(spawnProcId, ok) {
@ -187,14 +211,14 @@ function finish(spawnProcId, ok) {
// Run e2e tests over the AOT build for projects that examples it.
function runProtractorAoT(appDir, outputFile) {
fs.appendFileSync(outputFile, '++ AoT version ++\n');
const aotBuildSpawnInfo = spawnExt('yarn', ['build:aot'], { cwd: appDir });
const aotBuildSpawnInfo = spawnExt('yarn', ['build:aot'], {cwd: appDir});
let promise = aotBuildSpawnInfo.promise;
const copyFileCmd = 'copy-dist-files.js';
if (fs.existsSync(appDir + '/' + copyFileCmd)) {
promise = promise.then(() => spawnExt('node', [copyFileCmd], { cwd: appDir }).promise);
promise = promise.then(() => spawnExt('node', [copyFileCmd], {cwd: appDir}).promise);
}
const aotRunSpawnInfo = spawnExt('yarn', ['serve:aot'], { cwd: appDir }, true);
const aotRunSpawnInfo = spawnExt('yarn', ['serve:aot'], {cwd: appDir}, true);
return runProtractorSystemJS(promise, appDir, aotRunSpawnInfo, outputFile);
}
@ -206,11 +230,11 @@ function runE2eTestsCLI(appDir, outputFile) {
console.log(`\n\n=========== Running aio example tests for: ${appDir}`);
// `--no-webdriver-update` is needed to preserve the ChromeDriver version already installed.
const config = loadExampleConfig(appDir);
const commands = config.e2e || [{ cmd: 'yarn', args: ['e2e', '--no-webdriver-update'] }];
const commands = config.e2e || [{cmd: 'yarn', args: ['e2e', '--prod', '--no-webdriver-update']}];
const e2eSpawnPromise = commands.reduce((prevSpawnPromise, { cmd, args }) => {
const e2eSpawnPromise = commands.reduce((prevSpawnPromise, {cmd, args}) => {
return prevSpawnPromise.then(() => {
const currSpawn = spawnExt(cmd, args, { cwd: appDir });
const currSpawn = spawnExt(cmd, args, {cwd: appDir});
return currSpawn.promise.then(
() => Promise.resolve(finish(currSpawn.proc.pid, true)),
() => Promise.reject(finish(currSpawn.proc.pid, false)));
@ -218,25 +242,39 @@ function runE2eTestsCLI(appDir, outputFile) {
}, Promise.resolve());
return e2eSpawnPromise.then(
() => { fs.appendFileSync(outputFile, `Passed: ${appDir}\n\n`); return true; },
() => { fs.appendFileSync(outputFile, `Failed: ${appDir}\n\n`); return false; });
() => {
fs.appendFileSync(outputFile, `Passed: ${appDir}\n\n`);
return true;
},
() => {
fs.appendFileSync(outputFile, `Failed: ${appDir}\n\n`);
return false;
});
}
// Report final status.
function reportStatus(status, outputFile) {
let log = [''];
log.push('Suites ignored due to legacy guides:');
IGNORED_EXAMPLES.filter(example => !fixmeIvyExamples.find(ex => ex.startsWith(example)))
.forEach(function(val) { log.push(' ' + val); });
if (argv.ivy) {
log.push('');
log.push('Suites ignored due to breakage with Ivy:');
fixmeIvyExamples.forEach(function(val) { log.push(' ' + val); });
}
log.push('');
log.push('Suites passed:');
status.passed.forEach(function (val) {
log.push(' ' + val);
});
status.passed.forEach(function(val) { log.push(' ' + val); });
if (status.failed.length == 0) {
log.push('All tests passed');
} else {
log.push('Suites failed:');
status.failed.forEach(function (val) {
log.push(' ' + val);
});
status.failed.forEach(function(val) { log.push(' ' + val); });
}
log.push('\nElapsed time: ' + status.elapsedTime + ' seconds');
log = log.join('\n');
@ -255,68 +293,59 @@ function spawnExt(command, args, options, ignoreClose = false) {
} catch (e) {
console.log(e);
reject(e);
return { proc: null, promise };
return {proc: null, promise};
}
proc.stdout.on('data', function (data) {
process.stdout.write(data.toString());
});
proc.stderr.on('data', function (data) {
process.stdout.write(data.toString());
});
proc.on('close', function (returnCode) {
proc.stdout.on('data', function(data) { process.stdout.write(data.toString()); });
proc.stderr.on('data', function(data) { process.stdout.write(data.toString()); });
proc.on('close', function(returnCode) {
console.log(`completed: ${descr} \n`);
// Many tasks (e.g., tsc) complete but are actually errors;
// Confirm return code is zero.
returnCode === 0 || ignoreClose ? resolve(0) : reject(returnCode);
});
proc.on('error', function (data) {
proc.on('error', function(data) {
console.log(`completed with error: ${descr} \n`);
console.log(data.toString());
reject(data);
});
});
return { proc, promise };
return {proc, promise};
}
function getE2eSpecs(basePath, filter) {
let specs = {};
return getE2eSpecsFor(basePath, SJS_SPEC_FILENAME, filter).then(sjsPaths => {
specs.systemjs = sjsPaths;
}).then(() => {
return getE2eSpecsFor(basePath, CLI_SPEC_FILENAME, filter).then(cliPaths => {
return cliPaths.map(p => {
return p.replace(`${CLI_SPEC_FILENAME}`, '');
});
});
}).then(cliPaths => {
specs.cli = cliPaths;
}).then(() => specs);
return getE2eSpecsFor(basePath, SJS_SPEC_FILENAME, filter)
.then(sjsPaths => { specs.systemjs = sjsPaths; })
.then(() => {
return getE2eSpecsFor(basePath, CLI_SPEC_FILENAME, filter).then(cliPaths => {
return cliPaths.map(p => { return p.replace(`${CLI_SPEC_FILENAME}`, ''); });
});
})
.then(cliPaths => { specs.cli = cliPaths; })
.then(() => specs);
}
// Find all e2e specs in a given example folder.
function getE2eSpecsFor(basePath, specFile, filter) {
// Only get spec file at the example root.
const e2eSpecGlob = `${filter ? `*${filter}*` : '*'}/${specFile}`;
return globby(e2eSpecGlob, { cwd: basePath, nodir: true })
.then(paths => paths
.filter(file => !IGNORED_EXAMPLES.some(ignored => file.startsWith(ignored)))
.map(file => path.join(basePath, file))
);
return globby(e2eSpecGlob, {cwd: basePath, nodir: true})
.then(
paths => paths.filter(file => !IGNORED_EXAMPLES.some(ignored => file.startsWith(ignored)))
.map(file => path.join(basePath, file)));
}
// Load configuration for an example. Used for SystemJS
function loadExampleConfig(exampleFolder) {
// Default config.
let config = {
build: 'build',
run: 'serve:e2e'
};
let config = {build: 'build', run: 'serve:e2e'};
try {
const exampleConfig = fs.readJsonSync(`${exampleFolder}/${EXAMPLE_CONFIG_FILENAME}`);
Object.assign(config, exampleConfig);
} catch (e) { }
} catch (e) {
}
return config;
}

View File

@ -6,6 +6,16 @@
},
"exclude": [
"test.ts",
"**/*.spec.ts"
"**/*.spec.ts",
"**/*.avoid.ts",
"**/*.0.ts",
"**/*.1.ts",
"**/*.1b.ts",
"**/*.2.ts",
"**/*.3.ts",
"**/*.4.ts",
"**/*.5.ts",
"**/*.6.ts",
"**/*.7.ts"
]
}
}

View File

@ -0,0 +1,25 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"types": []
},
"exclude": [
"test.ts",
"**/*.spec.ts",
"**/*.avoid.ts",
"**/*.0.ts",
"**/*.1.ts",
"**/*.1b.ts",
"**/*.2.ts",
"**/*.3.ts",
"**/*.4.ts",
"**/*.5.ts",
"**/*.6.ts",
"**/*.7.ts"
],
"angularCompilerOptions": {
"enableIvy": "ngtsc",
"allowEmptyCodegenFiles": true
}
}

View File

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

View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"es2015",
"dom"
],
"removeComments": false,
"noImplicitAny": true,
"skipLibCheck": true,
"suppressImplicitAnyIndexErrors": true
},
"files": [
"app/app.module.ts",
"app/main.ts"
],
"angularCompilerOptions": {
"skipMetadataEmit": true,
"enableIvy": "ngtsc"
}
}

View File

@ -18,22 +18,22 @@
"author": "",
"license": "MIT",
"dependencies": {
"@angular/animations": "^7.0.0",
"@angular/common": "^7.0.0",
"@angular/compiler": "^7.0.0",
"@angular/core": "^7.0.0",
"@angular/elements": "^7.0.0",
"@angular/forms": "^7.0.0",
"@angular/http": "^7.0.0",
"@angular/platform-browser": "^7.0.0",
"@angular/platform-browser-dynamic": "^7.0.0",
"@angular/router": "^7.0.0",
"@angular/service-worker": "^7.0.0",
"@angular/upgrade": "^7.0.0",
"@nguniversal/common": "^7.0.0",
"@nguniversal/express-engine": "^7.0.0",
"@nguniversal/module-map-ngfactory-loader": "^7.0.0",
"angular-in-memory-web-api": "^0.6.0",
"@angular/animations": "^7.1.0",
"@angular/common": "^7.1.0",
"@angular/compiler": "^7.1.0",
"@angular/core": "^7.1.0",
"@angular/elements": "^7.1.0",
"@angular/forms": "^7.1.0",
"@angular/http": "^7.1.0",
"@angular/platform-browser": "^7.1.0",
"@angular/platform-browser-dynamic": "^7.1.0",
"@angular/router": "^7.1.0",
"@angular/service-worker": "^7.1.0",
"@angular/upgrade": "^7.1.0",
"@nguniversal/common": "^7.1.0",
"@nguniversal/express-engine": "^7.1.0",
"@nguniversal/module-map-ngfactory-loader": "^7.1.0",
"angular-in-memory-web-api": "github:brandonroberts/in-memory-web-api-bazel#50a34d8",
"core-js": "^2.5.4",
"express": "^4.14.1",
"rxjs": "^6.3.0",
@ -42,11 +42,11 @@
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.10.0",
"@angular/cli": "^7.0.0",
"@angular/compiler-cli": "^7.0.0",
"@angular/language-service": "^7.0.0",
"@angular/platform-server": "^7.0.0",
"@angular-devkit/build-angular": "^0.11.0",
"@angular/cli": "^7.1.0",
"@angular/compiler-cli": "^7.1.0",
"@angular/language-service": "^7.1.0",
"@angular/platform-server": "^7.1.0",
"@types/angular": "^1.6.47",
"@types/angular-animate": "^1.5.10",
"@types/angular-mocks": "^1.6.0",

File diff suppressed because it is too large Load Diff

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