imglab 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78faee0a4ff6558f7ece0d993cac443de2b480e0c230a5586dc6fdbc8c6867db
4
- data.tar.gz: e6cbb31a3d1e86d8b54cc7c9985b10cd3555886d941ca66925b6752f8bacf51d
3
+ metadata.gz: 9b66cec4bc8fd3fb132c6deae52a45fee6282e40a15e31ba1c15a8fa54868705
4
+ data.tar.gz: 41a3f77bb418201e13167b89c86c03d59359061dd116381508cfb76517a8d462
5
5
  SHA512:
6
- metadata.gz: cb456e7d68b9e66ae072ec27f5232c455cd32f040b3b029dbd0d03362709f22bbd3c61a3b2d908589eff85ff28dde67ceba0c7dd2d12ccb458a121ac035c4974
7
- data.tar.gz: 4053ed5c372ad62d78bd0af9c8d762b0cd9a6dfa9cba6215328d59bfd73e75951b96c97986ee5657a455954d3fd09cc4d8ce91292edda7061a67b006e8e3c329
6
+ metadata.gz: d2a4c896cfdf4db54f0f2521cc50c085b87ca80ff49024341d8cc63c4be178edfdf1895b0075566c1636747d4db7cc23cb7a102d20c9e7f24b3d4beab9e7c683
7
+ data.tar.gz: 0e938c85258bf827bbf80dc93c330f994fcab7cb967ee882c6ae3ec37f05e4b7bd7e6c40e7fdac401e3738832d4b0728266ac3041650c2e37bc97849e21b6caf
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  Add this line to your application's Gemfile:
8
8
 
9
9
  ```ruby
10
- gem "imglab", "~> 0.2"
10
+ gem "imglab", "~> 0.3"
11
11
  ```
12
12
 
13
13
  And then execute:
@@ -24,7 +24,7 @@ $ gem install imglab
24
24
 
25
25
  ## Ruby compatibility
26
26
 
27
- `imglab` has been successfully tested on the following Ruby versions: `3.1`, `3.0`, `2.7`, `2.6`, `2.5`, `2.4`, `2.3`, `2.2`, `2.1` and `2.0`.
27
+ `imglab` has been successfully tested on the following Ruby versions: `3.2`, `3.1`, `3.0`, `2.7`, `2.6`, `2.5`, `2.4`, `2.3`, `2.2`, `2.1` and `2.0`.
28
28
 
29
29
  ## Generating URLs
30
30
 
