react-intl 2.2.0 → 2.3.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 +145 -615
- package/dist/react-intl.js.map +1 -1
- package/dist/react-intl.min.js +2 -2
- package/dist/react-intl.min.js.map +1 -1
- package/lib/index.es.js +74 -520
- package/lib/index.js +110 -556
- package/package.json +24 -20
- package/yarn.lock +4804 -0
- package/src/components/date.js +0 -46
- package/src/components/html-message.js +0 -87
- package/src/components/message.js +0 -134
- package/src/components/number.js +0 -46
- package/src/components/plural.js +0 -58
- package/src/components/provider.js +0 -176
- package/src/components/relative.js +0 -163
- package/src/components/time.js +0 -46
- package/src/define-messages.js +0 -11
- package/src/en.js +0 -2
- package/src/format.js +0 -275
- package/src/index.js +0 -12
- package/src/inject.js +0 -61
- package/src/locale-data-registry.js +0 -42
- package/src/plural.js +0 -28
- package/src/react-intl.js +0 -24
- package/src/types.js +0 -88
- package/src/utils.js +0 -93
package/src/components/date.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2015, Yahoo Inc.
|
|
3
|
-
* Copyrights licensed under the New BSD License.
|
|
4
|
-
* See the accompanying LICENSE file for terms.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React, {Component, PropTypes} from 'react';
|
|
8
|
-
import {intlShape, dateTimeFormatPropTypes} from '../types';
|
|
9
|
-
import {invariantIntlContext, shouldIntlComponentUpdate} from '../utils';
|
|
10
|
-
|
|
11
|
-
export default class FormattedDate extends Component {
|
|
12
|
-
static displayName = 'FormattedDate';
|
|
13
|
-
|
|
14
|
-
static contextTypes = {
|
|
15
|
-
intl: intlShape,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
static propTypes = {
|
|
19
|
-
...dateTimeFormatPropTypes,
|
|
20
|
-
value : PropTypes.any.isRequired,
|
|
21
|
-
format : PropTypes.string,
|
|
22
|
-
children: PropTypes.func,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
constructor(props, context) {
|
|
26
|
-
super(props, context);
|
|
27
|
-
invariantIntlContext(context);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
shouldComponentUpdate(...next) {
|
|
31
|
-
return shouldIntlComponentUpdate(this, ...next);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
render() {
|
|
35
|
-
const {formatDate, textComponent: Text} = this.context.intl;
|
|
36
|
-
const {value, children} = this.props;
|
|
37
|
-
|
|
38
|
-
let formattedDate = formatDate(value, this.props);
|
|
39
|
-
|
|
40
|
-
if (typeof children === 'function') {
|
|
41
|
-
return children(formattedDate);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return <Text>{formattedDate}</Text>;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2015, Yahoo Inc.
|
|
3
|
-
* Copyrights licensed under the New BSD License.
|
|
4
|
-
* See the accompanying LICENSE file for terms.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React, {Component, PropTypes} from 'react';
|
|
8
|
-
import {intlShape, messageDescriptorPropTypes} from '../types';
|
|
9
|
-
import {
|
|
10
|
-
invariantIntlContext,
|
|
11
|
-
shallowEquals,
|
|
12
|
-
shouldIntlComponentUpdate,
|
|
13
|
-
} from '../utils';
|
|
14
|
-
|
|
15
|
-
export default class FormattedHTMLMessage extends Component {
|
|
16
|
-
static displayName = 'FormattedHTMLMessage';
|
|
17
|
-
|
|
18
|
-
static contextTypes = {
|
|
19
|
-
intl: intlShape,
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
static propTypes = {
|
|
23
|
-
...messageDescriptorPropTypes,
|
|
24
|
-
values : PropTypes.object,
|
|
25
|
-
tagName : PropTypes.string,
|
|
26
|
-
children: PropTypes.func,
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
static defaultProps = {
|
|
30
|
-
values: {},
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
constructor(props, context) {
|
|
34
|
-
super(props, context);
|
|
35
|
-
invariantIntlContext(context);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
shouldComponentUpdate(nextProps, ...next) {
|
|
39
|
-
const {values} = this.props;
|
|
40
|
-
const {values: nextValues} = nextProps;
|
|
41
|
-
|
|
42
|
-
if (!shallowEquals(nextValues, values)) {
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Since `values` has already been checked, we know they're not
|
|
47
|
-
// different, so the current `values` are carried over so the shallow
|
|
48
|
-
// equals comparison on the other props isn't affected by the `values`.
|
|
49
|
-
let nextPropsToCheck = {
|
|
50
|
-
...nextProps,
|
|
51
|
-
values,
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
return shouldIntlComponentUpdate(this, nextPropsToCheck, ...next);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
render() {
|
|
58
|
-
const {formatHTMLMessage, textComponent: Text} = this.context.intl;
|
|
59
|
-
|
|
60
|
-
const {
|
|
61
|
-
id,
|
|
62
|
-
description,
|
|
63
|
-
defaultMessage,
|
|
64
|
-
values: rawValues,
|
|
65
|
-
tagName: Component = Text,
|
|
66
|
-
children,
|
|
67
|
-
} = this.props;
|
|
68
|
-
|
|
69
|
-
let descriptor = {id, description, defaultMessage};
|
|
70
|
-
let formattedHTMLMessage = formatHTMLMessage(descriptor, rawValues);
|
|
71
|
-
|
|
72
|
-
if (typeof children === 'function') {
|
|
73
|
-
return children(formattedHTMLMessage);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Since the message presumably has HTML in it, we need to set
|
|
77
|
-
// `innerHTML` in order for it to be rendered and not escaped by React.
|
|
78
|
-
// To be safe, all string prop values were escaped when formatting the
|
|
79
|
-
// message. It is assumed that the message is not UGC, and came from the
|
|
80
|
-
// developer making it more like a template.
|
|
81
|
-
//
|
|
82
|
-
// Note: There's a perf impact of using this component since there's no
|
|
83
|
-
// way for React to do its virtual DOM diffing.
|
|
84
|
-
const html = {__html: formattedHTMLMessage};
|
|
85
|
-
return <Component dangerouslySetInnerHTML={html}/>;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2015, Yahoo Inc.
|
|
3
|
-
* Copyrights licensed under the New BSD License.
|
|
4
|
-
* See the accompanying LICENSE file for terms.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React, {Component, PropTypes, isValidElement} from 'react';
|
|
8
|
-
import {intlShape, messageDescriptorPropTypes} from '../types';
|
|
9
|
-
import {
|
|
10
|
-
invariantIntlContext,
|
|
11
|
-
shallowEquals,
|
|
12
|
-
shouldIntlComponentUpdate,
|
|
13
|
-
} from '../utils';
|
|
14
|
-
|
|
15
|
-
export default class FormattedMessage extends Component {
|
|
16
|
-
static displayName = 'FormattedMessage';
|
|
17
|
-
|
|
18
|
-
static contextTypes = {
|
|
19
|
-
intl: intlShape,
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
static propTypes = {
|
|
23
|
-
...messageDescriptorPropTypes,
|
|
24
|
-
values : PropTypes.object,
|
|
25
|
-
tagName : PropTypes.string,
|
|
26
|
-
children: PropTypes.func,
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
static defaultProps = {
|
|
30
|
-
values : {},
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
constructor(props, context) {
|
|
34
|
-
super(props, context);
|
|
35
|
-
invariantIntlContext(context);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
shouldComponentUpdate(nextProps, ...next) {
|
|
39
|
-
const {values} = this.props;
|
|
40
|
-
const {values: nextValues} = nextProps;
|
|
41
|
-
|
|
42
|
-
if (!shallowEquals(nextValues, values)) {
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Since `values` has already been checked, we know they're not
|
|
47
|
-
// different, so the current `values` are carried over so the shallow
|
|
48
|
-
// equals comparison on the other props isn't affected by the `values`.
|
|
49
|
-
let nextPropsToCheck = {
|
|
50
|
-
...nextProps,
|
|
51
|
-
values,
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
return shouldIntlComponentUpdate(this, nextPropsToCheck, ...next);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
render() {
|
|
58
|
-
const {formatMessage, textComponent: Text} = this.context.intl;
|
|
59
|
-
|
|
60
|
-
const {
|
|
61
|
-
id,
|
|
62
|
-
description,
|
|
63
|
-
defaultMessage,
|
|
64
|
-
values,
|
|
65
|
-
tagName: Component = Text,
|
|
66
|
-
children,
|
|
67
|
-
} = this.props;
|
|
68
|
-
|
|
69
|
-
let tokenDelimiter;
|
|
70
|
-
let tokenizedValues;
|
|
71
|
-
let elements;
|
|
72
|
-
|
|
73
|
-
let hasValues = values && Object.keys(values).length > 0;
|
|
74
|
-
if (hasValues) {
|
|
75
|
-
// Creates a token with a random UID that should not be guessable or
|
|
76
|
-
// conflict with other parts of the `message` string.
|
|
77
|
-
let uid = Math.floor(Math.random() * 0x10000000000).toString(16);
|
|
78
|
-
|
|
79
|
-
let generateToken = (() => {
|
|
80
|
-
let counter = 0;
|
|
81
|
-
return () => `ELEMENT-${uid}-${counter += 1}`;
|
|
82
|
-
})();
|
|
83
|
-
|
|
84
|
-
// Splitting with a delimiter to support IE8. When using a regex
|
|
85
|
-
// with a capture group IE8 does not include the capture group in
|
|
86
|
-
// the resulting array.
|
|
87
|
-
tokenDelimiter = `@__${uid}__@`;
|
|
88
|
-
tokenizedValues = {};
|
|
89
|
-
elements = {};
|
|
90
|
-
|
|
91
|
-
// Iterates over the `props` to keep track of any React Element
|
|
92
|
-
// values so they can be represented by the `token` as a placeholder
|
|
93
|
-
// when the `message` is formatted. This allows the formatted
|
|
94
|
-
// message to then be broken-up into parts with references to the
|
|
95
|
-
// React Elements inserted back in.
|
|
96
|
-
Object.keys(values).forEach((name) => {
|
|
97
|
-
let value = values[name];
|
|
98
|
-
|
|
99
|
-
if (isValidElement(value)) {
|
|
100
|
-
let token = generateToken();
|
|
101
|
-
tokenizedValues[name] = tokenDelimiter + token + tokenDelimiter;
|
|
102
|
-
elements[token] = value;
|
|
103
|
-
} else {
|
|
104
|
-
tokenizedValues[name] = value;
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
let descriptor = {id, description, defaultMessage};
|
|
110
|
-
let formattedMessage = formatMessage(descriptor, tokenizedValues || values);
|
|
111
|
-
|
|
112
|
-
let nodes;
|
|
113
|
-
|
|
114
|
-
let hasElements = elements && Object.keys(elements).length > 0;
|
|
115
|
-
if (hasElements) {
|
|
116
|
-
// Split the message into parts so the React Element values captured
|
|
117
|
-
// above can be inserted back into the rendered message. This
|
|
118
|
-
// approach allows messages to render with React Elements while
|
|
119
|
-
// keeping React's virtual diffing working properly.
|
|
120
|
-
nodes = formattedMessage
|
|
121
|
-
.split(tokenDelimiter)
|
|
122
|
-
.filter((part) => !!part)
|
|
123
|
-
.map((part) => elements[part] || part);
|
|
124
|
-
} else {
|
|
125
|
-
nodes = [formattedMessage];
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (typeof children === 'function') {
|
|
129
|
-
return children(...nodes);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return <Component>{nodes}</Component>;
|
|
133
|
-
}
|
|
134
|
-
}
|
package/src/components/number.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2015, Yahoo Inc.
|
|
3
|
-
* Copyrights licensed under the New BSD License.
|
|
4
|
-
* See the accompanying LICENSE file for terms.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React, {Component, PropTypes} from 'react';
|
|
8
|
-
import {intlShape, numberFormatPropTypes} from '../types';
|
|
9
|
-
import {invariantIntlContext, shouldIntlComponentUpdate} from '../utils';
|
|
10
|
-
|
|
11
|
-
export default class FormattedNumber extends Component {
|
|
12
|
-
static displayName = 'FormattedNumber';
|
|
13
|
-
|
|
14
|
-
static contextTypes = {
|
|
15
|
-
intl: intlShape,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
static propTypes = {
|
|
19
|
-
...numberFormatPropTypes,
|
|
20
|
-
value : PropTypes.any.isRequired,
|
|
21
|
-
format : PropTypes.string,
|
|
22
|
-
children: PropTypes.func,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
constructor(props, context) {
|
|
26
|
-
super(props, context);
|
|
27
|
-
invariantIntlContext(context);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
shouldComponentUpdate(...next) {
|
|
31
|
-
return shouldIntlComponentUpdate(this, ...next);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
render() {
|
|
35
|
-
const {formatNumber, textComponent: Text} = this.context.intl;
|
|
36
|
-
const {value, children} = this.props;
|
|
37
|
-
|
|
38
|
-
let formattedNumber = formatNumber(value, this.props);
|
|
39
|
-
|
|
40
|
-
if (typeof children === 'function') {
|
|
41
|
-
return children(formattedNumber);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return <Text>{formattedNumber}</Text>;
|
|
45
|
-
}
|
|
46
|
-
}
|
package/src/components/plural.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2015, Yahoo Inc.
|
|
3
|
-
* Copyrights licensed under the New BSD License.
|
|
4
|
-
* See the accompanying LICENSE file for terms.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React, {Component, PropTypes} from 'react';
|
|
8
|
-
import {intlShape, pluralFormatPropTypes} from '../types';
|
|
9
|
-
import {invariantIntlContext, shouldIntlComponentUpdate} from '../utils';
|
|
10
|
-
|
|
11
|
-
export default class FormattedPlural extends Component {
|
|
12
|
-
static displayName = 'FormattedPlural';
|
|
13
|
-
|
|
14
|
-
static contextTypes = {
|
|
15
|
-
intl: intlShape,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
static propTypes = {
|
|
19
|
-
...pluralFormatPropTypes,
|
|
20
|
-
value: PropTypes.any.isRequired,
|
|
21
|
-
|
|
22
|
-
other: PropTypes.node.isRequired,
|
|
23
|
-
zero : PropTypes.node,
|
|
24
|
-
one : PropTypes.node,
|
|
25
|
-
two : PropTypes.node,
|
|
26
|
-
few : PropTypes.node,
|
|
27
|
-
many : PropTypes.node,
|
|
28
|
-
|
|
29
|
-
children: PropTypes.func,
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
static defaultProps = {
|
|
33
|
-
style: 'cardinal',
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
constructor(props, context) {
|
|
37
|
-
super(props, context);
|
|
38
|
-
invariantIntlContext(context);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
shouldComponentUpdate(...next) {
|
|
42
|
-
return shouldIntlComponentUpdate(this, ...next);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
render() {
|
|
46
|
-
const {formatPlural, textComponent: Text} = this.context.intl;
|
|
47
|
-
const {value, other, children} = this.props;
|
|
48
|
-
|
|
49
|
-
let pluralCategory = formatPlural(value, this.props);
|
|
50
|
-
let formattedPlural = this.props[pluralCategory] || other;
|
|
51
|
-
|
|
52
|
-
if (typeof children === 'function') {
|
|
53
|
-
return children(formattedPlural);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return <Text>{formattedPlural}</Text>;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2015, Yahoo Inc.
|
|
3
|
-
* Copyrights licensed under the New BSD License.
|
|
4
|
-
* See the accompanying LICENSE file for terms.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {Component, Children, PropTypes} from 'react';
|
|
8
|
-
import IntlMessageFormat from 'intl-messageformat';
|
|
9
|
-
import IntlRelativeFormat from 'intl-relativeformat';
|
|
10
|
-
import IntlPluralFormat from '../plural';
|
|
11
|
-
import memoizeIntlConstructor from 'intl-format-cache';
|
|
12
|
-
import invariant from 'invariant';
|
|
13
|
-
import {shouldIntlComponentUpdate, filterProps} from '../utils';
|
|
14
|
-
import {intlConfigPropTypes, intlFormatPropTypes, intlShape} from '../types';
|
|
15
|
-
import * as format from '../format';
|
|
16
|
-
import {hasLocaleData} from '../locale-data-registry';
|
|
17
|
-
|
|
18
|
-
const intlConfigPropNames = Object.keys(intlConfigPropTypes);
|
|
19
|
-
const intlFormatPropNames = Object.keys(intlFormatPropTypes);
|
|
20
|
-
|
|
21
|
-
// These are not a static property on the `IntlProvider` class so the intl
|
|
22
|
-
// config values can be inherited from an <IntlProvider> ancestor.
|
|
23
|
-
const defaultProps = {
|
|
24
|
-
formats : {},
|
|
25
|
-
messages: {},
|
|
26
|
-
textComponent: 'span',
|
|
27
|
-
|
|
28
|
-
defaultLocale : 'en',
|
|
29
|
-
defaultFormats: {},
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export default class IntlProvider extends Component {
|
|
33
|
-
static displayName = 'IntlProvider';
|
|
34
|
-
|
|
35
|
-
static contextTypes = {
|
|
36
|
-
intl: intlShape,
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
static childContextTypes = {
|
|
40
|
-
intl: intlShape.isRequired,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
static propTypes = {
|
|
44
|
-
...intlConfigPropTypes,
|
|
45
|
-
children : PropTypes.element.isRequired,
|
|
46
|
-
initialNow: PropTypes.any,
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
constructor(props, context = {}) {
|
|
50
|
-
super(props, context);
|
|
51
|
-
|
|
52
|
-
invariant(typeof Intl !== 'undefined',
|
|
53
|
-
'[React Intl] The `Intl` APIs must be available in the runtime, ' +
|
|
54
|
-
'and do not appear to be built-in. An `Intl` polyfill should be loaded.\n' +
|
|
55
|
-
'See: http://formatjs.io/guides/runtime-environments/'
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
const {intl: intlContext} = context;
|
|
59
|
-
|
|
60
|
-
// Used to stabilize time when performing an initial rendering so that
|
|
61
|
-
// all relative times use the same reference "now" time.
|
|
62
|
-
let initialNow;
|
|
63
|
-
if (isFinite(props.initialNow)) {
|
|
64
|
-
initialNow = Number(props.initialNow);
|
|
65
|
-
} else {
|
|
66
|
-
// When an `initialNow` isn't provided via `props`, look to see an
|
|
67
|
-
// <IntlProvider> exists in the ancestry and call its `now()`
|
|
68
|
-
// function to propagate its value for "now".
|
|
69
|
-
initialNow = intlContext ? intlContext.now() : Date.now();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Creating `Intl*` formatters is expensive. If there's a parent
|
|
73
|
-
// `<IntlProvider>`, then its formatters will be used. Otherwise, this
|
|
74
|
-
// memoize the `Intl*` constructors and cache them for the lifecycle of
|
|
75
|
-
// this IntlProvider instance.
|
|
76
|
-
const {formatters = {
|
|
77
|
-
getDateTimeFormat: memoizeIntlConstructor(Intl.DateTimeFormat),
|
|
78
|
-
getNumberFormat : memoizeIntlConstructor(Intl.NumberFormat),
|
|
79
|
-
getMessageFormat : memoizeIntlConstructor(IntlMessageFormat),
|
|
80
|
-
getRelativeFormat: memoizeIntlConstructor(IntlRelativeFormat),
|
|
81
|
-
getPluralFormat : memoizeIntlConstructor(IntlPluralFormat),
|
|
82
|
-
}} = (intlContext || {});
|
|
83
|
-
|
|
84
|
-
this.state = {
|
|
85
|
-
...formatters,
|
|
86
|
-
|
|
87
|
-
// Wrapper to provide stable "now" time for initial render.
|
|
88
|
-
now: () => {
|
|
89
|
-
return this._didDisplay ? Date.now() : initialNow;
|
|
90
|
-
},
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
getConfig() {
|
|
95
|
-
const {intl: intlContext} = this.context;
|
|
96
|
-
|
|
97
|
-
// Build a whitelisted config object from `props`, defaults, and
|
|
98
|
-
// `context.intl`, if an <IntlProvider> exists in the ancestry.
|
|
99
|
-
let config = filterProps(this.props, intlConfigPropNames, intlContext);
|
|
100
|
-
|
|
101
|
-
// Apply default props. This must be applied last after the props have
|
|
102
|
-
// been resolved and inherited from any <IntlProvider> in the ancestry.
|
|
103
|
-
// This matches how React resolves `defaultProps`.
|
|
104
|
-
for (let propName in defaultProps) {
|
|
105
|
-
if (config[propName] === undefined) {
|
|
106
|
-
config[propName] = defaultProps[propName];
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (!hasLocaleData(config.locale)) {
|
|
111
|
-
const {
|
|
112
|
-
locale,
|
|
113
|
-
defaultLocale,
|
|
114
|
-
defaultFormats,
|
|
115
|
-
} = config;
|
|
116
|
-
|
|
117
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
118
|
-
console.error(
|
|
119
|
-
`[React Intl] Missing locale data for locale: "${locale}". ` +
|
|
120
|
-
`Using default locale: "${defaultLocale}" as fallback.`
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Since there's no registered locale data for `locale`, this will
|
|
125
|
-
// fallback to the `defaultLocale` to make sure things can render.
|
|
126
|
-
// The `messages` are overridden to the `defaultProps` empty object
|
|
127
|
-
// to maintain referential equality across re-renders. It's assumed
|
|
128
|
-
// each <FormattedMessage> contains a `defaultMessage` prop.
|
|
129
|
-
config = {
|
|
130
|
-
...config,
|
|
131
|
-
locale : defaultLocale,
|
|
132
|
-
formats : defaultFormats,
|
|
133
|
-
messages: defaultProps.messages,
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return config;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
getBoundFormatFns(config, state) {
|
|
141
|
-
return intlFormatPropNames.reduce((boundFormatFns, name) => {
|
|
142
|
-
boundFormatFns[name] = format[name].bind(null, config, state);
|
|
143
|
-
return boundFormatFns;
|
|
144
|
-
}, {});
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
getChildContext() {
|
|
148
|
-
const config = this.getConfig();
|
|
149
|
-
|
|
150
|
-
// Bind intl factories and current config to the format functions.
|
|
151
|
-
const boundFormatFns = this.getBoundFormatFns(config, this.state);
|
|
152
|
-
|
|
153
|
-
const {now, ...formatters} = this.state;
|
|
154
|
-
|
|
155
|
-
return {
|
|
156
|
-
intl: {
|
|
157
|
-
...config,
|
|
158
|
-
...boundFormatFns,
|
|
159
|
-
formatters,
|
|
160
|
-
now,
|
|
161
|
-
},
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
shouldComponentUpdate(...next) {
|
|
166
|
-
return shouldIntlComponentUpdate(this, ...next);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
componentDidMount() {
|
|
170
|
-
this._didDisplay = true;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
render() {
|
|
174
|
-
return Children.only(this.props.children);
|
|
175
|
-
}
|
|
176
|
-
}
|