From 16292e77e55ed3c6b1ccd207f1a183c8bd32a29e Mon Sep 17 00:00:00 2001 From: Alec Winograd Date: Tue, 19 Feb 2019 20:19:00 -0600 Subject: [PATCH 1/3] Replace contextType with createContext for isInAParentText --- .../src/exports/Image/index.js | 20 ++++++------- .../src/exports/Text/index.js | 30 ++++++++----------- .../src/exports/View/index.js | 21 +++++++------ 3 files changed, 33 insertions(+), 38 deletions(-) diff --git a/packages/react-native-web/src/exports/Image/index.js b/packages/react-native-web/src/exports/Image/index.js index cf72f098c..9825949c2 100644 --- a/packages/react-native-web/src/exports/Image/index.js +++ b/packages/react-native-web/src/exports/Image/index.js @@ -17,6 +17,7 @@ import ImageResizeMode from './ImageResizeMode'; import ImageSourcePropType from './ImageSourcePropType'; import ImageStylePropTypes from './ImageStylePropTypes'; import ImageUriCache from './ImageUriCache'; +import { IsInAParentTextConsumer } from '../Text'; import StyleSheet from '../StyleSheet'; import StyleSheetPropType from '../../modules/StyleSheetPropType'; import View from '../View'; @@ -96,10 +97,6 @@ type State = { class Image extends Component<*, State> { static displayName = 'Image'; - static contextTypes = { - isInAParentText: bool - }; - static propTypes = { ...ViewPropTypes, blurRadius: number, @@ -179,7 +176,7 @@ class Image extends Component<*, State> { this._isMounted = false; } - render() { + renderInner(isInAParentText) { const { shouldDisplaySource } = this.state; const { accessibilityLabel, @@ -267,12 +264,7 @@ class Image extends Component<*, State> { accessibilityLabel={accessibilityLabel} accessible={accessible} onLayout={this._createLayoutHandler(finalResizeMode)} - style={[ - styles.root, - this.context.isInAParentText && styles.inline, - imageSizeStyle, - flatStyle - ]} + style={[styles.root, isInAParentText && styles.inline, imageSizeStyle, flatStyle]} testID={testID} > { ); } + render() { + return createElement(IsInAParentTextConsumer, null, isInAParentText => { + return this.renderInner(isInAParentText); + }); + } + _createImageLoader() { const { source } = this.props; this._destroyImageLoader(); diff --git a/packages/react-native-web/src/exports/Text/index.js b/packages/react-native-web/src/exports/Text/index.js index 0610649c2..c380ff730 100644 --- a/packages/react-native-web/src/exports/Text/index.js +++ b/packages/react-native-web/src/exports/Text/index.js @@ -10,30 +10,20 @@ import applyLayout from '../../modules/applyLayout'; import applyNativeMethods from '../../modules/applyNativeMethods'; -import { bool } from 'prop-types'; -import { Component } from 'react'; +import { Component, createContext } from 'react'; import createElement from '../createElement'; import StyleSheet from '../StyleSheet'; import TextPropTypes from './TextPropTypes'; +const { Provider, Consumer } = createContext(false); +export const IsInAParentTextConsumer = Consumer; + class Text extends Component<*> { static displayName = 'Text'; static propTypes = TextPropTypes; - static childContextTypes = { - isInAParentText: bool - }; - - static contextTypes = { - isInAParentText: bool - }; - - getChildContext() { - return { isInAParentText: true }; - } - - render() { + renderInner(isInAParentText) { const { dir, numberOfLines, @@ -57,8 +47,6 @@ class Text extends Component<*> { ...otherProps } = this.props; - const { isInAParentText } = this.context; - if (onPress) { otherProps.accessible = true; otherProps.onClick = this._createPressHandler(onPress); @@ -69,7 +57,7 @@ class Text extends Component<*> { otherProps.dir = dir !== undefined ? dir : 'auto'; otherProps.style = [ styles.initial, - this.context.isInAParentText === true && styles.isInAParentText, + isInAParentText === true && styles.isInAParentText, style, selectable === false && styles.notSelectable, numberOfLines === 1 && styles.singleLineStyle, @@ -81,6 +69,12 @@ class Text extends Component<*> { return createElement(component, otherProps); } + render() { + return createElement(IsInAParentTextConsumer, null, isInAParentText => { + return createElement(Provider, { value: true }, this.renderInner(isInAParentText)); + }); + } + _createEnterHandler(fn) { return e => { if (e.keyCode === 13) { diff --git a/packages/react-native-web/src/exports/View/index.js b/packages/react-native-web/src/exports/View/index.js index 2407c1fc3..da408496a 100644 --- a/packages/react-native-web/src/exports/View/index.js +++ b/packages/react-native-web/src/exports/View/index.js @@ -8,10 +8,10 @@ import applyLayout from '../../modules/applyLayout'; import applyNativeMethods from '../../modules/applyNativeMethods'; -import { bool } from 'prop-types'; import createElement from '../createElement'; import filterSupportedProps from './filterSupportedProps'; import invariant from 'fbjs/lib/invariant'; +import { IsInAParentTextConsumer } from '../Text'; import StyleSheet from '../StyleSheet'; import ViewPropTypes, { type ViewProps } from './ViewPropTypes'; import React, { Component } from 'react'; @@ -30,13 +30,9 @@ const calculateHitSlopStyle = hitSlop => { class View extends Component { static displayName = 'View'; - static contextTypes = { - isInAParentText: bool - }; - static propTypes = ViewPropTypes; - render() { + renderInner(isInAParentText) { const hitSlop = this.props.hitSlop; const supportedProps = filterSupportedProps(this.props); @@ -49,11 +45,12 @@ class View extends Component { }); } - const { isInAParentText } = this.context; - supportedProps.style = StyleSheet.compose( styles.initial, - StyleSheet.compose(isInAParentText && styles.inline, this.props.style) + StyleSheet.compose( + isInAParentText && styles.inline, + this.props.style + ) ); if (hitSlop) { @@ -64,6 +61,12 @@ class View extends Component { return createElement('div', supportedProps); } + + render() { + return createElement(IsInAParentTextConsumer, null, isInAParentText => { + return this.renderInner(isInAParentText); + }); + } } const styles = StyleSheet.create({ From 846d8450bd823b5e4b9631e3f4e2ebdbd6e102d1 Mon Sep 17 00:00:00 2001 From: Alec Winograd Date: Thu, 21 Feb 2019 09:32:26 -0600 Subject: [PATCH 2/3] Craete TextAncestor module to match react-native implementation --- .../src/exports/Image/index.js | 10 +++++----- .../src/exports/Text/index.js | 12 ++++++------ .../src/exports/TextAncestor/index.js | 19 +++++++++++++++++++ .../src/exports/View/index.js | 10 +++++----- 4 files changed, 35 insertions(+), 16 deletions(-) create mode 100644 packages/react-native-web/src/exports/TextAncestor/index.js diff --git a/packages/react-native-web/src/exports/Image/index.js b/packages/react-native-web/src/exports/Image/index.js index 9825949c2..7d2d00d9d 100644 --- a/packages/react-native-web/src/exports/Image/index.js +++ b/packages/react-native-web/src/exports/Image/index.js @@ -17,9 +17,9 @@ import ImageResizeMode from './ImageResizeMode'; import ImageSourcePropType from './ImageSourcePropType'; import ImageStylePropTypes from './ImageStylePropTypes'; import ImageUriCache from './ImageUriCache'; -import { IsInAParentTextConsumer } from '../Text'; import StyleSheet from '../StyleSheet'; import StyleSheetPropType from '../../modules/StyleSheetPropType'; +import TextAncestor from '../TextAncestor'; import View from '../View'; import ViewPropTypes from '../ViewPropTypes'; import { bool, func, number, oneOf, shape } from 'prop-types'; @@ -176,7 +176,7 @@ class Image extends Component<*, State> { this._isMounted = false; } - renderInner(isInAParentText) { + renderInner(hasTextAncestor) { const { shouldDisplaySource } = this.state; const { accessibilityLabel, @@ -264,7 +264,7 @@ class Image extends Component<*, State> { accessibilityLabel={accessibilityLabel} accessible={accessible} onLayout={this._createLayoutHandler(finalResizeMode)} - style={[styles.root, isInAParentText && styles.inline, imageSizeStyle, flatStyle]} + style={[styles.root, hasTextAncestor && styles.inline, imageSizeStyle, flatStyle]} testID={testID} > { } render() { - return createElement(IsInAParentTextConsumer, null, isInAParentText => { - return this.renderInner(isInAParentText); + return createElement(TextAncestor.Consumer, null, hasTextAncestor => { + return this.renderInner(hasTextAncestor); }); } diff --git a/packages/react-native-web/src/exports/Text/index.js b/packages/react-native-web/src/exports/Text/index.js index c380ff730..13353eb01 100644 --- a/packages/react-native-web/src/exports/Text/index.js +++ b/packages/react-native-web/src/exports/Text/index.js @@ -10,14 +10,12 @@ import applyLayout from '../../modules/applyLayout'; import applyNativeMethods from '../../modules/applyNativeMethods'; -import { Component, createContext } from 'react'; +import { Component } from 'react'; import createElement from '../createElement'; import StyleSheet from '../StyleSheet'; +import TextAncestor from '../TextAncestor'; import TextPropTypes from './TextPropTypes'; -const { Provider, Consumer } = createContext(false); -export const IsInAParentTextConsumer = Consumer; - class Text extends Component<*> { static displayName = 'Text'; @@ -70,8 +68,10 @@ class Text extends Component<*> { } render() { - return createElement(IsInAParentTextConsumer, null, isInAParentText => { - return createElement(Provider, { value: true }, this.renderInner(isInAParentText)); + return createElement(TextAncestor.Consumer, null, hasTextAncestor => { + return hasTextAncestor + ? this.renderInner(hasTextAncestor) + : createElement(TextAncestor.Provider, { value: true }, this.renderInner(hasTextAncestor)); }); } diff --git a/packages/react-native-web/src/exports/TextAncestor/index.js b/packages/react-native-web/src/exports/TextAncestor/index.js new file mode 100644 index 000000000..799df1585 --- /dev/null +++ b/packages/react-native-web/src/exports/TextAncestor/index.js @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2015-present, Nicolas Gallagher. + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import { createContext } from 'react'; + +/** + * Whether the current element is the descendant of a element. + **/ +/* $FlowFixMe(>=0.85.0 site=react_native_fb) This comment suppresses an error + * found when Flow v0.85 was deployed. To see the error, delete this comment + * and run Flow. */ +export default createContext(false); diff --git a/packages/react-native-web/src/exports/View/index.js b/packages/react-native-web/src/exports/View/index.js index da408496a..99766c868 100644 --- a/packages/react-native-web/src/exports/View/index.js +++ b/packages/react-native-web/src/exports/View/index.js @@ -11,8 +11,8 @@ import applyNativeMethods from '../../modules/applyNativeMethods'; import createElement from '../createElement'; import filterSupportedProps from './filterSupportedProps'; import invariant from 'fbjs/lib/invariant'; -import { IsInAParentTextConsumer } from '../Text'; import StyleSheet from '../StyleSheet'; +import TextAncestor from '../TextAncestor'; import ViewPropTypes, { type ViewProps } from './ViewPropTypes'; import React, { Component } from 'react'; @@ -32,7 +32,7 @@ class View extends Component { static propTypes = ViewPropTypes; - renderInner(isInAParentText) { + renderInner(hasTextAncestor) { const hitSlop = this.props.hitSlop; const supportedProps = filterSupportedProps(this.props); @@ -48,7 +48,7 @@ class View extends Component { supportedProps.style = StyleSheet.compose( styles.initial, StyleSheet.compose( - isInAParentText && styles.inline, + hasTextAncestor && styles.inline, this.props.style ) ); @@ -63,8 +63,8 @@ class View extends Component { } render() { - return createElement(IsInAParentTextConsumer, null, isInAParentText => { - return this.renderInner(isInAParentText); + return createElement(TextAncestor.Consumer, null, hasTextAncestor => { + return this.renderInner(hasTextAncestor); }); } } From efdc66c93cf6a456f0bec1e43bf07aae4b37b280 Mon Sep 17 00:00:00 2001 From: Alec Winograd Date: Thu, 21 Feb 2019 09:42:52 -0600 Subject: [PATCH 3/3] Bump flow to ^0.78.0 to match react-native-0.57 --- .flowconfig | 2 +- package.json | 2 +- packages/react-native-web/src/exports/Clipboard/index.js | 1 + .../src/modules/normalizeNativeEvent/index.js | 1 + yarn.lock | 7 ++++--- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.flowconfig b/.flowconfig index 78ed67bea..65c3be904 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,5 +1,5 @@ [version] -^0.63.0 +^0.78.0 [ignore] /.*/__tests__/.* diff --git a/package.json b/package.json index 05937f181..8e391e1ed 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "eslint-config-prettier": "^2.9.0", "eslint-plugin-promise": "^3.7.0", "eslint-plugin-react": "^7.7.0", - "flow-bin": "^0.63.1", + "flow-bin": "^0.78.0", "glob": "^7.1.2", "husky": "^0.14.3", "jest": "^22.4.3", diff --git a/packages/react-native-web/src/exports/Clipboard/index.js b/packages/react-native-web/src/exports/Clipboard/index.js index ff7287cbd..2b28054e8 100644 --- a/packages/react-native-web/src/exports/Clipboard/index.js +++ b/packages/react-native-web/src/exports/Clipboard/index.js @@ -14,6 +14,7 @@ export default class Clipboard { static isAvailable() { if (clipboardAvailable === undefined) { clipboardAvailable = + /* $FlowFixMe(<0.93.0) */ typeof document.queryCommandSupported === 'function' && document.queryCommandSupported('copy'); } diff --git a/packages/react-native-web/src/modules/normalizeNativeEvent/index.js b/packages/react-native-web/src/modules/normalizeNativeEvent/index.js index 126dd0992..b9f17732f 100644 --- a/packages/react-native-web/src/modules/normalizeNativeEvent/index.js +++ b/packages/react-native-web/src/modules/normalizeNativeEvent/index.js @@ -25,6 +25,7 @@ const normalizeTouches = touches => { return emptyArray; } + // $FlowFixMe return Array.prototype.slice.call(touches).map(touch => { const identifier = touch.identifier > 20 ? touch.identifier % 20 : touch.identifier; let rect; diff --git a/yarn.lock b/yarn.lock index 51fd834a0..87f51e17c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4678,9 +4678,10 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" -flow-bin@^0.63.1: - version "0.63.1" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.63.1.tgz#ab00067c197169a5fb5b4996c8f6927b06694828" +flow-bin@^0.78.0: + version "0.78.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.78.0.tgz#df9fe7f9c9a2dfaff39083949fe2d831b41627b7" + integrity sha512-LV55tE+ItkC9HQAbEK+VxpBe54Ryp/dj4q9KmqDIfhV7mtP+hbvc/1AUf/AaWFIve3eURO0cxoGN4ZQQ3o2HTg== flow-parser@^0.*: version "0.76.0"