imgix-rails 2.1.4 → 4.2.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.
@@ -1,174 +1,31 @@
1
1
  require "imgix/rails/url_helper"
2
+ require "action_view"
2
3
 
3
4
  class Imgix::Rails::Tag
4
5
  include Imgix::Rails::UrlHelper
5
6
  include ActionView::Helpers
6
7
 
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={})
8
+ def initialize(path, source: nil, tag_options: {}, url_params: {}, srcset_options: {}, attribute_options: {})
9
+ @path = path
27
10
  @source = source
28
- @options = options
11
+ @tag_options = tag_options
12
+ @url_params = url_params
13
+ @srcset_options = srcset_options
14
+ @attribute_options = attribute_options
29
15
  end
30
16
 
31
17
  protected
32
18
 
33
- def srcset(opts=@options)
34
- @source = replace_hostname(@source)
35
- widths = opts[:widths] || target_widths
36
-
37
- widths.map do |width|
38
- srcset_options = opts.slice(*self.class.available_parameters).except(:widths)
39
- srcset_options[:w] = width
40
-
41
- if opts[:w].present? && opts[:h].present?
42
- srcset_options[:h] = (width * (opts[:h].to_f / opts[:w])).round
43
- end
44
-
45
- "#{ix_image_url(@source, srcset_options)} #{width}w"
46
- end.join(', ')
47
- end
48
-
49
- private
50
-
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 }
19
+ def srcset(source: @source, path: @path, url_params: @url_params, srcset_options: @srcset_options, tag_options: @tag_options)
20
+ params = url_params.clone
86
21
 
87
- def devices
88
- phones + phablets + tablets + bootstrap_breaks
89
- end
90
-
91
- def bootstrap_breaks
92
- breaks = [
93
- BOOTSTRAP_SM,
94
- BOOTSTRAP_MD,
95
- BOOTSTRAP_LG,
96
- BOOTSTRAP_XL
97
- ]
98
-
99
- breaks + breaks.map { |b| b[:dpr] = 2; b }
100
- end
101
-
102
- def phones
103
- [
104
- IPHONE,
105
- IPHONE_4,
106
- IPHONE_6,
107
- LG_G3
108
- ]
109
- end
110
-
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
125
-
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
136
-
137
- # Return the widths to generate given the input `sizes`
138
- # attribute.
139
- #
140
- # @return {Array} An array of {Fixnum} instances representing the unique `srcset` URLs to generate.
141
- 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)
152
- end
153
-
154
- widths
155
- end
156
-
157
- def device_widths
158
- devices.map do |device|
159
- (device[:css_width] * device[:dpr]).round
160
- end
161
- end
22
+ width_tolerance = ::Imgix::Rails.config.imgix[:srcset_width_tolerance]
23
+ min_width = @srcset_options[:min_width]
24
+ max_width = @srcset_options[:max_width]
25
+ widths = @srcset_options[:widths]
26
+ disable_variable_quality = @srcset_options[:disable_variable_quality]
27
+ options = { widths: widths, width_tolerance: width_tolerance, min_width: min_width, max_width: max_width, disable_variable_quality: disable_variable_quality}
162
28
 
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]
29
+ ix_image_srcset(@source, @path, params, options)
173
30
  end
174
31
  end
@@ -3,56 +3,118 @@ module Imgix
3
3
  class ConfigurationError < StandardError; end
4
4
 
5
5
  module UrlHelper
6
- def ix_image_url(source, options={})
6
+ def ix_image_url(*args)
7
7
  validate_configuration!
8
8
 
9
- source = replace_hostname(source)
9
+ case args.size
10
+ when 1
11
+ path = args[0]
12
+ source = nil
13
+ params = {}
14
+ when 2
15
+ if args[0].is_a?(String) && args[1].is_a?(Hash)
16
+ source = nil
17
+ path = args[0]
18
+ params = args[1]
19
+ elsif args[0].is_a?(String) && args[1].is_a?(String)
20
+ source = args[0]
21
+ path = args[1]
22
+ params = {}
23
+ else
24
+ raise RuntimeError.new("path and source must be of type String; params must be of type Hash")
25
+ end
26
+ when 3
27
+ source = args[0]
28
+ path = args[1]
29
+ params = args[2]
30
+ else
31
+ raise RuntimeError.new('path missing')
32
+ end
33
+
34
+ imgix_client(source).path(path).to_url(params).html_safe
35
+ end
36
+
37
+ protected
38
+
39
+ def ix_image_srcset(*args)
40
+ validate_configuration!
10
41
 
