react-intl 2.2.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +20 -0
- package/dist/react-intl.js +1017 -1475
- package/dist/react-intl.js.map +1 -1
- package/dist/react-intl.min.js +1 -2
- package/dist/react-intl.min.js.map +1 -1
- package/lib/index.es.js +983 -1428
- package/lib/index.js +990 -1435
- package/locale-data/af.js +1 -1
- package/locale-data/agq.js +1 -1
- package/locale-data/ak.js +1 -1
- package/locale-data/am.js +1 -1
- package/locale-data/ar.js +1 -1
- package/locale-data/ars.js +1 -0
- package/locale-data/as.js +1 -1
- package/locale-data/asa.js +1 -1
- package/locale-data/ast.js +1 -1
- package/locale-data/az.js +1 -1
- package/locale-data/bas.js +1 -1
- package/locale-data/be.js +1 -1
- package/locale-data/bem.js +1 -1
- package/locale-data/bez.js +1 -1
- package/locale-data/bg.js +1 -1
- package/locale-data/bh.js +1 -1
- package/locale-data/bm.js +1 -1
- package/locale-data/bn.js +1 -1
- package/locale-data/bo.js +1 -1
- package/locale-data/br.js +1 -1
- package/locale-data/brx.js +1 -1
- package/locale-data/bs.js +1 -1
- package/locale-data/ca.js +1 -1
- package/locale-data/ce.js +1 -1
- package/locale-data/cgg.js +1 -1
- package/locale-data/chr.js +1 -1
- package/locale-data/ckb.js +1 -1
- package/locale-data/cs.js +1 -1
- package/locale-data/cu.js +1 -1
- package/locale-data/cy.js +1 -1
- package/locale-data/da.js +1 -1
- package/locale-data/dav.js +1 -1
- package/locale-data/de.js +1 -1
- package/locale-data/dje.js +1 -1
- package/locale-data/dsb.js +1 -1
- package/locale-data/dua.js +1 -1
- package/locale-data/dv.js +1 -1
- package/locale-data/dyo.js +1 -1
- package/locale-data/dz.js +1 -1
- package/locale-data/ebu.js +1 -1
- package/locale-data/ee.js +1 -1
- package/locale-data/el.js +1 -1
- package/locale-data/en.js +1 -1
- package/locale-data/eo.js +1 -1
- package/locale-data/es.js +1 -1
- package/locale-data/et.js +1 -1
- package/locale-data/eu.js +1 -1
- package/locale-data/ewo.js +1 -1
- package/locale-data/fa.js +1 -1
- package/locale-data/ff.js +1 -1
- package/locale-data/fi.js +1 -1
- package/locale-data/fil.js +1 -1
- package/locale-data/fo.js +1 -1
- package/locale-data/fr.js +1 -1
- package/locale-data/fur.js +1 -1
- package/locale-data/fy.js +1 -1
- package/locale-data/ga.js +1 -1
- package/locale-data/gd.js +1 -1
- package/locale-data/gl.js +1 -1
- package/locale-data/gsw.js +1 -1
- package/locale-data/gu.js +1 -1
- package/locale-data/guw.js +1 -1
- package/locale-data/guz.js +1 -1
- package/locale-data/gv.js +1 -1
- package/locale-data/ha.js +1 -1
- package/locale-data/haw.js +1 -1
- package/locale-data/he.js +1 -1
- package/locale-data/hi.js +1 -1
- package/locale-data/hr.js +1 -1
- package/locale-data/hsb.js +1 -1
- package/locale-data/hu.js +1 -1
- package/locale-data/hy.js +1 -1
- package/locale-data/id.js +1 -1
- package/locale-data/ig.js +1 -1
- package/locale-data/ii.js +1 -1
- package/locale-data/in.js +1 -1
- package/locale-data/index.js +1 -10
- package/locale-data/is.js +1 -1
- package/locale-data/it.js +1 -1
- package/locale-data/iu.js +1 -1
- package/locale-data/iw.js +1 -1
- package/locale-data/ja.js +1 -1
- package/locale-data/jbo.js +1 -1
- package/locale-data/jgo.js +1 -1
- package/locale-data/ji.js +1 -1
- package/locale-data/jmc.js +1 -1
- package/locale-data/jv.js +1 -1
- package/locale-data/jw.js +1 -1
- package/locale-data/ka.js +1 -1
- package/locale-data/kab.js +1 -1
- package/locale-data/kaj.js +1 -1
- package/locale-data/kam.js +1 -1
- package/locale-data/kcg.js +1 -1
- package/locale-data/kde.js +1 -1
- package/locale-data/kea.js +1 -1
- package/locale-data/khq.js +1 -1
- package/locale-data/ki.js +1 -1
- package/locale-data/kk.js +1 -1
- package/locale-data/kkj.js +1 -1
- package/locale-data/kl.js +1 -1
- package/locale-data/kln.js +1 -1
- package/locale-data/km.js +1 -1
- package/locale-data/kn.js +1 -1
- package/locale-data/ko.js +1 -1
- package/locale-data/kok.js +1 -1
- package/locale-data/ks.js +1 -1
- package/locale-data/ksb.js +1 -1
- package/locale-data/ksf.js +1 -1
- package/locale-data/ksh.js +1 -1
- package/locale-data/ku.js +1 -1
- package/locale-data/kw.js +1 -1
- package/locale-data/ky.js +1 -1
- package/locale-data/lag.js +1 -1
- package/locale-data/lb.js +1 -1
- package/locale-data/lg.js +1 -1
- package/locale-data/lkt.js +1 -1
- package/locale-data/ln.js +1 -1
- package/locale-data/lo.js +1 -1
- package/locale-data/lrc.js +1 -1
- package/locale-data/lt.js +1 -1
- package/locale-data/lu.js +1 -1
- package/locale-data/luo.js +1 -1
- package/locale-data/luy.js +1 -1
- package/locale-data/lv.js +1 -1
- package/locale-data/mas.js +1 -1
- package/locale-data/mer.js +1 -1
- package/locale-data/mfe.js +1 -1
- package/locale-data/mg.js +1 -1
- package/locale-data/mgh.js +1 -1
- package/locale-data/mgo.js +1 -1
- package/locale-data/mk.js +1 -1
- package/locale-data/ml.js +1 -1
- package/locale-data/mn.js +1 -1
- package/locale-data/mo.js +1 -1
- package/locale-data/mr.js +1 -1
- package/locale-data/ms.js +1 -1
- package/locale-data/mt.js +1 -1
- package/locale-data/mua.js +1 -1
- package/locale-data/my.js +1 -1
- package/locale-data/mzn.js +1 -1
- package/locale-data/nah.js +1 -1
- package/locale-data/naq.js +1 -1
- package/locale-data/nb.js +1 -1
- package/locale-data/nd.js +1 -1
- package/locale-data/nds.js +1 -0
- package/locale-data/ne.js +1 -1
- package/locale-data/nl.js +1 -1
- package/locale-data/nmg.js +1 -1
- package/locale-data/nn.js +1 -1
- package/locale-data/nnh.js +1 -1
- package/locale-data/no.js +1 -1
- package/locale-data/nqo.js +1 -1
- package/locale-data/nr.js +1 -1
- package/locale-data/nso.js +1 -1
- package/locale-data/nus.js +1 -1
- package/locale-data/ny.js +1 -1
- package/locale-data/nyn.js +1 -1
- package/locale-data/om.js +1 -1
- package/locale-data/or.js +1 -1
- package/locale-data/os.js +1 -1
- package/locale-data/pa.js +1 -1
- package/locale-data/pap.js +1 -1
- package/locale-data/pl.js +1 -1
- package/locale-data/prg.js +1 -1
- package/locale-data/ps.js +1 -1
- package/locale-data/pt.js +1 -1
- package/locale-data/qu.js +1 -1
- package/locale-data/rm.js +1 -1
- package/locale-data/rn.js +1 -1
- package/locale-data/ro.js +1 -1
- package/locale-data/rof.js +1 -1
- package/locale-data/ru.js +1 -1
- package/locale-data/rw.js +1 -1
- package/locale-data/rwk.js +1 -1
- package/locale-data/sah.js +1 -1
- package/locale-data/saq.js +1 -1
- package/locale-data/sbp.js +1 -1
- package/locale-data/sdh.js +1 -1
- package/locale-data/se.js +1 -1
- package/locale-data/seh.js +1 -1
- package/locale-data/ses.js +1 -1
- package/locale-data/sg.js +1 -1
- package/locale-data/sh.js +1 -1
- package/locale-data/shi.js +1 -1
- package/locale-data/si.js +1 -1
- package/locale-data/sk.js +1 -1
- package/locale-data/sl.js +1 -1
- package/locale-data/sma.js +1 -1
- package/locale-data/smi.js +1 -1
- package/locale-data/smj.js +1 -1
- package/locale-data/smn.js +1 -1
- package/locale-data/sms.js +1 -1
- package/locale-data/sn.js +1 -1
- package/locale-data/so.js +1 -1
- package/locale-data/sq.js +1 -1
- package/locale-data/sr.js +1 -1
- package/locale-data/ss.js +1 -1
- package/locale-data/ssy.js +1 -1
- package/locale-data/st.js +1 -1
- package/locale-data/sv.js +1 -1
- package/locale-data/sw.js +1 -1
- package/locale-data/syr.js +1 -1
- package/locale-data/ta.js +1 -1
- package/locale-data/te.js +1 -1
- package/locale-data/teo.js +1 -1
- package/locale-data/th.js +1 -1
- package/locale-data/ti.js +1 -1
- package/locale-data/tig.js +1 -1
- package/locale-data/tk.js +1 -1
- package/locale-data/tl.js +1 -1
- package/locale-data/tn.js +1 -1
- package/locale-data/to.js +1 -1
- package/locale-data/tr.js +1 -1
- package/locale-data/ts.js +1 -1
- package/locale-data/twq.js +1 -1
- package/locale-data/tzm.js +1 -1
- package/locale-data/ug.js +1 -1
- package/locale-data/uk.js +1 -1
- package/locale-data/ur.js +1 -1
- package/locale-data/uz.js +1 -1
- package/locale-data/vai.js +1 -1
- package/locale-data/ve.js +1 -1
- package/locale-data/vi.js +1 -1
- package/locale-data/vo.js +1 -1
- package/locale-data/vun.js +1 -1
- package/locale-data/wa.js +1 -1
- package/locale-data/wae.js +1 -1
- package/locale-data/wo.js +1 -1
- package/locale-data/xh.js +1 -1
- package/locale-data/xog.js +1 -1
- package/locale-data/yav.js +1 -1
- package/locale-data/yi.js +1 -1
- package/locale-data/yo.js +1 -1
- package/locale-data/yue.js +1 -0
- package/locale-data/zgh.js +1 -1
- package/locale-data/zh.js +1 -1
- package/locale-data/zu.js +1 -1
- package/package.json +33 -27
- package/src/components/date.js +30 -29
- package/src/components/html-message.js +63 -62
- package/src/components/message.js +117 -114
- package/src/components/number.js +30 -29
- package/src/components/plural.js +37 -36
- package/src/components/provider.js +135 -134
- package/src/components/relative.js +128 -120
- package/src/components/time.js +30 -29
- package/src/define-messages.js +3 -3
- package/src/en.js +1 -1
- package/src/format.js +209 -208
- package/src/inject.js +38 -40
- package/src/locale-data-registry.js +21 -21
- package/src/plural.js +9 -9
- package/src/types.js +58 -48
- package/src/utils.js +65 -55
- package/yarn.lock +4832 -0
package/src/en.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// GENERATED FILE
|
|
2
|
-
export default {"locale":"en","pluralRuleFunction":function (n,ord){var s=String(n).split("."),v0=!s[1],t0=Number(s[0])==n,n10=t0&&s[0].slice(-1),n100=t0&&s[0].slice(-2);if(ord)return n10==1&&n100!=11?"one":n10==2&&n100!=12?"two":n10==3&&n100!=13?"few":"other";return n==1&&v0?"one":"other"},"fields":{"year":{"displayName":"year","relative":{"0":"this year","1":"next year","-1":"last year"},"relativeTime":{"future":{"one":"in {0} year","other":"in {0} years"},"past":{"one":"{0} year ago","other":"{0} years ago"}}},"month":{"displayName":"month","relative":{"0":"this month","1":"next month","-1":"last month"},"relativeTime":{"future":{"one":"in {0} month","other":"in {0} months"},"past":{"one":"{0} month ago","other":"{0} months ago"}}},"day":{"displayName":"day","relative":{"0":"today","1":"tomorrow","-1":"yesterday"},"relativeTime":{"future":{"one":"in {0} day","other":"in {0} days"},"past":{"one":"{0} day ago","other":"{0} days ago"}}},"hour":{"displayName":"hour","relativeTime":{"future":{"one":"in {0} hour","other":"in {0} hours"},"past":{"one":"{0} hour ago","other":"{0} hours ago"}}},"minute":{"displayName":"minute","relativeTime":{"future":{"one":"in {0} minute","other":"in {0} minutes"},"past":{"one":"{0} minute ago","other":"{0} minutes ago"}}},"second":{"displayName":"second","relative":{"0":"now"},"relativeTime":{"future":{"one":"in {0} second","other":"in {0} seconds"},"past":{"one":"{0} second ago","other":"{0} seconds ago"}}}}};
|
|
2
|
+
export default {"locale":"en","pluralRuleFunction":function (n,ord){var s=String(n).split("."),v0=!s[1],t0=Number(s[0])==n,n10=t0&&s[0].slice(-1),n100=t0&&s[0].slice(-2);if(ord)return n10==1&&n100!=11?"one":n10==2&&n100!=12?"two":n10==3&&n100!=13?"few":"other";return n==1&&v0?"one":"other"},"fields":{"year":{"displayName":"year","relative":{"0":"this year","1":"next year","-1":"last year"},"relativeTime":{"future":{"one":"in {0} year","other":"in {0} years"},"past":{"one":"{0} year ago","other":"{0} years ago"}}},"month":{"displayName":"month","relative":{"0":"this month","1":"next month","-1":"last month"},"relativeTime":{"future":{"one":"in {0} month","other":"in {0} months"},"past":{"one":"{0} month ago","other":"{0} months ago"}}},"day":{"displayName":"day","relative":{"0":"today","1":"tomorrow","-1":"yesterday"},"relativeTime":{"future":{"one":"in {0} day","other":"in {0} days"},"past":{"one":"{0} day ago","other":"{0} days ago"}}},"hour":{"displayName":"hour","relative":{"0":"this hour"},"relativeTime":{"future":{"one":"in {0} hour","other":"in {0} hours"},"past":{"one":"{0} hour ago","other":"{0} hours ago"}}},"minute":{"displayName":"minute","relative":{"0":"this minute"},"relativeTime":{"future":{"one":"in {0} minute","other":"in {0} minutes"},"past":{"one":"{0} minute ago","other":"{0} minutes ago"}}},"second":{"displayName":"second","relative":{"0":"now"},"relativeTime":{"future":{"one":"in {0} second","other":"in {0} seconds"},"past":{"one":"{0} second ago","other":"{0} seconds ago"}}}}};
|
package/src/format.js
CHANGED
|
@@ -8,268 +8,269 @@ import invariant from 'invariant';
|
|
|
8
8
|
import IntlRelativeFormat from 'intl-relativeformat';
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
dateTimeFormatPropTypes,
|
|
12
|
+
numberFormatPropTypes,
|
|
13
|
+
relativeFormatPropTypes,
|
|
14
|
+
pluralFormatPropTypes,
|
|
15
15
|
} from './types';
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
escape,
|
|
19
|
-
filterProps,
|
|
20
|
-
} from './utils';
|
|
17
|
+
import {escape, filterProps} from './utils';
|
|
21
18
|
|
|
22
19
|
const DATE_TIME_FORMAT_OPTIONS = Object.keys(dateTimeFormatPropTypes);
|
|
23
|
-
const NUMBER_FORMAT_OPTIONS
|
|
24
|
-
const RELATIVE_FORMAT_OPTIONS
|
|
25
|
-
const PLURAL_FORMAT_OPTIONS
|
|
20
|
+
const NUMBER_FORMAT_OPTIONS = Object.keys(numberFormatPropTypes);
|
|
21
|
+
const RELATIVE_FORMAT_OPTIONS = Object.keys(relativeFormatPropTypes);
|
|
22
|
+
const PLURAL_FORMAT_OPTIONS = Object.keys(pluralFormatPropTypes);
|
|
26
23
|
|
|
27
24
|
const RELATIVE_FORMAT_THRESHOLDS = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
second: 60, // seconds to minute
|
|
26
|
+
minute: 60, // minutes to hour
|
|
27
|
+
hour: 24, // hours to day
|
|
28
|
+
day: 30, // days to month
|
|
29
|
+
month: 12, // months to year
|
|
33
30
|
};
|
|
34
31
|
|
|
35
32
|
function updateRelativeFormatThresholds(newThresholds) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
const {thresholds} = IntlRelativeFormat;
|
|
34
|
+
({
|
|
35
|
+
second: thresholds.second,
|
|
36
|
+
minute: thresholds.minute,
|
|
37
|
+
hour: thresholds.hour,
|
|
38
|
+
day: thresholds.day,
|
|
39
|
+
month: thresholds.month,
|
|
40
|
+
} = newThresholds);
|
|
44
41
|
}
|
|
45
42
|
|
|
46
43
|
function getNamedFormat(formats, type, name) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
);
|
|
56
|
-
}
|
|
44
|
+
let format = formats && formats[type] && formats[type][name];
|
|
45
|
+
if (format) {
|
|
46
|
+
return format;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
50
|
+
console.error(`[React Intl] No ${type} format named: ${name}`);
|
|
51
|
+
}
|
|
57
52
|
}
|
|
58
53
|
|
|
59
54
|
export function formatDate(config, state, value, options = {}) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
55
|
+
const {locale, formats} = config;
|
|
56
|
+
const {format} = options;
|
|
57
|
+
|
|
58
|
+
let date = new Date(value);
|
|
59
|
+
let defaults = format && getNamedFormat(formats, 'date', format);
|
|
60
|
+
let filteredOptions = filterProps(
|
|
61
|
+
options,
|
|
62
|
+
DATE_TIME_FORMAT_OPTIONS,
|
|
63
|
+
defaults
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
return state.getDateTimeFormat(locale, filteredOptions).format(date);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
70
|
+
console.error(`[React Intl] Error formatting date.\n${e}`);
|
|
75
71
|
}
|
|
72
|
+
}
|
|
76
73
|
|
|
77
|
-
|
|
74
|
+
return String(date);
|
|
78
75
|
}
|
|
79
76
|
|
|
80
77
|
export function formatTime(config, state, value, options = {}) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
78
|
+
const {locale, formats} = config;
|
|
79
|
+
const {format} = options;
|
|
80
|
+
|
|
81
|
+
let date = new Date(value);
|
|
82
|
+
let defaults = format && getNamedFormat(formats, 'time', format);
|
|
83
|
+
let filteredOptions = filterProps(
|
|
84
|
+
options,
|
|
85
|
+
DATE_TIME_FORMAT_OPTIONS,
|
|
86
|
+
defaults
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
if (
|
|
90
|
+
!filteredOptions.hour &&
|
|
91
|
+
!filteredOptions.minute &&
|
|
92
|
+
!filteredOptions.second
|
|
93
|
+
) {
|
|
94
|
+
// Add default formatting options if hour, minute, or second isn't defined.
|
|
95
|
+
filteredOptions = {...filteredOptions, hour: 'numeric', minute: 'numeric'};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
return state.getDateTimeFormat(locale, filteredOptions).format(date);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
102
|
+
console.error(`[React Intl] Error formatting time.\n${e}`);
|
|
101
103
|
}
|
|
104
|
+
}
|
|
102
105
|
|
|
103
|
-
|
|
106
|
+
return String(date);
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
export function formatRelative(config, state, value, options = {}) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
`[React Intl] Error formatting relative time.\n${e}`
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
} finally {
|
|
131
|
-
updateRelativeFormatThresholds(oldThresholds);
|
|
110
|
+
const {locale, formats} = config;
|
|
111
|
+
const {format} = options;
|
|
112
|
+
|
|
113
|
+
let date = new Date(value);
|
|
114
|
+
let now = new Date(options.now);
|
|
115
|
+
let defaults = format && getNamedFormat(formats, 'relative', format);
|
|
116
|
+
let filteredOptions = filterProps(options, RELATIVE_FORMAT_OPTIONS, defaults);
|
|
117
|
+
|
|
118
|
+
// Capture the current threshold values, then temporarily override them with
|
|
119
|
+
// specific values just for this render.
|
|
120
|
+
const oldThresholds = {...IntlRelativeFormat.thresholds};
|
|
121
|
+
updateRelativeFormatThresholds(RELATIVE_FORMAT_THRESHOLDS);
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
return state.getRelativeFormat(locale, filteredOptions).format(date, {
|
|
125
|
+
now: isFinite(now) ? now : state.now(),
|
|
126
|
+
});
|
|
127
|
+
} catch (e) {
|
|
128
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
129
|
+
console.error(`[React Intl] Error formatting relative time.\n${e}`);
|
|
132
130
|
}
|
|
131
|
+
} finally {
|
|
132
|
+
updateRelativeFormatThresholds(oldThresholds);
|
|
133
|
+
}
|
|
133
134
|
|
|
134
|
-
|
|
135
|
+
return String(date);
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
export function formatNumber(config, state, value, options = {}) {
|
|
138
|
-
|
|
139
|
-
|
|
139
|
+
const {locale, formats} = config;
|
|
140
|
+
const {format} = options;
|
|
140
141
|
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
let defaults = format && getNamedFormat(formats, 'number', format);
|
|
143
|
+
let filteredOptions = filterProps(options, NUMBER_FORMAT_OPTIONS, defaults);
|
|
143
144
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
`[React Intl] Error formatting number.\n${e}`
|
|
150
|
-
);
|
|
151
|
-
}
|
|
145
|
+
try {
|
|
146
|
+
return state.getNumberFormat(locale, filteredOptions).format(value);
|
|
147
|
+
} catch (e) {
|
|
148
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
149
|
+
console.error(`[React Intl] Error formatting number.\n${e}`);
|
|
152
150
|
}
|
|
151
|
+
}
|
|
153
152
|
|
|
154
|
-
|
|
153
|
+
return String(value);
|
|
155
154
|
}
|
|
156
155
|
|
|
157
156
|
export function formatPlural(config, state, value, options = {}) {
|
|
158
|
-
|
|
157
|
+
const {locale} = config;
|
|
159
158
|
|
|
160
|
-
|
|
159
|
+
let filteredOptions = filterProps(options, PLURAL_FORMAT_OPTIONS);
|
|
161
160
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
`[React Intl] Error formatting plural.\n${e}`
|
|
168
|
-
);
|
|
169
|
-
}
|
|
161
|
+
try {
|
|
162
|
+
return state.getPluralFormat(locale, filteredOptions).format(value);
|
|
163
|
+
} catch (e) {
|
|
164
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
165
|
+
console.error(`[React Intl] Error formatting plural.\n${e}`);
|
|
170
166
|
}
|
|
167
|
+
}
|
|
171
168
|
|
|
172
|
-
|
|
169
|
+
return 'other';
|
|
173
170
|
}
|
|
174
171
|
|
|
175
|
-
export function formatMessage(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
} = config;
|
|
172
|
+
export function formatMessage(
|
|
173
|
+
config,
|
|
174
|
+
state,
|
|
175
|
+
messageDescriptor = {},
|
|
176
|
+
values = {}
|
|
177
|
+
) {
|
|
178
|
+
const {locale, formats, messages, defaultLocale, defaultFormats} = config;
|
|
183
179
|
|
|
184
|
-
|
|
185
|
-
id,
|
|
186
|
-
defaultMessage,
|
|
187
|
-
} = messageDescriptor;
|
|
180
|
+
const {id, defaultMessage} = messageDescriptor;
|
|
188
181
|
|
|
189
|
-
|
|
190
|
-
|
|
182
|
+
// `id` is a required field of a Message Descriptor.
|
|
183
|
+
invariant(id, '[React Intl] An `id` must be provided to format a message.');
|
|
191
184
|
|
|
192
|
-
|
|
193
|
-
|
|
185
|
+
const message = messages && messages[id];
|
|
186
|
+
const hasValues = Object.keys(values).length > 0;
|
|
194
187
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
188
|
+
// Avoid expensive message formatting for simple messages without values. In
|
|
189
|
+
// development messages will always be formatted in case of missing values.
|
|
190
|
+
if (!hasValues && process.env.NODE_ENV === 'production') {
|
|
191
|
+
return message || defaultMessage || id;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
let formattedMessage;
|
|
195
|
+
|
|
196
|
+
if (message) {
|
|
197
|
+
try {
|
|
198
|
+
let formatter = state.getMessageFormat(message, locale, formats);
|
|
200
199
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
} catch (e) {
|
|
211
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
212
|
-
console.error(
|
|
213
|
-
`[React Intl] Error formatting message: "${id}" for locale: "${locale}"` +
|
|
214
|
-
(defaultMessage ? ', using default message as fallback.' : '') +
|
|
215
|
-
`\n${e}`
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
} else {
|
|
220
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
221
|
-
// This prevents warnings from littering the console in development
|
|
222
|
-
// when no `messages` are passed into the <IntlProvider> for the
|
|
223
|
-
// default locale, and a default message is in the source.
|
|
224
|
-
if (!defaultMessage ||
|
|
225
|
-
(locale && locale.toLowerCase() !== defaultLocale.toLowerCase())) {
|
|
226
|
-
|
|
227
|
-
console.error(
|
|
228
|
-
`[React Intl] Missing message: "${id}" for locale: "${locale}"` +
|
|
229
|
-
(defaultMessage ? ', using default message as fallback.' : '')
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
200
|
+
formattedMessage = formatter.format(values);
|
|
201
|
+
} catch (e) {
|
|
202
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
203
|
+
console.error(
|
|
204
|
+
`[React Intl] Error formatting message: "${id}" for locale: "${locale}"` +
|
|
205
|
+
(defaultMessage ? ', using default message as fallback.' : '') +
|
|
206
|
+
`\n${e}`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
233
209
|
}
|
|
210
|
+
} else {
|
|
211
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
212
|
+
// This prevents warnings from littering the console in development
|
|
213
|
+
// when no `messages` are passed into the <IntlProvider> for the
|
|
214
|
+
// default locale, and a default message is in the source.
|
|
215
|
+
if (
|
|
216
|
+
!defaultMessage ||
|
|
217
|
+
(locale && locale.toLowerCase() !== defaultLocale.toLowerCase())
|
|
218
|
+
) {
|
|
219
|
+
console.error(
|
|
220
|
+
`[React Intl] Missing message: "${id}" for locale: "${locale}"` +
|
|
221
|
+
(defaultMessage ? ', using default message as fallback.' : '')
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
234
226
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
227
|
+
if (!formattedMessage && defaultMessage) {
|
|
228
|
+
try {
|
|
229
|
+
let formatter = state.getMessageFormat(
|
|
230
|
+
defaultMessage,
|
|
231
|
+
defaultLocale,
|
|
232
|
+
defaultFormats
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
formattedMessage = formatter.format(values);
|
|
236
|
+
} catch (e) {
|
|
237
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
238
|
+
console.error(
|
|
239
|
+
`[React Intl] Error formatting the default message for: "${id}"` +
|
|
240
|
+
`\n${e}`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
250
243
|
}
|
|
244
|
+
}
|
|
251
245
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
246
|
+
if (!formattedMessage) {
|
|
247
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
248
|
+
console.error(
|
|
249
|
+
`[React Intl] Cannot format message: "${id}", ` +
|
|
250
|
+
`using message ${message || defaultMessage
|
|
251
|
+
? 'source'
|
|
252
|
+
: 'id'} as fallback.`
|
|
253
|
+
);
|
|
259
254
|
}
|
|
255
|
+
}
|
|
260
256
|
|
|
261
|
-
|
|
257
|
+
return formattedMessage || message || defaultMessage || id;
|
|
262
258
|
}
|
|
263
259
|
|
|
264
|
-
export function formatHTMLMessage(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
260
|
+
export function formatHTMLMessage(
|
|
261
|
+
config,
|
|
262
|
+
state,
|
|
263
|
+
messageDescriptor,
|
|
264
|
+
rawValues = {}
|
|
265
|
+
) {
|
|
266
|
+
// Process all the values before they are used when formatting the ICU
|
|
267
|
+
// Message string. Since the formatted message might be injected via
|
|
268
|
+
// `innerHTML`, all String-based values need to be HTML-escaped.
|
|
269
|
+
let escapedValues = Object.keys(rawValues).reduce((escaped, name) => {
|
|
270
|
+
let value = rawValues[name];
|
|
271
|
+
escaped[name] = typeof value === 'string' ? escape(value) : value;
|
|
272
|
+
return escaped;
|
|
273
|
+
}, {});
|
|
274
|
+
|
|
275
|
+
return formatMessage(config, state, messageDescriptor, escapedValues);
|
|
275
276
|
}
|
package/src/inject.js
CHANGED
|
@@ -13,49 +13,47 @@ import {intlShape} from './types';
|
|
|
13
13
|
import {invariantIntlContext} from './utils';
|
|
14
14
|
|
|
15
15
|
function getDisplayName(Component) {
|
|
16
|
-
|
|
16
|
+
return Component.displayName || Component.name || 'Component';
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export default function injectIntl(WrappedComponent, options = {}) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
/>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
20
|
+
const {intlPropName = 'intl', withRef = false} = options;
|
|
21
|
+
|
|
22
|
+
class InjectIntl extends Component {
|
|
23
|
+
static displayName = `InjectIntl(${getDisplayName(WrappedComponent)})`;
|
|
24
|
+
|
|
25
|
+
static contextTypes = {
|
|
26
|
+
intl: intlShape,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
static WrappedComponent = WrappedComponent;
|
|
30
|
+
|
|
31
|
+
constructor(props, context) {
|
|
32
|
+
super(props, context);
|
|
33
|
+
invariantIntlContext(context);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getWrappedInstance() {
|
|
37
|
+
invariant(
|
|
38
|
+
withRef,
|
|
39
|
+
'[React Intl] To access the wrapped instance, ' +
|
|
40
|
+
'the `{withRef: true}` option must be set when calling: ' +
|
|
41
|
+
'`injectIntl()`'
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
return this.refs.wrappedInstance;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
render() {
|
|
48
|
+
return (
|
|
49
|
+
<WrappedComponent
|
|
50
|
+
{...this.props}
|
|
51
|
+
{...{[intlPropName]: this.context.intl}}
|
|
52
|
+
ref={withRef ? 'wrappedInstance' : null}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
58
55
|
}
|
|
56
|
+
}
|
|
59
57
|
|
|
60
|
-
|
|
58
|
+
return InjectIntl;
|
|
61
59
|
}
|
|
@@ -8,35 +8,35 @@ import IntlMessageFormat from 'intl-messageformat';
|
|
|
8
8
|
import IntlRelativeFormat from 'intl-relativeformat';
|
|
9
9
|
|
|
10
10
|
export function addLocaleData(data = []) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
let locales = Array.isArray(data) ? data : [data];
|
|
12
|
+
|
|
13
|
+
locales.forEach(localeData => {
|
|
14
|
+
if (localeData && localeData.locale) {
|
|
15
|
+
IntlMessageFormat.__addLocaleData(localeData);
|
|
16
|
+
IntlRelativeFormat.__addLocaleData(localeData);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export function hasLocaleData(locale) {
|
|
22
|
-
|
|
22
|
+
let localeParts = (locale || '').split('-');
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
localeParts.pop();
|
|
24
|
+
while (localeParts.length > 0) {
|
|
25
|
+
if (hasIMFAndIRFLocaleData(localeParts.join('-'))) {
|
|
26
|
+
return true;
|
|
30
27
|
}
|
|
31
28
|
|
|
32
|
-
|
|
29
|
+
localeParts.pop();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return false;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
function hasIMFAndIRFLocaleData(locale) {
|
|
36
|
-
|
|
36
|
+
let normalizedLocale = locale && locale.toLowerCase();
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
return !!(
|
|
39
|
+
IntlMessageFormat.__localeData__[normalizedLocale] &&
|
|
40
|
+
IntlRelativeFormat.__localeData__[normalizedLocale]
|
|
41
|
+
);
|
|
42
42
|
}
|