mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-03-26 07:04:05 +08:00
[ReactNative] verifyPropTypes against native exports
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
var EdgeInsetsPropType = require('EdgeInsetsPropType');
|
||||
var NativeMethodsMixin = require('NativeMethodsMixin');
|
||||
var NativeModules = require('NativeModules');
|
||||
var Platform = require('Platform');
|
||||
var PropTypes = require('ReactPropTypes');
|
||||
var ImageResizeMode = require('ImageResizeMode');
|
||||
var ImageStylePropTypes = require('ImageStylePropTypes');
|
||||
@@ -27,7 +28,9 @@ var flattenStyle = require('flattenStyle');
|
||||
var insetsDiffer = require('insetsDiffer');
|
||||
var invariant = require('invariant');
|
||||
var merge = require('merge');
|
||||
var requireNativeComponent = require('requireNativeComponent');
|
||||
var warning = require('warning');
|
||||
var verifyPropTypes = require('verifyPropTypes');
|
||||
|
||||
/**
|
||||
* A react component for displaying different types of images,
|
||||
@@ -64,6 +67,13 @@ var Image = React.createClass({
|
||||
source: PropTypes.shape({
|
||||
uri: PropTypes.string,
|
||||
}),
|
||||
/**
|
||||
* A static image to display while downloading the final image off the
|
||||
* network.
|
||||
*/
|
||||
defaultSource: PropTypes.shape({
|
||||
uri: PropTypes.string,
|
||||
}),
|
||||
/**
|
||||
* Whether this element should be revealed as an accessible element.
|
||||
*/
|
||||
@@ -80,6 +90,11 @@ var Image = React.createClass({
|
||||
* [Apple documentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/index.html#//apple_ref/occ/instm/UIImage/resizableImageWithCapInsets)
|
||||
*/
|
||||
capInsets: EdgeInsetsPropType,
|
||||
/**
|
||||
* Determines how to resize the image when the frame doesn't match the raw
|
||||
* image dimensions.
|
||||
*/
|
||||
resizeMode: PropTypes.oneOf(['cover', 'contain', 'stretch']),
|
||||
style: StyleSheetPropType(ImageStylePropTypes),
|
||||
/**
|
||||
* A unique identifier for this element to be used in UI Automation
|
||||
@@ -104,6 +119,12 @@ var Image = React.createClass({
|
||||
},
|
||||
|
||||
render: function() {
|
||||
for (var prop in nativeOnlyProps) {
|
||||
if (this.props[prop] !== undefined) {
|
||||
console.warn('Prop `' + prop + ' = ' + this.props[prop] + '` should ' +
|
||||
'not be set directly on Image.');
|
||||
}
|
||||
}
|
||||
var style = flattenStyle([styles.base, this.props.style]);
|
||||
invariant(style, "style must be initialized");
|
||||
var source = this.props.source;
|
||||
@@ -119,28 +140,36 @@ var Image = React.createClass({
|
||||
if (this.props.style && this.props.style.tintColor) {
|
||||
warning(RawImage === RCTStaticImage, 'tintColor style only supported on static images.');
|
||||
}
|
||||
|
||||
var resizeMode = this.props.resizeMode || style.resizeMode;
|
||||
var contentModes = NativeModules.UIManager.UIView.ContentMode;
|
||||
var resizeMode;
|
||||
if (style.resizeMode === ImageResizeMode.stretch) {
|
||||
resizeMode = contentModes.ScaleToFill;
|
||||
} else if (style.resizeMode === ImageResizeMode.contain) {
|
||||
resizeMode = contentModes.ScaleAspectFit;
|
||||
var contentMode;
|
||||
if (resizeMode === ImageResizeMode.stretch) {
|
||||
contentMode = contentModes.ScaleToFill;
|
||||
} else if (resizeMode === ImageResizeMode.contain) {
|
||||
contentMode = contentModes.ScaleAspectFit;
|
||||
} else { // ImageResizeMode.cover or undefined
|
||||
resizeMode = contentModes.ScaleAspectFill;
|
||||
contentMode = contentModes.ScaleAspectFill;
|
||||
}
|
||||
|
||||
var nativeProps = merge(this.props, {
|
||||
style,
|
||||
resizeMode,
|
||||
contentMode,
|
||||
tintColor: style.tintColor,
|
||||
});
|
||||
if (Platform.OS === 'android') {
|
||||
// TODO: update android native code to not need this
|
||||
nativeProps.resizeMode = contentMode;
|
||||
delete nativeProps.contentMode;
|
||||
}
|
||||
|
||||
if (isStored) {
|
||||
nativeProps.imageTag = source.uri;
|
||||
} else {
|
||||
nativeProps.src = source.uri;
|
||||
}
|
||||
if (this.props.defaultSource) {
|
||||
nativeProps.defaultImageSrc = this.props.defaultSource.uri;
|
||||
}
|
||||
return <RawImage {...nativeProps} />;
|
||||
}
|
||||
});
|
||||
@@ -151,24 +180,39 @@ var styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
var CommonImageViewAttributes = merge(ReactIOSViewAttributes.UIView, {
|
||||
accessible: true,
|
||||
accessibilityLabel: true,
|
||||
capInsets: {diff: insetsDiffer}, // UIEdgeInsets=UIEdgeInsetsZero
|
||||
imageTag: true,
|
||||
resizeMode: true,
|
||||
if (Platform.OS === 'android') {
|
||||
var CommonImageViewAttributes = merge(ReactIOSViewAttributes.UIView, {
|
||||
accessible: true,
|
||||
accessibilityLabel: true,
|
||||
capInsets: {diff: insetsDiffer}, // UIEdgeInsets=UIEdgeInsetsZero
|
||||
imageTag: true,
|
||||
resizeMode: true,
|
||||
src: true,
|
||||
testID: PropTypes.string,
|
||||
});
|
||||
|
||||
var RCTStaticImage = createReactIOSNativeComponentClass({
|
||||
validAttributes: merge(CommonImageViewAttributes, { tintColor: true }),
|
||||
uiViewClassName: 'RCTStaticImage',
|
||||
});
|
||||
|
||||
var RCTNetworkImage = createReactIOSNativeComponentClass({
|
||||
validAttributes: merge(CommonImageViewAttributes, { defaultImageSrc: true }),
|
||||
uiViewClassName: 'RCTNetworkImageView',
|
||||
});
|
||||
} else {
|
||||
var RCTStaticImage = requireNativeComponent('RCTStaticImage', null);
|
||||
var RCTNetworkImage = requireNativeComponent('RCTNetworkImageView', null);
|
||||
}
|
||||
var nativeOnlyProps = {
|
||||
src: true,
|
||||
testID: PropTypes.string,
|
||||
});
|
||||
|
||||
var RCTStaticImage = createReactIOSNativeComponentClass({
|
||||
validAttributes: merge(CommonImageViewAttributes, { tintColor: true }),
|
||||
uiViewClassName: 'RCTStaticImage',
|
||||
});
|
||||
|
||||
var RCTNetworkImage = createReactIOSNativeComponentClass({
|
||||
validAttributes: merge(CommonImageViewAttributes, { defaultImageSrc: true }),
|
||||
uiViewClassName: 'RCTNetworkImageView',
|
||||
});
|
||||
defaultImageSrc: true,
|
||||
imageTag: true,
|
||||
contentMode: true,
|
||||
};
|
||||
if (__DEV__) {
|
||||
verifyPropTypes(Image, RCTStaticImage.viewConfig, nativeOnlyProps);
|
||||
verifyPropTypes(Image, RCTNetworkImage.viewConfig, nativeOnlyProps);
|
||||
}
|
||||
|
||||
module.exports = Image;
|
||||
|
||||
@@ -29,6 +29,6 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
RCT_REMAP_VIEW_PROPERTY(defaultImageSrc, defaultImage, UIImage)
|
||||
RCT_REMAP_VIEW_PROPERTY(src, imageURL, NSURL)
|
||||
RCT_REMAP_VIEW_PROPERTY(resizeMode, contentMode, UIViewContentMode)
|
||||
RCT_EXPORT_VIEW_PROPERTY(contentMode, UIViewContentMode)
|
||||
|
||||
@end
|
||||
|
||||
@@ -26,7 +26,7 @@ RCT_EXPORT_MODULE()
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(capInsets, UIEdgeInsets)
|
||||
RCT_REMAP_VIEW_PROPERTY(resizeMode, contentMode, UIViewContentMode)
|
||||
RCT_EXPORT_VIEW_PROPERTY(contentMode, UIViewContentMode)
|
||||
RCT_CUSTOM_VIEW_PROPERTY(src, NSURL, RCTStaticImage)
|
||||
{
|
||||
if (json) {
|
||||
|
||||
Reference in New Issue
Block a user