Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop use of the Intl API to improve browser support #18284

Closed
wants to merge 3 commits into from

Conversation

Projects
None yet
7 participants
@ocombe
Copy link
Contributor

ocombe commented Jul 21, 2017

PR Type

What kind of change does this PR introduce?

[x] Bugfix
[x] Feature

What is the current behavior?

We need the intl API for i18n pipes

Issue Number: #10809, #9524, #7008, #9324, #7590, #6724, #3429, #17576, #17478, #17319, #17200, #16838, #16624, #16625, #16591, #14131, #12632, #11376, #11187

What is the new behavior?

We don't need the intl API anymore, we extract and use data from CLDR instead.

Date pipe:

  • new formats (breaking change), see comparative document
  • new optional parameter: timezone that lets you specify the timezone for a date (it will shift the date values based on the locale timezone so that you see it as it was from this other timezone).
  • new optional parameter: locale that lets you use a specific locale for this pipe (instead of using the default LOCALE_ID)

Plural pipe:

  • new optional parameter: locale that lets you use a specific locale for this pipe (instead of using the default LOCALE_ID)

Decimal pipe:

  • new optional parameter: locale that lets you use a specific locale for this pipe (instead of using the default LOCALE_ID)

Percent pipe:

  • new optional parameter: locale that lets you use a specific locale for this pipe (instead of using the default LOCALE_ID)

Currency pipe:

  • the parameter symbolDisplay is no longer a boolean (it still works with a boolean, but it prints a warning to let you know that it changed), it’s now taking the values code, symbol, or symbol-narrow (the default is still code) which gives you access to more options for to show your currencies (e.g. the canadian dollar with the code CAD has the symbol CA$ and the symbol-narrow $).
  • new optional parameter: locale that lets you use a specific locale for this pipe (instead of using the default LOCALE_ID)

Does this PR introduce a breaking change?

[x] Yes

All i18n pipes have been updated to not require the intl API anymore. Some results might vary, see the document to update from v4 to v5 for more information.

TODO

  • write a document to update from v4 to v5

@ocombe ocombe requested review from IgorMinar and vicb Jul 21, 2017

@googlebot googlebot added the cla: yes label Jul 21, 2017

@ocombe ocombe changed the title Fix intl api 10809 feat(core): remove dependency to intl API Jul 21, 2017


const dateTimeTranslations = {dayPeriodsFormat, daysFormat, monthsFormat, eras};

