Compare commits

..

1 Commits

Author SHA1 Message Date
cf4edbce40 feat(compiler-cli): expose ngtsc as a TscPlugin
This lets us run ngtsc under the tsc_wrapped custom compiler (Used in Bazel)
It also allows others to simply wire ngtsc into an existing typescript compilation binary
2019-01-28 14:52:06 -08:00
97 changed files with 1243 additions and 2409 deletions

View File

@ -22,18 +22,12 @@ test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test
# Filesystem interactions #
###############################
# Create symlinks in the project:
# - dist/bin for outputs
# - dist/testlogs, dist/genfiles
# - bazel-out
# NB: bazel-out should be excluded from the editor configuration.
# The checked-in /.vscode/settings.json does this for VSCode.
# Other editors may require manual config to ignore this directory.
# In the past, we say a problem where VSCode traversed a massive tree, opening file handles and
# Don't create symlinks like bazel-out in the project.
# These cause VSCode to traverse a massive tree, opening file handles and
# eventually a surprising failure with auto-discovery of the C++ toolchain in
# MacOS High Sierra.
# See https://github.com/bazelbuild/bazel/issues/4603
build --symlink_prefix=dist/
build --symlink_prefix=/
# Performance: avoid stat'ing input files
build --watchfs

4
.gitignore vendored
View File

@ -1,7 +1,7 @@
.DS_STORE
/dist/
/bazel-out/
/bazel-*
/integration/bazel/bazel-*
e2e_test.*
node_modules
@ -13,9 +13,9 @@ pubspec.lock
.c9
.idea/
.settings/
.vscode/launch.json
*.swo
modules/.settings
.vscode
modules/.vscode
# Don't check in secret files

15
.vscode/settings.json vendored
View File

@ -1,15 +0,0 @@
{
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/node_modules/**": true,
"**/bazel-out/**": true,
"**/dist/**": true,
},
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/bazel-out": true,
"**/dist": true,
},
}

View File

