11
11
import applyNativeMethods from '../../modules/applyNativeMethods' ;
12
12
import createElement from '../createElement' ;
13
13
import css from '../StyleSheet/css' ;
14
- import { getAssetByID } from '../../modules/AssetRegistry' ;
15
14
import resolveShadowValue from '../StyleSheet/resolveShadowValue' ;
16
15
import ImageLoader from '../../modules/ImageLoader' ;
17
16
import ImageResizeMode from './ImageResizeMode' ;
@@ -33,8 +32,8 @@ const STATUS_LOADING = 'LOADING';
33
32
const STATUS_PENDING = 'PENDING' ;
34
33
const STATUS_IDLE = 'IDLE' ;
35
34
36
- const getImageState = ( uri , shouldDisplaySource ) => {
37
- return shouldDisplaySource ? STATUS_LOADED : uri ? STATUS_PENDING : STATUS_IDLE ;
35
+ const getImageState = ( source , shouldDisplaySource ) => {
36
+ return shouldDisplaySource ? STATUS_LOADED : source ? STATUS_PENDING : STATUS_IDLE ;
38
37
} ;
39
38
40
39
const resolveAssetDimensions = source => {
@@ -44,51 +43,17 @@ const resolveAssetDimensions = source => {
44
43
} ;
45
44
} ;
46
45
47
- const svgDataUriPattern = / ^ ( d a t a : i m a g e \/ s v g \+ x m l ; u t f 8 , ) ( .* ) / ;
48
- const resolveAssetSource = source => {
49
- let resolvedSource = {
50
- method : 'GET' ,
51
- uri : '' ,
52
- headers : { } ,
53
- width : undefined ,
54
- height : undefined
55
- } ;
56
- if ( typeof source === 'number' ) {
57
- // get the URI from the packager
58
- const asset = getAssetByID ( source ) ;
59
- const scale = asset . scales [ 0 ] ;
60
- const scaleSuffix = scale !== 1 ? `@${ scale } x` : '' ;
61
- resolvedSource . uri = asset
62
- ? `${ asset . httpServerLocation } /${ asset . name } ${ scaleSuffix } .${ asset . type } `
63
- : '' ;
64
- resolvedSource . width = asset . width ;
65
- resolvedSource . height = asset . height ;
66
- } else if ( typeof source === 'string' ) {
67
- resolvedSource . uri = source ;
68
- } else if ( typeof source === 'object' ) {
69
- resolvedSource = {
70
- ...resolvedSource ,
71
- ...source
72
- } ;
46
+ const getCacheUrl = e => {
47
+ if ( e . target ) {
48
+ return e . target . src ;
73
49
}
74
50
75
- if ( resolvedSource . uri ) {
76
- const match = resolvedSource . uri . match ( svgDataUriPattern ) ;
77
- // inline SVG markup may contain characters (e.g., #, ") that need to be escaped
78
- if ( match ) {
79
- const [ , prefix , svg ] = match ;
80
- const encodedSvg = encodeURIComponent ( svg ) ;
81
- resolvedSource . uri = `${ prefix } ${ encodedSvg } ` ;
82
- }
51
+ // Target is not defined at this moment anymore in Chrome and thus we use path
52
+ if ( e . path && e . path [ 0 ] ) {
53
+ return e . path [ 0 ] . src ;
83
54
}
84
55
85
- return resolvedSource ;
86
- } ;
87
- const getCacheId = source => {
88
- return JSON . stringify ( resolveAssetSource ( source ) ) ;
89
- } ;
90
- const getCacheUrl = e => {
91
- return e . path && e . path [ 0 ] . src ;
56
+ return undefined ;
92
57
} ;
93
58
94
59
let filterId = 0 ;
@@ -174,19 +139,18 @@ class Image extends Component<*, State> {
174
139
constructor ( props , context ) {
175
140
super ( props , context ) ;
176
141
// If an image has been loaded before, render it immediately
177
- const cacheId = getCacheId ( props . source ) ;
178
- const resolvedSource = resolveAssetSource ( props . source ) ;
179
- const resolvedDefaultSource = resolveAssetSource ( props . defaultSource ) ;
180
- const cachedSource = ImageUriCache . get ( cacheId ) ;
142
+ const resolvedSource = ImageLoader . resolveSource ( props . source ) ;
143
+ const resolvedDefaultSource = ImageLoader . resolveSource ( props . defaultSource ) ;
144
+ const cachedSource = ImageUriCache . get ( props . source ) ;
181
145
const shouldDisplaySource = ! ! cachedSource ;
182
146
this . state = {
183
147
layout : { } ,
184
148
shouldDisplaySource,
185
149
displayImageUri : shouldDisplaySource
186
- ? cachedSource . uri
150
+ ? cachedSource . displayImageUri
187
151
: resolvedDefaultSource . uri || resolvedSource . uri
188
152
} ;
189
- this . _imageState = getImageState ( resolvedSource . uri , shouldDisplaySource ) ;
153
+ this . _imageState = getImageState ( props . source , shouldDisplaySource ) ;
190
154
this . _filterId = filterId ;
191
155
filterId ++ ;
192
156
}
@@ -201,15 +165,16 @@ class Image extends Component<*, State> {
201
165
}
202
166
203
167
componentDidUpdate ( prevProps ) {
204
- const prevCacheId = getCacheId ( prevProps . source ) ;
205
- const cacheId = getCacheId ( this . props . source ) ;
206
- const hasDefaultSource = this . props . defaultSource != null ;
168
+ const { defaultSource, source } = this . props ;
169
+ const prevCacheId = ImageUriCache . createCacheId ( prevProps . source ) ;
170
+ const cacheId = ImageUriCache . createCacheId ( source ) ;
171
+ const hasDefaultSource = defaultSource != null ;
207
172
if ( prevCacheId !== cacheId ) {
208
- ImageUriCache . remove ( prevCacheId ) ;
209
- const isPreviouslyLoaded = ImageUriCache . has ( cacheId ) ;
210
- isPreviouslyLoaded && ImageUriCache . add ( cacheId ) ;
211
- this . _updateImageState ( getImageState ( cacheId , isPreviouslyLoaded ) , hasDefaultSource ) ;
212
- } else if ( hasDefaultSource && prevProps . defaultSource !== this . props . defaultSource ) {
173
+ ImageUriCache . remove ( prevProps . source ) ;
174
+ const shouldDisplaySource = ImageUriCache . has ( source ) ;
175
+ shouldDisplaySource && ImageUriCache . add ( source ) ;
176
+ this . _updateImageState ( getImageState ( source , shouldDisplaySource ) , hasDefaultSource ) ;
177
+ } else if ( hasDefaultSource && prevProps . defaultSource !== defaultSource ) {
213
178
this . _updateImageState ( this . _imageState , hasDefaultSource ) ;
214
179
}
215
180
if ( this . _imageState === STATUS_PENDING ) {
@@ -218,8 +183,7 @@ class Image extends Component<*, State> {
218
183
}
219
184
220
185
componentWillUnmount ( ) {
221
- const cacheId = getCacheId ( this . props . source ) ;
222
- ImageUriCache . remove ( cacheId ) ;
186
+ ImageUriCache . remove ( this . props . source ) ;
223
187
this . _destroyImageLoader ( ) ;
224
188
this . _isMounted = false ;
225
189
}
@@ -259,7 +223,7 @@ class Image extends Component<*, State> {
259
223
}
260
224
}
261
225
262
- const selectedSource = resolveAssetSource ( shouldDisplaySource ? source : defaultSource ) ;
226
+ const selectedSource = ImageLoader . resolveSource ( shouldDisplaySource ? source : defaultSource ) ;
263
227
const imageSizeStyle = resolveAssetDimensions ( selectedSource ) ;
264
228
const backgroundImage = displayImageUri ? `url("${ displayImageUri } ")` : null ;
265
229
const flatStyle = { ...StyleSheet . flatten ( this . props . style ) } ;
@@ -338,7 +302,7 @@ class Image extends Component<*, State> {
338
302
const { source } = this . props ;
339
303
this . _destroyImageLoader ( ) ;
340
304
this . _imageRequestId = ImageLoader . load (
341
- resolveAssetSource ( source ) ,
305
+ ImageLoader . resolveSource ( source ) ,
342
306
this . _onLoad ,
343
307
this . _onError
344
308
) ;
@@ -384,7 +348,7 @@ class Image extends Component<*, State> {
384
348
if ( onError ) {
385
349
onError ( {
386
350
nativeEvent : {
387
- error : `Failed to load resource ${ resolveAssetSource ( source ) . uri } (404)`
351
+ error : `Failed to load resource ${ ImageLoader . resolveSource ( source ) . uri } (404)`
388
352
}
389
353
} ) ;
390
354
}
@@ -394,7 +358,8 @@ class Image extends Component<*, State> {
394
358
_onLoad = e => {
395
359
const { onLoad, source } = this . props ;
396
360
const event = { nativeEvent : e } ;
397
- ImageUriCache . add ( getCacheId ( source ) , getCacheUrl ( e ) ) ;
361
+
362
+ ImageUriCache . add ( source , getCacheUrl ( e ) ) ;
398
363
this . _updateImageState ( STATUS_LOADED ) ;
399
364
if ( onLoad ) {
400
365
onLoad ( event ) ;
@@ -422,15 +387,18 @@ class Image extends Component<*, State> {
422
387
} ;
423
388
424
389
_updateImageState ( status : ?string , hasDefaultSource : ?boolean = false ) {
425
- const { source } = this . props ;
390
+ const { source, defaultSource } = this . props ;
391
+ const resolvedSource = ImageLoader . resolveSource ( defaultSource ) ;
392
+ const resolvedDefaultSource = ImageLoader . resolveSource ( source ) ;
426
393
this . _imageState = status ;
427
394
const shouldDisplaySource =
428
395
this . _imageState === STATUS_LOADED ||
429
396
( this . _imageState === STATUS_LOADING && ! hasDefaultSource ) ;
430
- const cachedId = getCacheId ( source ) ;
431
- const { displayImageUri } = ImageUriCache . has ( cachedId )
432
- ? ImageUriCache . get ( cachedId )
433
- : this . state ;
397
+ const { displayImageUri } = ImageUriCache . has ( source )
398
+ ? ImageUriCache . get ( source )
399
+ : {
400
+ displayImageUri : resolvedSource . uri || resolvedDefaultSource . uri
401
+ } ;
434
402
435
403
// only triggers a re-render when the image is loading and has no default image (to support PJPEG), loaded, or failed
436
404
if (
0 commit comments