roadie 3.0.0.pre1 → 3.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/Changelog.md +22 -1
  4. data/Gemfile +0 -4
  5. data/Guardfile +3 -2
  6. data/README.md +6 -4
  7. data/lib/roadie.rb +3 -1
  8. data/lib/roadie/filesystem_provider.rb +13 -2
  9. data/lib/roadie/inliner.rb +10 -8
  10. data/lib/roadie/markup_improver.rb +1 -1
  11. data/lib/roadie/provider_list.rb +5 -1
  12. data/lib/roadie/rspec/asset_provider.rb +9 -9
  13. data/lib/roadie/selector.rb +1 -0
  14. data/lib/roadie/style_attribute_builder.rb +25 -0
  15. data/lib/roadie/style_block.rb +0 -1
  16. data/lib/roadie/upgrade_guide.rb +36 -0
  17. data/lib/roadie/version.rb +1 -1
  18. data/roadie.gemspec +2 -1
  19. data/spec/integration_spec.rb +15 -15
  20. data/spec/lib/roadie/asset_scanner_spec.rb +27 -27
  21. data/spec/lib/roadie/css_not_found_spec.rb +4 -3
  22. data/spec/lib/roadie/document_spec.rb +19 -19
  23. data/spec/lib/roadie/filesystem_provider_spec.rb +29 -6
  24. data/spec/lib/roadie/inliner_spec.rb +18 -18
  25. data/spec/lib/roadie/markup_improver_spec.rb +17 -17
  26. data/spec/lib/roadie/null_provider_spec.rb +4 -4
  27. data/spec/lib/roadie/provider_list_spec.rb +23 -15
  28. data/spec/lib/roadie/selector_spec.rb +16 -13
  29. data/spec/lib/roadie/style_attribute_builder_spec.rb +29 -0
  30. data/spec/lib/roadie/style_block_spec.rb +6 -6
  31. data/spec/lib/roadie/style_property_spec.rb +22 -22
  32. data/spec/lib/roadie/stylesheet_spec.rb +8 -8
  33. data/spec/lib/roadie/test_provider_spec.rb +5 -5
  34. data/spec/lib/roadie/url_generator_spec.rb +21 -20
  35. data/spec/lib/roadie/url_rewriter_spec.rb +7 -7
  36. data/spec/shared_examples/asset_provider.rb +4 -4
  37. data/spec/shared_examples/url_rewriter.rb +6 -6
  38. data/spec/spec_helper.rb +2 -1
  39. data/spec/support/have_attribute_matcher.rb +2 -2
  40. data/spec/support/have_node_matcher.rb +2 -2
  41. data/spec/support/have_selector_matcher.rb +2 -2
  42. data/spec/support/have_styling_matcher.rb +7 -5
  43. metadata +36 -21
  44. data/lib/roadie/style_properties.rb +0 -29
  45. data/spec/lib/roadie/style_properties_spec.rb +0 -61
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8dbb2ff6110e3730b2c4b818bbfa1724ad8912ea
4
- data.tar.gz: fe0bf94a18e731475ee8bcf1e16d4d6cd6692071
3
+ metadata.gz: fb9d9810978beb19ef7c13d2ef8953827b418bb1
4
+ data.tar.gz: db5db2dc87d93790b131fd0b3c515e9c24114525
5
5
  SHA512:
6
- metadata.gz: 97d48f412f42884ab58afa39325178256bee9f81a5822e8415e746cd3181931048d982a607d12ec5cf11efd5ad11c439cf88f8165f05c7df781f02002641082c
7
- data.tar.gz: bdb1604da3762385097b4e156fe38300580d4f3d899dda4d4ed66e5a8fd846405be0eb99df85e54c07cceda0f5a37f0af277773ecd3adf61050f0445ae6d947d
6
+ metadata.gz: 7cf63f4924682f07f21960926b8b804e9d82e7db8b8c90b2e658557983e9e098534841b823d162736a3d3cc973c23f568987db3e3911fbadcdc0234998c09587
7
+ data.tar.gz: c65545723737f33444e7c2797a8b01b288d0945a556100217fe7b0f86748bcfbc00908e1cd2204ea21fe26b543f0ebbf40e510831ba681fa6f66cc43ec67e981
data/.travis.yml CHANGED
@@ -2,6 +2,7 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
+ - 2.1.2
5
6
  - jruby
