Compare commits
59 Commits
6.0.0-beta
...
mhevery-pa
Author | SHA1 | Date | |
---|---|---|---|
27a2515c74 | |||
407b5cf408 | |||
4c1743cce3 | |||
7305e8b45e | |||
285dd6be34 | |||
b10540a0b5 | |||
b62739a989 | |||
bb577c624b | |||
02483a01ad | |||
120bdeecdc | |||
8dff9d84ed | |||
b4cd27979b | |||
11b12670b2 | |||
dd48df105b | |||
18174e5564 | |||
72265f796f | |||
6e8bc310f0 | |||
c40ae7f7cf | |||
5bd93b1f0f | |||
a1cc02f0bd | |||
5778bb820a | |||
87754ad5ec | |||
d364117aa8 | |||
6245637e81 | |||
ab69f12e2c | |||
1278cca883 | |||
ede9cb7c2f | |||
c3fb820473 | |||
2af19c96f2 | |||
dcca799dbb | |||
d3d3f7191a | |||
e0b31dbfef | |||
8df56fe93a | |||
676d9c2c4b | |||
2b68e8d98a | |||
d964491f2a | |||
e6080527c6 | |||
3b7bab7d22 | |||
108fa15792 | |||
1b2271a3b1 | |||
f9381e42de | |||
bbb8f386f1 | |||
08aa54e1d9 | |||
fac4d8d42a | |||
170885c51b | |||
5713faa667 | |||
23596b3f30 | |||
f8fa20d71a | |||
d6d8fe829a | |||
5269ce287e | |||
3e03dbe576 | |||
33b338120c | |||
811679a583 | |||
2c33d17609 | |||
9c99e6a838 | |||
98174758ad | |||
97b928053d | |||
1fe55e252c | |||
53ed4b4648 |
@ -44,6 +44,7 @@ groups:
|
||||
all:
|
||||
users: all
|
||||
required: 1
|
||||
rejection_value: -999
|
||||
# In this group, your self-approval does not count
|
||||
author_approval:
|
||||
auto: false
|
||||
|
@ -24,9 +24,7 @@ filegroup(
|
||||
"typescript",
|
||||
"zone.js",
|
||||
"tsutils",
|
||||
"@types/jasmine",
|
||||
"@types/node",
|
||||
"@types/source-map",
|
||||
"@types",
|
||||
"tsickle",
|
||||
"hammerjs",
|
||||
"protobufjs",
|
||||
|
@ -72,7 +72,7 @@ Before you submit your Pull Request (PR) consider the following guidelines:
|
||||
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR
|
||||
that relates to your submission. You don't want to duplicate effort.
|
||||
1. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
|
||||
We cannot accept code without this.
|
||||
We cannot accept code without this. Make sure you sign with the primary email address of the Git identity that has been granted access to the Angular repository.
|
||||
1. Fork the angular/angular repo.
|
||||
1. Make your changes in a new git branch:
|
||||
|
||||
@ -259,6 +259,19 @@ changes to be accepted, the CLA must be signed. It's a quick process, we promise
|
||||
* For corporations we'll need you to
|
||||
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
|
||||
|
||||
<hr>
|
||||
|
||||
If you have more than one Git identity, you must make sure that you sign the CLA using the primary email address associated with the ID that has been granted access to the Angular repository. Git identities can be associated with more than one email address, and only one is primary. Here are some links to help you sort out multiple Git identities and email addresses:
|
||||
|
||||
* https://help.github.com/articles/setting-your-commit-email-address-in-git/
|
||||
* https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean
|
||||
* https://help.github.com/articles/about-commit-email-addresses/
|
||||
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
|
||||
|
||||
Note that if you have more than one Git identity, it is important to verify that you are logged in with the same ID with which you signed the CLA, before you commit changes. If not, your PR will fail the CLA check.
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
[angular-group]: https://groups.google.com/forum/#!forum/angular
|
||||
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
|
||||
|
@ -5,7 +5,7 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
|
||||
git_repository(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
remote = "https://github.com/bazelbuild/rules_nodejs.git",
|
||||
tag = "0.3.1",
|
||||
commit = "230d39a391226f51c03448f91eb61370e2e58c42",
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
|
||||
@ -16,7 +16,7 @@ node_repositories(package_json = ["//:package.json"])
|
||||
git_repository(
|
||||
name = "build_bazel_rules_typescript",
|
||||
remote = "https://github.com/bazelbuild/rules_typescript.git",
|
||||
commit = "c4ea003acd7d42269b81a2d25eb832972cd24912"
|
||||
commit = "eb3244363e1cb265c84e723b347926f28c29aa35"
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* #docregion import */
|
||||
@import 'hero-details-box.css';
|
||||
/* The AOT compiler needs the `./` to show that this is local */
|
||||
@import './hero-details-box.css';
|
||||
/* #enddocregion import */
|
||||
|
||||
/* #docregion host */
|
||||
|
@ -5,7 +5,8 @@ import { Hero } from './hero';
|
||||
@Component({
|
||||
selector: 'app-hero-team',
|
||||
template: `
|
||||
<link rel="stylesheet" href="assets/hero-team.component.css">
|
||||
<!-- We must use a relative URL so that the AOT compiler can find the stylesheet -->
|
||||
<link rel="stylesheet" href="../assets/hero-team.component.css">
|
||||
<h3>Team</h3>
|
||||
<ul>
|
||||
<li *ngFor="let member of hero.team">
|
||||
|
@ -92,7 +92,7 @@ You can control your app compilation by providing template compiler options in t
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"fullTemplateTypeCheck": true,
|
||||
"preserveWhiteSpace": false,
|
||||
"preserveWhiteSpaces": false,
|
||||
...
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ You can run the <live-example></live-example> in Stackblitz and download the cod
|
||||
## Using component styles
|
||||
|
||||
For every Angular component you write, you may define not only an HTML template,
|
||||
but also the CSS styles that go with that template,
|
||||
but also the CSS styles that go with that template,
|
||||
specifying any selectors, rules, and media queries that you need.
|
||||
|
||||
One way to do this is to set the `styles` property in the component metadata.
|
||||
@ -42,7 +42,7 @@ This scoping restriction is a ***styling modularity feature***.
|
||||
* You can use the CSS class names and selectors that make the most sense in the context of each component.
|
||||
|
||||
|
||||
* Class names and selectors are local to the component and don't collide with
|
||||
* Class names and selectors are local to the component and don't collide with
|
||||
classes and selectors used elsewhere in the application.
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ This scoping restriction is a ***styling modularity feature***.
|
||||
## Special selectors
|
||||
|
||||
Component styles have a few special *selectors* from the world of shadow DOM style scoping
|
||||
(described in the [CSS Scoping Module Level 1](https://www.w3.org/TR/css-scoping-1) page on the
|
||||
(described in the [CSS Scoping Module Level 1](https://www.w3.org/TR/css-scoping-1) page on the
|
||||
[W3C](https://www.w3.org) site).
|
||||
The following sections describe these selectors.
|
||||
|
||||
@ -78,7 +78,7 @@ The `:host` selector is the only way to target the host element. You can't reach
|
||||
the host element from inside the component with other selectors because it's not part of the
|
||||
component's own template. The host element is in a parent component's template.
|
||||
|
||||
Use the *function form* to apply host styles conditionally by
|
||||
Use the *function form* to apply host styles conditionally by
|
||||
including another selector inside parentheses after `:host`.
|
||||
|
||||
The next example targets the host element again, but only when it also has the `active` CSS class.
|
||||
@ -104,15 +104,15 @@ if some ancestor element has the CSS class `theme-light`.
|
||||
|
||||
### (deprecated) `/deep/`, `>>>`, and `::ng-deep`
|
||||
|
||||
Component styles normally apply only to the HTML in the component's own template.
|
||||
Component styles normally apply only to the HTML in the component's own template.
|
||||
|
||||
Use the `/deep/` shadow-piercing descendant combinator to force a style down through the child
|
||||
component tree into all the child component views.
|
||||
The `/deep/` combinator works to any depth of nested components, and it applies to both the view
|
||||
children and content children of the component.
|
||||
children and content children of the component.
|
||||
|
||||
The following example targets all `<h3>` elements, from the host element down
|
||||
through this component to all of its child elements in the DOM.
|
||||
The following example targets all `<h3>` elements, from the host element down
|
||||
through this component to all of its child elements in the DOM.
|
||||
|
||||
<code-example path="component-styles/src/app/hero-details.component.css" region="deep" title="src/app/hero-details.component.css" linenums="false">
|
||||
|
||||
@ -140,7 +140,7 @@ Until then `::ng-deep` should be preferred for a broader compatibility with the
|
||||
|
||||
## Loading component styles
|
||||
|
||||
There are several ways to add styles to a component:
|
||||
There are several ways to add styles to a component:
|
||||
|
||||
* By setting `styles` or `styleUrls` metadata.
|
||||
* Inline in the template HTML.
|
||||
@ -177,8 +177,8 @@ to a component's `@Component` decorator:
|
||||
|
||||
<code-tabs>
|
||||
<code-pane title="src/app/hero-app.component.ts (CSS in file)" path="component-styles/src/app/hero-app.component.1.ts"></code-pane>
|
||||
<code-pane title="src/app/hero-app.component.css" path="component-styles/src/app/hero-app.component.1.css"></code-pane>
|
||||
</code-tabs>
|
||||
<code-pane title="src/app/hero-app.component.css" path="component-styles/src/app/hero-app.component.css"></code-pane>
|
||||
</code-tabs>
|
||||
|
||||
<div class="alert is-critical">
|
||||
|
||||
@ -209,14 +209,14 @@ inside `<style>` tags.
|
||||
|
||||
### Template link tags
|
||||
|
||||
You can also write `<link>` tags into the component's HTML template.
|
||||
You can also write `<link>` tags into the component's HTML template.
|
||||
|
||||
<code-example path="component-styles/src/app/hero-team.component.ts" region="stylelink" title="src/app/hero-team.component.ts">
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-critical">
|
||||
|
||||
The link tag's `href` URL must be relative to the
|
||||
The link tag's `href` URL must be relative to the
|
||||
_**application root**_, not relative to the component file.
|
||||
|
||||
When building with the CLI, be sure to include the linked style file among the assets to be copied to the server as described in the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-asset-configuration).
|
||||
@ -244,7 +244,7 @@ See the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-
|
||||
|
||||
### Non-CSS style files
|
||||
|
||||
If you're building with the CLI,
|
||||
If you're building with the CLI,
|
||||
you can write style files in [sass](http://sass-lang.com/), [less](http://lesscss.org/), or [stylus](http://stylus-lang.com/) and specify those files in the `@Component.styleUrls` metadata with the appropriate extensions (`.scss`, `.less`, `.styl`) as in the following example:
|
||||
|
||||
<code-example>
|
||||
@ -259,7 +259,7 @@ you can write style files in [sass](http://sass-lang.com/), [less](http://lesscs
|
||||
The CLI build process runs the pertinent CSS preprocessor.
|
||||
|
||||
When generating a component file with `ng generate component`, the CLI emits an empty CSS styles file (`.css`) by default.
|
||||
You can configure the CLI to default to your preferred CSS preprocessor
|
||||
You can configure the CLI to default to your preferred CSS preprocessor
|
||||
as explained in the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-css-preprocessors
|
||||
"CSS Preprocessor integration").
|
||||
|
||||
@ -281,7 +281,7 @@ component* basis, you can set the *view encapsulation mode* in the component met
|
||||
Choose from the following modes:
|
||||
|
||||
* `Native` view encapsulation uses the browser's native shadow DOM implementation (see
|
||||
[Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM)
|
||||
[Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM)
|
||||
on the [MDN](https://developer.mozilla.org) site)
|
||||
to attach a shadow DOM to the component's host element, and then puts the component
|
||||
view inside that shadow DOM. The component's styles are included within the shadow DOM.
|
||||
@ -290,18 +290,18 @@ Choose from the following modes:
|
||||
(and renaming) the CSS code to effectively scope the CSS to the component's view.
|
||||
For details, see [Appendix 1](guide/component-styles#inspect-generated-css).
|
||||
|
||||
* `None` means that Angular does no view encapsulation.
|
||||
Angular adds the CSS to the global styles.
|
||||
The scoping rules, isolations, and protections discussed earlier don't apply.
|
||||
* `None` means that Angular does no view encapsulation.
|
||||
Angular adds the CSS to the global styles.
|
||||
The scoping rules, isolations, and protections discussed earlier don't apply.
|
||||
This is essentially the same as pasting the component's styles into the HTML.
|
||||
|
||||
|
||||
To set the components encapsulation mode, use the `encapsulation` property in the component metadata:
|
||||
|
||||
<code-example path="component-styles/src/app/quest-summary.component.ts" region="encapsulation.native" title="src/app/quest-summary.component.ts" linenums="false">
|
||||
</code-example>
|
||||
|
||||
`Native` view encapsulation only works on browsers that have native support
|
||||
for shadow DOM (see [Shadow DOM v0](http://caniuse.com/#feat=shadowdom) on the
|
||||
for shadow DOM (see [Shadow DOM v0](http://caniuse.com/#feat=shadowdom) on the
|
||||
[Can I use](http://caniuse.com) site). The support is still limited,
|
||||
which is why `Emulated` view encapsulation is the default mode and recommended
|
||||
in most cases.
|
||||
@ -331,7 +331,7 @@ There are two kinds of generated attributes:
|
||||
|
||||
* An element that would be a shadow DOM host in native encapsulation has a
|
||||
generated `_nghost` attribute. This is typically the case for component host elements.
|
||||
* An element within a component's view has a `_ngcontent` attribute
|
||||
* An element within a component's view has a `_ngcontent` attribute
|
||||
that identifies to which host's emulated shadow DOM this element belongs.
|
||||
|
||||
The exact values of these attributes aren't important. They are automatically
|
||||
@ -351,5 +351,5 @@ by the generated component styles, which are in the `<head>` section of the DOM:
|
||||
</code-example>
|
||||
|
||||
These styles are post-processed so that each selector is augmented
|
||||
with `_nghost` or `_ngcontent` attribute selectors.
|
||||
with `_nghost` or `_ngcontent` attribute selectors.
|
||||
These extra selectors enable the scoping rules described in this page.
|
||||
|
@ -165,7 +165,7 @@ Such [entry components](guide/ngmodule-faq#q-entry-component-defined) can never
|
||||
While there's no harm in exporting them, there's also no benefit.
|
||||
* Pure service modules that don't have public (exported) declarations.
|
||||
For example, there's no point in re-exporting `HttpClientModule` because it doesn't export anything.
|
||||
It's only purpose is to add http service providers to the application as a whole.
|
||||
Its only purpose is to add http service providers to the application as a whole.
|
||||
|
||||
<hr/>
|
||||
|
||||
@ -190,7 +190,7 @@ An NgModule can export a combination of its own declarations, selected imported
|
||||
Don't bother re-exporting pure service modules.
|
||||
Pure service modules don't export [declarable](guide/bootstrapping#the-declarations-array) classes that another NgModule could use.
|
||||
For example, there's no point in re-exporting `HttpClientModule` because it doesn't export anything.
|
||||
It's only purpose is to add http service providers to the application as a whole.
|
||||
Its only purpose is to add http service providers to the application as a whole.
|
||||
|
||||
|
||||
<hr/>
|
||||
|
@ -297,7 +297,7 @@ These properties include `index` and `odd` and a special property named `$implic
|
||||
Angular sets them to the current value of the context's `index` and `odd` properties.
|
||||
|
||||
* The context property for `let-hero` wasn't specified.
|
||||
It's intended source is implicit.
|
||||
Its intended source is implicit.
|
||||
Angular sets `let-hero` to the value of the context's `$implicit` property
|
||||
which `NgFor` has initialized with the hero for the current iteration.
|
||||
|
||||
|
@ -588,7 +588,7 @@ and a controller:
|
||||
|
||||
You can *upgrade* this component to Angular using the `UpgradeComponent` class.
|
||||
By creating a new Angular **directive** that extends `UpgradeComponent` and doing a `super` call
|
||||
inside it's constructor, you have a fully upgraded AngularJS component to be used inside Angular.
|
||||
inside its constructor, you have a fully upgraded AngularJS component to be used inside Angular.
|
||||
All that is left is to add it to `AppModule`'s `declarations` array.
|
||||
|
||||
<code-example path="upgrade-module/src/app/upgrade-static/hero-detail.component.ts" region="hero-detail-upgrade" title="hero-detail.component.ts">
|
||||
@ -602,7 +602,7 @@ All that is left is to add it to `AppModule`'s `declarations` array.
|
||||
Upgraded components are Angular **directives**, instead of **components**, because Angular
|
||||
is unaware that AngularJS will create elements under it. As far as Angular knows, the upgraded
|
||||
component is just a directive - a tag - and Angular doesn't have to concern itself with
|
||||
it's children.
|
||||
its children.
|
||||
|
||||
</div>
|
||||
|
||||
@ -784,7 +784,7 @@ compilation can pick it up.
|
||||
<code-example path="upgrade-module/src/app/ajs-to-a-providers/app.module.ts" region="register" title="app.module.ts">
|
||||
</code-example>
|
||||
|
||||
You can then inject it in Angular using it's class as a type annotation:
|
||||
You can then inject it in Angular using its class as a type annotation:
|
||||
|
||||
<code-example path="upgrade-module/src/app/ajs-to-a-providers/hero-detail.component.ts" title="hero-detail.component.ts">
|
||||
|
||||
@ -1260,7 +1260,7 @@ app. Switch to the [ngUpgrade bootstrap](#bootstrapping-hybrid-applications) met
|
||||
instead.
|
||||
|
||||
First, remove the `ng-app` attribute from `index.html`.
|
||||
Then import `UpgradeModule` in the `AppModule`, and override it's `ngDoBootstrap` method:
|
||||
Then import `UpgradeModule` in the `AppModule`, and override its `ngDoBootstrap` method:
|
||||
|
||||
<code-example path="upgrade-phonecat-2-hybrid/app/app.module.ts" region="upgrademodule" title="app/app.module.ts">
|
||||
</code-example>
|
||||
@ -1619,7 +1619,7 @@ instead of the default "push state" strategy.
|
||||
Now update the `AppModule` to import this `AppRoutingModule` and also the
|
||||
declare the root `AppComponent` as the bootstrap component.
|
||||
That tells Angular that it should bootstrap the app with the _root_ `AppComponent` and
|
||||
insert it's view into the host web page.
|
||||
insert its view into the host web page.
|
||||
|
||||
You must also remove the bootstrap of the AngularJS module from `ngDoBootstrap()` in `app.module.ts`
|
||||
and the `UpgradeModule` import.
|
||||
@ -1695,7 +1695,7 @@ module configuration files and not needed in Angular:
|
||||
|
||||
The external typings for AngularJS may be uninstalled as well. The only ones
|
||||
you still need are for Jasmine and Angular polyfills.
|
||||
The `@angular/upgrade` package and it's mapping in `systemjs.config.js` can also go.
|
||||
The `@angular/upgrade` package and its mapping in `systemjs.config.js` can also go.
|
||||
|
||||
<code-example format="">
|
||||
npm uninstall @angular/upgrade --save
|
||||
|
@ -44,7 +44,8 @@
|
||||
"docs-lint": "eslint --ignore-path=\"tools/transforms/.eslintignore\" tools/transforms",
|
||||
"docs-test": "node tools/transforms/test.js",
|
||||
"tools-test": "./scripts/deploy-to-firebase.test.sh && yarn docs-test && yarn boilerplate:test && jasmine tools/ng-packages-installer/index.spec.js",
|
||||
"serve-and-sync": "concurrently --kill-others \"yarn docs-watch\" \"yarn start\"",
|
||||
"preserve-and-sync": "yarn docs",
|
||||
"serve-and-sync": "concurrently --kill-others \"yarn docs-watch --watch-only\" \"yarn start\"",
|
||||
"boilerplate:add": "node ./tools/examples/example-boilerplate add",
|
||||
"boilerplate:remove": "node ./tools/examples/example-boilerplate remove",
|
||||
"boilerplate:test": "node tools/examples/test.js",
|
||||
|
@ -153,122 +153,202 @@ describe('AppComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('SideNav when side-by-side (wide)', () => {
|
||||
describe('SideNav', () => {
|
||||
const navigateTo = (path: string) => {
|
||||
locationService.go(path);
|
||||
component.updateSideNav();
|
||||
fixture.detectChanges();
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
component.onResize(sideBySideBreakPoint + 1); // side-by-side
|
||||
});
|
||||
|
||||
it('should open when nav to a guide page (guide/pipes)', () => {
|
||||
navigateTo('guide/pipes');
|
||||
expect(sidenav.opened).toBe(true);
|
||||
});
|
||||
|
||||
it('should open when nav to an api page', () => {
|
||||
navigateTo('api/a/b/c/d');
|
||||
expect(sidenav.opened).toBe(true);
|
||||
});
|
||||
|
||||
it('should be closed when nav to a marketing page (features)', () => {
|
||||
navigateTo('features');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
describe('when manually closed', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
navigateTo('guide/pipes');
|
||||
hamburger.click();
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be closed', () => {
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should stay closed when nav from one guide page to another', () => {
|
||||
navigateTo('guide/bags');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should stay closed when nav from a guide page to api page', () => {
|
||||
navigateTo('api');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should reopen when nav to market page and back to guide page', () => {
|
||||
navigateTo('features');
|
||||
navigateTo('guide/bags');
|
||||
expect(sidenav.opened).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('SideNav when NOT side-by-side (narrow)', () => {
|
||||
const navigateTo = (path: string) => {
|
||||
locationService.go(path);
|
||||
component.updateSideNav();
|
||||
const resizeTo = (width: number) => {
|
||||
component.onResize(width);
|
||||
fixture.detectChanges();
|
||||
};
|
||||
const toggleSidenav = () => {
|
||||
hamburger.click();
|
||||
fixture.detectChanges();
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
component.onResize(sideBySideBreakPoint - 1); // NOT side-by-side
|
||||
});
|
||||
describe('when side-by-side (wide)', () => {
|
||||
beforeEach(() => resizeTo(sideBySideBreakPoint + 1)); // side-by-side
|
||||
|
||||
it('should be closed when nav to a guide page (guide/pipes)', () => {
|
||||
navigateTo('guide/pipes');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should be closed when nav to an api page', () => {
|
||||
navigateTo('api/a/b/c/d');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should be closed when nav to a marketing page (features)', () => {
|
||||
navigateTo('features');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
describe('when manually opened', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
it('should open when navigating to a guide page (guide/pipes)', () => {
|
||||
navigateTo('guide/pipes');
|
||||
hamburger.click();
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be open', () => {
|
||||
expect(sidenav.opened).toBe(true);
|
||||
});
|
||||
|
||||
it('should close when click in gray content area overlay', () => {
|
||||
const sidenavBackdrop = fixture.debugElement.query(By.css('.mat-drawer-backdrop')).nativeElement;
|
||||
sidenavBackdrop.click();
|
||||
fixture.detectChanges();
|
||||
expect(sidenav.opened).toBe(false);
|
||||
it('should open when navigating to an api page', () => {
|
||||
navigateTo('api/a/b/c/d');
|
||||
expect(sidenav.opened).toBe(true);
|
||||
});
|
||||
|
||||
it('should close when nav to another guide page', () => {
|
||||
navigateTo('guide/bags');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should close when nav to api page', () => {
|
||||
navigateTo('api');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should close again when nav to market page', () => {
|
||||
it('should be closed when navigating to a marketing page (features)', () => {
|
||||
navigateTo('features');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
describe('when manually closed', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
navigateTo('guide/pipes');
|
||||
toggleSidenav();
|
||||
});
|
||||
|
||||
it('should be closed', () => {
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should stay closed when navigating from one guide page to another', () => {
|
||||
navigateTo('guide/bags');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should stay closed when navigating from a guide page to api page', () => {
|
||||
navigateTo('api');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should reopen when navigating to market page and back to guide page', () => {
|
||||
navigateTo('features');
|
||||
navigateTo('guide/bags');
|
||||
expect(sidenav.opened).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when NOT side-by-side (narrow)', () => {
|
||||
beforeEach(() => resizeTo(sideBySideBreakPoint - 1)); // NOT side-by-side
|
||||
|
||||
it('should be closed when navigating to a guide page (guide/pipes)', () => {
|
||||
navigateTo('guide/pipes');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should be closed when navigating to an api page', () => {
|
||||
navigateTo('api/a/b/c/d');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should be closed when navigating to a marketing page (features)', () => {
|
||||
navigateTo('features');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
describe('when manually opened', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
navigateTo('guide/pipes');
|
||||
toggleSidenav();
|
||||
});
|
||||
|
||||
it('should be open', () => {
|
||||
expect(sidenav.opened).toBe(true);
|
||||
});
|
||||
|
||||
it('should close when clicking in gray content area overlay', () => {
|
||||
const sidenavBackdrop = fixture.debugElement.query(By.css('.mat-drawer-backdrop')).nativeElement;
|
||||
sidenavBackdrop.click();
|
||||
fixture.detectChanges();
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should close when navigating to another guide page', () => {
|
||||
navigateTo('guide/bags');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should close when navigating to api page', () => {
|
||||
navigateTo('api');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
it('should close again when navigating to market page', () => {
|
||||
navigateTo('features');
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('when changing side-by-side (narrow --> wide)', () => {
|
||||
const sidenavDocs = ['api/a/b/c/d', 'guide/pipes'];
|
||||
const nonSidenavDocs = ['features', 'about'];
|
||||
|
||||
sidenavDocs.forEach(doc => {
|
||||
it(`should open when on a sidenav doc (${doc})`, () => {
|
||||
resizeTo(sideBySideBreakPoint - 1);
|
||||
|
||||
navigateTo(doc);
|
||||
expect(sidenav.opened).toBe(false);
|
||||
|
||||
resizeTo(sideBySideBreakPoint + 1);
|
||||
expect(sidenav.opened).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
nonSidenavDocs.forEach(doc => {
|
||||
it(`should remain closed when on a non-sidenav doc (${doc})`, () => {
|
||||
resizeTo(sideBySideBreakPoint - 1);
|
||||
|
||||
navigateTo(doc);
|
||||
expect(sidenav.opened).toBe(false);
|
||||
|
||||
resizeTo(sideBySideBreakPoint + 1);
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when manually opened', () => {
|
||||
sidenavDocs.forEach(doc => {
|
||||
it(`should remain opened when on a sidenav doc (${doc})`, () => {
|
||||
resizeTo(sideBySideBreakPoint - 1);
|
||||
|
||||
navigateTo(doc);
|
||||
toggleSidenav();
|
||||
expect(sidenav.opened).toBe(true);
|
||||
|
||||
resizeTo(sideBySideBreakPoint + 1);
|
||||
expect(sidenav.opened).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
nonSidenavDocs.forEach(doc => {
|
||||
it(`should close when on a non-sidenav doc (${doc})`, () => {
|
||||
resizeTo(sideBySideBreakPoint - 1);
|
||||
|
||||
navigateTo(doc);
|
||||
toggleSidenav();
|
||||
expect(sidenav.opened).toBe(true);
|
||||
|
||||
resizeTo(sideBySideBreakPoint + 1);
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when changing side-by-side (wide --> narrow)', () => {
|
||||
const sidenavDocs = ['api/a/b/c/d', 'guide/pipes'];
|
||||
const nonSidenavDocs = ['features', 'about'];
|
||||
|
||||
sidenavDocs.forEach(doc => {
|
||||
it(`should close when on a sidenav doc (${doc})`, () => {
|
||||
navigateTo(doc);
|
||||
expect(sidenav.opened).toBe(true);
|
||||
|
||||
resizeTo(sideBySideBreakPoint - 1);
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
nonSidenavDocs.forEach(doc => {
|
||||
it(`should remain closed when on a non-sidenav doc (${doc})`, () => {
|
||||
navigateTo(doc);
|
||||
expect(sidenav.opened).toBe(false);
|
||||
|
||||
resizeTo(sideBySideBreakPoint - 1);
|
||||
expect(sidenav.opened).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -387,14 +467,14 @@ describe('AppComponent', () => {
|
||||
expect(scrollSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should scroll again when nav to the same hash twice in succession', () => {
|
||||
it('should scroll again when navigating to the same hash twice in succession', () => {
|
||||
locationService.go('guide/pipes');
|
||||
locationService.go('guide/pipes#somewhere');
|
||||
locationService.go('guide/pipes#somewhere');
|
||||
expect(scrollSpy.calls.count()).toBe(2);
|
||||
});
|
||||
|
||||
it('should scroll when nav to the same path', () => {
|
||||
it('should scroll when navigating to the same path', () => {
|
||||
locationService.go('guide/pipes');
|
||||
scrollSpy.calls.reset();
|
||||
|
||||
|
@ -235,6 +235,14 @@ export class AppComponent implements OnInit {
|
||||
onResize(width: number) {
|
||||
this.isSideBySide = width > this.sideBySideWidth;
|
||||
this.showFloatingToc.next(width > this.showFloatingTocWidth);
|
||||
|
||||
if (this.isSideBySide && !this.isSideNavDoc) {
|
||||
// If this is a non-sidenav doc and the screen is wide enough so that we can display menu
|
||||
// items in the top-bar, ensure the sidenav is closed.
|
||||
// (This condition can only be met when the resize event changes the value of `isSideBySide`
|
||||
// from `false` to `true` while on a non-sidenav doc.)
|
||||
this.sideNavToggle(false);
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event.target', '$event.button', '$event.ctrlKey', '$event.metaKey', '$event.altKey'])
|
||||
|
@ -31,14 +31,6 @@
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="translucent">
|
||||
|
||||
<!--
|
||||
Initially tell the Google crawler not to index this page.
|
||||
If the page loads correctly will remove this tag (in the DocViewer).
|
||||
Subsequent navigations will update the tag dynamically (i.e. soft 404).
|
||||
Don't do the same for `robots` in general here, since they might not be able to handle the tag changing dynamically.
|
||||
-->
|
||||
<meta name="googlebot" content="noindex">
|
||||
|
||||
<!-- Google Analytics -->
|
||||
<script>
|
||||
// Note this is a customised version of the GA tracking snippet
|
||||
|
@ -35,7 +35,6 @@ mat-sidenav.mat-sidenav.sidenav {
|
||||
min-width: 260px;
|
||||
background-color: $offwhite;
|
||||
box-shadow: 6px 0 6px rgba(0,0,0,0.10);
|
||||
height: calc(100vh - 64px);
|
||||
|
||||
&.collapsed {
|
||||
top: 56px;
|
||||
|
@ -43,7 +43,7 @@
|
||||
"zone.js": "^0.8.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "1.5.0",
|
||||
"@angular/cli": "1.6.5",
|
||||
"@types/angular": "^1.5.16",
|
||||
"@types/angular-animate": "^1.5.5",
|
||||
"@types/angular-cookies": "^1.4.2",
|
||||
@ -66,7 +66,7 @@
|
||||
"http-server": "^0.9.0",
|
||||
"jasmine": "~2.8.0",
|
||||
"jasmine-core": "~2.8.0",
|
||||
"jasmine-marbles":"^0.2.0",
|
||||
"jasmine-marbles": "^0.2.0",
|
||||
"jasmine-spec-reporter": "^4.2.1",
|
||||
"karma": "^1.3.0",
|
||||
"karma-chrome-launcher": "^2.0.0",
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -58,7 +58,7 @@ new as of May 2017 and not very stable yet.
|
||||
- Test all packages: `bazel test packages/...`
|
||||
|
||||
You can use [ibazel] to get a "watch mode" that continuously
|
||||
keeps the outputs up-to-date as you save sources.
|
||||
keeps the outputs up-to-date as you save sources.
|
||||
|
||||
### Debugging a Node Test
|
||||
|
||||
@ -68,6 +68,44 @@ keeps the outputs up-to-date as you save sources.
|
||||
|
||||
The process should automatically connect to the debugger.
|
||||
|
||||
### Debugging a Node Test in VSCode
|
||||
|
||||
First time setup:
|
||||
- Go to Debug > Add configuration (in the menu bar) to open `launch.json`
|
||||
- Add the following to the `configurations` array:
|
||||
|
||||
```
|
||||
{
|
||||
"name": "Attach (inspect)",
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"port": 9229,
|
||||
"address": "localhost",
|
||||
"restart": false,
|
||||
"sourceMaps": true,
|
||||
"localRoot": "${workspaceRoot}",
|
||||
"remoteRoot": null
|
||||
},
|
||||
{
|
||||
"name": "Attach (no-sm,inspect)",
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"port": 9229,
|
||||
"address": "localhost",
|
||||
"restart": false,
|
||||
"sourceMaps": false,
|
||||
"localRoot": "${workspaceRoot}",
|
||||
"remoteRoot": null
|
||||
},
|
||||
```
|
||||
|
||||
The easiest way to debug a test for now is to add a `debugger` statement in the code
|
||||
and launch the bazel corresponding test (`bazel test <target> --config=debug`).
|
||||
|
||||
Bazel will wait on a connection. Go to the debug view (by clicking on the sidebar or
|
||||
Apple+Shift+D on Mac) and click on the green play icon next to the configuration name
|
||||
(ie `Attach (inspect)`).
|
||||
|
||||
### Debugging a Karma Test
|
||||
|
||||
- Run test: `bazel run packages/core/test:test_web`
|
||||
|
4
integration/.gitignore
vendored
4
integration/.gitignore
vendored
@ -1,13 +1,9 @@
|
||||
built/
|
||||
dist/
|
||||
vendor/
|
||||
yarn.lock
|
||||
.ng-cli/
|
||||
cli-*/**
|
||||
*/src/*.d.ts
|
||||
*/src/*.js
|
||||
**/*.ngfactory.ts
|
||||
**/*.ngsummary.json
|
||||
**/*.ngsummary.ts
|
||||
*/yarn*
|
||||
**/.yarn_local_cache*
|
||||
|
@ -1,11 +1,24 @@
|
||||
# Integration tests for Angular
|
||||
|
||||
This directory contains end-to-end tests for Angular. Each directory is a self-contained
|
||||
application that exactly mimics how a user might expect Angular to work, so they allow
|
||||
high-fidelity reproductions of real-world issues.
|
||||
This directory contains end-to-end tests for Angular. Each directory is a self-contained application that exactly mimics how a user might expect Angular
|
||||
to work, so they allow high-fidelity reproductions of real-world issues.
|
||||
|
||||
For this to work, we first build the Angular distribution just like we would publish
|
||||
it to npm, then install the distribution into each app.
|
||||
For this to work, we first build the Angular distribution just like we would
|
||||
publish it to npm, then install the distribution into each app.
|
||||
|
||||
To test Angular CLI applications, we generate integration tests such as `cli-hello-world`.
|
||||
This was generated with a current version of the CLI, and the only modification was replacement of `@angular/*` packages with their counterparts coming from `file:../../dist/packages-dist/*`.
|
||||
When a significant change is released in the CLI, the application should be re-generated from scratch:
|
||||
|
||||
```bash
|
||||
$ cd integration
|
||||
$ rm -rf cli-hello-world
|
||||
$ ng new cli-hello-world
|
||||
# Edit cli-hello-world/package.json to point the @angular packages to dist/packages-dist, and preserve local mods to
|
||||
# ng build
|
||||
# ng test
|
||||
# typescript version
|
||||
```
|
||||
|
||||
## Writing an integration test
|
||||
|
||||
@ -29,6 +42,8 @@ you can install the package directly from `file:../../node_modules`.
|
||||
|
||||
## Running integration tests
|
||||
|
||||
First you must run `build.sh` to create the current distribution.
|
||||
|
||||
You can iterate on the tests by keeping the dist folder up-to-date.
|
||||
See the `package.json` of the test(s) you're debugging, to see which dist/ folders they install from.
|
||||
Then run the right `tsc --watch` command to keep those dist folders up-to-date, for example:
|
||||
|
@ -18,14 +18,14 @@
|
||||
"hello_world__render3__closure": {
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"bundle": 7065
|
||||
"bundle": 8153
|
||||
}
|
||||
}
|
||||
},
|
||||
"hello_world__render3__rollup": {
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"bundle": 56550
|
||||
"bundle": 34304
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
|
||||
git_repository(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
remote = "https://github.com/bazelbuild/rules_nodejs.git",
|
||||
tag = "0.3.1",
|
||||
commit = "230d39a391226f51c03448f91eb61370e2e58c42",
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")
|
||||
@ -14,7 +14,7 @@ node_repositories(package_json = ["//:package.json"])
|
||||
git_repository(
|
||||
name = "build_bazel_rules_typescript",
|
||||
remote = "https://github.com/bazelbuild/rules_typescript.git",
|
||||
commit = "c4ea003acd7d42269b81a2d25eb832972cd24912"
|
||||
commit = "eb3244363e1cb265c84e723b347926f28c29aa35"
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
|
||||
|
@ -20,7 +20,6 @@
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "ngc -p angular.tsconfig.json",
|
||||
"test": "WORKAROUND https://github.com/bazelbuild/bazel/issues/4242, can't build ...",
|
||||
"test": "bazel build //src/... --noshow_progress"
|
||||
"test": "bazel build //... --noshow_progress"
|
||||
}
|
||||
}
|
995
integration/bazel/yarn.lock
Normal file
995
integration/bazel/yarn.lock
Normal file
@ -0,0 +1,995 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@angular/animations@file:../../dist/packages-dist/animations":
|
||||
version "5.2.0-e94fb16a2"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/bazel@file:../../dist/packages-dist/bazel":
|
||||
version "5.2.0-e94fb16a2"
|
||||
dependencies:
|
||||
"@types/node" "6.0.84"
|
||||
|
||||
"@angular/common@file:../../dist/packages-dist/common":
|
||||
version "5.2.0-e94fb16a2"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli":
|
||||
version "5.2.0-e94fb16a2"
|
||||
dependencies:
|
||||
chokidar "^1.4.2"
|
||||
minimist "^1.2.0"
|
||||
reflect-metadata "^0.1.2"
|
||||
tsickle "^0.26.0"
|
||||
|
||||
"@angular/compiler@file:../../dist/packages-dist/compiler":
|
||||
version "5.2.0-e94fb16a2"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/core@file:../../dist/packages-dist/core":
|
||||
version "5.2.0-e94fb16a2"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/platform-browser@file:../../dist/packages-dist/platform-browser":
|
||||
version "5.2.0-e94fb16a2"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@types/node@6.0.84":
|
||||
version "6.0.84"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.84.tgz#193ffe5a9f42864d425ffd9739d95b753c6a1eab"
|
||||
|
||||
"@types/source-map@0.5.1":
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/source-map/-/source-map-0.5.1.tgz#7e74db5d06ab373a712356eebfaea2fad0ea2367"
|
||||
|
||||
abbrev@1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
|
||||
|
||||
ajv@^4.9.1:
|
||||
version "4.11.8"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
|
||||
dependencies:
|
||||
co "^4.6.0"
|
||||
json-stable-stringify "^1.0.1"
|
||||
|
||||
ansi-regex@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
|
||||
anymatch@^1.3.0:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
|
||||
dependencies:
|
||||
micromatch "^2.1.5"
|
||||
normalize-path "^2.0.0"
|
||||
|
||||
aproba@^1.0.3:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
||||
|
||||
are-we-there-yet@~1.1.2:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d"
|
||||
dependencies:
|
||||
delegates "^1.0.0"
|
||||
readable-stream "^2.0.6"
|
||||
|
||||
arr-diff@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
|
||||
dependencies:
|
||||
arr-flatten "^1.0.1"
|
||||
|
||||
arr-flatten@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
|
||||
|
||||
array-unique@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
|
||||
|
||||
asn1@~0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
|
||||
|
||||
assert-plus@1.0.0, assert-plus@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
||||
|
||||
assert-plus@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
|
||||
|
||||
async-each@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
|
||||
aws-sign2@~0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
|
||||
|
||||
aws4@^1.2.1:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
|
||||
bcrypt-pbkdf@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
|
||||
dependencies:
|
||||
tweetnacl "^0.14.3"
|
||||
|
||||
binary-extensions@^1.0.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"
|
||||
|
||||
block-stream@*:
|
||||
version "0.0.9"
|
||||
resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
|
||||
dependencies:
|
||||
inherits "~2.0.0"
|
||||
|
||||
boom@2.x.x:
|
||||
version "2.10.1"
|
||||
resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
|
||||
dependencies:
|
||||
hoek "2.x.x"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
braces@^1.8.2:
|
||||
version "1.8.5"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
|
||||
dependencies:
|
||||
expand-range "^1.8.1"
|
||||
preserve "^0.2.0"
|
||||
repeat-element "^1.1.2"
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
|
||||
chokidar@^1.4.2:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
|
||||
dependencies:
|
||||
anymatch "^1.3.0"
|
||||
async-each "^1.0.0"
|
||||
glob-parent "^2.0.0"
|
||||
inherits "^2.0.1"
|
||||
is-binary-path "^1.0.0"
|
||||
is-glob "^2.0.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
readdirp "^2.0.0"
|
||||
optionalDependencies:
|
||||
fsevents "^1.0.0"
|
||||
|
||||
co@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
|
||||
code-point-at@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
|
||||
combined-stream@^1.0.5, combined-stream@~1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
|
||||
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
|
||||
cryptiles@2.x.x:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
|
||||
dependencies:
|
||||
boom "2.x.x"
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
debug@^2.2.0:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
deep-extend@~0.4.0:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
|
||||
delegates@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
||||
|
||||
detect-libc@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
|
||||
|
||||
ecc-jsbn@~0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
|
||||
dependencies:
|
||||
jsbn "~0.1.0"
|
||||
|
||||
expand-brackets@^0.1.4:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
|
||||
dependencies:
|
||||
is-posix-bracket "^0.1.0"
|
||||
|
||||
expand-range@^1.8.1:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
|
||||
dependencies:
|
||||
fill-range "^2.1.0"
|
||||
|
||||
extend@~3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
|
||||
|
||||
extglob@^0.3.1:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
|
||||
dependencies:
|
||||
is-extglob "^1.0.0"
|
||||
|
||||
extsprintf@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
||||
|
||||
extsprintf@^1.2.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
|
||||
filename-regex@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
|
||||
|
||||
fill-range@^2.1.0:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723"
|
||||
dependencies:
|
||||
is-number "^2.1.0"
|
||||
isobject "^2.0.0"
|
||||
randomatic "^1.1.3"
|
||||
repeat-element "^1.1.2"
|
||||
repeat-string "^1.5.2"
|
||||
|
||||
for-in@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
|
||||
for-own@^0.1.4:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce"
|
||||
dependencies:
|
||||
for-in "^1.0.1"
|
||||
|
||||
forever-agent@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
|
||||
form-data@~2.1.1:
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.5"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
|
||||
fsevents@^1.0.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8"
|
||||
dependencies:
|
||||
nan "^2.3.0"
|
||||
node-pre-gyp "^0.6.39"
|
||||
|
||||
fstream-ignore@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105"
|
||||
dependencies:
|
||||
fstream "^1.0.0"
|
||||
inherits "2"
|
||||
minimatch "^3.0.0"
|
||||
|
||||
fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2:
|
||||
version "1.0.11"
|
||||
resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171"
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
inherits "~2.0.0"
|
||||
mkdirp ">=0.5 0"
|
||||
rimraf "2"
|
||||
|
||||
gauge@~2.7.3:
|
||||
version "2.7.4"
|
||||
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
|
||||
dependencies:
|
||||
aproba "^1.0.3"
|
||||
console-control-strings "^1.0.0"
|
||||
has-unicode "^2.0.0"
|
||||
object-assign "^4.1.0"
|
||||
signal-exit "^3.0.0"
|
||||
string-width "^1.0.1"
|
||||
strip-ansi "^3.0.1"
|
||||
wide-align "^1.1.0"
|
||||
|
||||
getpass@^0.1.1:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
glob-base@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
|
||||
dependencies:
|
||||
glob-parent "^2.0.0"
|
||||
is-glob "^2.0.0"
|
||||
|
||||
glob-parent@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28"
|
||||
dependencies:
|
||||
is-glob "^2.0.0"
|
||||
|
||||
glob@^7.0.5:
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
graceful-fs@^4.1.2:
|
||||
version "4.1.11"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
|
||||
|
||||
har-schema@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
|
||||
|
||||
har-validator@~4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
|
||||
dependencies:
|
||||
ajv "^4.9.1"
|
||||
har-schema "^1.0.5"
|
||||
|
||||
has-unicode@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
|
||||
|
||||
hawk@3.1.3, hawk@~3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
|
||||
dependencies:
|
||||
boom "2.x.x"
|
||||
cryptiles "2.x.x"
|
||||
hoek "2.x.x"
|
||||
sntp "1.x.x"
|
||||
|
||||
hoek@2.x.x:
|
||||
version "2.16.3"
|
||||
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
|
||||
|
||||
http-signature@~1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
|
||||
dependencies:
|
||||
assert-plus "^0.2.0"
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
|
||||
ini@~1.3.0:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
||||
|
||||
is-binary-path@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
|
||||
dependencies:
|
||||
binary-extensions "^1.0.0"
|
||||
|
||||
is-buffer@^1.1.5:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
|
||||
is-dotfile@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
|
||||
|
||||
is-equal-shallow@^0.1.3:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
|
||||
dependencies:
|
||||
is-primitive "^2.0.0"
|
||||
|
||||
is-extendable@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
|
||||
|
||||
is-extglob@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
|
||||
|
||||
is-fullwidth-code-point@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
|
||||
dependencies:
|
||||
number-is-nan "^1.0.0"
|
||||
|
||||
is-glob@^2.0.0, is-glob@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
|
||||
dependencies:
|
||||
is-extglob "^1.0.0"
|
||||
|
||||
is-number@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
|
||||
dependencies:
|
||||
kind-of "^3.0.2"
|
||||
|
||||
is-number@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
|
||||
dependencies:
|
||||
kind-of "^3.0.2"
|
||||
|
||||
is-posix-bracket@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
|
||||
|
||||
is-primitive@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
|
||||
|
||||
is-typedarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||
|
||||
isarray@1.0.0, isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
|
||||
isobject@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
|
||||
dependencies:
|
||||
isarray "1.0.0"
|
||||
|
||||
isstream@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
|
||||
jsbn@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
|
||||
json-schema@0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
|
||||
json-stable-stringify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
|
||||
dependencies:
|
||||
jsonify "~0.0.0"
|
||||
|
||||
json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
|
||||
jsonify@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
|
||||
|
||||
jsprim@^1.2.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
||||
dependencies:
|
||||
assert-plus "1.0.0"
|
||||
extsprintf "1.3.0"
|
||||
json-schema "0.2.3"
|
||||
verror "1.10.0"
|
||||
|
||||
kind-of@^3.0.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
|
||||
dependencies:
|
||||
is-buffer "^1.1.5"
|
||||
|
||||
kind-of@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57"
|
||||
dependencies:
|
||||
is-buffer "^1.1.5"
|
||||
|
||||
micromatch@^2.1.5:
|
||||
version "2.3.11"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
|
||||
dependencies:
|
||||
arr-diff "^2.0.0"
|
||||
array-unique "^0.2.1"
|
||||
braces "^1.8.2"
|
||||
expand-brackets "^0.1.4"
|
||||
extglob "^0.3.1"
|
||||
filename-regex "^2.0.0"
|
||||
is-extglob "^1.0.0"
|
||||
is-glob "^2.0.1"
|
||||
kind-of "^3.0.2"
|
||||
normalize-path "^2.0.1"
|
||||
object.omit "^2.0.0"
|
||||
parse-glob "^3.0.4"
|
||||
regex-cache "^0.4.2"
|
||||
|
||||
mime-db@~1.30.0:
|
||||
version "1.30.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
|
||||
|
||||
mime-types@^2.1.12, mime-types@~2.1.7:
|
||||
version "2.1.17"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
|
||||
dependencies:
|
||||
mime-db "~1.30.0"
|
||||
|
||||
minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||
|
||||
minimist@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||
|
||||
"mkdirp@>=0.5 0", mkdirp@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
dependencies:
|
||||
minimist "0.0.8"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
|
||||
nan@^2.3.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
|
||||
|
||||
node-pre-gyp@^0.6.39:
|
||||
version "0.6.39"
|
||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649"
|
||||
dependencies:
|
||||
detect-libc "^1.0.2"
|
||||
hawk "3.1.3"
|
||||
mkdirp "^0.5.1"
|
||||
nopt "^4.0.1"
|
||||
npmlog "^4.0.2"
|
||||
rc "^1.1.7"
|
||||
request "2.81.0"
|
||||
rimraf "^2.6.1"
|
||||
semver "^5.3.0"
|
||||
tar "^2.2.1"
|
||||
tar-pack "^3.4.0"
|
||||
|
||||
nopt@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
|
||||
dependencies:
|
||||
abbrev "1"
|
||||
osenv "^0.1.4"
|
||||
|
||||
normalize-path@^2.0.0, normalize-path@^2.0.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
|
||||
dependencies:
|
||||
remove-trailing-separator "^1.0.1"
|
||||
|
||||
npmlog@^4.0.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
|
||||
dependencies:
|
||||
are-we-there-yet "~1.1.2"
|
||||
console-control-strings "~1.1.0"
|
||||
gauge "~2.7.3"
|
||||
set-blocking "~2.0.0"
|
||||
|
||||
number-is-nan@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
||||
|
||||
oauth-sign@~0.8.1:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
||||
|
||||
object-assign@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
object.omit@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
|
||||
dependencies:
|
||||
for-own "^0.1.4"
|
||||
is-extendable "^0.1.1"
|
||||
|
||||
once@^1.3.0, once@^1.3.3:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
os-homedir@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
|
||||
|
||||
os-tmpdir@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
|
||||
osenv@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644"
|
||||
dependencies:
|
||||
os-homedir "^1.0.0"
|
||||
os-tmpdir "^1.0.0"
|
||||
|
||||
parse-glob@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
|
||||
dependencies:
|
||||
glob-base "^0.3.0"
|
||||
is-dotfile "^1.0.0"
|
||||
is-extglob "^1.0.0"
|
||||
is-glob "^2.0.0"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
|
||||
performance-now@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
|
||||
|
||||
preserve@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
|
||||
|
||||
process-nextick-args@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
|
||||
|
||||
punycode@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||
|
||||
qs@~6.4.0:
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
|
||||
|
||||
randomatic@^1.1.3:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c"
|
||||
dependencies:
|
||||
is-number "^3.0.0"
|
||||
kind-of "^4.0.0"
|
||||
|
||||
rc@^1.1.7:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.3.tgz#51575a900f8dd68381c710b4712c2154c3e2035b"
|
||||
dependencies:
|
||||
deep-extend "~0.4.0"
|
||||
ini "~1.3.0"
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.3"
|
||||
isarray "~1.0.0"
|
||||
process-nextick-args "~1.0.6"
|
||||
safe-buffer "~5.1.1"
|
||||
string_decoder "~1.0.3"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readdirp@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
minimatch "^3.0.2"
|
||||
readable-stream "^2.0.2"
|
||||
set-immediate-shim "^1.0.1"
|
||||
|
||||
reflect-metadata@^0.1.2:
|
||||
version "0.1.10"
|
||||
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.10.tgz#b4f83704416acad89988c9b15635d47e03b9344a"
|
||||
|
||||
regex-cache@^0.4.2:
|
||||
version "0.4.4"
|
||||
resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd"
|
||||
dependencies:
|
||||
is-equal-shallow "^0.1.3"
|
||||
|
||||
remove-trailing-separator@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
|
||||
|
||||
repeat-element@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
|
||||
|
||||
repeat-string@^1.5.2:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
|
||||
|
||||
request@2.81.0:
|
||||
version "2.81.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
|
||||
dependencies:
|
||||
aws-sign2 "~0.6.0"
|
||||
aws4 "^1.2.1"
|
||||
caseless "~0.12.0"
|
||||
combined-stream "~1.0.5"
|
||||
extend "~3.0.0"
|
||||
forever-agent "~0.6.1"
|
||||
form-data "~2.1.1"
|
||||
har-validator "~4.2.1"
|
||||
hawk "~3.1.3"
|
||||
http-signature "~1.1.0"
|
||||
is-typedarray "~1.0.0"
|
||||
isstream "~0.1.2"
|
||||
json-stringify-safe "~5.0.1"
|
||||
mime-types "~2.1.7"
|
||||
oauth-sign "~0.8.1"
|
||||
performance-now "^0.2.0"
|
||||
qs "~6.4.0"
|
||||
safe-buffer "^5.0.1"
|
||||
stringstream "~0.0.4"
|
||||
tough-cookie "~2.3.0"
|
||||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.0.0"
|
||||
|
||||
rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
|
||||
dependencies:
|
||||
glob "^7.0.5"
|
||||
|
||||
"rxjs@file:../../node_modules/rxjs":
|
||||
version "5.5.5"
|
||||
dependencies:
|
||||
symbol-observable "1.0.1"
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
|
||||
|
||||
semver@^5.3.0:
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
|
||||
|
||||
set-blocking@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||
|
||||
set-immediate-shim@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
|
||||
|
||||
signal-exit@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||
|
||||
sntp@1.x.x:
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
|
||||
dependencies:
|
||||
hoek "2.x.x"
|
||||
|
||||
source-map-support@^0.4.2:
|
||||
version "0.4.18"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
|
||||
dependencies:
|
||||
source-map "^0.5.6"
|
||||
|
||||
source-map@^0.5.6:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
|
||||
sshpk@^1.7.0:
|
||||
version "1.13.1"
|
||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
|
||||
dependencies:
|
||||
asn1 "~0.2.3"
|
||||
assert-plus "^1.0.0"
|
||||
dashdash "^1.12.0"
|
||||
getpass "^0.1.1"
|
||||
optionalDependencies:
|
||||
bcrypt-pbkdf "^1.0.0"
|
||||
ecc-jsbn "~0.1.1"
|
||||
jsbn "~0.1.0"
|
||||
tweetnacl "~0.14.0"
|
||||
|
||||
string-width@^1.0.1, string-width@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
|
||||
dependencies:
|
||||
code-point-at "^1.0.0"
|
||||
is-fullwidth-code-point "^1.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
|
||||
string_decoder@~1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
stringstream@~0.0.4:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
|
||||
|
||||
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
strip-json-comments@~2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
|
||||
symbol-observable@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4"
|
||||
|
||||
tar-pack@^3.4.0:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f"
|
||||
dependencies:
|
||||
debug "^2.2.0"
|
||||
fstream "^1.0.10"
|
||||
fstream-ignore "^1.0.5"
|
||||
once "^1.3.3"
|
||||
readable-stream "^2.1.4"
|
||||
rimraf "^2.5.1"
|
||||
tar "^2.2.1"
|
||||
uid-number "^0.0.6"
|
||||
|
||||
tar@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
|
||||
dependencies:
|
||||
block-stream "*"
|
||||
fstream "^1.0.2"
|
||||
inherits "2"
|
||||
|
||||
tough-cookie@~2.3.0:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
|
||||
dependencies:
|
||||
punycode "^1.4.1"
|
||||
|
||||
tsickle@^0.26.0:
|
||||
version "0.26.0"
|
||||
resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.26.0.tgz#40b30a2dd6abcb33b182e37596674bd1cfe4039c"
|
||||
dependencies:
|
||||
minimist "^1.2.0"
|
||||
mkdirp "^0.5.1"
|
||||
source-map "^0.5.6"
|
||||
source-map-support "^0.4.2"
|
||||
|
||||
tslib@^1.7.1:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.1.tgz#6946af2d1d651a7b1863b531d6e5afa41aa44eac"
|
||||
|
||||
tunnel-agent@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||
version "0.14.5"
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||
|
||||
"typescript@file:../../node_modules/typescript":
|
||||
version "2.6.2"
|
||||
|
||||
uid-number@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
|
||||
|
||||
util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
|
||||
uuid@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
|
||||
|
||||
verror@1.10.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
core-util-is "1.0.2"
|
||||
extsprintf "^1.2.0"
|
||||
|
||||
wide-align@^1.1.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710"
|
||||
dependencies:
|
||||
string-width "^1.0.2"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
|
||||
"zone.js@file:../../node_modules/zone.js":
|
||||
version "0.8.17"
|
60
integration/cli-hello-world/.angular-cli.json
Normal file
60
integration/cli-hello-world/.angular-cli.json
Normal file
@ -0,0 +1,60 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"project": {
|
||||
"name": "cli-hello-world"
|
||||
},
|
||||
"apps": [
|
||||
{
|
||||
"root": "src",
|
||||
"outDir": "dist",
|
||||
"assets": [
|
||||
"assets",
|
||||
"favicon.ico"
|
||||
],
|
||||
"index": "index.html",
|
||||
"main": "main.ts",
|
||||
"polyfills": "polyfills.ts",
|
||||
"test": "test.ts",
|
||||
"tsconfig": "tsconfig.app.json",
|
||||
"testTsconfig": "tsconfig.spec.json",
|
||||
"prefix": "app",
|
||||
"styles": [
|
||||
"styles.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"environmentSource": "environments/environment.ts",
|
||||
"environments": {
|
||||
"dev": "environments/environment.ts",
|
||||
"prod": "environments/environment.prod.ts"
|
||||
}
|
||||
}
|
||||
],
|
||||
"e2e": {
|
||||
"protractor": {
|
||||
"config": "./protractor.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": [
|
||||
{
|
||||
"project": "src/tsconfig.app.json",
|
||||
"exclude": "**/node_modules/**"
|
||||
},
|
||||
{
|
||||
"project": "src/tsconfig.spec.json",
|
||||
"exclude": "**/node_modules/**"
|
||||
},
|
||||
{
|
||||
"project": "e2e/tsconfig.e2e.json",
|
||||
"exclude": "**/node_modules/**"
|
||||
}
|
||||
],
|
||||
"test": {
|
||||
"karma": {
|
||||
"config": "./karma.conf.js"
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"styleExt": "css",
|
||||
"component": {}
|
||||
}
|
||||
}
|
13
integration/cli-hello-world/.editorconfig
Normal file
13
integration/cli-hello-world/.editorconfig
Normal file
@ -0,0 +1,13 @@
|
||||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
27
integration/cli-hello-world/README.md
Normal file
27
integration/cli-hello-world/README.md
Normal file
@ -0,0 +1,27 @@
|
||||
# CliHelloWorld
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.6.6.
|
||||
|
||||
## Development server
|
||||
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Running end-to-end tests
|
||||
|
||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
14
integration/cli-hello-world/e2e/app.e2e-spec.ts
Normal file
14
integration/cli-hello-world/e2e/app.e2e-spec.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { AppPage } from './app.po';
|
||||
|
||||
describe('cli-hello-world App', () => {
|
||||
let page: AppPage;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new AppPage();
|
||||
});
|
||||
|
||||
it('should display welcome message', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getParagraphText()).toEqual('Welcome to app!');
|
||||
});
|
||||
});
|
11
integration/cli-hello-world/e2e/app.po.ts
Normal file
11
integration/cli-hello-world/e2e/app.po.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { browser, by, element } from 'protractor';
|
||||
|
||||
export class AppPage {
|
||||
navigateTo() {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
}
|
||||
}
|
14
integration/cli-hello-world/e2e/tsconfig.e2e.json
Normal file
14
integration/cli-hello-world/e2e/tsconfig.e2e.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"baseUrl": "./",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"jasminewd2",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
39
integration/cli-hello-world/karma.conf.js
Normal file
39
integration/cli-hello-world/karma.conf.js
Normal file
@ -0,0 +1,39 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular/cli'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular/cli/plugins/karma')
|
||||
],
|
||||
client:{
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
reports: [ 'html', 'lcovonly' ],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
angularCli: {
|
||||
environment: 'dev'
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['CustomChrome'],
|
||||
singleRun: false,
|
||||
customLaunchers: {
|
||||
CustomChrome: {
|
||||
base: 'Chrome',
|
||||
flags: ['--no-sandbox']
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
48
integration/cli-hello-world/package.json
Normal file
48
integration/cli-hello-world/package.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "cli-hello-world",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build --prod --build-optimizer",
|
||||
"test": "ng test --single-run",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "file:../../dist/packages-dist/animations",
|
||||
"@angular/common": "file:../../dist/packages-dist/common",
|
||||
"@angular/compiler": "file:../../dist/packages-dist/compiler",
|
||||
"@angular/core": "file:../../dist/packages-dist/core",
|
||||
"@angular/forms": "file:../../dist/packages-dist/forms",
|
||||
"@angular/http": "file:../../dist/packages-dist/http",
|
||||
"@angular/platform-browser": "file:../../dist/packages-dist/platform-browser",
|
||||
"@angular/platform-browser-dynamic": "file:../../dist/packages-dist/platform-browser-dynamic",
|
||||
"@angular/router": "file:../../dist/packages-dist/router",
|
||||
"core-js": "^2.4.1",
|
||||
"rxjs": "^5.5.6",
|
||||
"zone.js": "^0.8.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "1.6.6",
|
||||
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
|
||||
"@angular/language-service": "file:../../dist/packages-dist/language-service",
|
||||
"@types/jasmine": "~2.8.3",
|
||||
"@types/jasminewd2": "~2.0.2",
|
||||
"@types/node": "~6.0.60",
|
||||
"codelyzer": "^4.0.1",
|
||||
"jasmine-core": "~2.8.0",
|
||||
"jasmine-spec-reporter": "~4.2.1",
|
||||
"karma": "~2.0.0",
|
||||
"karma-chrome-launcher": "~2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "^1.2.1",
|
||||
"karma-jasmine": "~1.1.0",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"protractor": "~5.1.2",
|
||||
"ts-node": "~4.1.0",
|
||||
"tslint": "~5.9.1",
|
||||
"typescript": "2.4.2"
|
||||
}
|
||||
}
|
31
integration/cli-hello-world/protractor.conf.js
Normal file
31
integration/cli-hello-world/protractor.conf.js
Normal file
@ -0,0 +1,31 @@
|
||||
// Protractor configuration file, see link for more information
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
specs: [
|
||||
'./e2e/**/*.e2e-spec.ts'
|
||||
],
|
||||
capabilities: {
|
||||
'browserName': 'chrome',
|
||||
chromeOptions: {
|
||||
args: ['--no-sandbox']
|
||||
}
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:4200/',
|
||||
framework: 'jasmine',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000,
|
||||
print: function() {}
|
||||
},
|
||||
onPrepare() {
|
||||
require('ts-node').register({
|
||||
project: 'e2e/tsconfig.e2e.json'
|
||||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||
}
|
||||
};
|
20
integration/cli-hello-world/src/app/app.component.html
Normal file
20
integration/cli-hello-world/src/app/app.component.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!--The content below is only a placeholder and can be replaced.-->
|
||||
<div style="text-align:center">
|
||||
<h1>
|
||||
Welcome to {{ title }}!
|
||||
</h1>
|
||||
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
|
||||
</div>
|
||||
<h2>Here are some links to help you start: </h2>
|
||||
<ul>
|
||||
<li>
|
||||
<h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
|
||||
</li>
|
||||
<li>
|
||||
<h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
|
||||
</li>
|
||||
<li>
|
||||
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
|
||||
</li>
|
||||
</ul>
|
||||
|
27
integration/cli-hello-world/src/app/app.component.spec.ts
Normal file
27
integration/cli-hello-world/src/app/app.component.spec.ts
Normal file
@ -0,0 +1,27 @@
|
||||
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 'app'`, async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('app');
|
||||
}));
|
||||
it('should render title in a h1 tag', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
|
||||
}));
|
||||
});
|
10
integration/cli-hello-world/src/app/app.component.ts
Normal file
10
integration/cli-hello-world/src/app/app.component.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'app';
|
||||
}
|
18
integration/cli-hello-world/src/app/app.module.ts
Normal file
18
integration/cli-hello-world/src/app/app.module.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
0
integration/cli-hello-world/src/assets/.gitkeep
Normal file
0
integration/cli-hello-world/src/assets/.gitkeep
Normal file
@ -0,0 +1,3 @@
|
||||
export const environment = {
|
||||
production: true
|
||||
};
|
@ -0,0 +1,8 @@
|
||||
// The file contents for the current environment will overwrite these during build.
|
||||
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
|
||||
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
|
||||
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
||||
|
||||
export const environment = {
|
||||
production: false
|
||||
};
|
BIN
integration/cli-hello-world/src/favicon.ico
Normal file
BIN
integration/cli-hello-world/src/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
14
integration/cli-hello-world/src/index.html
Normal file
14
integration/cli-hello-world/src/index.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CliHelloWorld</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>
|
12
integration/cli-hello-world/src/main.ts
Normal file
12
integration/cli-hello-world/src/main.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.catch(err => console.log(err));
|
66
integration/cli-hello-world/src/polyfills.ts
Normal file
66
integration/cli-hello-world/src/polyfills.ts
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||
* You can add your own extra polyfills to this file.
|
||||
*
|
||||
* This file is divided into 2 sections:
|
||||
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||
* file.
|
||||
*
|
||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||
* 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/docs/ts/latest/guide/browser-support.html
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
* BROWSER POLYFILLS
|
||||
*/
|
||||
|
||||
/** 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';
|
||||
// import 'core-js/es6/parse-int';
|
||||
// import 'core-js/es6/parse-float';
|
||||
// import 'core-js/es6/number';
|
||||
// import 'core-js/es6/math';
|
||||
// import 'core-js/es6/string';
|
||||
// import 'core-js/es6/date';
|
||||
// import 'core-js/es6/array';
|
||||
// import 'core-js/es6/regexp';
|
||||
// import 'core-js/es6/map';
|
||||
// import 'core-js/es6/weak-map';
|
||||
// import 'core-js/es6/set';
|
||||
|
||||
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
||||
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||
|
||||
/** IE10 and IE11 requires the following for the Reflect API. */
|
||||
// import 'core-js/es6/reflect';
|
||||
|
||||
|
||||
/** 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';
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
* APPLICATION IMPORTS
|
||||
*/
|
1
integration/cli-hello-world/src/styles.css
Normal file
1
integration/cli-hello-world/src/styles.css
Normal file
@ -0,0 +1 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
20
integration/cli-hello-world/src/test.ts
Normal file
20
integration/cli-hello-world/src/test.ts
Normal file
@ -0,0 +1,20 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: any;
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
13
integration/cli-hello-world/src/tsconfig.app.json
Normal file
13
integration/cli-hello-world/src/tsconfig.app.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/app",
|
||||
"baseUrl": "./",
|
||||
"module": "es2015",
|
||||
"types": []
|
||||
},
|
||||
"exclude": [
|
||||
"test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
19
integration/cli-hello-world/src/tsconfig.spec.json
Normal file
19
integration/cli-hello-world/src/tsconfig.spec.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/spec",
|
||||
"baseUrl": "./",
|
||||
"module": "commonjs",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
19
integration/cli-hello-world/tsconfig.json
Normal file
19
integration/cli-hello-world/tsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es5",
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
],
|
||||
"lib": [
|
||||
"es2017",
|
||||
"dom"
|
||||
]
|
||||
}
|
||||
}
|
143
integration/cli-hello-world/tslint.json
Normal file
143
integration/cli-hello-world/tslint.json
Normal file
@ -0,0 +1,143 @@
|
||||
{
|
||||
"rulesDirectory": [
|
||||
"node_modules/codelyzer"
|
||||
],
|
||||
"rules": {
|
||||
"arrow-return-shorthand": true,
|
||||
"callable-types": true,
|
||||
"class-name": true,
|
||||
"comment-format": [
|
||||
true,
|
||||
"check-space"
|
||||
],
|
||||
"curly": true,
|
||||
"deprecation": {
|
||||
"severity": "warn"
|
||||
},
|
||||
"eofline": true,
|
||||
"forin": true,
|
||||
"import-blacklist": [
|
||||
true,
|
||||
"rxjs",
|
||||
"rxjs/Rx"
|
||||
],
|
||||
"import-spacing": true,
|
||||
"indent": [
|
||||
true,
|
||||
"spaces"
|
||||
],
|
||||
"interface-over-type-literal": true,
|
||||
"label-position": true,
|
||||
"max-line-length": [
|
||||
true,
|
||||
140
|
||||
],
|
||||
"member-access": false,
|
||||
"member-ordering": [
|
||||
true,
|
||||
{
|
||||
"order": [
|
||||
"static-field",
|
||||
"instance-field",
|
||||
"static-method",
|
||||
"instance-method"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-arg": true,
|
||||
"no-bitwise": true,
|
||||
"no-console": [
|
||||
true,
|
||||
"debug",
|
||||
"info",
|
||||
"time",
|
||||
"timeEnd",
|
||||
"trace"
|
||||
],
|
||||
"no-construct": true,
|
||||
"no-debugger": true,
|
||||
"no-duplicate-super": true,
|
||||
"no-empty": false,
|
||||
"no-empty-interface": true,
|
||||
"no-eval": true,
|
||||
"no-inferrable-types": [
|
||||
true,
|
||||
"ignore-params"
|
||||
],
|
||||
"no-misused-new": true,
|
||||
"no-non-null-assertion": true,
|
||||
"no-shadowed-variable": true,
|
||||
"no-string-literal": false,
|
||||
"no-string-throw": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-trailing-whitespace": true,
|
||||
"no-unnecessary-initializer": true,
|
||||
"no-unused-expression": true,
|
||||
"no-use-before-declare": true,
|
||||
"no-var-keyword": true,
|
||||
"object-literal-sort-keys": false,
|
||||
"one-line": [
|
||||
true,
|
||||
"check-open-brace",
|
||||
"check-catch",
|
||||
"check-else",
|
||||
"check-whitespace"
|
||||
],
|
||||
"prefer-const": true,
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"radix": true,
|
||||
"semicolon": [
|
||||
true,
|
||||
"always"
|
||||
],
|
||||
"triple-equals": [
|
||||
true,
|
||||
"allow-null-check"
|
||||
],
|
||||
"typedef-whitespace": [
|
||||
true,
|
||||
{
|
||||
"call-signature": "nospace",
|
||||
"index-signature": "nospace",
|
||||
"parameter": "nospace",
|
||||
"property-declaration": "nospace",
|
||||
"variable-declaration": "nospace"
|
||||
}
|
||||
],
|
||||
"unified-signatures": true,
|
||||
"variable-name": false,
|
||||
"whitespace": [
|
||||
true,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type"
|
||||
],
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"app",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"app",
|
||||
"kebab-case"
|
||||
],
|
||||
"no-output-on-prefix": true,
|
||||
"use-input-property-decorator": true,
|
||||
"use-output-property-decorator": true,
|
||||
"use-host-property-decorator": true,
|
||||
"no-input-rename": true,
|
||||
"no-output-rename": true,
|
||||
"use-life-cycle-interface": true,
|
||||
"use-pipe-transform-interface": true,
|
||||
"component-class-suffix": true,
|
||||
"directive-class-suffix": true
|
||||
}
|
||||
}
|
7546
integration/cli-hello-world/yarn.lock
Normal file
7546
integration/cli-hello-world/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
2453
integration/dynamic-compiler/yarn.lock
Normal file
2453
integration/dynamic-compiler/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
2421
integration/hello_world__closure/yarn.lock
Normal file
2421
integration/hello_world__closure/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,7 @@ export class HelloWorld {
|
||||
|
||||
/** @nocollapse */
|
||||
static ngComponentDef: ComponentDef<HelloWorld> = defineComponent({
|
||||
type: HelloWorld,
|
||||
tag: 'hello-world',
|
||||
template: function (ctx: HelloWorld, cm: boolean) {
|
||||
if (cm) {
|
||||
|
2344
integration/hello_world__render3__closure/yarn.lock
Normal file
2344
integration/hello_world__render3__closure/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@ -20,15 +20,14 @@
|
||||
"lite-server": "2.2.2",
|
||||
"protractor": "file:../../node_modules/protractor",
|
||||
"rollup": "0.54.0",
|
||||
"rollup-plugin-angular-optimizer": "0.2.0",
|
||||
"rollup-plugin-commonjs": "8.2.6",
|
||||
"rollup-plugin-node-resolve": "3.0.2",
|
||||
"rollup-plugin-replace": "2.0.0",
|
||||
"rollup-plugin-typescript2": "0.10.0",
|
||||
"rollup-plugin-uglify": "2.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "webdriver-manager update --gecko false --standalone false $CHROMEDRIVER_VERSION_ARG",
|
||||
"rollup": "rollup -c rollup.config.js",
|
||||
"rollup": "tsc && rollup -c rollup.config.js",
|
||||
"test": "yarn run rollup && concurrently \"yarn run serve\" \"yarn run protractor\" --kill-others --success first",
|
||||
"serve": "lite-server -c e2e/browser.config.json",
|
||||
"preprotractor": "tsc -p e2e",
|
||||
|
@ -1,32 +1,21 @@
|
||||
import buildOptimizer from 'rollup-plugin-angular-optimizer'
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import nodeResolve from 'rollup-plugin-node-resolve';
|
||||
import replace from 'rollup-plugin-replace';
|
||||
import typescript2 from 'rollup-plugin-typescript2';
|
||||
import uglify from 'rollup-plugin-uglify';
|
||||
|
||||
export default {
|
||||
input: `src/index.ts`,
|
||||
input: `built/index.js`,
|
||||
output: {
|
||||
name: 'hw',
|
||||
file: `dist/bundle.js`,
|
||||
format: 'iife',
|
||||
sourcemap: false
|
||||
sourcemap: true
|
||||
},
|
||||
plugins: [
|
||||
typescript2({
|
||||
typescript: require('typescript'),
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true
|
||||
}),
|
||||
replace({
|
||||
delimiters: ['', ''],
|
||||
values: {
|
||||
'/** @class */': '/** @__PURE__ */'
|
||||
}
|
||||
}),
|
||||
buildOptimizer(),
|
||||
nodeResolve({jsnext: true, module: true}),
|
||||
commonjs({
|
||||
include: 'node_modules/rxjs/**',
|
||||
include: 'node_modules/rxjs/**'
|
||||
}),
|
||||
uglify({
|
||||
mangle: true,
|
||||
|
@ -14,6 +14,7 @@ export class HelloWorld {
|
||||
|
||||
/** @nocollapse */
|
||||
static ngComponentDef: ComponentDef<HelloWorld> = defineComponent({
|
||||
type: HelloWorld,
|
||||
tag: 'hello-world',
|
||||
template: function (ctx: HelloWorld, cm: boolean) {
|
||||
if (cm) {
|
||||
|
@ -11,19 +11,15 @@
|
||||
"strict": true,
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"outDir": "built",
|
||||
"rootDir": ".",
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"types": []
|
||||
"types": [],
|
||||
"lib": ["es2015", "dom"]
|
||||
},
|
||||
|
||||
"exclude": [
|
||||
"vendor",
|
||||
"node_modules",
|
||||
"built",
|
||||
"dist",
|
||||
"e2e"
|
||||
"files": [
|
||||
"src/index.ts"
|
||||
]
|
||||
}
|
||||
|
2486
integration/hello_world__render3__rollup/yarn.lock
Normal file
2486
integration/hello_world__render3__rollup/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
2337
integration/hello_world__systemjs_umd/yarn.lock
Normal file
2337
integration/hello_world__systemjs_umd/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,8 @@
|
||||
"scripts": {
|
||||
"postinstall": "webdriver-manager update --gecko false --standalone false $CHROMEDRIVER_VERSION_ARG",
|
||||
"closure": "java -jar node_modules/google-closure-compiler/compiler.jar --flagfile closure.conf",
|
||||
"test": "ngc && yarn run closure && concurrently \"yarn run serve\" \"yarn run protractor\" --kill-others --success first",
|
||||
"test": "ngc && yarn run closure && concurrently \"yarn run serve\" \"yarn run protractor\" --kill-others --success first && npm run test-locale-folder",
|
||||
"test-locale-folder": "node test-locale-folder.js",
|
||||
"serve": "lite-server -c e2e/browser.config.json",
|
||||
"preprotractor": "tsc -p e2e",
|
||||
"protractor": "protractor e2e/protractor.config.js"
|
||||
|
14
integration/i18n/test-locale-folder.js
Normal file
14
integration/i18n/test-locale-folder.js
Normal file
@ -0,0 +1,14 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const packageJson = require('@angular/common/package.json');
|
||||
const localesFolder = packageJson['locales'];
|
||||
if (!localesFolder) {
|
||||
throw new Error(`@angular/common/package.json does not contain 'locales' entry.`)
|
||||
}
|
||||
const enLocalePath = `@angular/common/${localesFolder}/en`;
|
||||
try {
|
||||
require.resolve(enLocalePath);
|
||||
} catch (err) {
|
||||
throw new Error(`@angular/common does not contain 'en' locale in ${enLocalePath}.`)
|
||||
}
|
2421
integration/i18n/yarn.lock
Normal file
2421
integration/i18n/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
1008
integration/language_service_plugin/yarn.lock
Normal file
1008
integration/language_service_plugin/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,69 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e -o pipefail
|
||||
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
echo "Angular cli integration create project"
|
||||
echo
|
||||
echo "./ng-cli-create.sh [project-name]"
|
||||
echo
|
||||
else
|
||||
TEMP=`dirname $0`
|
||||
INTEGRATION_DIR=`(cd $TEMP; pwd)`
|
||||
PROJECT=$1
|
||||
PROJECT_DIR=$INTEGRATION_DIR/$PROJECT
|
||||
NG=$INTEGRATION_DIR/.ng-cli/node_modules/.bin/ng
|
||||
(
|
||||
echo "==================="
|
||||
echo Creating $PROJECT...
|
||||
echo "==================="
|
||||
cd $INTEGRATION_DIR
|
||||
rm -rf $PROJECT
|
||||
$NG set --global packageManager=yarn
|
||||
$NG new $PROJECT --skip-install --skip-git
|
||||
echo "==================="
|
||||
echo $PROJECT created
|
||||
echo "==================="
|
||||
)
|
||||
|
||||
|
||||
# By default `ng new` creates a package.json which uses @angular/* from NPM.
|
||||
# Instead we want to use them from the current build so we overwrite theme here.
|
||||
(
|
||||
echo "==================="
|
||||
echo Updating $PROJECT bundles
|
||||
echo "==================="
|
||||
cd $PROJECT_DIR
|
||||
|
||||
sed -i -E 's/ng build/ng build --prod --build-optimizer/g' package.json
|
||||
sed -i -E 's/ng test/ng test --single-run/g' package.json
|
||||
sed -i -E 's/"typescript\"\: \".*\"/"typescript": "2.4.2"/g' package.json
|
||||
|
||||
yarn add \
|
||||
file:../../dist/packages-dist/compiler-cli \
|
||||
file:../../dist/packages-dist/language-service \
|
||||
--save-dev --skip-integrity-check --emoji
|
||||
|
||||
yarn add \
|
||||
file:../../dist/packages-dist/core \
|
||||
file:../../dist/packages-dist/common \
|
||||
file:../../dist/packages-dist/forms \
|
||||
file:../../dist/packages-dist/http \
|
||||
--save --skip-integrity-check --emoji
|
||||
|
||||
# yarn bug: can not install all of them in a single command and it has to be broken into separate invocations.
|
||||
yarn add \
|
||||
file:../../dist/packages-dist/animations \
|
||||
file:../../dist/packages-dist/compiler \
|
||||
file:../../dist/packages-dist/platform-browser \
|
||||
file:../../dist/packages-dist/platform-browser-dynamic \
|
||||
--save --skip-integrity-check --emoji
|
||||
|
||||
yarn install --emoji
|
||||
|
||||
echo "==================="
|
||||
echo $PROJECT created succesfully
|
||||
echo "==================="
|
||||
)
|
||||
fi
|
@ -19,22 +19,6 @@ rm_cache
|
||||
mkdir $cache
|
||||
trap rm_cache EXIT
|
||||
|
||||
# cli-hello-world test is disabled because it uses un-pinned dependencies
|
||||
# TODO(alexeagle): re-enable when it's pinned
|
||||
|
||||
# # We need to install `ng` but don't want to do it globally so we place it into `.ng-cli` folder.
|
||||
# (
|
||||
# mkdir -p .ng-cli
|
||||
# cd .ng-cli
|
||||
|
||||
# # workaround for https://github.com/yarnpkg/yarn/pull/4464 which causes cli to be installed into the root node_modules
|
||||
# echo '{"name": "ng-cli"}' > package.json
|
||||
# yarn init -y
|
||||
|
||||
# yarn add @angular/cli@$ANGULAR_CLI_VERSION --cache-folder ../$cache
|
||||
# )
|
||||
# ./ng-cli-create.sh cli-hello-world
|
||||
|
||||
for testDir in $(ls | grep -v node_modules) ; do
|
||||
[[ -d "$testDir" ]] || continue
|
||||
echo "#################################"
|
||||
@ -42,8 +26,6 @@ for testDir in $(ls | grep -v node_modules) ; do
|
||||
echo "#################################"
|
||||
(
|
||||
cd $testDir
|
||||
# Workaround for https://github.com/yarnpkg/yarn/issues/2256
|
||||
rm -f yarn.lock
|
||||
rm -rf dist
|
||||
yarn install --cache-folder ../$cache
|
||||
yarn test || exit 1
|
||||
@ -52,9 +34,13 @@ for testDir in $(ls | grep -v node_modules) ; do
|
||||
if [[ $testDir == cli-hello-world ]]; then
|
||||
yarn build
|
||||
fi
|
||||
trackPayloadSize "$testDir" "dist/*.js" true false "${thisDir}/_payload-limits.json"
|
||||
if [[ -v TRAVIS ]]; then
|
||||
trackPayloadSize "$testDir" "dist/*.js" true false "${thisDir}/_payload-limits.json"
|
||||
fi
|
||||
fi
|
||||
)
|
||||
done
|
||||
|
||||
trackPayloadSize "umd" "../dist/packages-dist/*/bundles/*.umd.min.js" false false
|
||||
if [[ -v TRAVIS ]]; then
|
||||
trackPayloadSize "umd" "../dist/packages-dist/*/bundles/*.umd.min.js" false false
|
||||
fi
|
||||
|
1042
integration/typings_test_ts24/yarn.lock
Normal file
1042
integration/typings_test_ts24/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
1042
integration/typings_test_ts25/yarn.lock
Normal file
1042
integration/typings_test_ts25/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
1042
integration/typings_test_ts26/yarn.lock
Normal file
1042
integration/typings_test_ts26/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@ -16,6 +16,7 @@ export class LargeTableComponent {
|
||||
|
||||
/** @nocollapse */
|
||||
static ngComponentDef: ComponentDef<LargeTableComponent> = defineComponent({
|
||||
type: LargeTableComponent,
|
||||
tag: 'largetable',
|
||||
template: function(ctx: LargeTableComponent, cm: boolean) {
|
||||
if (cm) {
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ɵC as C, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵb1 as b1, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as _detectChanges, ɵe as e, ɵp as p, ɵs as s, ɵt as t, ɵv as v} from '@angular/core';
|
||||
import {ɵC as C, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵb1 as b1, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as _detectChanges, ɵe as e, ɵp as p, ɵr as r, ɵs as s, ɵt as t, ɵv as v} from '@angular/core';
|
||||
import {ComponentDef} from '@angular/core/src/render3/interfaces/definition';
|
||||
|
||||
import {TreeNode, buildTree, emptyTree} from '../util';
|
||||
@ -36,6 +36,7 @@ export class TreeComponent {
|
||||
|
||||
/** @nocollapse */
|
||||
static ngComponentDef: ComponentDef<TreeComponent> = defineComponent({
|
||||
type: TreeComponent,
|
||||
tag: 'tree',
|
||||
template: function(ctx: TreeComponent, cm: boolean) {
|
||||
if (cm) {
|
||||
@ -58,7 +59,7 @@ export class TreeComponent {
|
||||
}
|
||||
p(0, 'data', b(ctx.data.left));
|
||||
TreeComponent.ngComponentDef.h(1, 0);
|
||||
TreeComponent.ngComponentDef.r(1, 0);
|
||||
r(1, 0);
|
||||
}
|
||||
v();
|
||||
}
|
||||
@ -75,7 +76,7 @@ export class TreeComponent {
|
||||
}
|
||||
p(0, 'data', b(ctx.data.right));
|
||||
TreeComponent.ngComponentDef.h(1, 0);
|
||||
TreeComponent.ngComponentDef.r(1, 0);
|
||||
r(1, 0);
|
||||
}
|
||||
v();
|
||||
}
|
||||
@ -92,6 +93,7 @@ export class TreeFunction {
|
||||
|
||||
/** @nocollapse */
|
||||
static ngComponentDef: ComponentDef<TreeFunction> = defineComponent({
|
||||
type: TreeFunction,
|
||||
tag: 'tree',
|
||||
template: function(ctx: TreeFunction, cm: boolean) {
|
||||
// bit of a hack
|
||||
|
@ -27,7 +27,7 @@ nodejs_binary(
|
||||
"@build_bazel_rules_typescript//internal:worker_protocol.proto",
|
||||
],
|
||||
entry_point = "angular/packages/bazel/src/ngc-wrapped/index.js",
|
||||
node_modules = "@build_bazel_rules_typescript_deps//:node_modules",
|
||||
node_modules = "@build_bazel_rules_typescript_tsc_wrapped_deps//:node_modules",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
|
@ -6,16 +6,41 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Inject, ModuleWithProviders, NgModule, Optional} from '@angular/core';
|
||||
import {Injectable, Injector, ModuleWithProviders, NgModule, Optional} from '@angular/core';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
|
||||
import {HttpBackend, HttpHandler} from './backend';
|
||||
import {HttpClient} from './client';
|
||||
import {HTTP_INTERCEPTORS, HttpInterceptor, HttpInterceptorHandler, NoopInterceptor} from './interceptor';
|
||||
import {JsonpCallbackContext, JsonpClientBackend, JsonpInterceptor} from './jsonp';
|
||||
import {HttpRequest} from './request';
|
||||
import {HttpEvent} from './response';
|
||||
import {BrowserXhr, HttpXhrBackend, XhrFactory} from './xhr';
|
||||
import {HttpXsrfCookieExtractor, HttpXsrfInterceptor, HttpXsrfTokenExtractor, XSRF_COOKIE_NAME, XSRF_HEADER_NAME} from './xsrf';
|
||||
|
||||
/**
|
||||
* An `HttpHandler` that applies a bunch of `HttpInterceptor`s
|
||||
* to a request before passing it to the given `HttpBackend`.
|
||||
*
|
||||
* The interceptors are loaded lazily from the injector, to allow
|
||||
* interceptors to themselves inject classes depending indirectly
|
||||
* on `HttpInterceptingHandler` itself.
|
||||
*/
|
||||
@Injectable()
|
||||
export class HttpInterceptingHandler implements HttpHandler {
|
||||
private chain: HttpHandler|null = null;
|
||||
|
||||
constructor(private backend: HttpBackend, private injector: Injector) {}
|
||||
|
||||
handle(req: HttpRequest<any>): Observable<HttpEvent<any>> {
|
||||
if (this.chain === null) {
|
||||
const interceptors = this.injector.get(HTTP_INTERCEPTORS, []);
|
||||
this.chain = interceptors.reduceRight(
|
||||
(next, interceptor) => new HttpInterceptorHandler(next, interceptor), this.backend);
|
||||
}
|
||||
return this.chain.handle(req);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an `HttpHandler` that applies a bunch of `HttpInterceptor`s
|
||||
@ -118,13 +143,7 @@ export class HttpClientXsrfModule {
|
||||
],
|
||||
providers: [
|
||||
HttpClient,
|
||||
// HttpHandler is the backend + interceptors and is constructed
|
||||
// using the interceptingHandler factory function.
|
||||
{
|
||||
provide: HttpHandler,
|
||||
useFactory: interceptingHandler,
|
||||
deps: [HttpBackend, [new Optional(), new Inject(HTTP_INTERCEPTORS)]],
|
||||
},
|
||||
{provide: HttpHandler, useClass: HttpInterceptingHandler},
|
||||
HttpXhrBackend,
|
||||
{provide: HttpBackend, useExisting: HttpXhrBackend},
|
||||
BrowserXhr,
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
import {Injector} from '@angular/core';
|
||||
import {Injectable, Injector} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
|
||||
@ -47,6 +47,15 @@ class InterceptorB extends TestInterceptor {
|
||||
constructor() { super('B'); }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class ReentrantInterceptor implements HttpInterceptor {
|
||||
constructor(private client: HttpClient) {}
|
||||
|
||||
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||
return next.handle(req);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
describe('HttpClientModule', () => {
|
||||
let injector: Injector;
|
||||
@ -84,5 +93,16 @@ class InterceptorB extends TestInterceptor {
|
||||
});
|
||||
injector.get(HttpTestingController).expectOne('/test').flush('ok!');
|
||||
});
|
||||
it('allows interceptors to inject HttpClient', (done: DoneFn) => {
|
||||
TestBed.resetTestingModule();
|
||||
injector = TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule],
|
||||
providers: [
|
||||
{provide: HTTP_INTERCEPTORS, useClass: ReentrantInterceptor, multi: true},
|
||||
],
|
||||
});
|
||||
injector.get(HttpClient).get('/test').subscribe(() => { done(); });
|
||||
injector.get(HttpTestingController).expectOne('/test').flush('ok!');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@
|
||||
"dependencies": {
|
||||
"tslib": "^1.7.1"
|
||||
},
|
||||
"locales": "locales",
|
||||
"peerDependencies": {
|
||||
"rxjs": "^5.5.0",
|
||||
"@angular/core": "0.0.0-PLACEHOLDER"
|
||||
|
@ -24,7 +24,7 @@ import {Directive, EmbeddedViewRef, Input, OnChanges, SimpleChange, SimpleChange
|
||||
* `[ngTemplateOutletContext]` should be an object, the object's keys will be available for binding
|
||||
* by the local template `let` declarations.
|
||||
*
|
||||
* Note: using the key `$implicit` in the context object will set it's value as default.
|
||||
* Note: using the key `$implicit` in the context object will set its value as default.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
|
@ -14,6 +14,7 @@ import {LocationStrategy} from './location_strategy';
|
||||
/** @experimental */
|
||||
export interface PopStateEvent {
|
||||
pop?: boolean;
|
||||
state?: any;
|
||||
type?: string;
|
||||
url?: string;
|
||||
}
|
||||
@ -56,6 +57,7 @@ export class Location {
|
||||
this._subject.emit({
|
||||
'url': this.path(true),
|
||||
'pop': true,
|
||||
'state': ev.state,
|
||||
'type': ev.type,
|
||||
});
|
||||
});
|
||||
@ -103,16 +105,16 @@ export class Location {
|
||||
* Changes the browsers URL to the normalized version of the given URL, and pushes a
|
||||
* new item onto the platform's history.
|
||||
*/
|
||||
go(path: string, query: string = ''): void {
|
||||
this._platformStrategy.pushState(null, '', path, query);
|
||||
go(path: string, query: string = '', state: any = null): void {
|
||||
this._platformStrategy.pushState(state, '', path, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the browsers URL to the normalized version of the given URL, and replaces
|
||||
* the top item on the platform's history stack.
|
||||
*/
|
||||
replaceState(path: string, query: string = ''): void {
|
||||
this._platformStrategy.replaceState(null, '', path, query);
|
||||
replaceState(path: string, query: string = '', state: any = null): void {
|
||||
this._platformStrategy.replaceState(state, '', path, query);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +58,10 @@ export const LOCATION_INITIALIZED = new InjectionToken<Promise<any>>('Location I
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export interface LocationChangeEvent { type: string; }
|
||||
export interface LocationChangeEvent {
|
||||
type: string;
|
||||
state: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental
|
||||
|
@ -18,8 +18,8 @@ import localeTh from '@angular/common/locales/th';
|
||||
import localeAr from '@angular/common/locales/ar';
|
||||
|
||||
{
|
||||
describe('DatePipe', () => {
|
||||
let date: Date;
|
||||
let date: Date;
|
||||
xdescribe('DatePipe', () => {
|
||||
const isoStringWithoutTime = '2015-01-01';
|
||||
let pipe: DatePipe;
|
||||
|
||||
|
@ -12,7 +12,7 @@ import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_refle
|
||||
import {browserDetection} from '@angular/platform-browser/testing/src/browser_util';
|
||||
|
||||
{
|
||||
describe('DeprecatedDatePipe', () => {
|
||||
xdescribe('DeprecatedDatePipe', () => {
|
||||
let date: Date;
|
||||
const isoStringWithoutTime = '2015-01-01';
|
||||
let pipe: DeprecatedDatePipe;
|
||||
|
@ -19,7 +19,7 @@ import {ISubscription} from 'rxjs/Subscription';
|
||||
@Injectable()
|
||||
export class SpyLocation implements Location {
|
||||
urlChanges: string[] = [];
|
||||
private _history: LocationState[] = [new LocationState('', '')];
|
||||
private _history: LocationState[] = [new LocationState('', '', null)];
|
||||
private _historyIndex: number = 0;
|
||||
/** @internal */
|
||||
_subject: EventEmitter<any> = new EventEmitter();
|
||||
@ -34,6 +34,8 @@ export class SpyLocation implements Location {
|
||||
|
||||
path(): string { return this._history[this._historyIndex].path; }
|
||||
|
||||
private state(): string { return this._history[this._historyIndex].state; }
|
||||
|
||||
isCurrentPathEqualTo(path: string, query: string = ''): boolean {
|
||||
const givenPath = path.endsWith('/') ? path.substring(0, path.length - 1) : path;
|
||||
const currPath =
|
||||
@ -60,13 +62,13 @@ export class SpyLocation implements Location {
|
||||
return this._baseHref + url;
|
||||
}
|
||||
|
||||
go(path: string, query: string = '') {
|
||||
go(path: string, query: string = '', state: any = null) {
|
||||
path = this.prepareExternalUrl(path);
|
||||
|
||||
if (this._historyIndex > 0) {
|
||||
this._history.splice(this._historyIndex + 1);
|
||||
}
|
||||
this._history.push(new LocationState(path, query));
|
||||
this._history.push(new LocationState(path, query, state));
|
||||
this._historyIndex = this._history.length - 1;
|
||||
|
||||
const locationState = this._history[this._historyIndex - 1];
|
||||
@ -79,7 +81,7 @@ export class SpyLocation implements Location {
|
||||
this._subject.emit({'url': url, 'pop': false});
|
||||
}
|
||||
|
||||
replaceState(path: string, query: string = '') {
|
||||
replaceState(path: string, query: string = '', state: any = null) {
|
||||
path = this.prepareExternalUrl(path);
|
||||
|
||||
const history = this._history[this._historyIndex];
|
||||
@ -89,6 +91,7 @@ export class SpyLocation implements Location {
|
||||
|
||||
history.path = path;
|
||||
history.query = query;
|
||||
history.state = state;
|
||||
|
||||
const url = path + (query.length > 0 ? ('?' + query) : '');
|
||||
this.urlChanges.push('replace: ' + url);
|
||||
@ -97,14 +100,14 @@ export class SpyLocation implements Location {
|
||||
forward() {
|
||||
if (this._historyIndex < (this._history.length - 1)) {
|
||||
this._historyIndex++;
|
||||
this._subject.emit({'url': this.path(), 'pop': true});
|
||||
this._subject.emit({'url': this.path(), 'state': this.state(), 'pop': true});
|
||||
}
|
||||
}
|
||||
|
||||
back() {
|
||||
if (this._historyIndex > 0) {
|
||||
this._historyIndex--;
|
||||
this._subject.emit({'url': this.path(), 'pop': true});
|
||||
this._subject.emit({'url': this.path(), 'state': this.state(), 'pop': true});
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,10 +121,5 @@ export class SpyLocation implements Location {
|
||||
}
|
||||
|
||||
class LocationState {
|
||||
path: string;
|
||||
query: string;
|
||||
constructor(path: string, query: string) {
|
||||
this.path = path;
|
||||
this.query = query;
|
||||
}
|
||||
constructor(public path: string, public query: string, public state: any) {}
|
||||
}
|
||||
|
@ -1878,5 +1878,68 @@ describe('ngc transformer command-line', () => {
|
||||
expect(exitCode).toBe(0, 'Compile failed');
|
||||
expect(emittedFile('hello-world.js')).toContain('ngComponentDef');
|
||||
});
|
||||
|
||||
it('should emit an injection of a string token', () => {
|
||||
write('tsconfig.json', `{
|
||||
"extends": "./tsconfig-base.json",
|
||||
"files": ["hello-world.ts"],
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": true
|
||||
}
|
||||
}`);
|
||||
|
||||
write('hello-world.ts', `
|
||||
import {Component, Inject, NgModule} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'hello-world',
|
||||
template: 'Hello, world!'
|
||||
})
|
||||
export class HelloWorldComponent {
|
||||
constructor (@Inject('test') private test: string) {}
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [HelloWorldComponent],
|
||||
providers: [
|
||||
{provide: 'test', useValue: 'test'}
|
||||
]
|
||||
})
|
||||
export class HelloWorldModule {}
|
||||
`);
|
||||
const errors: string[] = [];
|
||||
const exitCode = main(['-p', path.join(basePath, 'tsconfig.json')], msg => errors.push(msg));
|
||||
expect(exitCode).toBe(0, `Compile failed:\n${errors.join('\n ')}`);
|
||||
expect(emittedFile('hello-world.js')).toContain('ngComponentDef');
|
||||
});
|
||||
|
||||
it('should emit an example that uses the E() instruction', () => {
|
||||
write('tsconfig.json', `{
|
||||
"extends": "./tsconfig-base.json",
|
||||
"files": ["hello-world.ts"],
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": true
|
||||
}
|
||||
}`);
|
||||
|
||||
write('hello-world.ts', `
|
||||
import {Component, NgModule} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'hello-world',
|
||||
template: '<h1><div style="text-align:center"> Hello, {{name}}! </div></h1> '
|
||||
})
|
||||
export class HelloWorldComponent {
|
||||
name = 'World';
|
||||
}
|
||||
|
||||
@NgModule({declarations: [HelloWorldComponent]})
|
||||
export class HelloWorldModule {}
|
||||
`);
|
||||
const errors: string[] = [];
|
||||
const exitCode = main(['-p', path.join(basePath, 'tsconfig.json')], msg => errors.push(msg));
|
||||
expect(exitCode).toBe(0, `Compile failed:\n${errors.join('\n ')}`);
|
||||
expect(emittedFile('hello-world.js')).toContain('ngComponentDef');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -27,7 +27,7 @@ class FixupExpression extends o.Expression {
|
||||
shared: boolean;
|
||||
|
||||
visitExpression(visitor: o.ExpressionVisitor, context: any): any {
|
||||
this.resolved.visitExpression(visitor, context);
|
||||
return this.resolved.visitExpression(visitor, context);
|
||||
}
|
||||
|
||||
isEquivalent(e: o.Expression): boolean {
|
||||
|
@ -66,6 +66,9 @@ export class Identifiers {
|
||||
|
||||
static memory: o.ExternalReference = {name: 'ɵm', moduleName: CORE};
|
||||
|
||||
static projection: o.ExternalReference = {name: 'ɵP', moduleName: CORE};
|
||||
static projectionDef: o.ExternalReference = {name: 'ɵpD', moduleName: CORE};
|
||||
|
||||
static refreshComponent: o.ExternalReference = {name: 'ɵr', moduleName: CORE};
|
||||
|
||||
static directiveLifeCycle: o.ExternalReference = {name: 'ɵl', moduleName: CORE};
|
||||
|
@ -15,11 +15,13 @@ import {Identifiers} from '../identifiers';
|
||||
import * as o from '../output/output_ast';
|
||||
import {ParseSourceSpan} from '../parse_util';
|
||||
import {CssSelector} from '../selector';
|
||||
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ProviderAst, QueryMatch, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '../template_parser/template_ast';
|
||||
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ProviderAst, QueryMatch, RecursiveTemplateAstVisitor, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '../template_parser/template_ast';
|
||||
import {OutputContext, error} from '../util';
|
||||
|
||||
import {Identifiers as R3} from './r3_identifiers';
|
||||
|
||||
|
||||
|
||||
/** Name of the context parameter passed into a template function */
|
||||
const CONTEXT_NAME = 'ctx';
|
||||
|
||||
@ -32,10 +34,17 @@ const TEMPORARY_NAME = '_t';
|
||||
/** The prefix reference variables */
|
||||
const REFERENCE_PREFIX = '_r';
|
||||
|
||||
/** The name of the implicit context reference */
|
||||
const IMPLICIT_REFERENCE = '$implicit';
|
||||
|
||||
export function compileDirective(
|
||||
outputCtx: OutputContext, directive: CompileDirectiveMetadata, reflector: CompileReflector) {
|
||||
const definitionMapValues: {key: string, quoted: boolean, value: o.Expression}[] = [];
|
||||
|
||||
// e.g. 'type: MyDirective`
|
||||
definitionMapValues.push(
|
||||
{key: 'type', value: outputCtx.importExpr(directive.type.reference), quoted: false});
|
||||
|
||||
// e.g. `factory: () => new MyApp(injectElementRef())`
|
||||
const templateFactory = createFactory(directive.type, outputCtx, reflector);
|
||||
definitionMapValues.push({key: 'factory', value: templateFactory, quoted: false});
|
||||
@ -63,7 +72,11 @@ export function compileComponent(
|
||||
reflector: CompileReflector) {
|
||||
const definitionMapValues: {key: string, quoted: boolean, value: o.Expression}[] = [];
|
||||
|
||||
// e.g. `tag: 'my-app'
|
||||
// e.g. `type: MyApp`
|
||||
definitionMapValues.push(
|
||||
{key: 'type', value: outputCtx.importExpr(component.type.reference), quoted: false});
|
||||
|
||||
// e.g. `tag: 'my-app'`
|
||||
// This is optional and only included if the first selector of a component has element.
|
||||
const selector = component.selector && CssSelector.parse(component.selector);
|
||||
const firstSelector = selector && selector[0];
|
||||
@ -97,8 +110,8 @@ export function compileComponent(
|
||||
const templateFunctionExpression =
|
||||
new TemplateDefinitionBuilder(
|
||||
outputCtx, outputCtx.constantPool, reflector, CONTEXT_NAME, ROOT_SCOPE.nestedScope(), 0,
|
||||
templateTypeName, templateName)
|
||||
.buildTemplateFunction(template);
|
||||
component.template !.ngContentSelectors, templateTypeName, templateName)
|
||||
.buildTemplateFunction(template, []);
|
||||
definitionMapValues.push({key: 'template', value: templateFunctionExpression, quoted: false});
|
||||
|
||||
|
||||
@ -123,13 +136,15 @@ export function compileComponent(
|
||||
|
||||
// TODO: Remove these when the things are fully supported
|
||||
function unknown<T>(arg: o.Expression | o.Statement | TemplateAst): never {
|
||||
throw new Error(`Builder ${this.constructor.name} is unable to handle ${o.constructor.name} yet`);
|
||||
throw new Error(
|
||||
`Builder ${this.constructor.name} is unable to handle ${arg.constructor.name} yet`);
|
||||
}
|
||||
|
||||
function unsupported(feature: string): never {
|
||||
if (this) {
|
||||
throw new Error(`Builder ${this.constructor.name} doesn't support ${feature} yet`);
|
||||
}
|
||||
throw new Error(`Feature ${feature} is supported yet`);
|
||||
throw new Error(`Feature ${feature} is not supported yet`);
|
||||
}
|
||||
|
||||
const BINDING_INSTRUCTION_MAP: {[index: number]: o.ExternalReference | undefined} = {
|
||||
@ -214,16 +229,57 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
private _hostMode: o.Statement[] = [];
|
||||
private _refreshMode: o.Statement[] = [];
|
||||
private _postfix: o.Statement[] = [];
|
||||
private _contentProjections: Map<NgContentAst, NgContentInfo>;
|
||||
private _projectionDefinitionIndex = 0;
|
||||
private unsupported = unsupported;
|
||||
private invalid = invalid;
|
||||
|
||||
constructor(
|
||||
private outputCtx: OutputContext, private constantPool: ConstantPool,
|
||||
private reflector: CompileReflector, private contextParameter: string,
|
||||
private bindingScope: BindingScope, private level = 0, private contextName: string|null,
|
||||
private templateName: string|null) {}
|
||||
private bindingScope: BindingScope, private level = 0, private ngContentSelectors: string[],
|
||||
private contextName: string|null, private templateName: string|null) {}
|
||||
|
||||
buildTemplateFunction(asts: TemplateAst[], variables: VariableAst[]): o.FunctionExpr {
|
||||
// Create variable bindings
|
||||
for (const variable of variables) {
|
||||
const variableName = variable.name;
|
||||
const expression =
|
||||
o.variable(this.contextParameter).prop(variable.value || IMPLICIT_REFERENCE);
|
||||
const scopedName = this.bindingScope.freshReferenceName();
|
||||
const declaration = o.variable(scopedName).set(expression).toDeclStmt(o.INFERRED_TYPE, [
|
||||
o.StmtModifier.Final
|
||||
]);
|
||||
|
||||
// Add the reference to the local scope.
|
||||
this.bindingScope.set(variableName, scopedName);
|
||||
|
||||
// Declare the local variable in binding mode
|
||||
this._bindingMode.push(declaration);
|
||||
}
|
||||
|
||||
// Collect content projections
|
||||
if (this.ngContentSelectors && this.ngContentSelectors.length > 0) {
|
||||
const contentProjections = getContentProjection(asts, this.ngContentSelectors);
|
||||
this._contentProjections = contentProjections;
|
||||
if (contentProjections.size > 0) {
|
||||
const infos: R3CssSelector[] = [];
|
||||
Array.from(contentProjections.values()).forEach(info => {
|
||||
if (info.selector) {
|
||||
infos[info.index - 1] = info.selector;
|
||||
}
|
||||
});
|
||||
const projectionIndex = this._projectionDefinitionIndex = this.allocateDataSlot();
|
||||
const parameters: o.Expression[] = [o.literal(projectionIndex)];
|
||||
!infos.some(value => !value) || error(`content project information skipped an index`);
|
||||
if (infos.length > 1) {
|
||||
parameters.push(this.outputCtx.constantPool.getConstLiteral(
|
||||
asLiteral(infos), /* forceShared */ true));
|
||||
}
|
||||
this.instruction(this._creationMode, null, R3.projectionDef, ...parameters);
|
||||
}
|
||||
}
|
||||
|
||||
buildTemplateFunction(asts: TemplateAst[]): o.FunctionExpr {
|
||||
templateVisitAll(this, asts);
|
||||
|
||||
return o.fn(
|
||||
@ -254,8 +310,16 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
|
||||
getLocal(name: string): o.Expression|null { return this.bindingScope.get(name); }
|
||||
|
||||
// TODO(chuckj): Implement ng-content
|
||||
visitNgContent = unknown;
|
||||
visitNgContent(ast: NgContentAst) {
|
||||
const info = this._contentProjections.get(ast) !;
|
||||
info || error(`Expected ${ast.sourceSpan} to be included in content projection collection`);
|
||||
const slot = this.allocateDataSlot();
|
||||
const parameters = [o.literal(slot), o.literal(this._projectionDefinitionIndex)];
|
||||
if (info.index !== 0) {
|
||||
parameters.push(o.literal(info.index));
|
||||
}
|
||||
this.instruction(this._creationMode, ast.sourceSpan, R3.projection, ...parameters);
|
||||
}
|
||||
|
||||
private _computeDirectivesArray(directives: DirectiveAst[]) {
|
||||
const directiveIndexMap = new Map<any, number>();
|
||||
@ -395,8 +459,9 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
this, implicit, input.value, this.bindingContext(), BindingForm.TrySimple, interpolate);
|
||||
this._bindingMode.push(...convertedBinding.stmts);
|
||||
this.instruction(
|
||||
this._bindingMode, directive.sourceSpan, R3.elementProperty,
|
||||
o.literal(input.templateName), o.literal(nodeIndex), convertedBinding.currValExpr);
|
||||
this._bindingMode, directive.sourceSpan, R3.elementProperty, o.literal(nodeIndex),
|
||||
o.literal(input.templateName),
|
||||
o.importExpr(R3.bind).callFn([convertedBinding.currValExpr]));
|
||||
}
|
||||
|
||||
// e.g. TodoComponentDef.r(0, 0);
|
||||
@ -444,8 +509,9 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
// Create the template function
|
||||
const templateVisitor = new TemplateDefinitionBuilder(
|
||||
this.outputCtx, this.constantPool, this.reflector, templateContext,
|
||||
this.bindingScope.nestedScope(), this.level + 1, contextName, templateName);
|
||||
const templateFunctionExpr = templateVisitor.buildTemplateFunction(ast.children);
|
||||
this.bindingScope.nestedScope(), this.level + 1, this.ngContentSelectors, contextName,
|
||||
templateName);
|
||||
const templateFunctionExpr = templateVisitor.buildTemplateFunction(ast.children, ast.variables);
|
||||
this._postfix.push(templateFunctionExpr.toDeclStmt(templateName, null));
|
||||
}
|
||||
|
||||
@ -483,7 +549,7 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver {
|
||||
private bindingContext() { return `${this._bindingContext++}`; }
|
||||
|
||||
private instruction(
|
||||
statements: o.Statement[], span: ParseSourceSpan, reference: o.ExternalReference,
|
||||
statements: o.Statement[], span: ParseSourceSpan|null, reference: o.ExternalReference,
|
||||
...params: o.Expression[]) {
|
||||
statements.push(o.importExpr(reference, null, span).callFn(params, span).toStmt());
|
||||
}
|
||||
@ -542,7 +608,9 @@ function createFactory(
|
||||
} else if (tokenRef === viewContainerRef) {
|
||||
args.push(o.importExpr(R3.injectViewContainerRef).callFn([]));
|
||||
} else {
|
||||
args.push(o.importExpr(R3.inject).callFn([outputCtx.importExpr(token)]));
|
||||
const value =
|
||||
token.identifier != null ? outputCtx.importExpr(tokenRef) : o.literal(tokenRef);
|
||||
args.push(o.importExpr(R3.inject).callFn([value]));
|
||||
}
|
||||
} else {
|
||||
unsupported('dependency without a token');
|
||||
@ -563,3 +631,68 @@ function invalid<T>(arg: o.Expression | o.Statement | TemplateAst): never {
|
||||
function findComponent(directives: DirectiveAst[]): DirectiveAst|undefined {
|
||||
return directives.filter(directive => directive.directive.isComponent)[0];
|
||||
}
|
||||
|
||||
interface NgContentInfo {
|
||||
index: number;
|
||||
selector?: R3CssSelector;
|
||||
}
|
||||
|
||||
class ContentProjectionVisitor extends RecursiveTemplateAstVisitor {
|
||||
private index = 1;
|
||||
constructor(
|
||||
private projectionMap: Map<NgContentAst, NgContentInfo>,
|
||||
private ngContentSelectors: string[]) {
|
||||
super();
|
||||
}
|
||||
|
||||
visitNgContent(ast: NgContentAst) {
|
||||
const selectorText = this.ngContentSelectors[ast.index];
|
||||
selectorText != null || error(`could not find selector for index ${ast.index} in ${ast}`);
|
||||
if (!selectorText || selectorText === '*') {
|
||||
this.projectionMap.set(ast, {index: 0});
|
||||
} else {
|
||||
const cssSelectors = CssSelector.parse(selectorText);
|
||||
this.projectionMap.set(
|
||||
ast, {index: this.index++, selector: parseSelectorsToR3Selector(cssSelectors)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getContentProjection(asts: TemplateAst[], ngContentSelectors: string[]) {
|
||||
const projectIndexMap = new Map<NgContentAst, NgContentInfo>();
|
||||
const visitor = new ContentProjectionVisitor(projectIndexMap, ngContentSelectors);
|
||||
templateVisitAll(visitor, asts);
|
||||
return projectIndexMap;
|
||||
}
|
||||
|
||||
// These are a copy the CSS types from core/src/render3/interfaces/projection.ts
|
||||
// They are duplicated here as they cannot be directly referenced from core.
|
||||
type R3SimpleCssSelector = (string | null)[];
|
||||
type R3CssSelectorWithNegations =
|
||||
[R3SimpleCssSelector, null] | [R3SimpleCssSelector, R3SimpleCssSelector];
|
||||
type R3CssSelector = R3CssSelectorWithNegations[];
|
||||
|
||||
function parserSelectorToSimpleSelector(selector: CssSelector): R3SimpleCssSelector {
|
||||
const classes =
|
||||
selector.classNames && selector.classNames.length ? ['class', ...selector.classNames] : [];
|
||||
return [selector.element, ...selector.attrs, ...classes];
|
||||
}
|
||||
|
||||
function parserSelectorToR3Selector(selector: CssSelector): R3CssSelectorWithNegations {
|
||||
const positive = parserSelectorToSimpleSelector(selector);
|
||||
const negative = selector.notSelectors && selector.notSelectors.length &&
|
||||
parserSelectorToSimpleSelector(selector.notSelectors[0]);
|
||||
|
||||
return negative ? [positive, negative] : [positive, null];
|
||||
}
|
||||
|
||||
function parseSelectorsToR3Selector(selectors: CssSelector[]): R3CssSelector {
|
||||
return selectors.map(parserSelectorToR3Selector);
|
||||
}
|
||||
|
||||
function asLiteral(value: any): o.Expression {
|
||||
if (Array.isArray(value)) {
|
||||
return o.literalArr(value.map(asLiteral));
|
||||
}
|
||||
return o.literal(value, o.INFERRED_TYPE);
|
||||
}
|
||||
|
@ -178,6 +178,7 @@ describe('r3_view_compiler', () => {
|
||||
// ChildComponent definition should be:
|
||||
const ChildComponentDefinition = `
|
||||
static ngComponentDef = IDENT.ɵdefineComponent({
|
||||
type: ChildComponent,
|
||||
tag: 'child',
|
||||
factory: function ChildComponent_Factory() { return new ChildComponent(); },
|
||||
template: function ChildComponent_Template(ctx: IDENT, cm: IDENT) {
|
||||
@ -190,6 +191,7 @@ describe('r3_view_compiler', () => {
|
||||
// SomeDirective definition should be:
|
||||
const SomeDirectiveDefinition = `
|
||||
static ngDirectiveDef = IDENT.ɵdefineDirective({
|
||||
type: SomeDirective,
|
||||
factory: function SomeDirective_Factory() {return new SomeDirective(); }
|
||||
});
|
||||
`;
|
||||
@ -197,6 +199,7 @@ describe('r3_view_compiler', () => {
|
||||
// MyComponent definition should be:
|
||||
const MyComponentDefinition = `
|
||||
static ngComponentDef = IDENT.ɵdefineComponent({
|
||||
type: MyComponent,
|
||||
tag: 'my-component',
|
||||
factory: function MyComponent_Factory() { return new MyComponent(); },
|
||||
template: function MyComponent_Template(ctx: IDENT, cm: IDENT) {
|
||||
@ -253,10 +256,12 @@ describe('r3_view_compiler', () => {
|
||||
|
||||
const IfDirectiveDefinition = `
|
||||
static ngDirectiveDef = IDENT.ɵdefineDirective({
|
||||
type: IfDirective,
|
||||
factory: function IfDirective_Factory() { return new IfDirective(IDENT.ɵinjectTemplateRef()); }
|
||||
});`;
|
||||
const MyComponentDefinition = `
|
||||
static ngComponentDef = IDENT.ɵdefineComponent({
|
||||
type: MyComponent,
|
||||
tag: 'my-component',
|
||||
factory: function MyComponent_Factory() { return new MyComponent(); },
|
||||
template: function MyComponent_Template(ctx: IDENT, cm: IDENT) {
|
||||
@ -292,6 +297,82 @@ describe('r3_view_compiler', () => {
|
||||
expectEmit(source, directives, 'Incorrect shared directive constant');
|
||||
});
|
||||
|
||||
it('should support content projection', () => {
|
||||
const files = {
|
||||
app: {
|
||||
'spec.ts': `
|
||||
import {Component, Directive, NgModule, TemplateRef} from '@angular/core';
|
||||
|
||||
@Component({selector: 'simple', template: '<div><ng-content></ng-content></div>'})
|
||||
export class SimpleComponent {}
|
||||
|
||||
@Component({
|
||||
selector: 'complex',
|
||||
template: \`
|
||||
<div id="first"><ng-content select="span[title=toFirst]"></ng-content></div>
|
||||
<div id="second"><ng-content select="span[title=toSecond]"></ng-content></div>\`
|
||||
})
|
||||
export class ComplexComponent { }
|
||||
|
||||
@NgModule({declarations: [SimpleComponent, ComplexComponent]})
|
||||
export class MyModule {}
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: '<simple>content</simple> <complex></complex>'
|
||||
})
|
||||
export class MyApp {}
|
||||
`
|
||||
}
|
||||
};
|
||||
|
||||
const SimpleComponentDefinition = `
|
||||
static ngComponentDef = IDENT.ɵdefineComponent({
|
||||
type: SimpleComponent,
|
||||
tag: 'simple',
|
||||
factory: function SimpleComponent_Factory() { return new SimpleComponent(); },
|
||||
template: function SimpleComponent_Template(ctx: IDENT, cm: IDENT) {
|
||||
if (cm) {
|
||||
IDENT.ɵpD(0);
|
||||
IDENT.ɵE(1, 'div');
|
||||
IDENT.ɵP(2, 0);
|
||||
IDENT.ɵe();
|
||||
}
|
||||
}
|
||||
});`;
|
||||
|
||||
const ComplexComponentDefinition = `
|
||||
static ngComponentDef = IDENT.ɵdefineComponent({
|
||||
type: ComplexComponent,
|
||||
tag: 'complex',
|
||||
factory: function ComplexComponent_Factory() { return new ComplexComponent(); },
|
||||
template: function ComplexComponent_Template(ctx: IDENT, cm: IDENT) {
|
||||
if (cm) {
|
||||
IDENT.ɵpD(0, IDENT);
|
||||
IDENT.ɵE(1, 'div', IDENT);
|
||||
IDENT.ɵP(2, 0, 1);
|
||||
IDENT.ɵe();
|
||||
IDENT.ɵE(3, 'div', IDENT);
|
||||
IDENT.ɵP(4, 0, 2);
|
||||
IDENT.ɵe();
|
||||
}
|
||||
}
|
||||
});
|
||||
`;
|
||||
|
||||
const ComplexComponent_ProjectionConst = `
|
||||
const IDENT = [[[['span', 'title', 'tofirst'], null]], [[['span', 'title', 'tosecond'], null]]];
|
||||
`;
|
||||
|
||||
const result = compile(files, angularFiles);
|
||||
const source = result.source;
|
||||
|
||||
expectEmit(result.source, SimpleComponentDefinition, 'Incorrect SimpleComponent definition');
|
||||
expectEmit(
|
||||
result.source, ComplexComponentDefinition, 'Incorrect ComplexComponent definition');
|
||||
expectEmit(result.source, ComplexComponent_ProjectionConst, 'Incorrect projection const');
|
||||
});
|
||||
|
||||
it('local reference', () => {
|
||||
const files = {
|
||||
app: {
|
||||
@ -309,6 +390,7 @@ describe('r3_view_compiler', () => {
|
||||
|
||||
const MyComponentDefinition = `
|
||||
static ngComponentDef = IDENT.ɵdefineComponent({
|
||||
type: MyComponent,
|
||||
tag: 'my-component',
|
||||
factory: function MyComponent_Factory() { return new MyComponent(); },
|
||||
template: function MyComponent_Template(ctx: IDENT, cm: IDENT) {
|
||||
@ -331,6 +413,226 @@ describe('r3_view_compiler', () => {
|
||||
expectEmit(source, MyComponentDefinition, 'Incorrect MyComponent.ngComponentDef');
|
||||
expectEmit(source, locals, 'Incorrect locals constant definition');
|
||||
});
|
||||
|
||||
describe('template variables', () => {
|
||||
const shared = {
|
||||
shared: {
|
||||
'for_of.ts': `
|
||||
import {Directive, Input, SimpleChanges, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||
|
||||
export interface ForOfContext {
|
||||
$implicit: any;
|
||||
index: number;
|
||||
even: boolean;
|
||||
odd: boolean;
|
||||
}
|
||||
|
||||
@Directive({selector: '[forOf]'})
|
||||
export class ForOfDirective {
|
||||
private previous: any[];
|
||||
|
||||
constructor(private view: ViewContainerRef, private template: TemplateRef<any>) {}
|
||||
|
||||
@Input() forOf: any[];
|
||||
|
||||
ngOnChanges(simpleChanges: SimpleChanges) {
|
||||
if ('forOf' in simpleChanges) {
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
|
||||
ngDoCheck(): void {
|
||||
const previous = this.previous;
|
||||
const current = this.forOf;
|
||||
if (!previous || previous.length != current.length ||
|
||||
previous.some((value: any, index: number) => current[index] !== previous[index])) {
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
|
||||
private update() {
|
||||
// TODO(chuckj): Not implemented yet
|
||||
// this.view.clear();
|
||||
if (this.forOf) {
|
||||
const current = this.forOf;
|
||||
for (let i = 0; i < current.length; i++) {
|
||||
const context = {$implicit: current[i], index: i, even: i % 2 == 0, odd: i % 2 == 1};
|
||||
// TODO(chuckj): Not implemented yet
|
||||
// this.view.createEmbeddedView(this.template, context);
|
||||
}
|
||||
this.previous = [...this.forOf];
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
};
|
||||
|
||||
it('should support a let variable and reference', () => {
|
||||
const files = {
|
||||
app: {
|
||||
...shared,
|
||||
'spec.ts': `
|
||||
import {Component, NgModule} from '@angular/core';
|
||||
import {ForOfDirective} from './shared/for_of';
|
||||
|
||||
@Component({
|
||||
selector: 'my-component',
|
||||
template: \`<ul><li *for="let item of items">{{item.name}}</li></ul>\`
|
||||
})
|
||||
export class MyComponent {
|
||||
items = [{name: 'one'}, {name: 'two'}];
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [MyComponent, ForOfDirective]
|
||||
})
|
||||
export class MyModule {}
|
||||
`
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(chuckj): Enforce this when the directives are specified
|
||||
const ForDirectiveDefinition = `
|
||||
static ngDirectiveDef = IDENT.ɵdefineDirective({
|
||||
factory: function ForOfDirective_Factory() {
|
||||
return new ForOfDirective(IDENT.ɵinjectViewContainerRef(), IDENT.ɵinjectTemplateRef());
|
||||
},
|
||||
features: [IDENT.ɵNgOnChangesFeature(NgForOf)],
|
||||
refresh: function ForOfDirective_Refresh(directiveIndex: IDENT, elementIndex: IDENT) {
|
||||
IDENT.ɵm<ForOfDirective>(directiveIndex).ngDoCheck();
|
||||
},
|
||||
inputs: {forOf: 'forOf'}
|
||||
});
|
||||
`;
|
||||
|
||||
const MyComponentDefinition = `
|
||||
static ngComponentDef = IDENT.ɵdefineComponent({
|
||||
type: MyComponent,
|
||||
tag: 'my-component',
|
||||
factory: function MyComponent_Factory() { return new MyComponent(); },
|
||||
template: function MyComponent_Template(ctx: IDENT, cm: IDENT) {
|
||||
if (cm) {
|
||||
IDENT.ɵE(0, 'ul');
|
||||
IDENT.ɵC(1, IDENT, MyComponent_ForOfDirective_Template_1);
|
||||
IDENT.ɵe();
|
||||
}
|
||||
IDENT.ɵp(1, 'forOf', IDENT.ɵb(ctx.items));
|
||||
IDENT.ɵcR(1);
|
||||
ForOfDirective.ngDirectiveDef.r(2, 1);
|
||||
IDENT.ɵcr();
|
||||
|
||||
function MyComponent_ForOfDirective_Template_1(ctx0: IDENT, cm: IDENT) {
|
||||
if (cm) {
|
||||
IDENT.ɵE(0, 'li');
|
||||
IDENT.ɵT(1);
|
||||
IDENT.ɵe();
|
||||
}
|
||||
const IDENT = ctx0.$implicit;
|
||||
IDENT.ɵt(1, IDENT.ɵb1('', IDENT.name, ''));
|
||||
}
|
||||
}
|
||||
});
|
||||
`;
|
||||
|
||||
const result = compile(files, angularFiles);
|
||||
const source = result.source;
|
||||
|
||||
// TODO(chuckj): Enforce this when the directives are specified
|
||||
// expectEmit(source, ForDirectiveDefinition, 'Invalid directive definition');
|
||||
expectEmit(source, MyComponentDefinition, 'Invalid component definition');
|
||||
});
|
||||
|
||||
it('should support accessing parent template variables', () => {
|
||||
const files = {
|
||||
app: {
|
||||
...shared,
|
||||
'spec.ts': `
|
||||
import {Component, NgModule} from '@angular/core';
|
||||
import {ForOfDirective} from './shared/for_of';
|
||||
|
||||
@Component({
|
||||
selector: 'my-component',
|
||||
template: \`
|
||||
<ul>
|
||||
<li *for="let item of items">
|
||||
<div>{{item.name}}</div>
|
||||
<ul>
|
||||
<li *for="let info of item.infos">
|
||||
{{item.name}}: {{info.description}}
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>\`
|
||||
})
|
||||
export class MyComponent {
|
||||
items: Item[] = [
|
||||
{name: 'one', infos: [{description: '11'}, {description: '12'}]},
|
||||
{name: 'two', infos: [{description: '21'}, {description: '22'}]}
|
||||
];
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [MyComponent, ForOfDirective]
|
||||
})
|
||||
export class MyModule {}
|
||||
`
|
||||
}
|
||||
};
|
||||
|
||||
const MyComponentDefinition = `
|
||||
static ngComponentDef = IDENT.ɵdefineComponent({
|
||||
type: MyComponent,
|
||||
tag: 'my-component',
|
||||
factory: function MyComponent_Factory() { return new MyComponent(); },
|
||||
template: function MyComponent_Template(ctx: IDENT, cm: IDENT) {
|
||||
if (cm) {
|
||||
IDENT.ɵE(0, 'ul');
|
||||
IDENT.ɵC(1, IDENT, MyComponent_ForOfDirective_Template_1);
|
||||
IDENT.ɵe();
|
||||
}
|
||||
IDENT.ɵp(1, 'forOf', IDENT.ɵb(ctx.items));
|
||||
IDENT.ɵcR(1);
|
||||
IDENT.r(2, 1);
|
||||
IDENT.ɵcr();
|
||||
|
||||
function MyComponent_ForOfDirective_Template_1(ctx0: IDENT, cm: IDENT) {
|
||||
if (cm) {
|
||||
IDENT.ɵE(0, 'li');
|
||||
IDENT.ɵE(1, 'div');
|
||||
IDENT.ɵT(2);
|
||||
IDENT.ɵe();
|
||||
IDENT.ɵE(3, 'ul');
|
||||
IDENT.ɵC(4, IDENT, MyComponent_ForOfDirective_ForOfDirective_Template_4);
|
||||
IDENT.ɵe();
|
||||
IDENT.ɵe();
|
||||
}
|
||||
const IDENT = ctx0.$implicit;
|
||||
IDENT.ɵp(4, 'forOf', IDENT.ɵb(IDENT.infos));
|
||||
IDENT.ɵt(2, IDENT.ɵb1('', IDENT.name, ''));
|
||||
IDENT.ɵcR(4);
|
||||
IDENT.r(5, 4);
|
||||
IDENT.ɵcr();
|
||||
|
||||
function MyComponent_ForOfDirective_ForOfDirective_Template_4(
|
||||
ctx1: IDENT, cm: IDENT) {
|
||||
if (cm) {
|
||||
IDENT.ɵE(0, 'li');
|
||||
IDENT.ɵT(1);
|
||||
IDENT.ɵe();
|
||||
}
|
||||
const IDENT = ctx1.$implicit;
|
||||
IDENT.ɵt(1, IDENT.ɵb2(' ', IDENT.name, ': ', IDENT.description, ' '));
|
||||
}
|
||||
}
|
||||
}
|
||||
});`;
|
||||
|
||||
const result = compile(files, angularFiles);
|
||||
const source = result.source;
|
||||
expectEmit(source, MyComponentDefinition, 'Invalid component definition');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -389,7 +691,7 @@ function expectEmit(source: string, emitted: string, description: string) {
|
||||
if (!m) {
|
||||
const contextPieceWidth = contextWidth / 2;
|
||||
fail(
|
||||
`${description}: Expected to find ${expected} '${source.substr(0,last)}[<---HERE]${source.substr(last)}'`);
|
||||
`${description}: Expected to find ${expected} '${source.substr(0,last)}[<---HERE expected "${expected}"]${source.substr(last)}'`);
|
||||
return;
|
||||
} else {
|
||||
last = (m.index || 0) + m[0].length;
|
||||
@ -401,7 +703,7 @@ function expectEmit(source: string, emitted: string, description: string) {
|
||||
}
|
||||
|
||||
const IDENT_LIKE = /^[a-z][A-Z]/;
|
||||
const SPECIAL_RE_CHAR = /\/|\(|\)|\||\*|\+|\[|\]|\{|\}/g;
|
||||
const SPECIAL_RE_CHAR = /\/|\(|\)|\||\*|\+|\[|\]|\{|\}|\$/g;
|
||||
function r(...pieces: (string | RegExp)[]): RegExp {
|
||||
let results: string[] = [];
|
||||
let first = true;
|
||||
|
@ -34,5 +34,6 @@ export {
|
||||
s as ɵs,
|
||||
t as ɵt,
|
||||
v as ɵv,
|
||||
r as ɵr,
|
||||
} from './render3/index';
|
||||
// clang-format on
|
||||
|
@ -13,8 +13,8 @@ import {ComponentRef as viewEngine_ComponentRef} from '../linker/component_facto
|
||||
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef} from '../linker/view_ref';
|
||||
|
||||
import {assertNotNull} from './assert';
|
||||
import {NG_HOST_SYMBOL, createError, createLView, directiveCreate, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate} from './instructions';
|
||||
import {ComponentDef, ComponentType, TypedComponentDef} from './interfaces/definition';
|
||||
import {NG_HOST_SYMBOL, createError, createLView, createTView, directiveCreate, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate} from './instructions';
|
||||
import {ComponentDef, ComponentType} from './interfaces/definition';
|
||||
import {LElementNode} from './interfaces/node';
|
||||
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
||||
import {notImplemented, stringify} from './util';
|
||||
@ -166,13 +166,13 @@ export const NULL_INJECTOR: Injector = {
|
||||
export function renderComponent<T>(
|
||||
componentType: ComponentType<T>, opts: CreateComponentOptions = {}): T {
|
||||
const rendererFactory = opts.rendererFactory || domRendererFactory3;
|
||||
const componentDef = componentType.ngComponentDef as TypedComponentDef<T>;
|
||||
const componentDef = componentType.ngComponentDef as ComponentDef<T>;
|
||||
if (componentDef.type != componentType) componentDef.type = componentType;
|
||||
let component: T;
|
||||
const hostNode = locateHostElement(rendererFactory, opts.host || componentDef.tag);
|
||||
const oldView = enterView(
|
||||
createLView(
|
||||
-1, rendererFactory.createRenderer(hostNode, componentDef.rendererType), {data: []}),
|
||||
-1, rendererFactory.createRenderer(hostNode, componentDef.rendererType), createTView()),
|
||||
null !);
|
||||
try {
|
||||
// Create element node at index 0 in data array
|
||||
|
@ -13,8 +13,7 @@ import {Type} from '../type';
|
||||
import {resolveRendererType2} from '../view/util';
|
||||
|
||||
import {diPublic} from './di';
|
||||
import {componentRefresh} from './instructions';
|
||||
import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, TypedDirectiveDef} from './interfaces/definition';
|
||||
import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs} from './interfaces/definition';
|
||||
|
||||
|
||||
|
||||
@ -34,22 +33,26 @@ import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, TypedDir
|
||||
* ```
|
||||
*/
|
||||
export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): ComponentDef<T> {
|
||||
const type = componentDefinition.type;
|
||||
const def = <ComponentDef<any>>{
|
||||
type: type,
|
||||
diPublic: null,
|
||||
n: componentDefinition.factory,
|
||||
tag: (componentDefinition as ComponentDefArgs<T>).tag || null !,
|
||||
template: (componentDefinition as ComponentDefArgs<T>).template || null !,
|
||||
r: componentDefinition.refresh || (componentDefinition.template ?
|
||||
function(d: number, e: number) {
|
||||
componentRefresh(d, e, componentDefinition.template);
|
||||
} :
|
||||
noop),
|
||||
h: componentDefinition.hostBindings || noop,
|
||||
inputs: invertObject(componentDefinition.inputs),
|
||||
outputs: invertObject(componentDefinition.outputs),
|
||||
methods: invertObject(componentDefinition.methods),
|
||||
rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
|
||||
exportAs: componentDefinition.exportAs,
|
||||
onInit: type.prototype.ngOnInit || null,
|
||||
doCheck: type.prototype.ngDoCheck || null,
|
||||
afterContentInit: type.prototype.ngAfterContentInit || null,
|
||||
afterContentChecked: type.prototype.ngAfterContentChecked || null,
|
||||
afterViewInit: type.prototype.ngAfterViewInit || null,
|
||||
afterViewChecked: type.prototype.ngAfterViewChecked || null,
|
||||
onDestroy: type.prototype.ngOnDestroy || null
|
||||
};
|
||||
const feature = componentDefinition.features;
|
||||
feature && feature.forEach((fn) => fn(def));
|
||||
@ -96,19 +99,30 @@ export function NgOnChangesFeature<T>(type: Type<T>): (definition: DirectiveDef<
|
||||
}
|
||||
});
|
||||
}
|
||||
proto.ngDoCheck = (function(delegateDoCheck) {
|
||||
|
||||
// If an onInit hook is defined, it will need to wrap the ngOnChanges call
|
||||
// so the call order is changes-init-check in creation mode. In subsequent
|
||||
// change detection runs, only the check wrapper will be called.
|
||||
if (definition.onInit != null) {
|
||||
definition.onInit = onChangesWrapper(definition.onInit);
|
||||
}
|
||||
|
||||
definition.doCheck = onChangesWrapper(definition.doCheck);
|
||||
|
||||
function onChangesWrapper(delegateHook: (() => void) | null) {
|
||||
return function(this: OnChangesExpando) {
|
||||
let simpleChanges = this[PRIVATE_PREFIX];
|
||||
if (simpleChanges != null) {
|
||||
this.ngOnChanges(simpleChanges);
|
||||
this[PRIVATE_PREFIX] = null;
|
||||
}
|
||||
delegateDoCheck && delegateDoCheck.apply(this);
|
||||
delegateHook && delegateHook.apply(this);
|
||||
};
|
||||
})(proto.ngDoCheck);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export function PublicFeature<T>(definition: DirectiveDef<T>) {
|
||||
definition.diPublic = diPublic;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import {Type} from '../type';
|
||||
|
||||
import {assertLessThan} from './assert';
|
||||
import {assertPreviousIsParent, getPreviousOrParentNode, getRenderer, renderEmbeddedTemplate} from './instructions';
|
||||
import {ComponentTemplate, DirectiveDef, TypedDirectiveDef} from './interfaces/definition';
|
||||
import {ComponentTemplate, DirectiveDef} from './interfaces/definition';
|
||||
import {LInjector} from './interfaces/injector';
|
||||
import {LContainerNode, LElementNode, LNode, LNodeFlags, LViewNode} from './interfaces/node';
|
||||
import {QueryReadType} from './interfaces/query';
|
||||
@ -158,7 +158,7 @@ function createInjectionError(text: string, token: any) {
|
||||
* @param di The node injector in which a directive will be added
|
||||
* @param def The definition of the directive to be made public
|
||||
*/
|
||||
export function diPublicInInjector(di: LInjector, def: TypedDirectiveDef<any>): void {
|
||||
export function diPublicInInjector(di: LInjector, def: DirectiveDef<any>): void {
|
||||
bloomAdd(di, def.type);
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ export function diPublicInInjector(di: LInjector, def: TypedDirectiveDef<any>):
|
||||
*
|
||||
* @param def The definition of the directive to be made public
|
||||
*/
|
||||
export function diPublic(def: TypedDirectiveDef<any>): void {
|
||||
export function diPublic(def: DirectiveDef<any>): void {
|
||||
diPublicInInjector(getOrCreateNodeInjector(), def);
|
||||
}
|
||||
|
||||
@ -291,7 +291,7 @@ export function getOrCreateInjectable<T>(
|
||||
for (let i = start, ii = start + size; i < ii; i++) {
|
||||
// Get the definition for the directive at this index and, if it is injectable (diPublic),
|
||||
// and matches the given token, return the directive instance.
|
||||
const directiveDef = tData[i] as TypedDirectiveDef<any>;
|
||||
const directiveDef = tData[i] as DirectiveDef<any>;
|
||||
if (directiveDef.diPublic && directiveDef.type == token) {
|
||||
return node.view.data[i];
|
||||
}
|
||||
@ -392,7 +392,10 @@ export class ReadFromInjectorFn<T> {
|
||||
* @returns The ElementRef instance to use
|
||||
*/
|
||||
export function getOrCreateElementRef(di: LInjector): viewEngine_ElementRef {
|
||||
return di.elementRef || (di.elementRef = new ElementRef(di.node.native));
|
||||
return di.elementRef ||
|
||||
(di.elementRef = new ElementRef(
|
||||
((di.node.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Container) ? null :
|
||||
di.node.native));
|
||||
}
|
||||
|
||||
export const QUERY_READ_TEMPLATE_REF = <QueryReadType<viewEngine_TemplateRef<any>>>(
|
||||
|
174
packages/core/src/render3/hooks.ts
Normal file
174
packages/core/src/render3/hooks.ts
Normal file
@ -0,0 +1,174 @@
|
||||
/**
|
||||
* @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 {DirectiveDef} from './interfaces/definition';
|
||||
import {LNodeFlags} from './interfaces/node';
|
||||
import {HookData, LView, LifecycleStage, TView} from './interfaces/view';
|
||||
|
||||
|
||||
|
||||
/** Constants used by lifecycle hooks to determine when and how a hook should be called. */
|
||||
export const enum LifecycleHook {
|
||||
ON_INIT = 0b00,
|
||||
ON_CHECK = 0b01,
|
||||
|
||||
/* Mask used to get the type of the lifecycle hook from flags in hook queue */
|
||||
TYPE_MASK = 0b00000000000000000000000000000001,
|
||||
|
||||
/* Shift needed to get directive index from flags in hook queue */
|
||||
INDX_SHIFT = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is the first template pass, any ngOnInit or ngDoCheck hooks will be queued into
|
||||
* TView.initHooks during directiveCreate.
|
||||
*
|
||||
* The directive index and hook type are encoded into one number (1st bit: type, remaining bits:
|
||||
* directive index), then saved in the even indices of the initHooks array. The odd indices
|
||||
* hold the hook functions themselves.
|
||||
*
|
||||
* @param index The index of the directive in LView.data
|
||||
* @param hooks The static hooks map on the directive def
|
||||
* @param tView The current TView
|
||||
*/
|
||||
export function queueInitHooks(
|
||||
index: number, onInit: (() => void) | null, doCheck: (() => void) | null, tView: TView): void {
|
||||
if (tView.firstTemplatePass === true) {
|
||||
if (onInit != null) {
|
||||
(tView.initHooks || (tView.initHooks = [])).push(getInitFlags(index), onInit);
|
||||
}
|
||||
|
||||
if (doCheck != null) {
|
||||
(tView.initHooks || (tView.initHooks = [])).push(getCheckFlags(index), doCheck);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops through the directives on a node and queues all their hooks except ngOnInit
|
||||
* and ngDoCheck, which are queued separately in directiveCreate.
|
||||
*/
|
||||
export function queueLifecycleHooks(flags: number, currentView: LView): void {
|
||||
const tView = currentView.tView;
|
||||
if (tView.firstTemplatePass === true) {
|
||||
const size = (flags & LNodeFlags.SIZE_MASK) >> LNodeFlags.SIZE_SHIFT;
|
||||
const start = flags >> LNodeFlags.INDX_SHIFT;
|
||||
|
||||
// It's necessary to loop through the directives at elementEnd() (rather than processing in
|
||||
// directiveCreate) so we can preserve the current hook order. Content, view, and destroy
|
||||
// hooks for projected components and directives must be called *before* their hosts.
|
||||
for (let i = start, end = start + size; i < end; i++) {
|
||||
const def = (tView.data[i] as DirectiveDef<any>);
|
||||
queueContentHooks(def, tView, i);
|
||||
queueViewHooks(def, tView, i);
|
||||
queueDestroyHooks(def, tView, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Queues afterContentInit and afterContentChecked hooks on TView */
|
||||
function queueContentHooks(def: DirectiveDef<any>, tView: TView, i: number): void {
|
||||
if (def.afterContentInit != null) {
|
||||
(tView.contentHooks || (tView.contentHooks = [])).push(getInitFlags(i), def.afterContentInit);
|
||||
}
|
||||
|
||||
if (def.afterContentChecked != null) {
|
||||
(tView.contentHooks || (tView.contentHooks = [
|
||||
])).push(getCheckFlags(i), def.afterContentChecked);
|
||||
}
|
||||
}
|
||||
|
||||
/** Queues afterViewInit and afterViewChecked hooks on TView */
|
||||
function queueViewHooks(def: DirectiveDef<any>, tView: TView, i: number): void {
|
||||
if (def.afterViewInit != null) {
|
||||
(tView.viewHooks || (tView.viewHooks = [])).push(getInitFlags(i), def.afterViewInit);
|
||||
}
|
||||
|
||||
if (def.afterViewChecked != null) {
|
||||
(tView.viewHooks || (tView.viewHooks = [])).push(getCheckFlags(i), def.afterViewChecked);
|
||||
}
|
||||
}
|
||||
|
||||
/** Queues onDestroy hooks on TView */
|
||||
function queueDestroyHooks(def: DirectiveDef<any>, tView: TView, i: number): void {
|
||||
if (def.onDestroy != null) {
|
||||
(tView.destroyHooks || (tView.destroyHooks = [])).push(i, def.onDestroy);
|
||||
}
|
||||
}
|
||||
|
||||
/** Generates flags for init-only hooks */
|
||||
function getInitFlags(index: number): number {
|
||||
return index << LifecycleHook.INDX_SHIFT;
|
||||
}
|
||||
|
||||
/** Generates flags for hooks called every change detection run */
|
||||
function getCheckFlags(index: number): number {
|
||||
return (index << LifecycleHook.INDX_SHIFT) | LifecycleHook.ON_CHECK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls onInit and doCheck calls if they haven't already been called.
|
||||
*
|
||||
* @param currentView The current view
|
||||
*/
|
||||
export function executeInitHooks(currentView: LView): void {
|
||||
const initHooks = currentView.tView.initHooks;
|
||||
|
||||
if (currentView.lifecycleStage === LifecycleStage.INIT && initHooks != null) {
|
||||
executeLifecycleHooks(currentView, initHooks);
|
||||
currentView.lifecycleStage = LifecycleStage.CONTENT_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls all afterContentInit and afterContentChecked hooks for the view, then splices
|
||||
* out afterContentInit hooks to prep for the next run in update mode.
|
||||
*
|
||||
* @param currentView The current view
|
||||
*/
|
||||
export function executeContentHooks(currentView: LView): void {
|
||||
const contentHooks = currentView.tView.contentHooks;
|
||||
|
||||
if (currentView.lifecycleStage < LifecycleStage.VIEW_INIT && contentHooks != null) {
|
||||
executeLifecycleHooks(currentView, contentHooks);
|
||||
currentView.lifecycleStage = LifecycleStage.VIEW_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over afterViewInit and afterViewChecked functions and calls them.
|
||||
*
|
||||
* @param currentView The current view
|
||||
*/
|
||||
export function executeViewHooks(currentView: LView): void {
|
||||
const viewHooks = currentView.tView.viewHooks;
|
||||
|
||||
if (viewHooks != null) {
|
||||
executeLifecycleHooks(currentView, viewHooks);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls lifecycle hooks with their contexts, skipping init hooks if it's not
|
||||
* creation mode.
|
||||
*
|
||||
* @param currentView The current view
|
||||
* @param arr The array in which the hooks are found
|
||||
*/
|
||||
function executeLifecycleHooks(currentView: LView, arr: HookData): void {
|
||||
const data = currentView.data;
|
||||
const creationMode = currentView.creationMode;
|
||||
|
||||
for (let i = 0; i < arr.length; i += 2) {
|
||||
const flags = arr[i] as number;
|
||||
const initOnly = (flags & LifecycleHook.TYPE_MASK) === LifecycleHook.ON_INIT;
|
||||
if (initOnly === false || creationMode) {
|
||||
(arr[i | 1] as() => void).call(data[flags >> LifecycleHook.INDX_SHIFT]);
|
||||
}
|
||||
}
|
||||
}
|
@ -24,8 +24,6 @@ export {InjectFlags, QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_REA
|
||||
// clang-format off
|
||||
export {
|
||||
|
||||
LifecycleHook,
|
||||
|
||||
NO_CHANGE as NC,
|
||||
|
||||
bind as b,
|
||||
@ -52,7 +50,6 @@ export {
|
||||
elementStart as E,
|
||||
elementStyle as s,
|
||||
|
||||
lifecycle as l,
|
||||
listener as L,
|
||||
memory as m,
|
||||
|
||||
@ -68,10 +65,13 @@ export {
|
||||
|
||||
export {
|
||||
QueryList,
|
||||
|
||||
|
||||
query as Q,
|
||||
queryRefresh as qR,
|
||||
} from './query';
|
||||
|
||||
export {LifecycleHook} from './hooks';
|
||||
|
||||
// clang-format on
|
||||
|
||||
export {
|
||||
|
@ -8,39 +8,22 @@
|
||||
|
||||
import './ng_dev_mode';
|
||||
|
||||
import {ElementRef} from '../linker/element_ref';
|
||||
import {TemplateRef} from '../linker/template_ref';
|
||||
import {ViewContainerRef} from '../linker/view_container_ref';
|
||||
import {Type} from '../type';
|
||||
|
||||
import {assertEqual, assertLessThan, assertNotEqual, assertNotNull} from './assert';
|
||||
import {LContainer, TContainer} from './interfaces/container';
|
||||
import {LInjector} from './interfaces/injector';
|
||||
import {CssSelector, LProjection} from './interfaces/projection';
|
||||
import {LQuery, QueryReadType} from './interfaces/query';
|
||||
import {LView, TData, TView} from './interfaces/view';
|
||||
import {LQueries} from './interfaces/query';
|
||||
import {LView, LifecycleStage, TData, TView} from './interfaces/view';
|
||||
|
||||
import {LContainerNode, LElementNode, LNode, LNodeFlags, LProjectionNode, LTextNode, LViewNode, TNode, TContainerNode, InitialInputData, InitialInputs, PropertyAliases, PropertyAliasValue,} from './interfaces/node';
|
||||
import {assertNodeType, assertNodeOfPossibleTypes} from './node_assert';
|
||||
import {appendChild, insertChild, insertView, processProjectedNode, removeView} from './node_manipulation';
|
||||
import {appendChild, insertChild, insertView, appendProjectedNode, removeView, canInsertNativeNode} from './node_manipulation';
|
||||
import {isNodeMatchingSelector} from './node_selector_matcher';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType, TypedDirectiveDef, TypedComponentDef} from './interfaces/definition';
|
||||
import {RComment, RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3} from './interfaces/renderer';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType} from './interfaces/definition';
|
||||
import {RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3} from './interfaces/renderer';
|
||||
import {isDifferent, stringify} from './util';
|
||||
import {executeViewHooks, executeContentHooks, queueLifecycleHooks, queueInitHooks, executeInitHooks} from './hooks';
|
||||
|
||||
|
||||
/**
|
||||
* Enum used by the lifecycle (l) instruction to determine which lifecycle hook is requesting
|
||||
* processing.
|
||||
*/
|
||||
export const enum LifecycleHook {
|
||||
ON_INIT = 1,
|
||||
ON_DESTROY = 2,
|
||||
ON_CHANGES = 4,
|
||||
AFTER_VIEW_INIT = 8,
|
||||
AFTER_VIEW_CHECKED = 16
|
||||
}
|
||||
|
||||
/**
|
||||
* Directive (D) sets a property on all component instances using this constant as a key and the
|
||||
* component's host node (LElement) as the value. This is used in methods like detectChanges to
|
||||
@ -91,9 +74,9 @@ let tData: TData;
|
||||
/** State of the current view being processed. */
|
||||
let currentView: LView;
|
||||
// The initialization has to be after the `let`, otherwise `createLView` can't see `let`.
|
||||
currentView = createLView(null !, null !, {data: []});
|
||||
currentView = createLView(null !, null !, createTView());
|
||||
|
||||
let currentQuery: LQuery|null;
|
||||
let currentQueries: LQueries|null;
|
||||
|
||||
/**
|
||||
* This property gets set before entering a template.
|
||||
@ -112,10 +95,11 @@ let data: any[];
|
||||
let bindingIndex: number;
|
||||
|
||||
/**
|
||||
* When a view is destroyed, listeners need to be released
|
||||
* and onDestroy callbacks need to be called. This cleanup array
|
||||
* stores both listener data (in chunks of 4) and onDestroy data
|
||||
* (in chunks of 2), as they'll be processed at the same time.
|
||||
* When a view is destroyed, listeners need to be released and outputs need to be
|
||||
* unsubscribed. This cleanup array stores both listener data (in chunks of 4)
|
||||
* and output data (in chunks of 2) for a particular view. Combining the arrays
|
||||
* saves on memory (70 bytes per array) and on a few bytes of code size (for two
|
||||
* separate for loops).
|
||||
*
|
||||
* If it's a listener being stored:
|
||||
* 1st index is: event name to remove
|
||||
@ -123,15 +107,12 @@ let bindingIndex: number;
|
||||
* 3rd index is: listener function
|
||||
* 4th index is: useCapture boolean
|
||||
*
|
||||
* If it's an onDestroy function:
|
||||
* 1st index is: onDestroy function
|
||||
* If it's an output subscription:
|
||||
* 1st index is: unsubscribe function
|
||||
* 2nd index is: context for function
|
||||
*/
|
||||
let cleanup: any[]|null;
|
||||
|
||||
/** Index in the data array at which view hooks begin to be stored. */
|
||||
let viewHookStartIndex: number|null;
|
||||
|
||||
/**
|
||||
* Swap the current state with a new state.
|
||||
*
|
||||
@ -151,7 +132,6 @@ export function enterView(newView: LView, host: LElementNode | LViewNode | null)
|
||||
tData = newView.tView.data;
|
||||
creationMode = newView.creationMode;
|
||||
|
||||
viewHookStartIndex = newView.viewHookStartIndex;
|
||||
cleanup = newView.cleanup;
|
||||
renderer = newView.renderer;
|
||||
|
||||
@ -161,6 +141,8 @@ export function enterView(newView: LView, host: LElementNode | LViewNode | null)
|
||||
}
|
||||
|
||||
currentView = newView;
|
||||
currentQueries = newView.queries;
|
||||
|
||||
return oldView !;
|
||||
}
|
||||
|
||||
@ -169,7 +151,10 @@ export function enterView(newView: LView, host: LElementNode | LViewNode | null)
|
||||
* the direction of traversal (up or down the view tree) a bit clearer.
|
||||
*/
|
||||
export function leaveView(newView: LView): void {
|
||||
executeViewHooks();
|
||||
executeViewHooks(currentView);
|
||||
currentView.creationMode = false;
|
||||
currentView.lifecycleStage = LifecycleStage.INIT;
|
||||
currentView.tView.firstTemplatePass = false;
|
||||
enterView(newView, null);
|
||||
}
|
||||
|
||||
@ -189,10 +174,11 @@ export function createLView(
|
||||
next: null,
|
||||
bindingStartIndex: null,
|
||||
creationMode: true,
|
||||
viewHookStartIndex: null,
|
||||
template: template,
|
||||
context: context,
|
||||
dynamicViewCount: 0,
|
||||
lifecycleStage: LifecycleStage.INIT,
|
||||
queries: null,
|
||||
};
|
||||
|
||||
return newView;
|
||||
@ -208,19 +194,20 @@ export function createLNode(
|
||||
export function createLNode(
|
||||
index: null, type: LNodeFlags.View, native: null, lView: LView): LViewNode;
|
||||
export function createLNode(
|
||||
index: number, type: LNodeFlags.Container, native: RComment,
|
||||
index: number, type: LNodeFlags.Container, native: undefined,
|
||||
lContainer: LContainer): LContainerNode;
|
||||
export function createLNode(
|
||||
index: number, type: LNodeFlags.Projection, native: null,
|
||||
lProjection: LProjection): LProjectionNode;
|
||||
export function createLNode(
|
||||
index: number | null, type: LNodeFlags, native: RText | RElement | RComment | null,
|
||||
index: number | null, type: LNodeFlags, native: RText | RElement | null | undefined,
|
||||
state?: null | LView | LContainer | LProjection): LElementNode<extNode&LViewNode&
|
||||
LContainerNode&LProjectionNode {
|
||||
const parent = isParent ? previousOrParentNode :
|
||||
previousOrParentNode && previousOrParentNode.parent as LNode;
|
||||
let query = (isParent ? currentQuery : previousOrParentNode && previousOrParentNode.query) ||
|
||||
parent && parent.query && parent.query.child();
|
||||
let queries =
|
||||
(isParent ? currentQueries : previousOrParentNode && previousOrParentNode.queries) ||
|
||||
parent && parent.queries && parent.queries.child();
|
||||
const isState = state != null;
|
||||
const node: LElementNode<extNode&LViewNode&LContainerNode&LProjectionNode = {
|
||||
flags: type,
|
||||
@ -231,8 +218,9 @@ export function createLNode(
|
||||
next: null,
|
||||
nodeInjector: parent ? parent.nodeInjector : null,
|
||||
data: isState ? state as any : null,
|
||||
query: query,
|
||||
tNode: null
|
||||
queries: queries,
|
||||
tNode: null,
|
||||
pNextOrParent: null
|
||||
};
|
||||
|
||||
if ((type & LNodeFlags.ViewOrElement) === LNodeFlags.ViewOrElement && isState) {
|
||||
@ -255,7 +243,7 @@ export function createLNode(
|
||||
|
||||
// Now link ourselves into the tree.
|
||||
if (isParent) {
|
||||
currentQuery = null;
|
||||
currentQueries = null;
|
||||
if (previousOrParentNode.view === currentView ||
|
||||
(previousOrParentNode.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.View) {
|
||||
// We are in the same view, which means we are adding content node to the parent View.
|
||||
@ -320,7 +308,7 @@ export function renderEmbeddedTemplate<T>(
|
||||
previousOrParentNode = null !;
|
||||
let cm: boolean = false;
|
||||
if (viewNode == null) {
|
||||
const view = createLView(-1, renderer, {data: []}, template, context);
|
||||
const view = createLView(-1, renderer, createTView(), template, context);
|
||||
viewNode = createLNode(null, LNodeFlags.View, null, view);
|
||||
cm = true;
|
||||
}
|
||||
@ -347,14 +335,13 @@ export function renderComponentOrTemplate<T>(
|
||||
template(componentOrContext !, creationMode);
|
||||
} else {
|
||||
// Element was stored at 0 and directive was stored at 1 in renderComponent
|
||||
// so to refresh the component, r() needs to be called with (1, 0)
|
||||
(componentOrContext.constructor as ComponentType<T>).ngComponentDef.r(1, 0);
|
||||
// so to refresh the component, refresh() needs to be called with (1, 0)
|
||||
componentRefresh(1, 0);
|
||||
}
|
||||
} finally {
|
||||
if (rendererFactory.end) {
|
||||
rendererFactory.end();
|
||||
}
|
||||
hostView.creationMode = false;
|
||||
leaveView(oldView);
|
||||
}
|
||||
}
|
||||
@ -430,8 +417,6 @@ export function elementStart(
|
||||
if (hostComponentDef) {
|
||||
// TODO(mhevery): This assumes that the directives come in correct order, which
|
||||
// is not guaranteed. Must be refactored to take it into account.
|
||||
(hostComponentDef as TypedComponentDef<any>).type =
|
||||
nameOrComponentType as ComponentType<any>;
|
||||
directiveCreate(++index, hostComponentDef.n(), hostComponentDef, queryName);
|
||||
}
|
||||
hack_declareDirectives(index, directiveTypes, localRefs);
|
||||
@ -459,7 +444,6 @@ function hack_declareDirectives(
|
||||
// TODO(misko): refactor this to store the `DirectiveDef` in `TView.data`.
|
||||
const directiveType = directiveTypes[i];
|
||||
const directiveDef = directiveType.ngDirectiveDef;
|
||||
(directiveDef as TypedDirectiveDef<any>).type = directiveType;
|
||||
directiveCreate(
|
||||
++index, directiveDef.n(), directiveDef, hack_findQueryName(directiveDef, localRefs));
|
||||
}
|
||||
@ -494,7 +478,19 @@ function hack_findQueryName(
|
||||
* @returns TView
|
||||
*/
|
||||
function getOrCreateTView(template: ComponentTemplate<any>): TView {
|
||||
return template.ngPrivateData || (template.ngPrivateData = { data: [] } as never);
|
||||
return template.ngPrivateData || (template.ngPrivateData = createTView() as never);
|
||||
}
|
||||
|
||||
/** Creates a TView instance */
|
||||
export function createTView(): TView {
|
||||
return {
|
||||
data: [],
|
||||
firstTemplatePass: true,
|
||||
initHooks: null,
|
||||
contentHooks: null,
|
||||
viewHooks: null,
|
||||
destroyHooks: null
|
||||
};
|
||||
}
|
||||
|
||||
function setUpAttributes(native: RElement, attrs: string[]): void {
|
||||
@ -611,8 +607,9 @@ export function elementEnd() {
|
||||
previousOrParentNode = previousOrParentNode.parent !;
|
||||
}
|
||||
ngDevMode && assertNodeType(previousOrParentNode, LNodeFlags.Element);
|
||||
const query = previousOrParentNode.query;
|
||||
query && query.addNode(previousOrParentNode);
|
||||
const queries = previousOrParentNode.queries;
|
||||
queries && queries.addNode(previousOrParentNode);
|
||||
queueLifecycleHooks(previousOrParentNode.flags, currentView);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -831,23 +828,22 @@ export function text(index: number, value?: any): void {
|
||||
* @param value Stringified value to write.
|
||||
*/
|
||||
export function textBinding<T>(index: number, value: T | NO_CHANGE): void {
|
||||
// TODO(misko): I don't think index < nodes.length check is needed here.
|
||||
let existingNode = index < data.length && data[index] as LTextNode;
|
||||
if (existingNode && existingNode.native) {
|
||||
ngDevMode && assertDataInRange(index);
|
||||
let existingNode = data[index] as LTextNode;
|
||||
ngDevMode && assertNotNull(existingNode, 'existing node');
|
||||
if (existingNode.native) {
|
||||
// If DOM node exists and value changed, update textContent
|
||||
value !== NO_CHANGE &&
|
||||
((renderer as ProceduralRenderer3).setValue ?
|
||||
(renderer as ProceduralRenderer3).setValue(existingNode.native, stringify(value)) :
|
||||
existingNode.native.textContent = stringify(value));
|
||||
} else if (existingNode) {
|
||||
} else {
|
||||
// Node was created but DOM node creation was delayed. Create and append now.
|
||||
existingNode.native =
|
||||
((renderer as ProceduralRenderer3).createText ?
|
||||
(renderer as ProceduralRenderer3).createText(stringify(value)) :
|
||||
(renderer as ObjectOrientedRenderer3).createTextNode !(stringify(value)));
|
||||
insertChild(existingNode, currentView);
|
||||
} else {
|
||||
text(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -906,6 +902,11 @@ export function directiveCreate<T>(
|
||||
if (tNode && tNode.attrs) {
|
||||
setInputsFromAttrs<T>(instance, directiveDef !.inputs, tNode);
|
||||
}
|
||||
|
||||
// Init hooks are queued now so ngOnInit is called in host components before
|
||||
// any projected components.
|
||||
queueInitHooks(index, directiveDef.onInit, directiveDef.doCheck, currentView.tView);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ -966,76 +967,6 @@ function generateInitialInputs(
|
||||
return initialInputData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a lifecycle hook type and determines when and how the related lifecycle hook
|
||||
* callback should run.
|
||||
*
|
||||
* For the onInit lifecycle hook, it will return whether or not the ngOnInit() function
|
||||
* should run. If so, ngOnInit() will be called outside of this function.
|
||||
*
|
||||
* e.g. l(LifecycleHook.ON_INIT) && ctx.ngOnInit();
|
||||
*
|
||||
* For the onDestroy lifecycle hook, this instruction also accepts an onDestroy
|
||||
* method that should be stored and called internally when the parent view is being
|
||||
* cleaned up.
|
||||
*
|
||||
* e.g. l(LifecycleHook.ON_DESTROY, ctx, ctx.onDestroy);
|
||||
*
|
||||
* @param lifecycle
|
||||
* @param self
|
||||
* @param method
|
||||
*/
|
||||
export function lifecycle(lifecycle: LifecycleHook.ON_DESTROY, self: any, method: Function): void;
|
||||
export function lifecycle(
|
||||
lifecycle: LifecycleHook.AFTER_VIEW_INIT, self: any, method: Function): void;
|
||||
export function lifecycle(
|
||||
lifecycle: LifecycleHook.AFTER_VIEW_CHECKED, self: any, method: Function): void;
|
||||
export function lifecycle(lifecycle: LifecycleHook): boolean;
|
||||
export function lifecycle(lifecycle: LifecycleHook, self?: any, method?: Function): boolean {
|
||||
if (lifecycle === LifecycleHook.ON_INIT) {
|
||||
return creationMode;
|
||||
} else if (lifecycle === LifecycleHook.ON_DESTROY) {
|
||||
(cleanup || (currentView.cleanup = cleanup = [])).push(method, self);
|
||||
} else if (
|
||||
creationMode && (lifecycle === LifecycleHook.AFTER_VIEW_INIT ||
|
||||
lifecycle === LifecycleHook.AFTER_VIEW_CHECKED)) {
|
||||
if (viewHookStartIndex == null) {
|
||||
currentView.viewHookStartIndex = viewHookStartIndex = data.length;
|
||||
}
|
||||
data.push(lifecycle, method, self);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Iterates over view hook functions and calls them. */
|
||||
export function executeViewHooks(): void {
|
||||
if (viewHookStartIndex == null) return;
|
||||
|
||||
// Instead of using splice to remove init hooks after their first run (expensive), we
|
||||
// shift over the AFTER_CHECKED hooks as we call them and truncate once at the end.
|
||||
let checkIndex = viewHookStartIndex as number;
|
||||
let writeIndex = checkIndex;
|
||||
while (checkIndex < data.length) {
|
||||
// Call lifecycle hook with its context
|
||||
data[checkIndex + 1].call(data[checkIndex + 2]);
|
||||
|
||||
if (data[checkIndex] === LifecycleHook.AFTER_VIEW_CHECKED) {
|
||||
// We know if the writeIndex falls behind that there is an init that needs to
|
||||
// be overwritten.
|
||||
if (writeIndex < checkIndex) {
|
||||
data[writeIndex] = data[checkIndex];
|
||||
data[writeIndex + 1] = data[checkIndex + 1];
|
||||
data[writeIndex + 2] = data[checkIndex + 2];
|
||||
}
|
||||
writeIndex += 3;
|
||||
}
|
||||
checkIndex += 3;
|
||||
}
|
||||
|
||||
// Truncate once at the writeIndex
|
||||
data.length = writeIndex;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////
|
||||
//// ViewContainer & View
|
||||
@ -1057,28 +988,23 @@ export function container(
|
||||
tagName?: string, attrs?: string[], localRefs?: string[] | null): void {
|
||||
ngDevMode && assertEqual(currentView.bindingStartIndex, null, 'bindingStartIndex');
|
||||
|
||||
// If the direct parent of the container is a view, its views (including its comment)
|
||||
// will need to be added through insertView() when its parent view is being inserted.
|
||||
// For now, it is marked "headless" so we know to append its views later.
|
||||
let comment = renderer.createComment(ngDevMode ? 'container' : '');
|
||||
let renderParent: LElementNode|null = null;
|
||||
const currentParent = isParent ? previousOrParentNode : previousOrParentNode.parent !;
|
||||
ngDevMode && assertNotEqual(currentParent, null, 'currentParent');
|
||||
if (appendChild(currentParent, comment, currentView)) {
|
||||
// we are adding to an Element which is either:
|
||||
// - Not a component (will not be re-projected, just added)
|
||||
// - View of the Component
|
||||
renderParent = currentParent as LElementNode;
|
||||
}
|
||||
|
||||
const node = createLNode(index, LNodeFlags.Container, comment, <LContainer>{
|
||||
const lContainer = <LContainer>{
|
||||
views: [],
|
||||
nextIndex: 0, renderParent,
|
||||
nextIndex: 0,
|
||||
// If the direct parent of the container is a view, its views will need to be added
|
||||
// through insertView() when its parent view is being inserted:
|
||||
renderParent: canInsertNativeNode(currentParent, currentView) ? currentParent : null,
|
||||
template: template == null ? null : template,
|
||||
next: null,
|
||||
parent: currentView,
|
||||
dynamicViewCount: 0,
|
||||
});
|
||||
queries: null
|
||||
};
|
||||
|
||||
const node = createLNode(index, LNodeFlags.Container, undefined, lContainer);
|
||||
|
||||
if (node.tNode == null) {
|
||||
// TODO(misko): implement queryName caching
|
||||
@ -1093,8 +1019,13 @@ export function container(
|
||||
|
||||
isParent = false;
|
||||
ngDevMode && assertNodeType(previousOrParentNode, LNodeFlags.Container);
|
||||
const query = previousOrParentNode.query;
|
||||
query && query.addNode(previousOrParentNode);
|
||||
const queries = node.queries;
|
||||
if (queries) {
|
||||
// check if a given container node matches
|
||||
queries.addNode(node);
|
||||
// prepare place for matching nodes from views inserted into a given container
|
||||
lContainer.queries = queries.container();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1108,6 +1039,13 @@ export function containerRefreshStart(index: number): void {
|
||||
ngDevMode && assertNodeType(previousOrParentNode, LNodeFlags.Container);
|
||||
isParent = true;
|
||||
(previousOrParentNode as LContainerNode).data.nextIndex = 0;
|
||||
ngDevMode && assertEqual(
|
||||
(previousOrParentNode as LContainerNode).native === undefined, true,
|
||||
'previousOrParentNode.native === undefined');
|
||||
|
||||
// We need to execute init hooks here so ngOnInit hooks are called in top level views
|
||||
// before they are called in embedded views (for backwards compatibility).
|
||||
executeInitHooks(currentView);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1125,6 +1063,7 @@ export function containerRefreshEnd(): void {
|
||||
}
|
||||
ngDevMode && assertNodeType(previousOrParentNode, LNodeFlags.Container);
|
||||
const container = previousOrParentNode as LContainerNode;
|
||||
container.native = undefined;
|
||||
ngDevMode && assertNodeType(container, LNodeFlags.Container);
|
||||
const nextIndex = container.data.nextIndex;
|
||||
while (nextIndex < container.data.views.length) {
|
||||
@ -1171,6 +1110,10 @@ export function viewStart(viewBlockId: number): boolean {
|
||||
// When we create a new LView, we always reset the state of the instructions.
|
||||
const newView =
|
||||
createLView(viewBlockId, renderer, getOrCreateEmbeddedTView(viewBlockId, container));
|
||||
if (lContainer.queries) {
|
||||
newView.queries = lContainer.queries.enterView(lContainer.nextIndex);
|
||||
}
|
||||
|
||||
enterView(newView, createLNode(null, LNodeFlags.View, null, newView));
|
||||
lContainer.nextIndex++;
|
||||
}
|
||||
@ -1194,7 +1137,7 @@ function getOrCreateEmbeddedTView(viewIndex: number, parent: LContainerNode): TV
|
||||
ngDevMode && assertNodeType(parent, LNodeFlags.Container);
|
||||
const tContainer = (parent !.tNode as TContainerNode).data;
|
||||
if (viewIndex >= tContainer.length || tContainer[viewIndex] == null) {
|
||||
tContainer[viewIndex] = { data: [] } as TView;
|
||||
tContainer[viewIndex] = createTView();
|
||||
}
|
||||
return tContainer[viewIndex];
|
||||
}
|
||||
@ -1215,7 +1158,6 @@ export function viewEnd(): void {
|
||||
|
||||
if (viewIdChanged) {
|
||||
insertView(container, viewNode, containerState.nextIndex - 1);
|
||||
currentView.creationMode = false;
|
||||
}
|
||||
}
|
||||
leaveView(currentView !.parent !);
|
||||
@ -1232,29 +1174,29 @@ export function viewEnd(): void {
|
||||
*
|
||||
* @param directiveIndex
|
||||
* @param elementIndex
|
||||
* @param template
|
||||
*/
|
||||
export const componentRefresh:
|
||||
<T>(directiveIndex: number, elementIndex: number, template: ComponentTemplate<T>) =>
|
||||
void = function<T>(
|
||||
directiveIndex: number, elementIndex: number, template: ComponentTemplate<T>) {
|
||||
ngDevMode && assertDataInRange(elementIndex);
|
||||
const element = data ![elementIndex] as LElementNode;
|
||||
ngDevMode && assertNodeOfPossibleTypes(element, LNodeFlags.Element, LNodeFlags.Container);
|
||||
ngDevMode && assertNotEqual(element.data, null, 'isComponent');
|
||||
ngDevMode && assertDataInRange(directiveIndex);
|
||||
const hostView = element.data !;
|
||||
ngDevMode && assertNotEqual(hostView, null, 'hostView');
|
||||
const directive = data[directiveIndex];
|
||||
const oldView = enterView(hostView, element);
|
||||
try {
|
||||
template(directive, creationMode);
|
||||
} finally {
|
||||
hostView.creationMode = false;
|
||||
refreshDynamicChildren();
|
||||
leaveView(oldView);
|
||||
export function componentRefresh<T>(directiveIndex: number, elementIndex: number): void {
|
||||
executeInitHooks(currentView);
|
||||
executeContentHooks(currentView);
|
||||
const template = (tData[directiveIndex] as ComponentDef<T>).template;
|
||||
if (template != null) {
|
||||
ngDevMode && assertDataInRange(elementIndex);
|
||||
const element = data ![elementIndex] as LElementNode;
|
||||
ngDevMode && assertNodeType(element, LNodeFlags.Element);
|
||||
ngDevMode && assertNotEqual(element.data, null, 'isComponent');
|
||||
ngDevMode && assertDataInRange(directiveIndex);
|
||||
const directive = data[directiveIndex];
|
||||
const hostView = element.data !;
|
||||
ngDevMode && assertNotEqual(hostView, null, 'hostView');
|
||||
const oldView = enterView(hostView, element);
|
||||
try {
|
||||
template(directive, creationMode);
|
||||
} finally {
|
||||
refreshDynamicChildren();
|
||||
leaveView(oldView);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instruction to distribute projectable nodes among <ng-content> occurrences in a given template.
|
||||
@ -1309,6 +1251,34 @@ export function projectionDef(index: number, selectors?: CssSelector[]): void {
|
||||
data[index] = distributedNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the linked list of a projection node, by appending another linked list.
|
||||
*
|
||||
* @param projectionNode Projection node whose projected nodes linked list has to be updated
|
||||
* @param appendedFirst First node of the linked list to append.
|
||||
* @param appendedLast Last node of the linked list to append.
|
||||
*/
|
||||
function appendToProjectionNode(
|
||||
projectionNode: LProjectionNode,
|
||||
appendedFirst: LElementNode | LTextNode | LContainerNode | null,
|
||||
appendedLast: LElementNode | LTextNode | LContainerNode | null) {
|
||||
// appendedFirst can be null if and only if appendedLast is also null
|
||||
ngDevMode &&
|
||||
assertEqual(!appendedFirst === !appendedLast, true, '!appendedFirst === !appendedLast');
|
||||
if (!appendedLast) {
|
||||
// nothing to append
|
||||
return;
|
||||
}
|
||||
const projectionNodeData = projectionNode.data;
|
||||
if (projectionNodeData.tail) {
|
||||
projectionNodeData.tail.pNextOrParent = appendedFirst;
|
||||
} else {
|
||||
projectionNodeData.head = appendedFirst;
|
||||
}
|
||||
projectionNodeData.tail = appendedLast;
|
||||
appendedLast.pNextOrParent = projectionNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts previously re-distributed projected nodes. This instruction must be preceded by a call
|
||||
* to the projectionDef instruction.
|
||||
@ -1318,8 +1288,7 @@ export function projectionDef(index: number, selectors?: CssSelector[]): void {
|
||||
* @param selectorIndex - 0 means <ng-content> without any selector
|
||||
*/
|
||||
export function projection(nodeIndex: number, localIndex: number, selectorIndex: number = 0): void {
|
||||
const projectedNodes: LProjection = [];
|
||||
const node = createLNode(nodeIndex, LNodeFlags.Projection, null, projectedNodes);
|
||||
const node = createLNode(nodeIndex, LNodeFlags.Projection, null, {head: null, tail: null});
|
||||
isParent = false; // self closing
|
||||
const currentParent = node.parent;
|
||||
|
||||
@ -1330,18 +1299,27 @@ export function projection(nodeIndex: number, localIndex: number, selectorIndex:
|
||||
const nodesForSelector =
|
||||
valueInData<LNode[][]>(componentNode.data !.data !, localIndex)[selectorIndex];
|
||||
|
||||
// build the linked list of projected nodes:
|
||||
for (let i = 0; i < nodesForSelector.length; i++) {
|
||||
const nodeToProject = nodesForSelector[i];
|
||||
if ((nodeToProject.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Projection) {
|
||||
const previouslyProjectedNodes = (nodeToProject as LProjectionNode).data;
|
||||
for (let j = 0; j < previouslyProjectedNodes.length; j++) {
|
||||
processProjectedNode(
|
||||
projectedNodes, previouslyProjectedNodes[j], currentParent, currentView);
|
||||
}
|
||||
const previouslyProjected = (nodeToProject as LProjectionNode).data;
|
||||
appendToProjectionNode(node, previouslyProjected.head, previouslyProjected.tail);
|
||||
} else {
|
||||
processProjectedNode(
|
||||
projectedNodes, nodeToProject as LElementNode | LTextNode | LContainerNode, currentParent,
|
||||
currentView);
|
||||
appendToProjectionNode(
|
||||
node, nodeToProject as LTextNode | LElementNode | LContainerNode,
|
||||
nodeToProject as LTextNode | LElementNode | LContainerNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (canInsertNativeNode(currentParent, currentView)) {
|
||||
// process each node in the list of projected nodes:
|
||||
let nodeToProject: LNode|null = node.data.head;
|
||||
const lastNodeToProject = node.data.tail;
|
||||
while (nodeToProject) {
|
||||
appendProjectedNode(
|
||||
nodeToProject as LTextNode | LElementNode | LContainerNode, currentParent, currentView);
|
||||
nodeToProject = nodeToProject === lastNodeToProject ? null : nodeToProject.pNextOrParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1868,8 +1846,8 @@ function valueInData<T>(data: any[], index: number, value?: T): T {
|
||||
return value !;
|
||||
}
|
||||
|
||||
export function getCurrentQuery(QueryType: {new (): LQuery}): LQuery {
|
||||
return currentQuery || (currentQuery = new QueryType());
|
||||
export function getCurrentQueries(QueryType: {new (): LQueries}): LQueries {
|
||||
return currentQueries || (currentQueries = new QueryType());
|
||||
}
|
||||
|
||||
export function getPreviousOrParentNode(): LNode {
|
||||
@ -1895,4 +1873,4 @@ function assertDataInRange(index: number, arr?: any[]) {
|
||||
|
||||
function assertDataNext(index: number) {
|
||||
assertEqual(data.length, index, 'data.length not in sequence');
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,11 @@
|
||||
|
||||
import {ComponentTemplate} from './definition';
|
||||
import {LElementNode, LViewNode} from './node';
|
||||
import {LQueries} from './query';
|
||||
import {LView, TView} from './view';
|
||||
|
||||
|
||||
|
||||
/** The state associated with an LContainer */
|
||||
export interface LContainer {
|
||||
/**
|
||||
@ -67,12 +69,17 @@ export interface LContainer {
|
||||
*/
|
||||
readonly template: ComponentTemplate<any>|null;
|
||||
|
||||
|
||||
/**
|
||||
* A count of dynamic views rendered into this container. If this is non-zero, the `views` array
|
||||
* will be traversed when refreshing dynamic views on this container.
|
||||
*/
|
||||
dynamicViewCount: number;
|
||||
|
||||
/**
|
||||
* Queries active for this container - all the views inserted to / removed from
|
||||
* this container are reported to queries referenced here.
|
||||
*/
|
||||
queries: LQueries|null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,6 +27,9 @@ export const enum DirectiveDefFlags {ContentQuery = 0b10}
|
||||
* `DirectiveDef` is a compiled version of the Directive used by the renderer instructions.
|
||||
*/
|
||||
export interface DirectiveDef<T> {
|
||||
/** Token representing the directive. Used by DI. */
|
||||
type: Type<T>;
|
||||
|
||||
/** Function that makes a directive public to the DI system. */
|
||||
diPublic: ((def: DirectiveDef<any>) => void)|null;
|
||||
|
||||
@ -64,42 +67,23 @@ export interface DirectiveDef<T> {
|
||||
*/
|
||||
n(): T;
|
||||
|
||||
/**
|
||||
* Refreshes the view of the component. Also calls lifecycle hooks like
|
||||
* ngAfterViewInit, if they are defined on the component.
|
||||
*
|
||||
* NOTE: this property is short (1 char) because it is used in component
|
||||
* templates which is sensitive to size.
|
||||
*
|
||||
* @param directiveIndex index of the directive in the containing template
|
||||
* @param elementIndex index of an host element for a given directive.
|
||||
*/
|
||||
r(directiveIndex: number, elementIndex: number): void;
|
||||
|
||||
/**
|
||||
* Refreshes host bindings on the associated directive. Also calls lifecycle hooks
|
||||
* like ngOnInit and ngDoCheck, if they are defined on the directive.
|
||||
*/
|
||||
// Note: This call must be separate from r() because hooks like ngOnInit need to
|
||||
// be called breadth-first across a view before processing onInits in children
|
||||
// (for backwards compatibility). Child template processing thus needs to be
|
||||
// delayed until all inputs and host bindings in a view have been checked.
|
||||
h(directiveIndex: number, elementIndex: number): void;
|
||||
|
||||
/* The following are lifecycle hooks for this component */
|
||||
onInit: (() => void)|null;
|
||||
doCheck: (() => void)|null;
|
||||
afterContentInit: (() => void)|null;
|
||||
afterContentChecked: (() => void)|null;
|
||||
afterViewInit: (() => void)|null;
|
||||
afterViewChecked: (() => void)|null;
|
||||
onDestroy: (() => void)|null;
|
||||
}
|
||||
|
||||
export interface ComponentDef<T> extends DirectiveDef<T> {
|
||||
/**
|
||||
* Refreshes the view of the component. Also calls lifecycle hooks like
|
||||
* ngAfterViewInit, if they are defined on the component.
|
||||
*
|
||||
* NOTE: this property is short (1 char) because it is used in
|
||||
* component templates which is sensitive to size.
|
||||
*
|
||||
* @param directiveIndex index of the directive in the containing template
|
||||
* @param elementIndex index of an host element for a given component.
|
||||
*/
|
||||
r(directiveIndex: number, elementIndex: number): void;
|
||||
|
||||
/**
|
||||
* The tag name which should be used by the component.
|
||||
*
|
||||
@ -122,31 +106,20 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
|
||||
readonly rendererType: RendererType2|null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private: do not export
|
||||
*/
|
||||
export interface TypedDirectiveDef<T> extends DirectiveDef<T> { type: DirectiveType<T>; }
|
||||
|
||||
/**
|
||||
* Private: do not export
|
||||
*/
|
||||
export interface TypedComponentDef<T> extends ComponentDef<T> { type: ComponentType<T>; }
|
||||
|
||||
export interface DirectiveDefArgs<T> {
|
||||
type: Type<T>;
|
||||
factory: () => T;
|
||||
refresh?: (directiveIndex: number, elementIndex: number) => void;
|
||||
inputs?: {[P in keyof T]?: string};
|
||||
outputs?: {[P in keyof T]?: string};
|
||||
methods?: {[P in keyof T]?: string};
|
||||
features?: DirectiveDefFeature[];
|
||||
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
|
||||
exportAs?: string;
|
||||
}
|
||||
|
||||
export interface ComponentDefArgs<T> extends DirectiveDefArgs<T> {
|
||||
tag: string;
|
||||
template: ComponentTemplate<T>;
|
||||
refresh?: (directiveIndex: number, elementIndex: number) => void;
|
||||
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
|
||||
features?: ComponentDefFeature[];
|
||||
rendererType?: RendererType2;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user