1- import React , { Component } from 'react' ;
1+ import React from 'react' ;
22import cloudinary , { Util } from 'cloudinary-core' ;
33import CloudinaryComponent from '../CloudinaryComponent' ;
44import { debounce , firstDefined , closestAbove , requestAnimationFrame , isElement } from '../../Util' ;
55
6+ const defaultBreakpoints = ( width , steps = 100 ) => {
7+ return steps * Math . ceil ( width / steps ) ;
8+ } ;
9+
610/**
711 * A component representing a Cloudinary served image
812 */
913class Image extends CloudinaryComponent {
1014 constructor ( props , context ) {
11- function defaultBreakpoints ( width , steps = 100 ) {
12- return steps * Math . ceil ( width / steps ) ;
13- }
14-
1515 super ( props , context ) ;
1616 this . handleResize = this . handleResize . bind ( this ) ;
1717
18+ this . state = { } ;
19+
1820 let state = { responsive : false , url : undefined , breakpoints : defaultBreakpoints } ;
1921 this . state = Object . assign ( state , this . prepareState ( props , context ) ) ;
2022 }
@@ -26,7 +28,7 @@ class Image extends CloudinaryComponent {
2628 */
2729 get window ( ) {
2830 let windowRef = null ;
29- if ( typeof window !== "undefined" ) {
31+ if ( typeof window !== "undefined" ) {
3032 windowRef = window
3133 }
3234 return ( this . element && this . element . ownerDocument ) ? ( this . element . ownerDocument . defaultView || windowRef ) : windowRef ;
@@ -37,38 +39,39 @@ class Image extends CloudinaryComponent {
3739 this . setState ( state ) ;
3840 }
3941
40- /**
41- * Generate update state of this element
42- * @param {Object } [props=this.props]
43- * @param {Object } [context=this.context]
44- * @returns {Object } state updates
45- * @private
46- */
4742 prepareState ( props = this . props , context = this . context ) {
4843 let extendedProps = CloudinaryComponent . normalizeOptions ( context , props ) ;
4944 let url = this . getUrl ( extendedProps ) ;
5045 let state = { } ;
46+ let updatedOptions = { } ;
47+
5148 if ( extendedProps . breakpoints !== undefined ) {
5249 state . breakpoints = extendedProps . breakpoints ;
5350 }
5451 if ( extendedProps . responsive ) {
5552 state . responsive = true ;
56- url = this . cloudinary_update ( url , state ) ;
53+ updatedOptions = this . cloudinaryUpdate ( url , state ) ;
54+ url = updatedOptions . url ;
5755 }
5856
5957 let currentState = this . state || { } ;
58+
59+ state . width = updatedOptions . width ;
60+
6061 if ( ! Util . isEmpty ( url ) && url !== currentState . url ) {
6162 state . url = url ;
6263 }
64+
65+
6366 return state ;
6467 }
6568
66- handleResize ( e ) {
69+ handleResize ( ) {
6770 if ( ! this . props . responsive || this . rqf ) return ;
6871 this . rqf = requestAnimationFrame ( ( ) => {
6972 this . rqf = null ;
7073 let newState = this . prepareState ( ) ;
71- if ( ! Util . isEmpty ( newState . url ) ) {
74+ if ( ! Util . isEmpty ( newState . url ) ) {
7275 this . setState ( newState ) ;
7376 }
7477 } ) ;
@@ -124,10 +127,9 @@ class Image extends CloudinaryComponent {
124127 } ;
125128
126129 applyBreakpoints ( width , steps , options ) {
127- var responsive_use_breakpoints ;
128130 options = CloudinaryComponent . normalizeOptions ( this . context , this . props , options ) ;
129- responsive_use_breakpoints = options . responsive_use_breakpoints ;
130- if ( ( ! responsive_use_breakpoints ) || ( responsive_use_breakpoints === 'resize' && ! options . resizing ) ) {
131+ let responsiveUseBreakpoints = options . responsiveUseBreakpoints ;
132+ if ( ( ! responsiveUseBreakpoints ) || ( responsiveUseBreakpoints === 'resize' && ! options . resizing ) ) {
131133 return width ;
132134 } else {
133135 return this . calc_breakpoint ( width , steps ) ;
@@ -136,7 +138,7 @@ class Image extends CloudinaryComponent {
136138
137139 calc_breakpoint ( width , steps ) {
138140 var breakpoints , point ;
139- breakpoints = this . state . breakpoints || defaultBreakpoints ;
141+ breakpoints = ( this . state && this . state . breakpoints ) || defaultBreakpoints ;
140142 if ( Util . isFunction ( breakpoints ) ) {
141143 return breakpoints ( width , steps ) ;
142144 } else {
@@ -179,16 +181,10 @@ class Image extends CloudinaryComponent {
179181 } ;
180182
181183 maxWidth ( requiredWidth ) {
182- var imageWidth ;
183- imageWidth = this . state . width || 0 ;
184- if ( requiredWidth > imageWidth ) {
185- imageWidth = requiredWidth ;
186- this . setState ( { width : requiredWidth } ) ;
187- }
188- return imageWidth ;
184+ return Math . max ( ( this . state && this . state . width ) || 0 , requiredWidth ) ;
189185 } ;
190186
191- cloudinary_update ( url , options = { } ) {
187+ cloudinaryUpdate ( url , options = { } ) {
192188 var requiredWidth ;
193189 var match ;
194190 let resultUrl = this . updateDpr ( url , options . roundDpr ) ;
@@ -199,16 +195,19 @@ class Image extends CloudinaryComponent {
199195 requiredWidth = this . maxWidth ( containerWidth , this . element ) ;
200196 resultUrl = resultUrl . replace ( / w _ a u t o : b r e a k p o i n t s ( [ _ 0 - 9 ] * ) ( : [ 0 - 9 ] + ) ? / ,
201197 "w_auto:breakpoints$1:" + requiredWidth ) ;
202- } else if ( match = / w _ a u t o ( : ( \d + ) ) ? / . exec ( resultUrl ) ) {
203- requiredWidth = this . applyBreakpoints ( containerWidth , match [ 2 ] , options ) ;
204- requiredWidth = this . maxWidth ( requiredWidth , this . element ) ;
205- resultUrl = resultUrl . replace ( / w _ a u t o [ ^ , \/ ] * / g, "w_" + requiredWidth ) ;
198+ } else {
199+ match = / w _ a u t o ( : ( \d + ) ) ? / . exec ( resultUrl ) ;
200+ if ( match ) {
201+ requiredWidth = this . applyBreakpoints ( containerWidth , match [ 2 ] , options ) ;
202+ requiredWidth = this . maxWidth ( requiredWidth , this . element ) ;
203+ resultUrl = resultUrl . replace ( / w _ a u t o [ ^ , \/ ] * / g, "w_" + requiredWidth ) ;
204+ }
206205 }
207206 } else {
208207 resultUrl = "" ;
209208 }
210209 }
211- return resultUrl ;
210+ return { url : resultUrl , width : requiredWidth } ;
212211 }
213212}
214213
0 commit comments