@ -1,43 +1,3 @@
<a name="8.0.0-beta.1"></a>
# [8.0.0-beta.1](https://github.com/angular/angular/compare/8.0.0-beta.0...8.0.0-beta.1) (2019-01-22)
### Bug Fixes
* **bazel:** increase node memory limit for ng_module rule to prevent OOM for big modules ([#28237](https://github.com/angular/angular/issues/28237)) ([73616ab](https://github.com/angular/angular/commit/73616ab))
* **router:** `skipLocationChange` with named outlets ([#28300](https://github.com/angular/angular/issues/28300)) ([50df897](https://github.com/angular/angular/commit/50df897)), closes [#27680](https://github.com/angular/angular/issues/27680) [#28200](https://github.com/angular/angular/issues/28200)
### Features
* **bazel:** Add support for SASS ([#28167](https://github.com/angular/angular/issues/28167)) ([f59f18c](https://github.com/angular/angular/commit/f59f18c))
* **compiler-cli:** resolve generated Sass/Less files to .css inputs ([#28166](https://github.com/angular/angular/issues/28166)) ([a58fd21](https://github.com/angular/angular/commit/a58fd21))
* **forms:** add `markAllAsTouched()` to `AbstractControl` ([#26812](https://github.com/angular/angular/issues/26812)) ([45bf911](https://github.com/angular/angular/commit/45bf911)), closes [#19400](https://github.com/angular/angular/issues/19400)
### Reverts
* "ci: use image based cache for windows BuildKite ([#27990](https://github.com/angular/angular/issues/27990))" ([#28160](https://github.com/angular/angular/issues/28160)) ([7bdf3fe](https://github.com/angular/angular/commit/7bdf3fe))
<a name="7.2.2"></a>
## [7.2.2](https://github.com/angular/angular/compare/7.2.1...7.2.2) (2019-01-22)
### Bug Fixes
* **bazel:** Fix integration test after v8 bump ([#28194](https://github.com/angular/angular/issues/28194)) ([7b772e9](https://github.com/angular/angular/commit/7b772e9)), closes [#28142](https://github.com/angular/angular/issues/28142)
* **router:** `skipLocationChange` with named outlets ([#28301](https://github.com/angular/angular/issues/28301)) ([32737a6](https://github.com/angular/angular/commit/32737a6)), closes [#27680](https://github.com/angular/angular/issues/27680) [#28200](https://github.com/angular/angular/issues/28200)
### Features
* **bazel:** Add support for SASS ([#28167](https://github.com/angular/angular/issues/28167)) ([a4d9192](https://github.com/angular/angular/commit/a4d9192))
* **compiler-cli:** resolve generated Sass/Less files to .css inputs ([#28166](https://github.com/angular/angular/issues/28166)) ([4c00059](https://github.com/angular/angular/commit/4c00059))
<a name="8.0.0-beta.0"></a>
# [8.0.0-beta.0](https://github.com/angular/angular/compare/7.2.0...8.0.0-beta.0) (2019-01-16)

View File

@ -1,71 +0,0 @@
'use strict'; // necessary for es6 output in node
import { browser, element, by, protractor } from 'protractor';
describe('Event binding example', function () {
beforeEach(function () {
browser.get('');
});
let saveButton = element.all(by.css('button')).get(0);
let onSaveButton = element.all(by.css('button')).get(1);
let myClick = element.all(by.css('button')).get(2);
let deleteButton = element.all(by.css('button')).get(3);
let saveNoProp = element.all(by.css('button')).get(4);
let saveProp = element.all(by.css('button')).get(5);
it('should display Event Binding with Angular', function () {
expect(element(by.css('h1')).getText()).toEqual('Event Binding');
});
it('should display 6 buttons', function() {
expect(saveButton.getText()).toBe('Save');
expect(onSaveButton.getText()).toBe('on-click Save');
expect(myClick.getText()).toBe('click with myClick');
expect(deleteButton.getText()).toBe('Delete');
expect(saveNoProp.getText()).toBe('Save, no propagation');
expect(saveProp.getText()).toBe('Save with propagation');
});
it('should support user input', function () {
let input = element(by.css('input'));
let bindingResult = element.all(by.css('h4')).get(1);
expect(bindingResult.getText()).toEqual('Result: teapot');
input.sendKeys('abc');
expect(bindingResult.getText()).toEqual('Result: teapotabc');
});
it('should hide the item img', async () => {
let deleteButton = element.all(by.css('button')).get(3);
await deleteButton.click();
browser.switchTo().alert().accept();
expect(element.all(by.css('img')).get(0).getCssValue('display')).toEqual('none');
});
it('should show two alerts', async () => {
let parentDiv = element.all(by.css('.parent-div'));
let childDiv = element.all(by.css('div > div')).get(1);
await parentDiv.click();
browser.switchTo().alert().accept();
expect(childDiv.getText()).toEqual('Click me too! (child)');
await childDiv.click();
expect(browser.switchTo().alert().getText()).toEqual('Click me. Event target class is child-div');
browser.switchTo().alert().accept();
});
it('should show 1 alert from Save, no prop, button', async () => {
await saveNoProp.click();
expect(browser.switchTo().alert().getText()).toEqual('Saved. Event target is Save, no propagation');
browser.switchTo().alert().accept();
});
it('should show 2 alerts from Save w/prop button', async () => {
await saveProp.click();
expect(browser.switchTo().alert().getText()).toEqual('Saved.');
browser.switchTo().alert().accept();
expect(browser.switchTo().alert().getText()).toEqual('Saved.');
browser.switchTo().alert().accept();
});
});

View File

@ -1,25 +0,0 @@
.group {
background-color: #dae8f9;
padding: 1rem;
margin: 1rem 0;
}
.parent-div {
background-color: #bdd1f7;
border: solid 1px rgb(25, 118, 210);
padding: 1rem;
}
.parent-div:hover {
background-color: #8fb4f9;
}
.child-div {
margin-top: 1rem;
background-color: #fff;
padding: 1rem;
}
.child-div:hover {
background-color: #eee;
}

View File

@ -1,53 +0,0 @@
<h1 id="event-binding">Event Binding</h1>
<div class="group">
<h3>Target event</h3>
<!-- #docregion event-binding-1 -->
<button (click)="onSave($event)">Save</button>
<!-- #enddocregion event-binding-1 -->
<!-- #docregion event-binding-2 -->
<button on-click="onSave($event)">on-click Save</button>
<!-- #enddocregion event-binding-2 -->
<!-- #docregion custom-directive -->
<h4>myClick is an event on the custom ClickDirective:</h4>
<button (myClick)="clickMessage=$event" clickable>click with myClick</button>
{{clickMessage}}
<!-- #enddocregion custom-directive -->
</div>
<div class="group">
<h3>$event and event handling statements</h3>
<h4>Result: {{currentItem.name}}</h4>
<!-- #docregion event-binding-3-->
<input [value]="currentItem.name"
(input)="currentItem.name=$event.target.value" >
without NgModel
<!-- #enddocregion event-binding-3-->
</div>
<div class="group">
<h3>Binding to a nested component</h3>
<h4>Custom events with EventEmitter</h4>
<!-- #docregion event-binding-to-component -->
<app-item-detail (deleteRequest)="deleteItem($event)" [item]="currentItem"></app-item-detail>
<!-- #enddocregion event-binding-to-component -->
<h4>Click to see event target class:</h4>
<div class="parent-div" (click)="onClickMe($event)" clickable>Click me (parent)
<div class="child-div">Click me too! (child) </div>
</div>
<h3>Saves only once:</h3>
<div (click)="onSave()" clickable>
<button (click)="onSave($event)">Save, no propagation</button>
</div>
<h3>Saves twice:</h3>
<div (click)="onSave()" clickable>
<button (click)="onSave()">Save with propagation</button>
</div>

View File

@ -1,27 +0,0 @@
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'Featured product:'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('Featured product:');
}));
it('should render title in a p tag', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('p').textContent).toContain('Featured product:');
}));
});

View File

@ -1,29 +0,0 @@
import { Component } from '@angular/core';
import { Item } from './item';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
currentItem = { name: 'teapot'} ;
clickMessage = '';
onSave(event: KeyboardEvent) {
const evtMsg = event ? ' Event target is ' + (<HTMLElement>event.target).textContent : '';
alert('Saved.' + evtMsg);
if (event) { event.stopPropagation(); }
}
deleteItem(item: Item) {
alert(`Delete the ${item}.`);
}
onClickMe(event: KeyboardEvent) {
const evtMsg = event ? ' Event target class is ' + (<HTMLElement>event.target).className : '';
alert('Click me.' + evtMsg);
}
}

View File

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

View File

@ -1,18 +0,0 @@
/* tslint:disable use-output-property-decorator directive-class-suffix */
import { Directive, ElementRef, EventEmitter, Output } from '@angular/core';
@Directive({selector: '[myClick]'})
export class ClickDirective {
@Output('myClick') clicks = new EventEmitter<string>(); // @Output(alias) propertyName = ...
toggle = false;
constructor(el: ElementRef) {
el.nativeElement
.addEventListener('click', (event: Event) => {
this.toggle = !this.toggle;
this.clicks.emit(this.toggle ? 'Click!' : '');
});
}
}

View File

@ -1,11 +0,0 @@
.detail {
border: 1px solid rgb(25, 118, 210);
padding: 1rem;
margin: 1rem 0;
}
img {
max-width: 100px;
display: block;
padding: 1rem 0;
}

View File

@ -1,9 +0,0 @@
<div class="detail">
<p>This is the ItemDetailComponent</p>
<!-- #docregion line-through -->
<img src="{{itemImageUrl}}" [style.display]="displayNone">
<span [style.text-decoration]="lineThrough">{{ item.name }}
</span>
<button (click)="delete()">Delete</button>
<!-- #enddocregion line-through -->
</div>

View File

@ -1,25 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ItemDetailComponent } from './item-detail.component';
describe('ItemDetailComponent', () => {
let component: ItemDetailComponent;
let fixture: ComponentFixture<ItemDetailComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ItemDetailComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ItemDetailComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,30 +0,0 @@
/* tslint:disable use-input-property-decorator use-output-property-decorator */
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Item } from '../item';
@Component({
selector: 'app-item-detail',
styleUrls: ['./item-detail.component.css'],
templateUrl: './item-detail.component.html'
})
export class ItemDetailComponent {
@Input() item;
itemImageUrl = 'assets/teapot.svg';
lineThrough = '';
displayNone = '';
@Input() prefix = '';
// #docregion deleteRequest
// This component makes a request but it can't actually delete a hero.
@Output() deleteRequest = new EventEmitter<Item>();
delete() {
this.deleteRequest.emit(this.item.name);
this.displayNone = this.displayNone ? '' : 'none';
this.lineThrough = this.lineThrough ? '' : 'line-through';
}
// #enddocregion deleteRequest
}

View File

@ -1,4 +0,0 @@
export class Item {
name: '';
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 23 KiB

View File

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

View File

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

View File

@ -1,10 +0,0 @@
{
"description": "Event Binding",
"files": [
"!**/*.d.ts",
"!**/*.js",
"!**/*.[1,2].*"
],
"file": "src/app/app.component.ts",
"tags": ["Event Binding"]
}

View File

@ -42,7 +42,7 @@ export class HeroService {
// #enddocregion getHeroes-2
tap(_ => this.log('fetched heroes')),
// #docregion getHeroes-2
catchError(this.handleError<Hero[]>('getHeroes', []))
catchError(this.handleError('getHeroes', []))
);
// #docregion getHeroes-1
}

View File

@ -453,7 +453,7 @@ The compiler understands all syntax forms that the _collector_ supports, but it
The compiler can only reference _exported symbols_.
Decorated component class members must be public. You cannot make an `@Input()` property private or protected.
Decorated component class members must be public. You cannot make an `@Input()` property private or internal.
Data bound properties must also be public.

View File

@ -73,7 +73,7 @@ Angular provides predefined pipes for common transformations, and you can also d
## Services and dependency injection
For data or logic that isn't associated with a specific view, and that you want to share across components, you create a *service* class. A service class definition is immediately preceded by the `@Injectable()` decorator. The decorator provides the metadata that allows other providers to be **injected** as dependencies into your class.
For data or logic that isn't associated with a specific view, and that you want to share across components, you create a *service* class. A service class definition is immediately preceded by the `@Injectable()` decorator. The decorator provides the metadata that allows your service to be *injected* into client components as a dependency.
*Dependency injection* (DI) lets you keep your component classes lean and efficient. They don't fetch data from the server, validate user input, or log directly to the console; they delegate such tasks to services.

View File

@ -1055,7 +1055,7 @@ The default route should redirect to the `HeroListComponent` _only_ when the _en
Remember to restore the redirect to `pathMatch = 'full'`.
Learn more in Victor Savkin's
[post on redirects](http://vsavkin.tumblr.com/post/146722301646/angular-router-empty-paths-componentless-routes).
[post on redirects](http://victorsavkin.com/post/146722301646/angular-router-empty-paths-componentless-routes).
</div>
@ -3796,7 +3796,7 @@ The relevant *Crisis Center* code for this milestone follows.
</code-pane>
<code-pane header="crisis-detail.component.ts" path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.ts">
<code-pane header="crisis-detail.component.html" path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.html">
</code-pane>

View File

@ -797,6 +797,7 @@ content harmlessly.
<hr/>
{@a other-bindings}
## Attribute, class, and style bindings
@ -943,44 +944,56 @@ Note that a _style property_ name can be written in either
{@a event-binding}
## Event binding `(event)`
## Event binding ( <span class="syntax">(event)</span> )
Event binding allows you to listen for certain events such as
keystrokes, mouse movements, clicks, and touches. For an example
demonstrating all of the points in this section, see the <live-example name="event-binding">event binding example</live-example>.
The bindings directives you've met so far flow data in one direction: **from a component to an element**.
Angular event binding syntax consists of a **target event** name
Users don't just stare at the screen. They enter text into input boxes. They pick items from lists.
They click buttons. Such user actions may result in a flow of data in the opposite direction:
**from an element to a component**.
The only way to know about a user action is to listen for certain events such as
keystrokes, mouse movements, clicks, and touches.
You declare your interest in user actions through Angular event binding.
Event binding syntax consists of a **target event** name
within parentheses on the left of an equal sign, and a quoted
template statement on the right.
[template statement](guide/template-syntax#template-statements) on the right.
The following event binding listens for the button's click events, calling
the component's `onSave()` method whenever a click occurs:
<figure>
<img src='generated/images/guide/event-binding/syntax-diagram.svg' alt="Syntax diagram">
</figure>
<code-example path="template-syntax/src/app/app.component.html" region="event-binding-1" header="src/app/app.component.html" linenums="false">
</code-example>
### Target event
As above, the target is the button's click event.
A **name between parentheses** &mdash; for example, `(click)` &mdash;
identifies the target event. In the following example, the target is the button's click event.
<code-example path="event-binding/src/app/app.component.html" region="event-binding-1" header="src/app/app.component.html" linenums="false">
<code-example path="template-syntax/src/app/app.component.html" region="event-binding-1" header="src/app/app.component.html" linenums="false">
</code-example>
Alternatively, use the `on-` prefix, known as the canonical form:
Some people prefer the `on-` prefix alternative, known as the **canonical form**:
<code-example path="event-binding/src/app/app.component.html" region="event-binding-2" header="src/app/app.component.html" linenums="false">
<code-example path="template-syntax/src/app/app.component.html" region="event-binding-2" header="src/app/app.component.html" linenums="false">
</code-example>
Element events may be the more common targets, but Angular looks first to see if the name matches an event property
of a known directive, as it does in the following example:
<code-example path="event-binding/src/app/app.component.html" region="custom-directive" header="src/app/app.component.html" linenums="false">
<code-example path="template-syntax/src/app/app.component.html" region="event-binding-3" header="src/app/app.component.html" linenums="false">
</code-example>
<div class="alert is-helpful">
The `myClick` directive is further described in the section
on [aliasing input/output properties](guide/template-syntax#aliasing-io).
</div>
If the name fails to match an element event or an output property of a known directive,
Angular reports an “unknown directive” error.
### *$event* and event handling statements
In an event binding, Angular sets up an event handler for the target event.
@ -990,73 +1003,72 @@ The template statement typically involves a receiver, which performs an action
in response to the event, such as storing a value from the HTML control
into a model.
The binding conveys information about the event. This information can include data values such as an event object, string, or number named `$event`.
The binding conveys information about the event, including data values, through
an **event object named `$event`**.
The target event determines the shape of the `$event` object.
The shape of the event object is determined by the target event.
If the target event is a native DOM element event, then `$event` is a
[DOM event object](https://developer.mozilla.org/en-US/docs/Web/Events),
with properties such as `target` and `target.value`.
Consider this example:
<code-example path="event-binding/src/app/app.component.html" region="event-binding-3" header="src/app/app.component.html" linenums="false">
<code-example path="template-syntax/src/app/app.component.html" region="without-NgModel" header="src/app/app.component.html" linenums="false">
</code-example>
This code sets the `<input>` `value` property by binding to the `name` property.
To listen for changes to the value, the code binds to the `input`
event of the `<input>` element.
This code sets the input box `value` property by binding to the `name` property.
To listen for changes to the value, the code binds to the input box's `input` event.
When the user makes changes, the `input` event is raised, and the binding executes
the statement within a context that includes the DOM event object, `$event`.
To update the `name` property, the changed text is retrieved by following the path `$event.target.value`.
If the event belongs to a directive&mdash;recall that components
are directives&mdash;`$event` has whatever shape the directive produces.
If the event belongs to a directive (recall that components are directives),
`$event` has whatever shape the directive decides to produce.
{@a eventemitter}
### Custom events with `EventEmitter`
{@a custom-event}
### Custom events with <span class="syntax">EventEmitter</span>
Directives typically raise custom events with an Angular [EventEmitter](api/core/EventEmitter).
The directive creates an `EventEmitter` and exposes it as a property.
The directive calls `EventEmitter.emit(payload)` to fire an event, passing in a message payload, which can be anything.
Parent directives listen for the event by binding to this property and accessing the payload through the `$event` object.
Consider an `ItemDetailComponent` that presents item information and responds to user actions.
Although the `ItemDetailComponent` has a delete button, it doesn't know how to delete the hero. It can only raise an event reporting the user's delete request.
Consider a `HeroDetailComponent` that presents hero information and responds to user actions.
Although the `HeroDetailComponent` has a delete button it doesn't know how to delete the hero itself.
The best it can do is raise an event reporting the user's delete request.
Here are the pertinent excerpts from that `ItemDetailComponent`:
Here are the pertinent excerpts from that `HeroDetailComponent`:
<code-example path="event-binding/src/app/item-detail/item-detail.component.html" linenums="false" header="src/app/item-detail/item-detail.component.ts (template)" region="line-through">
<code-example path="template-syntax/src/app/hero-detail.component.ts" linenums="false" header="src/app/hero-detail.component.ts (template)" region="template-1">
</code-example>
<code-example path="event-binding/src/app/item-detail/item-detail.component.ts" linenums="false" header="src/app/item-detail/item-detail.component.ts (deleteRequest)" region="deleteRequest">
<code-example path="template-syntax/src/app/hero-detail.component.ts" linenums="false" header="src/app/hero-detail.component.ts (deleteRequest)" region="deleteRequest">
</code-example>
The component defines a `deleteRequest` property that returns an `EventEmitter`.
When the user clicks *delete*, the component invokes the `delete()` method,
telling the `EventEmitter` to emit an `Item` object.
telling the `EventEmitter` to emit a `Hero` object.
Now imagine a hosting parent component that binds to the `deleteRequest` event
of the `ItemDetailComponent`.
Now imagine a hosting parent component that binds to the `HeroDetailComponent`'s `deleteRequest` event.
<code-example path="event-binding/src/app/app.component.html" linenums="false" header="src/app/app.component.html (event-binding-to-component)" region="event-binding-to-component">
<code-example path="template-syntax/src/app/app.component.html" linenums="false" header="src/app/app.component.html (event-binding-to-component)" region="event-binding-to-component">
</code-example>
When the `deleteRequest` event fires, Angular calls the parent component's
`deleteItem()` method, passing the *item-to-delete* (emitted by `ItemDetail`)
in the `$event` variable.
When the `deleteRequest` event fires, Angular calls the parent component's `deleteHero` method,
passing the *hero-to-delete* (emitted by `HeroDetail`) in the `$event` variable.
### Template statements have side effects
Though [template expressions](guide/template-syntax#template-expressions) shouldn't have [side effects](guide/template-syntax#avoid-side-effects), template
statements usually do. The `deleteItem()` method does have
a side effect: it deletes an item.
The `deleteHero` method has a side effect: it deletes a hero.
Template statement side effects are not just OK, but expected.
Deleting an item updates the model, and depending on your code, triggers
other changes including queries and saving to a remote server.
These changes propagate through the system and ultimately display in this and other views.
Deleting the hero updates the model, perhaps triggering other changes
including queries and saves to a remote server.
These changes percolate through the system and are ultimately displayed in this and other views.
<hr/>

View File

@ -2398,7 +2398,7 @@ So when you call `createComponent()`, the `TestBed` compiles implicitly.
That's not a problem when the source code is in memory.
But the `BannerComponent` requires external files
that the compiler must read from the file system,
that the compile must read from the file system,
an inherently _asynchronous_ operation.
If the `TestBed` were allowed to continue, the tests would run and fail mysteriously

View File

@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 600 125" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;"><g transform="matrix(0.469484,0,0,0.469925,-158.685,-184.211)"><text x="374px" y="472px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:64px;">&lt;button</text><text x="607.094px" y="472px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:64px;fill:#df002d;">(click)</text><text x="774.156px" y="472px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:64px;">=&quot;</text><text x="834.25px" y="472px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:64px;fill:#0022be;">onSave()</text><text x="1093.94px" y="472px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:64px;">&quot;&gt;Save&lt;/button&gt;</text></g><path d="M142.827,95.824l-6.663,-3.032l17.828,-39.26l-6.187,-2.815l13.842,-5.191l5.195,13.852l-6.187,-2.815l-17.828,39.261Z" style="fill:#df002d;"/><path d="M337.08,93.548l-6.915,2.399l-13.342,-38.531l-6.422,2.228l6.458,-13.308l13.3,6.453l-6.421,2.228l13.342,38.531Z" style="fill:#3345cc;"/><g><rect x="23.005" y="76.128" width="197.653" height="31.485" style="fill:#fff;stroke:#000;stroke-width:0.7px;"/><text x="31.989px" y="98.214px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:22.556px;fill:#df002d;">target even<tspan x="144.743px " y="98.214px ">t</tspan> name</text></g><g><rect x="275.117" y="76.128" width="228.169" height="31.955" style="fill:#fff;stroke:#000;stroke-width:0.7px;"/><text x="293.078px" y="98.214px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:22.556px;fill:#3345cc;">template st<tspan x="403.3px " y="98.214px ">a</tspan>tement</text></g></svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -116,7 +116,7 @@ Most apps strive for a consistent look across the application.
The CLI generated an empty `styles.css` for this purpose.
Put your application-wide styles there.
Open `src/styles.css` and add the code below to the file.
Here's an excerpt from the `styles.css` for the _Tour of Heroes_ sample app.
<code-example path="toh-pt0/src/styles.1.css" header="src/styles.css (excerpt)">
</code-example>

View File

@ -17,7 +17,7 @@
"build": "yarn ~~build",
"prebuild-local": "yarn setup-local",
"build-local": "yarn ~~build",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js fd4e960d6",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 4ae713b5a",
"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",

View File

@ -52,7 +52,7 @@ describe('AppComponent', () => {
await newDocPromise; // Wait for the new document to be fetched.
fixture.detectChanges(); // Propagate document change to the view (i.e to `DocViewer`).
await docRenderedPromise; // Wait for the `docRendered` event.
}
};
function initializeTest(waitForDoc = true) {
fixture = TestBed.createComponent(AppComponent);
@ -73,7 +73,7 @@ describe('AppComponent', () => {
tocService = de.injector.get<TocService>(TocService);
return waitForDoc && awaitDocRendered();
}
};
describe('with proper DocViewer', () => {

View File

@ -125,7 +125,7 @@ export class ApiListComponent implements OnInit {
return status === 'all' ||
status === item.stability ||
(status === 'security-risk' && item.securityRisk);
}
};
function matchesType() {
return type === 'all' || type === item.docType;

View File

@ -54,7 +54,7 @@ export class ApiService implements OnDestroy {
section.items.every(item => item.stability === 'deprecated');
});
}));
}
};
constructor(private http: HttpClient, private logger: Logger) { }

View File

@ -79,7 +79,7 @@ describe('ContributorListComponent', () => {
return comp;
}
interface SearchResult { [index: string]: string; }
interface SearchResult { [index: string]: string; };
class TestLocationService {
searchResult: SearchResult = {};

View File

@ -245,7 +245,7 @@ class FakeComponentFactory extends ComponentFactory<any> {
rootSelectorOrNode?: string | any,
ngModule?: NgModuleRef<any>): ComponentRef<any> {
return jasmine.createSpy('ComponentRef') as any;
}
};
}
class FakeComponentFactoryResolver extends ComponentFactoryResolver {

View File

@ -37,6 +37,6 @@ describe('Getting Started NgFor Component', () => {
component.parseError$.subscribe(error => {
expect(error).toBeTruthy();
});
})
});
});

View File

@ -46,6 +46,6 @@ describe('Getting Started NgIf Component', () => {
component.parseError$.subscribe(error => {
expect(error).toBeTruthy();
});
})
});
});

View File

@ -26,7 +26,7 @@ export class ResourceService {
(categories as ConnectableObservable<Category[]>).connect();
return categories;
}
};
}
// Extract sorted Category[] from resource JSON data

View File

@ -100,10 +100,9 @@ export class DocViewerComponent implements OnDestroy {
if (needsToc && !embeddedToc) {
// Add an embedded ToC if it's needed and there isn't one in the content already.
titleEl!.insertAdjacentHTML('afterend', '<aio-toc class="embedded"></aio-toc>');
} else if (!needsToc && embeddedToc && embeddedToc.parentNode !== null) {
} else if (!needsToc && embeddedToc) {
// Remove the embedded Toc if it's there and not needed.
// We cannot use ChildNode.remove() because of IE11
embeddedToc.parentNode.removeChild(embeddedToc);
embeddedToc.remove();
}
return () => {

View File

@ -14,4 +14,4 @@ export class Deployment {
mode: string = this.location.search()['mode'] || environment.mode;
constructor(private location: LocationService) {}
}
};

View File

@ -68,10 +68,7 @@ export class TocService {
}
}
// now remove the anchor
if (anchorLink.parentNode !== null) {
// We cannot use ChildNode.remove() because of IE11
anchorLink.parentNode.removeChild(anchorLink);
}
anchorLink.remove();
}
// security: the document element which provides this heading content
// is always authored by the documentation team and is considered to be safe

View File

@ -75,7 +75,6 @@
],
"radix": true,
"semicolon": [
true,
"always"
],
"triple-equals": [

View File

@ -3,8 +3,8 @@
"master": {
"uncompressed": {
"runtime": 1497,
"main": 189865,
"polyfills": 38449
"main": 187437,
"polyfills": 59608
}
}
},
@ -12,7 +12,7 @@
"master": {
"uncompressed": {
"runtime": 1440,
"main": 584188,
"main": 584077,
"polyfills": 38390
}
}

View File

@ -13,6 +13,3 @@ build --local_resources=14336,8.0,1.0
# Use the Angular 6 compiler
build --define=compile=legacy
# Don't create symlinks
build --symlink_prefix=/

View File

@ -26,17 +26,16 @@
"@angular/router": "file:../../dist/packages-dist/router",
"core-js": "file:../../node_modules/core-js",
"rxjs": "file:../../node_modules/rxjs",
"tslib": "^1.9.3",
"zone.js": "file:../../node_modules/zone.js"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.12.1",
"@angular-devkit/build-angular": "~0.12.0-rc.0",
"@angular/cli": "file:../../node_modules/@angular/cli",
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
"@angular/language-service": "file:../../dist/packages-dist/language-service",
"@types/node": "~8.9.4",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",

View File

@ -2,6 +2,14 @@
# yarn lockfile v1
"@angular-devkit/architect@0.12.0-rc.0":
version "0.12.0-rc.0"
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.12.0-rc.0.tgz#8e5d624ab42962abf9c75139a0171fe739233e22"
integrity sha512-A4w9YumA+GuUcJfiWc8YEwY3wCrzbxpt+M4n2g/9j7Lf0a7WgsdUG+Btb4eCEuUhjsWDlGPTZIFl+KIPTv+WHQ==
dependencies:
"@angular-devkit/core" "7.2.0-rc.0"
rxjs "6.3.3"
"@angular-devkit/architect@0.12.1":
version "0.12.1"
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.12.1.tgz#397768d1ccd0cef76db96d6b39db8aebad68c031"
@ -10,24 +18,16 @@
"@angular-devkit/core" "7.2.1"
rxjs "6.3.3"
"@angular-devkit/architect@0.12.2":
version "0.12.2"
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.12.2.tgz#1bfa43881c8927b8e12ffd4a2a3a645d6356e748"
integrity sha512-32Eim3PM/CJKGcCF1FJQ91ohuF2vBGMd4t1DILaoOMXHWmPLI9N4ILzWHfqFLRvb8QFgLn4VNG7CI9K7GcSBlQ==
"@angular-devkit/build-angular@~0.12.0-rc.0":
version "0.12.0-rc.0"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.12.0-rc.0.tgz#b82d96bf359d5e1c32736499944a161d3e80e882"
integrity sha512-7QvqVgihLLOEBuUF2sT5R8c4al7J30pViXhWEIwJjgl2VzEYYumYHJEFLqDAwimyLdCY4XeMsBlYnpWLpbmM3Q==
dependencies:
"@angular-devkit/core" "7.2.2"
rxjs "6.3.3"
"@angular-devkit/build-angular@~0.12.1":
version "0.12.2"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.12.2.tgz#4776f535633227848c4bda34b1e8f89574c33746"
integrity sha512-4PDykCNDjjFo6Ximhq2efiufoUP6pj8KvhB8UI03mLbn/Os1W0y1lmiPJn+NjeBLwFWH9DqW9Vxk/pYek7MtEA==
dependencies:
"@angular-devkit/architect" "0.12.2"
"@angular-devkit/build-optimizer" "0.12.2"
"@angular-devkit/build-webpack" "0.12.2"
"@angular-devkit/core" "7.2.2"
"@ngtools/webpack" "7.2.2"
"@angular-devkit/architect" "0.12.0-rc.0"
"@angular-devkit/build-optimizer" "0.12.0-rc.0"
"@angular-devkit/build-webpack" "0.12.0-rc.0"
"@angular-devkit/core" "7.2.0-rc.0"
"@ngtools/webpack" "7.2.0-rc.0"
ajv "6.6.2"
autoprefixer "9.4.3"
circular-dependency-plugin "5.0.2"
@ -47,7 +47,7 @@
opn "5.3.0"
parse5 "4.0.0"
portfinder "1.0.17"
postcss "7.0.11"
postcss "7.0.5"
postcss-import "12.0.0"
postcss-loader "3.0.0"
raw-loader "0.5.1"
@ -56,45 +56,45 @@
semver "5.5.1"
source-map-loader "0.2.4"
source-map-support "0.5.9"
speed-measure-webpack-plugin "1.2.5"
speed-measure-webpack-plugin "1.2.3"
stats-webpack-plugin "0.7.0"
style-loader "0.23.1"
stylus "0.54.5"
stylus-loader "3.0.2"
terser-webpack-plugin "1.2.1"
terser-webpack-plugin "1.1.0"
tree-kill "1.2.0"
webpack "4.28.4"
webpack "4.23.1"
webpack-dev-middleware "3.4.0"
webpack-dev-server "3.1.14"
webpack-dev-server "3.1.10"
webpack-merge "4.1.4"
webpack-sources "1.3.0"
webpack-subresource-integrity "1.1.0-rc.6"
optionalDependencies:
node-sass "4.10.0"
"@angular-devkit/build-optimizer@0.12.2":
version "0.12.2"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.12.2.tgz#c35f4a67a2304a4deeb8e5d2e6c1edde0429c309"
integrity sha512-5SARSE18X5/churU0Qc0gOfDt5EwuwKsJmIA7hHBzi44iotQm5c8ea0q0acua4/U4K+jOsF6A4Faa08Vr2624A==
"@angular-devkit/build-optimizer@0.12.0-rc.0":
version "0.12.0-rc.0"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.12.0-rc.0.tgz#7ed2f9d4b32a98e506d17356f5dda5e26526da44"
integrity sha512-IlZixc5NDyYNH6S/LRw0/ogQDnnMoKJZH4GKLDT/mWvE8KBNJyoOvqPFBMC1onPqaHxGz+P9B9kssTkFvsITnA==
dependencies:
loader-utils "1.1.0"
source-map "0.5.6"
typescript "3.2.2"
webpack-sources "1.2.0"
"@angular-devkit/build-webpack@0.12.2":
version "0.12.2"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.12.2.tgz#00f1a3a5ab3f4bc8e35d1826f8b476dc0016a1e7"
integrity sha512-Uv3f8XJc/5UTj2T7XjxFYDhuybFIIitLGxBpp/hEIc7eXI4MsJKB6CoDJy+2BQch7c/QjKH7W3dmTxzuSJ2j3g==
"@angular-devkit/build-webpack@0.12.0-rc.0":
version "0.12.0-rc.0"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.12.0-rc.0.tgz#aff981fb3f36dd3ec2946cb07953de3149cbc4e1"
integrity sha512-hwNBzt2ZPVx2V9gb87mU1YqZE8w4FX49xcHw0SCLLdZHWveUy8SCaVaPQ8i7+bJXKKu0PLSDwLnzGhoKc+mBWg==
dependencies:
"@angular-devkit/architect" "0.12.2"
"@angular-devkit/core" "7.2.2"
"@angular-devkit/architect" "0.12.0-rc.0"
"@angular-devkit/core" "7.2.0-rc.0"
rxjs "6.3.3"
"@angular-devkit/core@7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.2.1.tgz#8c6df59eab77bcc98a348c8cdf9eb217c8b751a5"
integrity sha512-zOozPswSM1cTkltw5LeSPoZ/fJ2d3vN304IVgKgrM5/Fs54bd7nTaBcAK+HvjKS+5KmykYrXW47Q4CdFJikluQ==
"@angular-devkit/core@7.2.0-rc.0":
version "7.2.0-rc.0"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.2.0-rc.0.tgz#6cd53211825c475cdc73b01b4b05d7a308bc4a84"
integrity sha512-dHaQL9kUCSYgAtSJ29cP4MsGO/1JfA+zeZESxZMRuUVVhanmL5+f7kIPQbwB4wiGj3htDnxpMvqOlff3NxkQWQ==
dependencies:
ajv "6.6.2"
chokidar "2.0.4"
@ -102,10 +102,10 @@
rxjs "6.3.3"
source-map "0.7.3"
"@angular-devkit/core@7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.2.2.tgz#f0daf3e24f0ce8105341118f4505c1db4e284ab0"
integrity sha512-gDF8iXiPN870WuBMl7bCQ5+Qz5SjGL/qMcvP4hli5hkn+kMAhgG38ligUK1bbhPQUJ+Z/nSOEmyv8gLHO09SZg==
"@angular-devkit/core@7.2.1":
version "7.2.1"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.2.1.tgz#8c6df59eab77bcc98a348c8cdf9eb217c8b751a5"
integrity sha512-zOozPswSM1cTkltw5LeSPoZ/fJ2d3vN304IVgKgrM5/Fs54bd7nTaBcAK+HvjKS+5KmykYrXW47Q4CdFJikluQ==
dependencies:
ajv "6.6.2"
chokidar "2.0.4"
@ -122,7 +122,7 @@
rxjs "6.3.3"
"@angular/animations@file:../../dist/packages-dist/animations":
version "8.0.0-beta.0"
version "7.2.0"
dependencies:
tslib "^1.9.0"
@ -140,12 +140,12 @@
symbol-observable "1.2.0"
"@angular/common@file:../../dist/packages-dist/common":
version "8.0.0-beta.0"
version "7.2.0"
dependencies:
tslib "^1.9.0"
"@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli":
version "8.0.0-beta.0"
version "7.2.0"
dependencies:
canonical-path "1.0.0"
chokidar "^1.4.2"
@ -160,40 +160,40 @@
yargs "9.0.1"
"@angular/compiler@file:../../dist/packages-dist/compiler":
version "8.0.0-beta.0"
version "7.2.0"
dependencies:
tslib "^1.9.0"
"@angular/core@file:../../dist/packages-dist/core":
version "8.0.0-beta.0"
version "7.2.0"
dependencies:
tslib "^1.9.0"
"@angular/forms@file:../../dist/packages-dist/forms":
version "8.0.0-beta.0"
version "7.2.0"
dependencies:
tslib "^1.9.0"
"@angular/http@file:../../dist/packages-dist/http":
version "8.0.0-beta.0"
version "7.2.0"
dependencies:
tslib "^1.9.0"
"@angular/language-service@file:../../dist/packages-dist/language-service":
version "8.0.0-beta.0"
version "7.2.0"
"@angular/platform-browser-dynamic@file:../../dist/packages-dist/platform-browser-dynamic":
version "8.0.0-beta.0"
version "7.2.0"
dependencies:
tslib "^1.9.0"
"@angular/platform-browser@file:../../dist/packages-dist/platform-browser":
version "8.0.0-beta.0"
version "7.2.0"
dependencies:
tslib "^1.9.0"
"@angular/router@file:../../dist/packages-dist/router":
version "8.0.0-beta.0"
version "7.2.0"
dependencies:
tslib "^1.9.0"
@ -285,12 +285,12 @@
lodash "^4.17.10"
to-fast-properties "^2.0.0"
"@ngtools/webpack@7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-7.2.2.tgz#361d877f01feae800a58901b066b46539e1fe0e3"
integrity sha512-xjvQ8tlyyReE69q+whAubwX4fayPoy4NHSIDa429qdcUypkvhSScAtou003oVAKG519rznykDrUHAWtvFMVf4Q==
"@ngtools/webpack@7.2.0-rc.0":
version "7.2.0-rc.0"
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-7.2.0-rc.0.tgz#750700efe60dc0b716a21f05e4f495ea46a1fc13"
integrity sha512-Gzqf+Vo8Fi9NxUcUAYy8cn/PWG9rJ+hgheY5WrG1knEI8FWOgdzwKiqv4CjwXhlvCamuv7vxfWB5VIGOoq2npA==
dependencies:
"@angular-devkit/core" "7.2.2"
"@angular-devkit/core" "7.2.0-rc.0"
enhanced-resolve "4.1.0"
rxjs "6.3.3"
tree-kill "1.2.0"
@ -370,147 +370,147 @@
"@types/source-list-map" "*"
source-map "^0.6.1"
"@webassemblyjs/ast@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace"
integrity sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==
"@webassemblyjs/ast@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.10.tgz#0cfc61d61286240b72fc522cb755613699eea40a"
integrity sha512-wTUeaByYN2EA6qVqhbgavtGc7fLTOx0glG2IBsFlrFG51uXIGlYBTyIZMf4SPLo3v1bgV/7lBN3l7Z0R6Hswew==
dependencies:
"@webassemblyjs/helper-module-context" "1.7.11"
"@webassemblyjs/helper-wasm-bytecode" "1.7.11"
"@webassemblyjs/wast-parser" "1.7.11"
"@webassemblyjs/helper-module-context" "1.7.10"
"@webassemblyjs/helper-wasm-bytecode" "1.7.10"
"@webassemblyjs/wast-parser" "1.7.10"
"@webassemblyjs/floating-point-hex-parser@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz#a69f0af6502eb9a3c045555b1a6129d3d3f2e313"
integrity sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==
"@webassemblyjs/floating-point-hex-parser@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.10.tgz#ee63d729c6311a85863e369a473f9983f984e4d9"
integrity sha512-gMsGbI6I3p/P1xL2UxqhNh1ga2HCsx5VBB2i5VvJFAaqAjd2PBTRULc3BpTydabUQEGlaZCzEUQhLoLG7TvEYQ==
"@webassemblyjs/helper-api-error@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz#c7b6bb8105f84039511a2b39ce494f193818a32a"
integrity sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==
"@webassemblyjs/helper-api-error@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.10.tgz#bfcb3bbe59775357475790a2ad7b289f09b2f198"
integrity sha512-DoYRlPWtuw3yd5BOr9XhtrmB6X1enYF0/54yNvQWGXZEPDF5PJVNI7zQ7gkcKfTESzp8bIBWailaFXEK/jjCsw==
"@webassemblyjs/helper-buffer@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz#3122d48dcc6c9456ed982debe16c8f37101df39b"
integrity sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==
"@webassemblyjs/helper-buffer@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.10.tgz#0a8c624c67ad0b214d2e003859921a1988cb151b"
integrity sha512-+RMU3dt/dPh4EpVX4u5jxsOlw22tp3zjqE0m3ftU2tsYxnPULb4cyHlgaNd2KoWuwasCQqn8Mhr+TTdbtj3LlA==
"@webassemblyjs/helper-code-frame@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz#cf8f106e746662a0da29bdef635fcd3d1248364b"
integrity sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==
"@webassemblyjs/helper-code-frame@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.10.tgz#0ab7e22fad0241a173178c73976fc0edf50832ce"
integrity sha512-UiytbpKAULOEab2hUZK2ywXen4gWJVrgxtwY3Kn+eZaaSWaRM8z/7dAXRSoamhKFiBh1uaqxzE/XD9BLlug3gw==
dependencies:
"@webassemblyjs/wast-printer" "1.7.11"
"@webassemblyjs/wast-printer" "1.7.10"
"@webassemblyjs/helper-fsm@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz#df38882a624080d03f7503f93e3f17ac5ac01181"
integrity sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==
"@webassemblyjs/helper-fsm@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.10.tgz#0915e7713fbbb735620a9d3e4fa3d7951f97ac64"
integrity sha512-w2vDtUK9xeSRtt5+RnnlRCI7wHEvLjF0XdnxJpgx+LJOvklTZPqWkuy/NhwHSLP19sm9H8dWxKeReMR7sCkGZA==
"@webassemblyjs/helper-module-context@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz#d874d722e51e62ac202476935d649c802fa0e209"
integrity sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==
"@webassemblyjs/helper-module-context@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.10.tgz#9beb83f72740f5ac8075313b5cac5e796510f755"
integrity sha512-yE5x/LzZ3XdPdREmJijxzfrf+BDRewvO0zl8kvORgSWmxpRrkqY39KZSq6TSgIWBxkK4SrzlS3BsMCv2s1FpsQ==
"@webassemblyjs/helper-wasm-bytecode@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz#dd9a1e817f1c2eb105b4cf1013093cb9f3c9cb06"
integrity sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==
"@webassemblyjs/helper-wasm-bytecode@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.10.tgz#797b1e734bbcfdea8399669cdc58308ef1c7ffc0"
integrity sha512-u5qy4SJ/OrxKxZqJ9N3qH4ZQgHaAzsopsYwLvoWJY6Q33r8PhT3VPyNMaJ7ZFoqzBnZlCcS/0f4Sp8WBxylXfg==
"@webassemblyjs/helper-wasm-section@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz#9c9ac41ecf9fbcfffc96f6d2675e2de33811e68a"
integrity sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==
"@webassemblyjs/helper-wasm-section@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.10.tgz#c0ea3703c615d7bc3e3507c3b7991c8767b2f20e"
integrity sha512-Ecvww6sCkcjatcyctUrn22neSJHLN/TTzolMGG/N7S9rpbsTZ8c6Bl98GpSpV77EvzNijiNRHBG0+JO99qKz6g==
dependencies:
"@webassemblyjs/ast" "1.7.11"
"@webassemblyjs/helper-buffer" "1.7.11"
"@webassemblyjs/helper-wasm-bytecode" "1.7.11"
"@webassemblyjs/wasm-gen" "1.7.11"
"@webassemblyjs/ast" "1.7.10"
"@webassemblyjs/helper-buffer" "1.7.10"
"@webassemblyjs/helper-wasm-bytecode" "1.7.10"
"@webassemblyjs/wasm-gen" "1.7.10"
"@webassemblyjs/ieee754@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz#c95839eb63757a31880aaec7b6512d4191ac640b"
integrity sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==
"@webassemblyjs/ieee754@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.10.tgz#62c1728b7ef0f66ef8221e2966a0afd75db430df"
integrity sha512-HRcWcY+YWt4+s/CvQn+vnSPfRaD4KkuzQFt5MNaELXXHSjelHlSEA8ZcqT69q0GTIuLWZ6JaoKar4yWHVpZHsQ==
dependencies:
"@xtuc/ieee754" "^1.2.0"
"@webassemblyjs/leb128@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.11.tgz#d7267a1ee9c4594fd3f7e37298818ec65687db63"
integrity sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==
"@webassemblyjs/leb128@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.10.tgz#167e0bb4b06d7701585772a73fba9f4df85439f6"
integrity sha512-og8MciYlA8hvzCLR71hCuZKPbVBfLQeHv7ImKZ4nlyxrYbG7uJHYtHiHu6OV9SqrGuD03H/HtXC4Bgdjfm9FHw==
dependencies:
"@xtuc/long" "4.2.1"
"@webassemblyjs/utf8@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.11.tgz#06d7218ea9fdc94a6793aa92208160db3d26ee82"
integrity sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==
"@webassemblyjs/utf8@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.10.tgz#b6728f5b6f50364abc155be029f9670e6685605a"
integrity sha512-Ng6Pxv6siyZp635xCSnH3mKmIFgqWPCcGdoo0GBYgyGdxu7cUj4agV7Uu1a8REP66UYUFXJLudeGgd4RvuJAnQ==
"@webassemblyjs/wasm-edit@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz#8c74ca474d4f951d01dbae9bd70814ee22a82005"
integrity sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==
"@webassemblyjs/wasm-edit@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.10.tgz#83fe3140f5a58f5a30b914702be9f0e59a399092"
integrity sha512-e9RZFQlb+ZuYcKRcW9yl+mqX/Ycj9+3/+ppDI8nEE/NCY6FoK8f3dKBcfubYV/HZn44b+ND4hjh+4BYBt+sDnA==
dependencies:
"@webassemblyjs/ast" "1.7.11"
"@webassemblyjs/helper-buffer" "1.7.11"
"@webassemblyjs/helper-wasm-bytecode" "1.7.11"
"@webassemblyjs/helper-wasm-section" "1.7.11"
"@webassemblyjs/wasm-gen" "1.7.11"
"@webassemblyjs/wasm-opt" "1.7.11"
"@webassemblyjs/wasm-parser" "1.7.11"
"@webassemblyjs/wast-printer" "1.7.11"
"@webassemblyjs/ast" "1.7.10"
"@webassemblyjs/helper-buffer" "1.7.10"
"@webassemblyjs/helper-wasm-bytecode" "1.7.10"
"@webassemblyjs/helper-wasm-section" "1.7.10"
"@webassemblyjs/wasm-gen" "1.7.10"
"@webassemblyjs/wasm-opt" "1.7.10"
"@webassemblyjs/wasm-parser" "1.7.10"
"@webassemblyjs/wast-printer" "1.7.10"
"@webassemblyjs/wasm-gen@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz#9bbba942f22375686a6fb759afcd7ac9c45da1a8"
integrity sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==
"@webassemblyjs/wasm-gen@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.10.tgz#4de003806ae29c97ab3707782469b53299570174"
integrity sha512-M0lb6cO2Y0PzDye/L39PqwV+jvO+2YxEG5ax+7dgq7EwXdAlpOMx1jxyXJTScQoeTpzOPIb+fLgX/IkLF8h2yw==
dependencies:
"@webassemblyjs/ast" "1.7.11"
"@webassemblyjs/helper-wasm-bytecode" "1.7.11"
"@webassemblyjs/ieee754" "1.7.11"
"@webassemblyjs/leb128" "1.7.11"
"@webassemblyjs/utf8" "1.7.11"
"@webassemblyjs/ast" "1.7.10"
"@webassemblyjs/helper-wasm-bytecode" "1.7.10"
"@webassemblyjs/ieee754" "1.7.10"
"@webassemblyjs/leb128" "1.7.10"
"@webassemblyjs/utf8" "1.7.10"
"@webassemblyjs/wasm-opt@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz#b331e8e7cef8f8e2f007d42c3a36a0580a7d6ca7"
integrity sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==
"@webassemblyjs/wasm-opt@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.10.tgz#d151e31611934a556c82789fdeec41a814993c2a"
integrity sha512-R66IHGCdicgF5ZliN10yn5HaC7vwYAqrSVJGjtJJQp5+QNPBye6heWdVH/at40uh0uoaDN/UVUfXK0gvuUqtVg==
dependencies:
"@webassemblyjs/ast" "1.7.11"
"@webassemblyjs/helper-buffer" "1.7.11"
"@webassemblyjs/wasm-gen" "1.7.11"
"@webassemblyjs/wasm-parser" "1.7.11"
"@webassemblyjs/ast" "1.7.10"
"@webassemblyjs/helper-buffer" "1.7.10"
"@webassemblyjs/wasm-gen" "1.7.10"
"@webassemblyjs/wasm-parser" "1.7.10"
"@webassemblyjs/wasm-parser@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz#6e3d20fa6a3519f6b084ef9391ad58211efb0a1a"
integrity sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==
"@webassemblyjs/wasm-parser@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.10.tgz#0367be7bf8f09e3e6abc95f8e483b9206487ec65"
integrity sha512-AEv8mkXVK63n/iDR3T693EzoGPnNAwKwT3iHmKJNBrrALAhhEjuPzo/lTE4U7LquEwyvg5nneSNdTdgrBaGJcA==
dependencies:
"@webassemblyjs/ast" "1.7.11"
"@webassemblyjs/helper-api-error" "1.7.11"
"@webassemblyjs/helper-wasm-bytecode" "1.7.11"
"@webassemblyjs/ieee754" "1.7.11"
"@webassemblyjs/leb128" "1.7.11"
"@webassemblyjs/utf8" "1.7.11"
"@webassemblyjs/ast" "1.7.10"
"@webassemblyjs/helper-api-error" "1.7.10"
"@webassemblyjs/helper-wasm-bytecode" "1.7.10"
"@webassemblyjs/ieee754" "1.7.10"
"@webassemblyjs/leb128" "1.7.10"
"@webassemblyjs/utf8" "1.7.10"
"@webassemblyjs/wast-parser@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz#25bd117562ca8c002720ff8116ef9072d9ca869c"
integrity sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==
"@webassemblyjs/wast-parser@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.10.tgz#058f598b52f730b23fc874d4775b6286b6247264"
integrity sha512-YTPEtOBljkCL0VjDp4sHe22dAYSm3ZwdJ9+2NTGdtC7ayNvuip1wAhaAS8Zt9Q6SW9E5Jf5PX7YE3XWlrzR9cw==
dependencies:
"@webassemblyjs/ast" "1.7.11"
"@webassemblyjs/floating-point-hex-parser" "1.7.11"
"@webassemblyjs/helper-api-error" "1.7.11"
"@webassemblyjs/helper-code-frame" "1.7.11"
"@webassemblyjs/helper-fsm" "1.7.11"
"@webassemblyjs/ast" "1.7.10"
"@webassemblyjs/floating-point-hex-parser" "1.7.10"
"@webassemblyjs/helper-api-error" "1.7.10"
"@webassemblyjs/helper-code-frame" "1.7.10"
"@webassemblyjs/helper-fsm" "1.7.10"
"@xtuc/long" "4.2.1"
"@webassemblyjs/wast-printer@1.7.11":
version "1.7.11"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz#c4245b6de242cb50a2cc950174fdbf65c78d7813"
integrity sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==
"@webassemblyjs/wast-printer@1.7.10":
version "1.7.10"
resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.10.tgz#d817909d2450ae96c66b7607624d98a33b84223b"
integrity sha512-mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA==
dependencies:
"@webassemblyjs/ast" "1.7.11"
"@webassemblyjs/wast-parser" "1.7.11"
"@webassemblyjs/ast" "1.7.10"
"@webassemblyjs/wast-parser" "1.7.10"
"@xtuc/long" "4.2.1"
"@xtuc/ieee754@^1.2.0":
@ -1388,15 +1388,6 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chardet@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
@ -1601,6 +1592,11 @@ commander@^2.12.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
commander@~2.13.0:
version "2.13.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==
commander@~2.17.1:
version "2.17.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
@ -2087,7 +2083,7 @@ detect-libc@^1.0.2:
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
detect-node@^2.0.4:
detect-node@^2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
@ -3038,10 +3034,10 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
handle-thing@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754"
integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==
handle-thing@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4"
integrity sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=
handlebars@^4.0.1, handlebars@^4.0.11:
version "4.0.12"
@ -4923,7 +4919,7 @@ object.pick@^1.3.0:
dependencies:
isobject "^3.0.1"
obuf@^1.0.0, obuf@^1.1.2:
obuf@^1.0.0, obuf@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
@ -5396,14 +5392,14 @@ postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.1:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
postcss@7.0.11:
version "7.0.11"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.11.tgz#f63c513b78026d66263bb2ca995bf02e3d1a697d"
integrity sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==
postcss@7.0.5:
version "7.0.5"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.5.tgz#70e6443e36a6d520b0fd4e7593fcca3635ee9f55"
integrity sha512-HBNpviAUFCKvEh7NZhw1e8MBPivRszIiUnhrJ+sBFVSYSqubrzwX3KG51mYgcRHX8j/cAgZJedONZcm5jTBdgQ==
dependencies:
chalk "^2.4.2"
chalk "^2.4.1"
source-map "^0.6.1"
supports-color "^6.1.0"
supports-color "^5.5.0"
postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.6:
version "7.0.7"
@ -5690,7 +5686,7 @@ read-pkg@^2.0.0:
normalize-package-data "^2.3.2"
path-type "^2.0.0"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
@ -5703,15 +5699,6 @@ read-pkg@^2.0.0:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^3.0.6:
version "3.1.1"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.1.1.tgz#ed6bbc6c5ba58b090039ff18ce670515795aeb06"
integrity sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==
dependencies:
inherits "^2.0.3"
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
readable-stream@~2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
@ -6021,7 +6008,7 @@ schema-utils@^0.3.0:
dependencies:
ajv "^5.0.0"
schema-utils@^0.4.4:
schema-utils@^0.4.4, schema-utils@^0.4.5:
version "0.4.7"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187"
integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==
@ -6465,33 +6452,35 @@ spdx-license-ids@^3.0.0:
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e"
integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==
spdy-transport@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31"
integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==
spdy-transport@^2.0.18:
version "2.1.1"
resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.1.1.tgz#c54815d73858aadd06ce63001e7d25fa6441623b"
integrity sha512-q7D8c148escoB3Z7ySCASadkegMmUZW8Wb/Q1u0/XBgDKMO880rLQDj8Twiew/tYi7ghemKUi/whSYOwE17f5Q==
dependencies:
debug "^4.1.0"
detect-node "^2.0.4"
debug "^2.6.8"
detect-node "^2.0.3"
hpack.js "^2.1.6"
obuf "^1.1.2"
readable-stream "^3.0.6"
wbuf "^1.7.3"
obuf "^1.1.1"
readable-stream "^2.2.9"
safe-buffer "^5.0.1"
wbuf "^1.7.2"
spdy@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.0.tgz#81f222b5a743a329aa12cea6a390e60e9b613c52"
integrity sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==
spdy@^3.4.1:
version "3.4.7"
resolved "https://registry.yarnpkg.com/spdy/-/spdy-3.4.7.tgz#42ff41ece5cc0f99a3a6c28aabb73f5c3b03acbc"
integrity sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=
dependencies:
debug "^4.1.0"
handle-thing "^2.0.0"
debug "^2.6.8"
handle-thing "^1.2.5"
http-deceiver "^1.2.7"
safe-buffer "^5.0.1"
select-hose "^2.0.0"
spdy-transport "^3.0.0"
spdy-transport "^2.0.18"
speed-measure-webpack-plugin@1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.2.5.tgz#8179936eb8c5e891f7481bd5075a9ea9a0f74823"
integrity sha512-S/guYjC4Izn5wY2d0+M4zowED/F77Lxh9yjkTZ+XAr244pr9c1MYNcXcRe9lx2hmAj0GPbOrBXgOF2YIp/CZ8A==
speed-measure-webpack-plugin@1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.2.3.tgz#de170b5cefbfa1c039d95e639edd3ad50cfc7c48"
integrity sha512-p+taQ69VkRUXYMoZOx2nxV/Tz8tt79ahctoZJyJDHWP7fEYvwFNf5Pd73k5kZ6auu0pTsPNLEUwWpM8mCk85Zw==
dependencies:
chalk "^2.0.1"
@ -6637,7 +6626,7 @@ string-width@^1.0.1, string-width@^1.0.2:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
string_decoder@^1.0.0, string_decoder@^1.1.1:
string_decoder@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==
@ -6754,13 +6743,6 @@ supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-co
dependencies:
has-flag "^3.0.0"
supports-color@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
dependencies:
has-flag "^3.0.0"
symbol-observable@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
@ -6793,10 +6775,10 @@ tar@^4, tar@^4.4.6:
safe-buffer "^5.1.2"
yallist "^3.0.2"
terser-webpack-plugin@1.2.1, terser-webpack-plugin@^1.1.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.2.1.tgz#7545da9ae5f4f9ae6a0ac961eb46f5e7c845cc26"
integrity sha512-GGSt+gbT0oKcMDmPx4SRSfJPE1XaN3kQRWG4ghxKQw9cn5G9x6aCKSsgYdvyM0na9NJ4Drv0RG6jbBByZ5CMjw==
terser-webpack-plugin@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.1.0.tgz#cf7c25a1eee25bf121f4a587bb9e004e3f80e528"
integrity sha512-61lV0DSxMAZ8AyZG7/A4a3UPlrbOBo8NIQ4tJzLPAdGOQ+yoNC7l5ijEow27lBAL2humer01KLS6bGIMYQxKoA==
dependencies:
cacache "^11.0.2"
find-cache-dir "^2.0.0"
@ -6944,7 +6926,7 @@ ts-node@~7.0.0:
source-map-support "^0.5.6"
yn "^2.0.0"
tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
@ -7019,6 +7001,14 @@ typescript@3.2.2:
"typescript@file:../../node_modules/typescript":
version "3.2.2"
uglify-es@^3.3.4:
version "3.3.9"
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677"
integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==
dependencies:
commander "~2.13.0"
source-map "~0.6.1"
uglify-js@^3.1.4:
version "3.4.9"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3"
@ -7027,6 +7017,20 @@ uglify-js@^3.1.4:
commander "~2.17.1"
source-map "~0.6.1"
uglifyjs-webpack-plugin@^1.2.4:
version "1.3.0"
resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz#75f548160858163a08643e086d5fefe18a5d67de"
integrity sha512-ovHIch0AMlxjD/97j9AYovZxG5wnHOPkL7T1GKochBADp/Zwc44pEWNqpKl1Loupp1WhFg7SlYmHZRUfdAacgw==
dependencies:
cacache "^10.0.4"
find-cache-dir "^1.0.0"
schema-utils "^0.4.5"
serialize-javascript "^1.4.0"
source-map "^0.6.1"
uglify-es "^3.3.4"
webpack-sources "^1.1.0"
worker-farm "^1.5.2"
ultron@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
@ -7115,7 +7119,7 @@ useragent@2.3.0:
lru-cache "4.1.x"
tmp "0.0.x"
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
@ -7194,7 +7198,7 @@ watchpack@^1.5.0:
graceful-fs "^4.1.2"
neo-async "^2.5.0"
wbuf@^1.1.0, wbuf@^1.7.3:
wbuf@^1.1.0, wbuf@^1.7.2:
version "1.7.3"
resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df"
integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==
@ -7244,10 +7248,10 @@ webpack-dev-middleware@3.4.0:
range-parser "^1.0.3"
webpack-log "^2.0.0"
webpack-dev-server@3.1.14:
version "3.1.14"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.1.14.tgz#60fb229b997fc5a0a1fc6237421030180959d469"
integrity sha512-mGXDgz5SlTxcF3hUpfC8hrQ11yhAttuUQWf1Wmb+6zo3x6rb7b9mIfuQvAPLdfDRCGRGvakBWHdHOa0I9p/EVQ==
webpack-dev-server@3.1.10:
version "3.1.10"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.1.10.tgz#507411bee727ee8d2fdffdc621b66a64ab3dea2b"
integrity sha512-RqOAVjfqZJtQcB0LmrzJ5y4Jp78lv9CK0MZ1YJDTaTmedMZ9PU9FLMQNrMCfVu8hHzaVLVOJKBlGEHMN10z+ww==
dependencies:
ansi-html "0.0.7"
bonjour "^3.5.0"
@ -7268,14 +7272,12 @@ webpack-dev-server@3.1.14:
portfinder "^1.0.9"
schema-utils "^1.0.0"
selfsigned "^1.9.1"
semver "^5.6.0"
serve-index "^1.7.2"
sockjs "0.3.19"
sockjs-client "1.3.0"
spdy "^4.0.0"
spdy "^3.4.1"
strip-ansi "^3.0.0"
supports-color "^5.1.0"
url "^0.11.0"
webpack-dev-middleware "3.4.0"
webpack-log "^2.0.0"
yargs "12.0.2"
@ -7318,15 +7320,15 @@ webpack-subresource-integrity@1.1.0-rc.6:
dependencies:
webpack-core "^0.6.8"
webpack@4.28.4:
version "4.28.4"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.28.4.tgz#1ddae6c89887d7efb752adf0c3cd32b9b07eacd0"
integrity sha512-NxjD61WsK/a3JIdwWjtIpimmvE6UrRi3yG54/74Hk9rwNj5FPkA4DJCf1z4ByDWLkvZhTZE+P3C/eh6UD5lDcw==
webpack@4.23.1:
version "4.23.1"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.23.1.tgz#db7467b116771ae020c58bdfe2a0822785bb8239"
integrity sha512-iE5Cu4rGEDk7ONRjisTOjVHv3dDtcFfwitSxT7evtYj/rANJpt1OuC/Kozh1pBa99AUBr1L/LsaNB+D9Xz3CEg==
dependencies:
"@webassemblyjs/ast" "1.7.11"
"@webassemblyjs/helper-module-context" "1.7.11"
"@webassemblyjs/wasm-edit" "1.7.11"
"@webassemblyjs/wasm-parser" "1.7.11"
"@webassemblyjs/ast" "1.7.10"
"@webassemblyjs/helper-module-context" "1.7.10"
"@webassemblyjs/wasm-edit" "1.7.10"
"@webassemblyjs/wasm-parser" "1.7.10"
acorn "^5.6.2"
acorn-dynamic-import "^3.0.0"
ajv "^6.1.0"
@ -7344,7 +7346,7 @@ webpack@4.28.4:
node-libs-browser "^2.0.0"
schema-utils "^0.4.4"
tapable "^1.1.0"
terser-webpack-plugin "^1.1.0"
uglifyjs-webpack-plugin "^1.2.4"
watchpack "^1.5.0"
webpack-sources "^1.3.0"

View File

@ -24,11 +24,10 @@
"@angular/router": "file:../../dist/packages-dist/router",
"core-js": "file:../../node_modules/core-js",
"rxjs": "file:../../node_modules/rxjs",
"tslib": "^1.9.3",
"zone.js": "file:../../node_modules/zone.js"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.12.1",
"@angular-devkit/build-angular": "~0.10.3",
"@angular/cli": "file:../../node_modules/@angular/cli",
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
"@angular/language-service": "file:../../dist/packages-dist/language-service",

View File

@ -11,17 +11,14 @@
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
* Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/** IE9, IE10, IE11, and Chrome <55 requires all of the following polyfills.
* This also includes Android Emulators with older versions of Chrome and Google Search/Googlebot
*/
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
// import 'core-js/es6/symbol';
// import 'core-js/es6/object';
// import 'core-js/es6/function';
@ -43,36 +40,19 @@
/** IE10 and IE11 requires the following for the Reflect API. */
// import 'core-js/es6/reflect';
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/** Evergreen browsers require these. **/
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import 'core-js/es7/reflect';
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags.ts';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*
* (window as any).__Zone_enable_cross_context_check = true;
*
*/
* Required to support Web Animations `@angular/platform-browser/animations`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
**/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
@ -80,6 +60,7 @@
import 'zone.js/dist/zone'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/

View File

@ -7,7 +7,6 @@
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es5",
"typeRoots": [
"node_modules/@types"

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "angular-srcs",
"version": "8.0.0-beta.1",
"version": "8.0.0-beta.0",
"private": true,
"branchPattern": "2.0.*",
"description": "Angular - a web framework for modern web apps",
@ -36,7 +36,7 @@
"@angular-devkit/core": "^7.0.4",
"@angular-devkit/schematics": "^7.0.4",
"@bazel/karma": "~0.22.1",
"@bazel/typescript": "~0.22.1",
"@bazel/typescript": "0.22.1-7-g68fed6a",
"@schematics/angular": "^7.0.4",
"@types/chokidar": "1.7.3",
"@types/convert-source-map": "^1.5.1",
@ -146,9 +146,5 @@
"vlq": "0.2.2",
"vrsource-tslint-rules": "5.1.1",
"webpack": "1.12.9"
},
"// 4": "natives is needed for gulp to work with node >= 10.13, see #28213",
"resolutions": {
"natives": "1.1.6"
}
}

View File

@ -26,61 +26,15 @@ export class NgForOfContext<T> {
}
/**
* A [structural directive](guide/structural-directives) that renders
* a template for each item in a collection.
* The directive is placed on an element, which becomes the parent
* of the cloned templates.
*
* The `ngForOf` directive is generally used in the
* [shorthand form](guide/structural-directives#the-asterisk--prefix) `*ngFor`.
* In this form, the template to be rendered for each iteration is the content
* of an anchor element containing the directive.
*
* The following example shows the shorthand syntax with some options,
* contained in an `<li>` element.
*
* ```
* <li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>
* ```
*
* The shorthand form expands into a long form that uses the `ngForOf` selector
* on an `<ng-template>` element.
* The content of the `<ng-template>` element is the `<li>` element that held the
* short-form directive.
*
* Here is the expanded version of the short-form example.
*
* ```
* <ng-template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn">
* <li>...</li>
* </ng-template>
* ```
*
* Angular automatically expands the shorthand syntax as it compiles the template.
* The context for each embedded view is logically merged to the current component
* context according to its lexical position.
*
* When using the shorthand syntax, Angular allows only [one structural directive
* on an element](guide/structural-directives#one-structural-directive-per-host-element).
* If you want to iterate conditionally, for example,
* put the `*ngIf` on a container element that wraps the `*ngFor` element.
* For futher discussion, see
* [Structural Directives](guide/structural-directives#one-per-element).
* The `NgForOf` directive instantiates a template once per item from an iterable. The context
* for each instantiated template inherits from the outer context with the given loop variable
* set to the current item from the iterable.
*
* @usageNotes
*
* ### Local variables
* ### Local Variables
*
* `NgForOf` provides exported values that can be aliased to local variables.
* For example:
*
* ```
* <li *ngFor="let user of userObservable | async as users; index as i; first as isFirst">
* {{i}}/{{users.length}}. {{user}} <span *ngIf="isFirst">default</span>
* </li>
* ```
*
* The following exported values can be aliased to local variables:
* `NgForOf` provides several exported values that can be aliased to local variables:
*
* - `$implicit: T`: The value of the individual items in the iterable (`ngForOf`).
* - `ngForOf: NgIterable<T>`: The value of the iterable expression. Useful when the expression is
@ -92,64 +46,65 @@ export class NgForOfContext<T> {
* - `even: boolean`: True when the item has an even index in the iterable.
* - `odd: boolean`: True when the item has an odd index in the iterable.
*
* ### Change propagation
* ```
* <li *ngFor="let user of userObservable | async as users; index as i; first as isFirst">
* {{i}}/{{users.length}}. {{user}} <span *ngIf="isFirst">default</span>
* </li>
* ```
*
* ### Change Propagation
*
* When the contents of the iterator changes, `NgForOf` makes the corresponding changes to the DOM:
*
* * When an item is added, a new instance of the template is added to the DOM.
* * When an item is removed, its template instance is removed from the DOM.
* * When items are reordered, their respective templates are reordered in the DOM.
* * Otherwise, the DOM element for that item will remain the same.
*
* Angular uses object identity to track insertions and deletions within the iterator and reproduce
* those changes in the DOM. This has important implications for animations and any stateful
* controls that are present, such as `<input>` elements that accept user input. Inserted rows can
* controls (such as `<input>` elements which accept user input) that are present. Inserted rows can
* be animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state
* such as user input.
* For more on animations, see [Transitions and Triggers](guide/transition-and-triggers).
*
* The identities of elements in the iterator can change while the data does not.
* This can happen, for example, if the iterator is produced from an RPC to the server, and that
* RPC is re-run. Even if the data hasn't changed, the second response produces objects with
* different identities, and Angular must tear down the entire DOM and rebuild it (as if all old
* elements were deleted and all new elements inserted).
* It is possible for the identities of elements in the iterator to change while the data does not.
* This can happen, for example, if the iterator produced from an RPC to the server, and that
* RPC is re-run. Even if the data hasn't changed, the second response will produce objects with
* different identities, and Angular will tear down the entire DOM and rebuild it (as if all old
* elements were deleted and all new elements inserted). This is an expensive operation and should
* be avoided if possible.
*
* To avoid this expensive operation, you can customize the default tracking algorithm.
* by supplying the `trackBy` option to `NgForOf`.
* `trackBy` takes a function that has two arguments: `index` and `item`.
* To customize the default tracking algorithm, `NgForOf` supports `trackBy` option.
* `trackBy` takes a function which has two arguments: `index` and `item`.
* If `trackBy` is given, Angular tracks changes by the return value of the function.
*
* @see [Structural Directives](guide/structural-directives)
* ### Syntax
*
* - `<li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>`
*
* With `<ng-template>` element:
*
* ```
* <ng-template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn">
* <li>...</li>
* </ng-template>
* ```
*
* ### Example
*
* See a [live demo](http://plnkr.co/edit/KVuXxDp0qinGDyo307QW?p=preview) for a more detailed
* example.
*
* @ngModule CommonModule
* @publicApi
*/
@Directive({selector: '[ngFor][ngForOf]'})
export class NgForOf<T> implements DoCheck {
/**
* The value of the iterable expression, which can be used as a
* [template input variable](guide/structural-directives#template-input-variable).
*/
@Input()
set ngForOf(ngForOf: NgIterable<T>) {
this._ngForOf = ngForOf;
this._ngForOfDirty = true;
}
/**
* A function that defines how to track changes for items in the iterable.
*
* When items are added, moved, or removed in the iterable,
* the directive must re-render the appropriate DOM nodes.
* To minimize churn in the DOM, only nodes that have changed
* are re-rendered.
*
* By default, the change detector assumes that
* the object instance identifies the node in the iterable.
* When this function is supplied, the directive uses
* the result of calling this function to identify the item node,
* rather than the identity of the object itself.
*
* The function receives two inputs,
* the iteration index and the node object ID.
*/
@Input()
set ngForTrackBy(fn: TrackByFunction<T>) {
if (isDevMode() && fn != null && typeof fn !== 'function') {
@ -176,10 +131,6 @@ export class NgForOf<T> implements DoCheck {
private _viewContainer: ViewContainerRef, private _template: TemplateRef<NgForOfContext<T>>,
private _differs: IterableDiffers) {}
/**
* A reference to the template that is stamped out for each item in the iterable.
* @see [template reference variable](guide/template-syntax#template-reference-variables--var-)
*/
@Input()
set ngForTemplate(value: TemplateRef<NgForOfContext<T>>) {
// TODO(TS2.1): make TemplateRef<Partial<NgForRowOf<T>>> once we move to TS v2.1
@ -190,9 +141,6 @@ export class NgForOf<T> implements DoCheck {
}
}
/**
* Applies the changes when needed.
*/
ngDoCheck(): void {
if (this._ngForOfDirty) {
this._ngForOfDirty = false;
@ -256,9 +204,9 @@ export class NgForOf<T> implements DoCheck {
}
/**
* Asserts the correct type of the context for the template that `NgForOf` will render.
* Assert the correct type of the context for the template that `NgForOf` will render.
*
* The presence of this method is a signal to the Ivy template type-check compiler that the
* The presence of this method is a signal to the Ivy template type check compiler that the
* `NgForOf` structural directive renders its template with a specific context type.
*/
static ngTemplateContextGuard<T>(dir: NgForOf<T>, ctx: any): ctx is NgForOfContext<T> {

View File

@ -10,140 +10,94 @@ import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef, ɵstri
/**
* A structural directive that conditionally includes a template based on the value of
* an expression coerced to Boolean.
* When the expression evaluates to true, Angular renders the template
* provided in a `then` clause, and when false or null,
* Angular renders the template provided in an optional `else` clause. The default
* template for the `else` clause is blank.
* Conditionally includes a template based on the value of an `expression`.
*
* A [shorthand form](guide/structural-directives#the-asterisk--prefix) of the directive,
* `*ngIf="condition"`, is generally used, provided
* as an attribute of the anchor element for the inserted template.
* Angular expands this into a more explicit version, in which the anchor element
* is contained in an `<ng-template>` element.
* `ngIf` evaluates the `expression` and then renders the `then` or `else` template in its place
* when expression is truthy or falsy respectively. Typically the:
* - `then` template is the inline template of `ngIf` unless bound to a different value.
* - `else` template is blank unless it is bound.
*
* Simple form with shorthand syntax:
*
* ```
* <div *ngIf="condition">Content to render when condition is true.</div>
* ```
*
* Simple form with expanded syntax:
*
* ```
* <ng-template [ngIf]="condition"><div>Content to render when condition is
* true.</div></ng-template>
* ```
*
* Form with an "else" block:
*
* ```
* <div *ngIf="condition; else elseBlock">Content to render when condition is true.</div>
* <ng-template #elseBlock>Content to render when condition is false.</ng-template>
* ```
*
* Shorthand form with "then" and "else" blocks:
*
* ```
* <div *ngIf="condition; then thenBlock else elseBlock"></div>
* <ng-template #thenBlock>Content to render when condition is true.</ng-template>
* <ng-template #elseBlock>Content to render when condition is false.</ng-template>
* ```
*
* Form with storing the value locally:
*
* ```
* <div *ngIf="condition as value; else elseBlock">{{value}}</div>
* <ng-template #elseBlock>Content to render when value is null.</ng-template>
* ```
*
* @usageNotes
*
* The `*ngIf` directive is most commonly used to conditionally show an inline template,
* as seen in the following example.
* The default `else` template is blank.
* ### Most common usage
*
* The most common usage of the `ngIf` directive is to conditionally show the inline template as
* seen in this example:
* {@example common/ngIf/ts/module.ts region='NgIfSimple'}
*
* ### Showing an alternative template using `else`
*
* To display a template when `expression` evaluates to false, use an `else` template
* binding as shown in the following example.
* The `else` binding points to an `<ng-template>` element labeled `#elseBlock`.
* The template can be defined anywhere in the component view, but is typically placed right after
* If it is necessary to display a template when the `expression` is falsy use the `else` template
* binding as shown. Note that the `else` binding points to a `<ng-template>` labeled `#elseBlock`.
* The template can be defined anywhere in the component view but is typically placed right after
* `ngIf` for readability.
*
* {@example common/ngIf/ts/module.ts region='NgIfElse'}
*
* ### Using an external `then` template
* ### Using non-inlined `then` template
*
* In the previous example, the then-clause template is specified inline, as the content of the
* tag that contains the `ngIf` directive. You can also specify a template that is defined
* externally, by referencing a labeled `<ng-template>` element. When you do this, you can
* change which template to use at runtime, as shown in the following example.
* Usually the `then` template is the inlined template of the `ngIf`, but it can be changed using
* a binding (just like `else`). Because `then` and `else` are bindings, the template references can
* change at runtime as shown in this example.
*
* {@example common/ngIf/ts/module.ts region='NgIfThenElse'}
*
* ### Storing a conditional result in a variable
* ### Storing conditional result in a variable
*
* You might want to show a set of properties from the same object. If you are waiting
* for asynchronous data, the object can be undefined.
* In this case, you can use `ngIf` and store the result of the condition in a local
* variable as shown in the the following example.
* A common pattern is that we need to show a set of properties from the same object. If the
* object is undefined, then we have to use the safe-traversal-operator `?.` to guard against
* dereferencing a `null` value. This is especially the case when waiting on async data such as
* when using the `async` pipe as shown in following example:
*
* ```
* Hello {{ (userStream|async)?.last }}, {{ (userStream|async)?.first }}!
* ```
*
* There are several inefficiencies in the above example:
* - We create multiple subscriptions on `userStream`. One for each `async` pipe, or two in the
* example above.
* - We cannot display an alternative screen while waiting for the data to arrive asynchronously.
* - We have to use the safe-traversal-operator `?.` to access properties, which is cumbersome.
* - We have to place the `async` pipe in parenthesis.
*
* A better way to do this is to use `ngIf` and store the result of the condition in a local
* variable as shown in the the example below:
*
* {@example common/ngIf/ts/module.ts region='NgIfAs'}
*
* This code uses only one `AsyncPipe`, so only one subscription is created.
* The conditional statement stores the result of `userStream|async` in the local variable `user`.
* You can then bind the local `user` repeatedly.
* Notice that:
* - We use only one `async` pipe and hence only one subscription gets created.
* - `ngIf` stores the result of the `userStream|async` in the local variable `user`.
* - The local `user` can then be bound repeatedly in a more efficient way.
* - No need to use the safe-traversal-operator `?.` to access properties as `ngIf` will only
* display the data if `userStream` returns a value.
* - We can display an alternative template while waiting for the data.
*
* The conditional displays the data only if `userStream` returns a value,
* so you don't need to use the
* [safe-navigation-operator](guide/template-syntax#safe-navigation-operator) (`?.`)
* to guard against null values when accessing properties.
* You can display an alternative template while waiting for the data.
* ### Syntax
*
* ### Shorthand syntax
*
* The shorthand syntax `*ngIf` expands into two separate template specifications
* for the "then" and "else" clauses. For example, consider the following shorthand statement,
* that is meant to show a loading page while waiting for data to be loaded.
* Simple form:
* - `<div *ngIf="condition">...</div>`
* - `<ng-template [ngIf]="condition"><div>...</div></ng-template>`
*
* Form with an else block:
* ```
* <div class="hero-list" *ngIf="heroes else loading">
* ...
* </div>
*
* <ng-template #loading>
* <div>Loading...</div>
* </ng-template>
* <div *ngIf="condition; else elseBlock">...</div>
* <ng-template #elseBlock>...</ng-template>
* ```
*
* You can see that the "else" clause references the `<ng-template>`
* with the `#loading` label, and the template for the "then" clause
* is provided as the content of the anchor element.
*
* However, when Angular expands the shorthand syntax, it creates
* another `<ng-template>` tag, with `ngIf` and `ngIfElse` directives.
* The anchor element containing the template for the "then" clause becomes
* the content of this unlabeled `<ng-template>` tag.
*
* Form with a `then` and `else` block:
* ```
* <ng-template [ngIf]="hero-list" [ngIfElse]="loading">
* <div class="hero-list">
* ...
* </div>
* </ng-template>
*
* <ng-template #loading>
* <div>Loading...</div>
* </ng-template>
* <div *ngIf="condition; then thenBlock else elseBlock"></div>
* <ng-template #thenBlock>...</ng-template>
* <ng-template #elseBlock>...</ng-template>
* ```
*
* The presence of the implicit template object has implications for the nesting of
* structural directives. For more on this subject, see
* [Structural Directives](https://angular.io/guide/structural-directives#one-per-element).
* Form with storing the value locally:
* ```
* <div *ngIf="condition as value; else elseBlock">{{value}}</div>
* <ng-template #elseBlock>...</ng-template>
* ```
*
* @ngModule CommonModule
* @publicApi
@ -160,18 +114,12 @@ export class NgIf {
this._thenTemplateRef = templateRef;
}
/**
* The Boolean expression to evaluate as the condition for showing a template.
*/
@Input()
set ngIf(condition: any) {
this._context.$implicit = this._context.ngIf = condition;
this._updateView();
}
/**
* A template to show if the condition expression evaluates to true.
*/
@Input()
set ngIfThen(templateRef: TemplateRef<NgIfContext>|null) {
assertTemplate('ngIfThen', templateRef);
@ -180,9 +128,6 @@ export class NgIf {
this._updateView();
}
/**
* A template to show if the condition expression evaluates to false.
*/
@Input()
set ngIfElse(templateRef: TemplateRef<NgIfContext>|null) {
assertTemplate('ngIfElse', templateRef);

View File

@ -12,35 +12,21 @@ import {Directive, DoCheck, ElementRef, Input, KeyValueChanges, KeyValueDiffer,
* @ngModule CommonModule
*
* @usageNotes
*
* Set the font of the containing element to the result of an expression.
*
* ```
* <some-element [ngStyle]="{'font-style': styleExp}">...</some-element>
* ```
*
* Set the width of the containing element to a pixel value returned by an expression.
*
* ```
* <some-element [ngStyle]="{'max-width.px': widthExp}">...</some-element>
* ```
*
* Set a collection of style values using an expression that returns key-value pairs.
*
* ```
* <some-element [ngStyle]="objExp">...</some-element>
* ```
*
* @description
*
* An attribute directive that updates styles for the containing HTML element.
* Sets one or more style properties, specified as colon-separated key-value pairs.
* The key is a style name, with an optional `.<unit>` suffix
* (such as 'top.px', 'font-style.em').
* The value is an expression to be evaluated.
* The resulting non-null value, expressed in the given unit,
* is assigned to the given style property.
* If the result of evaluation is null, the corresponding style is removed.
* Update an HTML element styles.
*
* The styles are updated according to the value of the expression evaluation:
* - keys are style names with an optional `.<unit>` suffix (ie 'top.px', 'font-style.em'),
* - values are the values assigned to those properties (expressed in the given unit).
*
* @publicApi
*/
@ -55,24 +41,13 @@ export class NgStyle implements DoCheck {
private _differs: KeyValueDiffers, private _ngEl: ElementRef, private _renderer: Renderer2) {}
@Input()
set ngStyle(
/**
* A map of style properties, specified as colon-separated
* key-value pairs.
* * The key is a style name, with an optional `.<unit>` suffix
* (such as 'top.px', 'font-style.em').
* * The value is an expression to be evaluated.
*/
values: {[key: string]: string}) {
set ngStyle(values: {[key: string]: string}) {
this._ngStyle = values;
if (!this._differ && values) {
this._differ = this._differs.find(values).create();
}
}
/**
* Applies the new styles if needed.
*/
ngDoCheck() {
if (this._differ) {
const changes = this._differ.diff(this._ngStyle);

View File

@ -29,7 +29,6 @@ ts_library(
"//packages/compiler-cli/src/ngtsc/imports",
"//packages/compiler-cli/src/ngtsc/partial_evaluator",
"//packages/compiler-cli/src/ngtsc/reflection",
"//packages/compiler-cli/src/ngtsc/routing",
"//packages/compiler-cli/src/ngtsc/shims",
"//packages/compiler-cli/src/ngtsc/switch",
"//packages/compiler-cli/src/ngtsc/transform",

View File

@ -24,3 +24,4 @@ export {CompilerOptions as AngularCompilerOptions} from './src/transformers/api'
export {NgTools_InternalApi_NG_2 as __NGTOOLS_PRIVATE_API_2} from './src/ngtools_api';
export {ngToTsDiagnostic} from './src/transformers/util';
export {NgTscPlugin} from './src/ngtsc/tsc_plugin';

View File

@ -115,7 +115,7 @@ function createEmitCallback(options: api.CompilerOptions): api.TsEmitCallback|un
export interface NgcParsedConfiguration extends ParsedConfiguration { watch?: boolean; }
export function readNgcCommandLineAndConfiguration(args: string[]): NgcParsedConfiguration {
function readNgcCommandLineAndConfiguration(args: string[]): NgcParsedConfiguration {
const options: api.CompilerOptions = {};
const parsedArgs = require('minimist')(args);
if (parsedArgs.i18nFile) options.i18nInFile = parsedArgs.i18nFile;

View File

@ -76,7 +76,7 @@ export class DecorationAnalyzer {
new InjectableDecoratorHandler(this.reflectionHost, this.isCore),
new NgModuleDecoratorHandler(
this.reflectionHost, this.evaluator, this.scopeRegistry, this.referencesRegistry,
this.isCore, /* routeAnalyzer */ null),
this.isCore),
new PipeDecoratorHandler(this.reflectionHost, this.evaluator, this.scopeRegistry, this.isCore),
];

View File

@ -14,7 +14,6 @@ ts_library(
"//packages/compiler-cli/src/ngtsc/imports",
"//packages/compiler-cli/src/ngtsc/partial_evaluator",
"//packages/compiler-cli/src/ngtsc/reflection",
"//packages/compiler-cli/src/ngtsc/routing",
"//packages/compiler-cli/src/ngtsc/transform",
"//packages/compiler-cli/src/ngtsc/typecheck",
"@ngdeps//@types/node",

View File

@ -13,7 +13,6 @@ import {ErrorCode, FatalDiagnosticError} from '../../diagnostics';
import {Reference, ResolvedReference} from '../../imports';
import {PartialEvaluator, ResolvedValue} from '../../partial_evaluator';
import {Decorator, ReflectionHost, reflectObjectLiteral, typeNodeToValueExpr} from '../../reflection';
import {NgModuleRouteAnalyzer} from '../../routing';
import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform';
import {generateSetClassMetadataCall} from './metadata';
@ -36,7 +35,7 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
constructor(
private reflector: ReflectionHost, private evaluator: PartialEvaluator,
private scopeRegistry: SelectorScopeRegistry, private referencesRegistry: ReferencesRegistry,
private isCore: boolean, private routeAnalyzer: NgModuleRouteAnalyzer|null) {}
private isCore: boolean) {}
detect(node: ts.Declaration, decorators: Decorator[]|null): Decorator|undefined {
if (!decorators) {
@ -78,20 +77,18 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
declarations = this.resolveTypeList(expr, declarationMeta, 'declarations');
}
let imports: Reference<ts.Declaration>[] = [];
let rawImports: ts.Expression|null = null;
if (ngModule.has('imports')) {
rawImports = ngModule.get('imports') !;
const expr = ngModule.get('imports') !;
const importsMeta = this.evaluator.evaluate(
rawImports, ref => this._extractModuleFromModuleWithProvidersFn(ref.node));
imports = this.resolveTypeList(rawImports, importsMeta, 'imports');
expr, ref => this._extractModuleFromModuleWithProvidersFn(ref.node));
imports = this.resolveTypeList(expr, importsMeta, 'imports');
}
let exports: Reference<ts.Declaration>[] = [];
let rawExports: ts.Expression|null = null;
if (ngModule.has('exports')) {
rawExports = ngModule.get('exports') !;
const expr = ngModule.get('exports') !;
const exportsMeta = this.evaluator.evaluate(
rawExports, ref => this._extractModuleFromModuleWithProvidersFn(ref.node));
exports = this.resolveTypeList(rawExports, exportsMeta, 'exports');
expr, ref => this._extractModuleFromModuleWithProvidersFn(ref.node));
exports = this.resolveTypeList(expr, exportsMeta, 'exports');
this.referencesRegistry.add(node, ...exports);
}
let bootstrap: Reference<ts.Declaration>[] = [];
@ -126,7 +123,6 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
const providers: Expression = ngModule.has('providers') ?
new WrappedNodeExpr(ngModule.get('providers') !) :
new LiteralArrayExpr([]);
const rawProviders = ngModule.has('providers') ? ngModule.get('providers') ! : null;
const injectorImports: WrappedNodeExpr<ts.Expression>[] = [];
if (ngModule.has('imports')) {
@ -136,11 +132,6 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
injectorImports.push(new WrappedNodeExpr(ngModule.get('exports') !));
}
if (this.routeAnalyzer !== null) {
this.routeAnalyzer.add(
node.getSourceFile(), node.name !.text, rawImports, rawExports, rawProviders);
}
const ngInjectorDef: R3InjectorMetadata = {
name: node.name !.text,
type: new WrappedNodeExpr(node.name !),
@ -197,12 +188,11 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
}
/**
* Given a `FunctionDeclaration`, `MethodDeclaration` or `FunctionExpression`, check if it is
* typed as a `ModuleWithProviders` and return an expression referencing the module if available.
* Given a `FunctionDeclaration` or `MethodDeclaration`, check if it is typed as a
* `ModuleWithProviders` and return an expression referencing the module if available.
*/
private _extractModuleFromModuleWithProvidersFn(node: ts.FunctionDeclaration|
ts.MethodDeclaration|
ts.FunctionExpression): ts.Expression|null {
ts.MethodDeclaration): ts.Expression|null {
const type = node.type || null;
return type &&
(this._reflectModuleFromTypeParam(type) || this._reflectModuleFromLiteralType(type));

View File

@ -12,7 +12,6 @@ import * as path from 'path';
import * as ts from 'typescript';
import {ShimGenerator} from '../../shims';
import {relativePathBetween} from '../../util/src/path';
export class FlatIndexGenerator implements ShimGenerator {
readonly flatIndexPath: string;
@ -28,7 +27,10 @@ export class FlatIndexGenerator implements ShimGenerator {
recognize(fileName: string): boolean { return fileName === this.flatIndexPath; }
generate(): ts.SourceFile {
const relativeEntryPoint = relativePathBetween(this.flatIndexPath, this.entryPoint);
const relativeEntryPoint = './' +
path.posix.relative(path.posix.dirname(this.flatIndexPath), this.entryPoint)
.replace(/\.tsx?$/, '');
const contents = `/**
* Generated bundle index. Do not edit.
*/

View File

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import {normalizeSeparators} from '../../util/src/path';
import {isNonDeclarationTsPath} from '../../util/src/typescript';
export function findFlatIndexEntryPoint(rootFiles: ReadonlyArray<string>): string|null {
@ -14,24 +13,22 @@ export function findFlatIndexEntryPoint(rootFiles: ReadonlyArray<string>): strin
// 1) if it's the only file!!!!!!
// 2) (deprecated) if it's named 'index.ts' and has the shortest path of all such files.
const tsFiles = rootFiles.filter(file => isNonDeclarationTsPath(file));
let resolvedEntryPoint: string|null = null;
if (tsFiles.length === 1) {
// There's only one file - this is the flat module index.
resolvedEntryPoint = tsFiles[0];
return tsFiles[0];
} else {
// In the event there's more than one TS file, one of them can still be selected as the
// flat module index if it's named 'index.ts'. If there's more than one 'index.ts', the one
// with the shortest path wins.
//
// This behavior is DEPRECATED and only exists to support existing usages.
let indexFile: string|null = null;
for (const tsFile of tsFiles) {
if (tsFile.endsWith('/index.ts') &&
(resolvedEntryPoint === null || tsFile.length <= resolvedEntryPoint.length)) {
resolvedEntryPoint = tsFile;
(indexFile === null || tsFile.length <= indexFile.length)) {
indexFile = tsFile;
}
}
return indexFile;
}
return resolvedEntryPoint ? normalizeSeparators(resolvedEntryPoint) : null;
}

View File

@ -1,28 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {findFlatIndexEntryPoint} from '../src/logic';
describe('entry_point logic', () => {
describe('findFlatIndexEntryPoint', () => {
it('should use the only source file if only a single one is specified',
() => { expect(findFlatIndexEntryPoint(['/src/index.ts'])).toBe('/src/index.ts'); });
it('should use the shortest source file ending with "index.ts" for multiple files', () => {
expect(findFlatIndexEntryPoint([
'/src/deep/index.ts', '/src/index.ts', '/index.ts'
])).toBe('/index.ts');
});
it('should normalize the path separators for the found entry point',
() => { expect(findFlatIndexEntryPoint(['\\src\\index.ts'])).toBe('/src/index.ts'); });
});
});

View File

@ -8,4 +8,4 @@
export {ImportRewriter, NoopImportRewriter, R3SymbolsImportRewriter, validateAndRewriteCoreSymbol} from './src/core';
export {AbsoluteReference, ImportMode, NodeReference, Reference, ResolvedReference} from './src/references';
export {ModuleResolver, ReferenceResolver, TsReferenceResolver} from './src/resolver';
export {ReferenceResolver, TsReferenceResolver} from './src/resolver';

View File

@ -17,28 +17,6 @@ export interface ReferenceResolver {
Reference<ts.Declaration>;
}
/**
* Used by `RouterEntryPointManager` and `NgModuleRouteAnalyzer` (which is in turn is used by
* `NgModuleDecoratorHandler`) for resolving the module source-files references in lazy-loaded
* routes (relative to the source-file containing the `NgModule` that provides the route
* definitions).
*/
export class ModuleResolver {
constructor(
private program: ts.Program, private compilerOptions: ts.CompilerOptions,
private host: ts.CompilerHost) {}
resolveModuleName(module: string, containingFile: ts.SourceFile): ts.SourceFile|null {
const resolved =
ts.resolveModuleName(module, containingFile.fileName, this.compilerOptions, this.host)
.resolvedModule;
if (resolved === undefined) {
return null;
}
return this.program.getSourceFile(resolved.resolvedFileName) || null;
}
}
export class TsReferenceResolver implements ReferenceResolver {
private moduleExportsCache = new Map<string, Map<ts.Declaration, string>|null>();

View File

@ -6,6 +6,5 @@
* found in the LICENSE file at https://angular.io/license
*/
export {DynamicValue} from './src/dynamic';
export {ForeignFunctionResolver, PartialEvaluator} from './src/interface';
export {BuiltinFn, EnumValue, ResolvedValue, ResolvedValueArray, ResolvedValueMap} from './src/result';
export {BuiltinFn, DynamicValue, EnumValue, ResolvedValue, ResolvedValueArray, ResolvedValueMap, isDynamicValue} from './src/result';

View File

@ -6,19 +6,16 @@
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {DynamicValue} from './dynamic';
import {BuiltinFn, ResolvedValue, ResolvedValueArray} from './result';
import {BuiltinFn, DYNAMIC_VALUE, ResolvedValue, ResolvedValueArray} from './result';
export class ArraySliceBuiltinFn extends BuiltinFn {
constructor(private node: ts.Node, private lhs: ResolvedValueArray) { super(); }
constructor(private lhs: ResolvedValueArray) { super(); }
evaluate(args: ResolvedValueArray): ResolvedValue {
if (args.length === 0) {
return this.lhs;
} else {
return DynamicValue.fromUnknown(this.node);
return DYNAMIC_VALUE;
}
}
}

View File

@ -1,110 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {Reference} from '../../imports';
/**
* The reason why a value cannot be determined statically.
*/
export const enum DynamicValueReason {
/**
* A value could not be determined statically, because it contains a term that could not be
* determined statically.
* (E.g. a property assignment or call expression where the lhs is a `DynamicValue`, a template
* literal with a dynamic expression, an object literal with a spread assignment which could not
* be determined statically, etc.)
*/
DYNAMIC_INPUT,
/**
* A string could not be statically evaluated.
* (E.g. a dynamically constructed object property name or a template literal expression that
* could not be statically resolved to a primitive value.)
*/
DYNAMIC_STRING,
/**
* An external reference could not be resolved to a value which can be evaluated.
* (E.g. a call expression for a function declared in `.d.ts`.)
*/
EXTERNAL_REFERENCE,
/**
* A type of `ts.Expression` that `StaticInterpreter` doesn't know how to evaluate.
*/
UNKNOWN_EXPRESSION_TYPE,
/**
* A declaration of a `ts.Identifier` could not be found.
*/
UNKNOWN_IDENTIFIER,
/**
* A value could not be determined statically for any reason other the above.
*/
UNKNOWN,
}
/**
* Represents a value which cannot be determined statically.
*/
export class DynamicValue<R = {}> {
private constructor(
readonly node: ts.Node, readonly reason: R, private code: DynamicValueReason) {}
static fromDynamicInput(node: ts.Node, input: DynamicValue): DynamicValue<DynamicValue> {
return new DynamicValue(node, input, DynamicValueReason.DYNAMIC_INPUT);
}
static fromDynamicString(node: ts.Node): DynamicValue {
return new DynamicValue(node, {}, DynamicValueReason.DYNAMIC_STRING);
}
static fromExternalReference(node: ts.Node, ref: Reference<ts.Declaration>):
DynamicValue<Reference<ts.Declaration>> {
return new DynamicValue(node, ref, DynamicValueReason.EXTERNAL_REFERENCE);
}
static fromUnknownExpressionType(node: ts.Node): DynamicValue {
return new DynamicValue(node, {}, DynamicValueReason.UNKNOWN_EXPRESSION_TYPE);
}
static fromUnknownIdentifier(node: ts.Identifier): DynamicValue {
return new DynamicValue(node, {}, DynamicValueReason.UNKNOWN_IDENTIFIER);
}
static fromUnknown(node: ts.Node): DynamicValue {
return new DynamicValue(node, {}, DynamicValueReason.UNKNOWN);
}
isFromDynamicInput(this: DynamicValue<R>): this is DynamicValue<DynamicValue> {
return this.code === DynamicValueReason.DYNAMIC_INPUT;
}
isFromDynamicString(this: DynamicValue<R>): this is DynamicValue {
return this.code === DynamicValueReason.DYNAMIC_STRING;
}
isFromExternalReference(this: DynamicValue<R>): this is DynamicValue<Reference<ts.Declaration>> {
return this.code === DynamicValueReason.EXTERNAL_REFERENCE;
}
isFromUnknownExpressionType(this: DynamicValue<R>): this is DynamicValue {
return this.code === DynamicValueReason.UNKNOWN_EXPRESSION_TYPE;
}
isFromUnknownIdentifier(this: DynamicValue<R>): this is DynamicValue {
return this.code === DynamicValueReason.UNKNOWN_IDENTIFIER;
}
isFromUnknown(this: DynamicValue<R>): this is DynamicValue {
return this.code === DynamicValueReason.UNKNOWN;
}
}

View File

@ -15,8 +15,8 @@ import {StaticInterpreter} from './interpreter';
import {ResolvedValue} from './result';
export type ForeignFunctionResolver =
(node: Reference<ts.FunctionDeclaration|ts.MethodDeclaration|ts.FunctionExpression>,
args: ReadonlyArray<ts.Expression>) => ts.Expression | null;
(node: Reference<ts.FunctionDeclaration|ts.MethodDeclaration>, args: ts.Expression[]) =>
ts.Expression | null;
export class PartialEvaluator {
constructor(

View File

@ -12,9 +12,7 @@ import {AbsoluteReference, NodeReference, Reference, ReferenceResolver, Resolved
import {Declaration, ReflectionHost} from '../../reflection';
import {ArraySliceBuiltinFn} from './builtin';
import {DynamicValue} from './dynamic';
import {ForeignFunctionResolver} from './interface';
import {BuiltinFn, EnumValue, ResolvedValue, ResolvedValueArray, ResolvedValueMap} from './result';
import {BuiltinFn, DYNAMIC_VALUE, EnumValue, ResolvedValue, ResolvedValueArray, ResolvedValueMap, isDynamicValue} from './result';
/**
@ -74,7 +72,9 @@ interface Context {
*/
resolutionContext: string;
scope: Scope;
foreignFunctionResolver?: ForeignFunctionResolver;
foreignFunctionResolver?
(ref: Reference<ts.FunctionDeclaration|ts.MethodDeclaration|ts.FunctionExpression>,
args: ReadonlyArray<ts.Expression>): ts.Expression|null;
}
export class StaticInterpreter {
@ -126,7 +126,7 @@ export class StaticInterpreter {
} else if (this.host.isClass(node)) {
return this.visitDeclaration(node, context);
} else {
return DynamicValue.fromUnknownExpressionType(node);
return DYNAMIC_VALUE;
}
}
@ -137,15 +137,21 @@ export class StaticInterpreter {
const element = node.elements[i];
if (ts.isSpreadElement(element)) {
const spread = this.visitExpression(element.expression, context);
if (spread instanceof DynamicValue) {
array.push(DynamicValue.fromDynamicInput(element.expression, spread));
} else if (!Array.isArray(spread)) {
throw new Error(`Unexpected value in spread expression: ${spread}`);
} else {
array.push(...spread);
if (isDynamicValue(spread)) {
return DYNAMIC_VALUE;
}
if (!Array.isArray(spread)) {
throw new Error(`Unexpected value in spread expression: ${spread}`);
}
array.push(...spread);
} else {
array.push(this.visitExpression(element, context));
const result = this.visitExpression(element, context);
if (isDynamicValue(result)) {
return DYNAMIC_VALUE;
}
array.push(result);
}
}
return array;
@ -158,28 +164,30 @@ export class StaticInterpreter {
const property = node.properties[i];
if (ts.isPropertyAssignment(property)) {
const name = this.stringNameFromPropertyName(property.name, context);
// Check whether the name can be determined statically.
if (name === undefined) {
return DynamicValue.fromDynamicInput(node, DynamicValue.fromDynamicString(property.name));
return DYNAMIC_VALUE;
}
map.set(name, this.visitExpression(property.initializer, context));
} else if (ts.isShorthandPropertyAssignment(property)) {
const symbol = this.checker.getShorthandAssignmentValueSymbol(property);
if (symbol === undefined || symbol.valueDeclaration === undefined) {
map.set(property.name.text, DynamicValue.fromUnknown(property));
} else {
map.set(property.name.text, this.visitDeclaration(symbol.valueDeclaration, context));
return DYNAMIC_VALUE;
}
map.set(property.name.text, this.visitDeclaration(symbol.valueDeclaration, context));
} else if (ts.isSpreadAssignment(property)) {
const spread = this.visitExpression(property.expression, context);
if (spread instanceof DynamicValue) {
return DynamicValue.fromDynamicInput(node, spread);
} else if (!(spread instanceof Map)) {
if (isDynamicValue(spread)) {
return DYNAMIC_VALUE;
}
if (!(spread instanceof Map)) {
throw new Error(`Unexpected value in spread assignment: ${spread}`);
}
spread.forEach((value, key) => map.set(key, value));
} else {
return DynamicValue.fromUnknown(node);
return DYNAMIC_VALUE;
}
}
return map;
@ -193,10 +201,8 @@ export class StaticInterpreter {
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ||
value == null) {
pieces.push(`${value}`);
} else if (value instanceof DynamicValue) {
return DynamicValue.fromDynamicInput(node, value);
} else {
return DynamicValue.fromDynamicInput(node, DynamicValue.fromDynamicString(span.expression));
return DYNAMIC_VALUE;
}
pieces.push(span.literal.text);
}
@ -206,7 +212,7 @@ export class StaticInterpreter {
private visitIdentifier(node: ts.Identifier, context: Context): ResolvedValue {
const decl = this.host.getDeclarationOfIdentifier(node);
if (decl === null) {
return DynamicValue.fromUnknownIdentifier(node);
return DYNAMIC_VALUE;
}
const result =
this.visitDeclaration(decl.node, {...context, ...joinModuleContext(context, node, decl)});
@ -264,19 +270,19 @@ export class StaticInterpreter {
if (node.argumentExpression === undefined) {
throw new Error(`Expected argument in ElementAccessExpression`);
}
if (lhs instanceof DynamicValue) {
return DynamicValue.fromDynamicInput(node, lhs);
if (isDynamicValue(lhs)) {
return DYNAMIC_VALUE;
}
const rhs = this.visitExpression(node.argumentExpression, context);
if (rhs instanceof DynamicValue) {
return DynamicValue.fromDynamicInput(node, rhs);
if (isDynamicValue(rhs)) {
return DYNAMIC_VALUE;
}
if (typeof rhs !== 'string' && typeof rhs !== 'number') {
throw new Error(
`ElementAccessExpression index should be string or number, got ${typeof rhs}: ${rhs}`);
}
return this.accessHelper(node, lhs, rhs, context);
return this.accessHelper(lhs, rhs, context);
}
private visitPropertyAccessExpression(node: ts.PropertyAccessExpression, context: Context):
@ -284,16 +290,17 @@ export class StaticInterpreter {
const lhs = this.visitExpression(node.expression, context);
const rhs = node.name.text;
// TODO: handle reference to class declaration.
if (lhs instanceof DynamicValue) {
return DynamicValue.fromDynamicInput(node, lhs);
if (isDynamicValue(lhs)) {
return DYNAMIC_VALUE;
}
return this.accessHelper(node, lhs, rhs, context);
return this.accessHelper(lhs, rhs, context);
}
private visitSourceFile(node: ts.SourceFile, context: Context): ResolvedValue {
const declarations = this.host.getExportsOfModule(node);
if (declarations === null) {
return DynamicValue.fromUnknown(node);
return DYNAMIC_VALUE;
}
const map = new Map<string, ResolvedValue>();
declarations.forEach((decl, name) => {
@ -306,9 +313,7 @@ export class StaticInterpreter {
return map;
}
private accessHelper(
node: ts.Expression, lhs: ResolvedValue, rhs: string|number,
context: Context): ResolvedValue {
private accessHelper(lhs: ResolvedValue, rhs: string|number, context: Context): ResolvedValue {
const strIndex = `${rhs}`;
if (lhs instanceof Map) {
if (lhs.has(strIndex)) {
@ -320,10 +325,10 @@ export class StaticInterpreter {
if (rhs === 'length') {
return lhs.length;
} else if (rhs === 'slice') {
return new ArraySliceBuiltinFn(node, lhs);
return new ArraySliceBuiltinFn(lhs);
}
if (typeof rhs !== 'number' || !Number.isInteger(rhs)) {
return DynamicValue.fromUnknown(node);
return DYNAMIC_VALUE;
}
if (rhs < 0 || rhs >= lhs.length) {
throw new Error(`Index out of bounds: ${rhs} vs ${lhs.length}`);
@ -350,17 +355,14 @@ export class StaticInterpreter {
}
return value;
}
} else if (lhs instanceof DynamicValue) {
return DynamicValue.fromDynamicInput(node, lhs);
} else {
throw new Error(`Invalid dot property access: ${lhs} dot ${rhs}`);
}
throw new Error(`Invalid dot property access: ${lhs} dot ${rhs}`);
}
private visitCallExpression(node: ts.CallExpression, context: Context): ResolvedValue {
const lhs = this.visitExpression(node.expression, context);
if (lhs instanceof DynamicValue) {
return DynamicValue.fromDynamicInput(node, lhs);
if (isDynamicValue(lhs)) {
return DYNAMIC_VALUE;
}
// If the call refers to a builtin function, attempt to evaluate the function.
@ -385,8 +387,8 @@ export class StaticInterpreter {
expr = context.foreignFunctionResolver(lhs, node.arguments);
}
if (expr === null) {
return DynamicValue.fromDynamicInput(
node, DynamicValue.fromExternalReference(node.expression, lhs));
throw new Error(
`could not resolve foreign function declaration: ${node.getSourceFile().fileName} ${(lhs.node.name as ts.Identifier).text}`);
}
// If the function is declared in a different file, resolve the foreign function expression
@ -430,8 +432,8 @@ export class StaticInterpreter {
private visitConditionalExpression(node: ts.ConditionalExpression, context: Context):
ResolvedValue {
const condition = this.visitExpression(node.condition, context);
if (condition instanceof DynamicValue) {
return DynamicValue.fromDynamicInput(node, condition);
if (isDynamicValue(condition)) {
return condition;
}
if (condition) {
@ -450,11 +452,7 @@ export class StaticInterpreter {
const op = UNARY_OPERATORS.get(operatorKind) !;
const value = this.visitExpression(node.operand, context);
if (value instanceof DynamicValue) {
return DynamicValue.fromDynamicInput(node, value);
} else {
return op(value);
}
return isDynamicValue(value) ? DYNAMIC_VALUE : op(value);
}
private visitBinaryExpression(node: ts.BinaryExpression, context: Context): ResolvedValue {
@ -472,13 +470,8 @@ export class StaticInterpreter {
lhs = this.visitExpression(node.left, context);
rhs = this.visitExpression(node.right, context);
}
if (lhs instanceof DynamicValue) {
return DynamicValue.fromDynamicInput(node, lhs);
} else if (rhs instanceof DynamicValue) {
return DynamicValue.fromDynamicInput(node, rhs);
} else {
return opRecord.op(lhs, rhs);
}
return isDynamicValue(lhs) || isDynamicValue(rhs) ? DYNAMIC_VALUE : opRecord.op(lhs, rhs);
}
private visitParenthesizedExpression(node: ts.ParenthesizedExpression, context: Context):
@ -507,10 +500,13 @@ function isFunctionOrMethodReference(ref: Reference<ts.Node>):
}
function literal(value: ResolvedValue): any {
if (value instanceof DynamicValue || value === null || value === undefined ||
typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
if (value === null || value === undefined || typeof value === 'string' ||
typeof value === 'number' || typeof value === 'boolean') {
return value;
}
if (isDynamicValue(value)) {
return DYNAMIC_VALUE;
}
throw new Error(`Value ${value} is not literal and cannot be used in this context.`);
}

View File

@ -10,8 +10,6 @@ import * as ts from 'typescript';
import {Reference} from '../../imports';
import {DynamicValue} from './dynamic';
/**
* A value resulting from static resolution.
@ -21,7 +19,34 @@ import {DynamicValue} from './dynamic';
* available statically.
*/
export type ResolvedValue = number | boolean | string | null | undefined | Reference | EnumValue |
ResolvedValueArray | ResolvedValueMap | BuiltinFn | DynamicValue<{}>;
ResolvedValueArray | ResolvedValueMap | BuiltinFn | DynamicValue;
/**
* Represents a value which cannot be determined statically.
*
* Use `isDynamicValue` to determine whether a `ResolvedValue` is a `DynamicValue`.
*/
export class DynamicValue {
/**
* This is needed so the "is DynamicValue" assertion of `isDynamicValue` actually has meaning.
*
* Otherwise, "is DynamicValue" is akin to "is {}" which doesn't trigger narrowing.
*/
private _isDynamic = true;
}
/**
* An internal flyweight for `DynamicValue`. Eventually the dynamic value will carry information
* on the location of the node that could not be statically computed.
*/
export const DYNAMIC_VALUE: DynamicValue = new DynamicValue();
/**
* Used to test whether a `ResolvedValue` is a `DynamicValue`.
*/
export function isDynamicValue(value: any): value is DynamicValue {
return value === DYNAMIC_VALUE;
}
/**
* An array of `ResolvedValue`s.

View File

@ -16,16 +16,14 @@ import {ComponentDecoratorHandler, DirectiveDecoratorHandler, InjectableDecorato
import {BaseDefDecoratorHandler} from './annotations/src/base_def';
import {ErrorCode, ngErrorCode} from './diagnostics';
import {FlatIndexGenerator, ReferenceGraph, checkForPrivateExports, findFlatIndexEntryPoint} from './entry_point';
import {ImportRewriter, ModuleResolver, NoopImportRewriter, R3SymbolsImportRewriter, Reference, TsReferenceResolver} from './imports';
import {ImportRewriter, NoopImportRewriter, R3SymbolsImportRewriter, Reference, TsReferenceResolver} from './imports';
import {PartialEvaluator} from './partial_evaluator';
import {TypeScriptReflectionHost} from './reflection';
import {HostResourceLoader} from './resource_loader';
import {NgModuleRouteAnalyzer} from './routing';
import {FactoryGenerator, FactoryInfo, GeneratedShimsHostWrapper, ShimGenerator, SummaryGenerator, generatedFactoryTransform} from './shims';
import {ivySwitchTransform} from './switch';
import {IvyCompilation, ivyTransformFactory} from './transform';
import {TypeCheckContext, TypeCheckProgramHost} from './typecheck';
import {normalizeSeparators} from './util/src/path';
import {isDtsPath} from './util/src/typescript';
export class NgtscProgram implements api.Program {
@ -44,10 +42,8 @@ export class NgtscProgram implements api.Program {
private entryPoint: ts.SourceFile|null;
private exportReferenceGraph: ReferenceGraph|null = null;
private flatIndexGenerator: FlatIndexGenerator|null = null;
private routeAnalyzer: NgModuleRouteAnalyzer|null = null;
private constructionDiagnostics: ts.Diagnostic[] = [];
private moduleResolver: ModuleResolver;
constructor(
@ -111,9 +107,8 @@ export class NgtscProgram implements api.Program {
});
} else {
const flatModuleId = options.flatModuleId || null;
const flatModuleOutFile = normalizeSeparators(options.flatModuleOutFile);
this.flatIndexGenerator =
new FlatIndexGenerator(entryPoint, flatModuleOutFile, flatModuleId);
new FlatIndexGenerator(entryPoint, options.flatModuleOutFile, flatModuleId);
generators.push(this.flatIndexGenerator);
rootFiles.push(this.flatIndexGenerator.flatIndexPath);
}
@ -127,7 +122,6 @@ export class NgtscProgram implements api.Program {
ts.createProgram(rootFiles, options, this.host, oldProgram && oldProgram.getTsProgram());
this.entryPoint = entryPoint !== null ? this.tsProgram.getSourceFile(entryPoint) || null : null;
this.moduleResolver = new ModuleResolver(this.tsProgram, options, this.host);
}
getTsProgram(): ts.Program { return this.tsProgram; }
@ -186,14 +180,7 @@ export class NgtscProgram implements api.Program {
.filter((result): result is Promise<void> => result !== undefined));
}
listLazyRoutes(entryRoute?: string|undefined): api.LazyRoute[] {
if (entryRoute !== undefined) {
throw new Error(
`Listing specific routes is unsupported for now (got query for ${entryRoute})`);
}
this.ensureAnalyzed();
return this.routeAnalyzer !.listLazyRoutes();
}
listLazyRoutes(entryRoute?: string|undefined): api.LazyRoute[] { return []; }
getLibrarySummaries(): Map<string, api.LibrarySummary> {
throw new Error('Method not implemented.');
@ -299,8 +286,6 @@ export class NgtscProgram implements api.Program {
referencesRegistry = new NoopReferencesRegistry();
}
this.routeAnalyzer = new NgModuleRouteAnalyzer(this.moduleResolver, evaluator);
// Set up the IvyCompilation, which manages state for the Ivy transformer.
const handlers = [
new BaseDefDecoratorHandler(this.reflector, evaluator),
@ -311,8 +296,7 @@ export class NgtscProgram implements api.Program {
new DirectiveDecoratorHandler(this.reflector, evaluator, scopeRegistry, this.isCore),
new InjectableDecoratorHandler(this.reflector, this.isCore),
new NgModuleDecoratorHandler(
this.reflector, evaluator, scopeRegistry, referencesRegistry, this.isCore,
this.routeAnalyzer),
this.reflector, evaluator, scopeRegistry, referencesRegistry, this.isCore),
new PipeDecoratorHandler(this.reflector, evaluator, scopeRegistry, this.isCore),
];

View File

@ -1,19 +0,0 @@
package(default_visibility = ["//visibility:public"])
load("//tools:defaults.bzl", "ts_library")
ts_library(
name = "routing",
srcs = glob([
"index.ts",
"src/**/*.ts",
]),
module_name = "@angular/compiler-cli/src/ngtsc/routing",
deps = [
"//packages/compiler",
"//packages/compiler-cli/src/ngtsc/imports",
"//packages/compiler-cli/src/ngtsc/partial_evaluator",
"@ngdeps//@types/node",
"@ngdeps//typescript",
],
)

View File

@ -1,11 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/// <reference types="node" />
export {LazyRoute, NgModuleRouteAnalyzer} from './src/analyzer';

View File

@ -1,65 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {ModuleResolver} from '../../imports';
import {PartialEvaluator} from '../../partial_evaluator';
import {scanForRouteEntryPoints} from './lazy';
import {RouterEntryPointManager} from './route';
export interface NgModuleRawRouteData {
sourceFile: ts.SourceFile;
moduleName: string;
imports: ts.Expression|null;
exports: ts.Expression|null;
providers: ts.Expression|null;
}
export interface LazyRoute {
route: string;
module: {name: string, filePath: string};
referencedModule: {name: string, filePath: string};
}
export class NgModuleRouteAnalyzer {
private modules = new Map<string, NgModuleRawRouteData>();
private entryPointManager: RouterEntryPointManager;
constructor(moduleResolver: ModuleResolver, private evaluator: PartialEvaluator) {
this.entryPointManager = new RouterEntryPointManager(moduleResolver);
}
add(sourceFile: ts.SourceFile, moduleName: string, imports: ts.Expression|null,
exports: ts.Expression|null, providers: ts.Expression|null): void {
const key = `${sourceFile.fileName}#${moduleName}`;
if (this.modules.has(key)) {
throw new Error(`Double route analyzing ${key}`);
}
this.modules.set(
key, {
sourceFile, moduleName, imports, exports, providers,
});
}
listLazyRoutes(): LazyRoute[] {
const routes: LazyRoute[] = [];
for (const key of Array.from(this.modules.keys())) {
const data = this.modules.get(key) !;
const entryPoints = scanForRouteEntryPoints(
data.sourceFile, data.moduleName, data, this.entryPointManager, this.evaluator);
routes.push(...entryPoints.map(entryPoint => ({
route: entryPoint.loadChildren,
module: entryPoint.from,
referencedModule: entryPoint.resolvedTo,
})));
}
return routes;
}
}

View File

@ -1,164 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {AbsoluteReference, NodeReference, Reference} from '../../imports';
import {ForeignFunctionResolver, PartialEvaluator, ResolvedValue} from '../../partial_evaluator';
import {NgModuleRawRouteData} from './analyzer';
import {RouterEntryPoint, RouterEntryPointManager} from './route';
const ROUTES_MARKER = '__ngRoutesMarker__';
export interface LazyRouteEntry {
loadChildren: string;
from: RouterEntryPoint;
resolvedTo: RouterEntryPoint;
}
export function scanForRouteEntryPoints(
ngModule: ts.SourceFile, moduleName: string, data: NgModuleRawRouteData,
entryPointManager: RouterEntryPointManager, evaluator: PartialEvaluator): LazyRouteEntry[] {
const loadChildrenIdentifiers: string[] = [];
const from = entryPointManager.fromNgModule(ngModule, moduleName);
if (data.providers !== null) {
loadChildrenIdentifiers.push(...scanForProviders(data.providers, evaluator));
}
if (data.imports !== null) {
loadChildrenIdentifiers.push(...scanForRouterModuleUsage(data.imports, evaluator));
}
if (data.exports !== null) {
loadChildrenIdentifiers.push(...scanForRouterModuleUsage(data.exports, evaluator));
}
const routes: LazyRouteEntry[] = [];
for (const loadChildren of loadChildrenIdentifiers) {
const resolvedTo = entryPointManager.resolveLoadChildrenIdentifier(loadChildren, ngModule);
if (resolvedTo !== null) {
routes.push({
loadChildren, from, resolvedTo,
});
}
}
return routes;
}
function scanForProviders(expr: ts.Expression, evaluator: PartialEvaluator): string[] {
const loadChildrenIdentifiers: string[] = [];
const providers = evaluator.evaluate(expr);
function recursivelyAddProviders(provider: ResolvedValue): void {
if (Array.isArray(provider)) {
for (const entry of provider) {
recursivelyAddProviders(entry);
}
} else if (provider instanceof Map) {
if (provider.has('provide') && provider.has('useValue')) {
const provide = provider.get('provide');
const useValue = provider.get('useValue');
if (isRouteToken(provide) && Array.isArray(useValue)) {
loadChildrenIdentifiers.push(...scanForLazyRoutes(useValue));
}
}
}
}
recursivelyAddProviders(providers);
return loadChildrenIdentifiers;
}
function scanForRouterModuleUsage(expr: ts.Expression, evaluator: PartialEvaluator): string[] {
const loadChildrenIdentifiers: string[] = [];
const imports = evaluator.evaluate(expr, routerModuleFFR);
function recursivelyAddRoutes(imp: ResolvedValue) {
if (Array.isArray(imp)) {
for (const entry of imp) {
recursivelyAddRoutes(entry);
}
} else if (imp instanceof Map) {
if (imp.has(ROUTES_MARKER) && imp.has('routes')) {
const routes = imp.get('routes');
if (Array.isArray(routes)) {
loadChildrenIdentifiers.push(...scanForLazyRoutes(routes));
}
}
}
}
recursivelyAddRoutes(imports);
return loadChildrenIdentifiers;
}
function scanForLazyRoutes(routes: ResolvedValue[]): string[] {
const loadChildrenIdentifiers: string[] = [];
function recursivelyScanRoutes(routes: ResolvedValue[]): void {
for (let route of routes) {
if (!(route instanceof Map)) {
continue;
}
if (route.has('loadChildren')) {
const loadChildren = route.get('loadChildren');
if (typeof loadChildren === 'string') {
loadChildrenIdentifiers.push(loadChildren);
}
} else if (route.has('children')) {
const children = route.get('children');
if (Array.isArray(children)) {
recursivelyScanRoutes(routes);
}
}
}
}
recursivelyScanRoutes(routes);
return loadChildrenIdentifiers;
}
/**
* A foreign function resolver that converts `RouterModule.forRoot/forChild(X)` to a special object
* of the form `{__ngRoutesMarker__: true, routes: X}`.
*
* These objects are then recognizable inside the larger set of imports/exports.
*/
const routerModuleFFR: ForeignFunctionResolver =
function routerModuleFFR(
ref: Reference<ts.FunctionDeclaration|ts.MethodDeclaration|ts.FunctionExpression>,
args: ReadonlyArray<ts.Expression>): ts.Expression |
null {
if (!isMethodNodeReference(ref) || !ts.isClassDeclaration(ref.node.parent)) {
return null;
} else if (ref.moduleName !== '@angular/router') {
return null;
} else if (
ref.node.parent.name === undefined || ref.node.parent.name.text !== 'RouterModule') {
return null;
} else if (
!ts.isIdentifier(ref.node.name) ||
(ref.node.name.text !== 'forRoot' && ref.node.name.text !== 'forChild')) {
return null;
}
const routes = args[0];
return ts.createObjectLiteral([
ts.createPropertyAssignment(ROUTES_MARKER, ts.createTrue()),
ts.createPropertyAssignment('routes', routes),
]);
};
function isMethodNodeReference(
ref: Reference<ts.FunctionDeclaration|ts.MethodDeclaration|ts.FunctionExpression>):
ref is NodeReference<ts.MethodDeclaration> {
return ref instanceof NodeReference && ts.isMethodDeclaration(ref.node);
}
function isRouteToken(ref: ResolvedValue): boolean {
return ref instanceof AbsoluteReference && ref.moduleName === '@angular/router' &&
ref.symbolName === 'ROUTES';
}

View File

@ -1,58 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {ModuleResolver} from '../../imports';
export abstract class RouterEntryPoint {
abstract readonly filePath: string;
abstract readonly moduleName: string;
// Alias of moduleName.
abstract readonly name: string;
abstract toString(): string;
}
class RouterEntryPointImpl implements RouterEntryPoint {
constructor(readonly filePath: string, readonly moduleName: string) {}
get name(): string { return this.moduleName; }
toString(): string { return `${this.filePath}#${this.moduleName}`; }
}
export class RouterEntryPointManager {
private map = new Map<string, RouterEntryPoint>();
constructor(private moduleResolver: ModuleResolver) {}
resolveLoadChildrenIdentifier(loadChildrenIdentifier: string, context: ts.SourceFile):
RouterEntryPoint|null {
const [relativeFile, moduleName] = loadChildrenIdentifier.split('#');
if (moduleName === undefined) {
return null;
}
const resolvedSf = this.moduleResolver.resolveModuleName(relativeFile, context);
if (resolvedSf === null) {
return null;
}
return this.fromNgModule(resolvedSf, moduleName);
}
fromNgModule(sf: ts.SourceFile, moduleName: string): RouterEntryPoint {
const absoluteFile = sf.fileName;
const key = `${absoluteFile}#${moduleName}`;
if (!this.map.has(key)) {
this.map.set(key, new RouterEntryPointImpl(absoluteFile, moduleName));
}
return this.map.get(key) !;
}
}

View File

@ -0,0 +1,96 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {PluginCompilerHost} from '@bazel/typescript/tsc_wrapped/plugin_api';
import * as ts from 'typescript';
/**
* Extension of the TypeScript compiler host that supports files added to the Program which
* were never on disk.
*
* This is used for backwards-compatibility with the ViewEngine compiler, which used ngsummary
* and ngfactory files as inputs to the program. We call these inputs "synthetic".
*
* They need to be program inputs because user code may import from these generated files.
*
* TODO(alxhub): remove this after all ng_module users have migrated to Ivy
*/
export class SyntheticFilesCompilerHost implements PluginCompilerHost {
/**
* SourceFiles which are added to the program but which never existed on disk.
*/
syntheticFiles = new Map<string, ts.SourceFile>();
constructor(
private rootFiles: string[], private delegate: ts.CompilerHost,
generatedFiles: (rootFiles: string[]) => {
[fileName: string]: (host: ts.CompilerHost) => ts.SourceFile | undefined
}, ) {
// Allow ngtsc to contribute in-memory synthetic files, which will be loaded
// as if they existed on disk as action inputs.
const angularGeneratedFiles = generatedFiles !(rootFiles);
for (const f of Object.keys(angularGeneratedFiles)) {
const generator = angularGeneratedFiles[f];
const generated = generator(delegate);
if (generated) {
this.syntheticFiles.set(generated.fileName, generated);
}
}
}
fileExists(filePath: string): boolean {
if (this.syntheticFiles.has(filePath)) {
return true;
}
return this.delegate.fileExists(filePath);
}
/** Loads a source file from in-memory map, or delegates. */
getSourceFile(
fileName: string, languageVersion: ts.ScriptTarget,
onError?: (message: string) => void): ts.SourceFile|undefined {
const syntheticFile = this.syntheticFiles.get(fileName);
if (syntheticFile) {
return syntheticFile !;
}
return this.delegate.getSourceFile(fileName, languageVersion, onError);
}
get inputFiles() { return [...this.rootFiles, ...Array.from(this.syntheticFiles.keys())]; }
fileNameToModuleId(fileName: string) {
return fileName; // TODO: Ivy logic. don't forget that the delegate has the google3 logic
}
// Delegate everything else to the original compiler host.
getDefaultLibFileName(options: ts.CompilerOptions): string {
return this.delegate.getDefaultLibFileName(options);
}
writeFile(
fileName: string, content: string, writeByteOrderMark: boolean,
onError: ((message: string) => void)|undefined,
sourceFiles: ReadonlyArray<ts.SourceFile>|undefined): void {
this.delegate.writeFile(fileName, content, writeByteOrderMark, onError, sourceFiles);
}
getCanonicalFileName(path: string) { return this.delegate.getCanonicalFileName(path); }
getCurrentDirectory(): string { return this.delegate.getCurrentDirectory(); }
useCaseSensitiveFileNames(): boolean { return this.delegate.useCaseSensitiveFileNames(); }
getNewLine(): string { return this.delegate.getNewLine(); }
getDirectories(path: string) { return this.delegate.getDirectories(path); }
readFile(fileName: string): string|undefined { return this.delegate.readFile(fileName); }
trace(s: string): void { console.error(s); }
}

View File

@ -0,0 +1,69 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {PluginCompilerHost, TscPlugin, createProxy} from '@bazel/typescript/tsc_wrapped/plugin_api';
import * as ts from 'typescript';
import {SyntheticFilesCompilerHost} from './synthetic_files_compiler_host';
export class NgTscPlugin implements TscPlugin {
constructor(private angularCompilerOptions: unknown) {}
wrap(program: ts.Program, config: {}, host: ts.CompilerHost) {
const proxy = createProxy(program);
proxy.getSemanticDiagnostics = (sourceFile: ts.SourceFile) => {
const result: ts.Diagnostic[] = [...program.getSemanticDiagnostics(sourceFile)];
// For demo purposes, trigger a diagnostic when the sourcefile has a magic string
if (sourceFile.text.indexOf('diag') >= 0) {
const fake: ts.Diagnostic = {
file: sourceFile,
start: 0,
length: 3,
messageText: 'Example Angular Compiler Diagnostic',
category: ts.DiagnosticCategory.Error,
code: 12345,
// source is the name of the plugin.
source: 'Angular',
};
result.push(fake);
}
return result;
};
return proxy;
}
createTransformers(host: PluginCompilerHost) {
const afterDeclarations: Array<ts.TransformerFactory<ts.SourceFile|ts.Bundle>> =
[(context: ts.TransformationContext) => (sf: ts.SourceFile | ts.Bundle) => {
const visitor = (node: ts.Node): ts.Node => {
if (node.kind === ts.SyntaxKind.ClassDeclaration) {
const clz = node as ts.ClassDeclaration;
// For demo purposes, transform the class name in the .d.ts output
return ts.updateClassDeclaration(
clz, clz.decorators, node.modifiers, ts.createIdentifier('NEWNAME'),
clz.typeParameters, clz.heritageClauses, clz.members);
}
return ts.visitEachChild(node, visitor, context);
};
return visitor(sf) as ts.SourceFile;
}];
return {afterDeclarations};
}
wrapHost(inputFiles: string[], compilerHost: ts.CompilerHost) {
return new SyntheticFilesCompilerHost(inputFiles, compilerHost, this.generatedFiles);
}
generatedFiles(rootFiles: string[]) {
return {
'file-1.ts': (host: ts.CompilerHost) =>
ts.createSourceFile('file-1.ts', 'contents', ts.ScriptTarget.ES5),
};
}
}

View File

@ -2543,7 +2543,7 @@ describe('compiler compliance', () => {
@Directive({selector: '[some-directive]', exportAs: 'someDir, otherDir'})
export class SomeDirective {}
@NgModule({declarations: [SomeDirective]})
@NgModule({declarations: [SomeDirective, MyComponent]})
export class MyModule{}
`
}

View File

@ -7,7 +7,6 @@ ts_library(
deps = [
"//packages/compiler",
"//packages/compiler-cli",
"//packages/compiler-cli/src/ngtsc/routing",
"//packages/compiler-cli/test:test_utils",
"@ngdeps//typescript",
],

View File

@ -11,9 +11,7 @@ import * as fs from 'fs';
import * as path from 'path';
import * as ts from 'typescript';
import {createCompilerHost, createProgram} from '../../ngtools2';
import {main, mainDiagnosticsForTest, readNgcCommandLineAndConfiguration} from '../../src/main';
import {LazyRoute} from '../../src/ngtsc/routing';
import {main, mainDiagnosticsForTest} from '../../src/main';
import {TestSupport, isInBazel, setup} from '../test_support';
function setupFakeCore(support: TestSupport): void {
@ -129,12 +127,5 @@ export class NgtscTestEnvironment {
return mainDiagnosticsForTest(['-p', this.basePath]) as ReadonlyArray<ts.Diagnostic>;
}
driveRoutes(entryPoint?: string): LazyRoute[] {
const {rootNames, options} = readNgcCommandLineAndConfiguration(['-p', this.basePath]);
const host = createCompilerHost({options});
const program = createProgram({rootNames, host, options});
return program.listLazyRoutes(entryPoint);
}
static get supported(): boolean { return isInBazel(); }
}

View File

@ -1610,17 +1610,6 @@ describe('ngtsc behavioral tests', () => {
expect(dtsContents).toContain('/// <amd-module name="@mymodule" />');
});
it('should generate a proper flat module index file when nested', () => {
env.tsconfig({
'flatModuleOutFile': './public-api/index.js',
});
env.write('test.ts', `export const SOME_EXPORT = 'some-export'`);
env.driveMain();
expect(env.getContents('./public-api/index.js')).toContain(`export * from '../test';`);
});
it('should report an error when a flat module index is requested but no entrypoint can be determined',
() => {
env.tsconfig({'flatModuleOutFile': 'flat.js'});
@ -1949,45 +1938,6 @@ describe('ngtsc behavioral tests', () => {
expect(trim(jsContents)).toContain(trim(hostBindingsFn));
});
});
it('should detect all lazy routes', () => {
env.tsconfig();
env.write('test.ts', `
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
@NgModule({
imports: [
RouterModule.forChild([
{path: '', loadChildren: './lazy#LazyModule'},
]),
],
})
export class TestModule {}
`);
env.write('lazy.ts', `
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
@NgModule({})
export class LazyModule {}
`);
env.write('node_modules/@angular/router/index.d.ts', `
import {ModuleWithProviders} from '@angular/core';
export declare var ROUTES;
export declare class RouterModule {
static forRoot(arg1: any, arg2: any): ModuleWithProviders<RouterModule>;
static forChild(arg1: any): ModuleWithProviders<RouterModule>;
}
`);
const routes = env.driveRoutes();
expect(routes.length).toBe(1);
expect(routes[0].route).toEqual('./lazy#LazyModule');
expect(routes[0].module.filePath.endsWith('/test.ts')).toBe(true);
expect(routes[0].referencedModule.filePath.endsWith('/lazy.ts')).toBe(true);
});
});
function expectTokenAtPosition<T extends ts.Node>(

View File

@ -117,10 +117,8 @@ export interface IterableChangeRecord<V> {
export interface CollectionChangeRecord<V> extends IterableChangeRecord<V> {}
/**
* An optional function passed into the `NgForOf` directive that defines how to track
* changes for items in an iterable.
* The function takes the iteration index and item ID.
* When supplied, Angular tracks changes by the return value of the function.
* An optional function passed into {@link NgForOf} that defines how to track
* items in an iterable (e.g. fby index or id)
*
* @publicApi
*/

View File

@ -74,7 +74,6 @@ export {
pureFunction8 as ɵpureFunction8,
pureFunctionV as ɵpureFunctionV,
getCurrentView as ɵgetCurrentView,
getDirectives as ɵgetDirectives,
getHostElement as ɵgetHostElement,
restoreView as ɵrestoreView,
containerRefreshStart as ɵcontainerRefreshStart,

View File

@ -47,11 +47,9 @@ export abstract class TemplateRef<C> {
abstract get elementRef(): ElementRef;
/**
* Instantiates an embedded view based on this template,
* and attaches it to the view container.
* @param context The data-binding context of the embedded view, as declared
* in the `<ng-template>` usage.
* @returns The new embedded view object.
* Creates a view object and attaches it to the view container of the parent view.
* @param context The context for the new view, inherited from the anchor element.
* @returns The new view object.
*/
abstract createEmbeddedView(context: C): EmbeddedViewRef<C>;

View File

@ -516,12 +516,12 @@ export interface Component extends Directive {
/**
* An encapsulation policy for the template and CSS styles. One of:
* - `ViewEncapsulation.Native`: Deprecated. Use `ViewEncapsulation.ShadowDom` instead.
* - `ViewEncapsulation.Native`: Use shadow roots. This works
* only if natively available on the platform.
* - `ViewEncapsulation.Emulated`: Use shimmed CSS that
* emulates the native behavior.
* - `ViewEncapsulation.None`: Use global CSS without any
* encapsulation.
* - `ViewEncapsulation.ShadowDom`: Use Shadow DOM v1 to encapsulate styles.
*
* If not supplied, the value is taken from `CompilerOptions`. The default compiler option is
* `ViewEncapsulation.Emulated`.

View File

@ -7,7 +7,7 @@
*/
import {LifecycleHooksFeature, renderComponent, whenRendered} from './component';
import {defineBase, defineComponent, defineDirective, defineNgModule, definePipe} from './definition';
import {getComponent, getDirectives, getHostElement, getRenderedText} from './discovery_utils';
import {getComponent, getHostElement, getRenderedText} from './discovery_utils';
import {InheritDefinitionFeature} from './features/inherit_definition_feature';
import {ProvidersFeature} from './features/providers_feature';
import {BaseDef, ComponentDef, ComponentDefWithMeta, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveDefWithMeta, DirectiveType, PipeDef, PipeDefWithMeta} from './interfaces/definition';
@ -170,7 +170,6 @@ export {
definePipe,
getHostElement,
getComponent,
getDirectives,
getRenderedText,
renderComponent,
whenRendered,

View File

@ -951,12 +951,12 @@ export function setStyle(
ngDevMode && ngDevMode.rendererSetStyle++;
isProceduralRenderer(renderer) ?
renderer.setStyle(native, prop, value, RendererStyleFlags3.DashCase) :
native.style[prop] = value;
native['style'].setProperty(prop, value);
} else {
ngDevMode && ngDevMode.rendererRemoveStyle++;
isProceduralRenderer(renderer) ?
renderer.removeStyle(native, prop, RendererStyleFlags3.DashCase) :
native.style[prop] = '';
native['style'].removeProperty(prop);
}
}

View File

@ -9,7 +9,7 @@ import '../../util/ng_dev_mode';
import {StyleSanitizeFn} from '../../sanitization/style_sanitizer';
import {getLContext} from '../context_discovery';
import {LCONTAINER_LENGTH, LContainer} from '../interfaces/container';
import {LContainer} from '../interfaces/container';
import {LContext} from '../interfaces/context';
import {AttributeMarker, TAttributes, TNode, TNodeFlags} from '../interfaces/node';
import {PlayState, Player, PlayerContext, PlayerIndex} from '../interfaces/player';
@ -96,7 +96,7 @@ export function getStylingContext(index: number, viewData: LView): StylingContex
export function isStylingContext(value: any): value is StylingContext {
// Not an LView or an LContainer
return Array.isArray(value) && typeof value[StylingIndex.MasterFlagPosition] === 'number' &&
value.length !== LCONTAINER_LENGTH;
Array.isArray(value[StylingIndex.InitialStyleValuesPosition]);
}
export function isAnimationProp(name: string): boolean {

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ElementRef, QueryList, ViewContainerRef} from '@angular/core';
import {ElementRef, QueryList} from '@angular/core';
import {AttributeMarker, defineComponent, template, defineDirective, InheritDefinitionFeature, ProvidersFeature} from '../../src/render3/index';
import {allocHostVars, bind, directiveInject, element, elementAttribute, elementEnd, elementProperty, elementStyleProp, elementStyling, elementStylingApply, elementStart, listener, load, text, textBinding, loadQueryList, registerContentQuery, elementHostAttrs} from '../../src/render3/instructions';
@ -1131,58 +1131,6 @@ describe('host bindings', () => {
expect(hostBindingEl.style.width).toEqual('5px');
});
it('should bind to host styles on containers', () => {
let hostBindingDir !: HostBindingToStyles;
/**
* host: {
* '[style.width.px]': 'width'
* }
*/
class HostBindingToStyles {
width = 2;
static ngDirectiveDef = defineDirective({
type: HostBindingToStyles,
selectors: [['', 'hostStyles', '']],
factory: () => hostBindingDir = new HostBindingToStyles(),
hostBindings: (rf: RenderFlags, ctx: HostBindingToStyles, elIndex: number) => {
if (rf & RenderFlags.Create) {
elementStyling(null, ['width'], null, ctx);
}
if (rf & RenderFlags.Update) {
elementStyleProp(0, 0, ctx.width, 'px', ctx);
elementStylingApply(0, ctx);
}
}
});
}
class ContainerDir {
constructor(public vcr: ViewContainerRef) {}
static ngDirectiveDef = defineDirective({
type: ContainerDir,
selectors: [['', 'containerDir', '']],
factory: () => new ContainerDir(directiveInject(ViewContainerRef as any)),
});
}
/** <div hostStyles containerDir></div> */
const App = createComponent('app', (rf: RenderFlags, ctx: any) => {
if (rf & RenderFlags.Create) {
element(0, 'div', ['containerDir', '', 'hostStyles', '']);
}
}, 1, 0, [ContainerDir, HostBindingToStyles]);
const fixture = new ComponentFixture(App);
const hostBindingEl = fixture.hostElement.querySelector('div') as HTMLElement;
expect(hostBindingEl.style.width).toEqual('2px');
hostBindingDir.width = 5;
fixture.update();
expect(hostBindingEl.style.width).toEqual('5px');
});
it('should apply static host classes', () => {
/**
* host: {

View File

@ -380,41 +380,6 @@ describe('style and class based bindings', () => {
.toEqual(
'<svg style="height: 100px; width: 100px;"><circle fill="yellow" stroke="green"></circle></svg>');
});
it('should support binding to camelCased style properties', () => {
// <div [style.borderWidth]="borderWidth"></div>
class Comp {
borderWidth: string = '3px';
static ngComponentDef = defineComponent({
type: Comp,
selectors: [['comp']],
factory: () => new Comp(),
consts: 1,
vars: 0,
template: (rf: RenderFlags, ctx: Comp) => {
if (rf & RenderFlags.Create) {
elementStart(0, 'div');
elementStyling(null, ['borderWidth']);
elementEnd();
}
if (rf & RenderFlags.Update) {
elementStyleProp(0, 0, ctx.borderWidth);
elementStylingApply(0);
}
}
});
}
const fixture = new ComponentFixture(Comp);
fixture.update();
const target = fixture.hostElement.querySelector('div') !as any;
expect(target.style.borderWidth).toEqual('3px');
expect(fixture.html).toEqual('<div style="border-width: 3px;"></div>');
});
});
describe('dynamic styling properties within a styling context', () => {

View File

@ -43,6 +43,8 @@ export class ServerRendererFactory2 implements RendererFactory2 {
(<EmulatedEncapsulationServerRenderer2>renderer).applyToHost(element);
return renderer;
}
case ViewEncapsulation.Native:
throw new Error('Native encapsulation is not supported on the server!');
default: {
if (!this.rendererByCompId.has(type.id)) {
const styles = flattenStyles(type.id, type.styles, []);

View File

@ -291,7 +291,6 @@ function defaultRouterHook(snapshot: RouterStateSnapshot, runExtras: {
export class Router {
private currentUrlTree: UrlTree;
private rawUrlTree: UrlTree;
private browserUrlTree: UrlTree;
private readonly transitions: BehaviorSubject<NavigationTransition>;
private navigations: Observable<NavigationTransition>;
private lastSuccessfulNavigation: Navigation|null = null;
@ -401,7 +400,6 @@ export class Router {
this.resetConfig(config);
this.currentUrlTree = createEmptyUrlTree();
this.rawUrlTree = this.currentUrlTree;
this.browserUrlTree = this.parseUrl(this.location.path());
this.configLoader = new RouterConfigLoader(loader, compiler, onLoadStart, onLoadEnd);
this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
@ -463,7 +461,7 @@ export class Router {
return of (t).pipe(
switchMap(t => {
const urlTransition =
!this.navigated || t.extractedUrl.toString() !== this.browserUrlTree.toString();
!this.navigated || t.extractedUrl.toString() !== this.currentUrlTree.toString();
const processCurrentUrl =
(this.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
@ -504,14 +502,8 @@ export class Router {
this.paramsInheritanceStrategy, this.relativeLinkResolution),
// Update URL if in `eager` update mode
tap(t => {
if (this.urlUpdateStrategy === 'eager') {
if (!t.extras.skipLocationChange) {
this.setBrowserUrl(t.urlAfterRedirects, !!t.extras.replaceUrl, t.id);
}
this.browserUrlTree = t.urlAfterRedirects;
}
}),
tap(t => this.urlUpdateStrategy === 'eager' && !t.extras.skipLocationChange &&
this.setBrowserUrl(t.urlAfterRedirects, !!t.extras.replaceUrl, t.id)),
// Fire RoutesRecognized
tap(t => {
@ -671,12 +663,8 @@ export class Router {
(this as{routerState: RouterState}).routerState = t.targetRouterState !;
if (this.urlUpdateStrategy === 'deferred') {
if (!t.extras.skipLocationChange) {
this.setBrowserUrl(
this.rawUrlTree, !!t.extras.replaceUrl, t.id, t.extras.state);
}
this.browserUrlTree = t.urlAfterRedirects;
if (this.urlUpdateStrategy === 'deferred' && !t.extras.skipLocationChange) {
this.setBrowserUrl(this.rawUrlTree, !!t.extras.replaceUrl, t.id, t.extras.state);
}
}),

View File

@ -12,7 +12,7 @@ import {ChangeDetectionStrategy, Component, Injectable, NgModule, NgModuleFactor
import {ComponentFixture, TestBed, fakeAsync, inject, tick} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {ActivatedRoute, ActivatedRouteSnapshot, ActivationEnd, ActivationStart, CanActivate, CanDeactivate, ChildActivationEnd, ChildActivationStart, DefaultUrlSerializer, DetachedRouteHandle, Event, GuardsCheckEnd, GuardsCheckStart, Navigation, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, PRIMARY_OUTLET, ParamMap, Params, PreloadAllModules, PreloadingStrategy, Resolve, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, Router, RouterEvent, RouterModule, RouterPreloader, RouterStateSnapshot, RoutesRecognized, RunGuardsAndResolvers, UrlHandlingStrategy, UrlSegmentGroup, UrlSerializer, UrlTree} from '@angular/router';
import {ActivatedRoute, ActivatedRouteSnapshot, ActivationEnd, ActivationStart, CanActivate, CanDeactivate, ChildActivationEnd, ChildActivationStart, DetachedRouteHandle, Event, GuardsCheckEnd, GuardsCheckStart, Navigation, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, PRIMARY_OUTLET, ParamMap, Params, PreloadAllModules, PreloadingStrategy, Resolve, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, Router, RouterEvent, RouterModule, RouterPreloader, RouterStateSnapshot, RoutesRecognized, RunGuardsAndResolvers, UrlHandlingStrategy, UrlSegmentGroup, UrlSerializer, UrlTree} from '@angular/router';
import {Observable, Observer, Subscription, of } from 'rxjs';
import {filter, first, map, tap} from 'rxjs/operators';
@ -571,131 +571,64 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]');
})));
it('should navigate after navigation with skipLocationChange',
it('should eagerly update the URL with urlUpdateStrategy="eagar"',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = TestBed.createComponent(RootCmpWithNamedOutlet);
const fixture = TestBed.createComponent(RootCmp);
advance(fixture);
router.resetConfig([{path: 'show', outlet: 'main', component: SimpleCmp}]);
router.resetConfig([{path: 'team/:id', component: TeamCmp}]);
router.navigate([{outlets: {main: 'show'}}], {skipLocationChange: true});
router.navigateByUrl('/team/22');
advance(fixture);
expect(location.path()).toEqual('');
expect(location.path()).toEqual('/team/22');
expect(fixture.nativeElement).toHaveText('main [simple]');
expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]');
router.urlUpdateStrategy = 'eager';
(router as any).hooks.beforePreactivation = () => {
expect(location.path()).toEqual('/team/33');
expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]');
return of (null);
};
router.navigateByUrl('/team/33');
router.navigate([{outlets: {main: null}}], {skipLocationChange: true});
advance(fixture);
expect(location.path()).toEqual('');
expect(fixture.nativeElement).toHaveText('main []');
expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]');
})));
describe('"eager" urlUpdateStrategy', () => {
beforeEach(() => {
const serializer = new DefaultUrlSerializer();
TestBed.configureTestingModule({
providers: [{
provide: 'authGuardFail',
useValue: (a: any, b: any) => {
return new Promise(res => { setTimeout(() => res(serializer.parse('/login')), 1); });
}
}]
});
it('should eagerly update URL after redirects are applied with urlUpdateStrategy="eagar"',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = TestBed.createComponent(RootCmp);
advance(fixture);
});
router.resetConfig([{path: 'team/:id', component: TeamCmp}]);
router.navigateByUrl('/team/22');
advance(fixture);
expect(location.path()).toEqual('/team/22');
it('should eagerly update the URL with urlUpdateStrategy="eagar"',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = TestBed.createComponent(RootCmp);
advance(fixture);
expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]');
router.resetConfig([{path: 'team/:id', component: TeamCmp}]);
router.urlUpdateStrategy = 'eager';
router.navigateByUrl('/team/22');
advance(fixture);
expect(location.path()).toEqual('/team/22');
let urlAtNavStart = '';
let urlAtRoutesRecognized = '';
router.events.subscribe(e => {
if (e instanceof NavigationStart) {
urlAtNavStart = location.path();
}
if (e instanceof RoutesRecognized) {
urlAtRoutesRecognized = location.path();
}
});
expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]');
router.navigateByUrl('/team/33');
router.urlUpdateStrategy = 'eager';
(router as any).hooks.beforePreactivation = () => {
expect(location.path()).toEqual('/team/33');
expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]');
return of (null);
};
router.navigateByUrl('/team/33');
advance(fixture);
expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]');
})));
it('should eagerly update the URL with urlUpdateStrategy="eagar"',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = TestBed.createComponent(RootCmp);
advance(fixture);
router.urlUpdateStrategy = 'eager';
router.resetConfig([
{path: 'team/:id', component: SimpleCmp, canActivate: ['authGuardFail']},
{path: 'login', component: AbsoluteSimpleLinkCmp}
]);
router.navigateByUrl('/team/22');
advance(fixture);
expect(location.path()).toEqual('/team/22');
// Redirects to /login
advance(fixture, 1);
expect(location.path()).toEqual('/login');
// Perform the same logic again, and it should produce the same result
router.navigateByUrl('/team/22');
advance(fixture);
expect(location.path()).toEqual('/team/22');
// Redirects to /login
advance(fixture, 1);
expect(location.path()).toEqual('/login');
})));
it('should eagerly update URL after redirects are applied with urlUpdateStrategy="eagar"',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = TestBed.createComponent(RootCmp);
advance(fixture);
router.resetConfig([{path: 'team/:id', component: TeamCmp}]);
router.navigateByUrl('/team/22');
advance(fixture);
expect(location.path()).toEqual('/team/22');
expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]');
router.urlUpdateStrategy = 'eager';
let urlAtNavStart = '';
let urlAtRoutesRecognized = '';
router.events.subscribe(e => {
if (e instanceof NavigationStart) {
urlAtNavStart = location.path();
}
if (e instanceof RoutesRecognized) {
urlAtRoutesRecognized = location.path();
}
});
router.navigateByUrl('/team/33');
advance(fixture);
expect(urlAtNavStart).toBe('/team/22');
expect(urlAtRoutesRecognized).toBe('/team/33');
expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]');
})));
});
advance(fixture);
expect(urlAtNavStart).toBe('/team/22');
expect(urlAtRoutesRecognized).toBe('/team/33');
expect(fixture.nativeElement).toHaveText('team 33 [ , right: ]');
})));
it('should navigate back and forward',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
@ -4723,10 +4656,6 @@ class DummyLinkCmp {
}
}
@Component({selector: 'link-cmp', template: `<a [routerLink]="['/simple']">link</a>`})
class AbsoluteSimpleLinkCmp {
}
@Component({selector: 'link-cmp', template: `<a [routerLink]="['../simple']">link</a>`})
class RelativeLinkCmp {
}
@ -4900,10 +4829,6 @@ class RootCmpWithOnInit {
class RootCmpWithTwoOutlets {
}
@Component({selector: 'root-cmp', template: `main [<router-outlet name="main"></router-outlet>]`})
class RootCmpWithNamedOutlet {
}
@Component({selector: 'throwing-cmp', template: ''})
class ThrowingCmp {
constructor() { throw new Error('Throwing Cmp'); }
@ -4911,8 +4836,8 @@ class ThrowingCmp {
function advance(fixture: ComponentFixture<any>, millis?: number): void {
tick(millis);
function advance(fixture: ComponentFixture<any>): void {
tick();
fixture.detectChanges();
}
@ -4940,7 +4865,6 @@ class LazyComponent {
StringLinkCmp,
DummyLinkCmp,
AbsoluteLinkCmp,
AbsoluteSimpleLinkCmp,
RelativeLinkCmp,
DummyLinkWithParentCmp,
LinkWithQueryParamsAndFragment,
@ -4955,7 +4879,6 @@ class LazyComponent {
RootCmp,
RelativeLinkInIfCmp,
RootCmpWithTwoOutlets,
RootCmpWithNamedOutlet,
EmptyQueryParamsCmp,
ThrowingCmp
],
@ -4970,7 +4893,6 @@ class LazyComponent {
StringLinkCmp,
DummyLinkCmp,
AbsoluteLinkCmp,
AbsoluteSimpleLinkCmp,
RelativeLinkCmp,
DummyLinkWithParentCmp,
LinkWithQueryParamsAndFragment,
@ -4986,7 +4908,6 @@ class LazyComponent {
RootCmpWithOnInit,
RelativeLinkInIfCmp,
RootCmpWithTwoOutlets,
RootCmpWithNamedOutlet,
EmptyQueryParamsCmp,
ThrowingCmp
],
@ -5002,7 +4923,6 @@ class LazyComponent {
StringLinkCmp,
DummyLinkCmp,
AbsoluteLinkCmp,
AbsoluteSimpleLinkCmp,
RelativeLinkCmp,
DummyLinkWithParentCmp,
LinkWithQueryParamsAndFragment,
@ -5018,7 +4938,6 @@ class LazyComponent {
RootCmpWithOnInit,
RelativeLinkInIfCmp,
RootCmpWithTwoOutlets,
RootCmpWithNamedOutlet,
EmptyQueryParamsCmp,
ThrowingCmp
]

View File

@ -1,9 +1,6 @@
#!/usr/bin/env bash
# https://www.tldp.org/LDP/abs/html/options.html#AEN19601
# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
set -u -e -E -o pipefail
set -u -e -o pipefail
BASEDIR=$(dirname "$0")
BASEDIR=`(cd $BASEDIR; pwd)`
@ -110,26 +107,11 @@ REWRITE_MESSAGE="git filter-branch -f --msg-filter \"$BASEDIR/utils/github_close
PUSH_BRANCHES="git push git@github.com:angular/angular.git merge_pr_master:$MASTER_BRANCH merge_pr_patch:$PATCH_BRANCH"
CHERRY_PICK_PR="git cherry-pick merge_pr_base..merge_pr"
# Checks that each PR branch to be merged upstream contains SHAs of commits that significantly changed our CI infrastructure.
#
# This check is used to enforce that we don't merge PRs that have not been rebased recently and could result in merging
# of non-approved or otherwise bad changes.
REQUIRED_BASE_SHA_MASTER="3fba6eff79a9b50909199eaa4ebf754c1c4adba6" # pullapprove => CODEOWNERS migration
REQUIRED_BASE_SHA_PATCH="e3853e842ea5c10fafbc310a76a4a7f47ed8c65e" # pullapprove => CODEOWNERS migration
if [[ $MERGE_MASTER == 1 ]]; then
REQUIRED_BASE_SHA="$REQUIRED_BASE_SHA_MASTER"
# check patch only if patch-only PR
elif [[ $MERGE_PATCH == 1 ]]; then
REQUIRED_BASE_SHA="$REQUIRED_BASE_SHA_PATCH"
fi
CHECK_IF_PR_REBASED="git branch --quiet merge_pr --contains $REQUIRED_BASE_SHA"
echo "======================"
echo "GitHub Merge PR Steps"
echo "======================"
echo " $FETCH_PR"
echo " $BASE_PR"
echo " $CHECK_IF_PR_REBASED"
echo " $SQUASH_PR"
echo " $REWRITE_MESSAGE"
if [[ $MERGE_MASTER == 1 ]]; then
@ -145,19 +127,6 @@ echo ">>> Fetch PR: $FETCH_PR"
$FETCH_PR
echo ">>> Mark base: $BASE_PR"
$BASE_PR
echo ">>> Check if PR rebased: $CHECK_IF_PR_REBASED"
if [[ $($CHECK_IF_PR_REBASED) != "" ]]; then
echo "The PR is sufficiently rebased!"
else
echo ""
echo ""
echo "Failed to merge pull request #${PR_NUMBER} because it hasn't been rebased recently and could be bypassing new or updated CI checks!"
echo ""
echo "Please rebase the PR and try again."
echo ""
$RESTORE_BRANCH
exit 1
fi
echo ">>> Autosquash: $SQUASH_PR"
GIT_EDITOR=echo $SQUASH_PR
echo ">>> Rewrite message: $REWRITE_MESSAGE"
@ -184,3 +153,4 @@ if [[ $PUSH_UPSTREAM == 1 ]]; then
fi
echo
echo ">>>>>> SUCCESS <<<<<< PR#$PR_NUMBER merged."

View File

@ -156,10 +156,10 @@
semver "5.6.0"
tmp "0.0.33"
"@bazel/typescript@~0.22.1":
version "0.22.1"
resolved "https://registry.yarnpkg.com/@bazel/typescript/-/typescript-0.22.1.tgz#b52c00e8560019e2f9d273d45c04785e0ec9d9bd"
integrity sha512-88DaCCnNg8rPlKP0eAQEZuoiJkEPeiItpUS3oBR1sFQNBRJb56D25ahK8+N6LJk4qaH+ZQ1/AHOPDhfEEWvDzA==
"@bazel/typescript@0.22.1-7-g68fed6a":
version "0.22.1-7-g68fed6a"
resolved "https://registry.yarnpkg.com/@bazel/typescript/-/typescript-0.22.1-7-g68fed6a.tgz#d6340fbfcfdeb3893e66ec8a435b850cfa83d60f"
integrity sha512-EBPxbge/RBas7zSLvCjUgtpIVdjU+AgZ6YyCMTaYcn4hzD1eYQUpGHT+fa9/icHvk/84wWGXCFRb1+uZsBofVA==
dependencies:
protobufjs "5.0.3"
semver "5.6.0"
@ -6122,10 +6122,10 @@ nanomatch@^1.2.9:
snapdragon "^0.8.1"
to-regex "^3.0.1"
natives@1.1.6, natives@^1.1.0:
version "1.1.6"
resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.6.tgz#a603b4a498ab77173612b9ea1acdec4d980f00bb"
integrity sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==
natives@^1.1.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.4.tgz#2f0f224fc9a7dd53407c7667c84cf8dbe773de58"
integrity sha512-Q29yeg9aFKwhLVdkTAejM/HvYG0Y1Am1+HUkFQGn5k2j8GS+v60TVmZh6nujpEAj/qql+wGUrlryO8bF+b1jEg==
needle@^2.2.1:
version "2.2.4"