Skip to content

Commit

Permalink
[ReactNative] Use network image for new image assets
Browse files Browse the repository at this point in the history
  • Loading branch information
frantic committed Apr 21, 2015
1 parent c0c2d4c commit c6ad7b8
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 7 deletions.
20 changes: 13 additions & 7 deletions Libraries/Image/Image.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
'use strict';

var EdgeInsetsPropType = require('EdgeInsetsPropType');
var ImageResizeMode = require('ImageResizeMode');
var ImageStylePropTypes = require('ImageStylePropTypes');
var NativeMethodsMixin = require('NativeMethodsMixin');
var NativeModules = require('NativeModules');
var PropTypes = require('ReactPropTypes');
var ImageResizeMode = require('ImageResizeMode');
var ImageStylePropTypes = require('ImageStylePropTypes');
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var StyleSheet = require('StyleSheet');
Expand All @@ -26,8 +26,9 @@ var flattenStyle = require('flattenStyle');
var invariant = require('invariant');
var merge = require('merge');
var requireNativeComponent = require('requireNativeComponent');
var warning = require('warning');
var resolveAssetSource = require('resolveAssetSource');
var verifyPropTypes = require('verifyPropTypes');
var warning = require('warning');

/**
* A react component for displaying different types of images,
Expand Down Expand Up @@ -122,10 +123,15 @@ var Image = React.createClass({
'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;
invariant(source, "source must be initialized");
invariant(source, 'source must be initialized');

var {width, height} = source;
var style = flattenStyle([{width, height}, styles.base, this.props.style]);
invariant(style, 'style must be initialized');

source = resolveAssetSource(source);

var isNetwork = source.uri && source.uri.match(/^https?:/);
invariant(
!(isNetwork && source.isStatic),
Expand Down Expand Up @@ -171,8 +177,8 @@ var styles = StyleSheet.create({
},
});

var RCTStaticImage = requireNativeComponent('RCTStaticImage', null);
var RCTNetworkImage = requireNativeComponent('RCTNetworkImageView', null);
var RCTStaticImage = requireNativeComponent('RCTStaticImage', null);

var nativeOnlyProps = {
src: true,
Expand Down
76 changes: 76 additions & 0 deletions Libraries/Image/__tests__/resolveAssetSource-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';

jest.dontMock('../resolveAssetSource');

var resolveAssetSource;
var SourceCode;

describe('resolveAssetSource', () => {
beforeEach(() => {
jest.resetModuleRegistry();
SourceCode = require('NativeModules').SourceCode;
resolveAssetSource = require('../resolveAssetSource');
});

it('returns same source for simple static and network images', () => {
var source1 = {uri: 'https://www.facebook.com/logo'};
expect(resolveAssetSource(source1)).toBe(source1);

var source2 = {isStatic: true, uri: 'logo'};
expect(resolveAssetSource(source2)).toBe(source2);
});

describe('bundle was loaded from network', () => {
beforeEach(() => {
SourceCode.scriptURL = 'http://10.0.0.1:8081/main.bundle';
});

it('uses network image', () => {
var source = {
path: '/Users/react/project/logo.png',
uri: 'assets/logo.png',
};
expect(resolveAssetSource(source)).toEqual({
isStatic: false,
uri: 'http://10.0.0.1:8081/assets/logo.png',
});
});

it('does not change deprecated assets', () => {
// Deprecated require('image!logo') should stay unchanged
var source = {
path: '/Users/react/project/logo.png',
uri: 'logo',
deprecated: true,
};
expect(resolveAssetSource(source)).toEqual({
isStatic: true,
uri: 'logo',
});
});
});

describe('bundle was loaded from file', () => {
it('uses pre-packed image', () => {
SourceCode.scriptURL = 'file:///Path/To/Simulator/main.bundle';

var source = {
path: '/Users/react/project/logo.png',
uri: 'assets/logo.png',
};
expect(resolveAssetSource(source)).toEqual({
isStatic: true,
uri: 'assets/logo.png',
});
});
});

});
66 changes: 66 additions & 0 deletions Libraries/Image/resolveAssetSource.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule resolveAssetSource
*/
'use strict';

var SourceCode = require('NativeModules').SourceCode;

var _serverURL;

function getServerURL() {
if (_serverURL === undefined) {
var scriptURL = SourceCode.scriptURL;
var serverURLMatch = scriptURL && scriptURL.match(/^https?:\/\/.*?\//);
if (serverURLMatch) {
_serverURL = serverURLMatch[0];
} else {
_serverURL = null;
}
}

return _serverURL;
}

// TODO(frantic):
// * Use something other than `path`/`isStatic` for asset identification, `__packager_asset`?
// * Add cache invalidating hashsum
// * Move code that selects scale to client
function resolveAssetSource(source) {
if (source.deprecated) {
return {
...source,
path: undefined,
isStatic: true,
deprecated: undefined,
};
}

var serverURL = getServerURL();
if (source.path) {
if (serverURL) {
return {
...source,
path: undefined,
uri: serverURL + source.uri,
isStatic: false,
};
} else {
return {
...source,
path: undefined,
isStatic: true,
};
}
}

return source;
}

module.exports = resolveAssetSource;

0 comments on commit c6ad7b8

Please sign in to comment.