forked from jenseng/react-i18nliner
-
Notifications
You must be signed in to change notification settings - Fork 2
/
ComponentInterpolator.js
79 lines (70 loc) · 2.06 KB
/
ComponentInterpolator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
var React = require('react');
var cloneWithProps = require('react/lib/cloneWithProps');
var invariant = require('react/lib/invariant');
var { string, object } = React.PropTypes;
var WRAPPER_PATTERN = /(\*+)/;
var PLACEHOLDER_PATTERN = /(%\{.*?\})/;
var ComponentInterpolator = React.createClass({
propTypes: {
string: string.isRequired,
wrappers: object.isRequired
},
componentWillMount() {
invariant(
!this.props.children,
'<ComponentInterpolator> cannot have any children'
);
},
inferChildren() {
var tokens = (this.props.string || '').split(WRAPPER_PATTERN);
return this.interpolateAllComponents(tokens);
},
interpolateAllComponents(tokens, eof) {
var token, child;
var children = [];
var wrappers = this.props.wrappers || {};
while (tokens.length) {
token = tokens.shift();
if (token === eof) break;
if (token.match(WRAPPER_PATTERN)) {
invariant(
child = wrappers[token],
`<ComponentInterpolator> expected '${token}' wrapper, none found`
);
child = cloneWithProps(child, {
key: tokens.length,
children: this.interpolateAllComponents(tokens, token)
});
children.push(child);
}
else {
children.push.apply(children, this.interpolatePlaceholders(token));
}
}
return children;
},
interpolatePlaceholders(string) {
var token;
var tokens = string.split(PLACEHOLDER_PATTERN);
var children = [];
while (tokens.length) {
token = tokens.shift();
if (token.match(PLACEHOLDER_PATTERN)) {
token = token.slice(2, -1);
invariant(
child = this.props[token],
`<ComponentInterpolator> expected '${token}' placeholder value, none found`
);
child = cloneWithProps(child, {key: tokens.length});
children.push(child);
} else {
children.push(token);
}
}
return children;
},
render() {
return React.createElement('span', {}, this.inferChildren());
}
});
module.exports = ComponentInterpolator;