diff --git a/packages/core/src/core_private_export.ts b/packages/core/src/core_private_export.ts index 5094aa1fda..fab88f1b34 100644 --- a/packages/core/src/core_private_export.ts +++ b/packages/core/src/core_private_export.ts @@ -33,6 +33,5 @@ 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 {unregisterLocaleData as ɵunregisterLocaleData, getLocalePluralCase as ɵgetLocalePluralCase, findLocaleData as ɵfindLocaleData, registerLocaleData as ɵregisterLocaleData} from './i18n/locale_data_api'; -export {LocaleDataIndex as ɵLocaleDataIndex, CurrencyIndex as ɵCurrencyIndex, ExtraLocaleDataIndex as ɵExtraLocaleDataIndex} from './i18n/locale_data'; +export {LocaleDataIndex as ɵLocaleDataIndex, CurrencyIndex as ɵCurrencyIndex, ExtraLocaleDataIndex as ɵExtraLocaleDataIndex, getLocalePluralCase as ɵgetLocalePluralCase, findLocaleData as ɵfindLocaleData, registerLocaleData as ɵregisterLocaleData, unregisterAllLocaleData as ɵunregisterLocaleData} from './i18n/locale_data_api'; export {allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, getSanitizationBypassType as ɵgetSanitizationBypassType, BypassType as ɵBypassType, unwrapSafeValue as ɵunwrapSafeValue, SafeHtml as ɵSafeHtml, SafeResourceUrl as ɵSafeResourceUrl, SafeScript as ɵSafeScript, SafeStyle as ɵSafeStyle, SafeUrl as ɵSafeUrl, SafeValue as ɵSafeValue} from './sanitization/bypass'; diff --git a/packages/core/src/i18n/locale_data.ts b/packages/core/src/i18n/locale_data.ts deleted file mode 100644 index 875b6f53d1..0000000000 --- a/packages/core/src/i18n/locale_data.ts +++ /dev/null @@ -1,52 +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 -} - -/** - * Index of each type of locale data from the extra locale data array - */ -export const enum ExtraLocaleDataIndex { - ExtraDayPeriodFormats = 0, - ExtraDayPeriodStandalone, - ExtraDayPeriodsRules -} - -/** - * Index of each value in currency data (used to describe CURRENCIES_EN in currencies.ts) - */ -export const enum CurrencyIndex {Symbol = 0, SymbolNarrow, NbOfDigits} diff --git a/packages/core/src/i18n/locale_data_api.ts b/packages/core/src/i18n/locale_data_api.ts index cdc2bd20d7..dc46a3daf5 100644 --- a/packages/core/src/i18n/locale_data_api.ts +++ b/packages/core/src/i18n/locale_data_api.ts @@ -5,9 +5,13 @@ * 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'; +import {global} from '../util/global'; + +/** + * This const is used to store the locale data registered with `registerLocaleData` + */ +let LOCALE_DATA: {[localeId: string]: any} = {}; /** * Register locale data to be used internally by Angular. See the @@ -75,19 +79,64 @@ export function getLocalePluralCase(locale: string): (value: number) => number { /** - * Helper function to get the given `normalizedLocale` from `LOCALE_DATA`. + * Helper function to get the given `normalizedLocale` from `LOCALE_DATA` + * or from the global `ng.common.locale`. */ export function getLocaleData(normalizedLocale: string): any { + if (!(normalizedLocale in LOCALE_DATA)) { + LOCALE_DATA[normalizedLocale] = global.ng && global.ng.common && global.ng.common.locales && + global.ng.common.locales[normalizedLocale]; + } return LOCALE_DATA[normalizedLocale]; } /** * Helper function to remove all the locale data from `LOCALE_DATA`. */ -export function unregisterLocaleData() { - Object.keys(LOCALE_DATA).forEach(key => delete LOCALE_DATA[key]); +export function unregisterAllLocaleData() { + LOCALE_DATA = {}; } +/** + * 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 +} + +/** + * Index of each type of locale data from the extra locale data array + */ +export const enum ExtraLocaleDataIndex { + ExtraDayPeriodFormats = 0, + ExtraDayPeriodStandalone, + ExtraDayPeriodsRules +} + +/** + * Index of each value in currency data (used to describe CURRENCIES_EN in currencies.ts) + */ +export const enum CurrencyIndex {Symbol = 0, SymbolNarrow, NbOfDigits} + /** * Returns the canonical form of a locale name - lowercase with `_` replaced with `-`. */ diff --git a/packages/core/test/i18n/locale_data_api_spec.ts b/packages/core/test/i18n/locale_data_api_spec.ts index 00ab67726f..9121e3b2cb 100644 --- a/packages/core/test/i18n/locale_data_api_spec.ts +++ b/packages/core/test/i18n/locale_data_api_spec.ts @@ -5,18 +5,23 @@ * 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 {findLocaleData, registerLocaleData, unregisterLocaleData} from '../../src/i18n/locale_data_api'; +import {findLocaleData, registerLocaleData, unregisterAllLocaleData} from '../../src/i18n/locale_data_api'; +import {global} from '../../src/util/global'; { describe('locale data api', () => { const localeCaESVALENCIA: any[] = ['ca-ES-VALENCIA']; + const localeDe: any[] = ['de']; + const localeDeCH: any[] = ['de-CH']; const localeEn: any[] = ['en']; const localeFr: any[] = ['fr']; const localeFrCA: any[] = ['fr-CA']; const localeZh: any[] = ['zh']; const localeEnAU: any[] = ['en-AU']; + const fakeGlobalFr: any[] = ['fr']; beforeAll(() => { + // Sumulate manually registering some locale data registerLocaleData(localeCaESVALENCIA); registerLocaleData(localeEn); registerLocaleData(localeFr); @@ -25,9 +30,20 @@ import {findLocaleData, registerLocaleData, unregisterLocaleData} from '../../sr registerLocaleData(localeFrCA, 'fake_Id2'); registerLocaleData(localeZh); registerLocaleData(localeEnAU); + + // Simulate some locale data existing on the global already + global.ng = global.ng || {}; + global.ng.common = global.ng.common || {locales: {}}; + global.ng.common.locales = global.ng.common.locales || {}; + global.ng.common.locales['fr'] = fakeGlobalFr; + global.ng.common.locales['de'] = localeDe; + global.ng.common.locales['de-ch'] = localeDeCH; }); - afterAll(() => unregisterLocaleData()); + afterAll(() => { + unregisterAllLocaleData(); + global.ng.common.locales = undefined; + }); describe('findLocaleData', () => { it('should throw if the LOCALE_DATA for the chosen locale or its parent locale is not available', @@ -55,6 +71,15 @@ import {findLocaleData, registerLocaleData, unregisterLocaleData} from '../../sr expect(findLocaleData('fake_iD')).toEqual(localeFr); expect(findLocaleData('fake-id2')).toEqual(localeFrCA); }); + + it('should find the exact LOCALE_DATA if the locale is on the global object', + () => { expect(findLocaleData('de-CH')).toEqual(localeDeCH); }); + + it('should find the parent LOCALE_DATA if the exact locale is not available and the parent locale is on the global object', + () => { expect(findLocaleData('de-BE')).toEqual(localeDe); }); + + it('should find the registered LOCALE_DATA even if the same locale is on the global object', + () => { expect(findLocaleData('fr')).not.toBe(fakeGlobalFr); }); }); }); }