@@ -178,7 +178,7 @@ Imglab.url("assets", "image.jpeg", width: 500, height: 500, mode: "crop", crop:
178
178
 
179
179
  ### Specifying URL parameters
180
180
 
181
- Some imglab parameters can receive URLs as values. It is possible to specify these parameter values as strings.
181
+ Some imglab parameters can receive URLs as values. It is possible to specify these parameter values as strings:
182
182
 
183
183
  ```ruby
184
184
  Imglab.url("assets", "image.jpeg", width: 500, height: 600, watermark: "logo.svg")
@@ -200,7 +200,7 @@ Imglab.url(
200
200
  "image.jpeg",
201
201
  width: 500,
202
202
  height: 600,
203
- watermark: Imglab.url("assets", "logo.svg", width: 100, format: "png")
203
+ watermark: Imglab.url("assets", "logo.svg", width: 100, format: :png)
204
204
  )
205
205
  "https://assets.imglab-cdn.net/image.jpeg?width=500&height=600&watermark=https%3A%2F%2Fassets.imglab-cdn.net%2Flogo.svg%3Fwidth%3D100%26format%3Dpng"
206
206
  ```
@@ -213,7 +213,7 @@ Imglab.url(
213
213
  "image.jpeg",
214
214
  width: 500,
215
215
  height: 600,
216
- watermark: Imglab.url("marketing", "logo.svg", width: 100, format: "png")
216
+ watermark: Imglab.url("marketing", "logo.svg", width: 100, format: :png)
217
217
  )
218
218
  "https://assets.imglab-cdn.net/image.jpeg?width=500&height=600&watermark=https%3A%2F%2Fmarketing.imglab-cdn.net%2Flogo.svg%3Fwidth%3D100%26format%3Dpng"
219
219
  ```
@@ -228,7 +228,7 @@ Imglab.url(
228
228
  "image.jpeg",
229
229
  width: 500,
230
230
  height: 600,
231
- watermark: Imglab.url(marketing_source, "logo.svg", width: 100, format: "png")
231
+ watermark: Imglab.url(marketing_source, "logo.svg", width: 100, format: :png)
232
232
  )
233
233
  ```
234
234
 
@@ -257,8 +257,8 @@ Imglab.url("assets", "image.jpeg", width: 500, expires: 1.hour.from_now)
257
257
  For on-premises imglab server is possible to define custom sources pointing to your server location.
258
258
 
259
259
  * `:https` - a `boolean` value specifying if the source should use https or not (default: `true`)
260
- * `:host` - a `string` specifying the host where the imglab server is located. (default: `imglab-cdn.net`)
261
- * `:port` - a `integer` specifying a port where the imglab server is located.
260
+ * `:host` - a `string` specifying the host where the imglab server is located. (default: `"imglab-cdn.net"`)
261
+ * `:port` - an `integer` specifying a port where the imglab server is located. (default: `nil`)
262
262
  * `:subdomains` - a `boolean` value specifying if the source should be specified using subdomains instead of using the path. (default: `true`)
263
263
 
264
264
  If we have our on-premises imglab server at `http://my-company.com:8080` with a source named `images` we can use the following source settings to access a `logo.png` image:
@@ -266,7 +266,7 @@ If we have our on-premises imglab server at `http://my-company.com:8080` with a
266
266
  ```ruby
267
267
  source = Imglab::Source.new("images", https: false, host: "my-company.com", port: 8080)
268
268
 
269
- Imglab.url(source, "logo.png", width: 300, height: 300, format: "png")
269
+ Imglab.url(source, "logo.png", width: 300, height: 300, format: :png)
270
270
  "http://images.my-company.com:8080/logo.png?width=300&height=300&format=png"
271
271
  ```
272
272
 
@@ -282,7 +282,7 @@ source = Imglab::Source.new(
282
282
  secure_salt: "images-secure-salt"
283
283
  )
284
284
 
285
- Imglab.url(source, "logo.png", width: 300, height: 300, format: "png")
285
+ Imglab.url(source, "logo.png", width: 300, height: 300, format: :png)
286
286
  "http://images.my-company.com:8080/logo.png?width=300&height=300&format=png&signature=generated-signature"
287
287
  ```
288
288
 
@@ -299,10 +299,309 @@ source = Imglab::Source.new(
299
299
  subdomains: false
300
300
  )
301
301
 
302
- Imglab.url(source, "logo.png", width: 300, height: 300, format: "png")
302
+ Imglab.url(source, "logo.png", width: 300, height: 300, format: :png)
303
303
  "http://my-company.com:8080/images/logo.png?width=300&height=300&format=png"
304
304
  ```
305
305
 
306
+ ## Generating srcsets
307
+
308
+ You can use `Imglab.srcset` function to generate custom string values for `srcset` attributes, to be used for Web responsive images inside an `<img>` HTML element or picture `<source>`.
309
+
310
+ This function works similarly to `Imglab.url`, expecting the same parameters and values, except for some specific query parameters that have a special meaning and can receive `Range` and arrays as values.
311
+
312
+ > To learn more about responsive images and the `srcset` attribute, you can take a look to the [MDN article about responsive images](https://developer.mozilla.org/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images).
313
+
314
+ ### Fixed size
315
+
316
+ When enough information is provided about the image output size (using `width` or `height` parameters), `srcset` function will generate URLs with a default sequence of device pixel ratios:
317
+
318
+ For the following example we are specying a fixed value of `500` pixels for `width` parameter:
319
+
320
+ ```ruby
321
+ Imglab.srcset("assets", "image.jpeg", width: 500)
322
+ ```
323
+
324
+ Generating the following output:
325
+
326
+ ```html
327
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=1 1x,
328
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=2 2x,
329
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=3 3x,
330
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=4 4x,
331
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=5 5x,
332
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=6 6x
333
+ ```
334
+
335
+ A very common practice consists in reducing the quality of images with high pixel density, decreasing the final file size. To achieve this you can optionally specify a Ruby `Range` value for `quality` parameter, gradually reducing the file size while increasing the image size.
336
+
337
+ In this example we are specifying a fixed `width` value of `500` pixels and a `quality` range between `80` and `40`:
338
+
339
+ ```ruby
340
+ Imglab.srcset("assets", "image.jpeg", width: 500, quality: 80..40)
341
+ ```
342
+
343
+ ```html
344
+ https://assets.imglab-cdn.net/image.jpeg?width=500&quality=80&dpr=1 1x,
345
+ https://assets.imglab-cdn.net/image.jpeg?width=500&quality=70&dpr=2 2x,
346
+ https://assets.imglab-cdn.net/image.jpeg?width=500&quality=61&dpr=3 3x,
347
+ https://assets.imglab-cdn.net/image.jpeg?width=500&quality=53&dpr=4 4x,
348
+ https://assets.imglab-cdn.net/image.jpeg?width=500&quality=46&dpr=5 5x,
349
+ https://assets.imglab-cdn.net/image.jpeg?width=500&quality=40&dpr=6 6x
350
+ ```
351
+
352
+ A custom `Range` value can be set for `dpr` parameter too, overriding the default sequence of generated dprs:
353
+
354
+ ```ruby
355
+ Imglab.srcset("assets", "image.jpeg", width: 500, dpr: 1..4)
356
+ ```
357
+
358
+ ```html
359
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=1 1x,
360
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=2 2x,
361
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=3 3x,
362
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=4 4x
363
+ ```
364
+
365
+ Using `Range` values for `dpr` and `quality` parameters in the same `srcset` call is also possible:
366
+
367
+ ```ruby
368
+ Imglab.srcset("assets", "image.jpeg", width: 500, dpr: 1..4, quality: 80..40)
369
+ ```
370
+
371
+ ```html
372
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=1&quality=80 1x,
373
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=2&quality=63 2x,
374
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=3&quality=50 3x,
375
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=4&quality=40 4x
376
+ ```
377
+
378
+ If necessary you can also use arrays with explicit values for `dpr` and `quality`:
379
+
380
+ ```ruby
381
+ Imglab.srcset("assets", "image.jpeg", width: 500, dpr: [1, 2, 3], quality: [80, 75, 60])
382
+ ```
383
+
384
+ ```html
385
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=1&quality=80 1x,
386
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=2&quality=75 2x,
387
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=3&quality=60 3x
388
+ ```
389
+
390
+ Or even use a specific `quality` value for all the URLs in the same srcset:
391
+
392
+ ```ruby
393
+ Imglab.srcset("assets", "image.jpeg", width: 500, dpr: [1, 2, 3], quality: 70)
394
+ ```
395
+
396
+ ```html
397
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=1&quality=70 1x,
398
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=2&quality=70 2x,
399
+ https://assets.imglab-cdn.net/image.jpeg?width=500&dpr=3&quality=70 3x
400
+ ```
401
+
402
+ ### Fluid width
403
+
404
+ When a specific sequence of widths is required you can use a `Range`, `sequence`, or array for `width` parameter.
405
+
406
+ When a `Range` value is used, a sequence with a default size of 16 URLs will be generated inside the specified interval:
407
+
408
+ ```ruby
409
+ Imglab.srcset("assets", "image.jpeg", width: 100..2000)
410
+ ```
411
+
412
+ ```html
413
+ https://assets.imglab-cdn.net/image.jpeg?width=100 100w,
414
+ https://assets.imglab-cdn.net/image.jpeg?width=122 122w,
415
+ https://assets.imglab-cdn.net/image.jpeg?width=149 149w,
416
+ https://assets.imglab-cdn.net/image.jpeg?width=182 182w,
417
+ https://assets.imglab-cdn.net/image.jpeg?width=222 222w,
418
+ https://assets.imglab-cdn.net/image.jpeg?width=271 271w,
419
+ https://assets.imglab-cdn.net/image.jpeg?width=331 331w,
420
+ https://assets.imglab-cdn.net/image.jpeg?width=405 405w,
421
+ https://assets.imglab-cdn.net/image.jpeg?width=494 494w,
422
+ https://assets.imglab-cdn.net/image.jpeg?width=603 603w,
423
+ https://assets.imglab-cdn.net/image.jpeg?width=737 737w,
424
+ https://assets.imglab-cdn.net/image.jpeg?width=900 900w,
425
+ https://assets.imglab-cdn.net/image.jpeg?width=1099 1099w,
426
+ https://assets.imglab-cdn.net/image.jpeg?width=1341 1341w,
427
+ https://assets.imglab-cdn.net/image.jpeg?width=1638 1638w,
428
+ https://assets.imglab-cdn.net/image.jpeg?width=2000 2000w
429
+ ```
430
+
431
+ If required you can specify a `Range` value for `quality` parameter too:
432
+
433
+ ```ruby
434
+ Imglab.srcset("assets", "image.jpeg", width: 100..2000, quality: 80..40)
435
+ ```
436
+
437
+ ```html
438
+ https://assets.imglab-cdn.net/image.jpeg?width=100&quality=80 100w,
439
+ https://assets.imglab-cdn.net/image.jpeg?width=122&quality=76 122w,
440
+ https://assets.imglab-cdn.net/image.jpeg?width=149&quality=73 149w,
441
+ https://assets.imglab-cdn.net/image.jpeg?width=182&quality=70 182w,
442
+ https://assets.imglab-cdn.net/image.jpeg?width=222&quality=66 222w,
443
+ https://assets.imglab-cdn.net/image.jpeg?width=271&quality=63 271w,
444
+ https://assets.imglab-cdn.net/image.jpeg?width=331&quality=61 331w,
445
+ https://assets.imglab-cdn.net/image.jpeg?width=405&quality=58 405w,
446
+ https://assets.imglab-cdn.net/image.jpeg?width=494&quality=55 494w,
447
+ https://assets.imglab-cdn.net/image.jpeg?width=603&quality=53 603w,
448
+ https://assets.imglab-cdn.net/image.jpeg?width=737&quality=50 737w,
449
+ https://assets.imglab-cdn.net/image.jpeg?width=900&quality=48 900w,
450
+ https://assets.imglab-cdn.net/image.jpeg?width=1099&quality=46 1099w,
451
+ https://assets.imglab-cdn.net/image.jpeg?width=1341&quality=44 1341w,
452
+ https://assets.imglab-cdn.net/image.jpeg?width=1638&quality=42 1638w,
453
+ https://assets.imglab-cdn.net/image.jpeg?width=2000&quality=40 2000w
454
+ ```
455
+
456
+ If you want to generate a sequence of numbers for `width` parameter with a specific number of URLs you can use `Imglab::Sequence` module helper:
457
+
458
+ ```ruby
459
+ # Remember to include Imglab::Sequence module before using sequence helper
460
+ include Imglab::Sequence
461
+
462
+ # Generating a srcset string with a sequence between 100 and 2000 pixels for width parameter with a size of 5 URLs
463
+ Imglab.srcset("assets", "image.jpeg", width: sequence(100, 2000, 5))
464
+ ```
465
+
466
+ ```html
467
+ https://assets.imglab-cdn.net/image.jpeg?width=100 100w,
468
+ https://assets.imglab-cdn.net/image.jpeg?width=211 211w,
469
+ https://assets.imglab-cdn.net/image.jpeg?width=447 447w,
470
+ https://assets.imglab-cdn.net/image.jpeg?width=946 946w,
471
+ https://assets.imglab-cdn.net/image.jpeg?width=2000 2000w
472
+ ```
473
+
474
+ Using an array with specific values will generate URLs only for those widths:
475
+
476
+ ```ruby
477
+ Imglab.srcset("assets", "image.jpeg", width: [100, 300, 500])
478
+ ```
479
+
480
+ ```html
481
+ https://assets.imglab-cdn.net/image.jpeg?width=100 100w,
482
+ https://assets.imglab-cdn.net/image.jpeg?width=300 300w,
483
+ https://assets.imglab-cdn.net/image.jpeg?width=500 500w
484
+ ```
485
+
486
+ It is also possible to specify an array of values for `height` and `quality` parameters:
487
+
488
+ ```ruby
489
+ Imglab.srcset("assets", "image.jpeg", width: [100, 300, 500], height: [200, 400, 600], quality: [75, 70, 65])
490
+ ```
491
+
492
+ ```html
493
+ https://assets.imglab-cdn.net/image.jpeg?width=100&height=200&quality=75 100w,
494
+ https://assets.imglab-cdn.net/image.jpeg?width=300&height=400&quality=70 300w,
495
+ https://assets.imglab-cdn.net/image.jpeg?width=500&height=600&quality=65 500w
496
+ ```
497
+
498
+ ### No size
499
+
500
+ When `srcset` function doesn't have information about the image output size (`width` or `height` parameters are not set) it will generate a default sequence of 16 URLs specifying a `width` value with an interval between `100` and `8192` pixels:
501
+
502
+ ```ruby
503
+ Imglab.srcset("assets", "image.jpeg")
504
+ ```
505
+
506
+ ```html
507
+ https://assets.imglab-cdn.net/image.jpeg?width=100 100w,
508
+ https://assets.imglab-cdn.net/image.jpeg?width=134 134w,
509
+ https://assets.imglab-cdn.net/image.jpeg?width=180 180w,
510
+ https://assets.imglab-cdn.net/image.jpeg?width=241 241w,
511
+ https://assets.imglab-cdn.net/image.jpeg?width=324 324w,
512
+ https://assets.imglab-cdn.net/image.jpeg?width=434 434w,
513
+ https://assets.imglab-cdn.net/image.jpeg?width=583 583w,
514
+ https://assets.imglab-cdn.net/image.jpeg?width=781 781w,
515
+ https://assets.imglab-cdn.net/image.jpeg?width=1048 1048w,
516
+ https://assets.imglab-cdn.net/image.jpeg?width=1406 1406w,
517
+ https://assets.imglab-cdn.net/image.jpeg?width=1886 1886w,
518
+ https://assets.imglab-cdn.net/image.jpeg?width=2530 2530w,
519
+ https://assets.imglab-cdn.net/image.jpeg?width=3394 3394w,
520
+ https://assets.imglab-cdn.net/image.jpeg?width=4553 4553w,
521
+ https://assets.imglab-cdn.net/image.jpeg?width=6107 6107w,
522
+ https://assets.imglab-cdn.net/image.jpeg?width=8192 8192w
523
+ ```
524
+
525
+ It is always possible to change this default behavior using `Imglab::Sequence` helper. In the following example we are specifying a sequence between `320` and `4096` pixels and generating 10 different URLs:
526
+
527
+ ```ruby
528
+ include Imglab::Sequence
529
+
530
+ Imglab.srcset("assets", "image.jpeg", width: sequence(320, 4096, 10))
531
+ ```
532
+
533
+ ```html
534
+ https://assets.imglab-cdn.net/image.jpeg?width=320 320w,
535
+ https://assets.imglab-cdn.net/image.jpeg?width=425 425w,
536
+ https://assets.imglab-cdn.net/image.jpeg?width=564 564w,
537
+ https://assets.imglab-cdn.net/image.jpeg?width=749 749w,
538
+ https://assets.imglab-cdn.net/image.jpeg?width=994 994w,
539
+ https://assets.imglab-cdn.net/image.jpeg?width=1319 1319w,
540
+ https://assets.imglab-cdn.net/image.jpeg?width=1751 1751w,
541
+ https://assets.imglab-cdn.net/image.jpeg?width=2324 2324w,
542
+ https://assets.imglab-cdn.net/image.jpeg?width=3086 3086w,
543
+ https://assets.imglab-cdn.net/image.jpeg?width=4096 4096w
544
+ ```
545
+
546
+ ### Image aspect ratio and srcset
547
+
548
+ A usual scenario is to generate multiple URLs while maintaining the same aspect ratio for all of them. If a specific image aspect ratio is required while using `srcset` function you can set a value to `aspect-ratio` parameter along with `mode` parameter using `crop`, `contain`, `face`, or `force` resize modes.
549
+
550
+ For the following example we are using a specific value of `300` pixels for `width` and an aspect ratio of `1:1` (square), cropping the image with `crop` resize mode and setting output format to `webp`:
551
+
552
+ ```ruby
553
+ Imglab.srcset("assets", "image.jpeg", width: 300, aspect_ratio: "1:1", mode: :crop, format: :webp)
554
+ ```
555
+
556
+ ```html
557
+ https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=1 1x,
558
+ https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=2 2x,
559
+ https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=3 3x,
560
+ https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=4 4x,
561
+ https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=5 5x,
562
+ https://assets.imglab-cdn.net/image.jpeg?width=300&aspect-ratio=1%3A1&mode=crop&format=webp&dpr=6 6x
563
+ ```
564
+
565
+ You can instead use `height` value. In this example we are specifying a fixed value of `300` pixels for `height` parameter, a `aspect-ratio` of `16:9` (widescreen) with `crop` resize mode, and `webp` output format:
566
+
567
+ ```ruby
568
+ Imglab.srcset("assets", "image.jpeg", height: 300, aspect_ratio: "16:9", mode: :crop, format: :webp)
569
+ ```
570
+
571
+ ```html
572
+ https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=1 1x,
573
+ https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=2 2x,
574
+ https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=3 3x,
575
+ https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=4 4x,
576
+ https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=5 5x,
577
+ https://assets.imglab-cdn.net/image.jpeg?height=300&aspect-ratio=16%3A9&mode=crop&format=webp&dpr=6 6x
578
+ ```
579
+
580
+ You can also use fluid values for `width` parameter while maintaining the same aspect ratio for all generated URLs. In this example, we are using a `range` value between `100` and `4096` for `width` parameter, a value of `1:1` for `aspect-ratio`, `crop` resize mode and `webp` output format:
581
+
582
+ ```ruby
583
+ Imglab.srcset("assets", "image.jpeg", width: 100..4096, aspect_ratio: "1:1", mode: :crop, format: :webp)
584
+ ```
585
+
586
+ ```html
587
+ https://assets.imglab-cdn.net/image.jpeg?width=100&aspect-ratio=1%3A1&mode=crop&format=webp 100w,
588
+ https://assets.imglab-cdn.net/image.jpeg?width=128&aspect-ratio=1%3A1&mode=crop&format=webp 128w,
589
+ https://assets.imglab-cdn.net/image.jpeg?width=164&aspect-ratio=1%3A1&mode=crop&format=webp 164w,
590
+ https://assets.imglab-cdn.net/image.jpeg?width=210&aspect-ratio=1%3A1&mode=crop&format=webp 210w,
591
+ https://assets.imglab-cdn.net/image.jpeg?width=269&aspect-ratio=1%3A1&mode=crop&format=webp 269w,
592
+ https://assets.imglab-cdn.net/image.jpeg?width=345&aspect-ratio=1%3A1&mode=crop&format=webp 345w,
593
+ https://assets.imglab-cdn.net/image.jpeg?width=442&aspect-ratio=1%3A1&mode=crop&format=webp 442w,
594
+ https://assets.imglab-cdn.net/image.jpeg?width=566&aspect-ratio=1%3A1&mode=crop&format=webp 566w,
595
+ https://assets.imglab-cdn.net/image.jpeg?width=724&aspect-ratio=1%3A1&mode=crop&format=webp 724w,
596
+ https://assets.imglab-cdn.net/image.jpeg?width=928&aspect-ratio=1%3A1&mode=crop&format=webp 928w,
597
+ https://assets.imglab-cdn.net/image.jpeg?width=1188&aspect-ratio=1%3A1&mode=crop&format=webp 1188w,
598
+ https://assets.imglab-cdn.net/image.jpeg?width=1522&aspect-ratio=1%3A1&mode=crop&format=webp 1522w,
599
+ https://assets.imglab-cdn.net/image.jpeg?width=1949&aspect-ratio=1%3A1&mode=crop&format=webp 1949w,
600
+ https://assets.imglab-cdn.net/image.jpeg?width=2497&aspect-ratio=1%3A1&mode=crop&format=webp 2497w,
601
+ https://assets.imglab-cdn.net/image.jpeg?width=3198&aspect-ratio=1%3A1&mode=crop&format=webp 3198w,
602
+ https://assets.imglab-cdn.net/image.jpeg?width=4096&aspect-ratio=1%3A1&mode=crop&format=webp 4096w
603
+ ```
604
+
306
605
  ## License
307
606
 
308
607
  imglab source code is released under [MIT License](LICENSE).
data/lib/imglab/color.rb CHANGED
@@ -150,7 +150,7 @@ module Imglab::Color
150
150
  whitesmoke
151
151
  yellow
152
152
  yellowgreen
153
- ]
153
+ ].freeze
154
154
 
