diff --git a/ComponentInterpolator.js b/ComponentInterpolator.js
index 189871e..19627c7 100644
--- a/ComponentInterpolator.js
+++ b/ComponentInterpolator.js
@@ -1,98 +1,75 @@
-/*
-Given:
-
-Ohai {this.props.user}, click here right now please!
-
-Pre-process it into:
-
-
-
-
-
-*/
+/**
+ * Given:
+ *
+ * Ohai {this.props.user}, click here right now please!
+ *
+ * Pre-process it into:
+ *
+ * ,
+ * '**': ,
+ * '***': }}
+ * />
+ *
+ * Which is equivalent to:
+ *
+ * Ohai {this.props.user}, click here right now please!
+ *
+ * ... but completely localizable :)
+ */
var React = require('react');
var cloneWithProps = require('react/lib/cloneWithProps');
var invariant = require('react/lib/invariant');
-var { string } = React.PropTypes;
-
-var OWN_PROPS = ['defaultValue', 'translateKey', 'children'];
+var { string, object } = React.PropTypes;
var ComponentInterpolator = React.createClass({
propTypes: {
- string: string.isRequired
+ string: string.isRequired,
+ wrappers: object.isRequired
},
componentWillMount() {
- var textCount = this.textCount();
- var componentCount = this.componentCount();
invariant(
- textCount === 0,
- ' cannot have any text children'
+ !this.props.children,
+ ' cannot have any children'
);
},
- textCount(node) {
- node = node || this;
- count = 0;
- React.Children.forEach(node.props.children, (child) => {
- count += typeof child === 'string' ? 1 : this.textCount(child);
- });
- return count;
- },
-
- componentCount(node) {
- node = node || this;
- count = 0;
- React.Children.forEach(node.props.children, (child) => {
- count += typeof child === 'string' ? 0 : 1 + this.componentCount(child);
- });
- return count;
+ inferChildren() {
+ var tokens = (this.props.string || '').split(/(\*+)/);
+ return this.interpolateComponents(tokens);
},
- inferChildren(string, children) {
- var tokens = (string || '').split(/(\*+)/);
- return this.interpolateChildren(tokens, children);
- },
-
- interpolateChildren(tokens, children, eof) {
- children = children instanceof Array ? children.slice() : children ? [children] : [];
- var token, child, newChildren = [];
+ interpolateComponents(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(/\*/)) {
- child = children.shift();
+ invariant(
+ child = wrappers[token],
+ `'s string expected ${token} wrapper, none found`
+ )
child = cloneWithProps(child, {
- key: child.props.key,
- children: this.interpolateChildren(tokens, child.props.children, token)
+ key: token,
+ children: this.interpolateComponents(tokens, token)
});
}
else {
child = token;
}
- newChildren.push(child);
- }
- return newChildren;
- },
-
- extraProps() {
- var props = {};
- for (var key in this.props) {
- if (OWN_PROPS.indexOf(key) === -1)
- props[key] = this.props[key];
+ children.push(child);
}
- return props;
+ return children;
},
render() {
- var options = this.extraProps();
- var translateKey = this.props.translateKey;
- var defaultValue = this.props.defaultValue || this.props.children;
- options.defaultValue = defaultValue;
-
- var children = this.inferChildren(this.props.string, this.props.children);
- return React.createElement('span', { children });
+ return React.createElement('span', {}, this.inferChildren());
}
});
diff --git a/__tests__/ComponentInterpolator.test.js b/__tests__/ComponentInterpolator.test.js
index aee5a3e..4418f68 100644
--- a/__tests__/ComponentInterpolator.test.js
+++ b/__tests__/ComponentInterpolator.test.js
@@ -9,20 +9,30 @@ var removeNoise = function(string) {
describe('ComponentInterpolator', function() {
it('renders', function() {
- var subject = Subject({string: 'Hello World'});
+ var subject = Subject({
+ string: 'Hello World',
+ wrappers: {}
+ });
expect(subject.isMounted()).toEqual(true);
expect(subject.getDOMNode().textContent).toEqual('Hello World');
});
it('escapes html in the string', function() {
- var subject = Subject({string: 'My favorite tag is '});
+ var subject = Subject({
+ string: 'My favorite tag is ',
+ wrappers: {}
+ });
expect(subject.getDOMNode().textContent).toEqual('My favorite tag is ');
});
it('interpolates components', function() {
var subject = Subject({
string: 'Ohai, Jane, click *here* right ***now **please** ***',
- children: [, ]
+ wrappers: {
+ '*': ,
+ '**': ,
+ '***':
+ }
});
expect(removeNoise(subject.getDOMNode().innerHTML)).toEqual(
'Ohai, Jane, click here right now please '