Compare commits

..

1 Commits

Author SHA1 Message Date
5bd3916608 release: cut the v6.1.0-rc.0 release 2018-07-11 14:20:42 -07:00
134 changed files with 1643 additions and 4135 deletions

View File

@ -12,8 +12,8 @@
## IMPORTANT
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
var_1: &docker_image angular/ngcontainer:0.3.3
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.3
var_1: &docker_image angular/ngcontainer:0.3.2
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.2
# Define common ENV vars
var_3: &define_env_vars

View File

@ -22,7 +22,6 @@ node_modules_filegroup(
"jasmine",
"minimist",
"protobufjs",
"protractor",
"reflect-metadata",
"source-map-support",
"tsickle",
@ -35,9 +34,6 @@ node_modules_filegroup(
"@types",
"@webcomponents/custom-elements",
],
patterns = [
"node_modules/protractor/**",
],
)
filegroup(

View File

@ -1,12 +1,3 @@
<a name="6.0.9"></a>
## [6.0.9](https://github.com/angular/angular/compare/6.0.8...6.0.9) (2018-07-11)
### Bug Fixes
* **common:** format fractional seconds ([#24844](https://github.com/angular/angular/issues/24844)) ([3c93d07](https://github.com/angular/angular/commit/3c93d07)), closes [#24831](https://github.com/angular/angular/issues/24831)
<a name="6.1.0-rc.0"></a>
# [6.1.0-rc.0](https://github.com/angular/angular/compare/6.1.0-beta.3...6.1.0-rc.0) (2018-07-11)

View File

@ -13,16 +13,16 @@ http_archive(
http_archive(
name = "io_bazel_rules_webtesting",
url = "https://github.com/bazelbuild/rules_webtesting/archive/7ffe970bbf380891754487f66c3d680c087d67f2.zip",
strip_prefix = "rules_webtesting-7ffe970bbf380891754487f66c3d680c087d67f2",
sha256 = "4fb0dca8c9a90547891b7ef486592775a523330fc4555c88cd8f09270055c2ce",
url = "https://github.com/bazelbuild/rules_webtesting/archive/v0.2.0.zip",
strip_prefix = "rules_webtesting-0.2.0",
sha256 = "cecc12f07e95740750a40d38e8b14b76fefa1551bef9332cb432d564d693723c",
)
http_archive(
name = "build_bazel_rules_typescript",
url = "https://github.com/bazelbuild/rules_typescript/archive/0.15.1.zip",
strip_prefix = "rules_typescript-0.15.1",
sha256 = "3792cc20ef13bb1d1d8b1760894c3320f02a87843e3a04fed7e8e454a75328b6",
url = "https://github.com/rkirov/rules_typescript/archive/v0.16.0.zip",
strip_prefix = "rules_typescript-0.16.0",
sha256 = "f5aedd3a792e5af19cd0c0f0318cb692e2989e816e896e794152d07808fccacd",
)
http_archive(
@ -58,7 +58,7 @@ http_archive(
# Even better, things like aspects will visit the entire graph including
# ts_library rules in the devkit repository.
http_archive(
name = "angular_cli",
name = "angular_devkit",
url = "https://github.com/angular/angular-cli/archive/v6.1.0-rc.0.zip",
strip_prefix = "angular-cli-6.1.0-rc.0",
sha256 = "8cf320ea58c321e103f39087376feea502f20eaf79c61a4fdb05c7286c8684fd",
@ -77,7 +77,7 @@ http_archive(
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
check_bazel_version("0.15.0")
check_bazel_version("0.14.0")
node_repositories(package_json = ["//:package.json"])
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")

View File

@ -40,7 +40,7 @@ Angular inserts an instance of the `HeroListComponent` view between those tags.
* `templateUrl`: The module-relative address of this component's HTML template. Alternatively, you can provide the HTML template inline, as the value of the `template` property. This template defines the component's _host view_.
* `providers`: An array of **dependency injection providers** for services that the component requires. In the example, this tells Angular how to provide the `HeroService` instance that the component's constructor uses to get the list of heroes to display.
* `providers`: An array of **dependency injection providers** for services that the component requires. In the example, this tells Angular how provide the `HeroService` instance that the component's constructor uses to get the list of heroes to display.
<hr/>
@ -177,4 +177,4 @@ or modify aspects of DOM elements and components
You can also write your own directives. Components such as `HeroListComponent` are one kind of custom directive. You can also create custom structural and attribute directives.
<!-- PENDING: link to where to learn more about other kinds! -->
<!-- PENDING: link to where to learn more about other kinds! -->

View File

@ -216,9 +216,10 @@ You can also write `<link>` tags into the component's HTML template.
<div class="alert is-critical">
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).
The link tag's `href` URL must be relative to the
_**application root**_, not relative to the component file.
Once included, the CLI will include the stylesheet, whether the link tag's href URL is relative to the application root or 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).
</div>

View File

@ -69,7 +69,7 @@ DOM event object in the `$event` variable which this code passes as a parameter
The properties of an `$event` object vary depending on the type of DOM event. For example,
a mouse event includes different information than an input box editing event.
a mouse event includes different information than a input box editing event.
All [standard DOM event objects](https://developer.mozilla.org/en-US/docs/Web/API/Event)
have a `target` property, a reference to the element that raised the event.

View File

@ -641,12 +641,6 @@
"title": "Angular Academy (Canada)",
"url": "http://www.angularacademy.ca"
},
"at": {
"desc": "Angular Training teaches Angular on-site all over the world. Also provides consulting and mentoring.",
"rev": true,
"title": "Angular Training",
"url": "http://www.angulartraining.com"
},
"-KLIBo_lm-WrK1Sjtt-2": {
"desc": "Basic and Advanced training across Europe in German",
"rev": true,

View File

@ -21,10 +21,10 @@
<article class="api-list-container l-content-small docs-content">
<div *ngFor="let section of filteredSections | async" >
<h2 *ngIf="section.items"><a [href]="section.path">{{section.title}}</a></h2>
<ul class="api-list" *ngIf="section.items?.length">
<h2>{{section.title}}</h2>
<ul class="api-list">
<ng-container *ngFor="let item of section.items">
<li class="api-item">
<li *ngIf="item.show" class="api-item">
<a [href]="item.path"><span class="symbol {{item.docType}}"></span> {{item.title}}</a>
</li>
</ng-container>

View File

@ -36,13 +36,18 @@ describe('ApiListComponent', () => {
*/
function expectFilteredResult(label: string, itemTest: (item: ApiItem) => boolean) {
component.filteredSections.subscribe(filtered => {
filtered = filtered.filter(section => section.items);
let badItem: ApiItem|undefined;
expect(filtered.length).toBeGreaterThan(0, 'expected something');
expect(filtered.every(section => section.items!.every(itemTest))).toBe(true, label);
expect(filtered.every(section => section.items.every(
item => {
const ok = item.show === itemTest(item);
if (!ok) { badItem = item; }
return ok;
}
))).toBe(true, `${label} fail: ${JSON.stringify(badItem, null, 2)}`);
});
}
describe('#filteredSections', () => {
beforeEach(() => {
@ -60,45 +65,34 @@ describe('ApiListComponent', () => {
expectFilteredResult('query: class', item => /class/.test(item.name));
});
it('items should be an array for every item in section when query matches section name', () => {
it('item.show should be true for every item in section when query matches section name', () => {
component.setQuery('core');
component.filteredSections.subscribe(filtered => {
filtered = filtered.filter(section => Array.isArray(section.items));
expect(filtered.length).toBe(1, 'only one section');
expect(filtered[0].name).toBe('core');
expect(filtered[0].items).toEqual(sections.find(section => section.name === 'core')!.items);
expect(filtered[0].items.every(item => !!item.show)).toBe(true, 'all core items shown');
});
});
describe('section.items', () => {
it('should null if there are no matching items and the section itself does not match', () => {
component.setQuery('core');
component.filteredSections.subscribe(filtered => {
const commonSection = filtered.find(section => section.name === 'common')!;
expect(commonSection.items).toBe(null);
});
});
it('should be visible if they have the selected stability status', () => {
component.setStatus({value: 'stable', title: 'Stable'});
expectFilteredResult('status: stable', item => item.stability === 'stable');
});
it('should be visible if they have the selected security status', () => {
component.setStatus({value: 'security-risk', title: 'Security Risk'});
expectFilteredResult('status: security-risk', item => item.securityRisk);
});
it('should be visible if they match the selected API type', () => {
component.setType({value: 'class', title: 'Class'});
expectFilteredResult('type: class', item => item.docType === 'class');
});
it('item.show should be true for items with selected status', () => {
component.setStatus({value: 'stable', title: 'Stable'});
expectFilteredResult('status: stable', item => item.stability === 'stable');
});
it('should have no sections and no items visible when there is no match', () => {
it('item.show should be true for items with "security-risk" status when selected', () => {
component.setStatus({value: 'security-risk', title: 'Security Risk'});
expectFilteredResult('status: security-risk', item => item.securityRisk);
});
it('item.show should be true for items of selected type', () => {
component.setType({value: 'class', title: 'Class'});
expectFilteredResult('type: class', item => item.docType === 'class');
});
it('should have no sections and no items when no match', () => {
component.setQuery('fizbuzz');
component.filteredSections.subscribe(filtered => {
expect(filtered.some(section => !!section.items)).toBeFalsy();
expect(filtered.length).toBe(0, 'expected no sections');
});
});
});
@ -114,11 +108,9 @@ describe('ApiListComponent', () => {
fixture.detectChanges();
component.filteredSections.subscribe(filtered => {
filtered = filtered.filter(s => s.items);
console.log(filtered);
expect(filtered.length).toBe(1, 'sections');
expect(filtered[0].name).toBe(section, 'section name');
const items = filtered[0].items!;
const items = filtered[0].items.filter(i => i.show);
expect(items.length).toBe(1, 'items');
const item = items[0];
@ -226,7 +218,6 @@ const apiSections: ApiSection[] = [
{
"name": "common",
"title": "common",
"path": "api/common",
"items": [
{
"name": "class_1",
@ -265,7 +256,6 @@ const apiSections: ApiSection[] = [
{
"name": "core",
"title": "core",
"path": "api/core",
"items": [
{
"name": "class_3",

View File

@ -49,8 +49,7 @@ export class ApiListComponent implements OnInit {
{ value: 'function', title: 'Function' },
{ value: 'interface', title: 'Interface' },
{ value: 'pipe', title: 'Pipe'},
{ value: 'type-alias', title: 'Type alias' },
{ value: 'package', title: 'Package'}
{ value: 'type-alias', title: 'Type Alias' }
];
statuses: Option[] = [
@ -72,8 +71,7 @@ export class ApiListComponent implements OnInit {
this.apiService.sections,
this.criteriaSubject,
(sections, criteria) => {
return sections
.map(section => ({ ...section, items: this.filterSection(section, criteria) }));
return sections.filter(section => this.filterSection(section, criteria));
}
);
@ -109,8 +107,13 @@ export class ApiListComponent implements OnInit {
//////// Private //////////
private filterSection(section: ApiSection, { query, status, type }: SearchCriteria) {
const items = section.items!.filter(item => {
return matchesType() && matchesStatus() && matchesQuery();
let showSection = false;
section.items.forEach(item => {
item.show = matchesType() && matchesStatus() && matchesQuery();
// show section if any of its items will be shown
showSection = showSection || item.show;
function matchesQuery() {
return !query ||
@ -129,8 +132,8 @@ export class ApiListComponent implements OnInit {
}
});
// If there are no items we still return an empty array if the section name matches and the type is 'package'
return items.length ? items : (type === 'package' && (!query || section.name.indexOf(query) !== -1)) ? [] : null;
return showSection;
}
// Get initial search criteria from URL search params

View File

@ -50,7 +50,7 @@ describe('ApiService', () => {
describe('#sections', () => {
it('first subscriber should fetch sections', done => {
const data = [{name: 'a', title: 'A', path: '', items: []}, {name: 'b', title: 'B', path: '', items: []}];
const data = [{name: 'a', title: 'A', items: []}, {name: 'b', title: 'B', items: []}];
service.sections.subscribe(sections => {
expect(sections).toEqual(data);
@ -61,7 +61,7 @@ describe('ApiService', () => {
});
it('second subscriber should get previous sections and NOT trigger refetch', done => {
const data = [{name: 'a', title: 'A', path: '', items: []}, {name: 'b', title: 'B', path: '', items: []}];
const data = [{name: 'a', title: 'A', items: []}, {name: 'b', title: 'B', items: []}];
let subscriptions = 0;
service.sections.subscribe(sections => {
@ -91,7 +91,7 @@ describe('ApiService', () => {
let call = 0;
let data = [{name: 'a', title: 'A', path: '', items: []}, {name: 'b', title: 'B', path: '', items: []}];
let data = [{name: 'a', title: 'A', items: []}, {name: 'b', title: 'B', items: []}];
service.sections.subscribe(sections => {
// called twice during this test
@ -103,7 +103,7 @@ describe('ApiService', () => {
httpMock.expectOne({}).flush(data);
// refresh/refetch
data = [{name: 'c', title: 'C', path: '', items: []}];
data = [{name: 'c', title: 'C', items: []}];
service.fetchSections();
httpMock.expectOne({}).flush(data);

View File

@ -14,13 +14,14 @@ export interface ApiItem {
docType: string;
stability: string;
securityRisk: boolean;
show?: boolean;
}
export interface ApiSection {
path: string;
name: string;
title: string;
items: ApiItem[]|null;
items: ApiItem[];
}
@Injectable()

View File

@ -28,7 +28,7 @@ h2 {
h3 {
font-size: 20px;
font-weight: 400;
margin: 24px 0px 12px;
margin: 24px 0px;
clear: both;
}
@ -55,10 +55,6 @@ h6 {
}
h2, h3, h4, h5, h6 {
a {
font-size: inherit;
}
@media screen and (max-width: 600px) {
margin: 8px 0;
}
@ -109,7 +105,7 @@ table {
border-collapse: collapse;
border-radius: 2px;
border-spacing: 0;
margin: 12px 0 32px;
margin: 0 0 32px 0;
}
table tbody th {

View File

@ -1,8 +1,8 @@
.api-body {
max-width: 1200px;
table {
margin: 12px 0 24px;
th {
text-transform: none;
@ -18,12 +18,6 @@
vertical-align: middle;
}
tbody > tr > td tr td:first-child {
@media screen and (max-width: 480px) {
background-color: inherit;
}
}
hr {
margin: 16px 0;
}
@ -47,217 +41,5 @@
.short-description {
margin-left: 0;
}
&.parameters-table {
margin-top: 0;
font-size: 14px;
box-shadow: none;
tr {
border: 0;
@media screen and (max-width: 480px) {
display: flex;
flex-direction: column;
}
td:first-child {
font-weight: 600;
}
}
td {
padding: 8px 8px 8px 0;
border: 0;
vertical-align: top;
}
td:nth-child(1) {
width: 20%;
}
}
}
.class-overview {
position: relative;
code-example {
clear: left;
}
}
.icon-action-header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.method-table th {
display: flex;
}
.method-table, .option-table {
th {
.action-icons {
a {
color: $mediumgray;
.material-icons:hover {
background: none;
color: $blue;
}
}
}
}
h3 {
margin: 6px 0;
font-weight: bold;
clear: left;
}
h4 {
font-size: 14px;
font-weight: bold;
margin-top: 12px;
}
}
.api-heading {
padding: 5px 0;
font-size: 14px;
font-weight: bold;
}
.short-description {
margin: 6px 0 0 10px;
}
.properties-table {
font-size: 14px;
thead th {
&:nth-child(1) {
width: 20%;
}
&:nth-child(2) {
width: 20%;
}
}
}
details.overloads {
box-shadow: none;
.icon-action-header a {
display: flex;
}
.detail-contents {
padding: 0;
border: 1px solid $lightgray;
border-radius: 2px;
box-shadow: none;
> *:not(hr) {
margin: 16px 24px;
}
}
summary {
height: inherit;
padding: 0 8px 8px;
h4 {
margin: 0;
}
}
table {
&.is-full-width {
width: auto;
}
}
}
.from-constructor, .read-only-property {
font-size: 12px;
font-weight: 600;
letter-spacing: 0.5px;
font-style: italic;
background-color: $lightgray;
border-radius: 4px;
padding: 4px 6px;
}
}
.breadcrumb-container {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.github-links {
.material-icons {
border-radius: 4px;
padding: 4px;
font-size: 20px;
&:hover {
background-color: $mist;
}
}
}
.api-header {
display: flex;
align-items: center;
@media screen and (max-width: 600px) {
flex-direction: column;
align-items: flex-start;
}
}
// ____________________________________________
/*
* General styling to make detail/summary tags look a bit more material
* To get the best out of it you should structure your usage like this:
*
* ```
* <details>
* <summary>Some title</summary>
* <div class="details-content">
* Some content
* </div>
* </details>
*
*/
summary {
cursor: pointer;
font-size: 16px;
position: relative;
padding: 16px 24px;
color: $black;
height: 16px;
display: block; // Remove the built in details marker in FF
&::-webkit-details-marker {
display: none; // Remove the built in details marker in webkit
}
}
details {
box-shadow: 0 1px 4px 0 rgba($black, 0.37);
.detail-contents {
padding: 16px 24px;
}
&[open] > i.material-icons {
@include rotate(180deg); // Rotate the icon
}
}
}

View File

@ -0,0 +1,114 @@
.github-links {
float: right;
.material-icons {
border-radius: 4px;
padding: 4px;
font-size: 20px;
&:hover {
background-color: $mist;
}
}
}
.api-header {
display: flex;
align-items: center;
@media screen and (max-width: 600px) {
flex-direction: column;
align-items: flex-start;
}
}
.api-body {
.class-overview {
position: relative;
code-example {
clear: left;
}
}
.method-table, .option-table {
th {
display: flex;
align-items: center;
h3 {
flex: 1;
}
.github-links {
a {
color: $mediumgray;
.material-icons:hover {
background: none;
color: $blue;
}
}
}
}
h3 {
margin: 6px 0;
font-weight: bold;
clear: left;
}
h4 {
font-size: 14px;
font-weight: bold;
margin-top: 12px;
}
}
.api-heading {
padding: 5px 0;
font-size: 16px;
font-weight: bold;
}
.short-description {
margin: 6px 0 0 10px;
}
.properties-table {
font-size: 14px;
thead th {
&:nth-child(1) {
width: 20%;
}
&:nth-child(2) {
width: 20%;
}
}
}
.parameters-table {
margin-top: 0;
font-size: 14px;
td:nth-child(1) {
width: 20%;
}
}
details.overloads {
margin-left: -8px;
summary {
height: inherit;
padding: 8px 12px;
h4 {
margin: 0;
clear: left;
}
}
}
.from-constructor, .read-only-property {
font-style: italic;
color: $blue;
}
}

View File

@ -0,0 +1,48 @@
/*
* General styling to make detail/summary tags look a bit more material
* To get the best out of it you should structure your usage like this:
*
* ```
* <details>
* <summary>Some title</summary>
* <div class="details-content">
* Some content
* </div>
* </details>
*
*/
summary {
cursor: pointer;
font-size: 16px;
position: relative;
padding: 16px 24px;
color: $black;
height: 16px;
display: block; // Remove the built in details marker in FF
&::-webkit-details-marker {
display: none; // Remove the built in details marker in webkit
}
&::before {
content: '\E5CE'; // See https://material.io/icons/#ic_expand_less
font-family: 'Material Icons';
font-size: 24px;
-webkit-font-smoothing: antialiased;
@include rotate(0deg); // We will rotate 180 degrees when details is open
float: right;
}
}
details {
box-shadow: 0 1px 4px 0 rgba($black, 0.37);
.detail-contents {
padding: 16px 24px;
}
&[open] > summary::before {
@include rotate(180deg); // Rotate the icon
}
}

View File

@ -3,3 +3,12 @@ hr {
background: $lightgray;
height: 1px;
}
.hr-margin {
display: block;
height: 1px;
border: 0;
margin-top: 16px;
margin-bottom: 16px;
padding: 0;
}

View File

@ -3,6 +3,7 @@
============================== */
@import 'alert';
@import 'api-pages';
@import 'api-list';
@import 'buttons';
@import 'callout';
@ -10,6 +11,7 @@
@import 'code';
@import 'contribute';
@import 'contributor';
@import 'details';
@import 'edit-page-cta';
@import 'features';
@import 'filetree';

View File

@ -105,7 +105,7 @@ $api-symbols: (
content: 'T',
background: $light-green-600
),
package: (
module: (
content: 'Pk',
background: $purple-600
)

View File

@ -33,7 +33,6 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
.processor(require('./processors/simplifyMemberAnchors'))
.processor(require('./processors/computeStability'))
.processor(require('./processors/removeInjectableConstructors'))
.processor(require('./processors/processPackages'))
/**
* These are the API doc types that will be rendered to actual files.
@ -41,7 +40,7 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
* more Angular specific API types, such as decorators and directives.
*/
.factory(function API_DOC_TYPES_TO_RENDER(EXPORT_DOC_TYPES) {
return EXPORT_DOC_TYPES.concat(['decorator', 'directive', 'pipe', 'package']);
return EXPORT_DOC_TYPES.concat(['decorator', 'directive', 'pipe', 'module']);
})
/**
@ -59,10 +58,8 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
return API_DOC_TYPES_TO_RENDER.concat(API_CONTAINED_DOC_TYPES);
})
.factory(require('./readers/package-content'))
// Where do we get the source files?
.config(function(readTypeScriptModules, readFilesProcessor, collectExamples, tsParser, packageContentFileReader) {
.config(function(readTypeScriptModules, readFilesProcessor, collectExamples, tsParser) {
// Tell TypeScript how to load modules that start with with `@angular`
tsParser.options.paths = { '@angular/*': [API_SOURCE_PATH + '/*'] };
@ -105,19 +102,12 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
'upgrade/static/index.ts',
];
readFilesProcessor.fileReaders.push(packageContentFileReader);
// API Examples
readFilesProcessor.sourceFiles = [
{
basePath: API_SOURCE_PATH,
include: API_SOURCE_PATH + '/examples/**/*',
fileReader: 'exampleFileReader'
},
{
basePath: API_SOURCE_PATH,
include: API_SOURCE_PATH + '/**/PACKAGE.md',
fileReader: 'packageContentFileReader'
}
];
collectExamples.exampleFolders.push('examples');
@ -133,7 +123,7 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
.config(function(computeStability, splitDescription, addNotYetDocumentedProperty, API_DOC_TYPES_TO_RENDER, API_DOC_TYPES) {
computeStability.docTypes = API_DOC_TYPES_TO_RENDER;
// Only split the description on the API docs
splitDescription.docTypes = API_DOC_TYPES.concat(['package-content']);
splitDescription.docTypes = API_DOC_TYPES;
addNotYetDocumentedProperty.docTypes = API_DOC_TYPES;
})
@ -190,7 +180,7 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
generateApiListDoc.outputFolder = API_SEGMENT;
computePathsProcessor.pathTemplates.push({
docTypes: ['package'],
docTypes: ['module'],
getPath: function computeModulePath(doc) {
doc.moduleFolder = `${API_SEGMENT}/${doc.id.replace(/\/index$/, '')}`;
return doc.moduleFolder;

View File

@ -33,7 +33,7 @@ describe('addSelectorsAsAliases processor', () => {
{ docType: 'directive', name: 'NgModel', aliases: ['NgModel'], directiveOptions: { selector: '\'[ngModel]:not([formControlName]):not([formControl])\'' } },
{ docType: 'component', name: 'MyComponent', aliases: ['MyComponent'], componentOptions: { selector: '\'my-component\'' } },
{ docType: 'decorator', name: 'MyDecorator', aliases: ['MyDecorator'] },
{ docType: 'package', name: 'myPackage', aliases: ['myPackage'], id: 'some/myPackage' },
{ docType: 'module', name: 'myModule', aliases: ['myModule'], id: 'some/myModule' },
{ docType: 'var', name: 'myVar', aliases: ['myVar'] },
{ docType: 'let', name: 'myLet', aliases: ['myLet'] },
{ docType: 'const', name: 'myConst', aliases: ['myConst'] },

View File

@ -14,14 +14,14 @@ describe('angular-api-package: computeApiBreadCrumbs processor', () => {
});
it('should attach a breadCrumbs property to each of the API_DOC_TYPES_TO_RENDER docs', () => {
const API_DOC_TYPES_TO_RENDER = ['class', 'interface', 'package'];
const API_DOC_TYPES_TO_RENDER = ['class', 'interface', 'module'];
const processor = processorFactory(API_DOC_TYPES_TO_RENDER);
const docs = [
{ docType: 'class', name: 'ClassA', path: 'module-1/class-a', moduleDoc: { id: 'moduleOne', path: 'module-1' } },
{ docType: 'interface', name: 'InterfaceB', path: 'module-2/interface-b', moduleDoc: { id: 'moduleTwo', path: 'module-2' } },
{ docType: 'guide', name: 'Guide One', path: 'guide/guide-1' },
{ docType: 'package', name: 'testing', id: 'http/testing', path: 'http/testing' },
{ docType: 'module', name: 'testing', id: 'http/testing', path: 'http/testing' },
];
processor.$process(docs);

View File

@ -8,7 +8,7 @@ module.exports = function computeSearchTitleProcessor() {
case 'function':
doc.searchTitle = `${doc.name}()`;
break;
case 'package':
case 'module':
doc.searchTitle = `${doc.id} package`;
break;
}

View File

@ -31,7 +31,7 @@ describe('computeSearchTitle processor', () => {
{ docType: 'pipe', name: 'MyPipe', pipeOptions: { name: 'myPipe' } },
{ docType: 'directive', name: 'MyDirective', directiveOptions: {} },
{ docType: 'decorator', name: 'MyDecorator' },
{ docType: 'package', name: 'myPackage', id: 'some/myPackage' },
{ docType: 'module', name: 'myModule', id: 'some/myModule' },
{ docType: 'var', name: 'myVar' },
{ docType: 'let', name: 'myLet' },
{ docType: 'const', name: 'myConst' },
@ -45,7 +45,7 @@ describe('computeSearchTitle processor', () => {
expect(docs[4].searchTitle).toBeUndefined();
expect(docs[5].searchTitle).toBeUndefined();
expect(docs[6].searchTitle).toBeUndefined();
expect(docs[7].searchTitle).toEqual('some/myPackage package');
expect(docs[7].searchTitle).toEqual('some/myModule package');
expect(docs[8].searchTitle).toBeUndefined();
expect(docs[9].searchTitle).toBeUndefined();
expect(docs[10].searchTitle).toBeUndefined();

View File

@ -12,20 +12,19 @@ module.exports = function generateApiListDoc() {
path: this.outputFolder + '/api-list.json',
outputPath: this.outputFolder + '/api-list.json',
data: docs
.filter(doc => doc.docType === 'package')
.map(getPackageInfo)
.filter(doc => doc.docType === 'module')
.map(getModuleInfo)
});
}
};
};
function getPackageInfo(packageDoc) {
const packageName = packageDoc.id.replace(/\/index$/, '');
function getModuleInfo(moduleDoc) {
const moduleName = moduleDoc.id.replace(/\/index$/, '');
return {
name: packageName.toLowerCase(),
title: packageName,
path: packageDoc.path,
items: packageDoc.exports
name: moduleName.toLowerCase(),
title: moduleName,
items: moduleDoc.exports
// Ignore internals and private exports (indicated by the ɵ prefix)
.filter(doc => !doc.internal && !doc.privateExport)
.map(getExportInfo)

View File

@ -38,28 +38,28 @@ describe('generateApiListDoc processor', () => {
it('should add an info object to the doc for each module doc', () => {
const processor = processorFactory();
const docs = [
{ docType: 'package', id: '@angular/common/index', exports: [], path: 'common' },
{ docType: 'package', id: '@angular/core/index', exports: [], path: 'core' },
{ docType: 'package', id: '@angular/http/index', exports: [], path: 'http' },
{ docType: 'module', id: '@angular/common/index', exports: [] },
{ docType: 'module', id: '@angular/core/index', exports: [] },
{ docType: 'module', id: '@angular/http/index', exports: [] },
];
processor.$process(docs);
expect(docs[3].data).toEqual([
{ name: '@angular/common', title: '@angular/common', items: [], path: 'common' },
{ name: '@angular/core', title: '@angular/core', items: [], path: 'core' },
{ name: '@angular/http', title: '@angular/http', items: [], path: 'http' },
{ name: '@angular/common', title: '@angular/common', items: [] },
{ name: '@angular/core', title: '@angular/core', items: [] },
{ name: '@angular/http', title: '@angular/http', items: [] },
]);
});
it('should add info about each export on each module', () => {
const processor = processorFactory();
const docs = [
{ docType: 'package', id: '@angular/common/index', exports: [
{ docType: 'module', id: '@angular/common/index', exports: [
{ docType: 'directive', name: 'AaaAaa', path: 'aaa' },
{ docType: 'pipe', name: 'BbbBbb', path: 'bbb' },
{ docType: 'decorator', name: 'CccCcc', path: 'ccc' },
{ docType: 'class', name: 'DddDdd', path: 'ddd' }
] },
{ docType: 'package', id: '@angular/core/index', exports: [
{ docType: 'module', id: '@angular/core/index', exports: [
{ docType: 'interface', name: 'EeeEee', path: 'eee' },
{ docType: 'function', name: 'FffFff', path: 'fff' },
{ docType: 'enum', name: 'GggGgg', path: 'ggg' },
@ -86,7 +86,7 @@ describe('generateApiListDoc processor', () => {
it('should ignore internal and private exports', () => {
const processor = processorFactory();
const docs = [
{ docType: 'package', id: '@angular/common/index', exports: [
{ docType: 'module', id: '@angular/common/index', exports: [
{ docType: 'directive', name: 'AaaAaa', path: 'aaa', internal: true },
{ docType: 'class', name: 'XxxXxx', path: 'xxx', privateExport: true },
{ docType: 'pipe', name: 'BbbBbb', path: 'bbb' }
@ -101,7 +101,7 @@ describe('generateApiListDoc processor', () => {
it('should convert `let` and `var` docTypes to `const`', () => {
const processor = processorFactory();
const docs = [
{ docType: 'package', id: '@angular/common/index', exports: [
{ docType: 'module', id: '@angular/common/index', exports: [
{ docType: 'var', name: 'AaaAaa', path: 'aaa' },
{ docType: 'let', name: 'BbbBbb', path: 'bbb' },
]}
@ -116,7 +116,7 @@ describe('generateApiListDoc processor', () => {
it('should convert security to a boolean securityRisk', () => {
const processor = processorFactory();
const docs = [
{ docType: 'package', id: '@angular/common/index', exports: [
{ docType: 'module', id: '@angular/common/index', exports: [
{ docType: 'class', name: 'AaaAaa', path: 'aaa', security: 'This is a security risk' },
{ docType: 'class', name: 'BbbBbb', path: 'bbb', security: '' },
]}
@ -131,7 +131,7 @@ describe('generateApiListDoc processor', () => {
it('should convert stability tags to the stable string property', () => {
const processor = processorFactory();
const docs = [
{ docType: 'package', id: '@angular/common/index', exports: [
{ docType: 'module', id: '@angular/common/index', exports: [
{ docType: 'class', name: 'AaaAaa', path: 'aaa', stable: undefined },
{ docType: 'class', name: 'BbbBbb', path: 'bbb', experimental: 'Some message' },
{ docType: 'class', name: 'CccCcc', path: 'ccc', deprecated: null },
@ -150,7 +150,7 @@ describe('generateApiListDoc processor', () => {
it('should sort items in each group alphabetically', () => {
const processor = processorFactory();
const docs = [
{ docType: 'package', id: '@angular/common/index', exports: [
{ docType: 'module', id: '@angular/common/index', exports: [
{ docType: 'class', name: 'DddDdd', path: 'uuu' },
{ docType: 'class', name: 'BbbBbb', path: 'vvv' },
{ docType: 'class', name: 'AaaAaa', path: 'xxx' },

View File

@ -1,63 +0,0 @@
const { dirname } = require('canonical-path');
module.exports = function processPackages() {
return {
$runAfter: ['extractDecoratedClassesProcessor'],
$runBefore: ['computing-ids'],
$process(docs) {
const packageContentFiles = {};
const packageMap = {};
docs = docs.filter(doc => {
if (doc.docType === 'package-content') {
packageContentFiles[dirname(doc.fileInfo.filePath)] = doc;
return false;
} else {
return true;
}
});
docs.forEach(doc => {
if (doc.docType === 'module') {
// Convert the doc type from "module" to "package"
doc.docType = 'package';
// The name is actually the full id
doc.name = `@angular/${doc.id}`;
// Partition the exports into groups by type
if (doc.exports) {
doc.classes = doc.exports.filter(doc => doc.docType === 'class');
doc.decorators = doc.exports.filter(doc => doc.docType === 'decorator');
doc.functions = doc.exports.filter(doc => doc.docType === 'function');
doc.structures = doc.exports.filter(doc => doc.docType === 'enum' || doc.docType === 'interface');
doc.directives = doc.exports.filter(doc => doc.docType === 'directive');
doc.pipes = doc.exports.filter(doc => doc.docType === 'pipe');
doc.types = doc.exports.filter(doc => doc.docType === 'type-alias' || doc.docType === 'const');
}
// Copy over docs from the PACKAGE.md file that is used to document packages
const readmeDoc = packageContentFiles[dirname(doc.fileInfo.filePath)];
if (readmeDoc) {
doc.shortDescription = readmeDoc.shortDescription;
doc.description = readmeDoc.description;
doc.see = readmeDoc.see;
doc.fileInfo = readmeDoc.fileInfo;
}
// Compute the primary/secondary entry point relationships
const packageParts = doc.id.split('/');
const primaryPackageName = packageParts[0];
doc.isPrimaryPackage = packageParts.length === 1;
doc.packageInfo = packageMap[primaryPackageName] = packageMap[primaryPackageName] || { primary: undefined, secondary: [] };
if (doc.isPrimaryPackage) {
doc.packageInfo.primary = doc;
} else {
doc.packageInfo.secondary.push(doc);
}
}
});
return docs;
}
};
};

View File

@ -1,180 +0,0 @@
const testPackage = require('../../helpers/test-package');
const processorFactory = require('./processPackages');
const Dgeni = require('dgeni');
describe('processPackages processor', () => {
it('should be available on the injector', () => {
const dgeni = new Dgeni([testPackage('angular-api-package')]);
const injector = dgeni.configureInjector();
const processor = injector.get('processPackages');
expect(processor.$process).toBeDefined();
expect(processor.$runAfter).toEqual(['extractDecoratedClassesProcessor']);
expect(processor.$runBefore).toEqual(['computing-ids']);
});
it('should filter out any `package-content` docs from the collection', () => {
const docs = [
{ fileInfo: { filePath: 'some/a' }, docType: 'a', id: 'a' },
{ fileInfo: { filePath: 'some/x' }, docType: 'package-content', id: 'x' },
{ fileInfo: { filePath: 'some/b' }, docType: 'b', id: 'b' },
{ fileInfo: { filePath: 'some/y' }, docType: 'package-content', id: 'y' },
{ fileInfo: { filePath: 'some/z' }, docType: 'package-content', id: 'z' },
];
const processor = processorFactory();
const newDocs = processor.$process(docs);
expect(newDocs).toEqual([
{ fileInfo: { filePath: 'some/a' }, docType: 'a', id: 'a' },
{ fileInfo: { filePath: 'some/b' }, docType: 'b', id: 'b' },
]);
});
it('should change `module` docs to `package` docs', () => {
const processor = processorFactory();
const docs = [
{ fileInfo: { filePath: 'some/a' }, docType: 'module', id: 'a' },
{ fileInfo: { filePath: 'some/b' }, docType: 'module', id: 'b' },
{ docType: 'other', id: 'c' },
];
const newDocs = processor.$process(docs);
expect(newDocs).toEqual([
jasmine.objectContaining({ docType: 'package', id: 'a' }),
jasmine.objectContaining({ docType: 'package', id: 'b' }),
jasmine.objectContaining({ docType: 'other', id: 'c' }),
]);
});
it('should attach the relevant package contents to the package doc', () => {
const docs = [
{
fileInfo: { filePath: 'some/package-1/index' },
docType: 'module',
id: 'package-1',
someProp: 'foo',
},
{
fileInfo: { filePath: 'some/package-1/PACKAGE.md' },
docType: 'package-content',
id: 'package-1/PACKAGE.md',
shortDescription: 'some short description',
description: 'some description',
see: [ 'a', 'b' ],
},
{
fileInfo: { filePath: 'some/package-2/index' },
docType: 'module',
id: 'package-2',
},
];
const processor = processorFactory();
const newDocs = processor.$process(docs);
const package1 = jasmine.objectContaining({
fileInfo: { filePath: 'some/package-1/PACKAGE.md' },
docType: 'package',
name: '@angular/package-1',
id: 'package-1',
someProp: 'foo',
shortDescription: 'some short description',
description: 'some description',
see: [ 'a', 'b' ],
isPrimaryPackage: true,
});
const package2 = jasmine.objectContaining({
fileInfo: { filePath: 'some/package-2/index' },
docType: 'package',
name: '@angular/package-2',
id: 'package-2',
isPrimaryPackage: true,
});
expect(newDocs).toEqual([package1, package2]);
});
it('should compute primary and second package info', () => {
const docs = [
{
fileInfo: { filePath: 'some/package-1/index' },
docType: 'module',
id: 'package-1',
},
{
fileInfo: { filePath: 'some/package-1/sub-1index' },
docType: 'module',
id: 'package-1/sub-1',
},
{
fileInfo: { filePath: 'some/package-1/sub-2index' },
docType: 'module',
id: 'package-1/sub-2',
},
];
const processor = processorFactory();
const newDocs = processor.$process(docs);
expect(newDocs[0].isPrimaryPackage).toBe(true);
expect(newDocs[1].isPrimaryPackage).toBe(false);
expect(newDocs[2].isPrimaryPackage).toBe(false);
expect(newDocs[0].packageInfo.primary).toBe(newDocs[0]);
expect(newDocs[1].packageInfo.primary).toBe(newDocs[0]);
expect(newDocs[2].packageInfo.primary).toBe(newDocs[0]);
expect(newDocs[0].packageInfo.secondary).toEqual([newDocs[1], newDocs[2]]);
expect(newDocs[1].packageInfo.secondary).toEqual([newDocs[1], newDocs[2]]);
expect(newDocs[2].packageInfo.secondary).toEqual([newDocs[1], newDocs[2]]);
});
it('should partition the exports of packages into groups', () => {
const docs = [
{
fileInfo: { filePath: 'some/x' },
docType: 'module',
id: 'x',
exports: [
{ docType: 'directive', id: 'directive-1' },
{ docType: 'function', id: 'function-1' },
{ docType: 'directive', id: 'directive-2' },
{ docType: 'decorator', id: 'decorator-1' },
{ docType: 'class', id: 'class-1' },
{ docType: 'type-alias', id: 'type-alias-1' },
{ docType: 'class', id: 'class-2' },
{ docType: 'pipe', id: 'pipe-1' },
{ docType: 'const', id: 'const-1' },
{ docType: 'const', id: 'const-2' },
{ docType: 'enum', id: 'enum-1' },
{ docType: 'interface', id: 'interface-1' },
{ docType: 'interface', id: 'interface-2' },
]
},
];
const processor = processorFactory();
const newDocs = processor.$process(docs);
expect(newDocs[0].decorators).toEqual([
{ docType: 'decorator', id: 'decorator-1' },
]);
expect(newDocs[0].functions).toEqual([
{ docType: 'function', id: 'function-1' },
]);
expect(newDocs[0].structures).toEqual([
{ docType: 'enum', id: 'enum-1' },
{ docType: 'interface', id: 'interface-1' },
{ docType: 'interface', id: 'interface-2' },
]);
expect(newDocs[0].directives).toEqual([
{ docType: 'directive', id: 'directive-1' },
{ docType: 'directive', id: 'directive-2' },
]);
expect(newDocs[0].pipes).toEqual([
{ docType: 'pipe', id: 'pipe-1' },
]);
expect(newDocs[0].types).toEqual([
{ docType: 'type-alias', id: 'type-alias-1' },
{ docType: 'const', id: 'const-1' },
{ docType: 'const', id: 'const-2' },
]);
});
});

View File

@ -1,25 +0,0 @@
/**
* @dgService
* @description
* This file reader will pull the contents from a text file that will be used
* as the description of a package.
*
* The doc will initially have the form:
* ```
* {
* content: 'the content of the file',
* startingLine: 1
* }
* ```
*/
module.exports = function packageContentFileReader() {
return {
name: 'packageContentFileReader',
defaultPattern: /PACKAGE\.md$/,
getDocs: function(fileInfo) {
// We return a single element array because content files only contain one document
return [{docType: 'package-content', content: fileInfo.content, startingLine: 1}];
}
};
};

View File

@ -14,7 +14,7 @@ module.exports = function createOverviewDump() {
modules: []
};
_.forEach(docs, function(doc) {
if (doc.docType === 'package') {
if (doc.docType === 'module') {
overviewDoc.modules.push(doc);
}
});

View File

@ -2,21 +2,19 @@
{% set comma = joiner(',') %}
{% set slash = joiner('/') %}
<article>
<div class="breadcrumb-container">
<div class="breadcrumb">
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{%- for crumb in doc.breadCrumbs %}{$ comma() $}
{ "@type": "ListItem", "position": {$ loop.index $}, "item": { "@id": "https://angular.io/{$ crumb.path $}", "name": "{$ crumb.text $}" } }{% endfor %}
]
}
</script>
{% for crumb in doc.breadCrumbs %}{% if not loop.last %} {$ slash() $} {% if crumb.path %}<a href="{$ crumb.path $}">{$ crumb.text $}</a>{% else %}{$ crumb.text $}{% endif %}{% endif %}{% endfor %}
</div>
{$ github.githubLinks(doc, versionInfo) $}
{$ github.githubLinks(doc, versionInfo) $}
<div class="breadcrumb">
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{%- for crumb in doc.breadCrumbs %}{$ comma() $}
{ "@type": "ListItem", "position": {$ loop.index $}, "item": { "@id": "https://angular.io/{$ crumb.path $}", "name": "{$ crumb.text $}" } }{% endfor %}
]
}
</script>
{% for crumb in doc.breadCrumbs %}{% if not loop.last %} {$ slash() $} {% if crumb.path %}<a href="{$ crumb.path $}">{$ crumb.text $}</a>{% else %}{$ crumb.text $}{% endif %}{% endif %}{% endfor %}
</div>
<header class="api-header">
<h1>{$ doc.name $}</h1>

View File

@ -1,12 +1,12 @@
{% macro githubViewHref(doc, versionInfo) -%}
https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}/tree/{$ versionInfo.currentVersion.isSnapshot and versionInfo.currentVersion.SHA or versionInfo.currentVersion.raw $}/packages/{$ doc.fileInfo.realProjectRelativePath or doc.fileInfo.relativePath $}#L{$ doc.startingLine + 1 $}-L{$ doc.endingLine + 1 $}
https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}/tree/{$ versionInfo.currentVersion.isSnapshot and versionInfo.currentVersion.SHA or versionInfo.currentVersion.raw $}/packages/{$ doc.fileInfo.realProjectRelativePath $}#L{$ doc.startingLine + 1 $}-L{$ doc.endingLine + 1 $}
{%- endmacro -%}
{% macro githubEditHref(doc, versionInfo) -%}
https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}/edit/master/packages/{$ doc.fileInfo.realProjectRelativePath or doc.fileInfo.relativePath $}?message=docs(
https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}/edit/master/packages/{$ doc.fileInfo.realProjectRelativePath $}?message=docs(
{%- if doc.moduleDoc %}{$ doc.moduleDoc.id.split('/')[0] $}
{%- elseif doc.docType === 'package' %}{$ doc.id.split('/')[0] $}
{%- elseif doc.docType === 'module' %}{$ doc.id.split('/')[0] $}
{%- else %}...{%- endif -%}
)%3A%20describe%20your%20change...#L{$ doc.startingLine + 1 $}-L{$ doc.endingLine + 1 $}
{%- endmacro -%}
@ -16,4 +16,4 @@ https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInf
<a href="{$ githubEditHref(doc, versionInfo) $}" aria-label="Suggest Edits" title="Suggest Edits"><i class="material-icons" aria-hidden="true" role="img">mode_edit</i></a>
<a href="{$ githubViewHref(doc, versionInfo) $}" aria-label="View Source" title="View Source"><i class="material-icons" aria-hidden="true" role="img">code</i></a>
</div>
{%- endmacro -%}
{%- endmacro -%}

View File

@ -47,17 +47,17 @@
<code-example language="ts" hideCopy="true" linenums="false" class="no-box api-heading">{$ renderMemberSyntax(overload) $}</code-example>
<h6 class="no-anchor">Parameters</h6>
<h4 class="no-anchor">Parameters</h4>
{$ params.renderParameters(overload.parameterDocs, cssClass + '-parameters', cssClass + '-parameter') $}
{% if overload.type or overload.returns.type %}
<h6 class="no-anchor">Returns</h6>
<h4 class="no-anchor">Returns</h4>
{% marked %}`{$ (overload.type or overload.returns.type) $}`{% if overload.returns %}: {$ overload.returns.description $}{% endif %}{% endmarked %}
{% endif %}
{% if overload.throws.length %}
<h6 class="no-anchor">Throws</h6>
<h4 class="no-anchor">Throws</h4>
{% for error in overload.throws %}
{% marked %}`{$ (error.typeList or 'Error') $}` {$ error.description $}{% endmarked %}
{% endfor %}
@ -73,7 +73,7 @@
{%- macro renderMethodDetail(versionInfo, method, cssClass) -%}
<a id="{$ method.anchor $}"></a>
<table class="is-full-width method-table {$ cssClass $}">
{% if method.name !== 'constructor' %}<thead><tr><th class="icon-action-header">
{% if method.name !== 'constructor' %}<thead><tr><th>
<h3>
{% if method.isCallMember %}<i>call signature</i>
{% elseif method.isNewMember %}<i>construct signature</i>
@ -106,22 +106,12 @@
<tr>
<td>
<details class="overloads">
<summary>
<div class="icon-action-header">
<h4 class="no-anchor">Overloads</h4>
<a>Show All <i class="material-icons">expand_more</i></a>
</div>
</summary>
<summary><h4 class="no-anchor">{$ method.overloads.length $} overloads...</h4></summary>
<div class="detail-contents">
{% for overload in method.overloads %}
<div>
<h5 class="icon-action-header no-anchor">
<span>Overload #_ of {$ method.overloads.length $}</span>
<i class="material-icons">expand_more</i></h5>
{% for overload in method.overloads %}
{$ renderOverloadInfo(overload, cssClass + '-overload', method) $}
{% if not loop.last %}<hr class="hr-margin">{% endif %}
{% if not loop.last %}<hr class="hr-margin fullwidth">{% endif %}
{% endfor %}
</div>
</div>
</details>
</td>
@ -180,10 +170,10 @@
<td><a id="{$ property.anchor $}"></a>{$ property.name $}</td>
{% if hasTypes %}<td><label class="property-type-label"><code>{$ property.type | escape $}</code></label></td>{% endif %}
<td>
{%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}<span class='read-only-property'>Read Only</span>{% endif %}
{%- if (property.isGetAccessor or property.isReadonly) and not property.isSetAccessor %}<span class='read-only-property'>Read-only.</span>{% endif %}
{% if property.shortDescription %}{$ property.shortDescription | marked $}{% endif %}
{$ (property.description or property.constructorParamDoc.description) | marked $}
{% if property.constructorParamDoc %} <span class='from-constructor'>Declared in Constructor</span>{% endif %}
{% if property.constructorParamDoc %} <span class='from-constructor'>Declared in constructor.</span>{% endif %}
</td>
</tr>
{% endfor %}

View File

@ -0,0 +1,16 @@
{% extends 'base.template.html' -%}
{% block body -%}
{% include "includes/deprecation.html" %}
{% include "includes/description.html" %}
<section class="export-list">
<ul>
{% for export in doc.exports -%}
<li><a href="{$ export.path $}">{$ export.name $}</a></li>
{%- endfor %}
</ul>
</section>
{%- endblock %}

View File

@ -1,40 +0,0 @@
{% extends 'base.template.html' -%}
{% macro listItems(items, title) %}
{% if items.length %}
<section class="export-list">
<h3>{$ title $}</h3>
<table class="is-full-width list-table">
{% for item in items %}
<tr>
<td><code class="code-anchor">
<a href="{$ item.path $}">{$ item.name $}</a></code></td>
<td>{% if item.shortDescription %}{$ item.shortDescription | marked $}{% endif %}</td>
</tr>
{% endfor %}
</table>
</section>
{% endif %}
{% endmacro %}
{% block body -%}
{% include "includes/deprecation.html" %}
{$ doc.shortDescription | marked $}
{% if doc.description %}{$ doc.description | marked $}{% endif %}
{% include "includes/see-also.html" %}
<h2>Entry points</h2>
{$ listItems([doc.packageInfo.primary], 'Primary') $}
{$ listItems(doc.packageInfo.secondary, 'Secondary') $}
<h2>Exports</h2>
{$ listItems(doc.classes, 'Classes') $}
{$ listItems(doc.decorators, 'Decorators') $}
{$ listItems(doc.functions, 'Functions') $}
{$ listItems(doc.structures, 'Structures') $}
{$ listItems(doc.directives, 'Directives') $}
{$ listItems(doc.pipes, 'Pipes') $}
{$ listItems(doc.types, 'Types') $}
{%- endblock %}

View File

@ -1,9 +1,5 @@
package(default_visibility = ["//visibility:public"])
exports_files([
"protractor.conf.js",
])
filegroup(
name = "node_modules",
srcs = glob(

View File

@ -13,9 +13,9 @@ http_archive(
http_archive(
name = "io_bazel_rules_webtesting",
url = "https://github.com/bazelbuild/rules_webtesting/archive/8fd9ce0fd9254bde251da0bc373d6cd08e811434.zip",
strip_prefix = "rules_webtesting-8fd9ce0fd9254bde251da0bc373d6cd08e811434",
sha256 = "4baee95fcfadfbaf868707af8accfd1cb98c5d13f808908e0152468bfb47f0f7",
url = "https://github.com/bazelbuild/rules_webtesting/archive/v0.2.0.zip",
strip_prefix = "rules_webtesting-0.2.0",
sha256 = "cecc12f07e95740750a40d38e8b14b76fefa1551bef9332cb432d564d693723c",
)
http_archive(
@ -44,7 +44,7 @@ http_archive(
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
check_bazel_version("0.15.0")
check_bazel_version("0.14.0")
node_repositories(package_json = ["//:package.json"])
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")

View File

@ -18,13 +18,17 @@
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
"@types/jasmine": "2.8.7",
"@types/source-map": "0.5.1",
"concurrently": "3.5.1",
"http-server": "0.11.1",
"protractor": "file:../../node_modules/protractor",
"tsutils": "file:../../node_modules/tsutils",
"typescript": "file:../../node_modules/typescript"
},
"scripts": {
"postinstall": "ngc -p angular.tsconfig.json",
"test": "bazel build ... --noshow_progress && bazel test ..."
"postinstall": "concurrently \"webdriver-manager update $CHROMEDRIVER_VERSION_ARG\" \"ngc -p angular.tsconfig.json\"",
"test": "bazel build //... --noshow_progress && yarn e2e",
"pree2e": "bazel build test/...",
"e2e": "yarn e2e-prodserver && yarn e2e-devserver",
"e2e-prodserver": "concurrently \"bazel run //src:prodserver\" \"while ! nc -z 127.0.0.1 5432; do sleep 1; done && protractor\" --kill-others --success first",
"e2e-devserver": "concurrently \"bazel run //src:devserver\" \"while ! nc -z 127.0.0.1 5432; do sleep 1; done && protractor\" --kill-others --success first"
}
}
}

View File

@ -1,4 +1,9 @@
exports.config = {
specs: ['bazel-bin/test/e2e/*.spec.js'],
capabilities: {browserName: 'chrome', chromeOptions: {args: ['--no-sandbox']}},
directConnect: true,
baseUrl: 'http://localhost:5432/',
framework: 'jasmine',
getPageTimeout: 60 * 1000,
allScriptsTimeout: 60 * 1000,
};

View File

@ -1,5 +1,3 @@
package(default_visibility = ["//visibility:public"])
load("@angular//:index.bzl", "ng_module")
# Allow targets under sub-packages to reference the tsconfig.json file
@ -48,11 +46,15 @@ genrule(
nodejs_binary(
name = "prodserver",
args = [
"./src",
"-p",
"5432",
],
data = [
"index.html",
":bundle",
":zone.js",
],
entry_point = "http-server/bin/http-server",
templated_args = ["src"],
)

View File

@ -1,34 +1,7 @@
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
load("@angular//:index.bzl", "protractor_web_test_suite")
ts_library(
name = "e2e",
testonly = 1,
srcs = ["app.spec.ts"],
)
ts_library(
name = "ts_on_prepare",
testonly = 1,
srcs = ["on-prepare.ts"],
tsconfig = ":tsconfig.json",
deps = ["@angular//src/protractor/utils"],
)
protractor_web_test_suite(
name = "devserver_test",
configuration = "//:protractor.conf.js",
data = ["@angular//src/protractor/utils"],
on_prepare = ":ts_on_prepare",
server = "//src:devserver",
deps = [":e2e"],
)
protractor_web_test_suite(
name = "prodserver_test",
configuration = "//:protractor.conf.js",
data = ["@angular//src/protractor/utils"],
on_prepare = ":ts_on_prepare",
server = "//src:prodserver",
deps = [":e2e"],
srcs = glob(["*.ts"]),
)

View File

@ -1,4 +1,4 @@
import {browser, by, element} from 'protractor';
import {browser, by, element, ExpectedConditions} from 'protractor';
jasmine.DEFAULT_TIMEOUT_INTERVAL = 120000;

View File

@ -1,12 +0,0 @@
import { browser } from 'protractor';
import {OnPrepareConfig, runServer} from '@angular/bazel/protractor-utils';
export = function(config: OnPrepareConfig) {
const portFlag = config.server.endsWith('prodserver') ? '-p' : '-port';
return runServer(config.workspace, config.server, portFlag, [])
.then(serverSpec => {
const serverUrl = `http://localhost:${serverSpec.port}`;
console.log(`Server has been started, starting tests against ${serverUrl}`);
browser.baseUrl = serverUrl;
});
}

View File

@ -1,5 +0,0 @@
{
"compilerOptions": {
"lib": ["es2015"]
}
}

View File

@ -3,12 +3,12 @@
"@angular/animations@file:../../dist/packages-dist/animations":
version "6.1.0-beta.1"
version "6.0.0-rc.5"
dependencies:
tslib "^1.9.0"
"@angular/bazel@file:../../dist/packages-dist/bazel":
version "6.1.0-beta.1"
version "6.0.0-rc.5"
dependencies:
"@bazel/typescript" "^0.15.0"
"@types/node" "6.0.84"
@ -17,12 +17,12 @@
shelljs "0.7.8"
"@angular/common@file:../../dist/packages-dist/common":
version "6.1.0-beta.1"
version "6.0.0-rc.5"
dependencies:
tslib "^1.9.0"
"@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli":
version "6.1.0-beta.1"
version "6.0.0-rc.5"
dependencies:
chokidar "^1.4.2"
minimist "^1.2.0"
@ -30,22 +30,22 @@
tsickle "^0.29.0"
"@angular/compiler@file:../../dist/packages-dist/compiler":
version "6.1.0-beta.1"
version "6.0.0-rc.5"
dependencies:
tslib "^1.9.0"
"@angular/core@file:../../dist/packages-dist/core":
version "6.1.0-beta.1"
version "6.0.0-rc.5"
dependencies:
tslib "^1.9.0"
"@angular/platform-browser-dynamic@file:../../dist/packages-dist/platform-browser-dynamic":
version "6.1.0-beta.1"
version "6.0.0-rc.5"
dependencies:
tslib "^1.9.0"
"@angular/platform-browser@file:../../dist/packages-dist/platform-browser":
version "6.1.0-beta.1"
version "6.0.0-rc.5"
dependencies:
tslib "^1.9.0"
@ -74,16 +74,16 @@
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
"@types/node@*":
version "10.3.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.3.4.tgz#c74e8aec19e555df44609b8057311052a2c84d9e"
version "10.1.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.1.4.tgz#606651d3f8a8bec08b8cb262161aab9209f4a29d"
"@types/node@6.0.84":
version "6.0.84"
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.84.tgz#193ffe5a9f42864d425ffd9739d95b753c6a1eab"
"@types/node@^6.0.46":
version "6.0.113"
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.113.tgz#4b41f38ad03e4b41f9dc259b3b58aecb22c9aebc"
version "6.0.111"
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.111.tgz#85f880a1bab78d395a5de9bcb5319e73a0c31400"
"@types/q@^0.0.32":
version "0.0.32"
@ -132,6 +132,10 @@ ajv@^5.1.0:
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
ansi-regex@^0.2.0, ansi-regex@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
@ -140,6 +144,10 @@ ansi-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
ansi-styles@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de"
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
@ -278,6 +286,16 @@ caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
chalk@0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174"
dependencies:
ansi-styles "^1.1.0"
escape-string-regexp "^1.0.0"
has-ansi "^0.1.0"
strip-ansi "^0.3.0"
supports-color "^0.2.0"
chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@ -337,10 +355,27 @@ combined-stream@1.0.6, combined-stream@~1.0.5:
dependencies:
delayed-stream "~1.0.0"
commander@2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.6.0.tgz#9df7e52fb2a0cb0fb89058ee80c3104225f37e1d"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
concurrently@3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-3.5.1.tgz#ee8b60018bbe86b02df13e5249453c6ececd2521"
dependencies:
chalk "0.5.1"
commander "2.6.0"
date-fns "^1.23.0"
lodash "^4.5.1"
rx "2.3.24"
spawn-command "^0.0.2-1"
supports-color "^3.2.3"
tree-kill "^1.1.0"
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"
@ -359,6 +394,10 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
date-fns@^1.23.0:
version "1.29.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6"
debug@2, debug@^2.1.2, debug@^2.2.0:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@ -418,7 +457,7 @@ ecstatic@^3.0.0:
minimist "^1.1.0"
url-join "^2.0.2"
escape-string-regexp@^1.0.2:
escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
@ -606,12 +645,22 @@ har-validator@~5.0.3:
ajv "^5.1.0"
har-schema "^2.0.0"
has-ansi@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e"
dependencies:
ansi-regex "^0.2.0"
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
dependencies:
ansi-regex "^2.0.0"
has-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@ -845,6 +894,10 @@ lcid@^1.0.0:
dependencies:
invert-kv "^1.0.0"
lodash@^4.5.1:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
long@~3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b"
@ -1250,8 +1303,8 @@ requires-port@^1.0.0:
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
resolve@^1.1.6:
version "1.8.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
version "1.7.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3"
dependencies:
path-parse "^1.0.5"
@ -1261,6 +1314,10 @@ rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1:
dependencies:
glob "^7.0.5"
rx@2.3.24:
version "2.3.24"
resolved "https://registry.yarnpkg.com/rx/-/rx-2.3.24.tgz#14f950a4217d7e35daa71bbcbe58eff68ea4b2b7"
"rxjs@file:../../node_modules/rxjs":
version "6.0.0"
dependencies:
@ -1270,7 +1327,7 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0,
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2:
"safer-buffer@>= 2.1.2 < 3":
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@ -1356,15 +1413,18 @@ source-map@^0.6.0:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
spawn-command@^0.0.2-1:
version "0.0.2-1"
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0"
sshpk@^1.7.0:
version "1.14.2"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98"
version "1.14.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.1.tgz#130f5975eddad963f1d56f92b9ac6c51fa9f83eb"
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
dashdash "^1.12.0"
getpass "^0.1.1"
safer-buffer "^2.0.2"
optionalDependencies:
bcrypt-pbkdf "^1.0.0"
ecc-jsbn "~0.1.1"
@ -1392,6 +1452,12 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
strip-ansi@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220"
dependencies:
ansi-regex "^0.2.1"
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"
@ -1408,10 +1474,20 @@ 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"
supports-color@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
supports-color@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
dependencies:
has-flag "^1.0.0"
tar@^4:
version "4.4.4"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.4.tgz#ec8409fae9f665a4355cc3b4087d0820232bb8cd"
@ -1440,6 +1516,10 @@ tough-cookie@~2.3.3:
dependencies:
punycode "^1.4.1"
tree-kill@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.0.tgz#5846786237b4239014f05db156b643212d4c6f36"
tsickle@^0.29.0:
version "0.29.0"
resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.29.0.tgz#812806554bb46c1aa16eb0fe2a051da95ca8f5a4"
@ -1449,15 +1529,10 @@ tsickle@^0.29.0:
source-map "^0.6.0"
source-map-support "^0.5.0"
tslib@^1.8.1, tslib@^1.9.0:
tslib@^1.9.0:
version "1.9.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.2.tgz#8be0cc9a1f6dc7727c38deb16c2ebd1a2892988e"
"tsutils@file:../../node_modules/tsutils":
version "2.20.0"
dependencies:
tslib "^1.8.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
@ -1469,7 +1544,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
"typescript@file:../../node_modules/typescript":
version "2.8.3"
version "2.7.2"
ultron@1.0.x:
version "1.0.2"

View File

@ -77,7 +77,7 @@ module.exports = function(config) {
'dist/all/@angular/compiler/test/aot/**',
'dist/all/@angular/compiler/test/render3/**',
'dist/all/@angular/core/test/bundling/**',
'dist/all/@angular/core/test/render3/ivy/**',
'dist/all/@angular/core/test/render3/**',
'dist/all/@angular/elements/schematics/**',
'dist/all/@angular/examples/**/e2e_test/*',
'dist/all/@angular/language-service/**',

View File

@ -48,13 +48,13 @@ export class LargeTableComponent {
{
if (rf2 & RenderFlags.Create) {
E(0, 'td');
s(c0);
{ T(1); }
s(1, c0);
{ T(2); }
e();
}
if (rf2 & RenderFlags.Update) {
sp(0, 0, cell.row % 2 ? '' : 'grey');
t(1, b(cell.value));
sp(1, 0, cell.row % 2 ? '' : 'grey');
t(2, b(cell.value));
}
}
v();

View File

@ -41,16 +41,16 @@ export class TreeComponent {
template: function(rf: RenderFlags, ctx: TreeComponent) {
if (rf & RenderFlags.Create) {
E(0, 'span');
s(c0);
{ T(1); }
s(1, c0);
{ T(2); }
e();
C(2);
C(3);
C(4);
}
if (rf & RenderFlags.Update) {
sp(0, 0, ctx.data.depth % 2 ? '' : 'grey');
t(1, i1(' ', ctx.data.value, ' '));
cR(2);
sp(1, 0, ctx.data.depth % 2 ? '' : 'grey');
t(2, i1(' ', ctx.data.value, ' '));
cR(3);
{
if (ctx.data.left != null) {
let rf0 = V(0);
@ -67,7 +67,7 @@ export class TreeComponent {
}
}
cr();
cR(3);
cR(4);
{
if (ctx.data.right != null) {
let rf0 = V(0);
@ -114,18 +114,18 @@ export function TreeTpl(rf: RenderFlags, ctx: TreeNode) {
E(0, 'tree');
{
E(1, 'span');
s(c1);
{ T(2); }
s(2, c1);
{ T(3); }
e();
C(3);
C(4);
C(5);
}
e();
}
if (rf & RenderFlags.Update) {
sp(1, 0, ctx.depth % 2 ? '' : 'grey');
t(2, i1(' ', ctx.value, ' '));
cR(3);
sp(2, 0, ctx.depth % 2 ? '' : 'grey');
t(3, i1(' ', ctx.value, ' '));
cR(4);
{
if (ctx.left != null) {
let rf0 = V(0);
@ -134,7 +134,7 @@ export function TreeTpl(rf: RenderFlags, ctx: TreeNode) {
}
}
cr();
cR(4);
cR(5);
{
if (ctx.right != null) {
let rf0 = V(0);

View File

@ -26,7 +26,6 @@ ng_package(
entry_point = "packages/animations/index.js",
tags = [
"ivy-jit",
"ivy-local",
"release-with-framework",
],
deps = [

View File

@ -1,29 +0,0 @@
Implements a domain-specific language (DSL) for defining web animation sequences for HTML elements as
multiple transformations over time.
Use this API to define how an HTML element can move, change color, grow or shrink, fade, or slide off
the page. These changes can occur simultaneously or sequentially. You can control the timing of each
of these transformations. The function calls generate the data structures and metadata that enable Angular
to integrate animations into templates and run them based on application states.
Animation definitions are linked to components through the `{@link Component.animations animations}`
property in the `@Component` metadata, typically in the component file of the HTML element to be animated.
The `trigger()` function encapsulates a named animation, with all other function calls nested within. Use
the trigger name to bind the named animation to a specific triggering element in the HTML template.
Angular animations are based on CSS web transition functionality, so anything that can be styled or
transformed in CSS can be animated the same way in Angular. Angular animations allow you to:
* Set animation timings, styles, keyframes, and transitions.
* Animate HTML elements in complex sequences and choreographies.
* Animate HTML elements as they are inserted and removed from the DOM, including responsive real-time
filtering.
* Create reusable animations.
* Animate parent and child elements.
Additional animation functionality is provided in other Angular modules for animation testing, for
route-based animations, and for programmatic animation controls that allow an end user to fast forward
and reverse an animation sequence.
@see Find out more in the [animations guide](guide/animations).
@see See what polyfills you might need in the [browser support guide](guide/browser-support).

View File

@ -9,11 +9,6 @@ Users should not load files under "/src"
load("//packages/bazel/src:ng_module.bzl", _ng_module = "ng_module")
load("//packages/bazel/src/ng_package:ng_package.bzl", _ng_package = "ng_package")
load("//packages/bazel/src/protractor:protractor_web_test.bzl",
_protractor_web_test = "protractor_web_test",
_protractor_web_test_suite = "protractor_web_test_suite")
ng_module = _ng_module
ng_package = _ng_package
protractor_web_test = _protractor_web_test
protractor_web_test_suite = _protractor_web_test_suite

View File

@ -5,7 +5,6 @@ filegroup(
srcs = glob(["*"]) + [
"//packages/bazel/src/ng_package:package_assets",
"//packages/bazel/src/ngc-wrapped:package_assets",
"//packages/bazel/src/protractor:package_assets",
],
visibility = ["//packages/bazel:__subpackages__"],
)
@ -14,7 +13,7 @@ load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
nodejs_binary(
name = "rollup_with_build_optimizer",
data = ["@angular_cli//packages/angular_devkit/build_optimizer:lib"],
data = ["@angular_devkit//packages/angular_devkit/build_optimizer:lib"],
# Since our rule extends the one in rules_nodejs, we use the same runtime
# dependency @build_bazel_rules_nodejs_rollup_deps. We don't need any
# additional npm dependencies when we run rollup or uglify.

View File

@ -24,7 +24,7 @@ load(":esm5.bzl", "esm5_outputs_aspect", "flatten_esm5", "esm5_root_dir")
PACKAGES=["packages/core/src", "packages/common/src", "packages/compiler/src", "external/rxjs"]
PLUGIN_CONFIG="{sideEffectFreeModules: [\n%s]}" % ",\n".join(
[" '.esm5/{0}'".format(p) for p in PACKAGES])
BO_ROLLUP="angular_cli/packages/angular_devkit/build_optimizer/src/build-optimizer/rollup-plugin.js"
BO_ROLLUP="angular_devkit/packages/angular_devkit/build_optimizer/src/build-optimizer/rollup-plugin.js"
BO_PLUGIN="require('%s').default(%s)" % (BO_ROLLUP, PLUGIN_CONFIG)
def _use_plain_rollup(ctx):

View File

@ -1,13 +0,0 @@
package(default_visibility = ["//visibility:public"])
filegroup(
name = "package_assets",
srcs = glob(["*"]) + [
"//packages/bazel/src/protractor/utils:package_assets",
],
visibility = ["//packages/bazel:__subpackages__"],
)
exports_files([
"protractor.conf.js",
])

View File

@ -1,154 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
const path = require('path');
const DEBUG = false;
const configPath = 'TMPL_config';
const onPreparePath = 'TMPL_on_prepare';
const workspace = 'TMPL_workspace';
const server = 'TMPL_server';
if (DEBUG)
console.info(`Protractor test starting with:
cwd: ${process.cwd()}
configPath: ${configPath}
onPreparePath: ${onPreparePath}
workspace: ${workspace}
server: ${server}`);
// Helper function to warn when a user specified value is being overwritten
function setConf(conf, name, value, msg) {
if (conf[name] && conf[name] !== value) {
console.warn(
`Your protractor configuration specifies an option which is overwritten by Bazel: '${name}' ${msg}`);
}
conf[name] = value;
}
let conf = {};
// Import the user's base protractor configuration if specified
if (configPath) {
const baseConf = require(configPath);
if (!baseConf.config) {
throw new Error('Invalid base protractor configration. Expected config to be exported.');
}
conf = baseConf.config;
}
// Import the user's on prepare function if specified
if (onPreparePath) {
const onPrepare = require(onPreparePath);
if (typeof onPrepare === 'function') {
const original = conf.onPrepare;
conf.onPrepare = function() {
return Promise.resolve(original ? original() : null)
.then(() => Promise.resolve(onPrepare({workspace, server})));
};
} else {
throw new Error(
'Invalid protractor on_prepare script. Expected a function as the default export.');
}
}
// Override the user's base protractor configuration as appropriate based on the
// ts_web_test_suite & rules_webtesting WEB_TEST_METADATA attributes
setConf(conf, 'framework', 'jasmine2', 'is set to jasmine2');
const specs = [TMPL_specs]
.map(s => require.resolve(s))
.filter(s => s.endsWith('.spec.js') || s.endsWith('.test.js'));
setConf(conf, 'specs', specs, 'are determined by the srcs and deps attribute');
// WEB_TEST_METADATA is configured in rules_webtesting based on value
// of the browsers attribute passed to ts_web_test_suite
// We setup the protractor configuration based on the values in this object
if (process.env['WEB_TEST_METADATA']) {
const webTestMetadata = require(process.env['WEB_TEST_METADATA']);
if (DEBUG) console.info(`WEB_TEST_METADATA: ${JSON.stringify(webTestMetadata, null, 2)}`);
if (webTestMetadata['environment'] === 'sauce') {
// If a sauce labs browser is chosen for the test such as
// "@io_bazel_rules_webtesting//browsers/sauce:chrome-win10"
// than the 'environment' will equal 'sauce'.
// We expect that a SAUCE_USERNAME and SAUCE_ACCESS_KEY is available
// from the environment for this test to run
// TODO(gmagolan): implement sauce labs support for protractor
throw new Error('Saucelabs not yet support by protractor_web_test_suite.');
// if (!process.env.SAUCE_USERNAME || !process.env.SAUCE_ACCESS_KEY) {
// console.error('Make sure the SAUCE_USERNAME and SAUCE_ACCESS_KEY environment variables are
// set.');
// process.exit(1);
// }
// setConf(conf, 'sauceUser', process.env.SAUCE_USERNAME, 'is determined by the SAUCE_USERNAME
// environment variable');
// setConf(conf, 'sauceKey', process.env.SAUCE_ACCESS_KEY, 'is determined by the
// SAUCE_ACCESS_KEY environment variable');
} else if (webTestMetadata['environment'] === 'local') {
// When a local chrome or firefox browser is chosen such as
// "@io_bazel_rules_webtesting//browsers:chromium-local" or
// "@io_bazel_rules_webtesting//browsers:firefox-local"
// then the 'environment' will equal 'local' and
// 'webTestFiles' will contain the path to the binary to use
const webTestNamedFiles = webTestMetadata['webTestFiles'][0]['namedFiles'];
const headless = !process.env['DISPLAY'];
if (webTestNamedFiles['CHROMIUM']) {
const chromeBin = path.join(process.cwd(), 'external', webTestNamedFiles['CHROMIUM']);
const args = [];
if (headless) {
args.push('--headless');
args.push('--disable-gpu');
}
setConf(conf, 'directConnect', true, 'is set to true for chrome');
setConf(
conf, 'chromeDriver',
path.join(process.cwd(), 'external', webTestNamedFiles['CHROMEDRIVER']),
'is determined by the browsers attribute');
setConf(
conf, 'capabilities', {
browserName: 'chrome',
chromeOptions: {
binary: chromeBin,
args: args,
}
},
'is determined by the browsers attribute');
}
if (webTestNamedFiles['FIREFOX']) {
// TODO(gmagolan): implement firefox support for protractor
throw new Error('Firefox not yet support by protractor_web_test_suite');
// const firefoxBin = path.join('external', webTestNamedFiles['FIREFOX']);
// const args = [];
// if (headless) {
// args.push("--headless")
// args.push("--marionette")
// }
// setConf(conf, 'seleniumAddress', process.env.WEB_TEST_HTTP_SERVER.trim() + "/wd/hub", 'is
// configured by Bazel for firefox browser')
// setConf(conf, 'capabilities', {
// browserName: "firefox",
// 'moz:firefoxOptions': {
// binary: firefoxBin,
// args: args,
// }
// }, 'is determined by the browsers attribute');
}
} else {
console.warn(`Unknown WEB_TEST_METADATA environment '${webTestMetadata['environment']}'`);
}
}
// Export the complete protractor configuration
if (DEBUG) console.info(`Protractor configuration: ${JSON.stringify(conf, null, 2)}`);
exports.config = conf;

View File

@ -1,341 +0,0 @@
# 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
"""Implementation of the protractor_web_test and protractor_web_test_suite rules.
"""
load("@build_bazel_rules_nodejs//internal:node.bzl",
"sources_aspect",
"expand_path_into_runfiles",
)
load("@io_bazel_rules_webtesting//web:web.bzl", "web_test_suite")
load("@io_bazel_rules_webtesting//web/internal:constants.bzl", "DEFAULT_WRAPPED_TEST_TAGS")
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
_CONF_TMPL = "//packages/bazel/src/protractor:protractor.conf.js"
def _protractor_web_test_impl(ctx):
configuration = ctx.actions.declare_file(
"%s.conf.js" % ctx.label.name,
sibling=ctx.outputs.executable)
files = depset(ctx.files.srcs)
for d in ctx.attr.deps:
if hasattr(d, "node_sources"):
files = depset(transitive = [files, d.node_sources])
elif hasattr(d, "files"):
files = depset(transitive = [files, d.files])
specs = [
expand_path_into_runfiles(ctx, f.short_path)
for f in files
]
configuration_sources = []
if ctx.file.configuration:
configuration_sources = [ctx.file.configuration]
if hasattr(ctx.attr.configuration, "node_sources"):
configuration_sources = ctx.attr.configuration.node_sources.to_list()
configuration_file = ctx.file.configuration
if hasattr(ctx.attr.configuration, "typescript"):
configuration_file = ctx.attr.configuration.typescript.es5_sources.to_list()[0]
on_prepare_sources = []
if ctx.file.on_prepare:
on_prepare_sources = [ctx.file.on_prepare]
if hasattr(ctx.attr.on_prepare, "node_sources"):
on_prepare_sources = ctx.attr.on_prepare.node_sources.to_list()
on_prepare_file = ctx.file.on_prepare
if hasattr(ctx.attr.on_prepare, "typescript"):
on_prepare_file = ctx.attr.on_prepare.typescript.es5_sources.to_list()[0]
protractor_executable_path = ctx.executable.protractor.short_path
if protractor_executable_path.startswith('..'):
protractor_executable_path = "external" + protractor_executable_path[2:]
server_executable_path = ''
if ctx.executable.server:
server_executable_path = ctx.executable.server.short_path
if server_executable_path.startswith('..'):
server_executable_path = "external" + protractor_executable_path[2:]
ctx.actions.expand_template(
output = configuration,
template = ctx.file._conf_tmpl,
substitutions = {
"TMPL_config": expand_path_into_runfiles(ctx, configuration_file.short_path) if configuration_file else "",
"TMPL_on_prepare": expand_path_into_runfiles(ctx, on_prepare_file.short_path) if on_prepare_file else "",
"TMPL_workspace": ctx.workspace_name,
"TMPL_server": server_executable_path,
"TMPL_specs": "\n".join([" '%s'," % e for e in specs]),
})
runfiles = [configuration] + configuration_sources + on_prepare_sources
ctx.actions.write(
output = ctx.outputs.executable,
is_executable = True,
content = """#!/usr/bin/env bash
if [ -e "$RUNFILE_MANIFEST_FILE" ]; then
while read line; do
declare -a PARTS=($line)
if [ "${{PARTS[0]}}" == "angular/{TMPL_protractor}" ]; then
readonly PROTRACTOR=${{PARTS[1]}}
elif [ "${{PARTS[0]}}" == "angular/{TMPL_conf}" ]; then
readonly CONF=${{PARTS[1]}}
fi
done < $RUNFILE_MANIFEST_FILE
else
readonly PROTRACTOR={TMPL_protractor}
readonly CONF={TMPL_conf}
fi
export HOME=$(mktemp -d)
# Print the protractor version in the test log
PROTRACTOR_VERSION=$($PROTRACTOR --version)
echo "Protractor $PROTRACTOR_VERSION"
# Run the protractor binary
$PROTRACTOR $CONF
""".format(TMPL_protractor = protractor_executable_path,
TMPL_conf = configuration.short_path))
return [DefaultInfo(
files = depset([ctx.outputs.executable]),
runfiles = ctx.runfiles(
files = runfiles,
transitive_files = files,
# Propagate protractor_bin and its runfiles
collect_data = True,
collect_default = True,
),
executable = ctx.outputs.executable,
)]
_protractor_web_test = rule(
implementation = _protractor_web_test_impl,
test = True,
executable = True,
attrs = {
"configuration": attr.label(
doc = "Protractor configuration file",
allow_single_file = True,
cfg = "data",
aspects = [sources_aspect]),
"srcs": attr.label_list(
doc = "A list of JavaScript test files",
allow_files = [".js"]),
"on_prepare": attr.label(
doc = """A file with a node.js script to run once before all tests run.
If the script exports a function which returns a promise, protractor
will wait for the promise to resolve before beginning tests.""",
allow_single_file = True,
cfg = "data",
aspects = [sources_aspect]),
"deps": attr.label_list(
doc = "Other targets which produce JavaScript such as `ts_library`",
allow_files = True,
aspects = [sources_aspect]),
"data": attr.label_list(
doc = "Runtime dependencies",
cfg = "data"),
"server": attr.label(
doc = "Optional server executable target",
executable = True,
cfg = "data",
single_file = False,
allow_files = True),
"protractor": attr.label(
doc = "Protractor executable target (set by protractor_web_test macro)",
executable = True,
cfg = "data",
single_file = False,
allow_files = True),
"_conf_tmpl": attr.label(
default = Label(_CONF_TMPL),
allow_single_file = True,
),
},
)
def protractor_web_test(
name,
configuration = None,
on_prepare = None,
srcs = [],
deps = [],
data = [],
server = None,
tags = [],
**kwargs):
"""Runs a protractor test in a browser.
Args:
name: The name of the test
configuration: Protractor configuration file.
on_prepare: A file with a node.js script to run once before all tests run.
If the script exports a function which returns a promise, protractor
will wait for the promise to resolve before beginning tests.
srcs: JavaScript source files
deps: Other targets which produce JavaScript such as `ts_library`
data: Runtime dependencies
server: Optional server executable target
tags: Standard Bazel tags, this macro adds one for ibazel
**kwargs: passed through to `_protractor_web_test`
"""
protractor_bin_name = name + "_protractor_bin"
nodejs_binary(
name = protractor_bin_name,
entry_point = "protractor/bin/protractor",
data = srcs + deps + data,
node_modules = "@//:node_modules",
testonly = 1,
visibility = ["//visibility:private"],
)
# Our binary dependency must be in data[] for collect_data to pick it up
# FIXME: maybe we can just ask :protractor_bin_name for its runfiles attr
web_test_data = data + [":" + protractor_bin_name]
if server:
web_test_data += [server]
_protractor_web_test(
name = name,
configuration = configuration,
on_prepare=on_prepare,
srcs = srcs,
deps = deps,
data = web_test_data,
server = server,
protractor = protractor_bin_name,
tags = tags + [
# Users don't need to know that this tag is required to run under ibazel
"ibazel_notify_changes",
],
**kwargs)
def protractor_web_test_suite(
name,
configuration = None,
on_prepare = None,
srcs = [],
deps = [],
data = [],
server = None,
browsers=["@io_bazel_rules_webtesting//browsers:chromium-local"],
args=None,
browser_overrides=None,
config=None,
flaky=None,
local=None,
shard_count=None,
size=None,
tags = [],
test_suite_tags=None,
timeout=None,
visibility=None,
web_test_data=[],
wrapped_test_tags=None,
**remaining_keyword_args):
"""Defines a test_suite of web_test targets that wrap a protractor_web_test target.
Args:
name: The base name of the test.
configuration: Protractor configuration file.
on_prepare: A file with a node.js script to run once before all tests run.
If the script exports a function which returns a promise, protractor
will wait for the promise to resolve before beginning tests.
srcs: JavaScript source files
deps: Other targets which produce JavaScript such as `ts_library`
data: Runtime dependencies
server: Optional server executable target
browsers: A sequence of labels specifying the browsers to use.
args: Args for web_test targets generated by this extension.
browser_overrides: Dictionary; optional; default is an empty dictionary. A
dictionary mapping from browser names to browser-specific web_test
attributes, such as shard_count, flakiness, timeout, etc. For example:
{'//browsers:chrome-native': {'shard_count': 3, 'flaky': 1}
'//browsers:firefox-native': {'shard_count': 1, 'timeout': 100}}.
config: Label; optional; Configuration of web test features.
flaky: A boolean specifying that the test is flaky. If set, the test will
be retried up to 3 times (default: 0)
local: boolean; optional.
shard_count: The number of test shards to use per browser. (default: 1)
size: A string specifying the test size. (default: 'large')
tags: A list of test tag strings to apply to each generated web_test target.
This macro adds a couple for ibazel.
test_suite_tags: A list of tag strings for the generated test_suite.
timeout: A string specifying the test timeout (default: computed from size)
visibility: List of labels; optional.
web_test_data: Data dependencies for the web_test.
wrapped_test_tags: A list of test tag strings to use for the wrapped test
**remaining_keyword_args: Arguments for the wrapped test target.
"""
# Check explicitly for None so that users can set this to the empty list
if wrapped_test_tags == None:
wrapped_test_tags = DEFAULT_WRAPPED_TEST_TAGS
size = size or "large"
wrapped_test_name = name + "_wrapped_test"
protractor_bin_name = name + "_protractor_bin"
# Users don't need to know that this tag is required to run under ibazel
tags = tags + ["ibazel_notify_changes"]
nodejs_binary(
name = protractor_bin_name,
entry_point = "protractor/bin/protractor",
data = srcs + deps + data,
node_modules = "@//:node_modules",
testonly = 1,
visibility = ["//visibility:private"],
)
# Our binary dependency must be in data[] for collect_data to pick it up
# FIXME: maybe we can just ask the :protractor_bin_name for its runfiles attr
web_test_data = web_test_data + [":" + protractor_bin_name]
if server:
web_test_data += [server]
_protractor_web_test(
name=wrapped_test_name,
configuration=configuration,
on_prepare=on_prepare,
srcs=srcs,
deps=deps,
data=web_test_data,
server=server,
protractor=protractor_bin_name,
args=args,
flaky=flaky,
local=local,
shard_count=shard_count,
size=size,
tags=wrapped_test_tags,
timeout=timeout,
visibility=["//visibility:private"],
**remaining_keyword_args)
web_test_suite(
name=name,
launcher=":"+wrapped_test_name,
args=args,
browsers=browsers,
browser_overrides=browser_overrides,
config=config,
data=web_test_data,
flaky=flaky,
local=local,
shard_count=shard_count,
size=size,
tags=tags,
test=wrapped_test_name,
test_suite_tags=test_suite_tags,
timeout=timeout,
visibility=visibility)

View File

@ -1,16 +0,0 @@
package(default_visibility = ["//visibility:public"])
filegroup(
name = "package_assets",
srcs = glob(["*"]),
visibility = ["//packages/bazel:__subpackages__"],
)
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
ts_library(
name = "utils",
srcs = ["index.ts"],
module_name = "@angular/bazel/protractor-utils",
tsconfig = ":tsconfig.json",
)

View File

@ -1,94 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as child_process from 'child_process';
import * as net from 'net';
import * as path from 'path';
export function isTcpPortFree(port: number): Promise<boolean> {
return new Promise((resolve, reject) => {
const server = net.createServer();
server.on('error', (e) => { resolve(false); });
server.on('close', () => { resolve(true); });
server.listen(port, () => { server.close(); });
});
}
export function isTcpPortBound(port: number): Promise<boolean> {
return new Promise((resolve, reject) => {
const client = new net.Socket();
client.once('connect', () => { resolve(true); });
client.once('error', (e) => { resolve(false); });
client.connect(port);
});
}
export async function findFreeTcpPort(): Promise<number> {
const range = {
min: 32768,
max: 60000,
};
for (let i = 0; i < 100; i++) {
let port = Math.floor(Math.random() * (range.max - range.min) + range.min);
if (await isTcpPortFree(port)) {
return port;
}
}
throw new Error('Unable to find a free port');
}
// Interface for config parameter of the protractor_web_test_suite onPrepare function
export interface OnPrepareConfig {
// The workspace name
workspace: string;
// The server binary to run
server: string;
}
export function waitForServer(port: number, timeout: number): Promise<boolean> {
return isTcpPortBound(port).then(isBound => {
if (!isBound) {
if (timeout <= 0) {
throw new Error('Timeout waiting for server to start');
}
const wait = Math.min(timeout, 500);
return new Promise((res, rej) => setTimeout(res, wait))
.then(() => waitForServer(port, timeout - wait));
}
return true;
});
}
// Return type from runServer function
export interface ServerSpec {
// Port number that the server is running on
port: number;
}
export function runServer(
workspace: string, binary: string, portFlag: string, args: string[],
timeout = 5000): Promise<ServerSpec> {
return findFreeTcpPort().then(function(port) {
const runfiles_path = process.env.TEST_SRCDIR;
const cmd = path.join(runfiles_path, workspace, binary);
args = args.concat([portFlag, port.toString()]);
const child = child_process.spawn(
cmd, args, {cwd: path.join(runfiles_path, workspace), stdio: 'inherit'});
child.on('exit', function(code) {
if (code != 0) {
throw new Error(`non-zero exit code ${code} from server`);
}
});
return waitForServer(port, timeout).then(() => { return {port}; });
});
}

View File

@ -1,6 +0,0 @@
{
"compilerOptions": {
"noImplicitAny": true,
"lib": ["es2015"]
}
}

View File

@ -1,54 +0,0 @@
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver", "ts_library")
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary", "rollup_bundle")
load("//tools/http-server:http_server.bzl", "http_server")
ts_library(
name = "app",
srcs = ["app.ts"],
)
ts_devserver(
name = "devserver",
serving_path = "/bundle.min.js",
static_files = ["index.html"],
deps = [":app"],
)
rollup_bundle(
name = "bundle",
entry_point = "packages/bazel/test/protractor-2/app",
deps = [":app"],
)
http_server(
name = "prodserver",
data = [
"index.html",
":bundle",
],
)
ts_library(
name = "ts_spec",
testonly = True,
srcs = ["test.spec.ts"],
)
protractor_web_test_suite(
name = "prodserver_test",
configuration = ":conf.js",
data = ["//packages/bazel/src/protractor/utils"],
on_prepare = ":on-prepare.js",
server = ":prodserver",
deps = [":ts_spec"],
)
protractor_web_test_suite(
name = "devserver_test",
configuration = ":conf.js",
data = ["//packages/bazel/src/protractor/utils"],
on_prepare = ":on-prepare.js",
server = ":prodserver",
deps = [":ts_spec"],
)

View File

@ -1,12 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
const el: HTMLDivElement = document.createElement('div');
el.innerText = 'Hello, Protractor';
el.className = 'ts1';
document.body.appendChild(el);

View File

@ -1,11 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
exports.config = {
onPrepare: function() { global.userOnPrepareGotCalled = true; }
};

View File

@ -1,9 +0,0 @@
<!doctype html>
<html>
<head>
<title>protractor test</title>
</head>
<body>
<script src="/bundle.min.js"></script>
</body>
</html>

View File

@ -1,22 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
const protractorUtils = require('@angular/bazel/protractor-utils');
const protractor = require('protractor');
module.exports = function(config) {
if (!global.userOnPrepareGotCalled) {
throw new Error('Expecting user configuration onPrepare to have been called');
}
const portFlag = config.server.endsWith('prodserver') ? '-p' : '-port';
return protractorUtils.runServer(config.workspace, config.server, portFlag, [])
.then(serverSpec => {
const serverUrl = `http://localhost:${serverSpec.port}`;
protractor.browser.baseUrl = serverUrl;
});
};

View File

@ -1,28 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*
* @fileoverview A small demo of how to run a protractor test.
*/
import {ExpectedConditions, browser, by, element} from 'protractor';
// This test uses Protractor without Angular, so disable Angular features
browser.waitForAngularEnabled(false);
describe('app', () => {
beforeAll(() => {
browser.get('');
browser.wait(ExpectedConditions.presenceOf(element(by.css('div.ts1'))), 100000);
});
it('should display: Hello, Protractor', (done) => {
const div = element(by.css('div.ts1'));
div.getText().then(t => expect(t).toEqual(`Hello, Protractor`));
done();
});
});

View File

@ -1,5 +0,0 @@
{
"compilerOptions": {
"lib": ["es2015"]
}
}

View File

@ -1,23 +0,0 @@
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
ts_library(
name = "ts_spec",
testonly = True,
srcs = ["test.spec.ts"],
)
ts_library(
name = "ts_conf",
testonly = True,
srcs = ["conf.ts"],
tsconfig = ":tsconfig.json",
deps = ["//packages/bazel/src/protractor/utils"],
)
protractor_web_test_suite(
name = "test",
configuration = ":ts_conf",
data = ["//packages/bazel/src/protractor/utils"],
deps = [":ts_spec"],
)

View File

@ -1,30 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as protractorUtils from '@angular/bazel/protractor-utils';
import {browser} from 'protractor';
const http = require('http');
exports.config = {
onPrepare() {
return protractorUtils.findFreeTcpPort().then(port => {
const app = new http.Server();
app.on('request', (req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('Hello World');
res.end('\n');
});
browser.baseUrl = `http://localhost:${port}`;
return new Promise(resolve => { app.listen(port, () => { resolve(); }); });
});
}
};

View File

@ -1,20 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*
* @fileoverview A small demo of how to run a protractor test.
*/
import {$, browser} from 'protractor';
describe('Basic test', () => {
it('should say hello world', () => {
browser.waitForAngularEnabled(false);
browser.get('/');
expect($('body').getText()).toContain('Hello World');
});
});

View File

@ -1,5 +0,0 @@
{
"compilerOptions": {
"lib": ["es2015"]
}
}

View File

@ -29,7 +29,6 @@ ng_package(
packages = ["//packages/common/locales:package"],
tags = [
"ivy-jit",
"ivy-local",
"release-with-framework",
],
deps = [

View File

@ -1,35 +0,0 @@
load("//tools:defaults.bzl", "ts_library", "ts_web_test_suite")
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
ts_library(
name = "test_lib",
testonly = 1,
srcs = glob(
["**/*.ts"],
exclude = ["**/*_node_only_spec.ts"],
),
deps = [
"//packages/common/http",
"//packages/common/http/testing",
"//packages/core",
"//packages/core/testing",
"@rxjs",
"@rxjs//operators",
],
)
jasmine_node_test(
name = "test",
bootstrap = ["angular/tools/testing/init_node_spec.js"],
deps = [
":test_lib",
"//tools/testing:node",
],
)
ts_web_test_suite(
name = "test_web",
deps = [
":test_lib",
],
)

View File

@ -76,17 +76,13 @@ class SampleTokenExtractor {
it('does not re-parse if document.cookie has not changed', () => {
expect(extractor.getToken()).toEqual('test');
expect(extractor.getToken()).toEqual('test');
expect(getParseCount(extractor)).toEqual(1);
expect(extractor.parseCount).toEqual(1);
});
it('re-parses if document.cookie changes', () => {
expect(extractor.getToken()).toEqual('test');
document['cookie'] = 'XSRF-TOKEN=blah';
expect(extractor.getToken()).toEqual('blah');
expect(getParseCount(extractor)).toEqual(2);
expect(extractor.parseCount).toEqual(2);
});
});
}
function getParseCount(extractor: HttpXsrfCookieExtractor): number {
return (extractor as any).parseCount;
}

View File

@ -193,9 +193,20 @@ function padNumber(
return neg + strNum;
}
function formatFractionalSeconds(milliseconds: number, digits: number): string {
const strMs = padNumber(milliseconds, 3);
return strMs.substr(0, digits);
/**
* Trim a fractional part to `digits` number of digits.
* Right pads with "0" to fit the requested number of digits if needed.
*
* @param num The fractional part value
* @param digits The width of the output
*/
function trimRPadFractional(num: number, digits: number): string {
let strNum = String(num);
// Add padding at the end
while (strNum.length < digits) {
strNum = strNum + 0;
}
return strNum.substr(0, digits);
}
/**
@ -215,7 +226,7 @@ function dateGetter(
part = 12;
}
} else if (name === DateType.FractionalSeconds) {
return formatFractionalSeconds(part, size);
return trimRPadFractional(part, size);
}
const localeMinus = getLocaleNumberSymbol(locale, NumberSymbol.MinusSign);

View File

@ -319,10 +319,6 @@ describe('Format date', () => {
expect(formatDate(3000, 'm:ss.S', 'en')).toEqual('0:03.0');
expect(formatDate(3000, 'm:ss.SS', 'en')).toEqual('0:03.00');
expect(formatDate(3000, 'm:ss.SSS', 'en')).toEqual('0:03.000');
expect(formatDate(3001, 'm:ss', 'en')).toEqual('0:03');
expect(formatDate(3001, 'm:ss.S', 'en')).toEqual('0:03.0');
expect(formatDate(3001, 'm:ss.SS', 'en')).toEqual('0:03.00');
expect(formatDate(3001, 'm:ss.SSS', 'en')).toEqual('0:03.001');
});
});
});

View File

@ -38,7 +38,6 @@ npm_package(
],
tags = [
"ivy-jit",
"ivy-local",
"release-with-framework",
],
deps = [":compiler-cli"],

View File

@ -37,13 +37,10 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
}
analyze(node: ts.ClassDeclaration, decorator: Decorator): AnalysisOutput<NgModuleAnalysis> {
if (decorator.args === null || decorator.args.length > 1) {
if (decorator.args === null || decorator.args.length !== 1) {
throw new Error(`Incorrect number of arguments to @NgModule decorator`);
}
// @NgModule can be invoked without arguments. In case it is, pretend as if a blank object
// literal was specified. This simplifies the code below.
const meta = decorator.args.length === 1 ? decorator.args[0] : ts.createObjectLiteral([]);
const meta = decorator.args[0];
if (!ts.isObjectLiteralExpression(meta)) {
throw new Error(`Decorator argument must be literal.`);
}
@ -135,12 +132,6 @@ function resolveTypeList(resolvedList: ResolvedValue, name: string): Reference[]
}
resolvedList.forEach((entry, idx) => {
// Unwrap ModuleWithProviders for modules that are locally declared (and thus static resolution
// was able to descend into the function and return an object literal, a Map).
if (entry instanceof Map && entry.has('ngModule')) {
entry = entry.get('ngModule') !;
}
if (Array.isArray(entry)) {
// Recurse into nested arrays.
refList.push(...resolveTypeList(entry, name));
@ -153,7 +144,7 @@ function resolveTypeList(resolvedList: ResolvedValue, name: string): Reference[]
refList.push(entry);
} else {
// TODO(alxhub): expand ModuleWithProviders.
throw new Error(`Value at position ${idx} in ${name} array is not a reference: ${entry}`);
throw new Error(`Value at position ${idx} in ${name} array is not a reference`);
}
});

View File

@ -59,7 +59,7 @@ export class DtsFileTransformer {
const imports = this.imports.getAllImports(tsPath, this.coreImportsFrom);
if (imports.length !== 0) {
dts = imports.map(i => `import * as ${i.as} from '${i.name}';\n`).join('') + dts;
dts = imports.map(i => `import * as ${i.as} from '${i.name}';\n`).join() + dts;
}
return dts;

View File

@ -35,8 +35,8 @@ const CORE_SUPPORTED_SYMBOLS = new Set<string>([
'ɵdefineNgModule',
'inject',
'InjectableDef',
'ɵInjectorDef',
'ɵNgModuleDef',
'InjectorDef',
'NgModuleDef',
]);
export class ImportManager {

View File

@ -43,9 +43,8 @@ const EXPECTED_XMB = `<?xml version="1.0" encoding="UTF-8" ?>
<!ELEMENT ex (#PCDATA)>
]>
<messagebundle>
<msg id="8136548302122759730" desc="desc" meaning="meaning"><source>src/basic.html:1</source><source>src/comp2.ts:1</source><source>src/basic.html:1</source>translate me</msg>
<msg id="9038505069473852515"><source>src/basic.html:3,4</source><source>src/comp2.ts:3,4</source><source>src/comp2.ts:2,3</source><source>src/basic.html:3,4</source>
Welcome</msg>
<msg id="8136548302122759730" desc="desc" meaning="meaning"><source>src/module.ts:1</source>translate me</msg>
<msg id="3492007542396725315"><source>src/module.ts:2</source>Welcome</msg>
</messagebundle>
`;
@ -56,39 +55,18 @@ const EXPECTED_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
<trans-unit id="76e1eccb1b772fa9f294ef9c146ea6d0efa8a2d4" datatype="html">
<source>translate me</source>
<context-group purpose="location">
<context context-type="sourcefile">src/basic.html</context>
<context context-type="linenumber">1</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/comp2.ts</context>
<context context-type="linenumber">1</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/basic.html</context>
<context context-type="sourcefile">src/module.ts</context>
<context context-type="linenumber">1</context>
</context-group>
<note priority="1" from="description">desc</note>
<note priority="1" from="meaning">meaning</note>
</trans-unit>
<trans-unit id="085a5ecc40cc87451d216725b2befd50866de18a" datatype="html">
<source>
Welcome</source>
<trans-unit id="65cc4ab3b4c438e07c89be2b677d08369fb62da2" datatype="html">
<source>Welcome</source>
<context-group purpose="location">
<context context-type="sourcefile">src/basic.html</context>
<context context-type="linenumber">3</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/comp2.ts</context>
<context context-type="linenumber">3</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/comp2.ts</context>
<context context-type="sourcefile">src/module.ts</context>
<context context-type="linenumber">2</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/basic.html</context>
<context context-type="linenumber">3</context>
</context-group>
</trans-unit>
</body>
</file>
@ -102,24 +80,18 @@ const EXPECTED_XLIFF2 = `<?xml version="1.0" encoding="UTF-8" ?>
<notes>
<note category="description">desc</note>
<note category="meaning">meaning</note>
<note category="location">src/basic.html:1</note>
<note category="location">src/comp2.ts:1</note>
<note category="location">src/basic.html:1</note>
<note category="location">src/module.ts:1</note>
</notes>
<segment>
<source>translate me</source>
</segment>
</unit>
<unit id="9038505069473852515">
<unit id="3492007542396725315">
<notes>
<note category="location">src/basic.html:3,4</note>
<note category="location">src/comp2.ts:3,4</note>
<note category="location">src/comp2.ts:2,3</note>
<note category="location">src/basic.html:3,4</note>
<note category="location">src/module.ts:2</note>
</notes>
<segment>
<source>
Welcome</source>
<source>Welcome</source>
</segment>
</unit>
</file>
@ -183,54 +155,21 @@ describe('extract_i18n command line', () => {
});
function writeSources() {
const welcomeMessage = `
<!--i18n-->
Welcome<!--/i18n-->
`;
write('src/basic.html', `<div title="translate me" i18n-title="meaning|desc"></div>
<p id="welcomeMessage">${welcomeMessage}</p>`);
write('src/comp1.ts', `
import {Component} from '@angular/core';
write('src/basic.html', [
`<div title="translate me" i18n-title="meaning|desc"></div>`,
`<p id="welcomeMessage"><!--i18n-->Welcome<!--/i18n--></p>`,
].join('\n'));
write('src/module.ts', `
import {Component, NgModule} from '@angular/core';
@Component({
selector: 'basic',
templateUrl: './basic.html',
})
export class BasicCmp1 {}`);
write('src/comp2.ts', `
import {Component} from '@angular/core';
@Component({
selector: 'basic2',
template: \`<div title="translate me" i18n-title="meaning|desc"></div>
<p id="welcomeMessage">${welcomeMessage}</p>\`,
})
export class BasicCmp2 {}
@Component({
selector: 'basic4',
template: \`<p id="welcomeMessage">${welcomeMessage}</p>\`,
})
export class BasicCmp4 {}`);
write('src/comp3.ts', `
import {Component} from '@angular/core';
@Component({
selector: 'basic3',
templateUrl: './basic.html',
})
export class BasicCmp3 {}`);
write('src/module.ts', `
import {NgModule} from '@angular/core';
import {BasicCmp1} from './comp1';
import {BasicCmp2, BasicCmp4} from './comp2';
import {BasicCmp3} from './comp3';
export class BasicCmp {}
@NgModule({
declarations: [BasicCmp1, BasicCmp2, BasicCmp3, BasicCmp4]
declarations: [BasicCmp]
})
export class I18nModule {}
`);

View File

@ -144,7 +144,7 @@ describe('ngtsc behavioral tests', () => {
expect(jsContents).not.toContain('__decorate');
const dtsContents = getContents('test.d.ts');
expect(dtsContents).toContain('static ngComponentDef: i0.ɵComponentDef<TestCmp, \'test-cmp\'>');
expect(dtsContents).toContain('static ngComponentDef: i0.ComponentDef<TestCmp, \'test-cmp\'>');
});
it('should compile Components without errors', () => {
@ -196,9 +196,9 @@ describe('ngtsc behavioral tests', () => {
'declarations: [TestCmp], imports: [], exports: [] })');
const dtsContents = getContents('test.d.ts');
expect(dtsContents).toContain('static ngComponentDef: i0.ɵComponentDef<TestCmp, \'test-cmp\'>');
expect(dtsContents).toContain('static ngComponentDef: i0.ComponentDef<TestCmp, \'test-cmp\'>');
expect(dtsContents)
.toContain('static ngModuleDef: i0.ɵNgModuleDef<TestModule, [TestCmp], [], []>');
.toContain('static ngModuleDef: i0.NgModuleDef<TestModule, [TestCmp], [], []>');
expect(dtsContents).not.toContain('__decorate');
});
@ -240,8 +240,8 @@ describe('ngtsc behavioral tests', () => {
const dtsContents = getContents('test.d.ts');
expect(dtsContents)
.toContain('static ngModuleDef: i0.ɵNgModuleDef<TestModule, [TestCmp], [OtherModule], []>');
expect(dtsContents).toContain('static ngInjectorDef: i0.ɵInjectorDef');
.toContain('static ngModuleDef: i0.NgModuleDef<TestModule, [TestCmp], [OtherModule], []>');
expect(dtsContents).toContain('static ngInjectorDef: i0.InjectorDef');
});
it('should compile Pipes without errors', () => {
@ -342,6 +342,6 @@ describe('ngtsc behavioral tests', () => {
expect(jsContents).toContain('pipes: [TestPipe]');
const dtsContents = getContents('test.d.ts');
expect(dtsContents).toContain('i0.ɵNgModuleDef<TestModule, [TestPipe,TestCmp], [], []>');
expect(dtsContents).toContain('i0.NgModuleDef<TestModule, [TestPipe,TestCmp], [], []>');
});
});

View File

@ -23,7 +23,6 @@ ng_package(
include_devmode_srcs = True,
tags = [
"ivy-jit",
"ivy-local",
"release-with-framework",
],
deps = [

View File

@ -318,12 +318,10 @@ export class AotCompiler {
});
compMetas.forEach(compMeta => {
const html = compMeta.template !.template !;
// Template URL points to either an HTML or TS file depending on whether
// the file is used with `templateUrl:` or `template:`, respectively.
const templateUrl = compMeta.template !.templateUrl !;
const interpolationConfig =
InterpolationConfig.fromArray(compMeta.template !.interpolation);
errors.push(...messageBundle.updateFromTemplate(html, templateUrl, interpolationConfig) !);
errors.push(
...messageBundle.updateFromTemplate(html, file.fileName, interpolationConfig) !);
});
});

View File

@ -380,6 +380,8 @@ export const enum RenderFlags {
Update = 0b10
}
// Note this will expand once `class` is introduced to styling
export const enum InitialStylingFlags {
VALUES_MODE = 0b1,
/** Mode for matching initial style values */
INITIAL_STYLES = 0b00,
}

View File

@ -75,14 +75,10 @@ export class Extractor {
});
compMetas.forEach(compMeta => {
const html = compMeta.template !.template !;
// Template URL points to either an HTML or TS file depending on
// whether the file is used with `templateUrl:` or `template:`,
// respectively.
const templateUrl = compMeta.template !.templateUrl !;
const interpolationConfig =
InterpolationConfig.fromArray(compMeta.template !.interpolation);
errors.push(...this.messageBundle.updateFromTemplate(
html, templateUrl, interpolationConfig) !);
html, file.fileName, interpolationConfig) !);
});
});

View File

@ -33,11 +33,13 @@ export class Identifiers {
static elementAttribute: o.ExternalReference = {name: 'ɵa', moduleName: CORE};
static elementClassProp: o.ExternalReference = {name: cp', moduleName: CORE};
static elementClass: o.ExternalReference = {name: k', moduleName: CORE};
static elementClassNamed: o.ExternalReference = {name: 'ɵkn', moduleName: CORE};
static elementStyling: o.ExternalReference = {name: 'ɵs', moduleName: CORE};
static elementStylingMap: o.ExternalReference = {name: 'ɵsm', moduleName: CORE};
static elementStyle: o.ExternalReference = {name: 'ɵsm', moduleName: CORE};
static elementStyleProp: o.ExternalReference = {name: 'ɵsp', moduleName: CORE};
@ -102,7 +104,7 @@ export class Identifiers {
static defineComponent: o.ExternalReference = {name: 'ɵdefineComponent', moduleName: CORE};
static ComponentDef: o.ExternalReference = {
name: 'ɵComponentDef',
name: 'ComponentDef',
moduleName: CORE,
};
@ -112,12 +114,12 @@ export class Identifiers {
};
static DirectiveDef: o.ExternalReference = {
name: 'ɵDirectiveDef',
name: 'DirectiveDef',
moduleName: CORE,
};
static InjectorDef: o.ExternalReference = {
name: 'ɵInjectorDef',
name: 'InjectorDef',
moduleName: CORE,
};
@ -127,7 +129,7 @@ export class Identifiers {
};
static NgModuleDef: o.ExternalReference = {
name: 'ɵNgModuleDef',
name: 'NgModuleDef',
moduleName: CORE,
};

View File

@ -107,8 +107,7 @@ export function compileInjector(meta: R3InjectorMetadata): R3InjectorDef {
providers: meta.providers,
imports: meta.imports,
})]);
const type =
new o.ExpressionType(o.importExpr(R3.InjectorDef, [new o.ExpressionType(meta.type)]));
const type = new o.ExpressionType(o.importExpr(R3.InjectorDef));
return {expression, type};
}

View File

@ -88,14 +88,9 @@ export function compileDirectiveFromMetadata(
bindingParser: BindingParser): R3DirectiveDef {
const definitionMap = baseDirectiveFields(meta, constantPool, bindingParser);
const expression = o.importExpr(R3.defineDirective).callFn([definitionMap.toLiteralMap()]);
// On the type side, remove newlines from the selector as it will need to fit into a TypeScript
// string literal, which must be on one line.
const selectorForType = (meta.selector || '').replace(/\n/g, '');
const type = new o.ExpressionType(o.importExpr(
R3.DirectiveDef,
[new o.ExpressionType(meta.type), new o.ExpressionType(o.literal(selectorForType))]));
[new o.ExpressionType(meta.type), new o.ExpressionType(o.literal(meta.selector || ''))]));
return {expression, type};
}
@ -162,14 +157,10 @@ export function compileComponentFromMetadata(
definitionMap.set('pipes', o.literalArr(Array.from(pipesUsed)));
}
// On the type side, remove newlines from the selector as it will need to fit into a TypeScript
// string literal, which must be on one line.
const selectorForType = (meta.selector || '').replace(/\n/g, '');
const expression = o.importExpr(R3.defineComponent).callFn([definitionMap.toLiteralMap()]);
const type = new o.ExpressionType(o.importExpr(
R3.ComponentDef,
[new o.ExpressionType(meta.type), new o.ExpressionType(o.literal(selectorForType))]));
[new o.ExpressionType(meta.type), new o.ExpressionType(o.literal(meta.selector || ''))]));
return {expression, type};
}

View File

@ -40,12 +40,19 @@ function mapBindingToInstruction(type: BindingType): o.ExternalReference|undefin
case BindingType.Attribute:
return R3.elementAttribute;
case BindingType.Class:
return R3.elementClassProp;
return R3.elementClassNamed;
default:
return undefined;
}
}
// `className` is used below instead of `class` because the interception
// code (where this map is used) deals with DOM element property values
// (like elm.propName) and not component bindining properties (like [propName]).
const SPECIAL_CASED_PROPERTIES_INSTRUCTION_MAP: {[index: string]: o.ExternalReference} = {
'className': R3.elementClass
};
export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver {
private _dataIndex = 0;
private _bindingContext = 0;
@ -303,59 +310,33 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
const i18nMessages: o.Statement[] = [];
const attributes: o.Expression[] = [];
const initialStyleDeclarations: o.Expression[] = [];
const initialClassDeclarations: o.Expression[] = [];
const styleInputs: t.BoundAttribute[] = [];
const classInputs: t.BoundAttribute[] = [];
const allOtherInputs: t.BoundAttribute[] = [];
element.inputs.forEach((input: t.BoundAttribute) => {
switch (input.type) {
// [attr.style] or [attr.class] should not be treated as styling-based
// bindings since they are intended to be written directly to the attr
// and therefore will skip all style/class resolution that is present
// with style="", [style]="" and [style.prop]="", class="",
// [class.prop]="". [class]="" assignments
case BindingType.Property:
if (input.name == 'style') {
// this should always go first in the compilation (for [style])
styleInputs.splice(0, 0, input);
} else if (isClassBinding(input)) {
// this should always go first in the compilation (for [class])
classInputs.splice(0, 0, input);
} else {
allOtherInputs.push(input);
}
break;
case BindingType.Style:
styleInputs.push(input);
break;
case BindingType.Class:
classInputs.push(input);
break;
default:
allOtherInputs.push(input);
break;
// [attr.style] should not be treated as a styling-based
// binding since it is intended to write directly to the attr
// and therefore will skip all style resolution that is present
// with style="", [style]="" and [style.prop]="" assignments
if (input.name == 'style' && input.type == BindingType.Property) {
// this should always go first in the compilation (for [style])
styleInputs.splice(0, 0, input);
} else if (input.type == BindingType.Style) {
styleInputs.push(input);
} else {
allOtherInputs.push(input);
}
});
let currStyleIndex = 0;
let currClassIndex = 0;
let staticStylesMap: {[key: string]: any}|null = null;
let staticClassesMap: {[key: string]: boolean}|null = null;
const stylesIndexMap: {[key: string]: number} = {};
const classesIndexMap: {[key: string]: number} = {};
Object.getOwnPropertyNames(outputAttrs).forEach(name => {
const value = outputAttrs[name];
if (name == 'style') {
staticStylesMap = parseStyle(value);
Object.keys(staticStylesMap).forEach(prop => { stylesIndexMap[prop] = currStyleIndex++; });
} else if (name == 'class') {
staticClassesMap = {};
value.split(/\s+/g).forEach(className => {
classesIndexMap[className] = currClassIndex++;
staticClassesMap ![className] = true;
});
} else {
attributes.push(o.literal(name));
if (attrI18nMetas.hasOwnProperty(name)) {
@ -376,14 +357,6 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
}
}
for (let i = 0; i < classInputs.length; i++) {
const input = classInputs[i];
const isMapBasedClassBinding = i === 0 && isClassBinding(input);
if (!isMapBasedClassBinding && !stylesIndexMap.hasOwnProperty(input.name)) {
classesIndexMap[input.name] = currClassIndex++;
}
}
// this will build the instructions so that they fall into the following syntax
// => [prop1, prop2, prop3, 0, prop1, value1, prop2, value2]
Object.keys(stylesIndexMap).forEach(prop => {
@ -391,7 +364,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
});
if (staticStylesMap) {
initialStyleDeclarations.push(o.literal(core.InitialStylingFlags.VALUES_MODE));
initialStyleDeclarations.push(o.literal(core.InitialStylingFlags.INITIAL_STYLES));
Object.keys(staticStylesMap).forEach(prop => {
initialStyleDeclarations.push(o.literal(prop));
@ -400,22 +373,6 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
});
}
Object.keys(classesIndexMap).forEach(prop => {
initialClassDeclarations.push(o.literal(prop));
});
if (staticClassesMap) {
initialClassDeclarations.push(o.literal(core.InitialStylingFlags.VALUES_MODE));
Object.keys(staticClassesMap).forEach(className => {
initialClassDeclarations.push(o.literal(className));
initialClassDeclarations.push(o.literal(true));
});
}
const hasStylingInstructions = initialStyleDeclarations.length || styleInputs.length ||
initialClassDeclarations.length || classInputs.length;
const attrArg: o.Expression = attributes.length > 0 ?
this.constantPool.getConstLiteral(o.literalArr(attributes), true) :
o.TYPED_NULL_EXPR;
@ -454,8 +411,10 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
const implicit = o.variable(CONTEXT_NAME);
const elementStyleIndex =
(initialStyleDeclarations.length || styleInputs.length) ? this.allocateDataSlot() : 0;
const createSelfClosingInstruction =
!hasStylingInstructions && element.children.length === 0 && element.outputs.length === 0;
elementStyleIndex === 0 && element.children.length === 0 && element.outputs.length === 0;
if (createSelfClosingInstruction) {
this.instruction(
@ -470,30 +429,16 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
...trimTrailingNulls(parameters));
// initial styling for static style="..." attributes
if (hasStylingInstructions) {
const paramsList: (o.Expression)[] = [];
if (elementStyleIndex > 0) {
let paramsList: (o.Expression)[] = [o.literal(elementStyleIndex)];
if (initialStyleDeclarations.length) {
// the template compiler handles initial style (e.g. style="foo") values
// the template compiler handles initial styling (e.g. style="foo") values
// in a special command called `elementStyle` so that the initial styles
// can be processed during runtime. These initial styles values are bound to
// a constant because the inital style values do not change (since they're static).
paramsList.push(
this.constantPool.getConstLiteral(o.literalArr(initialStyleDeclarations), true));
} else if (initialClassDeclarations.length) {
// no point in having an extra `null` value unless there are follow-up params
paramsList.push(o.NULL_EXPR);
}
if (initialClassDeclarations.length) {
// the template compiler handles initial class styling (e.g. class="foo") values
// in a special command called `elementClass` so that the initial class
// can be processed during runtime. These initial class values are bound to
// a constant because the inital class values do not change (since they're static).
paramsList.push(
this.constantPool.getConstLiteral(o.literalArr(initialClassDeclarations), true));
}
this._creationCode.push(o.importExpr(R3.elementStyling).callFn(paramsList).toStmt());
}
@ -520,74 +465,46 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
});
}
if ((styleInputs.length || classInputs.length) && hasStylingInstructions) {
const indexLiteral = o.literal(elementIndex);
const firstStyle = styleInputs[0];
const mapBasedStyleInput = firstStyle && firstStyle.name == 'style' ? firstStyle : null;
const firstClass = classInputs[0];
const mapBasedClassInput = firstClass && isClassBinding(firstClass) ? firstClass : null;
const stylingInput = mapBasedStyleInput || mapBasedClassInput;
if (stylingInput) {
const params: o.Expression[] = [];
if (mapBasedStyleInput) {
params.push(this.convertPropertyBinding(implicit, mapBasedStyleInput.value, true));
} else if (mapBasedClassInput) {
params.push(o.NULL_EXPR);
}
if (mapBasedClassInput) {
params.push(this.convertPropertyBinding(implicit, mapBasedClassInput.value, true));
}
this.instruction(
this._bindingCode, stylingInput.sourceSpan, R3.elementStylingMap, indexLiteral,
...params);
}
let lastInputCommand: t.BoundAttribute|null = null;
if (styleInputs.length) {
let i = mapBasedStyleInput ? 1 : 0;
for (i; i < styleInputs.length; i++) {
const input = styleInputs[i];
const convertedBinding = this.convertPropertyBinding(implicit, input.value, true);
if (styleInputs.length && elementStyleIndex > 0) {
const indexLiteral = o.literal(elementStyleIndex);
styleInputs.forEach((input, i) => {
const isMapBasedStyleBinding = i == 0 && input.name == 'style';
const convertedBinding = this.convertPropertyBinding(implicit, input.value, true);
if (isMapBasedStyleBinding) {
this.instruction(
this._bindingCode, input.sourceSpan, R3.elementStyle, indexLiteral, convertedBinding);
} else {
const key = input.name;
const styleIndex: number = stylesIndexMap[key] !;
let styleIndex: number = stylesIndexMap[key] !;
this.instruction(
this._bindingCode, input.sourceSpan, R3.elementStyleProp, indexLiteral,
o.literal(styleIndex), convertedBinding);
}
});
lastInputCommand = styleInputs[styleInputs.length - 1];
}
if (classInputs.length) {
let i = mapBasedClassInput ? 1 : 0;
for (i; i < classInputs.length; i++) {
const input = classInputs[i];
const convertedBinding = this.convertPropertyBinding(implicit, input.value, true);
const key = input.name;
const classIndex: number = classesIndexMap[key] !;
this.instruction(
this._bindingCode, input.sourceSpan, R3.elementClassProp, indexLiteral,
o.literal(classIndex), convertedBinding);
}
lastInputCommand = classInputs[classInputs.length - 1];
}
this.instruction(
this._bindingCode, lastInputCommand !.sourceSpan, R3.elementStylingApply, indexLiteral);
const spanEnd = styleInputs[styleInputs.length - 1].sourceSpan;
this.instruction(this._bindingCode, spanEnd, R3.elementStylingApply, indexLiteral);
}
// Generate element input bindings
allOtherInputs.forEach((input: t.BoundAttribute) => {
if (input.type === BindingType.Animation) {
console.error('warning: animation bindings not yet supported');
return;
this._unsupported('animations');
}
const convertedBinding = this.convertPropertyBinding(implicit, input.value);
const specialInstruction = SPECIAL_CASED_PROPERTIES_INSTRUCTION_MAP[input.name];
if (specialInstruction) {
// special case for [style] and [class] bindings since they are not handled as
// standard properties within this implementation. Instead they are
// handed off to special cased instruction handlers which will then
// delegate them as animation sequences (or input bindings for dirs/cmps)
this.instruction(
this._bindingCode, input.sourceSpan, specialInstruction, o.literal(elementIndex),
convertedBinding);
return;
}
const instruction = mapBindingToInstruction(input.type);
if (instruction) {
// TODO(chuckj): runtime: security context?
@ -1057,7 +974,3 @@ export function makeBindingParser(): BindingParser {
new Parser(new Lexer()), DEFAULT_INTERPOLATION_CONFIG, new DomElementSchemaRegistry(), null,
[]);
}
function isClassBinding(input: t.BoundAttribute): boolean {
return input.name == 'className' || input.name == 'class';
}

View File

@ -6,12 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/
import {InitialStylingFlags} from '../../src/core';
import {MockDirectory, setup} from '../aot/test_util';
import {compile, expectEmit} from './mock_compile';
/* These tests are codified version of the tests in compiler_canonical_spec.ts. Every
* test in compiler_canonical_spec.ts should have a corresponding test here.
*/
@ -47,17 +44,15 @@ describe('compiler compliance', () => {
// The template should look like this (where IDENT is a wild card for an identifier):
const template = `
const $c1$ = ['title', 'Hello'];
const $c2$ = ['my-app', ${InitialStylingFlags.VALUES_MODE}, 'my-app', true];
const $c3$ = ['cx', '20', 'cy', '30', 'r', '50'];
const $c1$ = ['class', 'my-app', 'title', 'Hello'];
const $c2$ = ['cx', '20', 'cy', '30', 'r', '50'];
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
if (rf & 1) {
$r3$.ɵE(0, 'div', $c1$);
$r3$.ɵs((null as any), $c2$);
$r3$.ɵNS();
$r3$.ɵE(1, 'svg');
$r3$.ɵEe(2, 'circle', $c3$);
$r3$.ɵEe(2, 'circle', $c2$);
$r3$.ɵe();
$r3$.ɵNH();
$r3$.ɵE(3, 'p');
@ -98,13 +93,11 @@ describe('compiler compliance', () => {
// The template should look like this (where IDENT is a wild card for an identifier):
const template = `
const $c1$ = ['title', 'Hello'];
const $c2$ = ['my-app', ${InitialStylingFlags.VALUES_MODE}, 'my-app', true];
const $c1$ = ['class', 'my-app', 'title', 'Hello'];
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
if (rf & 1) {
$r3$.ɵE(0, 'div', $c1$);
$r3$.ɵs((null as any), $c2$);
$r3$.ɵNM();
$r3$.ɵE(1, 'math');
$r3$.ɵEe(2, 'infinity');
@ -148,13 +141,11 @@ describe('compiler compliance', () => {
// The template should look like this (where IDENT is a wild card for an identifier):
const template = `
const $c1$ = ['title', 'Hello'];
const $c2$ = ['my-app', ${InitialStylingFlags.VALUES_MODE}, 'my-app', true];
const $c1$ = ['class', 'my-app', 'title', 'Hello'];
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
if (rf & 1) {
$r3$.ɵE(0, 'div', $c1$);
$r3$.ɵs((null as any), $c2$);
$r3$.ɵT(1, 'Hello ');
$r3$.ɵE(2, 'b');
$r3$.ɵT(3, 'World');
@ -331,7 +322,6 @@ describe('compiler compliance', () => {
const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }';
const template = `
const _c0 = ['background-color'];
const _c1 = ['error'];
class MyComponent {
static ngComponentDef = i0.ɵdefineComponent({type:MyComponent,selectors:[['my-component']],
factory:function MyComponent_Factory(){
@ -339,13 +329,13 @@ describe('compiler compliance', () => {
},template:function MyComponent_Template(rf:number,ctx:any){
if (rf & 1) {
$r3$.ɵE(0, 'div');
$r3$.ɵs(_c0, _c1);
$r3$.ɵs(1, _c0);
$r3$.ɵe();
}
if (rf & 2) {
$r3$.ɵsp(0, 0, ctx.color);
$r3$cp(0, 0, ctx.error);
$r3$sa(0);
$r3$.ɵsp(1, 0, ctx.color);
$r3$sa(1);
$r3$kn(0, 'error', $r3$.ɵb(ctx.error));
}
}
`;

View File

@ -43,12 +43,12 @@ describe('compiler compliance: styling', () => {
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) {
if (rf & 1) {
$r3$.ɵE(0, 'div');
$r3$.ɵs();
$r3$.ɵs(1);
$r3$.ɵe();
}
if (rf & 2) {
$r3$.ɵsm(0, $ctx$.myStyleExp);
$r3$.ɵsa(0);
$r3$.ɵsm(1, $ctx$.myStyleExp);
$r3$.ɵsa(1);
}
}
`;
@ -57,7 +57,7 @@ describe('compiler compliance: styling', () => {
expectEmit(result.source, template, 'Incorrect template');
});
it('should place initial, multi, singular and application followed by attribute style instructions in the template code in that order',
it('should place initial, multi, singular and application followed by attribute styling instructions in the template code in that order',
() => {
const files = {
app: {
@ -85,7 +85,7 @@ describe('compiler compliance: styling', () => {
};
const template = `
const _c0 = ['opacity','width','height',${InitialStylingFlags.VALUES_MODE},'opacity','1'];
const _c0 = ['opacity','width','height',${InitialStylingFlags.INITIAL_STYLES},'opacity','1'];
class MyComponent {
static ngComponentDef = i0.ɵdefineComponent({
type: MyComponent,
@ -96,14 +96,14 @@ describe('compiler compliance: styling', () => {
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) {
if (rf & 1) {
$r3$.ɵE(0, 'div');
$r3$.ɵs(_c0);
$r3$.ɵs(1, _c0);
$r3$.ɵe();
}
if (rf & 2) {
$r3$.ɵsm(0, $ctx$.myStyleExp);
$r3$.ɵsp(0, 1, $ctx$.myWidth);
$r3$.ɵsp(0, 2, $ctx$.myHeight);
$r3$.ɵsa(0);
$r3$.ɵsm(1, $ctx$.myStyleExp);
$r3$.ɵsp(1, 1, $ctx$.myWidth);
$r3$.ɵsp(1, 2, $ctx$.myHeight);
$r3$.ɵsa(1);
$r3$.ɵa(0, 'style', $r3$.ɵb('border-width: 10px'));
}
}
@ -127,7 +127,7 @@ describe('compiler compliance: styling', () => {
template: \`<div [class]="myClassExp"></div>\`
})
export class MyComponent {
myClassExp = {'foo':true}
myClassExp = [{color:'orange'}, {color:'green', duration:1000}]
}
@NgModule({declarations: [MyComponent]})
@ -139,13 +139,10 @@ describe('compiler compliance: styling', () => {
const template = `
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) {
if (rf & 1) {
$r3$.ɵE(0, 'div');
$r3$.ɵs();
$r3$.ɵe();
$r3$.ɵEe(0, 'div');
}
if (rf & 2) {
$r3$sm(0,(null as any),$ctx$.myClassExp);
$r3$.ɵsa(0);
$r3$k(0,$r3$.ɵb($ctx$.myClassExp));
}
}
`;
@ -153,112 +150,5 @@ describe('compiler compliance: styling', () => {
const result = compile(files, angularFiles);
expectEmit(result.source, template, 'Incorrect template');
});
it('should place initial, multi, singular and application followed by attribute class instructions in the template code in that order',
() => {
const files = {
app: {
'spec.ts': `
import {Component, NgModule} from '@angular/core';
@Component({
selector: 'my-component',
template: \`<div class="grape"
[attr.class]="'banana'"
[class.apple]="yesToApple"
[class]="myClassExp"
[class.orange]="yesToOrange"></div>\`
})
export class MyComponent {
myClassExp = {a:true, b:true};
yesToApple = true;
yesToOrange = true;
}
@NgModule({declarations: [MyComponent]})
export class MyModule {}
`
}
};
const template = `
const _c0 = ['grape','apple','orange',${InitialStylingFlags.VALUES_MODE},'grape',true];
class MyComponent {
static ngComponentDef = i0.ɵdefineComponent({
type: MyComponent,
selectors:[['my-component']],
factory:function MyComponent_Factory(){
return new MyComponent();
},
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) {
if (rf & 1) {
$r3$.ɵE(0, 'div');
$r3$.ɵs((null as any), _c0);
$r3$.ɵe();
}
if (rf & 2) {
$r3$.ɵsm(0, (null as any), $ctx$.myClassExp);
$r3$.ɵcp(0, 1, $ctx$.yesToApple);
$r3$.ɵcp(0, 2, $ctx$.yesToOrange);
$r3$.ɵsa(0);
$r3$.ɵa(0, 'class', $r3$.ɵb('banana'));
}
}
});
`;
const result = compile(files, angularFiles);
expectEmit(result.source, template, 'Incorrect template');
});
it('should not generate the styling apply instruction if there are only static style/class attributes',
() => {
const files = {
app: {
'spec.ts': `
import {Component, NgModule} from '@angular/core';
@Component({
selector: 'my-component',
template: \`<div class="foo"
style="width:100px"
[attr.class]="'round'"
[attr.style]="'height:100px'"></div>\`
})
export class MyComponent {}
@NgModule({declarations: [MyComponent]})
export class MyModule {}
`
}
};
const template = `
const _c0 = ['width',${InitialStylingFlags.VALUES_MODE},'width','100px'];
const _c1 = ['foo',${InitialStylingFlags.VALUES_MODE},'foo',true];
class MyComponent {
static ngComponentDef = i0.ɵdefineComponent({
type: MyComponent,
selectors:[['my-component']],
factory:function MyComponent_Factory(){
return new MyComponent();
},
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) {
if (rf & 1) {
$r3$.ɵE(0, 'div');
$r3$.ɵs(_c0, _c1);
$r3$.ɵe();
}
if (rf & 2) {
$r3$.ɵa(0, 'class', $r3$.ɵb('round'));
$r3$.ɵa(0, 'style', $r3$.ɵb('height:100px'));
}
}
});
`;
const result = compile(files, angularFiles);
expectEmit(result.source, template, 'Incorrect template');
});
});
});

View File

@ -39,7 +39,6 @@ export {
T as ɵT,
V as ɵV,
Q as ɵQ,
Qr as ɵQr,
d as ɵd,
P as ɵP,
b as ɵb,
@ -70,7 +69,6 @@ export {
cR as ɵcR,
cr as ɵcr,
qR as ɵqR,
ql as ɵql,
e as ɵe,
p as ɵp,
pD as ɵpD,
@ -80,7 +78,8 @@ export {
sm as ɵsm,
sp as ɵsp,
sa as ɵsa,
cp as ɵcp,
k as ɵk,
kn as ɵkn,
t as ɵt,
v as ɵv,
st as ɵst,

View File

@ -13,7 +13,7 @@
*/
export * from './di/metadata';
export {InjectableType, InjectorDef, InjectorType, defineInjectable, defineInjector} from './di/defs';
export {InjectableType, InjectorType, defineInjectable, defineInjector} from './di/defs';
export {forwardRef, resolveForwardRef, ForwardRefFn} from './di/forward_ref';
export {Injectable, InjectableDecorator, InjectableProvider} from './di/injectable';
export {inject, InjectFlags, INJECTOR, Injector} from './di/injector';

View File

@ -342,12 +342,9 @@ export interface Directive {
* View queries are set before the `ngAfterViewInit` callback is called.
*
* @usageNotes
*
* ### Example
*
* The following example shows how queries are defined
* and when their results are available in lifecycle hooks:
*
* The followoing example (shows what??)
* ```
* @Component({
* selector: 'someDir',
@ -478,7 +475,7 @@ export interface Directive {
}
/**
* Type of the Directive metadata.
* Type of the Component metadata.
*/
export const Directive: DirectiveDecorator = makeDecorator(
'Directive', (dir: Directive = {}) => dir, undefined, undefined,

View File

@ -19,9 +19,9 @@
* The below symbols are used for @Injectable and @NgModule compilation.
*/
export {InjectableDef, InjectorDef as ɵInjectorDef, defineInjectable, defineInjector} from './di/defs';
export {InjectableDef, InjectorDef, defineInjectable, defineInjector} from './di/defs';
export {inject} from './di/injector';
export {NgModuleDef as ɵNgModuleDef} from './metadata/ng_module';
export {NgModuleDef} from './metadata/ng_module';
export {defineNgModule as ɵdefineNgModule} from './render3/definition';

View File

@ -63,7 +63,6 @@ export function assertComponentType(
msg: string =
'Type passed in is not ComponentType, it does not have \'ngComponentDef\' property.') {
if (!actual.ngComponentDef) {
debugger;
throwError(msg);
}
}
@ -71,4 +70,4 @@ export function assertComponentType(
function throwError(msg: string): never {
debugger; // Left intentionally for better debugger experience.
throw new Error(`ASSERTION ERROR: ${msg}`);
}
}

View File

@ -48,7 +48,7 @@ export function defineComponent<T>(componentDefinition: {
/**
* Factory method used to create an instance of directive.
*/
factory: () => T;
factory: () => T | ({0: T} & any[]); /* trying to say T | [T, ...any] */
/**
* Static attributes to set on host element.
@ -120,14 +120,6 @@ export function defineComponent<T>(componentDefinition: {
*/
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
/**
* Function to create instances of content queries associated with a given directive.
*/
contentQueries?: (() => void);
/** Refreshes content queries associated with directives in a given view */
contentQueriesRefresh?: ((directiveIndex: number, queryIndex: number) => void);
/**
* Defines the name that can be used in the template to assign this directive to a variable.
*
@ -224,8 +216,6 @@ export function defineComponent<T>(componentDefinition: {
factory: componentDefinition.factory,
template: componentDefinition.template || null !,
hostBindings: componentDefinition.hostBindings || null,
contentQueries: componentDefinition.contentQueries || null,
contentQueriesRefresh: componentDefinition.contentQueriesRefresh || null,
attributes: componentDefinition.attributes || null,
inputs: invertObject(componentDefinition.inputs, declaredInputs),
declaredInputs: declaredInputs,
@ -458,14 +448,6 @@ export const defineDirective = defineComponent as any as<T>(directiveDefinition:
*/
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
/**
* Function to create instances of content queries associated with a given directive.
*/
contentQueries?: (() => void);
/** Refreshes content queries associated with directives in a given view */
contentQueriesRefresh?: ((directiveIndex: number, queryIndex: number) => void);
/**
* Defines the name that can be used in the template to assign this directive to a variable.
*

View File

@ -19,7 +19,7 @@ import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_Vie
import {Type} from '../type';
import {assertDefined, assertGreaterThan, assertLessThan} from './assert';
import {addToViewTree, assertPreviousIsParent, createEmbeddedViewNode, createLContainer, createLNodeObject, createTNode, getPreviousOrParentNode, getRenderer, isComponent, renderEmbeddedTemplate, resolveDirective} from './instructions';
import {addToViewTree, assertPreviousIsParent, createEmbeddedViewNode, createLContainer, createLNodeObject, createTNode, getDirectiveInstance, getPreviousOrParentNode, getRenderer, isComponent, renderEmbeddedTemplate, resolveDirective} from './instructions';
import {VIEWS} from './interfaces/container';
import {ComponentTemplate, DirectiveDefInternal, RenderFlags} from './interfaces/definition';
import {LInjector} from './interfaces/injector';
@ -378,7 +378,7 @@ export function getOrCreateInjectable<T>(
// and matches the given token, return the directive instance.
const directiveDef = defs[i] as DirectiveDefInternal<any>;
if (directiveDef.type === token && directiveDef.diPublic) {
return node.view[DIRECTIVES] ![i];
return getDirectiveInstance(node.view[DIRECTIVES] ![i]);
}
}
}

View File

@ -51,13 +51,14 @@ export {
element as Ee,
elementAttribute as a,
elementClassProp as cp,
elementClass as k,
elementClassNamed as kn,
elementEnd as e,
elementProperty as p,
elementStart as E,
elementStyling as s,
elementStylingMap as sm,
elementStyle as sm,
elementStyleProp as sp,
elementStylingApply as sa,
@ -115,11 +116,6 @@ export {
query as Q,
queryRefresh as qR,
} from './query';
export {
registerContentQuery as Qr,
loadQueryList as ql,
} from './instructions';
export {
pureFunction0 as f0,
pureFunction1 as f1,

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