roadie 3.0.0.pre1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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