Compare commits

...

113 Commits

Author SHA1 Message Date
a38293d213 release: cut the zone.js-0.11.2 release to fix several new issues (#39298)
PR Close #39298
2020-10-16 10:18:55 -07:00
4dc8d83d84 docs: edit attribute-binding doc and move colSpan note to property binding (#38860)
This commit edits the copy of the attribute binding documentation, moves the
colspan section that is primarily about property binding to the property
binding document, and adds a docregion to the attribute-binding
example to help clarify a point in the document.
Part of the copy edit reformats the style precedence list in tabular format
so that it is easier to read and understand.

PR Close #38860
2020-10-16 10:06:16 -07:00
492e236ae6 docs: Typos fixes in built-in directives guide (#38520)
PR Close #38520
2020-10-16 10:05:26 -07:00
34b74cecb6 build(docs-infra): add a tool to create new examples (#39283)
This tool can be run from anywhere in the aio folder as:

```sh
yarn create-example <example-name>
```

It will create some basic scaffold files to get the example started.
After creation the developer should then use `yarn boilerplate:add`
or similar to ensure that the example can be run and tested.

You can optionally provide an absolute path to a pre-existing CLI
project and it will copy over appropriate files (ignoring boilerplate)
to the newly created example.

```sh
yarn create-example <example-name> /path/to/other/cli/project
```

Fixes #39275

PR Close #39283
2020-10-16 08:14:38 -07:00
81aa119739 fix(core): convert legacy-sanitized values to Trusted Types (#39218)
Use the bypass-specific Trusted Types policy for automatically upgrade
any values from custom sanitizers or the bypassSecurityTrust functions
to a Trusted Type. Update tests to reflect the new behavior.

PR Close #39218
2020-10-16 08:13:52 -07:00
49197d12a0 feat(core): create a Trusted Types policy for bypass conversions (#39218)
When an application uses a custom sanitizer or one of the
bypassSecurityTrust functions, Angular has no way of knowing whether
they are implemented in a secure way. (It doesn't even know if they're
introduced by the application or by a shady third-party dependency.)
Thus using Angular's main Trusted Types policy to bless values coming
from these two sources would undermine the security that Trusted Types
brings.

Instead, introduce a Trusted Types policy called angular#unsafe-bypass
specifically for blessing values from these sources. This allows an
application to enforce Trusted Types even if their application uses a
custom sanitizer or the bypassSecurityTrust functions, knowing that
compromises to either of these two sources may lead to arbitrary script
execution. In the future Angular will provide a way to implement
custom sanitizers in a manner that makes better use of Trusted Types.

PR Close #39218
2020-10-16 08:13:52 -07:00
9ec2bad4dc refactor(core): make HTML sanitizer return TrustedHTML (#39218)
Make Angular's HTML sanitizer return a TrustedHTML, as its output is
trusted not to cause XSS vulnerabilities when used in a context where a
browser may parse and evaluate HTML. Also update tests to reflect the
new behaviour.

PR Close #39218
2020-10-16 08:13:52 -07:00
e8d47c2d41 feat(core): allow returning Trusted Types from SanitizerFn (#39218)
Sanitizers in Angular currently return strings, which will then
eventually make their way down to the DOM, e.g. as the value of an
attribute or property. This may cause a Trusted Types violation. As a
step towards fixing that, make it possible to return Trusted Types from
the SanitizerFn interface, which represents the internal sanitization
pipeline. DOM renderer interfaces are also updated to reflect the fact
that setAttribute and setAttributeNS must be able to accept Trusted
Types.

PR Close #39218
2020-10-16 08:13:52 -07:00
765fa337e3 fix(compiler): use Trusted Types policy in JIT compiler (#39210)
The JIT compiler uses the Function constructor to compile arbitrary
strings into executable code at runtime, which causes Trusted Types
violations. To address this, JitEvaluator is instead made to use the
Trusted Types compatible Function constructor introduced by Angular's
Trusted Types policy for JIT.

PR Close #39210
2020-10-16 08:13:14 -07:00
6570292672 feat(core): create a Trusted Types policy for JIT compiler (#39210)
Introduce a Trusted Types policy for use by Angular's JIT compiler named
angular#unsafe-jit. As the compiler turns arbitrary untrusted strings
into executable code at runtime, using Angular's main Trusted Types
policy does not seem appropriate, unless it can be ensured that the
provided strings are indeed trusted. Until then, this JIT policy can be
allowed by applications that rely on the JIT compiler but want to
enforce Trusted Types, knowing that a compromise of the JIT compiler can
lead to arbitrary script execution. In particular, this is required for
enabling Trusted Types in Angular unit tests, since they make use of the
JIT compiler.

Also export the internal Trusted Types definitions from the core package
so that they can be used in the compiler package.

PR Close #39210
2020-10-16 08:13:14 -07:00
4610093c87 fix(core): guard reading of global ngDevMode for undefined. (#36055)
When reading globals such as `ngDevMode` the read should be guarded by `typeof ngDevMode` otherwise it will throw if not
defined in `"use strict"` mode.

PR Close #36055
2020-10-16 08:12:22 -07:00
a3812c6cbd refactor(core): renames checkNoChangesMode to be clearer (#39277)
getCheckNoChangesMode was discovered to be unclear as to the purpose of
it. This refactor is a simple renaming to make it much clearer what that
method and property does.

PR Close #39277
2020-10-15 17:01:20 -07:00
96f59f64a0 docs: Very minor spelling mistake (#39299)
1659: teh -> the
PR Close #39299
2020-10-15 17:00:18 -07:00
5bda62c51d refactor(language-service): Return directive defs when input name is part of selector (#39243)
When an input name is part of the directive selector, it would be good to return the directive as well
when performing 'go to definition' or 'go to type definition'. As an example, this would allow
'go to type definition' for ngIf to take the user to the NgIf directive.
'Go to type definition' would otherwise return no results because the
input is a generic type. This would also be the case for all primitive
input types.

PR Close #39243
2020-10-15 14:17:24 -07:00
f9f3c54c9a build(docs-infra): upgrade cli command docs sources to 06ad10668 (#39288)
Updating [angular#master](https://github.com/angular/angular/tree/master) from
[cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in
[commit range](d807b8240...06ad10668):

**Modified**
- help/generate.json

PR Close #39288
2020-10-15 14:16:23 -07:00
7669827436 docs: fix typo at console.log (#39252)
PR Close #39252
2020-10-15 14:15:36 -07:00
178a0437b7 docs(core): fix typo in the "Template statements" guide (#39244)
PR Close #39244
2020-10-15 14:14:25 -07:00
34dbba4a90 refactor(dev-infra): remove branches created for g3 comparison (#39137)
Previously, temporary branches were created to be used for comparison to
the g3 branch, instead comparisons are now done using the branches
latest shas.

PR Close #39137
2020-10-15 14:11:31 -07:00
ef608bff83 docs: update readme (#32084)
PR Close #32084
2020-10-15 14:08:17 -07:00
06d0d8e31d docs: Move pipes documentation from Components to Templates (#38983)
PR Close #38983
2020-10-15 14:07:28 -07:00
60f761b4c2 docs: deprecate displaying data in views topic (#38885)
The Displaying Data in Views topic is actually a small tutorial
that describes Angular features such as interpolation and
structural directives. These content is already covered in
our getting started tutorial and in Tour of Heroes.

This change adds redirects to the Template Syntax section
of the Getting Started tutorial and deletes displaying-data.md.

PR Close #38885
2020-10-15 14:05:28 -07:00
93437bbc16 ci: update master branch version to be 11.1.0-next.0 (#39292)
Since the `11.0.x` branch was created, we change the master branch version to be 11.1.0-next.0
(i.e. next minor version after v11.0.0 release).

PR Close #39292
2020-10-15 14:02:36 -07:00
85be258845 ci: add jessicajaniuk to require-minimum-review reviewers (#39268)
Add jessicajaniuk@ to the list of reviewers included in the required
minimum reviewers list.

PR Close #39268
2020-10-15 11:06:03 -07:00
56ab6d56e9 docs: Update output directory name in Deployment guide (#39247)
The default output directory is no longer `dist/` but `dist/project-name/`
PR Close #39247
2020-10-15 09:08:23 -07:00
6e18d2dacc fix(compiler): promote constants in templates to Trusted Types (#39211)
Angular treats constant values of attributes and properties in templates
as secure. This means that these values are not sanitized, and are
instead passed directly to the corresponding setAttribute or setProperty
function. In cases where the given attribute or property is
security-sensitive, this causes a Trusted Types violation.

To address this, functions for promoting constant strings to each of the
three Trusted Types are introduced to Angular's private codegen API. The
compiler is updated to wrap constant strings with calls to these
functions as appropriate when constructing the `consts` array. This is
only done for security-sensitive attributes and properties, as
classified by Angular's dom_security_schema.

PR Close #39211
2020-10-15 09:08:01 -07:00
9bfb508b87 build: replace @types/trusted-types dep with minimal type defs (#39211)
The @types/trusted-types type definitions are currently imported in
types.d.ts, which causes them to eventually be imported in core.d.ts.
This forces anyone compiling against @angular/core to provide the
@types/trusted-types package in their compilation unit, which we don't
want.

To address this, get rid of the @types/trusted-types and instead import
a minimal version of the Trusted Types type definitions directly into
Angular's codebase.

Update the existing references to Trusted Types to point to the new
definitions.

PR Close #39211
2020-10-15 09:08:00 -07:00
497af77d7a build(zone.js): zone.js should output esm format for fesm2015 bundles (#39203)
Zone.js support `Angular package format` since `0.11`, but the `fesm2015` bundles
are not `esm` format, it still use `umd` bundle which is not correct, in this PR,
a new `esm` bundle output is added in `rollup_bundle` rule under `tools`, so
zone.js can use the new rule to generate `esm` bundles.

PR Close #39203
2020-10-15 09:07:38 -07:00
822b838fbc fix(ngcc): ensure that "inline exports" can be interpreted correctly (#39267)
Previously, inline exports of the form `exports.foo = <implementation>;` were
being interpreted (by the ngtsc `PartialInterpeter`) as `Reference` objects.
This is not what is desired since it prevents the value of the export
from being unpacked, such as when analyzing `NgModule` declarations:

```
exports.directives = [Directive1, Directive2];

@NgImport({declarations: [exports.directives]})
class AppModule {}
```

In this example the interpreter would think that `exports.directives`
was a reference rather than an array that needs to be unpacked.

This bug was picked up by the ngcc-validation repository. See
https://github.com/angular/ngcc-validation/pull/1990 and
https://circleci.com/gh/angular/ngcc-validation/17130

PR Close #39267
2020-10-14 14:11:45 -07:00
ac0016cd82 refactor(compiler-cli): visit inline declarations with implementations differently (#39267)
Some inline declarations are of the form:

```
exports.<name> = <implementation>;
```

In this case the declaration `node` is `exports.<name>`.
When interpreting such inline declarations we actually want
to visit the `implementation` expression rather than visiting
the declaration `node`.

This commit adds `implementation?: ts.Expression` to the
`InlineDeclaration` type and updates the interpreter to visit
these expressions as described above.

PR Close #39267
2020-10-14 14:11:45 -07:00
eb9eebbb45 refactor(elements): simplify code after IE<11 support removal (#39265)
Support for IE<11 is being removed in v11. PR #39090 removed some code
that was no longer needed.

Now that there are no longer multiple code-paths (which was previously
needed for IE<11 support), this commit simplifies the code further (for
example, to avoid unnecessary functions calls and to avoid iterating
over a component's inputs multiple times).

PR Close #39265
2020-10-14 14:11:22 -07:00
aee2d3f994 docs: fix broken link (#39256)
PR Close #39256
2020-10-14 14:10:59 -07:00
8f1317f06f fix(language-service): [Ivy] create compiler only when program changes (#39231)
This commit fixes a bug in which a new Ivy Compiler is created every time
language service receives a new request. This is not needed if the
`ts.Program` has not changed.

A new class `CompilerFactory` is created to manage Compiler lifecycle and
keep track of template changes so that it knows when to override them.
With this change, we no longer need the method `getModifiedResourceFile()`
on the adapter. Instead, we call `overrideComponentTemplate` on the
template type checker.

This commit also changes the incremental build strategy from
`PatchedIncrementalBuildStrategy` to `TrackedIncrementalBuildStrategy`.

PR Close #39231
2020-10-14 14:10:37 -07:00
a83693ddd9 refactor(core): use relative import paths in micro benchmarks (#39142)
This commit updates micro benchmarks to use relative path to Ivy runtime code. Keeping absolute
locations caused issues with build optimizer that retained certain symbols and they appeared in the
output twice.

PR Close #39142
2020-10-14 14:10:13 -07:00
dd66aa290a test(core): add micro benchmarks for i18n scenarios (#39142)
This commit adds micro benchmarks to run micro benchmarks for i18n-related logic in the
following scenarios:

- i18n static attributes
- i18n attributes with interpolations
- i18n blocks of static text
- i18n blocks of text + interpolations
- simple ICUs
- nested ICUs

First 4 scenarios also have baseline scenarios (non-i18n) so that we can compare i18n perf with
non-i18n logic.

PR Close #39142
2020-10-14 14:10:13 -07:00
0e5a945ed4 ci: setup windows from scratch (#39139)
Rather than setting up windows by relying on attaching the saved workspace
failes from the previous step, instead checkout and install the yarn items
within the windows steps.  Additionally, since the bazel remote cache is
used and relied on, saving the cached results of the bazel runs to be resumed
on subsequent runs does not provide enough value to make it worth the time
consumed.

PR Close #39139
2020-10-14 14:09:49 -07:00
90e9574ac7 ci: run windows CI jobs on PRs (#39139)
Previously windows CI jobs were only run on upstream branches, with the addition
of larger Windows executors as well as the improvement of setup speed in the
windows environment setup script allows for the windows tests to pass in a
reasonable timeframe.

PR Close #39139
2020-10-14 14:09:49 -07:00
cdf642b609 docs: update marketing home loved-by-millions svg (#39105)
docs: include entire worldmap

docs: feedback changes on loved-by-millions

PR Close #39105
2020-10-14 14:09:26 -07:00
a5d8d03edb release: cut the v11.0.0-next.6 release 2020-10-14 13:50:18 -07:00
5cfe81f919 docs: release notes for the v10.1.6 release 2020-10-14 13:42:57 -07:00
0ec7043490 feat(core): add initialNavigation schematic (#36926)
Add a schematic to update users to the new v11 `initialNavigation`
options for `RouterModule`. This replaces the deprecated/removed
`true`, `false`, `legacy_disabled`, and `legacy_enabled` options
with the newer `enabledBlocking` and `enabledNonBlocking` options.

PR Close #36926
2020-10-14 12:01:07 -07:00
c4becca0e4 feat(router): add new initialNavigation options to replace legacy (#37480)
As of Angular v4, four of the options for
`ExtraOptions#initialNavigation` have been deprecated. We intend
to remove them in v11. The final state for these options is:
`enabledBlocking`, `enabledNonBlocking`, and `disabled`. We plan
to remove and deprecate the remaining option in the next two
major releases.

New options:
- `enabledNonBlocking`: same as legacy_enabled
- `enabledBlocking`: same as enabled

BREAKING CHANGE:

* The `initialNavigation` property for the options in
  `RouterModule.forRoot` no longer supports `legacy_disabled`,
  `legacy_enabled`, `true`, or `false` as valid values.
  `legacy_enabled` (the old default) is instead `enabledNonBlocking`
* `enabled` is deprecated as a valid value for the
  `RouterModule.forRoot` `initialNavigation` option. `enabledBlocking`
  has been introduced to replace it

PR Close #37480
2020-10-14 11:20:51 -07:00
b0a8b69ae8 docs: update removed section in deprecations to reference v11 (#38762)
Updates the removed section in the deprecations guide to talk about APIs removed
in v11 rather than the pervious versions.

PR Close #38762
2020-10-14 10:40:55 -07:00
93ee05d92a fix(router): create schematic for preserveQueryParams (#38762)
Create a schematic for migrating preserveQueryParams to use queryParamsHandler
instead.

PR Close #38762
2020-10-14 10:40:55 -07:00
783a5bd7bb fix(router): remove preserveQueryParams symbol (#38762)
Remove preserveQueryParams as it was deprecated for removal in v4, use
queryParamsHandling="preserve" instead.

BREAKING CHANGE: preserveQueryParams has been removed, use
queryParamsHandling="preserve" instead

PR Close #38762
2020-10-14 10:40:55 -07:00
c6350116b5 docs: add Discord as an official communication channel (#39149)
PR Close #39149
2020-10-14 10:23:15 -07:00
898be92f70 perf(ngcc): do not rescan program source files when referenced from multiple root files (#39254)
When ngcc is configured to run with the `--use-program-dependencies`
flag, as is the case in the CLI's asynchronous processing, it will scan
all source files in the program, starting from the program's root files
as configured in the tsconfig. Each individual root file could
potentially rescan files that had already been scanned for an earlier
root file, causing a severe performance penalty if the number of root
files is large. This would be the case if glob patterns are used in the
"include" specification of a tsconfig file.

This commit avoids the performance penalty by keeping track of the files
that have been scanned across all root files, such that no source file
is scanned multiple times.

Fixes #39240

PR Close #39254
2020-10-14 09:34:11 -07:00
f6d5cdfbd7 fix(core): use Trusted Types policy in named_array_type (#39209)
Address a Trusted Types violation that occurs in createNamedArrayType
during development mode. Instead of passing strings directly to "new
Function", use the Trusted Types compatible function constructor exposed
by the Trusted Types policy.

PR Close #39209
2020-10-14 09:33:48 -07:00
5913e5c4e8 feat(core): add Trusted Types workaround for Function constructor (#39209)
Chrome currently does not support passing TrustedScript to the Function
constructor, and instead fails with a Trusted Types violation when
called. As the Function constructor is used in a handful of places
within Angular, such as in the JIT compiler and named_array_type, the
workaround proposed on the following page is implemented:
https://github.com/w3c/webappsec-trusted-types/wiki/Trusted-Types-for-function-constructor

To be precise, it constructs a string representing an anonymous function
in a way that is equivalent to what the Function constructor does,
promotes it to a TrustedScript and then calls eval.

To facilitate backwards compatibility, new Function is used directly in
environments that do not support Trusted Types.

PR Close #39209
2020-10-14 09:33:47 -07:00
929e0df377 refactor(dev-infra): Adjust caretaker queries (#39257)
- The current initial triage does not include PRs. This includes them by removing the issue filter
- The merge assistance label is often applied to PRs that do not have
status=success. Caretaker should handle these as well

PR Close #39257
2020-10-14 09:07:04 -07:00
c53f19ac47 refactor(zone.js): rename several internal apis in fake async zone spec (#39127)
In `FakeAsyncZoneSpec`, there are several variables and APIs to identify
different times, and the names are confusing, in this commit, they are
renamed for more clear understandings.

1. currentTickTime, the tick millis advanced.
2. getFakeBaseSystemTime(), return the fake base system time.
3. setFakeBaseSystemTime(), set the fake base system time.
4. getRealSystemTime(), get the underlying native system time.

PR Close #39127
2020-10-13 15:56:22 -07:00
ffc3332dcd fix(zone.js): jest getRealSystemTime should return native time (#39127)
`jest.getRealSystemTime()` should return native `Date.now()`, the
current implemenation return the wrong value which is the fixed
number.

PR Close #39127
2020-10-13 15:56:22 -07:00
8fd25d9614 docs: remove IE10 references from comments in the code (#39090)
PR Close #39090
2020-10-13 15:51:49 -07:00
a051d97429 test(core): remove IE10 reference from browserslist files (#39090)
This commit updates `browserslist` files to exclude IE10 references.

PR Close #39090
2020-10-13 15:51:49 -07:00
0001dbdede refactor(core): remove IE-sepcific logic from setClassMetadata function (#39090)
This commit simplifies the logic in the `setClassMetadata` function to avoid the code needed to
support IE 9 and IE 10.

PR Close #39090
2020-10-13 15:51:49 -07:00
cbef410e3f refactor(elements): remove code to support IE9/10 (#39090)
Since support for IE 9 and IE 10 browsers is removed in v11, the code that was added to support
these browsers is no longer needed.

PR Close #39090
2020-10-13 15:51:49 -07:00
db37c17e02 refactor(core): remove NG_PROV_DEF_FALLBACK needed for IE10 only (#39090)
This commit removes a workaround previously used for IE 9 and 10 to identify whether InjectableDef
was defined on a given class instance. Since support for IE 9 and 10 is removed, this fallback is
no longer needed.

PR Close #39090
2020-10-13 15:51:48 -07:00
61e6ca9b1f test(platform-browser): remove IE9 and IE10 checks from tests (#39090)
This commit removes IE 9 and IE 10 checks from the browser detection spec.
Also unblocks tests that were previously disabled due to issues in IE10.

PR Close #39090
2020-10-13 15:51:48 -07:00
78a33eeef9 test(core): remove code specific to IE 9 and IE 10 (#39090)
This commit updates core tests and removes the code needed to support IE 9 and IE 10 only.
The code is no longer needed since IE 9 and IE 10 support is removed in v11.

PR Close #39090
2020-10-13 15:51:48 -07:00
584f37cfca updated sajee's profile (#39019)
PR Close #39019
2020-10-13 14:59:03 -07:00
7d4929918d fix(core): use Trusted Types policy in inert DOM builder (#39208)
When Angular is used in an environment that enforces Trusted Types, the
inert DOM builder raises a Trusted Types violation due to its use of
DOMParser and element.innerHTML with plain strings. Since it is only
used internally (in the HTML sanitizer and for i18n ICU parsing), we
update it to use Angular's Trusted Types policy to promote the provided
HTML to TrustedHTML.

PR Close #39208
2020-10-13 14:58:06 -07:00
b642f0bf45 docs(zone.js): update changelog to add jest useFakeTimers feature (#39126)
Since we are merged https://github.com/angular/angular/issues/38851 PR
about integration of jest.useFakeTimers with fakeAsync, so the
new release should also include this feature, this PR updated the zone.js
0.11.2 changelog.

PR Close #39126
2020-10-13 14:57:09 -07:00
520911efd4 docs: fix typo in the Reactive Forms guide #5 (#39245)
PR Close #39245
2020-10-13 13:38:28 -07:00
0875fd2360 feat(core): create internal Trusted Types module (#39207)
Add a module that provides a Trusted Types policy for use internally by
Angular. The policy is created lazily and stored in a module-local
variable. For now the module does not allow configuring custom policies
or policy names, and instead creates its own policy with 'angular' as a
fixed policy name. This is to more easily support tree-shakability.

Helper functions for unsafely converting strings to each of the three
Trusted Types are also introduced, with documentation that make it clear
that their use requires a security review. When Trusted Types are not
available, these helper functions fall back to returning strings.

PR Close #39207
2020-10-13 11:23:36 -07:00
c4266fb729 feat(core): depend on type definitions for Trusted Types (#39207)
To facilitate the upcoming Trusted Types support being added to Angular,
add the TypeScript type definitions for the Trusted Types browser API as
a dependency in the root package.json and types.d.ts since they're
needed for compiling the Angular packages.

PR Close #39207
2020-10-13 11:23:36 -07:00
5ce71e0fbc feat(core): add automated migration to replace async with waitForAsync (#39212)
Adds a migration that finds all imports and calls to the deprecated `async` function from
`@angular/core/testing` and replaces them with `waitForAsync`.

These changes also move a bit of code out of the `Renderer2` migration so that it can be reused.

PR Close #39212
2020-10-13 09:55:34 -07:00
437e563507 refactor(language-service): Allow "go to definition" for directives in Ivy (#39228)
For directives/components, it would be generally more appropriate for
"go to type definition" to be the function which navigates to the class
definition. However, for a better user experience, we should do this
for "go to definition" as well.

PR Close #39228
2020-10-13 08:52:29 -07:00
b0b4953fd6 fix(router): Allow undefined inputs on routerLink (#39151)
This make it coherent with typing of Router.createUrlTree to which
those inputs are directly forwarded to. And hence it allow to pass
`undefined`, `null` or a value to the routerLink directive.

BREAKING CHANGE: in most cases this should not break, but if you were
accessing the values of `queryParams`, `fragment` or `queryParamsHandling`
you might need to relax the typing to also accept `undefined` and `null`.

Signed-off-by: Adrien Crivelli <adrien.crivelli@gmail.com>

PR Close #39151
2020-10-12 12:52:37 -07:00
72f4497f11 docs: move Inputs and Outputs topic to Components section (#38984)
PR Close #38984
2020-10-12 12:40:49 -07:00
96dd78e0c6 fix(dev-infra): detect all commit message keywords that can close a PR (#39229)
Previously, the `isCommitClosingPullRequest()` method (used in
`ng-dev release` to detect whether a commit is closing a PR based on
keywords found in the commit message) was only able to detect a subset
of the keywords supported by GitHub.

This is fine currently, because the merge script adds `PR Close #XYZ`
when merging a PR, but it might break in the future.

This commit makes the code more robust by ensuring the method can detect
all keywords supported by GitHub for automatically closing a PR based on
a commit message.

Original discussion:
https://github.com/angular/angular/pull/39135#discussion_r503440973

PR Close #39229
2020-10-12 12:02:48 -07:00
c9b36f9150 fix(dev-infra): fix error message in invokeSetNpmDistCommand() function (#39229)
In #39135, the commit message string was accidentally changed from a
template literal to a regular string literal. This prevented the
`npmDistTag` variable from being correctly displayed in the error
message.

This commit fixes it by switching it back to a template literal.

NOTE:
This was pointed out in
https://github.com/angular/angular/pull/39135#discussion_r503361412, but
the PR was accidentally merged before the review feedback had been
addressed.

PR Close #39229
2020-10-12 12:02:48 -07:00
c76dda6aeb fix(dev-infra): correctly check for commit that closes PR (#39135)
The `ng-dev release publish` command needs to check whether a commit
closed a pull request. This is implemented via checking the commit
message for specific closing keywords referencing the pull request
number.

The regex used previously failed to correctly ensure that the specified
pull request was referenced. For example, it would allow `#12345` to
also match for `#1234`.

This commit fixes the regex.

PR Close #39135
2020-10-12 10:47:13 -07:00
6947ceaf44 refactor(dev-infra): several code style and typo fixes (#39135)
This commit addresses comments from [my review][1] on PR #38656 (which
was merged without comments addressed). The changes are mostly related
to code style and typos.

[1]: https://github.com/angular/angular/pull/38656#pullrequestreview-482129333

PR Close #39135
2020-10-12 10:47:13 -07:00
5471789664 refactor(animations): do not assign to innerHTML (#37397)
This should not change behavior, but it prevents false-positive warnings in various static analysis
tools, including tools used internally at Google.

PR Close #37397
2020-10-12 10:44:59 -07:00
952710b43b refactor(compiler-cli): ensure isNamed....() helpers check name is identity (#38959)
Previously the `node.name` property was only checked to ensure it was
defined. But that meant that it was a `ts.BindingName`, which also includes
`ts.BindingPattern`, which we do not support. But these helper methods were
forcefully casting the value to `ts.Identifier.

Now we also check that the `node.name` is actually an `ts.Identifier`.

PR Close #38959
2020-10-12 08:32:47 -07:00
2736a43ecb fix(compiler-cli): support namespaced query types in directives (#38959)
Previously directive "queries" that relied upon a namespaced type

```ts
queries: {
  'mcontent': new core.ContentChild('test2'),
}
```

caused an error to be thrown. This is now supported.

PR Close #38959
2020-10-12 08:32:47 -07:00
f4fee86f77 fix(ngcc): support inline export declarations in UMD files (#38959)
Previously, any declarations that were defined "inline" were not
recognised by the `UmdReflectionHost`.

For example, the following syntax was completely unrecognized:

```ts
var Foo_1;
exports.Foo = Foo_1 = (function() {
  function Foo() {}
  return Foo;
})();
exports.Foo = Foo_1 = __decorate(SomeDecorator, Foo);
```

Such inline classes were ignored and not processed by ngcc.

This lack of processing led to failures in Ivy applications that relied
on UMD formats of libraries such as `syncfusion/ej2-angular-ui-components`.

Now all known inline UMD exports are recognized and processed accordingly.

Fixes #38947

PR Close #38959
2020-10-12 08:32:46 -07:00
47eab61cad test(ngcc): use isNamedDeclaration() helper to simplify tests (#38959)
Previously these tests were checking multiple specific expression
types. The new helper function is more general and will also support
`PropertyAccessExpression` nodes for `InlineDeclaration` types.

PR Close #38959
2020-10-12 08:32:46 -07:00
0accd1e68d refactor(compiler-cli): implement DeclarationNode node type (#38959)
Previously the `ConcreteDeclaration` and `InlineDeclaration` had
different properties for the underlying node type. And the `InlineDeclaration`
did not store a value that represented its declaration.

It turns out that a natural declaration node for an inline type is the
expression. For example in UMD/CommonJS this would be the `exports.<name>`
property access node.

So this expression is now used for the `node` of `InlineDeclaration` types
and the `expression` property is dropped.

To support this the codebase has been refactored to use a new `DeclarationNode`
type which is a union of `ts.Declaration|ts.Expression` instead of `ts.Declaration`
throughout.

PR Close #38959
2020-10-12 08:32:46 -07:00
2c0282f4c2 test(ngcc): use isNamedFunctionDeclaration() in UMD tests (#38959)
This makes these tests more resilient to changes in the test code
structure. For example switching from

```
var SomeClass = <implementation>;
exports.SomeClass = SomeClass;
```

to

```
exports.SomeClass = <implementation>;
```

PR Close #38959
2020-10-12 08:32:46 -07:00
6650d71fe2 test(compiler-cli): make the getDeclaration() utility more resilient to code format (#38959)
Previously `getDeclaration()` would only return the first node that matched
the name passed in and then assert the predicate on this single node.
It also only considered a subset of possible declaration types that we might
care about.

Now the function will parse the whole tree collecting an array of all the
nodes that match the name. It then filters this array based on the predicate
and only errors if the filtered array is empty.

This makes this function much more resilient to more esoteric code formats
such as UMD.

PR Close #38959
2020-10-12 08:32:46 -07:00
65997c0649 refactor(ngcc): simplify and break up ES2015 functions with helpers (#38959)
The protected helper functions can then be overridden by subclasses of the
Esm2015ReflectionHost.

PR Close #38959
2020-10-12 08:32:46 -07:00
1d6e67478e refactor(ngcc): simplify and rename getClassDeclarationFromInnerDeclaration() (#38959)
The new function does not try to restrict the kind of AST node that it
finds, leaving that to the caller. This will make it more resuable in the
UMD reflection host.

PR Close #38959
2020-10-12 08:32:46 -07:00
5038e5741b fix(ngcc): handle aliases in UMD export declarations (#38959)
Sometimes UMD exports appear in the following form:

```
exports.MyClass = alias1 = alias2 = <<declaration>>
```

Previously the declaration of the export would have been captured
as `alias1 = alias2 = <<declaration>>`, which the `PartialInterpreter`
would have failed on, since it cannot handle assignments.

Now we skip over these aliases capturing only the `<<declaration>>`
expression.

Fixes #38947

PR Close #38959
2020-10-12 08:32:46 -07:00
11485d96fb fix(ngcc): map exports to the current module in UMD files (#38959)
UMD files export values by assigning them to an `exports` variable.
When evaluating expressions ngcc was failing to cope with expressions
like `exports.MyComponent`.

This commit fixes the `UmdReflectionHost.getDeclarationOfIdentifier()`
method to map the `exports` variable to the current source file.

PR Close #38959
2020-10-12 08:32:46 -07:00
acfce0ba1b test(ngcc): fix incorrect test setup (#38959)
The `SIMPLE_CLASS_FILE` contained a `ChildClass` that had an
internal aliases implementation and extended a `SuperClass` base
class. The call to `__extends` was using the wrong argument for
the child class.

PR Close #38959
2020-10-12 08:32:45 -07:00
ed81588c79 refactor(compiler-cli): move map creation to avoid unnecessary work (#38959)
If the `symbol` for the given `node` does not exist then there is no
point in creating the `map`.

PR Close #38959
2020-10-12 08:32:45 -07:00
87274e3eec refactor(ngcc): rename ExportStatement to ExportsStatement (#38959)
This clarifies that this is specifically about statements of the form
`exports.<name> = <declaration>`, rather than a general export
statement such as `export class <ClassName> { ... }`.

PR Close #38959
2020-10-12 08:32:45 -07:00
a5a7845593 refactor(ngcc): remove unused imports (#38959)
The `isAssignment` and `isAssignmentStatement` are not used in this file.

PR Close #38959
2020-10-12 08:32:45 -07:00
f35e9158b2 refactor(compiler-cli): remove unnecessary constraint on isDeclarationReference() (#38959)
There is no need to check that the `ref.node` is of any particular type
because immediately after this check the entry is tested to see if it passes
`isClassDeclarationReference()`.

The only difference is that the error that is reported is slightly different
in the case that it is a `ref` but not one of the TS node types.

Previously:

```
`Value at position ${idx} in the NgModule.${arrayName} of ${
                className} is not a reference`
```

now

```
`Value at position ${idx} in the NgModule.${arrayName} of ${
                  className} is not a class`
```

Arguably the previous message was wrong, since this entry IS a reference
but is not a class.

PR Close #38959
2020-10-12 08:32:45 -07:00
cee393d0da test(compiler-cli): improve error message if a unit test is bad (#38959)
The message now also reports the name of the predicate function
that failed.

PR Close #38959
2020-10-12 08:32:45 -07:00
118f37b174 test(zone.js): do not run tests on IE 9 and IE 10 (#39189)
Since IE 9 and IE 10 were deprecated and support is removed in v11, this commit updates ZoneJs
configs to avoid running tests in these browsers.

PR Close #39189
2020-10-12 08:27:25 -07:00
e930b0cd19 build(docs-infra): support passing args to ng serve via serve-and-sync (#39201)
When working on the docs, it is helpful to run a local instance of the
angular.io app and run scripts that watch both the docs contents and the
app build artifacts to automatically update the running instance on
changes. Typically, this is achieved via the `start` and `docs-watch`
npm scripts. As a convenience, one can run the `serve-and-sync` script,
which runs both in one terminal.

Previously, it was not possible to pass arguments to `ng nerve` (which
is what the `start` script runs under the hood) when running it via
`serve-and-sync`.

This commit adds support for passing any arguments passed to
`serve-and-sync` through to the `start` script. This can be useful for
things like specifying a custom host or port.

PR Close #39201
2020-10-12 08:27:00 -07:00
62945efab7 build(docs-infra): upgrade cli command docs sources to d807b8240 (#39214)
Updating [angular#master](https://github.com/angular/angular/tree/master) from
[cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in
[commit range](7208ef964...d807b8240):

**Modified**
- help/new.json

PR Close #39214
2020-10-12 08:26:36 -07:00
4cc5982e58 docs: add linkable section about updating commit messages in CONTRIBUTING.md (#39215)
A common review request is updating the commit message of a commit.
Since this is something that is not straight forward for inexperienced
contributors, it is useful to be able to point a contributor to some
docs outlining the process.

This commit adds such a section in `CONTRIBUTING.md` (as discussed in
https://github.com/angular/angular/pull/39110#discussion_r499935502).

PR Close #39215
2020-10-12 08:26:09 -07:00
a84976fdfc feat(language-service): Add getTypeDefinitionAtPosition (go to type definition) (#39145)
This commit adds the implementation for providing "go to type definition"
functionality in the Ivy Language Service.

PR Close #39145
2020-10-09 10:57:37 -07:00
bf717b1a31 fix(elements): detect matchesSelector prototype without IIFE (#37799)
Although in SSR we patch the global prototypes with DOM globals
like Element and Node, this patch does not occur before the
matches function is called in Angular Elements. This is similar
to the behavior in @angular/upgrade.

Fixes #24551

PR Close #37799
2020-10-09 10:02:24 -07:00
9f3388e491 build(docs-infra): upgrade cli command docs sources to 7208ef964 (#39181)
Updating [angular#master](https://github.com/angular/angular/tree/master) from
[cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in
[commit range](65fb6788d...7208ef964):

**Modified**
- help/generate.json
- help/new.json

PR Close #39181
2020-10-09 10:02:02 -07:00
b2342d4116 feat(dev-infra): Add github links to caretaker checks (#39185)
This commit adds links to the PR/Issue for queries in the caretaker check.

PR Close #39185
2020-10-09 09:39:33 -07:00
7f689a291a fix(compiler): incorrectly encapsulating @import containing colons and semicolons (#38716)
At a high level, the current shadow DOM shim logic works by escaping the content of a CSS rule
(e.g. `div {color: red;}` becomes `div {%BLOCK%}`), using a regex to parse out things like the
selector and the rule body, and then re-adding the content after the selector has been modified.
The problem is that the regex has to be very broad in order capture all of the different use cases,
which can cause it to match strings suffixed with a semi-colon in some places where it shouldn't,
like this URL from Google Fonts `https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap`.
Most of the time this is fine, because the logic that escapes the rule content to `%BLOCK%` will
have converted it to something that won't be matched by the regex. However, it breaks down for rules
like `@import` which don't have a body, but can still have quoted content with characters that can
match the regex.

These changes resolve the issue by making a second pass over the escaped string and replacing all
of the remaining quoted content with `%QUOTED%` before parsing it with the regex. Once everything
has been processed, we make a final pass where we restore the quoted content.

In a previous iteration of this PR, I went with a shorter approach which narrowed down the
regex so that it doesn't capture rules without a body. It fixed the issue, but it also ended
up breaking some of the more contrived unit test cases. I decided not to pursue it further, because
we would've ended up with a very long and brittle regex that likely would've broken in even weirder
ways.

Fixes #38587.

PR Close #38716
2020-10-09 08:33:04 -07:00
ca4ef61c06 build: bump Chromium to next stable version: 84.0.4147 (#39179)
Bump Chrome to the next stable release (84.0.4147) by following the
instructions in dev-infra/browsers/README.md.

With Chrome 86 about to be released as stable, the current local version
(Chrome 83) is starting to lag behind. It also contains a bug that
blocks Angular unit and integration tests from using Trusted Types.

PR Close #39179
2020-10-09 07:53:11 -07:00
4a1c12c773 feat(core): remove ViewEncapsulation.Native (#38882)
Removes `ViewEncapsulation.Native` which has been deprecated for several major versions.

BREAKING CHANGES:
* `ViewEncapsulation.Native` has been removed. Use `ViewEncapsulation.ShadowDom` instead. Existing
usages will be updated automatically by `ng update`.

PR Close #38882
2020-10-08 11:56:03 -07:00
0e733f3689 feat(core): add automated migration to replace ViewEncapsulation.Native (#38882)
Adds an automated migration that replaces any usages of the deprecated
`ViewEncapsulation.Native` with `ViewEncapsulation.ShadowDom`.

PR Close #38882
2020-10-08 11:56:03 -07:00
0a16e60afa fix(compiler-cli): type checking of expressions within ICUs (#39072)
Expressions within ICU expressions in templates were not previously
type-checked, as they were skipped while traversing the elements
within a template. This commit enables type checking of these
expressions by actually visiting the expressions.

BREAKING CHANGE:
Expressions within ICUs are now type-checked again, fixing a regression
in Ivy. This may cause compilation failures if errors are found in
expressions that appear within an ICU. Please correct these expressions
to resolve the type-check errors.

Fixes #39064

PR Close #39072
2020-10-08 11:55:27 -07:00
f84b3786dc test(language-service): test ICU expressions in hybrid visitor (#39072)
This commit adds tests for locating expressions within ICU expressions.

PR Close #39072
2020-10-08 11:55:27 -07:00
4b06ef75aa refactor(compiler): associate accurate source spans with ICU expressions (#39072)
Prior to this change, expressions within ICUs would have a source span
corresponding with the whole ICU. This commit narrows down the source
spans of these expressions to the exact location in the source file, as
a prerequisite for reporting type check errors within these expressions.

PR Close #39072
2020-10-08 11:55:27 -07:00
42a164f522 build: upgrade angular build, integration/bazel and @angular/bazel package to rule_nodejs 2.2.0 (#39182)
Updates to rules_nodejs 2.2.0. This is the first major release in 7 months and includes a number of features as well
as breaking changes.

Release notes: https://github.com/bazelbuild/rules_nodejs/releases/tag/2.0.0

Features of note for angular/angular:

* stdout/stderr/exit code capture; this could be potentially be useful

* TypeScript (ts_project); a simpler tsc rule that ts_library that can be used in the repo where ts_library is too
  heavy weight

Breaking changes of note for angular/angular:

* loading custom rules from npm packages: `ts_library` is no longer loaded from `@npm_bazel_typescript//:index.bzl`
  (which no longer exists) but is now loaded from `@npm//@bazel/typescript:index.bzl`

* with the loading changes above, `load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")` is
  no longer needed in the WORKSPACE which also means that yarn_install does not need to run unless building/testing
  a target that depends on @npm. In angular/angular this is a minor improvement as almost everything depends on @npm.

* @angular/bazel package is also updated in this PR to support the new load location; Angular + Bazel users that
  require it for ng_package (ng_module is no longer needed in OSS with Angular 10) will need to load from
  `@npm//@angular/bazel:index.bzl`. I investigated if it was possible to maintain backward compatability for the old
  load location `@npm_angular_bazel` but it is not since the package itself needs to be updated to load from
  `@npm//@bazel/typescript:index.bzl` instead of `@npm_bazel_typescript//:index.bzl` as it depends on ts_library
  internals for ng_module.

* runfiles.resolve will now throw instead of returning undefined to match behavior of node require

Other changes in angular/angular:

* integration/bazel has been updated to use both ng_module and ts_libary with use_angular_plugin=true.
  The latter is the recommended way for rules_nodejs users to compile Angular 10 with Ivy. Bazel + Angular ViewEngine is
  supported with @angular/bazel <= 9.0.5 and Angular <= 8. There is still Angular ViewEngine example on rules_nodejs
  https://github.com/bazelbuild/rules_nodejs/tree/stable/examples/angular_view_engine on these older versions but users
  that want to update to Angular 10 and are on Bazel must switch to Ivy and at that point ts_library with
  use_angular_plugin=true is more performant that ng_module. Angular example in rules_nodejs is configured this way
  as well: https://github.com/bazelbuild/rules_nodejs/tree/stable/examples/angular. As an aside, we also have an
  example of building Angular 10 with architect() rule directly instead of using ts_library with angular plugin:
  https://github.com/bazelbuild/rules_nodejs/tree/stable/examples/angular_bazel_architect.

NB: ng_module is still required for angular/angular repository as it still builds ViewEngine & @angular/bazel
also provides the ng_package rule. ng_module can be removed in the future if ViewEngine is no longer needed in
angular repo.

* JSModuleInfo provider added to ng_module. this is for forward compat for future rules_nodejs versions.

PR Close #39182
2020-10-08 11:54:59 -07:00
049b453149 fix(core): migrate relative link resolution with single quotes (#39102)
This is a roll forward of #39082, using `ts.createIdentifier(`'legacy'`)` as a cross-version compatible way of making
a single quoted string literal.

Migrated code now uses single quotes, which is in line with the default linting options, so there is no lint error after
migration.

PR Close #39102
2020-10-08 10:10:07 -07:00
dace4aacb6 docs: fix for HttpRequest expansion panel (#39166)
Fixes #39156

PR Close #39166
2020-10-08 09:38:09 -07:00
63624a2d46 feat(language-service): [Ivy] getSemanticDiagnostics for external templates (#39065)
This PR enables `getSemanticDiagnostics()` to be called on external templates.

Several changes are needed to land this feature:

1. The adapter needs to implement two additional methods:
   a. `readResource()`
       Load the template from snapshot instead of reading from disk
   b. `getModifiedResourceFiles()`
       Inform the compiler that external templates have changed so that the
       loader could invalidate its internal cache.
2. Create `ScriptInfo` for external templates in MockHost.
   Prior to this, MockHost only track changes in TypeScript files. Now it
   needs to create `ScriptInfo` for external templates as well.

For (1), in order to make sure we don't reload the template if it hasn't
changed, we need to keep track of its version. Since the complexity has
increased, the adapter is refactored into its own class.

PR Close #39065
2020-10-08 08:45:54 -07:00
4604fe9ed2 feat(language-service): Add module name to directive quick info (#39121)
This commit adds the module name as the `containerName` to the quick info
for directives.

PR Close #39121
2020-10-08 08:45:29 -07:00
01ec0f0933 feat(docs-infra): add short url for strict mode guide (#39129)
With this change we add a short url to strict mode guide
(angular.io/strict -> angular.io/guide/strict-mode). This is important because
of two reasons.

1) Reduce the clutter in the terminal when we include the strict mode guide url in a prompt.
2) Easiler to share in conferences, slides etc..

PR Close #39129
2020-10-08 08:45:02 -07:00
de66818cf6 test(compiler-cli): temporarily disable integrationtest (#39168)
Temporarily disable the //packages/compiler-cli/integrationtest:integrationtest
target while continuing to investigate its unknown failures

PR Close #39168
2020-10-08 08:43:48 -07:00
4ede190571 refactor(compiler-cli): wrap RHS of property write in parens (#39143)
The right needs to be wrapped in parens or we cannot accurately match its
span to just the RHS. For example, the span in `e = $event /*0,10*/` is ambiguous.
It could refer to either the whole binary expression or just the RHS.
We should instead generate `e = ($event /*0,10*/)` so we know the span 0,10 matches RHS.
This is specifically needed for the TemplateTypeChecker/Language Service
when mapping template positions to items in the TCB.

PR Close #39143
2020-10-07 14:49:46 -07:00
418 changed files with 10892 additions and 5652 deletions

View File

@ -74,8 +74,8 @@ test --test_output=errors
# Trick bazel into treating BUILD files under integration/bazel as being regular files
# This lets us glob() up all the files inside this integration test to make them inputs to tests
# (Note, we cannot use common --deleted_packages because the bazel version command doesn't support it)
build --deleted_packages=integration/bazel,integration/bazel/src,integration/bazel/src/hello-world,integration/bazel/test,integration/bazel/test/e2e
query --deleted_packages=integration/bazel,integration/bazel/src,integration/bazel/src/hello-world,integration/bazel/test,integration/bazel/test/e2e
build --deleted_packages=integration/bazel,integration/bazel/src,integration/bazel/src/hello-world,integration/bazel/test,integration/bazel/tools,integration/bazel/test/e2e
query --deleted_packages=integration/bazel,integration/bazel/src,integration/bazel/src/hello-world,integration/bazel/test,integration/bazel/tools,integration/bazel/test/e2e
################################
# Temporary Settings for Ivy #

View File

@ -27,8 +27,6 @@ var_3: &cache_key v7-angular-node-12-{{ checksum ".bazelversion" }}-{{ checksum
# folder will contain all previously used versions and ultimately cause the cache restoring to
# be slower due to its growing size.
var_4: &cache_key_fallback v7-angular-node-12-{{ checksum ".bazelversion" }}
var_3_win: &cache_key_win v7-angular-win-node-12-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
var_4_win: &cache_key_win_fallback v7-angular-win-node-12-{{ checksum ".bazelversion" }}
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
@ -183,23 +181,12 @@ commands:
setup_win:
description: Setup windows node environment
steps:
# Use the Linux workspace directly, as it already has checkout, rebased and node modules.
- custom_attach_workspace
- checkout
# Install Bazel pre-requisites that aren't in the preconfigured CircleCI Windows VM.
- run: ./.circleci/windows-env.ps1
- run: node --version
- run: yarn --version
- restore_cache:
keys:
- *cache_key_win
- *cache_key_win_fallback
# Reinstall to get windows binaries.
- run: yarn install --frozen-lockfile --non-interactive
# Install @bazel/bazelisk globally and use that for the first run.
# Workaround for https://github.com/bazelbuild/rules_nodejs/issues/894
# NB: the issue was for @bazel/bazel but the same problem applies to @bazel/bazelisk
- run: yarn global add @bazel/bazelisk@$env:BAZELISK_VERSION
- run: bazelisk info
notify_webhook_on_fail:
description: Notify a webhook about failure
@ -766,12 +753,6 @@ jobs:
# Probably a powershell command parsing thing. There's no problem using a yarn script though.
command: yarn circleci-win-ve
no_output_timeout: 45m
# Save bazel repository cache to use on subsequent runs.
# We don't save node_modules because it's faster to use the linux workspace and reinstall.
- save_cache:
key: *cache_key_win
paths:
- "C:/Users/circleci/bazel_repository_cache"
test_ivy_aot_win:
executor: windows-executor
@ -863,26 +844,25 @@ workflows:
- build-npm-packages
- build-ivy-npm-packages
- legacy-unit-tests-saucelabs
- components-repo-unit-tests:
requires:
- build-npm-packages
# Temporarily disabled components-repo-unit-tests to update rules_nodejs to 2.0.0. Breaking changes in
# rules_nodejs create a dependency sandwich between angular/angular & angular/components that are very
# difficult and time consuming to resolve and involve patching @angular/bazel in components repo such
# as https://github.com/angular/components/commit/9e7ba251207df77164d73d66620e619bcbc4d2ad. It is simpler to
# 1) land angular/angular upgrade to rule_nodejs 2.0.0 which has breaking changes
# 2) land angular/components upgrade to rules_nodejs 2.0.0 using the @angular/bazel builds snapshot
# 3) update angular/angular to the landed components commit and re-enable these tests
# - components-repo-unit-tests:
# requires:
# - build-npm-packages
- test_zonejs:
requires:
- setup
# Windows Jobs
# These are very slow so we run them on non-PRs only for now.
# TODO: remove the filter when CircleCI makes Windows FS faster.
# The Windows jobs are only run after their non-windows counterparts finish successfully.
# This isn't strictly necessary as there is no artifact dependency, but helps economize
# CI resources by not attempting to build when we know should fail.
- test_win:
<<: *skip_on_pull_requests
requires:
- test
- setup
- test_ivy_aot_win:
<<: *skip_on_pull_requests
requires:
- test_ivy_aot
- setup
monitoring:
jobs:

View File

@ -2,8 +2,8 @@
# https://docs.bazel.build/versions/master/install-windows.html
# https://docs.bazel.build/versions/master/windows.html
# Install MSYS2 and packages
choco install msys2 --version 20180531.0.0 --no-progress --package-parameters "/NoUpdate"
C:\tools\msys64\usr\bin\bash.exe -l -c "pacman --needed --noconfirm -S zip unzip patch diffutils git"
choco install msys2 --version 20200903.0.0 --no-progress --package-parameters "/NoUpdate"
C:\tools\msys64\usr\bin\bash.exe -l -c "pacman --needed --noconfirm -S zip unzip patch diffutils"
# Add PATH modifications to the Powershell profile. This is the win equivalent of .bash_profile.
# https://docs.microsoft.com/en-us/previous-versions//bb613488(v=vs.85)

View File

@ -9,11 +9,11 @@ export const caretaker: CaretakerConfig = {
},
{
name: 'Merge Assistance Queue',
query: `is:pr is:open status:success label:"action: merge-assistance"`,
query: `is:pr is:open label:"action: merge-assistance"`,
},
{
name: 'Initial Triage Queue',
query: `is:open is:issue no:milestone`,
query: `is:open no:milestone`,
}
]
};

View File

@ -26,7 +26,7 @@ export const release: ReleaseConfig = {
],
// TODO: Implement release package building here.
buildPackages: async () => [],
// TODO: This can be removed once there is a org-wide tool for changelog generation.
// TODO: This can be removed once there is an org-wide tool for changelog generation.
generateReleaseNotesForHead: async () => {
exec('yarn -s gulp changelog', {cwd: join(__dirname, '../')});
},

View File

@ -186,6 +186,7 @@ groups:
- IgorMinar # Igor Minar
- jbogarthyde # Judy Bogart
- jelbourn # Jeremy Elbourn
- jessicajaniuk # Jessica Janiuk
- JiaLiPassion # Jia Li
- JoostK # Joost Koehoorn
- josephperrott # Joey Perrott
@ -405,6 +406,7 @@ groups:
'aio/content/guide/structural-directives.md',
'aio/content/examples/structural-directives/**',
'aio/content/guide/svg-in-templates.md',
'aio/content/guide/style-precedence.md',
'aio/content/images/guide/structural-directives/**',
'aio/content/guide/template-statements.md',
'aio/content/guide/user-input.md',
@ -1120,6 +1122,7 @@ groups:
'docs/SAVED_REPLIES.md',
'docs/TOOLS.md',
'docs/TRIAGE_AND_LABELS.md',
'docs/images/**',
'goldens/*',
'modules/*',
'packages/*',

View File

@ -47,3 +47,9 @@ filegroup(
"@npm//:node_modules/angular-mocks-1.6/angular-mocks.js",
],
)
# Detect if the build is running under --stamp
config_setting(
name = "stamp",
values = {"stamp": "true"},
)

View File

@ -1,3 +1,80 @@
<a name="11.0.0-next.6"></a>
# 11.0.0-next.6 (2020-10-14)
### Bug Fixes
* **compiler-cli:** type checking of expressions within ICUs ([#39072](https://github.com/angular/angular/issues/39072)) ([0a16e60](https://github.com/angular/angular/commit/0a16e60)), closes [#39064](https://github.com/angular/angular/issues/39064)
* **core:** migrate relative link resolution with single quotes ([#39102](https://github.com/angular/angular/issues/39102)) ([049b453](https://github.com/angular/angular/commit/049b453)), closes [#39082](https://github.com/angular/angular/issues/39082)
* **core:** use Trusted Types policy in inert DOM builder ([#39208](https://github.com/angular/angular/issues/39208)) ([7d49299](https://github.com/angular/angular/commit/7d49299))
* **core:** use Trusted Types policy in named_array_type ([#39209](https://github.com/angular/angular/issues/39209)) ([f6d5cdf](https://github.com/angular/angular/commit/f6d5cdf))
* **router:** Allow undefined inputs on routerLink ([#39151](https://github.com/angular/angular/issues/39151)) ([b0b4953](https://github.com/angular/angular/commit/b0b4953))
* **router:** create schematic for preserveQueryParams ([#38762](https://github.com/angular/angular/issues/38762)) ([93ee05d](https://github.com/angular/angular/commit/93ee05d))
* **router:** remove preserveQueryParams symbol ([#38762](https://github.com/angular/angular/issues/38762)) ([783a5bd](https://github.com/angular/angular/commit/783a5bd))
### Features
* **core:** add automated migration to replace async with waitForAsync ([#39212](https://github.com/angular/angular/issues/39212)) ([5ce71e0](https://github.com/angular/angular/commit/5ce71e0))
* **core:** add automated migration to replace ViewEncapsulation.Native ([#38882](https://github.com/angular/angular/issues/38882)) ([0e733f3](https://github.com/angular/angular/commit/0e733f3))
* **core:** add initialNavigation schematic ([#36926](https://github.com/angular/angular/issues/36926)) ([0ec7043](https://github.com/angular/angular/commit/0ec7043))
* **core:** add Trusted Types workaround for Function constructor ([#39209](https://github.com/angular/angular/issues/39209)) ([5913e5c](https://github.com/angular/angular/commit/5913e5c))
* **core:** create internal Trusted Types module ([#39207](https://github.com/angular/angular/issues/39207)) ([0875fd2](https://github.com/angular/angular/commit/0875fd2))
* **core:** depend on type definitions for Trusted Types ([#39207](https://github.com/angular/angular/issues/39207)) ([c4266fb](https://github.com/angular/angular/commit/c4266fb))
* **core:** remove ViewEncapsulation.Native ([#38882](https://github.com/angular/angular/issues/38882)) ([4a1c12c](https://github.com/angular/angular/commit/4a1c12c))
* **language-service:** [Ivy] getSemanticDiagnostics for external templates ([#39065](https://github.com/angular/angular/issues/39065)) ([63624a2](https://github.com/angular/angular/commit/63624a2))
* **language-service:** Add getTypeDefinitionAtPosition (go to type definition) ([#39145](https://github.com/angular/angular/issues/39145)) ([a84976f](https://github.com/angular/angular/commit/a84976f))
* **language-service:** Add module name to directive quick info ([#39121](https://github.com/angular/angular/issues/39121)) ([4604fe9](https://github.com/angular/angular/commit/4604fe9))
* **router:** add new initialNavigation options to replace legacy ([#37480](https://github.com/angular/angular/issues/37480)) ([c4becca](https://github.com/angular/angular/commit/c4becca))
### BREAKING CHANGES
* **router:** * The `initialNavigation` property for the options in
`RouterModule.forRoot` no longer supports `legacy_disabled`,
`legacy_enabled`, `true`, or `false` as valid values.
`legacy_enabled` (the old default) is instead `enabledNonBlocking`
* `enabled` is deprecated as a valid value for the
`RouterModule.forRoot` `initialNavigation` option. `enabledBlocking`
has been introduced to replace it
* **router:** preserveQueryParams has been removed, use
queryParamsHandling="preserve" instead
* **router:** If you were accessing the `RouterLink` values of `queryParams`,
`fragment` or `queryParamsHandling` you might need to relax the typing to also
accept `undefined` and `null`. ([#39151](https://github.com/angular/angular/issues/39151))
* **core:** * `ViewEncapsulation.Native` has been removed. Use `ViewEncapsulation.ShadowDom` instead. Existing
usages will be updated automatically by `ng update`.
* **compiler-cli:** Expressions within ICUs are now type-checked again, fixing a regression
in Ivy. This may cause compilation failures if errors are found in
expressions that appear within an ICU. Please correct these expressions
to resolve the type-check errors.
<a name="10.1.6"></a>
## 10.1.6 (2020-10-14)
### Bug Fixes
* **compiler:** incorrectly encapsulating [@import](https://github.com/import) containing colons and semicolons ([#38716](https://github.com/angular/angular/issues/38716)) ([52a0c6b](https://github.com/angular/angular/commit/52a0c6b)), closes [#38587](https://github.com/angular/angular/issues/38587)
* **compiler-cli:** support namespaced query types in directives ([#38959](https://github.com/angular/angular/issues/38959)) ([#39272](https://github.com/angular/angular/issues/39272)) ([f752ab9](https://github.com/angular/angular/commit/f752ab9))
* **elements:** detect matchesSelector prototype without IIFE ([#37799](https://github.com/angular/angular/issues/37799)) ([952fd86](https://github.com/angular/angular/commit/952fd86)), closes [#24551](https://github.com/angular/angular/issues/24551)
* **ngcc:** ensure that "inline exports" can be interpreted correctly ([#39272](https://github.com/angular/angular/issues/39272)) ([e08d021](https://github.com/angular/angular/commit/e08d021))
* **ngcc:** handle aliases in UMD export declarations ([#38959](https://github.com/angular/angular/issues/38959)) ([#39272](https://github.com/angular/angular/issues/39272)) ([9963c5d](https://github.com/angular/angular/commit/9963c5d)), closes [#38947](https://github.com/angular/angular/issues/38947)
* **ngcc:** map `exports` to the current module in UMD files ([#38959](https://github.com/angular/angular/issues/38959)) ([#39272](https://github.com/angular/angular/issues/39272)) ([13c4a7b](https://github.com/angular/angular/commit/13c4a7b))
* **ngcc:** support inline export declarations in UMD files ([#38959](https://github.com/angular/angular/issues/38959)) ([#39272](https://github.com/angular/angular/issues/39272)) ([9c875b3](https://github.com/angular/angular/commit/9c875b3)), closes [#38947](https://github.com/angular/angular/issues/38947)
### build
* upgrade angular build, integration/bazel and [@angular](https://github.com/angular)/bazel package to rule_nodejs 2.2.0 ([#39182](https://github.com/angular/angular/issues/39182)) ([7628c36](https://github.com/angular/angular/commit/7628c36))
### Performance Improvements
* **ngcc:** do not rescan program source files when referenced from multiple root files ([#39254](https://github.com/angular/angular/issues/39254)) ([5221df8](https://github.com/angular/angular/commit/5221df8)), closes [#39240](https://github.com/angular/angular/issues/39240)
<a name="11.0.0-next.5"></a>
# 11.0.0-next.5 (2020-10-07)

View File

@ -3,7 +3,7 @@
As contributors and maintainers of the Angular project, we pledge to respect everyone who contributes by posting issues, updating documentation, submitting pull requests, providing feedback in comments, and any other activities.
Communication through any of Angular's channels (GitHub, Gitter, IRC, mailing lists, Google+, Twitter, etc.) must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
Communication through any of Angular's channels (GitHub, Discord, Gitter, IRC, mailing lists, Twitter, etc.) must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
We promise to extend courtesy and respect to everyone involved in this project regardless of gender, gender identity, sexual orientation, disability, age, race, ethnicity, religion, or level of experience. We expect anyone contributing to the Angular project to do the same.

View File

@ -32,7 +32,7 @@ Stack Overflow is a much better place to ask questions since:
To save your and our time, we will systematically close all issues that are requests for general support and redirect people to Stack Overflow.
If you would like to chat about the question in real-time, you can reach out via [our gitter channel][gitter].
If you would like to chat about the question in real-time, you can reach out via [our Discord server][discord].
## <a name="issue"></a> Found a Bug?
@ -137,17 +137,37 @@ If we ask for changes via code reviews then:
For more info on working with fixup commits see [here](docs/FIXUP_COMMITS.md).
> Fixup commits (as shown above) are preferred when addressing review feedback, but in some cases you may need to amend the original commit instead of creating a fixup commit (for example, if you want to update the commit message).
> To amend the last commit and update the Pull Request:
>
> ```shell
> git commit --all --amend
> git push --force-with-lease
> ```
That's it! Thank you for your contribution!
##### Updating the commit message
A reviewer might often suggest changes to a commit message (for example, to add more context for a change or adhere to our [commit message guidelines](#commit)).
In order to update the commit message of the last commit on your branch:
1. Check out your branch:
```shell
git checkout my-fix-branch
```
2. Amend the last commit and modify the commit message:
```shell
git commit --amend
```
3. Push to your GitHub repository:
```shell
git push --force-with-lease
```
> NOTE:<br />
> If you need to update the commit message of an earlier commit, you can use `git rebase` in interactive mode.
> See the [git docs](https://git-scm.com/docs/git-rebase#_interactive_mode) for more details.
#### After your pull request is merged
After your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository:
@ -362,7 +382,7 @@ The following documents can help you sort out issues with GitHub accounts and mu
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
[dev-doc]: https://github.com/angular/angular/blob/master/docs/DEVELOPER.md
[github]: https://github.com/angular/angular
[gitter]: https://gitter.im/angular/angular
[discord]: https://discord.gg/angular
[individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
[js-style-guide]: https://google.github.io/styleguide/jsguide.html
[jsfiddle]: http://jsfiddle.net

145
README.md
View File

@ -1,26 +1,151 @@
[![CircleCI](https://circleci.com/gh/angular/angular/tree/master.svg?style=shield)](https://circleci.com/gh/angular/workflows/angular/tree/master)
[![Join the chat at https://gitter.im/angular/angular](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/angular/angular?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![npm version](https://badge.fury.io/js/%40angular%2Fcore.svg)](https://www.npmjs.com/@angular/core)
<h1 align="center">Angular - One framework. Mobile & desktop.</h1>
<p align="center">
<img src="aio/src/assets/images/logos/angular/angular.png" alt="angular-logo" width="120px" height="120px"/>
<br>
<i>Angular is a development platform for building mobile and desktop web applications
<br> using Typescript/JavaScript and other languages.</i>
<br>
</p>
# Angular
<p align="center">
<a href="https://www.angular.io"><strong>www.angular.io</strong></a>
<br>
</p>
Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages.
<p align="center">
<a href="CONTRIBUTING.md">Contributing Guidelines</a>
·
<a href="https://github.com/angular/angular/issues">Submit an Issue</a>
·
<a href="https://blog.angular.io/">Blog</a>
<br>
<br>
</p>
<p align="center">
<a href="https://circleci.com/gh/angular/workflows/angular/tree/master">
<img src="https://img.shields.io/circleci/build/github/angular/angular/master.svg?logo=circleci&logoColor=fff&label=CircleCI" alt="CI status" />
</a>&nbsp;
<a href="https://www.npmjs.com/@angular/core">
<img src="https://img.shields.io/npm/v/@angular/core.svg?logo=npm&logoColor=fff&label=NPM+package&color=limegreen" alt="Angular on npm" />
</a>&nbsp;
<a href="https://discord.gg/angular">
<img src="https://img.shields.io/discord/463752820026376202.svg?logo=discord&logoColor=fff&label=Discord&color=7389d8" alt="Discord conversation" />
</a>
</p>
<hr>
## Documentation
Get started with Angular, learn the fundamentals and explore advanced topics on our documentation website.
- [Getting Started][quickstart]
- [Architecture][architecture]
- [Components and Templates][componentstemplates]
- [Forms][forms]
- [API][api]
### Advanced
- [Angular Elements][angularelements]
- [Server Side Rendering][ssr]
- [Schematics][schematics]
- [Lazy Loading][lazyloading]
## Development Setup
### Prerequisites
- Install [Node.js] which includes [Node Package Manager][npm]
### Setting Up a Project
Intall the Angular CLI globally:
```
npm install -g @angular/cli
```
Create workspace:
```
ng new [PROJECT NAME]
```
Run the application:
```
cd [PROJECT NAME]
ng serve
```
## Quickstart
[Get started in 5 minutes][quickstart].
## Ecosystem
<p>
<img src="/docs/images/angular-ecosystem-logos.png" alt="angular ecosystem logos" width="500px" height="auto">
</p>
- [Angular Command Line (CLI)][cli]
- [Angular Material][angularmaterial]
## Changelog
[Learn about the latest improvements][changelog].
## Want to help?
## Upgrading
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
guidelines for [contributing][contributing] and then check out one of our issues in the [hotlist: community-help](https://github.com/angular/angular/labels/hotlist%3A%20community-help).
Check out our [upgrade guide](https://update.angular.io/) to find out the best way to upgrade your project.
[contributing]: https://github.com/angular/angular/blob/master/CONTRIBUTING.md
## Contributing
### Contributing Guidelines
Read through our [contributing guidelines][contributing] to learn about our submission process, coding rules and more.
### Want to Help?
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our guidelines for [contributing][contributing] and then check out one of our issues in the [hotlist: community-help](https://github.com/angular/angular/labels/hotlist%3A%20community-help).
### Code of Conduct
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct][codeofconduct].
## Community
Join the conversation and help the community.
- [Twitter][twitter]
- [Gitter][gitter]
- Find a Local [Meetup][meetup]
[![Love Angular badge](https://img.shields.io/badge/angular-love-blue?logo=angular&angular=love)](https://www.github.com/angular/angular)
**Love Angular? Give our repo a star :star: :arrow_up:.**
[contributing]: CONTRIBUTING.md
[quickstart]: https://angular.io/start
[changelog]: https://github.com/angular/angular/blob/master/CHANGELOG.md
[changelog]: CHANGELOG.md
[ng]: https://angular.io
[documentation]: https://angular.io/docs
[angularmaterial]: https://material.angular.io/
[cli]: https://cli.angular.io/
[architecture]: https://angular.io/guide/architecture
[componentstemplates]: https://angular.io/guide/displaying-data
[forms]: https://angular.io/guide/forms-overview
[api]: https://angular.io/api
[angularelements]: https://angular.io/guide/elements
[ssr]: https://angular.io/guide/universal
[schematics]: https://angular.io/guide/schematics
[lazyloading]: https://angular.io/guide/lazy-loading-ngmodules
[node.js]: https://nodejs.org/
[npm]: https://www.npmjs.com/get-npm
[codeofconduct]: CODE_OF_CONDUCT.md
[twitter]: https://www.twitter.com/angular
[gitter]: https://gitter.im/angular/angular
[meetup]: https://www.meetup.com/find/?keywords=angular"

View File

@ -8,8 +8,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Fetch rules_nodejs so we can install our npm dependencies
http_archive(
name = "build_bazel_rules_nodejs",
sha256 = "84abf7ac4234a70924628baa9a73a5a5cbad944c4358cf9abdb4aab29c9a5b77",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.7.0/rules_nodejs-1.7.0.tar.gz"],
sha256 = "4952ef879704ab4ad6729a29007e7094aef213ea79e9f2e94cbe1c9a753e63ef",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.2.0/rules_nodejs-2.2.0.tar.gz"],
)
# Check the rules_nodejs version and download npm dependencies
@ -17,7 +17,7 @@ http_archive(
# assert on that.
load("@build_bazel_rules_nodejs//:index.bzl", "check_rules_nodejs_version", "node_repositories", "yarn_install")
check_rules_nodejs_version(minimum_version_string = "1.7.0")
check_rules_nodejs_version(minimum_version_string = "2.2.0")
# Setup the Node.js toolchain
node_repositories(
@ -39,23 +39,18 @@ yarn_install(
yarn_lock = "//:yarn.lock",
)
# Install all bazel dependencies of the @npm npm packages
load("@npm//: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 protractor dependencies
load("@npm_bazel_protractor//:package.bzl", "npm_bazel_protractor_dependencies")
load("@npm//@bazel/protractor:package.bzl", "npm_bazel_protractor_dependencies")
npm_bazel_protractor_dependencies()
# Load karma dependencies
load("@npm_bazel_karma//:package.bzl", "npm_bazel_karma_dependencies")
load("@npm//@bazel/karma:package.bzl", "npm_bazel_karma_dependencies")
npm_bazel_karma_dependencies()
@ -68,11 +63,6 @@ load("//dev-infra/browsers:browser_repositories.bzl", "browser_repositories")
browser_repositories()
# Setup the rules_typescript tooolchain
load("@npm_bazel_typescript//:index.bzl", "ts_setup_workspace")
ts_setup_workspace()
# Setup the rules_sass toolchain
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")

View File

@ -36,8 +36,9 @@ Here are the most important tasks you might need to use:
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally.
* `yarn boilerplate:add:viewengine` - same as `boilerplate:add` but also turns on `ViewEngine` (pre-Ivy) mode.
* `yarn boilerplate:remove` - remove all the boilerplate code that was added via `yarn boilerplate:add`.
* `yarn create-example` - create a new example directory containing initial source files.
* `yarn generate-stackblitz` - generate the stackblitz files that are used by the `live-example` tags in the docs.
* `yarn generate-zips` - generate the zip files from the examples. Zip available via the `live-example` tags in the docs.

View File

@ -32,6 +32,8 @@
**/karma-test-shim.js
**/browser-test-shim.js
**/node_modules
**/yarn.lock
**/package-lock.json
# built files
*.map

View File

@ -3,8 +3,10 @@
<h2>Attribute binding</h2>
<!-- #docregion attrib-binding-colspan -->
<table border=1>
<!-- #docregion colspan -->
<!-- expression calculates colspan=2 -->
<tr><td [attr.colspan]="1 + 1">One-Two</td></tr>
<!-- #enddocregion colspan -->
<!-- ERROR: There is no `colspan` property to set!
<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
@ -32,31 +34,31 @@
<!-- #docregion basic-specificity -->
<h3>Basic specificity</h3>
<!-- The `class.special` binding will override any value for the `special` class in `classExpr`. -->
<div [class.special]="isSpecial" [class]="classExpr">Some text.</div>
<!-- The `class.special` binding overrides any value for the `special` class in `classExpression`. -->
<div [class.special]="isSpecial" [class]="classExpression">Some text.</div>
<!-- The `style.color` binding will override any value for the `color` property in `styleExpr`. -->
<div [style.color]="color" [style]="styleExpr">Some text.</div>
<!-- The `style.color` binding overrides any value for the `color` property in `styleExpression`. -->
<div [style.color]="color" [style]="styleExpression">Some text.</div>
<!-- #enddocregion basic-specificity -->
<!-- #docregion source-specificity -->
<h3>Source specificity</h3>
<!-- The `class.special` template binding will override any host binding to the `special` class set by `dirWithClassBinding` or `comp-with-host-binding`.-->
<!-- The `class.special` template binding overrides any host binding to the `special` class set by `dirWithClassBinding` or `comp-with-host-binding`.-->
<comp-with-host-binding [class.special]="isSpecial" dirWithClassBinding>Some text.</comp-with-host-binding>
<!-- The `style.color` template binding will override any host binding to the `color` property set by `dirWithStyleBinding` or `comp-with-host-binding`. -->
<!-- The `style.color` template binding overrides any host binding to the `color` property set by `dirWithStyleBinding` or `comp-with-host-binding`. -->
<comp-with-host-binding [style.color]="color" dirWithStyleBinding>Some text.</comp-with-host-binding>
<!-- #enddocregion source-specificity -->
<!-- #docregion dynamic-priority -->
<h3>Dynamic vs static</h3>
<!-- If `classExpr` has a value for the `special` class, this value will override the `class="special"` below -->
<div class="special" [class]="classExpr">Some text.</div>
<!-- If `classExpression` has a value for the `special` class, this value overrides the `class="special"` below -->
<div class="special" [class]="classExpression">Some text.</div>
<!-- If `styleExpr` has a value for the `color` property, this value will override the `style="color: blue"` below -->
<div style="color: blue" [style]="styleExpr">Some text.</div>
<!-- If `styleExpression` has a value for the `color` property, this value overrides the `style="color: blue"` below -->
<div style="color: blue" [style]="styleExpression">Some text.</div>
<!-- #enddocregion dynamic-priority -->

View File

@ -9,7 +9,7 @@ export class AppComponent {
actionName = 'Go for it';
isSpecial = true;
canSave = true;
classExpr = 'special clearance';
styleExpr = 'color: red';
classExpression = 'special clearance';
styleExpression = 'color: red';
color = 'blue';
}

View File

@ -11,6 +11,9 @@ export class CompWithHostBindingComponent {
@HostBinding('style.color')
color = 'green';
// #docregion hostbinding
@HostBinding('style.width')
width = '200px';
// #enddocregion hostbinding
}

View File

@ -13,8 +13,8 @@ import { Component, ViewEncapsulation } from '@angular/core';
export class QuestSummaryComponent { }
// #enddocregion
/*
// #docregion encapsulation.native
// #docregion encapsulation.shadow
// warning: few browsers support shadow DOM encapsulation at this time
encapsulation: ViewEncapsulation.Native
// #enddocregion encapsulation.native
encapsulation: ViewEncapsulation.ShadowDom
// #enddocregion encapsulation.shadow
*/

View File

@ -23,13 +23,13 @@ describe('retry-on-error', () => {
docRegionDefault(mockConsole, ajax);
expect(mockConsole.log.calls.allArgs()).toEqual([
['Subscribed to AJAX'],
['Error occured.'],
['Error occurred.'],
['Subscribed to AJAX'],
['Error occured.'],
['Error occurred.'],
['Subscribed to AJAX'],
['Error occured.'],
['Error occurred.'],
['Subscribed to AJAX'],
['Error occured.'],
['Error occurred.'],
['data: ', []],
]);
});

View File

@ -17,7 +17,7 @@ export function docRegionDefault(console, ajax) {
const apiData = ajax('/api/data').pipe(
map((res: any) => {
if (!res.response) {
console.log('Error occured.');
console.log('Error occurred.');
throw new Error('Value expected!');
}
return res.response;

View File

@ -89,7 +89,7 @@ This example from the `HeroListComponent` template uses three of these forms.
<code-example path="architecture/src/app/hero-list.component.1.html" header="src/app/hero-list.component.html (binding)" region="binding"></code-example>
* The `{{hero.name}}` [*interpolation*](guide/displaying-data#interpolation)
* The `{{hero.name}}` [*interpolation*](guide/interpolation)
displays the component's `hero.name` property value within the `<li>` element.
* The `[hero]` [*property binding*](guide/property-binding) passes the value of
@ -166,8 +166,8 @@ The example template uses two built-in structural directives to add application
<code-example path="architecture/src/app/hero-list.component.1.html" header="src/app/hero-list.component.html (structural)" region="structural"></code-example>
* [`*ngFor`](guide/displaying-data#ngFor) is an iterative; it tells Angular to stamp out one `<li>` per hero in the `heroes` list.
* [`*ngIf`](guide/displaying-data#ngIf) is a conditional; it includes the `HeroDetail` component only if a selected hero exists.
* [`*ngFor`](guide/structural-directives#inside-ngfor) is an iterative; it tells Angular to stamp out one `<li>` per hero in the `heroes` list.
* [`*ngIf`](guide/structural-directives#ngif-case-study) is a conditional; it includes the `HeroDetail` component only if a selected hero exists.
#### Attribute directives

View File

@ -11,7 +11,7 @@ about the features and tools that can help you develop and deliver Angular appli
## Application architecture
* The [Components and templates](guide/displaying-data) guide explains how to connect the application data in your [components](guide/glossary#component) to your page-display [templates](guide/glossary#template), to create a complete interactive application.
* The **Main Concepts** section located in the table of contents contains several topics that explain how to connect the application data in your [components](guide/glossary#component) to your page-display [templates](guide/glossary#template), to create a complete interactive application.
* The [NgModules](guide/ngmodules) guide provides in-depth information on the modular structure of an Angular application.
@ -21,7 +21,7 @@ about the features and tools that can help you develop and deliver Angular appli
## Responsive programming
The **Components and Templates** guide provides guidance and details of the [template syntax](guide/template-syntax) that you use to display your component data when and where you want it within a view, and to collect input from users that you can respond to.
The [template syntax](guide/template-syntax) and related topics contain details about how to display your component data when and where you want it within a view, and how to collect input from users that you can respond to.
Additional pages and sections describe some basic programming techniques for Angular apps.
@ -52,8 +52,6 @@ For some platforms and applications, you might also want to use the PWA (Progres
## Support for the development cycle
The **Development Workflow** section describes the tools and processes you use to compile, test, and deploy Angular applications.
* [CLI Command Reference](cli): The Angular CLI is a command-line tool that you use to create projects, generate application and library code, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.
* [Compilation](guide/aot-compiler): Angular provides just-in-time (JIT) compilation for the development environment, and ahead-of-time (AOT) compilation for the production environment.
@ -68,7 +66,6 @@ The **Development Workflow** section describes the tools and processes you use t
* [Accessibility](guide/accessibility): Make your app accessible to all users.
## File structure, configuration, and dependencies
* [Workspace and file structure](guide/file-structure): Understand the structure of Angular workspace and project folders.

View File

@ -1,6 +1,7 @@
# Attribute, class, and style bindings
The template syntax provides specialized one-way bindings for scenarios less well-suited to property binding.
Attribute binding in Angular helps you set values for attributes directly.
With attribute binding, you can improve accessibility, style your application dynamically, and manage multiple CSS classes or styles simultaneously.
<div class="alert is-helpful">
@ -8,23 +9,36 @@ See the <live-example></live-example> for a working example containing the code
</div>
## Binding to an attribute
## Attribute binding
It is recommended that you set an element property with a [property binding](guide/property-binding) whenever possible.
However, sometimes you don't have an element property to bind.
In those situations, you can use attribute binding.
Set the value of an attribute directly with an **attribute binding**. This is the only exception to the rule that a binding sets a target property and the only binding that creates and sets an attribute.
For example, [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) and
[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG) are purely attributes.
Neither ARIA nor SVG correspond to element properties and don't set element properties.
In these cases, you must use attribute binding because there are no corresponding property targets.
Usually, setting an element property with a [property binding](guide/property-binding)
is preferable to setting the attribute with a string. However, sometimes
there is no element property to bind, so attribute binding is the solution.
Consider the [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) and
[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG). They are purely attributes, don't correspond to element properties, and don't set element properties. In these cases, there are no property targets to bind to.
## Syntax
Attribute binding syntax resembles property binding, but
instead of an element property between brackets, start with the prefix `attr`,
followed by a dot (`.`), and the name of the attribute.
You then set the attribute value, using an expression that resolves to a string,
or remove the attribute when the expression resolves to `null`.
Attribute binding syntax resembles [property binding](guide/property-binding), but instead of an element property between brackets, you precede the name of the attribute with the prefix `attr`, followed by a dot.
Then, you set the attribute value with an expression that resolves to a string.
<code-example language="html">
&lt;p [attr.attribute-you-are-targeting]="expression"&gt;&lt;/p&gt;
</code-example>
<div class="alert is-helpful">
When the expression resolves to `null`, Angular removes the attribute altogether.
</div>
## Binding ARIA attributes
One of the primary use cases for attribute binding
is to set ARIA attributes, as in this example:
@ -33,32 +47,30 @@ is to set ARIA attributes, as in this example:
{@a colspan}
## Binding to `colspan`
Another common use case for attribute binding is with the `colspan` attribute in tables.
Binding to the `colspan` attribute helps you keep your tables programmatically dynamic.
Depending on the amount of data that your application populates a table with, the number of columns that a row spans could change.
To use attribute binding with the `<td>` attribute `colspan`:
1. Specify the `colspan` attribute by using the following syntax: `[attr.colspan]`.
1. Set `[attr.colspan]` equal to an expression.
In the following example, binds the `colspan` attribute to the expression `1 + 1`.
<code-example path="attribute-binding/src/app/app.component.html" region="colspan" header="src/app/app.component.html"></code-example>
This binding causes the `<tr>` to span two columns.
<div class="alert is-helpful">
#### `colspan` and `colSpan`
Sometimes there are differences between the name of property and an attribute.
Notice the difference between the `colspan` attribute and the `colSpan` property.
If you wrote something like this:
<code-example language="html">
&lt;tr&gt;&lt;td colspan="{{1 + 1}}"&gt;Three-Four&lt;/td&gt;&lt;/tr&gt;
</code-example>
You'd get this error:
<code-example language="bash">
Template parse errors:
Can't bind to 'colspan' since it isn't a known native property
</code-example>
As the message says, the `<td>` element does not have a `colspan` property. This is true
because `colspan` is an attribute&mdash;`colSpan`, with a capital `S`, is the
corresponding property. Interpolation and property binding can set only *properties*, not attributes.
Instead, you'd use property binding and write it like this:
<code-example path="attribute-binding/src/app/app.component.html" region="colSpan" header="src/app/app.component.html"></code-example>
`colspan` is an attribute of `<tr>`, while `colSpan` with a capital "S" is a property.
When using attribute binding, use `colspan` with a lowercase "s".
For more information on how to bind to the `colSpan` property, see the [`colspan` and `colSpan`](guide/property-binding#colspan) section of [Property Binding](guide/property-binding).
</div>
@ -66,28 +78,32 @@ Instead, you'd use property binding and write it like this:
{@a class-binding}
## Class binding
## Binding to the `class` attribute
Here's how to set the `class` attribute without a binding in plain HTML:
You can use class binding to add and remove CSS class names from an element's `class` attribute.
```html
<!-- standard class attribute setting -->
<div class="foo bar">Some text</div>
```
### Binding to a single CSS `class`
You can also add and remove CSS class names from an element's `class` attribute with a **class binding**.
To create a single class binding, use the prefix `class` followed by a dot and the name of the CSS class&mdash;for example, `[class.sale]="onSale"`.
Angular adds the class when the bound expression, `onSale` is truthy, and it removes the class when the expression is falsy&mdash;with the exception of `undefined`.
See [styling delegation](guide/style-precedence#styling-delegation) for more information.
To create a single class binding, start with the prefix `class` followed by a dot (`.`) and the name of the CSS class (for example, `[class.foo]="hasFoo"`).
Angular adds the class when the bound expression is truthy, and it removes the class when the expression is falsy (with the exception of `undefined`, see [styling delegation](#styling-delegation)).
### Binding to multiple CSS classes
To create a binding to multiple classes, use a generic `[class]` binding without the dot (for example, `[class]="classExpr"`).
The expression can be a space-delimited string of class names, or you can format it as an object with class names as the keys and truthy/falsy expressions as the values.
With object format, Angular will add a class only if its associated value is truthy.
To bind to multiple classes, use `[class]` set to an expression&mdash;for example, `[class]="classExpression"`.
The expression can be a space-delimited string of class names, or an object with class names as the keys and truthy or falsy expressions as the values.
With an object format, Angular adds a class only if its associated value is truthy.
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
Updating the property without changing object identity will have no effect.
<div class="alert is-important">
If there are multiple bindings to the same class name, conflicts are resolved using [styling precedence](#styling-precedence).
With any object-like expression&mdash;such as `object`, `Array`, `Map`, or `Set`&mdash;the identity of the object must change for Angular to update the class list.
Updating the property without changing object identity has no effect.
</div>
If there are multiple bindings to the same class name, Angular uses [styling precedence](guide/style-precedence) to determine which binding to use.
The following table summarizes class binding syntax.
<style>
td, th {vertical-align: top}
@ -118,13 +134,13 @@ If there are multiple bindings to the same class name, conflicts are resolved us
</tr>
<tr>
<td>Single class binding</td>
<td><code>[class.foo]="hasFoo"</code></td>
<td><code>[class.sale]="onSale"</code></td>
<td><code>boolean | undefined | null</code></td>
<td><code>true</code>, <code>false</code></td>
</tr>
<tr>
<td rowspan=3>Multi-class binding</td>
<td rowspan=3><code>[class]="classExpr"</code></td>
<td rowspan=3><code>[class]="classExpression"</code></td>
<td><code>string</code></td>
<td><code>"my-class-1 my-class-2 my-class-3"</code></td>
</tr>
@ -138,44 +154,44 @@ If there are multiple bindings to the same class name, conflicts are resolved us
</tr>
</table>
The [NgClass](guide/built-in-directives/#ngclass) directive can be used as an alternative to direct `[class]` bindings.
However, using the above class binding syntax without `NgClass` is preferred because due to improvements in class binding in Angular, `NgClass` no longer provides significant value, and might eventually be removed in the future.
<hr/>
## Style binding
{@a style-binding}
Here's how to set the `style` attribute without a binding in plain HTML:
## Binding to the style attribute
```html
<!-- standard style attribute setting -->
<div style="color: blue">Some text</div>
```
You can use style binding to set styles dynamically.
You can also set styles dynamically with a **style binding**.
### Binding to a single style
To create a single style binding, start with the prefix `style` followed by a dot (`.`) and the name of the CSS style property (for example, `[style.width]="width"`).
The property will be set to the value of the bound expression, which is normally a string.
To create a single style binding, use the prefix `style` followed by a dot and the name of the CSS style property&mdash;for example, `[style.width]="width"`.
Angular sets the property to the value of the bound expression, which is usually a string.
Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
<div class="alert is-helpful">
Note that a _style property_ name can be written in either
[dash-case](guide/glossary#dash-case), as shown above, or
[camelCase](guide/glossary#camelcase), such as `fontSize`.
You can write a style property name in either [dash-case](guide/glossary#dash-case), or
[camelCase](guide/glossary#camelcase).
</div>
If there are multiple styles you'd like to toggle, you can bind to the `[style]` property directly without the dot (for example, `[style]="styleExpr"`).
The expression attached to the `[style]` binding is most often a string list of styles like `"width: 100px; height: 100px;"`.
### Binding to multiple styles
You can also format the expression as an object with style names as the keys and style values as the values, like `{width: '100px', height: '100px'}`.
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
Updating the property without changing object identity will have no effect.
To toggle multiple styles, bind to the `[style]` attribute&mdash;for example, `[style]="styleExpression"`).
The expression is often a string list of styles such as `"width: 100px; height: 100px;"`.
If there are multiple bindings to the same style property, conflicts are resolved using [styling precedence rules](#styling-precedence).
You can also format the expression as an object with style names as the keys and style values as the values, such as `{width: '100px', height: '100px'}`.
<div class="alert is-important">
With any object-like expression&mdash;such as `object`, `Array`, `Map`, or `Set`&mdash;the identity of the object must change for Angular to update the class list.
Updating the property without changing object identity has no effect.
</div>
If there are multiple bindings to the same style attribute, Angular uses [styling precedence](guide/style-precedence) to determine which binding to use.
The following table summarizes style binding syntax.
<style>
td, th {vertical-align: top}
@ -219,7 +235,7 @@ If there are multiple bindings to the same style property, conflicts are resolve
</tr>
<tr>
<td rowspan=3>Multi-style binding</td>
<td rowspan=3><code>[style]="styleExpr"</code></td>
<td rowspan=3><code>[style]="styleExpression"</code></td>
<td><code>string</code></td>
<td><code>"width: 100px; height: 100px"</code></td>
</tr>
@ -232,72 +248,3 @@ If there are multiple bindings to the same style property, conflicts are resolve
<td><code>['width', '100px']</code></td>
</tr>
</table>
The [NgStyle](guide/built-in-directives/#ngstyle) directive can be used as an alternative to direct `[style]` bindings.
However, using the above style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future.
<hr/>
{@a styling-precedence}
## Styling Precedence
A single HTML element can have its CSS class list and style values bound to multiple sources (for example, host bindings from multiple directives).
When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element.
<div class="alert is-helpful">
<h4>Styling precedence (highest to lowest)</h4>
1. Template bindings
1. Property binding (for example, `<div [class.foo]="hasFoo">` or `<div [style.color]="color">`)
1. Map binding (for example, `<div [class]="classExpr">` or `<div [style]="styleExpr">`)
1. Static value (for example, `<div class="foo">` or `<div style="color: blue">`)
1. Directive host bindings
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
1. Component host bindings
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
</div>
The more specific a class or style binding is, the higher its precedence.
A binding to a specific class (for example, `[class.foo]`) will take precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) will take precedence over a generic `[style]` binding.
<code-example path="attribute-binding/src/app/app.component.html" region="basic-specificity" header="src/app/app.component.html"></code-example>
Specificity rules also apply when it comes to bindings that originate from different sources.
It's possible for an element to have bindings in the template where it's declared, from host bindings on matched directives, and from host bindings on matched components.
Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence.
Directive host bindings are considered less specific because directives can be used in multiple locations, so they have a lower precedence than template bindings.
Directives often augment component behavior, so host bindings from components have the lowest precedence.
<code-example path="attribute-binding/src/app/app.component.html" region="source-specificity" header="src/app/app.component.html"></code-example>
In addition, bindings take precedence over static attributes.
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding will take precedence because it is dynamic.
<code-example path="attribute-binding/src/app/app.component.html" region="dynamic-priority" header="src/app/app.component.html"></code-example>
{@a styling-delegation}
### Delegating to styles with lower precedence
It is possible for higher precedence styles to "delegate" to lower precedence styles using `undefined` values.
Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` will cause Angular to fall back to the next-highest precedence binding to that style.
For example, consider the following template:
<code-example path="attribute-binding/src/app/app.component.html" region="style-delegation" header="src/app/app.component.html"></code-example>
Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding.
In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property will fall back to the value of the `comp-with-host-binding` host binding.
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely.

View File

@ -194,7 +194,7 @@ which explains the following:
* Using [`<ng-container>`](guide/structural-directives#ngcontainer "<ng-container>")
to group elements when there is no suitable host element for the directive.
* How to write your own structural directive.
* That you can only apply [one structural directive](guide/structural-directives#one-per-element "one per host element") to an element.
* Why you [can only apply one structural directive](guide/structural-directives#one-per-element "one per host element") to an element.
</div>
@ -281,7 +281,7 @@ You define a block of HTML that defines how a single item should be displayed
and then you tell Angular to use that block as a template for rendering each item in the list.
The text assigned to `*ngFor` is the instruction that guides the repeater process.
The following example shows `NgFor` applied to a simple `<div>`. (Don't forget the asterisk (`*`) in front of `ngFor`.)
The following example shows `NgFor` applied to a simple `<div>`.
<code-example path="built-in-directives/src/app/app.component.html" region="NgFor-1" header="src/app/app.component.html"></code-example>

View File

@ -97,7 +97,7 @@ For the simplest deployment, create a production build and copy the output direc
</code-example>
2. Copy _everything_ within the output folder (`dist/` by default) to a folder on the server.
2. Copy _everything_ within the output folder (`dist/project-name/` by default) to a folder on the server.
3. Configure the server to redirect requests for missing files to `index.html`.
Learn more about server-side redirects [below](#fallback).
@ -211,11 +211,11 @@ modified to serve `index.html`:
# .
# -- server.rb
# -- public
# |-- dist
# |-- project-name
# |-- index.html
get '/' do
folderDir = settings.public_folder + '/dist' # ng build output folder
folderDir = settings.public_folder + '/project-name' # ng build output folder
send_file File.join(folderDir, 'index.html')
end
```
@ -383,11 +383,11 @@ Build your app for production _including the source maps_
</code-example>
List the generated bundles in the `dist/` folder.
List the generated bundles in the `dist/project-name/` folder.
<code-example language="none" class="code-shell">
ls dist/*.js
ls dist/project-name/*.js
</code-example>
@ -396,7 +396,7 @@ The following example displays the graph for the _main_ bundle.
<code-example language="none" class="code-shell">
node_modules/.bin/source-map-explorer dist/main*
node_modules/.bin/source-map-explorer dist/project-name/main*
</code-example>

View File

@ -41,10 +41,8 @@ v9 - v12
| `@angular/core` | [`DefaultIterableDiffer`](#core) | <!--v7--> v11 |
| `@angular/core` | [`ReflectiveKey`](#core) | <!--v8--> v11 |
| `@angular/core` | [`RenderComponentType`](#core) | <!--v7--> v11 |
| `@angular/core` | [`ViewEncapsulation.Native`](#core) | <!--v6--> v11 |
| `@angular/core` | [`WrappedValue`](#core) | <!--v10--> v12 |
| `@angular/forms` | [`ngModel` with reactive forms](#ngmodel-reactive) | <!--v6--> v11 |
| `@angular/router` | [`preserveQueryParams`](#router) | <!--v7--> v11 |
| `@angular/upgrade` | [`@angular/upgrade`](#upgrade) | <!--v8--> v11 |
| `@angular/upgrade` | [`getAngularLib`](#upgrade-static) | <!--v8--> v11 |
| `@angular/upgrade` | [`setAngularLib`](#upgrade-static) | <!--v8--> v11 |
@ -89,7 +87,6 @@ Tip: In the [API reference section](api) of this doc site, deprecated APIs are i
| [`DefaultIterableDiffer`](api/core/DefaultIterableDiffer) | n/a | v4 | Not part of public API. |
| [`ReflectiveInjector`](api/core/ReflectiveInjector) | [`Injector.create`](api/core/Injector#create) | v5 | See [`ReflectiveInjector`](#reflectiveinjector) |
| [`ReflectiveKey`](api/core/ReflectiveKey) | none | v5 | none |
| [`ViewEncapsulation.Native`](api/core/ViewEncapsulation#Native) | [`ViewEncapsulation.ShadowDom`](api/core/ViewEncapsulation#ShadowDom) | v6 | Use the native encapsulation mechanism of the renderer. See [view.ts](https://github.com/angular/angular/blob/3e992e18ebf51d6036818f26c3d77b52d3ec48eb/packages/core/src/metadata/view.ts#L32).
| [`defineInjectable`](api/core/defineInjectable) | `ɵɵdefineInjectable` | v8 | Used only in generated code. No source code should depend on this API. |
| [`entryComponents`](api/core/NgModule#entryComponents) | none | v9 | See [`entryComponents`](#entryComponents) |
| [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | none | v9 | See [`ANALYZE_FOR_ENTRY_COMPONENTS`](#entryComponents) |
@ -115,12 +112,6 @@ Tip: In the [API reference section](api) of this doc site, deprecated APIs are i
| --- | ----------- | --------------------- | ----- |
| [`ngModel` with reactive forms](#ngmodel-reactive) | [`FormControlDirective`](api/forms/FormControlDirective) | v6 | none |
{@a router}
### @angular/router
| API | Replacement | Deprecation announced | Notes |
| --- | ----------- | --------------------- | ----- |
| [`preserveQueryParams`](api/router/UrlCreationOptions#preserveQueryParams) | [`queryParamsHandling`](api/router/UrlCreationOptions#queryParamsHandling) | v4 | none |
{@a upgrade}
### @angular/upgrade
@ -490,15 +481,13 @@ This section contains a complete list all of the currently deprecated CLI flags.
{@a removed}
## Removed APIs
The following APIs have been removed starting with version 10.0.0*:
The following APIs have been removed starting with version 11.0.0*:
| Package | API | Replacement | Notes |
| ---------------- | -------------- | ----------- | ----- |
| `@angular/core` | Undecorated base classes that use Angular features | Add Angular decorator | See [migration guide](guide/migration-undecorated-classes) for more info |
| `@angular/core` | `ModuleWithProviders` without a generic | `ModuleWithProviders` with a generic | See [migration guide](guide/migration-module-with-providers) for more info |
| `@angular/core` | Style Sanitization | no action needed | See [style sanitization API removal](#style-sanitization) for more info
| `@angular/router` | `preserveQueryParams` | [`queryParamsHandling`](api/router/UrlCreationOptions#queryParamsHandling) | |
*To see APIs removed in version 9, check out this guide on the [version 9 docs site](https://v9.angular.io/guide/deprecations#removed).
*To see APIs removed in version 10, check out this guide on the [version 10 docs site](https://v10.angular.io/guide/deprecations#removed).
{@a esm5-fesm5}

View File

@ -1,312 +0,0 @@
# Displaying data in views
Angular [components](guide/glossary#component) form the data structure of your application.
The HTML [template](guide/glossary#template) associated with a component provides the means to display that data in the context of a web page.
Together, a component's class and template form a [view](guide/glossary#view) of your application data.
The process of combining data values with their representation on the page is called [data binding](guide/glossary#data-binding).
You display your data to a user (and collect data from the user) by *binding* controls in the HTML template to the data properties of the component class.
In addition, you can add logic to the template by including [directives](guide/glossary#directive), which tell Angular how to modify the page as it is rendered.
Angular defines a *template language* that expands HTML notation with syntax that allows you to define various kinds of data binding and logical directives.
When the page is rendered, Angular interprets the template syntax to update the HTML according to your logic and current data state.
Before you read the complete [template syntax guide](guide/template-syntax), the exercises on this page give you a quick demonstration of how template syntax works.
In this demo, you'll create a component with a list of heroes.
You'll display the list of hero names and conditionally show a message below the list.
The final UI looks like this:
<div class="lightbox">
<img src="generated/images/guide/displaying-data/final.png" alt="Final UI">
</div>
<div class="alert is-helpful">
The <live-example></live-example> demonstrates all of the syntax and code snippets described in this page.
</div>
{@a interpolation}
## Showing component properties with interpolation
The easiest way to display a component property is to bind the property name through interpolation.
With interpolation, you put the property name in the view template, enclosed in double curly braces: `{{myHero}}`.
Use the CLI command [`ng new displaying-data`](cli/new) to create a workspace and app named `displaying-data`.
Delete the <code>app.component.html</code> file. It is not needed for this example.
Then modify the <code>app.component.ts</code> file by
changing the template and the body of the component.
When you're done, it should look like this:
<code-example path="displaying-data/src/app/app.component.1.ts" header="src/app/app.component.ts"></code-example>
You added two properties to the formerly empty component: `title` and `myHero`.
The template displays the two component properties using double curly brace
interpolation:
<code-example path="displaying-data/src/app/app.component.1.ts" header="src/app/app.component.ts (template)" region="template"></code-example>
<div class="alert is-helpful">
The template is a multi-line string within ECMAScript 2015 backticks (<code>\`</code>).
The backtick (<code>\`</code>)&mdash;which is *not* the same character as a single
quote (`'`)&mdash;allows you to compose a string over several lines, which makes the
HTML more readable.
</div>
Angular automatically pulls the value of the `title` and `myHero` properties from the component and
inserts those values into the browser. Angular updates the display
when these properties change.
<div class="alert is-helpful">
More precisely, the redisplay occurs after some kind of asynchronous event related to
the view, such as a keystroke, a timer completion, or a response to an HTTP request.
</div>
Notice that you don't call **new** to create an instance of the `AppComponent` class.
Angular is creating an instance for you. How?
The CSS `selector` in the `@Component` decorator specifies an element named `<app-root>`.
That element is a placeholder in the body of your `index.html` file:
<code-example path="displaying-data/src/index.html" header="src/index.html (body)" region="body"></code-example>
When you bootstrap with the `AppComponent` class (in <code>main.ts</code>), Angular looks for a `<app-root>`
in the `index.html`, finds it, instantiates an instance of `AppComponent`, and renders it
inside the `<app-root>` tag.
Now run the app. It should display the title and hero name:
<div class="lightbox">
<img src="generated/images/guide/displaying-data/title-and-hero.png" alt="Title and Hero">
</div>
The next few sections review some of the coding choices in the app.
## Choosing the template source
The `@Component` metadata tells Angular where to find the component's template.
You can store your component's template in one of two places.
* You can define the template *inline* using the `template` property of the `@Component` decorator. An inline template is useful for a small demo or test.
* Alternatively, you can define the template in a separate HTML file and link to that file in the `templateUrl` property of the `@Component` decorator. This configuration is typical for anything more complex than a small test or demo, and is the default when you generate a new component.
In either style, the template data bindings have the same access to the component's properties.
Here the app uses inline HTML because the template is small and the demo is simpler without the additional HTML file.
<div class="alert is-helpful">
By default, the Angular CLI command [`ng generate component`](cli/generate) generates components with a template file.
You can override that by adding the "-t" (short for `inlineTemplate=true`) option:
<code-example hideCopy language="sh" class="code-shell">
ng generate component hero -t
</code-example>
</div>
## Initialization
The following example uses variable assignment to initialize the components.
<code-example path="displaying-data/src/app/app-ctor.component.1.ts" region="class"></code-example>
You could instead declare and initialize the properties using a constructor.
This app uses more terse "variable assignment" style simply for brevity.
{@a ngFor}
## Add logic to loop through data
The `*ngFor` directive (predefined by Angular) lets you loop through data. The following example uses the directive to show all of the values in an array property.
To display a list of heroes, begin by adding an array of hero names to the component and redefine `myHero` to be the first name in the array.
<code-example path="displaying-data/src/app/app.component.2.ts" header="src/app/app.component.ts (class)" region="class"></code-example>
Now use the Angular `ngFor` directive in the template to display each item in the `heroes` list.
<code-example path="displaying-data/src/app/app.component.2.ts" header="src/app/app.component.ts (template)" region="template"></code-example>
This UI uses the HTML unordered list with `<ul>` and `<li>` tags. The `*ngFor`
in the `<li>` element is the Angular "repeater" directive.
It marks that `<li>` element (and its children) as the "repeater template":
<code-example path="displaying-data/src/app/app.component.2.ts" header="src/app/app.component.ts (li)" region="li"></code-example>
<div class="alert is-important">
Don't forget the leading asterisk (\*) in `*ngFor`. It is an essential part of the syntax.
Read more about `ngFor` and `*` in the [ngFor section](guide/built-in-directives#ngfor) of the [Built-in directives](guide/built-in-directives) page.
</div>
Notice the `hero` in the `ngFor` double-quoted instruction;
it is an example of a template input variable. Read
more about template input variables in the [microsyntax](guide/built-in-directives#microsyntax) section of
the [Built-in directives](guide/built-in-directives) page.
Angular duplicates the `<li>` for each item in the list, setting the `hero` variable
to the item (the hero) in the current iteration. Angular uses that variable as the
context for the interpolation in the double curly braces.
<div class="alert is-helpful">
In this case, `ngFor` is displaying an array, but `ngFor` can
repeat items for any [iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) object.
</div>
Now the heroes appear in an unordered list.
<div class="lightbox">
<img src="generated/images/guide/displaying-data/hero-names-list.png" alt="After ngfor">
</div>
## Creating a class for the data
The app's code defines the data directly inside the component, which isn't best practice.
In a simple demo, however, it's fine.
At the moment, the binding is to an array of strings.
In real applications, most bindings are to more specialized objects.
To convert this binding to use specialized objects, turn the array
of hero names into an array of `Hero` objects. For that you'll need a `Hero` class:
<code-example language="sh" class="code-shell">
ng generate class hero
</code-example>
This command creates the following code.
<code-example path="displaying-data/src/app/hero.ts" header="src/app/hero.ts"></code-example>
You've defined a class with a constructor and two properties: `id` and `name`.
It might not look like the class has properties, but it does.
The declaration of the constructor parameters takes advantage of a TypeScript shortcut.
Consider the first parameter:
<code-example path="displaying-data/src/app/hero.ts" header="src/app/hero.ts (id)" region="id"></code-example>
That brief syntax does a lot:
* Declares a constructor parameter and its type.
* Declares a public property of the same name.
* Initializes that property with the corresponding argument when creating an instance of the class.
### Using the Hero class
After importing the `Hero` class, the `AppComponent.heroes` property can return a _typed_ array
of `Hero` objects:
<code-example path="displaying-data/src/app/app.component.3.ts" header="src/app/app.component.ts (heroes)" region="heroes"></code-example>
Next, update the template.
At the moment it displays the hero's `id` and `name`.
Fix that to display only the hero's `name` property.
<code-example path="displaying-data/src/app/app.component.3.ts" header="src/app/app.component.ts (template)" region="template"></code-example>
The display looks the same, but the code is clearer.
{@a ngIf}
## Conditional display with NgIf
Sometimes an app needs to display a view or a portion of a view only under specific circumstances.
Let's change the example to display a message if there are more than three heroes.
The Angular `ngIf` directive inserts or removes an element based on a _truthy/falsy_ condition.
To see it in action, add the following paragraph at the bottom of the template:
<code-example path="displaying-data/src/app/app.component.ts" header="src/app/app.component.ts (message)" region="message"></code-example>
<div class="alert is-important">
Don't forget the leading asterisk (\*) in `*ngIf`. It is an essential part of the syntax.
Read more about `ngIf` and `*` in the [ngIf section](guide/built-in-directives#ngIf) of the [Built-in directives](guide/built-in-directives) page.
</div>
The template expression inside the double quotes,
`*ngIf="heroes.length > 3"`, looks and behaves much like TypeScript.
When the component's list of heroes has more than three items, Angular adds the paragraph
to the DOM and the message appears.
If there are three or fewer items, Angular omits the paragraph, so no message appears.
For more information, see [template expression operators](guide/interpolation#template-expressions).
<div class="alert is-helpful">
Angular isn't showing and hiding the message. It is adding and removing the paragraph element from the DOM. That improves performance, especially in larger projects when conditionally including or excluding
big chunks of HTML with many data bindings.
</div>
Try it out. Because the array has four items, the message should appear.
Go back into <code>app.component.ts</code> and delete or comment out one of the elements from the heroes array.
The browser should refresh automatically and the message should disappear.
## Summary
Now you know how to use:
* **Interpolation** with double curly braces to display a component property.
* **ngFor** to display an array of items.
* A TypeScript class to shape the **model data** for your component and display properties of that model.
* **ngIf** to conditionally display a chunk of HTML based on a boolean expression.
Here's the final code:
<code-tabs>
<code-pane header="src/app/app.component.ts" path="displaying-data/src/app/app.component.ts" region="final">
</code-pane>
<code-pane header="src/app/hero.ts" path="displaying-data/src/app/hero.ts">
</code-pane>
<code-pane header="src/app/app.module.ts" path="displaying-data/src/app/app.module.ts">
</code-pane>
<code-pane header="main.ts" path="displaying-data/src/main.ts">
</code-pane>
</code-tabs>

View File

@ -4,7 +4,7 @@ An entry component is any component that Angular loads imperatively, (which mean
<div class="alert is-helpful">
To contrast the two types of components, there are components which are included in the template, which are declarative. Additionally, there are components which you load imperatively; that is, entry components.
To contrast the two types of components, there are components which are included in the template, which are declarative. Additionally, there are components which you load imperatively; that is, entry components.
</div>
@ -75,11 +75,10 @@ All router components must be entry components. Because this would require you t
## The `entryComponents` array
<div class="alert is-helpful">
Since 9.0.0 with Ivy, the `entryComponents` property is no longer necessary. See [deprecations guide](guide/deprecations#entryComponents).
Since 9.0.0 with Ivy, the `entryComponents` property is no longer necessary. See [deprecations guide](guide/deprecations#entryComponents).
</div>
Though the `@NgModule` decorator has an `entryComponents` array, most of the time

View File

@ -627,10 +627,11 @@ The [npm package manager](https://docs.npmjs.com/getting-started/what-is-npm) is
Learn more about how Angular uses [Npm Packages](guide/npm-packages).
{@ ngc}
{@a ngc}
## ngc
`ngc` is a Typescript-to-Javascript transpiler that processes Angular decorators, metadata, and templates, and emits JavaScript code.
The most recent implementation is internally refered to as `ngtsc` because it's a minimalistic wrapper around the TypeScript compiler `tsc` that adds a transform for processing Angular code.
The most recent implementation is internally referred to as `ngtsc` because it's a minimalistic wrapper around the TypeScript compiler `tsc` that adds a transform for processing Angular code.
{@a O}

View File

@ -39,7 +39,34 @@ which is the attribute, spelled with a lowercase `s`.
For more details, see the [MDN HTMLTableCellElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) documentation.
For more information about `colSpan` and `colspan`, see the [Attribute binding](guide/attribute-binding#colspan) guide.
{@a colspan}
#### `colspan` and `colSpan`
A common point of confusion is between the attribute, `colspan`, and the property, `colSpan`.
Notice that these two names differ by only a single letter.
If you wrote something like this:
<code-example language="html">
&lt;tr&gt;&lt;td colspan="{{1 + 1}}"&gt;Three-Four&lt;/td&gt;&lt;/tr&gt;
</code-example>
You'd get this error:
<code-example language="bash">
Template parse errors:
Can't bind to 'colspan' since it isn't a known native property
</code-example>
As the message says, the `<td>` element does not have a `colspan` property. This is true
because `colspan` is an attribute&mdash;`colSpan`, with a capital `S`, is the
corresponding property. Interpolation and property binding can set only *properties*, not attributes.
Instead, you'd use property binding and write it like this:
<code-example path="attribute-binding/src/app/app.component.html" region="colSpan" header="src/app/app.component.html"></code-example>
Another example is disabling a button when the component says that it `isUnchanged`:

View File

@ -180,7 +180,7 @@ A form group tracks the status and changes for each of its controls, so if one o
<code-example path="reactive-forms/src/app/profile-editor/profile-editor.component.1.html" region="formgroup" header="src/app/profile-editor/profile-editor.component.html (template form group)"></code-example>
Note that just as a form group contains a group of controls, the *profile form* `FormGroup` is bound to the `form` element with the `FormGroup` directive, creating a communication layer between the model and the form containing the inputs. The `formControlName` input provided by the `FormControlName` directive binds each individual input to the form control defined in `FormGroup`. The form controls communicate with their respective elements. They also communicate changes to the form group instance, which provides the source of truth for the model value.
Note that just as a form group contains a group of controls, the *profileForm* `FormGroup` is bound to the `form` element with the `FormGroup` directive, creating a communication layer between the model and the form containing the inputs. The `formControlName` input provided by the `FormControlName` directive binds each individual input to the form control defined in `FormGroup`. The form controls communicate with their respective elements. They also communicate changes to the form group instance, which provides the source of truth for the model value.
**Save form data**

View File

@ -1656,7 +1656,7 @@ _before_ the `AppRoutingModule`:
</code-tabs>
Remove the initial crisis center route from the `app-routing.module.ts` because now the `HeroesModule` and the `CrisisCenter` modules provide teh feature routes.
Remove the initial crisis center route from the `app-routing.module.ts` because now the `HeroesModule` and the `CrisisCenter` modules provide the feature routes.
The `app-routing.module.ts` file retains the top-level application routes such as the default and wildcard routes.

View File

@ -0,0 +1,133 @@
# Style Precedence
When there are multiple bindings to the same class name or style attribute, Angular uses a set of precedence rules to determine which classes or styles to apply to the element.
These rules specify an order for which style- and class-related bindings have priority.
This styling precedence is as follows, from the most specific with the highest priority to least specific with the lowest priorty:
1. Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence.
<table width="100%">
<col width="40%"></col>
<col width="60%"></col>
<thead>
<tr>
<th>Binding type</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>Property binding</td>
<td><code>&lt;div [class.foo]="hasFoo"&gt;</code><br><code>&lt;div [style.color]="color"&gt;</code></td>
</tr>
<tr>
<td>Map binding</td>
<td><code>&lt;div [class]="classExpression"&gt;</code><br><code>&lt;div [style]="styleExpression"&gt;</code></td>
</tr>
<tr>
<td>Static value</td>
<td><code>&lt;div class="foo"&gt;</code><br><code>&lt;div style="color: blue"&gt;</code></td>
</tr>
</tbody>
</table>
1. Directive host bindings are less specific because you can use directives in multiple locations, so they have a lower precedence than template bindings.
<table width="100%">
<col width="40%"></col>
<col width="60%"></col>
<thead>
<tr>
<th>Binding type</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>Property binding</td>
<td><code>host: {'[class.foo]': 'hasFoo'}</code><br><code>host: {'[style.color]': 'color'}</code></td>
</tr>
<tr>
<td>Map binding</td>
<td><code>host: {'[class]': 'classExpr'}</code><br><code>host: {'[style]': 'styleExpr'}</code></td>
</tr>
<tr>
<td>Static value</td>
<td><code>host: {'class': 'foo'}</code><br><code>host: {'style': 'color: blue'}</code></td>
</tr>
</tbody>
</table>
1. Component host bindings have the lowest precedence.
<table width="100%">
<col width="40%"></col>
<col width="60%"></col>
<thead>
<tr>
<th>Binding type</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>Property binding</td>
<td><code>host: {'[class.foo]': 'hasFoo'}</code><br><code>host: {'[style.color]': 'color'}</code></td>
</tr>
<tr>
<td>Map binding</td>
<td><code>host: {'[class]': 'classExpression'}</code><br><code>host: {'[style]': 'styleExpression'}</code></td>
</tr>
<tr>
<td>Static value</td>
<td><code>host: {'class': 'foo'}</code><br><code>host: {'style': 'color: blue'}</code></td>
</tr>
</tbody>
</table>
## Precedence and specificity
In the following example, binding to a specific class, as in `[class.special]`, takes precedence over a generic `[class]` binding.
Similarly, binding to a specific style, as in `[style.color]`, takes precedence over a generic `[style]` binding.
<code-example path="attribute-binding/src/app/app.component.html" region="basic-specificity" header="src/app/app.component.html"></code-example>
## Precedence and bindings from different sources
Specificity rules also apply to bindings even when they originate from different sources.
An element can have bindings that originate from its own template, from host bindings on matched directives, and from host bindings on matched components.
<code-example path="attribute-binding/src/app/app.component.html" region="source-specificity" header="src/app/app.component.html"></code-example>
## Precedence of bindings and static attributes
Bindings take precedence over static attributes because they are dynamic.
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding takes precedence.
<code-example path="attribute-binding/src/app/app.component.html" region="dynamic-priority" header="src/app/app.component.html"></code-example>
{@a styling-delegation}
## Delegating to styles with lower precedence
Higher precedence styles can defer to lower precedence styles using `undefined` values.
For example, consider the following template:
<code-example path="attribute-binding/src/app/app.component.html" region="style-delegation" header="src/app/app.component.html"></code-example>
Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding.
<code-example path="attribute-binding/src/app/comp-with-host-binding.component.ts" region="hostbinding" header="src/app/comp-with-host-binding.component.ts and dirWithHostBinding.directive.ts"></code-example>
If `dirWithHostBinding` sets its binding to `undefined`, the `width` property falls back to the value of the `comp-with-host-binding` host binding.
<code-example header="dirWithHostBinding directive">
@HostBinding('style.width')
width = ''; // undefined
</code-example>
<div class="alert is-helpful">
If `dirWithHostBinding` sets its binding to `null`, Angular removes the `width` property entirely.
<code-example header="dirWithHostBinding">
@HostBinding('style.width')
width = null;
</code-example>
</div>

View File

@ -14,7 +14,7 @@ In the following example, the template statement `deleteHero()` appears in quote
<code-example path="template-syntax/src/app/app.component.html" region="context-component-statement" header="src/app/app.component.html"></code-example>
When the user clicks the **Delete hero** button, Angular calls the `deleteHero()` function in the component class.
When the user clicks the **Delete hero** button, Angular calls the `deleteHero()` method in the component class.
You can use template statements with elements, components, or directives in response to events.

View File

@ -234,8 +234,8 @@ To fix this issue, listen to both the _Enter_ key and the _blur_ event.
## Put it all together
The previous page showed how to [display data](guide/displaying-data).
This page demonstrated event binding techniques.
This page demonstrated several event binding techniques.
Now, put it all together in a micro-app
that can display a list of heroes and add new heroes to the list.

View File

@ -13,8 +13,6 @@ Choose from the following modes:
to attach a shadow DOM to the component's host element, and then puts the component
view inside that shadow DOM. The component's styles are included within the shadow DOM.
* `Native` view encapsulation uses a now deprecated version of the browser's native shadow DOM implementation - [learn about the changes](https://hayato.io/2016/shadowdomv1/).
* `Emulated` view encapsulation (the default) emulates the behavior of shadow DOM by preprocessing
(and renaming) the CSS code to effectively scope the CSS to the component's view.
For details, see [Inspecting generated CSS](guide/view-encapsulation#inspect-generated-css) below.
@ -26,7 +24,7 @@ Choose from the following modes:
To set the components encapsulation mode, use the `encapsulation` property in the component metadata:
<code-example path="component-styles/src/app/quest-summary.component.ts" region="encapsulation.native" header="src/app/quest-summary.component.ts"></code-example>
<code-example path="component-styles/src/app/quest-summary.component.ts" region="encapsulation.shadow" header="src/app/quest-summary.component.ts"></code-example>
`ShadowDom` view encapsulation only works on browsers that have native support
for shadow DOM (see [Shadow DOM v1](https://caniuse.com/#feat=shadowdomv1) on the
@ -80,4 +78,4 @@ by the generated component styles, which are in the `<head>` section of the DOM:
These styles are post-processed so that each selector is augmented
with `_nghost` or `_ngcontent` attribute selectors.
These extra selectors enable the scoping rules described in this page.
These extra selectors enable the scoping rules described in this page.

View File

@ -9,7 +9,7 @@ To understand the benefits of `NgZone`, it is important to have a clear grasp of
### Displaying and updating data in Angular
In Angular, you can [display data](guide/displaying-data) by binding controls in an HTML template to the properties of an Angular component.
In Angular, you can display data by binding controls in an HTML template to the properties of an Angular component.
<code-example path="displaying-data/src/app/app.component.1.ts" header="src/app/app.component.ts"></code-example>
@ -102,13 +102,13 @@ In Angular, this step is unnecessary. Whenever you update the data, your HTML is
To understand how change detection works, first consider when the application needs to update the HTML. Typically, updates occur for one of the following reasons:
1. Component initialization. For example, when bootstrapping an Angular application, Angular loads the bootstrap component and triggers the [ApplicationRef.tick()](api/core/ApplicationRef#tick) to call change detection and View Rendering. Just as in the [displaying data](guide/displaying-data) sample, the `AppComponent` is the bootstrap component. This component has the properties `title` and `myHero`, which the application renders in the HTML.
1. Component initialization. For example, when bootstrapping an Angular application, Angular loads the bootstrap component and triggers the [ApplicationRef.tick()](api/core/ApplicationRef#tick) to call change detection and View Rendering.
2. Event listener. The DOM event listener can update the data in an Angular component and also trigger change detection, as in the following example.
1. Event listener. The DOM event listener can update the data in an Angular component and also trigger change detection, as in the following example.
<code-example path="user-input/src/app/click-me.component.ts" region="click-me-component" header="src/app/click-me.component.ts"></code-example>
3. HTTP Data Request. You can also get data from a server through an HTTP request. For example:
1. HTTP Data Request. You can also get data from a server through an HTTP request. For example:
```typescript
@Component({

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 56 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 257 KiB

After

Width:  |  Height:  |  Size: 79 KiB

View File

@ -461,8 +461,8 @@
"name": "Sajeetharan Sinnathurai",
"picture": "sajee.jpg",
"twitter": "kokkisajee",
"website": "https://sajeetharan.herokuapp.com/",
"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.",
"website": "https://sajeetharan.com/",
"bio": "Sajeetharan is a Cloud Architect, 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.",
"groups": ["GDE"]
},
"lacolaco": {

View File

@ -106,17 +106,12 @@
"title": "User Input",
"tooltip": "User input triggers DOM events. Angular listens to those events with event bindings that funnel updated values back into your app's components and models."
},
{
"url": "guide/pipes",
"title": "Pipes",
"tooltip": "Pipes transform displayed values within a template."
},
{
"url": "guide/lifecycle-hooks",
"title": "Component Lifecycle",
"tooltip": "Angular calls lifecycle hook methods on directives and components as it creates, changes, and destroys them."
},
{
{
"url": "guide/view-encapsulation",
"title": "View Encapsulation",
"tooltip": "Describes how component CSS styles are encapsulated into a component's view."
@ -131,6 +126,11 @@
"title": "Component Styles",
"tooltip": "Add CSS styles that are specific to a component."
},
{
"url": "guide/inputs-outputs",
"title": "Inputs and Outputs",
"tooltip": "Introductory guide to sharing data between parent and child directives or components."
},
{
"url": "guide/dynamic-component-loader",
"title": "Dynamic Components",
@ -162,6 +162,11 @@
"title": "Template statements",
"tooltip": "Introductory guide to statements in templates that respond to events that components, directives, or elements raise."
},
{
"url": "guide/pipes",
"title": "Pipes",
"tooltip": "Pipes transform displayed values within a template."
},
{
"url": "guide/binding-syntax",
"title": "Binding syntax",
@ -192,11 +197,6 @@
"title": "Template reference variables",
"tooltip": "Introductory guide to referring to DOM elements within a template."
},
{
"url": "guide/inputs-outputs",
"title": "Inputs and Outputs",
"tooltip": "Introductory guide to sharing data between parent and child directives or components."
},
{
"url": "guide/template-expression-operators",
"title": "Template expression operators",
@ -609,11 +609,6 @@
"title": "Building a Template-driven Form",
"tooltip": "Create a template-driven form using directives and Angular template syntax."
},
{
"url": "guide/displaying-data",
"title": "Data binding",
"tooltip": "Property binding helps show app data in the UI."
},
{
"url": "guide/web-worker",
"title": "Web Workers",
@ -1009,6 +1004,11 @@
"title": "Stack Overflow",
"tooltip": "Stack Overflow: where the community answers your technical Angular questions."
},
{
"url": "https://discord.gg/angular",
"title": "Join Discord",
"tooltip": "Join the discussions at Angular Community Discord server."
},
{
"url": "https://gitter.im/angular/angular",
"title": "Gitter",

View File

@ -31,6 +31,7 @@
{"type": 301, "source": "/guide/quickstart", "destination": "/start"},
{"type": 301, "source": "/getting-started", "destination": "/start"},
{"type": 301, "source": "/getting-started/:rest*", "destination": "/start/:rest*"},
{"type": 301, "source": "/guide/displaying-data", "destination": "/start#template-syntax"},
// Renaming of Getting Started topics
{"type": 301, "source": "/start/data", "destination": "/start/start-data"},
@ -128,7 +129,8 @@
// The below paths are referenced in users projects generated by the CLI
{"type": 301, "source": "/config/tsconfig", "destination": "/guide/typescript-configuration"},
{"type": 301, "source": "/config/solution-tsconfig", "destination": "https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#solution-style-tsconfig"},
{"type": 301, "source": "/config/app-package-json", "destination": "/guide/strict-mode#non-local-side-effects-in-applications"}
{"type": 301, "source": "/config/app-package-json", "destination": "/guide/strict-mode#non-local-side-effects-in-applications"},
{"type": 301, "source": "/strict", "destination": "/guide/strict-mode"}
],
"rewrites": [
{

View File

@ -102,6 +102,9 @@
"!/guide/cli-quickstart",
"!/guide/cli-quickstart.html",
"!/guide/cli-quickstart/",
"!/guide/displaying-data",
"!/guide/displaying-data.html",
"!/guide/displaying-data/",
"!/guide/learning-angular",
"!/guide/learning-angular.html",
"!/guide/learning-angular/",
@ -148,6 +151,7 @@
"!/styleguide/**",
"!/testing",
"!/testing/**",
"!/config/**"
"!/config/**",
"!/strict"
]
}

View File

@ -23,7 +23,7 @@
"build-local-with-viewengine": "yarn ~~build",
"prebuild-local-with-viewengine-ci": "node scripts/switch-to-viewengine && yarn setup-local-ci",
"build-local-with-viewengine-ci": "yarn ~~build --progress=false",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 65fb6788d",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 06ad10668",
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
"test": "yarn check-env && ng test",
"pree2e": "yarn check-env && yarn update-webdriver",
@ -64,13 +64,14 @@
"tools-lint": "tslint --config \"tools/tslint.json\" --project \"tools/firebase-test-utils\"",
"tools-test": "./scripts/deploy-to-firebase.test.sh && yarn docs-test && yarn boilerplate:test && jasmine tools/ng-packages-installer/index.spec.js && yarn firebase-utils-test",
"preserve-and-sync": "yarn docs",
"serve-and-sync": "run-p \"start\" \"docs-watch --watch-only\"",
"serve-and-sync": "run-p \"docs-watch --watch-only\" \"start {@}\" --",
"boilerplate:add": "node ./tools/examples/example-boilerplate add",
"boilerplate:add:viewengine": "yarn boilerplate:add --viewengine",
"boilerplate:remove": "node ./tools/examples/example-boilerplate remove",
"boilerplate:test": "node tools/examples/test.js",
"generate-stackblitz": "node ./tools/stackblitz-builder/generateStackblitz",
"generate-zips": "node ./tools/example-zipper/generateZips",
"create-example": "node ./tools/examples/create-example.js",
"build-404-page": "node scripts/build-404-page",
"update-webdriver": "node ../scripts/webdriver-manager-update.js",
"~~audit-web-app": "node scripts/audit-web-app",
@ -153,7 +154,7 @@
"lunr": "^2.1.0",
"npm-run-all": "^4.1.5",
"protractor": "~5.4.4",
"puppeteer": "3.3.0",
"puppeteer": "5.1.0",
"rehype": "^6.0.0",
"rehype-slug": "^2.0.0",
"remark": "^9.0.0",
@ -172,6 +173,6 @@
"unist-util-visit-parents": "^1.1.1",
"watchr": "^3.0.1",
"xregexp": "^4.0.0",
"yargs": "^7.0.2"
"yargs": "^16.1.0"
}
}

View File

@ -21,7 +21,7 @@ const initialDocViewerContent = initialDocViewerElement ? initialDocViewerElemen
selector: 'aio-doc-viewer',
template: ''
// TODO(robwormald): shadow DOM and emulated don't work here (?!)
// encapsulation: ViewEncapsulation.Native
// encapsulation: ViewEncapsulation.ShadowDom
})
export class DocViewerComponent implements OnDestroy {
// Enable/Disable view transition animations.

View File

@ -18,7 +18,7 @@
* BROWSER POLYFILLS
*/
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
/** IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**

View File

@ -38,7 +38,11 @@
margin: 0;
clear: left;
}
.actions {
display: flex;
color: $blue;
@include font-size(14);
}
.show-all {
display: initial;
}

View File

@ -5,7 +5,7 @@ export function createCustomEvent(doc: Document, name: string, detail: any): Cus
const bubbles = false;
const cancelable = false;
// On IE9-11, `CustomEvent` is not a constructor.
// On IE11, `CustomEvent` is not a constructor.
if (typeof CustomEvent !== 'function') {
const event = doc.createEvent('CustomEvent');
event.initCustomEvent(name, bubbles, cancelable, detail);

View File

@ -177,6 +177,7 @@
/getting-started/forms /start/start-forms
/getting-started/deployment /start/start-deployment
/guide/cli-quickstart /start
/guide/displaying-data /start#template-syntax
/guide/learning-angular /start
/guide/learning-angular.html /start
/guide/metadata /guide/aot-compiler

View File

@ -29,11 +29,12 @@ sub-folder. Also there are a number of common boilerplate files that are needed
example's project. We maintain these common boilerplate files centrally to reduce the amount of effort
if one of them needs to change.
This `examples` tool folder contains two utilities:
This `examples` tool folder contains three utilities:
* example-boilerplate.js - install/remove the npm dependencies and boilerplate files into/from each of the
examples' subfolders.
* run-example-e2e.js - run the e2e tests for one or more examples
* create-example.js - create a new example from the `example-scaffold/` directory or by importing files from a CLI project.
See the [README.md](examples/README.md) for more details.

View File

@ -150,6 +150,14 @@ See [aio/README.md](../../README.md#developer-tasks) for the available command-l
Running the script will create an `aio/protractor-results.txt` file with the results of the tests.
### `create-example.js`
The [create-example.js](./create-example.js) script creates a new example under the `aio/content/examples` directory.
You must provide a new name for the example.
By default the script will place basic scaffold files into the new example (from [shared/example-scaffold](./shared/example-scaffold)).
But you can also specify the path to a separate CLI project, from which the script will copy files that would not be considered "boilerplate".
See the [Boilerplate overview](#boilerplate-overview) for more information.
### Updating example dependencies

View File

@ -7,9 +7,9 @@ Follow these steps to update the examples to the latest versions of Angular (and
> NOTE:
> The [angular-cli-diff](https://github.com/cexbrayat/angular-cli-diff) repo can be a useful resource for discovering what dependency versions are used for a basic CLI app at a specific CLI version.
- In the [shared/](./shared) folder, run `yarn` to update the dependencies in the [shared/node_modules/](./shared/node_modules) folder and the [shared/yarn.lock](./shared/yarn.lock) file.
- In the [shared/](./shared) directory, run `yarn` to update the dependencies in the [shared/node_modules/](./shared/node_modules) directory and the [shared/yarn.lock](./shared/yarn.lock) file.
- In the [shared/](./shared) folder, run `yarn sync-deps` to update the dependency versions of the `package.json` files in each sub-folder of [shared/boilerplate/](./shared/boilerplate) to match the ones in [shared/package.json](./shared/package.json).
- In the [shared/](./shared) directory, run `yarn sync-deps` to update the dependency versions of the `package.json` files in each sub-folder of [shared/boilerplate/](./shared/boilerplate) to match the ones in [shared/package.json](./shared/package.json).
- Follow the steps in the following section to update the rest of the boilerplate files.
@ -24,7 +24,7 @@ Any necessary changes to boilerplate files will be done automatically through mi
> You have to make these changes (if any) manually.
> Again, the [angular-cli-diff](https://github.com/cexbrayat/angular-cli-diff) repo can be a useful resource for discovering changes between versions.
- In the [shared/boilerplate/cli/](./shared/boilerplate/cli) folder, run the following commands to migrate the the project to the current versions of Angular CLI and the Angular framework (updated in previous steps):
- In the [shared/boilerplate/cli/](./shared/boilerplate/cli) directory, run the following commands to migrate the the project to the current versions of Angular CLI and the Angular framework (updated in previous steps):
```sh
# Ensure dependencies are installed.
yarn install
@ -38,8 +38,11 @@ Any necessary changes to boilerplate files will be done automatically through mi
> In order for `ng update` to work, there must be a `node_modules/` directory with installed dependencies inside the [shared/boilerplate/cli/](./shared/boilerplate/cli) directory.
> This `node_modules/` directory is only needed during the update operation and is otherwise ignored (both by git and by the [example-boilerplate.js](./example-boilerplate.js) script) by means of the [shared/boilerplate/.gitignore](./shared/boilerplate/.gitignore) file.
- The previous command made any necessary changes to boilerplate files inside the `cli/` folder, but the same changes need to be applied to the other CLI-based boilerplate folders.
Inspect the changes in `cli/` and manually apply the necessary ones to other CLI-based boilerplate folders.
- The previous command made any necessary changes to boilerplate files inside the `cli/` directory, but the same changes need to be applied to the other CLI-based boilerplate directories.
Inspect the changes in `cli/` and manually apply the necessary ones to other CLI-based boilerplate directories.
- Also ensure that any relevant changes in the [shared/boilerplate/cli/](./shared/boilerplate/cli) directory are copied to the [shared/example-scaffold/](./shared/example-scaffold) directory, which is used when creating new examples (via `yarn create-example ...`).
Only files that would not be considered boilerplate should be added to the `example-scaffold/` directory.
- Ensure any changes to [cli/tslint.json](./shared/boilerplate/cli/tslint.json) are ported over to [systemjs/tslint.json](./shared/boilerplate/systemjs/tslint.json) and also [aio/content/examples/tslint.json](../../content/examples/tslint.json).
This last part is important, since this file is used to lint example code on CI.

View File

@ -0,0 +1,6 @@
const path = require('canonical-path');
exports.EXAMPLES_BASE_PATH = path.resolve(__dirname, '../../content/examples');
exports.EXAMPLE_CONFIG_FILENAME = 'example-config.json';
exports.SHARED_PATH = path.resolve(__dirname, 'shared');
exports.STACKBLITZ_CONFIG_FILENAME = 'stackblitz.json';

View File

@ -0,0 +1,140 @@
const fs = require('fs-extra');
const glob = require('glob');
const ignore = require('ignore');
const path = require('canonical-path');
const shelljs = require('shelljs');
const yargs = require('yargs');
const {EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, SHARED_PATH, STACKBLITZ_CONFIG_FILENAME} =
require('./constants');
const BASIC_SOURCE_PATH = path.resolve(SHARED_PATH, 'example-scaffold');
shelljs.set('-e');
if (require.main === module) {
const options =
yargs(process.argv.slice(2))
.command(
'$0 <name> [source]',
[
'Create a new <name> example.',
'',
'If [source] is provided then the relevant files from the CLI project at that path are copied into the example.',
].join('\n'))
.strict()
.version(false)
.argv;
const exampleName = options.name;
const examplePath = path.resolve(EXAMPLES_BASE_PATH, exampleName);
console.log('Creating new example at', examplePath);
createEmptyExample(exampleName, examplePath);
const sourcePath =
options.source !== undefined ? path.resolve(options.source) : BASIC_SOURCE_PATH;
console.log('Copying files from', sourcePath);
copyExampleFiles(sourcePath, examplePath, exampleName);
console.log(`The new "${exampleName}" example has been created.`);
console.log('Now run "yarn boilerplate:add" to set it up for development.');
console.log(
'You can find more info on working with docs examples in aio/tools/examples/README.md.')
}
/**
* Create the directory and marker files for the new example.
*/
function createEmptyExample(exampleName, examplePath) {
ensureExamplePath(examplePath);
writeExampleConfigFile(examplePath);
writeStackBlitzFile(exampleName, examplePath);
}
/**
* Ensure that the new example directory exists.
*/
function ensureExamplePath(examplePath) {
if (fs.existsSync(examplePath)) {
throw new Error(
`Unable to create example. The path to the new example already exists: ${examplePath}`);
}
fs.ensureDirSync(examplePath);
}
/**
* Write the `example-config.json` file to the new example.
*/
function writeExampleConfigFile(examplePath) {
fs.writeFileSync(path.resolve(examplePath, EXAMPLE_CONFIG_FILENAME), '');
}
/**
* Write the `stackblitz.json` file into the new example.
*/
function writeStackBlitzFile(exampleName, examplePath) {
const config = {
description: titleize(exampleName),
files: ['!**/*.d.ts', '!**/*.js', '!**/*.[1,2].*'],
tags: [exampleName.split('-')]
};
fs.writeFileSync(
path.resolve(examplePath, STACKBLITZ_CONFIG_FILENAME),
JSON.stringify(config, null, 2) + '\n');
}
/**
* Copy all the files from the `sourcePath`, which are not ignored by the `.gitignore` file in the
* `EXAMPLES_BASE_PATH`, to the `examplePath`.
*/
function copyExampleFiles(sourcePath, examplePath, exampleName) {
const gitIgnoreSource = getGitIgnore(sourcePath);
const gitIgnoreExamples = getGitIgnore(EXAMPLES_BASE_PATH);
// Grab the files in the source folder and filter them based on the gitignore rules.
const sourceFiles =
glob.sync('**/*', {
cwd: sourcePath,
dot: true,
ignore: ['**/node_modules/**', '.git/**', '.gitignore'],
mark: true
})
// Filter out the directories, leaving only files
.filter(filePath => !/\/$/.test(filePath))
// Filter out files that match the source directory .gitignore rules
.filter(filePath => !gitIgnoreSource.ignores(filePath))
// Filter out files that match the examples directory .gitignore rules
.filter(filePath => !gitIgnoreExamples.ignores(path.join(exampleName, filePath)));
for (const sourceFile of sourceFiles) {
console.log(' - ', sourceFile);
const destPath = path.resolve(examplePath, sourceFile)
fs.ensureDirSync(path.dirname(destPath));
fs.copySync(path.resolve(sourcePath, sourceFile), destPath);
}
}
function getGitIgnore(directory) {
const gitIgnoreMatcher = ignore();
const gitignoreFilePath = path.resolve(directory, '.gitignore');
if (fs.existsSync(gitignoreFilePath)) {
const gitignoreFile = fs.readFileSync(gitignoreFilePath, 'utf8');
gitIgnoreMatcher.add(gitignoreFile);
}
return gitIgnoreMatcher;
}
/**
* Convert a kebab-case string to space separated Title Case string.
*/
function titleize(input) {
return input.replace(
/(-|^)(.)/g, (_, pre, char) => `${pre === '-' ? ' ' : ''}${char.toUpperCase()}`);
}
exports.createEmptyExample = createEmptyExample;
exports.ensureExamplePath = ensureExamplePath;
exports.writeExampleConfigFile = writeExampleConfigFile;
exports.writeStackBlitzFile = writeStackBlitzFile;
exports.copyExampleFiles = copyExampleFiles;
exports.titleize = titleize;

View File

@ -0,0 +1,130 @@
const path = require('canonical-path');
const fs = require('fs-extra');
const {glob} = require('glob');
const {EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, SHARED_PATH, STACKBLITZ_CONFIG_FILENAME} =
require('./constants');
const {
copyExampleFiles,
createEmptyExample,
ensureExamplePath,
titleize,
writeExampleConfigFile,
writeStackBlitzFile
} = require('./create-example');
describe('create-example tool', () => {
describe('createEmptyExample', () => {
it('should create an empty example with marker files', () => {
spyOn(fs, 'existsSync').and.returnValue(false);
spyOn(fs, 'ensureDirSync');
const writeFileSpy = spyOn(fs, 'writeFileSync');
createEmptyExample('foo-bar', '/path/to/foo-bar');
expect(writeFileSpy).toHaveBeenCalledTimes(2);
expect(writeFileSpy)
.toHaveBeenCalledWith(`/path/to/foo-bar/${EXAMPLE_CONFIG_FILENAME}`, jasmine.any(String));
expect(writeFileSpy)
.toHaveBeenCalledWith(
`/path/to/foo-bar/${STACKBLITZ_CONFIG_FILENAME}`, jasmine.any(String));
});
});
describe('ensureExamplePath', () => {
it('should error if the path already exists', () => {
spyOn(fs, 'existsSync').and.returnValue(true);
expect(() => ensureExamplePath('foo/bar'))
.toThrowError(
`Unable to create example. The path to the new example already exists: foo/bar`);
});
it('should create the directory on disk', () => {
spyOn(fs, 'existsSync').and.returnValue(false);
const spy = spyOn(fs, 'ensureDirSync');
ensureExamplePath('foo/bar');
expect(spy).toHaveBeenCalledWith('foo/bar');
});
});
describe('writeExampleConfigFile', () => {
it('should write a JSON file to disk', () => {
const spy = spyOn(fs, 'writeFileSync');
writeExampleConfigFile('/foo/bar');
expect(spy).toHaveBeenCalledWith(`/foo/bar/${EXAMPLE_CONFIG_FILENAME}`, '');
});
});
describe('writeStackBlitzFile', () => {
it('should write a JSON file to disk', () => {
const spy = spyOn(fs, 'writeFileSync');
writeStackBlitzFile('bar-bar', '/foo/bar-bar');
expect(spy).toHaveBeenCalledWith(`/foo/bar-bar/${STACKBLITZ_CONFIG_FILENAME}`, [
'{',
' "description": "Bar Bar",',
' "files": [',
' "!**/*.d.ts",',
' "!**/*.js",',
' "!**/*.[1,2].*"',
' ],',
' "tags": [',
' [',
' "bar",',
' "bar"',
' ]',
' ]',
'}',
'',
].join('\n'));
});
});
describe('copyExampleFiles', () => {
it('should copy over files that are not ignored by git', () => {
const examplesGitIgnorePath = path.resolve(EXAMPLES_BASE_PATH, '.gitignore');
const sourceGitIgnorePath = path.resolve('/source/path', '.gitignore');
spyOn(console, 'log');
spyOn(fs, 'existsSync').and.returnValue(true);
const readFileSyncSpy = spyOn(fs, 'readFileSync').and.callFake(p => {
switch (p) {
case examplesGitIgnorePath:
return '**/a/b/**';
case sourceGitIgnorePath:
return '**/*.bad';
default:
throw new Error('Unexpected path');
}
});
spyOn(glob, 'sync').and.returnValue([
'a/', 'a/b/', 'a/c', 'x.ts', 'x.bad', 'a/b/y.ts', 'a/b/y.bad'
]);
const ensureDirSyncSpy = spyOn(fs, 'ensureDirSync');
const copySyncSpy = spyOn(fs, 'copySync');
copyExampleFiles('/source/path', '/path/to/test-example', 'test-example');
expect(readFileSyncSpy).toHaveBeenCalledWith(examplesGitIgnorePath, 'utf8');
expect(readFileSyncSpy).toHaveBeenCalledWith(sourceGitIgnorePath, 'utf8');
expect(ensureDirSyncSpy.calls.allArgs()).toEqual([
['/path/to/test-example/a'],
['/path/to/test-example'],
]);
expect(copySyncSpy.calls.allArgs()).toEqual([
['/source/path/a/c', '/path/to/test-example/a/c'],
['/source/path/x.ts', '/path/to/test-example/x.ts'],
]);
});
});
describe('titleize', () => {
it('should convert a kebab-case string to title-case', () => {
expect(titleize('abc')).toEqual('Abc');
expect(titleize('abc-def')).toEqual('Abc Def');
expect(titleize('123')).toEqual('123');
expect(titleize('abc---def')).toEqual('Abc - Def');
});
});
});

View File

@ -4,8 +4,8 @@ const ignore = require('ignore');
const path = require('canonical-path');
const shelljs = require('shelljs');
const yargs = require('yargs');
const {EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, SHARED_PATH} = require('./constants');
const SHARED_PATH = path.resolve(__dirname, 'shared');
const SHARED_NODE_MODULES_PATH = path.resolve(SHARED_PATH, 'node_modules');
const BOILERPLATE_BASE_PATH = path.resolve(SHARED_PATH, 'boilerplate');
@ -13,9 +13,6 @@ const BOILERPLATE_CLI_PATH = path.resolve(BOILERPLATE_BASE_PATH, 'cli');
const BOILERPLATE_COMMON_PATH = path.resolve(BOILERPLATE_BASE_PATH, 'common');
const BOILERPLATE_VIEWENGINE_PATH = path.resolve(BOILERPLATE_BASE_PATH, 'viewengine');
const EXAMPLES_BASE_PATH = path.resolve(__dirname, '../../content/examples');
const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
class ExampleBoilerPlate {
/**
* Add boilerplate files to all the examples

View File

@ -14,5 +14,4 @@ last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 9-10 # Angular support for IE 9-10 has been deprecated and will be removed as of Angular v11. To opt-in, remove the 'not' prefix on this line.
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

View File

@ -18,7 +18,7 @@
* BROWSER POLYFILLS
*/
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
/** IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**

View File

@ -18,7 +18,7 @@
* BROWSER POLYFILLS
*/
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
/** IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**

View File

@ -22,7 +22,7 @@ import '@angular/localize/init';
* BROWSER POLYFILLS
*/
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
/** IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**

View File

@ -0,0 +1,20 @@
import { AppPage } from './app.po';
import { browser, logging } from 'protractor';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
// Add your e2e tests here
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});

View File

@ -0,0 +1 @@
<h1>Replace the src folder in this {{title}} with yours.</h1>

View File

@ -0,0 +1,20 @@
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
// Add your unit tests here
});

View File

@ -0,0 +1,10 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
title = 'example';
}

View File

@ -0,0 +1,16 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Ponyracer</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>

View File

@ -0,0 +1,12 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

View File

@ -76,7 +76,7 @@
"lite-server": "^2.2.2",
"lodash": "^4.16.2",
"protractor": "~7.0.0",
"puppeteer": "3.3.0",
"puppeteer": "5.1.0",
"rimraf": "^2.5.4",
"rollup": "^1.1.0",
"rollup-plugin-commonjs": "^9.2.1",

View File

@ -4336,6 +4336,11 @@ dev-ip@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/dev-ip/-/dev-ip-1.0.1.tgz#a76a3ed1855be7a012bb8ac16cb80f3c00dc28f0"
devtools-protocol@0.0.767361:
version "0.0.767361"
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.767361.tgz#5977f2558b84f9df36f62501bdddb82f3ae7b66b"
integrity sha512-ziRTdhEVQ9jEwedaUaXZ7kl9w9TF/7A3SXQ0XuqrJB+hMS62POHZUWTbumDN2ehRTfvWqTPc2Jw4gUl/jggmHA==
dezalgo@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456"
@ -7704,6 +7709,11 @@ mitt@^1.1.3:
resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.2.0.tgz#cb24e6569c806e31bd4e3995787fe38a04fdf90d"
integrity sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==
mitt@^2.0.1:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mitt/-/mitt-2.1.0.tgz#f740577c23176c6205b121b2973514eade1b2230"
integrity sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==
mixin-deep@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.0.tgz#47a8732ba97799457c8c1eca28f95132d7e8150a"
@ -8759,7 +8769,7 @@ pkg-dir@^3.0.0:
dependencies:
find-up "^3.0.0"
pkg-dir@^4.1.0:
pkg-dir@^4.1.0, pkg-dir@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
@ -9363,15 +9373,18 @@ punycode@^2.1.1:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
puppeteer@3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-3.3.0.tgz#95839af9fdc0aa4de7e5ee073a4c0adeb9e2d3d7"
integrity sha512-23zNqRltZ1PPoK28uRefWJ/zKb5Jhnzbbwbpcna2o5+QMn17F0khq5s1bdH3vPlyj+J36pubccR8wiNA/VE0Vw==
puppeteer@5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-5.1.0.tgz#e7bae2caa6e3a13a622755e4c27689d9812c38ca"
integrity sha512-IZBFG8XcA+oHxYo5rEpJI/HQignUis2XPijPoFpNxla2O+WufonGsUsSqrhRXgBKOME5zNfhRdUY2LvxAiKlhw==
dependencies:
debug "^4.1.0"
devtools-protocol "0.0.767361"
extract-zip "^2.0.0"
https-proxy-agent "^4.0.0"
mime "^2.0.3"
mitt "^2.0.1"
pkg-dir "^4.2.0"
progress "^2.0.1"
proxy-from-env "^1.0.0"
rimraf "^3.0.2"

View File

@ -132,11 +132,11 @@
<summary>
<div class="icon-action-header">
<h4 class="no-anchor">{$ method.overloads.length $} overloads...</h4>
<a>
<span class="actions">
<span class="show-all">Show All</span>
<span class="collapse-all">Hide All</span>
<i class="material-icons expand">expand_more</i>
</a>
</span>
</div>
</summary>
<div class="detail-contents">

View File

@ -3075,11 +3075,6 @@ camelcase@^2.0.1:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=
camelcase@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo=
camelcase@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
@ -3459,7 +3454,7 @@ cli-width@^3.0.0:
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
cliui@^3.0.3, cliui@^3.2.0:
cliui@^3.0.3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=
@ -3495,6 +3490,15 @@ cliui@^6.0.0:
strip-ansi "^6.0.0"
wrap-ansi "^6.2.0"
cliui@^7.0.2:
version "7.0.2"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.2.tgz#e3a412e1d5ec0ccbe50d1b4120fc8164e97881f4"
integrity sha512-lhpKkuUj67j5JgZIPZxLe7nSa4MQoojzRVWQyzMqBp2hBg6gwRjUDAwC1YDeBaC3APDBKNnjWbv2mlDF4XgOSA==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.0"
wrap-ansi "^7.0.0"
clone@^1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
@ -4509,6 +4513,11 @@ detect-node@^2.0.4:
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
devtools-protocol@0.0.767361:
version "0.0.767361"
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.767361.tgz#5977f2558b84f9df36f62501bdddb82f3ae7b66b"
integrity sha512-ziRTdhEVQ9jEwedaUaXZ7kl9w9TF/7A3SXQ0XuqrJB+hMS62POHZUWTbumDN2ehRTfvWqTPc2Jw4gUl/jggmHA==
dezalgo@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456"
@ -4900,7 +4909,7 @@ errno@^0.1.1, errno@^0.1.3, errno@~0.1.7:
dependencies:
prr "~1.0.1"
error-ex@^1.2.0, error-ex@^1.3.1:
error-ex@^1.3.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
@ -5012,6 +5021,11 @@ es6-weak-map@^2.0.1, es6-weak-map@^2.0.2:
es6-iterator "^2.0.3"
es6-symbol "^3.1.1"
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@ -5578,14 +5592,6 @@ find-free-port@^2.0.0:
resolved "https://registry.yarnpkg.com/find-free-port/-/find-free-port-2.0.0.tgz#4b22e5f6579eb1a38c41ac6bcb3efed1b6da9b1b"
integrity sha1-SyLl9leesaOMQaxryz7+0bbamxs=
find-up@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=
dependencies:
path-exists "^2.0.0"
pinkie-promise "^2.0.0"
find-up@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
@ -5920,7 +5926,7 @@ get-caller-file@^1.0.1:
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
get-caller-file@^2.0.1:
get-caller-file@^2.0.1, get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
@ -7369,11 +7375,6 @@ is-url@^1.2.2:
resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52"
integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
is-utf8@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
is-whitespace-character@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7"
@ -8132,17 +8133,6 @@ listenercount@~1.0.1:
resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937"
integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=
load-json-file@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=
dependencies:
graceful-fs "^4.1.2"
parse-json "^2.2.0"
pify "^2.0.0"
pinkie-promise "^2.0.0"
strip-bom "^2.0.0"
load-json-file@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
@ -8926,6 +8916,11 @@ mississippi@^3.0.0:
stream-each "^1.1.0"
through2 "^2.0.0"
mitt@^2.0.1:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mitt/-/mitt-2.1.0.tgz#f740577c23176c6205b121b2973514eade1b2230"
integrity sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==
mixin-deep@^1.2.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566"
@ -9814,13 +9809,6 @@ parse-entities@^1.0.2, parse-entities@^1.1.0:
is-decimal "^1.0.0"
is-hexadecimal "^1.0.0"
parse-json@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=
dependencies:
error-ex "^1.2.0"
parse-json@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
@ -9900,13 +9888,6 @@ path-dirname@^1.0.0:
resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=
path-exists@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=
dependencies:
pinkie-promise "^2.0.0"
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
@ -9949,15 +9930,6 @@ path-to-regexp@^1.7.0:
dependencies:
isarray "0.0.1"
path-type@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=
dependencies:
graceful-fs "^4.1.2"
pify "^2.0.0"
pinkie-promise "^2.0.0"
path-type@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
@ -10040,7 +10012,7 @@ pkg-dir@^3.0.0:
dependencies:
find-up "^3.0.0"
pkg-dir@^4.1.0:
pkg-dir@^4.1.0, pkg-dir@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
@ -10695,15 +10667,18 @@ punycode@^2.1.0, punycode@^2.1.1:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
puppeteer@3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-3.3.0.tgz#95839af9fdc0aa4de7e5ee073a4c0adeb9e2d3d7"
integrity sha512-23zNqRltZ1PPoK28uRefWJ/zKb5Jhnzbbwbpcna2o5+QMn17F0khq5s1bdH3vPlyj+J36pubccR8wiNA/VE0Vw==
puppeteer@5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-5.1.0.tgz#e7bae2caa6e3a13a622755e4c27689d9812c38ca"
integrity sha512-IZBFG8XcA+oHxYo5rEpJI/HQignUis2XPijPoFpNxla2O+WufonGsUsSqrhRXgBKOME5zNfhRdUY2LvxAiKlhw==
dependencies:
debug "^4.1.0"
devtools-protocol "0.0.767361"
extract-zip "^2.0.0"
https-proxy-agent "^4.0.0"
mime "^2.0.3"
mitt "^2.0.1"
pkg-dir "^4.2.0"
progress "^2.0.1"
proxy-from-env "^1.0.0"
rimraf "^3.0.2"
@ -10859,23 +10834,6 @@ read-package-tree@5.3.1:
readdir-scoped-modules "^1.0.0"
util-promisify "^2.1.0"
read-pkg-up@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=
dependencies:
find-up "^1.0.0"
read-pkg "^1.0.0"
read-pkg@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=
dependencies:
load-json-file "^1.0.0"
normalize-package-data "^2.3.2"
path-type "^1.0.0"
read-pkg@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
@ -12368,7 +12326,7 @@ string-length@^1.0.0:
dependencies:
strip-ansi "^3.0.0"
string-width@^1.0.1, string-width@^1.0.2:
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
@ -12500,13 +12458,6 @@ strip-ansi@^6.0.0:
dependencies:
ansi-regex "^5.0.0"
strip-bom@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=
dependencies:
is-utf8 "^0.2.0"
strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
@ -13997,11 +13948,6 @@ when@~3.6.x:
resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e"
integrity sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=
which-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=
which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
@ -14101,6 +14047,15 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
@ -14233,7 +14188,7 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1:
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^3.2.0, y18n@^3.2.1:
y18n@^3.2.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
@ -14243,6 +14198,11 @@ y18n@^3.2.0, y18n@^3.2.1:
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
y18n@^5.0.2:
version "5.0.3"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.3.tgz#978115b82befe2b5c762bf55980b7b01a4a2d5d9"
integrity sha512-JeFbcHQ/7hVmMBXW6UB6Tg7apStHd/ztGz1JN78y3pFi/q0Ht1eA6PVkvw56gm7UA8fcJR/ziRlYEDMGoju0yQ==
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
@ -14282,12 +14242,10 @@ yargs-parser@^18.1.0, yargs-parser@^18.1.1, yargs-parser@^18.1.3:
camelcase "^5.0.0"
decamelize "^1.2.0"
yargs-parser@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=
dependencies:
camelcase "^3.0.0"
yargs-parser@^20.2.2:
version "20.2.2"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.2.tgz#84562c6b1c41ccec2f13d346c7dd83f8d1a0dc70"
integrity sha512-XmrpXaTl6noDsf1dKpBuUNCOHqjs0g3jRMXf/ztRxdOmb+er8kE5z5b55Lz3p5u2T8KJ59ENBnASS8/iapVJ5g==
yargs@15.3.0:
version "15.3.0"
@ -14370,24 +14328,18 @@ yargs@^15.3.1:
y18n "^4.0.0"
yargs-parser "^18.1.1"
yargs@^7.0.2:
version "7.1.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8"
integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=
yargs@^16.1.0:
version "16.1.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.1.0.tgz#fc333fe4791660eace5a894b39d42f851cd48f2a"
integrity sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g==
dependencies:
camelcase "^3.0.0"
cliui "^3.2.0"
decamelize "^1.1.1"
get-caller-file "^1.0.1"
os-locale "^1.4.0"
read-pkg-up "^1.0.1"
cliui "^7.0.2"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
require-main-filename "^1.0.1"
set-blocking "^2.0.0"
string-width "^1.0.2"
which-module "^1.0.0"
y18n "^3.2.1"
yargs-parser "^5.0.0"
string-width "^4.2.0"
y18n "^5.0.2"
yargs-parser "^20.2.2"
yauzl@^2.10.0:
version "2.10.0"

View File

@ -1,5 +1,5 @@
load("@build_bazel_rules_nodejs//:index.bzl", "pkg_npm")
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "cli",
@ -49,7 +49,7 @@ pkg_npm(
# substitutions to replace these in the published version of dev-infra.
"//dev-infra/": "@npm_angular_dev_infra_private//",
"//packages/benchpress": "@npm//@angular/benchpress",
"//packages/bazel/": "@npm_angular_bazel//",
"//packages/bazel": "@npm//@angular/bazel",
"//packages/zone.js/bundles:zone.umd.js": "@npm//:node_modules/zone.js/dist/zone.js",
"//packages/core": "@npm//@angular/core",
"//packages/platform-browser": "@npm//@angular/platform-browser",
@ -57,7 +57,7 @@ pkg_npm(
# This substitution is particularly verbose because we need to make sure
# that only things available via Angular Bazel are imported from
# tools/defaults.bzl.
"load\(\"//tools:defaults.bzl\", \"ng_module\"\)": "load(\"@npm_angular_bazel//:index.bzl\", \"ng_module\")",
"load\(\"//tools:defaults.bzl\", \"ng_module\"\)": "load(\"@npm//@angular/bazel:index.bzl\", \"ng_module\")",
},
visibility = ["//visibility:public"],
deps = [

View File

@ -1,4 +1,4 @@
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
load("@npm//@bazel/protractor:index.bzl", "protractor_web_test_suite")
"""
Macro that can be used to define a benchmark test. This differentiates from

View File

@ -1,6 +1,6 @@
load("//dev-infra/benchmark/ng_rollup_bundle:ng_rollup_bundle.bzl", "ng_rollup_bundle")
load("//tools:defaults.bzl", "ng_module")
load("@npm_bazel_typescript//:index.bzl", "ts_devserver", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_devserver", "ts_library")
load(":benchmark_test.bzl", "benchmark_test")
def copy_default_file(origin, destination):

View File

@ -1,6 +1,6 @@
package(default_visibility = ["//visibility:public"])
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "driver-utilities",

View File

@ -4,8 +4,8 @@
# found in the LICENSE file at https://angular.io/license
load("@build_bazel_rules_nodejs//:index.bzl", "npm_package_bin")
load("@npm_bazel_terser//:index.bzl", "terser_minified")
load("@npm_bazel_rollup//:index.bzl", "rollup_bundle")
load("@npm//@bazel/terser:index.bzl", "terser_minified")
load("@npm//@bazel/rollup:index.bzl", "rollup_bundle")
load("//dev-infra/bazel:expand_template.bzl", "expand_template")
def ng_rollup_bundle(

View File

@ -12,47 +12,47 @@ def define_chromium_repositories():
platform_http_file(
name = "org_chromium_chromium_amd64",
licenses = ["notice"], # BSD 3-clause (maybe more?)
sha256 = "2cfd74ee58c79d8b7aada05c899a930967e2fd8bb0186582cde02c7340863f64",
# 83.0.4103
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/756066/chrome-linux.zip"],
sha256 = "0e303931d9c3e065a160f5d31f1178c647f0748fb0b58b1945b84b04fe1c1165",
# 84.0.4147
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/768968/chrome-linux.zip"],
)
platform_http_file(
name = "org_chromium_chromium_macos",
licenses = ["notice"], # BSD 3-clause (maybe more?)
sha256 = "b841ec5ad03b08422d97593fc719f1c5b038703388ad65e6cd8cc8272d58958c",
# 83.0.4103
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/756053/chrome-mac.zip"],
sha256 = "39118c96db1b3fdb0129f434912a329c5ca07d3a1c6c6cda673d3383d83e2f9a",
# 84.0.4147
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/768968/chrome-mac.zip"],
)
platform_http_file(
name = "org_chromium_chromium_windows",
licenses = ["notice"], # BSD 3-clause (maybe more?)
sha256 = "4683d7ac88dfec4b98d1da3012ecc8e42cc8c1a560a7b95589ad4cc96bf90fcb",
# 83.0.4103
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Win/756065/chrome-win.zip"],
sha256 = "3429746fa80c917c6f4d5d96aba4e58894b905a2b8392e43ddb470c5ba612d60",
# 84.0.4147
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Win/768975/chrome-win.zip"],
)
platform_http_file(
name = "org_chromium_chromedriver_amd64",
licenses = ["reciprocal"], # BSD 3-clause, ICU, MPL 1.1, libpng (BSD/MIT-like), Academic Free License v. 2.0, BSD 2-clause, MIT
sha256 = "95dded16000b82e31445361da7d251ed707e027a4b61e9a3ec5fbd1cc2f62bb1",
# 83.0.4103
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/756066/chromedriver_linux64.zip"],
sha256 = "f6b9852031d185739a2c1816508fe8158eb92782d13e831b8345957ef2506fe8",
# 84.0.4147
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/768968/chromedriver_linux64.zip"],
)
platform_http_file(
name = "org_chromium_chromedriver_macos",
licenses = ["reciprocal"], # BSD 3-clause, ICU, MPL 1.1, libpng (BSD/MIT-like), Academic Free License v. 2.0, BSD 2-clause, MIT
sha256 = "17260e9b2222b0c905a1861285210192baef830f4281778903e7cebb8db683cc",
# 83.0.4103
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/756053/chromedriver_mac64.zip"],
sha256 = "aa0124085146556d5d32ad172670e5dcef79b7429380112ad02898047ba7a8b7",
# 84.0.4147
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/768968/chromedriver_mac64.zip"],
)
platform_http_file(
name = "org_chromium_chromedriver_windows",
licenses = ["reciprocal"], # BSD 3-clause, ICU, MPL 1.1, libpng (BSD/MIT-like), Academic Free License v. 2.0, BSD 2-clause, MIT
sha256 = "de1423b2d69f96e451e902d686e8d471610d786c345a8de59dd1a5a436e45fc2",
# 83.0.4103
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Win/756065/chromedriver_win32.zip"],
sha256 = "c4b04fd263e757d3aa99c596832f2c414f9f00e80d2769590e2b9044072b140e",
# 84.0.4147
urls = ["https://commondatastorage.googleapis.com/chromium-browser-snapshots/Win/768975/chromedriver_win32.zip"],
)

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "caretaker",

View File

@ -35,31 +35,17 @@ export async function printG3Comparison(git: GitClient) {
return;
}
/** Random prefix to create unique branch names. */
const randomPrefix = `prefix${Math.floor(Math.random() * 1000000)}`;
/** Ref name of the temporary master branch. */
const masterRef = `${randomPrefix}-master`;
/** Ref name of the temporary g3 branch. */
const g3Ref = `${randomPrefix}-g3`;
/** Url of the ref for fetching master and g3 branches. */
const refUrl = `https://github.com/${git.remoteConfig.owner}/${git.remoteConfig.name}.git`;
/** The result fo the fetch command. */
const fetchResult =
git.runGraceful(['fetch', '-q', refUrl, `master:${masterRef}`, `g3:${g3Ref}`]);
/** The latest sha for the g3 branch. */
const g3Ref = getShaForBranchLatest('g3');
/** The latest sha for the master branch. */
const masterRef = getShaForBranchLatest('master');
// If the upstream repository does not have a g3 branch to compare to, skip the comparison.
if (fetchResult.status !== 0) {
if (fetchResult.stderr.includes(`couldn't find remote ref g3`)) {
return debug('No g3 branch exists on upstream, skipping.');
}
throw Error('Fetch of master and g3 branches for comparison failed.');
if (!g3Ref && !masterRef) {
return debug('Exiting early as either the g3 or master was unable to be retrieved');
}
/** The statistical information about the git diff between master and g3. */
const stats = getDiffStats(git);
// Delete the temporarily created mater and g3 branches.
git.runGraceful(['branch', '-D', masterRef, g3Ref]);
const stats = getDiffStats();
info.group(bold('g3 branch check'));
info(`${stats.commits} commits between g3 and master`);
@ -73,11 +59,27 @@ export async function printG3Comparison(git: GitClient) {
info();
/** Fetch and retrieve the latest sha for a specific branch. */
function getShaForBranchLatest(branch: string) {
/** The result fo the fetch command. */
const fetchResult = git.runGraceful([
'fetch', '-q', `https://github.com/${git.remoteConfig.owner}/${git.remoteConfig.name}.git`,
branch
]);
if (fetchResult.status !== 0 &&
fetchResult.stderr.includes(`couldn't find remote ref ${branch}`)) {
debug(`No '${branch}' branch exists on upstream, skipping.`);
return false;
}
return git.runGraceful(['rev-parse', 'FETCH_HEAD']).stdout.trim();
}
/**
* Get git diff stats between master and g3, for all files and filtered to only g3 affecting
* files.
*/
function getDiffStats(git: GitClient) {
function getDiffStats() {
/** The diff stats to be returned. */
const stats = {
insertions: 0,
@ -86,7 +88,6 @@ export async function printG3Comparison(git: GitClient) {
commits: 0,
};
// Determine the number of commits between master and g3 refs. */
stats.commits = parseInt(git.run(['rev-list', '--count', `${g3Ref}..${masterRef}`]).stdout, 10);

View File

@ -6,12 +6,17 @@
* found in the LICENSE file at https://angular.io/license
*/
import {alias, params, types} from 'typed-graphqlify';
import {alias, onUnion, params, types} from 'typed-graphqlify';
import {bold, debug, info} from '../../utils/console';
import {GitClient} from '../../utils/git';
import {CaretakerConfig} from '../config';
/**
* Cap the returned issues in the queries to an arbitrary 100. At that point, caretaker has a lot
* of work to do and showing more than that isn't really useful.
*/
const MAX_RETURNED_ISSUES = 20;
/** Retrieve the number of matching issues for each github query. */
export async function printGithubTasks(git: GitClient, config?: CaretakerConfig) {
@ -19,7 +24,7 @@ export async function printGithubTasks(git: GitClient, config?: CaretakerConfig)
debug('No github queries defined in the configuration, skipping.');
return;
}
info.group(bold('Github Tasks'));
info.group(bold(`Github Tasks`));
await getGithubInfo(git, config);
info.groupEnd();
info();
@ -28,7 +33,12 @@ export async function printGithubTasks(git: GitClient, config?: CaretakerConfig)
/** Retrieve query match counts and log discovered counts to the console. */
async function getGithubInfo(git: GitClient, {githubQueries: queries = []}: CaretakerConfig) {
/** The query object for graphql. */
const graphQlQuery: {[key: string]: {issueCount: number}} = {};
const graphQlQuery: {
[key: string]: {
issueCount: number,
nodes: Array<{url: string}>,
}
} = {};
/** The Github search filter for the configured repository. */
const repoFilter = `repo:${git.remoteConfig.owner}/${git.remoteConfig.name}`;
queries.forEach(({name, query}) => {
@ -37,14 +47,37 @@ async function getGithubInfo(git: GitClient, {githubQueries: queries = []}: Care
graphQlQuery[queryKey] = params(
{
type: 'ISSUE',
first: MAX_RETURNED_ISSUES,
query: `"${repoFilter} ${query.replace(/"/g, '\\"')}"`,
},
{issueCount: types.number},
{
issueCount: types.number,
nodes: [{...onUnion({
PullRequest: {
url: types.string,
},
Issue: {
url: types.string,
},
})}],
},
);
});
/** The results of the generated github query. */
const results = await git.github.graphql.query(graphQlQuery);
Object.values(results).forEach((result, i) => {
info(`${queries[i]?.name.padEnd(25)} ${result.issueCount}`);
if (result.issueCount > 0) {
const {owner, name: repo} = git.remoteConfig;
const url = encodeURI(`https://github.com/${owner}/${repo}/issues?q=${queries[i]?.query}`);
info.group(`${url}`);
if (result.nodes.length === MAX_RETURNED_ISSUES && result.nodes.length < result.issueCount) {
info(`(first ${MAX_RETURNED_ISSUES})`);
}
for (const node of result.nodes) {
info(`- ${node.url}`);
}
info.groupEnd();
}
});
}

View File

@ -1,5 +1,5 @@
load("//tools:defaults.bzl", "jasmine_node_test")
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "commit-message",

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "format",

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "ngbot",

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "pr",

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "checkout",

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "common",

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "discover-new-conflicts",

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
load("//tools:defaults.bzl", "jasmine_node_test")
ts_library(

View File

@ -41,8 +41,8 @@ export async function getDefaultTargetLabelConfiguration(
// allow merging of PRs with `target: major`.
if (!next.isMajor) {
throw new InvalidTargetLabelError(
`Unable to merge pull request. The "${nextBranchName}" branch will be ` +
`released as a minor version.`);
`Unable to merge pull request. The "${nextBranchName}" branch will be released as ` +
'a minor version.');
}
return [nextBranchName];
},

View File

@ -30,8 +30,8 @@ export async function assertActiveLtsBranch(
const ltsNpmTag = getLtsNpmDistTagOfMajor(version.major);
const ltsVersion = semver.parse(distTags[ltsNpmTag]);
// Ensure that there is a LTS version tagged for the given version-branch major. e.g.
// if the version branch is `9.2.x` then we want to make sure that there is a LTS
// Ensure that there is an LTS version tagged for the given version-branch major. e.g.
// if the version branch is `9.2.x` then we want to make sure that there is an LTS
// version tagged in NPM for `v9`, following the `v{major}-lts` tag convention.
if (ltsVersion === null) {
throw new InvalidTargetBranchError(`No LTS version tagged for v${version.major} in NPM.`);

View File

@ -33,7 +33,7 @@ export async function mergePullRequest(
prNumber: number, githubToken: string, projectRoot: string = getRepoBaseDir(),
config?: MergeConfigWithRemote) {
// Set the environment variable to skip all git commit hooks triggered by husky. We are unable to
// rely on `---no-verify` as some hooks still run, notably the `prepare-commit-msg` hook.
// rely on `--no-verify` as some hooks still run, notably the `prepare-commit-msg` hook.
process.env['HUSKY_SKIP_HOOKS'] = '1';
const api = await createPullRequestMergeTask(githubToken, projectRoot, config);

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "rebase",

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
load("//tools:defaults.bzl", "jasmine_node_test")
ts_library(

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "release",

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
load("//tools:defaults.bzl", "jasmine_node_test")
ts_library(

View File

@ -60,7 +60,7 @@ describe('ng-dev release build', () => {
});
it('should error if package has not been built', async () => {
// Set up a NPM package that is not built.
// Set up an NPM package that is not built.
npmPackages.push('@angular/non-existent');
spyOn(console, 'error');

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "config",

View File

@ -1,4 +1,4 @@
load("@npm_bazel_typescript//:index.bzl", "ts_library")
load("@npm//@bazel/typescript:index.bzl", "ts_library")
ts_library(
name = "publish",

View File

@ -7,7 +7,7 @@
*/
import {promises as fs} from 'fs';
import * as Ora from 'ora';
import * as ora from 'ora';
import {join} from 'path';
import * as semver from 'semver';
@ -44,7 +44,7 @@ export interface PullRequest {
forkBranch: string;
}
/** Constructor type for a instantiating a release action */
/** Constructor type for instantiating a release action */
export interface ReleaseActionConstructor<T extends ReleaseAction = ReleaseAction> {
/** Whether the release action is currently active. */
isActive(active: ActiveReleaseTrains): Promise<boolean>;
@ -107,25 +107,22 @@ export abstract class ReleaseAction {
if (state === 'failure') {
error(
red(` ✘ Cannot stage release. Commit "${commitSha}" does not pass all github ` +
`status checks. Please make sure this commit passes all checks before re-running.`));
'status checks. Please make sure this commit passes all checks before re-running.'));
error(` Please have a look at: ${branchCommitsUrl}`);
if (await promptConfirm('Do you want to ignore the Github status and proceed?')) {
info(yellow(
` ⚠ Upstream commit is failing CI checks, but status has been ` +
`forcibly ignored.`));
' ⚠ Upstream commit is failing CI checks, but status has been forcibly ignored.'));
return;
}
throw new UserAbortedReleaseActionError();
} else if (state === 'pending') {
error(
red(` ✘ Commit "${commitSha}" still has pending github statuses that ` +
`need to succeed before staging a release.`));
'need to succeed before staging a release.'));
error(red(` Please have a look at: ${branchCommitsUrl}`));
if (await promptConfirm('Do you want to ignore the Github status and proceed?')) {
info(yellow(
` ⚠ Upstream commit is pending CI, but status has been ` +
`forcibly ignored.`));
info(yellow(' ⚠ Upstream commit is pending CI, but status has been forcibly ignored.'));
return;
}
throw new UserAbortedReleaseActionError();
@ -157,9 +154,9 @@ export abstract class ReleaseAction {
*/
protected async waitForEditsAndCreateReleaseCommit(newVersion: semver.SemVer) {
info(yellow(
` ⚠ Please review the changelog and ensure that the log contains only changes ` +
`that apply to the public API surface. Manual changes can be made. When done, please ` +
`proceed with the prompt below.`));
' ⚠ Please review the changelog and ensure that the log contains only changes ' +
'that apply to the public API surface. Manual changes can be made. When done, please ' +
'proceed with the prompt below.'));
if (!await promptConfirm('Do you want to proceed and commit the changes?')) {
throw new UserAbortedReleaseActionError();
@ -188,7 +185,7 @@ export abstract class ReleaseAction {
const forks = result.repository.forks.nodes;
if (forks.length === 0) {
error(red(` ✘ Unable to find fork for currently authenticated user.`));
error(red(' ✘ Unable to find fork for currently authenticated user.'));
error(red(` Please ensure you created a fork of: ${owner}/${name}.`));
throw new FatalReleaseActionError();
}
@ -304,7 +301,7 @@ export abstract class ReleaseAction {
return new Promise((resolve, reject) => {
debug(`Waiting for pull request #${id} to be merged.`);
const spinner = Ora().start(`Waiting for pull request #${id} to be merged.`);
const spinner = ora().start(`Waiting for pull request #${id} to be merged.`);
const intervalId = setInterval(async () => {
const prState = await getPullRequestState(this.git, id);
if (prState === 'merged') {
@ -451,7 +448,7 @@ export abstract class ReleaseAction {
info(green(
` ✓ Pull request for cherry-picking the changelog into "${nextBranch}" ` +
`has been created.`));
'has been created.'));
info(yellow(` Please ask team members to review: ${url}.`));
return true;
}
@ -490,7 +487,7 @@ export abstract class ReleaseAction {
if (!await this._isCommitForVersionStaging(newVersion, versionBumpCommitSha)) {
error(red(` ✘ Latest commit in "${publishBranch}" branch is not a staging commit.`));
error(red(` Please make sure the staging pull request has been merged.`));
error(red(' Please make sure the staging pull request has been merged.'));
throw new FatalReleaseActionError();
}
@ -514,13 +511,13 @@ export abstract class ReleaseAction {
await this._publishBuiltPackageToNpm(builtPackage, npmDistTag);
}
info(green(` ✓ Published all packages successfully`));
info(green(' ✓ Published all packages successfully'));
}
/** Publishes the given built package to NPM with the specified NPM dist tag. */
private async _publishBuiltPackageToNpm(pkg: BuiltPackage, npmDistTag: string) {
debug(`Starting publish of "${pkg.name}".`);
const spinner = Ora().start(`Publishing "${pkg.name}"`);
const spinner = ora().start(`Publishing "${pkg.name}"`);
try {
await runNpmPublish(pkg.outputPath, npmDistTag, this.config.publishRegistry);

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