Skip to content

Commit

Permalink
RN: Replace context.isInAParentText w/ React.createContext
Browse files Browse the repository at this point in the history
Reviewed By: sahrens

Differential Revision: D7895382

fbshipit-source-id: 4affcecd147b8e8c506e0d94f223bac3e6dfdf66
  • Loading branch information
yungsters authored and facebook-github-bot committed May 9, 2018
1 parent 5d4c542 commit e1339bc
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 95 deletions.
21 changes: 7 additions & 14 deletions Libraries/Components/TextInput/TextInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const PropTypes = require('prop-types');
const ReactNative = require('ReactNative');
const StyleSheet = require('StyleSheet');
const Text = require('Text');
const TextAncestor = require('TextAncestor');
const TextInputState = require('TextInputState');
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
* found when Flow v0.54 was deployed. To see the error delete this comment and
Expand All @@ -28,7 +29,6 @@ const TimerMixin = require('react-timer-mixin');
const TouchableWithoutFeedback = require('TouchableWithoutFeedback');
const UIManager = require('UIManager');
const ViewPropTypes = require('ViewPropTypes');
const {ViewContextTypes} = require('ViewContext');

const emptyFunction = require('fbjs/lib/emptyFunction');
const invariant = require('fbjs/lib/invariant');
Expand All @@ -47,8 +47,6 @@ const onlyMultiline = {
children: true,
};

import type {ViewChildContext} from 'ViewContext';

