Skip to content

Commit

Permalink
Merge pull request #15245 from Prince-Mendiratta/inconsistent-currenc…
Browse files Browse the repository at this point in the history
…y-symbol

[Intl] Polyfill Intl.NumberFormat if unexpected locale data on browser
  • Loading branch information
techievivek authored Feb 21, 2023
2 parents 80890b9 + 98924d4 commit 660e389
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 10 deletions.
9 changes: 9 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,15 @@ const CONST = {
'Zambia',
'Zimbabwe',
],

// Values for checking if polyfill is required on a platform
POLYFILL_TEST: {
STYLE: 'currency',
CURRENCY: 'XAF',
FORMAT: 'symbol',
SAMPLE_INPUT: '123456.789',
EXPECTED_OUTPUT: 'FCFA 123,457',
},
};

export default CONST;
15 changes: 15 additions & 0 deletions src/libs/IntlPolyfill/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import shouldPolyfill from './shouldPolyfill';
import polyfillNumberFormat from './polyfillNumberFormat';

/**
* Polyfill the Intl API if the ICU version is old.
* This ensures that the currency data is consistent across platforms and browsers.
*/
export default function intlPolyfill() {
if (!shouldPolyfill()) {
return;
}

// Just need to polyfill Intl.NumberFormat for web based platforms
polyfillNumberFormat();
}
17 changes: 17 additions & 0 deletions src/libs/IntlPolyfill/index.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import shouldPolyfill from './shouldPolyfill';
import polyfillNumberFormat from './polyfillNumberFormat';

/**
* Polyfill the Intl API, always performed for native devices.
*/
export default function polyfill() {
if (!shouldPolyfill()) {
return;
}

// Native devices require extra polyfills
require('@formatjs/intl-getcanonicallocales/polyfill');
require('@formatjs/intl-locale/polyfill');
require('@formatjs/intl-pluralrules/polyfill');
polyfillNumberFormat();
}
13 changes: 13 additions & 0 deletions src/libs/IntlPolyfill/polyfillNumberFormat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Common imports that are required for all platforms
*/

function polyfillNumberFormat() {
require('@formatjs/intl-numberformat/polyfill-force');

// Load en & es Locale data
require('@formatjs/intl-numberformat/locale-data/en');
require('@formatjs/intl-numberformat/locale-data/es');
}

export default polyfillNumberFormat;
29 changes: 29 additions & 0 deletions src/libs/IntlPolyfill/shouldPolyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import CONST from '../../CONST';

/**
* Check if the locale data is as expected on the device.
* Ensures that the currency data is consistent across devices.
* @returns {Boolean}
*/
function oldCurrencyData() {
return (
new Intl.NumberFormat(CONST.DEFAULT_LOCALE, {
style: CONST.POLYFILL_TEST.STYLE,
currency: CONST.POLYFILL_TEST.CURRENCY,
currencyDisplay: CONST.POLYFILL_TEST.FORMAT,
}).format(CONST.POLYFILL_TEST.SAMPLE_INPUT) !== CONST.POLYFILL_TEST.EXPECTED_OUTPUT
);
}

/**
* Check for the existence of the Intl API and ensure results will
* be as expected.
* @returns {Boolean}
*/
export default function shouldPolyfill() {
return (
typeof Intl === 'undefined'
|| !('NumberFormat' in Intl)
|| oldCurrencyData()
);
}
4 changes: 4 additions & 0 deletions src/setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CONST from '../CONST';
import platformSetup from './platformSetup';
import * as Metrics from '../libs/Metrics';
import * as Device from '../libs/actions/Device';
import intlPolyfill from '../libs/IntlPolyfill';

export default function () {
/*
Expand Down Expand Up @@ -47,6 +48,9 @@ export default function () {
I18nManager.allowRTL(false);
I18nManager.forceRTL(false);

// Polyfill the Intl API if locale data is not as expected
intlPolyfill();

// Perform any other platform-specific setup
platformSetup();
}
10 changes: 0 additions & 10 deletions src/setup/platformSetup/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@ import PushNotification from '../../libs/Notification/PushNotification';
import * as Report from '../../libs/actions/Report';
import Performance from '../../libs/Performance';

// we only need polyfills for Mobile.
import '@formatjs/intl-getcanonicallocales/polyfill';
import '@formatjs/intl-locale/polyfill';
import '@formatjs/intl-pluralrules/polyfill';
import '@formatjs/intl-numberformat/polyfill';

// Load en & es Locale data
import '@formatjs/intl-numberformat/locale-data/en';
import '@formatjs/intl-numberformat/locale-data/es';

export default function () {
// We do not want to send crash reports if we are on a locally built release version of the app.
// Crashlytics is disabled by default for debug builds, but not local release builds so we are using
Expand Down

0 comments on commit 660e389

Please sign in to comment.