From 60ead15e4fa0c9af81a91a7047b88055b95bbe9d Mon Sep 17 00:00:00 2001 From: watanabeyu Date: Sun, 4 Nov 2018 15:45:04 +0900 Subject: [PATCH 1/4] var o = Object.create(null); -> const o = Object.create(null); --- .../__tests__/deepFreezeAndThrowOnMutationInDev-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Libraries/Utilities/__tests__/deepFreezeAndThrowOnMutationInDev-test.js b/Libraries/Utilities/__tests__/deepFreezeAndThrowOnMutationInDev-test.js index c8bafdc65441bc..1ed6231c663603 100644 --- a/Libraries/Utilities/__tests__/deepFreezeAndThrowOnMutationInDev-test.js +++ b/Libraries/Utilities/__tests__/deepFreezeAndThrowOnMutationInDev-test.js @@ -28,7 +28,7 @@ describe('deepFreezeAndThrowOnMutationInDev', function() { it('should not throw on object without prototype', () => { __DEV__ = true; - var o = Object.create(null); + const o = Object.create(null); o.key = 'Value'; expect(() => deepFreezeAndThrowOnMutationInDev(o)).not.toThrow(); }); @@ -134,7 +134,7 @@ describe('deepFreezeAndThrowOnMutationInDev', function() { expect(o.key1.key2).toBe('newValue'); }); - it("shouldn't recurse infinitely", () => { + it('shouldn\'t recurse infinitely', () => { __DEV__ = true; const o = {}; o.circular = o; From 87c944e3ebd38a5e951c2213affab2fd9879e213 Mon Sep 17 00:00:00 2001 From: watanabeyu Date: Thu, 15 Nov 2018 12:04:39 +0900 Subject: [PATCH 2/4] create StackEntryProps and flow strict-local --- Libraries/Components/StatusBar/StatusBar.js | 100 +++++++++++++------- 1 file changed, 64 insertions(+), 36 deletions(-) diff --git a/Libraries/Components/StatusBar/StatusBar.js b/Libraries/Components/StatusBar/StatusBar.js index 52e6a764d2ca74..5cedf1436431f7 100644 --- a/Libraries/Components/StatusBar/StatusBar.js +++ b/Libraries/Components/StatusBar/StatusBar.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @flow + * @flow strict-local */ 'use strict'; @@ -103,13 +103,52 @@ type Props = $ReadOnly<{| barStyle?: ?('default' | 'light-content' | 'dark-content'), |}>; +type StackEntryProps = { + /** + * The background color of the status bar. + * + * @platform android + */ + backgroundColor: { + value: ?string, + animated: ?boolean, + }, + /** + * Sets the color of the status bar text. + */ + barStyle: { + value: ?string, + animated: ?boolean, + }, + /** + * If the status bar is translucent. + * When translucent is set to true, the app will draw under the status bar. + * This is useful when using a semi transparent status bar color. + */ + translucent: ?boolean, + /** + * + */ + hidden: { + value: ?boolean, + animated: boolean, + transition: ?('slide' | 'fade'), + }, + /** + * If the network activity indicator should be visible. + * + * @platform ios + */ + networkActivityIndicatorVisible: ?boolean, +}; + /** * Merges the prop stack with the default values. */ function mergePropsStack( - propsStack: Array, - defaultValues: Object, -): Object { + propsStack: Array, + defaultValues: StackEntryProps, +): StackEntryProps { return propsStack.reduce((prev, cur) => { for (const prop in cur) { if (cur[prop] != null) { @@ -124,32 +163,24 @@ function mergePropsStack( * Returns an object to insert in the props stack from the props * and the transition/animation info. */ -function createStackEntry(props: any): any { +function createStackEntry(props: Props): StackEntryProps { return { - backgroundColor: - props.backgroundColor != null - ? { - value: props.backgroundColor, - animated: props.animated, - } - : null, - barStyle: - props.barStyle != null - ? { - value: props.barStyle, - animated: props.animated, - } - : null, - translucent: props.translucent, - hidden: - props.hidden != null - ? { - value: props.hidden, - animated: props.animated, - transition: props.showHideTransition, - } - : null, - networkActivityIndicatorVisible: props.networkActivityIndicatorVisible, + backgroundColor: { + value: props.backgroundColor, + animated: props.animated, + }, + barStyle: { + value: props.barStyle, + animated: props.animated, + }, + translucent: props.translucent || false, + hidden: { + value: props.hidden, + animated: props.animated || false, + transition: props.showHideTransition, + }, + networkActivityIndicatorVisible: + props.networkActivityIndicatorVisible || false, }; } @@ -195,7 +226,7 @@ function createStackEntry(props: any): any { class StatusBar extends React.Component { static _propsStack = []; - static _defaultProps = createStackEntry({ + static _defaultProps: StackEntryProps = createStackEntry({ animated: false, showHideTransition: 'fade', backgroundColor: 'black', @@ -230,10 +261,9 @@ class StatusBar extends React.Component { * changing the status bar hidden property. */ static setHidden(hidden: boolean, animation?: StatusBarAnimation) { - animation = animation || 'none'; StatusBar._defaultProps.hidden.value = hidden; if (Platform.OS === 'ios') { - StatusBarManager.setHidden(hidden, animation); + StatusBarManager.setHidden(hidden, animation || 'none'); } else if (Platform.OS === 'android') { StatusBarManager.setHidden(hidden); } @@ -245,10 +275,9 @@ class StatusBar extends React.Component { * @param animated Animate the style change. */ static setBarStyle(style: StatusBarStyle, animated?: boolean) { - animated = animated || false; StatusBar._defaultProps.barStyle.value = style; if (Platform.OS === 'ios') { - StatusBarManager.setStyle(style, animated); + StatusBarManager.setStyle(style, animated || false); } else if (Platform.OS === 'android') { StatusBarManager.setStyle(style); } @@ -279,9 +308,8 @@ class StatusBar extends React.Component { console.warn('`setBackgroundColor` is only available on Android'); return; } - animated = animated || false; StatusBar._defaultProps.backgroundColor.value = color; - StatusBarManager.setColor(processColor(color), animated); + StatusBarManager.setColor(processColor(color), animated || false); } /** From ae8cfcc290587132cf2d8505238965524f44aadb Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 15 Nov 2018 12:12:20 +0900 Subject: [PATCH 3/4] Delete deepFreezeAndThrowOnMutationInDev-test.js --- .../deepFreezeAndThrowOnMutationInDev-test.js | 143 ------------------ 1 file changed, 143 deletions(-) delete mode 100644 Libraries/Utilities/__tests__/deepFreezeAndThrowOnMutationInDev-test.js diff --git a/Libraries/Utilities/__tests__/deepFreezeAndThrowOnMutationInDev-test.js b/Libraries/Utilities/__tests__/deepFreezeAndThrowOnMutationInDev-test.js deleted file mode 100644 index 1ed6231c663603..00000000000000 --- a/Libraries/Utilities/__tests__/deepFreezeAndThrowOnMutationInDev-test.js +++ /dev/null @@ -1,143 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @emails oncall+react_native - */ - -const deepFreezeAndThrowOnMutationInDev = require('deepFreezeAndThrowOnMutationInDev'); - -describe('deepFreezeAndThrowOnMutationInDev', function() { - it('should be a noop on non object values', () => { - __DEV__ = true; - expect(() => deepFreezeAndThrowOnMutationInDev('')).not.toThrow(); - expect(() => deepFreezeAndThrowOnMutationInDev(null)).not.toThrow(); - expect(() => deepFreezeAndThrowOnMutationInDev(false)).not.toThrow(); - expect(() => deepFreezeAndThrowOnMutationInDev(5)).not.toThrow(); - expect(() => deepFreezeAndThrowOnMutationInDev()).not.toThrow(); - __DEV__ = false; - expect(() => deepFreezeAndThrowOnMutationInDev('')).not.toThrow(); - expect(() => deepFreezeAndThrowOnMutationInDev(null)).not.toThrow(); - expect(() => deepFreezeAndThrowOnMutationInDev(false)).not.toThrow(); - expect(() => deepFreezeAndThrowOnMutationInDev(5)).not.toThrow(); - expect(() => deepFreezeAndThrowOnMutationInDev()).not.toThrow(); - }); - - it('should not throw on object without prototype', () => { - __DEV__ = true; - const o = Object.create(null); - o.key = 'Value'; - expect(() => deepFreezeAndThrowOnMutationInDev(o)).not.toThrow(); - }); - - it('should throw on mutation in dev with strict', () => { - 'use strict'; - __DEV__ = true; - const o = {key: 'oldValue'}; - deepFreezeAndThrowOnMutationInDev(o); - expect(() => { - o.key = 'newValue'; - }).toThrowError( - 'You attempted to set the key `key` with the value `"newValue"` ' + - 'on an object that is meant to be immutable and has been frozen.', - ); - expect(o.key).toBe('oldValue'); - }); - - it('should throw on mutation in dev without strict', () => { - __DEV__ = true; - const o = {key: 'oldValue'}; - deepFreezeAndThrowOnMutationInDev(o); - expect(() => { - o.key = 'newValue'; - }).toThrowError( - 'You attempted to set the key `key` with the value `"newValue"` ' + - 'on an object that is meant to be immutable and has been frozen.', - ); - expect(o.key).toBe('oldValue'); - }); - - it('should throw on nested mutation in dev with strict', () => { - 'use strict'; - __DEV__ = true; - const o = {key1: {key2: {key3: 'oldValue'}}}; - deepFreezeAndThrowOnMutationInDev(o); - expect(() => { - o.key1.key2.key3 = 'newValue'; - }).toThrowError( - 'You attempted to set the key `key3` with the value `"newValue"` ' + - 'on an object that is meant to be immutable and has been frozen.', - ); - expect(o.key1.key2.key3).toBe('oldValue'); - }); - - it('should throw on nested mutation in dev without strict', () => { - __DEV__ = true; - const o = {key1: {key2: {key3: 'oldValue'}}}; - deepFreezeAndThrowOnMutationInDev(o); - expect(() => { - o.key1.key2.key3 = 'newValue'; - }).toThrowError( - 'You attempted to set the key `key3` with the value `"newValue"` ' + - 'on an object that is meant to be immutable and has been frozen.', - ); - expect(o.key1.key2.key3).toBe('oldValue'); - }); - - it('should throw on insertion in dev with strict', () => { - 'use strict'; - __DEV__ = true; - const o = {oldKey: 'value'}; - deepFreezeAndThrowOnMutationInDev(o); - expect(() => { - o.newKey = 'value'; - }).toThrowError( - /(Cannot|Can't) add property newKey, object is not extensible/, - ); - expect(o.newKey).toBe(undefined); - }); - - it('should not throw on insertion in dev without strict', () => { - __DEV__ = true; - const o = {oldKey: 'value'}; - deepFreezeAndThrowOnMutationInDev(o); - expect(() => { - o.newKey = 'value'; - }).not.toThrow(); - expect(o.newKey).toBe(undefined); - }); - - it('should mutate and not throw on mutation in prod', () => { - 'use strict'; - __DEV__ = false; - const o = {key: 'oldValue'}; - deepFreezeAndThrowOnMutationInDev(o); - expect(() => { - o.key = 'newValue'; - }).not.toThrow(); - expect(o.key).toBe('newValue'); - }); - - // This is a limitation of the technique unfortunately - it('should not deep freeze already frozen objects', () => { - 'use strict'; - __DEV__ = true; - const o = {key1: {key2: 'oldValue'}}; - Object.freeze(o); - deepFreezeAndThrowOnMutationInDev(o); - expect(() => { - o.key1.key2 = 'newValue'; - }).not.toThrow(); - expect(o.key1.key2).toBe('newValue'); - }); - - it('shouldn\'t recurse infinitely', () => { - __DEV__ = true; - const o = {}; - o.circular = o; - deepFreezeAndThrowOnMutationInDev(o); - }); -}); From 47a5fb81726120b9a65d298dc5d0ee137190c938 Mon Sep 17 00:00:00 2001 From: watanabeyu Date: Thu, 29 Nov 2018 11:29:45 +0900 Subject: [PATCH 4/4] change setHidden arguments 0 required yes -> no --- Libraries/Components/StatusBar/StatusBar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Libraries/Components/StatusBar/StatusBar.js b/Libraries/Components/StatusBar/StatusBar.js index 5cedf1436431f7..9803929e6232ca 100644 --- a/Libraries/Components/StatusBar/StatusBar.js +++ b/Libraries/Components/StatusBar/StatusBar.js @@ -146,7 +146,7 @@ type StackEntryProps = { * Merges the prop stack with the default values. */ function mergePropsStack( - propsStack: Array, + propsStack: $ReadOnlyArray, defaultValues: StackEntryProps, ): StackEntryProps { return propsStack.reduce((prev, cur) => { @@ -260,7 +260,7 @@ class StatusBar extends React.Component { * @param animation Optional animation when * changing the status bar hidden property. */ - static setHidden(hidden: boolean, animation?: StatusBarAnimation) { + static setHidden(hidden: boolean = true, animation?: StatusBarAnimation) { StatusBar._defaultProps.hidden.value = hidden; if (Platform.OS === 'ios') { StatusBarManager.setHidden(hidden, animation || 'none');