From 72f33ce8923ae70a845ce300f8ef0e3ab21d7724 Mon Sep 17 00:00:00 2001 From: Edvin Erikson Date: Fri, 11 Mar 2016 01:27:33 +0100 Subject: [PATCH] added component name to css property warnings --- .../dom/shared/CSSPropertyOperations.js | 56 ++++++--- .../__tests__/CSSPropertyOperations-test.js | 119 ++++++++++++------ .../__tests__/ReactDOMComponent-test.js | 2 +- 3 files changed, 119 insertions(+), 58 deletions(-) diff --git a/src/renderers/dom/shared/CSSPropertyOperations.js b/src/renderers/dom/shared/CSSPropertyOperations.js index 5044488c8c..aac1b75f87 100644 --- a/src/renderers/dom/shared/CSSPropertyOperations.js +++ b/src/renderers/dom/shared/CSSPropertyOperations.js @@ -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, diff --git a/src/renderers/dom/shared/__tests__/CSSPropertyOperations-test.js b/src/renderers/dom/shared/__tests__/CSSPropertyOperations-test.js index 075c29cde8..d33d2e6b1e 100644 --- a/src/renderers/dom/shared/__tests__/CSSPropertyOperations-test.js +++ b/src/renderers/dom/shared/__tests__/CSSPropertyOperations-test.js @@ -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
; + }, + }); spyOn(console, 'error'); - - expect(CSSPropertyOperations.createMarkupForStyles({ - 'background-color': 'crimson', - })).toBe('background-color:crimson;'); - + var root = document.createElement('div'); + ReactDOM.render(, 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
; + }, + }); spyOn(console, 'error'); - - var root = document.createElement('div'); var styles = { '-ms-transform': 'translate3d(0, 0, 0)', '-webkit-transform': 'translate3d(0, 0, 0)', }; - - ReactDOM.render(
, root); - ReactDOM.render(
, root); + var root = document.createElement('div'); + ReactDOM.render(, root); + ReactDOM.render(, 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 (
); + }, }); - + spyOn(console, 'error'); + var root = document.createElement('div'); + ReactDOM.render(, 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 (
); + }, }); - + spyOn(console, 'error'); + var root = document.createElement('div'); + ReactDOM.render(, 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
; + }, }); + spyOn(console, 'error'); + var root = document.createElement('div'); + ReactDOM.render(, 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`.' ); }); }); diff --git a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js index 1e07d5a4c2..13816e4346 100644 --- a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js +++ b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js @@ -200,7 +200,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.', ); });