Merge pull request #6242 from edvinerikson/add-origin-to-css-warnings

added component name to css property warnings
This commit is contained in:
Paul O’Shannessy
2016-03-23 12:12:51 -07:00
3 changed files with 119 additions and 58 deletions
@@ -52,7 +52,7 @@ if (__DEV__) {
var warnedStyleValues = {};
var warnedForNaNValue = false;
var warnHyphenatedStyleName = function(name) {
var warnHyphenatedStyleName = function(name, owner) {
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
return;
}
@@ -60,13 +60,14 @@ if (__DEV__) {
warnedStyleNames[name] = true;
warning(
false,
'Unsupported style property %s. Did you mean %s?',
'Unsupported style property %s. Did you mean %s?%s',
name,
camelizeStyleName(name)
camelizeStyleName(name),
checkRenderMessage(owner)
);
};
var warnBadVendoredStyleName = function(name) {
var warnBadVendoredStyleName = function(name, owner) {
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
return;
}
@@ -74,13 +75,14 @@ if (__DEV__) {
warnedStyleNames[name] = true;
warning(
false,
'Unsupported vendor-prefixed style property %s. Did you mean %s?',
'Unsupported vendor-prefixed style property %s. Did you mean %s?%s',
name,
name.charAt(0).toUpperCase() + name.slice(1)
name.charAt(0).toUpperCase() + name.slice(1),
checkRenderMessage(owner)
);
};
var warnStyleValueWithSemicolon = function(name, value) {
var warnStyleValueWithSemicolon = function(name, value, owner) {
if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
return;
}
@@ -88,14 +90,15 @@ if (__DEV__) {
warnedStyleValues[value] = true;
warning(
false,
'Style property values shouldn\'t contain a semicolon. ' +
'Style property values shouldn\'t contain a semicolon.%s ' +
'Try "%s: %s" instead.',
checkRenderMessage(owner),
name,
value.replace(badStyleValueWithSemicolonPattern, '')
);
};
var warnStyleValueIsNaN = function(name, value) {
var warnStyleValueIsNaN = function(name, value, owner) {
if (warnedForNaNValue) {
return;
}
@@ -103,26 +106,42 @@ if (__DEV__) {
warnedForNaNValue = true;
warning(
false,
'`NaN` is an invalid value for the `%s` css style property',
name
'`NaN` is an invalid value for the `%s` css style property.%s',
name,
checkRenderMessage(owner)
);
};
var checkRenderMessage = function(owner) {
if (owner) {
var name = owner.getName();
if (name) {
return ' Check the render method of `' + name + '`.';
}
}
return '';
};
/**
* @param {string} name
* @param {*} value
* @param {ReactDOMComponent} component
*/
var warnValidStyle = function(name, value) {
var warnValidStyle = function(name, value, component) {
var owner;
if (component) {
owner = component._currentElement._owner;
}
if (name.indexOf('-') > -1) {
warnHyphenatedStyleName(name);
warnHyphenatedStyleName(name, owner);
} else if (badVendoredStyleNamePattern.test(name)) {
warnBadVendoredStyleName(name);
warnBadVendoredStyleName(name, owner);
} else if (badStyleValueWithSemicolonPattern.test(value)) {
warnStyleValueWithSemicolon(name, value);
warnStyleValueWithSemicolon(name, value, owner);
}
if (typeof value === 'number' && isNaN(value)) {
warnStyleValueIsNaN(name, value);
warnStyleValueIsNaN(name, value, owner);
}
};
}
@@ -153,7 +172,7 @@ var CSSPropertyOperations = {
}
var styleValue = styles[styleName];
if (__DEV__) {
warnValidStyle(styleName, styleValue);
warnValidStyle(styleName, styleValue, component);
}
if (styleValue != null) {
serialized += processStyleName(styleName) + ':';
@@ -170,6 +189,7 @@ var CSSPropertyOperations = {
*
* @param {DOMElement} node
* @param {object} styles
* @param {ReactDOMComponent} component
*/
setValueForStyles: function(node, styles, component) {
var style = node.style;
@@ -178,7 +198,7 @@ var CSSPropertyOperations = {
continue;
}
if (__DEV__) {
warnValidStyle(styleName, styles[styleName]);
warnValidStyle(styleName, styles[styleName], component);
}
var styleValue = dangerousStyleValue(
styleName,
@@ -108,75 +108,116 @@ describe('CSSPropertyOperations', function() {
});
it('should warn when using hyphenated style names', function() {
var Comp = React.createClass({
displayName: 'Comp',
render: function() {
return <div style={{ 'background-color': 'crimson' }}/>;
},
});
spyOn(console, 'error');
expect(CSSPropertyOperations.createMarkupForStyles({
'background-color': 'crimson',
})).toBe('background-color:crimson;');
var root = document.createElement('div');
ReactDOM.render(<Comp />, root);
expect(console.error.argsForCall.length).toBe(1);
expect(console.error.argsForCall[0][0]).toContain('backgroundColor');
expect(console.error.argsForCall[0][0]).toEqual(
'Warning: Unsupported style property background-color. Did you mean backgroundColor? ' +
'Check the render method of `Comp`.'
);
});
it('should warn when updating hyphenated style names', function() {
var Comp = React.createClass({
displayName: 'Comp',
render: function() {
return <div style={this.props.style} />;
},
});
spyOn(console, 'error');
var root = document.createElement('div');
var styles = {
'-ms-transform': 'translate3d(0, 0, 0)',
'-webkit-transform': 'translate3d(0, 0, 0)',
};
ReactDOM.render(<div />, root);
ReactDOM.render(<div style={styles} />, root);
var root = document.createElement('div');
ReactDOM.render(<Comp />, root);
ReactDOM.render(<Comp style={styles} />, root);
expect(console.error.argsForCall.length).toBe(2);
expect(console.error.argsForCall[0][0]).toContain('msTransform');
expect(console.error.argsForCall[1][0]).toContain('WebkitTransform');
expect(console.error.argsForCall[0][0]).toEqual(
'Warning: Unsupported style property -ms-transform. Did you mean msTransform? ' +
'Check the render method of `Comp`.'
);
expect(console.error.argsForCall[1][0]).toEqual(
'Warning: Unsupported style property -webkit-transform. Did you mean WebkitTransform? ' +
'Check the render method of `Comp`.'
);
});
it('warns when miscapitalizing vendored style names', function() {
spyOn(console, 'error');
CSSPropertyOperations.createMarkupForStyles({
msTransform: 'translate3d(0, 0, 0)',
oTransform: 'translate3d(0, 0, 0)',
webkitTransform: 'translate3d(0, 0, 0)',
var Comp = React.createClass({
displayName: 'Comp',
render: function() {
return (<div style={{
msTransform: 'translate3d(0, 0, 0)',
oTransform: 'translate3d(0, 0, 0)',
webkitTransform: 'translate3d(0, 0, 0)',
}} />);
},
});
spyOn(console, 'error');
var root = document.createElement('div');
ReactDOM.render(<Comp />, root);
// msTransform is correct already and shouldn't warn
expect(console.error.argsForCall.length).toBe(2);
expect(console.error.argsForCall[0][0]).toContain('oTransform');
expect(console.error.argsForCall[0][0]).toContain('OTransform');
expect(console.error.argsForCall[1][0]).toContain('webkitTransform');
expect(console.error.argsForCall[1][0]).toContain('WebkitTransform');
expect(console.error.argsForCall[0][0]).toEqual(
'Warning: Unsupported vendor-prefixed style property oTransform. ' +
'Did you mean OTransform? Check the render method of `Comp`.'
);
expect(console.error.argsForCall[1][0]).toEqual(
'Warning: Unsupported vendor-prefixed style property webkitTransform. ' +
'Did you mean WebkitTransform? Check the render method of `Comp`.'
);
});
it('should warn about style having a trailing semicolon', function() {
spyOn(console, 'error');
CSSPropertyOperations.createMarkupForStyles({
fontFamily: 'Helvetica, arial',
backgroundImage: 'url(foo;bar)',
backgroundColor: 'blue;',
color: 'red; ',
var Comp = React.createClass({
displayName: 'Comp',
render: function() {
return (<div style={{
fontFamily: 'Helvetica, arial',
backgroundImage: 'url(foo;bar)',
backgroundColor: 'blue;',
color: 'red; ',
}} />);
},
});
spyOn(console, 'error');
var root = document.createElement('div');
ReactDOM.render(<Comp />, root);
expect(console.error.calls.length).toBe(2);
expect(console.error.argsForCall[0][0]).toContain('Try "backgroundColor: blue" instead');
expect(console.error.argsForCall[1][0]).toContain('Try "color: red" instead');
expect(console.error.argsForCall[0][0]).toEqual(
'Warning: Style property values shouldn\'t contain a semicolon. ' +
'Check the render method of `Comp`. Try "backgroundColor: blue" instead.',
);
expect(console.error.argsForCall[1][0]).toEqual(
'Warning: Style property values shouldn\'t contain a semicolon. ' +
'Check the render method of `Comp`. Try "color: red" instead.',
);
});
it('should warn about style containing a NaN value', function() {
spyOn(console, 'error');
CSSPropertyOperations.createMarkupForStyles({
fontSize: NaN,
var Comp = React.createClass({
displayName: 'Comp',
render: function() {
return <div style={{ fontSize: NaN }}/>;
},
});
spyOn(console, 'error');
var root = document.createElement('div');
ReactDOM.render(<Comp />, root);
expect(console.error.calls.length).toBe(1);
expect(console.error.argsForCall[0][0]).toEqual(
'Warning: `NaN` is an invalid value for the `fontSize` css style property'
'Warning: `NaN` is an invalid value for the `fontSize` css style property. ' +
'Check the render method of `Comp`.'
);
});
});
@@ -198,7 +198,7 @@ describe('ReactDOMComponent', function() {
expect(console.error.argsForCall.length).toBe(1);
expect(console.error.argsForCall[0][0]).toEqual(
'Warning: `NaN` is an invalid value for the `fontSize` css style property',
'Warning: `NaN` is an invalid value for the `fontSize` css style property.',
);
});