Compare commits
59 Commits
6.1.0
...
6.0.0-rc.6
Author | SHA1 | Date | |
---|---|---|---|
4008e36e80 | |||
e47bb52084 | |||
ac2b530f4b | |||
64bf6edf00 | |||
adf6235479 | |||
04c18ac1aa | |||
1b26dd8cdb | |||
f721b06bde | |||
0bc8443e12 | |||
db17231597 | |||
540626a3a6 | |||
391bfcede5 | |||
d8de6488dd | |||
151fb66848 | |||
02424ff0d0 | |||
f0925d9705 | |||
212b806eda | |||
b9431e88fb | |||
7790cfa0d0 | |||
41b5149509 | |||
06f865640d | |||
824f74f27b | |||
5301c43eed | |||
f280d1aef1 | |||
5e741d42a6 | |||
0035d41030 | |||
08f447ceec | |||
8953f123e3 | |||
6274007e3b | |||
ee76be7783 | |||
a8c720bc3a | |||
ac47a3cd93 | |||
041458a3d2 | |||
2cb74b748f | |||
cb0bfe7a43 | |||
8ee11aeaa6 | |||
bf89fcb361 | |||
4f70c5b6f7 | |||
ad3ebec2a5 | |||
3f5d61f2dd | |||
11ada7f78b | |||
0b96bc7456 | |||
fefadadff3 | |||
946057ae29 | |||
d4293aaaaa | |||
e3dcc227f6 | |||
c9230dd90e | |||
234af9ba59 | |||
7204028d3e | |||
f7c55952bf | |||
e38e3bd135 | |||
cd20c01ba1 | |||
12a191ef3f | |||
65e67b3c3a | |||
32e57f6197 | |||
7de69ba29b | |||
44193c0b94 | |||
6db8241ffa | |||
33c594516c |
@ -153,7 +153,7 @@ groups:
|
||||
- "packages/compiler/src/i18n/*"
|
||||
users:
|
||||
- vicb #primary
|
||||
- chuckjaz
|
||||
- alxhub
|
||||
- IgorMinar #fallback
|
||||
- mhevery #fallback
|
||||
|
||||
@ -187,7 +187,7 @@ groups:
|
||||
- "packages/compiler-cli/src/ngtools*"
|
||||
users:
|
||||
- alexeagle
|
||||
- chuckjaz
|
||||
- alxhub
|
||||
- vicb
|
||||
- IgorMinar #fallback
|
||||
- mhevery #fallback
|
||||
|
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,3 +1,16 @@
|
||||
<a name="6.0.0-rc.6"></a>
|
||||
# [6.0.0-rc.6](https://github.com/angular/angular/compare/6.0.0-rc.5...6.0.0-rc.6) (2018-04-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** avoid a crash in ngc-wrapped. ([#23468](https://github.com/angular/angular/issues/23468)) ([0bc8443](https://github.com/angular/angular/commit/0bc8443))
|
||||
* **compiler:** handle undefined annotation metadata ([#23349](https://github.com/angular/angular/issues/23349)) ([b9431e8](https://github.com/angular/angular/commit/b9431e8))
|
||||
* **router:** cache route handle if found ([#22475](https://github.com/angular/angular/issues/22475)) ([d8de648](https://github.com/angular/angular/commit/d8de648)), closes [#22474](https://github.com/angular/angular/issues/22474)
|
||||
* **service-worker:** add badge to NOTIFICATION_OPTION_NAMES ([#23241](https://github.com/angular/angular/issues/23241)) ([fb59b2d](https://github.com/angular/angular/commit/fb59b2d)), closes [#23196](https://github.com/angular/angular/issues/23196)
|
||||
|
||||
|
||||
|
||||
<a name="5.2.10"></a>
|
||||
## [5.2.10](https://github.com/angular/angular/compare/5.2.9...5.2.10) (2018-04-16)
|
||||
|
||||
|
@ -1,73 +0,0 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"project": {
|
||||
"name": "site"
|
||||
},
|
||||
"apps": [
|
||||
{
|
||||
"root": "src",
|
||||
"outDir": "dist",
|
||||
"assets": [
|
||||
"assets",
|
||||
"generated",
|
||||
"app/search/search-worker.js",
|
||||
"favicon.ico",
|
||||
"pwa-manifest.json",
|
||||
"google385281288605d160.html",
|
||||
{ "glob": "custom-elements.min.js", "input": "../node_modules/@webcomponents/custom-elements", "output": "./assets/js" },
|
||||
{ "glob": "native-shim.js", "input": "../node_modules/@webcomponents/custom-elements/src", "output": "./assets/js" }
|
||||
],
|
||||
"index": "index.html",
|
||||
"main": "main.ts",
|
||||
"polyfills": "polyfills.ts",
|
||||
"test": "test.ts",
|
||||
"tsconfig": "tsconfig.app.json",
|
||||
"testTsconfig": "tsconfig.spec.json",
|
||||
"prefix": "aio",
|
||||
"serviceWorker": false,
|
||||
"styles": [
|
||||
"styles.scss"
|
||||
],
|
||||
"scripts": [
|
||||
],
|
||||
"environmentSource": "environments/environment.ts",
|
||||
"environments": {
|
||||
"dev": "environments/environment.ts",
|
||||
"next": "environments/environment.next.ts",
|
||||
"stable": "environments/environment.stable.ts",
|
||||
"archive": "environments/environment.archive.ts"
|
||||
}
|
||||
}
|
||||
],
|
||||
"e2e": {
|
||||
"protractor": {
|
||||
"config": "tests/e2e/protractor.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": [
|
||||
{
|
||||
"project": "src/tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"project": "src/tsconfig.spec.json"
|
||||
},
|
||||
{
|
||||
"project": "tests/e2e/tsconfig.e2e.json"
|
||||
}
|
||||
],
|
||||
"test": {
|
||||
"karma": {
|
||||
"config": "src/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"styleExt": "scss",
|
||||
"component": {
|
||||
"inlineStyle": true
|
||||
},
|
||||
"build": {
|
||||
"namedChunks": true
|
||||
}
|
||||
},
|
||||
"packageManager": "yarn"
|
||||
}
|
@ -22,7 +22,8 @@ Here are the most important tasks you might need to use:
|
||||
* `yarn start` - run a development web server that watches the files; then builds the doc-viewer and reloads the page, as necessary.
|
||||
* `yarn serve-and-sync` - run both the `docs-watch` and `start` in the same console.
|
||||
* `yarn lint` - check that the doc-viewer code follows our style rules.
|
||||
* `yarn test` - watch all the source files, for the doc-viewer, and run all the unit tests when any change.
|
||||
* `yarn test` - run all the unit tests once.
|
||||
* `yarn test --watch` - watch all the source files, for the doc-viewer, and run all the unit tests when any change.
|
||||
* `yarn e2e` - run all the e2e tests for the doc-viewer.
|
||||
|
||||
* `yarn docs` - generate all the docs from the source files.
|
||||
|
235
aio/angular.json
Normal file
235
aio/angular.json
Normal file
@ -0,0 +1,235 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular-devkit/core/src/workspace/workspace-schema.json",
|
||||
"version": 1,
|
||||
"cli": {
|
||||
"packageManager": "yarn"
|
||||
},
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"site": {
|
||||
"root": "",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"aot": true,
|
||||
"optimization": true,
|
||||
"buildOptimizer": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": true,
|
||||
"statsJson": true,
|
||||
"extractCss": true,
|
||||
"extractLicenses": true,
|
||||
"namedChunks": true,
|
||||
"vendorChunk": false,
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"assets": [
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "src/assets",
|
||||
"output": "/assets"
|
||||
},
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "src/generated",
|
||||
"output": "/generated"
|
||||
},
|
||||
{
|
||||
"glob": "app/search/search-worker.js",
|
||||
"input": "src",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"glob": "favicon.ico",
|
||||
"input": "src",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"glob": "pwa-manifest.json",
|
||||
"input": "src",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"glob": "google385281288605d160.html",
|
||||
"input": "src",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"glob": "custom-elements.min.js",
|
||||
"input": "node_modules/@webcomponents/custom-elements",
|
||||
"output": "/assets/js"
|
||||
},
|
||||
{
|
||||
"glob": "native-shim.js",
|
||||
"input": "node_modules/@webcomponents/custom-elements/src",
|
||||
"output": "/assets/js"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
{
|
||||
"input": "src/styles.scss"
|
||||
}
|
||||
],
|
||||
"scripts": [],
|
||||
|
||||
},
|
||||
"configurations": {
|
||||
"next": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"src": "src/environments/environment.ts",
|
||||
"replaceWith": "src/environments/environment.next.ts"
|
||||
}
|
||||
]
|
||||
},
|
||||
"stable": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"src": "src/environments/environment.ts",
|
||||
"replaceWith": "src/environments/environment.stable.ts"
|
||||
}
|
||||
]
|
||||
},
|
||||
"archive": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"src": "src/environments/environment.ts",
|
||||
"replaceWith": "src/environments/environment.archive.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "site:build"
|
||||
},
|
||||
"configurations": {
|
||||
"next": {
|
||||
"browserTarget": "site:build:next"
|
||||
},
|
||||
"stable": {
|
||||
"browserTarget": "site:build:stable"
|
||||
},
|
||||
"archive": {
|
||||
"browserTarget": "site:build:archive"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "site:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"karmaConfig": "src/karma.conf.js",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"scripts": [],
|
||||
"styles": [
|
||||
{
|
||||
"input": "src/styles.scss"
|
||||
}
|
||||
],
|
||||
"assets": [
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "src/assets",
|
||||
"output": "/assets"
|
||||
},
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "src/generated",
|
||||
"output": "/generated"
|
||||
},
|
||||
{
|
||||
"glob": "app/search/search-worker.js",
|
||||
"input": "src",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"glob": "favicon.ico",
|
||||
"input": "src",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"glob": "pwa-manifest.json",
|
||||
"input": "src",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"glob": "google385281288605d160.html",
|
||||
"input": "src",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"glob": "custom-elements.min.js",
|
||||
"input": "node_modules/@webcomponents/custom-elements",
|
||||
"output": "/assets/js"
|
||||
},
|
||||
{
|
||||
"glob": "native-shim.js",
|
||||
"input": "node_modules/@webcomponents/custom-elements/src",
|
||||
"output": "/assets/js"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"site-e2e": {
|
||||
"root": "",
|
||||
"projectType": "application",
|
||||
"cli": {},
|
||||
"schematics": {},
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "tests/e2e/protractor.conf.js",
|
||||
"devServerTarget": "site:serve"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"tests/e2e/tsconfig.e2e.json"
|
||||
],
|
||||
"exclude": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"inlineStyle": true,
|
||||
"prefix": "aio",
|
||||
"styleext": "scss"
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"prefix": "aio"
|
||||
}
|
||||
}
|
||||
}
|
6
aio/content/examples/.gitignore
vendored
6
aio/content/examples/.gitignore
vendored
@ -13,18 +13,20 @@
|
||||
**/src/tsconfig.app.json
|
||||
**/src/tsconfig.spec.json
|
||||
**/src/typings.d.ts
|
||||
**/e2e/app.po.ts
|
||||
**/e2e/src/app.po.ts
|
||||
**/e2e/tsconfig.e2e.json
|
||||
**/src/karma.conf.js
|
||||
**/.angular-cli.json
|
||||
**/.editorconfig
|
||||
**/angular.json
|
||||
**/tsconfig.json
|
||||
**/bs-config.e2e.json
|
||||
**/bs-config.json
|
||||
**/package.json
|
||||
**/tslint.json
|
||||
**/karma.conf.js
|
||||
**/karma-test-shim.js
|
||||
**/browser-test-shim.js
|
||||
**/browserslist
|
||||
**/node_modules
|
||||
|
||||
# built files
|
||||
|
@ -50,7 +50,7 @@ const templateC = `
|
||||
})
|
||||
// #docregion carol-class
|
||||
export class CarolComponent {
|
||||
name= 'Carol';
|
||||
name = 'Carol';
|
||||
// #docregion carol-ctor
|
||||
constructor( @Optional() public parent: Parent ) { }
|
||||
// #enddocregion carol-ctor
|
||||
@ -63,7 +63,7 @@ export class CarolComponent {
|
||||
template: templateC
|
||||
})
|
||||
export class ChrisComponent {
|
||||
name= 'Chris';
|
||||
name = 'Chris';
|
||||
constructor( @Optional() public parent: Parent ) { }
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ export class BarryComponent implements Parent {
|
||||
providers: [ provideParent(BobComponent) ]
|
||||
})
|
||||
export class BobComponent implements Parent {
|
||||
name= 'Bob';
|
||||
name = 'Bob';
|
||||
constructor( @SkipSelf() @Optional() public parent: Parent ) { }
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ export class BobComponent implements Parent {
|
||||
// #enddocregion beth-providers
|
||||
})
|
||||
export class BethComponent implements Parent {
|
||||
name= 'Beth';
|
||||
name = 'Beth';
|
||||
constructor( @SkipSelf() @Optional() public parent: Parent ) { }
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ export class BethComponent implements Parent {
|
||||
export class AlexComponent extends Base
|
||||
// #enddocregion alex-class-signature
|
||||
{
|
||||
name= 'Alex';
|
||||
name = 'Alex';
|
||||
}
|
||||
// #enddocregion alex, alex-1
|
||||
|
||||
@ -182,7 +182,7 @@ export class AlexComponent extends Base
|
||||
export class AliceComponent implements Parent
|
||||
// #enddocregion alice-class-signature
|
||||
{
|
||||
name= 'Alice';
|
||||
name = 'Alice';
|
||||
}
|
||||
// #enddocregion alice
|
||||
|
||||
|
@ -187,7 +187,7 @@ describe('Dependency Injection Tests', function () {
|
||||
let heroes = element.all(by.css('#authorized app-hero-list div'));
|
||||
expect(heroes.count()).toBeGreaterThan(0);
|
||||
|
||||
let filteredHeroes = heroes.filter(function(elem: ElementFinder, index: number){
|
||||
let filteredHeroes = heroes.filter(function(elem: ElementFinder, index: number) {
|
||||
return elem.getText().then(function(text: string) {
|
||||
return /secret/.test(text);
|
||||
});
|
@ -19,7 +19,7 @@ import { AdComponent } from './ad.component';
|
||||
// #docregion class
|
||||
export class AdBannerComponent implements OnInit, OnDestroy {
|
||||
@Input() ads: AdItem[];
|
||||
currentAdIndex: number = -1;
|
||||
currentAdIndex = -1;
|
||||
@ViewChild(AdDirective) adHost: AdDirective;
|
||||
interval: any;
|
||||
|
||||
|
@ -6,8 +6,8 @@ import { AdComponent } from './ad.component';
|
||||
@Component({
|
||||
template: `
|
||||
<div class="job-ad">
|
||||
<h4>{{data.headline}}</h4>
|
||||
|
||||
<h4>{{data.headline}}</h4>
|
||||
|
||||
{{data.body}}
|
||||
</div>
|
||||
`
|
||||
|
@ -8,7 +8,7 @@ import { AdComponent } from './ad.component';
|
||||
<div class="hero-profile">
|
||||
<h3>Featured Hero Profile</h3>
|
||||
<h4>{{data.name}}</h4>
|
||||
|
||||
|
||||
<p>{{data.bio}}</p>
|
||||
|
||||
<strong>Hire this hero today!</strong>
|
||||
|
@ -21,7 +21,7 @@ describe('Dynamic Form', function () {
|
||||
element(by.css('select option[value="solid"]')).click();
|
||||
|
||||
let saveButton = element.all(by.css('button')).get(0);
|
||||
saveButton.click().then(function(){
|
||||
saveButton.click().then(function() {
|
||||
expect(element(by.xpath("//strong[contains(text(),'Saved the following values')]")).isPresent()).toBe(true);
|
||||
});
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
// #docregion
|
||||
export class QuestionBase<T>{
|
||||
export class QuestionBase<T> {
|
||||
value: T;
|
||||
key: string;
|
||||
label: string;
|
||||
|
@ -88,7 +88,8 @@ describe('Router', () => {
|
||||
await crisisCenterEdit(2, true);
|
||||
});
|
||||
|
||||
it('can cancel changed crisis details', async () => {
|
||||
// TODO: Figure out why this test is failing now
|
||||
xit('can cancel changed crisis details', async () => {
|
||||
const page = getPageStruct();
|
||||
await page.crisisHref.click();
|
||||
await crisisCenterEdit(3, false);
|
@ -44,10 +44,7 @@ class Hero {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(i): temorarily disable these tests because angular-in-memory-web-api is not compatible with rxjs v6 yet
|
||||
// and we don't have the backwards compatibility package yet.
|
||||
// Reenable after rxjs v6 compatibility package is out or angular-in-memory-web-api is compatible with rxjs v6
|
||||
xdescribe('Tutorial part 6', () => {
|
||||
describe('Tutorial part 6', () => {
|
||||
|
||||
beforeAll(() => browser.get(''));
|
||||
|
@ -36,10 +36,6 @@
|
||||
'rxjs/operators': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/testing': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/ajax': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/operators': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/testing': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js' },
|
||||
'rxjs': { main: 'index.js', defaultExtension: 'js' },
|
||||
}
|
||||
});
|
||||
|
@ -987,7 +987,7 @@ import { configuration } from './configuration';
|
||||
The compiler encountered a type and can't determine which module exports that type.
|
||||
|
||||
This can happen if you refer to an ambient type.
|
||||
For example, the `Window` type is an ambiant type declared in the global `.d.ts` file.
|
||||
For example, the `Window` type is an ambient type declared in the global `.d.ts` file.
|
||||
|
||||
You'll get an error if you reference it in the component constructor,
|
||||
which the compiler must statically analyze.
|
||||
@ -999,17 +999,17 @@ export class MyComponent {
|
||||
constructor (private win: Window) { ... }
|
||||
}
|
||||
```
|
||||
TypeScript understands ambiant types so you don't import them.
|
||||
TypeScript understands ambient types so you don't import them.
|
||||
The Angular compiler does not understand a type that you neglect to export or import.
|
||||
|
||||
In this case, the compiler doesn't understand how to inject something with the `Window` token.
|
||||
|
||||
Do not refer to ambient types in metadata expressions.
|
||||
|
||||
If you must inject an instance of an ambiant type,
|
||||
If you must inject an instance of an ambient type,
|
||||
you can finesse the problem in four steps:
|
||||
|
||||
1. Create an injection token for an instance of the ambiant type.
|
||||
1. Create an injection token for an instance of the ambient type.
|
||||
1. Create a factory function that returns that instance.
|
||||
1. Add a `useFactory` provider with that factory function.
|
||||
1. Use `@Inject` to inject the instance.
|
||||
|
@ -61,7 +61,7 @@ The running application displays three heroes:
|
||||
E2E test that all children were instantiated and displayed as expected:
|
||||
|
||||
|
||||
<code-example path="component-interaction/e2e/app.e2e-spec.ts" region="parent-to-child" title="component-interaction/e2e/app.e2e-spec.ts">
|
||||
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="parent-to-child" title="component-interaction/e2e/src/app.e2e-spec.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
@ -105,7 +105,7 @@ Here's the `NameParentComponent` demonstrating name variations including a name
|
||||
E2E tests of input property setter with empty and non-empty names:
|
||||
|
||||
|
||||
<code-example path="component-interaction/e2e/app.e2e-spec.ts" region="parent-to-child-setter" title="component-interaction/e2e/app.e2e-spec.ts">
|
||||
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="parent-to-child-setter" title="component-interaction/e2e/src/app.e2e-spec.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
@ -164,7 +164,7 @@ Test that ***both*** input properties are set initially and that button clicks t
|
||||
the expected `ngOnChanges` calls and values:
|
||||
|
||||
|
||||
<code-example path="component-interaction/e2e/app.e2e-spec.ts" region="parent-to-child-onchanges" title="component-interaction/e2e/app.e2e-spec.ts">
|
||||
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="parent-to-child-onchanges" title="component-interaction/e2e/src/app.e2e-spec.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
@ -217,7 +217,7 @@ and the method processes it:
|
||||
Test that clicking the *Agree* and *Disagree* buttons update the appropriate counters:
|
||||
|
||||
|
||||
<code-example path="component-interaction/e2e/app.e2e-spec.ts" region="child-to-parent" title="component-interaction/e2e/app.e2e-spec.ts">
|
||||
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="child-to-parent" title="component-interaction/e2e/src/app.e2e-spec.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
@ -284,7 +284,7 @@ match the seconds displayed in the child's status message.
|
||||
Test also that clicking the *Stop* button pauses the countdown timer:
|
||||
|
||||
|
||||
<code-example path="component-interaction/e2e/app.e2e-spec.ts" region="countdown-timer-tests" title="component-interaction/e2e/app.e2e-spec.ts">
|
||||
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="countdown-timer-tests" title="component-interaction/e2e/src/app.e2e-spec.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
@ -433,7 +433,7 @@ Tests click buttons of both the parent `MissionControlComponent` and the `Astron
|
||||
and verify that the history meets expectations:
|
||||
|
||||
|
||||
<code-example path="component-interaction/e2e/app.e2e-spec.ts" region="bidirectional-service" title="component-interaction/e2e/app.e2e-spec.ts">
|
||||
<code-example path="component-interaction/e2e/src/app.e2e-spec.ts" region="bidirectional-service" title="component-interaction/e2e/src/app.e2e-spec.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
# Angular Glossary
|
||||
|
||||
Angular has its own vocabulary.
|
||||
Most Angular terms are common English words
|
||||
with a specific meaning within the Angular system.
|
||||
Most Angular terms are common English words or computing terms
|
||||
that have a specific meaning within the Angular system.
|
||||
|
||||
This glossary lists the most prominent terms
|
||||
and a few less familiar ones that have unusual or
|
||||
@ -19,14 +19,19 @@ unexpected definitions.
|
||||
|
||||
## Ahead-of-time (AOT) compilation
|
||||
|
||||
You can compile Angular applications at build time.
|
||||
By compiling your application using the compiler-cli, `ngc`, you can bootstrap directly to a module factory, meaning you don't need to include the Angular compiler in your JavaScript bundle.
|
||||
Ahead-of-time compiled applications also benefit from decreased load time and increased performance.
|
||||
The Angular ahead-of-time (AOT) compiler converts your Angular HTML and TypeScript code
|
||||
into efficient JavaScript code during the build phase before the browser downloads
|
||||
and runs that code.
|
||||
This is the best compilation mode for production environments, with decreased load time and increased performance.
|
||||
|
||||
By compiling your application using the `ngc` command-line tool, you can bootstrap directly to a module factory, meaning you don't need to include the Angular compiler in your JavaScript bundle.
|
||||
|
||||
Compare [just-in-time (JIT) compilation](guide/glossary#jit).
|
||||
|
||||
|
||||
## Annotation
|
||||
|
||||
In practice, a synonym for [Decoration](guide/glossary#decorator).
|
||||
A structure that provides metadata for a class. See [Decorator](guide/glossary#decorator).
|
||||
|
||||
|
||||
{@a attribute-directive}
|
||||
@ -41,126 +46,86 @@ A category of [directive](guide/glossary#directive) that can listen to and modif
|
||||
other HTML elements, attributes, properties, and components. They are usually represented
|
||||
as HTML attributes, hence the name.
|
||||
|
||||
For example, you can use the `ngClass` directive to add and remove CSS class names.
|
||||
|
||||
Learn about them in the [_Attribute Directives_](guide/attribute-directives) guide.
|
||||
Learn more in the [_Attribute Directives_](guide/attribute-directives) guide.
|
||||
|
||||
|
||||
{@a B}
|
||||
|
||||
## Barrel
|
||||
|
||||
A way to *roll up exports* from several ES2015 modules into a single convenient ES2015 module.
|
||||
The barrel itself is an ES2015 module file that re-exports selected exports of other ES2015 modules.
|
||||
|
||||
For example, imagine three ES2015 modules in a `heroes` folder:
|
||||
|
||||
<code-example>
|
||||
// heroes/hero.component.ts
|
||||
export class HeroComponent {}
|
||||
|
||||
// heroes/hero.model.ts
|
||||
export class Hero {}
|
||||
|
||||
// heroes/hero.service.ts
|
||||
export class HeroService {}
|
||||
</code-example>
|
||||
|
||||
Without a barrel, a consumer needs three import statements:
|
||||
|
||||
<code-example>
|
||||
import { HeroComponent } from '../heroes/hero.component.ts';
|
||||
import { Hero } from '../heroes/hero.model.ts';
|
||||
import { HeroService } from '../heroes/hero.service.ts';
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
You can add a barrel to the `heroes` folder (called `index`, by convention) that exports all of these items:
|
||||
|
||||
<code-example>
|
||||
export * from './hero.model.ts'; // re-export all of its exports
|
||||
export * from './hero.service.ts'; // re-export all of its exports
|
||||
export { HeroComponent } from './hero.component.ts'; // re-export the named thing
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Now a consumer can import what it needs from the barrel.
|
||||
|
||||
<code-example>
|
||||
import { Hero, HeroService } from '../heroes'; // index is implied
|
||||
</code-example>
|
||||
|
||||
|
||||
The Angular [scoped packages](guide/glossary#scoped-package) each have a barrel named `index`.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
You can often achieve the same result using [NgModules](guide/glossary#ngmodule) instead.
|
||||
|
||||
</div>
|
||||
|
||||
## Binding
|
||||
|
||||
Usually refers to [data binding](guide/glossary#data-binding) and the act of
|
||||
binding an HTML object property to a data object property.
|
||||
Generally, the practice of setting a variable or property to a data value.
|
||||
Within Angular, typically refers to [data binding](guide/glossary#data-binding),
|
||||
which coordinates DOM object properties with data object properties.
|
||||
|
||||
Sometimes refers to a [dependency-injection](guide/glossary#dependency-injection) binding
|
||||
between a "token"—also referred to as a "key"—and a dependency [provider](guide/glossary#provider).
|
||||
between a [token](guide/glossary#token) and a dependency [provider](guide/glossary#provider).
|
||||
|
||||
|
||||
## Bootstrap
|
||||
|
||||
You launch an Angular application by "bootstrapping" it using the application root NgModule (`AppModule`).
|
||||
A way to initialize and launch an app or system.
|
||||
|
||||
Bootstrapping identifies an application's top level "root" [component](guide/glossary#component),
|
||||
which is the first component that is loaded for the application.
|
||||
|
||||
You can bootstrap multiple apps in the same `index.html`, each app with its own top-level root.
|
||||
In Angular, an app's root NgModule (`AppModule`) has a `bootstrap` property that identifies the app's top-level [components](guide/glossary#component).
|
||||
During the bootstrap process, Angular creates and inserts these components into the `index.html` host web page.
|
||||
You can bootstrap multiple apps in the same `index.html`, each app with its own components.
|
||||
|
||||
Learn more in the [_Bootstrapping_](guide/bootstrapping) guide.
|
||||
|
||||
{@a C}
|
||||
|
||||
|
||||
{@a case-conventions}
|
||||
{@a dash-case}
|
||||
|
||||
{@a camelcase}
|
||||
|
||||
{@a kebab-case}
|
||||
|
||||
## Case conventions
|
||||
|
||||
Angular uses capitalization conventions to distinguish the names of various types, as described in the [Style Guide "Naming" section](guide/styleguide#02-01).
|
||||
|
||||
- camelCase : symbols, properties, methods, pipe names, interfaces, non-component directive selectors, constants
|
||||
- UpperCamelCase (also called PascalCase): Class names
|
||||
- dash-case (also called "kebab-case"): descriptive part of file names, component selectors
|
||||
- camelCase : symbols, properties, methods, pipe names, non-component directive selectors, constants
|
||||
- UpperCamelCase (or PascalCase): Class names, including classes that define components, interfaces, NgModules, directives, pipes, and so on.
|
||||
- dash-case (or "kebab-case"): descriptive part of file names, component selectors
|
||||
- underscore_case (or "snake_case"): not typically used in Angular
|
||||
- UPPER_SNAKE_CASE : traditional for constants (acceptable, but prefer camelCase)
|
||||
- UPPER_UNDERSCORE_CASE (or UPPER_SNAKE_CASE): traditional for constants (acceptable, but prefer camelCase)
|
||||
|
||||
{@a class-decorator}
|
||||
|
||||
## Class decorator
|
||||
|
||||
A [decorator](guide/glossary#decorator) statement immediately before a class definition that declares the class to be of the given type, and provides metadata suitable to the type.
|
||||
|
||||
The following class types can be declared:
|
||||
- `@Component`
|
||||
- `@Directive`
|
||||
- `@Pipe`
|
||||
- `@Injectable`
|
||||
- `@NgModule`
|
||||
|
||||
|
||||
{@a class-field-decorator}
|
||||
|
||||
## Class field decorator
|
||||
|
||||
A [decorator](guide/glossary#decorator) statement immediately before a field in a class definition that declares the type of that field. Some examples are `@Input` and `@Output`.
|
||||
|
||||
## CLI
|
||||
|
||||
The Angular CLI is a `command line interface` tool that can create a project, add files, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.
|
||||
The [Angular CLI](https://cli.angular.io/) is a command-line tool that can create a project, add files, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.
|
||||
|
||||
Learn more in the [Getting Started](guide/quickstart) guide.
|
||||
Learn more in the [Getting Started](guide/quickstart) guide.
|
||||
|
||||
{@a component}
|
||||
|
||||
## Component
|
||||
|
||||
An Angular class responsible for exposing data to a [view](guide/glossary#view) and handling most of the view’s display and user-interaction logic.
|
||||
A class with the `@Component` [decorator](guide/glossary#decorator) that associates it with a companion [template](guide/glossary#template).
|
||||
|
||||
The *component* is one of the most important building blocks in the Angular system.
|
||||
It is, in fact, an Angular [directive](guide/glossary#directive) with a companion [template](guide/glossary#template).
|
||||
A component is a special type of [directive](guide/glossary#directive) that represents a [view](guide/glossary#view).The `@Component` decorator extends the `@Directive` decorator with template-oriented features.
|
||||
|
||||
Apply the `@Component` [decorator](guide/glossary#decorator) to
|
||||
the component class, thereby attaching to the class the essential component metadata
|
||||
that Angular needs to create a component instance and render the component with its template
|
||||
as a view.
|
||||
An Angular component class is responsible for exposing data and handling most of the view's display and user-interaction logic through [data binding](guide/glossary#data-binding).
|
||||
|
||||
Those familiar with "MVC" and "MVVM" patterns will recognize
|
||||
the component in the role of "controller" or "view model".
|
||||
Read more about components, templates, and views in the [Architecture](guide/architecture) guide.
|
||||
|
||||
{@a custom-element}
|
||||
|
||||
@ -189,10 +154,7 @@ Data binding is an alternative to manually pushing application data values into
|
||||
event listeners, pulling changed values from the screen, and
|
||||
updating application data values.
|
||||
|
||||
Angular has a rich data-binding framework with a variety of data-binding
|
||||
operations and supporting declaration syntax.
|
||||
|
||||
Read about the following forms of binding in the [Template Syntax](guide/template-syntax) page:
|
||||
Read about the following forms of binding in the [Template Syntax](guide/template-syntax) page:
|
||||
|
||||
* [Interpolation](guide/template-syntax#interpolation).
|
||||
* [Property binding](guide/template-syntax#property-binding).
|
||||
@ -202,99 +164,54 @@ operations and supporting declaration syntax.
|
||||
* [Style binding](guide/template-syntax#style-binding).
|
||||
* [Two-way data binding with ngModel](guide/template-syntax#ngModel).
|
||||
|
||||
{@a declarable}
|
||||
|
||||
## Declarable
|
||||
|
||||
A class type that you can add to the `declarations` list of an [NgModule](guide/glossary#ngmodule).
|
||||
|
||||
You can declare [components](guide/glossary#component), [directives](guide/glossary#directive), and [pipes](guide/glossary#pipe).
|
||||
|
||||
Do not declare the following:
|
||||
- A class that's already declared in another NgModule.
|
||||
- An array of directives imported from another package. For example, don't declare `FORMS_DIRECTIVES` from `@angular/forms`.
|
||||
- NgModule classes.
|
||||
- Service classes.
|
||||
- Non-Angular classes and objects, such as strings, numbers, functions, entity models, configurations, business logic, and helper classes
|
||||
|
||||
|
||||
{@a decorator}
|
||||
|
||||
|
||||
{@a decoration}
|
||||
|
||||
|
||||
## Decorator | decoration
|
||||
|
||||
A *function* that adds metadata to a class, its members (properties, methods) and function arguments.
|
||||
|
||||
Decorators (also called annotations) are an experimental (stage 2), JavaScript language [feature](https://github.com/wycats/javascript-decorators). TypeScript adds support for decorators.
|
||||
A function that modifies the immediately following class or property definition.
|
||||
Decorators (also called annotations) are an experimental (stage 2), JavaScript language [feature](https://github.com/wycats/javascript-decorators).
|
||||
TypeScript adds support for decorators.
|
||||
|
||||
To apply a decorator, position it immediately above or to the left of the item it decorates.
|
||||
Angular defines decorators that attach metadata to classes or properties so that it knows what those classes or properties mean and how they should work.
|
||||
|
||||
Angular has its own set of decorators to help it interoperate with your application parts.
|
||||
The following example is a `@Component` decorator that identifies a
|
||||
class as an Angular [component](guide/glossary#component) and an `@Input` decorator applied to the `name` property
|
||||
of that component. The elided object argument to the `@Component` decorator would contain the pertinent component metadata.
|
||||
See [Class decorator](guide/glossary#class-decorator), [Class field decorator](guide/glossary#class-field-decorator).
|
||||
|
||||
```
|
||||
@Component({...})
|
||||
export class AppComponent {
|
||||
constructor(@Inject('SpecialFoo') public foo:Foo) {}
|
||||
@Input() name:string;
|
||||
}
|
||||
```
|
||||
|
||||
The scope of a decorator is limited to the language feature
|
||||
that it decorates. None of the decorations shown here will "leak" to other
|
||||
classes that follow it in the file.
|
||||
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
|
||||
|
||||
Always include parentheses `()` when applying a decorator.
|
||||
|
||||
|
||||
</div>
|
||||
{@a di}
|
||||
|
||||
|
||||
## Dependency injection
|
||||
|
||||
A design pattern and mechanism
|
||||
for creating and delivering parts of an application to other
|
||||
parts of an application that request them.
|
||||
A design pattern and mechanism for creating and delivering parts of an application (dependencies) to other parts of an application that require them.
|
||||
|
||||
Angular developers prefer to build applications by defining many simple parts
|
||||
that each do one thing well and then wiring them together at runtime.
|
||||
In Angular, dependencies are typically services, but can also be values, such as strings or functions. An [injector](guide/glossary#injector) for an app (created automatically during bootstrap) creates dependencies when needed, using a registered [provider](guide/glossary#provider) of the service or value. Different providers can provide different implementations of the same service.
|
||||
|
||||
These parts often rely on other parts. An Angular [component](guide/glossary#component)
|
||||
part might rely on a service part to get data or perform a calculation. When
|
||||
part "A" relies on another part "B," you say that "A" depends on "B" and
|
||||
that "B" is a dependency of "A."
|
||||
Learn more in the [Dependency Injection](guide/dependency-injection) guide.
|
||||
|
||||
You can ask a "dependency injection system" to create "A"
|
||||
for us and handle all the dependencies.
|
||||
If "A" needs "B" and "B" needs "C," the system resolves that chain of dependencies
|
||||
and returns a fully prepared instance of "A."
|
||||
{@a di-token}
|
||||
|
||||
## DI token
|
||||
|
||||
Angular provides and relies upon its own sophisticated
|
||||
dependency-injection system
|
||||
to assemble and run applications by "injecting" application parts
|
||||
into other application parts where and when needed.
|
||||
|
||||
At the core, an [`injector`](guide/glossary#injector) returns dependency values on request.
|
||||
The expression `injector.get(token)` returns the value associated with the given token.
|
||||
|
||||
A token is an Angular type (`InjectionToken`). You rarely need to work with tokens directly; most
|
||||
methods accept a class name (`Foo`) or a string ("foo") and Angular converts it
|
||||
to a token. When you write `injector.get(Foo)`, the injector returns
|
||||
the value associated with the token for the `Foo` class, typically an instance of `Foo` itself.
|
||||
|
||||
During many of its operations, Angular makes similar requests internally, such as when it creates a [`component`](guide/glossary#component) for display.
|
||||
|
||||
The `Injector` maintains an internal map of tokens to dependency values.
|
||||
If the `Injector` can't find a value for a given token, it creates
|
||||
a new value using a `Provider` for that token.
|
||||
|
||||
A [provider](guide/glossary#provider) is a recipe for
|
||||
creating new instances of a dependency value associated with a particular token.
|
||||
|
||||
An injector can only create a value for a given token if it has
|
||||
a `provider` for that token in its internal provider registry.
|
||||
Registering providers is a critical preparatory step.
|
||||
|
||||
Angular registers some of its own providers with every injector.
|
||||
You can register your own providers.
|
||||
|
||||
Read more in the [Dependency Injection](guide/dependency-injection) page.
|
||||
A lookup token associated with a dependency [provider](guide/glossary#provider), for use with the [dependency injection](guide/glossary#di) system.
|
||||
|
||||
|
||||
{@a directive}
|
||||
@ -305,34 +222,25 @@ Read more in the [Dependency Injection](guide/dependency-injection) page.
|
||||
|
||||
## Directive
|
||||
|
||||
An Angular class responsible for creating, reshaping, and interacting with HTML elements
|
||||
in the browser DOM. The directive is Angular's most fundamental feature.
|
||||
A class with the `@Directive` [decorator](guide/glossary#decorator) that can modify the structure of the DOM, or modify attributes in the DOM and component data model.
|
||||
|
||||
A directive is usually associated with an HTML element or attribute.
|
||||
This element or attribute is often referred to as the directive itself.
|
||||
A directive class is usually associated with an HTML element or attribute, and that element or attribute is often referred to as the directive itself.
|
||||
When Angular finds a directive in an HTML [template](guide/glossary#template), it creates the matching directive class instance and gives the instance control over that portion of the browser DOM.
|
||||
|
||||
When Angular finds a directive in an HTML template,
|
||||
it creates the matching directive class instance
|
||||
and gives the instance control over that portion of the browser DOM.
|
||||
There are three categories of directive:
|
||||
- [Components](guide/glossary#component) use `@Component` (an extension of `@Directive`) to associate a template with a class.
|
||||
- [Attribute directives](guide/glossary#attribute-directive) modify behavior and appearance of page elements.
|
||||
- [Structural directives](guide/glossary#structural-directive) modify the structure of the DOM.
|
||||
|
||||
You can invent custom HTML markup (for example, `<my-directive>`) to
|
||||
associate with your custom directives. You add this custom markup to HTML templates
|
||||
as if you were writing native HTML. In this way, directives become extensions of
|
||||
HTML itself.
|
||||
Angular supplies a number of built-in directives that begin with the `ng` prefix. You can also create new directives to implement your own functionality.
|
||||
You associate a _selector_ (an HTML tag such as `<my-directive>`) with a custom directive, thereby extending the [template syntax](guide/template-syntax) that you can use in your apps.
|
||||
|
||||
Directives fall into one of the following categories:
|
||||
|
||||
* [Components](guide/glossary#component) combine application logic with an HTML template to
|
||||
render application [views](guide/glossary#view). Components are usually represented as HTML elements.
|
||||
They are the building blocks of an Angular application.
|
||||
## Domain-specific language (DSL)
|
||||
|
||||
* [Attribute directives](guide/glossary#attribute-directive) can listen to and modify the behavior of
|
||||
other HTML elements, attributes, properties, and components. They are usually represented
|
||||
as HTML attributes, hence the name.
|
||||
A special-purpose library or API; see [Domain-specific language](https://en.wikipedia.org/wiki/Domain-specific_language).
|
||||
|
||||
* [Structural directives](guide/glossary#structural-directive) are responsible for
|
||||
shaping or reshaping HTML layout, typically by adding, removing, or manipulating
|
||||
elements and their children.
|
||||
Angular extends TypeScript with domain-specific languages for a number of domains relevant to Angular apps, defined in ngModules such as [animations](guide/animations), [forms](guide/forms), and [routing and navigation](guide/router).
|
||||
|
||||
{@a dynamic-components}
|
||||
|
||||
@ -350,7 +258,9 @@ See also [Custom element](guide/glossary#custom-element), which provides an easi
|
||||
|
||||
The [official JavaScript language specification](https://en.wikipedia.org/wiki/ECMAScript).
|
||||
|
||||
Not all browsers support the latest ECMAScript standard, but you can use transpilers (like [TypeScript](guide/glossary#typescript)) to write code using the latest features, which will then be transpiled to code that runs on versions that are supported by browsers.
|
||||
Not all browsers support the latest ECMAScript standard, but you can use a [transpiler](guide/glossary#transpile) (like [TypeScript](guide/glossary#typescript)) to write code using the latest features, which will then be transpiled to code that runs on versions that are supported by browsers.
|
||||
|
||||
To learn more, see the [Browser Support](guide/browser-support) page.
|
||||
|
||||
|
||||
{@a element}
|
||||
@ -363,6 +273,13 @@ The documentation generally refers to either elements (`ElementRef` instances) o
|
||||
|
||||
Compare [Custom element](guide/glossary#custom-element).
|
||||
|
||||
## Entry point
|
||||
|
||||
A JavaScript ID that makes parts of an NPM package available for import by other code.
|
||||
The Angular [scoped packages](guide/glossary#scoped-package) each have an entry point named `index`.
|
||||
|
||||
Within Angular, use [NgModules](guide/glossary#ngmodule) to achieve the same result.
|
||||
|
||||
|
||||
{@a F}
|
||||
|
||||
@ -374,6 +291,16 @@ Compare [Custom element](guide/glossary#custom-element).
|
||||
|
||||
{@a I}
|
||||
|
||||
{@a injectable}
|
||||
|
||||
## Injectable
|
||||
|
||||
An Angular class or other definition that provides a dependency using the [dependency injection](guide/glossary#di) mechanism. An injectable class is marked by the `@Injectable` [decorator](guide/glossary#decorator).
|
||||
|
||||
Both a [service](guide/glossary#service) and a [component](guide/glossary#component) that depends on that service must be marked as injectable. Other items, such as constant values, can be injectable.
|
||||
|
||||
{@a injector}
|
||||
|
||||
## Injector
|
||||
|
||||
An object in the Angular [dependency-injection system](guide/glossary#dependency-injection)
|
||||
@ -383,19 +310,19 @@ with a registered [provider](guide/glossary#provider). Injectors are created for
|
||||
|
||||
## Input
|
||||
|
||||
A directive property that can be the *target* of a
|
||||
[property binding](guide/template-syntax#property-binding) (explained in detail in the [Template Syntax](guide/template-syntax) page).
|
||||
Data values flow *into* this property from the data source identified
|
||||
in the template expression to the right of the equal sign.
|
||||
When defining a [directive](guide/glossary#directive), the `@Input` decorator on a directive property makes that property available as a *target* of a
|
||||
[property binding](guide/template-syntax#property-binding).
|
||||
Data values flow into an input property from the data source identified
|
||||
in the [template expression](guide/glossary#template-expression) to the right of the equal sign.
|
||||
|
||||
See the [Input and output properties](guide/template-syntax#inputs-outputs) section of the [Template Syntax](guide/template-syntax) page.
|
||||
To learn more, see [input and output properties](guide/template-syntax#inputs-outputs).
|
||||
|
||||
|
||||
## Interpolation
|
||||
|
||||
A form of [property data binding](guide/glossary#data-binding) in which a
|
||||
[template expression](guide/glossary#template-expression) between double-curly braces
|
||||
renders as text. That text may be concatenated with neighboring text
|
||||
renders as text. That text can be concatenated with neighboring text
|
||||
before it is assigned to an element property
|
||||
or displayed between element tags, as in this example.
|
||||
|
||||
@ -422,9 +349,10 @@ See [ECMAScript](guide/glossary#ecma), [TypeScript](guide/glossary#typescript).
|
||||
|
||||
## Just-in-time (JIT) compilation
|
||||
|
||||
A bootstrapping method of compiling components and modules in the browser
|
||||
and launching the application dynamically. Just-in-time mode is a good choice during development.
|
||||
Consider using the [ahead-of-time](guide/glossary#aot) mode for production apps.
|
||||
The Angular Just-in-Time (JIT) compiler converts your Angular HTML and TypeScript code into efficient JavaScript code at run time, as part of bootstrapping.
|
||||
JIT compilation is the default when you run Angular's `ng build` and `ng serve` CLI commands, and is a good choice during development. JIT mode is strongly discouraged for production use because it results in large application payloads that hinder the bootstrap performance.
|
||||
|
||||
Compare [ahead-of-time (AOT) compilation](guide/glossary#aot).
|
||||
|
||||
|
||||
{@a K}
|
||||
@ -432,13 +360,17 @@ Consider using the [ahead-of-time](guide/glossary#aot) mode for production apps.
|
||||
|
||||
{@a L}
|
||||
|
||||
## Lifecycle hooks
|
||||
{@a lazy-load}
|
||||
|
||||
[Directives](guide/glossary#directive) and [components](guide/glossary#component) have a lifecycle
|
||||
managed by Angular as it creates, updates, and destroys them.
|
||||
## Lazy loading
|
||||
|
||||
You can tap into key moments in that lifecycle by implementing
|
||||
one or more of the lifecycle hook interfaces.
|
||||
Lazy loading speeds up application load time by splitting the application into multiple bundles and loading them on demand.
|
||||
For example, dependencies can be lazy-loaded as needed&emdash;as opposed to "eager-loaded" modules that are required by the root module, and are thus loaded on launch.
|
||||
Similarly, the [router](guide/glossary#router) can load child views only when the parent view is activated, and you can build custom elements that can be loaded into an Angular app when needed.
|
||||
|
||||
## Lifecycle hook
|
||||
|
||||
An interface that allows you to tap into the lifecycle of [directives](guide/glossary#directive) and [components](guide/glossary#component) as they are created, updated, and destroyed.
|
||||
|
||||
Each interface has a single hook method whose name is the interface name prefixed with `ng`.
|
||||
For example, the `OnInit` interface has a hook method named `ngOnInit`.
|
||||
@ -454,118 +386,95 @@ Angular calls these hook methods in the following order:
|
||||
* `ngAfterViewChecked`: after every check of a component's views.
|
||||
* `ngOnDestroy`: just before the directive is destroyed.
|
||||
|
||||
Read more in the [Lifecycle Hooks](guide/lifecycle-hooks) page.
|
||||
To learn more, see the [Lifecycle Hooks](guide/lifecycle-hooks) page.
|
||||
|
||||
|
||||
{@a M}
|
||||
|
||||
## Module
|
||||
|
||||
<div class="alert is-important">
|
||||
In general, a module collects a block of code dedicated to a single purpose. Angular uses standard JavaScript modules, and also defines an Angular module, `NgModule`.
|
||||
|
||||
In JavaScript (ECMAScript), each file is a module and all objects defined in the file belong to that module. Objects can exported, making them public, and public objects can be imported for use by other modules.
|
||||
|
||||
Angular has the following types of modules:
|
||||
Angular ships as a collection of JavaScript modules, or libraries. Each Angular library name begins with the `@angular` prefix. Install them with the NPM package manager and import parts of them with JavaScript `import` declarations.
|
||||
|
||||
* [NgModules](guide/glossary#ngmodule).
|
||||
For details and examples, see the [NgModules](guide/ngmodules) page.
|
||||
* ES2015 modules, as described in this section.
|
||||
|
||||
For a comparison, see [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
|
||||
|
||||
</div>
|
||||
|
||||
A cohesive block of code dedicated to a single purpose.
|
||||
|
||||
Angular apps are modular.
|
||||
|
||||
In general, you assemble an application from many modules, both the ones you write and the ones you acquire from others.
|
||||
|
||||
A module *exports* something of value in that code, typically one thing such as a class;
|
||||
a module that needs that class *imports* it.
|
||||
|
||||
The structure of NgModules and the import/export syntax
|
||||
is based on the [ES2015 module standard](http://www.2ality.com/2014/09/es6-modules-final.html).
|
||||
|
||||
An application that adheres to this standard requires a module loader to
|
||||
load modules on request and resolve inter-module dependencies.
|
||||
Angular doesn't include a module loader and doesn't have a preference
|
||||
for any particular third-party library.
|
||||
You can use any module library that conforms to the standard.
|
||||
|
||||
Modules are typically named after the file in which the exported thing is defined.
|
||||
The Angular [DatePipe](https://github.com/angular/angular/blob/master/packages/common/src/pipes/date_pipe.ts)
|
||||
class belongs to a feature module named `date_pipe` in the file `date_pipe.ts`.
|
||||
|
||||
You rarely access Angular feature modules directly. You usually import them from an Angular [scoped package](guide/glossary#scoped-package) such as `@angular/core`.
|
||||
Compare the Angular [NgModule](guide/glossary#ngmodule).
|
||||
|
||||
|
||||
{@a N}
|
||||
|
||||
{@a ngmodule}
|
||||
|
||||
## NgModule
|
||||
|
||||
Helps you organize an application into cohesive blocks of functionality.
|
||||
An NgModule identifies the components, directives, and pipes that the application uses along with the list of external NgModules that the application needs, such as `FormsModule`.
|
||||
A class definition with an `@NgModule` [decorator](guide/glossary#decorator), that declares and serves as a manifest for a block of code dedicated to an application domain, a workflow, or a closely related set of capabilities.
|
||||
|
||||
Every Angular application has an application root-module class. By convention, the class is
|
||||
called `AppModule` and resides in a file named `app.module.ts`.
|
||||
Like a [JavaScript module](guide/glossary#module), an NgModule can export functionality for use by other NgModules, and import public functionality from other NgModules.
|
||||
|
||||
For details and examples, see [NgModules](guide/ngmodules) and the
|
||||
related files in that section.
|
||||
The metadata for an NgModule class collects components, directives, and pipes that the application uses along with the list of imports and exports. See also [Declarable](guide/glossary#declarable).
|
||||
|
||||
NgModules are typically named after the file in which the exported thing is defined; for example, the Angular [DatePipe](api/common/DatePipe) class belongs to a feature module named `date_pipe` in the file `date_pipe.ts`. You import them from an Angular [scoped package](guide/glossary#scoped-package) such as `@angular/core`.
|
||||
|
||||
Every Angular application has a root module. By convention, the class is called `AppModule` and resides in a file named `app.module.ts`.
|
||||
|
||||
To learn more, see the [NgModules](guide/ngmodules) guide.
|
||||
|
||||
|
||||
{@a O}
|
||||
|
||||
{@a observable}
|
||||
|
||||
|
||||
## Observable
|
||||
|
||||
An subscribable message publisher, which provides multiple items that arrive asynchronously over time.
|
||||
Observables help you manage asynchronous data, such as data coming from a backend service.
|
||||
Observables are used within Angular itself, including Angular's event system and its HTTP client service.
|
||||
A producer of multiple values, which it pushes to [subscribers](guide/glossary#subscriber). Used for asynchronous event handling throughout Angular. You execute an observable by subscribing to it with its `subscribe()` method, passing callbacks for notifications of new values, errors, or completion.
|
||||
|
||||
Observables are a proposed feature for ES2016, the next version of JavaScript.
|
||||
Currently, Angular depends on a third-party library called Reactive Extensions (RxJS) to provide observables.
|
||||
Observables can deliver single or multiple values of any type to subscribers, either synchronously (as a function delivers a value to its caller), or on a schedule. A subscriber receives notification of new values as they are produced, and of either error or normal completion.
|
||||
|
||||
For more information, see the [Observables guide](guide/observables).
|
||||
Angular uses a third-party library called [Reactive Extensions (RxJS)](http://reactivex.io/rxjs/).
|
||||
|
||||
To learn more, see the [Observables](guide/glossary#observable) guide.
|
||||
|
||||
|
||||
{@a observer}
|
||||
|
||||
## Observer
|
||||
|
||||
An object passed to the `subscribe()` method for an [observable](guide/glossary#observable) that defines the callbacks for the [subscriber](guide/glossary#subscriber).
|
||||
|
||||
## Output
|
||||
|
||||
A directive property that can be the *target* of event binding
|
||||
(read more in the [event binding](guide/template-syntax#event-binding)
|
||||
section of the [Template Syntax](guide/template-syntax) page).
|
||||
Events stream *out* of this property to the receiver identified
|
||||
in the template expression to the right of the equal sign.
|
||||
When defining a [directive](guide/glossary#directive), the `@Output` decorator on a directive property makes that property available as a *target* of [event binding](guide/template-syntax#event-binding).
|
||||
|
||||
See the [Input and output properties](guide/template-syntax#inputs-outputs) section of the [Template Syntax](guide/template-syntax) page.
|
||||
Events stream *out* of this property to the receiver identified
|
||||
in the [template expression](guide/glossary#template-expression) to the right of the equal sign.
|
||||
|
||||
To learn more, see [input and output properties](guide/template-syntax#inputs-outputs).
|
||||
|
||||
|
||||
{@a P}
|
||||
|
||||
## Pipe
|
||||
|
||||
An Angular pipe is a function that transforms input values to output values for
|
||||
display in a [view](guide/glossary#view).
|
||||
Here's an example that uses the built-in `currency` pipe to display
|
||||
a numeric value in the local currency.
|
||||
A class with the `@Pipe` decorator which defines a function that transforms input values to output values for display in a [view](guide/glossary#view).
|
||||
|
||||
Angular defines various pipes, and you can define new pipes.
|
||||
|
||||
To learn more, see the [pipes](guide/pipes) page.
|
||||
|
||||
<code-example language="html" escape="html">
|
||||
<label>Price: </label>{{product.price | currency}}
|
||||
## Polyfill
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
You can also write your own custom pipes.
|
||||
Read more in the page on [pipes](guide/pipes).
|
||||
An [NPM package](guide/npm-packages) that plugs gaps in a browser's JavaScript implementation. See the [Browser Support](guide/browser-support) guide for polyfills that support particular functionality for particular platforms.
|
||||
|
||||
|
||||
## Provider
|
||||
|
||||
A _provider_ creates a new instance of a dependency for the
|
||||
[dependency injection](guide/glossary#dependency-injection) system.
|
||||
It relates a lookup token to code—sometimes called a "recipe"—that can create a dependency value.
|
||||
A provider of an injectable service—specifically, a code recipe associated with a [DI token](guide/glossary#token), which an [injector](guide/glossary#injector) uses to create a new instance of a dependency for a class that requires it.
|
||||
|
||||
Angular registers its own providers with every injector, for services that Angular defines. You can register your own providers for services that your app needs.
|
||||
|
||||
See also [Service](guide/glossary#service), [Dependency Injection](guide/glossary#di).
|
||||
|
||||
|
||||
{@a Q}
|
||||
@ -589,24 +498,13 @@ Reactive forms are powerful, flexible, and a good choice for more complex data-e
|
||||
|
||||
## Router
|
||||
|
||||
Most applications consist of many screens or [views](guide/glossary#view).
|
||||
The user navigates among them by clicking links and buttons,
|
||||
and performing other similar actions that cause the application to
|
||||
replace one view with another.
|
||||
A tool that configures and implements navigation among states and [views](guide/glossary#view) within an Angular app.
|
||||
|
||||
The Angular component router is a richly featured mechanism for configuring and managing the entire view navigation process, including the creation and destruction
|
||||
of views.
|
||||
The Router module is an [NgModule](guide/glossary#ngmodule) that provides the necessary service providers and directives for navigating through application views. A [routing component](guide/glossary#routing-component) is one that imports the Router module and whose template contains a `RouterOutlet` element where it can display views produced by the router.
|
||||
|
||||
The Router defines navigation among views on a single page, as opposed to navigation among pages. It interprets URL-like links to determine which views to create or destroy, and which components to load or unload. It allows you to take advantage of [lazy-loading](guide/glossary#lazy-load) in your Angular apps.
|
||||
|
||||
In most cases, components become attached to a router by means
|
||||
of a `RouterConfig` that defines routes to views.
|
||||
|
||||
A [routing component's](guide/glossary#routing-component) template has a `RouterOutlet` element
|
||||
where it can display views produced by the router.
|
||||
|
||||
Other views in the application likely have anchor tags or buttons with `RouterLink`
|
||||
directives that users can click to navigate.
|
||||
|
||||
For more information, see the [Routing & Navigation](guide/router) page.
|
||||
To learn more, see the [Routing & Navigation](guide/router) guide.
|
||||
|
||||
|
||||
## Router module
|
||||
@ -615,6 +513,9 @@ A separate [NgModule](guide/glossary#ngmodule) that provides the necessary servi
|
||||
|
||||
For more information, see the [Routing & Navigation](guide/router) page.
|
||||
|
||||
## Router outlet
|
||||
|
||||
A directive that acts as a placeholder in a routing component's template, which Angular dynamically fills based on the current router state.
|
||||
|
||||
## Routing component
|
||||
|
||||
@ -627,16 +528,10 @@ For more information, see the [Routing & Navigation](guide/router) page.
|
||||
|
||||
## Scoped package
|
||||
|
||||
A way to group related *npm* packages.
|
||||
Read more at the [npm-scope](https://docs.npmjs.com/misc/scope) page.
|
||||
|
||||
NgModules are delivered within *scoped packages* such as `@angular/core`,
|
||||
`@angular/common`, `@angular/platform-browser-dynamic`, `@angular/http`, and `@angular/router`.
|
||||
|
||||
Import a scoped package the same way that you import a normal package.
|
||||
The only difference, from a consumer perspective,
|
||||
is that the scoped package name begins with the Angular *scope name*, `@angular`.
|
||||
A way to group related NPM packages.
|
||||
NgModules are delivered within *scoped packages* whose names begin with the Angular *scope name* `@angular`. For example, `@angular/core`, `@angular/common`, `@angular/http`, and `@angular/router`.
|
||||
|
||||
Import a scoped package in the same way that you import a normal package.
|
||||
|
||||
<code-example path="architecture/src/app/app.component.ts" linenums="false" title="architecture/src/app/app.component.ts (import)" region="import">
|
||||
|
||||
@ -645,20 +540,12 @@ is that the scoped package name begins with the Angular *scope name*, `@angular`
|
||||
|
||||
## Service
|
||||
|
||||
For data or logic that is not associated
|
||||
with a specific view or that you want to share across components, build services.
|
||||
In Angular, a service is a class with the [@Injectable](guide/glossary#injectable) decorator that encapsulates non-UI logic and code that can be re-used across an application.
|
||||
Angular distinguishes components from services in order to increase modularity and reusability.
|
||||
|
||||
Applications often require services such as a hero data service or a logging service.
|
||||
|
||||
A service is a class with a focused purpose.
|
||||
You often create a service to implement features that are
|
||||
independent from any specific view,
|
||||
provide shared data or logic across components, or encapsulate external interactions.
|
||||
|
||||
Applications often require services such as a data service or a logging service.
|
||||
|
||||
For more information, see the [Services](tutorial/toh-pt4) page of the [Tour of Heroes](tutorial) tutorial.
|
||||
The `@Injectable` metadata allows the service class to be used with the [dependency injection](guide/glossary#di) mechanism. The injectable class is instantiated by a [provider](guide/glossary#provider), and a module maintains a list of providers that can provide a particular type of service as needed by components or other services that require it.
|
||||
|
||||
To learn more, see [Introduction to Services](guide/architecture-services).
|
||||
|
||||
{@a structural-directive}
|
||||
|
||||
@ -668,21 +555,35 @@ For more information, see the [Services](tutorial/toh-pt4) page of the [Tour of
|
||||
|
||||
## Structural directives
|
||||
|
||||
A category of [directive](guide/glossary#directive) that can
|
||||
shape or reshape HTML layout, typically by adding and removing elements in the DOM.
|
||||
The `ngIf` "conditional element" directive and the `ngFor` "repeater" directive are well-known examples.
|
||||
A category of [directive](guide/glossary#directive) that is responsible for shaping or reshaping HTML layout by modifying the DOM (adding, removing, or manipulating elements and their children).
|
||||
|
||||
Read more in the [Structural Directives](guide/structural-directives) page.
|
||||
To learn more, see the [Structural Directives](guide/structural-directives) page.
|
||||
|
||||
{@a subscriber}
|
||||
|
||||
## Subscriber
|
||||
|
||||
A function that defines how to obtain or generate values or messages to be published. This function is executed when a consumer calls the `subscribe()` method of an [observable](guide/glossary#observable).
|
||||
|
||||
The act of subscribing to an observable triggers its execution, associates callbacks with it, and creates a `Subscription` object that lets you unsubscribe.
|
||||
|
||||
The `subscribe()` method takes a JavaScript object (called an "observer") with up to three callbacks, one for each type of notification that an observable can deliver:
|
||||
|
||||
- The `next` notification: sends a value such as a Number, a String, an Object, etc.
|
||||
- The `error` notification sends a JavaScript Error or exception.
|
||||
- The `complete` notification does not send a value, but the handler is called when the call completes. Scheduled values can continue to be returned after the call completes.
|
||||
|
||||
{@a T}
|
||||
|
||||
## Template
|
||||
|
||||
A chunk of HTML that Angular uses to render a [view](guide/glossary#view) with
|
||||
the support and guidance of an Angular [directive](guide/glossary#directive),
|
||||
most notably a [component](guide/glossary#component).
|
||||
A template defines how to render a component's [view](guide/glossary#view) in HTML
|
||||
|
||||
A template combines straight HTML with Angular [data-binding](guide/glossary#data-binding) syntax, [directives](guide/glossary#directive), and [template expressions](guide/glossary#template-expression) (logical constructs). The Angular elements insert or calculate values that modify the HTML elements before the page is displayed.
|
||||
|
||||
A template is associated with a [component](guide/glossary#component) class through `@Component` [decorator](guide/glossary#decorator). The HTML can be provided inline, as the value of the `template` property, or in a separate HTML file linked through the `templateUrl` property.
|
||||
|
||||
Additional templates, represented by a `TemplateRef` object, can define alternative or _embedded_ views, which can be referenced from multiple components.
|
||||
|
||||
## Template-driven forms
|
||||
|
||||
@ -701,6 +602,8 @@ Template-driven forms are convenient, quick, and simple. They are a good choice
|
||||
Read about how to build template-driven forms
|
||||
in the [Forms](guide/forms) page.
|
||||
|
||||
{@a template-expression}
|
||||
|
||||
|
||||
## Template expression
|
||||
|
||||
@ -711,24 +614,27 @@ Read about how to write template expressions
|
||||
in the [Template expressions](guide/template-syntax#template-expressions) section
|
||||
of the [Template Syntax](guide/template-syntax) page.
|
||||
|
||||
{@a token}
|
||||
|
||||
## Token
|
||||
|
||||
An opaque identifier used for efficient table lookup. In Angular, a [DI token](guide/glossary#di-token) is used to find [providers](guide/glossary#provider) of dependencies in the [dependency injection](guide/glossary#di) system.
|
||||
|
||||
{@a transpile}
|
||||
|
||||
## Transpile
|
||||
|
||||
The process of transforming code written in one form of JavaScript
|
||||
(such as TypeScript) into another form of JavaScript. (See also [ECMAScript](guide/glossary#ecma)).
|
||||
The translation process that tranforms one version of JavaScript to another version; for example, down-leveling ES2015 to the older ES5 version.
|
||||
|
||||
|
||||
{@a typescript}
|
||||
|
||||
|
||||
## TypeScript
|
||||
|
||||
A version of JavaScript that supports most [ECMAScript 2015](guide/glossary#ecma)
|
||||
language features such as [decorators](guide/glossary#decorator).
|
||||
|
||||
TypeScript is notable for its optional typing system, which provides
|
||||
compile-time type checking and strong tooling support (such as "intellisense,"
|
||||
code completion, refactoring, and intelligent search). Many code editors
|
||||
and IDEs support TypeScript either natively or with plugins.
|
||||
TypeScript is a programming language notable for its optional typing system, which provides
|
||||
compile-time type checking and strong tooling support (such as
|
||||
code completion, refactoring, inline documentation, and intelligent search). Many code editors
|
||||
and IDEs support TypeScript either natively or with plug-ins.
|
||||
|
||||
TypeScript is the preferred language for Angular development. Read more about TypeScript at [typescriptlang.org](http://www.typescriptlang.org/).
|
||||
|
||||
@ -739,18 +645,26 @@ TypeScript is the preferred language for Angular development. Read more about Ty
|
||||
|
||||
## View
|
||||
|
||||
A portion of the screen that displays information and responds
|
||||
to user actions such as clicks, mouse moves, and keystrokes.
|
||||
A view is the smallest grouping of display elements that can be created and destroyed together.
|
||||
|
||||
Angular renders a view under the control of one or more [directives](guide/glossary#directive),
|
||||
especially [component](guide/glossary#component) directives and their companion [templates](guide/glossary#template).
|
||||
The component plays such a prominent role that it's often
|
||||
convenient to refer to a component as a view.
|
||||
especially [component](guide/glossary#component) directives and their companion [templates](guide/glossary#template).
|
||||
|
||||
Views often contain other views. Any view might be loaded and unloaded
|
||||
dynamically as the user navigates through the application, typically
|
||||
under the control of a [router](guide/glossary#router).
|
||||
A view is specifically represented by a `ViewRef` instance associated with the component.
|
||||
A view that belongs to a component is called a _host view_.
|
||||
Views are typically collected into [view hierarchies](guide/glossary#view-tree).
|
||||
|
||||
Properties of elements in a view can change dynamically, in response to user actions; the structure (number and order) of elements in a view cannot. You can change the structure of elements by inserting, moving, or removing nested views within their view containers.
|
||||
|
||||
View hierarchies can be loaded and unloaded dynamically as the user navigates through the application, typically under the control of a [router](guide/glossary#router).
|
||||
|
||||
{@a view-tree}
|
||||
|
||||
## View hierarchy
|
||||
|
||||
A tree of related views that can be acted on as a unit. The root view is a component's _host view_. A host view can be the root of a tree of _embedded views_, collected in a _view container_ (`ViewContainerRef`) attached to an anchor element in the hosting component. The view hierarchy is a key part of Angular change detection.
|
||||
|
||||
The view hierarchy does not imply a component hierarchy. Views that are embedded in the context of a particular hierarchy can be host views of other components. Those components can be in the same NgModule as the hosting component, or belong to other NgModules.
|
||||
|
||||
{@a W}
|
||||
|
||||
@ -769,21 +683,11 @@ See [Custom element](guide/glossary#custom-element)
|
||||
|
||||
## Zone
|
||||
|
||||
A mechanism for encapsulating and intercepting
|
||||
a JavaScript application's asynchronous activity.
|
||||
An execution context for a set of asynchronous tasks. Useful for debugging, profiling, and testing apps that include asynchronous operations such as event processing, promises, and calls to remote servers.
|
||||
|
||||
The browser DOM and JavaScript have a limited number
|
||||
of asynchronous activities, such as DOM events (for example, clicks),
|
||||
[promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), and
|
||||
[XHR](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
|
||||
calls to remote servers.
|
||||
An Angular app runs in a zone where it can respond to asynchronous events by checking for data changes and updating the information it displays by resolving [data bindings](guide/glossary#data-binding).
|
||||
|
||||
Zones intercept all of these activities and give a "zone client" the opportunity
|
||||
to take action before and after the async activity finishes.
|
||||
|
||||
Angular runs your application in a zone where it can respond to
|
||||
asynchronous events by checking for data changes and updating
|
||||
the information it displays via [data bindings](guide/glossary#data-binding).
|
||||
A zone client can take action before and after an async operation completes.
|
||||
|
||||
Learn more about zones in this
|
||||
[Brian Ford video](https://www.youtube.com/watch?v=3IqtmUscE_U).
|
||||
|
@ -1,9 +1,16 @@
|
||||
[
|
||||
{
|
||||
"startDate": "2018-02-14",
|
||||
"endDate": "2018-04-22",
|
||||
"endDate": "2018-04-18",
|
||||
"message": "Join us for ng-conf<br/>Apr 18th-20th, 2018",
|
||||
"imageUrl": "generated/images/marketing/home/ng-conf.png",
|
||||
"linkUrl": "http://ng-conf.org/"
|
||||
},
|
||||
{
|
||||
"startDate": "2018-04-18",
|
||||
"endDate": "2018-04-22",
|
||||
"message": "Watch ng-conf live stream <br/>Apr 18th-20th, 2018",
|
||||
"imageUrl": "generated/images/marketing/home/ng-conf.png",
|
||||
"linkUrl": "https://www.ng-conf.org/livestream/"
|
||||
}
|
||||
]
|
||||
|
@ -574,6 +574,12 @@
|
||||
"title": "Learn Angular (francais)",
|
||||
"url": "http://www.learn-angular.fr/"
|
||||
},
|
||||
"upgrading-ajs": {
|
||||
"desc": "The world's most comprehensive, step-by-step course on using best practices and avoiding pitfalls while migrating from AngularJS to Angular.",
|
||||
"rev": true,
|
||||
"title": "Upgrading AngularJS",
|
||||
"url": "https://www.upgradingangularjs.com"
|
||||
},
|
||||
"toddmotto-ultimateangular": {
|
||||
"desc": "Online courses providing in-depth coverage of the Angular ecosystem, AngularJS, Angular and TypeScript, with functional code samples and a full-featured seed environment. Get a deep understanding of Angular and TypeScript from foundation to functional application, then move on to advanced topics with Todd Motto and collaborators.",
|
||||
"rev": true,
|
||||
|
@ -339,7 +339,7 @@ fix the dashboard hero links to navigate via the _parameterized_ dashboard route
|
||||
</code-example>
|
||||
|
||||
You're using Angular [interpolation binding](guide/template-syntax#interpolation) within the `*ngFor` repeater
|
||||
to insert the current interation's `hero.id` into each
|
||||
to insert the current iteration's `hero.id` into each
|
||||
[`routerLink`](#routerlink).
|
||||
|
||||
{@a heroes-component-links}
|
||||
|
@ -12,16 +12,16 @@
|
||||
"aio-use-npm": "node tools/ng-packages-installer restore .",
|
||||
"aio-check-local": "node tools/ng-packages-installer check .",
|
||||
"ng": "yarn check-env && ng",
|
||||
"start": "yarn check-env && ng serve --aot",
|
||||
"prebuild": "yarn setup",
|
||||
"build": "yarn ~~build",
|
||||
"start": "yarn check-env && ng serve",
|
||||
"build": "yarn build-for stable",
|
||||
"prebuild-for": "yarn setup",
|
||||
"build-for": "yarn ~~build --configuration",
|
||||
"prebuild-local": "yarn setup-local",
|
||||
"build-local": "yarn ~~build",
|
||||
"build-local": "yarn ~~build --configuration=stable",
|
||||
"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",
|
||||
"e2e": "ng e2e --no-webdriver-update",
|
||||
"e2e-prod": "yarn e2e --environment=dev --target=production",
|
||||
"presetup": "yarn install --frozen-lockfile && yarn ~~check-env && yarn boilerplate:remove",
|
||||
"setup": "yarn aio-use-npm && yarn example-use-npm",
|
||||
"postsetup": "yarn boilerplate:add && yarn build-ie-polyfills && yarn docs",
|
||||
@ -45,7 +45,7 @@
|
||||
"docs-watch": "node tools/transforms/authors-package/watchr.js",
|
||||
"docs-lint": "eslint --ignore-path=\"tools/transforms/.eslintignore\" tools/transforms",
|
||||
"docs-test": "node tools/transforms/test.js",
|
||||
"deployment-config-test": "jasmine-ts tests/deployment-config/unit/**/*.spec.ts",
|
||||
"redirects-test": "jasmine-ts tests/deployment/unit/**/*.spec.ts",
|
||||
"firebase-utils-test": "jasmine-ts tools/firebase-test-utils/*.spec.ts",
|
||||
"tools-lint": "tslint -c \"tools/tslint.json\" \"tools/firebase-test-utils/**/*.ts\"",
|
||||
"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",
|
||||
@ -58,10 +58,10 @@
|
||||
"generate-zips": "node ./tools/example-zipper/generateZips",
|
||||
"sw-manifest": "ngu-sw-manifest --dist dist --in ngsw-manifest.json --out dist/ngsw-manifest.json",
|
||||
"sw-copy": "cp node_modules/@angular/service-worker/bundles/worker-basic.min.js dist/",
|
||||
"build-ie-polyfills": "node node_modules/webpack/bin/webpack.js -p src/ie-polyfills.js src/generated/ie-polyfills.min.js",
|
||||
"build-ie-polyfills": "yarn webpack-cli src/ie-polyfills.js -o src/generated/ie-polyfills.min.js --mode production",
|
||||
"update-webdriver": "webdriver-manager update --standalone false --gecko false $CHROMEDRIVER_VERSION_ARG",
|
||||
"~~check-env": "node scripts/check-environment",
|
||||
"~~build": "ng build --target=production --environment=stable -sm",
|
||||
"~~build": "ng build",
|
||||
"post~~build": "yarn sw-manifest && yarn sw-copy"
|
||||
},
|
||||
"engines": {
|
||||
@ -70,34 +70,36 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^6.0.0-rc.1",
|
||||
"@angular/cdk": "^5.0.0-rc.1",
|
||||
"@angular/common": "^6.0.0-rc.1",
|
||||
"@angular/compiler": "^6.0.0-rc.1",
|
||||
"@angular/core": "^6.0.0-rc.1",
|
||||
"@angular/elements": "^6.0.0-rc.1",
|
||||
"@angular/forms": "^6.0.0-rc.1",
|
||||
"@angular/http": "^6.0.0-rc.1",
|
||||
"@angular/material": "^5.0.0-rc.1",
|
||||
"@angular/platform-browser": "^6.0.0-rc.1",
|
||||
"@angular/platform-browser-dynamic": "^6.0.0-rc.1",
|
||||
"@angular/platform-server": "^6.0.0-rc.1",
|
||||
"@angular/router": "^6.0.0-rc.1",
|
||||
"@angular/animations": "6.0.0-rc.5",
|
||||
"@angular/cdk": "6.0.0-rc.11",
|
||||
"@angular/common": "6.0.0-rc.5",
|
||||
"@angular/core": "6.0.0-rc.5",
|
||||
"@angular/elements": "6.0.0-rc.5",
|
||||
"@angular/forms": "6.0.0-rc.5",
|
||||
"@angular/http": "6.0.0-rc.5",
|
||||
"@angular/material": "6.0.0-rc.11",
|
||||
"@angular/platform-browser": "6.0.0-rc.5",
|
||||
"@angular/platform-browser-dynamic": "6.0.0-rc.5",
|
||||
"@angular/platform-server": "6.0.0-rc.5",
|
||||
"@angular/router": "6.0.0-rc.5",
|
||||
"@angular/service-worker": "^1.0.0-beta.16",
|
||||
"@webcomponents/custom-elements": "^1.0.8",
|
||||
"classlist.js": "^1.1.20150312",
|
||||
"core-js": "^2.4.1",
|
||||
"jasmine": "^2.6.0",
|
||||
"ng-pwa-tools": "^0.0.10",
|
||||
"rxjs": "6.0.0-rc.0",
|
||||
"rxjs-compat": "6.0.0-rc.0",
|
||||
"rxjs": "6.0.0-uncanny-rc.7",
|
||||
"rxjs-compat": "6.0.0-uncanny-rc.7",
|
||||
"tslib": "^1.9.0",
|
||||
"web-animations-js": "^2.2.5",
|
||||
"zone.js": "^0.8.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "^1.7.3",
|
||||
"@angular/compiler-cli": "^6.0.0-rc.1",
|
||||
"@angular-devkit/build-angular": "^0.5.6",
|
||||
"@angular/cli": "^6.0.0-rc.4",
|
||||
"@angular/compiler": "6.0.0-rc.5",
|
||||
"@angular/compiler-cli": "6.0.0-rc.5",
|
||||
"@angular/language-service": "6.0.0-rc.5",
|
||||
"@types/jasmine": "^2.5.52",
|
||||
"@types/jasminewd2": "^2.0.3",
|
||||
"@types/node": "~6.0.60",
|
||||
@ -105,7 +107,7 @@
|
||||
"canonical-path": "^0.0.2",
|
||||
"chalk": "^2.1.0",
|
||||
"cjson": "^0.5.0",
|
||||
"codelyzer": "~2.0.0",
|
||||
"codelyzer": "~4.2.1",
|
||||
"concurrently": "^3.4.0",
|
||||
"cross-spawn": "^5.1.0",
|
||||
"css-selector-parser": "^1.3.0",
|
||||
@ -146,16 +148,17 @@
|
||||
"shelljs": "^0.7.7",
|
||||
"tree-kill": "^1.1.0",
|
||||
"ts-node": "^3.3.0",
|
||||
"tslint": "~4.5.0",
|
||||
"tslint": "~5.9.1",
|
||||
"typescript": "~2.7.2",
|
||||
"uglify-js": "^3.0.15",
|
||||
"unist-util-filter": "^0.2.1",
|
||||
"unist-util-source": "^1.0.1",
|
||||
"unist-util-visit": "^1.1.1",
|
||||
"unist-util-visit-parents": "^1.1.1",
|
||||
"vrsource-tslint-rules": "^4.0.1",
|
||||
"vrsource-tslint-rules": "^5.8.2",
|
||||
"watchr": "^3.0.1",
|
||||
"webpack-cli": "^2.0.14",
|
||||
"xregexp": "^4.0.0",
|
||||
"yargs": "^7.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,10 @@
|
||||
"aio": {
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"inline": 1971,
|
||||
"main": 565539,
|
||||
"polyfills": 38514,
|
||||
"prettify": 14886
|
||||
"runtime": 2689,
|
||||
"main": 478529,
|
||||
"polyfills": 38453,
|
||||
"prettify": 14913
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ fi
|
||||
if [[ $TRAVIS_BRANCH == master ]]; then
|
||||
readonly deployEnv=next
|
||||
elif [[ $TRAVIS_BRANCH == $STABLE_BRANCH ]]; then
|
||||
readonly deployEnv=stable
|
||||
readonly deployEnv=stable
|
||||
else
|
||||
# Extract the major versions from the branches, e.g. the 4 from 4.3.x
|
||||
readonly majorVersion=${TRAVIS_BRANCH%%.*}
|
||||
@ -87,7 +87,7 @@ fi
|
||||
cd "`dirname $0`/.."
|
||||
|
||||
# Build the app
|
||||
yarn build --env=$deployEnv
|
||||
yarn build-for $deployEnv
|
||||
|
||||
# Include any mode-specific files
|
||||
cp -rf src/extra-files/$deployEnv/. dist/
|
||||
|
@ -5,12 +5,11 @@ set +x -eu -o pipefail
|
||||
readonly thisDir="$(cd $(dirname ${BASH_SOURCE[0]}); pwd)"
|
||||
readonly aioDir="$(realpath $thisDir/..)"
|
||||
|
||||
readonly appPtorConf="$aioDir/tests/e2e/protractor.conf.js"
|
||||
readonly cfgPtorConf="$aioDir/tests/deployment-config/e2e/protractor.conf.js"
|
||||
readonly protractorConf="$aioDir/tests/deployment/e2e/protractor.conf.js"
|
||||
readonly minPwaScore="95"
|
||||
readonly urls=(
|
||||
"https://angular.io/"
|
||||
"https://next.angular.io"
|
||||
"https://next.angular.io/"
|
||||
)
|
||||
|
||||
cd "$aioDir"
|
||||
@ -24,11 +23,8 @@ set +x -eu -o pipefail
|
||||
for url in "${urls[@]}"; do
|
||||
echo -e "\nChecking '$url'...\n-----"
|
||||
|
||||
# Run e2e tests.
|
||||
yarn protractor "$appPtorConf" --baseUrl "$url"
|
||||
|
||||
# Run deployment config tests.
|
||||
yarn protractor "$cfgPtorConf" --baseUrl "$url"
|
||||
# Run basic e2e and deployment config tests.
|
||||
yarn protractor "$protractorConf" --baseUrl "$url"
|
||||
|
||||
# Run PWA-score tests.
|
||||
yarn test-pwa-score "$url" "$minPwaScore"
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
<mat-sidenav-container class="sidenav-container" [class.starting]="isStarting" [class.has-floating-toc]="hasFloatingToc" role="main">
|
||||
|
||||
<mat-sidenav [ngClass]="{'collapsed': !isSideBySide}" #sidenav class="sidenav" [opened]="isOpened" [mode]="mode" (open)="updateHostClasses()" (close)="updateHostClasses()">
|
||||
<mat-sidenav [ngClass]="{'collapsed': !isSideBySide}" #sidenav class="sidenav" [mode]="mode" [opened]="isOpened" (openedChange)="updateHostClasses()">
|
||||
<aio-nav-menu *ngIf="!isSideBySide" [nodes]="topMenuNarrowNodes" [currentNode]="currentNodes?.TopBarNarrow" [isWide]="false"></aio-nav-menu>
|
||||
<aio-nav-menu [nodes]="sideNavNodes" [currentNode]="currentNodes?.SideNav" [isWide]="isSideBySide"></aio-nav-menu>
|
||||
|
||||
|
@ -6,8 +6,8 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { MatProgressBar, MatSidenav } from '@angular/material';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
import { Observable, timer } from 'rxjs';
|
||||
import { mapTo } from 'rxjs/operators';
|
||||
import { timer } from 'rxjs';
|
||||
import { first, mapTo } from 'rxjs/operators';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppModule } from './app.module';
|
||||
@ -64,13 +64,13 @@ describe('AppComponent', () => {
|
||||
const de = fixture.debugElement;
|
||||
const docViewerDe = de.query(By.css('aio-doc-viewer'));
|
||||
|
||||
documentService = de.injector.get(DocumentService) as DocumentService;
|
||||
documentService = de.injector.get<DocumentService>(DocumentService);
|
||||
docViewer = docViewerDe.nativeElement;
|
||||
docViewerComponent = docViewerDe.componentInstance;
|
||||
hamburger = de.query(By.css('.hamburger')).nativeElement;
|
||||
locationService = de.injector.get(LocationService) as any;
|
||||
locationService = de.injector.get<any>(LocationService);
|
||||
sidenav = de.query(By.directive(MatSidenav)).componentInstance;
|
||||
tocService = de.injector.get(TocService);
|
||||
tocService = de.injector.get<TocService>(TocService);
|
||||
|
||||
return waitForDoc && awaitDocRendered();
|
||||
};
|
||||
@ -463,7 +463,7 @@ describe('AppComponent', () => {
|
||||
let scrollToTopSpy: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
scrollService = fixture.debugElement.injector.get(ScrollService);
|
||||
scrollService = fixture.debugElement.injector.get<ScrollService>(ScrollService);
|
||||
scrollSpy = spyOn(scrollService, 'scroll');
|
||||
scrollToTopSpy = spyOn(scrollService, 'scrollToTop');
|
||||
});
|
||||
@ -1114,20 +1114,23 @@ describe('AppComponent', () => {
|
||||
checkHostClass('sidenav', 'open');
|
||||
|
||||
sidenav.close();
|
||||
await waitForEmit(sidenav.onClose);
|
||||
await waitForSidenavOpenedChange();
|
||||
fixture.detectChanges();
|
||||
checkHostClass('sidenav', 'closed');
|
||||
|
||||
sidenav.open();
|
||||
await waitForEmit(sidenav.onOpen);
|
||||
await waitForSidenavOpenedChange();
|
||||
fixture.detectChanges();
|
||||
checkHostClass('sidenav', 'open');
|
||||
|
||||
function waitForEmit(emitter: Observable<void>): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
emitter.subscribe(resolve);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
async function waitForSidenavOpenedChange() {
|
||||
const promise = new Promise(resolve => sidenav.openedChange.pipe(first()).subscribe(resolve));
|
||||
|
||||
await Promise.resolve(); // Wait for `MatSidenav.openedChange.emit()` to be called.
|
||||
jasmine.clock().tick(0); // Notify `MatSidenav.openedChange` observers.
|
||||
// (It is an async `EventEmitter`, thus uses `setTimeout()`.)
|
||||
|
||||
await promise;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -97,11 +97,11 @@ describe('ApiListComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('initial critera from location', () => {
|
||||
describe('initial criteria from location', () => {
|
||||
let locationService: TestLocationService;
|
||||
|
||||
beforeEach(() => {
|
||||
locationService = <any> fixture.componentRef.injector.get(LocationService);
|
||||
locationService = fixture.componentRef.injector.get<any>(LocationService);
|
||||
});
|
||||
|
||||
function expectOneItem(name: string, section: string, type: string, stability: string) {
|
||||
@ -110,7 +110,7 @@ describe('ApiListComponent', () => {
|
||||
component.filteredSections.subscribe(filtered => {
|
||||
expect(filtered.length).toBe(1, 'sections');
|
||||
expect(filtered[0].name).toBe(section, 'section name');
|
||||
const items = filtered[0].items.filter(item => item.show);
|
||||
const items = filtered[0].items.filter(i => i.show);
|
||||
expect(items.length).toBe(1, 'items');
|
||||
|
||||
const item = items[0];
|
||||
@ -168,7 +168,7 @@ describe('ApiListComponent', () => {
|
||||
let locationService: TestLocationService;
|
||||
|
||||
beforeEach(() => {
|
||||
locationService = <any> fixture.componentRef.injector.get(LocationService);
|
||||
locationService = fixture.componentRef.injector.get<any>(LocationService);
|
||||
});
|
||||
|
||||
it('should have query', () => {
|
||||
|
@ -16,9 +16,9 @@ import { ApiSection, ApiService } from './api.service';
|
||||
import { Option } from 'app/shared/select/select.component';
|
||||
|
||||
class SearchCriteria {
|
||||
query? = '';
|
||||
status? = 'all';
|
||||
type? = 'all';
|
||||
query ? = '';
|
||||
status ? = 'all';
|
||||
type ? = 'all';
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
@ -21,7 +21,7 @@ describe('ApiService', () => {
|
||||
]
|
||||
});
|
||||
|
||||
service = injector.get(ApiService);
|
||||
service = injector.get<ApiService>(ApiService);
|
||||
httpMock = injector.get(HttpTestingController);
|
||||
});
|
||||
|
||||
|
@ -15,18 +15,18 @@ import { CodeComponent } from './code.component';
|
||||
*/
|
||||
@Component({
|
||||
selector: 'code-example',
|
||||
template: `
|
||||
template: `
|
||||
<!-- Content projection is used to get the content HTML provided to this component -->
|
||||
<div #content style="display: none"><ng-content></ng-content></div>
|
||||
|
||||
|
||||
<header *ngIf="title">{{title}}</header>
|
||||
|
||||
<aio-code [ngClass]="classes"
|
||||
[language]="language"
|
||||
[linenums]="linenums"
|
||||
[path]="path"
|
||||
[region]="region"
|
||||
[hideCopy]="hidecopy"
|
||||
<aio-code [ngClass]="classes"
|
||||
[language]="language"
|
||||
[linenums]="linenums"
|
||||
[path]="path"
|
||||
[region]="region"
|
||||
[hideCopy]="hidecopy"
|
||||
[title]="title">
|
||||
</aio-code>
|
||||
`,
|
||||
|
@ -87,7 +87,7 @@ describe('CodeTabsComponent', () => {
|
||||
region="region-B"
|
||||
title="title-B">
|
||||
Code example 2
|
||||
</code-pane>
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
`
|
||||
})
|
||||
|
@ -24,7 +24,7 @@ export interface TabInfo {
|
||||
template: `
|
||||
<!-- Use content projection so that the provided HTML's code-panes can be split into tabs -->
|
||||
<div #content style="display: none"><ng-content></ng-content></div>
|
||||
|
||||
|
||||
<mat-tab-group class="code-tab-group" disableRipple>
|
||||
<mat-tab style="overflow-y: hidden;" *ngFor="let tab of tabs">
|
||||
<ng-template mat-tab-label>
|
||||
@ -37,7 +37,7 @@ export interface TabInfo {
|
||||
[region]="tab.region"
|
||||
[title]="tab.title">
|
||||
</aio-code>
|
||||
</mat-tab>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
`,
|
||||
})
|
||||
|
@ -19,7 +19,7 @@ describe('ContributorService', () => {
|
||||
]
|
||||
});
|
||||
|
||||
contribService = injector.get(ContributorService);
|
||||
contribService = injector.get<ContributorService>(ContributorService);
|
||||
httpMock = injector.get(HttpTestingController);
|
||||
});
|
||||
|
||||
|
@ -11,5 +11,5 @@ export class Contributor {
|
||||
website?: string;
|
||||
twitter?: string;
|
||||
bio?: string;
|
||||
isFlipped? = false;
|
||||
isFlipped ? = false;
|
||||
}
|
||||
|
@ -366,13 +366,18 @@ describe('TocComponent', () => {
|
||||
let parentScrollTop: number;
|
||||
|
||||
beforeEach(() => {
|
||||
const hostElem = fixture.nativeElement;
|
||||
const firstItem = page.listItems[0].nativeElement;
|
||||
const offsetParent = firstItem.offsetParent;
|
||||
|
||||
offsetParent.style.maxHeight = `${offsetParent.clientHeight - firstItem.clientHeight}px`;
|
||||
Object.defineProperty(offsetParent, 'scrollTop', {
|
||||
Object.assign(hostElem.style, {
|
||||
display: 'block',
|
||||
maxHeight: `${hostElem.clientHeight - firstItem.clientHeight}px`,
|
||||
overflow: 'auto',
|
||||
position: 'relative',
|
||||
});
|
||||
Object.defineProperty(hostElem, 'scrollTop', {
|
||||
get: () => parentScrollTop,
|
||||
set: v => parentScrollTop = v
|
||||
set: v => parentScrollTop = v,
|
||||
});
|
||||
|
||||
parentScrollTop = 0;
|
||||
@ -461,7 +466,7 @@ class TestTocService {
|
||||
activeItemIndex = new BehaviorSubject<number | null>(null);
|
||||
setActiveIndex(index: number|null) {
|
||||
this.activeItemIndex.next(index);
|
||||
if (asap.scheduled) {
|
||||
if (asap.scheduled !== undefined) {
|
||||
asap.flush();
|
||||
}
|
||||
}
|
||||
|
@ -90,5 +90,5 @@ export class TocComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
function count<T>(array: T[], fn: (item: T) => boolean) {
|
||||
return array.reduce((count, item) => fn(item) ? count + 1 : count, 0);
|
||||
return array.reduce((result, item) => fn(item) ? result + 1 : result, 0);
|
||||
}
|
||||
|
@ -5,12 +5,13 @@ describe('CustomIconRegistry', () => {
|
||||
it('should get the SVG element for a preloaded icon from the cache', () => {
|
||||
const mockHttp: any = {};
|
||||
const mockSanitizer: any = {};
|
||||
const mockDocument: any = {};
|
||||
const svgSrc = '<svg xmlns="http://www.w3.org/2000/svg" focusable="false" ' +
|
||||
'viewBox="0 0 24 24"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"/></svg>';
|
||||
const svgIcons: SvgIconInfo[] = [
|
||||
{ name: 'test_icon', svgSource: svgSrc }
|
||||
];
|
||||
const registry = new CustomIconRegistry(mockHttp, mockSanitizer, svgIcons);
|
||||
const registry = new CustomIconRegistry(mockHttp, mockSanitizer, mockDocument, svgIcons);
|
||||
let svgElement: SVGElement|undefined;
|
||||
registry.getNamedSvgIcon('test_icon').subscribe(el => svgElement = el);
|
||||
expect(svgElement).toEqual(createSvg(svgSrc));
|
||||
@ -19,6 +20,7 @@ describe('CustomIconRegistry', () => {
|
||||
it('should call through to the MdIconRegistry if the icon name is not in the preloaded cache', () => {
|
||||
const mockHttp: any = {};
|
||||
const mockSanitizer: any = {};
|
||||
const mockDocument: any = {};
|
||||
const svgSrc = '<svg xmlns="http://www.w3.org/2000/svg" focusable="false" ' +
|
||||
'viewBox="0 0 24 24"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"/></svg>';
|
||||
const svgIcons: SvgIconInfo[] = [
|
||||
@ -26,7 +28,7 @@ describe('CustomIconRegistry', () => {
|
||||
];
|
||||
spyOn(MatIconRegistry.prototype, 'getNamedSvgIcon');
|
||||
|
||||
const registry = new CustomIconRegistry(mockHttp, mockSanitizer, svgIcons);
|
||||
const registry = new CustomIconRegistry(mockHttp, mockSanitizer, mockDocument, svgIcons);
|
||||
|
||||
registry.getNamedSvgIcon('other_icon');
|
||||
expect(MatIconRegistry.prototype.getNamedSvgIcon).toHaveBeenCalledWith('other_icon', undefined);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { InjectionToken, Inject, Injectable } from '@angular/core';
|
||||
import { InjectionToken, Inject, Injectable, Optional } from '@angular/core';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { of } from 'rxjs';
|
||||
import { MatIconRegistry } from '@angular/material/icon';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
@ -35,8 +36,9 @@ interface SvgIconMap {
|
||||
export class CustomIconRegistry extends MatIconRegistry {
|
||||
private preloadedSvgElements: SvgIconMap = {};
|
||||
|
||||
constructor(http: HttpClient, sanitizer: DomSanitizer, @Inject(SVG_ICONS) svgIcons: SvgIconInfo[]) {
|
||||
super(http, sanitizer);
|
||||
constructor(http: HttpClient, sanitizer: DomSanitizer, @Optional() @Inject(DOCUMENT) document,
|
||||
@Inject(SVG_ICONS) svgIcons: SvgIconInfo[]) {
|
||||
super(http, sanitizer, document);
|
||||
this.loadSvgElements(svgIcons);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { DOCUMENT } from '@angular/platform-browser';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { fromEvent, Observable, ReplaySubject, Subject } from 'rxjs';
|
||||
import { auditTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { ReflectiveInjector } from '@angular/core';
|
||||
import { DOCUMENT, DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import { ScrollItem, ScrollSpyInfo, ScrollSpyService } from 'app/shared/scroll-spy.service';
|
||||
@ -33,8 +34,8 @@ describe('TocService', () => {
|
||||
|
||||
describe('tocList', () => {
|
||||
it('should emit the latest value to new subscribers', () => {
|
||||
const expectedValue1 = tocItem('Heading A');
|
||||
const expectedValue2 = tocItem('Heading B');
|
||||
const expectedValue1 = createTocItem('Heading A');
|
||||
const expectedValue2 = createTocItem('Heading B');
|
||||
let value1: TocItem[]|undefined;
|
||||
let value2: TocItem[]|undefined;
|
||||
|
||||
@ -48,8 +49,8 @@ describe('TocService', () => {
|
||||
});
|
||||
|
||||
it('should emit the same values to all subscribers', () => {
|
||||
const expectedValue1 = tocItem('Heading A');
|
||||
const expectedValue2 = tocItem('Heading B');
|
||||
const expectedValue1 = createTocItem('Heading A');
|
||||
const expectedValue2 = createTocItem('Heading B');
|
||||
const emittedValues: TocItem[][] = [];
|
||||
|
||||
tocService.tocList.subscribe(v => emittedValues.push(v));
|
||||
@ -149,8 +150,8 @@ describe('TocService', () => {
|
||||
describe('should clear tocList', () => {
|
||||
beforeEach(() => {
|
||||
// Start w/ dummy data from previous usage
|
||||
const expectedValue1 = tocItem('Heading A');
|
||||
const expectedValue2 = tocItem('Heading B');
|
||||
const expectedValue1 = createTocItem('Heading A');
|
||||
const expectedValue2 = createTocItem('Heading B');
|
||||
tocService.tocList.next([expectedValue1, expectedValue2]);
|
||||
expect(lastTocList).not.toEqual([]);
|
||||
});
|
||||
@ -369,7 +370,7 @@ class MockScrollSpyService {
|
||||
}
|
||||
}
|
||||
|
||||
function tocItem(title: string, level = 'h2', href = '', content = title) {
|
||||
function createTocItem(title: string, level = 'h2', href = '', content = title) {
|
||||
return { title, href, level, content };
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { DOCUMENT, DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||
import { ReplaySubject } from 'rxjs';
|
||||
import { ScrollSpyInfo, ScrollSpyService } from 'app/shared/scroll-spy.service';
|
||||
|
||||
|
@ -4,12 +4,10 @@
|
||||
// The list of which env maps to which file can be found in `angular-cli.json`.
|
||||
|
||||
|
||||
// Reflect.metadata polyfill is only needed in the JIT/dev mode.
|
||||
//
|
||||
// In order to load these polyfills early enough (before app code), polyfill.ts imports this file to
|
||||
// to change the order in the final bundle.
|
||||
import 'core-js/es6/reflect';
|
||||
import 'core-js/es7/reflect';
|
||||
// Reflect.metadata polyfill is only needed in the JIT, which use use only for tests
|
||||
// to make the unit tests work we load these polyfills in tests.ts instead
|
||||
// import 'core-js/es6/reflect';
|
||||
// import 'core-js/es7/reflect';
|
||||
|
||||
|
||||
export const environment = {
|
||||
|
@ -1,22 +1,23 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/0.13/config/configuration-file.html
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular/cli'],
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular/cli/plugins/karma')
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client:{
|
||||
client: {
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
reports: [ 'html', 'lcovonly' ],
|
||||
dir: require('path').join(__dirname, 'coverage'),
|
||||
reports: ['html', 'lcovonly'],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
angularCli: {
|
||||
|
@ -27,9 +27,6 @@
|
||||
* and executed before the rest of the application files are executed.
|
||||
*/
|
||||
|
||||
/** HACK: force import of environment.ts/environment.prod.ts to load env specific polyfills */
|
||||
import './environments/environment';
|
||||
|
||||
/** ALL Firefox browsers require the following to support `@angular/animation`. **/
|
||||
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||
|
||||
|
@ -3,25 +3,22 @@
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
|
||||
declare const __karma__: any;
|
||||
declare const require: any;
|
||||
|
||||
// Prevent Karma from running prematurely.
|
||||
__karma__.loaded = function () {};
|
||||
// Reflect.metadata polyfill is only needed in the JIT mode which we use only for unit tests
|
||||
import 'core-js/es6/reflect';
|
||||
import 'core-js/es7/reflect';
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
// Finally, start Karma to run the tests.
|
||||
__karma__.start();
|
||||
|
@ -3,19 +3,18 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/spec",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"baseUrl": "",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"test.ts"
|
||||
"test.ts",
|
||||
"polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"testing/**/*.ts",
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
}
|
17
aio/src/tslint.json
Normal file
17
aio/src/tslint.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"aio",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"aio",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
import { browser } from 'protractor';
|
||||
|
||||
describe(browser.baseUrl, () => {
|
||||
const sitemapUrls = browser.params.sitemapUrls;
|
||||
const legacyUrls = browser.params.legacyUrls;
|
||||
const goTo = async url => {
|
||||
// Go to the specified URL and then unregister the ServiceWorker
|
||||
// to ensure subsequent requests are passed through to the server.
|
||||
await browser.get(url);
|
||||
await browser.executeAsyncScript(cb => navigator.serviceWorker
|
||||
.getRegistrations()
|
||||
.then(regs => Promise.all(regs.map(reg => reg.unregister())))
|
||||
.then(cb));
|
||||
};
|
||||
|
||||
beforeAll(async done => {
|
||||
// Make an initial request to unregister the ServiceWorker.
|
||||
await goTo(browser.baseUrl);
|
||||
done();
|
||||
});
|
||||
|
||||
beforeEach(() => browser.waitForAngularEnabled(false));
|
||||
afterEach(() => browser.waitForAngularEnabled(true));
|
||||
|
||||
describe('(with sitemap URLs)', () => {
|
||||
sitemapUrls.forEach((url, i) => {
|
||||
it(`should not redirect '${url}' (${i + 1}/${sitemapUrls.length})`, async () => {
|
||||
await goTo(url);
|
||||
|
||||
const expectedUrl = browser.baseUrl + url;
|
||||
const actualUrl = (await browser.getCurrentUrl()).replace(/\?.*$/, '');
|
||||
|
||||
expect(actualUrl).toBe(expectedUrl);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('(with legacy URLs)', () => {
|
||||
legacyUrls.forEach(([fromUrl, toUrl], i) => {
|
||||
it(`should redirect '${fromUrl}' to '${toUrl}' (${i + 1}/${legacyUrls.length})`, async () => {
|
||||
await goTo(fromUrl);
|
||||
|
||||
const expectedUrl = (/^http/.test(toUrl) ? '' : browser.baseUrl.replace(/\/$/, '')) + toUrl;
|
||||
const actualUrl = (await browser.getCurrentUrl()).replace(/\?.*$/, '');
|
||||
|
||||
expect(actualUrl).toBe(expectedUrl);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
37
aio/tests/deployment/e2e/redirection.e2e-spec.ts
Normal file
37
aio/tests/deployment/e2e/redirection.e2e-spec.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { browser } from 'protractor';
|
||||
import { SitePage } from './site.po';
|
||||
|
||||
describe(browser.baseUrl, () => {
|
||||
const page = new SitePage();
|
||||
|
||||
beforeAll(done => page.init().then(done));
|
||||
|
||||
beforeEach(() => browser.waitForAngularEnabled(false));
|
||||
afterEach(() => browser.waitForAngularEnabled(true));
|
||||
|
||||
describe('(with sitemap URLs)', () => {
|
||||
page.sitemapUrls.forEach((url, i) => {
|
||||
it(`should not redirect '${url}' (${i + 1}/${page.sitemapUrls.length})`, async () => {
|
||||
await page.goTo(url);
|
||||
|
||||
const expectedUrl = browser.baseUrl + url;
|
||||
const actualUrl = (await browser.getCurrentUrl()).replace(/\?.*$/, '');
|
||||
|
||||
expect(actualUrl).toBe(expectedUrl);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('(with legacy URLs)', () => {
|
||||
page.legacyUrls.forEach(([fromUrl, toUrl], i) => {
|
||||
it(`should redirect '${fromUrl}' to '${toUrl}' (${i + 1}/${page.legacyUrls.length})`, async () => {
|
||||
await page.goTo(fromUrl);
|
||||
|
||||
const expectedUrl = (/^http/.test(toUrl) ? '' : browser.baseUrl.replace(/\/$/, '')) + toUrl;
|
||||
const actualUrl = (await browser.getCurrentUrl()).replace(/\?.*$/, '');
|
||||
|
||||
expect(actualUrl).toBe(expectedUrl);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
60
aio/tests/deployment/e2e/site.po.ts
Normal file
60
aio/tests/deployment/e2e/site.po.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import { browser, by, element, ExpectedConditions } from 'protractor';
|
||||
|
||||
export class SitePage {
|
||||
/** All URLs found in the app's `sitemap.xml` (i.e. valid URLs tha should not be redirected). */
|
||||
sitemapUrls: string[] = browser.params.sitemapUrls;
|
||||
|
||||
/** A list of legacy URLs that should be redirected to new URLs (in the form `[fromUrl, toUrl]`). */
|
||||
legacyUrls: string[][] = browser.params.legacyUrls;
|
||||
|
||||
/**
|
||||
* Enter a query into the search field.
|
||||
*/
|
||||
async enterSearch(query: string) {
|
||||
const searchInput = element(by.css('input[type=search]'));
|
||||
await searchInput.clear();
|
||||
await searchInput.sendKeys(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text content of the `aio-doc-viewer` element (in lowercase).
|
||||
*/
|
||||
async getDocViewerText() {
|
||||
const docViewer = element(by.css('aio-doc-viewer'));
|
||||
const text = await docViewer.getText();
|
||||
return text.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of text contents for all search result items found on the page.
|
||||
*/
|
||||
async getSearchResults() {
|
||||
const results = element.all(by.css('.search-results li'));
|
||||
await browser.wait(ExpectedConditions.presenceOf(results.first()), 8000);
|
||||
return await results.map<string>(link => link!.getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to a URL, disable animations, unregister the ServiceWorker, and wait for Angular.
|
||||
* (The SW is unregistered to ensure that subsequent requests are passed through to the server.)
|
||||
*/
|
||||
async goTo(url: string) {
|
||||
const unregisterServiceWorker = (cb: () => void) => navigator.serviceWorker
|
||||
.getRegistrations()
|
||||
.then(regs => Promise.all(regs.map(reg => reg.unregister())))
|
||||
.then(cb);
|
||||
|
||||
await browser.get(url || browser.baseUrl);
|
||||
await browser.executeScript('document.body.classList.add(\'no-animations\')');
|
||||
await browser.executeAsyncScript(unregisterServiceWorker);
|
||||
await browser.waitForAngular();
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the page object and get it ready for further requests.
|
||||
*/
|
||||
async init() {
|
||||
// Make an initial request to unregister the ServiceWorker.
|
||||
await this.goTo('');
|
||||
}
|
||||
}
|
103
aio/tests/deployment/e2e/smoke-tests.e2e-spec.ts
Normal file
103
aio/tests/deployment/e2e/smoke-tests.e2e-spec.ts
Normal file
@ -0,0 +1,103 @@
|
||||
import { browser } from 'protractor';
|
||||
import { SitePage } from './site.po';
|
||||
|
||||
describe(browser.baseUrl, () => {
|
||||
const page = new SitePage();
|
||||
|
||||
beforeAll(done => page.init().then(done));
|
||||
|
||||
beforeEach(() => browser.waitForAngularEnabled(false));
|
||||
afterEach(() => browser.waitForAngularEnabled(true));
|
||||
|
||||
describe('(smoke tests)', () => {
|
||||
it('should show the home page', () => {
|
||||
page.goTo('');
|
||||
const text = page.getDocViewerText();
|
||||
|
||||
expect(text).toContain('one framework');
|
||||
expect(text).toContain('mobile & desktop');
|
||||
});
|
||||
|
||||
describe('(marketing pages)', () => {
|
||||
const textPerUrl = {
|
||||
features: 'features & benefits',
|
||||
docs: 'what is angular?',
|
||||
events: 'events',
|
||||
resources: 'explore angular resources',
|
||||
};
|
||||
|
||||
Object.keys(textPerUrl).forEach(url => {
|
||||
it(`should show the page at '${url}'`, () => {
|
||||
page.goTo(url);
|
||||
expect(page.getDocViewerText()).toContain(textPerUrl[url]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('(docs pages)', () => {
|
||||
const textPerUrl = {
|
||||
api: 'api list',
|
||||
'guide/architecture': 'architecture',
|
||||
'guide/http': 'httpclient',
|
||||
'guide/quickstart': 'quickstart',
|
||||
'guide/security': 'security',
|
||||
tutorial: 'tutorial',
|
||||
};
|
||||
|
||||
Object.keys(textPerUrl).forEach(url => {
|
||||
it(`should show the page at '${url}'`, () => {
|
||||
page.goTo(url);
|
||||
expect(page.getDocViewerText()).toContain(textPerUrl[url]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('(api docs pages)', () => {
|
||||
const textPerUrl = {
|
||||
/* Class */ 'api/core/Injector': 'class injector',
|
||||
/* Const */ 'api/forms/NG_VALIDATORS': 'const ng_validators',
|
||||
/* Decorator */ 'api/core/Component': '@component',
|
||||
/* Directive */ 'api/common/NgIf': 'class ngif',
|
||||
/* Enum */ 'api/core/ChangeDetectionStrategy': 'enum changedetectionstrategy',
|
||||
/* Function */ 'api/animations/animate': 'animate(',
|
||||
/* Interface */ 'api/core/OnDestroy': 'interface ondestroy',
|
||||
/* Pipe */ 'api/common/JsonPipe': '| json',
|
||||
/* Type-Alias */ 'api/common/http/HttpEvent': 'type httpevent',
|
||||
};
|
||||
|
||||
Object.keys(textPerUrl).forEach(url => {
|
||||
it(`should show the page at '${url}'`, () => {
|
||||
page.goTo(url);
|
||||
expect(page.getDocViewerText()).toContain(textPerUrl[url]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('(search results)', () => {
|
||||
beforeEach(() => page.goTo(''));
|
||||
|
||||
it('should find pages when searching by a partial word in the title', () => {
|
||||
page.enterSearch('ngCont');
|
||||
expect(page.getSearchResults()).toContain('NgControl');
|
||||
});
|
||||
|
||||
it('should find API docs when searching for an instance member name', () => {
|
||||
page.enterSearch('writeValue');
|
||||
expect(page.getSearchResults()).toContain('ControlValueAccessor');
|
||||
});
|
||||
|
||||
it('should find API docs when searching for a static member name', () => {
|
||||
page.enterSearch('compose');
|
||||
expect(page.getSearchResults()).toContain('Validators');
|
||||
});
|
||||
});
|
||||
|
||||
it('should show relevant results on 404', () => {
|
||||
page.goTo('http/router');
|
||||
const results = page.getSearchResults();
|
||||
|
||||
expect(results).toContain('HttpClient');
|
||||
expect(results).toContain('Router');
|
||||
});
|
||||
});
|
||||
});
|
@ -39,14 +39,14 @@ describe('site App', function() {
|
||||
navItemHeadings.each(heading => testNavItemHeading(heading!, 1));
|
||||
|
||||
// Helpers
|
||||
function expectToBeCollapsed(element: ElementFinder) {
|
||||
expect(element.getAttribute('class')).toMatch(/\bcollapsed\b/);
|
||||
expect(element.getAttribute('class')).not.toMatch(/\bexpanded\b/);
|
||||
function expectToBeCollapsed(elementFinder: ElementFinder) {
|
||||
expect(elementFinder.getAttribute('class')).toMatch(/\bcollapsed\b/);
|
||||
expect(elementFinder.getAttribute('class')).not.toMatch(/\bexpanded\b/);
|
||||
}
|
||||
|
||||
function expectToBeExpanded(element: ElementFinder) {
|
||||
expect(element.getAttribute('class')).not.toMatch(/\bcollapsed\b/);
|
||||
expect(element.getAttribute('class')).toMatch(/\bexpanded\b/);
|
||||
function expectToBeExpanded(elementFinder: ElementFinder) {
|
||||
expect(elementFinder.getAttribute('class')).not.toMatch(/\bcollapsed\b/);
|
||||
expect(elementFinder.getAttribute('class')).toMatch(/\bexpanded\b/);
|
||||
}
|
||||
|
||||
function testNavItemHeading(heading: ElementFinder, level: number) {
|
||||
|
@ -21,7 +21,7 @@ export class SitePage {
|
||||
|
||||
getNavItem(pattern: RegExp) {
|
||||
return element.all(by.css('aio-nav-item .vertical-menu-item'))
|
||||
.filter(element => element.getText().then(text => pattern.test(text)))
|
||||
.filter(elementFinder => elementFinder.getText().then(text => pattern.test(text)))
|
||||
.first();
|
||||
}
|
||||
getNavItemHeadings(parent: ElementFinder, level: number) {
|
||||
@ -49,10 +49,10 @@ export class SitePage {
|
||||
return this.docViewer.getText();
|
||||
}
|
||||
|
||||
getInnerHtml(element) {
|
||||
getInnerHtml(elementFinder) {
|
||||
// `getInnerHtml` was removed from webDriver and this is the workaround.
|
||||
// See https://github.com/angular/protractor/blob/master/CHANGELOG.md#breaking-changes
|
||||
return browser.executeScript('return arguments[0].innerHTML;', element);
|
||||
return browser.executeScript('return arguments[0].innerHTML;', elementFinder);
|
||||
}
|
||||
|
||||
getScrollTop() {
|
||||
@ -63,8 +63,8 @@ export class SitePage {
|
||||
return browser.executeScript('window.scrollTo(0, document.body.scrollHeight)');
|
||||
}
|
||||
|
||||
click(element: ElementFinder) {
|
||||
return element.click().then(() => browser.waitForAngular());
|
||||
click(elementFinder: ElementFinder) {
|
||||
return elementFinder.click().then(() => browser.waitForAngular());
|
||||
}
|
||||
|
||||
enterSearch(query: string) {
|
||||
|
@ -1,10 +1,9 @@
|
||||
const fs = require('fs');
|
||||
const sh = require('shelljs');
|
||||
|
||||
const PATCH_LOCK = 'node_modules/@angular/cli/models/webpack-configs/.patched';
|
||||
const PATCH_LOCK = 'node_modules/@angular/cli/.patched';
|
||||
|
||||
if (!fs.existsSync(PATCH_LOCK)) {
|
||||
sh.exec('patch -p0 -i tools/cli-patches/webpack-no-global.patch');
|
||||
sh.touch(PATCH_LOCK);
|
||||
}
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
--- node_modules/@angular/cli/models/webpack-configs/browser.js 2017-11-01 12:07:56.000000000 +0100
|
||||
+++ node_modules/@angular/cli/models/webpack-configs/browser.js 2017-11-01 12:08:12.000000000 +0100
|
||||
@@ -104,11 +104,11 @@
|
||||
].concat(extraPlugins),
|
||||
node: {
|
||||
fs: 'empty',
|
||||
- global: true,
|
||||
+ global: false,
|
||||
crypto: 'empty',
|
||||
tls: 'empty',
|
||||
net: 'empty',
|
||||
- process: true,
|
||||
+ process: false,
|
||||
module: false,
|
||||
clearImmediate: false,
|
||||
setImmediate: false
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user