From 3c2438425bd02655b5265e136150014846477ab9 Mon Sep 17 00:00:00 2001 From: Feliks Khantsis Date: Fri, 22 Nov 2019 15:07:30 +0200 Subject: [PATCH] feat: add direction property to locale files (#33556) PR Close #33556 --- .gitignore | 1 - packages/common/src/common.ts | 2 +- packages/common/src/i18n/locale_data_api.ts | 12 ++++++++++++ .../common/test/i18n/locale_data_api_spec.ts | 12 +++++++++++- packages/core/src/i18n/locale_data_api.ts | 3 ++- packages/core/src/i18n/locale_en.ts | 19 +++++++++++++++---- tools/gulp-tasks/cldr/extract.js | 13 +++++++++++-- tools/public_api_guard/common/common.d.ts | 2 ++ 8 files changed, 54 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 1495b3c2cf..8b7a3f78e0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ e2e_test.* *.log node_modules -tools/gulp-tasks/cldr/cldr-data/ # Include when developing application packages. pubspec.lock diff --git a/packages/common/src/common.ts b/packages/common/src/common.ts index fa37614273..9e0763cd87 100644 --- a/packages/common/src/common.ts +++ b/packages/common/src/common.ts @@ -17,7 +17,7 @@ export {formatDate} from './i18n/format_date'; export {formatCurrency, formatNumber, formatPercent} from './i18n/format_number'; export {NgLocaleLocalization, NgLocalization} from './i18n/localization'; export {registerLocaleData} from './i18n/locale_data'; -export {Plural, NumberFormatStyle, FormStyle, Time, TranslationWidth, FormatWidth, NumberSymbol, WeekDay, getNumberOfCurrencyDigits, getCurrencySymbol, getLocaleDayPeriods, getLocaleDayNames, getLocaleMonthNames, getLocaleId, getLocaleEraNames, getLocaleWeekEndRange, getLocaleFirstDayOfWeek, getLocaleDateFormat, getLocaleDateTimeFormat, getLocaleExtraDayPeriodRules, getLocaleExtraDayPeriods, getLocalePluralCase, getLocaleTimeFormat, getLocaleNumberSymbol, getLocaleNumberFormat, getLocaleCurrencyName, getLocaleCurrencySymbol} from './i18n/locale_data_api'; +export {Plural, NumberFormatStyle, FormStyle, Time, TranslationWidth, FormatWidth, NumberSymbol, WeekDay, getNumberOfCurrencyDigits, getCurrencySymbol, getLocaleDayPeriods, getLocaleDayNames, getLocaleMonthNames, getLocaleId, getLocaleEraNames, getLocaleWeekEndRange, getLocaleFirstDayOfWeek, getLocaleDateFormat, getLocaleDateTimeFormat, getLocaleExtraDayPeriodRules, getLocaleExtraDayPeriods, getLocalePluralCase, getLocaleTimeFormat, getLocaleNumberSymbol, getLocaleNumberFormat, getLocaleCurrencyName, getLocaleCurrencySymbol, getLocaleDirection} from './i18n/locale_data_api'; export {parseCookieValue as ɵparseCookieValue} from './cookie'; export {CommonModule} from './common_module'; export {NgClass, NgClassBase, NgForOf, NgForOfContext, NgIf, NgIfContext, NgPlural, NgPluralCase, NgStyle, NgStyleBase, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet, NgComponentOutlet} from './directives/index'; diff --git a/packages/common/src/i18n/locale_data_api.ts b/packages/common/src/i18n/locale_data_api.ts index b3e1b22891..66e14703d5 100644 --- a/packages/common/src/i18n/locale_data_api.ts +++ b/packages/common/src/i18n/locale_data_api.ts @@ -561,6 +561,18 @@ export function getLocaleExtraDayPeriods( return getLastDefinedValue(dayPeriods, width) || []; } +/** + * Retrieves the writing direction of a specified locale + * @param locale A locale code for the locale format rules to use. + * @publicApi + * @returns 'rtl' or 'ltr' + * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n) + */ +export function getLocaleDirection(locale: string): 'ltr'|'rtl' { + const data = ɵfindLocaleData(locale); + return data[ɵLocaleDataIndex.Directionality]; +} + /** * Retrieves the first value that is defined in an array, going backwards from an index position. * diff --git a/packages/common/test/i18n/locale_data_api_spec.ts b/packages/common/test/i18n/locale_data_api_spec.ts index f8fad60d5f..c4cb78d6f0 100644 --- a/packages/common/test/i18n/locale_data_api_spec.ts +++ b/packages/common/test/i18n/locale_data_api_spec.ts @@ -12,7 +12,8 @@ import localeEn from '@angular/common/locales/en'; import localeFr from '@angular/common/locales/fr'; import localeZh from '@angular/common/locales/zh'; import localeEnAU from '@angular/common/locales/en-AU'; -import {getCurrencySymbol, getLocaleDateFormat, FormatWidth, getNumberOfCurrencyDigits} from '../../src/i18n/locale_data_api'; +import localeHe from '@angular/common/locales/he'; +import {getCurrencySymbol, getLocaleDateFormat, FormatWidth, getNumberOfCurrencyDigits, getLocaleDirection} from '../../src/i18n/locale_data_api'; { describe('locale data api', () => { @@ -21,6 +22,7 @@ import {getCurrencySymbol, getLocaleDateFormat, FormatWidth, getNumberOfCurrency ɵregisterLocaleData(localeFr); ɵregisterLocaleData(localeZh); ɵregisterLocaleData(localeEnAU); + ɵregisterLocaleData(localeHe); }); afterAll(() => { ɵunregisterLocaleData(); }); @@ -56,5 +58,13 @@ import {getCurrencySymbol, getLocaleDateFormat, FormatWidth, getNumberOfCurrency it('should find the last defined date format when format not defined', () => { expect(getLocaleDateFormat('zh', FormatWidth.Long)).toEqual('y年M月d日'); }); }); + + describe('getDirectionality', () => { + it('should have correct direction for rtl languages', + () => { expect(getLocaleDirection('he')).toEqual('rtl'); }); + + it('should have correct direction for ltr languages', + () => { expect(getLocaleDirection('en')).toEqual('ltr'); }); + }); }); } diff --git a/packages/core/src/i18n/locale_data_api.ts b/packages/core/src/i18n/locale_data_api.ts index dc46a3daf5..4b5895637f 100644 --- a/packages/core/src/i18n/locale_data_api.ts +++ b/packages/core/src/i18n/locale_data_api.ts @@ -119,6 +119,7 @@ export enum LocaleDataIndex { CurrencySymbol, CurrencyName, Currencies, + Directionality, PluralCase, ExtraData } @@ -142,4 +143,4 @@ export const enum CurrencyIndex {Symbol = 0, SymbolNarrow, NbOfDigits} */ function normalizeLocale(locale: string): string { return locale.toLowerCase().replace(/_/g, '-'); -} \ No newline at end of file +} diff --git a/packages/core/src/i18n/locale_en.ts b/packages/core/src/i18n/locale_en.ts index af207dab90..785c6d08e7 100644 --- a/packages/core/src/i18n/locale_en.ts +++ b/packages/core/src/i18n/locale_en.ts @@ -18,7 +18,9 @@ function plural(n: number): number { } export default [ - 'en', [['a', 'p'], ['AM', 'PM'], u], [['AM', 'PM'], u, u], + 'en', + [['a', 'p'], ['AM', 'PM'], u], + [['AM', 'PM'], u, u], [ ['S', 'M', 'T', 'W', 'T', 'F', 'S'], ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], @@ -33,9 +35,18 @@ export default [ 'October', 'November', 'December' ] ], - u, [['B', 'A'], ['BC', 'AD'], ['Before Christ', 'Anno Domini']], 0, [6, 0], + u, + [['B', 'A'], ['BC', 'AD'], ['Before Christ', 'Anno Domini']], + 0, + [6, 0], ['M/d/yy', 'MMM d, y', 'MMMM d, y', 'EEEE, MMMM d, y'], - ['h:mm a', 'h:mm:ss a', 'h:mm:ss a z', 'h:mm:ss a zzzz'], ['{1}, {0}', u, '{1} \'at\' {0}', u], + ['h:mm a', 'h:mm:ss a', 'h:mm:ss a z', 'h:mm:ss a zzzz'], + ['{1}, {0}', u, '{1} \'at\' {0}', u], ['.', ',', ';', '%', '+', '-', 'E', '×', '‰', '∞', 'NaN', ':'], - ['#,##0.###', '#,##0%', '¤#,##0.00', '#E0'], '$', 'US Dollar', {}, plural + ['#,##0.###', '#,##0%', '¤#,##0.00', '#E0'], + '$', + 'US Dollar', + {}, + 'ltr', + plural ]; diff --git a/tools/gulp-tasks/cldr/extract.js b/tools/gulp-tasks/cldr/extract.js index a7b9408e16..81c89e795f 100644 --- a/tools/gulp-tasks/cldr/extract.js +++ b/tools/gulp-tasks/cldr/extract.js @@ -50,7 +50,7 @@ module.exports = (gulp, done) => { const LOCALES = cldrData.availableLocales; console.log(`Loading CLDR data...`); - cldrJs.load(cldrData.all()); + cldrJs.load(cldrData.all().concat(cldrData('scriptMetadata'))); console.log(`Writing locale files`); if (!fs.existsSync(RELATIVE_I18N_FOLDER)) { @@ -154,7 +154,7 @@ function generateBasicLocaleString(locale, localeData, baseCurrencies) { [ locale, ...getDateTimeTranslations(localeData), ...getDateTimeSettings(localeData), ...getNumberSettings(localeData), ...getCurrencySettings(locale, localeData), - generateLocaleCurrencies(localeData, baseCurrencies) + generateLocaleCurrencies(localeData, baseCurrencies), getDirectionality(localeData), ], true) // We remove "undefined" added by spreading arrays when there is no value @@ -533,6 +533,15 @@ function getCurrencySettings(locale, localeData) { return currencySettings; } +/** + * Returns the writing direction for a locale + * @returns 'rtl' | 'ltr' + */ +function getDirectionality(localeData) { + const rtl = localeData.get('scriptMetadata/{script}/rtl'); + return rtl === 'YES' ? 'rtl' : 'ltr'; +} + /** * Transforms a string into a regexp */ diff --git a/tools/public_api_guard/common/common.d.ts b/tools/public_api_guard/common/common.d.ts index efa873e405..2b0ccd9f54 100644 --- a/tools/public_api_guard/common/common.d.ts +++ b/tools/public_api_guard/common/common.d.ts @@ -63,6 +63,8 @@ export declare function getLocaleDayNames(locale: string, formStyle: FormStyle, export declare function getLocaleDayPeriods(locale: string, formStyle: FormStyle, width: TranslationWidth): [string, string]; +export declare function getLocaleDirection(locale: string): 'ltr' | 'rtl'; + export declare function getLocaleEraNames(locale: string, width: TranslationWidth): [string, string]; export declare function getLocaleExtraDayPeriodRules(locale: string): (Time | [Time, Time])[];