6
7
  - rbx
7
8
 
data/Changelog.md CHANGED
@@ -1,6 +1,27 @@
1
1
  ### dev
2
2
 
3
- [full changelog](https://github.com/Mange/roadie/compare/v2.4.2...master)
3
+ [full changelog](https://github.com/Mange/roadie/compare/v3.0.0...master)
4
+
5
+ * Nothing yet.
6
+
7
+ ### 3.0.0
8
+
9
+ [full changelog](https://github.com/Mange/roadie/compare/v3.0.0.pre1...v3.0.0)
10
+
11
+ * Enhancements:
12
+ * `Roadie::ProviderList` responds to `#empty?` and `#last`
13
+ * `Roadie::FilesystemProvider` ignores query string in filename.
14
+
15
+ Older versions of Rails generated `<link>` tags with query strings in their URLs, like such:
16
+ `/stylesheets/email.css?1380694096`
17
+ * Blacklist `:enabled`, `:disabled` and `:checked` pseudo functions - [Tyler Hunt (tylerhunt)](https://github.com/tylerhunt).
18
+ * Add MRI 2.1.2 to Travis build matrix - [Grey Baker (greysteil)](https://github.com/greysteil).
19
+ * Try to detect an upgrade from Roadie 2 and mention how to make it work with the new version.
20
+ * Styles emitted in the `style` attribute should now be ordered as they were in the source CSS.
21
+
22
+ ### 3.0.0.pre1
23
+
24
+ [full changelog](https://github.com/Mange/roadie/compare/v2.4.2...v3.0.0.pre1)
4
25
 
5
26
  Complete rewrite of most of the code and a new direction for the gem.
6
27
 
data/Gemfile CHANGED
@@ -7,8 +7,4 @@ gem 'coveralls', group: :test, require: nil
7
7
  group :guard do
8
8
  gem 'guard'
9
9
  gem 'guard-rspec'
10
-
11
- # Guard for Mac
12
- gem 'rb-fsevent', '>= 0.9.0.pre5'
13
- gem 'growl'
14
10
  end
data/Guardfile CHANGED
@@ -1,6 +1,6 @@
1
1
  rspec_options = {
2
- cmd: 'rspec -f nested',
3
- keep_failed: true,
2
+ cmd: 'rspec -f documentation',
3
+ failed_mode: :keep,
4
4
  all_after_pass: true,
5
5
  all_on_start: true,
6
6
  run_all: {cmd: 'rspec -f progress'}
@@ -9,6 +9,7 @@ rspec_options = {
9
9
  guard 'rspec', rspec_options do
10
10
  watch(%r{^spec/.+_spec\.rb$})
11
11
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
12
+ watch('lib/roadie.rb') { "spec" }
12
13
 
13
14
  watch(%r{lib/roadie/rspec/.*\.rb}) { "spec" }
14
15
 
data/README.md CHANGED
@@ -7,7 +7,7 @@ Roadie
7
7
  [![Gem Version](https://badge.fury.io/rb/roadie.png)](http://badge.fury.io/rb/roadie)
8
8
  [![Dependency Status](https://gemnasium.com/Mange/roadie.png)](https://gemnasium.com/Mange/roadie)
9
9
 
10
- **Note: This README details the prerelease 3.0 version of Roadie. You might be using 2.0, which is much older and only for Rails.**
10
+ **Note: This README details the 3.x version of Roadie. You might be using 2.x, which is much older and only for Rails.**
11
11
 
12
12
  > Making HTML emails comfortable for the Ruby rockstars
13
13
 
@@ -70,11 +70,11 @@ Your document instance can be configured several options:
70
70
  In order to make URLs absolute you need to first configure the URL options of the document.
71
71
 
72
72
  ```ruby
73
- html = "... <a href="/about-us">Read more!</a> ..."
73
+ html = '... <a href="/about-us">Read more!</a> ...'
74
74
  document = Roadie::Document.new html
75
75
  document.url_options = {host: "myapp.com", protocol: "https"}
76
76
  document.transform
77
- # => "... <a href="https://myapp.com/about-us">Read more!</a> ..."
77
+ # => "... <a href=\"https://myapp.com/about-us\">Read more!</a> ..."
78
78
  ```
79
79
 
80
80
  The following URLs will be rewritten for you:
@@ -235,6 +235,7 @@ Tested with [Travis CI](http://travis-ci.org) using:
235
235
 
236
236
  * MRI 1.9.3
237
237
  * MRI 2.0.0
238
+ * MRI 2.1.2
238
239
  * JRuby (latest)
239
240
  * Rubinius >= 2.1 (experimental)
240
241
 
@@ -273,6 +274,7 @@ Documentation
273
274
 
274
275
  * [Online documentation for gem](http://rubydoc.info/gems/roadie/frames)
275
276
  * [Online documentation for master](http://rubydoc.info/github/Mange/roadie/master/frames)
277
+ * [Online documentation for Roadie 2.4](http://rubydoc.info/gems/roadie/2.4/frames)
276
278
  * [Changelog](https://github.com/Mange/roadie/blob/master/Changelog.md)
277
279
 
278
280
  Running specs
@@ -300,7 +302,7 @@ License
300
302
 
301
303
  (The MIT License)
302
304
 
303
- Copyright (c) 2009-2013
305
+ Copyright (c) 2009-2014
304
306
 
305
307
  * [Magnus Bergmark](https://github.com/Mange) <magnus.bergmark@gmail.com>
306
308
 
data/lib/roadie.rb CHANGED
@@ -7,7 +7,7 @@ require 'roadie/errors'
7
7
  require 'roadie/stylesheet'
8
8
  require 'roadie/selector'
9
9
  require 'roadie/style_property'
10
- require 'roadie/style_properties'
10
+ require 'roadie/style_attribute_builder'
11
11
  require 'roadie/style_block'
12
12
 
13
13
  require 'roadie/asset_provider'
@@ -22,3 +22,5 @@ require 'roadie/url_rewriter'
22
22
  require 'roadie/null_url_rewriter'
23
23
  require 'roadie/inliner'
24
24
  require 'roadie/document'
25
+
26
+ require 'roadie/upgrade_guide'
@@ -15,7 +15,6 @@ module Roadie
15
15
  @path = path
16
16
  end
17
17
 
18
- # @raise InsecurePathError
19
18
  # @return [Stylesheet, nil]
20
19
  def find_stylesheet(name)
21
20
  file_path = build_file_path(name)
@@ -24,10 +23,22 @@ module Roadie
24
23
  end
25
24
  end
26
25
 
26
+ # @raise InsecurePathError
27
+ # @return [Stylesheet]
28
+ def find_stylesheet!(name)
29
+ file_path = build_file_path(name)
30
+ if File.exist? file_path
31
+ Stylesheet.new file_path, File.read(file_path)
32
+ else
33
+ clean_name = File.basename file_path
34
+ raise CssNotFound.new(clean_name, %{#{file_path} does not exist. (Original name was "#{name}")})
35
+ end
36
+ end
37
+
27
38
  private
28
39
  def build_file_path(name)
29
40
  raise InsecurePathError, name if name.include?("..")
30
- File.join(@path, name)
41
+ File.join(@path, name[/^([^?]+)/])
31
42
  end
32
43
  end
33
44
  end
@@ -33,8 +33,8 @@ module Roadie
33
33
  attr_reader :stylesheets
34
34
 
35
35
  def apply(style_map)
36
- style_map.each_element do |element, properties|
37
- apply_element_style element, properties
36
+ style_map.each_element do |element, builder|
37
+ apply_element_style element, builder
38
38
  end
39
39
  end
40
40
 
@@ -57,8 +57,8 @@ module Roadie
57
57
  end
58
58
  end
59
59
 
60
- def apply_element_style(element, properties)
61
- element["style"] = [properties.to_s, element["style"]].compact.join(";")
60
+ def apply_element_style(element, builder)
61
+ element["style"] = [builder.attribute_string, element["style"]].compact.join(";")
62
62
  end
63
63
 
64
64
  def elements_matching_selector(stylesheet, selector, dom)
@@ -77,23 +77,25 @@ module Roadie
77
77
  end
78
78
 
79
79
  # @api private
80
- # StyleMap is a map between a DOM element and {StyleProperties}. Basically,
80
+ # StyleMap is a map between a DOM element and {StyleAttributeBuilder}. Basically,
81
81
  # it's an accumulator for properties, scoped on specific elements.
82
82
  class StyleMap
83
83
  def initialize
84
84
  @map = Hash.new { |hash, key|
85
- hash[key] = StyleProperties.new([])
85
+ hash[key] = StyleAttributeBuilder.new
86
86
  }
87
87
  end
88
88
 
89
89
  def add(elements, new_properties)
90
90
  Array(elements).each do |element|
91
- @map[element].merge!(new_properties)
91
+ new_properties.each do |property|
92
+ @map[element] << property
93
+ end
92
94
  end
93
95
  end
94
96
 
95
97
  def each_element
96
- @map.each_pair { |element, properties| yield element, properties }
98
+ @map.each_pair { |element, builder| yield element, builder }
97
99
  end
98
100
  end
99
101
  end
@@ -74,7 +74,7 @@ module Roadie
74
74
 
75
75
  def content_type_meta_element_missing?
76
76
  dom.xpath('html/head/meta').none? do |meta|
77
- meta['http-equiv'].downcase == 'content-type'
77
+ meta['http-equiv'].to_s.downcase == 'content-type'
78
78
  end
79
79
  end
80
80
 
@@ -52,6 +52,8 @@ module Roadie
52
52
  # @see Array#each
53
53
  # @!method size
54
54
  # @see Array#size
55
+ # @!method empty?
56
+ # @see Array#empty?
55
57
  # @!method push
56
58
  # @see Array#push
57
59
  # @!method <<
@@ -62,6 +64,8 @@ module Roadie
62
64
  # @see Array#unshift
63
65
  # @!method shift
64
66
  # @see Array#shift
65
- def_delegators :@providers, :each, :size, :push, :<<, :pop, :unshift, :shift
67
+ # @!method last
68
+ # @see Array#last
69
+ def_delegators :@providers, :each, :size, :empty?, :push, :<<, :pop, :unshift, :shift, :last
66
70
  end
67
71
  end
@@ -3,26 +3,26 @@ shared_examples_for "roadie asset provider" do |options|
3
3
  invalid_name = options[:invalid_name] or raise "You must provide an :invalid_name option to the shared examples"
4
4
 
5
5
  def verify_stylesheet(stylesheet)
6
- stylesheet.should_not be_nil
6
+ expect(stylesheet).to_not be_nil
7
7
 
8
8
  # Name
9
- stylesheet.name.should be_a(String)
10
- stylesheet.name.should_not be_empty
9
+ expect(stylesheet.name).to be_a(String)
10
+ expect(stylesheet.name).to_not be_empty
11
11
 
12
12
  # We do not want to force clients to always return non-empty files.
13
13
  # Stylesheet#initialize should crash when given a non-valid CSS (like nil,
14
14
  # for example)
15
- # stylesheet.blocks.should_not be_empty
15
+ # expect(stylesheet.blocks).to_not be_empty
16
16
  end
17
17
 
18
18
  it "responds to #find_stylesheet" do
19
- subject.should respond_to(:find_stylesheet)
20
- subject.method(:find_stylesheet).arity.should == 1
19
+ expect(subject).to respond_to(:find_stylesheet)
20
+ expect(subject.method(:find_stylesheet).arity).to eq 1
21
21
  end
22
22
 
23
23
  it "responds to #find_stylesheet!" do
24
- subject.should respond_to(:find_stylesheet!)
25
- subject.method(:find_stylesheet!).arity.should == 1
24
+ expect(subject).to respond_to(:find_stylesheet!)
25
+ expect(subject.method(:find_stylesheet!).arity).to eq 1
26
26
  end
27
27
 
28
28
  describe "#find_stylesheet" do
@@ -31,7 +31,7 @@ shared_examples_for "roadie asset provider" do |options|
31
31
  end
32
32
 
33
33
  it "cannot find an invalid stylesheet" do
34
- subject.find_stylesheet(invalid_name).should be_nil
34
+ expect(subject.find_stylesheet(invalid_name)).to be_nil
35
35
  end
36
36
  end
37
37
 
@@ -57,6 +57,7 @@ module Roadie
57
57
  :active :focus :hover :link :target :visited
58
58
  :-ms-input-placeholder :-moz-placeholder
59
59
  :before :after
60
+ :enabled :disabled :checked
60
61
  ].freeze
61
62
 
62
63
  def pseudo_element?
@@ -0,0 +1,25 @@
1
+ module Roadie
2
+ class StyleAttributeBuilder
3
+ def initialize
4
+ @styles = []
5
+ end
6
+
7
+ def <<(style)
8
+ @styles << style
9
+ end
10
+
11
+ def attribute_string
12
+ stable_sort(@styles).map(&:to_s).join(';')
13
+ end
14
+
15
+ private
16
+ def stable_sort(list)
17
+ # Ruby's sort is unstable for performance reasons. We need it to be
18
+ # stable, e.g. to preserve order of elements that are compared equal in
19
+ # the sorting.
20
+ # We can accomplish this by using the original array index as a second
21
+ # comparator for when the first one is equal.
22
+ list.each_with_index.sort_by { |item, index| [item, index] }.map(&:first)
23
+ end
24
+ end
25
+ end
@@ -11,7 +11,6 @@ module Roadie
11
11
  # @param [Array<StyleProperty>] properties
12
12
  def initialize(selector, properties)
13
13
  @selector = selector
14
- # TODO: Should we use {StyleProperties} instead? Why? Why not?
15
14
  @properties = properties
16
15
  end
17
16
 
@@ -0,0 +1,36 @@
1
+ #
2
+ # Let the user know that they need to act to get Roadie compatible with their
3
+ # Rails apps if they might have upgraded from Roadie 2.
4
+ # TODO: Remove this file by the time of version 3.1.
5
+ #
6
+
7
+ if defined?(Rails) && !defined?(ROADIE_I_KNOW_ABOUT_VERSION_3)
8
+ begin
9
+ require 'roadie/rails'
10
+ rescue LoadError
11
+ warn <<-WARNING
12
+ Hey there! It looks like you might have tried to upgrade to Roadie 3 from Roadie 2.
13
+
14
+ Roadie 3 is a completely new version that is no longer interfacing with Rails
15
+ out-of-the-box. In order to use it you need to add the gem roadie-rails too.
16
+
17
+ You should really read the upgrade guide since the API have changed:
18
+
19
+ https://github.com/Mange/roadie-rails/blob/master/Upgrading.md#upgrading-from-roadie-2
20
+
21
+ I hope this new version will work better for you, but if you are not ready to
22
+ upgrade right now add a version specifier to your Gemfile:
23
+
24
+ gem 'roadie', '~> 2.4' # Support any minor version in the Roadie 2 series.
25
+
26
+ In case you have a need for Roadie without the default Rails integration you
27
+ can remove this warning by setting a constant:
28
+
29
+ # config/application.rb
30
+ ROADIE_I_KNOW_ABOUT_VERSION_3 = true # Remove after Roadie 3.1
31
+
32
+ Thank you for your attention.
33
+ WARNING
34
+ raise
35
+ end
36
+ end
@@ -1,3 +1,3 @@
1
1
  module Roadie
2
- VERSION = '3.0.0.pre1'
2
+ VERSION = '3.0.0'
3
3
  end
data/roadie.gemspec CHANGED
@@ -20,7 +20,8 @@ Gem::Specification.new do |s|
20
20
  s.add_dependency 'nokogiri', '~> 1.6.0'
21
21
  s.add_dependency 'css_parser', '~> 1.3.4'
22
22
 
23
- s.add_development_dependency 'rspec'
23
+ s.add_development_dependency 'rspec', '~> 3.0'
24
+ s.add_development_dependency 'rspec-collection_matchers', '~> 1.0'
24
25
 
25
26
  s.extra_rdoc_files = %w[README.md Changelog.md]
26
27
  s.require_paths = %w[lib]
@@ -15,15 +15,15 @@ describe "Roadie functionality" do
15
15
  # See Nokogiri bugs #984 and #985
16
16
  # https://github.com/sparklemotion/nokogiri/issues/984
17
17
  # https://github.com/sparklemotion/nokogiri/issues/985
18
- result.should include("<!DOCTYPE html>")
18
+ expect(result).to include("<!DOCTYPE html>")
19
19
  end
20
20
 
21
- result.should include("<html>")
22
- result.should include("<head>")
23
- result.should include("<body>")
21
+ expect(result).to include("<html>")
22
+ expect(result).to include("<head>")
23
+ expect(result).to include("<body>")
24
24
 
25
- result.should include("<meta")
26
- result.should include("text/html; charset=Shift_JIS")
25
+ expect(result).to include("<meta")
26
+ expect(result).to include("text/html; charset=Shift_JIS")
27
27
  end
28
28
 
29
29
  it "inlines given css" do
@@ -44,8 +44,8 @@ describe "Roadie functionality" do
44
44
  CSS
45
45
 
46
46
  result = parse_html document.transform
47
- result.should have_styling('text-align' => 'center').at_selector('h1')
48
- result.should have_styling('color' => 'red').at_selector('p > em')
47
+ expect(result).to have_styling('text-align' => 'center').at_selector('h1')
48
+ expect(result).to have_styling('color' => 'red').at_selector('p > em')
49
49
  end
50
50
 
51
51
  it "inlines css from disk" do
@@ -64,7 +64,7 @@ describe "Roadie functionality" do
64
64
  HTML
65
65
 
66
66
  result = parse_html document.transform
67
- result.should have_styling('font-size' => '200%').at_selector('p > em')
67
+ expect(result).to have_styling('font-size' => '200%').at_selector('p > em')
68
68
  end
69
69
 
70
70
  it "crashes when stylesheets cannot be found, unless using NullProvider" do
@@ -107,15 +107,15 @@ describe "Roadie functionality" do
107
107
  document.url_options = {host: "myapp.com", scheme: "https", path: "rails/app/"}
108
108
  result = parse_html document.transform
109
109
 
110
- result.at_css("a")["href"].should == "https://myapp.com/rails/app/about_us"
110
+ expect(result.at_css("a")["href"]).to eq("https://myapp.com/rails/app/about_us")
111
111
 
112
- result.at_css("img")["src"].should == "https://myapp.com/rails/app/assets/about_us-abcdef1234567890.png"
112
+ expect(result.at_css("img")["src"]).to eq("https://myapp.com/rails/app/assets/about_us-abcdef1234567890.png")
113
113
 
114
- result.should have_styling(
114
+ expect(result).to have_styling(
115
115
  "background" => 'url("https://myapp.com/rails/app/assets/bg-abcdef1234567890.png")'
116
116
  ).at_selector("body")
117
117
 
118
- result.should have_styling(
118
+ expect(result).to have_styling(
119
119
  "background" => 'url(https://myapp.com/rails/app/assets/link-abcdef1234567890.png)'
120
120
  ).at_selector("a")
121
121
  end
@@ -134,7 +134,7 @@ describe "Roadie functionality" do
134
134
  document.after_transformation = proc { |dom| dom.at_css("span").remove }
135
135
 
136
136
  result = parse_html document.transform
137
- result.at_css("body")["class"].should == "roadie"
138
- result.at_css("span").should be_nil
137
+ expect(result.at_css("body")["class"]).to eq("roadie")
138
+ expect(result.at_css("span")).to be_nil
139
139
  end
140
140
  end