Compare commits
1 Commits
api-overlo
...
6.1.0-rc.0
Author | SHA1 | Date | |
---|---|---|---|
5bd3916608 |
@ -12,8 +12,8 @@
|
|||||||
## IMPORTANT
|
## IMPORTANT
|
||||||
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
|
# 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.
|
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
|
||||||
var_1: &docker_image angular/ngcontainer:0.3.3
|
var_1: &docker_image angular/ngcontainer:0.3.2
|
||||||
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.3
|
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.2
|
||||||
|
|
||||||
# Define common ENV vars
|
# Define common ENV vars
|
||||||
var_3: &define_env_vars
|
var_3: &define_env_vars
|
||||||
|
@ -22,7 +22,6 @@ node_modules_filegroup(
|
|||||||
"jasmine",
|
"jasmine",
|
||||||
"minimist",
|
"minimist",
|
||||||
"protobufjs",
|
"protobufjs",
|
||||||
"protractor",
|
|
||||||
"reflect-metadata",
|
"reflect-metadata",
|
||||||
"source-map-support",
|
"source-map-support",
|
||||||
"tsickle",
|
"tsickle",
|
||||||
@ -35,9 +34,6 @@ node_modules_filegroup(
|
|||||||
"@types",
|
"@types",
|
||||||
"@webcomponents/custom-elements",
|
"@webcomponents/custom-elements",
|
||||||
],
|
],
|
||||||
patterns = [
|
|
||||||
"node_modules/protractor/**",
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
|
@ -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>
|
<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)
|
# [6.1.0-rc.0](https://github.com/angular/angular/compare/6.1.0-beta.3...6.1.0-rc.0) (2018-07-11)
|
||||||
|
|
||||||
|
16
WORKSPACE
16
WORKSPACE
@ -13,16 +13,16 @@ http_archive(
|
|||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "io_bazel_rules_webtesting",
|
name = "io_bazel_rules_webtesting",
|
||||||
url = "https://github.com/bazelbuild/rules_webtesting/archive/7ffe970bbf380891754487f66c3d680c087d67f2.zip",
|
url = "https://github.com/bazelbuild/rules_webtesting/archive/v0.2.0.zip",
|
||||||
strip_prefix = "rules_webtesting-7ffe970bbf380891754487f66c3d680c087d67f2",
|
strip_prefix = "rules_webtesting-0.2.0",
|
||||||
sha256 = "4fb0dca8c9a90547891b7ef486592775a523330fc4555c88cd8f09270055c2ce",
|
sha256 = "cecc12f07e95740750a40d38e8b14b76fefa1551bef9332cb432d564d693723c",
|
||||||
)
|
)
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "build_bazel_rules_typescript",
|
name = "build_bazel_rules_typescript",
|
||||||
url = "https://github.com/bazelbuild/rules_typescript/archive/0.15.1.zip",
|
url = "https://github.com/rkirov/rules_typescript/archive/v0.16.0.zip",
|
||||||
strip_prefix = "rules_typescript-0.15.1",
|
strip_prefix = "rules_typescript-0.16.0",
|
||||||
sha256 = "3792cc20ef13bb1d1d8b1760894c3320f02a87843e3a04fed7e8e454a75328b6",
|
sha256 = "f5aedd3a792e5af19cd0c0f0318cb692e2989e816e896e794152d07808fccacd",
|
||||||
)
|
)
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
@ -58,7 +58,7 @@ http_archive(
|
|||||||
# Even better, things like aspects will visit the entire graph including
|
# Even better, things like aspects will visit the entire graph including
|
||||||
# ts_library rules in the devkit repository.
|
# ts_library rules in the devkit repository.
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "angular_cli",
|
name = "angular_devkit",
|
||||||
url = "https://github.com/angular/angular-cli/archive/v6.1.0-rc.0.zip",
|
url = "https://github.com/angular/angular-cli/archive/v6.1.0-rc.0.zip",
|
||||||
strip_prefix = "angular-cli-6.1.0-rc.0",
|
strip_prefix = "angular-cli-6.1.0-rc.0",
|
||||||
sha256 = "8cf320ea58c321e103f39087376feea502f20eaf79c61a4fdb05c7286c8684fd",
|
sha256 = "8cf320ea58c321e103f39087376feea502f20eaf79c61a4fdb05c7286c8684fd",
|
||||||
@ -77,7 +77,7 @@ http_archive(
|
|||||||
|
|
||||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
|
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"])
|
node_repositories(package_json = ["//:package.json"])
|
||||||
|
|
||||||
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
|
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
|
||||||
|
@ -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_.
|
* `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/>
|
<hr/>
|
||||||
|
|
||||||
|
@ -216,9 +216,10 @@ You can also write `<link>` tags into the component's HTML template.
|
|||||||
|
|
||||||
<div class="alert is-critical">
|
<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>
|
</div>
|
||||||
|
|
||||||
|
@ -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,
|
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)
|
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.
|
have a `target` property, a reference to the element that raised the event.
|
||||||
|
@ -641,12 +641,6 @@
|
|||||||
"title": "Angular Academy (Canada)",
|
"title": "Angular Academy (Canada)",
|
||||||
"url": "http://www.angularacademy.ca"
|
"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": {
|
"-KLIBo_lm-WrK1Sjtt-2": {
|
||||||
"desc": "Basic and Advanced training across Europe in German",
|
"desc": "Basic and Advanced training across Europe in German",
|
||||||
"rev": true,
|
"rev": true,
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
|
|
||||||
<article class="api-list-container l-content-small docs-content">
|
<article class="api-list-container l-content-small docs-content">
|
||||||
<div *ngFor="let section of filteredSections | async" >
|
<div *ngFor="let section of filteredSections | async" >
|
||||||
<h2 *ngIf="section.items"><a [href]="section.path">{{section.title}}</a></h2>
|
<h2>{{section.title}}</h2>
|
||||||
<ul class="api-list" *ngIf="section.items?.length">
|
<ul class="api-list">
|
||||||
<ng-container *ngFor="let item of section.items">
|
<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>
|
<a [href]="item.path"><span class="symbol {{item.docType}}"></span> {{item.title}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -36,13 +36,18 @@ describe('ApiListComponent', () => {
|
|||||||
*/
|
*/
|
||||||
function expectFilteredResult(label: string, itemTest: (item: ApiItem) => boolean) {
|
function expectFilteredResult(label: string, itemTest: (item: ApiItem) => boolean) {
|
||||||
component.filteredSections.subscribe(filtered => {
|
component.filteredSections.subscribe(filtered => {
|
||||||
filtered = filtered.filter(section => section.items);
|
let badItem: ApiItem|undefined;
|
||||||
expect(filtered.length).toBeGreaterThan(0, 'expected something');
|
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', () => {
|
describe('#filteredSections', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -60,45 +65,34 @@ describe('ApiListComponent', () => {
|
|||||||
expectFilteredResult('query: class', item => /class/.test(item.name));
|
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.setQuery('core');
|
||||||
component.filteredSections.subscribe(filtered => {
|
component.filteredSections.subscribe(filtered => {
|
||||||
filtered = filtered.filter(section => Array.isArray(section.items));
|
|
||||||
expect(filtered.length).toBe(1, 'only one section');
|
expect(filtered.length).toBe(1, 'only one section');
|
||||||
expect(filtered[0].name).toBe('core');
|
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('item.show should be true for items with selected status', () => {
|
||||||
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'});
|
component.setStatus({value: 'stable', title: 'Stable'});
|
||||||
expectFilteredResult('status: stable', item => item.stability === 'stable');
|
expectFilteredResult('status: stable', item => item.stability === 'stable');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be visible if they have the selected security status', () => {
|
it('item.show should be true for items with "security-risk" status when selected', () => {
|
||||||
component.setStatus({value: 'security-risk', title: 'Security Risk'});
|
component.setStatus({value: 'security-risk', title: 'Security Risk'});
|
||||||
expectFilteredResult('status: security-risk', item => item.securityRisk);
|
expectFilteredResult('status: security-risk', item => item.securityRisk);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be visible if they match the selected API type', () => {
|
it('item.show should be true for items of selected type', () => {
|
||||||
component.setType({value: 'class', title: 'Class'});
|
component.setType({value: 'class', title: 'Class'});
|
||||||
expectFilteredResult('type: class', item => item.docType === 'class');
|
expectFilteredResult('type: class', item => item.docType === 'class');
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('should have no sections and no items visible when there is no match', () => {
|
it('should have no sections and no items when no match', () => {
|
||||||
component.setQuery('fizbuzz');
|
component.setQuery('fizbuzz');
|
||||||
component.filteredSections.subscribe(filtered => {
|
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();
|
fixture.detectChanges();
|
||||||
|
|
||||||
component.filteredSections.subscribe(filtered => {
|
component.filteredSections.subscribe(filtered => {
|
||||||
filtered = filtered.filter(s => s.items);
|
|
||||||
console.log(filtered);
|
|
||||||
expect(filtered.length).toBe(1, 'sections');
|
expect(filtered.length).toBe(1, 'sections');
|
||||||
expect(filtered[0].name).toBe(section, 'section name');
|
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');
|
expect(items.length).toBe(1, 'items');
|
||||||
|
|
||||||
const item = items[0];
|
const item = items[0];
|
||||||
@ -226,7 +218,6 @@ const apiSections: ApiSection[] = [
|
|||||||
{
|
{
|
||||||
"name": "common",
|
"name": "common",
|
||||||
"title": "common",
|
"title": "common",
|
||||||
"path": "api/common",
|
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "class_1",
|
"name": "class_1",
|
||||||
@ -265,7 +256,6 @@ const apiSections: ApiSection[] = [
|
|||||||
{
|
{
|
||||||
"name": "core",
|
"name": "core",
|
||||||
"title": "core",
|
"title": "core",
|
||||||
"path": "api/core",
|
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "class_3",
|
"name": "class_3",
|
||||||
|
@ -49,8 +49,7 @@ export class ApiListComponent implements OnInit {
|
|||||||
{ value: 'function', title: 'Function' },
|
{ value: 'function', title: 'Function' },
|
||||||
{ value: 'interface', title: 'Interface' },
|
{ value: 'interface', title: 'Interface' },
|
||||||
{ value: 'pipe', title: 'Pipe'},
|
{ value: 'pipe', title: 'Pipe'},
|
||||||
{ value: 'type-alias', title: 'Type alias' },
|
{ value: 'type-alias', title: 'Type Alias' }
|
||||||
{ value: 'package', title: 'Package'}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
statuses: Option[] = [
|
statuses: Option[] = [
|
||||||
@ -72,8 +71,7 @@ export class ApiListComponent implements OnInit {
|
|||||||
this.apiService.sections,
|
this.apiService.sections,
|
||||||
this.criteriaSubject,
|
this.criteriaSubject,
|
||||||
(sections, criteria) => {
|
(sections, criteria) => {
|
||||||
return sections
|
return sections.filter(section => this.filterSection(section, criteria));
|
||||||
.map(section => ({ ...section, items: this.filterSection(section, criteria) }));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -109,8 +107,13 @@ export class ApiListComponent implements OnInit {
|
|||||||
//////// Private //////////
|
//////// Private //////////
|
||||||
|
|
||||||
private filterSection(section: ApiSection, { query, status, type }: SearchCriteria) {
|
private filterSection(section: ApiSection, { query, status, type }: SearchCriteria) {
|
||||||
const items = section.items!.filter(item => {
|
let showSection = false;
|
||||||
return matchesType() && matchesStatus() && matchesQuery();
|
|
||||||
|
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() {
|
function matchesQuery() {
|
||||||
return !query ||
|
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 showSection;
|
||||||
return items.length ? items : (type === 'package' && (!query || section.name.indexOf(query) !== -1)) ? [] : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get initial search criteria from URL search params
|
// Get initial search criteria from URL search params
|
||||||
|
@ -50,7 +50,7 @@ describe('ApiService', () => {
|
|||||||
describe('#sections', () => {
|
describe('#sections', () => {
|
||||||
|
|
||||||
it('first subscriber should fetch sections', done => {
|
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 => {
|
service.sections.subscribe(sections => {
|
||||||
expect(sections).toEqual(data);
|
expect(sections).toEqual(data);
|
||||||
@ -61,7 +61,7 @@ describe('ApiService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('second subscriber should get previous sections and NOT trigger refetch', done => {
|
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;
|
let subscriptions = 0;
|
||||||
|
|
||||||
service.sections.subscribe(sections => {
|
service.sections.subscribe(sections => {
|
||||||
@ -91,7 +91,7 @@ describe('ApiService', () => {
|
|||||||
|
|
||||||
let call = 0;
|
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 => {
|
service.sections.subscribe(sections => {
|
||||||
// called twice during this test
|
// called twice during this test
|
||||||
@ -103,7 +103,7 @@ describe('ApiService', () => {
|
|||||||
httpMock.expectOne({}).flush(data);
|
httpMock.expectOne({}).flush(data);
|
||||||
|
|
||||||
// refresh/refetch
|
// refresh/refetch
|
||||||
data = [{name: 'c', title: 'C', path: '', items: []}];
|
data = [{name: 'c', title: 'C', items: []}];
|
||||||
service.fetchSections();
|
service.fetchSections();
|
||||||
httpMock.expectOne({}).flush(data);
|
httpMock.expectOne({}).flush(data);
|
||||||
|
|
||||||
|
@ -14,13 +14,14 @@ export interface ApiItem {
|
|||||||
docType: string;
|
docType: string;
|
||||||
stability: string;
|
stability: string;
|
||||||
securityRisk: boolean;
|
securityRisk: boolean;
|
||||||
|
|
||||||
|
show?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiSection {
|
export interface ApiSection {
|
||||||
path: string;
|
|
||||||
name: string;
|
name: string;
|
||||||
title: string;
|
title: string;
|
||||||
items: ApiItem[]|null;
|
items: ApiItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -28,7 +28,7 @@ h2 {
|
|||||||
h3 {
|
h3 {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
margin: 24px 0px 12px;
|
margin: 24px 0px;
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,10 +55,6 @@ h6 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h2, h3, h4, h5, h6 {
|
h2, h3, h4, h5, h6 {
|
||||||
a {
|
|
||||||
font-size: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
@media screen and (max-width: 600px) {
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
}
|
}
|
||||||
@ -109,7 +105,7 @@ table {
|
|||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
margin: 12px 0 32px;
|
margin: 0 0 32px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
table tbody th {
|
table tbody th {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
.api-body {
|
.api-body {
|
||||||
|
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
|
|
||||||
table {
|
table {
|
||||||
margin: 12px 0 24px;
|
|
||||||
|
|
||||||
th {
|
th {
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
@ -18,12 +18,6 @@
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody > tr > td tr td:first-child {
|
|
||||||
@media screen and (max-width: 480px) {
|
|
||||||
background-color: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
margin: 16px 0;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
@ -47,217 +41,5 @@
|
|||||||
.short-description {
|
.short-description {
|
||||||
margin-left: 0;
|
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
114
aio/src/styles/2-modules/_api-pages.scss
Normal file
114
aio/src/styles/2-modules/_api-pages.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
48
aio/src/styles/2-modules/_details.scss
Normal file
48
aio/src/styles/2-modules/_details.scss
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -3,3 +3,12 @@ hr {
|
|||||||
background: $lightgray;
|
background: $lightgray;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hr-margin {
|
||||||
|
display: block;
|
||||||
|
height: 1px;
|
||||||
|
border: 0;
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
============================== */
|
============================== */
|
||||||
|
|
||||||
@import 'alert';
|
@import 'alert';
|
||||||
|
@import 'api-pages';
|
||||||
@import 'api-list';
|
@import 'api-list';
|
||||||
@import 'buttons';
|
@import 'buttons';
|
||||||
@import 'callout';
|
@import 'callout';
|
||||||
@ -10,6 +11,7 @@
|
|||||||
@import 'code';
|
@import 'code';
|
||||||
@import 'contribute';
|
@import 'contribute';
|
||||||
@import 'contributor';
|
@import 'contributor';
|
||||||
|
@import 'details';
|
||||||
@import 'edit-page-cta';
|
@import 'edit-page-cta';
|
||||||
@import 'features';
|
@import 'features';
|
||||||
@import 'filetree';
|
@import 'filetree';
|
||||||
|
@ -105,7 +105,7 @@ $api-symbols: (
|
|||||||
content: 'T',
|
content: 'T',
|
||||||
background: $light-green-600
|
background: $light-green-600
|
||||||
),
|
),
|
||||||
package: (
|
module: (
|
||||||
content: 'Pk',
|
content: 'Pk',
|
||||||
background: $purple-600
|
background: $purple-600
|
||||||
)
|
)
|
||||||
|
@ -33,7 +33,6 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
|||||||
.processor(require('./processors/simplifyMemberAnchors'))
|
.processor(require('./processors/simplifyMemberAnchors'))
|
||||||
.processor(require('./processors/computeStability'))
|
.processor(require('./processors/computeStability'))
|
||||||
.processor(require('./processors/removeInjectableConstructors'))
|
.processor(require('./processors/removeInjectableConstructors'))
|
||||||
.processor(require('./processors/processPackages'))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These are the API doc types that will be rendered to actual files.
|
* 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.
|
* more Angular specific API types, such as decorators and directives.
|
||||||
*/
|
*/
|
||||||
.factory(function API_DOC_TYPES_TO_RENDER(EXPORT_DOC_TYPES) {
|
.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);
|
return API_DOC_TYPES_TO_RENDER.concat(API_CONTAINED_DOC_TYPES);
|
||||||
})
|
})
|
||||||
|
|
||||||
.factory(require('./readers/package-content'))
|
|
||||||
|
|
||||||
// Where do we get the source files?
|
// 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`
|
// Tell TypeScript how to load modules that start with with `@angular`
|
||||||
tsParser.options.paths = { '@angular/*': [API_SOURCE_PATH + '/*'] };
|
tsParser.options.paths = { '@angular/*': [API_SOURCE_PATH + '/*'] };
|
||||||
@ -105,19 +102,12 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
|||||||
'upgrade/static/index.ts',
|
'upgrade/static/index.ts',
|
||||||
];
|
];
|
||||||
|
|
||||||
readFilesProcessor.fileReaders.push(packageContentFileReader);
|
|
||||||
|
|
||||||
// API Examples
|
// API Examples
|
||||||
readFilesProcessor.sourceFiles = [
|
readFilesProcessor.sourceFiles = [
|
||||||
{
|
{
|
||||||
basePath: API_SOURCE_PATH,
|
basePath: API_SOURCE_PATH,
|
||||||
include: API_SOURCE_PATH + '/examples/**/*',
|
include: API_SOURCE_PATH + '/examples/**/*',
|
||||||
fileReader: 'exampleFileReader'
|
fileReader: 'exampleFileReader'
|
||||||
},
|
|
||||||
{
|
|
||||||
basePath: API_SOURCE_PATH,
|
|
||||||
include: API_SOURCE_PATH + '/**/PACKAGE.md',
|
|
||||||
fileReader: 'packageContentFileReader'
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
collectExamples.exampleFolders.push('examples');
|
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) {
|
.config(function(computeStability, splitDescription, addNotYetDocumentedProperty, API_DOC_TYPES_TO_RENDER, API_DOC_TYPES) {
|
||||||
computeStability.docTypes = API_DOC_TYPES_TO_RENDER;
|
computeStability.docTypes = API_DOC_TYPES_TO_RENDER;
|
||||||
// Only split the description on the API docs
|
// 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;
|
addNotYetDocumentedProperty.docTypes = API_DOC_TYPES;
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -190,7 +180,7 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
|||||||
generateApiListDoc.outputFolder = API_SEGMENT;
|
generateApiListDoc.outputFolder = API_SEGMENT;
|
||||||
|
|
||||||
computePathsProcessor.pathTemplates.push({
|
computePathsProcessor.pathTemplates.push({
|
||||||
docTypes: ['package'],
|
docTypes: ['module'],
|
||||||
getPath: function computeModulePath(doc) {
|
getPath: function computeModulePath(doc) {
|
||||||
doc.moduleFolder = `${API_SEGMENT}/${doc.id.replace(/\/index$/, '')}`;
|
doc.moduleFolder = `${API_SEGMENT}/${doc.id.replace(/\/index$/, '')}`;
|
||||||
return doc.moduleFolder;
|
return doc.moduleFolder;
|
||||||
|
@ -33,7 +33,7 @@ describe('addSelectorsAsAliases processor', () => {
|
|||||||
{ docType: 'directive', name: 'NgModel', aliases: ['NgModel'], directiveOptions: { selector: '\'[ngModel]:not([formControlName]):not([formControl])\'' } },
|
{ docType: 'directive', name: 'NgModel', aliases: ['NgModel'], directiveOptions: { selector: '\'[ngModel]:not([formControlName]):not([formControl])\'' } },
|
||||||
{ docType: 'component', name: 'MyComponent', aliases: ['MyComponent'], componentOptions: { selector: '\'my-component\'' } },
|
{ docType: 'component', name: 'MyComponent', aliases: ['MyComponent'], componentOptions: { selector: '\'my-component\'' } },
|
||||||
{ docType: 'decorator', name: 'MyDecorator', aliases: ['MyDecorator'] },
|
{ 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: 'var', name: 'myVar', aliases: ['myVar'] },
|
||||||
{ docType: 'let', name: 'myLet', aliases: ['myLet'] },
|
{ docType: 'let', name: 'myLet', aliases: ['myLet'] },
|
||||||
{ docType: 'const', name: 'myConst', aliases: ['myConst'] },
|
{ docType: 'const', name: 'myConst', aliases: ['myConst'] },
|
||||||
|
@ -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', () => {
|
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 processor = processorFactory(API_DOC_TYPES_TO_RENDER);
|
||||||
|
|
||||||
const docs = [
|
const docs = [
|
||||||
{ docType: 'class', name: 'ClassA', path: 'module-1/class-a', moduleDoc: { id: 'moduleOne', path: 'module-1' } },
|
{ 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: 'interface', name: 'InterfaceB', path: 'module-2/interface-b', moduleDoc: { id: 'moduleTwo', path: 'module-2' } },
|
||||||
{ docType: 'guide', name: 'Guide One', path: 'guide/guide-1' },
|
{ 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);
|
processor.$process(docs);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ module.exports = function computeSearchTitleProcessor() {
|
|||||||
case 'function':
|
case 'function':
|
||||||
doc.searchTitle = `${doc.name}()`;
|
doc.searchTitle = `${doc.name}()`;
|
||||||
break;
|
break;
|
||||||
case 'package':
|
case 'module':
|
||||||
doc.searchTitle = `${doc.id} package`;
|
doc.searchTitle = `${doc.id} package`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ describe('computeSearchTitle processor', () => {
|
|||||||
{ docType: 'pipe', name: 'MyPipe', pipeOptions: { name: 'myPipe' } },
|
{ docType: 'pipe', name: 'MyPipe', pipeOptions: { name: 'myPipe' } },
|
||||||
{ docType: 'directive', name: 'MyDirective', directiveOptions: {} },
|
{ docType: 'directive', name: 'MyDirective', directiveOptions: {} },
|
||||||
{ docType: 'decorator', name: 'MyDecorator' },
|
{ docType: 'decorator', name: 'MyDecorator' },
|
||||||
{ docType: 'package', name: 'myPackage', id: 'some/myPackage' },
|
{ docType: 'module', name: 'myModule', id: 'some/myModule' },
|
||||||
{ docType: 'var', name: 'myVar' },
|
{ docType: 'var', name: 'myVar' },
|
||||||
{ docType: 'let', name: 'myLet' },
|
{ docType: 'let', name: 'myLet' },
|
||||||
{ docType: 'const', name: 'myConst' },
|
{ docType: 'const', name: 'myConst' },
|
||||||
@ -45,7 +45,7 @@ describe('computeSearchTitle processor', () => {
|
|||||||
expect(docs[4].searchTitle).toBeUndefined();
|
expect(docs[4].searchTitle).toBeUndefined();
|
||||||
expect(docs[5].searchTitle).toBeUndefined();
|
expect(docs[5].searchTitle).toBeUndefined();
|
||||||
expect(docs[6].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[8].searchTitle).toBeUndefined();
|
||||||
expect(docs[9].searchTitle).toBeUndefined();
|
expect(docs[9].searchTitle).toBeUndefined();
|
||||||
expect(docs[10].searchTitle).toBeUndefined();
|
expect(docs[10].searchTitle).toBeUndefined();
|
||||||
|
@ -12,20 +12,19 @@ module.exports = function generateApiListDoc() {
|
|||||||
path: this.outputFolder + '/api-list.json',
|
path: this.outputFolder + '/api-list.json',
|
||||||
outputPath: this.outputFolder + '/api-list.json',
|
outputPath: this.outputFolder + '/api-list.json',
|
||||||
data: docs
|
data: docs
|
||||||
.filter(doc => doc.docType === 'package')
|
.filter(doc => doc.docType === 'module')
|
||||||
.map(getPackageInfo)
|
.map(getModuleInfo)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function getPackageInfo(packageDoc) {
|
function getModuleInfo(moduleDoc) {
|
||||||
const packageName = packageDoc.id.replace(/\/index$/, '');
|
const moduleName = moduleDoc.id.replace(/\/index$/, '');
|
||||||
return {
|
return {
|
||||||
name: packageName.toLowerCase(),
|
name: moduleName.toLowerCase(),
|
||||||
title: packageName,
|
title: moduleName,
|
||||||
path: packageDoc.path,
|
items: moduleDoc.exports
|
||||||
items: packageDoc.exports
|
|
||||||
// Ignore internals and private exports (indicated by the ɵ prefix)
|
// Ignore internals and private exports (indicated by the ɵ prefix)
|
||||||
.filter(doc => !doc.internal && !doc.privateExport)
|
.filter(doc => !doc.internal && !doc.privateExport)
|
||||||
.map(getExportInfo)
|
.map(getExportInfo)
|
||||||
|
@ -38,28 +38,28 @@ describe('generateApiListDoc processor', () => {
|
|||||||
it('should add an info object to the doc for each module doc', () => {
|
it('should add an info object to the doc for each module doc', () => {
|
||||||
const processor = processorFactory();
|
const processor = processorFactory();
|
||||||
const docs = [
|
const docs = [
|
||||||
{ docType: 'package', id: '@angular/common/index', exports: [], path: 'common' },
|
{ docType: 'module', id: '@angular/common/index', exports: [] },
|
||||||
{ docType: 'package', id: '@angular/core/index', exports: [], path: 'core' },
|
{ docType: 'module', id: '@angular/core/index', exports: [] },
|
||||||
{ docType: 'package', id: '@angular/http/index', exports: [], path: 'http' },
|
{ docType: 'module', id: '@angular/http/index', exports: [] },
|
||||||
];
|
];
|
||||||
processor.$process(docs);
|
processor.$process(docs);
|
||||||
expect(docs[3].data).toEqual([
|
expect(docs[3].data).toEqual([
|
||||||
{ name: '@angular/common', title: '@angular/common', items: [], path: 'common' },
|
{ name: '@angular/common', title: '@angular/common', items: [] },
|
||||||
{ name: '@angular/core', title: '@angular/core', items: [], path: 'core' },
|
{ name: '@angular/core', title: '@angular/core', items: [] },
|
||||||
{ name: '@angular/http', title: '@angular/http', items: [], path: 'http' },
|
{ name: '@angular/http', title: '@angular/http', items: [] },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add info about each export on each module', () => {
|
it('should add info about each export on each module', () => {
|
||||||
const processor = processorFactory();
|
const processor = processorFactory();
|
||||||
const docs = [
|
const docs = [
|
||||||
{ docType: 'package', id: '@angular/common/index', exports: [
|
{ docType: 'module', id: '@angular/common/index', exports: [
|
||||||
{ docType: 'directive', name: 'AaaAaa', path: 'aaa' },
|
{ docType: 'directive', name: 'AaaAaa', path: 'aaa' },
|
||||||
{ docType: 'pipe', name: 'BbbBbb', path: 'bbb' },
|
{ docType: 'pipe', name: 'BbbBbb', path: 'bbb' },
|
||||||
{ docType: 'decorator', name: 'CccCcc', path: 'ccc' },
|
{ docType: 'decorator', name: 'CccCcc', path: 'ccc' },
|
||||||
{ docType: 'class', name: 'DddDdd', path: 'ddd' }
|
{ 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: 'interface', name: 'EeeEee', path: 'eee' },
|
||||||
{ docType: 'function', name: 'FffFff', path: 'fff' },
|
{ docType: 'function', name: 'FffFff', path: 'fff' },
|
||||||
{ docType: 'enum', name: 'GggGgg', path: 'ggg' },
|
{ docType: 'enum', name: 'GggGgg', path: 'ggg' },
|
||||||
@ -86,7 +86,7 @@ describe('generateApiListDoc processor', () => {
|
|||||||
it('should ignore internal and private exports', () => {
|
it('should ignore internal and private exports', () => {
|
||||||
const processor = processorFactory();
|
const processor = processorFactory();
|
||||||
const docs = [
|
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: 'directive', name: 'AaaAaa', path: 'aaa', internal: true },
|
||||||
{ docType: 'class', name: 'XxxXxx', path: 'xxx', privateExport: true },
|
{ docType: 'class', name: 'XxxXxx', path: 'xxx', privateExport: true },
|
||||||
{ docType: 'pipe', name: 'BbbBbb', path: 'bbb' }
|
{ docType: 'pipe', name: 'BbbBbb', path: 'bbb' }
|
||||||
@ -101,7 +101,7 @@ describe('generateApiListDoc processor', () => {
|
|||||||
it('should convert `let` and `var` docTypes to `const`', () => {
|
it('should convert `let` and `var` docTypes to `const`', () => {
|
||||||
const processor = processorFactory();
|
const processor = processorFactory();
|
||||||
const docs = [
|
const docs = [
|
||||||
{ docType: 'package', id: '@angular/common/index', exports: [
|
{ docType: 'module', id: '@angular/common/index', exports: [
|
||||||
{ docType: 'var', name: 'AaaAaa', path: 'aaa' },
|
{ docType: 'var', name: 'AaaAaa', path: 'aaa' },
|
||||||
{ docType: 'let', name: 'BbbBbb', path: 'bbb' },
|
{ docType: 'let', name: 'BbbBbb', path: 'bbb' },
|
||||||
]}
|
]}
|
||||||
@ -116,7 +116,7 @@ describe('generateApiListDoc processor', () => {
|
|||||||
it('should convert security to a boolean securityRisk', () => {
|
it('should convert security to a boolean securityRisk', () => {
|
||||||
const processor = processorFactory();
|
const processor = processorFactory();
|
||||||
const docs = [
|
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: 'AaaAaa', path: 'aaa', security: 'This is a security risk' },
|
||||||
{ docType: 'class', name: 'BbbBbb', path: 'bbb', security: '' },
|
{ docType: 'class', name: 'BbbBbb', path: 'bbb', security: '' },
|
||||||
]}
|
]}
|
||||||
@ -131,7 +131,7 @@ describe('generateApiListDoc processor', () => {
|
|||||||
it('should convert stability tags to the stable string property', () => {
|
it('should convert stability tags to the stable string property', () => {
|
||||||
const processor = processorFactory();
|
const processor = processorFactory();
|
||||||
const docs = [
|
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: 'AaaAaa', path: 'aaa', stable: undefined },
|
||||||
{ docType: 'class', name: 'BbbBbb', path: 'bbb', experimental: 'Some message' },
|
{ docType: 'class', name: 'BbbBbb', path: 'bbb', experimental: 'Some message' },
|
||||||
{ docType: 'class', name: 'CccCcc', path: 'ccc', deprecated: null },
|
{ docType: 'class', name: 'CccCcc', path: 'ccc', deprecated: null },
|
||||||
@ -150,7 +150,7 @@ describe('generateApiListDoc processor', () => {
|
|||||||
it('should sort items in each group alphabetically', () => {
|
it('should sort items in each group alphabetically', () => {
|
||||||
const processor = processorFactory();
|
const processor = processorFactory();
|
||||||
const docs = [
|
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: 'DddDdd', path: 'uuu' },
|
||||||
{ docType: 'class', name: 'BbbBbb', path: 'vvv' },
|
{ docType: 'class', name: 'BbbBbb', path: 'vvv' },
|
||||||
{ docType: 'class', name: 'AaaAaa', path: 'xxx' },
|
{ docType: 'class', name: 'AaaAaa', path: 'xxx' },
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
@ -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' },
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
@ -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}];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
@ -14,7 +14,7 @@ module.exports = function createOverviewDump() {
|
|||||||
modules: []
|
modules: []
|
||||||
};
|
};
|
||||||
_.forEach(docs, function(doc) {
|
_.forEach(docs, function(doc) {
|
||||||
if (doc.docType === 'package') {
|
if (doc.docType === 'module') {
|
||||||
overviewDoc.modules.push(doc);
|
overviewDoc.modules.push(doc);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{% set comma = joiner(',') %}
|
{% set comma = joiner(',') %}
|
||||||
{% set slash = joiner('/') %}
|
{% set slash = joiner('/') %}
|
||||||
<article>
|
<article>
|
||||||
<div class="breadcrumb-container">
|
{$ github.githubLinks(doc, versionInfo) $}
|
||||||
<div class="breadcrumb">
|
<div class="breadcrumb">
|
||||||
<script type="application/ld+json">
|
<script type="application/ld+json">
|
||||||
{
|
{
|
||||||
@ -16,8 +16,6 @@
|
|||||||
</script>
|
</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 %}
|
{% 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>
|
</div>
|
||||||
{$ github.githubLinks(doc, versionInfo) $}
|
|
||||||
</div>
|
|
||||||
<header class="api-header">
|
<header class="api-header">
|
||||||
<h1>{$ doc.name $}</h1>
|
<h1>{$ doc.name $}</h1>
|
||||||
<label class="api-type-label {$ doc.docType $}">{$ doc.docType $}</label>
|
<label class="api-type-label {$ doc.docType $}">{$ doc.docType $}</label>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{% macro githubViewHref(doc, versionInfo) -%}
|
{% 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 -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
|
|
||||||
{% macro githubEditHref(doc, versionInfo) -%}
|
{% 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] $}
|
{%- 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 -%}
|
{%- else %}...{%- endif -%}
|
||||||
)%3A%20describe%20your%20change...#L{$ doc.startingLine + 1 $}-L{$ doc.endingLine + 1 $}
|
)%3A%20describe%20your%20change...#L{$ doc.startingLine + 1 $}-L{$ doc.endingLine + 1 $}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
@ -47,17 +47,17 @@
|
|||||||
|
|
||||||
<code-example language="ts" hideCopy="true" linenums="false" class="no-box api-heading">{$ renderMemberSyntax(overload) $}</code-example>
|
<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') $}
|
{$ params.renderParameters(overload.parameterDocs, cssClass + '-parameters', cssClass + '-parameter') $}
|
||||||
|
|
||||||
{% if overload.type or overload.returns.type %}
|
{% 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 %}
|
{% marked %}`{$ (overload.type or overload.returns.type) $}`{% if overload.returns %}: {$ overload.returns.description $}{% endif %}{% endmarked %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
{% if overload.throws.length %}
|
{% if overload.throws.length %}
|
||||||
<h6 class="no-anchor">Throws</h6>
|
<h4 class="no-anchor">Throws</h4>
|
||||||
{% for error in overload.throws %}
|
{% for error in overload.throws %}
|
||||||
{% marked %}`{$ (error.typeList or 'Error') $}` {$ error.description $}{% endmarked %}
|
{% marked %}`{$ (error.typeList or 'Error') $}` {$ error.description $}{% endmarked %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -73,7 +73,7 @@
|
|||||||
{%- macro renderMethodDetail(versionInfo, method, cssClass) -%}
|
{%- macro renderMethodDetail(versionInfo, method, cssClass) -%}
|
||||||
<a id="{$ method.anchor $}"></a>
|
<a id="{$ method.anchor $}"></a>
|
||||||
<table class="is-full-width method-table {$ cssClass $}">
|
<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>
|
<h3>
|
||||||
{% if method.isCallMember %}<i>call signature</i>
|
{% if method.isCallMember %}<i>call signature</i>
|
||||||
{% elseif method.isNewMember %}<i>construct signature</i>
|
{% elseif method.isNewMember %}<i>construct signature</i>
|
||||||
@ -106,23 +106,13 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<details class="overloads">
|
<details class="overloads">
|
||||||
<summary>
|
<summary><h4 class="no-anchor">{$ method.overloads.length $} overloads...</h4></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>
|
|
||||||
<div class="detail-contents">
|
<div class="detail-contents">
|
||||||
{% for overload in method.overloads %}
|
{% 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>
|
|
||||||
{$ renderOverloadInfo(overload, cssClass + '-overload', method) $}
|
{$ 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 %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</details>
|
</details>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -180,10 +170,10 @@
|
|||||||
<td><a id="{$ property.anchor $}"></a>{$ property.name $}</td>
|
<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 %}
|
{% if hasTypes %}<td><label class="property-type-label"><code>{$ property.type | escape $}</code></label></td>{% endif %}
|
||||||
<td>
|
<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 %}
|
{% if property.shortDescription %}{$ property.shortDescription | marked $}{% endif %}
|
||||||
{$ (property.description or property.constructorParamDoc.description) | marked $}
|
{$ (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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
16
aio/tools/transforms/templates/api/module.template.html
Normal file
16
aio/tools/transforms/templates/api/module.template.html
Normal 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 %}
|
@ -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 %}
|
|
@ -1,9 +1,5 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
exports_files([
|
|
||||||
"protractor.conf.js",
|
|
||||||
])
|
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
name = "node_modules",
|
name = "node_modules",
|
||||||
srcs = glob(
|
srcs = glob(
|
||||||
|
@ -13,9 +13,9 @@ http_archive(
|
|||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "io_bazel_rules_webtesting",
|
name = "io_bazel_rules_webtesting",
|
||||||
url = "https://github.com/bazelbuild/rules_webtesting/archive/8fd9ce0fd9254bde251da0bc373d6cd08e811434.zip",
|
url = "https://github.com/bazelbuild/rules_webtesting/archive/v0.2.0.zip",
|
||||||
strip_prefix = "rules_webtesting-8fd9ce0fd9254bde251da0bc373d6cd08e811434",
|
strip_prefix = "rules_webtesting-0.2.0",
|
||||||
sha256 = "4baee95fcfadfbaf868707af8accfd1cb98c5d13f808908e0152468bfb47f0f7",
|
sha256 = "cecc12f07e95740750a40d38e8b14b76fefa1551bef9332cb432d564d693723c",
|
||||||
)
|
)
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
@ -44,7 +44,7 @@ http_archive(
|
|||||||
|
|
||||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
|
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"])
|
node_repositories(package_json = ["//:package.json"])
|
||||||
|
|
||||||
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
|
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
|
||||||
|
@ -18,13 +18,17 @@
|
|||||||
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
|
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
|
||||||
"@types/jasmine": "2.8.7",
|
"@types/jasmine": "2.8.7",
|
||||||
"@types/source-map": "0.5.1",
|
"@types/source-map": "0.5.1",
|
||||||
|
"concurrently": "3.5.1",
|
||||||
"http-server": "0.11.1",
|
"http-server": "0.11.1",
|
||||||
"protractor": "file:../../node_modules/protractor",
|
"protractor": "file:../../node_modules/protractor",
|
||||||
"tsutils": "file:../../node_modules/tsutils",
|
|
||||||
"typescript": "file:../../node_modules/typescript"
|
"typescript": "file:../../node_modules/typescript"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "ngc -p angular.tsconfig.json",
|
"postinstall": "concurrently \"webdriver-manager update $CHROMEDRIVER_VERSION_ARG\" \"ngc -p angular.tsconfig.json\"",
|
||||||
"test": "bazel build ... --noshow_progress && bazel test ..."
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,9 @@
|
|||||||
exports.config = {
|
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,
|
getPageTimeout: 60 * 1000,
|
||||||
allScriptsTimeout: 60 * 1000,
|
allScriptsTimeout: 60 * 1000,
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load("@angular//:index.bzl", "ng_module")
|
load("@angular//:index.bzl", "ng_module")
|
||||||
|
|
||||||
# Allow targets under sub-packages to reference the tsconfig.json file
|
# Allow targets under sub-packages to reference the tsconfig.json file
|
||||||
@ -48,11 +46,15 @@ genrule(
|
|||||||
|
|
||||||
nodejs_binary(
|
nodejs_binary(
|
||||||
name = "prodserver",
|
name = "prodserver",
|
||||||
|
args = [
|
||||||
|
"./src",
|
||||||
|
"-p",
|
||||||
|
"5432",
|
||||||
|
],
|
||||||
data = [
|
data = [
|
||||||
"index.html",
|
"index.html",
|
||||||
":bundle",
|
":bundle",
|
||||||
":zone.js",
|
":zone.js",
|
||||||
],
|
],
|
||||||
entry_point = "http-server/bin/http-server",
|
entry_point = "http-server/bin/http-server",
|
||||||
templated_args = ["src"],
|
|
||||||
)
|
)
|
||||||
|
@ -1,34 +1,7 @@
|
|||||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
|
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
|
||||||
load("@angular//:index.bzl", "protractor_web_test_suite")
|
|
||||||
|
|
||||||
ts_library(
|
ts_library(
|
||||||
name = "e2e",
|
name = "e2e",
|
||||||
testonly = 1,
|
testonly = 1,
|
||||||
srcs = ["app.spec.ts"],
|
srcs = glob(["*.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"],
|
|
||||||
)
|
)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {browser, by, element} from 'protractor';
|
import {browser, by, element, ExpectedConditions} from 'protractor';
|
||||||
|
|
||||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 120000;
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 120000;
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": ["es2015"]
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
|
|
||||||
"@angular/animations@file:../../dist/packages-dist/animations":
|
"@angular/animations@file:../../dist/packages-dist/animations":
|
||||||
version "6.1.0-beta.1"
|
version "6.0.0-rc.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.9.0"
|
tslib "^1.9.0"
|
||||||
|
|
||||||
"@angular/bazel@file:../../dist/packages-dist/bazel":
|
"@angular/bazel@file:../../dist/packages-dist/bazel":
|
||||||
version "6.1.0-beta.1"
|
version "6.0.0-rc.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@bazel/typescript" "^0.15.0"
|
"@bazel/typescript" "^0.15.0"
|
||||||
"@types/node" "6.0.84"
|
"@types/node" "6.0.84"
|
||||||
@ -17,12 +17,12 @@
|
|||||||
shelljs "0.7.8"
|
shelljs "0.7.8"
|
||||||
|
|
||||||
"@angular/common@file:../../dist/packages-dist/common":
|
"@angular/common@file:../../dist/packages-dist/common":
|
||||||
version "6.1.0-beta.1"
|
version "6.0.0-rc.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.9.0"
|
tslib "^1.9.0"
|
||||||
|
|
||||||
"@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli":
|
"@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli":
|
||||||
version "6.1.0-beta.1"
|
version "6.0.0-rc.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar "^1.4.2"
|
chokidar "^1.4.2"
|
||||||
minimist "^1.2.0"
|
minimist "^1.2.0"
|
||||||
@ -30,22 +30,22 @@
|
|||||||
tsickle "^0.29.0"
|
tsickle "^0.29.0"
|
||||||
|
|
||||||
"@angular/compiler@file:../../dist/packages-dist/compiler":
|
"@angular/compiler@file:../../dist/packages-dist/compiler":
|
||||||
version "6.1.0-beta.1"
|
version "6.0.0-rc.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.9.0"
|
tslib "^1.9.0"
|
||||||
|
|
||||||
"@angular/core@file:../../dist/packages-dist/core":
|
"@angular/core@file:../../dist/packages-dist/core":
|
||||||
version "6.1.0-beta.1"
|
version "6.0.0-rc.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.9.0"
|
tslib "^1.9.0"
|
||||||
|
|
||||||
"@angular/platform-browser-dynamic@file:../../dist/packages-dist/platform-browser-dynamic":
|
"@angular/platform-browser-dynamic@file:../../dist/packages-dist/platform-browser-dynamic":
|
||||||
version "6.1.0-beta.1"
|
version "6.0.0-rc.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.9.0"
|
tslib "^1.9.0"
|
||||||
|
|
||||||
"@angular/platform-browser@file:../../dist/packages-dist/platform-browser":
|
"@angular/platform-browser@file:../../dist/packages-dist/platform-browser":
|
||||||
version "6.1.0-beta.1"
|
version "6.0.0-rc.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.9.0"
|
tslib "^1.9.0"
|
||||||
|
|
||||||
@ -74,16 +74,16 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||||
|
|
||||||
"@types/node@*":
|
"@types/node@*":
|
||||||
version "10.3.4"
|
version "10.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.3.4.tgz#c74e8aec19e555df44609b8057311052a2c84d9e"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.1.4.tgz#606651d3f8a8bec08b8cb262161aab9209f4a29d"
|
||||||
|
|
||||||
"@types/node@6.0.84":
|
"@types/node@6.0.84":
|
||||||
version "6.0.84"
|
version "6.0.84"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.84.tgz#193ffe5a9f42864d425ffd9739d95b753c6a1eab"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.84.tgz#193ffe5a9f42864d425ffd9739d95b753c6a1eab"
|
||||||
|
|
||||||
"@types/node@^6.0.46":
|
"@types/node@^6.0.46":
|
||||||
version "6.0.113"
|
version "6.0.111"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.113.tgz#4b41f38ad03e4b41f9dc259b3b58aecb22c9aebc"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.111.tgz#85f880a1bab78d395a5de9bcb5319e73a0c31400"
|
||||||
|
|
||||||
"@types/q@^0.0.32":
|
"@types/q@^0.0.32":
|
||||||
version "0.0.32"
|
version "0.0.32"
|
||||||
@ -132,6 +132,10 @@ ajv@^5.1.0:
|
|||||||
fast-json-stable-stringify "^2.0.0"
|
fast-json-stable-stringify "^2.0.0"
|
||||||
json-schema-traverse "^0.3.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:
|
ansi-regex@^2.0.0:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
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"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
|
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:
|
ansi-styles@^2.2.1:
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
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"
|
version "0.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
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:
|
chalk@^1.1.1, chalk@^1.1.3:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
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:
|
dependencies:
|
||||||
delayed-stream "~1.0.0"
|
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:
|
concat-map@0.0.1:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
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:
|
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
|
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:
|
dependencies:
|
||||||
assert-plus "^1.0.0"
|
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:
|
debug@2, debug@^2.1.2, debug@^2.2.0:
|
||||||
version "2.6.9"
|
version "2.6.9"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||||
@ -418,7 +457,7 @@ ecstatic@^3.0.0:
|
|||||||
minimist "^1.1.0"
|
minimist "^1.1.0"
|
||||||
url-join "^2.0.2"
|
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"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
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"
|
ajv "^5.1.0"
|
||||||
har-schema "^2.0.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:
|
has-ansi@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-regex "^2.0.0"
|
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:
|
has-unicode@^2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
|
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
|
||||||
@ -845,6 +894,10 @@ lcid@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
invert-kv "^1.0.0"
|
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:
|
long@~3:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b"
|
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"
|
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||||
|
|
||||||
resolve@^1.1.6:
|
resolve@^1.1.6:
|
||||||
version "1.8.1"
|
version "1.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
|
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3"
|
||||||
dependencies:
|
dependencies:
|
||||||
path-parse "^1.0.5"
|
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:
|
dependencies:
|
||||||
glob "^7.0.5"
|
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":
|
"rxjs@file:../../node_modules/rxjs":
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
dependencies:
|
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"
|
version "5.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
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"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
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"
|
version "0.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
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:
|
sshpk@^1.7.0:
|
||||||
version "1.14.2"
|
version "1.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98"
|
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.1.tgz#130f5975eddad963f1d56f92b9ac6c51fa9f83eb"
|
||||||
dependencies:
|
dependencies:
|
||||||
asn1 "~0.2.3"
|
asn1 "~0.2.3"
|
||||||
assert-plus "^1.0.0"
|
assert-plus "^1.0.0"
|
||||||
dashdash "^1.12.0"
|
dashdash "^1.12.0"
|
||||||
getpass "^0.1.1"
|
getpass "^0.1.1"
|
||||||
safer-buffer "^2.0.2"
|
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
bcrypt-pbkdf "^1.0.0"
|
bcrypt-pbkdf "^1.0.0"
|
||||||
ecc-jsbn "~0.1.1"
|
ecc-jsbn "~0.1.1"
|
||||||
@ -1392,6 +1452,12 @@ string_decoder@~1.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.1.0"
|
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:
|
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
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"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
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:
|
supports-color@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
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:
|
tar@^4:
|
||||||
version "4.4.4"
|
version "4.4.4"
|
||||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.4.tgz#ec8409fae9f665a4355cc3b4087d0820232bb8cd"
|
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.4.tgz#ec8409fae9f665a4355cc3b4087d0820232bb8cd"
|
||||||
@ -1440,6 +1516,10 @@ tough-cookie@~2.3.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
punycode "^1.4.1"
|
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:
|
tsickle@^0.29.0:
|
||||||
version "0.29.0"
|
version "0.29.0"
|
||||||
resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.29.0.tgz#812806554bb46c1aa16eb0fe2a051da95ca8f5a4"
|
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 "^0.6.0"
|
||||||
source-map-support "^0.5.0"
|
source-map-support "^0.5.0"
|
||||||
|
|
||||||
tslib@^1.8.1, tslib@^1.9.0:
|
tslib@^1.9.0:
|
||||||
version "1.9.2"
|
version "1.9.2"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.2.tgz#8be0cc9a1f6dc7727c38deb16c2ebd1a2892988e"
|
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:
|
tunnel-agent@^0.6.0:
|
||||||
version "0.6.0"
|
version "0.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
|
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"
|
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||||
|
|
||||||
"typescript@file:../../node_modules/typescript":
|
"typescript@file:../../node_modules/typescript":
|
||||||
version "2.8.3"
|
version "2.7.2"
|
||||||
|
|
||||||
ultron@1.0.x:
|
ultron@1.0.x:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
|
@ -77,7 +77,7 @@ module.exports = function(config) {
|
|||||||
'dist/all/@angular/compiler/test/aot/**',
|
'dist/all/@angular/compiler/test/aot/**',
|
||||||
'dist/all/@angular/compiler/test/render3/**',
|
'dist/all/@angular/compiler/test/render3/**',
|
||||||
'dist/all/@angular/core/test/bundling/**',
|
'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/elements/schematics/**',
|
||||||
'dist/all/@angular/examples/**/e2e_test/*',
|
'dist/all/@angular/examples/**/e2e_test/*',
|
||||||
'dist/all/@angular/language-service/**',
|
'dist/all/@angular/language-service/**',
|
||||||
|
@ -48,13 +48,13 @@ export class LargeTableComponent {
|
|||||||
{
|
{
|
||||||
if (rf2 & RenderFlags.Create) {
|
if (rf2 & RenderFlags.Create) {
|
||||||
E(0, 'td');
|
E(0, 'td');
|
||||||
s(c0);
|
s(1, c0);
|
||||||
{ T(1); }
|
{ T(2); }
|
||||||
e();
|
e();
|
||||||
}
|
}
|
||||||
if (rf2 & RenderFlags.Update) {
|
if (rf2 & RenderFlags.Update) {
|
||||||
sp(0, 0, cell.row % 2 ? '' : 'grey');
|
sp(1, 0, cell.row % 2 ? '' : 'grey');
|
||||||
t(1, b(cell.value));
|
t(2, b(cell.value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v();
|
v();
|
||||||
|
@ -41,16 +41,16 @@ export class TreeComponent {
|
|||||||
template: function(rf: RenderFlags, ctx: TreeComponent) {
|
template: function(rf: RenderFlags, ctx: TreeComponent) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
E(0, 'span');
|
E(0, 'span');
|
||||||
s(c0);
|
s(1, c0);
|
||||||
{ T(1); }
|
{ T(2); }
|
||||||
e();
|
e();
|
||||||
C(2);
|
|
||||||
C(3);
|
C(3);
|
||||||
|
C(4);
|
||||||
}
|
}
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
sp(0, 0, ctx.data.depth % 2 ? '' : 'grey');
|
sp(1, 0, ctx.data.depth % 2 ? '' : 'grey');
|
||||||
t(1, i1(' ', ctx.data.value, ' '));
|
t(2, i1(' ', ctx.data.value, ' '));
|
||||||
cR(2);
|
cR(3);
|
||||||
{
|
{
|
||||||
if (ctx.data.left != null) {
|
if (ctx.data.left != null) {
|
||||||
let rf0 = V(0);
|
let rf0 = V(0);
|
||||||
@ -67,7 +67,7 @@ export class TreeComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cr();
|
cr();
|
||||||
cR(3);
|
cR(4);
|
||||||
{
|
{
|
||||||
if (ctx.data.right != null) {
|
if (ctx.data.right != null) {
|
||||||
let rf0 = V(0);
|
let rf0 = V(0);
|
||||||
@ -114,18 +114,18 @@ export function TreeTpl(rf: RenderFlags, ctx: TreeNode) {
|
|||||||
E(0, 'tree');
|
E(0, 'tree');
|
||||||
{
|
{
|
||||||
E(1, 'span');
|
E(1, 'span');
|
||||||
s(c1);
|
s(2, c1);
|
||||||
{ T(2); }
|
{ T(3); }
|
||||||
e();
|
e();
|
||||||
C(3);
|
|
||||||
C(4);
|
C(4);
|
||||||
|
C(5);
|
||||||
}
|
}
|
||||||
e();
|
e();
|
||||||
}
|
}
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
sp(1, 0, ctx.depth % 2 ? '' : 'grey');
|
sp(2, 0, ctx.depth % 2 ? '' : 'grey');
|
||||||
t(2, i1(' ', ctx.value, ' '));
|
t(3, i1(' ', ctx.value, ' '));
|
||||||
cR(3);
|
cR(4);
|
||||||
{
|
{
|
||||||
if (ctx.left != null) {
|
if (ctx.left != null) {
|
||||||
let rf0 = V(0);
|
let rf0 = V(0);
|
||||||
@ -134,7 +134,7 @@ export function TreeTpl(rf: RenderFlags, ctx: TreeNode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cr();
|
cr();
|
||||||
cR(4);
|
cR(5);
|
||||||
{
|
{
|
||||||
if (ctx.right != null) {
|
if (ctx.right != null) {
|
||||||
let rf0 = V(0);
|
let rf0 = V(0);
|
||||||
|
@ -26,7 +26,6 @@ ng_package(
|
|||||||
entry_point = "packages/animations/index.js",
|
entry_point = "packages/animations/index.js",
|
||||||
tags = [
|
tags = [
|
||||||
"ivy-jit",
|
"ivy-jit",
|
||||||
"ivy-local",
|
|
||||||
"release-with-framework",
|
"release-with-framework",
|
||||||
],
|
],
|
||||||
deps = [
|
deps = [
|
||||||
|
@ -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).
|
|
@ -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_module.bzl", _ng_module = "ng_module")
|
||||||
load("//packages/bazel/src/ng_package:ng_package.bzl", _ng_package = "ng_package")
|
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_module = _ng_module
|
||||||
ng_package = _ng_package
|
ng_package = _ng_package
|
||||||
protractor_web_test = _protractor_web_test
|
|
||||||
protractor_web_test_suite = _protractor_web_test_suite
|
|
||||||
|
@ -5,7 +5,6 @@ filegroup(
|
|||||||
srcs = glob(["*"]) + [
|
srcs = glob(["*"]) + [
|
||||||
"//packages/bazel/src/ng_package:package_assets",
|
"//packages/bazel/src/ng_package:package_assets",
|
||||||
"//packages/bazel/src/ngc-wrapped:package_assets",
|
"//packages/bazel/src/ngc-wrapped:package_assets",
|
||||||
"//packages/bazel/src/protractor:package_assets",
|
|
||||||
],
|
],
|
||||||
visibility = ["//packages/bazel:__subpackages__"],
|
visibility = ["//packages/bazel:__subpackages__"],
|
||||||
)
|
)
|
||||||
@ -14,7 +13,7 @@ load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
|
|||||||
|
|
||||||
nodejs_binary(
|
nodejs_binary(
|
||||||
name = "rollup_with_build_optimizer",
|
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
|
# 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
|
# dependency @build_bazel_rules_nodejs_rollup_deps. We don't need any
|
||||||
# additional npm dependencies when we run rollup or uglify.
|
# additional npm dependencies when we run rollup or uglify.
|
||||||
|
@ -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"]
|
PACKAGES=["packages/core/src", "packages/common/src", "packages/compiler/src", "external/rxjs"]
|
||||||
PLUGIN_CONFIG="{sideEffectFreeModules: [\n%s]}" % ",\n".join(
|
PLUGIN_CONFIG="{sideEffectFreeModules: [\n%s]}" % ",\n".join(
|
||||||
[" '.esm5/{0}'".format(p) for p in PACKAGES])
|
[" '.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)
|
BO_PLUGIN="require('%s').default(%s)" % (BO_ROLLUP, PLUGIN_CONFIG)
|
||||||
|
|
||||||
def _use_plain_rollup(ctx):
|
def _use_plain_rollup(ctx):
|
||||||
|
@ -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",
|
|
||||||
])
|
|
@ -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;
|
|
@ -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)
|
|
@ -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",
|
|
||||||
)
|
|
@ -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}; });
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"lib": ["es2015"]
|
|
||||||
}
|
|
||||||
}
|
|
@ -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"],
|
|
||||||
)
|
|
@ -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);
|
|
@ -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; }
|
|
||||||
};
|
|
@ -1,9 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>protractor test</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script src="/bundle.min.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -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;
|
|
||||||
});
|
|
||||||
};
|
|
@ -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();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": ["es2015"]
|
|
||||||
}
|
|
||||||
}
|
|
@ -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"],
|
|
||||||
)
|
|
@ -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(); }); });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
@ -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');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": ["es2015"]
|
|
||||||
}
|
|
||||||
}
|
|
@ -29,7 +29,6 @@ ng_package(
|
|||||||
packages = ["//packages/common/locales:package"],
|
packages = ["//packages/common/locales:package"],
|
||||||
tags = [
|
tags = [
|
||||||
"ivy-jit",
|
"ivy-jit",
|
||||||
"ivy-local",
|
|
||||||
"release-with-framework",
|
"release-with-framework",
|
||||||
],
|
],
|
||||||
deps = [
|
deps = [
|
||||||
|
@ -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",
|
|
||||||
],
|
|
||||||
)
|
|
@ -76,17 +76,13 @@ class SampleTokenExtractor {
|
|||||||
it('does not re-parse if document.cookie has not changed', () => {
|
it('does not re-parse if document.cookie has not changed', () => {
|
||||||
expect(extractor.getToken()).toEqual('test');
|
expect(extractor.getToken()).toEqual('test');
|
||||||
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', () => {
|
it('re-parses if document.cookie changes', () => {
|
||||||
expect(extractor.getToken()).toEqual('test');
|
expect(extractor.getToken()).toEqual('test');
|
||||||
document['cookie'] = 'XSRF-TOKEN=blah';
|
document['cookie'] = 'XSRF-TOKEN=blah';
|
||||||
expect(extractor.getToken()).toEqual('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;
|
|
||||||
}
|
|
@ -193,9 +193,20 @@ function padNumber(
|
|||||||
return neg + strNum;
|
return neg + strNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatFractionalSeconds(milliseconds: number, digits: number): string {
|
/**
|
||||||
const strMs = padNumber(milliseconds, 3);
|
* Trim a fractional part to `digits` number of digits.
|
||||||
return strMs.substr(0, 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;
|
part = 12;
|
||||||
}
|
}
|
||||||
} else if (name === DateType.FractionalSeconds) {
|
} else if (name === DateType.FractionalSeconds) {
|
||||||
return formatFractionalSeconds(part, size);
|
return trimRPadFractional(part, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
const localeMinus = getLocaleNumberSymbol(locale, NumberSymbol.MinusSign);
|
const localeMinus = getLocaleNumberSymbol(locale, NumberSymbol.MinusSign);
|
||||||
|
@ -319,10 +319,6 @@ describe('Format date', () => {
|
|||||||
expect(formatDate(3000, 'm:ss.S', 'en')).toEqual('0:03.0');
|
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.SS', 'en')).toEqual('0:03.00');
|
||||||
expect(formatDate(3000, 'm:ss.SSS', 'en')).toEqual('0:03.000');
|
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');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -38,7 +38,6 @@ npm_package(
|
|||||||
],
|
],
|
||||||
tags = [
|
tags = [
|
||||||
"ivy-jit",
|
"ivy-jit",
|
||||||
"ivy-local",
|
|
||||||
"release-with-framework",
|
"release-with-framework",
|
||||||
],
|
],
|
||||||
deps = [":compiler-cli"],
|
deps = [":compiler-cli"],
|
||||||
|
@ -37,13 +37,10 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
|
|||||||
}
|
}
|
||||||
|
|
||||||
analyze(node: ts.ClassDeclaration, decorator: Decorator): AnalysisOutput<NgModuleAnalysis> {
|
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`);
|
throw new Error(`Incorrect number of arguments to @NgModule decorator`);
|
||||||
}
|
}
|
||||||
|
const meta = decorator.args[0];
|
||||||
// @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([]);
|
|
||||||
if (!ts.isObjectLiteralExpression(meta)) {
|
if (!ts.isObjectLiteralExpression(meta)) {
|
||||||
throw new Error(`Decorator argument must be literal.`);
|
throw new Error(`Decorator argument must be literal.`);
|
||||||
}
|
}
|
||||||
@ -135,12 +132,6 @@ function resolveTypeList(resolvedList: ResolvedValue, name: string): Reference[]
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolvedList.forEach((entry, idx) => {
|
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)) {
|
if (Array.isArray(entry)) {
|
||||||
// Recurse into nested arrays.
|
// Recurse into nested arrays.
|
||||||
refList.push(...resolveTypeList(entry, name));
|
refList.push(...resolveTypeList(entry, name));
|
||||||
@ -153,7 +144,7 @@ function resolveTypeList(resolvedList: ResolvedValue, name: string): Reference[]
|
|||||||
refList.push(entry);
|
refList.push(entry);
|
||||||
} else {
|
} else {
|
||||||
// TODO(alxhub): expand ModuleWithProviders.
|
// 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`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ export class DtsFileTransformer {
|
|||||||
|
|
||||||
const imports = this.imports.getAllImports(tsPath, this.coreImportsFrom);
|
const imports = this.imports.getAllImports(tsPath, this.coreImportsFrom);
|
||||||
if (imports.length !== 0) {
|
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;
|
return dts;
|
||||||
|
@ -35,8 +35,8 @@ const CORE_SUPPORTED_SYMBOLS = new Set<string>([
|
|||||||
'ɵdefineNgModule',
|
'ɵdefineNgModule',
|
||||||
'inject',
|
'inject',
|
||||||
'InjectableDef',
|
'InjectableDef',
|
||||||
'ɵInjectorDef',
|
'InjectorDef',
|
||||||
'ɵNgModuleDef',
|
'NgModuleDef',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export class ImportManager {
|
export class ImportManager {
|
||||||
|
@ -43,9 +43,8 @@ const EXPECTED_XMB = `<?xml version="1.0" encoding="UTF-8" ?>
|
|||||||
<!ELEMENT ex (#PCDATA)>
|
<!ELEMENT ex (#PCDATA)>
|
||||||
]>
|
]>
|
||||||
<messagebundle>
|
<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="8136548302122759730" desc="desc" meaning="meaning"><source>src/module.ts: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>
|
<msg id="3492007542396725315"><source>src/module.ts:2</source>Welcome</msg>
|
||||||
Welcome</msg>
|
|
||||||
</messagebundle>
|
</messagebundle>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -56,39 +55,18 @@ const EXPECTED_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
|
|||||||
<trans-unit id="76e1eccb1b772fa9f294ef9c146ea6d0efa8a2d4" datatype="html">
|
<trans-unit id="76e1eccb1b772fa9f294ef9c146ea6d0efa8a2d4" datatype="html">
|
||||||
<source>translate me</source>
|
<source>translate me</source>
|
||||||
<context-group purpose="location">
|
<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>
|
|
||||||
<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="linenumber">1</context>
|
<context context-type="linenumber">1</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<note priority="1" from="description">desc</note>
|
<note priority="1" from="description">desc</note>
|
||||||
<note priority="1" from="meaning">meaning</note>
|
<note priority="1" from="meaning">meaning</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="085a5ecc40cc87451d216725b2befd50866de18a" datatype="html">
|
<trans-unit id="65cc4ab3b4c438e07c89be2b677d08369fb62da2" datatype="html">
|
||||||
<source>
|
<source>Welcome</source>
|
||||||
Welcome</source>
|
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/basic.html</context>
|
<context context-type="sourcefile">src/module.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="linenumber">3</context>
|
|
||||||
</context-group>
|
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/comp2.ts</context>
|
|
||||||
<context context-type="linenumber">2</context>
|
<context context-type="linenumber">2</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/basic.html</context>
|
|
||||||
<context context-type="linenumber">3</context>
|
|
||||||
</context-group>
|
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
@ -102,24 +80,18 @@ const EXPECTED_XLIFF2 = `<?xml version="1.0" encoding="UTF-8" ?>
|
|||||||
<notes>
|
<notes>
|
||||||
<note category="description">desc</note>
|
<note category="description">desc</note>
|
||||||
<note category="meaning">meaning</note>
|
<note category="meaning">meaning</note>
|
||||||
<note category="location">src/basic.html:1</note>
|
<note category="location">src/module.ts:1</note>
|
||||||
<note category="location">src/comp2.ts:1</note>
|
|
||||||
<note category="location">src/basic.html:1</note>
|
|
||||||
</notes>
|
</notes>
|
||||||
<segment>
|
<segment>
|
||||||
<source>translate me</source>
|
<source>translate me</source>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="9038505069473852515">
|
<unit id="3492007542396725315">
|
||||||
<notes>
|
<notes>
|
||||||
<note category="location">src/basic.html:3,4</note>
|
<note category="location">src/module.ts:2</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>
|
|
||||||
</notes>
|
</notes>
|
||||||
<segment>
|
<segment>
|
||||||
<source>
|
<source>Welcome</source>
|
||||||
Welcome</source>
|
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
</file>
|
</file>
|
||||||
@ -183,54 +155,21 @@ describe('extract_i18n command line', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function writeSources() {
|
function writeSources() {
|
||||||
const welcomeMessage = `
|
write('src/basic.html', [
|
||||||
<!--i18n-->
|
`<div title="translate me" i18n-title="meaning|desc"></div>`,
|
||||||
Welcome<!--/i18n-->
|
`<p id="welcomeMessage"><!--i18n-->Welcome<!--/i18n--></p>`,
|
||||||
`;
|
].join('\n'));
|
||||||
write('src/basic.html', `<div title="translate me" i18n-title="meaning|desc"></div>
|
write('src/module.ts', `
|
||||||
<p id="welcomeMessage">${welcomeMessage}</p>`);
|
import {Component, NgModule} from '@angular/core';
|
||||||
|
|
||||||
write('src/comp1.ts', `
|
|
||||||
import {Component} from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'basic',
|
selector: 'basic',
|
||||||
templateUrl: './basic.html',
|
templateUrl: './basic.html',
|
||||||
})
|
})
|
||||||
export class BasicCmp1 {}`);
|
export class BasicCmp {}
|
||||||
|
|
||||||
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';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [BasicCmp1, BasicCmp2, BasicCmp3, BasicCmp4]
|
declarations: [BasicCmp]
|
||||||
})
|
})
|
||||||
export class I18nModule {}
|
export class I18nModule {}
|
||||||
`);
|
`);
|
||||||
|
@ -144,7 +144,7 @@ describe('ngtsc behavioral tests', () => {
|
|||||||
expect(jsContents).not.toContain('__decorate');
|
expect(jsContents).not.toContain('__decorate');
|
||||||
|
|
||||||
const dtsContents = getContents('test.d.ts');
|
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', () => {
|
it('should compile Components without errors', () => {
|
||||||
@ -196,9 +196,9 @@ describe('ngtsc behavioral tests', () => {
|
|||||||
'declarations: [TestCmp], imports: [], exports: [] })');
|
'declarations: [TestCmp], imports: [], exports: [] })');
|
||||||
|
|
||||||
const dtsContents = getContents('test.d.ts');
|
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)
|
expect(dtsContents)
|
||||||
.toContain('static ngModuleDef: i0.ɵNgModuleDef<TestModule, [TestCmp], [], []>');
|
.toContain('static ngModuleDef: i0.NgModuleDef<TestModule, [TestCmp], [], []>');
|
||||||
expect(dtsContents).not.toContain('__decorate');
|
expect(dtsContents).not.toContain('__decorate');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -240,8 +240,8 @@ describe('ngtsc behavioral tests', () => {
|
|||||||
|
|
||||||
const dtsContents = getContents('test.d.ts');
|
const dtsContents = getContents('test.d.ts');
|
||||||
expect(dtsContents)
|
expect(dtsContents)
|
||||||
.toContain('static ngModuleDef: i0.ɵNgModuleDef<TestModule, [TestCmp], [OtherModule], []>');
|
.toContain('static ngModuleDef: i0.NgModuleDef<TestModule, [TestCmp], [OtherModule], []>');
|
||||||
expect(dtsContents).toContain('static ngInjectorDef: i0.ɵInjectorDef');
|
expect(dtsContents).toContain('static ngInjectorDef: i0.InjectorDef');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compile Pipes without errors', () => {
|
it('should compile Pipes without errors', () => {
|
||||||
@ -342,6 +342,6 @@ describe('ngtsc behavioral tests', () => {
|
|||||||
expect(jsContents).toContain('pipes: [TestPipe]');
|
expect(jsContents).toContain('pipes: [TestPipe]');
|
||||||
|
|
||||||
const dtsContents = getContents('test.d.ts');
|
const dtsContents = getContents('test.d.ts');
|
||||||
expect(dtsContents).toContain('i0.ɵNgModuleDef<TestModule, [TestPipe,TestCmp], [], []>');
|
expect(dtsContents).toContain('i0.NgModuleDef<TestModule, [TestPipe,TestCmp], [], []>');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -23,7 +23,6 @@ ng_package(
|
|||||||
include_devmode_srcs = True,
|
include_devmode_srcs = True,
|
||||||
tags = [
|
tags = [
|
||||||
"ivy-jit",
|
"ivy-jit",
|
||||||
"ivy-local",
|
|
||||||
"release-with-framework",
|
"release-with-framework",
|
||||||
],
|
],
|
||||||
deps = [
|
deps = [
|
||||||
|
@ -318,12 +318,10 @@ export class AotCompiler {
|
|||||||
});
|
});
|
||||||
compMetas.forEach(compMeta => {
|
compMetas.forEach(compMeta => {
|
||||||
const html = compMeta.template !.template !;
|
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 =
|
const interpolationConfig =
|
||||||
InterpolationConfig.fromArray(compMeta.template !.interpolation);
|
InterpolationConfig.fromArray(compMeta.template !.interpolation);
|
||||||
errors.push(...messageBundle.updateFromTemplate(html, templateUrl, interpolationConfig) !);
|
errors.push(
|
||||||
|
...messageBundle.updateFromTemplate(html, file.fileName, interpolationConfig) !);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -380,6 +380,8 @@ export const enum RenderFlags {
|
|||||||
Update = 0b10
|
Update = 0b10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note this will expand once `class` is introduced to styling
|
||||||
export const enum InitialStylingFlags {
|
export const enum InitialStylingFlags {
|
||||||
VALUES_MODE = 0b1,
|
/** Mode for matching initial style values */
|
||||||
|
INITIAL_STYLES = 0b00,
|
||||||
}
|
}
|
||||||
|
@ -75,14 +75,10 @@ export class Extractor {
|
|||||||
});
|
});
|
||||||
compMetas.forEach(compMeta => {
|
compMetas.forEach(compMeta => {
|
||||||
const html = compMeta.template !.template !;
|
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 =
|
const interpolationConfig =
|
||||||
InterpolationConfig.fromArray(compMeta.template !.interpolation);
|
InterpolationConfig.fromArray(compMeta.template !.interpolation);
|
||||||
errors.push(...this.messageBundle.updateFromTemplate(
|
errors.push(...this.messageBundle.updateFromTemplate(
|
||||||
html, templateUrl, interpolationConfig) !);
|
html, file.fileName, interpolationConfig) !);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -33,11 +33,13 @@ export class Identifiers {
|
|||||||
|
|
||||||
static elementAttribute: o.ExternalReference = {name: 'ɵa', moduleName: CORE};
|
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 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};
|
static elementStyleProp: o.ExternalReference = {name: 'ɵsp', moduleName: CORE};
|
||||||
|
|
||||||
@ -102,7 +104,7 @@ export class Identifiers {
|
|||||||
static defineComponent: o.ExternalReference = {name: 'ɵdefineComponent', moduleName: CORE};
|
static defineComponent: o.ExternalReference = {name: 'ɵdefineComponent', moduleName: CORE};
|
||||||
|
|
||||||
static ComponentDef: o.ExternalReference = {
|
static ComponentDef: o.ExternalReference = {
|
||||||
name: 'ɵComponentDef',
|
name: 'ComponentDef',
|
||||||
moduleName: CORE,
|
moduleName: CORE,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -112,12 +114,12 @@ export class Identifiers {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static DirectiveDef: o.ExternalReference = {
|
static DirectiveDef: o.ExternalReference = {
|
||||||
name: 'ɵDirectiveDef',
|
name: 'DirectiveDef',
|
||||||
moduleName: CORE,
|
moduleName: CORE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static InjectorDef: o.ExternalReference = {
|
static InjectorDef: o.ExternalReference = {
|
||||||
name: 'ɵInjectorDef',
|
name: 'InjectorDef',
|
||||||
moduleName: CORE,
|
moduleName: CORE,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -127,7 +129,7 @@ export class Identifiers {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static NgModuleDef: o.ExternalReference = {
|
static NgModuleDef: o.ExternalReference = {
|
||||||
name: 'ɵNgModuleDef',
|
name: 'NgModuleDef',
|
||||||
moduleName: CORE,
|
moduleName: CORE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,8 +107,7 @@ export function compileInjector(meta: R3InjectorMetadata): R3InjectorDef {
|
|||||||
providers: meta.providers,
|
providers: meta.providers,
|
||||||
imports: meta.imports,
|
imports: meta.imports,
|
||||||
})]);
|
})]);
|
||||||
const type =
|
const type = new o.ExpressionType(o.importExpr(R3.InjectorDef));
|
||||||
new o.ExpressionType(o.importExpr(R3.InjectorDef, [new o.ExpressionType(meta.type)]));
|
|
||||||
return {expression, type};
|
return {expression, type};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,14 +88,9 @@ export function compileDirectiveFromMetadata(
|
|||||||
bindingParser: BindingParser): R3DirectiveDef {
|
bindingParser: BindingParser): R3DirectiveDef {
|
||||||
const definitionMap = baseDirectiveFields(meta, constantPool, bindingParser);
|
const definitionMap = baseDirectiveFields(meta, constantPool, bindingParser);
|
||||||
const expression = o.importExpr(R3.defineDirective).callFn([definitionMap.toLiteralMap()]);
|
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(
|
const type = new o.ExpressionType(o.importExpr(
|
||||||
R3.DirectiveDef,
|
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};
|
return {expression, type};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,14 +157,10 @@ export function compileComponentFromMetadata(
|
|||||||
definitionMap.set('pipes', o.literalArr(Array.from(pipesUsed)));
|
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 expression = o.importExpr(R3.defineComponent).callFn([definitionMap.toLiteralMap()]);
|
||||||
const type = new o.ExpressionType(o.importExpr(
|
const type = new o.ExpressionType(o.importExpr(
|
||||||
R3.ComponentDef,
|
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};
|
return {expression, type};
|
||||||
}
|
}
|
||||||
|
@ -40,12 +40,19 @@ function mapBindingToInstruction(type: BindingType): o.ExternalReference|undefin
|
|||||||
case BindingType.Attribute:
|
case BindingType.Attribute:
|
||||||
return R3.elementAttribute;
|
return R3.elementAttribute;
|
||||||
case BindingType.Class:
|
case BindingType.Class:
|
||||||
return R3.elementClassProp;
|
return R3.elementClassNamed;
|
||||||
default:
|
default:
|
||||||
return undefined;
|
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 {
|
export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver {
|
||||||
private _dataIndex = 0;
|
private _dataIndex = 0;
|
||||||
private _bindingContext = 0;
|
private _bindingContext = 0;
|
||||||
@ -303,59 +310,33 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||||||
const i18nMessages: o.Statement[] = [];
|
const i18nMessages: o.Statement[] = [];
|
||||||
const attributes: o.Expression[] = [];
|
const attributes: o.Expression[] = [];
|
||||||
const initialStyleDeclarations: o.Expression[] = [];
|
const initialStyleDeclarations: o.Expression[] = [];
|
||||||
const initialClassDeclarations: o.Expression[] = [];
|
|
||||||
|
|
||||||
const styleInputs: t.BoundAttribute[] = [];
|
const styleInputs: t.BoundAttribute[] = [];
|
||||||
const classInputs: t.BoundAttribute[] = [];
|
|
||||||
const allOtherInputs: t.BoundAttribute[] = [];
|
const allOtherInputs: t.BoundAttribute[] = [];
|
||||||
|
|
||||||
element.inputs.forEach((input: t.BoundAttribute) => {
|
element.inputs.forEach((input: t.BoundAttribute) => {
|
||||||
switch (input.type) {
|
// [attr.style] should not be treated as a styling-based
|
||||||
// [attr.style] or [attr.class] should not be treated as styling-based
|
// binding since it is intended to write directly to the attr
|
||||||
// bindings since they are intended to be written directly to the attr
|
// and therefore will skip all style resolution that is present
|
||||||
// and therefore will skip all style/class resolution that is present
|
// with style="", [style]="" and [style.prop]="" assignments
|
||||||
// with style="", [style]="" and [style.prop]="", class="",
|
if (input.name == 'style' && input.type == BindingType.Property) {
|
||||||
// [class.prop]="". [class]="" assignments
|
|
||||||
case BindingType.Property:
|
|
||||||
if (input.name == 'style') {
|
|
||||||
// this should always go first in the compilation (for [style])
|
// this should always go first in the compilation (for [style])
|
||||||
styleInputs.splice(0, 0, input);
|
styleInputs.splice(0, 0, input);
|
||||||
} else if (isClassBinding(input)) {
|
} else if (input.type == BindingType.Style) {
|
||||||
// this should always go first in the compilation (for [class])
|
styleInputs.push(input);
|
||||||
classInputs.splice(0, 0, input);
|
|
||||||
} else {
|
} else {
|
||||||
allOtherInputs.push(input);
|
allOtherInputs.push(input);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case BindingType.Style:
|
|
||||||
styleInputs.push(input);
|
|
||||||
break;
|
|
||||||
case BindingType.Class:
|
|
||||||
classInputs.push(input);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
allOtherInputs.push(input);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let currStyleIndex = 0;
|
let currStyleIndex = 0;
|
||||||
let currClassIndex = 0;
|
|
||||||
let staticStylesMap: {[key: string]: any}|null = null;
|
let staticStylesMap: {[key: string]: any}|null = null;
|
||||||
let staticClassesMap: {[key: string]: boolean}|null = null;
|
|
||||||
const stylesIndexMap: {[key: string]: number} = {};
|
const stylesIndexMap: {[key: string]: number} = {};
|
||||||
const classesIndexMap: {[key: string]: number} = {};
|
|
||||||
Object.getOwnPropertyNames(outputAttrs).forEach(name => {
|
Object.getOwnPropertyNames(outputAttrs).forEach(name => {
|
||||||
const value = outputAttrs[name];
|
const value = outputAttrs[name];
|
||||||
if (name == 'style') {
|
if (name == 'style') {
|
||||||
staticStylesMap = parseStyle(value);
|
staticStylesMap = parseStyle(value);
|
||||||
Object.keys(staticStylesMap).forEach(prop => { stylesIndexMap[prop] = currStyleIndex++; });
|
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 {
|
} else {
|
||||||
attributes.push(o.literal(name));
|
attributes.push(o.literal(name));
|
||||||
if (attrI18nMetas.hasOwnProperty(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
|
// this will build the instructions so that they fall into the following syntax
|
||||||
// => [prop1, prop2, prop3, 0, prop1, value1, prop2, value2]
|
// => [prop1, prop2, prop3, 0, prop1, value1, prop2, value2]
|
||||||
Object.keys(stylesIndexMap).forEach(prop => {
|
Object.keys(stylesIndexMap).forEach(prop => {
|
||||||
@ -391,7 +364,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (staticStylesMap) {
|
if (staticStylesMap) {
|
||||||
initialStyleDeclarations.push(o.literal(core.InitialStylingFlags.VALUES_MODE));
|
initialStyleDeclarations.push(o.literal(core.InitialStylingFlags.INITIAL_STYLES));
|
||||||
|
|
||||||
Object.keys(staticStylesMap).forEach(prop => {
|
Object.keys(staticStylesMap).forEach(prop => {
|
||||||
initialStyleDeclarations.push(o.literal(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 ?
|
const attrArg: o.Expression = attributes.length > 0 ?
|
||||||
this.constantPool.getConstLiteral(o.literalArr(attributes), true) :
|
this.constantPool.getConstLiteral(o.literalArr(attributes), true) :
|
||||||
o.TYPED_NULL_EXPR;
|
o.TYPED_NULL_EXPR;
|
||||||
@ -454,8 +411,10 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||||||
|
|
||||||
const implicit = o.variable(CONTEXT_NAME);
|
const implicit = o.variable(CONTEXT_NAME);
|
||||||
|
|
||||||
|
const elementStyleIndex =
|
||||||
|
(initialStyleDeclarations.length || styleInputs.length) ? this.allocateDataSlot() : 0;
|
||||||
const createSelfClosingInstruction =
|
const createSelfClosingInstruction =
|
||||||
!hasStylingInstructions && element.children.length === 0 && element.outputs.length === 0;
|
elementStyleIndex === 0 && element.children.length === 0 && element.outputs.length === 0;
|
||||||
|
|
||||||
if (createSelfClosingInstruction) {
|
if (createSelfClosingInstruction) {
|
||||||
this.instruction(
|
this.instruction(
|
||||||
@ -470,30 +429,16 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||||||
...trimTrailingNulls(parameters));
|
...trimTrailingNulls(parameters));
|
||||||
|
|
||||||
// initial styling for static style="..." attributes
|
// initial styling for static style="..." attributes
|
||||||
if (hasStylingInstructions) {
|
if (elementStyleIndex > 0) {
|
||||||
const paramsList: (o.Expression)[] = [];
|
let paramsList: (o.Expression)[] = [o.literal(elementStyleIndex)];
|
||||||
|
|
||||||
if (initialStyleDeclarations.length) {
|
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
|
// in a special command called `elementStyle` so that the initial styles
|
||||||
// can be processed during runtime. These initial styles values are bound to
|
// 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).
|
// a constant because the inital style values do not change (since they're static).
|
||||||
paramsList.push(
|
paramsList.push(
|
||||||
this.constantPool.getConstLiteral(o.literalArr(initialStyleDeclarations), true));
|
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());
|
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) {
|
if (styleInputs.length && elementStyleIndex > 0) {
|
||||||
const indexLiteral = o.literal(elementIndex);
|
const indexLiteral = o.literal(elementStyleIndex);
|
||||||
|
styleInputs.forEach((input, i) => {
|
||||||
const firstStyle = styleInputs[0];
|
const isMapBasedStyleBinding = i == 0 && input.name == 'style';
|
||||||
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);
|
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 key = input.name;
|
||||||
const styleIndex: number = stylesIndexMap[key] !;
|
let styleIndex: number = stylesIndexMap[key] !;
|
||||||
this.instruction(
|
this.instruction(
|
||||||
this._bindingCode, input.sourceSpan, R3.elementStyleProp, indexLiteral,
|
this._bindingCode, input.sourceSpan, R3.elementStyleProp, indexLiteral,
|
||||||
o.literal(styleIndex), convertedBinding);
|
o.literal(styleIndex), convertedBinding);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
lastInputCommand = styleInputs[styleInputs.length - 1];
|
const spanEnd = styleInputs[styleInputs.length - 1].sourceSpan;
|
||||||
}
|
this.instruction(this._bindingCode, spanEnd, R3.elementStylingApply, indexLiteral);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate element input bindings
|
// Generate element input bindings
|
||||||
allOtherInputs.forEach((input: t.BoundAttribute) => {
|
allOtherInputs.forEach((input: t.BoundAttribute) => {
|
||||||
if (input.type === BindingType.Animation) {
|
if (input.type === BindingType.Animation) {
|
||||||
console.error('warning: animation bindings not yet supported');
|
this._unsupported('animations');
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const convertedBinding = this.convertPropertyBinding(implicit, input.value);
|
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);
|
const instruction = mapBindingToInstruction(input.type);
|
||||||
if (instruction) {
|
if (instruction) {
|
||||||
// TODO(chuckj): runtime: security context?
|
// TODO(chuckj): runtime: security context?
|
||||||
@ -1057,7 +974,3 @@ export function makeBindingParser(): BindingParser {
|
|||||||
new Parser(new Lexer()), DEFAULT_INTERPOLATION_CONFIG, new DomElementSchemaRegistry(), null,
|
new Parser(new Lexer()), DEFAULT_INTERPOLATION_CONFIG, new DomElementSchemaRegistry(), null,
|
||||||
[]);
|
[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isClassBinding(input: t.BoundAttribute): boolean {
|
|
||||||
return input.name == 'className' || input.name == 'class';
|
|
||||||
}
|
|
||||||
|
@ -6,12 +6,9 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {InitialStylingFlags} from '../../src/core';
|
|
||||||
import {MockDirectory, setup} from '../aot/test_util';
|
import {MockDirectory, setup} from '../aot/test_util';
|
||||||
|
|
||||||
import {compile, expectEmit} from './mock_compile';
|
import {compile, expectEmit} from './mock_compile';
|
||||||
|
|
||||||
|
|
||||||
/* These tests are codified version of the tests in compiler_canonical_spec.ts. Every
|
/* 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.
|
* 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):
|
// The template should look like this (where IDENT is a wild card for an identifier):
|
||||||
const template = `
|
const template = `
|
||||||
const $c1$ = ['title', 'Hello'];
|
const $c1$ = ['class', 'my-app', 'title', 'Hello'];
|
||||||
const $c2$ = ['my-app', ${InitialStylingFlags.VALUES_MODE}, 'my-app', true];
|
const $c2$ = ['cx', '20', 'cy', '30', 'r', '50'];
|
||||||
const $c3$ = ['cx', '20', 'cy', '30', 'r', '50'];
|
|
||||||
…
|
…
|
||||||
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
|
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
$r3$.ɵE(0, 'div', $c1$);
|
$r3$.ɵE(0, 'div', $c1$);
|
||||||
$r3$.ɵs((null as any), $c2$);
|
|
||||||
$r3$.ɵNS();
|
$r3$.ɵNS();
|
||||||
$r3$.ɵE(1, 'svg');
|
$r3$.ɵE(1, 'svg');
|
||||||
$r3$.ɵEe(2, 'circle', $c3$);
|
$r3$.ɵEe(2, 'circle', $c2$);
|
||||||
$r3$.ɵe();
|
$r3$.ɵe();
|
||||||
$r3$.ɵNH();
|
$r3$.ɵNH();
|
||||||
$r3$.ɵE(3, 'p');
|
$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):
|
// The template should look like this (where IDENT is a wild card for an identifier):
|
||||||
const template = `
|
const template = `
|
||||||
const $c1$ = ['title', 'Hello'];
|
const $c1$ = ['class', 'my-app', 'title', 'Hello'];
|
||||||
const $c2$ = ['my-app', ${InitialStylingFlags.VALUES_MODE}, 'my-app', true];
|
|
||||||
…
|
…
|
||||||
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
|
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
$r3$.ɵE(0, 'div', $c1$);
|
$r3$.ɵE(0, 'div', $c1$);
|
||||||
$r3$.ɵs((null as any), $c2$);
|
|
||||||
$r3$.ɵNM();
|
$r3$.ɵNM();
|
||||||
$r3$.ɵE(1, 'math');
|
$r3$.ɵE(1, 'math');
|
||||||
$r3$.ɵEe(2, 'infinity');
|
$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):
|
// The template should look like this (where IDENT is a wild card for an identifier):
|
||||||
const template = `
|
const template = `
|
||||||
const $c1$ = ['title', 'Hello'];
|
const $c1$ = ['class', 'my-app', 'title', 'Hello'];
|
||||||
const $c2$ = ['my-app', ${InitialStylingFlags.VALUES_MODE}, 'my-app', true];
|
|
||||||
…
|
…
|
||||||
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
|
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
$r3$.ɵE(0, 'div', $c1$);
|
$r3$.ɵE(0, 'div', $c1$);
|
||||||
$r3$.ɵs((null as any), $c2$);
|
|
||||||
$r3$.ɵT(1, 'Hello ');
|
$r3$.ɵT(1, 'Hello ');
|
||||||
$r3$.ɵE(2, 'b');
|
$r3$.ɵE(2, 'b');
|
||||||
$r3$.ɵT(3, 'World');
|
$r3$.ɵT(3, 'World');
|
||||||
@ -331,7 +322,6 @@ describe('compiler compliance', () => {
|
|||||||
const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }';
|
const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }';
|
||||||
const template = `
|
const template = `
|
||||||
const _c0 = ['background-color'];
|
const _c0 = ['background-color'];
|
||||||
const _c1 = ['error'];
|
|
||||||
class MyComponent {
|
class MyComponent {
|
||||||
static ngComponentDef = i0.ɵdefineComponent({type:MyComponent,selectors:[['my-component']],
|
static ngComponentDef = i0.ɵdefineComponent({type:MyComponent,selectors:[['my-component']],
|
||||||
factory:function MyComponent_Factory(){
|
factory:function MyComponent_Factory(){
|
||||||
@ -339,13 +329,13 @@ describe('compiler compliance', () => {
|
|||||||
},template:function MyComponent_Template(rf:number,ctx:any){
|
},template:function MyComponent_Template(rf:number,ctx:any){
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
$r3$.ɵE(0, 'div');
|
$r3$.ɵE(0, 'div');
|
||||||
$r3$.ɵs(_c0, _c1);
|
$r3$.ɵs(1, _c0);
|
||||||
$r3$.ɵe();
|
$r3$.ɵe();
|
||||||
}
|
}
|
||||||
if (rf & 2) {
|
if (rf & 2) {
|
||||||
$r3$.ɵsp(0, 0, ctx.color);
|
$r3$.ɵsp(1, 0, ctx.color);
|
||||||
$r3$.ɵcp(0, 0, ctx.error);
|
$r3$.ɵsa(1);
|
||||||
$r3$.ɵsa(0);
|
$r3$.ɵkn(0, 'error', $r3$.ɵb(ctx.error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -43,12 +43,12 @@ describe('compiler compliance: styling', () => {
|
|||||||
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) {
|
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
$r3$.ɵE(0, 'div');
|
$r3$.ɵE(0, 'div');
|
||||||
$r3$.ɵs();
|
$r3$.ɵs(1);
|
||||||
$r3$.ɵe();
|
$r3$.ɵe();
|
||||||
}
|
}
|
||||||
if (rf & 2) {
|
if (rf & 2) {
|
||||||
$r3$.ɵsm(0, $ctx$.myStyleExp);
|
$r3$.ɵsm(1, $ctx$.myStyleExp);
|
||||||
$r3$.ɵsa(0);
|
$r3$.ɵsa(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@ -57,7 +57,7 @@ describe('compiler compliance: styling', () => {
|
|||||||
expectEmit(result.source, template, 'Incorrect template');
|
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 = {
|
const files = {
|
||||||
app: {
|
app: {
|
||||||
@ -85,7 +85,7 @@ describe('compiler compliance: styling', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const template = `
|
const template = `
|
||||||
const _c0 = ['opacity','width','height',${InitialStylingFlags.VALUES_MODE},'opacity','1'];
|
const _c0 = ['opacity','width','height',${InitialStylingFlags.INITIAL_STYLES},'opacity','1'];
|
||||||
class MyComponent {
|
class MyComponent {
|
||||||
static ngComponentDef = i0.ɵdefineComponent({
|
static ngComponentDef = i0.ɵdefineComponent({
|
||||||
type: MyComponent,
|
type: MyComponent,
|
||||||
@ -96,14 +96,14 @@ describe('compiler compliance: styling', () => {
|
|||||||
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) {
|
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
$r3$.ɵE(0, 'div');
|
$r3$.ɵE(0, 'div');
|
||||||
$r3$.ɵs(_c0);
|
$r3$.ɵs(1, _c0);
|
||||||
$r3$.ɵe();
|
$r3$.ɵe();
|
||||||
}
|
}
|
||||||
if (rf & 2) {
|
if (rf & 2) {
|
||||||
$r3$.ɵsm(0, $ctx$.myStyleExp);
|
$r3$.ɵsm(1, $ctx$.myStyleExp);
|
||||||
$r3$.ɵsp(0, 1, $ctx$.myWidth);
|
$r3$.ɵsp(1, 1, $ctx$.myWidth);
|
||||||
$r3$.ɵsp(0, 2, $ctx$.myHeight);
|
$r3$.ɵsp(1, 2, $ctx$.myHeight);
|
||||||
$r3$.ɵsa(0);
|
$r3$.ɵsa(1);
|
||||||
$r3$.ɵa(0, 'style', $r3$.ɵb('border-width: 10px'));
|
$r3$.ɵa(0, 'style', $r3$.ɵb('border-width: 10px'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ describe('compiler compliance: styling', () => {
|
|||||||
template: \`<div [class]="myClassExp"></div>\`
|
template: \`<div [class]="myClassExp"></div>\`
|
||||||
})
|
})
|
||||||
export class MyComponent {
|
export class MyComponent {
|
||||||
myClassExp = {'foo':true}
|
myClassExp = [{color:'orange'}, {color:'green', duration:1000}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({declarations: [MyComponent]})
|
@NgModule({declarations: [MyComponent]})
|
||||||
@ -139,13 +139,10 @@ describe('compiler compliance: styling', () => {
|
|||||||
const template = `
|
const template = `
|
||||||
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) {
|
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
$r3$.ɵE(0, 'div');
|
$r3$.ɵEe(0, 'div');
|
||||||
$r3$.ɵs();
|
|
||||||
$r3$.ɵe();
|
|
||||||
}
|
}
|
||||||
if (rf & 2) {
|
if (rf & 2) {
|
||||||
$r3$.ɵsm(0,(null as any),$ctx$.myClassExp);
|
$r3$.ɵk(0,$r3$.ɵb($ctx$.myClassExp));
|
||||||
$r3$.ɵsa(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@ -153,112 +150,5 @@ describe('compiler compliance: styling', () => {
|
|||||||
const result = compile(files, angularFiles);
|
const result = compile(files, angularFiles);
|
||||||
expectEmit(result.source, template, 'Incorrect template');
|
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');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -39,7 +39,6 @@ export {
|
|||||||
T as ɵT,
|
T as ɵT,
|
||||||
V as ɵV,
|
V as ɵV,
|
||||||
Q as ɵQ,
|
Q as ɵQ,
|
||||||
Qr as ɵQr,
|
|
||||||
d as ɵd,
|
d as ɵd,
|
||||||
P as ɵP,
|
P as ɵP,
|
||||||
b as ɵb,
|
b as ɵb,
|
||||||
@ -70,7 +69,6 @@ export {
|
|||||||
cR as ɵcR,
|
cR as ɵcR,
|
||||||
cr as ɵcr,
|
cr as ɵcr,
|
||||||
qR as ɵqR,
|
qR as ɵqR,
|
||||||
ql as ɵql,
|
|
||||||
e as ɵe,
|
e as ɵe,
|
||||||
p as ɵp,
|
p as ɵp,
|
||||||
pD as ɵpD,
|
pD as ɵpD,
|
||||||
@ -80,7 +78,8 @@ export {
|
|||||||
sm as ɵsm,
|
sm as ɵsm,
|
||||||
sp as ɵsp,
|
sp as ɵsp,
|
||||||
sa as ɵsa,
|
sa as ɵsa,
|
||||||
cp as ɵcp,
|
k as ɵk,
|
||||||
|
kn as ɵkn,
|
||||||
t as ɵt,
|
t as ɵt,
|
||||||
v as ɵv,
|
v as ɵv,
|
||||||
st as ɵst,
|
st as ɵst,
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './di/metadata';
|
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 {forwardRef, resolveForwardRef, ForwardRefFn} from './di/forward_ref';
|
||||||
export {Injectable, InjectableDecorator, InjectableProvider} from './di/injectable';
|
export {Injectable, InjectableDecorator, InjectableProvider} from './di/injectable';
|
||||||
export {inject, InjectFlags, INJECTOR, Injector} from './di/injector';
|
export {inject, InjectFlags, INJECTOR, Injector} from './di/injector';
|
||||||
|
@ -342,12 +342,9 @@ export interface Directive {
|
|||||||
* View queries are set before the `ngAfterViewInit` callback is called.
|
* View queries are set before the `ngAfterViewInit` callback is called.
|
||||||
*
|
*
|
||||||
* @usageNotes
|
* @usageNotes
|
||||||
*
|
|
||||||
* ### Example
|
* ### Example
|
||||||
*
|
*
|
||||||
* The following example shows how queries are defined
|
* The followoing example (shows what??)
|
||||||
* and when their results are available in lifecycle hooks:
|
|
||||||
*
|
|
||||||
* ```
|
* ```
|
||||||
* @Component({
|
* @Component({
|
||||||
* selector: 'someDir',
|
* selector: 'someDir',
|
||||||
@ -478,7 +475,7 @@ export interface Directive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type of the Directive metadata.
|
* Type of the Component metadata.
|
||||||
*/
|
*/
|
||||||
export const Directive: DirectiveDecorator = makeDecorator(
|
export const Directive: DirectiveDecorator = makeDecorator(
|
||||||
'Directive', (dir: Directive = {}) => dir, undefined, undefined,
|
'Directive', (dir: Directive = {}) => dir, undefined, undefined,
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
* The below symbols are used for @Injectable and @NgModule compilation.
|
* 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 {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';
|
export {defineNgModule as ɵdefineNgModule} from './render3/definition';
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,7 +63,6 @@ export function assertComponentType(
|
|||||||
msg: string =
|
msg: string =
|
||||||
'Type passed in is not ComponentType, it does not have \'ngComponentDef\' property.') {
|
'Type passed in is not ComponentType, it does not have \'ngComponentDef\' property.') {
|
||||||
if (!actual.ngComponentDef) {
|
if (!actual.ngComponentDef) {
|
||||||
debugger;
|
|
||||||
throwError(msg);
|
throwError(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ export function defineComponent<T>(componentDefinition: {
|
|||||||
/**
|
/**
|
||||||
* Factory method used to create an instance of directive.
|
* 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.
|
* Static attributes to set on host element.
|
||||||
@ -120,14 +120,6 @@ export function defineComponent<T>(componentDefinition: {
|
|||||||
*/
|
*/
|
||||||
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
|
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.
|
* 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,
|
factory: componentDefinition.factory,
|
||||||
template: componentDefinition.template || null !,
|
template: componentDefinition.template || null !,
|
||||||
hostBindings: componentDefinition.hostBindings || null,
|
hostBindings: componentDefinition.hostBindings || null,
|
||||||
contentQueries: componentDefinition.contentQueries || null,
|
|
||||||
contentQueriesRefresh: componentDefinition.contentQueriesRefresh || null,
|
|
||||||
attributes: componentDefinition.attributes || null,
|
attributes: componentDefinition.attributes || null,
|
||||||
inputs: invertObject(componentDefinition.inputs, declaredInputs),
|
inputs: invertObject(componentDefinition.inputs, declaredInputs),
|
||||||
declaredInputs: declaredInputs,
|
declaredInputs: declaredInputs,
|
||||||
@ -458,14 +448,6 @@ export const defineDirective = defineComponent as any as<T>(directiveDefinition:
|
|||||||
*/
|
*/
|
||||||
hostBindings?: (directiveIndex: number, elementIndex: number) => void;
|
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.
|
* Defines the name that can be used in the template to assign this directive to a variable.
|
||||||
*
|
*
|
||||||
|
@ -19,7 +19,7 @@ import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_Vie
|
|||||||
import {Type} from '../type';
|
import {Type} from '../type';
|
||||||
|
|
||||||
import {assertDefined, assertGreaterThan, assertLessThan} from './assert';
|
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 {VIEWS} from './interfaces/container';
|
||||||
import {ComponentTemplate, DirectiveDefInternal, RenderFlags} from './interfaces/definition';
|
import {ComponentTemplate, DirectiveDefInternal, RenderFlags} from './interfaces/definition';
|
||||||
import {LInjector} from './interfaces/injector';
|
import {LInjector} from './interfaces/injector';
|
||||||
@ -378,7 +378,7 @@ export function getOrCreateInjectable<T>(
|
|||||||
// and matches the given token, return the directive instance.
|
// and matches the given token, return the directive instance.
|
||||||
const directiveDef = defs[i] as DirectiveDefInternal<any>;
|
const directiveDef = defs[i] as DirectiveDefInternal<any>;
|
||||||
if (directiveDef.type === token && directiveDef.diPublic) {
|
if (directiveDef.type === token && directiveDef.diPublic) {
|
||||||
return node.view[DIRECTIVES] ![i];
|
return getDirectiveInstance(node.view[DIRECTIVES] ![i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,13 +51,14 @@ export {
|
|||||||
|
|
||||||
element as Ee,
|
element as Ee,
|
||||||
elementAttribute as a,
|
elementAttribute as a,
|
||||||
elementClassProp as cp,
|
elementClass as k,
|
||||||
|
elementClassNamed as kn,
|
||||||
elementEnd as e,
|
elementEnd as e,
|
||||||
elementProperty as p,
|
elementProperty as p,
|
||||||
elementStart as E,
|
elementStart as E,
|
||||||
|
|
||||||
elementStyling as s,
|
elementStyling as s,
|
||||||
elementStylingMap as sm,
|
elementStyle as sm,
|
||||||
elementStyleProp as sp,
|
elementStyleProp as sp,
|
||||||
elementStylingApply as sa,
|
elementStylingApply as sa,
|
||||||
|
|
||||||
@ -115,11 +116,6 @@ export {
|
|||||||
query as Q,
|
query as Q,
|
||||||
queryRefresh as qR,
|
queryRefresh as qR,
|
||||||
} from './query';
|
} from './query';
|
||||||
export {
|
|
||||||
registerContentQuery as Qr,
|
|
||||||
loadQueryList as ql,
|
|
||||||
} from './instructions';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
pureFunction0 as f0,
|
pureFunction0 as f0,
|
||||||
pureFunction1 as f1,
|
pureFunction1 as f1,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user