in src/web/Styles.ts [269:486]
private _adaptStyles(def: any, validate: boolean, isTextStyle = false): Readonly<any> {
if (validate) {
StyleLeakDetector.detectLeaks(def);
}
// Expand composite types.
if (def.font) {
if (def.font.fontFamily !== undefined) {
def.fontFamily = def.font.fontFamily;
}
if (def.font.fontWeight !== undefined) {
def.fontWeight = def.font.fontWeight;
}
if (def.font.fontStyle !== undefined) {
def.fontStyle = def.font.fontStyle;
}
delete def.font;
}
if (def.flex !== undefined) {
// In development mode, see if we're going to overwrite explicit flexGrow
// or flexShrink attributes. It's a programming error to specify these in
// combination with flex.
if (AppConfig.isDevelopmentMode()) {
if (def.flexGrow !== undefined || def.flexShrink !== undefined) {
console.error('Conflicting rules for flex specified.');
}
}
const flexValue = def.flex as number;
delete def.flex;
if (flexValue > 0) {
// p 1 auto
def.flexGrow = flexValue;
def.flexShrink = 1;
} else if (flexValue < 0) {
// 0 -n auto
def.flexGrow = 0;
def.flexShrink = -flexValue;
} else {
// 0 0 auto
def.flexGrow = 0;
def.flexShrink = 0;
}
}
if (def.transform) {
const transformStrings: string[] = [];
const animatedTransforms: { [key: string]: {} } = {};
const staticTransforms: { [key: string]: string } = {};
_.each(def.transform, (t: { [key: string]: string }) => {
_.each(_.keys(t), key => {
// Animated transforms use Animated.Value objects rather
// than strings. We need to store these separately.
if (typeof t[key] === 'object') {
animatedTransforms[key] = t[key];
} else {
let value: string = t[key].toString();
if (key.indexOf('translate') === 0) {
value += 'px';
}
transformStrings.push(key + '(' + value + ')');
staticTransforms[key] = value;
}
});
});
delete def.transform;
if (transformStrings.length > 0) {
def.transform = transformStrings.join(' ');
}
if (_.keys(animatedTransforms).length > 0) {
def.animatedTransforms = animatedTransforms;
def.staticTransforms = staticTransforms;
}
}
if (def.shadowOffset !== undefined || def.shadowRadius !== undefined || def.shadowColor !== undefined) {
let width = 0;
let height = 0;
let radius = 0;
let color = 'black';
if (def.shadowOffset !== undefined) {
width = def.shadowOffset.width;
height = def.shadowOffset.height;
delete def.shadowOffset;
}
if (def.shadowRadius !== undefined) {
radius = def.shadowRadius;
delete def.shadowRadius;
}
if (def.shadowColor !== undefined) {
color = def.shadowColor;
delete def.shadowColor;
}
if (isTextStyle) {
def.textShadow = width + 'px ' + height + 'px ' + radius + 'px ' + color;
} else {
def.boxShadow = width + 'px ' + height + 'px ' + radius + 'px 0px ' + color;
}
}
// CSS (and React JS) support lineHeight defined as either a multiple of the font
// size or a pixel count. The RX.Types interface always uses a pixel count. We need to
// convert to the string notation to make CSS happy.
if (def.lineHeight !== undefined) {
def.lineHeight = def.lineHeight + 'px';
}
// Add default border width if border style or some subset of border widths
// were provided. Otherwise the browser will default to a two-pixel border.
if (def.borderStyle || def.borderTopWidth || def.borderRightWidth || def.borderBottomWidth || def.borderLeftWidth) {
if (def.borderWidth === undefined) {
if (def.borderTopWidth === undefined) {
def.borderTopWidth = 0;
}
if (def.borderRightWidth === undefined) {
def.borderRightWidth = 0;
}
if (def.borderBottomWidth === undefined) {
def.borderBottomWidth = 0;
}
if (def.borderLeftWidth === undefined) {
def.borderLeftWidth = 0;
}
}
}
// CSS doesn't support vertical/horizontal margins or padding.
if (def.marginVertical !== undefined) {
if (def.marginTop === undefined) {
def.marginTop = def.marginVertical;
}
if (def.marginBottom === undefined) {
def.marginBottom = def.marginVertical;
}
delete def.marginVertical;
}
if (def.marginHorizontal !== undefined) {
if (def.marginLeft === undefined) {
def.marginLeft = def.marginHorizontal;
}
if (def.marginRight === undefined) {
def.marginRight = def.marginHorizontal;
}
delete def.marginHorizontal;
}
if (def.paddingVertical !== undefined) {
if (def.paddingTop === undefined) {
def.paddingTop = def.paddingVertical;
}
if (def.paddingBottom === undefined) {
def.paddingBottom = def.paddingVertical;
}
delete def.paddingVertical;
}
if (def.paddingHorizontal !== undefined) {
if (def.paddingLeft === undefined) {
def.paddingLeft = def.paddingHorizontal;
}
if (def.paddingRight === undefined) {
def.paddingRight = def.paddingHorizontal;
}
delete def.paddingHorizontal;
}
// CSS doesn't support 'textDecorationLine'
if (def.textDecorationLine !== undefined) {
def.textDecoration = def.textDecorationLine;
delete def.textDecorationLine;
}
// CSS doesn't support 'textDecorationStyle'
if (def.textDecorationStyle !== undefined) {
if (def.textDecoration !== undefined) {
def.textDecoration += ' ' + def.textDecorationStyle;
} else {
def.textDecoration = def.textDecorationStyle;
}
delete def.textDecorationStyle;
}
// CSS doesn't support 'textDecorationColor'
if (def.textDecorationColor !== undefined) {
if (def.textDecoration !== undefined) {
def.textDecoration += ' ' + def.textDecorationColor;
} else {
def.textDecoration = def.textDecorationColor;
}
delete def.textDecorationColor;
}
// Add common aliases if necessary.
const jsAliases = this._getCssPropertyAliasesJsStyle();
for (const prop in jsAliases) {
if (def[prop] !== undefined && jsAliases[prop]) {
def[jsAliases[prop]] = def[prop];
}
}
// Add IE-specific word wrap property.
if (def.wordBreak === 'break-word') {
def.wordWrap = 'break-word';
}
return AppConfig.isDevelopmentMode() ? Object.freeze(def) : def;
}