Skip to content

Commit 7483e8b

Browse files
author
Amir Tocker
committed
Replace getOptions with normalizedOptions. Refactor Transformation to inherit CloudinaryComponent.
1 parent 1e13c4d commit 7483e8b

File tree

5 files changed

+91
-45
lines changed

5 files changed

+91
-45
lines changed

src/components/CloudinaryComponent/CloudinaryComponent.js

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -40,50 +40,53 @@ export default class CloudinaryComponent extends Component {
4040
}
4141

4242
getChildTransformations(children) {
43-
return React.Children.map(children, child =>
44-
CloudinaryComponent.getOptions(child.props, child.context) // TODO change to getTransformation()
45-
);
43+
return React.Children.map(children, child =>{
44+
let options = CloudinaryComponent.normalizeOptions(child.props, child.context);
45+
let childOptions = this.getChildTransformations(child.props.children);
46+
if(childOptions !== undefined && childOptions !== null){
47+
options.transformation = childOptions;
48+
}
49+
return options;
50+
});
4651
}
4752

48-
getTransformation() {
49-
let options = CloudinaryComponent.getOptions(this.props, this.context);
50-
let childrenOptions = this.getChildTransformations(this.props.children);
51-
if (!Util.isEmpty(childrenOptions)) {
52-
options.transformation = childrenOptions;
53+
getTransformation(props = this.props , context = this.context) {
54+
let options = CloudinaryComponent.normalizeOptions(context, props );
55+
if(this.props.children !== undefined){
56+
let childrenOptions = this.getChildTransformations(this.props.children);
57+
if (!Util.isEmpty(childrenOptions)) {
58+
options.transformation = childrenOptions;
59+
}
5360
}
5461
return options;
5562
}
5663

5764
/**
58-
* Combine props and context to create an option Object that can be passed to Cloudinary methods.<br>
59-
* All names are converted to snake_case.
60-
* @param props
61-
* @param context
62-
* @returns {{}}
65+
* Combine properties of all options to create an option Object that can be passed to Cloudinary methods.<br>
66+
* All names are converted to snake_case. undefined and null values are filtered out.
67+
* @returns {Object}
68+
* @param options one or more options objects
6369
*/
64-
static getOptions(props, context) {
65-
var options = {};
66-
67-
for (let key in context) {
68-
let value = context[key];
69-
if (value !== null && value !== undefined) {
70-
options[snakeCase(key)] = value;
70+
static normalizeOptions(...options) {
71+
var result = {};
72+
return options.reduce((left, right)=> {
73+
for (let key in right) {
74+
let value = right[key];
75+
if (value !== null && value !== undefined) {
76+
left[snakeCase(key)] = value;
77+
}
78+
}
79+
return left;
7180
}
72-
}
73-
for (let key in props) {
74-
let value = props[key];
75-
if (value !== null && value !== undefined) {
76-
options[snakeCase(key)] = value;
77-
}
78-
}
79-
return options;
81+
, {});
8082
}
8183

82-
getUrl(props, context = {}) {
83-
let options = this.getTransformation();
84+
getUrl(props = this.props , context = this.context) {
85+
let options = CloudinaryComponent.normalizeOptions(context, props);
86+
let transformation = this.getTransformation(props, context);
8487
let cl = Cloudinary.new(options);
85-
this.getChildTransformations(props.children);
86-
return cl.url(props.publicId, options);
88+
console.log("options: ", options, "transformation:", transformation);
89+
return cl.url(props.publicId, transformation);
8790
}
8891

8992
}
@@ -96,7 +99,7 @@ CloudinaryComponent.propTypes.publicId = PropTypes.string;
9699
CloudinaryComponent.childContextTypes = {};
97100

98101
/**
99-
* Create a React type definition object. All items are PropTypes.string.
102+
* Create a React type definition object. All items are PropTypes.string or [string] or object or [object].
100103
* @param {Array} configParams a list of parameter names
101104
* @returns {Object}
102105
*/

src/components/Image/Image.js

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,37 @@
11
import React, {Component, PropTypes} from 'react';
2-
import cloudinary from 'cloudinary-core';
2+
import cloudinary, {Util} from 'cloudinary-core';
33
import CloudinaryComponent from '../CloudinaryComponent';
44

55
export default class Image extends CloudinaryComponent {
66
constructor(props, context) {
77
super(props, context);
88
let url = this.getUrl(props, context);
9+
this.handleResize = this.handleResize.bind(this);
910
this.state = {url};
1011
}
1112

1213
componentWillReceiveProps(nextProps, nextContext) {
1314
let url = this.getUrl(nextProps, nextContext);
1415
if(url !== this.state.url){
15-
this.setState({url});
16+
console.log("setting url ", url);
17+
this.setState({url, width: 0});
1618
}
1719
}
1820

1921
componentWillMount() {
22+
window.addEventListener('resize', this.handleResize);
2023
}
2124

2225
componentDidMount() {
2326
}
2427

2528
componentWillUnmount() {
29+
window.removeEventListener('resize', this.handleResize);
30+
2631
}
2732

2833
componentWillUpdate(nextProps, nextState, nextContext) {
34+
2935
}
3036

3137
componentDidUpdate(prevProps, prevState, prevContext) {
@@ -35,11 +41,46 @@ export default class Image extends CloudinaryComponent {
3541
return true;
3642
}
3743

44+
getUrl(props, context, width){
45+
console.log("getUrl", this);
46+
width = width || (this.state ? this.state.width: undefined);
47+
console.log("width is ", width);
48+
if(width){
49+
console.log("Width is ", width);
50+
props = Object.assign({width}, props);
51+
}
52+
console.log(props);
53+
return super.getUrl(props, context);
54+
55+
}
56+
handleResize(e){
57+
const width = this.findContainerWidth(this.element);
58+
if(!width) {
59+
return;
60+
}
61+
let partialState = {width, url: this.getUrl(this.props, this.context, width)};
62+
this.setState(partialState);
63+
}
64+
65+
findContainerWidth(element) {
66+
console.log("findContainerWidth");
67+
var containerWidth, style;
68+
containerWidth = 0;
69+
while (((element = element != null ? element.parentNode : void 0) instanceof Element) && !containerWidth) {
70+
style = window.getComputedStyle(element);
71+
if (!/^inline/.test(style.display)) {
72+
containerWidth = Util.width(element);
73+
}
74+
}
75+
return containerWidth;
76+
};
77+
3878
render() {
39-
var {public_id, children, ...options} = CloudinaryComponent.getOptions(this.props, this.context);
79+
var {public_id, children, ...options} = CloudinaryComponent.normalizeOptions(this.props, this.context);
80+
console.log("render image", this.state.url, this.state.width);
4081
var attributes = cloudinary.Transformation.new(options).toHtmlAttributes();
4182
return (
42-
<img {...attributes} src={this.state.url} />
83+
<img {...attributes} src={this.state.url} ref={(e)=>{this.element = e;}}/>
4384
);
4485
}
4586
}

src/components/Transformation/Transformation.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, {Component} from 'react';
22
import CloudinaryComponent from '../CloudinaryComponent';
33

4-
export default class Transformation extends Component {
4+
export default class Transformation extends CloudinaryComponent {
55
constructor(props) {
66
super(props);
77
}

src/components/Video/Video.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default class Video extends CloudinaryComponent {
4141
this.props);
4242
sourceTransformation = sourceTransformation || {};
4343
sourceTypes = sourceTypes || Cloudinary.DEFAULT_VIDEO_PARAMS.source_types;
44-
options = CloudinaryComponent.getOptions(options, {});
44+
options = CloudinaryComponent.normalizeOptions(options, {});
4545
let cld = Cloudinary.new(options);
4646
let sources = [];
4747
let tagAttributes = Transformation.new(options).toHtmlAttributes();

stories/index.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ import CloudinaryContext from '../src/components/CloudinaryContext';
77
import cloudinary from 'cloudinary-core';
88

99
storiesOf('Image', module).addWithInfo('image', "Basic tag", ()=> {
10-
let t = {width: 0.5, crop: "scale"};
10+
// let t = {width: 0.5, crop: "scale"};
11+
let t = {crop: "scale"};
1112
return (
12-
<Image cloudName="demo" publicId="sample" transformation={t}/>
13+
<Image cloudName="demo" publicId="sample" crop="scale"/>
1314
)
1415
}
1516
).addWithInfo('image with alt', "Demostrate using an img tag attribute", ()=> {
@@ -39,14 +40,15 @@ storiesOf('Image', module).addWithInfo('image', "Basic tag", ()=> {
3940
</div>
4041
)
4142
}
42-
).addWithInfo('image with chained transformation', 'image with chained transformation', ()=> {
43+
).addWithInfo('image with nested chained transformation', 'image with chained transformation', ()=> {
4344
let t = {width: 0.5, crop: "scale"};
4445
return (
4546
<div>
4647
<Image cloudName="demo" publicId="sample">
47-
<Transformation width="200" crop="scale" angle="10"/>
48-
<Transformation width="100" crop="crop"/>
49-
<Transformation width="100" crop="scale" angle="-10"/>
48+
<Transformation angle="-45"/>
49+
<Transformation effect="trim" angle="45" crop="scale" width="600">
50+
<Transformation overlay="text:Arial_100:Hello" />
51+
</Transformation>
5052
</Image>
5153
<Image cloudName="demo" publicId="sample" width="100" crop="scale"/>
5254
</div>

0 commit comments

Comments
 (0)