From 9147092a156203d46cd1c865e06fa72a1e2d4137 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Mon, 15 Apr 2019 15:26:57 -0700 Subject: [PATCH] Revert "feat(ivy): use i18n locale data to determine the plural form of ICU expressions (#29249)" (#29918) This reverts commit 6a8cca797536dc69e18266741d70790eccb2121d. PR Close #29918 --- packages/common/src/i18n/locale_data.ts | 31 +- packages/common/src/i18n/locale_data_api.ts | 51 ++- .../{core => common}/src/i18n/locale_en.ts | 0 .../common/test/i18n/locale_data_api_spec.ts | 3 +- .../src/ngtsc/annotations/src/ng_module.ts | 21 +- packages/compiler-cli/src/ngtsc/program.ts | 3 +- packages/core/src/application_ref.ts | 5 - packages/core/src/core_private_export.ts | 2 - .../core/src/core_render3_private_export.ts | 2 - packages/core/src/i18n/locale_data.ts | 38 -- packages/core/src/i18n/locale_data_api.ts | 53 --- packages/core/src/i18n/localization.ts | 31 -- packages/core/src/render3/component.ts | 2 +- packages/core/src/render3/definition.ts | 6 +- packages/core/src/render3/fields.ts | 1 - packages/core/src/render3/i18n.ts | 382 ++++++++++++++++-- packages/core/src/render3/index.ts | 3 - packages/core/src/render3/jit/module.ts | 1 + packages/core/src/render3/ng_module_ref.ts | 8 +- packages/core/test/BUILD.bazel | 1 - packages/core/test/application_ref_spec.ts | 21 +- packages/core/test/i18n_integration_spec.ts | 45 +-- packages/core/test/render3/BUILD.bazel | 1 - packages/core/test/render3/i18n_spec.ts | 60 +-- .../core/testing/src/r3_test_bed_compiler.ts | 9 +- tools/gulp-tasks/cldr/extract.js | 15 +- tools/public_api_guard/common/common.d.ts | 2 +- 27 files changed, 451 insertions(+), 346 deletions(-) rename packages/{core => common}/src/i18n/locale_en.ts (100%) delete mode 100644 packages/core/src/i18n/locale_data.ts delete mode 100644 packages/core/src/i18n/locale_data_api.ts delete mode 100644 packages/core/src/i18n/localization.ts diff --git a/packages/common/src/i18n/locale_data.ts b/packages/common/src/i18n/locale_data.ts index 975dcc0b69..1d3301999a 100644 --- a/packages/common/src/i18n/locale_data.ts +++ b/packages/common/src/i18n/locale_data.ts @@ -6,7 +6,10 @@ * found in the LICENSE file at https://angular.io/license */ -import {ɵLOCALE_DATA as LOCALE_DATA, ɵLocaleDataIndex as LocaleDataIndex} from '@angular/core'; +/** + * @publicApi + */ +export const LOCALE_DATA: {[localeId: string]: any} = {}; /** * Register global data to be used internally by Angular. See the @@ -30,6 +33,32 @@ export function registerLocaleData(data: any, localeId?: string | any, extraData } } +/** + * Index of each type of locale data from the locale data array + */ +export const enum LocaleDataIndex { + LocaleId = 0, + DayPeriodsFormat, + DayPeriodsStandalone, + DaysFormat, + DaysStandalone, + MonthsFormat, + MonthsStandalone, + Eras, + FirstDayOfWeek, + WeekendRange, + DateFormat, + TimeFormat, + DateTimeFormat, + NumberSymbols, + NumberFormats, + CurrencySymbol, + CurrencyName, + Currencies, + PluralCase, + ExtraData +} + /** * Index of each type of locale data from the extra locale data array */ diff --git a/packages/common/src/i18n/locale_data_api.ts b/packages/common/src/i18n/locale_data_api.ts index 072add5903..46d02421cc 100644 --- a/packages/common/src/i18n/locale_data_api.ts +++ b/packages/common/src/i18n/locale_data_api.ts @@ -6,9 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import {ɵLocaleDataIndex as LocaleDataIndex, ɵfindLocaleData as findLocaleData, ɵgetLocalePluralCase} from '@angular/core'; +import localeEn from './locale_en'; +import {LOCALE_DATA, LocaleDataIndex, ExtraLocaleDataIndex, CurrencyIndex} from './locale_data'; import {CURRENCIES_EN, CurrenciesSymbols} from './currencies'; -import {CurrencyIndex, ExtraLocaleDataIndex} from './locale_data'; /** * Format styles that can be used to represent numbers. @@ -31,8 +31,7 @@ export enum NumberFormatStyle { * @see `NgPluralCase` * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n) * - * @publicApi - */ + * @publicApi */ export enum Plural { Zero = 0, One = 1, @@ -486,11 +485,19 @@ function getLocaleCurrencies(locale: string): {[code: string]: CurrenciesSymbols } /** - * @alias core/ɵgetLocalePluralCase + * Retrieves the plural function used by ICU expressions to determine the plural case to use + * for a given locale. + * @param locale A locale code for the locale format rules to use. + * @returns The plural function for the locale. + * @see `NgPlural` + * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n) + * * @publicApi */ -export const getLocalePluralCase: (locale: string) => ((value: number) => Plural) = - ɵgetLocalePluralCase; +export function getLocalePluralCase(locale: string): (value: number) => Plural { + const data = findLocaleData(locale); + return data[LocaleDataIndex.PluralCase]; +} function checkFullData(data: any) { if (!data[LocaleDataIndex.ExtraData]) { @@ -602,7 +609,37 @@ function extractTime(time: string): Time { return {hours: +h, minutes: +m}; } +/** + * Finds the locale data for a given locale. + * + * @param locale The locale code. + * @returns The locale data. + * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n) + * + * @publicApi + */ +export function findLocaleData(locale: string): any { + const normalizedLocale = locale.toLowerCase().replace(/_/g, '-'); + let match = LOCALE_DATA[normalizedLocale]; + if (match) { + return match; + } + + // let's try to find a parent locale + const parentLocale = normalizedLocale.split('-')[0]; + match = LOCALE_DATA[parentLocale]; + + if (match) { + return match; + } + + if (parentLocale === 'en') { + return localeEn; + } + + throw new Error(`Missing locale data for the locale "${locale}".`); +} /** * Retrieves the currency symbol for a given currency code. diff --git a/packages/core/src/i18n/locale_en.ts b/packages/common/src/i18n/locale_en.ts similarity index 100% rename from packages/core/src/i18n/locale_en.ts rename to packages/common/src/i18n/locale_en.ts diff --git a/packages/common/test/i18n/locale_data_api_spec.ts b/packages/common/test/i18n/locale_data_api_spec.ts index 6babf0bd20..9fee387070 100644 --- a/packages/common/test/i18n/locale_data_api_spec.ts +++ b/packages/common/test/i18n/locale_data_api_spec.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {ɵfindLocaleData as findLocaleData} from '@angular/core'; import localeCaESVALENCIA from '@angular/common/locales/ca-ES-VALENCIA'; import localeEn from '@angular/common/locales/en'; import localeFr from '@angular/common/locales/fr'; @@ -14,7 +13,7 @@ import localeZh from '@angular/common/locales/zh'; import localeFrCA from '@angular/common/locales/fr-CA'; import localeEnAU from '@angular/common/locales/en-AU'; import {registerLocaleData} from '../../src/i18n/locale_data'; -import {getCurrencySymbol, getLocaleDateFormat, FormatWidth, getNumberOfCurrencyDigits} from '../../src/i18n/locale_data_api'; +import {findLocaleData, getCurrencySymbol, getLocaleDateFormat, FormatWidth, getNumberOfCurrencyDigits} from '../../src/i18n/locale_data_api'; { describe('locale data api', () => { diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts b/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts index de599637a3..f82c2db834 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts @@ -6,8 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Expression, ExternalExpr, InvokeFunctionExpr, LiteralArrayExpr, LiteralExpr, R3Identifiers, R3InjectorMetadata, R3NgModuleMetadata, R3Reference, Statement, WrappedNodeExpr, compileInjector, compileNgModule} from '@angular/compiler'; -import {STRING_TYPE} from '@angular/compiler/src/output/output_ast'; +import {Expression, ExternalExpr, InvokeFunctionExpr, LiteralArrayExpr, R3Identifiers, R3InjectorMetadata, R3NgModuleMetadata, R3Reference, Statement, WrappedNodeExpr, compileInjector, compileNgModule} from '@angular/compiler'; import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError} from '../../diagnostics'; @@ -18,6 +17,7 @@ import {NgModuleRouteAnalyzer} from '../../routing'; import {LocalModuleScopeRegistry, ScopeData} from '../../scope'; import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence, ResolveResult} from '../../transform'; import {getSourceFile} from '../../util/src/typescript'; + import {generateSetClassMetadataCall} from './metadata'; import {ReferencesRegistry} from './references_registry'; import {combineResolvers, findAngularDecorator, forwardRefResolver, getValidConstructorDependencies, isExpressionForwardReference, toR3Reference, unwrapExpression} from './util'; @@ -41,7 +41,7 @@ export class NgModuleDecoratorHandler implements DecoratorHandler remove(this._modules, moduleRef)); ngZone !.runOutsideAngular( () => ngZone !.onError.subscribe( diff --git a/packages/core/src/core_private_export.ts b/packages/core/src/core_private_export.ts index a97e2d467e..1a446cbee5 100644 --- a/packages/core/src/core_private_export.ts +++ b/packages/core/src/core_private_export.ts @@ -34,5 +34,3 @@ export {makeDecorator as ɵmakeDecorator} from './util/decorators'; export {isObservable as ɵisObservable, isPromise as ɵisPromise} from './util/lang'; export {clearOverrides as ɵclearOverrides, initServicesIfNeeded as ɵinitServicesIfNeeded, overrideComponentView as ɵoverrideComponentView, overrideProvider as ɵoverrideProvider} from './view/index'; export {NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR} from './view/provider'; -export {getLocalePluralCase as ɵgetLocalePluralCase, findLocaleData as ɵfindLocaleData} from './i18n/locale_data_api'; -export {LOCALE_DATA as ɵLOCALE_DATA, LocaleDataIndex as ɵLocaleDataIndex} from './i18n/locale_data'; diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index ec94366dc0..179735a15e 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -136,8 +136,6 @@ export { ɵɵi18nPostprocess, i18nConfigureLocalize as ɵi18nConfigureLocalize, ɵɵi18nLocalize, - setLocaleId as ɵsetLocaleId, - DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, setClassMetadata as ɵsetClassMetadata, ɵɵresolveWindow, ɵɵresolveDocument, diff --git a/packages/core/src/i18n/locale_data.ts b/packages/core/src/i18n/locale_data.ts deleted file mode 100644 index 734cc16680..0000000000 --- a/packages/core/src/i18n/locale_data.ts +++ /dev/null @@ -1,38 +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 - */ - -/** - * This const is used to store the locale data registered with `registerLocaleData` - */ -export const LOCALE_DATA: {[localeId: string]: any} = {}; - -/** - * Index of each type of locale data from the locale data array - */ -export enum LocaleDataIndex { - LocaleId = 0, - DayPeriodsFormat, - DayPeriodsStandalone, - DaysFormat, - DaysStandalone, - MonthsFormat, - MonthsStandalone, - Eras, - FirstDayOfWeek, - WeekendRange, - DateFormat, - TimeFormat, - DateTimeFormat, - NumberSymbols, - NumberFormats, - CurrencySymbol, - CurrencyName, - Currencies, - PluralCase, - ExtraData -} diff --git a/packages/core/src/i18n/locale_data_api.ts b/packages/core/src/i18n/locale_data_api.ts deleted file mode 100644 index cc30c20348..0000000000 --- a/packages/core/src/i18n/locale_data_api.ts +++ /dev/null @@ -1,53 +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 {LOCALE_DATA, LocaleDataIndex} from './locale_data'; -import localeEn from './locale_en'; - -/** - * Retrieves the plural function used by ICU expressions to determine the plural case to use - * for a given locale. - * @param locale A locale code for the locale format rules to use. - * @returns The plural function for the locale. - * @see `NgPlural` - * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n) - */ -export function getLocalePluralCase(locale: string): (value: number) => number { - const data = findLocaleData(locale); - return data[LocaleDataIndex.PluralCase]; -} - -/** - * Finds the locale data for a given locale. - * - * @param locale The locale code. - * @returns The locale data. - * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n) - */ -export function findLocaleData(locale: string): any { - const normalizedLocale = locale.toLowerCase().replace(/_/g, '-'); - - let match = LOCALE_DATA[normalizedLocale]; - if (match) { - return match; - } - - // let's try to find a parent locale - const parentLocale = normalizedLocale.split('-')[0]; - match = LOCALE_DATA[parentLocale]; - - if (match) { - return match; - } - - if (parentLocale === 'en') { - return localeEn; - } - - throw new Error(`Missing locale data for the locale "${locale}".`); -} diff --git a/packages/core/src/i18n/localization.ts b/packages/core/src/i18n/localization.ts deleted file mode 100644 index 0cb492f18b..0000000000 --- a/packages/core/src/i18n/localization.ts +++ /dev/null @@ -1,31 +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 {getLocalePluralCase} from './locale_data_api'; - -/** - * Returns the plural case based on the locale - */ -export function getPluralCase(value: any, locale: string): string { - const plural = getLocalePluralCase(locale)(value); - - switch (plural) { - case 0: - return 'zero'; - case 1: - return 'one'; - case 2: - return 'two'; - case 3: - return 'few'; - case 4: - return 'many'; - default: - return 'other'; - } -} diff --git a/packages/core/src/render3/component.ts b/packages/core/src/render3/component.ts index f03645f88f..c93d8a10b0 100644 --- a/packages/core/src/render3/component.ts +++ b/packages/core/src/render3/component.ts @@ -60,7 +60,7 @@ export interface CreateComponentOptions { * Typically, the features in this list are features that cannot be added to the * other features list in the component definition because they rely on other factors. * - * Example: `LifecycleHooksFeature` is a function that adds lifecycle hook capabilities + * Example: `RootLifecycleHooks` is a function that adds lifecycle hook capabilities * to root components in a tree-shakable way. It cannot be added to the component * features list because there's no way of knowing when the component will be used as * a root component. diff --git a/packages/core/src/render3/definition.ts b/packages/core/src/render3/definition.ts index a9a8f97299..5c1fe79af0 100644 --- a/packages/core/src/render3/definition.ts +++ b/packages/core/src/render3/definition.ts @@ -17,7 +17,7 @@ import {noSideEffects} from '../util/closure'; import {stringify} from '../util/stringify'; import {EMPTY_ARRAY, EMPTY_OBJ} from './empty'; -import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_LOCALE_ID_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from './fields'; +import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from './fields'; import {ComponentDef, ComponentDefFeature, ComponentTemplate, ComponentType, ContentQueriesFunction, DirectiveDef, DirectiveDefFeature, DirectiveType, DirectiveTypesOrFactory, FactoryFn, HostBindingsFunction, PipeDef, PipeType, PipeTypesOrFactory, ViewQueriesFunction, ɵɵBaseDef} from './interfaces/definition'; // while SelectorFlags is unused here, it's required so that types don't get resolved lazily // see: https://github.com/Microsoft/web-build-tools/issues/1050 @@ -738,7 +738,3 @@ export function getNgModuleDef(type: any, throwNotFound?: boolean): NgModuleD } return ngModuleDef; } - -export function getNgLocaleIdDef(type: any): string|null { - return (type as any)[NG_LOCALE_ID_DEF] || null; -} diff --git a/packages/core/src/render3/fields.ts b/packages/core/src/render3/fields.ts index 92642b417f..26b29af9da 100644 --- a/packages/core/src/render3/fields.ts +++ b/packages/core/src/render3/fields.ts @@ -12,7 +12,6 @@ export const NG_COMPONENT_DEF = getClosureSafeProperty({ngComponentDef: getClosu export const NG_DIRECTIVE_DEF = getClosureSafeProperty({ngDirectiveDef: getClosureSafeProperty}); export const NG_PIPE_DEF = getClosureSafeProperty({ngPipeDef: getClosureSafeProperty}); export const NG_MODULE_DEF = getClosureSafeProperty({ngModuleDef: getClosureSafeProperty}); -export const NG_LOCALE_ID_DEF = getClosureSafeProperty({ngLocaleIdDef: getClosureSafeProperty}); export const NG_BASE_DEF = getClosureSafeProperty({ngBaseDef: getClosureSafeProperty}); /** diff --git a/packages/core/src/render3/i18n.ts b/packages/core/src/render3/i18n.ts index 9924e1904f..26e7eae042 100644 --- a/packages/core/src/render3/i18n.ts +++ b/packages/core/src/render3/i18n.ts @@ -7,12 +7,13 @@ */ import '../util/ng_i18n_closure_mode'; -import {getPluralCase} from '../i18n/localization'; + import {SRCSET_ATTRS, URI_ATTRS, VALID_ATTRS, VALID_ELEMENTS, getTemplateContent} from '../sanitization/html_sanitizer'; import {InertBodyHelper} from '../sanitization/inert_body'; import {_sanitizeUrl, sanitizeSrcset} from '../sanitization/url_sanitizer'; import {addAllToArray} from '../util/array_utils'; import {assertDefined, assertEqual, assertGreaterThan} from '../util/assert'; + import {attachPatchData} from './context_discovery'; import {attachI18nOpCodesDebug} from './debug'; import {ɵɵelementAttribute, ɵɵload, ɵɵtextBinding} from './instructions/all'; @@ -1025,6 +1026,351 @@ export function ɵɵi18nApply(index: number) { } } +enum Plural { + Zero = 0, + One = 1, + Two = 2, + Few = 3, + Many = 4, + Other = 5, +} + +/** + * Returns the plural case based on the locale. + * This is a copy of the deprecated function that we used in Angular v4. + * // TODO(ocombe): remove this once we can the real getPluralCase function + * + * @deprecated from v5 the plural case function is in locale data files common/locales/*.ts + */ +function getPluralCase(locale: string, nLike: number | string): Plural { + if (typeof nLike === 'string') { + nLike = parseInt(nLike, 10); + } + const n: number = nLike as number; + const nDecimal = n.toString().replace(/^[^.]*\.?/, ''); + const i = Math.floor(Math.abs(n)); + const v = nDecimal.length; + const f = parseInt(nDecimal, 10); + const t = parseInt(n.toString().replace(/^[^.]*\.?|0+$/g, ''), 10) || 0; + + const lang = locale.split('-')[0].toLowerCase(); + + switch (lang) { + case 'af': + case 'asa': + case 'az': + case 'bem': + case 'bez': + case 'bg': + case 'brx': + case 'ce': + case 'cgg': + case 'chr': + case 'ckb': + case 'ee': + case 'el': + case 'eo': + case 'es': + case 'eu': + case 'fo': + case 'fur': + case 'gsw': + case 'ha': + case 'haw': + case 'hu': + case 'jgo': + case 'jmc': + case 'ka': + case 'kk': + case 'kkj': + case 'kl': + case 'ks': + case 'ksb': + case 'ky': + case 'lb': + case 'lg': + case 'mas': + case 'mgo': + case 'ml': + case 'mn': + case 'nb': + case 'nd': + case 'ne': + case 'nn': + case 'nnh': + case 'nyn': + case 'om': + case 'or': + case 'os': + case 'ps': + case 'rm': + case 'rof': + case 'rwk': + case 'saq': + case 'seh': + case 'sn': + case 'so': + case 'sq': + case 'ta': + case 'te': + case 'teo': + case 'tk': + case 'tr': + case 'ug': + case 'uz': + case 'vo': + case 'vun': + case 'wae': + case 'xog': + if (n === 1) return Plural.One; + return Plural.Other; + case 'ak': + case 'ln': + case 'mg': + case 'pa': + case 'ti': + if (n === Math.floor(n) && n >= 0 && n <= 1) return Plural.One; + return Plural.Other; + case 'am': + case 'as': + case 'bn': + case 'fa': + case 'gu': + case 'hi': + case 'kn': + case 'mr': + case 'zu': + if (i === 0 || n === 1) return Plural.One; + return Plural.Other; + case 'ar': + if (n === 0) return Plural.Zero; + if (n === 1) return Plural.One; + if (n === 2) return Plural.Two; + if (n % 100 === Math.floor(n % 100) && n % 100 >= 3 && n % 100 <= 10) return Plural.Few; + if (n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 99) return Plural.Many; + return Plural.Other; + case 'ast': + case 'ca': + case 'de': + case 'en': + case 'et': + case 'fi': + case 'fy': + case 'gl': + case 'it': + case 'nl': + case 'sv': + case 'sw': + case 'ur': + case 'yi': + if (i === 1 && v === 0) return Plural.One; + return Plural.Other; + case 'be': + if (n % 10 === 1 && !(n % 100 === 11)) return Plural.One; + if (n % 10 === Math.floor(n % 10) && n % 10 >= 2 && n % 10 <= 4 && + !(n % 100 >= 12 && n % 100 <= 14)) + return Plural.Few; + if (n % 10 === 0 || n % 10 === Math.floor(n % 10) && n % 10 >= 5 && n % 10 <= 9 || + n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 14) + return Plural.Many; + return Plural.Other; + case 'br': + if (n % 10 === 1 && !(n % 100 === 11 || n % 100 === 71 || n % 100 === 91)) return Plural.One; + if (n % 10 === 2 && !(n % 100 === 12 || n % 100 === 72 || n % 100 === 92)) return Plural.Two; + if (n % 10 === Math.floor(n % 10) && (n % 10 >= 3 && n % 10 <= 4 || n % 10 === 9) && + !(n % 100 >= 10 && n % 100 <= 19 || n % 100 >= 70 && n % 100 <= 79 || + n % 100 >= 90 && n % 100 <= 99)) + return Plural.Few; + if (!(n === 0) && n % 1e6 === 0) return Plural.Many; + return Plural.Other; + case 'bs': + case 'hr': + case 'sr': + if (v === 0 && i % 10 === 1 && !(i % 100 === 11) || f % 10 === 1 && !(f % 100 === 11)) + return Plural.One; + if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 && + !(i % 100 >= 12 && i % 100 <= 14) || + f % 10 === Math.floor(f % 10) && f % 10 >= 2 && f % 10 <= 4 && + !(f % 100 >= 12 && f % 100 <= 14)) + return Plural.Few; + return Plural.Other; + case 'cs': + case 'sk': + if (i === 1 && v === 0) return Plural.One; + if (i === Math.floor(i) && i >= 2 && i <= 4 && v === 0) return Plural.Few; + if (!(v === 0)) return Plural.Many; + return Plural.Other; + case 'cy': + if (n === 0) return Plural.Zero; + if (n === 1) return Plural.One; + if (n === 2) return Plural.Two; + if (n === 3) return Plural.Few; + if (n === 6) return Plural.Many; + return Plural.Other; + case 'da': + if (n === 1 || !(t === 0) && (i === 0 || i === 1)) return Plural.One; + return Plural.Other; + case 'dsb': + case 'hsb': + if (v === 0 && i % 100 === 1 || f % 100 === 1) return Plural.One; + if (v === 0 && i % 100 === 2 || f % 100 === 2) return Plural.Two; + if (v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 3 && i % 100 <= 4 || + f % 100 === Math.floor(f % 100) && f % 100 >= 3 && f % 100 <= 4) + return Plural.Few; + return Plural.Other; + case 'ff': + case 'fr': + case 'hy': + case 'kab': + if (i === 0 || i === 1) return Plural.One; + return Plural.Other; + case 'fil': + if (v === 0 && (i === 1 || i === 2 || i === 3) || + v === 0 && !(i % 10 === 4 || i % 10 === 6 || i % 10 === 9) || + !(v === 0) && !(f % 10 === 4 || f % 10 === 6 || f % 10 === 9)) + return Plural.One; + return Plural.Other; + case 'ga': + if (n === 1) return Plural.One; + if (n === 2) return Plural.Two; + if (n === Math.floor(n) && n >= 3 && n <= 6) return Plural.Few; + if (n === Math.floor(n) && n >= 7 && n <= 10) return Plural.Many; + return Plural.Other; + case 'gd': + if (n === 1 || n === 11) return Plural.One; + if (n === 2 || n === 12) return Plural.Two; + if (n === Math.floor(n) && (n >= 3 && n <= 10 || n >= 13 && n <= 19)) return Plural.Few; + return Plural.Other; + case 'gv': + if (v === 0 && i % 10 === 1) return Plural.One; + if (v === 0 && i % 10 === 2) return Plural.Two; + if (v === 0 && + (i % 100 === 0 || i % 100 === 20 || i % 100 === 40 || i % 100 === 60 || i % 100 === 80)) + return Plural.Few; + if (!(v === 0)) return Plural.Many; + return Plural.Other; + case 'he': + if (i === 1 && v === 0) return Plural.One; + if (i === 2 && v === 0) return Plural.Two; + if (v === 0 && !(n >= 0 && n <= 10) && n % 10 === 0) return Plural.Many; + return Plural.Other; + case 'is': + if (t === 0 && i % 10 === 1 && !(i % 100 === 11) || !(t === 0)) return Plural.One; + return Plural.Other; + case 'ksh': + if (n === 0) return Plural.Zero; + if (n === 1) return Plural.One; + return Plural.Other; + case 'kw': + case 'naq': + case 'se': + case 'smn': + if (n === 1) return Plural.One; + if (n === 2) return Plural.Two; + return Plural.Other; + case 'lag': + if (n === 0) return Plural.Zero; + if ((i === 0 || i === 1) && !(n === 0)) return Plural.One; + return Plural.Other; + case 'lt': + if (n % 10 === 1 && !(n % 100 >= 11 && n % 100 <= 19)) return Plural.One; + if (n % 10 === Math.floor(n % 10) && n % 10 >= 2 && n % 10 <= 9 && + !(n % 100 >= 11 && n % 100 <= 19)) + return Plural.Few; + if (!(f === 0)) return Plural.Many; + return Plural.Other; + case 'lv': + case 'prg': + if (n % 10 === 0 || n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 19 || + v === 2 && f % 100 === Math.floor(f % 100) && f % 100 >= 11 && f % 100 <= 19) + return Plural.Zero; + if (n % 10 === 1 && !(n % 100 === 11) || v === 2 && f % 10 === 1 && !(f % 100 === 11) || + !(v === 2) && f % 10 === 1) + return Plural.One; + return Plural.Other; + case 'mk': + if (v === 0 && i % 10 === 1 || f % 10 === 1) return Plural.One; + return Plural.Other; + case 'mt': + if (n === 1) return Plural.One; + if (n === 0 || n % 100 === Math.floor(n % 100) && n % 100 >= 2 && n % 100 <= 10) + return Plural.Few; + if (n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 19) return Plural.Many; + return Plural.Other; + case 'pl': + if (i === 1 && v === 0) return Plural.One; + if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 && + !(i % 100 >= 12 && i % 100 <= 14)) + return Plural.Few; + if (v === 0 && !(i === 1) && i % 10 === Math.floor(i % 10) && i % 10 >= 0 && i % 10 <= 1 || + v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 5 && i % 10 <= 9 || + v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 12 && i % 100 <= 14) + return Plural.Many; + return Plural.Other; + case 'pt': + if (n === Math.floor(n) && n >= 0 && n <= 2 && !(n === 2)) return Plural.One; + return Plural.Other; + case 'ro': + if (i === 1 && v === 0) return Plural.One; + if (!(v === 0) || n === 0 || + !(n === 1) && n % 100 === Math.floor(n % 100) && n % 100 >= 1 && n % 100 <= 19) + return Plural.Few; + return Plural.Other; + case 'ru': + case 'uk': + if (v === 0 && i % 10 === 1 && !(i % 100 === 11)) return Plural.One; + if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 && + !(i % 100 >= 12 && i % 100 <= 14)) + return Plural.Few; + if (v === 0 && i % 10 === 0 || + v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 5 && i % 10 <= 9 || + v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 11 && i % 100 <= 14) + return Plural.Many; + return Plural.Other; + case 'shi': + if (i === 0 || n === 1) return Plural.One; + if (n === Math.floor(n) && n >= 2 && n <= 10) return Plural.Few; + return Plural.Other; + case 'si': + if (n === 0 || n === 1 || i === 0 && f === 1) return Plural.One; + return Plural.Other; + case 'sl': + if (v === 0 && i % 100 === 1) return Plural.One; + if (v === 0 && i % 100 === 2) return Plural.Two; + if (v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 3 && i % 100 <= 4 || !(v === 0)) + return Plural.Few; + return Plural.Other; + case 'tzm': + if (n === Math.floor(n) && n >= 0 && n <= 1 || n === Math.floor(n) && n >= 11 && n <= 99) + return Plural.One; + return Plural.Other; + // When there is no specification, the default is always "other" + // Spec: http://cldr.unicode.org/index/cldr-spec/plural-rules + // > other (required—general plural form — also used if the language only has a single form) + default: + return Plural.Other; + } +} + +function getPluralCategory(value: any, locale: string): string { + const plural = getPluralCase(locale, value); + + switch (plural) { + case Plural.Zero: + return 'zero'; + case Plural.One: + return 'one'; + case Plural.Two: + return 'two'; + case Plural.Few: + return 'few'; + case Plural.Many: + return 'many'; + default: + return 'other'; + } +} + /** * Returns the index of the current case of an ICU expression depending on the main binding value * @@ -1036,7 +1382,9 @@ function getCaseIndex(icuExpression: TIcu, bindingValue: string): number { if (index === -1) { switch (icuExpression.type) { case IcuType.plural: { - const resolvedCase = getPluralCase(bindingValue, getLocaleId()); + // TODO(ocombe): replace this hard-coded value by the real LOCALE_ID value + const locale = 'en-US'; + const resolvedCase = getPluralCategory(bindingValue, locale); index = icuExpression.cases.indexOf(resolvedCase); if (index === -1 && resolvedCase !== 'other') { index = icuExpression.cases.indexOf('other'); @@ -1282,7 +1630,7 @@ const LOCALIZE_PH_REGEXP = /\{\$(.*?)\}/g; * running outside of Closure Compiler. This method will not be needed once runtime translation * service support is introduced. * - * @codeGenApi + * @publicApi * @deprecated this method is temporary & should not be used as it will be removed soon */ export function ɵɵi18nLocalize(input: string, placeholders: {[key: string]: string} = {}) { @@ -1293,31 +1641,3 @@ export function ɵɵi18nLocalize(input: string, placeholders: {[key: string]: st input.replace(LOCALIZE_PH_REGEXP, (match, key) => placeholders[key] || '') : input; } - -/** - * The locale id that the application is currently using (for translations and ICU expressions). - * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine - * but is now defined as a global value. - */ -export const DEFAULT_LOCALE_ID = 'en-US'; -let LOCALE_ID = DEFAULT_LOCALE_ID; - -/** - * Sets the locale id that will be used for translations and ICU expressions. - * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine - * but is now defined as a global value. - * - * @param localeId - */ -export function setLocaleId(localeId: string) { - LOCALE_ID = localeId.toLowerCase().replace(/_/g, '-'); -} - -/** - * Gets the locale id that will be used for translations and ICU expressions. - * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine - * but is now defined as a global value. - */ -export function getLocaleId(): string { - return LOCALE_ID; -} diff --git a/packages/core/src/render3/index.ts b/packages/core/src/render3/index.ts index 4d81e5a017..408f786824 100644 --- a/packages/core/src/render3/index.ts +++ b/packages/core/src/render3/index.ts @@ -100,7 +100,6 @@ export { } from './state'; export { - DEFAULT_LOCALE_ID, ɵɵi18n, ɵɵi18nAttributes, ɵɵi18nExp, @@ -110,8 +109,6 @@ export { ɵɵi18nPostprocess, i18nConfigureLocalize, ɵɵi18nLocalize, - getLocaleId, - setLocaleId, } from './i18n'; export {NgModuleFactory, NgModuleRef, NgModuleType} from './ng_module_ref'; diff --git a/packages/core/src/render3/jit/module.ts b/packages/core/src/render3/jit/module.ts index dc9b35f406..c7c758b489 100644 --- a/packages/core/src/render3/jit/module.ts +++ b/packages/core/src/render3/jit/module.ts @@ -99,6 +99,7 @@ export function compileNgModuleDefs(moduleType: NgModuleType, ngModule: NgModule ngDevMode && assertDefined(moduleType, 'Required value moduleType'); ngDevMode && assertDefined(ngModule, 'Required value ngModule'); const declarations: Type[] = flatten(ngModule.declarations || EMPTY_ARRAY); + let ngModuleDef: any = null; Object.defineProperty(moduleType, NG_MODULE_DEF, { configurable: true, diff --git a/packages/core/src/render3/ng_module_ref.ts b/packages/core/src/render3/ng_module_ref.ts index fce592b1d4..d445ded545 100644 --- a/packages/core/src/render3/ng_module_ref.ts +++ b/packages/core/src/render3/ng_module_ref.ts @@ -17,8 +17,7 @@ import {NgModuleDef} from '../metadata/ng_module'; import {assertDefined} from '../util/assert'; import {stringify} from '../util/stringify'; import {ComponentFactoryResolver} from './component_ref'; -import {getNgLocaleIdDef, getNgModuleDef} from './definition'; -import {setLocaleId} from './i18n'; +import {getNgModuleDef} from './definition'; import {maybeUnwrapFn} from './util/misc_utils'; export interface NgModuleType extends Type { ngModuleDef: NgModuleDef; } @@ -45,11 +44,6 @@ export class NgModuleRef extends viewEngine_NgModuleRef implements Interna ngModuleDef, `NgModule '${stringify(ngModuleType)}' is not a subtype of 'NgModuleType'.`); - const ngLocaleIdDef = getNgLocaleIdDef(ngModuleType); - if (ngLocaleIdDef) { - setLocaleId(ngLocaleIdDef); - } - this._bootstrapComponents = maybeUnwrapFn(ngModuleDef !.bootstrap); const additionalProviders: StaticProvider[] = [ { diff --git a/packages/core/test/BUILD.bazel b/packages/core/test/BUILD.bazel index bc1d670deb..99fa8a82cc 100644 --- a/packages/core/test/BUILD.bazel +++ b/packages/core/test/BUILD.bazel @@ -18,7 +18,6 @@ ts_library( "//packages/animations/browser", "//packages/animations/browser/testing", "//packages/common", - "//packages/common/locales", "//packages/compiler", "//packages/compiler/testing", "//packages/core", diff --git a/packages/core/test/application_ref_spec.ts b/packages/core/test/application_ref_spec.ts index 454b72afad..8a56680ec3 100644 --- a/packages/core/test/application_ref_spec.ts +++ b/packages/core/test/application_ref_spec.ts @@ -8,16 +8,15 @@ import {DOCUMENT} from '@angular/common'; import {ResourceLoader} from '@angular/compiler'; -import {APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, Compiler, CompilerFactory, Component, InjectionToken, LOCALE_ID, NgModule, NgZone, PlatformRef, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core'; +import {APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, Compiler, CompilerFactory, Component, InjectionToken, NgModule, NgZone, PlatformRef, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core'; import {ApplicationRef} from '@angular/core/src/application_ref'; import {ErrorHandler} from '@angular/core/src/error_handler'; import {ComponentRef} from '@angular/core/src/linker/component_factory'; -import {getLocaleId} from '@angular/core/src/render3'; import {BrowserModule} from '@angular/platform-browser'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util'; import {expect} from '@angular/platform-browser/testing/src/matchers'; -import {ivyEnabled, onlyInIvy} from '@angular/private/testing'; +import {ivyEnabled} from '@angular/private/testing'; import {NoopNgZone} from '../src/zone/ng_zone'; import {ComponentFixtureNoNgZone, TestBed, async, inject, withModule} from '../testing'; @@ -327,22 +326,6 @@ class SomeComponent { expect(loadResourceSpy).toHaveBeenCalledTimes(1); expect(loadResourceSpy).toHaveBeenCalledWith('/test-template.html'); }); - - onlyInIvy('We only need to define `LOCALE_ID` for runtime i18n') - .it('should define `LOCALE_ID`', async() => { - @Component({ - selector: 'i18n-app', - templateUrl: '', - }) - class I18nComponent { - } - - const testModule = createModule( - {component: I18nComponent, providers: [{provide: LOCALE_ID, useValue: 'ro'}]}); - await defaultPlatform.bootstrapModule(testModule); - - expect(getLocaleId()).toEqual('ro'); - }); }); describe('bootstrapModuleFactory', () => { diff --git a/packages/core/test/i18n_integration_spec.ts b/packages/core/test/i18n_integration_spec.ts index baa959e024..af09a356a7 100644 --- a/packages/core/test/i18n_integration_spec.ts +++ b/packages/core/test/i18n_integration_spec.ts @@ -6,9 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {registerLocaleData} from '@angular/common'; -import {Component, ContentChild, ContentChildren, Directive, LOCALE_ID, QueryList, TemplateRef, ViewChild, ViewContainerRef, ɵi18nConfigureLocalize} from '@angular/core'; -import localeRo from '@angular/common/locales/ro'; +import {Component, ContentChild, ContentChildren, Directive, QueryList, TemplateRef, ViewChild, ViewContainerRef, ɵi18nConfigureLocalize} from '@angular/core'; import {TestBed} from '@angular/core/testing'; import {expect} from '@angular/platform-browser/testing/src/matchers'; import {onlyInIvy} from '@angular/private/testing'; @@ -639,45 +637,4 @@ onlyInIvy('Ivy i18n logic').describe('i18n', function() { expect(child.innerHTML).toBe(`
  • Section 1
  • Section 2
  • Section 3
  • `); } }); - - it('should return the correct plural form for ICU expressions when using a specific locale', - () => { - registerLocaleData(localeRo); - TestBed.configureTestingModule({providers: [{provide: LOCALE_ID, useValue: 'ro'}]}); - // We could also use `TestBed.overrideProvider(LOCALE_ID, {useValue: 'ro'});` - const template = ` - {count, plural, - =0 {no email} - =one {one email} - =few {a few emails} - =other {lots of emails} - }`; - const fixture = getFixtureWithOverrides({template}); - - expect(fixture.nativeElement.innerHTML).toEqual('a few emails'); - - // Change detection cycle, no model changes - fixture.detectChanges(); - expect(fixture.nativeElement.innerHTML).toEqual('a few emails'); - - fixture.componentInstance.count = 0; - fixture.detectChanges(); - expect(fixture.nativeElement.innerHTML).toEqual('no email'); - - fixture.componentInstance.count = 1; - fixture.detectChanges(); - expect(fixture.nativeElement.innerHTML).toEqual('one email'); - - fixture.componentInstance.count = 10; - fixture.detectChanges(); - expect(fixture.nativeElement.innerHTML).toEqual('a few emails'); - - fixture.componentInstance.count = 20; - fixture.detectChanges(); - expect(fixture.nativeElement.innerHTML).toEqual('lots of emails'); - - fixture.componentInstance.count = 0; - fixture.detectChanges(); - expect(fixture.nativeElement.innerHTML).toEqual('no email'); - }); }); diff --git a/packages/core/test/render3/BUILD.bazel b/packages/core/test/render3/BUILD.bazel index 63749d9109..2d769b430e 100644 --- a/packages/core/test/render3/BUILD.bazel +++ b/packages/core/test/render3/BUILD.bazel @@ -20,7 +20,6 @@ ts_library( "//packages/animations/browser", "//packages/animations/browser/testing", "//packages/common", - "//packages/common/locales", "//packages/compiler", "//packages/core", "//packages/core/src/di/interface", diff --git a/packages/core/test/render3/i18n_spec.ts b/packages/core/test/render3/i18n_spec.ts index 0a687a4d86..8f47b2509a 100644 --- a/packages/core/test/render3/i18n_spec.ts +++ b/packages/core/test/render3/i18n_spec.ts @@ -6,11 +6,10 @@ * found in the LICENSE file at https://angular.io/license */ -import {NgForOfContext, registerLocaleData} from '@angular/common'; -import localeRo from '@angular/common/locales/ro'; +import {NgForOfContext} from '@angular/common'; import {noop} from '../../../compiler/src/render3/view/util'; -import {Component as _Component, ɵNgModuleDef as NgModuleDef, ɵɵdefineInjector} from '../../src/core'; +import {Component as _Component} from '../../src/core'; import {ɵɵdefineComponent, ɵɵdefineDirective} from '../../src/render3/definition'; import {getTranslationForTemplate, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart} from '../../src/render3/i18n'; import {ɵɵallocHostVars, ɵɵbind, ɵɵelement, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementProperty, ɵɵelementStart, ɵɵnextContext, ɵɵprojection, ɵɵprojectionDef, ɵɵtemplate, ɵɵtext, ɵɵtextBinding} from '../../src/render3/instructions/all'; @@ -18,8 +17,8 @@ import {RenderFlags} from '../../src/render3/interfaces/definition'; import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nUpdateOpCode, I18nUpdateOpCodes, IcuType, TI18n} from '../../src/render3/interfaces/i18n'; import {AttributeMarker} from '../../src/render3/interfaces/node'; import {HEADER_OFFSET, LView, TVIEW} from '../../src/render3/interfaces/view'; -import {NgModuleFactory} from '../../src/render3/ng_module_ref'; import {getNativeByIndex, getTNode} from '../../src/render3/util/view_utils'; + import {NgForOf, NgIf} from './common_with_def'; import {ComponentFixture, TemplateFixture} from './render_util'; @@ -2260,57 +2259,4 @@ describe('Runtime i18n', () => { }); }); }); - - it('should return the correct plural form for ICU expressions when using a specific locale', - () => { - registerLocaleData(localeRo); - const MSG_DIV = `{�0�, plural, - =0 {no email} - =one {one email} - =few {a few emails} - =other {lots of emails} - }`; - const ctx = {value: 0}; - - class MyAppModule { - static ngLocaleIdDef = 'ro'; - static ngInjectorDef = ɵɵdefineInjector({factory: () => new MyAppModule()}); - static ngModuleDef: NgModuleDef = { bootstrap: [] } as any; - } - const myAppModuleFactory = new NgModuleFactory(MyAppModule); - const ngModuleRef = myAppModuleFactory.create(null); - - const fixture = prepareFixture( - () => { - ɵɵelementStart(0, 'div'); - ɵɵi18n(1, MSG_DIV); - ɵɵelementEnd(); - }, - () => { - ɵɵi18nExp(ɵɵbind(ctx.value)); - ɵɵi18nApply(1); - }, - 2, 1); - expect(fixture.html).toEqual('
    no email
    '); - - // Change detection cycle, no model changes - fixture.update(); - expect(fixture.html).toEqual('
    no email
    '); - - ctx.value = 1; - fixture.update(); - expect(fixture.html).toEqual('
    one email
    '); - - ctx.value = 10; - fixture.update(); - expect(fixture.html).toEqual('
    a few emails
    '); - - ctx.value = 20; - fixture.update(); - expect(fixture.html).toEqual('
    lots of emails
    '); - - ctx.value = 0; - fixture.update(); - expect(fixture.html).toEqual('
    no email
    '); - }); }); diff --git a/packages/core/testing/src/r3_test_bed_compiler.ts b/packages/core/testing/src/r3_test_bed_compiler.ts index 39aa31fb62..aac9429371 100644 --- a/packages/core/testing/src/r3_test_bed_compiler.ts +++ b/packages/core/testing/src/r3_test_bed_compiler.ts @@ -6,10 +6,10 @@ * found in the LICENSE file at https://angular.io/license */ +import {ApplicationInitStatus, COMPILER_OPTIONS, Compiler, Component, Directive, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgZone, Injector, Pipe, PlatformRef, Provider, Type, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵgetInjectableDef as getInjectableDef, ɵNG_COMPONENT_DEF as NG_COMPONENT_DEF, ɵNG_DIRECTIVE_DEF as NG_DIRECTIVE_DEF, ɵNG_INJECTOR_DEF as NG_INJECTOR_DEF, ɵNG_MODULE_DEF as NG_MODULE_DEF, ɵNG_PIPE_DEF as NG_PIPE_DEF, ɵRender3ComponentFactory as ComponentFactory, ɵRender3NgModuleRef as NgModuleRef, ɵɵInjectableDef as InjectableDef, ɵNgModuleFactory as R3NgModuleFactory, ɵNgModuleTransitiveScopes as NgModuleTransitiveScopes, ɵNgModuleType as NgModuleType, ɵDirectiveDef as DirectiveDef, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵtransitiveScopesFor as transitiveScopesFor,} from '@angular/core'; import {ResourceLoader} from '@angular/compiler'; -import {ApplicationInitStatus, COMPILER_OPTIONS, Compiler, Component, Directive, Injector, LOCALE_ID, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgZone, Pipe, PlatformRef, Provider, Type, ɵDEFAULT_LOCALE_ID as DEFAULT_LOCALE_ID, ɵDirectiveDef as DirectiveDef, ɵNG_COMPONENT_DEF as NG_COMPONENT_DEF, ɵNG_DIRECTIVE_DEF as NG_DIRECTIVE_DEF, ɵNG_INJECTOR_DEF as NG_INJECTOR_DEF, ɵNG_MODULE_DEF as NG_MODULE_DEF, ɵNG_PIPE_DEF as NG_PIPE_DEF, ɵNgModuleFactory as R3NgModuleFactory, ɵNgModuleTransitiveScopes as NgModuleTransitiveScopes, ɵNgModuleType as NgModuleType, ɵRender3ComponentFactory as ComponentFactory, ɵRender3NgModuleRef as NgModuleRef, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵgetInjectableDef as getInjectableDef, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵsetLocaleId as setLocaleId, ɵtransitiveScopesFor as transitiveScopesFor, ɵɵInjectableDef as InjectableDef} from '@angular/core'; -import {clearResolutionOfComponentResourcesQueue, isComponentDefPendingResolution, resolveComponentResources, restoreComponentResolutionQueue} from '../../src/metadata/resource_loading'; +import {clearResolutionOfComponentResourcesQueue, restoreComponentResolutionQueue, resolveComponentResources, isComponentDefPendingResolution} from '../../src/metadata/resource_loading'; import {MetadataOverride} from './metadata_override'; import {ComponentResolver, DirectiveResolver, NgModuleResolver, PipeResolver, Resolver} from './resolvers'; @@ -227,9 +227,6 @@ export class R3TestBedCompiler { const parentInjector = this.platform.injector; this.testModuleRef = new NgModuleRef(this.testModuleType, parentInjector); - // Set the locale ID, it can be overridden for the tests - const localeId = this.testModuleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID); - setLocaleId(localeId); // ApplicationInitStatus.runInitializers() is marked @internal to core. // Cast it to any before accessing it. @@ -504,8 +501,6 @@ export class R3TestBedCompiler { this.initialNgDefs.clear(); this.moduleProvidersOverridden.clear(); this.restoreComponentResolutionQueue(); - // Restore the locale ID to the default value, this shouldn't be necessary but we never know - setLocaleId(DEFAULT_LOCALE_ID); } private compileTestModule(): void { diff --git a/tools/gulp-tasks/cldr/extract.js b/tools/gulp-tasks/cldr/extract.js index 1a92bc8fd2..3c0e0ce16c 100644 --- a/tools/gulp-tasks/cldr/extract.js +++ b/tools/gulp-tasks/cldr/extract.js @@ -14,14 +14,11 @@ const cldr = require('cldr'); // used to extract all other cldr data const cldrJs = require('cldrjs'); -const COMMON_PACKAGE = 'packages/common'; -const CORE_PACKAGE = 'packages/core'; -const I18N_FOLDER = `${COMMON_PACKAGE}/src/i18n`; -const I18N_CORE_FOLDER = `${CORE_PACKAGE}/src/i18n`; -const I18N_DATA_FOLDER = `${COMMON_PACKAGE}/locales`; +const PACKAGE_FOLDER = 'packages/common'; +const I18N_FOLDER = `${PACKAGE_FOLDER}/src/i18n`; +const I18N_DATA_FOLDER = `${PACKAGE_FOLDER}/locales`; const I18N_DATA_EXTRA_FOLDER = `${I18N_DATA_FOLDER}/extra`; const RELATIVE_I18N_FOLDER = path.resolve(__dirname, `../../../${I18N_FOLDER}`); -const RELATIVE_I18N_CORE_FOLDER = path.resolve(__dirname, `../../../${I18N_CORE_FOLDER}`); const RELATIVE_I18N_DATA_FOLDER = path.resolve(__dirname, `../../../${I18N_DATA_FOLDER}`); const RELATIVE_I18N_DATA_EXTRA_FOLDER = path.resolve(__dirname, `../../../${I18N_DATA_EXTRA_FOLDER}`); const DEFAULT_RULE = 'function anonymous(n\n/*``*/) {\nreturn"other"\n}'; @@ -63,9 +60,9 @@ module.exports = (gulp, done) => { const baseCurrencies = generateBaseCurrencies(new cldrJs('en')); // additional "en" file that will be included in common - console.log(`Writing file ${I18N_CORE_FOLDER}/locale_en.ts`); + console.log(`Writing file ${I18N_FOLDER}/locale_en.ts`); const localeEnFile = generateLocale('en', new cldrJs('en'), baseCurrencies); - fs.writeFileSync(`${RELATIVE_I18N_CORE_FOLDER}/locale_en.ts`, localeEnFile); + fs.writeFileSync(`${RELATIVE_I18N_FOLDER}/locale_en.ts`, localeEnFile); LOCALES.forEach((locale, index) => { const localeData = new cldrJs(locale); @@ -85,7 +82,7 @@ module.exports = (gulp, done) => { .src([ `${I18N_DATA_FOLDER}/**/*.ts`, `${I18N_FOLDER}/currencies.ts`, - `${I18N_CORE_FOLDER}/locale_en.ts` + `${I18N_FOLDER}/locale_en.ts` ], {base: '.'}) .pipe(format.format('file', clangFormat)) .pipe(gulp.dest('.')); diff --git a/tools/public_api_guard/common/common.d.ts b/tools/public_api_guard/common/common.d.ts index 9ee2ea35e3..6ca180685f 100644 --- a/tools/public_api_guard/common/common.d.ts +++ b/tools/public_api_guard/common/common.d.ts @@ -103,7 +103,7 @@ export declare function getLocaleNumberFormat(locale: string, type: NumberFormat export declare function getLocaleNumberSymbol(locale: string, symbol: NumberSymbol): string; -export declare const getLocalePluralCase: (locale: string) => ((value: number) => Plural); +export declare function getLocalePluralCase(locale: string): (value: number) => Plural; export declare function getLocaleTimeFormat(locale: string, width: FormatWidth): string;