if(dayPeriodsFormat !== dayPeriodsStandalone) {

This comment has been minimized.

Copy link
@vicb

vicb Jul 21, 2017

Contributor

add comment on dedup

* ie: "en-US" will return "en", and "fr_ca" will return "fr-CA"
*/
function getNormalizedLocale(locale: string): string {
const normalizedLocale = locale.toLowerCase().replace(new RegExp('_', 'g'), '-');

This comment has been minimized.

Copy link
@vicb

vicb Jul 21, 2017

Contributor

nit: new RegExp('_', 'g') -> /-/g

* @experimental i18n support is experimental.
*/
export function findNgLocale(locale: string, localeData: NgLocale[] | null): NgLocale {
const currentLocale = getNormalizedLocale(locale);

This comment has been minimized.

Copy link
@vicb

vicb Jul 21, 2017

Contributor

currentLocale -> normalizedLocale

@@ -234,7 +234,6 @@ export function main() {
expect(bd.isIOS7).toBe(browser['isIOS7']);
expect(bd.isSlow).toBe(browser['isSlow']);
expect(bd.isChromeDesktop).toBe(browser['isChromeDesktop']);
expect(bd.isOldChrome).toBe(browser['isOldChrome']);

This comment has been minimized.

Copy link
@vicb

vicb Jul 21, 2017

Contributor

why this change ?

This comment has been minimized.

Copy link
@ocombe

ocombe Jul 24, 2017

Author Contributor

isOldChrome is only used by intl api, when I first did the PR, I removed the old pipes and the tests for them. But then I moved them as deprecated pipes instead, and forgot to revert this change. Doing it now.

@ocombe ocombe force-pushed the ocombe:fix-intl-api-10809 branch 3 times, most recently from 1053613 to d513368 Jul 24, 2017

@angular angular deleted a comment from mary-poppins Jul 25, 2017

@angular angular deleted a comment from mary-poppins Jul 25, 2017

@angular angular deleted a comment from mary-poppins Jul 25, 2017

@ocombe ocombe force-pushed the ocombe:fix-intl-api-10809 branch from d513368 to c33247f Jul 25, 2017

@angular angular deleted a comment from mary-poppins Jul 25, 2017

@ocombe ocombe force-pushed the ocombe:fix-intl-api-10809 branch from c33247f to 052a61a Jul 25, 2017

@mary-poppins

This comment has been minimized.

Copy link

mary-poppins commented Jul 25, 2017

@angular angular deleted a comment from mary-poppins Jul 25, 2017

* found in the LICENSE file at https://angular.io/license
*/
// This is generated code DO NOT MODIFY

This comment has been minimized.

Copy link
@vicb

vicb Jul 25, 2017

Contributor

THIS CODE IS GENERATED - DO NOT MODIFY

const format = NgLocaleAfNA.dateTime.translations.dayPeriods.format;
const std = NgLocaleAfNA.dateTime.translations.dayPeriods.standalone;

format.narrow = {...format.narrow, ...dpF.narrow};

This comment has been minimized.

Copy link
@vicb

vicb Jul 25, 2017

Contributor

Thoughts:

  • I think we can remove all of the {..., ...},
  • I think we can also remove the need to import the std objects and merge the full object

Because we are going to use an API to access the data (which goal is to abstract the storage format).

Also the registerLocaleData(...) could help here.

settings: ${getDateTimeSettings(localeData)}
},
number: {
settings: ${getNumberSettings(localeData)}

This comment has been minimized.

Copy link
@vicb

vicb Jul 25, 2017

Contributor

do we need a nested key here and below ?

This comment has been minimized.

Copy link
@ocombe

ocombe Jul 26, 2017

Author Contributor

not yet, just thinking about future things that we might add

const dpF = stringify(dayPeriods.format);
let dpStd = stringify(dayPeriods['stand-alone']);

if (dpF === dpStd) {

This comment has been minimized.

Copy link
@vicb

vicb Jul 25, 2017

Contributor

add a comment explaining what you do pls

const dpF = ${dpF};${dpStd ? `\nconst dpStd = ${dpStd};` : ''}
const format = NgLocale${toPascalCase(locale)}.dateTime.translations.dayPeriods.format;

This comment has been minimized.

Copy link
@vicb

vicb Jul 25, 2017

Contributor

There is probably no need to duplicate this logic as many time as we have locales

const dayPeriodsStandalone = stringify(dayPeriods['stand-alone']);

const daysFormat = stringify({
narrow: objectValues(dayNames.format.narrow),

This comment has been minimized.

Copy link
@vicb

vicb Jul 25, 2017

Contributor

Have you tried to generate arrays instead of obj ?
What is the diff in size ?

@@ -0,0 +1,94 @@
/**

This comment has been minimized.

Copy link
@vicb

vicb Jul 25, 2017

Contributor

Idea: I donc speak ar but the files look really similar for different regions (the QA part). Is there any check in place to make sure we do not duplicate the same data multiple times ?

This comment has been minimized.

Copy link
@ocombe

ocombe Jul 26, 2017

Author Contributor

Not between different locales no, but it doesn't really matter since people will only import one of them, not all

This comment has been minimized.

Copy link
@vicb

vicb Jul 26, 2017

Contributor

It will prevent devs to have to buy a new SSD only to npm install Angular.
The check is easy enough. Please git it a try to see how much we can save.

// This is generated code DO NOT MODIFY
// See angular/tools/gulp-tasks/cldr/extract.js

import {LOCALE_DATA, NgLocale, Plural} from '@angular/common';

This comment has been minimized.

Copy link
@vicb

vicb Jul 26, 2017

Contributor

meme remarque encore ici: probablement beaucoup de chose en commun avec fr-* (sauf currency et peut etre numbers). Would be NICE to check what we can factor.


/** @experimental */
export const CURRENCIES: {[code: string]: {[key: string]: string}} = {
'ADP': {symbol: 'ADP'},

This comment has been minimized.

Copy link
@vicb

vicb Jul 26, 2017

Contributor

An array would make sense here instead of an obj.

This comment has been minimized.

Copy link
@ocombe

ocombe Jul 26, 2017

Author Contributor

👍 Just saved 6.2ko minified by optimizing this file!

@mary-poppins

This comment has been minimized.

Copy link

mary-poppins commented Aug 21, 2017

@ocombe ocombe referenced this pull request Aug 21, 2017

Closed

CurrencyPipe tests failing on chrome mobile #18807

1 of 1 task complete

@ocombe ocombe force-pushed the ocombe:fix-intl-api-10809 branch from 591dea5 to 3ae3d61 Aug 21, 2017

@mary-poppins

This comment has been minimized.

Copy link

mary-poppins commented Aug 21, 2017

@ocombe ocombe force-pushed the ocombe:fix-intl-api-10809 branch from 3ae3d61 to 9613115 Aug 21, 2017

@mary-poppins

This comment has been minimized.

Copy link

mary-poppins commented Aug 21, 2017

@@ -14,7 +14,7 @@
export * from './location/index';
export {NgLocaleLocalization, NgLocalization} from './i18n/localization';
export {Plural, LOCALE_DATA} from './i18n/locale_data';
export {findLocaleData, registerLocaleData, 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';

This comment has been minimized.

Copy link
@vicb

vicb Aug 22, 2017

Contributor

hum ?

@ocombe ocombe force-pushed the ocombe:fix-intl-api-10809 branch from af9b055 to fcb32a1 Aug 22, 2017

feat(common): drop use of the Intl API to improve browser support
BREAKING CHANGE: Because of multiple bugs and browser inconsistencies, we have dropped the intl api in favor of data exported from the Unicode Common Locale Data Repository (CLDR).
Unfortunately we had to change the i18n pipes (date, number, currency, percent) and there are some breaking changes.

1. I18n pipes
* Breaking change:
  - By default Angular now only contains locale data for the language `en-US`, if you set the value of `LOCALE_ID` to another locale, you will have to import new locale data for this language because we don't use the intl API anymore.

* Features:
  - you don't need to use the intl polyfill for Angular anymore.
  - all i18n pipes now have an additional last parameter `locale` which allows you to use a specific locale instead of the one defined in the token `LOCALE_ID` (whose value is `en-US` by default).
  - the new locale data extracted from CLDR are now available to developers as well and can be used through an API (which should be especially useful for library authors).
  - you can still use the old pipes for now, but their names have been changed and they are no longer included in the `CommonModule`. To use them, you will have to import the `DeprecatedI18NPipesModule` after the `CommonModule` (the order is important):

  ```ts
  import { NgModule } from '@angular/core';
  import { CommonModule, DeprecatedI18NPipesModule } from '@angular/common';

  @NgModule({
    imports: [
      CommonModule,
      // import deprecated module after
      DeprecatedI18NPipesModule
    ]
  })
  export class AppModule { }
  ```

  Dont forget that you will still need to import the intl API polyfill if you want to use those deprecated pipes.


2. Date pipe
* Breaking changes:
  - the predefined formats (`short`, `shortTime`, `shortDate`, `medium`, ...) now use the patterns given by CLDR (like it was in AngularJS) instead of the ones from the intl API. You might notice some changes, e.g. `shortDate` will be `8/15/17` instead of `8/15/2017` for `en-US`.
  - the narrow version of eras is now `GGGGG` instead of `G`, the format `G` is now similar to `GG` and `GGG`.
  - the narrow version of months is now `MMMMM` instead of `L`, the format `L` is now the short standalone version of months.
  - the narrow version of the week day is now `EEEEE` instead of `E`, the format `E` is now similar to `EE` and `EEE`.
  - the timezone `z` will now fallback to `O` and output `GMT+1` instead of the complete zone name (e.g. `Pacific Standard Time`), this is because the quantity of data required to have all the zone names in all of the existing locales is too big.
  - the timezone `Z` will now output the ISO8601 basic format, e.g. `+0100`, you should now use `ZZZZ` to get `GMT+01:00`.

  | Field type | Format        | Example value         | v4 | v5            |
  |------------|---------------|-----------------------|----|---------------|
  | Eras       | Narrow        | A for AD              | G  | GGGGG         |
  | Months     | Narrow        | S for September       | L  | MMMMM         |
  | Week day   | Narrow        | M for Monday          | E  | EEEEE         |
  | Timezone   | Long location | Pacific Standard Time | z  | Not available |
  | Timezone   | Long GMT      | GMT+01:00             | Z  | ZZZZ          |

* Features
  - new predefined formats `long`, `full`, `longTime`, `fullTime`.
  - the format `yyy` is now supported, e.g. the year `52` will be `052` and the year `2017` will be `2017`.
  - standalone months are now supported with the formats `L` to `LLLLL`.
  - week of the year is now supported with the formats `w` and `ww`, e.g. weeks `5` and `05`.
  - week of the month is now supported with the format `W`, e.g. week `3`.
  - fractional seconds are now supported with the format `S` to `SSS`.
  - day periods for AM/PM now supports additional formats `aa`, `aaa`, `aaaa` and `aaaaa`. The formats `a` to `aaa` are similar, while `aaaa` is the wide version if available (e.g. `ante meridiem` for `am`), or equivalent to `a` otherwise, and `aaaaa` is the narrow version (e.g. `a` for `am`).
  - extra day periods are now supported with the formats `b` to `bbbbb` (and `B` to `BBBBB` for the standalone equivalents), e.g. `morning`, `noon`, `afternoon`, ....
  - the short non-localized timezones are now available with the format `O` to `OOOO`. The formats `O` to `OOO` will output `GMT+1` while the format `OOOO` will be `GMT+01:00`.
  - the ISO8601 basic time zones are now available with the formats `Z` to `ZZZZZ`. The formats `Z` to `ZZZ` will output `+0100`, while the format `ZZZZ` will be `GMT+01:00` and `ZZZZZ` will be `+01:00`.

* Bug fixes
  - the date pipe will now work exactly the same across all browsers, which will fix a lot of bugs for safari and IE.
  - eras can now be used on their own without the date, e.g. the format `GG` will be `AD` instead of `8 15, 2017 AD`.


3. Currency pipe
* Breaking change:
  - the default value for `symbolDisplay` is now `symbol` instead of `code`. This means that by default you will see `$4.99` for `en-US` instead of `USD4.99` previously.
  
* Deprecation:
  - the second parameter of the currency pipe (`symbolDisplay`) is no longer a boolean, it now takes the values `code`, `symbol` or `symbol-narrow`. A boolean value is still valid for now, but it is deprecated and it will print a warning message in the console.

* Features:
  - you can now choose between `code`, `symbol` or `symbol-narrow` which gives you access to more options for some currencies (e.g. the canadian dollar with the code `CAD` has the symbol `CA$` and the symbol-narrow `$`).


4. Percent pipe
* Breaking change
  - if you don't specify the number of digits to round to, the local format will be used (and it usually rounds numbers to 0 digits, instead of not rounding previously), e.g. `{{ 3.141592 | percent }}` will output `314%` for the locale `en-US` instead of `314.1592%` previously.


Fixes #10809, #9524, #7008, #9324, #7590, #6724, #3429, #17576, #17478, #17319, #17200, #16838, #16624, #16625, #16591, #14131, #12632, #11376, #11187

@ocombe ocombe force-pushed the ocombe:fix-intl-api-10809 branch from fcb32a1 to 6dc6dd5 Aug 22, 2017

mhevery added a commit that referenced this pull request Aug 22, 2017

mhevery added a commit that referenced this pull request Aug 22, 2017

feat(common): drop use of the Intl API to improve browser support (#1…
…8284)

BREAKING CHANGE: Because of multiple bugs and browser inconsistencies, we have dropped the intl api in favor of data exported from the Unicode Common Locale Data Repository (CLDR).
Unfortunately we had to change the i18n pipes (date, number, currency, percent) and there are some breaking changes.

1. I18n pipes
* Breaking change:
  - By default Angular now only contains locale data for the language `en-US`, if you set the value of `LOCALE_ID` to another locale, you will have to import new locale data for this language because we don't use the intl API anymore.

* Features:
  - you don't need to use the intl polyfill for Angular anymore.
  - all i18n pipes now have an additional last parameter `locale` which allows you to use a specific locale instead of the one defined in the token `LOCALE_ID` (whose value is `en-US` by default).
  - the new locale data extracted from CLDR are now available to developers as well and can be used through an API (which should be especially useful for library authors).
  - you can still use the old pipes for now, but their names have been changed and they are no longer included in the `CommonModule`. To use them, you will have to import the `DeprecatedI18NPipesModule` after the `CommonModule` (the order is important):

  ```ts
  import { NgModule } from '@angular/core';
  import { CommonModule, DeprecatedI18NPipesModule } from '@angular/common';

  @NgModule({
    imports: [
      CommonModule,
      // import deprecated module after
      DeprecatedI18NPipesModule
    ]
  })
  export class AppModule { }
  ```

  Dont forget that you will still need to import the intl API polyfill if you want to use those deprecated pipes.

2. Date pipe
* Breaking changes:
  - the predefined formats (`short`, `shortTime`, `shortDate`, `medium`, ...) now use the patterns given by CLDR (like it was in AngularJS) instead of the ones from the intl API. You might notice some changes, e.g. `shortDate` will be `8/15/17` instead of `8/15/2017` for `en-US`.
  - the narrow version of eras is now `GGGGG` instead of `G`, the format `G` is now similar to `GG` and `GGG`.
  - the narrow version of months is now `MMMMM` instead of `L`, the format `L` is now the short standalone version of months.
  - the narrow version of the week day is now `EEEEE` instead of `E`, the format `E` is now similar to `EE` and `EEE`.
  - the timezone `z` will now fallback to `O` and output `GMT+1` instead of the complete zone name (e.g. `Pacific Standard Time`), this is because the quantity of data required to have all the zone names in all of the existing locales is too big.
  - the timezone `Z` will now output the ISO8601 basic format, e.g. `+0100`, you should now use `ZZZZ` to get `GMT+01:00`.

  | Field type | Format        | Example value         | v4 | v5            |
  |------------|---------------|-----------------------|----|---------------|
  | Eras       | Narrow        | A for AD              | G  | GGGGG         |
  | Months     | Narrow        | S for September       | L  | MMMMM         |
  | Week day   | Narrow        | M for Monday          | E  | EEEEE         |
  | Timezone   | Long location | Pacific Standard Time | z  | Not available |
  | Timezone   | Long GMT      | GMT+01:00             | Z  | ZZZZ          |

* Features
  - new predefined formats `long`, `full`, `longTime`, `fullTime`.
  - the format `yyy` is now supported, e.g. the year `52` will be `052` and the year `2017` will be `2017`.
  - standalone months are now supported with the formats `L` to `LLLLL`.
  - week of the year is now supported with the formats `w` and `ww`, e.g. weeks `5` and `05`.
  - week of the month is now supported with the format `W`, e.g. week `3`.
  - fractional seconds are now supported with the format `S` to `SSS`.
  - day periods for AM/PM now supports additional formats `aa`, `aaa`, `aaaa` and `aaaaa`. The formats `a` to `aaa` are similar, while `aaaa` is the wide version if available (e.g. `ante meridiem` for `am`), or equivalent to `a` otherwise, and `aaaaa` is the narrow version (e.g. `a` for `am`).
  - extra day periods are now supported with the formats `b` to `bbbbb` (and `B` to `BBBBB` for the standalone equivalents), e.g. `morning`, `noon`, `afternoon`, ....
  - the short non-localized timezones are now available with the format `O` to `OOOO`. The formats `O` to `OOO` will output `GMT+1` while the format `OOOO` will be `GMT+01:00`.
  - the ISO8601 basic time zones are now available with the formats `Z` to `ZZZZZ`. The formats `Z` to `ZZZ` will output `+0100`, while the format `ZZZZ` will be `GMT+01:00` and `ZZZZZ` will be `+01:00`.

* Bug fixes
  - the date pipe will now work exactly the same across all browsers, which will fix a lot of bugs for safari and IE.
  - eras can now be used on their own without the date, e.g. the format `GG` will be `AD` instead of `8 15, 2017 AD`.

3. Currency pipe
* Breaking change:
  - the default value for `symbolDisplay` is now `symbol` instead of `code`. This means that by default you will see `$4.99` for `en-US` instead of `USD4.99` previously.

* Deprecation:
  - the second parameter of the currency pipe (`symbolDisplay`) is no longer a boolean, it now takes the values `code`, `symbol` or `symbol-narrow`. A boolean value is still valid for now, but it is deprecated and it will print a warning message in the console.

* Features:
  - you can now choose between `code`, `symbol` or `symbol-narrow` which gives you access to more options for some currencies (e.g. the canadian dollar with the code `CAD` has the symbol `CA$` and the symbol-narrow `$`).

4. Percent pipe
* Breaking change
  - if you don't specify the number of digits to round to, the local format will be used (and it usually rounds numbers to 0 digits, instead of not rounding previously), e.g. `{{ 3.141592 | percent }}` will output `314%` for the locale `en-US` instead of `314.1592%` previously.

Fixes #10809, #9524, #7008, #9324, #7590, #6724, #3429, #17576, #17478, #17319, #17200, #16838, #16624, #16625, #16591, #14131, #12632, #11376, #11187

PR Close #18284

@mhevery mhevery closed this in 33d250f Aug 22, 2017

@ocombe ocombe deleted the ocombe:fix-intl-api-10809 branch Nov 10, 2017

ocombe added a commit to ocombe/angular that referenced this pull request Mar 6, 2019

fix(common): remove deprecated support for intl API
BREAKING CHANGE:

In v5, we deprecated support for the intl API in order to improve the browser support. We are now removing these deprecated APIs for v8. See the original change here for more info on why: angular#18284.

ocombe added a commit to ocombe/angular that referenced this pull request Mar 7, 2019

fix(common): remove deprecated support for intl API
BREAKING CHANGE:

In v5, we deprecated support for the intl API in order to improve the browser support. We are now removing these deprecated APIs for v8. See the original change here for more info on why: angular#18284.

ocombe added a commit to ocombe/angular that referenced this pull request Mar 7, 2019

fix(common): remove deprecated support for intl API
BREAKING CHANGE:

In v5, we deprecated support for the intl API in order to improve the browser support. We are now removing these deprecated APIs for v8. See the original change here for more info on why: angular#18284.

ocombe added a commit to ocombe/angular that referenced this pull request Mar 7, 2019

fix(common): remove deprecated support for intl API
BREAKING CHANGE:

In v5, we deprecated support for the intl API in order to improve the browser support. We are now removing these deprecated APIs for v8. See the original change here for more info on why: angular#18284.

ocombe added a commit to ocombe/angular that referenced this pull request Mar 12, 2019

fix(common): remove deprecated support for intl API
BREAKING CHANGE:

In v5, we deprecated support for the intl API in order to improve the browser support. We are now removing these deprecated APIs for v8. See the original change here for more info on why: angular#18284.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.