11
- imgix_client.path(source).to_url(options).html_safe
42
+ case args.size
43
+ when 1
44
+ path = args[0]
45
+ source = nil
46
+ params = {}
47
+ when 2
48
+ if args[0].is_a?(String) && args[1].is_a?(Hash)
49
+ source = nil
50
+ path = args[0]
51
+ params = args[1]
52
+ elsif args[0].is_a?(String) && args[1].is_a?(String)
53
+ source = args[0]
54
+ path = args[1]
55
+ params = {}
56
+ else
57
+ raise RuntimeError.new("path and source must be of type String; params must be of type Hash")
58
+ end
59
+ when 3
60
+ source = args[0]
61
+ path = args[1]
62
+ params = args[2]
63
+ when 4
64
+ source = args[0]
65
+ path = args[1]
66
+ params = args[2]
67
+ options = args[3]
68
+ else
69
+ raise RuntimeError.new('path missing')
70
+ end
71
+ imgix_client(source).path(path).to_srcset(options: options, **params).html_safe
12
72
  end
13
73
 
14
74
  private
15
75
 
16
76
  def validate_configuration!
17
77
  imgix = ::Imgix::Rails.config.imgix
18
- unless imgix.try(:[], :source)
19
- raise ConfigurationError.new("imgix source is not configured. Please set config.imgix[:source].")
20
- end
21
78
 
22
- unless imgix[:source].is_a?(Array) || imgix[:source].is_a?(String)
23
- raise ConfigurationError.new("imgix source must be a String or an Array.")
79
+ if imgix.slice(:source, :sources).size != 1
80
+ raise ConfigurationError.new("Exactly one of :source, :sources is required")
24
81
  end
25
- end
26
-
27
- def replace_hostname(source)
28
- new_source = source.dup
29
82
 
30
- # Replace any hostnames configured to trim things down just to their paths.
31
- # We use split to remove the protocol in the process.
32
- hostnames_to_remove.each do |hostname|
33
- splits = source.split(hostname)
34
- new_source = splits.last if splits.size > 1
83
+ if imgix[:source]
84
+ unless imgix[:source].is_a?(String)
85
+ raise ConfigurationError.new("imgix source must be a String.")
86
+ end
35
87
  end
36
88
 
37
- new_source
89
+ if imgix[:sources]
90
+ unless imgix[:sources].is_a?(Hash)
91
+ raise ConfigurationError.new(":sources must be a Hash")
92
+ end
93
+ end
38
94
  end
39
95
 
40
- def hostnames_to_remove
41
- Array(::Imgix::Rails.config.imgix[:hostname_to_replace] || ::Imgix::Rails.config.imgix[:hostnames_to_replace])
96
+ def imgix_client(source)
97
+ begin
98
+ return imgix_clients.fetch(source)
99
+ rescue KeyError
100
+ raise RuntimeError.new("Unknown source '#{source}'")
101
+ end
42
102
  end
43
103
 
44
- def imgix_client
45
- return @imgix_client if @imgix_client
104
+ def imgix_clients
105
+ return @imgix_clients if @imgix_clients
46
106
  imgix = ::Imgix::Rails.config.imgix
47
107
 
48
108
  opts = {
49
- host: imgix[:source],
50
109
  library_param: "rails",
51
110
  library_version: Imgix::Rails::VERSION,
52
111
  use_https: true,
53
- secure_url_token: imgix[:secure_url_token]
54
112
  }
55
113
 
114
+ if imgix[:source].is_a?(String)
115
+ opts[:domain] = imgix[:source]
116
+ end
117
+
56
118
  if imgix.has_key?(:include_library_param)
57
119
  opts[:include_library_param] = imgix[:include_library_param]
58
120
  end
@@ -61,7 +123,21 @@ module Imgix
61
123
  opts[:use_https] = imgix[:use_https]
62
124
  end
63
125
 
64
- @imgix_client = ::Imgix::Client.new(opts)
126
+ sources = imgix[:sources] || { imgix[:source] => imgix[:secure_url_token] }
127
+ @imgix_clients = {}
128
+
129
+ sources.map do |source, token|
130
+ opts[:domain] = source
131
+ opts[:secure_url_token] = token
132
+ @imgix_clients[source] = ::Imgix::Client.new(opts)
133
+ end
134
+
135
+ default_source = imgix[:default_source] || imgix[:source]
136
+ if default_source
137
+ @imgix_clients[nil] = @imgix_clients.fetch(default_source)
138
+ end
139
+
140
+ @imgix_clients
65
141
  end
66
142
  end
67
143
  end
@@ -1,5 +1,5 @@
1
1
  module Imgix
2
2
  module Rails
3
- VERSION = '2.1.4'
3
+ VERSION = '4.2.0'
4
4
  end
5
5
  end
@@ -1,4 +1,5 @@
1
1
  require "imgix"
2
+ require "imgix/rails/tag"
2
3
  require "imgix/rails/image_tag"
3
4
  require "imgix/rails/picture_tag"
4
5
 
@@ -7,12 +8,12 @@ module Imgix
7
8
  module ViewHelper
8
9
  include UrlHelper
9
10
 
