roadie 2.3.4 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 3.2.0"
6
+
7
+ gemspec :path=>"../"
@@ -1,14 +1,14 @@
1
1
  PATH
2
- remote: /Users/mange/Projects/roadie
2
+ remote: /home/mange/Projects/roadie
3
3
  specs:
4
- roadie (2.3.3)
5
- actionmailer (> 3.0.0, < 3.3.0)
6
- css_parser
7
- nokogiri (>= 1.4.4)
4
+ roadie (2.3.4)
5
+ actionmailer (> 3.0.0, < 5.0.0)
6
+ css_parser (~> 1.3.4)
7
+ nokogiri (~> 1.6.0)
8
8
  sprockets
9
9
 
10
10
  GEM
11
- remote: http://rubygems.org/
11
+ remote: https://rubygems.org/
12
12
  specs:
13
13
  actionmailer (3.2.2)
14
14
  actionpack (= 3.2.2)
@@ -37,37 +37,36 @@ GEM
37
37
  activesupport (3.2.2)
38
38
  i18n (~> 0.6)
39
39
  multi_json (~> 1.0)
40
- addressable (2.3.2)
41
- appraisal (0.4.1)
40
+ addressable (2.3.5)
41
+ appraisal (0.5.1)
42
42
  bundler
43
43
  rake
44
44
  arel (3.0.2)
45
45
  builder (3.0.0)
46
- css_parser (1.2.6)
46
+ css_parser (1.3.4)
47
47
  addressable
48
- rdoc
49
48
  diff-lcs (1.1.3)
50
49
  erubis (2.7.0)
51
50
  hike (1.2.1)
52
- i18n (0.6.0)
53
- journey (1.0.3)
54
- json (1.6.5)
55
- json (1.6.5-java)
51
+ i18n (0.6.1)
52
+ journey (1.0.4)
53
+ json (1.7.5)
56
54
  mail (2.4.4)
57
55
  i18n (>= 0.4.0)
58
56
  mime-types (~> 1.16)
59
57
  treetop (~> 1.4.8)
60
- mime-types (1.18)
61
- multi_json (1.1.0)
62
- nokogiri (1.5.5)
63
- nokogiri (1.5.5-java)
58
+ mime-types (1.19)
59
+ mini_portile (0.5.0)
60
+ multi_json (1.4.0)
61
+ nokogiri (1.6.0)
62
+ mini_portile (~> 0.5.0)
64
63
  polyglot (0.3.3)
65
64
  rack (1.4.1)
66
65
  rack-cache (1.2)
67
66
  rack (>= 0.4)
68
67
  rack-ssl (1.3.2)
69
68
  rack
70
- rack-test (0.6.1)
69
+ rack-test (0.6.2)
71
70
  rack (>= 1.0)
72
71
  rails (3.2.2)
73
72
  actionmailer (= 3.2.2)
@@ -84,39 +83,42 @@ GEM
84
83
  rake (>= 0.8.7)
85
84
  rdoc (~> 3.4)
86
85
  thor (~> 0.14.6)
87
- rake (0.9.2.2)
86
+ rake (10.0.2)
88
87
  rdoc (3.12)
89
88
  json (~> 1.4)
90
- rspec (2.9.0)
91
- rspec-core (~> 2.9.0)
92
- rspec-expectations (~> 2.9.0)
93
- rspec-mocks (~> 2.9.0)
94
- rspec-core (2.9.0)
95
- rspec-expectations (2.9.0)
89
+ rspec (2.12.0)
90
+ rspec-core (~> 2.12.0)
91
+ rspec-expectations (~> 2.12.0)
92
+ rspec-mocks (~> 2.12.0)
93
+ rspec-core (2.12.1)
94
+ rspec-expectations (2.12.0)
96
95
  diff-lcs (~> 1.1.3)
97
- rspec-mocks (2.9.0)
98
- rspec-rails (2.9.0)
96
+ rspec-mocks (2.12.0)
97
+ rspec-rails (2.12.0)
99
98
  actionpack (>= 3.0)
100
99
  activesupport (>= 3.0)
101
100
  railties (>= 3.0)
102
- rspec (~> 2.9.0)
101
+ rspec-core (~> 2.12.0)
102
+ rspec-expectations (~> 2.12.0)
103
+ rspec-mocks (~> 2.12.0)
103
104
  sprockets (2.1.2)
104
105
  hike (~> 1.2)
105
106
  rack (~> 1.0)
106
107
  tilt (~> 1.1, != 1.3.0)
107
108
  thor (0.14.6)
108
109
  tilt (1.3.3)
109
- treetop (1.4.10)
110
+ treetop (1.4.12)
110
111
  polyglot
111
112
  polyglot (>= 0.3.1)
112
- tzinfo (0.3.32)
113
+ tzinfo (0.3.35)
113
114
 
