react-intl 2.6.0 → 2.8.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.
Files changed (260) hide show
  1. package/dist/react-intl.js +60 -52
  2. package/dist/react-intl.js.map +1 -1
  3. package/dist/react-intl.min.js +1 -1
  4. package/dist/react-intl.min.js.map +1 -1
  5. package/lib/index.es.js +60 -52
  6. package/lib/index.js +60 -52
  7. package/locale-data/af.js +1 -1
  8. package/locale-data/agq.js +1 -1
  9. package/locale-data/ak.js +1 -1
  10. package/locale-data/am.js +1 -1
  11. package/locale-data/ar.js +1 -1
  12. package/locale-data/ars.js +1 -1
  13. package/locale-data/as.js +1 -1
  14. package/locale-data/asa.js +1 -1
  15. package/locale-data/ast.js +1 -1
  16. package/locale-data/az.js +1 -1
  17. package/locale-data/bas.js +1 -1
  18. package/locale-data/be.js +1 -1
  19. package/locale-data/bem.js +1 -1
  20. package/locale-data/bez.js +1 -1
  21. package/locale-data/bg.js +1 -1
  22. package/locale-data/bh.js +1 -1
  23. package/locale-data/bm.js +1 -1
  24. package/locale-data/bn.js +1 -1
  25. package/locale-data/bo.js +1 -1
  26. package/locale-data/br.js +1 -1
  27. package/locale-data/brx.js +1 -1
  28. package/locale-data/bs.js +1 -1
  29. package/locale-data/ca.js +1 -1
  30. package/locale-data/ccp.js +1 -0
  31. package/locale-data/ce.js +1 -1
  32. package/locale-data/cgg.js +1 -1
  33. package/locale-data/chr.js +1 -1
  34. package/locale-data/ckb.js +1 -1
  35. package/locale-data/cs.js +1 -1
  36. package/locale-data/cu.js +1 -1
  37. package/locale-data/cy.js +1 -1
  38. package/locale-data/da.js +1 -1
  39. package/locale-data/dav.js +1 -1
  40. package/locale-data/de.js +1 -1
  41. package/locale-data/dje.js +1 -1
  42. package/locale-data/dsb.js +1 -1
  43. package/locale-data/dua.js +1 -1
  44. package/locale-data/dv.js +1 -1
  45. package/locale-data/dyo.js +1 -1
  46. package/locale-data/dz.js +1 -1
  47. package/locale-data/ebu.js +1 -1
  48. package/locale-data/ee.js +1 -1
  49. package/locale-data/el.js +1 -1
  50. package/locale-data/en.js +1 -1
  51. package/locale-data/eo.js +1 -1
  52. package/locale-data/es.js +1 -1
  53. package/locale-data/et.js +1 -1
  54. package/locale-data/eu.js +1 -1
  55. package/locale-data/ewo.js +1 -1
  56. package/locale-data/fa.js +1 -1
  57. package/locale-data/ff.js +1 -1
  58. package/locale-data/fi.js +1 -1
  59. package/locale-data/fil.js +1 -1
  60. package/locale-data/fo.js +1 -1
  61. package/locale-data/fr.js +1 -1
  62. package/locale-data/fur.js +1 -1
  63. package/locale-data/fy.js +1 -1
  64. package/locale-data/ga.js +1 -1
  65. package/locale-data/gd.js +1 -1
  66. package/locale-data/gl.js +1 -1
  67. package/locale-data/gsw.js +1 -1
  68. package/locale-data/gu.js +1 -1
  69. package/locale-data/guw.js +1 -1
  70. package/locale-data/guz.js +1 -1
  71. package/locale-data/gv.js +1 -1
  72. package/locale-data/ha.js +1 -1
  73. package/locale-data/haw.js +1 -1
  74. package/locale-data/he.js +1 -1
  75. package/locale-data/hi.js +1 -1
  76. package/locale-data/hr.js +1 -1
  77. package/locale-data/hsb.js +1 -1
  78. package/locale-data/hu.js +1 -1
  79. package/locale-data/hy.js +1 -1
  80. package/locale-data/ia.js +1 -0
  81. package/locale-data/id.js +1 -1
  82. package/locale-data/ig.js +1 -1
  83. package/locale-data/ii.js +1 -1
  84. package/locale-data/in.js +1 -1
  85. package/locale-data/index.js +1 -1
  86. package/locale-data/io.js +1 -0
  87. package/locale-data/is.js +1 -1
  88. package/locale-data/it.js +1 -1
  89. package/locale-data/iu.js +1 -1
  90. package/locale-data/iw.js +1 -1
  91. package/locale-data/ja.js +1 -1
  92. package/locale-data/jbo.js +1 -1
  93. package/locale-data/jgo.js +1 -1
  94. package/locale-data/ji.js +1 -1
  95. package/locale-data/jmc.js +1 -1
  96. package/locale-data/jv.js +1 -1
  97. package/locale-data/jw.js +1 -1
  98. package/locale-data/ka.js +1 -1
  99. package/locale-data/kab.js +1 -1
  100. package/locale-data/kaj.js +1 -1
  101. package/locale-data/kam.js +1 -1
  102. package/locale-data/kcg.js +1 -1
  103. package/locale-data/kde.js +1 -1
  104. package/locale-data/kea.js +1 -1
  105. package/locale-data/khq.js +1 -1
  106. package/locale-data/ki.js +1 -1
  107. package/locale-data/kk.js +1 -1
  108. package/locale-data/kkj.js +1 -1
  109. package/locale-data/kl.js +1 -1
  110. package/locale-data/kln.js +1 -1
  111. package/locale-data/km.js +1 -1
  112. package/locale-data/kn.js +1 -1
  113. package/locale-data/ko.js +1 -1
  114. package/locale-data/kok.js +1 -1
  115. package/locale-data/ks.js +1 -1
  116. package/locale-data/ksb.js +1 -1
  117. package/locale-data/ksf.js +1 -1
  118. package/locale-data/ksh.js +1 -1
  119. package/locale-data/ku.js +1 -1
  120. package/locale-data/kw.js +1 -1
  121. package/locale-data/ky.js +1 -1
  122. package/locale-data/lag.js +1 -1
  123. package/locale-data/lb.js +1 -1
  124. package/locale-data/lg.js +1 -1
  125. package/locale-data/lkt.js +1 -1
  126. package/locale-data/ln.js +1 -1
  127. package/locale-data/lo.js +1 -1
  128. package/locale-data/lrc.js +1 -1
  129. package/locale-data/lt.js +1 -1
  130. package/locale-data/lu.js +1 -1
  131. package/locale-data/luo.js +1 -1
  132. package/locale-data/luy.js +1 -1
  133. package/locale-data/lv.js +1 -1
  134. package/locale-data/mas.js +1 -1
  135. package/locale-data/mer.js +1 -1
  136. package/locale-data/mfe.js +1 -1
  137. package/locale-data/mg.js +1 -1
  138. package/locale-data/mgh.js +1 -1
  139. package/locale-data/mgo.js +1 -1
  140. package/locale-data/mi.js +1 -0
  141. package/locale-data/mk.js +1 -1
  142. package/locale-data/ml.js +1 -1
  143. package/locale-data/mn.js +1 -1
  144. package/locale-data/mo.js +1 -1
  145. package/locale-data/mr.js +1 -1
  146. package/locale-data/ms.js +1 -1
  147. package/locale-data/mt.js +1 -1
  148. package/locale-data/mua.js +1 -1
  149. package/locale-data/my.js +1 -1
  150. package/locale-data/mzn.js +1 -1
  151. package/locale-data/nah.js +1 -1
  152. package/locale-data/naq.js +1 -1
  153. package/locale-data/nb.js +1 -1
  154. package/locale-data/nd.js +1 -1
  155. package/locale-data/nds.js +1 -1
  156. package/locale-data/ne.js +1 -1
  157. package/locale-data/nl.js +1 -1
  158. package/locale-data/nmg.js +1 -1
  159. package/locale-data/nn.js +1 -1
  160. package/locale-data/nnh.js +1 -1
  161. package/locale-data/no.js +1 -1
  162. package/locale-data/nqo.js +1 -1
  163. package/locale-data/nr.js +1 -1
  164. package/locale-data/nso.js +1 -1
  165. package/locale-data/nus.js +1 -1
  166. package/locale-data/ny.js +1 -1
  167. package/locale-data/nyn.js +1 -1
  168. package/locale-data/om.js +1 -1
  169. package/locale-data/or.js +1 -1
  170. package/locale-data/os.js +1 -1
  171. package/locale-data/pa.js +1 -1
  172. package/locale-data/pap.js +1 -1
  173. package/locale-data/pl.js +1 -1
  174. package/locale-data/prg.js +1 -1
  175. package/locale-data/ps.js +1 -1
  176. package/locale-data/pt.js +1 -1
  177. package/locale-data/qu.js +1 -1
  178. package/locale-data/rm.js +1 -1
  179. package/locale-data/rn.js +1 -1
  180. package/locale-data/ro.js +1 -1
  181. package/locale-data/rof.js +1 -1
  182. package/locale-data/ru.js +1 -1
  183. package/locale-data/rw.js +1 -1
  184. package/locale-data/rwk.js +1 -1
  185. package/locale-data/sah.js +1 -1
  186. package/locale-data/saq.js +1 -1
  187. package/locale-data/sbp.js +1 -1
  188. package/locale-data/sc.js +1 -0
  189. package/locale-data/scn.js +1 -0
  190. package/locale-data/sd.js +1 -0
  191. package/locale-data/sdh.js +1 -1
  192. package/locale-data/se.js +1 -1
  193. package/locale-data/seh.js +1 -1
  194. package/locale-data/ses.js +1 -1
  195. package/locale-data/sg.js +1 -1
  196. package/locale-data/sh.js +1 -1
  197. package/locale-data/shi.js +1 -1
  198. package/locale-data/si.js +1 -1
  199. package/locale-data/sk.js +1 -1
  200. package/locale-data/sl.js +1 -1
  201. package/locale-data/sma.js +1 -1
  202. package/locale-data/smi.js +1 -1
  203. package/locale-data/smj.js +1 -1
  204. package/locale-data/smn.js +1 -1
  205. package/locale-data/sms.js +1 -1
  206. package/locale-data/sn.js +1 -1
  207. package/locale-data/so.js +1 -1
  208. package/locale-data/sq.js +1 -1
  209. package/locale-data/sr.js +1 -1
  210. package/locale-data/ss.js +1 -1
  211. package/locale-data/ssy.js +1 -1
  212. package/locale-data/st.js +1 -1
  213. package/locale-data/sv.js +1 -1
  214. package/locale-data/sw.js +1 -1
  215. package/locale-data/syr.js +1 -1
  216. package/locale-data/ta.js +1 -1
  217. package/locale-data/te.js +1 -1
  218. package/locale-data/teo.js +1 -1
  219. package/locale-data/tg.js +1 -0
  220. package/locale-data/th.js +1 -1
  221. package/locale-data/ti.js +1 -1
  222. package/locale-data/tig.js +1 -1
  223. package/locale-data/tk.js +1 -1
  224. package/locale-data/tl.js +1 -1
  225. package/locale-data/tn.js +1 -1
  226. package/locale-data/to.js +1 -1
  227. package/locale-data/tr.js +1 -1
  228. package/locale-data/ts.js +1 -1
  229. package/locale-data/tt.js +1 -0
  230. package/locale-data/twq.js +1 -1
  231. package/locale-data/tzm.js +1 -1
  232. package/locale-data/ug.js +1 -1
  233. package/locale-data/uk.js +1 -1
  234. package/locale-data/ur.js +1 -1
  235. package/locale-data/uz.js +1 -1
  236. package/locale-data/vai.js +1 -1
  237. package/locale-data/ve.js +1 -1
  238. package/locale-data/vi.js +1 -1
  239. package/locale-data/vo.js +1 -1
  240. package/locale-data/vun.js +1 -1
  241. package/locale-data/wa.js +1 -1
  242. package/locale-data/wae.js +1 -1
  243. package/locale-data/wo.js +1 -1
  244. package/locale-data/xh.js +1 -1
  245. package/locale-data/xog.js +1 -1
  246. package/locale-data/yav.js +1 -1
  247. package/locale-data/yi.js +1 -1
  248. package/locale-data/yo.js +1 -1
  249. package/locale-data/yue.js +1 -1
  250. package/locale-data/zgh.js +1 -1
  251. package/locale-data/zh.js +1 -1
  252. package/locale-data/zu.js +1 -1
  253. package/package.json +2 -2
  254. package/src/components/provider.js +16 -8
  255. package/src/en.js +1 -1
  256. package/src/format.js +55 -57
  257. package/src/inject.js +2 -2
  258. package/src/types.js +2 -0
  259. package/src/utils.js +11 -0
  260. package/yarn.lock +19 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-intl",