10
- def ix_image_tag(source, options={})
11
- Imgix::Rails::ImageTag.new(source, options).render
11
+ def ix_image_tag(source=nil, path, tag_options: {}, url_params: {}, srcset_options: {}, attribute_options: {})
12
+ return Imgix::Rails::ImageTag.new(path, source: source, tag_options: tag_options, url_params: url_params, srcset_options: srcset_options, attribute_options: attribute_options).render
12
13
  end
13
14
 
14
- def ix_picture_tag(source, picture_tag_options:, imgix_default_options:, breakpoints:)
15
- Imgix::Rails::PictureTag.new(source, picture_tag_options, imgix_default_options, breakpoints).render
15
+ def ix_picture_tag(source=nil, path, tag_options: {}, url_params: {}, breakpoints: {}, srcset_options: {})
16
+ return Imgix::Rails::PictureTag.new(path, source: source, tag_options: tag_options, url_params: url_params, breakpoints: breakpoints, srcset_options: srcset_options).render
16
17
  end
17
18
  end
18
19
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imgix-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.4
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kelly Sutton
@@ -9,40 +9,34 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2017-06-01 00:00:00.000000000 Z
12
+ date: 2021-01-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: imgix
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
19
- - !ruby/object:Gem::Version
20
- version: '1.1'
21
18
  - - ">="
22
19
  - !ruby/object:Gem::Version
23
- version: 1.1.0
20
+ version: '3.0'
24
21
  type: :runtime
25
22
  prerelease: false
26
23
  version_requirements: !ruby/object:Gem::Requirement
27
24
  requirements:
28
- - - "~>"
29
- - !ruby/object:Gem::Version
30
- version: '1.1'
31
25
  - - ">="
32
26
  - !ruby/object:Gem::Version
33
- version: 1.1.0
27
+ version: '3.0'
34
28
  - !ruby/object:Gem::Dependency
35
29
  name: bundler
36
30
  requirement: !ruby/object:Gem::Requirement
37
31
  requirements:
38
- - - "~>"
32
+ - - ">="
39
33
  - !ruby/object:Gem::Version
40
34
  version: '1.9'
41
35
  type: :development
42
36
  prerelease: false
43
37
  version_requirements: !ruby/object:Gem::Requirement
44
38
  requirements:
45
- - - "~>"
39
+ - - ">="
46
40
  - !ruby/object:Gem::Version
47
41
  version: '1.9'
48
42
  - !ruby/object:Gem::Dependency
@@ -51,14 +45,14 @@ dependencies:
51
45
  requirements:
52
46
  - - "~>"
53
47
  - !ruby/object:Gem::Version
54
- version: '10.0'
48
+ version: '12.3'
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
52
  requirements:
59
53
  - - "~>"
60
54
  - !ruby/object:Gem::Version
61
- version: '10.0'
55
+ version: '12.3'
62
56
  - !ruby/object:Gem::Dependency
63
57
  name: rspec
64
58
  requirement: !ruby/object:Gem::Requirement
@@ -97,10 +91,17 @@ executables: []
97
91
  extensions: []
98
92
  extra_rdoc_files: []
99
93
  files:
94
+ - ".github/CODEOWNERS"
95
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
96
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
97
+ - ".github/ISSUE_TEMPLATE/question.md"
98
+ - ".github/pull_request_template.md"
100
99
  - ".gitignore"
101
100
  - ".rspec"
102
101
  - ".travis.yml"
102
+ - CHANGELOG.md
103
103
  - Gemfile
104
+ - LICENSE
104
105
  - README.md
105
106
  - Rakefile
106
107
  - bin/console
@@ -114,11 +115,14 @@ files:
114
115
  - lib/imgix/rails/version.rb
115
116
  - lib/imgix/rails/view_helper.rb
116
117
  - lib/imgix/railtie.rb
117
- - vendor/parameters.json
118
118
  homepage: https://github.com/imgix/imgix-rails
119
119
  licenses:
120
- - MIT
120
+ - BSD-2-Clause
121
121
  metadata:
122
+ bug_tracker_uri: https://github.com/imgix/imgix-rails/issues
123
+ changelog_uri: https://github.com/imgix/imgix-rails/blob/main/CHANGELOG.md
124
+ documentation_uri: https://www.rubydoc.info/gems/imgix-rails/4.2.0
125
+ source_code_uri: https://github.com/imgix/imgix-rails/tree/v4.2.0
122
126
  allowed_push_host: https://rubygems.org
123
127
  post_install_message:
124
128
  rdoc_options: []
@@ -135,8 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
139
  - !ruby/object:Gem::Version
136
140
  version: '0'
137
141
  requirements: []
138
- rubyforge_project:
139
- rubygems_version: 2.6.8
142
+ rubygems_version: 3.1.4
140
143
  signing_key:
141
144
  specification_version: 4
142
145
  summary: Makes integrating imgix into your Rails app easier. It builds on imgix-rb