155
155
  # Returns a formatted color value as string.
156
156
  #
@@ -179,7 +179,7 @@ module Imglab::Color
179
179
  when args.size == 4 && valid_components?(*args)
180
180
  args.join(",")
181
181
  else
182
- raise ArgumentError.new("Invalid color")
182
+ raise ArgumentError, "Invalid color"
183
183
  end
184
184
  end
185
185
 
@@ -1,12 +1,12 @@
1
1
  module Imglab::Position
2
2
  extend self
3
3
 
4
- HORIZONTAL = %w[left center right]
5
- VERTICAL = %w[top middle bottom]
4
+ HORIZONTAL = %w[left center right].freeze
5
+ VERTICAL = %w[top middle bottom].freeze
6
6
 
7
7
  # Returns a formatted position value as string.
8
8
  #
9
- # @param args [Array<String>, String] the position with two directions or one single direction as strings.
9
+ # @param directions [Array<String>, String] the position with two directions or one single direction as strings.
10
10
  # @return [String] the formatted position with the specified arguments.
11
11
  # @raise [ArgumentError] when the specified arguments are not a valid position.
12
12
  #
@@ -20,24 +20,24 @@ module Imglab::Position
20
20
  # Imglab::Position.position("left", "center") #=> ArgumentError: Invalid position
