react-interpolate-component
Advanced tools
Comparing version 0.2.3 to 0.2.4
46
index.js
@@ -5,2 +5,3 @@ 'use strict'; | ||
var invariant = require('react/lib/invariant'); | ||
var extend = require('extend'); | ||
@@ -25,14 +26,24 @@ function isString(object) { | ||
render: function() { | ||
var props = this.props; | ||
var format = props.children; | ||
var parent = props.component; | ||
var unsafe = props.unsafe === true; | ||
var content; | ||
var format = this.props.children; | ||
var parent = this.props.component; | ||
var unsafe = this.props.unsafe === true; | ||
var props = extend({}, this.props); | ||
delete props.children; | ||
delete props.component; | ||
delete props.unsafe; | ||
invariant(isString(format), 'Interpolate expects a format string as only child'); | ||
if (unsafe) { | ||
content = format.split(REGEXP).reduce(function(memo, match, index) { | ||
var html = (index % 2 === 0) ? match : props[match]; | ||
var content = format.split(REGEXP).reduce(function(memo, match, index) { | ||
var html; | ||
if (index % 2 === 0) { | ||
html = match; | ||
} else { | ||
html = props[match]; | ||
delete props[match]; | ||
} | ||
if (React.isValidComponent(html)) { | ||
@@ -47,8 +58,10 @@ throw new Error('cannot interpolate a React component into unsafe text'); | ||
return this.transferPropsTo(parent({ dangerouslySetInnerHTML: { __html: content } })); | ||
props.dangerouslySetInnerHTML = { __html: content }; | ||
return parent(props); | ||
} else { | ||
content = format.split(REGEXP).reduce(function(memo, match, index) { | ||
var child = (index % 2 === 0) ? match : props[match]; | ||
var args = format.split(REGEXP).reduce(function(memo, match, index) { | ||
var child; | ||
if (!React.isValidComponent(child)) { | ||
if (index % 2 === 0) { | ||
if (match.length === 0) { | ||
@@ -58,11 +71,14 @@ return memo; | ||
child = React.DOM.span(null, child); | ||
child = match; | ||
} else { | ||
child = props[match]; | ||
delete props[match]; | ||
} | ||
memo['_' + index] = child; | ||
memo.push(child); | ||
return memo; | ||
}, {}); | ||
}, [props]); | ||
return this.transferPropsTo(parent(null, content)); | ||
return parent.apply(null, args); | ||
} | ||
@@ -69,0 +85,0 @@ } |
{ | ||
"name": "react-interpolate-component", | ||
"version": "0.2.3", | ||
"version": "0.2.4", | ||
"description": "A component for React that renders elements into a format string containing replacement fields", | ||
@@ -33,3 +33,5 @@ "main": "index.js", | ||
"homepage": "https://github.com/martinandert/react-interpolate-component", | ||
"dependencies": {}, | ||
"dependencies": { | ||
"extend": "~1.2.1" | ||
}, | ||
"peerDependencies": { | ||
@@ -36,0 +38,0 @@ "react": "~0.9.0" |
59
spec.js
@@ -9,11 +9,11 @@ var assert = require('assert'); | ||
assert.matches = function(actual, expected, message) { | ||
if (!expected.test(actual)) { | ||
assert.fail(actual, expected, message, '!~'); | ||
assert.matches = function(regexp, value, message) { | ||
if (!regexp.test(value)) { | ||
assert.fail(value, regexp, message, '=~'); | ||
} | ||
}; | ||
assert.doesNotMatch = function(actual, expected, message) { | ||
if (expected.test(actual)) { | ||
assert.fail(actual, expected, message, '=~'); | ||
assert.doesNotMatch = function(regexp, value, message) { | ||
if (regexp.test(value)) { | ||
assert.fail(value, regexp, message, '!~'); | ||
} | ||
@@ -23,10 +23,39 @@ }; | ||
describe('The Interpolate component', function() { | ||
it('transfers props to the container component', function() { | ||
var markup = render(Interpolate({ className: 'foo' }, 'bar')); | ||
assert.matches(markup, /^<span [^>]*?class="foo"/); | ||
it('does not mutate props', function() { | ||
var props = { className: 'foo', name: 'bar', value: 'baz', children: '%(name)s: %(value)s' }; | ||
var markup = render(Interpolate(props)); | ||
assert.deepEqual(props, { className: 'foo', name: 'bar', value: 'baz', children: '%(name)s: %(value)s' }); | ||
props.unsafe = true; | ||
markup = render(Interpolate(props)); | ||
assert.deepEqual(props, { className: 'foo', name: 'bar', value: 'baz', children: '%(name)s: %(value)s', unsafe: true }); | ||
}); | ||
it('transfers props to the container component that are not interpolation names', function() { | ||
var props = { className: 'foo', name: 'bar', value: 'baz' }; | ||
var format = '%(name)s: %(value)s'; | ||
var markup = render(Interpolate(props, format)); | ||
assert.matches(/^<span [^>]*?class="foo"/, markup); | ||
assert.doesNotMatch(/\sname="/, markup); | ||
assert.doesNotMatch(/\svalue="/, markup); | ||
props.unsafe = true; | ||
markup = render(Interpolate(props, format)); | ||
assert.matches(/^<span [^>]*?class="foo"/, markup); | ||
assert.doesNotMatch(/\sname="/, markup); | ||
assert.doesNotMatch(/\svalue="/, markup); | ||
}); | ||
it('renders a `span` HTML element as container by default', function() { | ||
var markup = render(Interpolate(null, 'bar')); | ||
assert.matches(/^<span\s/, markup); | ||
}); | ||
it('allows a custom container component to be set as prop', function() { | ||
var markup = render(Interpolate({ component: React.DOM.section }, 'bar')); | ||
assert.matches(markup, /^<section/); | ||
assert.matches(/^<section\s/, markup); | ||
}); | ||
@@ -48,8 +77,8 @@ | ||
it('interpolates properly', function() { | ||
var props = { foo: "bar", number: 42, comp: React.DOM.i(null, 'baz'), no: 'NO' }; | ||
var props = { foo: 'bar', number: 42, comp: React.DOM.i(null, 'baz'), no: 'NO' }; | ||
var format = 'lala %(foo)s lulu %(comp)s lili %(number)s lele'; | ||
var markup = render(Interpolate(props, format)); | ||
assert.matches(markup, /lala .*?bar.*? lulu .*?baz.*? lili .*?42.*? lele/); | ||
assert.doesNotMatch(markup, /%\(|\)s|foo|comp|number|no|NO/); | ||
assert.matches(/lala .*?bar.*? lulu .*?baz.*? lili .*?42.*? lele/, markup); | ||
assert.doesNotMatch(/%\(|\)s|foo|comp|number|no|NO/, markup); | ||
}); | ||
@@ -61,3 +90,3 @@ | ||
assert.doesNotMatch(markup, /<\/?script>/); | ||
assert.doesNotMatch(/<\/?script>/, markup); | ||
}); | ||
@@ -70,3 +99,3 @@ | ||
assert.matches(markup, /<script>alert\("Danger!"\);<\/script>/); | ||
assert.matches(/<script>alert\("Danger!"\);<\/script>/, markup); | ||
}); | ||
@@ -73,0 +102,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13741
208
2
+ Addedextend@~1.2.1
+ Addedextend@1.2.1(transitive)