Compare commits
64 Commits
5.0.0-beta
...
patch_sync
Author | SHA1 | Date | |
---|---|---|---|
f2f5286020 | |||
47220997e1 | |||
9ffa490d3f | |||
a80ecf6a77 | |||
7236095f6f | |||
d1c4a94bbf | |||
d76761bf01 | |||
c055dc7441 | |||
3dc4115c8b | |||
1f1caacbfd | |||
713d7c2360 | |||
079d884b6c | |||
a73389bc71 | |||
33d250ffaa | |||
409688fe17 | |||
ec56760c9b | |||
7ce9e06dab | |||
8ea6c56fe1 | |||
c0ba2b9ca7 | |||
fc7c858e62 | |||
55d151a82d | |||
5a1b9a34df | |||
70628112e8 | |||
29aa8b33df | |||
e25f05ae7c | |||
791c7efe29 | |||
2159342038 | |||
e228f2caa6 | |||
7522987a51 | |||
ff6a20d138 | |||
4eb1f91bee | |||
f53f7241a0 | |||
f2a2a6b478 | |||
d61b9021e0 | |||
499d05ddee | |||
b8a3736275 | |||
7d72d0eb9b | |||
7f4c964eef | |||
be9713c6e2 | |||
596e9f4e04 | |||
da14391cff | |||
60c803649b | |||
17b71ae382 | |||
a56468cf2f | |||
d7f42bfbe6 | |||
8f413268cf | |||
2a62d9f056 | |||
5f5a8e1da6 | |||
6e3498ca8e | |||
7bfd850493 | |||
ffb1553282 | |||
56a5b02d04 | |||
0cc77b4a69 | |||
a0ca01d580 | |||
2da45e629d | |||
845c68fdb3 | |||
21c44672c4 | |||
83713ddea4 | |||
3a500981ef | |||
0d45828460 | |||
43226cb93d | |||
2572bf508f | |||
6a1ab61cce | |||
27d5058e01 |
@ -41,7 +41,7 @@ jobs:
|
||||
- restore_cache:
|
||||
key: angular-{{ .Branch }}-{{ checksum "npm-shrinkwrap.json" }}
|
||||
|
||||
- run: bazel run @build_bazel_rules_typescript_node//:bin/npm install
|
||||
- run: bazel run @nodejs//:npm install
|
||||
- run: bazel build packages/...
|
||||
- save_cache:
|
||||
key: angular-{{ .Branch }}-{{ checksum "npm-shrinkwrap.json" }}
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,6 +5,7 @@ bazel-*
|
||||
e2e_test.*
|
||||
node_modules
|
||||
bower_components
|
||||
tools/gulp-tasks/cldr/cldr-data/
|
||||
|
||||
# Include when developing application packages.
|
||||
pubspec.lock
|
||||
|
@ -70,7 +70,6 @@ groups:
|
||||
- "tools/*"
|
||||
exclude:
|
||||
- "tools/public_api_guard/*"
|
||||
- "tools/ngc-wrapped/*"
|
||||
- "aio/*"
|
||||
users:
|
||||
- IgorMinar #primary
|
||||
@ -138,7 +137,7 @@ groups:
|
||||
files:
|
||||
- "packages/tsc-wrapped/*"
|
||||
- "packages/compiler-cli/*"
|
||||
- "tools/ngc-wrapped/*"
|
||||
- "packages/bazel/*"
|
||||
users:
|
||||
- alexeagle
|
||||
- chuckjaz
|
||||
|
22
WORKSPACE
22
WORKSPACE
@ -1,17 +1,21 @@
|
||||
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
|
||||
|
||||
git_repository(
|
||||
name = "build_bazel_rules_typescript",
|
||||
remote = "https://github.com/bazelbuild/rules_typescript.git",
|
||||
tag = "0.0.5",
|
||||
name = "build_bazel_rules_nodejs",
|
||||
remote = "https://github.com/bazelbuild/rules_nodejs.git",
|
||||
tag = "0.0.2",
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_typescript//:defs.bzl", "node_repositories")
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")
|
||||
|
||||
node_repositories(package_json = "//:package.json")
|
||||
node_repositories(package_json = ["//:package.json"])
|
||||
|
||||
git_repository(
|
||||
name = "build_bazel_rules_angular",
|
||||
remote = "https://github.com/bazelbuild/rules_angular.git",
|
||||
tag = "0.0.1",
|
||||
local_repository(
|
||||
name = "build_bazel_rules_typescript",
|
||||
path = "node_modules/@bazel/typescript",
|
||||
)
|
||||
|
||||
local_repository(
|
||||
name = "angular",
|
||||
path = "packages/bazel",
|
||||
)
|
@ -26,7 +26,7 @@ Here are the most important tasks you might need to use:
|
||||
* `yarn docs-lint` - check that the doc gen code follows our style rules.
|
||||
* `yarn docs-test` - run the unit tests for the doc generation code.
|
||||
|
||||
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally.
|
||||
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally. Add the option `-- --local` to use your local version of Angular contained in the "dist" folder.
|
||||
* `yarn boilerplate:remove` - remove all the boilerplate code that was added via `yarn boilerplate:add`.
|
||||
* `yarn generate-plunkers` - generate the plunker files that are used by the `live-example` tags in the docs.
|
||||
* `yarn generate-zips` - generate the zip files from the examples. Zip available via the `live-example` tags in the docs.
|
||||
@ -34,6 +34,7 @@ Here are the most important tasks you might need to use:
|
||||
* `yarn example-e2e` - run all e2e tests for examples
|
||||
- `yarn example-e2e -- --setup` - force webdriver update & other setup, then run tests
|
||||
- `yarn example-e2e -- --filter=foo` - limit e2e tests to those containing the word "foo"
|
||||
- `yarn example-e2e -- --setup --local` - run e2e tests with the local version of Angular contained in the "dist" folder
|
||||
|
||||
* `yarn build-ie-polyfills` - generates a js file of polyfills that can be loaded in Internet Explorer.
|
||||
|
||||
|
6
aio/content/examples/i18n/src/app/app.locale_data.ts
Normal file
6
aio/content/examples/i18n/src/app/app.locale_data.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// #docregion import-locale
|
||||
import { registerLocaleData } from '@angular/common';
|
||||
import localeFr from '@angular/common/i18n_data/locale_fr';
|
||||
|
||||
registerLocaleData(localeFr);
|
||||
// #enddocregion import-locale
|
@ -0,0 +1,7 @@
|
||||
// #docregion import-locale-extra
|
||||
import { registerLocaleData } from '@angular/common';
|
||||
import localeEnGB from '@angular/common/i18n_data/locale_en-GB';
|
||||
import localeEnGBExtra from '@angular/common/i18n_data/extra/locale_en-GB';
|
||||
|
||||
registerLocaleData(localeEnGB, localeEnGBExtra);
|
||||
// #enddocregion import-locale-extra
|
@ -28,7 +28,7 @@ describe('Pipes', function () {
|
||||
|
||||
it('should be able to toggle birthday formats', function () {
|
||||
let birthDayEle = element(by.css('hero-birthday2 > p'));
|
||||
expect(birthDayEle.getText()).toEqual(`The hero's birthday is 4/15/1988`);
|
||||
expect(birthDayEle.getText()).toEqual(`The hero's birthday is 4/15/88`);
|
||||
let buttonEle = element(by.cssContainingText('hero-birthday2 > button', 'Toggle Format'));
|
||||
expect(buttonEle.isDisplayed()).toBe(true);
|
||||
buttonEle.click().then(function() {
|
||||
|
@ -363,6 +363,10 @@ Those _npm_ commands are long and difficult to remember.
|
||||
|
||||
Add the following _npm_ convenience script to the `package.json` so you can compile and rollup in one command.
|
||||
|
||||
<code-example language="json">
|
||||
"build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup-config.js",
|
||||
</code-example>
|
||||
|
||||
Open a terminal window and try it.
|
||||
|
||||
<code-example language="none" class="code-shell">
|
||||
@ -526,10 +530,10 @@ Compiling with AOT presupposes certain supporting files, most of them discussed
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
Extend the `scripts` section of the `package.json` with these npm scripts:
|
||||
With the following npm script in the `scripts` section of the `package.json`, you can easily serve
|
||||
the AOT-compiled application:
|
||||
|
||||
<code-example language="json">
|
||||
"build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup-config.js",
|
||||
"serve:aot": "lite-server -c bs-config.aot.json",
|
||||
</code-example>
|
||||
|
||||
@ -545,7 +549,7 @@ Copy the AOT distribution files into the `/aot` folder with the node script:
|
||||
|
||||
</div>
|
||||
|
||||
Now AOT-compile the app and launch it with the `lite-server`:
|
||||
Now AOT-compile the app and launch:
|
||||
|
||||
<code-example language="none" class="code-shell">
|
||||
npm run build:aot && npm run serve:aot
|
||||
|
@ -347,7 +347,7 @@ Here are the features which may require additional polyfills:
|
||||
|
||||
<td>
|
||||
|
||||
[Date](api/common/DatePipe), [currency](api/common/CurrencyPipe), [decimal](api/common/DecimalPipe) and [percent](api/common/PercentPipe) pipes
|
||||
If you use the following deprecated i18n pipes: [date](api/common/DeprecatedDatePipe), [currency](api/common/DeprecatedCurrencyPipe), [decimal](api/common/DeprecatedDecimalPipe) and [percent](api/common/DeprecatedPercentPipe)
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
@ -126,7 +126,7 @@ http
|
||||
err => {
|
||||
console.log('Something went wrong!');
|
||||
}
|
||||
});
|
||||
);
|
||||
```
|
||||
|
||||
#### Getting error details
|
||||
@ -141,7 +141,7 @@ In both cases, you can look at the `HttpErrorResponse` to figure out what happen
|
||||
http
|
||||
.get<ItemsResponse>('/api/items')
|
||||
.subscribe(
|
||||
data => {...},
|
||||
data => {...},
|
||||
(err: HttpErrorResponse) => {
|
||||
if (err.error instanceof Error) {
|
||||
// A client-side or network error occurred. Handle it accordingly.
|
||||
@ -152,7 +152,7 @@ http
|
||||
console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
```
|
||||
|
||||
#### `.retry()`
|
||||
|
@ -40,6 +40,28 @@ You need to build and deploy a separate version of the application for each supp
|
||||
|
||||
{@a i18n-attribute}
|
||||
|
||||
## i18n pipes
|
||||
|
||||
Angular pipes can help you with internationalization: the `DatePipe`, `CurrencyPipe`, `DecimalPipe`
|
||||
and `PercentPipe` use locale data to format your data based on your `LOCALE_ID`.
|
||||
|
||||
By default Angular only contains locale data for the language `en-US`, if you set the value of
|
||||
`LOCALE_ID` to another locale, you will have to import new locale data for this language:
|
||||
|
||||
<code-example path="i18n/src/app/app.locale_data.ts" region="import-locale" title="src/app/app.locale_data.ts" linenums="false">
|
||||
</code-example>
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
Note that the files in `@angular/common/i18n_data` contain most of the locale data that you will
|
||||
need, but some advanced formatting options might only be available in the extra dataset that you can
|
||||
import from `@angular/common/i18n_data/extra`:
|
||||
|
||||
<code-example path="i18n/src/app/app.locale_data_extra.ts" region="import-locale-extra" title="src/app/app.locale_data_extra.ts" linenums="false">
|
||||
</code-example>
|
||||
|
||||
</div>
|
||||
|
||||
## Mark text with the _i18n_ attribute
|
||||
|
||||
The Angular `i18n` attribute is a marker for translatable content.
|
||||
|
@ -16,7 +16,7 @@ In the following example, the `@Component()` metadata object and the class const
|
||||
```typescript
|
||||
@Component({
|
||||
selector: 'app-typical',
|
||||
template: 'div>A typical component for {{data.name}}</div>
|
||||
template: '<div>A typical component for {{data.name}}</div>'
|
||||
)}
|
||||
export class TypicalComponent {
|
||||
@Input() data: TypicalData;
|
||||
|
@ -46,24 +46,6 @@ Inside the interpolation expression, you flow the component's `birthday` value t
|
||||
function on the right. All pipes work this way.
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
The `Date` and `Currency` pipes need the *ECMAScript Internationalization API*.
|
||||
Safari and other older browsers don't support it. You can add support with a polyfill.
|
||||
|
||||
|
||||
<code-example language="html">
|
||||
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en"></script>
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
## Built-in pipes
|
||||
|
@ -313,7 +313,7 @@ It's intended source is implicit.
|
||||
Angular sets `let-hero` to the value of the context's `$implicit` property
|
||||
which `NgFor` has initialized with the hero for the current iteration.
|
||||
|
||||
* The [API guide](api/common/NgFor "API: NgFor")
|
||||
* The [API guide](api/common/NgForOf "API: NgFor")
|
||||
describes additional `NgFor` directive properties and context properties.
|
||||
|
||||
These microsyntax mechanisms are available to you when you write your own structural directives.
|
||||
|
@ -1155,7 +1155,7 @@ other HTML elements, attributes, properties, and components.
|
||||
They are usually applied to elements as if they were HTML attributes, hence the name.
|
||||
|
||||
Many details are covered in the [_Attribute Directives_](guide/attribute-directives) guide.
|
||||
Many NgMdules such as the [`RouterModule`](guide/router "Routing and Navigation")
|
||||
Many NgModules such as the [`RouterModule`](guide/router "Routing and Navigation")
|
||||
and the [`FormsModule`](guide/forms "Forms") define their own attribute directives.
|
||||
This section is an introduction to the most commonly used attribute directives:
|
||||
|
||||
@ -1361,8 +1361,8 @@ to group elements when there is no suitable host element for the directive.
|
||||
_This_ section is an introduction to the common structural directives:
|
||||
|
||||
* [`NgIf`](guide/template-syntax#ngIf) - conditionally add or remove an element from the DOM
|
||||
* [`NgFor`](guide/template-syntax#ngFor) - repeat a template for each item in a list
|
||||
* [`NgSwitch`](guide/template-syntax#ngSwitch) - a set of directives that switch among alternative views
|
||||
* [NgForOf](guide/template-syntax#ngFor) - repeat a template for each item in a list
|
||||
|
||||
<hr/>
|
||||
|
||||
@ -1437,18 +1437,18 @@ described below.
|
||||
|
||||
{@a ngFor}
|
||||
|
||||
### NgFor
|
||||
### NgForOf
|
||||
|
||||
`NgFor` is a _repeater_ directive — a way to present a list of items.
|
||||
`NgForOf` is a _repeater_ directive — a way to present a list of items.
|
||||
You define a block of HTML that defines how a single item should be displayed.
|
||||
You tell Angular to use that block as a template for rendering each item in the list.
|
||||
|
||||
Here is an example of `NgFor` applied to a simple `<div>`:
|
||||
Here is an example of `NgForOf` applied to a simple `<div>`:
|
||||
|
||||
<code-example path="template-syntax/src/app/app.component.html" region="NgFor-1" title="src/app/app.component.html" linenums="false">
|
||||
</code-example>
|
||||
|
||||
You can also apply an `NgFor` to a component element, as in this example:
|
||||
You can also apply an `NgForOf` to a component element, as in this example:
|
||||
|
||||
<code-example path="template-syntax/src/app/app.component.html" region="NgFor-2" title="src/app/app.component.html" linenums="false">
|
||||
</code-example>
|
||||
@ -1485,10 +1485,10 @@ Learn about the _microsyntax_ in the [_Structural Directives_](guide/structural-
|
||||
### Template input variables
|
||||
|
||||
The `let` keyword before `hero` creates a _template input variable_ called `hero`.
|
||||
The `ngFor` directive iterates over the `heroes` array returned by the parent component's `heroes` property
|
||||
The `NgForOf` directive iterates over the `heroes` array returned by the parent component's `heroes` property
|
||||
and sets `hero` to the current item from the array during each iteration.
|
||||
|
||||
You reference the `hero` input variable within the `ngFor` host element
|
||||
You reference the `hero` input variable within the `NgForOf` host element
|
||||
(and within its descendents) to access the hero's properties.
|
||||
Here it is referenced first in an interpolation
|
||||
and then passed in a binding to the `hero` property of the `<hero-detail>` component.
|
||||
@ -1501,7 +1501,7 @@ Learn more about _template input variables_ in the
|
||||
|
||||
#### *ngFor with _index_
|
||||
|
||||
The `index` property of the `NgFor` directive context returns the zero-based index of the item in each iteration.
|
||||
The `index` property of the `NgForOf` directive context returns the zero-based index of the item in each iteration.
|
||||
You can capture the `index` in a template input variable and use it in the template.
|
||||
|
||||
The next example captures the `index` in a variable named `i` and displays it with the hero name like this.
|
||||
@ -1511,8 +1511,8 @@ The next example captures the `index` in a variable named `i` and displays it wi
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
Learn about the other `NgFor` context values such as `last`, `even`,
|
||||
and `odd` in the [NgFor API reference](api/common/NgFor).
|
||||
Learn about the other `NgForOf` context values such as `last`, `even`,
|
||||
and `odd` in the [NgForOf API reference](api/common/NgForOf).
|
||||
|
||||
</div>
|
||||
|
||||
@ -1520,7 +1520,7 @@ and `odd` in the [NgFor API reference](api/common/NgFor).
|
||||
|
||||
#### *ngFor with _trackBy_
|
||||
|
||||
The `NgFor` directive may perform poorly, especially with large lists.
|
||||
The `NgForOf` directive may perform poorly, especially with large lists.
|
||||
A small change to one item, an item removed, or an item added can trigger a cascade of DOM manipulations.
|
||||
|
||||
For example, re-querying the server could reset the list with all new hero objects.
|
||||
@ -1531,7 +1531,7 @@ But Angular sees only a fresh list of new object references.
|
||||
It has no choice but to tear down the old DOM elements and insert all new DOM elements.
|
||||
|
||||
Angular can avoid this churn with `trackBy`.
|
||||
Add a method to the component that returns the value `NgFor` _should_ track.
|
||||
Add a method to the component that returns the value `NgForOf` _should_ track.
|
||||
In this case, that value is the hero's `id`.
|
||||
|
||||
<code-example path="template-syntax/src/app/app.component.ts" region="trackByHeroes" title="src/app/app.component.ts" linenums="false">
|
||||
|
@ -10,13 +10,11 @@ Angular is a platform that makes it easy to build applications with the web. Ang
|
||||
<p class="card-footer">Angular in Action</p>
|
||||
</a>
|
||||
|
||||
<div class="docs-card">
|
||||
<a href="guide/quickstart" class="docs-card" title="Angular Quickstart">
|
||||
<section>Get Going with Angular</section>
|
||||
<p>Get going on your own environment with the Quickstart.</p>
|
||||
<p class="card-footer" >
|
||||
<a href="guide/quickstart" title="Angular Quickstart">Quickstart</a>
|
||||
</p>
|
||||
</div>
|
||||
<p class="card-footer">Quickstart</p>
|
||||
</a>
|
||||
|
||||
<a href="guide/architecture" class="docs-card" title="Angular Architecture">
|
||||
<section>Fundamentals</section>
|
||||
|
@ -37,6 +37,12 @@
|
||||
<td>London, United Kingdom</td>
|
||||
<td>November 07, 2017</td>
|
||||
</tr>
|
||||
<!-- ngAtlanta-->
|
||||
<tr>
|
||||
<th><a href="http://ng-atl.org/" title="ngAtlanta">ngAtlanta</a></th>
|
||||
<td>Atlanta, Georgia</td>
|
||||
<td>January 30, 2018</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</article>
|
||||
|
@ -202,7 +202,7 @@
|
||||
"url": "https://cli.angular.io"
|
||||
},
|
||||
"d1": {
|
||||
"desc": "A set of tslint rules for static code analysis of Angular TypeScript projects.",
|
||||
"desc": "Static analysis for Angular projects.",
|
||||
"logo": "",
|
||||
"rev": true,
|
||||
"title": "Codelyzer",
|
||||
@ -221,6 +221,13 @@
|
||||
"rev": true,
|
||||
"title": "Compodoc",
|
||||
"url": "https://github.com/compodoc/compodoc"
|
||||
},
|
||||
"ncg": {
|
||||
"desc": "Generate several types of CRUD apps complete with e2e testing using template-sets for Angular, Material Design, Bootstrap, Kendo UI, Ionic, ...",
|
||||
"logo": "https://avatars3.githubusercontent.com/u/27976684",
|
||||
"rev": true,
|
||||
"title": "NinjaCodeGen - Angular CRUD Generator",
|
||||
"url": "https://ninjaCodeGen.com"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -324,7 +331,7 @@
|
||||
"title": "Amexio - Angular Extensions",
|
||||
"url": "http://www.amexio.tech/",
|
||||
"logo": "http://www.amexio.org/amexio-logo.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +124,7 @@
|
||||
"unist-util-filter": "^0.2.1",
|
||||
"unist-util-source": "^1.0.1",
|
||||
"unist-util-visit": "^1.1.1",
|
||||
"unist-util-visit-parents": "^1.1.1",
|
||||
"vrsource-tslint-rules": "^4.0.1",
|
||||
"watchr": "^3.0.1",
|
||||
"yargs": "^7.0.2"
|
||||
|
@ -2,9 +2,13 @@
|
||||
|
||||
set -u -e -o pipefail
|
||||
|
||||
declare -A limitUncompressed
|
||||
limitUncompressed=(["inline"]=1600 ["main"]=525000 ["polyfills"]=38000)
|
||||
declare -A limitGzip7
|
||||
limitGzip7=(["inline"]=1000 ["main"]=127000 ["polyfills"]=12500)
|
||||
declare -A limitGzip9
|
||||
limitGzip9=(["inline"]=1000 ["main"]=127000 ["polyfills"]=12500)
|
||||
declare -A payloadLimits
|
||||
payloadLimits["aio", "uncompressed", "inline"]=1600
|
||||
payloadLimits["aio", "uncompressed", "main"]=525000
|
||||
payloadLimits["aio", "uncompressed", "polyfills"]=38000
|
||||
payloadLimits["aio", "gzip7", "inline"]=1000
|
||||
payloadLimits["aio", "gzip7", "main"]=127000
|
||||
payloadLimits["aio", "gzip7", "polyfills"]=12500
|
||||
payloadLimits["aio", "gzip9", "inline"]=1000
|
||||
payloadLimits["aio", "gzip9", "main"]=127000
|
||||
payloadLimits["aio", "gzip9", "polyfills"]=12500
|
||||
|
@ -4,79 +4,10 @@ set -eu -o pipefail
|
||||
|
||||
readonly thisDir=$(cd $(dirname $0); pwd)
|
||||
readonly parentDir=$(dirname $thisDir)
|
||||
readonly PROJECT_NAME="angular-payload-size"
|
||||
|
||||
# Track payload size functions
|
||||
source ../scripts/ci/payload-size.sh
|
||||
source ${thisDir}/_payload-limits.sh
|
||||
|
||||
failed=false
|
||||
payloadData=""
|
||||
for filename in dist/*.bundle.js; do
|
||||
size=$(stat -c%s "$filename")
|
||||
label=$(echo "$filename" | sed "s/.*\///" | sed "s/\..*//")
|
||||
payloadData="$payloadData\"uncompressed/$label\": $size, "
|
||||
trackPayloadSize "aio" "dist/*.bundle.js" true true
|
||||
|
||||
|
||||
gzip -7 $filename -c >> "${filename}7.gz"
|
||||
size7=$(stat -c%s "${filename}7.gz")
|
||||
payloadData="$payloadData\"gzip7/$label\": $size7, "
|
||||
|
||||
gzip -9 $filename -c >> "${filename}9.gz"
|
||||
size9=$(stat -c%s "${filename}9.gz")
|
||||
payloadData="$payloadData\"gzip9/$label\": $size9, "
|
||||
|
||||
if [[ $size -gt ${limitUncompressed[$label]} ]]; then
|
||||
failed=true
|
||||
echo "Uncompressed $label size is $size which is greater than ${limitUncompressed[$label]}"
|
||||
elif [[ $size7 -gt ${limitGzip7[$label]} ]]; then
|
||||
failed=true
|
||||
echo "Gzip7 $label size is $size7 which is greater than ${limitGzip7[$label]}"
|
||||
elif [[ $size9 -gt ${limitGzip9[$label]} ]]; then
|
||||
failed=true
|
||||
echo "Gzip9 $label size is $size9 which is greater than ${limitGzip9[$label]}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Add Timestamp
|
||||
timestamp=$(date +%s)
|
||||
payloadData="$payloadData\"timestamp\": $timestamp, "
|
||||
|
||||
# Add change source: application, dependencies, or 'application+dependencies'
|
||||
applicationChanged=false
|
||||
dependenciesChanged=false
|
||||
if [[ $(git diff --name-only $TRAVIS_COMMIT_RANGE $parentDir | grep -v aio/yarn.lock | grep -v content) ]]; then
|
||||
applicationChanged=true
|
||||
fi
|
||||
if [[ $(git diff --name-only $TRAVIS_COMMIT_RANGE $parentDir/yarn.lock) ]]; then
|
||||
dependenciesChanged=true
|
||||
fi
|
||||
|
||||
if $dependenciesChanged && $applicationChanged; then
|
||||
change='application+dependencies'
|
||||
elif $dependenciesChanged; then
|
||||
# only yarn.lock changed
|
||||
change='dependencies'
|
||||
elif $applicationChanged; then
|
||||
change='application'
|
||||
else
|
||||
# Nothing changed in aio/
|
||||
exit 0
|
||||
fi
|
||||
message=$(echo $TRAVIS_COMMIT_MESSAGE | sed 's/"/\\"/g' | sed 's/\\/\\\\/g')
|
||||
payloadData="$payloadData\"change\": \"$change\", \"message\": \"$message\""
|
||||
|
||||
payloadData="{${payloadData}}"
|
||||
|
||||
echo $payloadData
|
||||
|
||||
if [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then
|
||||
readonly safeBranchName=$(echo $TRAVIS_BRANCH | sed -e 's/\./_/g')
|
||||
readonly dbPath=/payload/aio/$safeBranchName/$TRAVIS_COMMIT
|
||||
|
||||
# WARNING: FIREBASE_TOKEN should NOT be printed.
|
||||
set +x
|
||||
firebase database:update --data "$payloadData" --project $PROJECT_NAME --confirm --token "$ANGULAR_PAYLOAD_FIREBASE_TOKEN" $dbPath
|
||||
fi
|
||||
|
||||
if [[ $failed = true ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
@ -310,13 +310,11 @@ describe('AppComponent', () => {
|
||||
expect(locationService.go).toHaveBeenCalledWith(versionWithUrl.url);
|
||||
});
|
||||
|
||||
// The current docs version should not have an href
|
||||
// This may change when we perfect our docs versioning approach
|
||||
it('should not navigate when change to a version without a url', () => {
|
||||
setupSelectorForTesting();
|
||||
const versionWithoutUrlIndex = component.docVersions.findIndex(v => !v.url);
|
||||
const versionWithoutUrl = component.docVersions[versionWithoutUrlIndex];
|
||||
selectElement.triggerEventHandler('change', { option: versionWithoutUrl, index: versionWithoutUrlIndex});
|
||||
const versionWithoutUrlIndex = component.docVersions.length;
|
||||
const versionWithoutUrl = component.docVersions[versionWithoutUrlIndex] = { title: 'foo', url: null };
|
||||
selectElement.triggerEventHandler('change', { option: versionWithoutUrl, index: versionWithoutUrlIndex });
|
||||
expect(locationService.go).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@ -794,6 +792,10 @@ describe('AppComponent', () => {
|
||||
createTestingModule('api', 'archive');
|
||||
initializeTest();
|
||||
expect(TestBed.get(LocationService).replace).not.toHaveBeenCalled();
|
||||
|
||||
createTestingModule('api/core/getPlatform', 'archive');
|
||||
initializeTest();
|
||||
expect(TestBed.get(LocationService).replace).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should redirect to `docs` if deployment mode is `next` and not at a docs page', () => {
|
||||
@ -824,6 +826,10 @@ describe('AppComponent', () => {
|
||||
createTestingModule('api', 'next');
|
||||
initializeTest();
|
||||
expect(TestBed.get(LocationService).replace).not.toHaveBeenCalled();
|
||||
|
||||
createTestingModule('api/core/getPlatform', 'next');
|
||||
initializeTest();
|
||||
expect(TestBed.get(LocationService).replace).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not redirect to `docs` if deployment mode is `stable` and not at a docs page', () => {
|
||||
@ -854,6 +860,10 @@ describe('AppComponent', () => {
|
||||
createTestingModule('api', 'stable');
|
||||
initializeTest();
|
||||
expect(TestBed.get(LocationService).replace).not.toHaveBeenCalled();
|
||||
|
||||
createTestingModule('api/core/getPlatform', 'stable');
|
||||
initializeTest();
|
||||
expect(TestBed.get(LocationService).replace).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -131,7 +131,7 @@ export class AppComponent implements OnInit {
|
||||
this.locationService.currentPath.subscribe(path => {
|
||||
// Redirect to docs if we are in not in stable mode and are not hitting a docs page
|
||||
// (i.e. we have arrived at a marketing page)
|
||||
if (this.deployment.mode !== 'stable' && !/^(docs$|api$|guide|tutorial)/.test(path)) {
|
||||
if (this.deployment.mode !== 'stable' && !/^(docs$|api|guide|tutorial)/.test(path)) {
|
||||
this.locationService.replace('docs');
|
||||
}
|
||||
if (path === this.currentPath) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
const visit = require('unist-util-visit');
|
||||
const visit = require('unist-util-visit-parents');
|
||||
const is = require('hast-util-is-element');
|
||||
const textContent = require('hast-util-to-string');
|
||||
|
||||
@ -17,8 +17,8 @@ module.exports = function autoLinkCode(getDocFromAlias) {
|
||||
|
||||
function autoLinkCodeImpl() {
|
||||
return (ast) => {
|
||||
visit(ast, node => {
|
||||
if (is(node, 'code')) {
|
||||
visit(ast, (node, ancestors) => {
|
||||
if (is(node, 'code') && ancestors.every(ancestor => !is(ancestor, 'a'))) {
|
||||
const docs = getDocFromAlias(textContent(node));
|
||||
if (docs.length === 1 && autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1) {
|
||||
const link = {
|
||||
|
@ -36,4 +36,11 @@ describe('autoLinkCode post-processor', () => {
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>MyClass</code>');
|
||||
});
|
||||
|
||||
it('should ignore code items that are already inside a link', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<a href="..."><div><code>MyClass</code></div></a>' };
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<a href="..."><div><code>MyClass</code></div></a>');
|
||||
});
|
||||
});
|
||||
|
@ -7789,6 +7789,10 @@ unist-util-stringify-position@^1.0.0:
|
||||
dependencies:
|
||||
has "^1.0.1"
|
||||
|
||||
unist-util-visit-parents@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-1.1.1.tgz#7d3f56b5b039a3c6e2d16e51cc093f10e4755342"
|
||||
|
||||
unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.1.1.tgz#e917a3b137658b335cb4420c7da2e74d928e4e94"
|
||||
|
36
build.sh
36
build.sh
@ -86,7 +86,7 @@ done
|
||||
#######################################
|
||||
isIgnoredDirectory() {
|
||||
name=$(basename ${1})
|
||||
if [[ -f "${1}" || "${name}" == "src" || "${name}" == "test" || "${name}" == "integrationtest" ]]; then
|
||||
if [[ -f "${1}" || "${name}" == "src" || "${name}" == "test" || "${name}" == "integrationtest" || "${name}" == "i18n_data" ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
@ -327,6 +327,16 @@ mapSources() {
|
||||
fi
|
||||
}
|
||||
|
||||
updateVersionReferences() {
|
||||
NPM_DIR="$1"
|
||||
(
|
||||
echo "====== VERSION: Updating version references in ${NPM_DIR}"
|
||||
cd ${NPM_DIR}
|
||||
echo "====== EXECUTE: perl -p -i -e \"s/0\.0\.0\-PLACEHOLDER/${VERSION}/g\" $""(grep -ril 0\.0\.0\-PLACEHOLDER .)"
|
||||
perl -p -i -e "s/0\.0\.0\-PLACEHOLDER/${VERSION}/g" $(grep -ril 0\.0\.0\-PLACEHOLDER .) < /dev/null 2> /dev/null
|
||||
)
|
||||
}
|
||||
|
||||
VERSION="${VERSION_PREFIX}${VERSION_SUFFIX}"
|
||||
echo "====== BUILDING: Version ${VERSION}"
|
||||
|
||||
@ -419,11 +429,13 @@ if [[ ${BUILD_TOOLS} == true || ${BUILD_ALL} == true ]]; then
|
||||
$(npm bin)/tsc -p packages/tsc-wrapped/tsconfig-build.json
|
||||
cp ./packages/tsc-wrapped/package.json ./dist/packages-dist/tsc-wrapped
|
||||
cp ./packages/tsc-wrapped/README.md ./dist/packages-dist/tsc-wrapped
|
||||
(
|
||||
cd dist/packages-dist/tsc-wrapped
|
||||
echo "====== EXECUTE: perl -p -i -e \"s/0\.0\.0\-PLACEHOLDER/${VERSION}/g\" $""(grep -ril 0\.0\.0\-PLACEHOLDER .)"
|
||||
perl -p -i -e "s/0\.0\.0\-PLACEHOLDER/${VERSION}/g" $(grep -ril 0\.0\.0\-PLACEHOLDER .) < /dev/null 2> /dev/null
|
||||
)
|
||||
updateVersionReferences dist/packages-dist/tsc-wrapped
|
||||
|
||||
rsync -a packages/bazel/ ./dist/packages-dist/bazel
|
||||
# Remove BEGIN-INTERNAL...END-INTERAL blocks
|
||||
# https://stackoverflow.com/questions/24175271/how-can-i-match-multi-line-patterns-in-the-command-line-with-perl-style-regex
|
||||
perl -0777 -n -i -e "s/(?m)^.*BEGIN-INTERNAL[\w\W]*END-INTERNAL.*\n//g; print" $(grep -ril BEGIN-INTERNAL dist/packages-dist/bazel) < /dev/null 2> /dev/null
|
||||
updateVersionReferences dist/packages-dist/bazel
|
||||
fi
|
||||
|
||||
for PACKAGE in ${PACKAGES[@]}
|
||||
@ -470,6 +482,11 @@ do
|
||||
minify ${BUNDLES_DIR}
|
||||
|
||||
) 2>&1 | grep -v "as external dependency"
|
||||
|
||||
if [[ ${PACKAGE} == "common" ]]; then
|
||||
echo "====== Copy i18n locale data"
|
||||
rsync -a --exclude=*.d.ts --exclude=*.metadata.json ${OUT_DIR}/i18n_data/ ${NPM_DIR}/i18n_data
|
||||
fi
|
||||
else
|
||||
echo "====== Copy ${PACKAGE} node tool"
|
||||
rsync -a ${OUT_DIR}/ ${NPM_DIR}
|
||||
@ -484,12 +501,7 @@ do
|
||||
|
||||
|
||||
if [[ -d ${NPM_DIR} ]]; then
|
||||
(
|
||||
echo "====== VERSION: Updating version references"
|
||||
cd ${NPM_DIR}
|
||||
echo "====== EXECUTE: perl -p -i -e \"s/0\.0\.0\-PLACEHOLDER/${VERSION}/g\" $""(grep -ril 0\.0\.0\-PLACEHOLDER .)"
|
||||
perl -p -i -e "s/0\.0\.0\-PLACEHOLDER/${VERSION}/g" $(grep -ril 0\.0\.0\-PLACEHOLDER .) < /dev/null 2> /dev/null
|
||||
)
|
||||
updateVersionReferences ${NPM_DIR}
|
||||
fi
|
||||
|
||||
travisFoldEnd "build package: ${PACKAGE}"
|
||||
|
@ -42,3 +42,5 @@ gulp.task('serve', loadTask('serve', 'default'));
|
||||
gulp.task('serve-examples', loadTask('serve', 'examples'));
|
||||
gulp.task('changelog', loadTask('changelog'));
|
||||
gulp.task('check-env', () => {/* this is a noop because the env test ran already above */});
|
||||
gulp.task('cldr:extract', loadTask('cldr', 'extract'));
|
||||
gulp.task('cldr:download', loadTask('cldr', 'download'));
|
||||
|
5
integration/.gitignore
vendored
5
integration/.gitignore
vendored
@ -1,10 +1,13 @@
|
||||
built/
|
||||
dist/
|
||||
vendor/
|
||||
yarn.lock
|
||||
.ng-cli/
|
||||
cli-*/**
|
||||
*/src/*.d.ts
|
||||
*/src/*.js
|
||||
**/*.ngfactory.ts
|
||||
**/*.ngsummary.json
|
||||
**/*.ngsummary.ts
|
||||
*/yarn*
|
||||
*/.yarn_local_cache*
|
||||
**/.yarn_local_cache*
|
||||
|
19
integration/_payload-limits.sh
Normal file
19
integration/_payload-limits.sh
Normal file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -u -e -o pipefail
|
||||
|
||||
declare -A payloadLimits
|
||||
payloadLimits["hello_world__closure", "uncompressed", "bundle"]=106000
|
||||
payloadLimits["hello_world__closure", "gzip7", "bundle"]=35000
|
||||
payloadLimits["hello_world__closure", "gzip9", "bundle"]=35000
|
||||
|
||||
payloadLimits["cli-hello-world", "uncompressed", "inline"]=1500
|
||||
payloadLimits["cli-hello-world", "uncompressed", "main"]=183000
|
||||
payloadLimits["cli-hello-world", "uncompressed", "polyfills"]=63000
|
||||
payloadLimits["cli-hello-world", "gzip7", "inline"]=900
|
||||
payloadLimits["cli-hello-world", "gzip7", "main"]=48000
|
||||
payloadLimits["cli-hello-world", "gzip7", "polyfills"]=21000
|
||||
payloadLimits["cli-hello-world", "gzip9", "inline"]=900
|
||||
payloadLimits["cli-hello-world", "gzip9", "main"]=48000
|
||||
payloadLimits["cli-hello-world", "gzip9", "polyfills"]=21000
|
||||
|
10
integration/bazel/BUILD.bazel
Normal file
10
integration/bazel/BUILD.bazel
Normal file
@ -0,0 +1,10 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
filegroup(
|
||||
name = "node_modules",
|
||||
srcs = glob([
|
||||
"node_modules/**/*.js",
|
||||
"node_modules/**/*.d.ts",
|
||||
"node_modules/**/*.json",
|
||||
])
|
||||
)
|
30
integration/bazel/WORKSPACE
Normal file
30
integration/bazel/WORKSPACE
Normal file
@ -0,0 +1,30 @@
|
||||
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
|
||||
|
||||
git_repository(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
remote = "https://github.com/bazelbuild/rules_nodejs.git",
|
||||
tag = "0.0.2",
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")
|
||||
node_repositories(package_json = ["//:package.json"])
|
||||
|
||||
local_repository(
|
||||
name = "build_bazel_rules_typescript",
|
||||
path = "node_modules/@bazel/typescript",
|
||||
)
|
||||
|
||||
local_repository(
|
||||
name = "angular",
|
||||
path = "node_modules/@angular/bazel",
|
||||
)
|
||||
|
||||
git_repository(
|
||||
name = "io_bazel_rules_sass",
|
||||
remote = "https://github.com/bazelbuild/rules_sass.git",
|
||||
tag = "0.0.2",
|
||||
)
|
||||
|
||||
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_repositories")
|
||||
|
||||
sass_repositories()
|
23
integration/bazel/angular.tsconfig.json
Normal file
23
integration/bazel/angular.tsconfig.json
Normal file
@ -0,0 +1,23 @@
|
||||
// WORKAROUND https://github.com/angular/angular/issues/18810
|
||||
// This file is required to run ngc on angular libraries, to write files like
|
||||
// node_modules/@angular/core/core.ngsummary.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2015"
|
||||
],
|
||||
"experimentalDecorators": true,
|
||||
"types": []
|
||||
},
|
||||
"include": [
|
||||
"node_modules/@angular/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules/@angular/bazel/**",
|
||||
"node_modules/@angular/compiler-cli/**",
|
||||
// Workaround bug introduced by 079d884
|
||||
"node_modules/@angular/common/i18n_data*",
|
||||
"node_modules/@angular/tsc-wrapped/**"
|
||||
]
|
||||
}
|
25
integration/bazel/package.json
Normal file
25
integration/bazel/package.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "angular-bazel",
|
||||
"description": "example and integration test for building Angular apps with Bazel",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@angular/animations": "file:../../dist/packages-dist/animations",
|
||||
"@angular/common": "file:../../dist/packages-dist/common",
|
||||
"@angular/compiler": "file:../../dist/packages-dist/compiler",
|
||||
"@angular/core": "file:../../dist/packages-dist/core",
|
||||
"@angular/platform-browser": "file:../../dist/packages-dist/platform-browser",
|
||||
"rxjs": "5.3.1",
|
||||
"zone.js": "0.8.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/bazel": "file:../../dist/packages-dist/bazel",
|
||||
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
|
||||
"@bazel/typescript": "0.0.7",
|
||||
"typescript": "~2.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "ngc -p angular.tsconfig.json",
|
||||
"test": "bazel build ..."
|
||||
}
|
||||
}
|
11
integration/bazel/src/BUILD.bazel
Normal file
11
integration/bazel/src/BUILD.bazel
Normal file
@ -0,0 +1,11 @@
|
||||
load("@angular//:index.bzl", "ng_module")
|
||||
|
||||
# Allow targets under sub-packages to reference the tsconfig.json file
|
||||
exports_files(["tsconfig.json"])
|
||||
|
||||
ng_module(
|
||||
name = "app",
|
||||
srcs = ["app.module.ts"],
|
||||
deps = ["//src/hello-world"],
|
||||
tsconfig = ":tsconfig.json",
|
||||
)
|
9
integration/bazel/src/app.module.ts
Normal file
9
integration/bazel/src/app.module.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import {HelloWorldModule} from './hello-world/hello-world.module';
|
||||
|
||||
import {NgModule} from '@angular/core';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule, HelloWorldModule]
|
||||
})
|
||||
export class AppModule {}
|
19
integration/bazel/src/hello-world/BUILD.bazel
Normal file
19
integration/bazel/src/hello-world/BUILD.bazel
Normal file
@ -0,0 +1,19 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
load("@angular//:index.bzl", "ng_module")
|
||||
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_binary")
|
||||
|
||||
sass_binary(
|
||||
name = "styles",
|
||||
src = "hello-world.component.scss",
|
||||
deps = [
|
||||
"//src/shared:colors",
|
||||
"//src/shared:fonts",
|
||||
],
|
||||
)
|
||||
|
||||
ng_module(
|
||||
name = "hello-world",
|
||||
srcs = glob(["*.ts"]),
|
||||
tsconfig = "//src:tsconfig.json",
|
||||
assets = [":styles"],
|
||||
)
|
12
integration/bazel/src/hello-world/hello-world.component.scss
Normal file
12
integration/bazel/src/hello-world/hello-world.component.scss
Normal file
@ -0,0 +1,12 @@
|
||||
@import "src/shared/fonts";
|
||||
@import "src/shared/colors";
|
||||
|
||||
html {
|
||||
body {
|
||||
font-family: $default-font-stack;
|
||||
h1 {
|
||||
font-family: $modern-font-stack;
|
||||
color: $example-red;
|
||||
}
|
||||
}
|
||||
}
|
15
integration/bazel/src/hello-world/hello-world.component.ts
Normal file
15
integration/bazel/src/hello-world/hello-world.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
import {Component, NgModule} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'hello-world-app',
|
||||
template: `
|
||||
<div>Hello {{ name }}!</div>
|
||||
<input type="text" [value]="name" (input)="name = $event.target.value"/>
|
||||
`,
|
||||
// TODO: might be better to point to .scss so this looks valid at design-time
|
||||
styleUrls: ['./styles.css']
|
||||
})
|
||||
export class HelloWorldComponent {
|
||||
name: string = 'world';
|
||||
}
|
8
integration/bazel/src/hello-world/hello-world.module.ts
Normal file
8
integration/bazel/src/hello-world/hello-world.module.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import {HelloWorldComponent} from './hello-world.component';
|
||||
import {NgModule} from '@angular/core';
|
||||
|
||||
@NgModule({
|
||||
declarations: [HelloWorldComponent],
|
||||
bootstrap: [HelloWorldComponent],
|
||||
})
|
||||
export class HelloWorldModule {}
|
13
integration/bazel/src/shared/BUILD.bazel
Normal file
13
integration/bazel/src/shared/BUILD.bazel
Normal file
@ -0,0 +1,13 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_library")
|
||||
|
||||
sass_library(
|
||||
name = "colors",
|
||||
srcs = ["_colors.scss"],
|
||||
)
|
||||
|
||||
sass_library(
|
||||
name = "fonts",
|
||||
srcs = ["_fonts.scss"],
|
||||
)
|
2
integration/bazel/src/shared/_colors.scss
Normal file
2
integration/bazel/src/shared/_colors.scss
Normal file
@ -0,0 +1,2 @@
|
||||
$example-blue: #0000ff;
|
||||
$example-red: #ff0000;
|
2
integration/bazel/src/shared/_fonts.scss
Normal file
2
integration/bazel/src/shared/_fonts.scss
Normal file
@ -0,0 +1,2 @@
|
||||
$default-font-stack: Cambria, "Hoefler Text", Utopia, "Liberation Serif", "Nimbus Roman No9 L Regular", Times, "Times New Roman", serif;
|
||||
$modern-font-stack: Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Bitstream Vera Serif", "Liberation Serif", Georgia, serif;
|
12
integration/bazel/src/tsconfig.json
Normal file
12
integration/bazel/src/tsconfig.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"lib": [
|
||||
"dom",
|
||||
"es5",
|
||||
"es2015.collection",
|
||||
"es2015.iterable",
|
||||
"es2015.promise"
|
||||
]
|
||||
}
|
||||
}
|
70
integration/ng-cli-create.sh
Executable file
70
integration/ng-cli-create.sh
Executable file
@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e -o pipefail
|
||||
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
echo "Angular cli integration create project"
|
||||
echo
|
||||
echo "./ng-cli-create.sh [project-name]"
|
||||
echo
|
||||
else
|
||||
TEMP=`dirname $0`
|
||||
INTEGRATION_DIR=`(cd $TEMP; pwd)`
|
||||
PROJECT=$1
|
||||
PROJECT_DIR=$INTEGRATION_DIR/$PROJECT
|
||||
NG=$INTEGRATION_DIR/.ng-cli/node_modules/.bin/ng
|
||||
(
|
||||
echo "==================="
|
||||
echo Creating $PROJECT...
|
||||
echo "==================="
|
||||
cd $INTEGRATION_DIR
|
||||
rm -rf $PROJECT
|
||||
$NG set --global packageManager=yarn
|
||||
$NG new $PROJECT --skip-install
|
||||
echo "==================="
|
||||
echo $PROJECT created
|
||||
echo "==================="
|
||||
)
|
||||
|
||||
|
||||
# By default `ng new` creates a package.json which uses @angular/* from NPM.
|
||||
# Instead we want to use them from the current build so we overwrite theme here.
|
||||
(
|
||||
echo "==================="
|
||||
echo Updating $PROJECT bundles
|
||||
echo "==================="
|
||||
cd $PROJECT_DIR
|
||||
|
||||
sed -i -E 's/ng build/ng build --prod --build-optimizer/g' package.json
|
||||
sed -i -E 's/ng test/ng test --single-run/g' package.json
|
||||
# workaround for https://github.com/angular/angular-cli/issues/7401
|
||||
sed -i -E 's/"@angular\/cli\"\: \".*\"/"@angular\/cli": "https:\/\/github.com\/angular\/cli-builds"/g' package.json
|
||||
|
||||
yarn add \
|
||||
file:../../dist/packages-dist/compiler-cli \
|
||||
file:../../dist/packages-dist/language-service \
|
||||
--save-dev --skip-integrity-check --emoji
|
||||
|
||||
yarn add \
|
||||
file:../../dist/packages-dist/core \
|
||||
file:../../dist/packages-dist/common \
|
||||
file:../../dist/packages-dist/forms \
|
||||
file:../../dist/packages-dist/http \
|
||||
--save --skip-integrity-check --emoji
|
||||
|
||||
# yarn bug: can not install all of them in a single command and it has to be broken into separate invocations.
|
||||
yarn add \
|
||||
file:../../dist/packages-dist/animations \
|
||||
file:../../dist/packages-dist/compiler \
|
||||
file:../../dist/packages-dist/platform-browser \
|
||||
file:../../dist/packages-dist/platform-browser-dynamic \
|
||||
--save --skip-integrity-check --emoji
|
||||
|
||||
yarn install --emoji
|
||||
|
||||
echo "==================="
|
||||
echo $PROJECT created succesfully
|
||||
echo "==================="
|
||||
)
|
||||
fi
|
@ -4,6 +4,10 @@ set -e -o pipefail
|
||||
|
||||
cd `dirname $0`
|
||||
|
||||
# Track payload size functions
|
||||
source ../scripts/ci/payload-size.sh
|
||||
source ./_payload-limits.sh
|
||||
|
||||
# Workaround https://github.com/yarnpkg/yarn/issues/2165
|
||||
# Yarn will cache file://dist URIs and not update Angular code
|
||||
readonly cache=.yarn_local_cache
|
||||
@ -14,6 +18,17 @@ rm_cache
|
||||
mkdir $cache
|
||||
trap rm_cache EXIT
|
||||
|
||||
# We need to install `ng` but don't want to do it globally so we plate it into `.ng-cli` folder.
|
||||
# This check prevents constant re-installing.
|
||||
if [ ! -d ".ng-cli" ]; then
|
||||
(
|
||||
mkdir -p .ng-cli
|
||||
cd .ng-cli
|
||||
yarn add https://github.com/angular/cli-builds --cache-folder ../$cache
|
||||
)
|
||||
fi
|
||||
./ng-cli-create.sh cli-hello-world
|
||||
|
||||
for testDir in $(ls | grep -v node_modules) ; do
|
||||
[[ -d "$testDir" ]] || continue
|
||||
echo "#################################"
|
||||
@ -23,7 +38,17 @@ for testDir in $(ls | grep -v node_modules) ; do
|
||||
cd $testDir
|
||||
# Workaround for https://github.com/yarnpkg/yarn/issues/2256
|
||||
rm -f yarn.lock
|
||||
rm -rf dist
|
||||
yarn install --cache-folder ../$cache
|
||||
yarn test || exit 1
|
||||
# Track payload size for cli-hello-world and hello_world__closure
|
||||
if [[ $testDir == cli-hello-world ]] || [[ $testDir == hello_world__closure ]]; then
|
||||
if [[ $testDir == cli-hello-world ]]; then
|
||||
yarn build
|
||||
fi
|
||||
trackPayloadSize "$testDir" "dist/*.js" true false
|
||||
fi
|
||||
)
|
||||
done
|
||||
|
||||
trackPayloadSize "umd" "../dist/packages-dist/*/bundles/*.umd.min.js" false false
|
||||
|
@ -1,41 +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 compiler from '@angular/compiler';
|
||||
import * as compilerTesting from '@angular/compiler/testing';
|
||||
import * as core from '@angular/core';
|
||||
import * as coreTesting from '@angular/core/testing';
|
||||
import * as forms from '@angular/forms';
|
||||
import * as http from '@angular/http';
|
||||
import * as httpTesting from '@angular/http/testing';
|
||||
import * as platformBrowserDynamic from '@angular/platform-browser-dynamic';
|
||||
import * as platformBrowser from '@angular/platform-browser';
|
||||
import * as platformBrowserTesting from '@angular/platform-browser/testing';
|
||||
import * as platformServer from '@angular/platform-server';
|
||||
import * as platformServerTesting from '@angular/platform-server/testing';
|
||||
import * as router from '@angular/router';
|
||||
import * as routerTesting from '@angular/router/testing';
|
||||
import * as upgrade from '@angular/upgrade';
|
||||
|
||||
export default {
|
||||
compiler,
|
||||
compilerTesting,
|
||||
core,
|
||||
coreTesting,
|
||||
forms,
|
||||
http,
|
||||
httpTesting,
|
||||
platformBrowser,
|
||||
platformBrowserTesting,
|
||||
platformBrowserDynamic,
|
||||
platformServer,
|
||||
platformServerTesting,
|
||||
router,
|
||||
routerTesting,
|
||||
upgrade
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "angular-integration",
|
||||
"description": "Assert that users with TypeScript 2.1 can type-check an Angular application",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@angular/animations": "file:../../dist/packages-dist/animations",
|
||||
"@angular/common": "file:../../dist/packages-dist/common",
|
||||
"@angular/compiler": "file:../../dist/packages-dist/compiler",
|
||||
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
|
||||
"@angular/core": "file:../../dist/packages-dist/core",
|
||||
"@angular/forms": "file:../../dist/packages-dist/forms",
|
||||
"@angular/http": "file:../../dist/packages-dist/http",
|
||||
"@angular/platform-browser": "file:../../dist/packages-dist/platform-browser",
|
||||
"@angular/platform-browser-dynamic": "file:../../dist/packages-dist/platform-browser-dynamic",
|
||||
"@angular/platform-server": "file:../../dist/packages-dist/platform-server",
|
||||
"@angular/router": "file:../../dist/packages-dist/router",
|
||||
"@angular/tsc-wrapped": "file:../../dist/packages-dist/tsc-wrapped",
|
||||
"@angular/upgrade": "file:../../dist/packages-dist/upgrade",
|
||||
"@types/jasmine": "2.5.41",
|
||||
"rxjs": "file:../../node_modules/rxjs",
|
||||
"typescript": "2.1.6",
|
||||
"zone.js": "0.7.6"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tsc"
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "../../dist/typing-test/",
|
||||
"rootDir": ".",
|
||||
"target": "es5",
|
||||
"lib": ["es5", "dom", "es2015.collection", "es2015.iterable", "es2015.promise"],
|
||||
"types": [],
|
||||
"strictNullChecks": true
|
||||
},
|
||||
"files": [
|
||||
"include-all.ts",
|
||||
"node_modules/@types/jasmine/index.d.ts"
|
||||
]
|
||||
}
|
@ -47,7 +47,8 @@ module.exports = function(config) {
|
||||
pattern: 'packages/platform-browser/test/browser/static_assets/**',
|
||||
included: false,
|
||||
watched: false,
|
||||
}
|
||||
},
|
||||
{pattern: 'packages/common/i18n/**', included: false, watched: false, served: true},
|
||||
],
|
||||
|
||||
exclude: [
|
||||
|
@ -1,7 +1,18 @@
|
||||
{
|
||||
"name": "angular-srcs",
|
||||
"version": "5.0.0-beta.0",
|
||||
"version": "5.0.0-beta.4",
|
||||
"dependencies": {
|
||||
"@bazel/typescript": {
|
||||
"version": "0.0.7",
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "7.0.18"
|
||||
},
|
||||
"tsickle": {
|
||||
"version": "0.23.6"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/angularjs": {
|
||||
"version": "1.5.13-alpha"
|
||||
},
|
||||
@ -1542,7 +1553,7 @@
|
||||
}
|
||||
},
|
||||
"cldr": {
|
||||
"version": "3.5.2",
|
||||
"version": "4.5.0",
|
||||
"dependencies": {
|
||||
"uglify-js": {
|
||||
"version": "1.3.3"
|
||||
@ -1552,6 +1563,59 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"cldr-data-downloader": {
|
||||
"version": "0.3.2",
|
||||
"dependencies": {
|
||||
"adm-zip": {
|
||||
"version": "0.4.4"
|
||||
},
|
||||
"async": {
|
||||
"version": "2.5.0"
|
||||
},
|
||||
"bl": {
|
||||
"version": "1.1.2"
|
||||
},
|
||||
"form-data": {
|
||||
"version": "1.0.1"
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.4"
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.27.0"
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.15"
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8"
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.0"
|
||||
},
|
||||
"q": {
|
||||
"version": "1.0.1"
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.2.3"
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.0.6"
|
||||
},
|
||||
"request": {
|
||||
"version": "2.74.0"
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.3.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"cldrjs": {
|
||||
"version": "0.5.0"
|
||||
},
|
||||
"cli-boxes": {
|
||||
"version": "1.0.0"
|
||||
},
|
||||
@ -1660,6 +1724,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"config-chain": {
|
||||
"version": "1.1.11"
|
||||
},
|
||||
"configstore": {
|
||||
"version": "2.1.0",
|
||||
"dependencies": {
|
||||
@ -3717,13 +3784,10 @@
|
||||
"version": "0.3.0"
|
||||
},
|
||||
"memoizeasync": {
|
||||
"version": "0.8.0",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "2.5.0"
|
||||
},
|
||||
"passerror": {
|
||||
"version": "0.0.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3876,6 +3940,14 @@
|
||||
"normalize-path": {
|
||||
"version": "2.0.1"
|
||||
},
|
||||
"npmconf": {
|
||||
"version": "2.0.9",
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "4.3.6"
|
||||
}
|
||||
}
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.0.2"
|
||||
},
|
||||
@ -4014,7 +4086,7 @@
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"passerror": {
|
||||
"version": "0.0.1"
|
||||
"version": "1.1.1"
|
||||
},
|
||||
"path-browserify": {
|
||||
"version": "0.0.0"
|
||||
@ -4081,6 +4153,9 @@
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.6"
|
||||
},
|
||||
"progress": {
|
||||
"version": "1.1.8"
|
||||
},
|
||||
"promise": {
|
||||
"version": "7.1.1"
|
||||
},
|
||||
@ -4095,6 +4170,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"proto-list": {
|
||||
"version": "1.2.4"
|
||||
},
|
||||
"protobufjs": {
|
||||
"version": "5.0.0",
|
||||
"dependencies": {
|
||||
@ -4342,6 +4420,9 @@
|
||||
"request-capture-har": {
|
||||
"version": "1.1.4"
|
||||
},
|
||||
"request-progress": {
|
||||
"version": "0.3.1"
|
||||
},
|
||||
"requires-port": {
|
||||
"version": "1.0.0"
|
||||
},
|
||||
@ -4760,6 +4841,9 @@
|
||||
"text-extensions": {
|
||||
"version": "1.3.3"
|
||||
},
|
||||
"throttleit": {
|
||||
"version": "0.0.2"
|
||||
},
|
||||
"through": {
|
||||
"version": "2.3.8"
|
||||
},
|
||||
@ -4932,6 +5016,9 @@
|
||||
"uglify-to-browserify": {
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"uid-number": {
|
||||
"version": "0.0.5"
|
||||
},
|
||||
"uid-safe": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
@ -5271,13 +5358,13 @@
|
||||
"version": "8.2.2"
|
||||
},
|
||||
"xmldom": {
|
||||
"version": "0.1.19"
|
||||
"version": "0.1.27"
|
||||
},
|
||||
"xmlhttprequest-ssl": {
|
||||
"version": "1.5.1"
|
||||
},
|
||||
"xpath": {
|
||||
"version": "0.0.7"
|
||||
"version": "0.0.24"
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1"
|
||||
|
183
npm-shrinkwrap.json
generated
183
npm-shrinkwrap.json
generated
@ -1,7 +1,24 @@
|
||||
{
|
||||
"name": "angular-srcs",
|
||||
"version": "5.0.0-beta.0",
|
||||
"version": "5.0.0-beta.4",
|
||||
"dependencies": {
|
||||
"@bazel/typescript": {
|
||||
"version": "0.0.7",
|
||||
"from": "@bazel/typescript@latest",
|
||||
"resolved": "https://registry.npmjs.org/@bazel/typescript/-/typescript-0.0.7.tgz",
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "7.0.18",
|
||||
"from": "@types/node@7.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.18.tgz"
|
||||
},
|
||||
"tsickle": {
|
||||
"version": "0.23.6",
|
||||
"from": "tsickle@0.23.6",
|
||||
"resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.23.6.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/angularjs": {
|
||||
"version": "1.5.13-alpha",
|
||||
"from": "@types/angularjs@latest",
|
||||
@ -2408,9 +2425,9 @@
|
||||
}
|
||||
},
|
||||
"cldr": {
|
||||
"version": "3.5.2",
|
||||
"from": "cldr@>=3.5.0 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cldr/-/cldr-3.5.2.tgz",
|
||||
"version": "4.5.0",
|
||||
"from": "cldr@4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/cldr/-/cldr-4.5.0.tgz",
|
||||
"dependencies": {
|
||||
"uglify-js": {
|
||||
"version": "1.3.3",
|
||||
@ -2424,6 +2441,93 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"cldr-data-downloader": {
|
||||
"version": "0.3.2",
|
||||
"from": "cldr-data-downloader@>=0.3.0 <0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cldr-data-downloader/-/cldr-data-downloader-0.3.2.tgz",
|
||||
"dependencies": {
|
||||
"adm-zip": {
|
||||
"version": "0.4.4",
|
||||
"from": "adm-zip@0.4.4",
|
||||
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz"
|
||||
},
|
||||
"async": {
|
||||
"version": "2.5.0",
|
||||
"from": "async@>=2.0.1 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz"
|
||||
},
|
||||
"bl": {
|
||||
"version": "1.1.2",
|
||||
"from": "bl@>=1.1.2 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz"
|
||||
},
|
||||
"form-data": {
|
||||
"version": "1.0.1",
|
||||
"from": "form-data@>=1.0.0-rc4 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz"
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"from": "isarray@>=1.0.0 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"from": "lodash@>=4.14.0 <5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz"
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.27.0",
|
||||
"from": "mime-db@>=1.27.0 <1.28.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz"
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.15",
|
||||
"from": "mime-types@>=2.1.7 <2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz"
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"from": "minimist@0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.0",
|
||||
"from": "mkdirp@0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz"
|
||||
},
|
||||
"q": {
|
||||
"version": "1.0.1",
|
||||
"from": "q@1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/q/-/q-1.0.1.tgz"
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.2.3",
|
||||
"from": "qs@>=6.2.0 <6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz"
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.0.6",
|
||||
"from": "readable-stream@>=2.0.5 <2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz"
|
||||
},
|
||||
"request": {
|
||||
"version": "2.74.0",
|
||||
"from": "request@>=2.74.0 <2.75.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.74.0.tgz"
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.3.2",
|
||||
"from": "tough-cookie@>=2.3.0 <2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"cldrjs": {
|
||||
"version": "0.5.0",
|
||||
"from": "cldrjs@0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/cldrjs/-/cldrjs-0.5.0.tgz"
|
||||
},
|
||||
"cli-boxes": {
|
||||
"version": "1.0.0",
|
||||
"from": "cli-boxes@>=1.0.0 <2.0.0",
|
||||
@ -2596,6 +2700,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"config-chain": {
|
||||
"version": "1.1.11",
|
||||
"from": "config-chain@>=1.1.8 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.11.tgz"
|
||||
},
|
||||
"configstore": {
|
||||
"version": "2.1.0",
|
||||
"from": "configstore@>=2.0.0 <3.0.0",
|
||||
@ -5917,19 +6026,14 @@
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz"
|
||||
},
|
||||
"memoizeasync": {
|
||||
"version": "0.8.0",
|
||||
"from": "memoizeasync@0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/memoizeasync/-/memoizeasync-0.8.0.tgz",
|
||||
"version": "1.0.0",
|
||||
"from": "memoizeasync@1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/memoizeasync/-/memoizeasync-1.0.0.tgz",
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "2.5.0",
|
||||
"from": "lru-cache@2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz"
|
||||
},
|
||||
"passerror": {
|
||||
"version": "0.0.2",
|
||||
"from": "passerror@0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/passerror/-/passerror-0.0.2.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -6176,6 +6280,18 @@
|
||||
"from": "normalize-path@>=2.0.1 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.0.1.tgz"
|
||||
},
|
||||
"npmconf": {
|
||||
"version": "2.0.9",
|
||||
"from": "npmconf@2.0.9",
|
||||
"resolved": "https://registry.npmjs.org/npmconf/-/npmconf-2.0.9.tgz",
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "4.3.6",
|
||||
"from": "semver@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0||>=4.0.0 <5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.0.2",
|
||||
"from": "npmlog@>=0.0.0 <1.0.0||>=1.0.0 <2.0.0||>=2.0.0 <3.0.0||>=3.0.0 <4.0.0||>=4.0.0 <5.0.0",
|
||||
@ -6400,9 +6516,9 @@
|
||||
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.0.tgz"
|
||||
},
|
||||
"passerror": {
|
||||
"version": "0.0.1",
|
||||
"from": "passerror@0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/passerror/-/passerror-0.0.1.tgz"
|
||||
"version": "1.1.1",
|
||||
"from": "passerror@1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/passerror/-/passerror-1.1.1.tgz"
|
||||
},
|
||||
"path-browserify": {
|
||||
"version": "0.0.0",
|
||||
@ -6511,6 +6627,11 @@
|
||||
"from": "process-nextick-args@>=1.0.6 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.6.tgz"
|
||||
},
|
||||
"progress": {
|
||||
"version": "1.1.8",
|
||||
"from": "progress@1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz"
|
||||
},
|
||||
"promise": {
|
||||
"version": "7.1.1",
|
||||
"from": "promise@>=7.0.3 <8.0.0",
|
||||
@ -6533,6 +6654,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"proto-list": {
|
||||
"version": "1.2.4",
|
||||
"from": "proto-list@>=1.2.1 <1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz"
|
||||
},
|
||||
"protobufjs": {
|
||||
"version": "5.0.0",
|
||||
"from": "protobufjs@5.0.0",
|
||||
@ -6934,6 +7060,11 @@
|
||||
"from": "request-capture-har@>=1.1.4 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/request-capture-har/-/request-capture-har-1.1.4.tgz"
|
||||
},
|
||||
"request-progress": {
|
||||
"version": "0.3.1",
|
||||
"from": "request-progress@0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz"
|
||||
},
|
||||
"requires-port": {
|
||||
"version": "1.0.0",
|
||||
"from": "requires-port@>=1.0.0 <2.0.0",
|
||||
@ -7604,6 +7735,11 @@
|
||||
"from": "text-extensions@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.3.3.tgz"
|
||||
},
|
||||
"throttleit": {
|
||||
"version": "0.0.2",
|
||||
"from": "throttleit@>=0.0.2 <0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz"
|
||||
},
|
||||
"through": {
|
||||
"version": "2.3.8",
|
||||
"from": "through@>=2.2.7 <3.0.0",
|
||||
@ -7880,6 +8016,11 @@
|
||||
"from": "uglify-to-browserify@>=1.0.0 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz"
|
||||
},
|
||||
"uid-number": {
|
||||
"version": "0.0.5",
|
||||
"from": "uid-number@0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.5.tgz"
|
||||
},
|
||||
"uid-safe": {
|
||||
"version": "2.0.0",
|
||||
"from": "uid-safe@>=2.0.0 <2.1.0",
|
||||
@ -8427,9 +8568,9 @@
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz"
|
||||
},
|
||||
"xmldom": {
|
||||
"version": "0.1.19",
|
||||
"from": "xmldom@0.1.19",
|
||||
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.19.tgz"
|
||||
"version": "0.1.27",
|
||||
"from": "xmldom@0.1.27",
|
||||
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz"
|
||||
},
|
||||
"xmlhttprequest-ssl": {
|
||||
"version": "1.5.1",
|
||||
@ -8437,9 +8578,9 @@
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.1.tgz"
|
||||
},
|
||||
"xpath": {
|
||||
"version": "0.0.7",
|
||||
"from": "xpath@0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.7.tgz"
|
||||
"version": "0.0.24",
|
||||
"from": "xpath@0.0.24",
|
||||
"resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.24.tgz"
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
|
@ -31,6 +31,7 @@
|
||||
"fsevents": "^1.0.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@bazel/typescript": "0.0.7",
|
||||
"@types/angularjs": "^1.5.13-alpha",
|
||||
"@types/base64-js": "^1.2.5",
|
||||
"@types/fs-extra": "0.0.22-alpha",
|
||||
@ -48,7 +49,9 @@
|
||||
"canonical-path": "0.0.2",
|
||||
"chokidar": "^1.1.0",
|
||||
"clang-format": "^1.0.32",
|
||||
"cldr": "^3.5.2",
|
||||
"cldr": "^4.5.0",
|
||||
"cldr-data-downloader": "^0.3.2",
|
||||
"cldrjs": "^0.5.0",
|
||||
"conventional-changelog": "^1.1.0",
|
||||
"cors": "^2.7.1",
|
||||
"dgeni": "^0.4.2",
|
||||
@ -78,7 +81,6 @@
|
||||
"nan": "^2.4.0",
|
||||
"node-uuid": "1.4.x",
|
||||
"parse5": "^3.0.1",
|
||||
"protobufjs": "^5.0.0",
|
||||
"protractor": "^4.0.14",
|
||||
"react": "^0.14.0",
|
||||
"rewire": "^2.3.3",
|
||||
|
@ -20,7 +20,7 @@ export class Animation {
|
||||
private _animationAst: Ast;
|
||||
constructor(private _driver: AnimationDriver, input: AnimationMetadata|AnimationMetadata[]) {
|
||||
const errors: any[] = [];
|
||||
const ast = buildAnimationAst(input, errors);
|
||||
const ast = buildAnimationAst(_driver, input, errors);
|
||||
if (errors.length) {
|
||||
const errorMessage = `animation validation failed:\n${errors.join("\n")}`;
|
||||
throw new Error(errorMessage);
|
||||
|
@ -7,6 +7,7 @@
|
||||
*/
|
||||
import {AUTO_STYLE, AnimateTimings, AnimationAnimateChildMetadata, AnimationAnimateMetadata, AnimationAnimateRefMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationMetadataType, AnimationOptions, AnimationQueryMetadata, AnimationQueryOptions, AnimationReferenceMetadata, AnimationSequenceMetadata, AnimationStaggerMetadata, AnimationStateMetadata, AnimationStyleMetadata, AnimationTransitionMetadata, AnimationTriggerMetadata, style, ɵStyleData} from '@angular/animations';
|
||||
|
||||
import {AnimationDriver} from '../render/animation_driver';
|
||||
import {getOrSetAsInMap} from '../render/shared';
|
||||
import {ENTER_SELECTOR, LEAVE_SELECTOR, NG_ANIMATING_SELECTOR, NG_TRIGGER_SELECTOR, SUBSTITUTION_EXPR_START, copyObj, extractStyleParams, iteratorToArray, normalizeAnimationEntry, resolveTiming, validateStyleParams} from '../util';
|
||||
|
||||
@ -54,8 +55,9 @@ const SELF_TOKEN_REGEX = new RegExp(`\s*${SELF_TOKEN}\s*,?`, 'g');
|
||||
* Otherwise an error will be thrown.
|
||||
*/
|
||||
export function buildAnimationAst(
|
||||
metadata: AnimationMetadata | AnimationMetadata[], errors: any[]): Ast {
|
||||
return new AnimationAstBuilderVisitor().build(metadata, errors);
|
||||
driver: AnimationDriver, metadata: AnimationMetadata | AnimationMetadata[],
|
||||
errors: any[]): Ast {
|
||||
return new AnimationAstBuilderVisitor(driver).build(metadata, errors);
|
||||
}
|
||||
|
||||
const LEAVE_TOKEN = ':leave';
|
||||
@ -65,6 +67,8 @@ const ENTER_TOKEN_REGEX = new RegExp(ENTER_TOKEN, 'g');
|
||||
const ROOT_SELECTOR = '';
|
||||
|
||||
export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
|
||||
constructor(private _driver: AnimationDriver) {}
|
||||
|
||||
build(metadata: AnimationMetadata|AnimationMetadata[], errors: any[]): Ast {
|
||||
const context = new AnimationAstBuilderContext(errors);
|
||||
this._resetContextStyleTimingState(context);
|
||||
@ -273,6 +277,12 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
|
||||
if (typeof tuple == 'string') return;
|
||||
|
||||
Object.keys(tuple).forEach(prop => {
|
||||
if (!this._driver.validateStyleProperty(prop)) {
|
||||
context.errors.push(
|
||||
`The provided animation property "${prop}" is not a supported CSS property for animations`);
|
||||
return;
|
||||
}
|
||||
|
||||
const collectedStyles = context.collectedStyles[context.currentQuerySelector !];
|
||||
const collectedEntry = collectedStyles[prop];
|
||||
let updateCollectedStyle = true;
|
||||
|
@ -447,7 +447,7 @@ export class AnimationTimelineContext {
|
||||
private _driver: AnimationDriver, public element: any,
|
||||
public subInstructions: ElementInstructionMap, public errors: any[],
|
||||
public timelines: TimelineBuilder[], initialTimeline?: TimelineBuilder) {
|
||||
this.currentTimeline = initialTimeline || new TimelineBuilder(element, 0);
|
||||
this.currentTimeline = initialTimeline || new TimelineBuilder(this._driver, element, 0);
|
||||
timelines.push(this.currentTimeline);
|
||||
}
|
||||
|
||||
@ -530,7 +530,7 @@ export class AnimationTimelineContext {
|
||||
easing: ''
|
||||
};
|
||||
const builder = new SubTimelineBuilder(
|
||||
instruction.element, instruction.keyframes, instruction.preStyleProps,
|
||||
this._driver, instruction.element, instruction.keyframes, instruction.preStyleProps,
|
||||
instruction.postStyleProps, updatedTimings, instruction.stretchStartingKeyframe);
|
||||
this.timelines.push(builder);
|
||||
return updatedTimings;
|
||||
@ -582,7 +582,7 @@ export class TimelineBuilder {
|
||||
private _currentEmptyStepKeyframe: ɵStyleData|null = null;
|
||||
|
||||
constructor(
|
||||
public element: any, public startTime: number,
|
||||
private _driver: AnimationDriver, public element: any, public startTime: number,
|
||||
private _elementTimelineStylesLookup?: Map<any, ɵStyleData>) {
|
||||
if (!this._elementTimelineStylesLookup) {
|
||||
this._elementTimelineStylesLookup = new Map<any, ɵStyleData>();
|
||||
@ -632,7 +632,7 @@ export class TimelineBuilder {
|
||||
fork(element: any, currentTime?: number): TimelineBuilder {
|
||||
this.applyStylesToKeyframe();
|
||||
return new TimelineBuilder(
|
||||
element, currentTime || this.currentTime, this._elementTimelineStylesLookup);
|
||||
this._driver, element, currentTime || this.currentTime, this._elementTimelineStylesLookup);
|
||||
}
|
||||
|
||||
private _loadKeyframe() {
|
||||
@ -796,10 +796,10 @@ class SubTimelineBuilder extends TimelineBuilder {
|
||||
public timings: AnimateTimings;
|
||||
|
||||
constructor(
|
||||
public element: any, public keyframes: ɵStyleData[], public preStyleProps: string[],
|
||||
public postStyleProps: string[], timings: AnimateTimings,
|
||||
driver: AnimationDriver, public element: any, public keyframes: ɵStyleData[],
|
||||
public preStyleProps: string[], public postStyleProps: string[], timings: AnimateTimings,
|
||||
private _stretchStartingKeyframe: boolean = false) {
|
||||
super(element, timings.delay);
|
||||
super(driver, element, timings.delay);
|
||||
this.timings = {duration: timings.duration, delay: timings.delay, easing: timings.easing};
|
||||
}
|
||||
|
||||
|
@ -7,13 +7,14 @@
|
||||
*/
|
||||
import {AnimationPlayer, NoopAnimationPlayer} from '@angular/animations';
|
||||
|
||||
import {containsElement, invokeQuery, matchesElement} from './shared';
|
||||
|
||||
import {containsElement, invokeQuery, matchesElement, validateStyleProperty} from './shared';
|
||||
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
export class NoopAnimationDriver implements AnimationDriver {
|
||||
validateStyleProperty(prop: string): boolean { return validateStyleProperty(prop); }
|
||||
|
||||
matchesElement(element: any, selector: string): boolean {
|
||||
return matchesElement(element, selector);
|
||||
}
|
||||
@ -41,6 +42,8 @@ export class NoopAnimationDriver implements AnimationDriver {
|
||||
export abstract class AnimationDriver {
|
||||
static NOOP: AnimationDriver = new NoopAnimationDriver();
|
||||
|
||||
abstract validateStyleProperty(prop: string): boolean;
|
||||
|
||||
abstract matchesElement(element: any, selector: string): boolean;
|
||||
|
||||
abstract containsElement(elm1: any, elm2: any): boolean;
|
||||
|
@ -25,9 +25,9 @@ export class AnimationEngine {
|
||||
// this method is designed to be overridden by the code that uses this engine
|
||||
public onRemovalComplete = (element: any, context: any) => {};
|
||||
|
||||
constructor(driver: AnimationDriver, normalizer: AnimationStyleNormalizer) {
|
||||
this._transitionEngine = new TransitionAnimationEngine(driver, normalizer);
|
||||
this._timelineEngine = new TimelineAnimationEngine(driver, normalizer);
|
||||
constructor(private _driver: AnimationDriver, normalizer: AnimationStyleNormalizer) {
|
||||
this._transitionEngine = new TransitionAnimationEngine(_driver, normalizer);
|
||||
this._timelineEngine = new TimelineAnimationEngine(_driver, normalizer);
|
||||
|
||||
this._transitionEngine.onRemovalComplete = (element: any, context: any) =>
|
||||
this.onRemovalComplete(element, context);
|
||||
@ -40,7 +40,8 @@ export class AnimationEngine {
|
||||
let trigger = this._triggerCache[cacheKey];
|
||||
if (!trigger) {
|
||||
const errors: any[] = [];
|
||||
const ast = buildAnimationAst(metadata as AnimationMetadata, errors) as TriggerAst;
|
||||
const ast =
|
||||
buildAnimationAst(this._driver, metadata as AnimationMetadata, errors) as TriggerAst;
|
||||
if (errors.length) {
|
||||
throw new Error(
|
||||
`The animation trigger "${name}" has failed to build due to the following errors:\n - ${errors.join("\n - ")}`);
|
||||
|
@ -166,6 +166,21 @@ if (typeof Element != 'undefined') {
|
||||
};
|
||||
}
|
||||
|
||||
let _CACHED_BODY: {style: any}|null = null;
|
||||
export function validateStyleProperty(prop: string): boolean {
|
||||
if (!_CACHED_BODY) {
|
||||
_CACHED_BODY = getBodyNode() || {};
|
||||
}
|
||||
return _CACHED_BODY !.style ? prop in _CACHED_BODY !.style : true;
|
||||
}
|
||||
|
||||
export function getBodyNode(): any|null {
|
||||
if (typeof document != 'undefined') {
|
||||
return document.body;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export const matchesElement = _matches;
|
||||
export const containsElement = _contains;
|
||||
export const invokeQuery = _query;
|
||||
|
@ -28,7 +28,7 @@ export class TimelineAnimationEngine {
|
||||
|
||||
register(id: string, metadata: AnimationMetadata|AnimationMetadata[]) {
|
||||
const errors: any[] = [];
|
||||
const ast = buildAnimationAst(metadata, errors);
|
||||
const ast = buildAnimationAst(this._driver, metadata, errors);
|
||||
if (errors.length) {
|
||||
throw new Error(
|
||||
`Unable to build the animation due to the following errors: ${errors.join("\n")}`);
|
||||
|
@ -16,7 +16,7 @@ import {AnimationStyleNormalizer} from '../dsl/style_normalization/animation_sty
|
||||
import {ENTER_CLASSNAME, LEAVE_CLASSNAME, NG_ANIMATING_CLASSNAME, NG_ANIMATING_SELECTOR, NG_TRIGGER_CLASSNAME, NG_TRIGGER_SELECTOR, copyObj, eraseStyles, setStyles} from '../util';
|
||||
|
||||
import {AnimationDriver} from './animation_driver';
|
||||
import {getOrSetAsInMap, listenOnPlayer, makeAnimationEvent, normalizeKeyframes, optimizeGroupPlayer} from './shared';
|
||||
import {getBodyNode, getOrSetAsInMap, listenOnPlayer, makeAnimationEvent, normalizeKeyframes, optimizeGroupPlayer} from './shared';
|
||||
|
||||
const QUEUED_CLASSNAME = 'ng-animate-queued';
|
||||
const QUEUED_SELECTOR = '.ng-animate-queued';
|
||||
@ -817,6 +817,7 @@ export class TransitionAnimationEngine {
|
||||
|
||||
const disabledElementsSet = new Set<any>();
|
||||
this.disabledNodes.forEach(node => {
|
||||
disabledElementsSet.add(node);
|
||||
const nodesThatAreDisabled = this.driver.query(node, QUEUED_SELECTOR, true);
|
||||
for (let i = 0; i < nodesThatAreDisabled.length; i++) {
|
||||
disabledElementsSet.add(nodesThatAreDisabled[i]);
|
||||
@ -960,22 +961,45 @@ export class TransitionAnimationEngine {
|
||||
const element = player.element;
|
||||
const previousPlayers =
|
||||
this._getPreviousPlayers(element, false, player.namespaceId, player.triggerName, null);
|
||||
previousPlayers.forEach(
|
||||
prevPlayer => { getOrSetAsInMap(allPreviousPlayersMap, element, []).push(prevPlayer); });
|
||||
previousPlayers.forEach(prevPlayer => {
|
||||
getOrSetAsInMap(allPreviousPlayersMap, element, []).push(prevPlayer);
|
||||
prevPlayer.destroy();
|
||||
});
|
||||
});
|
||||
|
||||
allPreviousPlayersMap.forEach(players => players.forEach(player => player.destroy()));
|
||||
|
||||
// PRE STAGE: fill the ! styles
|
||||
const preStylesMap = allPreStyleElements.size ?
|
||||
cloakAndComputeStyles(
|
||||
this.driver, enterNodesWithoutAnimations, allPreStyleElements, PRE_STYLE) :
|
||||
new Map<any, ɵStyleData>();
|
||||
// this is a special case for nodes that will be removed (either by)
|
||||
// having their own leave animations or by being queried in a container
|
||||
// that will be removed once a parent animation is complete. The idea
|
||||
// here is that * styles must be identical to ! styles because of
|
||||
// backwards compatibility (* is also filled in by default in many places).
|
||||
// Otherwise * styles will return an empty value or auto since the element
|
||||
// that is being getComputedStyle'd will not be visible (since * = destination)
|
||||
const replaceNodes = allLeaveNodes.filter(node => {
|
||||
return replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements);
|
||||
});
|
||||
|
||||
// POST STAGE: fill the * styles
|
||||
const postStylesMap = cloakAndComputeStyles(
|
||||
const [postStylesMap, allLeaveQueriedNodes] = cloakAndComputeStyles(
|
||||
this.driver, leaveNodesWithoutAnimations, allPostStyleElements, AUTO_STYLE);
|
||||
|
||||
allLeaveQueriedNodes.forEach(node => {
|
||||
if (replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements)) {
|
||||
replaceNodes.push(node);
|
||||
}
|
||||
});
|
||||
|
||||
// PRE STAGE: fill the ! styles
|
||||
const [preStylesMap] = allPreStyleElements.size ?
|
||||
cloakAndComputeStyles(
|
||||
this.driver, enterNodesWithoutAnimations, allPreStyleElements, PRE_STYLE) :
|
||||
[new Map<any, ɵStyleData>()];
|
||||
|
||||
replaceNodes.forEach(node => {
|
||||
const post = postStylesMap.get(node);
|
||||
const pre = preStylesMap.get(node);
|
||||
postStylesMap.set(node, { ...post, ...pre } as any);
|
||||
});
|
||||
|
||||
const rootPlayers: TransitionAnimationPlayer[] = [];
|
||||
const subPlayers: TransitionAnimationPlayer[] = [];
|
||||
queuedInstructions.forEach(entry => {
|
||||
@ -1015,11 +1039,20 @@ export class TransitionAnimationEngine {
|
||||
} else {
|
||||
eraseStyles(element, instruction.fromStyles);
|
||||
player.onDestroy(() => setStyles(element, instruction.toStyles));
|
||||
// there still might be a ancestor player animating this
|
||||
// element therefore we will still add it as a sub player
|
||||
// even if its animation may be disabled
|
||||
subPlayers.push(player);
|
||||
if (disabledElementsSet.has(element)) {
|
||||
skippedPlayers.push(player);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// find all of the sub players' corresponding inner animation player
|
||||
subPlayers.forEach(player => {
|
||||
// even if any players are not found for a sub animation then it
|
||||
// will still complete itself after the next tick since it's Noop
|
||||
const playersForElement = skippedPlayersMap.get(player.element);
|
||||
if (playersForElement && playersForElement.length) {
|
||||
const innerPlayer = optimizeGroupPlayer(playersForElement);
|
||||
@ -1051,7 +1084,7 @@ export class TransitionAnimationEngine {
|
||||
// until that animation is over (or the parent queried animation)
|
||||
if (details && details.hasAnimation) continue;
|
||||
|
||||
let players: AnimationPlayer[] = [];
|
||||
let players: TransitionAnimationPlayer[] = [];
|
||||
|
||||
// if this element is queried or if it contains queried children
|
||||
// then we want for the element not to be removed from the page
|
||||
@ -1070,8 +1103,10 @@ export class TransitionAnimationEngine {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (players.length) {
|
||||
removeNodesAfterAnimationDone(this, element, players);
|
||||
|
||||
const activePlayers = players.filter(p => !p.destroyed);
|
||||
if (activePlayers.length) {
|
||||
removeNodesAfterAnimationDone(this, element, activePlayers);
|
||||
} else {
|
||||
this.processLeaveNode(element);
|
||||
}
|
||||
@ -1141,10 +1176,6 @@ export class TransitionAnimationEngine {
|
||||
private _beforeAnimationBuild(
|
||||
namespaceId: string, instruction: AnimationTransitionInstruction,
|
||||
allPreviousPlayersMap: Map<any, TransitionAnimationPlayer[]>) {
|
||||
// it's important to do this step before destroying the players
|
||||
// so that the onDone callback below won't fire before this
|
||||
eraseStyles(instruction.element, instruction.fromStyles);
|
||||
|
||||
const triggerName = instruction.triggerName;
|
||||
const rootElement = instruction.element;
|
||||
|
||||
@ -1166,9 +1197,14 @@ export class TransitionAnimationEngine {
|
||||
if (realPlayer.beforeDestroy) {
|
||||
realPlayer.beforeDestroy();
|
||||
}
|
||||
player.destroy();
|
||||
players.push(player);
|
||||
});
|
||||
});
|
||||
|
||||
// this needs to be done so that the PRE/POST styles can be
|
||||
// computed properly without interfering with the previous animation
|
||||
eraseStyles(rootElement, instruction.fromStyles);
|
||||
}
|
||||
|
||||
private _buildAnimation(
|
||||
@ -1400,9 +1436,10 @@ function cloakElement(element: any, value?: string) {
|
||||
|
||||
function cloakAndComputeStyles(
|
||||
driver: AnimationDriver, elements: any[], elementPropsMap: Map<any, Set<string>>,
|
||||
defaultStyle: string): Map<any, ɵStyleData> {
|
||||
defaultStyle: string): [Map<any, ɵStyleData>, any[]] {
|
||||
const cloakVals = elements.map(element => cloakElement(element));
|
||||
const valuesMap = new Map<any, ɵStyleData>();
|
||||
const failedElements: any[] = [];
|
||||
|
||||
elementPropsMap.forEach((props: Set<string>, element: any) => {
|
||||
const styles: ɵStyleData = {};
|
||||
@ -1413,13 +1450,14 @@ function cloakAndComputeStyles(
|
||||
// by a parent animation element being detached.
|
||||
if (!value || value.length == 0) {
|
||||
element[REMOVAL_FLAG] = NULL_REMOVED_QUERIED_STATE;
|
||||
failedElements.push(element);
|
||||
}
|
||||
});
|
||||
valuesMap.set(element, styles);
|
||||
});
|
||||
|
||||
elements.forEach((element, i) => cloakElement(element, cloakVals[i]));
|
||||
return valuesMap;
|
||||
return [valuesMap, failedElements];
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1487,13 +1525,6 @@ function removeClass(element: any, className: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function getBodyNode(): any|null {
|
||||
if (typeof document != 'undefined') {
|
||||
return document.body;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function removeNodesAfterAnimationDone(
|
||||
engine: TransitionAnimationEngine, element: any, players: AnimationPlayer[]) {
|
||||
optimizeGroupPlayer(players).onDone(() => engine.processLeaveNode(element));
|
||||
@ -1526,3 +1557,20 @@ function objEquals(a: {[key: string]: any}, b: {[key: string]: any}): boolean {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function replacePostStylesAsPre(
|
||||
element: any, allPreStyleElements: Map<any, Set<string>>,
|
||||
allPostStyleElements: Map<any, Set<string>>): boolean {
|
||||
const postEntry = allPostStyleElements.get(element);
|
||||
if (!postEntry) return false;
|
||||
|
||||
let preEntry = allPreStyleElements.get(element);
|
||||
if (preEntry) {
|
||||
postEntry.forEach(data => preEntry !.add(data));
|
||||
} else {
|
||||
allPreStyleElements.set(element, postEntry);
|
||||
}
|
||||
|
||||
allPostStyleElements.delete(element);
|
||||
return true;
|
||||
}
|
||||
|
@ -8,11 +8,13 @@
|
||||
import {AnimationPlayer, ɵStyleData} from '@angular/animations';
|
||||
|
||||
import {AnimationDriver} from '../animation_driver';
|
||||
import {containsElement, invokeQuery, matchesElement} from '../shared';
|
||||
import {containsElement, invokeQuery, matchesElement, validateStyleProperty} from '../shared';
|
||||
|
||||
import {WebAnimationsPlayer} from './web_animations_player';
|
||||
|
||||
export class WebAnimationsDriver implements AnimationDriver {
|
||||
validateStyleProperty(prop: string): boolean { return validateStyleProperty(prop); }
|
||||
|
||||
matchesElement(element: any, selector: string): boolean {
|
||||
return matchesElement(element, selector);
|
||||
}
|
||||
|
@ -158,9 +158,9 @@ export class WebAnimationsPlayer implements AnimationPlayer {
|
||||
|
||||
destroy(): void {
|
||||
if (!this._destroyed) {
|
||||
this._destroyed = true;
|
||||
this._resetDomPlayerState();
|
||||
this._onFinish();
|
||||
this._destroyed = true;
|
||||
this._onDestroyFns.forEach(fn => fn());
|
||||
this._onDestroyFns = [];
|
||||
}
|
||||
|
@ -177,10 +177,12 @@ export function main() {
|
||||
|
||||
it('should throw if dynamic style substitutions are used without defaults within state() definitions',
|
||||
() => {
|
||||
const steps = [state('final', style({
|
||||
'width': '{{ one }}px',
|
||||
'borderRadius': '{{ two }}px {{ three }}px',
|
||||
}))];
|
||||
const steps = [
|
||||
state('final', style({
|
||||
'width': '{{ one }}px',
|
||||
'borderRadius': '{{ two }}px {{ three }}px',
|
||||
})),
|
||||
];
|
||||
|
||||
expect(() => { validateAndThrowAnimationSequence(steps); })
|
||||
.toThrowError(
|
||||
@ -198,6 +200,14 @@ export function main() {
|
||||
.toThrowError(
|
||||
/state\("panfinal", ...\) must define default values for all the following style substitutions: greyColor/);
|
||||
});
|
||||
|
||||
it('should throw an error if an invalid CSS property is used in the animation', () => {
|
||||
const steps = [animate(1000, style({abc: '500px'}))];
|
||||
|
||||
expect(() => { validateAndThrowAnimationSequence(steps); })
|
||||
.toThrowError(
|
||||
/The provided animation property "abc" is not a supported CSS property for animations/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('keyframe building', () => {
|
||||
@ -388,14 +398,13 @@ export function main() {
|
||||
|
||||
it('should allow multiple substitutions to occur within the same style value', () => {
|
||||
const steps = [
|
||||
style({transform: ''}),
|
||||
animate(1000, style({transform: 'translateX({{ x }}) translateY({{ y }})'}))
|
||||
style({borderRadius: '100px 100px'}),
|
||||
animate(1000, style({borderRadius: '{{ one }}px {{ two }}'})),
|
||||
];
|
||||
const players =
|
||||
invokeAnimationSequence(rootElement, steps, buildParams({x: '200px', y: '400px'}));
|
||||
invokeAnimationSequence(rootElement, steps, buildParams({one: '200', two: '400px'}));
|
||||
expect(players[0].keyframes).toEqual([
|
||||
{offset: 0, transform: ''},
|
||||
{offset: 1, transform: 'translateX(200px) translateY(400px)'}
|
||||
{offset: 0, borderRadius: '100px 100px'}, {offset: 1, borderRadius: '200px 400px'}
|
||||
]);
|
||||
});
|
||||
|
||||
@ -571,18 +580,12 @@ export function main() {
|
||||
() => {
|
||||
const steps = [
|
||||
animate(1000, style({height: '50px'})),
|
||||
animate(
|
||||
2000, keyframes([
|
||||
style({left: '0', transform: 'rotate(0deg)', offset: 0}),
|
||||
style({
|
||||
left: '40%',
|
||||
transform: 'rotate(250deg) translateY(-200px)',
|
||||
offset: .33
|
||||
}),
|
||||
style(
|
||||
{left: '60%', transform: 'rotate(180deg) translateY(200px)', offset: .66}),
|
||||
style({left: 'calc(100% - 100px)', transform: 'rotate(0deg)', offset: 1}),
|
||||
])),
|
||||
animate(2000, keyframes([
|
||||
style({left: '0', top: '0', offset: 0}),
|
||||
style({left: '40%', top: '50%', offset: .33}),
|
||||
style({left: '60%', top: '80%', offset: .66}),
|
||||
style({left: 'calc(100% - 100px)', top: '100%', offset: 1}),
|
||||
])),
|
||||
group([animate('2s', style({width: '200px'}))]),
|
||||
animate('2s', style({height: '300px'})),
|
||||
group([animate('2s', style({height: '500px', width: '500px'}))])
|
||||
@ -987,8 +990,9 @@ function invokeAnimationSequence(
|
||||
}
|
||||
|
||||
function validateAndThrowAnimationSequence(steps: AnimationMetadata | AnimationMetadata[]) {
|
||||
const driver = new MockAnimationDriver();
|
||||
const errors: any[] = [];
|
||||
const ast = buildAnimationAst(steps, errors);
|
||||
const ast = buildAnimationAst(driver, steps, errors);
|
||||
if (errors.length) {
|
||||
throw new Error(errors.join('\n'));
|
||||
}
|
||||
|
@ -411,8 +411,10 @@ export function main() {
|
||||
() => {
|
||||
const engine = makeEngine();
|
||||
const trig = trigger('something', [
|
||||
state('x', style({opacity: 0})), state('y', style({opacity: .5})),
|
||||
state('z', style({opacity: 1})), transition('* => *', animate(1000))
|
||||
state('x', style({opacity: 0})),
|
||||
state('y', style({opacity: .5})),
|
||||
state('z', style({opacity: 1})),
|
||||
transition('* => *', animate(1000)),
|
||||
]);
|
||||
|
||||
registerTrigger(element, engine, trig);
|
||||
@ -428,7 +430,7 @@ export function main() {
|
||||
|
||||
const player2 = engine.players[0];
|
||||
|
||||
expect(parseFloat(element.style.opacity)).toEqual(.5);
|
||||
expect(parseFloat(element.style.opacity)).not.toEqual(.5);
|
||||
|
||||
player2.finish();
|
||||
expect(parseFloat(element.style.opacity)).toEqual(1);
|
||||
@ -655,8 +657,9 @@ function registerTrigger(
|
||||
element: any, engine: TransitionAnimationEngine, metadata: AnimationTriggerMetadata,
|
||||
id: string = DEFAULT_NAMESPACE_ID) {
|
||||
const errors: any[] = [];
|
||||
const driver = new MockAnimationDriver();
|
||||
const name = metadata.name;
|
||||
const ast = buildAnimationAst(metadata as AnimationMetadata, errors) as TriggerAst;
|
||||
const ast = buildAnimationAst(driver, metadata as AnimationMetadata, errors) as TriggerAst;
|
||||
if (errors.length) {
|
||||
}
|
||||
const trigger = buildTrigger(name, ast);
|
||||
|
@ -11,12 +11,14 @@ import {trigger} from '@angular/animations';
|
||||
import {TriggerAst} from '../src/dsl/animation_ast';
|
||||
import {buildAnimationAst} from '../src/dsl/animation_ast_builder';
|
||||
import {AnimationTrigger, buildTrigger} from '../src/dsl/animation_trigger';
|
||||
import {MockAnimationDriver} from '../testing/src/mock_animation_driver';
|
||||
|
||||
export function makeTrigger(
|
||||
name: string, steps: any, skipErrors: boolean = false): AnimationTrigger {
|
||||
const driver = new MockAnimationDriver();
|
||||
const errors: any[] = [];
|
||||
const triggerData = trigger(name, steps);
|
||||
const triggerAst = buildAnimationAst(triggerData, errors) as TriggerAst;
|
||||
const triggerAst = buildAnimationAst(driver, triggerData, errors) as TriggerAst;
|
||||
if (!skipErrors && errors.length) {
|
||||
const LINE_START = '\n - ';
|
||||
throw new Error(
|
||||
|
@ -8,15 +8,18 @@
|
||||
import {AUTO_STYLE, AnimationPlayer, NoopAnimationPlayer, ɵStyleData} from '@angular/animations';
|
||||
|
||||
import {AnimationDriver} from '../../src/render/animation_driver';
|
||||
import {containsElement, invokeQuery, matchesElement} from '../../src/render/shared';
|
||||
import {containsElement, invokeQuery, matchesElement, validateStyleProperty} from '../../src/render/shared';
|
||||
import {allowPreviousPlayerStylesMerge} from '../../src/util';
|
||||
|
||||
|
||||
/**
|
||||
* @experimental Animation support is experimental.
|
||||
*/
|
||||
export class MockAnimationDriver implements AnimationDriver {
|
||||
static log: AnimationPlayer[] = [];
|
||||
|
||||
validateStyleProperty(prop: string): boolean { return validateStyleProperty(prop); }
|
||||
|
||||
matchesElement(element: any, selector: string): boolean {
|
||||
return matchesElement(element, selector);
|
||||
}
|
||||
|
@ -282,11 +282,12 @@ export interface AnimationStaggerMetadata extends AnimationMetadata {
|
||||
* <div [@myAnimationTrigger]="myStatusExp">...</div>
|
||||
* ```
|
||||
*
|
||||
* ## Disable Child Animations
|
||||
* ## Disable Animations
|
||||
* A special animation control binding called `@.disabled` can be placed on an element which will
|
||||
then disable animations for any inner animation triggers situated within the element.
|
||||
then disable animations for any inner animation triggers situated within the element as well as
|
||||
any animations on the element itself.
|
||||
*
|
||||
* When true, the `@.disabled` binding will prevent inner animations from rendering. The example
|
||||
* When true, the `@.disabled` binding will prevent all animations from rendering. The example
|
||||
below shows how to use this feature:
|
||||
*
|
||||
* ```ts
|
||||
@ -312,8 +313,8 @@ export interface AnimationStaggerMetadata extends AnimationMetadata {
|
||||
* The `@childAnimation` trigger will not animate because `@.disabled` prevents it from happening
|
||||
(when true).
|
||||
*
|
||||
* Note that `@.disbled` will only disable inner animations (any animations running on the same
|
||||
element will not be disabled).
|
||||
* Note that `@.disbled` will only disable all animations (this means any animations running on
|
||||
* the same element will also be disabled).
|
||||
*
|
||||
* ### Disabling Animations Application-wide
|
||||
* When an area of the template is set to have animations disabled, **all** inner components will
|
||||
|
1
packages/bazel/BUILD.bazel
Normal file
1
packages/bazel/BUILD.bazel
Normal file
@ -0,0 +1 @@
|
||||
# Empty marker file, indicating this directory is a Bazel package.
|
9
packages/bazel/WORKSPACE
Normal file
9
packages/bazel/WORKSPACE
Normal file
@ -0,0 +1,9 @@
|
||||
# By convention, the name should "describe the project in reverse-DNS form"
|
||||
# https://docs.bazel.build/versions/master/be/functions.html#workspace
|
||||
# But if we use "io_angular" then the loads used in BUILD files will
|
||||
# be unfamiliar to Angular users who import from '@angular/pkg' in
|
||||
# TypeScript files. We want to reduce the impedance between the Bazel
|
||||
# and node naming schemes.
|
||||
# We take the name "angular" so that users can write
|
||||
# load("@angular//:index.bzl", "ng_module")
|
||||
workspace(name = "angular")
|
9
packages/bazel/index.bzl
Normal file
9
packages/bazel/index.bzl
Normal file
@ -0,0 +1,9 @@
|
||||
# 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
|
||||
""" Public API surface is re-exported here.
|
||||
Users should not load files under "/src"
|
||||
"""
|
||||
|
||||
load("//src:ng_module.bzl", "ng_module")
|
15
packages/bazel/package.json
Normal file
15
packages/bazel/package.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "@angular/bazel",
|
||||
"version": "0.0.0-PLACEHOLDER",
|
||||
"description": "Angular - bazel build rules",
|
||||
"author": "angular",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@angular/compiler-cli": "0.0.0-PLACEHOLDER",
|
||||
"typescript": "~2.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/angular/angular.git"
|
||||
}
|
||||
}
|
1
packages/bazel/src/BUILD.bazel
Normal file
1
packages/bazel/src/BUILD.bazel
Normal file
@ -0,0 +1 @@
|
||||
# Empty marker file, indicating this directory is a Bazel package.
|
192
packages/bazel/src/ng_module.bzl
Normal file
192
packages/bazel/src/ng_module.bzl
Normal file
@ -0,0 +1,192 @@
|
||||
# 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
|
||||
|
||||
load(":rules_typescript.bzl",
|
||||
"tsc_wrapped_tsconfig",
|
||||
"COMMON_ATTRIBUTES",
|
||||
"compile_ts",
|
||||
"DEPS_ASPECTS",
|
||||
"ts_providers_dict_to_struct",
|
||||
"json_marshal",
|
||||
)
|
||||
|
||||
# Calculate the expected output of the template compiler for every source in
|
||||
# in the library. Most of these will be produced as empty files but it is
|
||||
# unknown, without parsing, which will be empty.
|
||||
def _expected_outs(ctx, label):
|
||||
devmode_js_files = []
|
||||
closure_js_files = []
|
||||
declaration_files = []
|
||||
summary_files = []
|
||||
|
||||
codegen_inputs = ctx.files.srcs
|
||||
|
||||
for src in ctx.files.srcs + ctx.files.assets:
|
||||
if src.short_path.endswith(".ts") and not src.short_path.endswith(".d.ts"):
|
||||
basename = src.short_path[len(ctx.label.package) + 1:-len(".ts")]
|
||||
devmode_js = [
|
||||
".ngfactory.js",
|
||||
".ngsummary.js",
|
||||
".js",
|
||||
]
|
||||
summaries = [".ngsummary.json"]
|
||||
|
||||
elif src.short_path.endswith(".css"):
|
||||
basename = src.short_path[len(ctx.label.package) + 1:-len(".css")]
|
||||
devmode_js = [
|
||||
".css.shim.ngstyle.js",
|
||||
".css.ngstyle.js",
|
||||
]
|
||||
summaries = []
|
||||
|
||||
closure_js = [f.replace(".js", ".closure.js") for f in devmode_js]
|
||||
declarations = [f.replace(".js", ".d.ts") for f in devmode_js]
|
||||
|
||||
devmode_js_files += [ctx.new_file(ctx.bin_dir, basename + ext) for ext in devmode_js]
|
||||
closure_js_files += [ctx.new_file(ctx.bin_dir, basename + ext) for ext in closure_js]
|
||||
declaration_files += [ctx.new_file(ctx.bin_dir, basename + ext) for ext in declarations]
|
||||
summary_files += [ctx.new_file(ctx.bin_dir, basename + ext) for ext in summaries]
|
||||
|
||||
return struct(
|
||||
closure_js = closure_js_files,
|
||||
devmode_js = devmode_js_files,
|
||||
declarations = declaration_files,
|
||||
summaries = summary_files,
|
||||
)
|
||||
|
||||
def _ngc_tsconfig(ctx, files, srcs, **kwargs):
|
||||
outs = _expected_outs(ctx, ctx.label)
|
||||
if "devmode_manifest" in kwargs:
|
||||
expected_outs = outs.devmode_js + outs.declarations + outs.summaries
|
||||
else:
|
||||
expected_outs = outs.closure_js
|
||||
|
||||
return dict(tsc_wrapped_tsconfig(ctx, files, srcs, **kwargs), **{
|
||||
"angularCompilerOptions": {
|
||||
"generateCodeForLibraries": False,
|
||||
# FIXME: wrong place to de-dupe
|
||||
"expectedOut": depset([o.path for o in expected_outs]).to_list()
|
||||
}
|
||||
})
|
||||
|
||||
def _collect_summaries_aspect_impl(target, ctx):
|
||||
results = target.angular.summaries if hasattr(target, "angular") else depset()
|
||||
|
||||
# If we are visiting empty-srcs ts_library, this is a re-export
|
||||
srcs = target.srcs if hasattr(target, "srcs") else []
|
||||
|
||||
# "re-export" rules should expose all the files of their deps
|
||||
if not srcs:
|
||||
for dep in ctx.rule.attr.deps:
|
||||
if (hasattr(dep, "angular")):
|
||||
results += dep.angular.summaries
|
||||
|
||||
return struct(collect_summaries_aspect_result = results)
|
||||
|
||||
_collect_summaries_aspect = aspect(
|
||||
implementation = _collect_summaries_aspect_impl,
|
||||
attr_aspects = ["deps"],
|
||||
)
|
||||
|
||||
def _compile_action(ctx, inputs, outputs, config_file_path):
|
||||
summaries = depset()
|
||||
for dep in ctx.attr.deps:
|
||||
if hasattr(dep, "collect_summaries_aspect_result"):
|
||||
summaries += dep.collect_summaries_aspect_result
|
||||
|
||||
action_inputs = inputs + summaries.to_list() + ctx.files.assets
|
||||
# print("ASSETS", [a.path for a in ctx.files.assets])
|
||||
# print("INPUTS", ctx.label, [o.path for o in summaries if o.path.find("core/src") > 0])
|
||||
|
||||
if hasattr(ctx.attr, "node_modules"):
|
||||
action_inputs += [f for f in ctx.files.node_modules
|
||||
if f.path.endswith(".ts") or f.path.endswith(".json")]
|
||||
if hasattr(ctx.attr, "tsconfig") and ctx.file.tsconfig:
|
||||
action_inputs += [ctx.file.tsconfig]
|
||||
|
||||
# One at-sign makes this a params-file, enabling the worker strategy.
|
||||
# Two at-signs escapes the argument so it's passed through to ngc
|
||||
# rather than the contents getting expanded.
|
||||
if ctx.attr._supports_workers:
|
||||
arguments = ["@@" + config_file_path]
|
||||
else:
|
||||
arguments = ["-p", config_file_path]
|
||||
|
||||
ctx.action(
|
||||
progress_message = "Compiling Angular templates (ngc) %s" % ctx.label,
|
||||
mnemonic = "AngularTemplateCompile",
|
||||
inputs = action_inputs,
|
||||
outputs = outputs,
|
||||
arguments = arguments,
|
||||
executable = ctx.executable.compiler,
|
||||
execution_requirements = {
|
||||
"supports-workers": str(int(ctx.attr._supports_workers)),
|
||||
},
|
||||
)
|
||||
|
||||
def _prodmode_compile_action(ctx, inputs, outputs, config_file_path):
|
||||
outs = _expected_outs(ctx, ctx.label)
|
||||
_compile_action(ctx, inputs, outputs + outs.closure_js, config_file_path)
|
||||
|
||||
def _devmode_compile_action(ctx, inputs, outputs, config_file_path):
|
||||
outs = _expected_outs(ctx, ctx.label)
|
||||
_compile_action(ctx, inputs, outputs + outs.devmode_js + outs.declarations + outs.summaries, config_file_path)
|
||||
|
||||
def ng_module_impl(ctx, ts_compile_actions):
|
||||
providers = ts_compile_actions(
|
||||
ctx, is_library=True, compile_action=_prodmode_compile_action,
|
||||
devmode_compile_action=_devmode_compile_action,
|
||||
tsc_wrapped_tsconfig=_ngc_tsconfig,
|
||||
outputs = _expected_outs)
|
||||
|
||||
#addl_declarations = [_expected_outs(ctx)]
|
||||
#providers["typescript"]["declarations"] += addl_declarations
|
||||
#providers["typescript"]["transitive_declarations"] += addl_declarations
|
||||
providers["angular"] = {
|
||||
"summaries": _expected_outs(ctx, ctx.label).summaries
|
||||
}
|
||||
|
||||
return providers
|
||||
|
||||
def _ng_module_impl(ctx):
|
||||
return ts_providers_dict_to_struct(ng_module_impl(ctx, compile_ts))
|
||||
|
||||
NG_MODULE_ATTRIBUTES = {
|
||||
"srcs": attr.label_list(allow_files = [".ts"]),
|
||||
|
||||
"deps": attr.label_list(aspects = DEPS_ASPECTS + [_collect_summaries_aspect]),
|
||||
|
||||
"assets": attr.label_list(allow_files = [
|
||||
".css",
|
||||
# TODO(alexeagle): change this to ".ng.html" when usages updated
|
||||
".html",
|
||||
]),
|
||||
|
||||
# TODO(alexeagle): wire up when we have i18n in bazel
|
||||
"no_i18n": attr.bool(default = False),
|
||||
|
||||
"compiler": attr.label(
|
||||
default = Label("//src/ngc-wrapped"),
|
||||
executable = True,
|
||||
cfg = "host",
|
||||
),
|
||||
|
||||
# TODO(alexeagle): enable workers for ngc
|
||||
"_supports_workers": attr.bool(default = False),
|
||||
}
|
||||
|
||||
ng_module = rule(
|
||||
implementation = _ng_module_impl,
|
||||
attrs = COMMON_ATTRIBUTES + NG_MODULE_ATTRIBUTES + {
|
||||
"tsconfig": attr.label(allow_files = True, single_file = True),
|
||||
|
||||
# @// is special syntax for the "main" repository
|
||||
# The default assumes the user specified a target "node_modules" in their
|
||||
# root BUILD file.
|
||||
"node_modules": attr.label(
|
||||
default = Label("@//:node_modules")
|
||||
),
|
||||
},
|
||||
)
|
27
packages/bazel/src/ngc-wrapped/BUILD.bazel
Normal file
27
packages/bazel/src/ngc-wrapped/BUILD.bazel
Normal file
@ -0,0 +1,27 @@
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
|
||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
|
||||
|
||||
licenses(["notice"]) # Apache 2.0
|
||||
|
||||
ts_library(
|
||||
name = "ngc_lib",
|
||||
srcs = ["index.ts"],
|
||||
deps = [
|
||||
# BEGIN-INTERNAL
|
||||
# Only needed when compiling within the Angular repo.
|
||||
# Users will get this dependency from node_modules.
|
||||
"@//packages/compiler-cli",
|
||||
# END-INTERNAL
|
||||
"@build_bazel_rules_typescript//internal/tsc_wrapped"
|
||||
],
|
||||
tsconfig = ":tsconfig.json",
|
||||
)
|
||||
|
||||
nodejs_binary(
|
||||
name = "ngc-wrapped",
|
||||
# Entry point assumes the user is outside this WORKSPACE,
|
||||
# and references our rules with @angular//src/ngc-wrapped
|
||||
entry_point = "angular/src/ngc-wrapped/index.js",
|
||||
data = [":ngc_lib"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
3
packages/bazel/src/ngc-wrapped/README.md
Normal file
3
packages/bazel/src/ngc-wrapped/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# ngc-wrapped
|
||||
|
||||
This is a wrapper around @angular/compiler-cli that makes ngc run under Bazel.
|
187
packages/bazel/src/ngc-wrapped/index.ts
Normal file
187
packages/bazel/src/ngc-wrapped/index.ts
Normal file
@ -0,0 +1,187 @@
|
||||
/**
|
||||
* @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 ng from '@angular/compiler-cli';
|
||||
import {CompilerHost, UncachedFileLoader, parseTsconfig} from '@bazel/typescript';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as tsickle from 'tsickle';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
const EXT = /(\.ts|\.d\.ts|\.js|\.jsx|\.tsx)$/;
|
||||
// FIXME: we should be able to add the assets to the tsconfig so FileLoader
|
||||
// knows about them
|
||||
const NGC_NON_TS_INPUTS =
|
||||
/(\.(ngsummary|ngstyle|ngfactory)(\.d)?\.ts|\.ngsummary\.json|\.css|\.html)$/;
|
||||
// FIXME should need only summary, css, html
|
||||
|
||||
function topologicalSort(
|
||||
result: tsickle.FileMap<boolean>, current: string, modulesManifest: tsickle.ModulesManifest,
|
||||
visiting: tsickle.FileMap<boolean>) {
|
||||
const referencedModules = modulesManifest.getReferencedModules(current);
|
||||
if (!referencedModules) return; // not in the local set of sources.
|
||||
for (const referencedModule of referencedModules) {
|
||||
const referencedFileName = modulesManifest.getFileNameFromModule(referencedModule);
|
||||
if (!referencedFileName) continue; // Ambient modules.
|
||||
if (!result[referencedFileName]) {
|
||||
if (visiting[referencedFileName]) {
|
||||
const path = current + ' -> ' + Object.keys(visiting).join(' -> ');
|
||||
throw new Error('Cyclical dependency between files:\n' + path);
|
||||
}
|
||||
visiting[referencedFileName] = true;
|
||||
topologicalSort(result, referencedFileName, modulesManifest, visiting);
|
||||
delete visiting[referencedFileName];
|
||||
}
|
||||
}
|
||||
result[current] = true;
|
||||
}
|
||||
// TODO(alexeagle): move to tsc-wrapped in third_party so it's shared
|
||||
export function constructManifest(
|
||||
modulesManifest: tsickle.ModulesManifest,
|
||||
host: {flattenOutDir: (f: string) => string}): string {
|
||||
const result: tsickle.FileMap<boolean> = {};
|
||||
for (const file of modulesManifest.fileNames) {
|
||||
topologicalSort(result, file, modulesManifest, {});
|
||||
}
|
||||
|
||||
// NB: The object literal maintains insertion order.
|
||||
return Object.keys(result).map(fn => host.flattenOutDir(fn)).join('\n') + '\n';
|
||||
}
|
||||
|
||||
export function main(args) {
|
||||
const project = args[1];
|
||||
const [{options: tsOptions, bazelOpts, files, config}] = parseTsconfig(project);
|
||||
|
||||
const {basePath} = ng.calcProjectFileAndBasePath(project);
|
||||
const ngOptions = ng.createNgCompilerOptions(basePath, config, tsOptions);
|
||||
if (!bazelOpts.es5Mode) {
|
||||
ngOptions.annotateForClosureCompiler = true;
|
||||
ngOptions.annotationsAs = 'static fields';
|
||||
}
|
||||
|
||||
function relativeToRootDir(filePath: string): string {
|
||||
if (tsOptions.rootDir) {
|
||||
const rel = path.relative(tsOptions.rootDir, filePath);
|
||||
if (rel.indexOf('.') != 0) return rel;
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
const expectedOuts = [...config['angularCompilerOptions']['expectedOut']];
|
||||
const tsHost = ts.createCompilerHost(tsOptions, true);
|
||||
|
||||
const originalWriteFile = tsHost.writeFile.bind(tsHost);
|
||||
tsHost.writeFile =
|
||||
(fileName: string, content: string, writeByteOrderMark: boolean,
|
||||
onError?: (message: string) => void, sourceFiles?: ts.SourceFile[]) => {
|
||||
const relative = relativeToRootDir(fileName);
|
||||
const expectedIdx = expectedOuts.findIndex(o => o === relative);
|
||||
if (expectedIdx >= 0) {
|
||||
expectedOuts.splice(expectedIdx, 1);
|
||||
originalWriteFile(fileName, content, writeByteOrderMark, onError, sourceFiles);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Patch fileExists when resolving modules, so that ngc can ask TypeScript to
|
||||
// resolve non-existing generated files that don't exist on disk, but are
|
||||
// synthetic and added to the `programWithStubs` based on real inputs.
|
||||
const generatedFileModuleResolverHost = Object.create(tsHost);
|
||||
generatedFileModuleResolverHost.fileExists = (fileName: string) => {
|
||||
const match = /^(.*?)\.(ngfactory|ngsummary|ngstyle|shim\.ngstyle)(.*)$/.exec(fileName);
|
||||
if (match) {
|
||||
const [, file, suffix, ext] = match;
|
||||
// Performance: skip looking for files other than .d.ts or .ts
|
||||
if (ext !== '.ts' && ext !== '.d.ts') return false;
|
||||
if (suffix.indexOf('ngstyle') >= 0) {
|
||||
// Look for foo.css on disk
|
||||
fileName = file;
|
||||
} else {
|
||||
// Look for foo.d.ts or foo.ts on disk
|
||||
fileName = file + (ext || '');
|
||||
}
|
||||
}
|
||||
return tsHost.fileExists(fileName);
|
||||
};
|
||||
|
||||
function generatedFileModuleResolver(
|
||||
moduleName: string, containingFile: string,
|
||||
compilerOptions: ts.CompilerOptions): ts.ResolvedModuleWithFailedLookupLocations {
|
||||
return ts.resolveModuleName(
|
||||
moduleName, containingFile, compilerOptions, generatedFileModuleResolverHost);
|
||||
}
|
||||
|
||||
const bazelHost = new CompilerHost(
|
||||
files, tsOptions, bazelOpts, tsHost, new UncachedFileLoader(), generatedFileModuleResolver);
|
||||
bazelHost.allowNonHermeticRead = (filePath: string) =>
|
||||
NGC_NON_TS_INPUTS.test(filePath) || filePath.split(path.sep).indexOf('node_modules') != -1;
|
||||
bazelHost.shouldSkipTsickleProcessing = (fileName: string): boolean =>
|
||||
bazelOpts.compilationTargetSrc.indexOf(fileName) === -1 && !NGC_NON_TS_INPUTS.test(fileName);
|
||||
|
||||
const ngHost = ng.createCompilerHost({options: ngOptions, tsHost: bazelHost});
|
||||
|
||||
ngHost.fileNameToModuleName = (importedFilePath: string, containingFilePath: string) =>
|
||||
relativeToRootDir(importedFilePath).replace(EXT, '');
|
||||
ngHost.toSummaryFileName = (fileName: string, referringSrcFileName: string) =>
|
||||
ngHost.fileNameToModuleName(fileName, referringSrcFileName);
|
||||
|
||||
const tsickleOpts = {
|
||||
googmodule: bazelOpts.googmodule,
|
||||
es5Mode: bazelOpts.es5Mode,
|
||||
prelude: bazelOpts.prelude,
|
||||
untyped: bazelOpts.untyped,
|
||||
typeBlackListPaths: new Set(bazelOpts.typeBlackListPaths),
|
||||
transformDecorators: bazelOpts.tsickle,
|
||||
transformTypesToClosure: bazelOpts.tsickle,
|
||||
};
|
||||
const emitCallback: ng.TsEmitCallback = ({
|
||||
program,
|
||||
targetSourceFile,
|
||||
writeFile,
|
||||
cancellationToken,
|
||||
emitOnlyDtsFiles,
|
||||
customTransformers = {},
|
||||
}) =>
|
||||
tsickle.emitWithTsickle(
|
||||
program, bazelHost, tsickleOpts, bazelHost, ngOptions, targetSourceFile, writeFile,
|
||||
cancellationToken, emitOnlyDtsFiles, {
|
||||
beforeTs: customTransformers.before,
|
||||
afterTs: customTransformers.after,
|
||||
});
|
||||
|
||||
const {diagnostics, emitResult} =
|
||||
ng.performCompilation({rootNames: files, options: ngOptions, host: ngHost, emitCallback});
|
||||
const tsickleEmitResult = emitResult as tsickle.EmitResult;
|
||||
let externs = '/** @externs */\n';
|
||||
if (diagnostics.length) {
|
||||
console.error(ng.formatDiagnostics(ngOptions, diagnostics));
|
||||
} else {
|
||||
if (bazelOpts.tsickleGenerateExterns) {
|
||||
externs += tsickle.getGeneratedExterns(tsickleEmitResult.externs);
|
||||
}
|
||||
if (bazelOpts.manifest) {
|
||||
const manifest = constructManifest(tsickleEmitResult.modulesManifest, bazelHost);
|
||||
fs.writeFileSync(bazelOpts.manifest, manifest);
|
||||
}
|
||||
}
|
||||
|
||||
if (bazelOpts.tsickleExternsPath) {
|
||||
// Note: when tsickleExternsPath is provided, we always write a file as a
|
||||
// marker that compilation succeeded, even if it's empty (just containing an
|
||||
// @externs).
|
||||
fs.writeFileSync(bazelOpts.tsickleExternsPath, externs);
|
||||
}
|
||||
|
||||
for (const missing of expectedOuts) {
|
||||
originalWriteFile(missing, '', false);
|
||||
}
|
||||
|
||||
return diagnostics.some(d => d.category === ts.DiagnosticCategory.Error) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
process.exitCode = main(process.argv.slice(2));
|
||||
}
|
5
packages/bazel/src/ngc-wrapped/tsconfig.json
Normal file
5
packages/bazel/src/ngc-wrapped/tsconfig.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["es5", "es2015.collection", "es2015.core"]
|
||||
}
|
||||
}
|
9
packages/bazel/src/rules_typescript.bzl
Normal file
9
packages/bazel/src/rules_typescript.bzl
Normal file
@ -0,0 +1,9 @@
|
||||
# Allows different paths for these imports in google3
|
||||
load("@build_bazel_rules_typescript//internal:build_defs.bzl", "tsc_wrapped_tsconfig")
|
||||
|
||||
load(
|
||||
"@build_bazel_rules_typescript//internal:common/compilation.bzl",
|
||||
"COMMON_ATTRIBUTES", "compile_ts", "DEPS_ASPECTS", "ts_providers_dict_to_struct"
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_typescript//internal:common/json_marshal.bzl", "json_marshal")
|
@ -5,6 +5,7 @@ ts_library(
|
||||
name = "common",
|
||||
srcs = glob(["**/*.ts"], exclude=[
|
||||
"http/**",
|
||||
"i18n/**",
|
||||
"test/**",
|
||||
"testing/**",
|
||||
]),
|
||||
|
22
packages/common/i18n_data/extra/locale_af-NA.ts
Normal file
22
packages/common/i18n_data/extra/locale_af-NA.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['mn', 'o', 'm', 'a', 'n'],
|
||||
['middernag', 'die oggend', 'die middag', 'die aand', 'die nag'],
|
||||
],
|
||||
[
|
||||
['mn', 'o', 'm', 'a', 'n'],
|
||||
['middernag', 'oggend', 'middag', 'aand', 'nag'],
|
||||
],
|
||||
['00:00', ['05:00', '12:00'], ['12:00', '18:00'], ['18:00', '24:00'], ['00:00', '05:00']]
|
||||
];
|
22
packages/common/i18n_data/extra/locale_af.ts
Normal file
22
packages/common/i18n_data/extra/locale_af.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['mn', 'o', 'm', 'a', 'n'],
|
||||
['middernag', 'die oggend', 'die middag', 'die aand', 'die nag'],
|
||||
],
|
||||
[
|
||||
['mn', 'o', 'm', 'a', 'n'],
|
||||
['middernag', 'oggend', 'middag', 'aand', 'nag'],
|
||||
],
|
||||
['00:00', ['05:00', '12:00'], ['12:00', '18:00'], ['18:00', '24:00'], ['00:00', '05:00']]
|
||||
];
|
12
packages/common/i18n_data/extra/locale_agq.ts
Normal file
12
packages/common/i18n_data/extra/locale_agq.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [];
|
12
packages/common/i18n_data/extra/locale_ak.ts
Normal file
12
packages/common/i18n_data/extra/locale_ak.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [];
|
25
packages/common/i18n_data/extra/locale_am.ts
Normal file
25
packages/common/i18n_data/extra/locale_am.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['እኩለ ሌሊት', 'ቀ', 'ጥዋት1', 'ከሰዓት1', 'ማታ1', 'ሌሊት1'],
|
||||
['እኩለ ሌሊት', 'ቀትር', 'ጥዋት1', 'ከሰዓት1', 'ማታ1', 'ሌሊት1'],
|
||||
],
|
||||
[
|
||||
['እኩለ ሌሊት', 'ቀትር', 'ጥዋት', 'ከሰዓት በኋላ', 'ማታ', 'ሌሊት'],
|
||||
['እኩለ ሌሊት', 'ቀትር', 'ጥዋት1', 'ከሰዓት በኋላ', 'ማታ', 'ሌሊት'],
|
||||
],
|
||||
[
|
||||
'00:00', '12:00', ['06:00', '12:00'], ['12:00', '18:00'], ['18:00', '24:00'],
|
||||
['00:00', '06:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-AE.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-AE.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-BH.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-BH.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-DJ.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-DJ.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-DZ.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-DZ.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-EG.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-EG.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-EH.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-EH.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-ER.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-ER.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-IL.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-IL.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-IQ.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-IQ.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-JO.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-JO.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-KM.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-KM.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-KW.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-KW.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-LB.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-LB.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
27
packages/common/i18n_data/extra/locale_ar-LY.ts
Normal file
27
packages/common/i18n_data/extra/locale_ar-LY.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// THIS CODE IS GENERATED - DO NOT MODIFY
|
||||
// See angular/tools/gulp-tasks/cldr/extract.js
|
||||
|
||||
export default [
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ل'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'ص', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً'],
|
||||
['فجرًا', 'صباحًا', 'ظهرًا', 'بعد الظهر', 'مساءً', 'منتصف الليل', 'ليلاً']
|
||||
],
|
||||
[
|
||||
['03:00', '06:00'], ['06:00', '12:00'], ['12:00', '13:00'], ['13:00', '18:00'],
|
||||
['18:00', '24:00'], ['00:00', '01:00'], ['01:00', '03:00']
|
||||
]
|
||||
];
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user