21
21
  # @example Specify an invalid single direction position (raising ArgumentError exception)
22
22
  # Imglab::Position.position("lefts") #=> ArgumentError: Invalid position
23
- def position(*args)
23
+ def position(*directions)
24
24
  case
25
- when args.size == 1 && valid_position?(args[0])
26
- args[0]
27
- when args.size == 2 && valid_position?(*args)
28
- args.join(",")
25
+ when directions.size == 1 && valid_position?(directions[0])
26
+ directions[0]
27
+ when directions.size == 2 && valid_position?(*directions)
28
+ directions.join(",")
29
29
  else
30
- raise ArgumentError.new("Invalid position")
30
+ raise ArgumentError, "Invalid position"
31
31
  end
32
32
  end
33
33
 
34
34
  private
35
35
 
36
- def valid_position?(*args)
36
+ def valid_position?(*directions)
37
37
  case
38
- when args.size == 1 && valid_direction?(args[0])
38
+ when directions.size == 1 && valid_direction?(directions[0])
39
39
  true
40
- when args.size == 2 && valid_directions?(args[0], args[1])
40
+ when directions.size == 2 && valid_directions?(directions[0], directions[1])
41
41
  true
42
42
  else
43
43
  false
@@ -0,0 +1,45 @@
1
+ module Imglab::Sequence
2
+ extend self
3
+
4
+ DEFAULT_SIZE = 16
5
+
6
+ # Returns a geometric sequence of integer numbers inside an interval and with specific size as array.
7
+ #
8
+ # @param first [Integer] the first integer number of the sequence.
9
+ # @param last [Integer] the last integer number of the sequence.
10
+ # @param size [Integer] the size of the sequence.
11
+ # @return [Array<Integer>] a sequence of integer numbers as array.
12
+ #
13
+ # @example Specify an ascending sequence of default size
14
+ # Imglab::Sequence.sequence(100, 8192) #=> [100, 134, 180, 241, 324, 434, 583, 781, 1048, 1406, 1886, 2530, 3394, 4553, 6107, 8192]
15
+ # @example Specify an ascending sequence of size 1
16
+ # Imglab::Sequence.sequence(100, 8192, 1) #=> [100]
17
+ # @example Specify an ascending sequence of size 2
18
+ # Imglab::Sequence.sequence(100, 8192, 2) #=> [100, 8192]
19
+ # @example Specify an ascending sequence of size 4
20
+ # Imglab::Sequence.sequence(100, 8192, 4) #=> [100, 434, 1886, 8192]
21
+ # @example Specify a descending sequence of size 6
22
+ # Imglab::Sequence.sequence(70, 60, 6) #=> [70, 68, 66, 64, 62, 60]
23
+ def sequence(first, last, size = DEFAULT_SIZE)
24
+ return [] if size <= 0
25
+ return [first] if size == 1
26
+ return [first, last] if size == 2
27
+
28
+ ratio = (last / first.to_f) ** (1 / (size - 1).to_f)
29
+
30
+ progression(first, ratio).take(size - 1).map(&:round).push(last)
31
+ end
32
+
33
+ private
34
+
35
+ def progression(first, ratio)
36
+ n = first
37
+
38
+ Enumerator.new do |y|
39
+ loop do
40
+ y << n
41
+ n *= ratio
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,22 +1,24 @@
1
1
  require "base64"
