UNPKG

react-native-web

Version:
178 lines (174 loc) 6.97 kB
/** * Copyright (c) Nicolas Gallagher. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * */ import normalizeValueWithProperty from './normalizeValueWithProperty'; import canUseDOM from '../../../modules/canUseDom'; /** * The browser implements the CSS cascade, where the order of properties is a * factor in determining which styles to paint. React Native is different. It * gives giving precedence to the more specific style property. For example, * the value of `paddingTop` takes precedence over that of `padding`. * * This module creates mutally exclusive style declarations by expanding all of * React Native's supported shortform properties (e.g. `padding`) to their * longfrom equivalents. */ var emptyObject = {}; var supportsCSS3TextDecoration = !canUseDOM || window.CSS != null && window.CSS.supports != null && (window.CSS.supports('text-decoration-line', 'none') || window.CSS.supports('-webkit-text-decoration-line', 'none')); var MONOSPACE_FONT_STACK = 'monospace,monospace'; var SYSTEM_FONT_STACK = '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif'; var STYLE_SHORT_FORM_EXPANSIONS = { borderColor: ['borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor'], borderBlockColor: ['borderTopColor', 'borderBottomColor'], borderInlineColor: ['borderRightColor', 'borderLeftColor'], borderRadius: ['borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius'], borderStyle: ['borderTopStyle', 'borderRightStyle', 'borderBottomStyle', 'borderLeftStyle'], borderBlockStyle: ['borderTopStyle', 'borderBottomStyle'], borderInlineStyle: ['borderRightStyle', 'borderLeftStyle'], borderWidth: ['borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth'], borderBlockWidth: ['borderTopWidth', 'borderBottomWidth'], borderInlineWidth: ['borderRightWidth', 'borderLeftWidth'], insetBlock: ['top', 'bottom'], insetInline: ['left', 'right'], marginBlock: ['marginTop', 'marginBottom'], marginInline: ['marginRight', 'marginLeft'], paddingBlock: ['paddingTop', 'paddingBottom'], paddingInline: ['paddingRight', 'paddingLeft'], overflow: ['overflowX', 'overflowY'], overscrollBehavior: ['overscrollBehaviorX', 'overscrollBehaviorY'], borderBlockStartColor: ['borderTopColor'], borderBlockStartStyle: ['borderTopStyle'], borderBlockStartWidth: ['borderTopWidth'], borderBlockEndColor: ['borderBottomColor'], borderBlockEndStyle: ['borderBottomStyle'], borderBlockEndWidth: ['borderBottomWidth'], //borderInlineStartColor: ['borderLeftColor'], //borderInlineStartStyle: ['borderLeftStyle'], //borderInlineStartWidth: ['borderLeftWidth'], //borderInlineEndColor: ['borderRightColor'], //borderInlineEndStyle: ['borderRightStyle'], //borderInlineEndWidth: ['borderRightWidth'], borderEndStartRadius: ['borderBottomLeftRadius'], borderEndEndRadius: ['borderBottomRightRadius'], borderStartStartRadius: ['borderTopLeftRadius'], borderStartEndRadius: ['borderTopRightRadius'], insetBlockEnd: ['bottom'], insetBlockStart: ['top'], //insetInlineEnd: ['right'], //insetInlineStart: ['left'], marginBlockStart: ['marginTop'], marginBlockEnd: ['marginBottom'], //marginInlineStart: ['marginLeft'], //marginInlineEnd: ['marginRight'], paddingBlockStart: ['paddingTop'], paddingBlockEnd: ['paddingBottom'] //paddingInlineStart: ['marginLeft'], //paddingInlineEnd: ['marginRight'], }; /** * Reducer */ var createReactDOMStyle = (style, isInline) => { if (!style) { return emptyObject; } var resolvedStyle = {}; var _loop = function _loop() { var value = style[prop]; if ( // Ignore everything with a null value value == null) { return "continue"; } if (prop === 'backgroundClip') { // TODO: remove once this issue is fixed // https://github.com/rofrischmann/inline-style-prefixer/issues/159 if (value === 'text') { resolvedStyle.backgroundClip = value; resolvedStyle.WebkitBackgroundClip = value; } } else if (prop === 'flex') { if (value === -1) { resolvedStyle.flexGrow = 0; resolvedStyle.flexShrink = 1; resolvedStyle.flexBasis = 'auto'; } else { resolvedStyle.flex = value; } } else if (prop === 'font') { resolvedStyle[prop] = value.replace('System', SYSTEM_FONT_STACK); } else if (prop === 'fontFamily') { if (value.indexOf('System') > -1) { var stack = value.split(/,\s*/); stack[stack.indexOf('System')] = SYSTEM_FONT_STACK; resolvedStyle[prop] = stack.join(','); } else if (value === 'monospace') { resolvedStyle[prop] = MONOSPACE_FONT_STACK; } else { resolvedStyle[prop] = value; } } else if (prop === 'textDecorationLine') { // use 'text-decoration' for browsers that only support CSS2 // text-decoration (e.g., IE, Edge) if (!supportsCSS3TextDecoration) { resolvedStyle.textDecoration = value; } else { resolvedStyle.textDecorationLine = value; } } else if (prop === 'writingDirection') { resolvedStyle.direction = value; } else { var _value = normalizeValueWithProperty(style[prop], prop); var longFormProperties = STYLE_SHORT_FORM_EXPANSIONS[prop]; if (isInline && prop === 'inset') { if (style.insetInline == null) { resolvedStyle.left = _value; resolvedStyle.right = _value; } if (style.insetBlock == null) { resolvedStyle.top = _value; resolvedStyle.bottom = _value; } } else if (isInline && prop === 'margin') { if (style.marginInline == null) { resolvedStyle.marginLeft = _value; resolvedStyle.marginRight = _value; } if (style.marginBlock == null) { resolvedStyle.marginTop = _value; resolvedStyle.marginBottom = _value; } } else if (isInline && prop === 'padding') { if (style.paddingInline == null) { resolvedStyle.paddingLeft = _value; resolvedStyle.paddingRight = _value; } if (style.paddingBlock == null) { resolvedStyle.paddingTop = _value; resolvedStyle.paddingBottom = _value; } } else if (longFormProperties) { longFormProperties.forEach((longForm, i) => { // The value of any longform property in the original styles takes // precedence over the shortform's value. if (style[longForm] == null) { resolvedStyle[longForm] = _value; } }); } else { resolvedStyle[prop] = _value; } } }; for (var prop in style) { var _ret = _loop(); if (_ret === "continue") continue; } return resolvedStyle; }; export default createReactDOMStyle;