if (Platform.OS === 'android') {
AndroidTextInput = requireNativeComponent('AndroidTextInput', null);
} else if (Platform.OS === 'ios') {
Expand Down Expand Up @@ -701,16 +699,7 @@ const TextInput = createReactClass({
}
},

getChildContext(): ViewChildContext {
return {
isInAParentText: true,
};
},

childContextTypes: ViewContextTypes,

contextTypes: {
...ViewContextTypes,
onFocusRequested: PropTypes.func,
focusEmitter: PropTypes.instanceOf(EventEmitter),
},
Expand All @@ -723,13 +712,17 @@ const TextInput = createReactClass({
},

render: function() {
let textInput;
if (Platform.OS === 'ios') {
return UIManager.RCTVirtualText
textInput = UIManager.RCTVirtualText
? this._renderIOS()
: this._renderIOSLegacy();
} else if (Platform.OS === 'android') {
return this._renderAndroid();
textInput = this._renderAndroid();
}
return (
<TextAncestor.Provider value={true}>{textInput}</TextAncestor.Provider>
);
},

_getText: function(): ?string {
Expand Down
38 changes: 20 additions & 18 deletions Libraries/Components/View/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,21 @@
* @flow
* @format
*/

'use strict';

const Platform = require('Platform');
const React = require('React');
const ReactNative = require('ReactNative');
const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
const TextAncestor = require('TextAncestor');
const ViewPropTypes = require('ViewPropTypes');
const {ViewContextTypes} = require('ViewContext');

const invariant = require('fbjs/lib/invariant');
const requireNativeComponent = require('requireNativeComponent');

import type {ViewProps} from 'ViewPropTypes';
import type {ViewChildContext} from 'ViewContext';

export type Props = ViewProps;

Expand All @@ -33,30 +34,31 @@ export type Props = ViewProps;
*/
class View extends ReactNative.NativeComponent<Props> {
static propTypes = ViewPropTypes;
static childContextTypes = ViewContextTypes;

viewConfig = {
uiViewClassName: 'RCTView',
validAttributes: ReactNativeViewAttributes.RCTView,
};

getChildContext(): ViewChildContext {
return {
isInAParentText: false,
};
}

/**
* WARNING: This method will not be used in production mode as in that mode we
* replace wrapper component View with generated native wrapper RCTView. Avoid
* adding functionality this component that you'd want to be available in both
* dev and prod modes.
*/
render() {
invariant(
!(this.context.isInAParentText && Platform.OS === 'android'),
'Nesting of <View> within <Text> is not supported on Android.',
return (
<TextAncestor.Consumer>
{hasTextAncestor => {
// TODO: Change iOS to behave the same as Android.
invariant(
!hasTextAncestor || Platform.OS !== 'android',
'Nesting of <View> within <Text> is not supported on Android.',
);
return <RCTView {...this.props} />;
}}
</TextAncestor.Consumer>
);

// WARNING: This method will not be used in production mode as in that mode we
// replace wrapper component View with generated native wrapper RCTView. Avoid
// adding functionality this component that you'd want to be available in both
// dev and prod modes.
return <RCTView {...this.props} />;
}
}

Expand Down
76 changes: 38 additions & 38 deletions Libraries/Image/Image.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* @flow
* @format
*/

'use strict';

var ImageResizeMode = require('ImageResizeMode');
Expand All @@ -18,6 +19,7 @@ var PropTypes = require('prop-types');
var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
var StyleSheet = require('StyleSheet');
var StyleSheetPropType = require('StyleSheetPropType');
const TextAncestor = require('TextAncestor');
var ViewPropTypes = require('ViewPropTypes');

var createReactClass = require('create-react-class');
Expand All @@ -26,8 +28,6 @@ var merge = require('merge');
var requireNativeComponent = require('requireNativeComponent');
var resolveAssetSource = require('resolveAssetSource');

const {ViewContextTypes} = require('ViewContext');

var {ImageLoader} = NativeModules;

let _requestId = 1;
Expand Down Expand Up @@ -202,8 +202,6 @@ var Image = createReactClass({
validAttributes: ReactNativeViewAttributes.RCTView,
},

contextTypes: ViewContextTypes,

render: function() {
const source = resolveAssetSource(this.props.source);
const defaultSource = resolveAssetSource(this.props.defaultSource);
Expand Down Expand Up @@ -236,42 +234,44 @@ var Image = createReactClass({
);
}

if (source && (source.uri || Array.isArray(source))) {
let style;
let sources;
if (source.uri) {
const {width, height} = source;
style = flattenStyle([{width, height}, styles.base, this.props.style]);
sources = [{uri: source.uri}];
} else {
style = flattenStyle([styles.base, this.props.style]);
sources = source;
}

const {onLoadStart, onLoad, onLoadEnd, onError} = this.props;
const nativeProps = merge(this.props, {
style,
shouldNotifyLoadEvents: !!(
onLoadStart ||
onLoad ||
onLoadEnd ||
onError
),
src: sources,
headers: source.headers,
defaultSrc: defaultSource ? defaultSource.uri : null,
loadingIndicatorSrc: loadingIndicatorSource
? loadingIndicatorSource.uri
: null,
});
if (!source || (!source.uri && !Array.isArray(source))) {
return null;
}

if (this.context.isInAParentText) {
return <RCTTextInlineImage {...nativeProps} />;
} else {
return <RKImage {...nativeProps} />;
}
let style;
let sources;
if (source.uri) {
const {width, height} = source;
style = flattenStyle([{width, height}, styles.base, this.props.style]);
sources = [{uri: source.uri}];
} else {
style = flattenStyle([styles.base, this.props.style]);
sources = source;
}
return null;

const {onLoadStart, onLoad, onLoadEnd, onError} = this.props;
const nativeProps = merge(this.props, {
style,
shouldNotifyLoadEvents: !!(onLoadStart || onLoad || onLoadEnd || onError),
src: sources,
headers: source.headers,
defaultSrc: defaultSource ? defaultSource.uri : null,
loadingIndicatorSrc: loadingIndicatorSource
? loadingIndicatorSource.uri
: null,
});

return (
<TextAncestor.Consumer>
{hasTextAncestor =>
hasTextAncestor ? (
<RCTTextInlineImage {...nativeProps} />
) : (
<RKImage {...nativeProps} />
)
}
</TextAncestor.Consumer>
);
},
});

Expand Down
29 changes: 14 additions & 15 deletions Libraries/Text/Text.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@
const React = require('React');
const ReactNative = require('ReactNative');
const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
const TextAncestor = require('TextAncestor');
const TextPropTypes = require('TextPropTypes');
const Touchable = require('Touchable');
const UIManager = require('UIManager');

const createReactNativeComponentClass = require('createReactNativeComponentClass');
const mergeFast = require('mergeFast');
const processColor = require('processColor');
const {ViewContextTypes} = require('ViewContext');

import type {PressEvent} from 'CoreEventTypes';
import type {TextProps} from 'TextProps';
import type {ViewChildContext} from 'ViewContext';

type State = {
isHighlighted: boolean,
Expand Down Expand Up @@ -61,8 +60,6 @@ const viewConfig = {
*/
class Text extends ReactNative.NativeComponent<TextProps, State> {
static propTypes = TextPropTypes;
static childContextTypes = ViewContextTypes;
static contextTypes = ViewContextTypes;

static defaultProps = {
accessible: true,
Expand All @@ -76,12 +73,6 @@ class Text extends ReactNative.NativeComponent<TextProps, State> {

viewConfig = viewConfig;

getChildContext(): ViewChildContext {
return {
isInAParentText: true,
};
}

_handlers: ?Object;

_hasPressHandler(): boolean {
Expand Down Expand Up @@ -215,11 +206,19 @@ class Text extends ReactNative.NativeComponent<TextProps, State> {
style: [this.props.style, {color: 'magenta'}],
};
}
if (this.context.isInAParentText) {
return <RCTVirtualText {...newProps} />;
} else {
return <RCTText {...newProps} />;
}
return (
<TextAncestor.Consumer>
{hasTextAncestor =>
hasTextAncestor ? (
<RCTVirtualText {...newProps} />
) : (
<TextAncestor.Provider value={true}>
<RCTText {...newProps} />
</TextAncestor.Provider>
)
}
</TextAncestor.Consumer>
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,12 @@
* @flow
* @format
*/
'use strict';

const PropTypes = require('prop-types');
'use strict';

export type ViewChildContext = {|
+isInAParentText: boolean,
|};
const React = require('React');

module.exports = {
ViewContextTypes: {
isInAParentText: PropTypes.bool,
},
};
/**
* Whether the current element is the descendant of a <Text> element.
*/
module.exports = React.createContext(false);

0 comments on commit e1339bc

Please sign in to comment.