3
- "version": "2.6.0",
3
+ "version": "2.8.0",
4
4
  "description": "Internationalize React apps. This library provides React components and an API to format dates, numbers, and strings, including pluralization and handling translations.",
5
5
  "keywords": [
6
6
  "intl",
@@ -99,7 +99,7 @@
99
99
  "expect": "^1.9.0",
100
100
  "expect-jsx": "^3.0.0",
101
101
  "express": "^4.13.3",
102
- "formatjs-extract-cldr-data": "^4.0.0",
102
+ "formatjs-extract-cldr-data": "^6.0.0",
103
103
  "glob": "^7.0.0",
104
104
  "intl": "^1.2.1",
105
105
  "intl-messageformat-parser": "^1.2.0",
@@ -11,7 +11,12 @@ import IntlRelativeFormat from 'intl-relativeformat';
11
11
  import IntlPluralFormat from '../plural';
12
12
  import memoizeIntlConstructor from 'intl-format-cache';
13
13
  import invariant from 'invariant';
14
- import {shouldIntlComponentUpdate, filterProps} from '../utils';
14
+ import {
15
+ createError,
16
+ defaultErrorHandler,
17
+ shouldIntlComponentUpdate,
18
+ filterProps,
19
+ } from '../utils';
15
20
  import {intlConfigPropTypes, intlFormatPropTypes, intlShape} from '../types';
16
21
  import * as format from '../format';
17
22
  import {hasLocaleData} from '../locale-data-registry';
@@ -29,6 +34,8 @@ const defaultProps = {
29
34
 
30
35
  defaultLocale: 'en',
31
36
  defaultFormats: {},
37
+
38
+ onError: defaultErrorHandler,
32
39
  };
33
40
 
34
41
  export default class IntlProvider extends Component {
@@ -84,7 +91,8 @@ export default class IntlProvider extends Component {
84
91
  getRelativeFormat: memoizeIntlConstructor(IntlRelativeFormat),
85
92
  getPluralFormat: memoizeIntlConstructor(IntlPluralFormat),
86
93
  },
87
- } = intlContext || {};
94
+ } =
95
+ intlContext || {};
88
96
 
