cloudinary 1.1.3 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/lib/cloudinary/utils.rb +38 -3
- data/lib/cloudinary/version.rb +1 -1
- data/spec/utils_spec.rb +71 -7
- data/vendor/assets/javascripts/cloudinary/jquery.cloudinary.js +28 -25
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40c8821125bf4aa673a4e681867b3544f6a07b8f
|
4
|
+
data.tar.gz: 8093407d979244579abefcdff28b689a1ede0911
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b99e1b9657ce647e83af64300d134da80fe46e8cf22f0e379b966b7d548f2a004c659ebce923805aeedcdb32031d131e06bcffc8db7c1003546cafd02d8b647
|
7
|
+
data.tar.gz: 494b6a5c1934cd0074047c37f6d9ee1e4506c08f97d9db02706b71dee4a970c23c710bf91f43a1b67509793a7a7780597cf8f01a80f3bde7b9f5e1699caae0ce
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,17 @@
|
|
1
1
|
|
2
|
+
1.1.4 / 2016-03-22
|
3
|
+
==================
|
4
|
+
|
5
|
+
New functionality and features
|
6
|
+
------------------------------
|
7
|
+
|
8
|
+
* Add conditional transformation
|
9
|
+
|
10
|
+
Other Changes
|
11
|
+
-------------
|
12
|
+
|
13
|
+
* Fix direct upload in the sample project
|
14
|
+
|
2
15
|
1.1.3 / 2016-03-16
|
3
16
|
==================
|
4
17
|
|
data/lib/cloudinary/utils.rb
CHANGED
@@ -10,7 +10,24 @@ class Cloudinary::Utils
|
|
10
10
|
# @deprecated Use Cloudinary::SHARED_CDN
|
11
11
|
SHARED_CDN = Cloudinary::SHARED_CDN
|
12
12
|
DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION = {:width => :auto, :crop => :limit}
|
13
|
-
|
13
|
+
CONDITIONAL_OPERATORS = {
|
14
|
+
"=" => 'eq',
|
15
|
+
"!=" => 'ne',
|
16
|
+
"<" => 'lt',
|
17
|
+
">" => 'gt',
|
18
|
+
"<=" => 'lte',
|
19
|
+
">=" => 'gte',
|
20
|
+
"&&" => 'and',
|
21
|
+
"||" => 'or'
|
22
|
+
}
|
23
|
+
|
24
|
+
CONDITIONAL_PARAMETERS = {
|
25
|
+
"width" => "w",
|
26
|
+
"height" => "h",
|
27
|
+
"aspect_ratio" => "ar",
|
28
|
+
"page_count" => "pc",
|
29
|
+
"face_count" => "fc"
|
30
|
+
}
|
14
31
|
# Warning: options are being destructively updated!
|
15
32
|
def self.generate_transformation_string(options={}, allow_implicit_crop_mode = false)
|
16
33
|
# allow_implicit_crop_mode was added to support height and width parameters without specifying a crop mode.
|
@@ -75,6 +92,7 @@ class Cloudinary::Utils
|
|
75
92
|
|
76
93
|
overlay = process_layer(options.delete(:overlay))
|
77
94
|
underlay = process_layer(options.delete(:underlay))
|
95
|
+
ifValue = process_if(options.delete(:if))
|
78
96
|
|
79
97
|
params = {
|
80
98
|
:a => angle,
|
@@ -125,9 +143,11 @@ class Cloudinary::Utils
|
|
125
143
|
params[range_value] = norm_range_value params[range_value] if params[range_value].present?
|
126
144
|
end
|
127
145
|
|
128
|
-
transformation = params.reject{|_k,v| v.blank?}.map{|k,v| "#{k}_#{v}"}.sort.join(",")
|
129
146
|
raw_transformation = options.delete(:raw_transformation)
|
130
|
-
transformation =
|
147
|
+
transformation = params.reject{|_k,v| v.blank?}.map{|k,v| "#{k}_#{v}"}.sort
|
148
|
+
transformation = transformation.join(",")
|
149
|
+
transformation = [ifValue, transformation, raw_transformation].reject(&:blank?).join(",")
|
150
|
+
|
131
151
|
transformations = base_transformations << transformation
|
132
152
|
if responsive_width
|
133
153
|
responsive_width_transformation = Cloudinary.config.responsive_width_transformation || DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION
|
@@ -144,6 +164,21 @@ class Cloudinary::Utils
|
|
144
164
|
transformations.reject(&:blank?).join("/")
|
145
165
|
end
|
146
166
|
|
167
|
+
# Parse "if" parameter
|
168
|
+
# Translates the condition if provided.
|
169
|
+
# @return [string] "if_" + ifValue
|
170
|
+
# @private
|
171
|
+
def self.process_if(ifValue)
|
172
|
+
if ifValue
|
173
|
+
ifValue = ifValue.gsub(
|
174
|
+
/(#{CONDITIONAL_PARAMETERS.keys.join("|")}|[=<>&|!]+)/,
|
175
|
+
CONDITIONAL_PARAMETERS.merge(CONDITIONAL_OPERATORS))
|
176
|
+
.gsub(/[ _]+/, "_")
|
177
|
+
|
178
|
+
ifValue = "if_" + ifValue
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
147
182
|
# Parse layer options
|
148
183
|
# @return [string] layer transformation string
|
149
184
|
# @private
|
data/lib/cloudinary/version.rb
CHANGED
data/spec/utils_spec.rb
CHANGED
@@ -391,13 +391,13 @@ describe Cloudinary::Utils do
|
|
391
391
|
describe param do
|
392
392
|
let(:root_path) { "http://res.cloudinary.com/#{cloud_name}" }
|
393
393
|
let(:layers_options) { [
|
394
|
-
|
395
|
-
["string",
|
396
|
-
["public_id",
|
397
|
-
["public_id with folder", { "public_id" => "folder/logo" },
|
398
|
-
["private",
|
399
|
-
["format",
|
400
|
-
["video",
|
394
|
+
# [name, options, result]
|
395
|
+
["string", "text:hello", "text:hello"],
|
396
|
+
["public_id", { "public_id" => "logo" }, "logo"],
|
397
|
+
["public_id with folder", { "public_id" => "folder/logo" }, "folder:logo"],
|
398
|
+
["private", { "public_id" => "logo", "type" => "private" }, "private:logo"],
|
399
|
+
["format", { "public_id" => "logo", "format" => "png" }, "logo.png"],
|
400
|
+
["video", { "resource_type" => "video", "public_id" => "cat" }, "video:cat"],
|
401
401
|
] }
|
402
402
|
it "should support #{param}" do
|
403
403
|
layers_options.each do |name, options, result|
|
@@ -667,5 +667,69 @@ describe Cloudinary::Utils do
|
|
667
667
|
expect(Cloudinary::Utils.encode_double_array([[1, 2, 3, 4], [5, 6, 7, 8]])).to eq("1,2,3,4|5,6,7,8")
|
668
668
|
end
|
669
669
|
|
670
|
+
describe ":if" do
|
671
|
+
describe 'with literal condition string' do
|
672
|
+
it "should include the if parameter as the first component in the transformation string" do
|
673
|
+
expect(["sample", { if: "w_lt_200", crop: "fill", height: 120, width: 80 }])
|
674
|
+
.to produce_url("#{upload_path}/if_w_lt_200,c_fill,h_120,w_80/sample")
|
675
|
+
expect(["sample", { crop: "fill", height: 120, if: "w_lt_200", width: 80 }])
|
676
|
+
.to produce_url("#{upload_path}/if_w_lt_200,c_fill,h_120,w_80/sample")
|
670
677
|
|
678
|
+
end
|
679
|
+
it "should allow multiple conditions when chaining transformations " do
|
680
|
+
expect(["sample", transformation: [{ if: "w_lt_200", crop: "fill", height: 120, width: 80 },
|
681
|
+
{ if: "w_gt_400", crop: "fit", width: 150, height: 150 },
|
682
|
+
{ effect: "sepia" }]])
|
683
|
+
.to produce_url("#{upload_path}/if_w_lt_200,c_fill,h_120,w_80/if_w_gt_400,c_fit,h_150,w_150/e_sepia/sample")
|
684
|
+
end
|
685
|
+
|
686
|
+
describe "including spaces and operators" do
|
687
|
+
it "should translate operators" do
|
688
|
+
expect(["sample", { if: "w < 200", crop: "fill", height: 120, width: 80 }])
|
689
|
+
.to produce_url("#{upload_path}/if_w_lt_200,c_fill,h_120,w_80/sample")
|
690
|
+
end
|
691
|
+
end
|
692
|
+
|
693
|
+
describe 'if end' do
|
694
|
+
it "should include the if_end as the last parameter in its component" do
|
695
|
+
expect(["sample", transformation: [{ if: "w_lt_200" },
|
696
|
+
{ crop: "fill", height: 120, width: 80, effect: "sharpen" },
|
697
|
+
{ effect: "brightness:50" },
|
698
|
+
{ effect: "shadow", color: "red" },
|
699
|
+
{ if: "end" }]])
|
700
|
+
.to produce_url("#{upload_path}/if_w_lt_200/c_fill,e_sharpen,h_120,w_80/e_brightness:50/co_red,e_shadow/if_end/sample")
|
701
|
+
end
|
702
|
+
it "should support if_else with transformation parameters" do
|
703
|
+
expect(["sample", transformation: [{ if: "w_lt_200", crop: "fill", height: 120, width: 80 },
|
704
|
+
{ if: "else", crop: "fill", height: 90, width: 100 }]])
|
705
|
+
.to produce_url("#{upload_path}/if_w_lt_200,c_fill,h_120,w_80/if_else,c_fill,h_90,w_100/sample")
|
706
|
+
end
|
707
|
+
it "if_else should be without any transformation parameters" do
|
708
|
+
expect(["sample", transformation: [{ if: "w_lt_200" },
|
709
|
+
{ crop: "fill", height: 120, width: 80 },
|
710
|
+
{ if: "else" },
|
711
|
+
{ crop: "fill", height: 90, width: 100 }]])
|
712
|
+
.to produce_url("#{upload_path}/if_w_lt_200/c_fill,h_120,w_80/if_else/c_fill,h_90,w_100/sample")
|
713
|
+
end
|
714
|
+
end
|
715
|
+
it "should support and translate operators: '=', '!=', '<', '>', '<=', '>=', '&&', '||'" do
|
716
|
+
|
717
|
+
allOperators =
|
718
|
+
'if_' +
|
719
|
+
'w_eq_0_and' +
|
720
|
+
'_w_ne_0_or' +
|
721
|
+
'_h_lt_0_and' +
|
722
|
+
'_ar_gt_0_and' +
|
723
|
+
'_pc_lte_0_and' +
|
724
|
+
'_fc_gte_0' +
|
725
|
+
',e_grayscale'
|
726
|
+
|
727
|
+
expect( ["sample",
|
728
|
+
:if =>"width = 0 && w != 0 || height < 0 and aspect_ratio > 0 and page_count <= 0 and face_count >= 0",
|
729
|
+
:effect =>"grayscale"])
|
730
|
+
.to produce_url("#{upload_path}/#{allOperators}/sample")
|
731
|
+
end
|
732
|
+
|
733
|
+
end
|
734
|
+
end
|
671
735
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
/**
|
3
|
-
* Cloudinary's JavaScript library - Version 2.0.
|
3
|
+
* Cloudinary's JavaScript library - Version 2.0.8
|
4
4
|
* Copyright Cloudinary
|
5
5
|
* see https://github.com/cloudinary/cloudinary_js
|
6
6
|
*
|
@@ -778,6 +778,19 @@ var extend = function(child, parent) { for (var key in parent) { if (hasProp.cal
|
|
778
778
|
"||": 'or'
|
779
779
|
};
|
780
780
|
|
781
|
+
Condition.PARAMETERS = {
|
782
|
+
"width": "w",
|
783
|
+
"height": "h",
|
784
|
+
"aspect_ratio": "ar",
|
785
|
+
"aspectRatio": "ar",
|
786
|
+
"page_count": "pc",
|
787
|
+
"pageCount": "pc",
|
788
|
+
"face_count": "fc",
|
789
|
+
"faceCount": "fc"
|
790
|
+
};
|
791
|
+
|
792
|
+
Condition.BOUNDRY = "[ _]+";
|
793
|
+
|
781
794
|
|
782
795
|
/**
|
783
796
|
* Represents a transformation condition
|
@@ -829,22 +842,12 @@ var extend = function(child, parent) { for (var key in parent) { if (hasProp.cal
|
|
829
842
|
*/
|
830
843
|
|
831
844
|
Condition.prototype.normalize = function(value) {
|
832
|
-
var
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
v = list[j];
|
839
|
-
if (Condition.OPERATORS[v] != null) {
|
840
|
-
results.push(Condition.OPERATORS[v]);
|
841
|
-
} else {
|
842
|
-
results.push(v);
|
843
|
-
}
|
844
|
-
}
|
845
|
-
return results;
|
846
|
-
})();
|
847
|
-
return list.join('_');
|
845
|
+
var replaceRE;
|
846
|
+
replaceRE = new RegExp("(" + Object.keys(Condition.PARAMETERS).join("|") + "|[=<>&|!]+)", "g");
|
847
|
+
value = value.replace(replaceRE, function(match) {
|
848
|
+
return Condition.OPERATORS[match] || Condition.PARAMETERS[match];
|
849
|
+
});
|
850
|
+
return value.replace(/[ _]+/g, '_');
|
848
851
|
};
|
849
852
|
|
850
853
|
|
@@ -969,8 +972,8 @@ var extend = function(child, parent) { for (var key in parent) { if (hasProp.cal
|
|
969
972
|
* @return {Condition} this condition
|
970
973
|
*/
|
971
974
|
|
972
|
-
Condition.prototype.
|
973
|
-
return this.predicate("
|
975
|
+
Condition.prototype.pageCount = function(operator, value) {
|
976
|
+
return this.predicate("pc", operator, value);
|
974
977
|
};
|
975
978
|
|
976
979
|
|
@@ -981,8 +984,8 @@ var extend = function(child, parent) { for (var key in parent) { if (hasProp.cal
|
|
981
984
|
* @return {Condition} this condition
|
982
985
|
*/
|
983
986
|
|
984
|
-
Condition.prototype.
|
985
|
-
return this.predicate("
|
987
|
+
Condition.prototype.faceCount = function(operator, value) {
|
988
|
+
return this.predicate("fc", operator, value);
|
986
989
|
};
|
987
990
|
|
988
991
|
return Condition;
|
@@ -1859,12 +1862,12 @@ var extend = function(child, parent) { for (var key in parent) { if (hasProp.cal
|
|
1859
1862
|
|
1860
1863
|
DEFAULT_CONFIGURATION_PARAMS = {
|
1861
1864
|
responsive_class: 'cld-responsive',
|
1862
|
-
|
1865
|
+
responsive_use_breakpoints: true,
|
1863
1866
|
round_dpr: true,
|
1864
1867
|
secure: (typeof window !== "undefined" && window !== null ? (ref = window.location) != null ? ref.protocol : void 0 : void 0) === 'https:'
|
1865
1868
|
};
|
1866
1869
|
|
1867
|
-
Configuration.CONFIG_PARAMS = ["api_key", "api_secret", "cdn_subdomain", "cloud_name", "cname", "private_cdn", "protocol", "resource_type", "responsive_class", "
|
1870
|
+
Configuration.CONFIG_PARAMS = ["api_key", "api_secret", "cdn_subdomain", "cloud_name", "cname", "private_cdn", "protocol", "resource_type", "responsive_class", "responsive_use_breakpoints", "responsive_width", "round_dpr", "secure", "secure_cdn_subdomain", "secure_distribution", "shorten", "type", "url_suffix", "use_root_path", "version"];
|
1868
1871
|
|
1869
1872
|
|
1870
1873
|
/**
|
@@ -2471,7 +2474,7 @@ var extend = function(child, parent) { for (var key in parent) { if (hasProp.cal
|
|
2471
2474
|
Cloudinary = (function() {
|
2472
2475
|
var AKAMAI_SHARED_CDN, CF_SHARED_CDN, DEFAULT_POSTER_OPTIONS, DEFAULT_VIDEO_SOURCE_TYPES, OLD_AKAMAI_SHARED_CDN, SHARED_CDN, VERSION, absolutize, applyBreakpoints, cdnSubdomainNumber, closestAbove, cloudinaryUrlPrefix, defaultBreakpoints, finalizeResourceType, parentWidth;
|
2473
2476
|
|
2474
|
-
VERSION = "2.0.
|
2477
|
+
VERSION = "2.0.8";
|
2475
2478
|
|
2476
2479
|
CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net";
|
2477
2480
|
|
@@ -3651,7 +3654,7 @@ var extend = function(child, parent) { for (var key in parent) { if (hasProp.cal
|
|
3651
3654
|
ImageTag: ImageTag,
|
3652
3655
|
VideoTag: VideoTag,
|
3653
3656
|
Cloudinary: Cloudinary,
|
3654
|
-
VERSION: "2.0.
|
3657
|
+
VERSION: "2.0.8",
|
3655
3658
|
CloudinaryJQuery: CloudinaryJQuery
|
3656
3659
|
};
|
3657
3660
|
return cloudinary;
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudinary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nadav Soferman
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-03-
|
13
|
+
date: 2016-03-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: aws_cf_signer
|