From c5ea25f7fb9cc162552c71c644d7bf8bd6954024 Mon Sep 17 00:00:00 2001 From: Alex Kotliarskyi Date: Wed, 22 Apr 2015 13:11:30 -0700 Subject: [PATCH] [ReactNative] Adopt client asset managing code to server changes --- Libraries/Image/Image.ios.js | 4 +- .../__tests__/resolveAssetSource-test.js | 67 +++++++++++++------ Libraries/Image/resolveAssetSource.js | 63 ++++++++++------- 3 files changed, 88 insertions(+), 46 deletions(-) diff --git a/Libraries/Image/Image.ios.js b/Libraries/Image/Image.ios.js index be95a3f3f..e917b6b63 100644 --- a/Libraries/Image/Image.ios.js +++ b/Libraries/Image/Image.ios.js @@ -123,15 +123,13 @@ var Image = React.createClass({ 'not be set directly on Image.'); } } - var source = this.props.source; + var source = resolveAssetSource(this.props.source); 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), diff --git a/Libraries/Image/__tests__/resolveAssetSource-test.js b/Libraries/Image/__tests__/resolveAssetSource-test.js index 69bcb116a..b385e29aa 100644 --- a/Libraries/Image/__tests__/resolveAssetSource-test.js +++ b/Libraries/Image/__tests__/resolveAssetSource-test.js @@ -13,6 +13,10 @@ jest.dontMock('../resolveAssetSource'); var resolveAssetSource; var SourceCode; +function expectResolvesAsset(input, expectedSource) { + expect(resolveAssetSource(input)).toEqual(expectedSource); +} + describe('resolveAssetSource', () => { beforeEach(() => { jest.resetModuleRegistry(); @@ -34,41 +38,66 @@ describe('resolveAssetSource', () => { }); it('uses network image', () => { - var source = { - path: '/Users/react/project/logo.png', - uri: 'assets/logo.png', - }; - expect(resolveAssetSource(source)).toEqual({ + expectResolvesAsset({ + __packager_asset: true, + fileSystemLocation: '/root/app/module/a', + httpServerLocation: '/assets/module/a', + width: 100, + height: 200, + scales: [1], + hash: '5b6f00f', + name: 'logo', + type: 'png', + }, { isStatic: false, - uri: 'http://10.0.0.1:8081/assets/logo.png', + width: 100, + height: 200, + uri: 'http://10.0.0.1:8081/assets/module/a/logo.png?hash=5b6f00f', }); }); it('does not change deprecated assets', () => { - // Deprecated require('image!logo') should stay unchanged - var source = { - path: '/Users/react/project/logo.png', - uri: 'logo', + expectResolvesAsset({ + __packager_asset: true, deprecated: true, - }; - expect(resolveAssetSource(source)).toEqual({ + fileSystemLocation: '/root/app/module/a', + httpServerLocation: '/assets/module/a', + width: 100, + height: 200, + scales: [1], + hash: '5b6f00f', + name: 'logo', + type: 'png', + }, { isStatic: true, + width: 100, + height: 200, uri: 'logo', }); }); }); describe('bundle was loaded from file', () => { - it('uses pre-packed image', () => { + beforeEach(() => { SourceCode.scriptURL = 'file:///Path/To/Simulator/main.bundle'; + }); - var source = { - path: '/Users/react/project/logo.png', - uri: 'assets/logo.png', - }; - expect(resolveAssetSource(source)).toEqual({ + it('uses pre-packed image', () => { + expectResolvesAsset({ + __packager_asset: true, + fileSystemLocation: '/root/app/module/a', + httpServerLocation: '/assets/module/a', + width: 100, + height: 200, + scales: [1], + hash: '5b6f00f', + name: 'logo', + type: 'png', + }, { isStatic: true, - uri: 'assets/logo.png', + width: 100, + height: 200, + uri: 'assets/module/a/logo.png', }); }); }); diff --git a/Libraries/Image/resolveAssetSource.js b/Libraries/Image/resolveAssetSource.js index 137f92f1c..2325e2c8c 100644 --- a/Libraries/Image/resolveAssetSource.js +++ b/Libraries/Image/resolveAssetSource.js @@ -17,9 +17,9 @@ var _serverURL; function getServerURL() { if (_serverURL === undefined) { var scriptURL = SourceCode.scriptURL; - var serverURLMatch = scriptURL && scriptURL.match(/^https?:\/\/.*?\//); - if (serverURLMatch) { - _serverURL = serverURLMatch[0]; + var match = scriptURL && scriptURL.match(/^https?:\/\/.*?\//); + if (match) { + _serverURL = match[0]; } else { _serverURL = null; } @@ -29,35 +29,50 @@ function getServerURL() { } // TODO(frantic): -// * Use something other than `path`/`isStatic` for asset identification, `__packager_asset`? -// * Add cache invalidating hashsum -// * Move code that selects scale to client +// * Pick best scale and append @Nx to file path +// * We are currently using httpServerLocation for both http and in-app bundle function resolveAssetSource(source) { + if (!source.__packager_asset) { + return source; + } + + // Deprecated assets are managed by Xcode for now, + // just returning image name as `uri` + // Examples: + // require('image!deprecatd_logo_example') + // require('./new-hotness-logo-example.png') if (source.deprecated) { return { - ...source, - path: undefined, + width: source.width, + height: source.height, isStatic: true, - deprecated: undefined, + uri: source.name || source.uri, // TODO(frantic): remove uri }; } + // TODO(frantic): currently httpServerLocation is used both as + // path in http URL and path within IPA. Should we have zipArchiveLocation? + var path = source.httpServerLocation; + if (path[0] === '/') { + path = path.substr(1); + } + 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, - }; - } + if (serverURL) { + return { + width: source.width, + height: source.height, + uri: serverURL + path + '/' + source.name + '.' + source.type + + '?hash=' + source.hash, + isStatic: false, + }; + } else { + return { + width: source.width, + height: source.height, + uri: path + '/' + source.name + '.' + source.type, + isStatic: true, + }; } return source;