From dd8a3c8d593083c8aa9bedfe038da1d97ff667de Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Mon, 30 Oct 2017 22:42:48 -0700 Subject: [PATCH] [fix] StyleSheet handling of default 'borderWidth' Problem: The default border width should be '0px', but setting a border width value to 'null' would override the default and result in no border width being applied to the element. This could cause unwanted user agent styles to be applied. Solution: createReactDOMStyle now replaces border width values of 'null' with '0px'. Fix #697 --- .../__tests__/createReactDOMStyle-test.js | 17 ++++++++ src/apis/StyleSheet/createReactDOMStyle.js | 39 +++++++++++++------ 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/apis/StyleSheet/__tests__/createReactDOMStyle-test.js b/src/apis/StyleSheet/__tests__/createReactDOMStyle-test.js index 8ba7fa9c..2abc4633 100644 --- a/src/apis/StyleSheet/__tests__/createReactDOMStyle-test.js +++ b/src/apis/StyleSheet/__tests__/createReactDOMStyle-test.js @@ -22,6 +22,23 @@ describe('apis/StyleSheet/createReactDOMStyle', () => { expect(firstStyle).toEqual(secondStyle); }); + describe('borderWidth styles', () => { + test('defaults to 0 when "null"', () => { + expect(createReactDOMStyle({ borderWidth: null })).toEqual({ + borderTopWidth: '0px', + borderRightWidth: '0px', + borderBottomWidth: '0px', + borderLeftWidth: '0px' + }); + expect(createReactDOMStyle({ borderWidth: 2, borderRightWidth: null })).toEqual({ + borderTopWidth: '2px', + borderRightWidth: '0px', + borderBottomWidth: '2px', + borderLeftWidth: '2px' + }); + }); + }); + describe('flexbox styles', () => { test('flex defaults', () => { expect(createReactDOMStyle({ display: 'flex' })).toEqual({ diff --git a/src/apis/StyleSheet/createReactDOMStyle.js b/src/apis/StyleSheet/createReactDOMStyle.js index 1387eb67..8f5954ba 100644 --- a/src/apis/StyleSheet/createReactDOMStyle.js +++ b/src/apis/StyleSheet/createReactDOMStyle.js @@ -52,6 +52,14 @@ const colorProps = { color: true }; +const borderWidthProps = { + borderWidth: true, + borderTopWidth: true, + borderRightWidth: true, + borderBottomWidth: true, + borderLeftWidth: true +}; + const systemFontStack = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif'; @@ -141,13 +149,26 @@ const createReducer = (style, styleProps) => { let hasResolvedTextShadow = false; return (resolvedStyle, prop) => { - const value = normalizeValue(prop, style[prop]); + let value = normalizeValue(prop, style[prop]); + + // Make sure the default border width is explicitly set to '0' to avoid + // falling back to any unwanted user-agent styles. + if (borderWidthProps[prop]) { + value = value == null ? normalizeValue(null, 0) : value; + } + + // Normalize color values + if (colorProps[prop]) { + value = processColor(value); + } + + // Ignore everything else with a null value if (value == null) { return resolvedStyle; } switch (prop) { - // ignore React Native styles + // Ignore some React Native styles case 'aspectRatio': case 'elevation': case 'overlayColor': @@ -251,23 +272,17 @@ const createReducer = (style, styleProps) => { } default: { - // normalize color values - let finalValue = value; - if (colorProps[prop]) { - finalValue = processColor(value); - } - const longFormProperties = styleShortFormProperties[prop]; if (longFormProperties) { longFormProperties.forEach((longForm, i) => { - // the value of any longform property in the original styles takes - // precedence over the shortform's value + // The value of any longform property in the original styles takes + // precedence over the shortform's value. if (styleProps.indexOf(longForm) === -1) { - resolvedStyle[longForm] = finalValue; + resolvedStyle[longForm] = value; } }); } else { - resolvedStyle[prop] = finalValue; + resolvedStyle[prop] = value; } } }