mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-04-22 19:58:25 +08:00
[change] Image 'source' dimensions and RN layout
Adds support for 'width' and 'height' set via the 'source' property. Emulates RN image layout (i.e., no dimensions by default). Fix #10
This commit is contained in:
@@ -218,7 +218,7 @@ const examples = [
|
||||
render: function() {
|
||||
return (
|
||||
<Image
|
||||
source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}}
|
||||
source={{ uri: 'http://facebook.github.io/react/img/logo_og.png', width: 1200, height: 630 }}
|
||||
style={styles.base}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -34,8 +34,8 @@ suite('components/Image', () => {
|
||||
test('sets background image when value is an object', () => {
|
||||
const defaultSource = { uri: 'https://google.com/favicon.ico' };
|
||||
const image = shallow(<Image defaultSource={defaultSource} />);
|
||||
const backgroundImage = StyleSheet.flatten(image.prop('style')).backgroundImage;
|
||||
assert(backgroundImage.indexOf(defaultSource.uri) > -1);
|
||||
const style = StyleSheet.flatten(image.prop('style'));
|
||||
assert(style.backgroundImage.indexOf(defaultSource.uri) > -1);
|
||||
});
|
||||
|
||||
test('sets background image when value is a string', () => {
|
||||
@@ -45,13 +45,30 @@ suite('components/Image', () => {
|
||||
const backgroundImage = StyleSheet.flatten(image.prop('style')).backgroundImage;
|
||||
assert(backgroundImage.indexOf(defaultSource) > -1);
|
||||
});
|
||||
|
||||
test('sets "height" and "width" styles if missing', () => {
|
||||
const defaultSource = { uri: 'https://google.com/favicon.ico', height: 10, width: 20 };
|
||||
const image = mount(<Image defaultSource={defaultSource} />);
|
||||
const html = image.html();
|
||||
assert(html.indexOf('height: 10px') > -1);
|
||||
assert(html.indexOf('width: 20px') > -1);
|
||||
});
|
||||
|
||||
test('does not override "height" and "width" styles', () => {
|
||||
const defaultSource = { uri: 'https://google.com/favicon.ico', height: 10, width: 20 };
|
||||
const image = mount(<Image defaultSource={defaultSource} style={{ height: 20, width: 40 }} />);
|
||||
const html = image.html();
|
||||
assert(html.indexOf('height: 20px') > -1);
|
||||
assert(html.indexOf('width: 40px') > -1);
|
||||
});
|
||||
});
|
||||
|
||||
test('prop "onError"', function (done) {
|
||||
this.timeout(5000);
|
||||
mount(<Image onError={onError} source={{ uri: 'https://google.com/favicon.icox' }} />);
|
||||
const image = mount(<Image onError={onError} source={{ uri: 'https://google.com/favicon.icox' }} />);
|
||||
function onError(e) {
|
||||
assert.equal(e.nativeEvent.type, 'error');
|
||||
assert.ok(e.nativeEvent.error);
|
||||
image.unmount();
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -63,6 +80,7 @@ suite('components/Image', () => {
|
||||
assert.equal(e.nativeEvent.type, 'load');
|
||||
const hasBackgroundImage = (image.html()).indexOf('url("https://google.com/favicon.ico")') > -1;
|
||||
assert.equal(hasBackgroundImage, true);
|
||||
image.unmount();
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -74,6 +92,7 @@ suite('components/Image', () => {
|
||||
assert.ok(true);
|
||||
const hasBackgroundImage = (image.html()).indexOf('url("https://google.com/favicon.ico")') > -1;
|
||||
assert.equal(hasBackgroundImage, true);
|
||||
image.unmount();
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -121,10 +140,11 @@ suite('components/Image', () => {
|
||||
|
||||
test('sets background image when value is an object', (done) => {
|
||||
const source = { uri: 'https://google.com/favicon.ico' };
|
||||
mount(<Image onLoad={onLoad} source={source} />);
|
||||
const image = mount(<Image onLoad={onLoad} source={source} />);
|
||||
function onLoad(e) {
|
||||
const src = e.nativeEvent.target.src;
|
||||
assert.equal(src, source.uri);
|
||||
image.unmount();
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -132,10 +152,11 @@ suite('components/Image', () => {
|
||||
test('sets background image when value is a string', (done) => {
|
||||
// emulate require-ed asset
|
||||
const source = 'https://google.com/favicon.ico';
|
||||
mount(<Image onLoad={onLoad} source={source} />);
|
||||
const image = mount(<Image onLoad={onLoad} source={source} />);
|
||||
function onLoad(e) {
|
||||
const src = e.nativeEvent.target.src;
|
||||
assert.equal(src, source);
|
||||
image.unmount();
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -17,11 +17,20 @@ const STATUS_IDLE = 'IDLE';
|
||||
|
||||
const ImageSourcePropType = PropTypes.oneOfType([
|
||||
PropTypes.shape({
|
||||
uri: PropTypes.string.isRequired
|
||||
height: PropTypes.number,
|
||||
uri: PropTypes.string.isRequired,
|
||||
width: PropTypes.number
|
||||
}),
|
||||
PropTypes.string
|
||||
]);
|
||||
|
||||
const resolveAssetDimensions = (source) => {
|
||||
if (typeof source === 'object') {
|
||||
const { height, width } = source;
|
||||
return { height, width };
|
||||
}
|
||||
};
|
||||
|
||||
const resolveAssetSource = (source) => {
|
||||
return ((typeof source === 'object') ? source.uri : source) || null;
|
||||
};
|
||||
@@ -93,12 +102,15 @@ class Image extends Component {
|
||||
} = this.props;
|
||||
|
||||
const displayImage = resolveAssetSource(!isLoaded ? defaultSource : source);
|
||||
const imageSizeStyle = resolveAssetDimensions(!isLoaded ? defaultSource : source);
|
||||
const backgroundImage = displayImage ? `url("${displayImage}")` : null;
|
||||
const flatStyle = StyleSheet.flatten(this.props.style);
|
||||
const resizeMode = this.props.resizeMode || flatStyle.resizeMode || ImageResizeMode.cover;
|
||||
const originalStyle = StyleSheet.flatten(this.props.style);
|
||||
const resizeMode = this.props.resizeMode || originalStyle.resizeMode || ImageResizeMode.cover;
|
||||
|
||||
const style = StyleSheet.flatten([
|
||||
styles.initial,
|
||||
flatStyle,
|
||||
imageSizeStyle,
|
||||
originalStyle,
|
||||
backgroundImage && { backgroundImage },
|
||||
resizeModeStyles[resizeMode]
|
||||
]);
|
||||
@@ -147,14 +159,18 @@ class Image extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
_onError = (e) => {
|
||||
const { onError } = this.props;
|
||||
const event = { nativeEvent: e };
|
||||
|
||||
_onError = () => {
|
||||
const { onError, source } = this.props;
|
||||
this._destroyImageLoader();
|
||||
this._updateImageState(STATUS_ERRORED);
|
||||
this._onLoadEnd();
|
||||
if (onError) { onError(event); }
|
||||
this._updateImageState(STATUS_ERRORED);
|
||||
if (onError) {
|
||||
onError({
|
||||
nativeEvent: {
|
||||
error: `Failed to load resource ${resolveAssetSource(source)} (404)`
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_onLoad = (e) => {
|
||||
@@ -189,7 +205,6 @@ class Image extends Component {
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
initial: {
|
||||
alignSelf: 'flex-start',
|
||||
backgroundColor: 'transparent',
|
||||
backgroundPosition: 'center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
|
||||
Reference in New Issue
Block a user