From c8d2e0a3bcacb457d1acc6ac0a4e50656e314ceb Mon Sep 17 00:00:00 2001 From: George Kalpakas Date: Fri, 15 Dec 2017 20:14:47 +0200 Subject: [PATCH 001/475] test(aio): wait for Angular to avoid flake in e2e test (#21047) PR Close #21047 --- aio/e2e/app.e2e-spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aio/e2e/app.e2e-spec.ts b/aio/e2e/app.e2e-spec.ts index a8ac1490ea..fd4794c6e8 100644 --- a/aio/e2e/app.e2e-spec.ts +++ b/aio/e2e/app.e2e-spec.ts @@ -58,6 +58,7 @@ describe('site App', function() { expect(page.getScrollTop()).toBeGreaterThan(0); page.getNavItem(/api/i).click(); + browser.waitForAngular(); expect(page.locationPath()).toBe('/api'); expect(page.getScrollTop()).toBe(0); }); @@ -69,6 +70,7 @@ describe('site App', function() { expect(page.getScrollTop()).toBeGreaterThan(0); page.getNavItem(/security/i).click(); + browser.waitForAngular(); expect(page.locationPath()).toBe('/guide/security'); expect(page.getScrollTop()).toBe(0); }); From 4f1a571ba60e7f07b788ae72dd755089fb537b05 Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Fri, 5 Jan 2018 10:29:09 -0800 Subject: [PATCH 002/475] docs: remove broken issuestats.com badges (#21334) PR Close #21334 --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 8949113a75..8a945ef2ad 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,6 @@ [![CircleCI](https://circleci.com/gh/angular/angular/tree/master.svg?style=shield)](https://circleci.com/gh/angular/angular/tree/master) [![BrowserStack Status](https://www.browserstack.com/automate/badge.svg?badge_key=LzF3RzBVVGt6VWE2S0hHaC9uYllOZz09LS1BVjNTclBKV0x4eVRlcjA4QVY1M0N3PT0=--eb4ce8c8dc2c1c5b2b5352d473ee12a73ac20e06)](https://www.browserstack.com/automate/public-build/LzF3RzBVVGt6VWE2S0hHaC9uYllOZz09LS1BVjNTclBKV0x4eVRlcjA4QVY1M0N3PT0=--eb4ce8c8dc2c1c5b2b5352d473ee12a73ac20e06) [![Join the chat at https://gitter.im/angular/angular](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/angular/angular?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Issue Stats](http://issuestats.com/github/angular/angular/badge/pr?style=flat)](http://issuestats.com/github/angular/angular) -[![Issue Stats](http://issuestats.com/github/angular/angular/badge/issue?style=flat)](http://issuestats.com/github/angular/angular) [![npm version](https://badge.fury.io/js/%40angular%2Fcore.svg)](https://www.npmjs.com/@angular/core) From 24df08efc774f3767652417419f630c7b660c5d3 Mon Sep 17 00:00:00 2001 From: Jesus Rodriguez Date: Wed, 3 Jan 2018 21:53:22 +0100 Subject: [PATCH 003/475] build(aio): fix plunker for custom plunkers (#21291) PR Close #21291 --- aio/tools/plunker-builder/builder.js | 1 + 1 file changed, 1 insertion(+) diff --git a/aio/tools/plunker-builder/builder.js b/aio/tools/plunker-builder/builder.js index 3c7856a1af..8876520066 100644 --- a/aio/tools/plunker-builder/builder.js +++ b/aio/tools/plunker-builder/builder.js @@ -152,6 +152,7 @@ class PlunkerBuilder { // Matches main.ts or main.1.ts if (/^main(?:[.-]\w+)?\.ts$/.test(relativeFileName)) { content = fileTranslator.translate(content, mainTsRules); + relativeFileName = 'main.ts'; } if (relativeFileName == 'systemjs.config.extras.js') { From 6cd4b1b41c6c3af2e4baeae3b56243778b426082 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Thu, 14 Dec 2017 19:52:41 +0000 Subject: [PATCH 004/475] build(aio): add `@nodoc` alias to the `@internal` tag (#21024) The `@internal` tag prevents code items from appearing in the docs and the typings files. You can now use `@nodoc` if you only want it to be excluded from the docs and not the typings files. Closes #20990 PR Close #21024 --- .../angular-api-package/tag-defs/internal.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/aio/tools/transforms/angular-api-package/tag-defs/internal.js b/aio/tools/transforms/angular-api-package/tag-defs/internal.js index f981361298..39be3e5389 100644 --- a/aio/tools/transforms/angular-api-package/tag-defs/internal.js +++ b/aio/tools/transforms/angular-api-package/tag-defs/internal.js @@ -1,5 +1,16 @@ +/** + * Use this tag to ensure that dgeni does not include this code item + * in the rendered docs. + * + * The `@internal` tag indicates to the compiler not to include the + * item in the public typings file. + * Use the `@nodoc` alias if you only want to hide the item from the + * docs but not from the typings file. + */ module.exports = function() { return { - name: 'internal', transforms: function() { return true; } + name: 'internal', + aliases: ['nodoc'], + transforms: function() { return true; } }; }; From e726d8182254847bf1cf8b39d35ffcaa0f9f860e Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Wed, 3 Jan 2018 14:14:33 -0800 Subject: [PATCH 005/475] build: force fetch PR in merge script (#21295) Use `-f` when doing `git fetch` for the PR. Without it the `git fetch` will not overwrite what is currently fetched locally, in essence doing fast-forward only. PR Close #21295 --- scripts/github/merge-pr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/github/merge-pr b/scripts/github/merge-pr index 871811053c..24d286d13b 100755 --- a/scripts/github/merge-pr +++ b/scripts/github/merge-pr @@ -67,7 +67,7 @@ else fi -FETCH_PR="git fetch https://github.com/angular/angular.git pull/$PR_NUMBER/head:angular/pr/$PR_NUMBER" +FETCH_PR="git fetch https://github.com/angular/angular.git pull/$PR_NUMBER/head:angular/pr/$PR_NUMBER -f" CHERRY_PICK_PR="git cherry-pick angular/pr/$PR_NUMBER~$PR_SHA_COUNT..angular/pr/$PR_NUMBER" REWRITE_MESSAGE="git filter-branch -f --msg-filter \"$BASEDIR/utils/github_closes.js $PR_NUMBER\" HEAD~$PR_SHA_COUNT..HEAD" From f9436f7a5b382851379635ce4c56c615dfa2c77f Mon Sep 17 00:00:00 2001 From: lharries Date: Fri, 29 Dec 2017 22:36:22 +0000 Subject: [PATCH 006/475] docs(aio): delete duplicated word (#21129) PR Close #21129 --- aio/content/tutorial/toh-pt4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aio/content/tutorial/toh-pt4.md b/aio/content/tutorial/toh-pt4.md index 6223933b46..64de5949bb 100644 --- a/aio/content/tutorial/toh-pt4.md +++ b/aio/content/tutorial/toh-pt4.md @@ -121,7 +121,7 @@ Import the `HeroService` instead. -Replace the the definition of the `heroes` property with a simple declaration. +Replace the definition of the `heroes` property with a simple declaration. From 2fc4cf67be8b385a84b1b58d712a80f17a3a47ae Mon Sep 17 00:00:00 2001 From: Kara Erickson Date: Fri, 5 Jan 2018 13:27:40 -0800 Subject: [PATCH 007/475] build(core): update payload size of hello world (#21340) PR Close #21340 --- integration/_payload-limits.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/_payload-limits.json b/integration/_payload-limits.json index d40ec97f1d..732aa40f72 100644 --- a/integration/_payload-limits.json +++ b/integration/_payload-limits.json @@ -1,4 +1,4 @@ { -"cli-hello-world":{"master":{"gzip7":{"inline":847,"main":42533,"polyfills":20207},"gzip9":{"inline":847,"main":42483,"polyfills":20204},"uncompressed":{"inline":1447,"main":151954,"polyfills":61254}}}, +"cli-hello-world":{"master":{"gzip7":{"inline":847,"main":43542,"polyfills":20207},"gzip9":{"inline":847,"main":43471,"polyfills":20204},"uncompressed":{"inline":1447,"main":158096,"polyfills":61254}}}, "hello_world__closure":{"master":{"gzip7":{"bundle":32793},"gzip9":{"bundle":32758},"uncompressed":{"bundle":100661}}} } From fecf768f43d4500bd34c4445a79efaed177cd4e3 Mon Sep 17 00:00:00 2001 From: Olivier Combe Date: Wed, 13 Dec 2017 15:16:05 +0100 Subject: [PATCH 008/475] fix(common): export currencies via `getCurrencySymbol` (#20983) PR Close #20983 --- packages/common/src/common.ts | 3 +-- packages/common/src/i18n/currencies.ts | 2 +- packages/common/src/i18n/locale_data_api.ts | 19 ++++++++++++------- packages/common/src/pipes/number_pipe.ts | 4 ++-- .../common/test/i18n/locale_data_api_spec.ts | 15 ++++++++++++++- .../common/test/pipes/number_pipe_spec.ts | 1 + tools/public_api_guard/common/common.d.ts | 8 +++----- 7 files changed, 34 insertions(+), 18 deletions(-) diff --git a/packages/common/src/common.ts b/packages/common/src/common.ts index 3391cd21a3..1041b7bf3e 100644 --- a/packages/common/src/common.ts +++ b/packages/common/src/common.ts @@ -14,8 +14,7 @@ export * from './location/index'; export {NgLocaleLocalization, NgLocalization} from './i18n/localization'; export {registerLocaleData} from './i18n/locale_data'; -export {Plural, NumberFormatStyle, FormStyle, Time, TranslationWidth, FormatWidth, NumberSymbol, WeekDay, getLocaleDayPeriods, getLocaleDayNames, getLocaleMonthNames, getLocaleId, getLocaleEraNames, getLocaleWeekEndRange, getLocaleFirstDayOfWeek, getLocaleDateFormat, getLocaleDateTimeFormat, getLocaleExtraDayPeriodRules, getLocaleExtraDayPeriods, getLocalePluralCase, getLocaleTimeFormat, getLocaleNumberSymbol, getLocaleNumberFormat, getLocaleCurrencyName, getLocaleCurrencySymbol} from './i18n/locale_data_api'; -export {CURRENCIES} from './i18n/currencies'; +export {Plural, NumberFormatStyle, FormStyle, Time, TranslationWidth, FormatWidth, NumberSymbol, WeekDay, getCurrencySymbol, getLocaleDayPeriods, getLocaleDayNames, getLocaleMonthNames, getLocaleId, getLocaleEraNames, getLocaleWeekEndRange, getLocaleFirstDayOfWeek, getLocaleDateFormat, getLocaleDateTimeFormat, getLocaleExtraDayPeriodRules, getLocaleExtraDayPeriods, getLocalePluralCase, getLocaleTimeFormat, getLocaleNumberSymbol, getLocaleNumberFormat, getLocaleCurrencyName, getLocaleCurrencySymbol} from './i18n/locale_data_api'; export {parseCookieValue as ɵparseCookieValue} from './cookie'; export {CommonModule, DeprecatedI18NPipesModule} from './common_module'; export {NgClass, NgForOf, NgForOfContext, NgIf, NgIfContext, NgPlural, NgPluralCase, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet, NgComponentOutlet} from './directives/index'; diff --git a/packages/common/src/i18n/currencies.ts b/packages/common/src/i18n/currencies.ts index a81807aa69..944e1b423b 100644 --- a/packages/common/src/i18n/currencies.ts +++ b/packages/common/src/i18n/currencies.ts @@ -9,7 +9,7 @@ // THIS CODE IS GENERATED - DO NOT MODIFY // See angular/tools/gulp-tasks/cldr/extract.js -/** @experimental */ +/** @internal */ export const CURRENCIES: {[code: string]: (string | undefined)[]} = { 'AOA': [, 'Kz'], 'ARS': [, '$'], diff --git a/packages/common/src/i18n/locale_data_api.ts b/packages/common/src/i18n/locale_data_api.ts index 6cd27145c3..9e5ecb0ac7 100644 --- a/packages/common/src/i18n/locale_data_api.ts +++ b/packages/common/src/i18n/locale_data_api.ts @@ -527,12 +527,17 @@ export function findLocaleData(locale: string): any { /** * Return the currency symbol for a given currency code, or the code if no symbol available - * (e.g.: $, US$, or USD) + * (e.g.: format narrow = $, format wide = US$, code = USD) * - * @internal + * @experimental i18n support is experimental. */ -export function findCurrencySymbol(code: string, format: 'wide' | 'narrow') { - const currency = CURRENCIES[code] || {}; - const symbol = currency[0] || code; - return format === 'wide' ? symbol : currency[1] || symbol; -} \ No newline at end of file +export function getCurrencySymbol(code: string, format: 'wide' | 'narrow'): string { + const currency = CURRENCIES[code] || []; + const symbolNarrow = currency[1]; + + if (format === 'narrow' && typeof symbolNarrow === 'string') { + return symbolNarrow; + } + + return currency[0] || code; +} diff --git a/packages/common/src/pipes/number_pipe.ts b/packages/common/src/pipes/number_pipe.ts index 130e3a5384..bb4616c29a 100644 --- a/packages/common/src/pipes/number_pipe.ts +++ b/packages/common/src/pipes/number_pipe.ts @@ -8,7 +8,7 @@ import {Inject, LOCALE_ID, Pipe, PipeTransform} from '@angular/core'; import {formatNumber} from '../i18n/format_number'; -import {NumberFormatStyle, findCurrencySymbol, getLocaleCurrencyName, getLocaleCurrencySymbol} from '../i18n/locale_data_api'; +import {NumberFormatStyle, getCurrencySymbol, getLocaleCurrencyName, getLocaleCurrencySymbol} from '../i18n/locale_data_api'; import {invalidPipeArgumentError} from './invalid_pipe_argument_error'; /** @@ -143,7 +143,7 @@ export class CurrencyPipe implements PipeTransform { let currency = currencyCode || 'USD'; if (display !== 'code') { - currency = findCurrencySymbol(currency, display === 'symbol' ? 'wide' : 'narrow'); + currency = getCurrencySymbol(currency, display === 'symbol' ? 'wide' : 'narrow'); } const {str, error} = formatNumber(value, locale, NumberFormatStyle.Currency, digits, currency); diff --git a/packages/common/test/i18n/locale_data_api_spec.ts b/packages/common/test/i18n/locale_data_api_spec.ts index 667977e82d..911a4cc61d 100644 --- a/packages/common/test/i18n/locale_data_api_spec.ts +++ b/packages/common/test/i18n/locale_data_api_spec.ts @@ -11,7 +11,7 @@ import localeEn from '@angular/common/locales/en'; import localeFr from '@angular/common/locales/fr'; import localeFrCA from '@angular/common/locales/fr-CA'; import {registerLocaleData} from '../../src/i18n/locale_data'; -import {findLocaleData} from '../../src/i18n/locale_data_api'; +import {findLocaleData, getCurrencySymbol} from '../../src/i18n/locale_data_api'; { describe('locale data api', () => { @@ -51,5 +51,18 @@ import {findLocaleData} from '../../src/i18n/locale_data_api'; expect(findLocaleData('fake-id2')).toEqual(localeFrCA); }); }); + + describe('getCurrencySymbolElseCode', () => { + it('should return the correct symbol', () => { + expect(getCurrencySymbol('USD', 'wide')).toEqual('$'); + expect(getCurrencySymbol('USD', 'narrow')).toEqual('$'); + expect(getCurrencySymbol('AUD', 'wide')).toEqual('A$'); + expect(getCurrencySymbol('AUD', 'narrow')).toEqual('$'); + expect(getCurrencySymbol('CRC', 'wide')).toEqual('CRC'); + expect(getCurrencySymbol('CRC', 'narrow')).toEqual('₡'); + expect(getCurrencySymbol('FAKE', 'wide')).toEqual('FAKE'); + expect(getCurrencySymbol('FAKE', 'narrow')).toEqual('FAKE'); + }); + }); }); } diff --git a/packages/common/test/pipes/number_pipe_spec.ts b/packages/common/test/pipes/number_pipe_spec.ts index f4b6d83bb4..abc0eb6c1a 100644 --- a/packages/common/test/pipes/number_pipe_spec.ts +++ b/packages/common/test/pipes/number_pipe_spec.ts @@ -122,6 +122,7 @@ import {beforeEach, describe, expect, it} from '@angular/core/testing/src/testin expect(pipe.transform(5.1234, 'CAD', 'symbol-narrow', '5.2-2')).toEqual('$00,005.12'); expect(pipe.transform(5.1234, 'CAD', 'symbol-narrow', '5.2-2', 'fr')) .toEqual('00 005,12 $'); + expect(pipe.transform(5.1234, 'FAKE', 'symbol')).toEqual('FAKE5.12'); }); it('should not support other objects', () => { diff --git a/tools/public_api_guard/common/common.d.ts b/tools/public_api_guard/common/common.d.ts index 07ccaf97dd..40d879e2ea 100644 --- a/tools/public_api_guard/common/common.d.ts +++ b/tools/public_api_guard/common/common.d.ts @@ -15,11 +15,6 @@ export declare class AsyncPipe implements OnDestroy, PipeTransform { export declare class CommonModule { } -/** @experimental */ -export declare const CURRENCIES: { - [code: string]: (string | undefined)[]; -}; - /** @stable */ export declare class CurrencyPipe implements PipeTransform { constructor(_locale: string); @@ -83,6 +78,9 @@ export declare enum FormStyle { Standalone = 1, } +/** @experimental */ +export declare function getCurrencySymbol(code: string, format: 'wide' | 'narrow'): string; + /** @experimental */ export declare function getLocaleCurrencyName(locale: string): string | null; From d2cfc6a719c4470457259a5eb979f16a7bef67ba Mon Sep 17 00:00:00 2001 From: Marc Laval Date: Wed, 3 Jan 2018 10:45:09 +0100 Subject: [PATCH 009/475] build: activate render3 tests in CI (#21279) PR Close #21279 --- karma-js.conf.js | 1 - packages/core/src/render3/instructions.ts | 10 ++++++++++ packages/core/test/render3/component_spec.ts | 14 +++++++------- packages/core/test/render3/render_util.ts | 5 ++++- .../core/test/render3/renderer_factory_spec.ts | 6 +++--- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/karma-js.conf.js b/karma-js.conf.js index 50b812b9d6..4c5a80083f 100644 --- a/karma-js.conf.js +++ b/karma-js.conf.js @@ -58,7 +58,6 @@ module.exports = function(config) { 'dist/all/@angular/**/*node_only_spec.js', 'dist/all/@angular/benchpress/**', 'dist/all/@angular/compiler-cli/**', - 'dist/all/@angular/core/test/render3/**', 'dist/all/@angular/compiler/test/aot/**', 'dist/all/@angular/examples/**/e2e_test/*', 'dist/all/@angular/language-service/**', diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index 15862a9f2a..cd8f6b268d 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -264,6 +264,14 @@ export function createLNode( //// Render ////////////////////////// +/** + * Resets the application state. + */ +function resetApplicationState() { + isParent = false; + previousOrParentNode = null !; +} + /** * * @param host Existing node to render into. @@ -274,6 +282,7 @@ export function renderTemplate( hostNode: RElement, template: ComponentTemplate, context: T, providedRendererFactory: RendererFactory3, host: LElement | null): LElement { if (host == null) { + resetApplicationState(); rendererFactory = providedRendererFactory; host = createLNode( null, LNodeFlags.Element, hostNode, @@ -499,6 +508,7 @@ export function locateHostElement( * @param rNode Render host element. */ export function hostElement(rNode: RElement | null, def: ComponentDef) { + resetApplicationState(); createLNode( 0, LNodeFlags.Element, rNode, createViewState(-1, renderer, getTemplateStatic(def.template))); } diff --git a/packages/core/test/render3/component_spec.ts b/packages/core/test/render3/component_spec.ts index 1d54685d31..88c21aeea0 100644 --- a/packages/core/test/render3/component_spec.ts +++ b/packages/core/test/render3/component_spec.ts @@ -8,7 +8,7 @@ import {ViewEncapsulation} from '../../src/core'; import {D, E, T, b, defineComponent, e, markDirty, t} from '../../src/render3/index'; -import {createRendererType2} from '../../src/view'; +import {createRendererType2} from '../../src/view/index'; import {getRendererFactory2} from './imported_renderer2'; import {containerEl, renderComponent, requestAnimationFrame} from './render_util'; @@ -117,15 +117,15 @@ describe('encapsulation', () => { it('should encapsulate children, but not host nor grand children', () => { renderComponent(WrapperComponent, getRendererFactory2(document)); expect(containerEl.outerHTML) - .toEqual( - '
foobar
'); + .toMatch( + /
foobar<\/span><\/leaf><\/encapsulated><\/div>/); }); it('should encapsulate host', () => { renderComponent(EncapsulatedComponent, getRendererFactory2(document)); expect(containerEl.outerHTML) - .toEqual( - '
foobar
'); + .toMatch( + /
foobar<\/span><\/leaf><\/div>/); }); it('should encapsulate host and children with different attributes', () => { @@ -167,7 +167,7 @@ describe('encapsulation', () => { renderComponent(WrapperComponentWith, getRendererFactory2(document)); expect(containerEl.outerHTML) - .toEqual( - '
bar
'); + .toMatch( + /
bar<\/span><\/leaf><\/div>/); }); }); diff --git a/packages/core/test/render3/render_util.ts b/packages/core/test/render3/render_util.ts index d08b7808b3..0602cf0005 100644 --- a/packages/core/test/render3/render_util.ts +++ b/packages/core/test/render3/render_util.ts @@ -35,7 +35,10 @@ requestAnimationFrame.flush = function() { export function resetDOM() { requestAnimationFrame.queue = []; if (containerEl) { - document.body.removeChild(containerEl); + try { + document.body.removeChild(containerEl); + } catch (e) { + } } containerEl = document.createElement('div'); containerEl.setAttribute('host', ''); diff --git a/packages/core/test/render3/renderer_factory_spec.ts b/packages/core/test/render3/renderer_factory_spec.ts index dc5eadcadf..3640d91823 100644 --- a/packages/core/test/render3/renderer_factory_spec.ts +++ b/packages/core/test/render3/renderer_factory_spec.ts @@ -10,8 +10,8 @@ import {AnimationEvent} from '@angular/animations'; import {MockAnimationDriver, MockAnimationPlayer} from '@angular/animations/browser/testing'; import {RendererType2, ViewEncapsulation} from '../../src/core'; -import {D, E, L, T, b, defineComponent, detectChanges, e, p} from '../../src/render3'; -import {createRendererType2} from '../../src/view'; +import {D, E, L, T, b, defineComponent, detectChanges, e, p} from '../../src/render3/index'; +import {createRendererType2} from '../../src/view/index'; import {getAnimationRendererFactory2, getRendererFactory2} from './imported_renderer2'; import {containerEl, document, renderComponent, renderToHtml} from './render_util'; @@ -185,7 +185,7 @@ describe('animation renderer factory', () => { const factory = getAnimationRendererFactory2(document); const component = renderComponent(SomeComponentWithAnimation, factory); expect(containerEl.innerHTML) - .toEqual('
foo
'); + .toMatch(/
foo<\/div>/); component.exp = 'on'; detectChanges(component); From a2f3f4550d6e87e64987ba27b961c8d39f25899b Mon Sep 17 00:00:00 2001 From: Marc Laval Date: Wed, 3 Jan 2018 11:42:48 +0100 Subject: [PATCH 010/475] test(core): properly stringify HTML elements in render3 tests (#21279) PR Close #21279 --- packages/core/test/render3/BUILD.bazel | 3 +++ packages/core/test/render3/component_spec.ts | 14 +++++++------- packages/core/test/render3/exports_spec.ts | 2 +- packages/core/test/render3/integration_spec.ts | 2 +- packages/core/test/render3/load_domino.ts | 9 ++++++--- packages/core/test/render3/properties_spec.ts | 4 ++-- packages/core/test/render3/render_util.ts | 7 ++++++- .../core/test/render3/renderer_factory_spec.ts | 6 +++--- 8 files changed, 29 insertions(+), 18 deletions(-) diff --git a/packages/core/test/render3/BUILD.bazel b/packages/core/test/render3/BUILD.bazel index b237d7c817..c7520c46b5 100644 --- a/packages/core/test/render3/BUILD.bazel +++ b/packages/core/test/render3/BUILD.bazel @@ -23,6 +23,7 @@ ts_library( "//packages/core", "//packages/platform-browser", "//packages/platform-browser/animations", + "//packages/platform-browser/testing", ], ) @@ -36,6 +37,8 @@ ts_library( tsconfig = "//packages:tsconfig", deps = [ ":render3_lib", + "//packages/platform-browser", + "//packages/platform-server", ], ) diff --git a/packages/core/test/render3/component_spec.ts b/packages/core/test/render3/component_spec.ts index 88c21aeea0..07039a2e96 100644 --- a/packages/core/test/render3/component_spec.ts +++ b/packages/core/test/render3/component_spec.ts @@ -11,7 +11,7 @@ import {D, E, T, b, defineComponent, e, markDirty, t} from '../../src/render3/in import {createRendererType2} from '../../src/view/index'; import {getRendererFactory2} from './imported_renderer2'; -import {containerEl, renderComponent, requestAnimationFrame} from './render_util'; +import {containerEl, renderComponent, requestAnimationFrame, toHtml} from './render_util'; describe('component', () => { class CounterComponent { @@ -37,22 +37,22 @@ describe('component', () => { describe('renderComponent', () => { it('should render on initial call', () => { renderComponent(CounterComponent); - expect(containerEl.innerHTML).toEqual('0'); + expect(toHtml(containerEl)).toEqual('0'); }); it('should re-render on input change or method invocation', () => { const component = renderComponent(CounterComponent); - expect(containerEl.innerHTML).toEqual('0'); + expect(toHtml(containerEl)).toEqual('0'); component.count = 123; markDirty(component, requestAnimationFrame); - expect(containerEl.innerHTML).toEqual('0'); + expect(toHtml(containerEl)).toEqual('0'); requestAnimationFrame.flush(); - expect(containerEl.innerHTML).toEqual('123'); + expect(toHtml(containerEl)).toEqual('123'); component.increment(); markDirty(component, requestAnimationFrame); - expect(containerEl.innerHTML).toEqual('123'); + expect(toHtml(containerEl)).toEqual('123'); requestAnimationFrame.flush(); - expect(containerEl.innerHTML).toEqual('124'); + expect(toHtml(containerEl)).toEqual('124'); }); }); diff --git a/packages/core/test/render3/exports_spec.ts b/packages/core/test/render3/exports_spec.ts index b7bff98f66..6f474a6918 100644 --- a/packages/core/test/render3/exports_spec.ts +++ b/packages/core/test/render3/exports_spec.ts @@ -176,7 +176,7 @@ describe('exports', () => { } expect(renderToHtml(Template, {})) - .toEqual('
'); + .toEqual('
'); }); it('should work with component refs', () => { diff --git a/packages/core/test/render3/integration_spec.ts b/packages/core/test/render3/integration_spec.ts index a28fa95415..3a50e0b939 100644 --- a/packages/core/test/render3/integration_spec.ts +++ b/packages/core/test/render3/integration_spec.ts @@ -11,7 +11,7 @@ import {NO_CHANGE} from '../../src/render3/instructions'; import {containerEl, renderToHtml} from './render_util'; -describe('iv integration test', () => { +describe('render3 integration test', () => { describe('render', () => { diff --git a/packages/core/test/render3/load_domino.ts b/packages/core/test/render3/load_domino.ts index e07ef10a9c..49e7b406df 100644 --- a/packages/core/test/render3/load_domino.ts +++ b/packages/core/test/render3/load_domino.ts @@ -9,11 +9,14 @@ // Needed to run animation tests require('zone.js/dist/zone-node.js'); +import {DominoAdapter} from '@angular/platform-server/src/domino_adapter'; +import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; + if (typeof window == 'undefined') { const domino = require('domino'); - const createWindow = domino.createWindow; - const window = createWindow('', 'http://localhost'); - (global as any).document = window.document; + + DominoAdapter.makeCurrent(); + (global as any).document = getDOM().getDefaultDocument(); // Trick to avoid Event patching from // https://github.com/angular/angular/blob/7cf5e95ac9f0f2648beebf0d5bd9056b79946970/packages/platform-browser/src/dom/events/dom_events.ts#L112-L132 diff --git a/packages/core/test/render3/properties_spec.ts b/packages/core/test/render3/properties_spec.ts index 2a62921ad0..d5be8b17eb 100644 --- a/packages/core/test/render3/properties_spec.ts +++ b/packages/core/test/render3/properties_spec.ts @@ -396,7 +396,7 @@ describe('elementProperty', () => { } } - expect(renderToHtml(Template, {})).toEqual(`
`); + expect(renderToHtml(Template, {})).toEqual(`
`); expect(myDir !.role).toEqual('button'); expect(myDir !.direction).toEqual('rtl'); }); @@ -444,7 +444,7 @@ describe('elementProperty', () => { } expect(renderToHtml(Template, {})) - .toEqual(`
`); + .toEqual(`
`); expect(myDir !.role).toEqual('button'); expect(myDir !.direction).toEqual('rtl'); expect(dirB !.roleB).toEqual('listbox'); diff --git a/packages/core/test/render3/render_util.ts b/packages/core/test/render3/render_util.ts index 0602cf0005..e7b7936b32 100644 --- a/packages/core/test/render3/render_util.ts +++ b/packages/core/test/render3/render_util.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ +import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util'; import {ComponentTemplate, ComponentType, DirectiveType, PublicFeature, defineComponent, defineDirective, renderComponent as _renderComponent} from '../../src/render3/index'; import {NG_HOST_SYMBOL, createLNode, createViewState, renderTemplate} from '../../src/render3/instructions'; import {LElement, LNodeFlags} from '../../src/render3/interfaces'; @@ -66,7 +67,11 @@ export function toHtml(componentOrElement: T | RElement): string { if (node) { return toHtml(node.native); } else { - return containerEl.innerHTML.replace(' style=""', '').replace(//g, ''); + return stringifyElement(componentOrElement) + .replace(/^
/, '') + .replace(/<\/div>$/, '') + .replace(' style=""', '') + .replace(//g, ''); } } diff --git a/packages/core/test/render3/renderer_factory_spec.ts b/packages/core/test/render3/renderer_factory_spec.ts index 3640d91823..3f885f42b5 100644 --- a/packages/core/test/render3/renderer_factory_spec.ts +++ b/packages/core/test/render3/renderer_factory_spec.ts @@ -14,7 +14,7 @@ import {D, E, L, T, b, defineComponent, detectChanges, e, p} from '../../src/ren import {createRendererType2} from '../../src/view/index'; import {getAnimationRendererFactory2, getRendererFactory2} from './imported_renderer2'; -import {containerEl, document, renderComponent, renderToHtml} from './render_util'; +import {containerEl, document, renderComponent, renderToHtml, toHtml} from './render_util'; describe('renderer factory lifecycle', () => { let logs: string[] = []; @@ -178,13 +178,13 @@ describe('animation renderer factory', () => { it('should work with components without animations', () => { renderComponent(SomeComponent, getAnimationRendererFactory2(document)); - expect(containerEl.innerHTML).toEqual('foo'); + expect(toHtml(containerEl)).toEqual('foo'); }); it('should work with animated components', (done) => { const factory = getAnimationRendererFactory2(document); const component = renderComponent(SomeComponentWithAnimation, factory); - expect(containerEl.innerHTML) + expect(toHtml(containerEl)) .toMatch(/
foo<\/div>/); component.exp = 'on'; From db55e86e91fce79a49950bfef0d00eb24315f057 Mon Sep 17 00:00:00 2001 From: Marc Laval Date: Wed, 3 Jan 2018 14:05:33 +0100 Subject: [PATCH 011/475] fix(core): make all render3 tests pass in IE9 (#21279) PR Close #21279 --- packages/core/src/render3/instructions.ts | 5 +++-- packages/platform-browser/testing/src/browser_util.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index cd8f6b268d..35b24224be 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -596,8 +596,9 @@ export function elementAttribute(index: number, attrName: string, value: any): v element.native.removeAttribute(attrName); } else { (renderer as ProceduralRenderer3).setAttribute ? - (renderer as ProceduralRenderer3).setAttribute(element.native, attrName, value) : - element.native.setAttribute(attrName, value); + (renderer as ProceduralRenderer3) + .setAttribute(element.native, attrName, stringify(value)) : + element.native.setAttribute(attrName, stringify(value)); } } } diff --git a/packages/platform-browser/testing/src/browser_util.ts b/packages/platform-browser/testing/src/browser_util.ts index 875e378d56..221c924fe9 100644 --- a/packages/platform-browser/testing/src/browser_util.ts +++ b/packages/platform-browser/testing/src/browser_util.ts @@ -104,10 +104,11 @@ export function stringifyElement(el: any /** TODO #9100 */): string { for (let i = 0; i < keys.length; i++) { const key = keys[i]; const attValue = attributeMap.get(key); + const lowerCaseKey = key.toLowerCase(); if (typeof attValue !== 'string') { - result += ` ${key}`; + result += ` ${lowerCaseKey}`; } else { - result += ` ${key}="${attValue}"`; + result += ` ${lowerCaseKey}="${attValue}"`; } } result += '>'; From b15d50af9b92dafe6eaee5318e4b5c823253f25d Mon Sep 17 00:00:00 2001 From: Kara Erickson Date: Fri, 5 Jan 2018 15:44:45 -0800 Subject: [PATCH 012/475] build(core): improve payload size failure message (#21346) PR Close #21346 --- scripts/ci/payload-size.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/ci/payload-size.js b/scripts/ci/payload-size.js index bf0f04028e..bf1699ab55 100644 --- a/scripts/ci/payload-size.js +++ b/scripts/ci/payload-size.js @@ -23,8 +23,13 @@ for (const compressionType in limitSizes) { if (Math.abs(actualSize - expectedSize) > expectedSize / 100) { failed = true; + // We must also catch when the size is significantly lower than the payload limit, so + // we are forced to update the expected payload number when the payload size reduces. + // Otherwise, we won't be able to catch future regressions that happen to be below + // the artificially inflated limit. + const operator = actualSize > expectedSize ? 'exceeded' : 'fell below'; console.log( - `Commit ${commit} ${compressionType} ${filename} exceeded expected size by >1% ` + + `Commit ${commit} ${compressionType} ${filename} ${operator} expected size by >1% ` + `(expected: ${expectedSize}, actual: ${actualSize}).`); } } From e99475260fe1e64e923d95c3f0a1787551ab045c Mon Sep 17 00:00:00 2001 From: chembu Date: Fri, 5 Jan 2018 08:10:35 -0800 Subject: [PATCH 013/475] docs(aio): document the template compiler options (#21333) PR Close #21333 --- aio/content/guide/aot-compiler.md | 322 +++++++++++++++++- packages/compiler-cli/src/transformers/api.ts | 2 +- 2 files changed, 322 insertions(+), 2 deletions(-) diff --git a/aio/content/guide/aot-compiler.md b/aio/content/guide/aot-compiler.md index 2f126c0ad1..e513e649f5 100644 --- a/aio/content/guide/aot-compiler.md +++ b/aio/content/guide/aot-compiler.md @@ -2,7 +2,7 @@ The Angular Ahead-of-Time (AOT) compiler converts your Angular HTML and TypeScript code into efficient JavaScript code during the build phase _before_ the browser downloads and runs that code. -This guide explains how to build with the AOT compiler and how to write Angular metadata that AOT can compile. +This guide explains how to build with the AOT compiler using different compiler options and how to write Angular metadata that AOT can compile.
@@ -77,6 +77,174 @@ AOT compiles HTML templates and components into JavaScript files long before the With no templates to read and no risky client-side HTML or JavaScript evaluation, there are fewer opportunities for injection attacks. +{@a compiler-options} + + ## Angular Compiler Options + + You can control your app compilation by providing template compiler options in the `tsconfig.json` file along with the options supplied to the TypeScript compiler. The template compiler options are specified as members of + `"angularCompilerOptions"` object as shown below: + + ```json + { + "compilerOptions": { + "experimentalDecorators": true, + ... + }, + "angularCompilerOptions": { + "fullTemplateTypeCheck": true, + "preserveWhiteSpace": false, + ... + } + } + ``` + + ### *skipMetadataEmit* + + This option tells the compiler not to produce `.metadata.json` files. + The option is `false` by default. + + `.metadata.json` files contain infomration needed by the template compiler from a `.ts` + file that is not included in the `.d.ts` file produced by the TypeScript compiler. This information contains, + for example, the content of annotations (such as a component's template) which TypeScript + emits to the `.js` file but not to the `.d.ts` file. + + This option should be set to `true` if using TypeScript's `--outFile` option, as the metadata files + are not valid for this style of TypeScript output. It is not recommeded to use `--outFile` with + Angular. Use a bundler, such as [webpack](https://webpack.js.org/), instead. + + This option can also be set to `true` when using factory summaries as the factory summaries + include a copy of the information that is in the `.metadata.json` file. + + ### *strictMetadataEmit* + + This option tells the template compiler to report an error to the `.metadata.json` + file if `"skipMetadataEmit"` is `false` . This option is `false` by default. This should only be used when `"skipMetadataEmit"` is `false` and `"skipTemplateCodeGen"` is `true`. + + It is intended to validate the `.metadata.json` files emitted for bundling with an `npm` package. The validation is overly strict and can emit errors for metadata that would never produce an error when used by the template compiler. You can choose to suppress the error emitted by this option for an exported symbol by including `@dynamic` in the comment documenting the symbol. + + It is valid for `.metadata.json` files to contain errors. The template compiler reports these errors + if the metadata is used to determine the contents of an annotation. The metadata + collector cannot predict the symbols that are designed to use in an annotation, so it will preemptively + include error nodes in the metadata for the exported symbols. The template compiler can then use the error + nodes to report an error if these symbols are used. If the client of a library intends to use a symbol in an annotation, the template compiler will not normally report + this until the client uses the symbol. This option allows detecting these errors during the build phase of + the library and is used, for example, in producing Angular libraries themselves. + + ### *skipTemplateCodegen* + + This option tells the compiler to suppress emitting `.ngfactory.js` and `.ngstyle.js` files. When set, + this turns off most of the template compiler and disables reporting template diagnostics. + This option can be used to instruct the + template compiler to produce `.metadata.json` files for distribution with an `npm` package while + avoiding the production of `.ngfactory.js` and `.ngstyle.js` files that cannot be distributed to + `npm`. + + ### *strictInjectionParameters* + + When set to `true`, this options tells the compiler to report an error for a parameter supplied + whose injection type cannot be determined. When this value option is not provided or is `false`, constructor parameters of classes marked with `@Injectable` whose type cannot be resolved will + produce a warning. + + *Note*: It is recommended to change this option explicitly to `true` as this option will default to `true` in the future. + + ### *flatModuleOutFile* + + When set to `true`, this option tells the template compiler to generate a flat module + index of the given file name and the corresponding flat module metadata. Use this option when creating + flat modules that are packaged similarly to `@angular/core` and `@angular/common`. When this option + is used, the `package.json` for the library should refer + to the generated flat module index instead of the library index file. With this + option only one `.metadata.json` file is produced that contains all the metadata necessary + for symbols exported from the library index. In the generated `.ngfactory.js` files, the flat + module index is used to import symbols that includes both the public API from the library index + as well as shrowded internal symbols. + + By default the `.ts` file supplied in the `files` field is assumed to be library index. + If more than one `.ts` file is specified, `libraryIndex` is used to select the file to use. + If more than one `.ts` file is supplied without a `libraryIndex`, an error is produced. A flat module + index `.d.ts` and `.js` will be created with the given `flatModuleOutFile` name in the same + location as the library index `.d.ts` file. For example, if a library uses + `public_api.ts` file as the library index of the module, the `tsconfig.json` `files` field + would be `["public_api.ts"]`. The `flatModuleOutFile` options could then be set to, for + example `"index.js"`, which produces `index.d.ts` and `index.metadata.json` files. The + library's `package.json`'s `module` field would be `"index.js"` and the `typings` field + would be `"index.d.ts"`. + + ### *flatModuleId* + + This option specifies the preferred module id to use for importing a flat module. + References generated by the template compiler will use this module name when importing symbols + from the flat module. + This is only meaningful when `flatModuleOutFile` is also supplied. Otherwise the compiler ignores + this option. + + ### *generateCodeForLibraries* + + This option tells the template compiler to generate factory files (`.ngfactory.js` and `.ngstyle.js`) + for `.d.ts` files with a corresponding `.metadata.json` file. This option defaults to + `true`. When this option is `false`, factory files are generated only for `.ts` files. + + This option should be set to `false` when using factory summaries. + + ### *fullTemplateTypeCheck* + + This option tells the compiler to enable the [binding expression validation](#binding-expresion-validation) + phase of the template compiler which uses TypeScript to validate binding expressions. + + This option is `false` by default. + + *Note*: It is recommended to set this to `true` as this option will default to `true` in the future. + + ### *annotateForClosureCompiler* + + This option tells the compiler to use [Tsickle](https://github.com/angular/tsickle) to annotate the emitted + JavaScript with [JsDoc](http://usejsdoc.org/) comments needed by the + [Closure Compiler](https://github.com/google/closure-compiler). This option defaults to `false`. + + ### *annotationsAs* + + Use this option to modify how the Angular specific annotations are emitted to improve tree-shaking. Non-Angular + annotations and decorators are unnaffected. Default is `static fields`. + + value | description + ----------------|------------------------------------------------------------- + `decorators` | Leave the Decorators in-place. This makes compilation faster. TypeScript will emit calls to the __decorate helper. Use `--emitDecoratorMetadata` for runtime reflection. However, the resulting code will not properly tree-shake. + `static fields` | Replace decorators with a static field in the class. Allows advanced tree-shakers like [Closure Compiler](https://github.com/google/closure-compiler) to remove unused classes. + + ### *trace* + + This tells the compiler to print extra information while compiling templates. + + ### *enableLegacyTemplate* + + The use of `