private _adaptStyles()

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;
    }