2
2
  require "openssl"
3
3
 
4
- class Imglab::Signature
4
+ module Imglab::Signature
5
+ extend self
6
+
5
7
  # Returns a generated signature for a source, path and encoded parameters.
6
8
  #
7
9
  # @param source [Imglab::Source] the source used to generate the signature.
8
10
  # @param path [String] the path of the resource.
9
11
  # @param encoded_params [String] encoded query params of the URL to generate the signature.
10
12
  # @return [String]
11
- def self.generate(source, path, encoded_params = nil)
13
+ def generate(source, path, encoded_params = nil)
12
14
  decoded_secure_key = Base64.decode64(source.secure_key)
13
15
  decoded_secure_salt = Base64.decode64(source.secure_salt)
14
16
 
15
17
  data = "#{decoded_secure_salt}/#{path}"
16
18
  data = encoded_params ? "#{data}?#{encoded_params}" : data
17
19
 
18
- hmac = OpenSSL::HMAC.digest(OpenSSL::Digest.new("sha256"), decoded_secure_key, data)
20
+ digest = OpenSSL::HMAC.digest(OpenSSL::Digest.new("sha256"), decoded_secure_key, data)
19
21
 
20
- Base64.urlsafe_encode64(hmac).tr("=", "")
22
+ Base64.urlsafe_encode64(digest).tr("=", "")
21
23
  end
22
24
  end
data/lib/imglab/source.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  class Imglab::Source
2
2
  DEFAULT_HTTPS = true
3
- DEFAULT_HOST = "imglab-cdn.net"
3
+ DEFAULT_HOST = "imglab-cdn.net".freeze
4
4
  DEFAULT_SUBDOMAINS = true
5
5
 
6
6
  attr_reader :name, :https, :port, :secure_key, :secure_salt, :subdomains
@@ -39,7 +39,7 @@ class Imglab::Source
39
39
  @subdomains ? "#{@name}.#{@host}" : @host
40
40
  end
41
41
 
42
- # Returns a the path to be used with the source.
42
+ # Returns the path to be used with the source.
43
43
  #
44
44
  # @param path [String]
45
45
  # @return [String]
@@ -51,7 +51,7 @@ class Imglab::Source
51
51
  #
52
52
  # @return [Boolean]
53
53
  def is_secure?
54
- @secure_key && @secure_salt
54
+ !!(@secure_key && @secure_salt)
55
55
  end
56
56
 
57
57
  # Overrided inspect method to don't show sensitive attributes like secure_key and secure_salt.
@@ -0,0 +1,89 @@
1
+ module Imglab::Srcset
2
+ module Utils
3
+ extend self
4
+
5
+ NORMALIZE_KEYS = %w[dpr width].freeze
6
+
7
+ SPLIT_DPR_KEYS = %w[dpr quality].freeze
8
+ SPLIT_WIDTH_KEYS = %w[width height quality].freeze
9
+
10
+ # Returns normalized params, rejecting values with keys included in normalized keys and with empty arrays.
11
+ #
12
+ # @param params [Hash]
13
+ # @return [Hash]
14
+ def normalize_params(params)
15
+ params.inject({}) do |normalized_params, (key, value)|
16
+ normalized_params.merge(normalize_param(key.to_s, value))
17
+ end
18
+ end
19
+
20
+ # Returns an array with the parameters to use in different URLs for a srcset split by dpr parameter.
21
+ #
22
+ # @param params [Hash]
23
+ # @return [Array]
24
+ def split_params_dpr(params)
25
+ split_values(params, SPLIT_DPR_KEYS, params.fetch("dpr").size).map do |dpr, quality|
26
+ params.merge(
27
+ {
28
+ "dpr" => dpr,
29
+ "quality" => quality
30
+ }.delete_if { |key, _value| !params.key?(key) }
31
+ )
32
+ end
33
+ end
34
+
35
+ # Returns an array with the parameters to use in different URLs for a srcset split by width parameter.
36
+ #
37
+ # @param params [Hash]
38
+ # @return [Array]
39
+ def split_params_width(params)
40
+ split_values(params, SPLIT_WIDTH_KEYS, split_size(params.fetch("width"))).map do |width, height, quality|
41
+ params.merge(
42
+ {
43
+ "width" => width,
44
+ "height" => height,
45
+ "quality" => quality
46
+ }.delete_if { |key, _value| !params.key?(key) }
47
+ )
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def normalize_param(key, value)
54
+ case
55
+ when NORMALIZE_KEYS.include?(key) && value == []
56
+ {}
57
+ else
58
+ { key => value }
59
+ end
60
+ end
61
+
62
+ def split_size(value)
63
+ case value
64
+ when Range
65
+ Imglab::Sequence::DEFAULT_SIZE
66
+ when Array
67
+ value.size
68
+ end
69
+ end
70
+
71
+ def split_values(params, keys, size)
72
+ values = keys.map { |key| split_value(key, params[key], size) }
73
+ values.first.zip(*values[1..-1])
74
+ end
75
+
76
+ def split_value(key, value, size)
77
+ case
78
+ when key == "dpr" && value.instance_of?(Range)
79
+ value.to_a
80
+ when value.instance_of?(Range)
81
+ Imglab::Sequence.sequence(value.first, value.last, size)
82
+ when value.instance_of?(Array)
83
+ value
84
+ else
85
+ Array.new(size, value)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,73 @@
1
+ module Imglab
2
+ extend self
3
+
4
+ FLUID_CLASSES = [Array, Range].freeze
5
+
6
+ DEFAULT_DPRS = [1, 2, 3, 4, 5, 6].freeze
7
+ DEFAULT_WIDTHS = Sequence.sequence(100, 8192).freeze
8
+
9
+ # Returns a formatted srcset `string` with the specified parameters.
10
+ #
11
+ # @param source [String, Imglab::Source] the source name or source object
12
+ # @param path [String] the path where the resource is located
13
+ # @param params [Hash] the query parameters that we want to use
14
+ # @return [String] the srcset value as a list of formatted URLs with the specified arguments
15
+ # @raise [ArgumentError] when the source name or source parameter has a not expected type or params are using unexpected values
16
+ #
17
+ # @example Creating a srcset with three different device pixel ratios:
18
+ # Imglab.srcset("assets", "example.jpeg", width: 500, dpr: [1, 2, 3]) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&dpr=1 1x,\n..."
19
+ # @example Creating a srcset with three different device pixel ratios using a range:
20
+ # Imglab.srcset("assets", "example.jpeg", width: 500, dpr: 1..3) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&dpr=1 1x,\n..."
21
+ # @example Creating a srcset with three different width sizes:
22
+ # Imglab.srcset("assets", "example.jpeg", width: [400, 800, 1200], format: "webp") #=> "https://assets.imglab-cdn.net/example.jpeg?width=400&format=webp 400w,\n..."
23
+ # @example Creating a srcset with a range of width sizes:
24
+ # Imglab.srcset("assets", "example.jpeg", width: 400..1200, format: "webp") #=> "https://assets.imglab-cdn.net/example.jpeg?width=400&format=webp 400w,\n..."
25
+ def srcset(source, path, params = {})
26
+ params = Srcset::Utils.normalize_params(params)
27
+
28
+ width, height, dpr = params.values_at("width", "height", "dpr")
29
+
30
+ case
31
+ when is_fluid?(width)
32
+ if is_fluid?(dpr)
33
+ raise ArgumentError, "dpr as #{dpr.class} is not allowed when width is Array or Range"
34
+ end
35
+
36
+ srcset_width(source, path, params)
37
+ when width || height
38
+ if is_fluid?(height)
39
+ raise ArgumentError, "height as #{height.class} is not allowed when width is not an Array or Range"
40
+ end
41
+
42
+ srcset_dpr(source, path, params.merge("dpr" => dprs(params)))
43
+ else
44
+ if is_fluid?(dpr)
45
+ raise ArgumentError, "dpr as #{dpr.class} is not allowed without specifying width or height"
46
+ end
47
+
48
+ srcset_width(source, path, params.merge("width" => DEFAULT_WIDTHS))
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def dprs(params)
55
+ is_fluid?(params["dpr"]) ? params["dpr"] : DEFAULT_DPRS
56
+ end
57
+
58
+ def is_fluid?(value)
59
+ FLUID_CLASSES.include?(value.class)
60
+ end
61
+
62
+ def srcset_dpr(source, path, params)
63
+ Srcset::Utils.split_params_dpr(params).map do |split_params|
64
+ "#{url(source, path, split_params)} #{split_params.fetch('dpr')}x"
65
+ end.join(",\n")
66
+ end
67
+
68
+ def srcset_width(source, path, params)
69
+ Srcset::Utils.split_params_width(params).map do |split_params|
70
+ "#{url(source, path, split_params)} #{split_params.fetch('width')}w"
71
+ end.join(",\n")
72
+ end
73
+ end
@@ -0,0 +1,55 @@
1
+ module Imglab::Url
2
+ module Utils
3
+ extend self
4
+
5
+ NORMALIZE_PATH_PREFIX_REGEXP = Regexp.compile(/\A\/*/)
6
+ NORMALIZE_PATH_SUFFIX_REGEXP = Regexp.compile(/\/*$/)
7
+
8
+ WEB_URI_SCHEMES = %w[https http].freeze
9
+
10
+ # Returns a normalized path where suffix and prefix slashes are removed.
11
+ #
12
+ # @param path [String]
13
+ # @return [String]
14
+ def normalize_path(path)
15
+ path.gsub(NORMALIZE_PATH_PREFIX_REGEXP, "").gsub(NORMALIZE_PATH_SUFFIX_REGEXP, "")
16
+ end
17
+
18
+ # Returns normalized params, transforming keys with undercores to hyphens.
19
+ #
20
+ # @param params [Hash]
21
+ # @return [Hash]
22
+ def normalize_params(params)
23
+ params.inject({}) do |normalized_params, value|
24
+ normalized_params.merge(normalize_param(dasherize(value[0]), value[1]))
25
+ end
26
+ end
27
+
28
+ # Returns a boolean value indicating whether a string is a valid HTTP/HTTPS URI or not.
29
+ #
30
+ # @param uri [String]
31
+ # @return [Boolean]
32
+ def web_uri?(uri)
33
+ WEB_URI_SCHEMES.include?(URI.parse(uri).scheme)
34
+ rescue URI::Error
35
+ false
36
+ end
37
+
38
+ private
39
+
40
+ def dasherize(value)
41
+ value.to_s.gsub("_", "-")
42
+ end
43
+
44
+ def normalize_param(key, value)
45
+ case
46
+ when key == "expires" && value.instance_of?(Time)
47
+ { key => value.to_i }
48
+ when value == nil
49
+ { key => "" }
50
+ else
51
+ { key => value }
52
+ end
53
+ end
54
+ end
55
+ end
data/lib/imglab/url.rb ADDED
@@ -0,0 +1,79 @@
1
+ module Imglab
2
+ extend self
3
+
4
+ # Returns a formatted URL `string` with the specified arguments.
5
+ #
6
+ # @param source [String, Imglab::Source] the source name or source object
7
+ # @param path [String] the path where the resource is located
8
+ # @param params [Hash] the query parameters that we want to use
9
+ # @return [String] the formatted URL with the specified arguments
10
+ # @raise [ArgumentError] when the source name or source parameter has a not expected type
11
+ #
12
+ # @example Creating a URL specifying source name as string
13
+ # Imglab.url("assets", "example.jpeg", width: 500, height: 600) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&height=600"
14
+ # @example Creating a URL specifying a Imglab::Source
15
+ # Imglab.url(Imglab::Source.new("assets"), "example.jpeg", width: 500, height: 600) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&height=600"
16
+ def url(source, path, params = {})
17
+ case source
18
+ when String
19
+ url_for_source(Source.new(source), path, params)
20
+ when Source
21
+ url_for_source(source, path, params)
22
+ else
23
+ raise ArgumentError, "Invalid source name or source. A string or a #{Source.name} instance is expected"
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def url_for_source(source, path, params)
30
+ normalized_path = Url::Utils.normalize_path(path)
31
+ normalized_params = Url::Utils.normalize_params(params)
32
+
33
+ URI::Generic.new(
34
+ source.scheme,
35
+ nil,
36
+ source.host,
37
+ source.port,
38
+ nil,
39
+ File.join("/", source.path(encode_path(normalized_path))),
40
+ nil,
41
+ encode_params(source, normalized_path, normalized_params),
42
+ nil
43
+ ).to_s
44
+ end
45
+
46
+ def encode_path(path)
47
+ if Url::Utils.web_uri?(path)
48
+ encode_path_component(path)
49
+ else
50
+ path.split("/").map do |path_component|
51
+ encode_path_component(path_component)
52
+ end.join("/")
53
+ end
54
+ end
55
+
56
+ def encode_path_component(path_component)
57
+ ERB::Util.url_encode(path_component)
58
+ end
59
+
60
+ def encode_params(source, path, params)
61
+ return encode_empty_params(source, path) if params.empty?
62
+
63
+ if source.is_secure?
64
+ signature = Signature.generate(source, path, URI.encode_www_form(params))
65
+
66
+ URI.encode_www_form(params.merge(signature: signature))
67
+ else
68
+ URI.encode_www_form(params)
69
+ end
70
+ end
71
+
72
+ def encode_empty_params(source, path)
73
+ return unless source.is_secure?
74
+
75
+ signature = Signature.generate(source, path)
76
+
77
+ URI.encode_www_form(signature: signature)
78
+ end
79
+ end
@@ -1,3 +1,3 @@
1
1
  module Imglab
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/imglab.rb CHANGED
@@ -5,84 +5,8 @@ require "imglab/source"
5
5
  require "imglab/signature"
6
6
  require "imglab/color"
7
7
  require "imglab/position"
8
- require "imglab/utils"
9
-
10
- module Imglab
11
- # Returns a formatted URL `string` with the specified arguments.
12
- #
13
- # @param source_name_or_source [String, Imglab::Source] the source name or source object
14
- # @param path [String] the path where the resource is located
15
- # @param params [Hash] the query parameters that we want to use
16
- # @return [String] the formatted URL with the specified arguments
17
- # @raise [ArgumentError] when the source name or source parameter has a not expected type.
18
- #
19
- # @example Creating a URL specifying source name as string
20
- # Imglab.url("assets", "example.jpeg", width: 500, height: 600) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&height=600"
21
- # @example Creating a URL specifying a Imglab::Source
22
- # Imglab.url(Imglab::Source.new("assets"), "example.jpeg", width: 500, height: 600) #=> "https://assets.imglab-cdn.net/example.jpeg?width=500&height=600"
23
- def self.url(source_name_or_source, path, params = {})
24
- case source_name_or_source
25
- when String
26
- url_for_source(Source.new(source_name_or_source), path, params)
27
- when Source
28
- url_for_source(source_name_or_source, path, params)
29
- else
30
- raise ArgumentError.new("Invalid source name or source. A string or #{Imglab::Source.name} is expected.")
31
- end
32
- end
33
-
34
- private
35
-
36
- def self.url_for_source(source, path, params)
37
- normalized_path = Utils.normalize_path(path)
38
- normalized_params = Utils.normalize_params(params)
39
-
40
- URI::Generic.new(
41
- source.scheme,
42
- nil,
43
- source.host,
44
- source.port,
45
- nil,
46
- File.join("/", source.path(encode_path(normalized_path))),
47
- nil,
48
- encode_params(source, normalized_path, normalized_params),
49
- nil
50
- ).to_s
51
- end
52
-
53
- def self.encode_path(path)
54
- if Utils.web_uri?(path)
55
- encode_path_component(path)
56
- else
57
- path.split("/").map do |path_component|
58
- encode_path_component(path_component)
59
- end.join("/")
60
- end
61
- end
62
-
63
- def self.encode_path_component(path_component)
64
- ERB::Util.url_encode(path_component)
65
- end
66
-
67
- def self.encode_params(source, path, params)
68
- return encode_empty_params(source, path) if params.empty?
69
-
70
- if source.is_secure?
71
- signature = Signature.generate(source, path, URI.encode_www_form(params))
72
-
73
- URI.encode_www_form(params.merge(signature: signature))
74
- else
75
- URI.encode_www_form(params)
76
- end
77
- end
78
-
79
- def self.encode_empty_params(source, path)
80
- if source.is_secure?
81
- signature = Signature.generate(source, path)
82
-
83
- URI.encode_www_form(signature: signature)
84
- else
85
- nil
86
- end
87
- end
88
- end
8
+ require "imglab/sequence"
9
+ require "imglab/url/utils"
10
+ require "imglab/url"
11
+ require "imglab/srcset/utils"
12
+ require "imglab/srcset"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imglab
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - imglab
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-06 00:00:00.000000000 Z
11
+ date: 2023-01-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Official Ruby library to integrate with imglab services.
14
14
  email:
@@ -29,9 +29,13 @@ files:
29
29
  - lib/imglab.rb
30
30
  - lib/imglab/color.rb
31
31
  - lib/imglab/position.rb
32
+ - lib/imglab/sequence.rb
32
33
  - lib/imglab/signature.rb
33
34
  - lib/imglab/source.rb
34
- - lib/imglab/utils.rb
35
+ - lib/imglab/srcset.rb
36
+ - lib/imglab/srcset/utils.rb
37
+ - lib/imglab/url.rb
38
+ - lib/imglab/url/utils.rb
35
39
  - lib/imglab/version.rb
36
40
  homepage: https://github.com/imglab-io/imglab-rb
37
41
  licenses:
data/lib/imglab/utils.rb DELETED
@@ -1,49 +0,0 @@
1
- class Imglab::Utils
2
- NORMALIZE_PATH_PREFIX_REGEXP = Regexp.compile(/\A\/*/)
3
- NORMALIZE_PATH_SUFFIX_REGEXP = Regexp.compile(/\/*$/)
4
-
5
- WEB_URI_SCHEMES = %w[https http]
6
-
7
- # Returns a normalized path where suffix and prefix slashes are removed.
8
- #
9
- # @param path [String]
10
- # @return [String]
11
- def self.normalize_path(path)
12
- path.gsub(NORMALIZE_PATH_PREFIX_REGEXP, "").gsub(NORMALIZE_PATH_SUFFIX_REGEXP, "")
13
- end
14
-
15
- # Returns normalized params, transforming keys with undercores to hyphens.
16
- #
17
- # @param params [Hash]
18
- # @return [Hash]
19
- def self.normalize_params(params)
20
- params.inject({}) do |normalized_params, value|
21
- normalized_params.merge(normalize_param(dasherize(value[0]), value[1]))
22
- end
23
- end
24
-
25
- # Returns a boolean value indicating whether a string is a valid HTTP/HTTPS URI or not.
26
- #
27
- # @param uri [String]
28
- # @return [Boolean]
29
- def self.web_uri?(uri)
30
- WEB_URI_SCHEMES.include?(URI.parse(uri).scheme)
31
- rescue URI::Error
32
- false
33
- end
34
-
35
- private
36
-
37
- def self.dasherize(value)
38
- value.to_s.gsub("_", "-")
39
- end
40
-
41
- def self.normalize_param(key, value)
42
- case
43
- when key == "expires" && value.instance_of?(Time)
44
- {key => value.to_i}
45
- else
46
- {key => value}
47
- end
48
- end
49
- end