retina_rails 0.1.3 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +37 -9
- data/lib/retina_rails.rb +7 -5
- data/lib/retina_rails/deprecation/carrierwave.rb +23 -0
- data/lib/retina_rails/deprecation/paperclip.rb +23 -0
- data/lib/retina_rails/exception.rb +15 -0
- data/lib/retina_rails/strategies.rb +19 -0
- data/lib/retina_rails/strategies/carrierwave.rb +101 -0
- data/lib/retina_rails/strategies/paperclip.rb +129 -0
- data/lib/retina_rails/version.rb +1 -1
- data/spec/deprecation/carrierwave_spec.rb +13 -0
- data/spec/deprecation/paperclip_spec.rb +14 -0
- data/spec/fixtures/db/retina_rails.sqlite3 +0 -0
- data/spec/spec_helper.rb +5 -1
- data/spec/{carrierwave_spec.rb → strategies/carrierwave_spec.rb} +37 -6
- data/spec/{paperclip_spec.rb → strategies/paperclip_spec.rb} +44 -8
- metadata +19 -14
- data/lib/retina_rails/carrierwave.rb +0 -79
- data/lib/retina_rails/extensions.rb +0 -26
- data/lib/retina_rails/paperclip.rb +0 -69
- data/spec/extensions_spec.rb +0 -38
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/retina_rails.png)](http://badge.fury.io/rb/retina_rails) [![Build Status](https://secure.travis-ci.org/jhnvz/retina_rails.png?branch=master)](http://travis-ci.org/jhnvz/retina_rails) [![Coverage Status](https://coveralls.io/repos/jhnvz/retina_rails/badge.png?branch=master)](https://coveralls.io/r/jhnvz/retina_rails) [![Code Climate](https://codeclimate.com/github/jhnvz/retina_rails.png)](https://codeclimate.com/github/jhnvz/retina_rails) [![Dependency Status](https://gemnasium.com/jhnvz/retina_rails.png)](https://gemnasium.com/jhnvz/retina_rails)
|
4
4
|
|
5
|
-
Makes your
|
5
|
+
Makes your life easier optimizing an application for retina displays.
|
6
6
|
|
7
7
|
How it works
|
8
8
|
------------
|
@@ -21,42 +21,70 @@ Installation
|
|
21
21
|
CarrierWave
|
22
22
|
------------
|
23
23
|
|
24
|
-
|
24
|
+
Simply add `retina!` to your uploader.
|
25
25
|
|
26
26
|
```ruby
|
27
27
|
class ExampleUploader < CarrierWave::Uploader::Base
|
28
28
|
|
29
|
+
retina!
|
30
|
+
|
29
31
|
version :small do
|
30
32
|
process :resize_to_fill => [30, 30]
|
31
33
|
process :retina_quality => 25
|
32
34
|
end
|
33
35
|
|
34
|
-
|
36
|
+
version :large, :retina => false do
|
37
|
+
process :resize_to_fill => [1000, 1000]
|
38
|
+
end
|
35
39
|
|
36
40
|
end
|
37
41
|
```
|
38
|
-
By default it sets the retina image quality to 40 which can be overriden with `process :retina_quality => 25`
|
42
|
+
By default it sets the retina image quality to 40 which can be overriden with `process :retina_quality => 25`. To disable the creation of a retina version simply call `version :small, :retina => false`.
|
43
|
+
|
44
|
+
### Custom processors
|
45
|
+
|
46
|
+
You can also use your custom processors like so:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
class ExampleUploader < CarrierWave::Uploader::Base
|
50
|
+
|
51
|
+
retina!
|
52
|
+
|
53
|
+
version :small, :retina => false do
|
54
|
+
process :resize_to_fill_with_gravity => [100, 100, 'North', :jpg, 75]
|
55
|
+
end
|
56
|
+
|
57
|
+
version :small_retina, :retina => false do
|
58
|
+
process :resize_to_fill_with_gravity => [200, 200, 'North', :jpg, 40]
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
This will generate `small.jpg` and `small@2x.jpg`.
|
65
|
+
|
39
66
|
|
40
67
|
Paperclip
|
41
68
|
------------
|
42
69
|
|
43
|
-
|
70
|
+
Simply add `retina!` to your model and set `:retina` to true.
|
44
71
|
|
45
72
|
```ruby
|
46
73
|
class ExampleUploader < ActiveRecord::Base
|
47
74
|
|
75
|
+
retina!
|
76
|
+
|
48
77
|
has_attached_file :image,
|
49
78
|
:styles => {
|
50
79
|
:original => ["800x800", :jpg],
|
51
80
|
:big => ["125x125#", :jpg]
|
52
81
|
},
|
53
|
-
:
|
54
|
-
|
55
|
-
include RetinaRails::Paperclip
|
82
|
+
:retina => true
|
83
|
+
# :retina => { :quality => 25 }
|
56
84
|
|
57
85
|
end
|
58
86
|
```
|
59
|
-
By default it sets the retina image quality to 40 which can be overriden by adding a `
|
87
|
+
By default it sets the retina image quality to 40 which can be overriden by adding a `quality` option.
|
60
88
|
|
61
89
|
For retina images use
|
62
90
|
------------
|
data/lib/retina_rails.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require 'retina_rails/
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
1
|
+
require 'retina_rails/version'
|
2
|
+
require 'retina_rails/strategies'
|
3
|
+
require 'retina_rails/helpers'
|
4
|
+
require 'retina_rails/exception'
|
5
|
+
|
6
|
+
require 'retina_rails/deprecation/carrierwave'
|
7
|
+
require 'retina_rails/deprecation/paperclip'
|
6
8
|
|
7
9
|
module RetinaRails
|
8
10
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RetinaRails
|
2
|
+
|
3
|
+
module CarrierWave
|
4
|
+
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
def raise_depraction_error!
|
10
|
+
raise RetinaRails::DeprecationError.new("As of version 1.0.0.beta1 activating RetinaRails by including `RetinaRails::Carrierwave` is depracted. Add `retina!` to your uploader instead.")
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
included do
|
16
|
+
|
17
|
+
raise_depraction_error!
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RetinaRails
|
2
|
+
|
3
|
+
module Paperclip
|
4
|
+
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
def raise_depraction_error!
|
10
|
+
raise RetinaRails::DeprecationError.new("As of version 1.0.0.beta1 activating RetinaRails by including `RetinaRails::Paperclip` is depracted. Add `retina!` to your model instead.")
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
included do
|
16
|
+
|
17
|
+
raise_depraction_error!
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'retina_rails/strategies/carrierwave'
|
2
|
+
require 'retina_rails/strategies/paperclip'
|
3
|
+
|
4
|
+
module RetinaRails
|
5
|
+
module Strategies
|
6
|
+
|
7
|
+
def self.include_strategies
|
8
|
+
if defined?(::CarrierWave)
|
9
|
+
::CarrierWave::Uploader::Base.send(:include, RetinaRails::Strategies::CarrierWave::Base)
|
10
|
+
end
|
11
|
+
if defined?(::Paperclip)
|
12
|
+
::ActiveRecord::Base.send(:include, RetinaRails::Strategies::Paperclip::Base)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
RetinaRails::Strategies.include_strategies
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module RetinaRails
|
2
|
+
module Strategies
|
3
|
+
module CarrierWave
|
4
|
+
module Base
|
5
|
+
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
def retina!
|
11
|
+
include Uploader
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
module Uploader
|
19
|
+
|
20
|
+
extend ActiveSupport::Concern
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
|
24
|
+
def version(name, options={}, &block)
|
25
|
+
super
|
26
|
+
|
27
|
+
retina_version name unless options[:retina] == false
|
28
|
+
end
|
29
|
+
|
30
|
+
# Define a retina version
|
31
|
+
# This method will simply copy all settings and add a larger (retina) version
|
32
|
+
def retina_version(name)
|
33
|
+
config = versions[name]
|
34
|
+
|
35
|
+
processors = config[:uploader].processors.dup
|
36
|
+
dimensions_processor = nil
|
37
|
+
|
38
|
+
## Check if there's a resize processor to get the dimensions
|
39
|
+
processors.each do |p|
|
40
|
+
dimensions_processor = processors.delete(p) if p[0].to_s.scan(/resize_to_fill|resize_to_limit|resize_to_fit|resize_and_pad/).any?
|
41
|
+
end
|
42
|
+
|
43
|
+
## Define a retina version if processor is present
|
44
|
+
if dimensions_processor
|
45
|
+
|
46
|
+
options = dimensions_processor[1].dup
|
47
|
+
|
48
|
+
width = options[0] * 2
|
49
|
+
height = options[1] * 2
|
50
|
+
|
51
|
+
2.times { options.delete_at(0) }
|
52
|
+
|
53
|
+
options.insert(0, height)
|
54
|
+
options.insert(0, width)
|
55
|
+
|
56
|
+
version "#{name}_retina", :retina => false do
|
57
|
+
process dimensions_processor[0] => options
|
58
|
+
|
59
|
+
quality_processor = nil
|
60
|
+
|
61
|
+
## Set other processors
|
62
|
+
processors.each do |processor|
|
63
|
+
process processor[0] => processor[1]
|
64
|
+
|
65
|
+
quality_processor = true if processor[0] == :retina_quality
|
66
|
+
end
|
67
|
+
|
68
|
+
## Set default quality if retina_quality is not defined
|
69
|
+
process :retina_quality => 40 if quality_processor.nil?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
## Set the correct filename for storage according to the convention (append @2x to filename)
|
77
|
+
def full_filename(for_file)
|
78
|
+
super.tap do |file_name|
|
79
|
+
file_name.sub!(/(.*)\./, '\1@2x.').gsub!('retina_', '') if version_name.to_s.include?('retina')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
## Set retina image quality
|
84
|
+
def retina_quality(percentage)
|
85
|
+
if version_name.to_s.include?('retina')
|
86
|
+
manipulate! do |img|
|
87
|
+
if defined?(Magick)
|
88
|
+
img.write(current_path) { self.quality = percentage } unless img.quality == percentage
|
89
|
+
elsif defined?(MiniMagick)
|
90
|
+
img.quality(percentage.to_s)
|
91
|
+
end
|
92
|
+
img = yield(img) if block_given?
|
93
|
+
img
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module RetinaRails
|
2
|
+
module Strategies
|
3
|
+
module Paperclip
|
4
|
+
|
5
|
+
module Base
|
6
|
+
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
def retina!
|
12
|
+
include Uploader
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
module Uploader
|
20
|
+
|
21
|
+
extend ActiveSupport::Concern
|
22
|
+
|
23
|
+
included do
|
24
|
+
|
25
|
+
## Override paperclip default options
|
26
|
+
Extensions.override_default_options
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
|
32
|
+
def has_attached_file(name, options={})
|
33
|
+
super
|
34
|
+
|
35
|
+
has_attached_retina_file name if options[:retina]
|
36
|
+
end
|
37
|
+
|
38
|
+
def has_attached_retina_file(name)
|
39
|
+
attachment = attachment_definitions[name]
|
40
|
+
|
41
|
+
## Check for style definitions
|
42
|
+
styles = attachment[:styles]
|
43
|
+
|
44
|
+
retina_options = if attachment[:retina].is_a?(Hash)
|
45
|
+
attachment[:retina]
|
46
|
+
else
|
47
|
+
{ :quality => 40 }
|
48
|
+
end
|
49
|
+
|
50
|
+
## Get retina quality
|
51
|
+
retina_quality = retina_options[:quality] || 40
|
52
|
+
|
53
|
+
if styles
|
54
|
+
|
55
|
+
retina_styles = {}
|
56
|
+
retina_convert_options = {}
|
57
|
+
convert_options = attachment[:convert_options]
|
58
|
+
|
59
|
+
## Iterate over styles and set optimzed dimensions
|
60
|
+
styles.each_pair do |key, value|
|
61
|
+
|
62
|
+
dimensions = value[0]
|
63
|
+
|
64
|
+
width = dimensions.scan(/\d+/)[0].to_i * 2
|
65
|
+
height = dimensions.scan(/\d+/)[1].to_i * 2
|
66
|
+
|
67
|
+
processor = dimensions.scan(/#|</).first
|
68
|
+
|
69
|
+
retina_styles["#{key}_retina".to_sym] = ["#{width}x#{height}#{processor}", value[1]]
|
70
|
+
|
71
|
+
## Set quality convert option
|
72
|
+
convert_option = convert_options[key] if convert_options
|
73
|
+
convert_option = convert_option ? "#{convert_option} -quality #{retina_quality}" : "-quality #{retina_quality}"
|
74
|
+
retina_convert_options["#{key}_retina".to_sym] = convert_option
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
## Append new retina optimzed styles
|
79
|
+
attachment[:styles].merge!(retina_styles)
|
80
|
+
|
81
|
+
## Set quality convert options
|
82
|
+
attachment[:convert_options] = {} if attachment[:convert_options].nil?
|
83
|
+
attachment[:convert_options].merge!(retina_convert_options)
|
84
|
+
|
85
|
+
## Make path work with retina optimization
|
86
|
+
original_path = attachment[:path]
|
87
|
+
attachment[:path] = Extensions.optimize_path(original_path) if original_path
|
88
|
+
|
89
|
+
## Make url work with retina optimization
|
90
|
+
original_url = attachment[:url]
|
91
|
+
attachment[:url] = Extensions.optimize_path(original_url) if original_url
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
module Extensions
|
99
|
+
|
100
|
+
## Insert :retina interpolation in url or path
|
101
|
+
def self.optimize_path(path)
|
102
|
+
path.scan(':retina').empty? ? path.gsub(':filename', ':basename.:extension').split('.').insert(-2, ':retina.').join : path
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.override_default_options
|
106
|
+
|
107
|
+
## Remove _retina from style so it doesn't end up in filename
|
108
|
+
::Paperclip.interpolates :style do |attachment, style|
|
109
|
+
style.to_s.end_with?('_retina') ? style.to_s[0..-8] : style
|
110
|
+
end
|
111
|
+
|
112
|
+
## Replace :retina with @2x if style ends with _retina
|
113
|
+
::Paperclip.interpolates :retina do |attachment, style|
|
114
|
+
style.to_s.end_with?('_retina') ? '@2x' : ''
|
115
|
+
end
|
116
|
+
|
117
|
+
## Make default url compatible with retina optimzer
|
118
|
+
url = ::Paperclip::Attachment.default_options[:url]
|
119
|
+
::Paperclip::Attachment.default_options[:url] = optimize_path(url)
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
data/lib/retina_rails/version.rb
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RetinaRails::CarrierWave do
|
4
|
+
|
5
|
+
it 'should raise a deprection error when included the old way' do
|
6
|
+
expect do
|
7
|
+
class DeprecatedUploader < CarrierWave::Uploader::Base
|
8
|
+
include RetinaRails::CarrierWave
|
9
|
+
end
|
10
|
+
end.to raise_error(RetinaRails::DeprecationError)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RetinaRails::Paperclip do
|
4
|
+
|
5
|
+
it 'should raise a deprection error when included the old way' do
|
6
|
+
expect do
|
7
|
+
class PaperclipUpload < ActiveRecord::Base
|
8
|
+
include RetinaRails::Paperclip
|
9
|
+
end
|
10
|
+
end.to raise_error(RetinaRails::DeprecationError)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
Binary file
|
data/spec/spec_helper.rb
CHANGED
@@ -4,6 +4,8 @@ class AnonymousUploader < CarrierWave::Uploader::Base
|
|
4
4
|
|
5
5
|
include CarrierWave::RMagick
|
6
6
|
|
7
|
+
retina!
|
8
|
+
|
7
9
|
version :small do
|
8
10
|
process :resize_to_fill => [30, 30]
|
9
11
|
process :quality => 60
|
@@ -23,12 +25,26 @@ class AnonymousUploader < CarrierWave::Uploader::Base
|
|
23
25
|
process :desaturate
|
24
26
|
end
|
25
27
|
|
28
|
+
version :small_without_retina, :retina => false do
|
29
|
+
process :quality => 60
|
30
|
+
end
|
31
|
+
|
32
|
+
version :small_custom_processor, :retina => false do
|
33
|
+
process :resize_to_fill_with_gravity => [100, 100, 'North', :jpg, 75]
|
34
|
+
end
|
35
|
+
|
36
|
+
version :small_custom_processor_retina, :retina => false do
|
37
|
+
process :resize_to_fill_with_gravity => [200, 200, 'North', :jpg, 40]
|
38
|
+
end
|
39
|
+
|
26
40
|
def desaturate
|
27
41
|
manipulate! do |img|
|
28
42
|
img = img.quantize 256, Magick::GRAYColorspace
|
29
43
|
end
|
30
44
|
end
|
31
45
|
|
46
|
+
def resize_to_fill_with_gravity(width, height, gravity, format, quality); end
|
47
|
+
|
32
48
|
def quality(percentage)
|
33
49
|
manipulate! do |img|
|
34
50
|
img.write(current_path) { self.quality = percentage } unless img.quality == percentage
|
@@ -39,8 +55,6 @@ class AnonymousUploader < CarrierWave::Uploader::Base
|
|
39
55
|
|
40
56
|
version :small_without_processor
|
41
57
|
|
42
|
-
include RetinaRails::CarrierWave
|
43
|
-
|
44
58
|
end
|
45
59
|
|
46
60
|
class CarrierWaveUpload
|
@@ -58,7 +72,7 @@ class CarrierWaveUpload
|
|
58
72
|
|
59
73
|
end
|
60
74
|
|
61
|
-
describe RetinaRails::CarrierWave do
|
75
|
+
describe RetinaRails::Strategies::CarrierWave do
|
62
76
|
|
63
77
|
include CarrierWave::Test::Matchers
|
64
78
|
|
@@ -67,7 +81,7 @@ describe RetinaRails::CarrierWave do
|
|
67
81
|
before do
|
68
82
|
AnonymousUploader.enable_processing = true
|
69
83
|
@uploader = AnonymousUploader.new(CarrierWaveUpload.new, :avatar)
|
70
|
-
@uploader.store!(File.open("#{
|
84
|
+
@uploader.store!(File.open("#{fixture_path}/images/avatar.jpeg"))
|
71
85
|
end
|
72
86
|
|
73
87
|
after do
|
@@ -139,7 +153,7 @@ describe RetinaRails::CarrierWave do
|
|
139
153
|
before do
|
140
154
|
AnonymousUploader.enable_processing = true
|
141
155
|
@uploader = AnonymousUploader.new(CarrierWaveUpload.new, :avatar)
|
142
|
-
@uploader.store!(File.open("#{
|
156
|
+
@uploader.store!(File.open("#{fixture_path}/images/avatar.with.dots.jpeg"))
|
143
157
|
end
|
144
158
|
|
145
159
|
it { File.basename(@uploader.small.current_path, 'jpeg').should == 'small_avatar.with.dots.' }
|
@@ -147,4 +161,21 @@ describe RetinaRails::CarrierWave do
|
|
147
161
|
|
148
162
|
end
|
149
163
|
|
150
|
-
|
164
|
+
context 'without retina' do
|
165
|
+
|
166
|
+
its(:versions) { should_not include :small_without_retina_retina }
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'custom processor' do
|
171
|
+
|
172
|
+
its(:versions) { should_not include :small_custom_processor_retina_retina }
|
173
|
+
|
174
|
+
it { File.basename(@uploader.small_custom_processor.current_path, 'jpeg').should include 'small_custom_processor_'}
|
175
|
+
|
176
|
+
it { File.basename(@uploader.small_custom_processor_retina.current_path, 'jpeg').should include '@2x'}
|
177
|
+
it { File.basename(@uploader.small_custom_processor_retina.current_path, 'jpeg').should_not include 'retina_'}
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
@@ -4,12 +4,14 @@ ROOT = File.dirname(__FILE__)
|
|
4
4
|
|
5
5
|
class PaperclipUpload < ActiveRecord::Base
|
6
6
|
|
7
|
+
retina!
|
8
|
+
|
7
9
|
has_attached_file :avatar,
|
8
10
|
:styles => {
|
9
11
|
:original => ["800x800", :jpg],
|
10
12
|
:big => ["125x125#", :jpg]
|
11
13
|
},
|
12
|
-
:
|
14
|
+
:retina => { :quality => 60 },
|
13
15
|
:path => "#{ROOT}/:class/:id/:basename_:style.:extension",
|
14
16
|
:url => "#{ROOT}/:class/:id/:basename_:style.:extension"
|
15
17
|
|
@@ -18,14 +20,13 @@ class PaperclipUpload < ActiveRecord::Base
|
|
18
20
|
:original => ["800x800", :jpg],
|
19
21
|
:big => ["125x125#", :jpg]
|
20
22
|
},
|
23
|
+
:retina => true,
|
21
24
|
:path => "#{ROOT}/:class/:id/:basename_:style.:extension",
|
22
25
|
:url => "#{ROOT}/:class/:id/:basename_:style.:extension"
|
23
26
|
|
24
|
-
include RetinaRails::Paperclip
|
25
|
-
|
26
27
|
end
|
27
28
|
|
28
|
-
describe RetinaRails::Paperclip do
|
29
|
+
describe RetinaRails::Strategies::Paperclip do
|
29
30
|
|
30
31
|
subject { PaperclipUpload }
|
31
32
|
|
@@ -41,7 +42,7 @@ describe RetinaRails::Paperclip do
|
|
41
42
|
|
42
43
|
context 'uploads' do
|
43
44
|
|
44
|
-
subject { PaperclipUpload.create(:avatar => File.open("#{
|
45
|
+
subject { PaperclipUpload.create(:avatar => File.open("#{fixture_path}/images/avatar.jpeg")) }
|
45
46
|
|
46
47
|
it { subject.avatar.url(:big).should == "#{ROOT}/paperclip_uploads/1/avatar_big.jpg" }
|
47
48
|
it { subject.avatar.url(:big_retina).should == "#{ROOT}/paperclip_uploads/2/avatar_big@2x.jpg" }
|
@@ -53,7 +54,7 @@ describe RetinaRails::Paperclip do
|
|
53
54
|
|
54
55
|
context 'with retina quality' do
|
55
56
|
|
56
|
-
subject { PaperclipUpload.create(:avatar => File.open("#{
|
57
|
+
subject { PaperclipUpload.create(:avatar => File.open("#{fixture_path}/images/avatar.jpeg")) }
|
57
58
|
|
58
59
|
it { Magick::Image.read(subject.avatar.url(:big)).first.quality.should == 84 }
|
59
60
|
it { Magick::Image.read(subject.avatar.url(:big_retina)).first.quality.should == 60 }
|
@@ -62,11 +63,46 @@ describe RetinaRails::Paperclip do
|
|
62
63
|
|
63
64
|
context 'without retina quality' do
|
64
65
|
|
65
|
-
subject { PaperclipUpload.create(:avatar_without_quality => File.open("#{
|
66
|
+
subject { PaperclipUpload.create(:avatar_without_quality => File.open("#{fixture_path}/images/avatar.jpeg")) }
|
66
67
|
|
67
68
|
it { Magick::Image.read(subject.avatar_without_quality.url(:big)).first.quality.should == 84 }
|
68
69
|
it { Magick::Image.read(subject.avatar_without_quality.url(:big_retina)).first.quality.should == 40 }
|
69
70
|
|
70
71
|
end
|
71
72
|
|
72
|
-
|
73
|
+
describe :optimze_path do
|
74
|
+
|
75
|
+
subject { RetinaRails::Strategies::Paperclip::Uploader::Extensions }
|
76
|
+
|
77
|
+
it { subject.optimize_path('/:filename').should == '/:basename:retina.:extension' }
|
78
|
+
|
79
|
+
it { subject.optimize_path('/:basename.:extension').should == '/:basename:retina.:extension' }
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
describe :override_default_options do
|
84
|
+
|
85
|
+
context 'Paperclip default' do
|
86
|
+
|
87
|
+
before { RetinaRails::Strategies::Paperclip::Uploader::Extensions.override_default_options }
|
88
|
+
|
89
|
+
it { Paperclip::Attachment.default_options[:url].should == '/system/:class/:attachment/:id_partition/:style/:basename:retina.:extension' }
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'User defined paperclip default' do
|
94
|
+
|
95
|
+
before do
|
96
|
+
|
97
|
+
Paperclip::Attachment.default_options[:url] = '/:class/:attachment/:id/:style/:basename.:extension'
|
98
|
+
RetinaRails::Strategies::Paperclip::Uploader::Extensions.override_default_options
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
it { Paperclip::Attachment.default_options[:url].should == '/:class/:attachment/:id/:style/:basename:retina.:extension' }
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: retina_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0.beta1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Johan van Zonneveld
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-05-
|
13
|
+
date: 2013-05-21 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -189,21 +189,25 @@ files:
|
|
189
189
|
- README.md
|
190
190
|
- Rakefile
|
191
191
|
- lib/retina_rails.rb
|
192
|
-
- lib/retina_rails/carrierwave.rb
|
193
|
-
- lib/retina_rails/
|
192
|
+
- lib/retina_rails/deprecation/carrierwave.rb
|
193
|
+
- lib/retina_rails/deprecation/paperclip.rb
|
194
|
+
- lib/retina_rails/exception.rb
|
194
195
|
- lib/retina_rails/helpers.rb
|
195
|
-
- lib/retina_rails/
|
196
|
+
- lib/retina_rails/strategies.rb
|
197
|
+
- lib/retina_rails/strategies/carrierwave.rb
|
198
|
+
- lib/retina_rails/strategies/paperclip.rb
|
196
199
|
- lib/retina_rails/version.rb
|
197
200
|
- retina_rails.gemspec
|
198
|
-
- spec/carrierwave_spec.rb
|
199
|
-
- spec/
|
201
|
+
- spec/deprecation/carrierwave_spec.rb
|
202
|
+
- spec/deprecation/paperclip_spec.rb
|
200
203
|
- spec/fixtures/db/retina_rails.sqlite3
|
201
204
|
- spec/fixtures/images/avatar.jpeg
|
202
205
|
- spec/fixtures/images/avatar.with.dots.jpeg
|
203
206
|
- spec/fixtures/manifest.yml
|
204
207
|
- spec/helpers_spec.rb
|
205
|
-
- spec/paperclip_spec.rb
|
206
208
|
- spec/spec_helper.rb
|
209
|
+
- spec/strategies/carrierwave_spec.rb
|
210
|
+
- spec/strategies/paperclip_spec.rb
|
207
211
|
- spec/support/rails.rb
|
208
212
|
- spec/support/schema.rb
|
209
213
|
- vendor/assets/javascripts/retina.js
|
@@ -222,9 +226,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
222
226
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
227
|
none: false
|
224
228
|
requirements:
|
225
|
-
- - ! '
|
229
|
+
- - ! '>'
|
226
230
|
- !ruby/object:Gem::Version
|
227
|
-
version:
|
231
|
+
version: 1.3.1
|
228
232
|
requirements: []
|
229
233
|
rubyforge_project:
|
230
234
|
rubygems_version: 1.8.25
|
@@ -232,14 +236,15 @@ signing_key:
|
|
232
236
|
specification_version: 3
|
233
237
|
summary: Makes your live easier optimizing for retina displays
|
234
238
|
test_files:
|
235
|
-
- spec/carrierwave_spec.rb
|
236
|
-
- spec/
|
239
|
+
- spec/deprecation/carrierwave_spec.rb
|
240
|
+
- spec/deprecation/paperclip_spec.rb
|
237
241
|
- spec/fixtures/db/retina_rails.sqlite3
|
238
242
|
- spec/fixtures/images/avatar.jpeg
|
239
243
|
- spec/fixtures/images/avatar.with.dots.jpeg
|
240
244
|
- spec/fixtures/manifest.yml
|
241
245
|
- spec/helpers_spec.rb
|
242
|
-
- spec/paperclip_spec.rb
|
243
246
|
- spec/spec_helper.rb
|
247
|
+
- spec/strategies/carrierwave_spec.rb
|
248
|
+
- spec/strategies/paperclip_spec.rb
|
244
249
|
- spec/support/rails.rb
|
245
250
|
- spec/support/schema.rb
|
@@ -1,79 +0,0 @@
|
|
1
|
-
module RetinaRails
|
2
|
-
|
3
|
-
module CarrierWave
|
4
|
-
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
included do
|
8
|
-
|
9
|
-
## Define retina version based on defined versions in the uploader class
|
10
|
-
versions.each do |v|
|
11
|
-
|
12
|
-
processors = v[1][:uploader].processors.dup
|
13
|
-
dimensions_processor = nil
|
14
|
-
|
15
|
-
## Check if there's a resize processor to get the dimensions
|
16
|
-
processors.each do |p|
|
17
|
-
dimensions_processor = processors.delete(p) if p[0].to_s.scan(/resize_to_fill|resize_to_limit|resize_to_fit|resize_and_pad/).any?
|
18
|
-
end
|
19
|
-
|
20
|
-
## Define a retina version if processor is present
|
21
|
-
if dimensions_processor
|
22
|
-
|
23
|
-
options = dimensions_processor[1].dup
|
24
|
-
|
25
|
-
width = options[0] * 2
|
26
|
-
height = options[1] * 2
|
27
|
-
|
28
|
-
2.times { options.delete_at(0) }
|
29
|
-
|
30
|
-
options.insert(0, height)
|
31
|
-
options.insert(0, width)
|
32
|
-
|
33
|
-
version "#{v[0]}_retina" do
|
34
|
-
process dimensions_processor[0] => options
|
35
|
-
|
36
|
-
quality_processor = nil
|
37
|
-
|
38
|
-
## Set other processors
|
39
|
-
processors.each do |processor|
|
40
|
-
process processor[0] => processor[1]
|
41
|
-
|
42
|
-
quality_processor = true if processor[0] == :retina_quality
|
43
|
-
end
|
44
|
-
|
45
|
-
## Set default quality if retina_quality is not defined
|
46
|
-
process :retina_quality => 40 if quality_processor.nil?
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
## Set the correct filename for storage according to the convention (append @2x to filename)
|
56
|
-
def full_filename(for_file)
|
57
|
-
super.tap do |file_name|
|
58
|
-
file_name.sub!(/(.*)\./, '\1@2x.').gsub!('retina_', '') if version_name.to_s.include?('retina')
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
## Set retina image quality
|
63
|
-
def retina_quality(percentage)
|
64
|
-
if version_name.to_s.include?('retina')
|
65
|
-
manipulate! do |img|
|
66
|
-
if defined?(Magick)
|
67
|
-
img.write(current_path) { self.quality = percentage } unless img.quality == percentage
|
68
|
-
elsif defined?(MiniMagick)
|
69
|
-
img.quality(percentage.to_s)
|
70
|
-
end
|
71
|
-
img = yield(img) if block_given?
|
72
|
-
img
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module RetinaRails::Extensions
|
2
|
-
|
3
|
-
## Insert :retina interpolation in url or path
|
4
|
-
def self.optimize_path(path)
|
5
|
-
path.scan(':retina').empty? ? path.gsub(':filename', ':basename.:extension').split('.').insert(-2, ':retina.').join : path
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.override_default_options
|
9
|
-
|
10
|
-
## Remove _retina from style so it doesn't end up in filename
|
11
|
-
Paperclip.interpolates :style do |attachment, style|
|
12
|
-
style.to_s.end_with?('_retina') ? style.to_s[0..-8] : style
|
13
|
-
end
|
14
|
-
|
15
|
-
## Replace :retina with @2x if style ends with _retina
|
16
|
-
Paperclip.interpolates :retina do |attachment, style|
|
17
|
-
style.to_s.end_with?('_retina') ? '@2x' : ''
|
18
|
-
end
|
19
|
-
|
20
|
-
## Make default url compatible with retina optimzer
|
21
|
-
url = Paperclip::Attachment.default_options[:url]
|
22
|
-
Paperclip::Attachment.default_options[:url] = optimize_path(url)
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
module RetinaRails
|
2
|
-
|
3
|
-
module Paperclip
|
4
|
-
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
included do
|
8
|
-
|
9
|
-
## Override paperclip default options
|
10
|
-
RetinaRails::Extensions.override_default_options
|
11
|
-
|
12
|
-
## Iterate over each has_attached_file
|
13
|
-
attachment_definitions.each_pair do |key, value|
|
14
|
-
|
15
|
-
## Check for style definitions
|
16
|
-
styles = attachment_definitions[key][:styles]
|
17
|
-
|
18
|
-
## Get retina quality
|
19
|
-
retina_quality = attachment_definitions[key][:retina_quality] || 40
|
20
|
-
|
21
|
-
if styles
|
22
|
-
|
23
|
-
retina_styles = {}
|
24
|
-
retina_convert_options = {}
|
25
|
-
convert_options = attachment_definitions[key][:convert_options]
|
26
|
-
|
27
|
-
## Iterate over styles and set optimzed dimensions
|
28
|
-
styles.each_pair do |key, value|
|
29
|
-
|
30
|
-
dimensions = value[0]
|
31
|
-
|
32
|
-
width = dimensions.scan(/\d+/)[0].to_i * 2
|
33
|
-
height = dimensions.scan(/\d+/)[1].to_i * 2
|
34
|
-
|
35
|
-
processor = dimensions.scan(/#|</).first
|
36
|
-
|
37
|
-
retina_styles["#{key}_retina".to_sym] = ["#{width}x#{height}#{processor}", value[1]]
|
38
|
-
|
39
|
-
## Set quality convert option
|
40
|
-
convert_option = convert_options[key] if convert_options
|
41
|
-
convert_option = convert_option ? "#{convert_option} -quality #{retina_quality}" : "-quality #{retina_quality}"
|
42
|
-
retina_convert_options["#{key}_retina".to_sym] = convert_option
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
## Append new retina optimzed styles
|
47
|
-
value[:styles].merge!(retina_styles)
|
48
|
-
|
49
|
-
## Set quality convert options
|
50
|
-
value[:convert_options] = {} if value[:convert_options].nil?
|
51
|
-
value[:convert_options].merge!(retina_convert_options)
|
52
|
-
|
53
|
-
## Make path work with retina optimization
|
54
|
-
original_path = attachment_definitions[key][:path]
|
55
|
-
value[:path] = RetinaRails::Extensions.optimize_path(original_path) if original_path
|
56
|
-
|
57
|
-
## Make url work with retina optimization
|
58
|
-
original_url = attachment_definitions[key][:url]
|
59
|
-
value[:url] = RetinaRails::Extensions.optimize_path(original_url) if original_url
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
data/spec/extensions_spec.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
describe RetinaRails::Extensions do
|
2
|
-
|
3
|
-
describe :optimze_path do
|
4
|
-
|
5
|
-
subject { RetinaRails::Extensions }
|
6
|
-
|
7
|
-
it { subject.optimize_path('/:filename').should == '/:basename:retina.:extension' }
|
8
|
-
|
9
|
-
it { subject.optimize_path('/:basename.:extension').should == '/:basename:retina.:extension' }
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
describe :override_default_options do
|
14
|
-
|
15
|
-
context 'Paperclip default' do
|
16
|
-
|
17
|
-
before { RetinaRails::Extensions.override_default_options }
|
18
|
-
|
19
|
-
it { Paperclip::Attachment.default_options[:url].should == '/system/:class/:attachment/:id_partition/:style/:basename:retina.:extension' }
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'User defined paperclip default' do
|
24
|
-
|
25
|
-
before do
|
26
|
-
|
27
|
-
Paperclip::Attachment.default_options[:url] = '/:class/:attachment/:id/:style/:basename.:extension'
|
28
|
-
RetinaRails::Extensions.override_default_options
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
it { Paperclip::Attachment.default_options[:url].should == '/:class/:attachment/:id/:style/:basename:retina.:extension' }
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|