89
97
  this.state = {
90
98
  ...formatters,
@@ -113,14 +121,14 @@ export default class IntlProvider extends Component {
113
121
  }
114
122
 
115
123
  if (!hasLocaleData(config.locale)) {
116
- const {locale, defaultLocale, defaultFormats} = config;
124
+ const {locale, defaultLocale, defaultFormats, onError} = config;
117
125
 
118
- if (process.env.NODE_ENV !== 'production') {
119
- console.error(
120
- `[React Intl] Missing locale data for locale: "${locale}". ` +
126
+ onError(
127
+ createError(
128
+ `Missing locale data for locale: "${locale}". ` +
121
129
  `Using default locale: "${defaultLocale}" as fallback.`
122
- );
123
- }
130
+ )
131
+ );
124
132
 
125
133
  // Since there's no registered locale data for `locale`, this will
126
134
  // fallback to the `defaultLocale` to make sure things can render.
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","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"}}}}};
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"}}},"year-short":{"displayName":"yr.","relative":{"0":"this yr.","1":"next yr.","-1":"last yr."},"relativeTime":{"future":{"one":"in {0} yr.","other":"in {0} yr."},"past":{"one":"{0} yr. ago","other":"{0} yr. 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"}}},"month-short":{"displayName":"mo.","relative":{"0":"this mo.","1":"next mo.","-1":"last mo."},"relativeTime":{"future":{"one":"in {0} mo.","other":"in {0} mo."},"past":{"one":"{0} mo. ago","other":"{0} mo. 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"}}},"day-short":{"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"}}},"hour-short":{"displayName":"hr.","relative":{"0":"this hour"},"relativeTime":{"future":{"one":"in {0} hr.","other":"in {0} hr."},"past":{"one":"{0} hr. ago","other":"{0} hr. 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"}}},"minute-short":{"displayName":"min.","relative":{"0":"this minute"},"relativeTime":{"future":{"one":"in {0} min.","other":"in {0} min."},"past":{"one":"{0} min. ago","other":"{0} min. 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"}}},"second-short":{"displayName":"sec.","relative":{"0":"now"},"relativeTime":{"future":{"one":"in {0} sec.","other":"in {0} sec."},"past":{"one":"{0} sec. ago","other":"{0} sec. ago"}}}}};
package/src/format.js CHANGED
@@ -6,6 +6,7 @@
6
6
 
7
7
  import invariant from 'invariant';
8
8
  import IntlRelativeFormat from 'intl-relativeformat';
9
+ import {isValidElement} from 'react';
9
10
 
10
11
  import {
11
12
  dateTimeFormatPropTypes,
@@ -14,7 +15,7 @@ import {
14
15
  pluralFormatPropTypes,
15
16
  } from './types';
16
17
 
17
- import {escape, filterProps} from './utils';
18
+ import {createError, defaultErrorHandler, escape, filterProps} from './utils';
18
19
 
19
20
  const DATE_TIME_FORMAT_OPTIONS = Object.keys(dateTimeFormatPropTypes);
20
21
  const NUMBER_FORMAT_OPTIONS = Object.keys(numberFormatPropTypes);
@@ -45,25 +46,24 @@ function updateRelativeFormatThresholds(newThresholds) {
45
46
  } = newThresholds);
46
47
  }
47
48
 
48
- function getNamedFormat(formats, type, name) {
49
+ function getNamedFormat(formats, type, name, onError) {
49
50
  let format = formats && formats[type] && formats[type][name];
50
51
  if (format) {
51
52
  return format;
52
53
  }
53
54
 
54
- if (process.env.NODE_ENV !== 'production') {
55
- console.error(`[React Intl] No ${type} format named: ${name}`);
56
- }
55
+ onError(createError(`No ${type} format named: ${name}`));
57
56
  }
58
57
 
59
58
  export function formatDate(config, state, value, options = {}) {
60
59
  const {locale, formats, timeZone} = config;
61
60
  const {format} = options;
62
61
 
62
+ let onError = config.onError || defaultErrorHandler;
63
63
  let date = new Date(value);
64
64
  let defaults = {
65
65
  ...(timeZone && {timeZone}),
66
- ...(format && getNamedFormat(formats, 'date', format)),
66
+ ...(format && getNamedFormat(formats, 'date', format, onError)),
67
67
  };
68
68
  let filteredOptions = filterProps(
69
69
  options,
@@ -74,9 +74,7 @@ export function formatDate(config, state, value, options = {}) {
74
74
  try {
75
75
  return state.getDateTimeFormat(locale, filteredOptions).format(date);
76
76
  } catch (e) {
77
- if (process.env.NODE_ENV !== 'production') {
78
- console.error(`[React Intl] Error formatting date.\n${e}`);
79
- }
77
+ onError(createError('Error formatting date.', e));
80
78
  }
81
79
 
82
80
  return String(date);
@@ -86,10 +84,11 @@ export function formatTime(config, state, value, options = {}) {
86
84
  const {locale, formats, timeZone} = config;
87
85
  const {format} = options;
88
86
 
87
+ let onError = config.onError || defaultErrorHandler;
89
88
  let date = new Date(value);
90
89
  let defaults = {
91
90
  ...(timeZone && {timeZone}),
92
- ...(format && getNamedFormat(formats, 'time', format)),
91
+ ...(format && getNamedFormat(formats, 'time', format, onError)),
93
92
  };
94
93
  let filteredOptions = filterProps(
95
94
  options,
@@ -109,9 +108,7 @@ export function formatTime(config, state, value, options = {}) {
109
108
  try {
110
109
  return state.getDateTimeFormat(locale, filteredOptions).format(date);
111
110
  } catch (e) {
112
- if (process.env.NODE_ENV !== 'production') {
113
- console.error(`[React Intl] Error formatting time.\n${e}`);
114
- }
111
+ onError(createError('Error formatting time.', e));
115
112
  }
116
113
 
117
114
  return String(date);
@@ -121,9 +118,10 @@ export function formatRelative(config, state, value, options = {}) {
121
118
  const {locale, formats} = config;
122
119
  const {format} = options;
123
120
 
121
+ let onError = config.onError || defaultErrorHandler;
124
122
  let date = new Date(value);
125
123
  let now = new Date(options.now);
126
- let defaults = format && getNamedFormat(formats, 'relative', format);
124
+ let defaults = format && getNamedFormat(formats, 'relative', format, onError);
127
125
  let filteredOptions = filterProps(options, RELATIVE_FORMAT_OPTIONS, defaults);
128
126
 
129
127
  // Capture the current threshold values, then temporarily override them with
@@ -136,9 +134,7 @@ export function formatRelative(config, state, value, options = {}) {
136
134
  now: isFinite(now) ? now : state.now(),
137
135
  });
138
136
  } catch (e) {
139
- if (process.env.NODE_ENV !== 'production') {
140
- console.error(`[React Intl] Error formatting relative time.\n${e}`);
141
- }
137
+ onError(createError('Error formatting relative time.', e));
142
138
  } finally {
143
139
  updateRelativeFormatThresholds(oldThresholds);
144
140
  }
@@ -150,15 +146,14 @@ export function formatNumber(config, state, value, options = {}) {
150
146
  const {locale, formats} = config;
151
147
  const {format} = options;
152
148
 
153
- let defaults = format && getNamedFormat(formats, 'number', format);
149
+ let onError = config.onError || defaultErrorHandler;
150
+ let defaults = format && getNamedFormat(formats, 'number', format, onError);
154
151
  let filteredOptions = filterProps(options, NUMBER_FORMAT_OPTIONS, defaults);
155
152
 
156
153
  try {
157
154
  return state.getNumberFormat(locale, filteredOptions).format(value);
158
155
  } catch (e) {
159
- if (process.env.NODE_ENV !== 'production') {
160
- console.error(`[React Intl] Error formatting number.\n${e}`);
161
- }
156
+ onError(createError('Error formatting number.', e));
162
157
  }
163
158
 
164
159
  return String(value);
@@ -168,13 +163,12 @@ export function formatPlural(config, state, value, options = {}) {
168
163
  const {locale} = config;
169
164
 
170
165
  let filteredOptions = filterProps(options, PLURAL_FORMAT_OPTIONS);
166
+ let onError = config.onError || defaultErrorHandler;
171
167
 
172
168
  try {
173
169
  return state.getPluralFormat(locale, filteredOptions).format(value);
174
170
  } catch (e) {
175
- if (process.env.NODE_ENV !== 'production') {
176
- console.error(`[React Intl] Error formatting plural.\n${e}`);
177
- }
171
+ onError(createError('Error formatting plural.', e));
178
172
  }
179
173
 
180
174
  return 'other';
@@ -190,6 +184,12 @@ export function formatMessage(
190
184
 
191
185
  const {id, defaultMessage} = messageDescriptor;
192
186
 
187
+ // Produce a better error if the user calls `intl.formatMessage(element)`
188
+ if (process.env.NODE_ENV !== 'production') {
189
+ invariant(!isValidElement(config), '[React Intl] Don\'t pass React elements to ' +
190
+ 'formatMessage(), pass `.props`.');
191
+ }
192
+
193
193
  // `id` is a required field of a Message Descriptor.
194
194
  invariant(id, '[React Intl] An `id` must be provided to format a message.');
195
195
 
@@ -203,6 +203,7 @@ export function formatMessage(
203
203
  }
204
204
 
205
205
  let formattedMessage;
206
+ let onError = config.onError || defaultErrorHandler;
206
207
 
207
208
  if (message) {
208
209
  try {
@@ -210,28 +211,28 @@ export function formatMessage(
210
211
 
211
212
  formattedMessage = formatter.format(values);
212
213
  } catch (e) {
213
- if (process.env.NODE_ENV !== 'production') {
214
- console.error(
215
- `[React Intl] Error formatting message: "${id}" for locale: "${locale}"` +
216
- (defaultMessage ? ', using default message as fallback.' : '') +
217
- `\n${e}`
218
- );
219
- }
214
+ onError(
215
+ createError(
216
+ `Error formatting message: "${id}" for locale: "${locale}"` +
217
+ (defaultMessage ? ', using default message as fallback.' : ''),
218
+ e
219
+ )
220
+ );
220
221
  }
221
222
  } else {
222
- if (process.env.NODE_ENV !== 'production') {
223
- // This prevents warnings from littering the console in development
224
- // when no `messages` are passed into the <IntlProvider> for the
225
- // default locale, and a default message is in the source.
226
- if (
227
- !defaultMessage ||
228
- (locale && locale.toLowerCase() !== defaultLocale.toLowerCase())
229
- ) {
230
- console.error(
231
- `[React Intl] Missing message: "${id}" for locale: "${locale}"` +
223
+ // This prevents warnings from littering the console in development
224
+ // when no `messages` are passed into the <IntlProvider> for the
225
+ // default locale, and a default message is in the source.
226
+ if (
227
+ !defaultMessage ||
228
+ (locale && locale.toLowerCase() !== defaultLocale.toLowerCase())
229
+ ) {
230
+ onError(
231
+ createError(
232
+ `Missing message: "${id}" for locale: "${locale}"` +
232
233
  (defaultMessage ? ', using default message as fallback.' : '')
233
- );
234
- }
234
+ )
235
+ );
235
236
  }
236
237
  }
237
238
 
@@ -245,24 +246,21 @@ export function formatMessage(
245
246
 
246
247
  formattedMessage = formatter.format(values);
247
248
  } catch (e) {
248
- if (process.env.NODE_ENV !== 'production') {
249
- console.error(
250
- `[React Intl] Error formatting the default message for: "${id}"` +
251
- `\n${e}`
252
- );
253
- }
249
+ onError(
250
+ createError(`Error formatting the default message for: "${id}"`, e)
251
+ );
254
252
  }
255
253
  }
256
254
 
257
255
  if (!formattedMessage) {
258
- if (process.env.NODE_ENV !== 'production') {
259
- console.error(
260
- `[React Intl] Cannot format message: "${id}", ` +
261
- `using message ${
262
- message || defaultMessage ? 'source' : 'id'
263
- } as fallback.`
264
- );
265
- }
256
+ onError(
257
+ createError(
258
+ `Cannot format message: "${id}", ` +
259
+ `using message ${message || defaultMessage
260
+ ? 'source'
261
+ : 'id'} as fallback.`
262
+ )
263
+ );
266
264
  }
267
265
 
268
266
  return formattedMessage || message || defaultMessage || id;
package/src/inject.js CHANGED
@@ -42,7 +42,7 @@ export default function injectIntl(WrappedComponent, options = {}) {
42
42
  '`injectIntl()`'
43
43
  );
44
44
 
45
- return this.refs.wrappedInstance;
45
+ return this._wrappedInstance;
46
46
  }
47
47
 
48
48
  render() {
@@ -50,7 +50,7 @@ export default function injectIntl(WrappedComponent, options = {}) {
50
50
  <WrappedComponent
51
51
  {...this.props}
52
52
  {...{[intlPropName]: this.context.intl}}
53
- ref={withRef ? 'wrappedInstance' : null}
53
+ ref={withRef ? /* istanbul ignore next */ (ref => this._wrappedInstance = ref) : null}
54
54
  />
55
55
  );
56
56
  }
package/src/types.js CHANGED
@@ -31,6 +31,8 @@ export const intlConfigPropTypes = {
31
31
 
32
32
  defaultLocale: string,
33
33
  defaultFormats: object,
34
+
35
+ onError: func,
34
36
  };
35
37
 
36
38
  export const intlFormatPropTypes = {
package/src/utils.js CHANGED
@@ -101,3 +101,14 @@ export function shouldIntlComponentUpdate(
101
101
  )
102
102
  );
103
103
  }
104
+
105
+ export function createError(message, exception) {
106
+ const eMsg = exception ? `\n${exception}` : '';
107
+ return `[React Intl] ${message}${eMsg}`;
108
+ }
109
+
110
+ export function defaultErrorHandler(error) {
111
+ if (process.env.NODE_ENV !== 'production') {
112
+ console.error(error);
113
+ }
114
+ }
package/yarn.lock CHANGED
@@ -1166,17 +1166,20 @@ circular-json@^0.3.1:
1166
1166
  version "0.3.1"
1167
1167
  resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d"
1168
1168
 
1169
- cldr-core@^31.0.1:
1170
- version "31.0.1"
1171
- resolved "https://registry.yarnpkg.com/cldr-core/-/cldr-core-31.0.1.tgz#24b3d59359ef890595665e5a8ca29e53901c6d54"
1169
+ cldr-core@^34.0.0:
1170
+ version "34.0.0"
1171
+ resolved "https://registry.yarnpkg.com/cldr-core/-/cldr-core-34.0.0.tgz#2e9d1f9909868e93e70c4813a74f331af028d66c"
1172
+ integrity sha512-PFHHn2SlqRdqD1ZC8Ddw5ZOSwJdqsmTY6fnOVsX5iMfOShqXs7QhpkIo4eOvz7rFdEivp/IrMDPs47Z4z1rD3g==
1172
1173
 
1173
- cldr-dates-full@^31.0.1:
1174
- version "31.0.1"
1175
- resolved "https://registry.yarnpkg.com/cldr-dates-full/-/cldr-dates-full-31.0.1.tgz#c49a4740250646148cfb55e02f20d7ae2c917f89"
1174
+ cldr-dates-full@^34.0.0:
1175
+ version "34.0.0"
1176
+ resolved "https://registry.yarnpkg.com/cldr-dates-full/-/cldr-dates-full-34.0.0.tgz#e2f9c254ab7d6b0a5d28481737138530eebb3be6"
1177
+ integrity sha512-mKGQF16YAEeMOlTA1oT8vWOnm2VuCE1yGQQN7CbnKirVhXigoa0uUiOwjajCZSVpLMyTwWi8AvlY1pjNlX6uRw==
1176
1178
 
1177
- cldr-numbers-full@^31.0.1:
1178
- version "31.0.1"
1179
- resolved "https://registry.yarnpkg.com/cldr-numbers-full/-/cldr-numbers-full-31.0.1.tgz#a78774e1544fbf9616d8f6812a312b10f4aaafbe"
1179
+ cldr-numbers-full@^34.0.0:
1180
+ version "34.0.0"
1181
+ resolved "https://registry.yarnpkg.com/cldr-numbers-full/-/cldr-numbers-full-34.0.0.tgz#f9e62bd4dda1fb4e17c7a3e4b170da2263f43dac"
1182
+ integrity sha512-+Bqxnym5Fv81u/iBoZvy2dUfPQdAc4KbX4QDptq9PLx846iQkRN0UKo3t5xZu97rUlRw2fFGaRt+KO6iMPo+RA==
1180
1183
 
1181
1184
  cli-cursor@^1.0.1:
1182
1185
  version "1.0.2"
@@ -2064,13 +2067,14 @@ form-data@^2.1.1, form-data@~2.1.1:
2064
2067
  combined-stream "^1.0.5"
2065
2068
  mime-types "^2.1.12"
2066
2069
 
2067
- formatjs-extract-cldr-data@^4.0.0:
2068
- version "4.0.0"
2069
- resolved "https://registry.yarnpkg.com/formatjs-extract-cldr-data/-/formatjs-extract-cldr-data-4.0.0.tgz#72b8c36f92a855989a381fa6c194566b34a1539f"
2070
+ formatjs-extract-cldr-data@^6.0.0:
2071
+ version "6.0.0"
2072
+ resolved "https://registry.yarnpkg.com/formatjs-extract-cldr-data/-/formatjs-extract-cldr-data-6.0.0.tgz#f05b6fe758ae109c1ee0b33c0c17781fe9cfb29b"
2073
+ integrity sha512-5AldF5PJMDi9Offq59NP7pswzEj3+ThiZcZY0mJ0DZINn3TZHrjx7jwewb4+G6c+3fTLt7KVl9SGc8qpet8j5w==
2070
2074
  dependencies:
2071
- cldr-core "^31.0.1"
2072
- cldr-dates-full "^31.0.1"
2073
- cldr-numbers-full "^31.0.1"
2075
+ cldr-core "^34.0.0"
2076
+ cldr-dates-full "^34.0.0"
2077
+ cldr-numbers-full "^34.0.0"
2074
2078
  glob "^5.0.1"
2075
2079
  make-plural "^2.1.3"
2076
2080
  object.assign "^4.0.3"