114
115
  PLATFORMS
115
- java
116
116
  ruby
117
117
 
118
118
  DEPENDENCIES
119
119
  appraisal
120
- rails (~> 3.2.0.rc1)
120
+ rails (~> 3.2.0)
121
+ rake
121
122
  roadie!
123
+ rspec
122
124
  rspec-rails
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 4.0"
6
+
7
+ gemspec :path=>"../"
@@ -0,0 +1,119 @@
1
+ PATH
2
+ remote: /home/mange/Projects/roadie
3
+ specs:
4
+ roadie (2.3.4)
5
+ actionmailer (> 3.0.0, < 5.0.0)
6
+ css_parser (~> 1.3.4)
7
+ nokogiri (~> 1.6.0)
8
+ sprockets
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ actionmailer (4.0.0)
14
+ actionpack (= 4.0.0)
15
+ mail (~> 2.5.3)
16
+ actionpack (4.0.0)
17
+ activesupport (= 4.0.0)
18
+ builder (~> 3.1.0)
19
+ erubis (~> 2.7.0)
20
+ rack (~> 1.5.2)
21
+ rack-test (~> 0.6.2)
22
+ activemodel (4.0.0)
23
+ activesupport (= 4.0.0)
24
+ builder (~> 3.1.0)
25
+ activerecord (4.0.0)
26
+ activemodel (= 4.0.0)
27
+ activerecord-deprecated_finders (~> 1.0.2)
28
+ activesupport (= 4.0.0)
29
+ arel (~> 4.0.0)
30
+ activerecord-deprecated_finders (1.0.3)
31
+ activesupport (4.0.0)
32
+ i18n (~> 0.6, >= 0.6.4)
33
+ minitest (~> 4.2)
34
+ multi_json (~> 1.3)
35
+ thread_safe (~> 0.1)
36
+ tzinfo (~> 0.3.37)
37
+ addressable (2.3.5)
38
+ appraisal (0.5.2)
39
+ bundler
40
+ rake
41
+ arel (4.0.0)
42
+ atomic (1.1.10)
43
+ builder (3.1.4)
44
+ css_parser (1.3.4)
45
+ addressable
46
+ diff-lcs (1.2.4)
47
+ erubis (2.7.0)
48
+ hike (1.2.3)
49
+ i18n (0.6.4)
50
+ mail (2.5.4)
51
+ mime-types (~> 1.16)
52
+ treetop (~> 1.4.8)
53
+ mime-types (1.23)
54
+ mini_portile (0.5.0)
55
+ minitest (4.7.5)
56
+ multi_json (1.7.7)
57
+ nokogiri (1.6.0)
58
+ mini_portile (~> 0.5.0)
59
+ polyglot (0.3.3)
60
+ rack (1.5.2)
61
+ rack-test (0.6.2)
62
+ rack (>= 1.0)
63
+ rails (4.0.0)
64
+ actionmailer (= 4.0.0)
65
+ actionpack (= 4.0.0)
66
+ activerecord (= 4.0.0)
67
+ activesupport (= 4.0.0)
68
+ bundler (>= 1.3.0, < 2.0)
69
+ railties (= 4.0.0)
70
+ sprockets-rails (~> 2.0.0)
71
+ railties (4.0.0)
72
+ actionpack (= 4.0.0)
73
+ activesupport (= 4.0.0)
74
+ rake (>= 0.8.7)
75
+ thor (>= 0.18.1, < 2.0)
76
+ rake (10.1.0)
77
+ rspec (2.13.0)
78
+ rspec-core (~> 2.13.0)
79
+ rspec-expectations (~> 2.13.0)
80
+ rspec-mocks (~> 2.13.0)
81
+ rspec-core (2.13.1)
82
+ rspec-expectations (2.13.0)
83
+ diff-lcs (>= 1.1.3, < 2.0)
84
+ rspec-mocks (2.13.1)
85
+ rspec-rails (2.13.2)
86
+ actionpack (>= 3.0)
87
+ activesupport (>= 3.0)
88
+ railties (>= 3.0)
89
+ rspec-core (~> 2.13.0)
90
+ rspec-expectations (~> 2.13.0)
91
+ rspec-mocks (~> 2.13.0)
92
+ sprockets (2.10.0)
93
+ hike (~> 1.2)
94
+ multi_json (~> 1.0)
95
+ rack (~> 1.0)
96
+ tilt (~> 1.1, != 1.3.0)
97
+ sprockets-rails (2.0.0)
98
+ actionpack (>= 3.0)
99
+ activesupport (>= 3.0)
100
+ sprockets (~> 2.8)
101
+ thor (0.18.1)
102
+ thread_safe (0.1.0)
103
+ atomic
104
+ tilt (1.4.1)
105
+ treetop (1.4.14)
106
+ polyglot
107
+ polyglot (>= 0.3.1)
108
+ tzinfo (0.3.37)
109
+
110
+ PLATFORMS
111
+ ruby
112
+
113
+ DEPENDENCIES
114
+ appraisal
115
+ rails (~> 4.0)
116
+ rake
117
+ roadie!
118
+ rspec
119
+ rspec-rails
@@ -38,22 +38,36 @@ module Roadie
38
38
  def current_provider
