retina_rails 1.0.4 → 2.0.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 +4 -4
- data/.gitignore +1 -3
- data/.travis.yml +16 -4
- data/README.md +57 -29
- data/UPGRADING +7 -0
- data/UPGRADING.md +60 -0
- data/lib/retina_rails.rb +11 -7
- data/lib/retina_rails/extensions.rb +16 -0
- data/lib/retina_rails/extensions/carrierwave.rb +25 -0
- data/lib/retina_rails/extensions/paperclip.rb +23 -0
- data/lib/retina_rails/helpers.rb +42 -12
- data/lib/retina_rails/processors.rb +14 -0
- data/lib/retina_rails/processors/carrierwave.rb +49 -0
- data/lib/retina_rails/processors/paperclip.rb +30 -0
- data/lib/retina_rails/strategies.rb +6 -7
- data/lib/retina_rails/strategies/carrierwave.rb +56 -50
- data/lib/retina_rails/strategies/paperclip.rb +53 -55
- data/lib/retina_rails/version.rb +1 -1
- data/retina_rails.gemspec +11 -4
- data/spec/fixtures/db/retina_rails.sqlite3 +0 -0
- data/spec/helpers_spec.rb +87 -13
- data/spec/spec_helper.rb +10 -4
- data/spec/strategies/carrierwave_spec.rb +117 -154
- data/spec/strategies/paperclip_spec.rb +77 -104
- data/spec/support/carrierwave.rb +15 -0
- data/spec/support/file_string_io.rb +2 -0
- data/spec/support/paperclip.rb +9 -0
- data/spec/support/rails.rb +0 -11
- data/spec/support/schema.rb +8 -2
- metadata +53 -52
- data/lib/retina_rails/deprecation/carrierwave.rb +0 -23
- data/lib/retina_rails/deprecation/paperclip.rb +0 -23
- data/lib/retina_rails/exception.rb +0 -15
- data/spec/deprecation/carrierwave_spec.rb +0 -13
- data/spec/deprecation/paperclip_spec.rb +0 -14
- data/spec/fixtures/images/avatar.with.dots.jpeg +0 -0
- data/spec/fixtures/manifest.yml +0 -10
- data/vendor/assets/javascripts/retina.js +0 -113
@@ -0,0 +1,14 @@
|
|
1
|
+
module RetinaRails
|
2
|
+
module Processors
|
3
|
+
|
4
|
+
def self.include_processors
|
5
|
+
if defined?(::CarrierWave)
|
6
|
+
require 'retina_rails/processors/carrierwave'
|
7
|
+
end
|
8
|
+
if defined?(::Paperclip)
|
9
|
+
require 'retina_rails/processors/paperclip'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end # Processors
|
14
|
+
end # RetinaRails
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module RetinaRails
|
2
|
+
module Processors
|
3
|
+
module CarrierWave
|
4
|
+
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
##
|
8
|
+
# Stores the original dimensions of the image as a serialized Hash in to the model
|
9
|
+
#
|
10
|
+
def store_retina_dimensions
|
11
|
+
if model
|
12
|
+
width, height = `identify -format "%wx%h" #{file.path}`.split(/x/) ## Read dimensions
|
13
|
+
|
14
|
+
## Set original height and width attributes on model
|
15
|
+
|
16
|
+
model.retina_dimensions = (model.retina_dimensions || {}).deep_merge!(
|
17
|
+
mounted_as => {
|
18
|
+
version_name => {
|
19
|
+
:width => width.to_i / 2,
|
20
|
+
:height => height.to_i / 2
|
21
|
+
}
|
22
|
+
}
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Process retina quality of the image.
|
29
|
+
# Works with ImageMagick and MiniMagick
|
30
|
+
#
|
31
|
+
# === Parameters
|
32
|
+
#
|
33
|
+
# [percentage (Int)] quality in percentage
|
34
|
+
#
|
35
|
+
def retina_quality(percentage)
|
36
|
+
manipulate! do |img|
|
37
|
+
if defined?(Magick)
|
38
|
+
img.write(current_path) { self.quality = percentage } unless img.quality == percentage
|
39
|
+
elsif defined?(MiniMagick)
|
40
|
+
img.quality(percentage.to_s)
|
41
|
+
end
|
42
|
+
img = yield(img) if block_given?
|
43
|
+
img
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end # CarrierWave
|
48
|
+
end # Processors
|
49
|
+
end # RetinaRails
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Paperclip
|
2
|
+
class SaveDimensions < Paperclip::Processor
|
3
|
+
|
4
|
+
##
|
5
|
+
# Stores the original dimensions of the image as a serialized Hash in to the model
|
6
|
+
#
|
7
|
+
def make
|
8
|
+
model = attachment.instance
|
9
|
+
file_path = file.path rescue nil
|
10
|
+
style = options[:style]
|
11
|
+
|
12
|
+
if file_path
|
13
|
+
width, height = `identify -format "%wx%h" #{file_path}`.split(/x/) ## Read dimensions
|
14
|
+
|
15
|
+
## Set original height and width attributes on model
|
16
|
+
model.retina_dimensions = (model.retina_dimensions || {}).deep_merge!(
|
17
|
+
attachment.name => {
|
18
|
+
style => {
|
19
|
+
:width => width.to_i / 2,
|
20
|
+
:height => height.to_i / 2
|
21
|
+
}
|
22
|
+
}
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
file
|
27
|
+
end
|
28
|
+
|
29
|
+
end # SaveDimensions
|
30
|
+
end # Paperclip
|
@@ -1,17 +1,16 @@
|
|
1
|
-
require 'retina_rails/strategies/carrierwave'
|
2
|
-
require 'retina_rails/strategies/paperclip'
|
3
|
-
|
4
1
|
module RetinaRails
|
5
2
|
module Strategies
|
6
3
|
|
7
4
|
def self.include_strategies
|
8
5
|
if defined?(::CarrierWave)
|
9
|
-
|
6
|
+
require 'retina_rails/strategies/carrierwave'
|
7
|
+
::CarrierWave::Uploader::Base.send(:include, CarrierWave::Base)
|
10
8
|
end
|
11
9
|
if defined?(::Paperclip)
|
12
|
-
|
10
|
+
require 'retina_rails/strategies/paperclip'
|
11
|
+
::ActiveRecord::Base.send(:include, Paperclip::Base)
|
13
12
|
end
|
14
13
|
end
|
15
14
|
|
16
|
-
end
|
17
|
-
end
|
15
|
+
end # Strategies
|
16
|
+
end # RetinaRails
|
@@ -11,25 +11,57 @@ module RetinaRails
|
|
11
11
|
include Uploader
|
12
12
|
end
|
13
13
|
|
14
|
-
end
|
14
|
+
end # ClassMethods
|
15
15
|
|
16
|
-
end
|
16
|
+
end # Base
|
17
17
|
|
18
18
|
module Uploader
|
19
19
|
|
20
20
|
extend ActiveSupport::Concern
|
21
|
+
include Processors::CarrierWave
|
21
22
|
|
22
23
|
module ClassMethods
|
23
24
|
|
25
|
+
##
|
26
|
+
# Adds a new version to this uploader
|
27
|
+
#
|
28
|
+
# === Parameters
|
29
|
+
#
|
30
|
+
# [name (#to_sym)] name of the version
|
31
|
+
# [options (Hash)] optional options hash
|
32
|
+
# [&block (Proc)] a block to eval on this version of the uploader
|
33
|
+
#
|
34
|
+
# === Examples
|
35
|
+
#
|
36
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
37
|
+
#
|
38
|
+
# retina!
|
39
|
+
#
|
40
|
+
# version :thumb do
|
41
|
+
# process :resize_to_fill => [30, 30]
|
42
|
+
# process :retina_quality => 25
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# version :thumb, :retina => false do
|
46
|
+
# process :resize_to_fill => [30, 30]
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# end
|
50
|
+
#
|
24
51
|
def version(name, options={}, &block)
|
25
52
|
super
|
26
53
|
|
27
|
-
|
54
|
+
optimize_retina!(name, { :if => options[:if] }) unless options[:retina] == false
|
28
55
|
end
|
29
56
|
|
30
|
-
|
31
|
-
#
|
32
|
-
|
57
|
+
##
|
58
|
+
# Optimize version for retina displays
|
59
|
+
#
|
60
|
+
# === Parameters
|
61
|
+
#
|
62
|
+
# [name (Sym)] name of the version
|
63
|
+
#
|
64
|
+
def optimize_retina!(name, options={})
|
33
65
|
config = versions[name]
|
34
66
|
options[:retina] = false
|
35
67
|
|
@@ -43,65 +75,39 @@ module RetinaRails
|
|
43
75
|
|
44
76
|
## Define a retina version if processor is present
|
45
77
|
if dimensions_processor
|
78
|
+
dimensions = dimensions_processor[1].dup
|
46
79
|
|
47
|
-
|
80
|
+
width = dimensions[0] * 2
|
81
|
+
height = dimensions[1] * 2
|
48
82
|
|
49
|
-
|
50
|
-
height = processor_options[1] * 2
|
83
|
+
2.times { dimensions.delete_at(0) }
|
51
84
|
|
52
|
-
|
85
|
+
dimensions.insert(0, height)
|
86
|
+
dimensions.insert(0, width)
|
53
87
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
version "#{name}_retina", options do
|
58
|
-
process dimensions_processor[0] => processor_options
|
88
|
+
## Override version with double height and width
|
89
|
+
version name, options do
|
90
|
+
process dimensions_processor[0] => dimensions
|
59
91
|
|
60
92
|
quality_processor = nil
|
61
93
|
|
62
94
|
## Set other processors
|
63
95
|
processors.each do |processor|
|
64
|
-
process processor[0] => processor[1]
|
65
|
-
|
66
96
|
quality_processor = true if processor[0] == :retina_quality
|
67
97
|
end
|
68
98
|
|
69
99
|
## Set default quality if retina_quality is not defined
|
70
|
-
process :retina_quality =>
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
100
|
+
process :retina_quality => 60 if quality_processor.nil?
|
74
101
|
|
75
|
-
|
76
|
-
|
77
|
-
## Set the correct filename for storage according to the convention (append @2x to filename)
|
78
|
-
def full_filename(for_file)
|
79
|
-
super.tap do |file_name|
|
80
|
-
if version_name.to_s.include?('retina')
|
81
|
-
has_extension = file_name.scan(/(jpg|jpeg|png|gif|bmp)/).any?
|
82
|
-
|
83
|
-
regex = has_extension ? /(.*)\./ : /.*/
|
84
|
-
file_name.sub!(regex, '\1@2x.').gsub!('retina_', '')
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
## Set retina image quality
|
90
|
-
def retina_quality(percentage)
|
91
|
-
if version_name.to_s.include?('retina')
|
92
|
-
manipulate! do |img|
|
93
|
-
if defined?(Magick)
|
94
|
-
img.write(current_path) { self.quality = percentage } unless img.quality == percentage
|
95
|
-
elsif defined?(MiniMagick)
|
96
|
-
img.quality(percentage.to_s)
|
102
|
+
## Store dimensions
|
103
|
+
process :store_retina_dimensions
|
97
104
|
end
|
98
|
-
img = yield(img) if block_given?
|
99
|
-
img
|
100
105
|
end
|
101
106
|
end
|
102
|
-
end
|
103
107
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
108
|
+
end # ClassMethods
|
109
|
+
|
110
|
+
end # Uploader
|
111
|
+
end # CarrierWave
|
112
|
+
end # Strategies
|
113
|
+
end # RetinaRails
|
@@ -9,33 +9,59 @@ module RetinaRails
|
|
9
9
|
module ClassMethods
|
10
10
|
|
11
11
|
def retina!
|
12
|
+
serialize :retina_dimensions
|
13
|
+
|
12
14
|
include Uploader
|
13
15
|
end
|
14
16
|
|
15
|
-
end
|
17
|
+
end # Class methods
|
16
18
|
|
17
|
-
end
|
19
|
+
end # Base
|
18
20
|
|
19
21
|
module Uploader
|
20
22
|
|
21
23
|
extend ActiveSupport::Concern
|
22
24
|
|
23
|
-
included do
|
24
|
-
|
25
|
-
## Override paperclip default options
|
26
|
-
Extensions.override_default_options
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
25
|
module ClassMethods
|
31
26
|
|
27
|
+
##
|
28
|
+
# Define an attachment with its options
|
29
|
+
#
|
30
|
+
# === Parameters
|
31
|
+
#
|
32
|
+
# [name (#to_sym)] name of the version
|
33
|
+
# [options (Hash)] optional options hash
|
34
|
+
#
|
35
|
+
# === Examples
|
36
|
+
#
|
37
|
+
# class Upload
|
38
|
+
#
|
39
|
+
# retina!
|
40
|
+
#
|
41
|
+
# has_attached_file :image,
|
42
|
+
# :styles => {
|
43
|
+
# :original => ["800x800", :jpg],
|
44
|
+
# :big => ["125x125#", :jpg]
|
45
|
+
# },
|
46
|
+
# :retina => true # Or
|
47
|
+
# :retina => { :quality => 25 } # Optional
|
48
|
+
#
|
49
|
+
# end
|
50
|
+
#
|
32
51
|
def has_attached_file(name, options={})
|
33
52
|
super
|
34
53
|
|
35
|
-
|
54
|
+
optimize_retina! name unless options[:retina] == false
|
36
55
|
end
|
37
56
|
|
38
|
-
|
57
|
+
##
|
58
|
+
# Optimize attachment for retina displays
|
59
|
+
#
|
60
|
+
# === Parameters
|
61
|
+
#
|
62
|
+
# [name (Sym)] name of the attachment
|
63
|
+
#
|
64
|
+
def optimize_retina!(name)
|
39
65
|
attachment = attachment_definitions[name]
|
40
66
|
|
41
67
|
## Check for style definitions
|
@@ -44,7 +70,7 @@ module RetinaRails
|
|
44
70
|
retina_options = if attachment[:retina].is_a?(Hash)
|
45
71
|
attachment[:retina]
|
46
72
|
else
|
47
|
-
{ :quality =>
|
73
|
+
{ :quality => 60 }
|
48
74
|
end
|
49
75
|
|
50
76
|
## Get retina quality
|
@@ -67,64 +93,36 @@ module RetinaRails
|
|
67
93
|
processor = dimensions.scan(/#|</).first
|
68
94
|
|
69
95
|
new_dimensions = "#{width}x#{height}#{processor}"
|
70
|
-
retina_styles[
|
96
|
+
retina_styles[key.to_sym] = value.kind_of?(Array) ? [new_dimensions, value[1]] : new_dimensions
|
71
97
|
|
72
98
|
## Set quality convert option
|
73
99
|
convert_option = convert_options[key] if convert_options
|
74
100
|
convert_option = convert_option ? "#{convert_option} -quality #{retina_quality}" : "-quality #{retina_quality}"
|
75
|
-
retina_convert_options[
|
101
|
+
retina_convert_options[key.to_sym] = convert_option
|
76
102
|
|
77
103
|
end
|
78
104
|
|
79
|
-
##
|
105
|
+
## Override styles with new retina dimensions
|
80
106
|
attachment[:styles].merge!(retina_styles)
|
81
107
|
|
82
108
|
## Set quality convert options
|
83
109
|
attachment[:convert_options] = {} if attachment[:convert_options].nil?
|
84
110
|
attachment[:convert_options].merge!(retina_convert_options)
|
85
111
|
|
86
|
-
##
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
module Extensions
|
100
|
-
|
101
|
-
## Insert :retina interpolation in url or path
|
102
|
-
def self.optimize_path(path)
|
103
|
-
path.scan(':retina').empty? ? path.gsub(':filename', ':basename.:extension').split('.').insert(-2, ':retina.').join : path
|
104
|
-
end
|
105
|
-
|
106
|
-
def self.override_default_options
|
107
|
-
|
108
|
-
## Remove _retina from style so it doesn't end up in filename
|
109
|
-
::Paperclip.interpolates :style do |attachment, style|
|
110
|
-
style.to_s.end_with?('_retina') ? style.to_s[0..-8] : style
|
111
|
-
end
|
112
|
+
## Set save dimensions processor
|
113
|
+
if attachment[:processors]
|
114
|
+
attachment[:processors] << :save_dimensions
|
115
|
+
attachment[:processors] << :thumbnail
|
116
|
+
else
|
117
|
+
attachment[:processors] = [:thumbnail, :save_dimensions]
|
118
|
+
end
|
112
119
|
|
113
|
-
## Replace :retina with @2x if style ends with _retina
|
114
|
-
::Paperclip.interpolates :retina do |attachment, style|
|
115
|
-
style.to_s.end_with?('_retina') ? '@2x' : ''
|
116
120
|
end
|
117
|
-
|
118
|
-
## Make default url compatible with retina optimzer
|
119
|
-
url = ::Paperclip::Attachment.default_options[:url]
|
120
|
-
::Paperclip::Attachment.default_options[:url] = optimize_path(url)
|
121
|
-
|
122
121
|
end
|
123
122
|
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
123
|
+
end # ClassMethods
|
124
|
+
end # Uploader
|
127
125
|
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
126
|
+
end # Paperclip
|
127
|
+
end # Strategies
|
128
|
+
end # RetinaRails
|
data/lib/retina_rails/version.rb
CHANGED
data/retina_rails.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |gem|
|
|
9
9
|
gem.authors = ['Johan van Zonneveld', 'Arjen Oosterkamp']
|
10
10
|
gem.email = ['johan@vzonneveld.nl', 'mail@arjen.me']
|
11
11
|
gem.homepage = 'https://github.com/jhnvz/retina_rails.git'
|
12
|
-
gem.summary = %q{Makes your life easier optimizing for retina displays}
|
13
|
-
gem.description = %q{Retina Rails
|
12
|
+
gem.summary = %q{Makes your life easier optimizing your application for retina displays}
|
13
|
+
gem.description = %q{Retina Rails makes your application use high-resolution images by default. It automatically optimizes uploaded images (CarrierWave or Paperclip) for retina displays by making them twice the size and reducing the quality.}
|
14
14
|
gem.license = 'MIT'
|
15
15
|
|
16
16
|
gem.files = `git ls-files`.split($/)
|
@@ -23,11 +23,18 @@ Gem::Specification.new do |gem|
|
|
23
23
|
gem.add_development_dependency 'rspec', '>= 2.3'
|
24
24
|
gem.add_development_dependency 'rspec-rails', '~> 2.0'
|
25
25
|
gem.add_development_dependency 'carrierwave'
|
26
|
-
gem.add_development_dependency 'paperclip'
|
26
|
+
gem.add_development_dependency 'paperclip'
|
27
27
|
gem.add_development_dependency 'rmagick'
|
28
28
|
gem.add_development_dependency 'sqlite3'
|
29
29
|
gem.add_development_dependency 'coveralls'
|
30
30
|
|
31
|
+
if RUBY_VERSION > '1.9.2'
|
32
|
+
gem.add_dependency 'rails', '>= 3.2.0'
|
33
|
+
else
|
34
|
+
gem.add_dependency 'rails', '>= 3.2.0', '< 4.0.0'
|
35
|
+
end
|
31
36
|
|
32
|
-
|
37
|
+
if File.exists?('UPGRADING')
|
38
|
+
gem.post_install_message = File.read("UPGRADING")
|
39
|
+
end
|
33
40
|
end
|