Warn when using hyphenated style property names

This commit is contained in:
Dan Abramov 2014-06-08 19:47:30 +04:00
parent 9d5ad77774
commit e625b8b234
5 changed files with 110 additions and 5 deletions

View File

@ -15,10 +15,11 @@ In React, inline styles are not specified as a string. Instead they are specifie
var divStyle = {
color: 'white',
backgroundImage: 'url(' + imgUrl + ')',
WebkitTransition: 'all' // note the capital 'W' here
WebkitTransition: 'all', // note the capital 'W' here
msTransition: 'all' // 'ms' is the only lowercase vendor prefix
};
React.renderComponent(<div style={divStyle}>Hello World!</div>, mountNode);
```
Style keys are camelCased in order to be consistent with accessing the properties on DOM nodes from JS (e.g. `node.style.backgroundImage`). Vendor prefixes should begin with a capital letter. This is why `WebkitTransition` has an uppercase "W".
Style keys are camelCased in order to be consistent with accessing the properties on DOM nodes from JS (e.g. `node.style.backgroundImage`). Vendor prefixes [other than `ms`](http://www.andismith.com/blog/2012/02/modernizr-prefixed/) should begin with a capital letter. This is why `WebkitTransition` has an uppercase "W".

View File

@ -21,14 +21,33 @@
var CSSProperty = require('CSSProperty');
var camelizeStyleName = require('camelizeStyleName');
var dangerousStyleValue = require('dangerousStyleValue');
var hyphenateStyleName = require('hyphenateStyleName');
var memoizeStringOnly = require('memoizeStringOnly');
var warning = require('warning');
var processStyleName = memoizeStringOnly(function(styleName) {
return hyphenateStyleName(styleName);
});
if (__DEV__) {
var warnedStyleNames = {};
var warnHyphenatedStyleName = function(name) {
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
return;
}
warnedStyleNames[name] = true;
warning(
false,
'Unsupported style property ' + name + '. Did you mean ' +
camelizeStyleName(name) + '?'
);
};
}
/**
* Operations for dealing with CSS properties.
*/
@ -52,6 +71,11 @@ var CSSPropertyOperations = {
if (!styles.hasOwnProperty(styleName)) {
continue;
}
if (__DEV__) {
if (styleName.indexOf('-') > -1) {
warnHyphenatedStyleName(styleName);
}
}
var styleValue = styles[styleName];
if (styleValue != null) {
serialized += processStyleName(styleName) + ':';
@ -74,6 +98,11 @@ var CSSPropertyOperations = {
if (!styles.hasOwnProperty(styleName)) {
continue;
}
if (__DEV__) {
if (styleName.indexOf('-') > -1) {
warnHyphenatedStyleName(styleName);
}
}
var styleValue = dangerousStyleValue(styleName, styles[styleName]);
if (styleValue) {
style[styleName] = styleValue;

View File

@ -108,4 +108,32 @@ describe('CSSPropertyOperations', function() {
expect(/style=".*"/.test(root.innerHTML)).toBe(false);
});
it('should warn when using hyphenated style names', function() {
spyOn(console, 'warn');
expect(CSSPropertyOperations.createMarkupForStyles({
'background-color': 'crimson'
})).toBe('background-color:crimson;');
expect(console.warn.argsForCall.length).toBe(1);
expect(console.warn.argsForCall[0][0]).toContain('backgroundColor');
});
it('should warn when updating hyphenated style names', function() {
spyOn(console, 'warn');
var root = document.createElement('div');
var styles = {
'-ms-transform': 'translate3d(0, 0, 0)',
'-webkit-transform': 'translate3d(0, 0, 0)'
};
React.renderComponent(<div />, root);
React.renderComponent(<div style={styles} />, root);
expect(console.warn.argsForCall.length).toBe(2);
expect(console.warn.argsForCall[0][0]).toContain('msTransform');
expect(console.warn.argsForCall[1][0]).toContain('WebkitTransform');
});
});

47
src/vendor/core/camelizeStyleName.js vendored Normal file
View File

@ -0,0 +1,47 @@
/**
* Copyright 2014 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @providesModule camelizeStyleName
* @typechecks
*/
"use strict";
var camelize = require('camelize');
var msPattern = /^-ms-/;
/**
* Camelcases a hyphenated CSS property name, for example:
*
* > camelizeStyleName('background-color')
* < "backgroundColor"
* > camelizeStyleName('-moz-transition')
* < "MozTransition"
* > camelizeStyleName('-ms-transition')
* < "msTransition"
*
* As Andi Smith suggests
* (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
* is converted to lowercase `ms`.
*
* @param {string} string
* @return {string}
*/
function camelizeStyleName(string) {
return camelize(string.replace(msPattern, 'ms-'));
}
module.exports = camelizeStyleName;

View File

@ -26,11 +26,11 @@ var msPattern = /^ms-/;
/**
* Hyphenates a camelcased CSS property name, for example:
*
* > hyphenate('backgroundColor')
* > hyphenateStyleName('backgroundColor')
* < "background-color"
* > hyphenate('MozTransition')
* > hyphenateStyleName('MozTransition')
* < "-moz-transition"
* > hyphenate('msTransition')
* > hyphenateStyleName('msTransition')
* < "-ms-transition"
*
* As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix