imgix-rails 2.1.4 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c75754475382bc08cea7f12c6d5bee8d0b794cc
4
- data.tar.gz: b2bc84807ab40633b2fa05c57a4c24a8484b7bb6
3
+ metadata.gz: 685c398ffbc9325b01ab084285513ec1587d71dc
4
+ data.tar.gz: d661d482080130d3af706b7815616825d9fd8785
5
5
  SHA512:
6
- metadata.gz: cd75ed3285539c743aada0c7ce94c1cf72a297f85b4545e0b3439e9cd4ebe3df5c56f84c90c789782191d054fd1287082b2a13a6bdf785e9b67f8d61ab204d54
7
- data.tar.gz: 6ee0e5ac18b1d7a4321b81e6c825e40dc4b1718dd20e11109c8eb6706dbb217ad1ebe5983d743b2faa056df602cf2047dc94703843a70b39741297eaa726dac5
6
+ metadata.gz: 797dd684241810df8b30356c6faca343e34f911129f7646fd1a37758a110a870363f951d2c20aedffbb480593434ec902f16882cda4dc2fa25f77a2730501334
7
+ data.tar.gz: a543310314e39172cc523188ef2e053fff42997f0f28276763dbe479de23131325886b654e7d57712f73837666b1bbb3a6592c2f1d6d5f15288ffcc1509791d8
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2018, Zebrafish Labs Inc.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24
+ POSSIBILITY OF SUCH DAMAGE.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  [![imgix logo](https://assets.imgix.net/imgix-logo-web-2014.pdf?page=2&fm=png&w=200&h=200)](https://imgix.com)
2
2
 
3
- # imgix-rails [![Build Status](https://travis-ci.org/imgix/imgix-rails.svg?branch=master)](https://travis-ci.org/imgix/imgix-rails) [![Slack Status](http://slack.imgix.com/badge.svg)](http://slack.imgix.com)
3
+ # imgix-rails [![Build Status](https://travis-ci.org/imgix/imgix-rails.svg?branch=master)](https://travis-ci.org/imgix/imgix-rails)
4
4
 
5
5
  `imgix-rails` is a gem designed to make integrating imgix into your Rails app easier. It builds on [imgix-rb](https://github.com/imgix/imgix-rb) to offer a few Rails-specific interfaces.
6
6
 
@@ -15,7 +15,6 @@ We recommend using something like [Paperclip](https://github.com/thoughtbot/pape
15
15
  * [ix_picture_tag](#ix_picture_tag)
16
16
  * [ix_image_url](#ix_image_url)
17
17
  * [Usage in Sprockets](#usage-in-sprockets)
18
- * [Hostname Removal](#hostname-removal)
19
18
  * [Using With Image Uploading Libraries](#using-with-image-uploading-libraries)
20
19
  * [Paperclip and CarrierWave](#paperclip-and-carrierwave)
21
20
  * [Refile](#refile)
@@ -50,7 +49,7 @@ Before you get started, you will need to define your imgix configuration in your
50
49
  ```ruby
51
50
  Rails.application.configure do
52
51
  config.imgix = {
53
- source: "Name of your source, e.g. assets.imgix.net"
52
+ source: "assets.imgix.net"
54
53
  }
55
54
  end
56
55
  ```
@@ -59,8 +58,30 @@ The following configuration flags will be respected:
59
58
 
60
59
  - `:use_https` toggles the use of HTTPS. Defaults to `true`
61
60
  - `:source` a String or Array that specifies the imgix Source address. Should be in the form of `"assets.imgix.net"`.
62
- - `:secure_url_token` a optional secure URL token found in your dashboard (https://webapp.imgix.com) used for signing requests
63
- - `:hostnames_to_replace` an Array of hostnames to replace with the value(s) specified by `:source`. This is useful if you store full-qualified S3 URLs in your database, but want to serve images through imgix.
61
+ - `:srcset_width_tolerance` an optional numeric value determining the maximum tolerance allowable, between the downloaded dimensions and rendered dimensions of the image (default `.08` i.e. `8%`).
62
+ - `:secure_url_token` an optional secure URL token found in your dashboard (https://dashboard.imgix.com) used for signing requests
63
+ - `:shard_strategy` Specify [domain sharding strategy](https://github.com/imgix/imgix-rb#domain-sharded-urls) with multiple sources. Acceptable values are `:cycle` and `:crc`. `:crc` is used by default.
64
+
65
+ #### Multi-source configuration
66
+
67
+ In addition to the standard configuration flags, the following options can be used for multi-source support.
68
+
69
+ - `:sources` a Hash of imgix source-secure_url_token key-value pairs. If the value for a source is `nil`, URLs generated for the corresponding source won't be secured. `:sources` and `:source` *cannot* be used together.
70
+ - `:default_source` optionally specify a default source for generating URLs.
71
+
72
+ Example:
73
+
74
+ ```ruby
75
+ Rails.application.configure do
76
+ config.imgix = {
77
+ sources: {
78
+ "assets.imgix.net" => "foobarbaz",
79
+ "assets2.imgix.net" => nil, # Will generate unsigned URLs
80
+ },
81
+ default_source: "assets.imgix.net"
82
+ }
83
+ end
84
+ ```
64
85
 
65
86
  <a name="ix_image_tag"></a>
66
87
  ### ix_image_tag
@@ -69,8 +90,15 @@ The `ix_image_tag` helper method makes it easy to pass parameters to imgix to ha
69
90
 
70
91
  `ix_image_tag` generates `<img>` tags with a filled-out `srcset` attribute that leans on imgix to do the hard work. If you already know the minimum or maximum number of physical pixels that this image will need to be displayed at, you can pass the `min_width` and/or `max_width` options. This will result in a smaller, more tailored `srcset`.
71
92
 
93
+ `ix_image_tag` takes the following arguments:
94
+
95
+ * `source`: an optional String indicating the source to be used. If unspecified `:source` or `:default_source` will be used. If specified, the value must be defined in the config.
96
+ * `path`: The path or URL of the image to display.
97
+ * `tag_options`: Any options to apply to the parent `picture` element. This is useful for adding class names, etc.
98
+ * `url_params`: Default imgix options. These will be used to generate a fallback `img` tag for older browsers, and used in each `source` unless overridden by `breakpoints`.
99
+
72
100
  ```erb
73
- <%= ix_image_tag('/unsplash/hotairballoon.jpg', { w: 300, h: 500, fit: 'crop', crop: 'right', alt: 'A hot air balloon on a sunny day' }) %>
101
+ <%= ix_image_tag('/unsplash/hotairballoon.jpg', url_params: { w: 300, h: 500, fit: 'crop', crop: 'right'}, tag_options: { alt: 'A hot air balloon on a sunny day' }) %>
74
102
  ```
75
103
 
76
104
  Will render out HTML like the following:
@@ -89,11 +117,19 @@ Will render out HTML like the following:
89
117
  >
90
118
  ```
91
119
 
120
+ Similarly
121
+
122
+ ```erb
123
+ <%= ix_image_tag('assets2.imgix.net', '/unsplash/hotairballoon.jpg') %>
124
+ ```
125
+
126
+ Will generate URLs using `assets2.imgix.net` source.
127
+
92
128
  We recommend leveraging this to generate powerful helpers within your application like the following:
93
129
 
94
130
  ```ruby
95
131
  def profile_image_tag(user)
96
- ix_image_tag(user.profile_image_url, { w: 100, h: 200, fit: 'crop' })
132
+ ix_image_tag(user.profile_image_url, url_params: { w: 100, h: 200, fit: 'crop' })
97
133
  end
98
134
  ```
99
135
 
@@ -106,7 +142,7 @@ Then rendering the portrait in your application is very easy:
106
142
  If you already know all the exact widths you need images for, you can specify that by passing the `widths` option as an array. In this case, imgix-rails will only generate `srcset` pairs for the specified `widths`.
107
143
 
108
144
  ```erb
109
- <%= ix_image_tag('/unsplash/hotairballoon.jpg', { widths: [320, 640, 960, 1280] w: 300, h: 500, fit: 'crop', crop: 'right', alt: 'A hot air balloon on a sunny day' }) %>
145
+ <%= ix_image_tag('/unsplash/hotairballoon.jpg', widths: [320, 640, 960, 1280], url_params: { w: 300, h: 500, fit: 'crop', crop: 'right'}, tag_options: { alt: 'A hot air balloon on a sunny day' }) %>
110
146
  ```
111
147
 
112
148
 
@@ -115,54 +151,89 @@ If you already know all the exact widths you need images for, you can specify th
115
151
 
116
152
  The `ix_picture_tag` helper method makes it easy to generate `picture` elements in your Rails app. `picture` elements are useful when an images needs to be art directed differently at different screen sizes.
117
153
 
118
- `ix_picture_tag` takes four arguments:
154
+ `ix_picture_tag` takes the following arguments:
119
155
 
120
- * `source`: The path or URL of the image to display.
121
- * `picture_tag_options`: Any options to apply to the parent `picture` element. This is useful for adding class names, etc.
122
- * `imgix_default_options`: Default imgix options. These will be used to generate a fallback `img` tag for older browsers, and used in each `source` unless overridden by `breakpoints`.
156
+ * `source`: an optional String indicating the source to be used. If unspecified `:source` or `:default_source` will be used. If specified, the value must be defined in the config.
157
+ * `path`: The path or URL of the image to display.
158
+ * `tag_options`: Any options to apply to the parent `picture` element. This is useful for adding class names, etc.
159
+ * `url_params`: Default imgix options. These will be used to generate a fallback `img` tag for older browsers, and used in each `source` unless overridden by `breakpoints`.
123
160
  * `breakpoints`: A hash describing the variants. Each key must be a media query (e.g. `(max-width: 880px)`), and each value must be a hash of param overrides for that media query. A `source` element will be generated for each breakpoint specified.
124
161
 
125
162
  ```erb
126
163
  <%= ix_picture_tag('bertandernie.jpg',
127
- picture_tag_options: {
164
+ tag_options: {
128
165
  class: 'a-picture-tag'
129
166
  },
130
- imgix_default_options: {
167
+ url_params: {
131
168
  w: 300,
132
169
  h: 300,
133
170
  fit: 'crop',
134
171
  },
135
172
  breakpoints: {
136
173
  '(max-width: 640px)' => {
137
- h: 100,
138
- sizes: 'calc(100vw - 20px)'
174
+ url_params: {
175
+ h: 100,
176
+ },
177
+ tag_options: {
178
+ sizes: 'calc(100vw - 20px)'
179
+ }
139
180
  },
140
181
  '(max-width: 880px)' => {
141
- crop: 'right',
142
- sizes: 'calc(100vw - 20px - 50%)'
182
+ url_params: {
183
+ crop: 'right',
184
+ },
185
+ tag_options: {
186
+ sizes: 'calc(100vw - 20px - 50%)'
187
+ }
143
188
  },
144
189
  '(min-width: 881px)' => {
145
- crop: 'left',
146
- sizes: '430px'
190
+ url_params: {
191
+ crop: 'left',
192
+ },
193
+ tag_options: {
194
+ sizes: '430px'
195
+ }
147
196
  }
148
197
  }
149
198
  ) %>
150
199
  ```
151
200
 
201
+ To generate a `picture` element on a different source:
202
+
203
+ ```erb
204
+ <%= ix_picture_tag('assets2.imgix.net', 'bertandernie.jpg',
205
+ tag_options: {},
206
+ url_params: {},
207
+ breakpoints: {
208
+ '(max-width: 640px)' => {
209
+ url_params: { h: 100 },
210
+ tag_options: { sizes: 'calc(100vw - 20px)' }
211
+ },
212
+ }
213
+ ) %>
214
+ ```
152
215
 
153
216
  <a name="ix_image_url"></a>
154
217
  ### ix_image_url
155
218
 
156
219
  The `ix_image_url` helper makes it easy to generate a URL to an image in your Rails app.
157
220
 
221
+ `ix_image_url` takes four arguments:
222
+
223
+ * `source`: an optional String indicating the source to be used. If unspecified `:source` or `:default_source` will be used. If specified, the value must be defined in the config.
224
+ * `path`: The path or URL of the image to display.
225
+ * `options`: Any options to apply to the parent `picture` element. This is useful for adding class names, etc.
226
+
158
227
  ```erb
159
228
  <%= ix_image_url('/users/1/avatar.png', { w: 400, h: 300 }) %>
229
+ <%= ix_image_url('assets2.imgix.net', '/users/1/avatar.png', { w: 400, h: 300 }) %>
160
230
  ```
161
231
 
162
- Will generate the following URL:
232
+ Will generate the following URLs:
163
233
 
164
234
  ```html
165
235
  https://assets.imgix.net/users/1/avatar.png?w=400&h=300
236
+ https://assets2.imgix.net/users/1/avatar.png?w=400&h=300
166
237
  ```
167
238
 
168
239
  Since `ix_image_url` lives inside `UrlHelper`, it can also be used in places other than your views quite easily. This is useful for things such as including imgix URLs in JSON output from a serializer class.
@@ -185,40 +256,6 @@ puts ix_image_url('/users/1/avatar.png', { w: 400, h: 300 })
185
256
  }
186
257
  ```
187
258
 
188
- ### Hostname Removal
189
-
190
- You can also configure imgix-rails to disregard given hostnames and only use the path component from given URLs. This is useful if you have [a Web Folder or an Amazon S3 imgix Source configured](https://www.imgix.com/docs/tutorials/creating-sources) but store the fully-qualified URLs for those resources in your database.
191
-
192
- For example, let's say you are using S3 for storage. An `#avatar_url` value might look like the following in your application:
193
-
194
- ```ruby
195
- @user.avatar_url #=> "https://s3.amazonaws.com/my-bucket/users/1.png"
196
- ```
197
-
198
- You would then configure imgix in your Rails application to disregard the `'s3.amazonaws.com'` hostname:
199
-
200
- ```ruby
201
- Rails.application.configure do
202
- config.imgix = {
203
- source: "my-imgix-source.imgix.net",
204
- hostname_to_replace: "s3.amazonaws.com"
205
- }
206
- end
207
- ```
208
-
209
- Now when you call `ix_image_tag` or another helper, you get an imgix URL:
210
-
211
- ```erb
212
- <%= ix_image_tag(@user.avatar_url) %>
213
- ```
214
-
215
- Renders:
216
-
217
- ```html
218
- <img src="https://my-imgix-source.imgix.net/my-bucket/users/1.png" />
219
- ```
220
-
221
-
222
259
  <a name="using-with-image-uploading-libraries"></a>
223
260
  ## Using With Image Uploading Libraries
224
261
 
@@ -283,3 +320,6 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
283
320
  3. Commit your changes (`git commit -am 'Add some feature'`)
284
321
  4. Push to the branch (`git push origin my-new-feature`)
285
322
  5. Create a new Pull Request
323
+
324
+ ## Code of Conduct
325
+ Users contributing to or participating in the development of this project are subject to the terms of imgix's [Code of Conduct](https://github.com/imgix/code-of-conduct).
data/imgix-rails.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Imgix::Rails::VERSION
9
9
  spec.authors = ["Kelly Sutton", "Paul Straw"]
10
10
  spec.email = ["kelly@imgix.com", "ixemail"]
11
- spec.licenses = ["MIT"]
11
+ spec.licenses = ["BSD-2-Clause"]
12
12
 
13
13
  spec.summary = %q{Makes integrating imgix into your Rails app easier. It builds on imgix-rb to offer a few Rails-specific interfaces.}
14
14
  spec.description = %q{Makes integrating imgix into your Rails app easier. It builds on imgix-rb to offer a few Rails-specific interfaces. Please see https://github.com/imgix/imgix-rails for more details.}
data/lib/imgix/rails.rb CHANGED
@@ -8,6 +8,7 @@ require "active_support"
8
8
 
9
9
  module Imgix
10
10
  module Rails
11
+ STRATEGIES = [:crc, :cycle]
11
12
  class Config < ::ActiveSupport::OrderedOptions; end
12
13
 
13
14
  def self.config
@@ -1,13 +1,11 @@
1
1
  require "imgix/rails/tag"
2
2
 
3
3
  class Imgix::Rails::ImageTag < Imgix::Rails::Tag
4
- def render
5
- @options[:srcset] = srcset
6
- @options[:sizes] ||= '100vw'
7
4
 
8
- @source = replace_hostname(@source)
9
- normal_opts = @options.slice!(*self.class.available_parameters)
5
+ def render
6
+ @tag_options[:srcset] = srcset
7
+ @tag_options[:sizes] ||= '100vw'
10
8
 
11
- image_tag(ix_image_url(@source, @options.except(:widths)), normal_opts)
9
+ image_tag(ix_image_url(@source, @path, @url_params), @tag_options)
12
10
  end
13
11
  end
@@ -4,25 +4,32 @@ require "imgix/rails/image_tag"
4
4
  class Imgix::Rails::PictureTag < Imgix::Rails::Tag
5
5
  include ActionView::Context
6
6
 
7
- def initialize(source, options, default_options, breakpoints)
7
+ def initialize(path, source: nil, tag_options: {}, url_params: {}, breakpoints: {}, widths: [])
8
+ @path = path
8
9
  @source = source
9
- @options = options
10
- @default_options = default_options
10
+ @tag_options = tag_options
11
+ @url_params = url_params
11
12
  @breakpoints = breakpoints
13
+ @widths = widths.length > 0 ? widths : target_widths
12
14
  end
13
15
 
14
16
  def render
15
- content_tag(:picture, @options) do
17
+ content_tag(:picture, @tag_options) do
16
18
  @breakpoints.each do |media, opts|
17
- html_opts = opts.except(*self.class.available_parameters)
18
- html_opts[:media] ||= media
19
- html_opts[:srcset] ||= srcset(@default_options.clone.merge(opts))
19
+ source_tag_opts = opts[:tag_options] || {}
20
+ source_tag_url_params = opts[:url_params] || {}
21
+ widths = opts[:widths]
22
+ unsupported_opts = opts.except(:tag_options, :url_params, :widths)
23
+ if unsupported_opts.length > 0
24
+ raise "'#{unsupported_opts.keys.join("', '")}' key(s) not supported; use tag_options, url_params, widths."
25
+ end
20
26
 
21
-
22
- concat(content_tag(:source, nil, html_opts))
27
+ source_tag_opts[:media] ||= media
28
+ source_tag_opts[:srcset] ||= srcset(url_params: @url_params.clone.merge(source_tag_url_params), widths: widths)
29
+ concat(content_tag(:source, nil, source_tag_opts))
23
30
  end
24
31
 
25
- concat Imgix::Rails::ImageTag.new(@source, @default_options).render
32
+ concat Imgix::Rails::ImageTag.new(@path, source: @source, url_params: @url_params).render
26
33
  end
27
34
  end
28
35
  end
@@ -4,171 +4,78 @@ class Imgix::Rails::Tag
4
4
  include Imgix::Rails::UrlHelper
5
5
  include ActionView::Helpers
6
6
 
7
- @@parameters = nil
8
-
9
- # Store our parameter information on the class instance so that
10
- # each instance of any this class or our subclasses doesn't have to
11
- # go back to disk to get this configuration information
12
- def self.available_parameters
13
- @@available_parameters ||= parameters.keys
14
- end
15
-
16
- def self.parameters
17
- return @@parameters if @@parameters
18
-
19
- path = File.expand_path("../../../../vendor/parameters.json", __FILE__)
20
- @@parameters = JSON.parse(File.read(path), symbolize_names: true)[:parameters]
21
- @@parameters[:widths] = nil
22
-
23
- @@parameters
24
- end
25
-
26
- def initialize(source, options={})
7
+ def initialize(path, source: nil, tag_options: {}, url_params: {}, widths: [])
8
+ @path = path
27
9
  @source = source
28
- @options = options
10
+ @tag_options = tag_options
11
+ @url_params = url_params
12
+ @widths = widths.length > 0 ? widths : target_widths
29
13
  end
30
14
 
31
15
  protected
32
16
 
33
- def srcset(opts=@options)
34
- @source = replace_hostname(@source)
35
- widths = opts[:widths] || target_widths
17
+ def srcset(url_params: @url_params, widths: @widths)
18
+ widths = widths || target_widths
36
19
 
37
- widths.map do |width|
38
- srcset_options = opts.slice(*self.class.available_parameters).except(:widths)
39
- srcset_options[:w] = width
20
+ srcset_url_params = url_params.clone
21
+ srcsetvalue = widths.map do |width|
22
+ srcset_url_params[:w] = width
40
23
 
41
- if opts[:w].present? && opts[:h].present?
42
- srcset_options[:h] = (width * (opts[:h].to_f / opts[:w])).round
24
+ if url_params[:w].present? && url_params[:h].present?
25
+ srcset_url_params[:h] = (width * (url_params[:h].to_f / url_params[:w])).round
43
26
  end
44
27
 
45
- "#{ix_image_url(@source, srcset_options)} #{width}w"
28
+ "#{ix_image_url(@source, @path, srcset_url_params)} #{width}w"
46
29
  end.join(', ')
30
+
31
+ srcsetvalue += ", #{ix_image_url(@source, @path, srcset_url_params.except(:w, :h))}"
47
32
  end
48
33
 
49
- private
34
+ @@standard_widths = nil
50
35
 
51
- MAXIMUM_SCREEN_WIDTH = 2560 * 2 # Physical resolution of 27" iMac (2016)
52
- SCREEN_STEP = 100
53
-
54
- # Taken from http://mydevice.io/devices/
55
-
56
- # Phones
57
- IPHONE = { css_width: 320, dpr: 1 }
58
- IPHONE_4 = { css_width: 320, dpr: 2 }
59
- IPHONE_6 = { css_width: 375, dpr: 2 }
60
- LG_G3 = { css_width: 360, dpr: 4 }
61
-
62
- # Phablets
63
- IPHONE_6_PLUS = { css_width: 414, dpr: 3 }
64
- IPHONE_6_PLUS_LANDSCAPE = { css_width: 736, dpr: 3 }
65
- MOTO_NEXUS_6 = { css_width: 412, dpr: 3.5 }
66
- MOTO_NEXUS_6_LANDSCAPE = { css_width: 690, dpr: 3.5 }
67
- LUMIA_1520 = { css_width: 432, dpr: 2.5 }
68
- LUMIA_1520_LANDSCAPE = { css_width: 768, dpr: 2.5 }
69
- GALAXY_NOTE_3 = { css_width: 360, dpr: 3 }
70
- GALAXY_NOTE_3_LANDSCAPE = { css_width: 640, dpr: 3 }
71
- GALAXY_NOTE_4 = { css_width: 360, dpr: 4 }
72
- GALAXY_NOTE_4_LANDSCAPE = { css_width: 640, dpr: 4 }
73
-
74
- # Tablets
75
- IPAD = { css_width: 768, dpr: 1 };
76
- IPAD_LANDSCAPE = { css_width: 1024, dpr: 1 };
77
- IPAD_3 = { css_width: 768, dpr: 2 };
78
- IPAD_3_LANDSCAPE = { css_width: 1024, dpr: 2 };
79
- IPAD_PRO = { css_width: 1024, dpr: 2 };
80
- IPAD_PRO_LANDSCAPE = { css_width: 1366, dpr: 2 };
81
-
82
- BOOTSTRAP_SM = { css_width: 576, dpr: 1 }
83
- BOOTSTRAP_MD = { css_width: 720, dpr: 1 }
84
- BOOTSTRAP_LG = { css_width: 940, dpr: 1 }
85
- BOOTSTRAP_XL = { css_width: 1140, dpr: 1 }
86
-
87
- def devices
88
- phones + phablets + tablets + bootstrap_breaks
36
+ def compute_standard_widths
37
+ tolerance = ::Imgix::Rails.config.imgix[:srcset_width_tolerance] || SRCSET_TOLERANCE
38
+ prev = MINIMUM_SCREEN_WIDTH
39
+ widths = []
40
+ while prev <= MAXIMUM_SCREEN_WIDTH do
41
+ widths.append(2 * (prev/2).round) # Ensure widths are even
42
+ prev = prev * (1 + tolerance*2.0)
43
+ end
44
+
45
+ widths
89
46
  end
90
47
 
91
- def bootstrap_breaks
92
- breaks = [
93
- BOOTSTRAP_SM,
94
- BOOTSTRAP_MD,
95
- BOOTSTRAP_LG,
96
- BOOTSTRAP_XL
97
- ]
48
+ def standard_widths
49
+ return @@standard_widths if @@standard_widths
98
50
 
99
- breaks + breaks.map { |b| b[:dpr] = 2; b }
100
- end
51
+ @@standard_widths = compute_standard_widths
52
+ @@standard_widths.freeze
101
53
 
102
- def phones
103
- [
104
- IPHONE,
105
- IPHONE_4,
106
- IPHONE_6,
107
- LG_G3
108
- ]
54
+ @@standard_widths
109
55
  end
110
56
 
111
- def phablets
112
- [
113
- IPHONE_6_PLUS,
114
- IPHONE_6_PLUS_LANDSCAPE,
115
- MOTO_NEXUS_6,
116
- MOTO_NEXUS_6_LANDSCAPE,
117
- LUMIA_1520,
118
- LUMIA_1520_LANDSCAPE,
119
- GALAXY_NOTE_3,
120
- GALAXY_NOTE_3_LANDSCAPE,
121
- GALAXY_NOTE_4,
122
- GALAXY_NOTE_4_LANDSCAPE
123
- ]
124
- end
57
+ private
125
58
 
126
- def tablets
127
- [
128
- IPAD,
129
- IPAD_LANDSCAPE,
130
- IPAD_3,
131
- IPAD_3_LANDSCAPE,
132
- IPAD_PRO,
133
- IPAD_PRO_LANDSCAPE
134
- ]
135
- end
59
+ MINIMUM_SCREEN_WIDTH = 100
60
+ MAXIMUM_SCREEN_WIDTH = 8192 # Maximum width supported by imgix
61
+ SRCSET_TOLERANCE = 0.08
136
62
 
137
63
  # Return the widths to generate given the input `sizes`
138
64
  # attribute.
139
65
  #
140
66
  # @return {Array} An array of {Fixnum} instances representing the unique `srcset` URLs to generate.
141
67
  def target_widths
142
- min_screen_width_required = @options[:min_width] || SCREEN_STEP
143
- max_screen_width_required = @options[:max_width] || MAXIMUM_SCREEN_WIDTH
144
-
145
- widths = (device_widths + screen_widths).select do |w|
146
- w <= max_screen_width_required && w >= min_screen_width_required
147
- end.compact.uniq.sort
148
-
149
- # Add exact widths for 1x, 2x, and 3x devices
150
- if @options[:w]
151
- widths.push(@options[:w], @options[:w] * 2, @options[:w] * 3)
68
+ min_width = @tag_options[:min_width]
69
+ max_width = @tag_options[:max_width]
70
+ if min_width || max_width
71
+ min_width = min_width || MINIMUM_SCREEN_WIDTH
72
+ max_width = max_width || MAXIMUM_SCREEN_WIDTH
73
+ widths = standard_widths.select { |w| min_width <= w && w <= max_width }
74
+ else
75
+ widths = standard_widths
152
76
  end
153
77
 
154
78
  widths
155
79
  end
156
80
 
157
- def device_widths
158
- devices.map do |device|
159
- (device[:css_width] * device[:dpr]).round
160
- end
161
- end
162
-
163
- # Generates an array of physical screen widths to represent
164
- # the different potential viewport sizes.
165
- #
166
- # We step by `SCREEN_STEP` to give some sanity to the amount
167
- # of widths we output.
168
- #
169
- # The upper bound is the widest known screen on the planet.
170
- # @return {Array} An array of {Fixnum} instances
171
- def screen_widths
172
- (0..MAXIMUM_SCREEN_WIDTH).step(SCREEN_STEP).to_a + [MAXIMUM_SCREEN_WIDTH]
173
- end
174
81
  end