39
39
  return config.roadie.provider if config.roadie.provider
40
40
 
41
- if config.respond_to?(:assets) and config.assets and config.assets.enabled
41
+ if assets_enabled?
42
42
  AssetPipelineProvider.new
43
43
  else
44
44
  FilesystemProvider.new
45
45
  end
46
46
  end
47
47
 
48
+ # Returns the value of +config.roadie.after_inlining+
49
+ #
50
+ def after_inlining_handler
51
+ config.roadie.after_inlining
52
+ end
53
+
48
54
  private
49
55
  def config
50
56
  Roadie.app.config
51
57
  end
58
+
59
+ def assets_enabled?
60
+ # In Rails 4.0, config.assets.enabled is nil by default, so we need to
61
+ # explicitly make sure it's not false rather than checking for a
62
+ # truthy value.
63
+ config.respond_to?(:assets) and config.assets and config.assets.enabled != false
64
+ end
52
65
  end
53
66
  end
54
67
 
55
68
  require 'roadie/version'
56
69
  require 'roadie/css_file_not_found'
70
+ require 'roadie/selector'
57
71
  require 'roadie/style_declaration'
58
72
 
59
73
  require 'roadie/asset_provider'
@@ -9,7 +9,11 @@ module Roadie
9
9
  module ActionMailerExtensions
10
10
  def self.included(base)
11
11
  base.class_eval do
12
- alias_method_chain :collect_responses_and_parts_order, :inline_styles
12
+ if base.method_defined?(:collect_responses)
13
+ alias_method_chain :collect_responses, :inline_styles
14
+ else
15
+ alias_method_chain :collect_responses_and_parts_order, :inline_styles
16
+ end
13
17
  alias_method_chain :mail, :inline_styles
14
18
  end
15
19
  end
@@ -22,11 +26,28 @@ module Roadie
22
26
  @targets = default_css_targets
23
27
  end
24
28
 
29
+ if headers.has_key?(:after_inlining)
30
+ @after_inlining_handler = headers[:after_inlining]
31
+ else
32
+ @after_inlining_handler = default_after_inlining || Roadie.after_inlining_handler
33
+ end
34
+
25
35
  mail_without_inline_styles(headers, &block).tap do |email|
26
- email.header.fields.delete_if { |field| field.name == 'css' }
36
+ email.header.fields.delete_if { |field| %w(css after_inlining).include?(field.name) }
37
+ end
38
+ end
39
+
40
+ # Rails 4
41
+ def collect_responses_with_inline_styles(headers, &block)
42
+ responses = collect_responses_without_inline_styles(headers, &block)
43
+ if Roadie.enabled?
44
+ responses.map { |response| inline_style_response(response) }
45
+ else
46
+ responses
27
47
  end
28
48
  end
29
49
 
50
+ # Rails 3
30
51
  def collect_responses_and_parts_order_with_inline_styles(headers, &block)
31
52
  responses, order = collect_responses_and_parts_order_without_inline_styles(headers, &block)
32
53
  if Roadie.enabled?
@@ -41,9 +62,17 @@ module Roadie
41
62
  self.class.default[:css]
42
63
  end
43
64
 
65
+ def default_after_inlining
66
+ self.class.default[:after_inlining]
67
+ end
68
+
69
+ def after_inlining_handler
70
+ @after_inlining_handler
71
+ end
72
+
44
73
  def inline_style_response(response)
45
74
  if response[:content_type] == 'text/html'
46
- response.merge :body => Roadie.inline_css(Roadie.current_provider, css_targets, response[:body], url_options)
75
+ response.merge :body => Roadie.inline_css(Roadie.current_provider, css_targets, response[:body], url_options, after_inlining_handler)
47
76
  else
48
77
  response
49
78
  end
@@ -54,8 +83,8 @@ module Roadie
54
83
  end
55
84
 
56
85
  def resolve_target(target)
57
- if target.respond_to? :bind
58
- target.bind(self).call
86
+ if target.kind_of? Proc
87
+ instance_exec(&target)
59
88
  elsif target.respond_to? :call
60
89
  target.call
61
90
  else
@@ -40,7 +40,7 @@ module Roadie
40
40
  # MyProvider.find("mystyle.css")
41
41
  # MyProvider.find(:mystyle)
42
42
  #
