cloudinary 1.1.7 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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.7
4
+ version: 1.2.0
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-06-06 00:00:00.000000000 Z
13
+ date: 2016-06-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws_cf_signer
@@ -168,9 +168,7 @@ files:
168
168
  - vendor/assets/html/cloudinary_cors.html
169
169
  - vendor/assets/javascripts/cloudinary/canvas-to-blob.min.js
170
170
  - vendor/assets/javascripts/cloudinary/index.js
171
- - vendor/assets/javascripts/cloudinary/jquery.cloudinary.coffee
172
171
  - vendor/assets/javascripts/cloudinary/jquery.cloudinary.js
173
- - vendor/assets/javascripts/cloudinary/jquery.cloudinary.js.map
174
172
  - vendor/assets/javascripts/cloudinary/jquery.fileupload-image.js
175
173
  - vendor/assets/javascripts/cloudinary/jquery.fileupload-process.js
176
174
  - vendor/assets/javascripts/cloudinary/jquery.fileupload-validate.js
@@ -1,2841 +0,0 @@
1
- ###*
2
- * Cloudinary's JavaScript library - Version 2.0.9
3
- * Copyright Cloudinary
4
- * see https://github.com/cloudinary/cloudinary_js
5
- *
6
- ###
7
-
8
- ((root, factory) ->
9
- if (typeof define == 'function') && define.amd
10
- define ['jquery'], factory
11
- else if typeof exports == 'object'
12
- module.exports = factory(require('jquery'))
13
- else
14
- root.cloudinary ||= {}
15
- for name, value of factory(jQuery)
16
- root.cloudinary[name] = value
17
- )(this, (jQuery)->
18
-
19
- ###*
20
- * Includes utility methods and lodash / jQuery shims
21
- ###
22
-
23
- ###*
24
- * Get data from the DOM element.
25
- *
26
- * This method will use jQuery's `data()` method if it is available, otherwise it will get the `data-` attribute
27
- * @param {Element} element - the element to get the data from
28
- * @param {string} name - the name of the data item
29
- * @returns the value associated with the `name`
30
- * @function Util.getData
31
- ###
32
- getData = ( element, name)->
33
- jQuery(element).data(name)
34
-
35
- ###*
36
- * Set data in the DOM element.
37
- *
38
- * This method will use jQuery's `data()` method if it is available, otherwise it will set the `data-` attribute
39
- * @param {Element} element - the element to set the data in
40
- * @param {string} name - the name of the data item
41
- * @param {*} value - the value to be set
42
- *
43
- ###
44
- setData = (element, name, value)->
45
- jQuery(element).data(name, value)
46
-
47
- ###*
48
- * Get attribute from the DOM element.
49
- *
50
- * This method will use jQuery's `attr()` method if it is available, otherwise it will get the attribute directly
51
- * @param {Element} element - the element to set the attribute for
52
- * @param {string} name - the name of the attribute
53
- * @returns {*} the value of the attribute
54
- *
55
- ###
56
- getAttribute = ( element, name)->
57
- jQuery(element).attr(name)
58
- ###*
59
- * Set attribute in the DOM element.
60
- *
61
- * This method will use jQuery's `attr()` method if it is available, otherwise it will set the attribute directly
62
- * @param {Element} element - the element to set the attribute for
63
- * @param {string} name - the name of the attribute
64
- * @param {*} value - the value to be set
65
- *
66
- ###
67
- setAttribute = (element, name, value)->
68
- jQuery(element).attr(name, value)
69
-
70
- removeAttribute = (element, name)->
71
- jQuery(element).removeAttr(name)
72
-
73
- setAttributes = (element, attributes)->
74
- jQuery(element).attr(attributes)
75
-
76
- hasClass = (element, name)->
77
- jQuery(element).hasClass(name)
78
-
79
- addClass = (element, name)->
80
- jQuery(element).addClass( name)
81
-
82
-
83
- width = (element)->
84
- jQuery(element).width()
85
-
86
- isEmpty = (item)->
87
- !item? ||
88
- (jQuery.isArray(item) || Util.isString(item)) && item.length == 0 ||
89
- (jQuery.isPlainObject(item) && jQuery.isEmptyObject(item))
90
-
91
-
92
- allStrings = (list)->
93
- for item in list
94
- return false unless Util.isString(item)
95
- return true
96
-
97
- isString = (item)->
98
- typeof item == 'string' || item?.toString() == '[object String]'
99
-
100
- merge = ()->
101
- args = (i for i in arguments)
102
- args.unshift(true) # deep extend
103
- jQuery.extend.apply(this, args )
104
-
105
- ###* Used to match words to create compound words. ###
106
-
107
- reWords = do ->
108
- upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]'
109
- lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'
110
- RegExp upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'
111
-
112
- camelCase = (source)->
113
- words = source.match(reWords)
114
- words = for word, i in words
115
- word = word.toLocaleLowerCase()
116
- if i then word.charAt(0).toLocaleUpperCase() + word.slice(1) else word
117
- words.join('')
118
-
119
- snakeCase = (source)->
120
- words = source.match(reWords)
121
- words = for word, i in words
122
- word.toLocaleLowerCase()
123
- words.join('_')
124
-
125
- compact = (arr)->
126
- for item in arr when item
127
- item
128
-
129
- cloneDeep = ()->
130
- args = jQuery.makeArray(arguments)
131
- args.unshift({}) # add "fresh" destination
132
- args.unshift(true) # deep
133
- jQuery.extend.apply(this, args)
134
-
135
- contains = (arr, item)->
136
- for i in arr when i == item
137
- return true
138
- return false
139
-
140
- defaults = ()->
141
- args = []
142
- return arguments[0] if arguments.length == 1
143
- # reverse the order of the arguments
144
- for a in arguments
145
- args.unshift(a)
146
- # bring destination object back to the start
147
- first = args.pop()
148
- args.unshift(first)
149
- jQuery.extend.apply(this, args)
150
-
151
- difference = (arr, values)->
152
- for item in arr when !contains(values, item)
153
- item
154
-
155
- functions = (object)->
156
- for i of object when jQuery.isFunction(object[i])
157
- i
158
-
159
- identity = (value)-> value
160
-
161
- without = (array, item)->
162
- newArray = []
163
- i = -1; length = array.length;
164
- while ++i < length
165
- newArray.push(array[i]) if array[i] != item
166
- newArray
167
-
168
- Util =
169
- hasClass: hasClass
170
- addClass: addClass
171
- getAttribute: getAttribute
172
- setAttribute: setAttribute
173
- removeAttribute: removeAttribute
174
- setAttributes: setAttributes
175
- getData: getData
176
- setData: setData
177
- width: width
178
- ###*
179
- * Return true if all items in list are strings
180
- * @param {Array} list - an array of items
181
- ###
182
- allStrings: allStrings
183
- isString: isString
184
- isArray: jQuery.isArray
185
- isEmpty: isEmpty
186
- ###*
187
- * Assign source properties to destination.
188
- * If the property is an object it is assigned as a whole, overriding the destination object.
189
- * @param {Object} destination - the object to assign to
190
- ###
191
- assign: jQuery.extend
192
- ###*
193
- * Recursively assign source properties to destination
194
- * @param {Object} destination - the object to assign to
195
- * @param {...Object} [sources] The source objects.
196
- ###
197
- merge: merge
198
- ###*
199
- * Convert string to camelCase
200
- * @param {string} string - the string to convert
201
- * @return {string} in camelCase format
202
- ###
203
- camelCase: camelCase
204
- ###*
205
- * Convert string to snake_case
206
- * @param {string} string - the string to convert
207
- * @return {string} in snake_case format
208
- ###
209
- snakeCase: snakeCase
210
- ###*
211
- * Create a new copy of the given object, including all internal objects.
212
- * @param {Object} value - the object to clone
213
- * @return {Object} a new deep copy of the object
214
- ###
215
- cloneDeep: cloneDeep
216
- ###*
217
- * Creates a new array from the parameter with "falsey" values removed
218
- * @param {Array} array - the array to remove values from
219
- * @return {Array} a new array without falsey values
220
- ###
221
- compact: compact
222
- ###*
223
- * Check if a given item is included in the given array
224
- * @param {Array} array - the array to search in
225
- * @param {*} item - the item to search for
226
- * @return {boolean} true if the item is included in the array
227
- ###
228
- contains: contains
229
- ###*
230
- * Assign values from sources if they are not defined in the destination.
231
- * Once a value is set it does not change
232
- * @param {Object} destination - the object to assign defaults to
233
- * @param {...Object} source - the source object(s) to assign defaults from
234
- * @return {Object} destination after it was modified
235
- ###
236
- defaults: defaults
237
- ###*
238
- * Returns values in the given array that are not included in the other array
239
- * @param {Array} arr - the array to select from
240
- * @param {Array} values - values to filter from arr
241
- * @return {Array} the filtered values
242
- ###
243
- difference: difference
244
- ###*
245
- * Returns true if argument is a function.
246
- * @param {*} value - the value to check
247
- * @return {boolean} true if the value is a function
248
- ###
249
- isFunction: jQuery.isFunction
250
- ###*
251
- * Returns a list of all the function names in obj
252
- * @param {Object} object - the object to inspect
253
- * @return {Array} a list of functions of object
254
- ###
255
- functions: functions
256
- ###*
257
- * Returns the provided value. This functions is used as a default predicate function.
258
- * @param {*} value
259
- * @return {*} the provided value
260
- ###
261
- identity: identity
262
- isPlainObject: jQuery.isPlainObject
263
- ###*
264
- * Remove leading or trailing spaces from text
265
- * @param {string} text
266
- * @return {string} the `text` without leading or trailing spaces
267
- ###
268
- trim: jQuery.trim
269
- ###*
270
- * Creates a new array without the given item.
271
- * @param {Array} array - original array
272
- * @param {*} item - the item to exclude from the new array
273
- * @return {Array} a new array made of the original array's items except for `item`
274
- ###
275
- without: without
276
-
277
- ###*
278
- * UTF8 encoder
279
- *
280
- ###
281
- utf8_encode = (argString) ->
282
- # http://kevin.vanzonneveld.net
283
- # + original by: Webtoolkit.info (http://www.webtoolkit.info/)
284
- # + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
285
- # + improved by: sowberry
286
- # + tweaked by: Jack
287
- # + bugfixed by: Onno Marsman
288
- # + improved by: Yves Sucaet
289
- # + bugfixed by: Onno Marsman
290
- # + bugfixed by: Ulrich
291
- # + bugfixed by: Rafal Kukawski
292
- # + improved by: kirilloid
293
- # * example 1: utf8_encode('Kevin van Zonneveld');
294
- # * returns 1: 'Kevin van Zonneveld'
295
- if argString == null or typeof argString == 'undefined'
296
- return ''
297
- string = argString + ''
298
- # .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
299
- utftext = ''
300
- start = undefined
301
- end = undefined
302
- stringl = 0
303
- start = end = 0
304
- stringl = string.length
305
- n = 0
306
- while n < stringl
307
- c1 = string.charCodeAt(n)
308
- enc = null
309
- if c1 < 128
310
- end++
311
- else if c1 > 127 and c1 < 2048
312
- enc = String.fromCharCode(c1 >> 6 | 192, c1 & 63 | 128)
313
- else
314
- enc = String.fromCharCode(c1 >> 12 | 224, c1 >> 6 & 63 | 128, c1 & 63 | 128)
315
- if enc != null
316
- if end > start
317
- utftext += string.slice(start, end)
318
- utftext += enc
319
- start = end = n + 1
320
- n++
321
- if end > start
322
- utftext += string.slice(start, stringl)
323
- utftext
324
-
325
- ###*
326
- * CRC32 calculator
327
- * Depends on 'utf8_encode'
328
- ###
329
- crc32 = (str) ->
330
- # http://kevin.vanzonneveld.net
331
- # + original by: Webtoolkit.info (http://www.webtoolkit.info/)
332
- # + improved by: T0bsn
333
- # + improved by: http://stackoverflow.com/questions/2647935/javascript-crc32-function-and-php-crc32-not-matching
334
- # - depends on: utf8_encode
335
- # * example 1: crc32('Kevin van Zonneveld');
336
- # * returns 1: 1249991249
337
- str = utf8_encode str
338
-
339
- table = '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D'
340
- crc = 0
341
- x = 0
342
- y = 0
343
- crc = crc ^ -1
344
- i = 0
345
- iTop = str.length
346
- while i < iTop
347
- y = (crc ^ str.charCodeAt(i)) & 0xFF
348
- x = '0x' + table.substr(y * 9, 8)
349
- crc = crc >>> 8 ^ x
350
- i++
351
- crc = crc ^ -1
352
- #convert to unsigned 32-bit int if needed
353
- if crc < 0
354
- crc += 4294967296
355
- crc
356
-
357
- ###*
358
- * Transformation parameters
359
- * Depends on 'util', 'transformation'
360
- ###
361
- class Param
362
- ###*
363
- * Represents a single parameter
364
- * @class Param
365
- * @param {string} name - The name of the parameter in snake_case
366
- * @param {string} short - The name of the serialized form of the parameter.
367
- * If a value is not provided, the parameter will not be serialized.
368
- * @param {function} [process=cloudinary.Util.identity ] - Manipulate origValue when value is called
369
- * @ignore
370
- ###
371
- constructor: (name, short, process = cloudinary.Util.identity)->
372
- ###*
373
- * The name of the parameter in snake_case
374
- * @member {string} Param#name
375
- ###
376
- @name = name
377
- ###*
378
- * The name of the serialized form of the parameter
379
- * @member {string} Param#short
380
- ###
381
- @short = short
382
- ###*
383
- * Manipulate origValue when value is called
384
- * @member {function} Param#process
385
- ###
386
- @process = process
387
-
388
- ###*
389
- * Set a (unprocessed) value for this parameter
390
- * @function Param#set
391
- * @param {*} origValue - the value of the parameter
392
- * @return {Param} self for chaining
393
- ###
394
- set: (origValue)->
395
- @origValue = origValue
396
- this
397
-
398
- ###*
399
- * Generate the serialized form of the parameter
400
- * @function Param#serialize
401
- * @return {string} the serialized form of the parameter
402
- ###
403
- serialize: ->
404
- val = @value()
405
- valid = if cloudinary.Util.isArray(val) || cloudinary.Util.isPlainObject(val) || cloudinary.Util.isString(val)
406
- !cloudinary.Util.isEmpty(val)
407
- else
408
- val?
409
- if @short? && valid
410
- "#{@short}_#{val}"
411
- else
412
- ''
413
-
414
- ###*
415
- * Return the processed value of the parameter
416
- * @function Param#value
417
- ###
418
- value: ->
419
- @process(@origValue)
420
-
421
- @norm_color: (value) -> value?.replace(/^#/, 'rgb:')
422
-
423
- build_array: (arg = []) ->
424
- if cloudinary.Util.isArray(arg)
425
- arg
426
- else
427
- [arg]
428
- ###*
429
- * Covert value to video codec string.
430
- *
431
- * If the parameter is an object,
432
- * @param {(string|Object)} param - the video codec as either a String or a Hash
433
- * @return {string} the video codec string in the format codec:profile:level
434
- * @example
435
- * vc_[ :profile : [level]]
436
- * or
437
- { codec: 'h264', profile: 'basic', level: '3.1' }
438
- * @ignore
439
- ###
440
- @process_video_params = (param) ->
441
- switch param.constructor
442
- when Object
443
- video = ""
444
- if 'codec' of param
445
- video = param['codec']
446
- if 'profile' of param
447
- video += ":" + param['profile']
448
- if 'level' of param
449
- video += ":" + param['level']
450
- video
451
- when String
452
- param
453
- else
454
- null
455
-
456
- class ArrayParam extends Param
457
- ###*
458
- * A parameter that represents an array
459
- * @param {string} name - The name of the parameter in snake_case
460
- * @param {string} short - The name of the serialized form of the parameter
461
- * If a value is not provided, the parameter will not be serialized.
462
- * @param {string} [sep='.'] - The separator to use when joining the array elements together
463
- * @param {function} [process=cloudinary.Util.identity ] - Manipulate origValue when value is called
464
- * @class ArrayParam
465
- * @extends Param
466
- * @ignore
467
- ###
468
- constructor: (name, short, sep = '.', process) ->
469
- @sep = sep
470
- super(name, short, process)
471
-
472
- serialize: ->
473
- if @short?
474
- array = @value()
475
- if cloudinary.Util.isEmpty(array)
476
- ''
477
- else
478
- flat = for t in @value()
479
- if cloudinary.Util.isFunction( t.serialize)
480
- t.serialize() # Param or Transformation
481
- else
482
- t
483
- "#{@short}_#{flat.join(@sep)}"
484
- else
485
- ''
486
-
487
- set: (origValue)->
488
- if !origValue? || cloudinary.Util.isArray(origValue)
489
- super(origValue)
490
- else
491
- super([origValue])
492
-
493
- class TransformationParam extends Param
494
- ###*
495
- * A parameter that represents a transformation
496
- * @param {string} name - The name of the parameter in snake_case
497
- * @param {string} [short='t'] - The name of the serialized form of the parameter
498
- * @param {string} [sep='.'] - The separator to use when joining the array elements together
499
- * @param {function} [process=cloudinary.Util.identity ] - Manipulate origValue when value is called
500
- * @class TransformationParam
501
- * @extends Param
502
- * @ignore
503
- ###
504
- constructor: (name, short = "t", sep = '.', process) ->
505
- @sep = sep
506
- super(name, short, process)
507
-
508
- serialize: ->
509
- if cloudinary.Util.isEmpty(@value())
510
- ''
511
- else if cloudinary.Util.allStrings(@value())
512
- joined = @value().join(@sep)
513
- if !cloudinary.Util.isEmpty(joined)
514
- "#{@short}_#{joined}"
515
- else
516
- ''
517
- else
518
- result = for t in @value() when t?
519
- if cloudinary.Util.isString( t) && !cloudinary.Util.isEmpty(t)
520
- "#{@short}_#{t}"
521
- else if cloudinary.Util.isFunction( t.serialize)
522
- t.serialize()
523
- else if cloudinary.Util.isPlainObject(t) && !cloudinary.Util.isEmpty(t)
524
- new Transformation(t).serialize()
525
- cloudinary.Util.compact(result)
526
-
527
- set: (@origValue)->
528
- if cloudinary.Util.isArray(@origValue)
529
- super(@origValue)
530
- else
531
- super([@origValue])
532
-
533
- class RangeParam extends Param
534
- ###*
535
- * A parameter that represents a range
536
- * @param {string} name - The name of the parameter in snake_case
537
- * @param {string} short - The name of the serialized form of the parameter
538
- * If a value is not provided, the parameter will not be serialized.
539
- * @param {function} [process=norm_range_value ] - Manipulate origValue when value is called
540
- * @class RangeParam
541
- * @extends Param
542
- * @ignore
543
- ###
544
- constructor: (name, short, process = @norm_range_value)->
545
- super(name, short, process)
546
-
547
- @norm_range_value: (value) ->
548
- offset = String(value).match(new RegExp('^' + offset_any_pattern + '$'))
549
- if offset
550
- modifier = if offset[5]? then 'p' else ''
551
- value = (offset[1] or offset[4]) + modifier
552
- value
553
-
554
- class RawParam extends Param
555
- constructor: (name, short, process = cloudinary.Util.identity)->
556
- super(name, short, process)
557
- serialize: ->
558
- @value()
559
-
560
- class LayerParam extends Param
561
-
562
- # Parse layer options
563
- # @return [string] layer transformation string
564
- # @private
565
- value: ()->
566
- layer = @origValue
567
- if cloudinary.Util.isPlainObject(layer)
568
- publicId = layer.public_id
569
- format = layer.format
570
- resourceType = layer.resource_type || "image"
571
- type = layer.type || "upload"
572
- text = layer.text
573
- textStyle = null
574
- components = []
575
-
576
- if publicId?
577
- publicId = publicId.replace(/\//g, ":")
578
- publicId = "#{publicId}.#{format}" if format?
579
-
580
- if !text? && resourceType != "text"
581
- if cloudinary.Util.isEmpty(publicId)
582
- throw "Must supply public_id for resource_type layer_parameter"
583
- if resourceType == "subtitles"
584
- textStyle = @textStyle(layer)
585
-
586
- else
587
- resourceType = "text"
588
- type = null
589
- # // type is ignored for text layers
590
- textStyle = @textStyle(layer)
591
- if text?
592
- unless publicId? ^ textStyle?
593
- throw "Must supply either style parameters or a public_id when providing text parameter in a text overlay/underlay"
594
- text = cloudinary.Util.smart_escape( cloudinary.Util.smart_escape(text, /([,\/])/))
595
-
596
- components.push(resourceType) if resourceType != "image"
597
- components.push(type) if type != "upload"
598
- components.push(textStyle)
599
- components.push(publicId)
600
- components.push(text)
601
- layer = cloudinary.Util.compact(components).join(":")
602
- layer
603
-
604
- LAYER_KEYWORD_PARAMS =[
605
- ["font_weight", "normal"],
606
- ["font_style", "normal"],
607
- ["text_decoration", "none"],
608
- ["text_align", null],
609
- ["stroke", "none"],
610
- ]
611
-
612
- textStyle: (layer)->
613
- fontFamily = layer.font_family
614
- fontSize = layer.font_size
615
- keywords =
616
- layer[attr] for [attr, defaultValue] in LAYER_KEYWORD_PARAMS when layer[attr] != defaultValue
617
-
618
- letterSpacing = layer.letter_spacing
619
- keywords.push("letter_spacing_#{letterSpacing}") unless cloudinary.Util.isEmpty(letterSpacing)
620
- lineSpacing = layer.line_spacing
621
- keywords.push("line_spacing_#{lineSpacing}") unless cloudinary.Util.isEmpty(lineSpacing)
622
- if !cloudinary.Util.isEmpty(fontSize) || !cloudinary.Util.isEmpty(fontFamily) || !cloudinary.Util.isEmpty(keywords)
623
- throw "Must supply font_family for text in overlay/underlay" if cloudinary.Util.isEmpty(fontFamily)
624
- throw "Must supply font_size for text in overlay/underlay" if cloudinary.Util.isEmpty(fontSize)
625
- keywords.unshift(fontSize)
626
- keywords.unshift(fontFamily)
627
- cloudinary.Util.compact(keywords).join("_")
628
-
629
-
630
- parameters = {}
631
- parameters.Param = Param
632
- parameters.ArrayParam = ArrayParam
633
- parameters.RangeParam = RangeParam
634
- parameters.RawParam = RawParam
635
- parameters.TransformationParam = TransformationParam
636
- parameters.LayerParam = LayerParam
637
-
638
-
639
- class Condition
640
- ###*
641
- * @internal
642
- ###
643
- @OPERATORS =
644
- "=": 'eq'
645
- "!=": 'ne'
646
- "<": 'lt'
647
- ">": 'gt'
648
- "<=": 'lte'
649
- ">=": 'gte'
650
- "&&": 'and'
651
- "||": 'or'
652
-
653
- @PARAMETERS =
654
- "width": "w"
655
- "height": "h"
656
- "aspect_ratio": "ar"
657
- "aspectRatio": "ar"
658
- "page_count": "pc"
659
- "pageCount": "pc"
660
- "face_count": "fc"
661
- "faceCount": "fc"
662
-
663
- @BOUNDRY = "[ _]+"
664
-
665
- ###*
666
- * Represents a transformation condition
667
- * @param {string} conditionStr - a condition in string format
668
- * @class Condition
669
- * @example
670
- * // normally this class is not instantiated directly
671
- * var tr = cloudinary.Transformation.new()
672
- * .if().width( ">", 1000).and().aspectRatio("<", "3:4").then()
673
- * .width(1000)
674
- * .crop("scale")
675
- * .else()
676
- * .width(500)
677
- * .crop("scale")
678
- *
679
- * var tr = cloudinary.Transformation.new()
680
- * .if("w > 1000 and aspectRatio < 3:4")
681
- * .width(1000)
682
- * .crop("scale")
683
- * .else()
684
- * .width(500)
685
- * .crop("scale")
686
- *
687
- ###
688
- constructor: (conditionStr)->
689
- @predicate_list = []
690
- @predicate_list.push(@normalize(conditionStr)) if conditionStr?
691
-
692
- ###*
693
- * Convenience constructor method
694
- * @function Condition.new
695
- ###
696
- @new = (conditionStr)-> new @(conditionStr)
697
-
698
- ###*
699
- * Normalize a string condition
700
- * @function Cloudinary#normalize
701
- * @param {string} value a condition, e.g. "w gt 100", "width_gt_100", "width > 100"
702
- * @return {string} the normalized form of the value condition, e.g. "w_gt_100"
703
- ###
704
- normalize: (value)->
705
- replaceRE = new RegExp("(" + Object.keys(Condition.PARAMETERS).join("|") + "|[=<>&|!]+)", "g")
706
- value = value.replace replaceRE, (match)->
707
- Condition.OPERATORS[match] || Condition.PARAMETERS[match]
708
- value.replace(/[ _]+/g,'_')
709
-
710
- ###*
711
- * Get the parent transformation of this condition
712
- * @return Transformation
713
- ###
714
- getParent: ()-> @parent
715
-
716
- ###*
717
- * Set the parent transformation of this condition
718
- * @param {Transformation} the parent transformation
719
- * @return {Condition} this condition
720
- ###
721
- setParent: (parent)->
722
- @parent = parent
723
- @
724
-
725
- ###*
726
- * Serialize the condition
727
- * @return {string} the condition as a string
728
- ###
729
- toString: ()-> @predicate_list.join("_")
730
-
731
- ###*
732
- * Add a condition
733
- * @function Condition#predicate
734
- * @internal
735
- ###
736
- predicate: (name, operator, value)->
737
- operator = Condition.OPERATORS[operator] if Condition.OPERATORS[operator]?
738
- @predicate_list.push( "#{name}_#{operator}_#{value}")
739
- @
740
-
741
- ###*
742
- * @function Condition#and
743
- ###
744
- and: ()->
745
- @predicate_list.push("and")
746
- @
747
-
748
- ###*
749
- * @function Condition#or
750
- ###
751
- or: ()->
752
- @predicate_list.push("or")
753
- @
754
-
755
- ###*
756
- * Conclude condition
757
- * @function Condition#then
758
- * @return {Transformation} the transformation this condition is defined for
759
- ###
760
- then: ()-> @getParent().if(@toString())
761
-
762
- ###*
763
- * @function Condition#height
764
- * @param {string} operator the comparison operator (e.g. "<", "lt")
765
- * @param {string|number} value the right hand side value
766
- * @return {Condition} this condition
767
- ###
768
- height: (operator, value)-> @predicate("h", operator, value)
769
-
770
- ###*
771
- * @function Condition#width
772
- * @param {string} operator the comparison operator (e.g. "<", "lt")
773
- * @param {string|number} value the right hand side value
774
- * @return {Condition} this condition
775
- ###
776
- width: (operator, value)-> @predicate("w", operator, value)
777
-
778
- ###*
779
- * @function Condition#aspectRatio
780
- * @param {string} operator the comparison operator (e.g. "<", "lt")
781
- * @param {string|number} value the right hand side value
782
- * @return {Condition} this condition
783
- ###
784
- aspectRatio: (operator, value)-> @predicate("ar", operator, value)
785
-
786
- ###*
787
- * @function Condition#pages
788
- * @param {string} operator the comparison operator (e.g. "<", "lt")
789
- * @param {string|number} value the right hand side value
790
- * @return {Condition} this condition
791
- ###
792
- pageCount: (operator, value)-> @predicate("pc", operator, value)
793
-
794
- ###*
795
- * @function Condition#faces
796
- * @param {string} operator the comparison operator (e.g. "<", "lt")
797
- * @param {string|number} value the right hand side value
798
- * @return {Condition} this condition
799
- ###
800
- faceCount: (operator, value)-> @predicate("fc", operator, value)
801
-
802
-
803
-
804
- ###*
805
- * TransformationBase
806
- * Depends on 'configuration', 'parameters','util'
807
- * @internal
808
- ###
809
-
810
- class TransformationBase
811
- trans_separator: '/'
812
- param_separator: ','
813
- lastArgCallback = (args)->
814
- callback = args?[args.length - 1]
815
- if(Util.isFunction(callback))
816
- callback
817
- else
818
- undefined
819
-
820
- ###*
821
- * The base class for transformations.
822
- * Members of this class are documented as belonging to the {@link Transformation} class for convenience.
823
- * @class TransformationBase
824
- ###
825
- constructor: (options = {}) ->
826
- ###* @private ###
827
- parent = undefined
828
- ###* @private ###
829
- trans = {}
830
-
831
-
832
-
833
- ###*
834
- * Return an options object that can be used to create an identical Transformation
835
- * @function Transformation#toOptions
836
- * @return {Object} Returns a plain object representing this transformation
837
- ###
838
- @toOptions ||= (withChain = true)->
839
- opt= {}
840
- for key, value of trans
841
- opt[key]= value.origValue
842
- for key, value of @otherOptions when value != undefined
843
- opt[key]= value
844
- if withChain && !Util.isEmpty(@chained)
845
- list = for tr in @chained
846
- tr.toOptions()
847
- list.push(opt)
848
- opt = {transformation: list}
849
- opt
850
-
851
- ###*
852
- * Set a parent for this object for chaining purposes.
853
- *
854
- * @function Transformation#setParent
855
- * @param {Object} object - the parent to be assigned to
856
- * @returns {Transformation} Returns this instance for chaining purposes.
857
- ###
858
- @setParent ||= (object)->
859
- parent = object
860
- @fromOptions( object.toOptions?()) if object?
861
- this
862
-
863
- ###*
864
- * Returns the parent of this object in the chain
865
- * @function Transformation#getParent
866
- * @protected
867
- * @return {Object} Returns the parent of this object if there is any
868
- ###
869
- @getParent ||= ()->
870
- parent
871
-
872
- #
873
- # Helper methods to create parameter methods
874
- # These methods are defined here because they access `trans` which is
875
- # a private member of `TransformationBase`
876
- #
877
-
878
- ###* @protected ###
879
- @param ||= (value, name, abbr, defaultValue, process) ->
880
- unless process?
881
- if Util.isFunction(defaultValue)
882
- process = defaultValue
883
- else
884
- process = Util.identity
885
- trans[name] = new Param(name, abbr, process).set(value)
886
- @
887
-
888
- ###* @protected ###
889
- @rawParam ||= (value, name, abbr, defaultValue, process = Util.identity) ->
890
- process = lastArgCallback(arguments)
891
- trans[name] = new RawParam(name, abbr, process).set(value)
892
- @
893
-
894
- ###* @protected ###
895
- @rangeParam ||= (value, name, abbr, defaultValue, process = Util.identity) ->
896
- process = lastArgCallback(arguments)
897
- trans[name] = new RangeParam(name, abbr, process).set(value)
898
- @
899
-
900
- ###* @protected ###
901
- @arrayParam ||= (value, name, abbr, sep = ":", defaultValue = [], process = Util.identity) ->
902
- process = lastArgCallback(arguments)
903
- trans[name] = new ArrayParam(name, abbr, sep, process).set(value)
904
- @
905
-
906
- ###* @protected ###
907
- @transformationParam ||= (value, name, abbr, sep = ".", defaultValue, process = Util.identity) ->
908
- process = lastArgCallback(arguments)
909
- trans[name] = new TransformationParam(name, abbr, sep, process).set(value)
910
- @
911
-
912
- @layerParam ||= (value, name, abbr) ->
913
- trans[name] = new LayerParam(name, abbr).set(value)
914
- @
915
-
916
- #
917
- # End Helper methods
918
- #
919
-
920
- ###*
921
- * Get the value associated with the given name.
922
- * @function Transformation#getValue
923
- * @param {string} name - the name of the parameter
924
- * @return {*} the processed value associated with the given name
925
- * @description Use {@link get}.origValue for the value originally provided for the parameter
926
- ###
927
- @getValue ||= (name)->
928
- trans[name]?.value() ? @otherOptions[name]
929
-
930
- ###*
931
- * Get the parameter object for the given parameter name
932
- * @function Transformation#get
933
- * @param {string} name the name of the transformation parameter
934
- * @returns {Param} the param object for the given name, or undefined
935
- ###
936
- @get ||= (name)->
937
- trans[name]
938
-
939
- ###*
940
- * Remove a transformation option from the transformation.
941
- * @function Transformation#remove
942
- * @param {string} name - the name of the option to remove
943
- * @return {*} Returns the option that was removed or null if no option by that name was found. The type of the
944
- * returned value depends on the value.
945
- ###
946
- @remove ||= (name)->
947
- switch
948
- when trans[name]?
949
- temp = trans[name]
950
- delete trans[name]
951
- temp.origValue
952
- when @otherOptions[name]?
953
- temp = @otherOptions[name]
954
- delete @otherOptions[name]
955
- temp
956
- else
957
- null
958
-
959
- ###*
960
- * Return an array of all the keys (option names) in the transformation.
961
- * @return {Array<string>} the keys in snakeCase format
962
- ###
963
- @keys ||= ()->
964
- (Util.snakeCase(key) for key of trans).sort()
965
-
966
- ###*
967
- * Returns a plain object representation of the transformation. Values are processed.
968
- * @function Transformation#toPlainObject
969
- * @return {Object} the transformation options as plain object
970
- ###
971
- @toPlainObject ||= ()->
972
- hash = {}
973
- for key of trans
974
- hash[key] = trans[key].value()
975
- hash[key] = Util.cloneDeep(hash[key]) if Util.isPlainObject(hash[key])
976
- unless Util.isEmpty(@chained)
977
- list = for tr in @chained
978
- tr.toPlainObject()
979
- list.push(hash)
980
- hash = {transformation: list}
981
- hash
982
-
983
- ###*
984
- * Complete the current transformation and chain to a new one.
985
- * In the URL, transformations are chained together by slashes.
986
- * @function Transformation#chain
987
- * @return {Transformation} Returns this transformation for chaining
988
- * @example
989
- * var tr = cloudinary.Transformation.new();
990
- * tr.width(10).crop('fit').chain().angle(15).serialize()
991
- * // produces "c_fit,w_10/a_15"
992
- ###
993
- @chain ||= ()->
994
- names = Object.getOwnPropertyNames(trans)
995
- unless names.length == 0
996
- tr = new @constructor(@toOptions(false))
997
- @resetTransformations()
998
- @chained.push(tr)
999
- @
1000
-
1001
-
1002
- @resetTransformations ||= ()->
1003
- trans = {}
1004
- @
1005
-
1006
- @otherOptions ||= {}
1007
-
1008
- ###*
1009
- * Transformation Class methods.
1010
- * This is a list of the parameters defined in Transformation.
1011
- * Values are camelCased.
1012
- * @private
1013
- * @ignore
1014
- * @type {Array<string>}
1015
- ###
1016
- @methods ||= Util.difference(Util.functions(Transformation.prototype), Util.functions(TransformationBase.prototype))
1017
-
1018
- ###*
1019
- * Parameters that are filtered out before passing the options to an HTML tag.
1020
- *
1021
- * The list of parameters is a combination of `Transformation::methods` and `Configuration::CONFIG_PARAMS`
1022
- * @const {Array<string>} Transformation.PARAM_NAMES
1023
- * @private
1024
- * @ignore
1025
- * @see toHtmlAttributes
1026
- ###
1027
- @PARAM_NAMES ||= (Util.snakeCase(m) for m in @methods).concat( Configuration.CONFIG_PARAMS)
1028
-
1029
- @chained = []
1030
-
1031
- # Finished constructing the instance, now process the options
1032
-
1033
- @fromOptions(options) unless Util.isEmpty(options)
1034
-
1035
- ###*
1036
- * Merge the provided options with own's options
1037
- * @param {Object} [options={}] key-value list of options
1038
- * @returns {Transformation} Returns this instance for chaining
1039
- ###
1040
- fromOptions: (options) ->
1041
- if options instanceof TransformationBase
1042
- @fromTransformation(options)
1043
- else
1044
- options or= {}
1045
- options = {transformation: options } if Util.isString(options) || Util.isArray(options)
1046
- options = Util.cloneDeep(options, (value) ->
1047
- if value instanceof TransformationBase
1048
- new value.constructor( value.toOptions())
1049
- )
1050
- for key, opt of options
1051
- @set key, opt
1052
- this
1053
-
1054
- fromTransformation: (other) ->
1055
- if other instanceof TransformationBase
1056
- for key in other.keys()
1057
- @set(key, other.get(key).origValue)
1058
- this
1059
-
1060
- ###*
1061
- * Set a parameter.
1062
- * The parameter name `key` is converted to
1063
- * @param {string} key - the name of the parameter
1064
- * @param {*} value - the value of the parameter
1065
- * @returns {Transformation} Returns this instance for chaining
1066
- ###
1067
- set: (key, value)->
1068
- camelKey = Util.camelCase( key)
1069
- if Util.contains( @methods, camelKey)
1070
- this[camelKey](value)
1071
- else
1072
- @otherOptions[key] = value
1073
- this
1074
-
1075
- hasLayer: ()->
1076
- @getValue("overlay") || @getValue("underlay")
1077
-
1078
-
1079
- ###*
1080
- * Generate a string representation of the transformation.
1081
- * @function Transformation#serialize
1082
- * @return {string} Returns the transformation as a string
1083
- ###
1084
- serialize: ->
1085
- resultArray = for tr in @chained
1086
- tr.serialize()
1087
- paramList = @keys()
1088
- transformations = @get("transformation")?.serialize()
1089
- ifParam = @get("if")?.serialize()
1090
- paramList = Util.difference(paramList, ["transformation", "if"])
1091
- transformationList = (@get(t)?.serialize() for t in paramList )
1092
- switch
1093
- when Util.isString(transformations)
1094
- transformationList.push( transformations)
1095
- when Util.isArray( transformations)
1096
- resultArray = resultArray.concat(transformations)
1097
- transformationList = (
1098
- for value in transformationList when Util.isArray(value) &&!Util.isEmpty(value) || !Util.isArray(value) && value
1099
- value
1100
- ).sort()
1101
- if ifParam == "if_end"
1102
- transformationList.push(ifParam)
1103
- else if !Util.isEmpty(ifParam)
1104
- transformationList.unshift(ifParam)
1105
-
1106
- transformationString = transformationList.join(@param_separator)
1107
- resultArray.push(transformationString) unless Util.isEmpty(transformationString)
1108
- Util.compact(resultArray).join(@trans_separator)
1109
-
1110
- ###*
1111
- * Provide a list of all the valid transformation option names
1112
- * @function Transformation#listNames
1113
- * @private
1114
- * @return {Array<string>} a array of all the valid option names
1115
- ###
1116
- listNames: ->
1117
- @methods
1118
-
1119
-
1120
- ###*
1121
- * Returns attributes for an HTML tag.
1122
- * @function Cloudinary.toHtmlAttributes
1123
- * @return PlainObject
1124
- ###
1125
- toHtmlAttributes: ()->
1126
- options = {}
1127
- for key, value of @otherOptions when !Util.contains(@PARAM_NAMES, key)
1128
- attrName = if /^html_/.test(key) then key.slice(5) else key
1129
- options[attrName] = value
1130
- # convert all "html_key" to "key" with the same value
1131
- for key in @keys() when /^html_/.test(key)
1132
- options[key.slice(5)] = @getValue(key)
1133
-
1134
- unless @hasLayer()|| @getValue("angle") || Util.contains( ["fit", "limit", "lfill"],@getValue("crop"))
1135
- width = @get("width")?.origValue
1136
- height = @get("height")?.origValue
1137
- if parseFloat(width) >= 1.0
1138
- options['width'] ?= width
1139
- if parseFloat(height) >= 1.0
1140
- options['height'] ?= height
1141
- options
1142
-
1143
- isValidParamName: (name) ->
1144
- @methods.indexOf(Util.camelCase(name)) >= 0
1145
-
1146
- ###*
1147
- * Delegate to the parent (up the call chain) to produce HTML
1148
- * @function Transformation#toHtml
1149
- * @return {string} HTML representation of the parent if possible.
1150
- * @example
1151
- * tag = cloudinary.ImageTag.new("sample", {cloud_name: "demo"})
1152
- * // ImageTag {name: "img", publicId: "sample"}
1153
- * tag.toHtml()
1154
- * // <img src="http://res.cloudinary.com/demo/image/upload/sample">
1155
- * tag.transformation().crop("fit").width(300).toHtml()
1156
- * // <img src="http://res.cloudinary.com/demo/image/upload/c_fit,w_300/sample">
1157
- ###
1158
-
1159
- toHtml: ()->
1160
- @getParent()?.toHtml?()
1161
-
1162
- toString: ()->
1163
- @serialize()
1164
-
1165
- class Transformation extends TransformationBase
1166
-
1167
- ###*
1168
- * Represents a single transformation.
1169
- * @class Transformation
1170
- * @example
1171
- * t = new cloudinary.Transformation();
1172
- * t.angle(20).crop("scale").width("auto");
1173
- *
1174
- * // or
1175
- *
1176
- * t = new cloudinary.Transformation( {angle: 20, crop: "scale", width: "auto"});
1177
- ###
1178
- constructor: (options = {})->
1179
- super(options)
1180
-
1181
- ###*
1182
- * Convenience constructor
1183
- * @param {Object} options
1184
- * @return {Transformation}
1185
- * @example cl = cloudinary.Transformation.new( {angle: 20, crop: "scale", width: "auto"})
1186
- ###
1187
- @new = (args)-> new Transformation(args)
1188
-
1189
- ###
1190
- Transformation Parameters
1191
- ###
1192
-
1193
- angle: (value)-> @arrayParam value, "angle", "a", "."
1194
- audioCodec: (value)-> @param value, "audio_codec", "ac"
1195
- audioFrequency: (value)-> @param value, "audio_frequency", "af"
1196
- aspectRatio: (value)-> @param value, "aspect_ratio", "ar"
1197
- background: (value)-> @param value, "background", "b", Param.norm_color
1198
- bitRate: (value)-> @param value, "bit_rate", "br"
1199
- border: (value)-> @param value, "border", "bo", (border) ->
1200
- if (Util.isPlainObject(border))
1201
- border = Util.assign({}, {color: "black", width: 2}, border)
1202
- "#{border.width}px_solid_#{Param.norm_color(border.color)}"
1203
- else
1204
- border
1205
- color: (value)-> @param value, "color", "co", Param.norm_color
1206
- colorSpace: (value)-> @param value, "color_space", "cs"
1207
- crop: (value)-> @param value, "crop", "c"
1208
- defaultImage: (value)-> @param value, "default_image", "d"
1209
- delay: (value)-> @param value, "delay", "l"
1210
- density: (value)-> @param value, "density", "dn"
1211
- duration: (value)-> @rangeParam value, "duration", "du"
1212
- dpr: (value)-> @param value, "dpr", "dpr", (dpr) ->
1213
- dpr = dpr.toString()
1214
- if (dpr == "auto")
1215
- "1.0"
1216
- else if (dpr?.match(/^\d+$/))
1217
- dpr + ".0"
1218
- else
1219
- dpr
1220
- effect: (value)-> @arrayParam value, "effect", "e", ":"
1221
- else: ()-> @if('else')
1222
- endIf: ()-> @if('end')
1223
- endOffset: (value)-> @rangeParam value, "end_offset", "eo"
1224
- fallbackContent: (value)-> @param value, "fallback_content"
1225
- fetchFormat: (value)-> @param value, "fetch_format", "f"
1226
- format: (value)-> @param value, "format"
1227
- flags: (value)-> @arrayParam value, "flags", "fl", "."
1228
- gravity: (value)-> @param value, "gravity", "g"
1229
- height: (value)-> @param value, "height", "h", =>
1230
- if ( @getValue("crop") || @getValue("overlay") || @getValue("underlay"))
1231
- value
1232
- else
1233
- null
1234
- htmlHeight: (value)-> @param value, "html_height"
1235
- htmlWidth:(value)-> @param value, "html_width"
1236
- if: (value = "")->
1237
- switch value
1238
- when "else"
1239
- @chain()
1240
- @param value, "if", "if"
1241
- when "end"
1242
- @chain()
1243
- for i in [@chained.length-1..0] by -1
1244
- ifVal = @chained[i].getValue("if")
1245
- if ifVal == "end"
1246
- break
1247
- else if ifVal?
1248
- trIf = Transformation.new().if(ifVal)
1249
- @chained[i].remove("if")
1250
- trRest = @chained[i]
1251
- @chained[i] = Transformation.new().transformation([trIf, trRest])
1252
- break unless ifVal == "else"
1253
- @param value, "if", "if"
1254
- when ""
1255
- Condition.new().setParent(this)
1256
- else
1257
- @param value, "if", "if", (value)->
1258
- Condition.new(value).toString()
1259
- keyframeInterval: (value)-> @param value, "keyframe_interval", "ki"
1260
- offset: (value)->
1261
- [start_o, end_o] = if( Util.isFunction(value?.split))
1262
- value.split('..')
1263
- else if Util.isArray(value)
1264
- value
1265
- else
1266
- [null,null]
1267
- @startOffset(start_o) if start_o?
1268
- @endOffset(end_o) if end_o?
1269
- opacity: (value)-> @param value, "opacity", "o"
1270
- overlay: (value)-> @layerParam value, "overlay", "l"
1271
- page: (value)-> @param value, "page", "pg"
1272
- poster: (value)-> @param value, "poster"
1273
- prefix: (value)-> @param value, "prefix", "p"
1274
- quality: (value)-> @param value, "quality", "q"
1275
- radius: (value)-> @param value, "radius", "r"
1276
- rawTransformation: (value)-> @rawParam value, "raw_transformation"
1277
- size: (value)->
1278
- if( Util.isFunction(value?.split))
1279
- [width, height] = value.split('x')
1280
- @width(width)
1281
- @height(height)
1282
- sourceTypes: (value)-> @param value, "source_types"
1283
- sourceTransformation: (value)-> @param value, "source_transformation"
1284
- startOffset: (value)-> @rangeParam value, "start_offset", "so"
1285
- streamingProfile: (value)-> @param value, "streaming_profile", "sp"
1286
- transformation: (value)-> @transformationParam value, "transformation", "t"
1287
- underlay: (value)-> @layerParam value, "underlay", "u"
1288
- videoCodec: (value)-> @param value, "video_codec", "vc", Param.process_video_params
1289
- videoSampling: (value)-> @param value, "video_sampling", "vs"
1290
- width: (value)-> @param value, "width", "w", =>
1291
- if ( @getValue("crop") || @getValue("overlay") || @getValue("underlay"))
1292
- value
1293
- else
1294
- null
1295
- x: (value)-> @param value, "x", "x"
1296
- y: (value)-> @param value, "y", "y"
1297
- zoom: (value)-> @param value, "zoom", "z"
1298
-
1299
-
1300
-
1301
- ###*
1302
- * Cloudinary configuration class
1303
- * Depends on 'utils'
1304
- ###
1305
- class Configuration
1306
-
1307
- ###*
1308
- * Defaults configuration.
1309
- * @const {Object} Configuration.DEFAULT_CONFIGURATION_PARAMS
1310
- ###
1311
- DEFAULT_CONFIGURATION_PARAMS ={
1312
- responsive_class: 'cld-responsive'
1313
- responsive_use_breakpoints: true
1314
- round_dpr: true
1315
- secure: window?.location?.protocol == 'https:'
1316
- }
1317
-
1318
- @CONFIG_PARAMS = [
1319
- "api_key"
1320
- "api_secret"
1321
- "cdn_subdomain"
1322
- "cloud_name"
1323
- "cname"
1324
- "private_cdn"
1325
- "protocol"
1326
- "resource_type"
1327
- "responsive_class"
1328
- "responsive_use_breakpoints"
1329
- "responsive_width"
1330
- "round_dpr"
1331
- "secure"
1332
- "secure_cdn_subdomain"
1333
- "secure_distribution"
1334
- "shorten"
1335
- "type"
1336
- "url_suffix"
1337
- "use_root_path"
1338
- "version"
1339
- ]
1340
- ###*
1341
- * Cloudinary configuration class
1342
- * @constructor Configuration
1343
- * @param {Object} options - configuration parameters
1344
- ###
1345
- constructor: (options ={})->
1346
- @configuration = Util.cloneDeep(options)
1347
- Util.defaults( @configuration, DEFAULT_CONFIGURATION_PARAMS)
1348
-
1349
- ###*
1350
- * Initialize the configuration.
1351
- * The function first tries to retrieve the configuration form the environment and then from the document.
1352
- * @function Configuration#init
1353
- * @return {Configuration} returns this for chaining
1354
- * @see fromDocument
1355
- * @see fromEnvironment
1356
- ###
1357
- init: ()->
1358
- @fromEnvironment()
1359
- @fromDocument()
1360
- @
1361
-
1362
- ###*
1363
- * Set a new configuration item
1364
- * @function Configuration#set
1365
- * @param {string} name - the name of the item to set
1366
- * @param {*} value - the value to be set
1367
- * @return {Configuration}
1368
- *
1369
- ###
1370
- set:(name, value)->
1371
- @configuration[name] = value
1372
- this
1373
-
1374
- ###*
1375
- * Get the value of a configuration item
1376
- * @function Configuration#get
1377
- * @param {string} name - the name of the item to set
1378
- * @return {*} the configuration item
1379
- ###
1380
- get: (name)->
1381
- @configuration[name]
1382
-
1383
- merge: (config={})->
1384
- Util.assign(@configuration, Util.cloneDeep(config))
1385
- this
1386
-
1387
- ###*
1388
- * Initialize Cloudinary from HTML meta tags.
1389
- * @function Configuration#fromDocument
1390
- * @return {Configuration}
1391
- * @example <meta name="cloudinary_cloud_name" content="mycloud">
1392
- *
1393
- ###
1394
- fromDocument: ->
1395
- meta_elements = document?.querySelectorAll('meta[name^="cloudinary_"]');
1396
- if meta_elements
1397
- for el in meta_elements
1398
- @configuration[el.getAttribute('name').replace('cloudinary_', '')] = el.getAttribute('content')
1399
- this
1400
-
1401
- ###*
1402
- * Initialize Cloudinary from the `CLOUDINARY_URL` environment variable.
1403
- *
1404
- * This function will only run under Node.js environment.
1405
- * @function Configuration#fromEnvironment
1406
- * @requires Node.js
1407
- ###
1408
- fromEnvironment: ->
1409
- cloudinary_url = process?.env?.CLOUDINARY_URL
1410
- if cloudinary_url?
1411
- uri = require('url').parse(cloudinary_url, true)
1412
- @configuration =
1413
- cloud_name: uri.host,
1414
- api_key: uri.auth and uri.auth.split(":")[0],
1415
- api_secret: uri.auth and uri.auth.split(":")[1],
1416
- private_cdn: uri.pathname?,
1417
- secure_distribution: uri.pathname and uri.pathname.substring(1)
1418
- if uri.query?
1419
- for k, v of uri.query
1420
- @configuration[k] = v
1421
- this
1422
-
1423
- ###*
1424
- * Create or modify the Cloudinary client configuration
1425
- *
1426
- * Warning: `config()` returns the actual internal configuration object. modifying it will change the configuration.
1427
- *
1428
- * This is a backward compatibility method. For new code, use get(), merge() etc.
1429
- * @function Configuration#config
1430
- * @param {hash|string|boolean} new_config
1431
- * @param {string} new_value
1432
- * @returns {*} configuration, or value
1433
- *
1434
- * @see {@link fromEnvironment} for initialization using environment variables
1435
- * @see {@link fromDocument} for initialization using HTML meta tags
1436
- ###
1437
- config: (new_config, new_value) ->
1438
- switch
1439
- when new_value != undefined
1440
- @set(new_config, new_value)
1441
- @configuration
1442
- when Util.isString(new_config)
1443
- @get(new_config)
1444
- when Util.isPlainObject(new_config)
1445
- @merge(new_config)
1446
- @configuration
1447
- else
1448
- # Backward compatibility - return the internal object
1449
- @configuration
1450
-
1451
- ###*
1452
- * Returns a copy of the configuration parameters
1453
- * @function Configuration#toOptions
1454
- * @returns {Object} a key:value collection of the configuration parameters
1455
- ###
1456
- toOptions: ()->
1457
- Util.cloneDeep(@configuration)
1458
-
1459
- ###*
1460
- * Generic HTML tag
1461
- * Depends on 'transformation', 'util'
1462
- ###
1463
- class HtmlTag
1464
- ###*
1465
- * Represents an HTML (DOM) tag
1466
- * @constructor HtmlTag
1467
- * @param {string} name - the name of the tag
1468
- * @param {string} [publicId]
1469
- * @param {Object} options
1470
- * @example tag = new HtmlTag( 'div', { 'width': 10})
1471
- ###
1472
- constructor: (name, publicId, options)->
1473
- @name = name
1474
- @publicId = publicId
1475
- if !options?
1476
- if Util.isPlainObject(publicId)
1477
- options = publicId
1478
- @publicId = undefined
1479
- else
1480
- options = {}
1481
- transformation = new Transformation(options)
1482
- transformation.setParent(this)
1483
- @transformation = ()->
1484
- transformation
1485
-
1486
- ###*
1487
- * Convenience constructor
1488
- * Creates a new instance of an HTML (DOM) tag
1489
- * @function HtmlTag.new
1490
- * @param {string} name - the name of the tag
1491
- * @param {string} [publicId]
1492
- * @param {Object} options
1493
- * @return {HtmlTag}
1494
- * @example tag = HtmlTag.new( 'div', { 'width': 10})
1495
- ###
1496
- @new = (name, publicId, options)->
1497
- new @(name, publicId, options)
1498
-
1499
- ###*
1500
- * Represent the given key and value as an HTML attribute.
1501
- * @function HtmlTag#toAttribute
1502
- * @protected
1503
- * @param {string} key - attribute name
1504
- * @param {*|boolean} value - the value of the attribute. If the value is boolean `true`, return the key only.
1505
- * @returns {string} the attribute
1506
- *
1507
- ###
1508
- toAttribute = (key, value) ->
1509
- if !value
1510
- undefined
1511
- else if value == true
1512
- key
1513
- else
1514
- "#{key}=\"#{value}\""
1515
-
1516
- ###*
1517
- * combine key and value from the `attr` to generate an HTML tag attributes string.
1518
- * `Transformation::toHtmlTagOptions` is used to filter out transformation and configuration keys.
1519
- * @protected
1520
- * @param {Object} attrs
1521
- * @return {string} the attributes in the format `'key1="value1" key2="value2"'`
1522
- * @ignore
1523
- ###
1524
- htmlAttrs: (attrs) ->
1525
- pairs = (toAttribute( key, value) for key, value of attrs when value).sort().join(' ')
1526
-
1527
- ###*
1528
- * Get all options related to this tag.
1529
- * @function HtmlTag#getOptions
1530
- * @returns {Object} the options
1531
- *
1532
- ###
1533
- getOptions: ()-> @transformation().toOptions()
1534
-
1535
- ###*
1536
- * Get the value of option `name`
1537
- * @function HtmlTag#getOption
1538
- * @param {string} name - the name of the option
1539
- * @returns {*} Returns the value of the option
1540
- *
1541
- ###
1542
- getOption: (name)-> @transformation().getValue(name)
1543
-
1544
- ###*
1545
- * Get the attributes of the tag.
1546
- * @function HtmlTag#attributes
1547
- * @returns {Object} attributes
1548
- ###
1549
- attributes: ()->
1550
- # The attributes are be computed from the options every time this method is invoked.
1551
- @transformation().toHtmlAttributes()
1552
-
1553
- ###*
1554
- * Set a tag attribute named `name` to `value`
1555
- * @function HtmlTag#setAttr
1556
- * @param {string} name - the name of the attribute
1557
- * @param {string} value - the value of the attribute
1558
- ###
1559
- setAttr: ( name, value)->
1560
- @transformation().set( "html_#{name}", value)
1561
- this
1562
-
1563
- ###*
1564
- * Get the value of the tag attribute `name`
1565
- * @function HtmlTag#getAttr
1566
- * @param {string} name - the name of the attribute
1567
- * @returns {*}
1568
- ###
1569
- getAttr: (name)->
1570
- @attributes()["html_#{name}"] || @attributes()[name]
1571
-
1572
- ###*
1573
- * Remove the tag attributed named `name`
1574
- * @function HtmlTag#removeAttr
1575
- * @param {string} name - the name of the attribute
1576
- * @returns {*}
1577
- ###
1578
- removeAttr: (name)->
1579
- @transformation().remove("html_#{name}") ? @transformation().remove(name)
1580
-
1581
- ###*
1582
- * @function HtmlTag#content
1583
- * @protected
1584
- * @ignore
1585
- ###
1586
- content: ()->
1587
- ""
1588
-
1589
- ###*
1590
- * @function HtmlTag#openTag
1591
- * @protected
1592
- * @ignore
1593
- ###
1594
- openTag: ()->
1595
- "<#{@name} #{@htmlAttrs(@attributes())}>"
1596
-
1597
- ###*
1598
- * @function HtmlTag#closeTag
1599
- * @protected
1600
- * @ignore
1601
- ###
1602
- closeTag:()->
1603
- "</#{@name}>"
1604
-
1605
- ###*
1606
- * Generates an HTML representation of the tag.
1607
- * @function HtmlTag#toHtml
1608
- * @returns {string} Returns HTML in string format
1609
- ###
1610
- toHtml: ()->
1611
- @openTag() + @content()+ @closeTag()
1612
-
1613
- ###*
1614
- * Creates a DOM object representing the tag.
1615
- * @function HtmlTag#toDOM
1616
- * @returns {Element}
1617
- ###
1618
- toDOM: ()->
1619
- throw "Can't create DOM if document is not present!" unless Util.isFunction( document?.createElement)
1620
- element = document.createElement(@name)
1621
- element[name] = value for name, value of @attributes()
1622
- element
1623
-
1624
- ###*
1625
- * Image Tag
1626
- * Depends on 'tags/htmltag', 'cloudinary'
1627
- ###
1628
- class ImageTag extends HtmlTag
1629
-
1630
- ###*
1631
- * Creates an HTML (DOM) Image tag using Cloudinary as the source.
1632
- * @constructor ImageTag
1633
- * @extends HtmlTag
1634
- * @param {string} [publicId]
1635
- * @param {Object} [options]
1636
- ###
1637
- constructor: (publicId, options = {})->
1638
- super("img", publicId, options)
1639
-
1640
- ###* @override ###
1641
- closeTag: ()->
1642
- ""
1643
-
1644
- ###* @override ###
1645
- attributes: ()->
1646
- attr = super() || []
1647
- attr['src'] ?= new Cloudinary(@getOptions()).url(@publicId)
1648
- attr
1649
-
1650
- ###*
1651
- * Video Tag
1652
- * Depends on 'tags/htmltag', 'util', 'cloudinary'
1653
- ###
1654
- class VideoTag extends HtmlTag
1655
-
1656
- VIDEO_TAG_PARAMS = ['source_types', 'source_transformation', 'fallback_content', 'poster']
1657
- DEFAULT_VIDEO_SOURCE_TYPES = ['webm', 'mp4', 'ogv']
1658
- DEFAULT_POSTER_OPTIONS = {format: 'jpg', resource_type: 'video'}
1659
-
1660
- ###*
1661
- * Creates an HTML (DOM) Video tag using Cloudinary as the source.
1662
- * @constructor VideoTag
1663
- * @extends HtmlTag
1664
- * @param {string} [publicId]
1665
- * @param {Object} [options]
1666
- ###
1667
- constructor: (publicId, options = {})->
1668
- options = Util.defaults({}, options, Cloudinary.DEFAULT_VIDEO_PARAMS)
1669
- super("video", publicId.replace(/\.(mp4|ogv|webm)$/, ''), options)
1670
-
1671
- ###*
1672
- * Set the transformation to apply on each source
1673
- * @function VideoTag#setSourceTransformation
1674
- * @param {Object} an object with pairs of source type and source transformation
1675
- * @returns {VideoTag} Returns this instance for chaining purposes.
1676
- ###
1677
- setSourceTransformation: (value)->
1678
- @transformation().sourceTransformation(value)
1679
- this
1680
-
1681
- ###*
1682
- * Set the source types to include in the video tag
1683
- * @function VideoTag#setSourceTypes
1684
- * @param {Array<string>} an array of source types
1685
- * @returns {VideoTag} Returns this instance for chaining purposes.
1686
- ###
1687
- setSourceTypes: (value)->
1688
- @transformation().sourceTypes(value)
1689
- this
1690
-
1691
- ###*
1692
- * Set the poster to be used in the video tag
1693
- * @function VideoTag#setPoster
1694
- * @param {string|Object} value
1695
- * - string: a URL to use for the poster
1696
- * - Object: transformation parameters to apply to the poster. May optionally include a public_id to use instead of the video public_id.
1697
- * @returns {VideoTag} Returns this instance for chaining purposes.
1698
- ###
1699
- setPoster: (value)->
1700
- @transformation().poster(value)
1701
- this
1702
-
1703
- ###*
1704
- * Set the content to use as fallback in the video tag
1705
- * @function VideoTag#setFallbackContent
1706
- * @param {string} value - the content to use, in HTML format
1707
- * @returns {VideoTag} Returns this instance for chaining purposes.
1708
- ###
1709
- setFallbackContent: (value)->
1710
- @transformation().fallbackContent(value)
1711
- this
1712
-
1713
- content: ()->
1714
- sourceTypes = @transformation().getValue('source_types')
1715
- sourceTransformation = @transformation().getValue('source_transformation')
1716
- fallback = @transformation().getValue('fallback_content')
1717
-
1718
- if Util.isArray(sourceTypes)
1719
- cld = new Cloudinary(@getOptions())
1720
- innerTags = for srcType in sourceTypes
1721
- transformation = sourceTransformation[srcType] or {}
1722
- src = cld.url("#{@publicId }", Util.defaults({}, transformation, {resource_type: 'video', format: srcType}))
1723
- videoType = if srcType == 'ogv' then 'ogg' else srcType
1724
- mimeType = 'video/' + videoType
1725
- "<source #{@htmlAttrs(src: src, type: mimeType)}>"
1726
- else
1727
- innerTags = []
1728
- innerTags.join('') + fallback
1729
-
1730
- attributes: ()->
1731
- sourceTypes = @getOption('source_types')
1732
- poster = @getOption('poster') ? {}
1733
-
1734
- if Util.isPlainObject(poster)
1735
- defaults = if poster.public_id? then Cloudinary.DEFAULT_IMAGE_PARAMS else DEFAULT_POSTER_OPTIONS
1736
- poster = new Cloudinary(@getOptions()).url(
1737
- poster.public_id ? @publicId,
1738
- Util.defaults({}, poster, defaults))
1739
-
1740
- attr = super() || []
1741
- attr = a for a in attr when !Util.contains(VIDEO_TAG_PARAMS)
1742
- unless Util.isArray(sourceTypes)
1743
- attr["src"] = new Cloudinary(@getOptions())
1744
- .url(@publicId, {resource_type: 'video', format: sourceTypes})
1745
- if poster?
1746
- attr["poster"] = poster
1747
- attr
1748
-
1749
- class Layer
1750
- ###*
1751
- * Layer
1752
- * @constructor Layer
1753
- * @param {Object} options - layer parameters
1754
- ###
1755
- constructor: (options)->
1756
- @options = {}
1757
- if options?
1758
- @options.resourceType = options["resource_type"]
1759
- @options.type = options["type"]
1760
- @options.publicId = options["public_id"]
1761
- @options.format = options["format"]
1762
-
1763
- resourceType: (value)->
1764
- @options.resourceType = value
1765
- @
1766
-
1767
- type: (value)->
1768
- @options.type = value
1769
- @
1770
-
1771
- publicId: (value)->
1772
- @options.publicId = value
1773
- @
1774
-
1775
- ###*
1776
- * Get the public ID, formatted for layer parameter
1777
- * @function Layer#getPublicId
1778
- * @return {String} public ID
1779
- ###
1780
- getPublicId: ()->
1781
- @options.publicId?.replace(/\//g, ":")
1782
-
1783
- ###*
1784
- * Get the public ID, with format if present
1785
- * @function Layer#getFullPublicId
1786
- * @return {String} public ID
1787
- ###
1788
- getFullPublicId: ()->
1789
- if @options.format?
1790
- @getPublicId() + "." + @options.format
1791
- else
1792
- @getPublicId()
1793
-
1794
- format: (value)->
1795
- @options.format = value
1796
- @
1797
-
1798
- ###*
1799
- * generate the string representation of the layer
1800
- * @function Layer#toString
1801
- ###
1802
- toString: ()->
1803
- components = []
1804
-
1805
- throw "Must supply publicId" unless @options.publicId?
1806
- components.push(@options.resourceType) unless (@options.resourceType == "image")
1807
- components.push(@options.type) unless (@options.type == "upload")
1808
-
1809
- components.push(@getFullPublicId())
1810
-
1811
- Util.compact(components).join( ":")
1812
- class TextLayer extends Layer
1813
- ###*
1814
- * @constructor TextLayer
1815
- * @param {Object} options - layer parameters
1816
- ###
1817
- constructor: (options)->
1818
- super(options)
1819
- @options.resourceType = "text"
1820
-
1821
-
1822
- resourceType: (resourceType)->
1823
- throw "Cannot modify resourceType for text layers"
1824
-
1825
- type: (type)->
1826
- throw "Cannot modify type for text layers"
1827
-
1828
- format: (format)->
1829
- throw "Cannot modify format for text layers"
1830
-
1831
- fontFamily: (fontFamily)->
1832
- @options.fontFamily = fontFamily
1833
- @
1834
-
1835
- fontSize: (fontSize)->
1836
- @options.fontSize = fontSize
1837
- @
1838
-
1839
- fontWeight: (fontWeight)->
1840
- @options.fontWeight = fontWeight
1841
- @
1842
-
1843
- fontStyle: (fontStyle)->
1844
- @options.fontStyle = fontStyle
1845
- @
1846
-
1847
- textDecoration: (textDecoration)->
1848
- @options.textDecoration = textDecoration
1849
- @
1850
-
1851
- textAlign: (textAlign)->
1852
- @options.textAlign = textAlign
1853
- @
1854
-
1855
- stroke: (stroke)->
1856
- @options.stroke = stroke
1857
- @
1858
-
1859
- letterSpacing: (letterSpacing)->
1860
- @options.letterSpacing = letterSpacing
1861
- @
1862
-
1863
- lineSpacing: (lineSpacing)->
1864
- @options.lineSpacing = lineSpacing
1865
- @
1866
-
1867
- text: (text)->
1868
- @options.text = text
1869
- @
1870
-
1871
- ###*
1872
- * generate the string representation of the layer
1873
- * @function TextLayer#toString
1874
- * @return {String}
1875
- ###
1876
- toString: ()->
1877
- if @options.publicId?
1878
- publicId = @getFullPublicId()
1879
- else if @options.text?
1880
- text = encodeURIComponent(@options.text).replace(/%2C/g, "%E2%80%9A").replace(/\//g, "%E2%81%84")
1881
- else
1882
- throw "Must supply either text or public_id."
1883
-
1884
- components = [@options.resourceType, textStyleIdentifier.call(@), publicId, text]
1885
- return Util.compact(components).join( ":")
1886
-
1887
- textStyleIdentifier = ()->
1888
- components = []
1889
- components.push(@options.fontWeight) unless @options.fontWeight == "normal"
1890
- components.push(@options.fontStyle) unless @options.fontStyle == "normal"
1891
- components.push(@options.textDecoration) unless @options.textDecoration == "none"
1892
- components.push(@options.textAlign)
1893
- components.push(@options.stroke) unless @options.stroke =="none"
1894
- components.push("letter_spacing_" + @options.letterSpacing) unless Util.isEmpty(@options.letterSpacing)
1895
- components.push("line_spacing_" + @options.lineSpacing) if @options.lineSpacing?
1896
- fontSize = "" + @options.fontSize if @options.fontSize?
1897
- components.unshift(@options.fontFamily, fontSize)
1898
-
1899
- components = Util.compact(components).join("_")
1900
-
1901
- unless Util.isEmpty(components)
1902
- throw "Must supply fontFamily." if Util.isEmpty(@options.fontFamily)
1903
- throw "Must supply fontSize." if Util.isEmpty(fontSize)
1904
-
1905
- return components
1906
-
1907
- class SubtitlesLayer extends TextLayer
1908
- ###*
1909
- * Represent a subtitles layer
1910
- * @constructor SubtitlesLayer
1911
- * @param {Object} options - layer parameters
1912
- ###
1913
- constructor: (options)->
1914
- super(options)
1915
- @options.resourceType = "subtitles"
1916
-
1917
- class Cloudinary
1918
- VERSION = "2.0.9"
1919
- CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net"
1920
- OLD_AKAMAI_SHARED_CDN = "cloudinary-a.akamaihd.net"
1921
- AKAMAI_SHARED_CDN = "res.cloudinary.com"
1922
- SHARED_CDN = AKAMAI_SHARED_CDN
1923
- DEFAULT_POSTER_OPTIONS = { format: 'jpg', resource_type: 'video' }
1924
- DEFAULT_VIDEO_SOURCE_TYPES = ['webm', 'mp4', 'ogv']
1925
-
1926
- ###*
1927
- * @const {Object} Cloudinary.DEFAULT_IMAGE_PARAMS
1928
- * Defaults values for image parameters.
1929
- *
1930
- * (Previously defined using option_consume() )
1931
- ###
1932
- @DEFAULT_IMAGE_PARAMS =
1933
- resource_type: "image"
1934
- transformation: []
1935
- type: 'upload'
1936
-
1937
- ###*
1938
- * Defaults values for video parameters.
1939
- * @const {Object} Cloudinary.DEFAULT_VIDEO_PARAMS
1940
- * (Previously defined using option_consume() )
1941
- ###
1942
- @DEFAULT_VIDEO_PARAMS =
1943
- fallback_content: ''
1944
- resource_type: "video"
1945
- source_transformation: {}
1946
- source_types: DEFAULT_VIDEO_SOURCE_TYPES
1947
- transformation: []
1948
- type: 'upload'
1949
-
1950
- ###*
1951
- * Main Cloudinary class
1952
- * @class Cloudinary
1953
- * @param {Object} options - options to configure Cloudinary
1954
- * @see Configuration for more details
1955
- * @example
1956
- * var cl = new cloudinary.Cloudinary( { cloud_name: "mycloud"});
1957
- * var imgTag = cl.image("myPicID");
1958
- ###
1959
- constructor: (options)->
1960
-
1961
- @devicePixelRatioCache= {}
1962
- @responsiveConfig= {}
1963
- @responsiveResizeInitialized= false
1964
-
1965
- configuration = new Configuration(options)
1966
-
1967
- # Provided for backward compatibility
1968
- @config= (newConfig, newValue) ->
1969
- configuration.config(newConfig, newValue)
1970
-
1971
- ###*
1972
- * Use \<meta\> tags in the document to configure this Cloudinary instance.
1973
- * @return {Cloudinary} this for chaining
1974
- ###
1975
- @fromDocument = ()->
1976
- configuration.fromDocument()
1977
- @
1978
-
1979
-
1980
- ###*
1981
- * Use environment variables to configure this Cloudinary instance.
1982
- * @return {Cloudinary} this for chaining
1983
- ###
1984
- @fromEnvironment = ()->
1985
- configuration.fromEnvironment()
1986
- @
1987
-
1988
- ###*
1989
- * Initialize configuration.
1990
- * @function Cloudinary#init
1991
- * @see Configuration#init
1992
- * @return {Cloudinary} this for chaining
1993
- ###
1994
- @init = ()->
1995
- configuration.init()
1996
- @
1997
-
1998
- ###*
1999
- * Convenience constructor
2000
- * @param {Object} options
2001
- * @return {Cloudinary}
2002
- * @example cl = cloudinary.Cloudinary.new( { cloud_name: "mycloud"})
2003
- ###
2004
- @new = (options)-> new @(options)
2005
-
2006
- ###*
2007
- * Return the resource type and action type based on the given configuration
2008
- * @function Cloudinary#finalizeResourceType
2009
- * @param {Object|string} resourceType
2010
- * @param {string} [type='upload']
2011
- * @param {string} [urlSuffix]
2012
- * @param {boolean} [useRootPath]
2013
- * @param {boolean} [shorten]
2014
- * @returns {string} resource_type/type
2015
- * @ignore
2016
- ###
2017
- finalizeResourceType = (resourceType,type,urlSuffix,useRootPath,shorten) ->
2018
- if Util.isPlainObject(resourceType)
2019
- options = resourceType
2020
- resourceType = options.resource_type
2021
- type = options.type
2022
- urlSuffix = options.url_suffix
2023
- useRootPath = options.use_root_path
2024
- shorten = options.shorten
2025
-
2026
- type?='upload'
2027
- if urlSuffix?
2028
- if resourceType=='image' && type=='upload'
2029
- resourceType = "images"
2030
- type = null
2031
- else if resourceType== 'raw' && type== 'upload'
2032
- resourceType = 'files'
2033
- type = null
2034
- else
2035
- throw new Error("URL Suffix only supported for image/upload and raw/upload")
2036
- if useRootPath
2037
- if (resourceType== 'image' && type== 'upload' || resourceType == "images")
2038
- resourceType = null
2039
- type = null
2040
- else
2041
- throw new Error("Root path only supported for image/upload")
2042
- if shorten && resourceType== 'image' && type== 'upload'
2043
- resourceType = 'iu'
2044
- type = null
2045
- [resourceType,type].join("/")
2046
-
2047
- absolutize = (url) ->
2048
- if !url.match(/^https?:\//)
2049
- prefix = document.location.protocol + '//' + document.location.host
2050
- if url[0] == '?'
2051
- prefix += document.location.pathname
2052
- else if url[0] != '/'
2053
- prefix += document.location.pathname.replace(/\/[^\/]*$/, '/')
2054
- url = prefix + url
2055
- url
2056
-
2057
- ###*
2058
- * Generate an resource URL.
2059
- * @function Cloudinary#url
2060
- * @param {string} publicId - the public ID of the resource
2061
- * @param {Object} [options] - options for the tag and transformations, possible values include all {@link Transformation} parameters
2062
- * and {@link Configuration} parameters
2063
- * @param {string} [options.type='upload'] - the classification of the resource
2064
- * @param {Object} [options.resource_type='image'] - the type of the resource
2065
- * @return {string} The resource URL
2066
- ###
2067
-
2068
- url: (publicId, options = {}) ->
2069
- if (!publicId)
2070
- return publicId
2071
- options = options.toOptions() if options instanceof Transformation
2072
- options = Util.defaults({}, options, @config(), Cloudinary.DEFAULT_IMAGE_PARAMS)
2073
- if options.type == 'fetch'
2074
- options.fetch_format = options.fetch_format or options.format
2075
- publicId = absolutize(publicId)
2076
-
2077
- transformation = new Transformation(options)
2078
- transformationString = transformation.serialize()
2079
-
2080
- throw 'Unknown cloud_name' unless options.cloud_name
2081
-
2082
- throw 'URL Suffix only supported in private CDN' if options.url_suffix and !options.private_cdn
2083
-
2084
- # if publicId has a '/' and doesn't begin with v<number> and doesn't start with http[s]:/ and version is empty
2085
- if publicId.search('/') >= 0 and !publicId.match(/^v[0-9]+/) and !publicId.match(/^https?:\//) and !options.version?.toString()
2086
- options.version = 1
2087
-
2088
- if publicId.match(/^https?:/)
2089
- if options.type == 'upload' or options.type == 'asset'
2090
- url = publicId
2091
- else
2092
- publicId = encodeURIComponent(publicId).replace(/%3A/g, ':').replace(/%2F/g, '/')
2093
- else
2094
- # Make sure publicId is URI encoded.
2095
- publicId = encodeURIComponent(decodeURIComponent(publicId)).replace(/%3A/g, ':').replace(/%2F/g, '/')
2096
- if options.url_suffix
2097
- if options.url_suffix.match(/[\.\/]/)
2098
- throw 'url_suffix should not include . or /'
2099
- publicId = publicId + '/' + options.url_suffix
2100
- if options.format
2101
- if !options.trust_public_id
2102
- publicId = publicId.replace(/\.(jpg|png|gif|webp)$/, '')
2103
- publicId = publicId + '.' + options.format
2104
-
2105
- prefix = cloudinaryUrlPrefix(publicId, options)
2106
- resourceTypeAndType = finalizeResourceType(options.resource_type, options.type, options.url_suffix, options.use_root_path, options.shorten)
2107
- version = if options.version then 'v' + options.version else ''
2108
-
2109
- url || Util.compact([
2110
- prefix
2111
- resourceTypeAndType
2112
- transformationString
2113
- version
2114
- publicId
2115
- ]).join('/').replace(/([^:])\/+/g, '$1/')
2116
-
2117
- ###*
2118
- * Generate an video resource URL.
2119
- * @function Cloudinary#video_url
2120
- * @param {string} publicId - the public ID of the resource
2121
- * @param {Object} [options] - options for the tag and transformations, possible values include all {@link Transformation} parameters
2122
- * and {@link Configuration} parameters
2123
- * @param {string} [options.type='upload'] - the classification of the resource
2124
- * @return {string} The video URL
2125
- ###
2126
- video_url: (publicId, options) ->
2127
- options = Util.assign({ resource_type: 'video' }, options)
2128
- @url(publicId, options)
2129
-
2130
- ###*
2131
- * Generate an video thumbnail URL.
2132
- * @function Cloudinary#video_thumbnail_url
2133
- * @param {string} publicId - the public ID of the resource
2134
- * @param {Object} [options] - options for the tag and transformations, possible values include all {@link Transformation} parameters
2135
- * and {@link Configuration} parameters
2136
- * @param {string} [options.type='upload'] - the classification of the resource
2137
- * @return {string} The video thumbnail URL
2138
- ###
2139
- video_thumbnail_url: (publicId, options) ->
2140
- options = Util.assign({}, DEFAULT_POSTER_OPTIONS, options)
2141
- @url(publicId, options)
2142
-
2143
- ###*
2144
- * Generate a string representation of the provided transformation options.
2145
- * @function Cloudinary#transformation_string
2146
- * @param {Object} options - the transformation options
2147
- * @returns {string} The transformation string
2148
- ###
2149
- transformation_string: (options) ->
2150
- new Transformation( options).serialize()
2151
-
2152
- ###*
2153
- * Generate an image tag.
2154
- * @function Cloudinary#image
2155
- * @param {string} publicId - the public ID of the image
2156
- * @param {Object} [options] - options for the tag and transformations
2157
- * @return {HTMLImageElement} an image tag element
2158
- ###
2159
- image: (publicId, options={}) ->
2160
- img = @imageTag(publicId, options)
2161
- # src must be removed before creating the DOM element to avoid loading the image
2162
- img.setAttr("src", '') unless options.src?
2163
- img = img.toDOM()
2164
- # cache the image src
2165
- Util.setData(img, 'src-cache', @url(publicId, options))
2166
- # set image src taking responsiveness in account
2167
- @cloudinary_update(img, options)
2168
- img
2169
-
2170
- ###*
2171
- * Creates a new ImageTag instance, configured using this own's configuration.
2172
- * @function Cloudinary#imageTag
2173
- * @param {string} publicId - the public ID of the resource
2174
- * @param {Object} options - additional options to pass to the new ImageTag instance
2175
- * @return {ImageTag} An ImageTag that is attached (chained) to this Cloudinary instance
2176
- ###
2177
- imageTag: (publicId, options)->
2178
- tag = new ImageTag(publicId, @config())
2179
- tag.transformation().fromOptions( options)
2180
- tag
2181
-
2182
- ###*
2183
- * Generate an image tag for the video thumbnail.
2184
- * @function Cloudinary#video_thumbnail
2185
- * @param {string} publicId - the public ID of the video
2186
- * @param {Object} [options] - options for the tag and transformations
2187
- * @return {HTMLImageElement} An image tag element
2188
- ###
2189
- video_thumbnail: (publicId, options) ->
2190
- @image publicId, Util.merge( {}, DEFAULT_POSTER_OPTIONS, options)
2191
-
2192
- ###*
2193
- * @function Cloudinary#facebook_profile_image
2194
- * @param {string} publicId - the public ID of the image
2195
- * @param {Object} [options] - options for the tag and transformations
2196
- * @return {HTMLImageElement} an image tag element
2197
- ###
2198
- facebook_profile_image: (publicId, options) ->
2199
- @image publicId, Util.assign({type: 'facebook'}, options)
2200
-
2201
- ###*
2202
- * @function Cloudinary#twitter_profile_image
2203
- * @param {string} publicId - the public ID of the image
2204
- * @param {Object} [options] - options for the tag and transformations
2205
- * @return {HTMLImageElement} an image tag element
2206
- ###
2207
- twitter_profile_image: (publicId, options) ->
2208
- @image publicId, Util.assign({type: 'twitter'}, options)
2209
-
2210
- ###*
2211
- * @function Cloudinary#twitter_name_profile_image
2212
- * @param {string} publicId - the public ID of the image
2213
- * @param {Object} [options] - options for the tag and transformations
2214
- * @return {HTMLImageElement} an image tag element
2215
- ###
2216
- twitter_name_profile_image: (publicId, options) ->
2217
- @image publicId, Util.assign({type: 'twitter_name'}, options)
2218
-
2219
- ###*
2220
- * @function Cloudinary#gravatar_image
2221
- * @param {string} publicId - the public ID of the image
2222
- * @param {Object} [options] - options for the tag and transformations
2223
- * @return {HTMLImageElement} an image tag element
2224
- ###
2225
- gravatar_image: (publicId, options) ->
2226
- @image publicId, Util.assign({type: 'gravatar'}, options)
2227
-
2228
- ###*
2229
- * @function Cloudinary#fetch_image
2230
- * @param {string} publicId - the public ID of the image
2231
- * @param {Object} [options] - options for the tag and transformations
2232
- * @return {HTMLImageElement} an image tag element
2233
- ###
2234
- fetch_image: (publicId, options) ->
2235
- @image publicId, Util.assign({type: 'fetch'}, options)
2236
-
2237
- ###*
2238
- * @function Cloudinary#video
2239
- * @param {string} publicId - the public ID of the image
2240
- * @param {Object} [options] - options for the tag and transformations
2241
- * @return {HTMLImageElement} an image tag element
2242
- ###
2243
- video: (publicId, options = {}) ->
2244
- @videoTag(publicId, options).toHtml()
2245
-
2246
- ###*
2247
- * Creates a new VideoTag instance, configured using this own's configuration.
2248
- * @function Cloudinary#videoTag
2249
- * @param {string} publicId - the public ID of the resource
2250
- * @param {Object} options - additional options to pass to the new VideoTag instance
2251
- * @return {VideoTag} A VideoTag that is attached (chained) to this Cloudinary instance
2252
- ###
2253
- videoTag: (publicId, options)->
2254
- options = Util.defaults({}, options, @config())
2255
- new VideoTag(publicId, options)
2256
-
2257
- ###*
2258
- * Generate the URL of the sprite image
2259
- * @function Cloudinary#sprite_css
2260
- * @param {string} publicId - the public ID of the resource
2261
- * @param {Object} [options] - options for the tag and transformations
2262
- * @see {@link http://cloudinary.com/documentation/sprite_generation Sprite generation}
2263
- ###
2264
- sprite_css: (publicId, options) ->
2265
- options = Util.assign({ type: 'sprite' }, options)
2266
- if !publicId.match(/.css$/)
2267
- options.format = 'css'
2268
- @url publicId, options
2269
-
2270
- ###*
2271
- * @function Cloudinary#responsive
2272
- ###
2273
- responsive: (options, bootstrap = true) ->
2274
- @responsiveConfig = Util.merge(@responsiveConfig or {}, options)
2275
- responsiveClass = @responsiveConfig['responsive_class'] ? @config('responsive_class')
2276
- @cloudinary_update( "img.#{responsiveClass}, img.cld-hidpi", @responsiveConfig) if bootstrap
2277
- responsiveResize = @responsiveConfig['responsive_resize'] ? @config('responsive_resize') ? true
2278
- if responsiveResize and !@responsiveResizeInitialized
2279
- @responsiveConfig.resizing = @responsiveResizeInitialized = true
2280
- timeout = null
2281
- window.addEventListener 'resize', =>
2282
- debounce = @responsiveConfig['responsive_debounce'] ? @config('responsive_debounce') ? 100
2283
-
2284
- reset = ->
2285
- if timeout
2286
- clearTimeout timeout
2287
- timeout = null
2288
-
2289
- run = =>
2290
- @cloudinary_update "img.#{responsiveClass}", @responsiveConfig
2291
-
2292
- waitFunc = ()->
2293
- reset()
2294
- run()
2295
-
2296
- wait = ->
2297
- reset()
2298
- timeout = setTimeout(waitFunc,debounce)
2299
- if debounce
2300
- wait()
2301
- else
2302
- run()
2303
-
2304
- ###*
2305
- * @function Cloudinary#calc_breakpoint
2306
- * @private
2307
- * @ignore
2308
- ###
2309
- calc_breakpoint: (element, width) ->
2310
- breakpoints = Util.getData(element, 'breakpoints') or Util.getData(element, 'stoppoints') or @config('breakpoints') or @config('stoppoints') or defaultBreakpoints
2311
- if Util.isFunction breakpoints
2312
- breakpoints(width)
2313
- else
2314
- if Util.isString breakpoints
2315
- breakpoints = (parseInt(point) for point in breakpoints.split(',')).sort((a, b) -> a - b)
2316
- closestAbove breakpoints, width
2317
-
2318
- ###*
2319
- * @function Cloudinary#calc_stoppoint
2320
- * @deprecated Use {@link calc_breakpoint} instead.
2321
- * @private
2322
- * @ignore
2323
- ###
2324
- calc_stoppoint: @::calc_breakpoint
2325
-
2326
- ###*
2327
- * @function Cloudinary#device_pixel_ratio
2328
- * @private
2329
- ###
2330
- device_pixel_ratio: (roundDpr = true)->
2331
- dpr = window?.devicePixelRatio or 1
2332
- dpr = Math.ceil(dpr) if roundDpr
2333
- if( dpr <= 0 || dpr == NaN)
2334
- dpr = 1
2335
- dprString = dpr.toString()
2336
- if dprString.match(/^\d+$/)
2337
- dprString += '.0'
2338
- dprString
2339
-
2340
- defaultBreakpoints = (width) ->
2341
- 100 * Math.ceil(width / 100)
2342
-
2343
- closestAbove = (list, value) ->
2344
- i = list.length - 2
2345
- while i >= 0 and list[i] >= value
2346
- i--
2347
- list[i + 1]
2348
-
2349
- # Produce a number between 1 and 5 to be used for cdn sub domains designation
2350
- cdnSubdomainNumber = (publicId)->
2351
- crc32(publicId) % 5 + 1
2352
-
2353
- # * cdn_subdomain - Boolean (default: false). Whether to automatically build URLs with multiple CDN sub-domains. See this blog post for more details.
2354
- # * private_cdn - Boolean (default: false). Should be set to true for Advanced plan's users that have a private CDN distribution.
2355
- # * secure_distribution - The domain name of the CDN distribution to use for building HTTPS URLs. Relevant only for Advanced plan's users that have a private CDN distribution.
2356
- # * cname - Custom domain name to use for building HTTP URLs. Relevant only for Advanced plan's users that have a private CDN distribution and a custom CNAME.
2357
- # * secure - Boolean (default: false). Force HTTPS URLs of images even if embedded in non-secure HTTP pages.
2358
- cloudinaryUrlPrefix = (publicId, options) ->
2359
- return '/res'+options.cloud_name if options.cloud_name?.indexOf("/")==0
2360
-
2361
- # defaults
2362
- protocol = "http://"
2363
- cdnPart = ""
2364
- subdomain = "res"
2365
- host = ".cloudinary.com"
2366
- path = "/" + options.cloud_name
2367
-
2368
- # modifications
2369
- if options.protocol
2370
- protocol = options.protocol + '//'
2371
-
2372
- if options.private_cdn
2373
- cdnPart = options.cloud_name + "-"
2374
- path = ""
2375
-
2376
- if options.cdn_subdomain
2377
- subdomain = "res-" + cdnSubdomainNumber(publicId)
2378
-
2379
- if options.secure
2380
- protocol = "https://"
2381
- subdomain = "res" if options.secure_cdn_subdomain == false
2382
- if options.secure_distribution? && options.secure_distribution != OLD_AKAMAI_SHARED_CDN && options.secure_distribution != SHARED_CDN
2383
- cdnPart = ""
2384
- subdomain = ""
2385
- host = options.secure_distribution
2386
-
2387
- else if options.cname
2388
- protocol = "http://"
2389
- cdnPart = ""
2390
- subdomain = if options.cdn_subdomain then 'a'+((crc32(publicId)%5)+1)+'.' else ''
2391
- host = options.cname
2392
-
2393
- [protocol, cdnPart, subdomain, host, path].join("")
2394
-
2395
-
2396
- ###*
2397
- * Finds all `img` tags under each node and sets it up to provide the image through Cloudinary
2398
- * @function Cloudinary#processImageTags
2399
- ###
2400
- processImageTags: (nodes, options = {}) ->
2401
- # similar to `$.fn.cloudinary`
2402
- options = Util.defaults({}, options, @config())
2403
- images = for node in nodes when node.tagName?.toUpperCase() == 'IMG'
2404
- imgOptions = Util.assign(
2405
- {
2406
- width: node.getAttribute('width')
2407
- height: node.getAttribute('height')
2408
- src: node.getAttribute('src')
2409
- }, options)
2410
- publicId = imgOptions['source'] || imgOptions['src']
2411
- delete imgOptions['source']
2412
- delete imgOptions['src']
2413
- url = @url(publicId, imgOptions)
2414
- imgOptions = new Transformation(imgOptions).toHtmlAttributes()
2415
- Util.setData(node, 'src-cache', url)
2416
- node.setAttribute('width', imgOptions.width)
2417
- node.setAttribute('height', imgOptions.height)
2418
-
2419
- @cloudinary_update( images, options)
2420
- this
2421
-
2422
- applyBreakpoints = (tag, width, options)->
2423
- responsive_use_breakpoints = options['responsive_use_breakpoints'] ? options['responsive_use_stoppoints'] ? @config('responsive_use_breakpoints') ? @config('responsive_use_stoppoints')
2424
- if (!responsive_use_breakpoints) || (responsive_use_breakpoints == 'resize' and !options.resizing)
2425
- width
2426
- else
2427
- @calc_breakpoint(tag, width)
2428
-
2429
- parentWidth = (element) ->
2430
- containerWidth = 0
2431
- while ((element = element?.parentNode) instanceof Element) and !containerWidth
2432
- style = window.getComputedStyle(element);
2433
- containerWidth = Util.width(element) unless /^inline/.test(style.display)
2434
- containerWidth
2435
-
2436
- ###*
2437
- * Update hidpi (dpr_auto) and responsive (w_auto) fields according to the current container size and the device pixel ratio.
2438
- * Only images marked with the cld-responsive class have w_auto updated.
2439
- * @function Cloudinary#cloudinary_update
2440
- * @param {(Array|string|NodeList)} elements - the elements to modify
2441
- * @param {Object} options
2442
- * @param {boolean|string} [options.responsive_use_breakpoints=true]
2443
- * - when `true`, always use breakpoints for width
2444
- * - when `"resize"` use exact width on first render and breakpoints on resize
2445
- * - when `false` always use exact width
2446
- * @param {boolean} [options.responsive] - if `true`, enable responsive on this element. Can be done by adding cld-responsive.
2447
- * @param {boolean} [options.responsive_preserve_height] - if set to true, original css height is preserved.
2448
- * Should only be used if the transformation supports different aspect ratios.
2449
- ###
2450
- cloudinary_update: (elements, options = {}) ->
2451
- elements = switch
2452
- when Util.isArray(elements)
2453
- elements
2454
- when elements.constructor.name == "NodeList"
2455
- elements
2456
- when Util.isString(elements)
2457
- document.querySelectorAll(elements)
2458
- else
2459
- [elements]
2460
-
2461
- responsiveClass = @responsiveConfig['responsive_class'] ? options['responsive_class'] ? @config('responsive_class')
2462
- roundDpr = options['round_dpr'] ? @config('round_dpr')
2463
-
2464
- for tag in elements when tag.tagName?.match(/img/i)
2465
- setUrl = true
2466
- if options.responsive
2467
- Util.addClass(tag, responsiveClass)
2468
- src = Util.getData(tag, 'src-cache') or Util.getData(tag, 'src')
2469
- unless Util.isEmpty(src)
2470
- # Update dpr according to the device's devicePixelRatio
2471
- src = src.replace(/\bdpr_(1\.0|auto)\b/g, 'dpr_' + @device_pixel_ratio(roundDpr))
2472
- if Util.hasClass(tag, responsiveClass) and /\bw_auto\b/.exec(src)
2473
- containerWidth = parentWidth(tag)
2474
- if containerWidth != 0
2475
- requestedWidth = applyBreakpoints.call(this, tag, containerWidth, options)
2476
-
2477
- imageWidth = Util.getData(tag, 'width') or 0
2478
- if requestedWidth > imageWidth
2479
- imageWidth = requestedWidth
2480
- Util.setData(tag, 'width', requestedWidth)
2481
-
2482
- # tag.style.setProperty("max-width", requestedWidth)
2483
- src = src.replace(/\bw_auto\b/g, 'w_' + imageWidth)
2484
-
2485
- Util.removeAttribute(tag, 'width')
2486
- Util.removeAttribute(tag, 'height') unless options.responsive_preserve_height
2487
- else
2488
- # Container doesn't know the size yet - usually because the image is hidden or outside the DOM.
2489
- setUrl = false
2490
- Util.setAttribute(tag, 'src', src) if setUrl
2491
- this
2492
-
2493
- ###*
2494
- * Provide a transformation object, initialized with own's options, for chaining purposes.
2495
- * @function Cloudinary#transformation
2496
- * @param {Object} options
2497
- * @return {Transformation}
2498
- ###
2499
- transformation: (options)->
2500
- Transformation.new( @config()).fromOptions(options).setParent( this)
2501
-
2502
-
2503
- ###*
2504
- * Cloudinary jQuery plugin
2505
- * Depends on 'jquery', 'util', 'transformation', 'cloudinary'
2506
- ###
2507
- class CloudinaryJQuery extends Cloudinary
2508
- ###*
2509
- * Cloudinary class with jQuery support
2510
- * @constructor CloudinaryJQuery
2511
- * @extends Cloudinary
2512
- ###
2513
- constructor: (options)->
2514
- super(options)
2515
-
2516
- ###*
2517
- * @override
2518
- ###
2519
- image: (publicId, options={})->
2520
- # generate a tag without the image src
2521
- tag_options = Util.merge( {src: ''}, options)
2522
- img = @imageTag(publicId, tag_options).toHtml()
2523
- # cache the image src
2524
- url = @url(publicId, options)
2525
- # set image src taking responsiveness in account
2526
- jQuery(img).data('src-cache', url).cloudinary_update(options);
2527
-
2528
- ###*
2529
- * @override
2530
- ###
2531
- responsive: (options) ->
2532
- responsiveConfig = jQuery.extend(responsiveConfig or {}, options)
2533
- responsiveClass = @responsiveConfig['responsive_class'] ? @config('responsive_class')
2534
- jQuery("img.#{responsiveClass}, img.cld-hidpi").cloudinary_update responsiveConfig
2535
- responsive_resize = responsiveConfig['responsive_resize'] ? @config('responsive_resize') ? true
2536
- if responsive_resize and !responsiveResizeInitialized
2537
- responsiveConfig.resizing = responsiveResizeInitialized = true
2538
- timeout = null
2539
- jQuery(window).on 'resize', =>
2540
- debounce = responsiveConfig['responsive_debounce'] ? @config('responsive_debounce') ? 100
2541
-
2542
- reset = ->
2543
- if timeout
2544
- clearTimeout timeout
2545
- timeout = null
2546
-
2547
- run = ->
2548
- jQuery("img.#{responsiveClass}").cloudinary_update responsiveConfig
2549
-
2550
- wait = ->
2551
- reset()
2552
- setTimeout (->
2553
- reset()
2554
- run()
2555
- ), debounce
2556
-
2557
- if debounce
2558
- wait()
2559
- else
2560
- run()
2561
-
2562
- ###*
2563
- * The following methods are provided through the jQuery class
2564
- * @class jQuery
2565
- ###
2566
-
2567
- ###*
2568
- * Convert all img tags in the collection to utilize Cloudinary.
2569
- * @function jQuery#cloudinary
2570
- * @param {Object} [options] - options for the tag and transformations
2571
- * @returns {jQuery}
2572
- ###
2573
- jQuery.fn.cloudinary = (options) ->
2574
- @filter('img').each(->
2575
- img_options = jQuery.extend({
2576
- width: jQuery(this).attr('width')
2577
- height: jQuery(this).attr('height')
2578
- src: jQuery(this).attr('src')
2579
- }, jQuery(this).data(), options)
2580
- public_id = img_options.source || img_options.src
2581
- delete img_options.source
2582
- delete img_options.src
2583
- url = jQuery.cloudinary.url(public_id, img_options)
2584
- img_options = new Transformation(img_options).toHtmlAttributes()
2585
- jQuery(this).data('src-cache', url).attr
2586
- width: img_options.width
2587
- height: img_options.height
2588
- ).cloudinary_update options
2589
- this
2590
-
2591
-
2592
-
2593
- ###*
2594
- * Update hidpi (dpr_auto) and responsive (w_auto) fields according to the current container size and the device pixel ratio.
2595
- * Only images marked with the cld-responsive class have w_auto updated.
2596
- * options:
2597
- * - responsive_use_stoppoints:
2598
- * - true - always use stoppoints for width
2599
- * - "resize" - use exact width on first render and stoppoints on resize (default)
2600
- * - false - always use exact width
2601
- * - responsive:
2602
- * - true - enable responsive on this element. Can be done by adding cld-responsive.
2603
- * Note that jQuery.cloudinary.responsive() should be called once on the page.
2604
- * - responsive_preserve_height: if set to true, original css height is perserved. Should only be used if the transformation supports different aspect ratios.
2605
- ###
2606
-
2607
- jQuery.fn.cloudinary_update = (options = {}) ->
2608
- jQuery.cloudinary.cloudinary_update @filter('img').toArray(), options
2609
- this
2610
-
2611
- webp = null
2612
-
2613
- ###*
2614
- * @function jQuery#webpify
2615
- ###
2616
- jQuery.fn.webpify = (options = {}, webp_options) ->
2617
- that = this
2618
- webp_options = webp_options ? options
2619
- if !webp
2620
- webp = jQuery.Deferred()
2621
- webp_canary = new Image
2622
- webp_canary.onerror = webp.reject
2623
- webp_canary.onload = webp.resolve
2624
- webp_canary.src = 'data:image/webp;base64,UklGRi4AAABXRUJQVlA4TCEAAAAvAUAAEB8wAiMwAgSSNtse/cXjxyCCmrYNWPwmHRH9jwMA'
2625
- jQuery ->
2626
- webp.done(->
2627
- jQuery(that).cloudinary jQuery.extend({}, webp_options, format: 'webp')
2628
- ).fail ->
2629
- jQuery(that).cloudinary options
2630
- this
2631
-
2632
- jQuery.fn.fetchify = (options) ->
2633
- @cloudinary jQuery.extend(options, 'type': 'fetch')
2634
-
2635
- jQuery.cloudinary = new CloudinaryJQuery()
2636
- jQuery.cloudinary.fromDocument()
2637
-
2638
- ###*
2639
- * This module extends CloudinaryJquery to support jQuery File Upload
2640
- * Depends on 'jquery', 'util', 'cloudinaryjquery', 'jquery.ui.widget', 'jquery.iframe-transport','jquery.fileupload'
2641
- ###
2642
-
2643
- ###*
2644
- * Delete a resource using the upload token
2645
- * @function CloudinaryJQuery#delete_by_token
2646
- * @param {string} delete_token - the delete token
2647
- * @param {Object} [options]
2648
- * @param {string} [options.url] - an alternative URL to use for the API
2649
- * @param {string} [options.cloud_name] - an alternative cloud_name to use. This parameter is ignored if `options.url` is provided.
2650
- ###
2651
- CloudinaryJQuery::delete_by_token = (delete_token, options) ->
2652
- options = options or {}
2653
- url = options.url
2654
- if !url
2655
- cloud_name = options.cloud_name or jQuery.cloudinary.config().cloud_name
2656
- url = 'https://api.cloudinary.com/v1_1/' + cloud_name + '/delete_by_token'
2657
- dataType = if jQuery.support.xhrFileUpload then 'json' else 'iframe json'
2658
- jQuery.ajax
2659
- url: url
2660
- method: 'POST'
2661
- data: token: delete_token
2662
- headers: 'X-Requested-With': 'XMLHttpRequest'
2663
- dataType: dataType
2664
-
2665
- ###*
2666
- * Creates an `input` tag and sets it up to upload files to cloudinary
2667
- * @function CloudinaryJQuery#unsigned_upload_tag
2668
- * @param {string}
2669
- ###
2670
- CloudinaryJQuery::unsigned_upload_tag = (upload_preset, upload_params, options) ->
2671
- jQuery('<input/>').attr(
2672
- type: 'file'
2673
- name: 'file').unsigned_cloudinary_upload upload_preset, upload_params, options
2674
-
2675
- ###*
2676
- * Initialize the jQuery File Upload plugin to upload to Cloudinary
2677
- * @function jQuery#cloudinary_fileupload
2678
- * @param {Object} options
2679
- * @returns {jQuery}
2680
- ###
2681
- jQuery.fn.cloudinary_fileupload = (options) ->
2682
- return this unless Util.isFunction(jQuery.fn.fileupload)
2683
- initializing = !@data('blueimpFileupload')
2684
- if initializing
2685
- options = jQuery.extend({
2686
- maxFileSize: 20000000
2687
- dataType: 'json'
2688
- headers: 'X-Requested-With': 'XMLHttpRequest'
2689
- }, options)
2690
- @fileupload options
2691
- if initializing
2692
- @bind 'fileuploaddone', (e, data) ->
2693
- if data.result.error
2694
- return
2695
- data.result.path = [
2696
- 'v'
2697
- data.result.version
2698
- '/'
2699
- data.result.public_id
2700
- if data.result.format then '.' + data.result.format else ''
2701
- ].join('')
2702
- if data.cloudinaryField and data.form.length > 0
2703
- upload_info = [
2704
- data.result.resource_type
2705
- data.result.type
2706
- data.result.path
2707
- ].join('/') + '#' + data.result.signature
2708
- multiple = jQuery(e.target).prop('multiple')
2709
-
2710
- add_field = ->
2711
- jQuery('<input/>').attr(
2712
- type: 'hidden'
2713
- name: data.cloudinaryField).val(upload_info).appendTo data.form
2714
-
2715
-
2716
- if multiple
2717
- add_field()
2718
- else
2719
- field = jQuery(data.form).find('input[name="' + data.cloudinaryField + '"]')
2720
- if field.length > 0
2721
- field.val upload_info
2722
- else
2723
- add_field()
2724
- jQuery(e.target).trigger 'cloudinarydone', data
2725
-
2726
- @bind 'fileuploadsend', (e, data) ->
2727
- # add a common unique ID to all chunks of the same uploaded file
2728
- data.headers = $.extend({}, data.headers, {'X-Unique-Upload-Id': (Math.random() * 10000000000).toString(16)})
2729
- return true;
2730
-
2731
- @bind 'fileuploadstart', (e) ->
2732
- jQuery(e.target).trigger 'cloudinarystart'
2733
-
2734
- @bind 'fileuploadstop', (e) ->
2735
- jQuery(e.target).trigger 'cloudinarystop'
2736
-
2737
- @bind 'fileuploadprogress', (e, data) ->
2738
- jQuery(e.target).trigger 'cloudinaryprogress', data
2739
-
2740
- @bind 'fileuploadprogressall', (e, data) ->
2741
- jQuery(e.target).trigger 'cloudinaryprogressall', data
2742
-
2743
- @bind 'fileuploadfail', (e, data) ->
2744
- jQuery(e.target).trigger 'cloudinaryfail', data
2745
-
2746
- @bind 'fileuploadalways', (e, data) ->
2747
- jQuery(e.target).trigger 'cloudinaryalways', data
2748
-
2749
- if !@fileupload('option').url
2750
- cloud_name = options.cloud_name or jQuery.cloudinary.config().cloud_name
2751
- resource_type = options.resource_type or 'auto'
2752
- type = options.type or 'upload'
2753
- upload_url = 'https://api.cloudinary.com/v1_1/' + cloud_name + '/' + resource_type + '/' + type
2754
- @fileupload 'option', 'url', upload_url
2755
- this
2756
-
2757
- ###*
2758
- * Add a file to upload
2759
- * @function jQuery#cloudinary_upload_url
2760
- * @param {string} remote_url - the url to add
2761
- * @returns {jQuery}
2762
- ###
2763
- jQuery.fn.cloudinary_upload_url = (remote_url) ->
2764
- return this unless Util.isFunction(jQuery.fn.fileupload)
2765
- @fileupload('option', 'formData').file = remote_url
2766
- @fileupload 'add', files: [ remote_url ]
2767
- delete @fileupload('option', 'formData').file
2768
- this
2769
-
2770
- ###*
2771
- * Initialize the jQuery File Upload plugin to upload to Cloudinary using unsigned upload
2772
- * @function jQuery#unsigned_cloudinary_upload
2773
- * @param {string} upload_preset - the upload preset to use
2774
- * @param {Object} [upload_params] - parameters that should be past to the server
2775
- * @param {Object} [options]
2776
- * @returns {jQuery}
2777
- ###
2778
- jQuery.fn.unsigned_cloudinary_upload = (upload_preset, upload_params = {}, options = {}) ->
2779
- upload_params = Util.cloneDeep(upload_params)
2780
- options = Util.cloneDeep(options)
2781
- attrs_to_move = [
2782
- 'cloud_name'
2783
- 'resource_type'
2784
- 'type'
2785
- ]
2786
- i = 0
2787
- while i < attrs_to_move.length
2788
- attr = attrs_to_move[i]
2789
- if upload_params[attr]
2790
- options[attr] = upload_params[attr]
2791
- delete upload_params[attr]
2792
- i++
2793
- # Serialize upload_params
2794
- for key of upload_params
2795
- value = upload_params[key]
2796
- if Util.isPlainObject(value)
2797
- upload_params[key] = jQuery.map(value, (v, k) ->
2798
- k + '=' + v
2799
- ).join('|')
2800
- else if Util.isArray(value)
2801
- if value.length > 0 and jQuery.isArray(value[0])
2802
- upload_params[key] = jQuery.map(value, (array_value) ->
2803
- array_value.join ','
2804
- ).join('|')
2805
- else
2806
- upload_params[key] = value.join(',')
2807
- if !upload_params.callback
2808
- upload_params.callback = '/cloudinary_cors.html'
2809
- upload_params.upload_preset = upload_preset
2810
- options.formData = upload_params
2811
- if options.cloudinary_field
2812
- options.cloudinaryField = options.cloudinary_field
2813
- delete options.cloudinary_field
2814
- html_options = options.html or {}
2815
- html_options.class = Util.trim("cloudinary_fileupload #{html_options.class || ''}")
2816
- if options.multiple
2817
- html_options.multiple = true
2818
- @attr(html_options).cloudinary_fileupload options
2819
- this
2820
-
2821
- jQuery.cloudinary = new CloudinaryJQuery()
2822
-
2823
- cloudinary =
2824
- utf8_encode: utf8_encode
2825
- crc32: crc32
2826
- Util: Util
2827
- Condition: Condition
2828
- Transformation: Transformation
2829
- Configuration: Configuration
2830
- HtmlTag: HtmlTag
2831
- ImageTag: ImageTag
2832
- VideoTag: VideoTag
2833
- Layer: Layer
2834
- TextLayer: TextLayer
2835
- SubtitlesLayer: SubtitlesLayer
2836
- Cloudinary: Cloudinary
2837
- VERSION: "2.0.9"
2838
- CloudinaryJQuery: CloudinaryJQuery
2839
-
2840
- cloudinary
2841
- )