-
Notifications
You must be signed in to change notification settings - Fork 47
/
index.coffee
78 lines (70 loc) · 2.18 KB
/
index.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
React = require 'react'
merge = require 'xtend'
ReactLoaderMixin = require 'react-loadermixin'
{PropTypes} = React
{span, img} = React.DOM
Status =
PENDING: 'pending'
LOADING: 'loading'
LOADED: 'loaded'
FAILED: 'failed'
hasSize = (i) ->
(i.naturalWidth + i.naturalHeight is 0) or (i.width + i.height is 0)
ImageLoaderImg = React.createClass
displayName: 'ImageLoaderImage'
handleLoad: (args...) ->
return unless @isMounted()
image = @refs.image
if 'naturalWidth' of image and not hasSize image
@handleError new Error "Image <#{image.src}> could not be loaded."
else @props.onLoad? args...
handleError: (args...) ->
@props.onError? args...
render: ->
@transferPropsTo (img
ref: 'image'
onLoad: @handleLoad
onError: @handleError
)
module.exports = ImageLoader = React.createClass
displayName: 'ImageLoader'
mixins: [ReactLoaderMixin]
propTypes:
wrapper: PropTypes.func
preloader: PropTypes.func
getInitialState: ->
status: Status.PENDING
getDefaultProps: ->
wrapper: span
loader: ImageLoaderImg
componentWillReceiveProps: (nextProps) ->
if @props.src isnt nextProps.src
@setState
status: if nextProps.src then Status.LOADING else Status.PENDING
getClassName: ->
className = "imageloader #{ @state.status }"
className += " #{ @props.className }" if @props.className
className
getImgProps: ->
# TODO: Should we strip props that are specific to ImageLoader/LoaderMixin?
merge @props,
style: merge @props.style,
display: if @state.status is Status.LOADED then null else 'none'
loaderDidLoad: ->
@setState status: Status.LOADED
loaderDidError: ->
@setState status: Status.FAILED
renderChildren: ->
if Array.isArray @props.children then @props.children[..]
else [@props.children]
render: ->
children = []
if @props.src
children.push @renderLoader ImageLoaderImg, @getImgProps()
if @props.preloader and @state.status isnt Status.LOADED
children.push new @props.preloader
if @state.status is Status.FAILED
children = children.concat @renderChildren()
@props.wrapper
className: @getClassName()
children