43
- # @param [String, Symbol] name Name of the file requested
43
+ # @param [String] name Name of the file requested
44
44
  # @raise [CSSFileNotFound] In case any of the elements is not found
45
45
  def find(name)
46
46
  raise "Not implemented"
@@ -29,12 +29,14 @@ module Roadie
29
29
  # @param [Array] targets List of CSS files to load via the provider
30
30
  # @param [String] html
31
31
  # @param [Hash] url_options Supported keys: +:host+, +:port+, +:protocol+
32
- def initialize(assets, targets, html, url_options)
32
+ # @param [lambda] after_inlining_handler A lambda that accepts one parameter or an object that responds to the +call+ method with one parameter.
33
+ def initialize(assets, targets, html, url_options, after_inlining_handler=nil)
33
34
  @assets = assets
34
35
  @css = assets.all(targets)
35
36
  @html = html
36
37
  @inline_css = []
37
38
  @url_options = url_options
39
+ @after_inlining_handler = after_inlining_handler
38
40
 
39
41
  if url_options and url_options[:asset_path_prefix]
40
42
  raise ArgumentError, "The asset_path_prefix URL option is not working anymore. You need to add the following configuration to your application.rb:\n" +
@@ -54,12 +56,13 @@ module Roadie
54
56
  inline_css_rules
55
57
  make_image_urls_absolute
56
58
  make_style_urls_absolute
59
+ after_inlining_handler.call(document) if after_inlining_handler.respond_to?(:call)
57
60
  @document = nil
58
61
  end
59
62
  end
60
63
 
61
64
  private
62
- attr_reader :css, :html, :assets, :url_options, :document
65
+ attr_reader :css, :html, :assets, :url_options, :document, :after_inlining_handler
63
66
 
64
67
  def inline_css
65
68
  @inline_css.join("\n")
@@ -133,9 +136,9 @@ module Roadie
133
136
  def elements_with_declarations
134
137
  Hash.new { |hash, key| hash[key] = [] }.tap do |element_declarations|
135
138
  parsed_css.each_rule_set do |rule_set|
136
- each_selector_without_pseudo(rule_set) do |selector, specificity|
139
+ each_good_selector(rule_set) do |selector|
137
140
  each_element_in_selector(selector) do |element|
138
- style_declarations_in_rule_set(specificity, rule_set) do |declaration|
141
+ style_declarations_in_rule_set(selector.specificity, rule_set) do |declaration|
139
142
  element_declarations[element] << declaration
140
143
  end
141
144
  end
@@ -144,16 +147,26 @@ module Roadie
144
147
  end
145
148
  end
146
149
 
147
- def each_selector_without_pseudo(rules)
148
- rules.selectors.reject { |selector| selector.include?(':') or selector.starts_with?('@') }.each do |selector|
149
- yield selector, CssParser.calculate_specificity(selector)
150
+ def each_good_selector(rules)
151
+ rules.selectors.each do |selector_string|
152
+ selector = Selector.new(selector_string)
153
+ yield selector if selector.inlinable?
150
154
  end
151
155
  end
152
156
 
153
157
  def each_element_in_selector(selector)
154
- document.css(selector.strip).each do |element|
158
+ document.css(selector.to_s).each do |element|
155
159
  yield element
156
160
  end
161
+ # There's no way to get a list of supported pseudo rules, so we're left
162
+ # with having to rescue errors.
163
+ # Pseudo selectors that are known to be bad are skipped automatically but
164
+ # this will catch the rest.
165
+ rescue Nokogiri::XML::XPath::SyntaxError, Nokogiri::CSS::SyntaxError => error
166
+ warn "Roadie cannot use #{selector.inspect} when inlining stylesheets"
167
+ rescue => error
168
+ warn "Roadie got error when looking for #{selector.inspect}: #{error}"
169
+ raise unless error.message.include?('XPath')
157
170
  end
158
171
 
159
172
  def style_declarations_in_rule_set(specificity, rule_set)
@@ -189,14 +202,21 @@ module Roadie
189
202
  def absolute_url_base(base_path)
190
203
  return nil unless url_options
191
204
  port = url_options[:port]
205
+ scheme = protocol_to_scheme url_options[:protocol]
192
206
  URI::Generic.build({
193
- :scheme => url_options[:protocol] || 'http',
207
+ :scheme => scheme,
194
208
  :host => url_options[:host],
195
209
  :port => (port ? port.to_i : nil),
196
210
  :path => base_path
197
211
  })
198
212
  end
199
213
 
214
+ # Strip :// from any protocol, if present
215
+ def protocol_to_scheme(protocol)
216
+ return 'http' unless protocol
217
+ protocol.to_s[/^\w+/]
218
+ end
219
+
200
220
  def all_link_elements_with_url
201
221
  document.css("link[rel=stylesheet]").map { |link| [link, URI.parse(link['href'])] }
202
222
  end