mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
d9915db43b
* Deleting a specific style name float for ie8 * Remove unnecessary condition
236 lines
6.6 KiB
JavaScript
236 lines
6.6 KiB
JavaScript
/**
|
|
* Copyright 2013-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule CSSPropertyOperations
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var CSSProperty = require('CSSProperty');
|
|
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
|
|
|
|
var camelizeStyleName = require('fbjs/lib/camelizeStyleName');
|
|
var dangerousStyleValue = require('dangerousStyleValue');
|
|
var getComponentName = require('getComponentName');
|
|
var hyphenateStyleName = require('fbjs/lib/hyphenateStyleName');
|
|
var memoizeStringOnly = require('fbjs/lib/memoizeStringOnly');
|
|
var warning = require('fbjs/lib/warning');
|
|
|
|
if (__DEV__) {
|
|
var {getCurrentFiberOwnerName} = require('ReactDebugCurrentFiber');
|
|
}
|
|
|
|
var processStyleName = memoizeStringOnly(function(styleName) {
|
|
return hyphenateStyleName(styleName);
|
|
});
|
|
|
|
var hasShorthandPropertyBug = false;
|
|
if (ExecutionEnvironment.canUseDOM) {
|
|
var tempStyle = document.createElement('div').style;
|
|
try {
|
|
// IE8 throws "Invalid argument." if resetting shorthand style properties.
|
|
tempStyle.font = '';
|
|
} catch (e) {
|
|
hasShorthandPropertyBug = true;
|
|
}
|
|
}
|
|
|
|
if (__DEV__) {
|
|
// 'msTransform' is correct, but the other prefixes should be capitalized
|
|
var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
|
|
|
|
// style values shouldn't contain a semicolon
|
|
var badStyleValueWithSemicolonPattern = /;\s*$/;
|
|
|
|
var warnedStyleNames = {};
|
|
var warnedStyleValues = {};
|
|
var warnedForNaNValue = false;
|
|
|
|
var warnHyphenatedStyleName = function(name, owner) {
|
|
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
|
|
return;
|
|
}
|
|
|
|
warnedStyleNames[name] = true;
|
|
warning(
|
|
false,
|
|
'Unsupported style property %s. Did you mean %s?%s',
|
|
name,
|
|
camelizeStyleName(name),
|
|
checkRenderMessage(owner),
|
|
);
|
|
};
|
|
|
|
var warnBadVendoredStyleName = function(name, owner) {
|
|
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
|
|
return;
|
|
}
|
|
|
|
warnedStyleNames[name] = true;
|
|
warning(
|
|
false,
|
|
'Unsupported vendor-prefixed style property %s. Did you mean %s?%s',
|
|
name,
|
|
name.charAt(0).toUpperCase() + name.slice(1),
|
|
checkRenderMessage(owner),
|
|
);
|
|
};
|
|
|
|
var warnStyleValueWithSemicolon = function(name, value, owner) {
|
|
if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
|
|
return;
|
|
}
|
|
|
|
warnedStyleValues[value] = true;
|
|
warning(
|
|
false,
|
|
"Style property values shouldn't contain a semicolon.%s " +
|
|
'Try "%s: %s" instead.',
|
|
checkRenderMessage(owner),
|
|
name,
|
|
value.replace(badStyleValueWithSemicolonPattern, ''),
|
|
);
|
|
};
|
|
|
|
var warnStyleValueIsNaN = function(name, value, owner) {
|
|
if (warnedForNaNValue) {
|
|
return;
|
|
}
|
|
|
|
warnedForNaNValue = true;
|
|
warning(
|
|
false,
|
|
'`NaN` is an invalid value for the `%s` css style property.%s',
|
|
name,
|
|
checkRenderMessage(owner),
|
|
);
|
|
};
|
|
|
|
var checkRenderMessage = function(owner) {
|
|
var ownerName;
|
|
if (owner != null) {
|
|
// Stack passes the owner manually all the way to CSSPropertyOperations.
|
|
ownerName = getComponentName(owner);
|
|
} else {
|
|
// Fiber doesn't pass it but uses ReactDebugCurrentFiber to track it.
|
|
// It is only enabled in development and tracks host components too.
|
|
ownerName = getCurrentFiberOwnerName();
|
|
// TODO: also report the stack.
|
|
}
|
|
if (ownerName) {
|
|
return '\n\nCheck the render method of `' + ownerName + '`.';
|
|
}
|
|
return '';
|
|
};
|
|
|
|
/**
|
|
* @param {string} name
|
|
* @param {*} value
|
|
* @param {ReactDOMComponent} component
|
|
*/
|
|
var warnValidStyle = function(name, value, component) {
|
|
var owner;
|
|
if (component) {
|
|
owner = component._currentElement._owner;
|
|
}
|
|
if (name.indexOf('-') > -1) {
|
|
warnHyphenatedStyleName(name, owner);
|
|
} else if (badVendoredStyleNamePattern.test(name)) {
|
|
warnBadVendoredStyleName(name, owner);
|
|
} else if (badStyleValueWithSemicolonPattern.test(value)) {
|
|
warnStyleValueWithSemicolon(name, value, owner);
|
|
}
|
|
|
|
if (typeof value === 'number' && isNaN(value)) {
|
|
warnStyleValueIsNaN(name, value, owner);
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Operations for dealing with CSS properties.
|
|
*/
|
|
var CSSPropertyOperations = {
|
|
/**
|
|
* Serializes a mapping of style properties for use as inline styles:
|
|
*
|
|
* > createMarkupForStyles({width: '200px', height: 0})
|
|
* "width:200px;height:0;"
|
|
*
|
|
* Undefined values are ignored so that declarative programming is easier.
|
|
* The result should be HTML-escaped before insertion into the DOM.
|
|
*
|
|
* @param {object} styles
|
|
* @param {ReactDOMComponent} component
|
|
* @return {?string}
|
|
*/
|
|
createMarkupForStyles: function(styles, component) {
|
|
var serialized = '';
|
|
for (var styleName in styles) {
|
|
if (!styles.hasOwnProperty(styleName)) {
|
|
continue;
|
|
}
|
|
var styleValue = styles[styleName];
|
|
if (__DEV__) {
|
|
warnValidStyle(styleName, styleValue, component);
|
|
}
|
|
if (styleValue != null) {
|
|
serialized += processStyleName(styleName) + ':';
|
|
serialized += dangerousStyleValue(styleName, styleValue, component) +
|
|
';';
|
|
}
|
|
}
|
|
return serialized || null;
|
|
},
|
|
|
|
/**
|
|
* Sets the value for multiple styles on a node. If a value is specified as
|
|
* '' (empty string), the corresponding style property will be unset.
|
|
*
|
|
* @param {DOMElement} node
|
|
* @param {object} styles
|
|
* @param {ReactDOMComponent} component
|
|
*/
|
|
setValueForStyles: function(node, styles, component) {
|
|
var style = node.style;
|
|
for (var styleName in styles) {
|
|
if (!styles.hasOwnProperty(styleName)) {
|
|
continue;
|
|
}
|
|
if (__DEV__) {
|
|
warnValidStyle(styleName, styles[styleName], component);
|
|
}
|
|
var styleValue = dangerousStyleValue(
|
|
styleName,
|
|
styles[styleName],
|
|
component,
|
|
);
|
|
if (styleName === 'float') {
|
|
styleName = 'cssFloat';
|
|
}
|
|
if (styleValue) {
|
|
style[styleName] = styleValue;
|
|
} else {
|
|
var expansion = hasShorthandPropertyBug &&
|
|
CSSProperty.shorthandPropertyExpansions[styleName];
|
|
if (expansion) {
|
|
// Shorthand property that IE8 won't like unsetting, so unset each
|
|
// component to placate it
|
|
for (var individualStyleName in expansion) {
|
|
style[individualStyleName] = '';
|
|
}
|
|
} else {
|
|
style[styleName] = '';
|
|
}
|
|
}
|
|
}
|
|
},
|
|
};
|
|
|
|
module.exports = CSSPropertyOperations;
|