inline-style 0.4.10 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- inline-style (0.4.9)
4
+ inline-style (0.4.10)
5
5
  css_parser
6
+ facets
6
7
  maca-fork-csspool
7
8
  nokogiri
8
9
 
@@ -12,6 +13,7 @@ GEM
12
13
  activesupport (3.0.4)
13
14
  css_parser (1.1.5)
14
15
  diff-lcs (1.1.2)
16
+ facets (2.9.1)
15
17
  ffi (1.0.7)
16
18
  rake (>= 0.8.7)
17
19
  i18n (0.5.0)
@@ -42,8 +44,12 @@ PLATFORMS
42
44
  ruby
43
45
 
44
46
  DEPENDENCIES
47
+ css_parser
48
+ facets
45
49
  inline-style!
50
+ maca-fork-csspool
46
51
  mail
52
+ nokogiri
47
53
  rack
48
54
  rspec
49
55
  rspec-core
@@ -24,8 +24,8 @@ Useful for html email: some clients (gmail, et all) won't render non inline styl
24
24
 
25
25
  require 'inline-style'
26
26
 
27
- html = File.read("#{ dir }/index.html")
28
- puts InlineStyle.process(html, :stylesheets_paths => "#{ dir }/styles")
27
+ html = File.read("./index.html")
28
+ puts InlineStyle.process(html, :stylesheets_paths => "./styles")
29
29
 
30
30
  index.html contains:
31
31
 
@@ -115,20 +115,13 @@ If using ActionMailer (which wraps mail):
115
115
 
116
116
  ActionMailer::Base.register_interceptor \
117
117
  InlineStyle::Mail::Interceptor.new(:stylesheets_path => 'public')
118
-
119
118
 
120
- == Issues:
121
-
122
- * It supports pseudo classes according to W3C specification for style in style attribute: http://www.w3.org/TR/css-style-attr, although browsers
123
- doesn't seems to.
124
-
125
119
 
126
120
  == Requirements:
127
121
 
128
122
  nokogiri && (css_parser || maca-fork-csspool)
129
123
 
130
124
 
131
-
132
125
  == Install:
133
126
 
134
127
  sudo gem install inline-style
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_development_dependency 'mail'
25
25
 
26
26
  s.add_dependency 'nokogiri'
27
+ s.add_dependency 'facets'
27
28
  s.add_dependency 'css_parser'
28
29
  s.add_dependency 'maca-fork-csspool'
29
30
  end
@@ -3,9 +3,9 @@ require 'open-uri'
3
3
 
4
4
  $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
5
5
 
6
- require "inline-style/selector"
7
- require "inline-style/rack/middleware" # This two may be should be required by user if she needs it
8
- require "inline-style/mail/interceptor"
6
+ require "inline-style/rule"
7
+ require "inline-style/rack-middleware" # This two may be should be required by user if she needs it
8
+ require "inline-style/mail-interceptor"
9
9
 
10
10
  class InlineStyle
11
11
  CSSParser =
@@ -20,82 +20,79 @@ class InlineStyle
20
20
  # @param [String, Nokogiri::HTML::Document] html Html or Nokogiri html to be inlined
21
21
  # @param [Hash] opts Processing options
22
22
  #
23
- # @option opts [String] :stylesheets_path (env['DOCUMENT_ROOT'])
23
+ # @option opts [String] :stylesheets_path (ENV['DOCUMENT_ROOT'])
24
24
  # Stylesheets root path or app's public directory where the stylesheets are to be found
25
- # @option opts [boolean] :pseudo (false)
26
- # If set to true will inline style for pseudo classes according to the W3C specification:
27
- # http://www.w3.org/TR/css-style-attr.
28
- # Should probably be left as false because browsers don't seem to comply with the specification for pseudo class style in the style attribute.
29
25
  def self.process html, opts = {}
30
26
  new(html, opts).process
31
27
  end
32
28
 
33
29
  def initialize html, opts = {}
34
- @html = html
35
- @stylesheets_path = opts[:stylesheets_path] || ''
36
- @pseudo = opts[:pseudo]
30
+ @stylesheets_path = opts[:stylesheets_path] || ENV['DOCUMENT_ROOT'] || '.'
31
+ @html = html
32
+ @dom = String === html ? Nokogiri.HTML(html) : html
37
33
  end
38
34
 
39
35
  def process
40
- nodes = {}
41
-
42
- css.each_rule_set do |rule_set|
43
- rule_set.each_selector do |selector|
44
- dom.css(selector.search).each do |node|
45
- nodes[node] ||= []
46
- nodes[node].push selector
47
-
48
- next unless node['style']
49
-
50
- path = node.css_path
51
- path << "##{ node['id'] }" if node['id']
52
- path << ".#{ node['class'].scan(/\S+/).join('.') }" if node['class']
53
-
54
- CSSParser.new("#{path}{#{node['style']}}").each_rule_set do |rule|
55
- rule.each_selector do |selector_inner|
56
- nodes[node].push selector_inner
57
- end
36
+ nodes_with_rules.each_pair do |node, rules|
37
+ rules = rules.sort_by{ |sel| "#{sel.specificity}%04d" % rules.index(sel) }
38
+
39
+ styles = []
40
+ rules.each do |rule|
41
+ next if rule.dynamic_pseudo_class
42
+ rule.declarations.each do |declaration|
43
+ if defined = styles.assoc(declaration.first)
44
+ styles[styles.index(defined)] = declaration # overrides defined declaration
45
+ else
46
+ styles << declaration
58
47
  end
59
48
  end
60
49
  end
61
- end
62
50
 
63
- nodes.each_pair do |node, selectors|
64
- selectors = selectors.sort_by{ |sel| "#{ sel.specificity }%03d" % selectors.index(sel) }
65
- selectors = selectors.reject {|sel| !@pseudo && sel.pseudo? }
66
- using_pseudo = selectors.any? &:pseudo?
67
-
68
- node['style'] = selectors.collect do |selector|
69
- if using_pseudo && !selector.pseudo?
70
- "{#{selector.inline_declarations}}"
71
- else
72
- selector.inline_declarations
73
- end
74
- end.join(' ').strip
51
+ style = styles.map{ |declaration| declaration.join(': ') }.join('; ')
52
+ node['style'] = "#{style};" unless style.empty?
75
53
  end
76
-
77
- html_already_parsed? ? @dom : @dom.to_s
54
+ pre_parsed? ? @dom : @dom.to_s
78
55
  end
79
56
 
80
57
  private
81
- def dom
82
- @dom ||= html_already_parsed? ? @html : Nokogiri.HTML(@html)
58
+ def nodes_with_rules
59
+ nodes, body = {}, @dom.css('body')
60
+
61
+ parse_css.rules.each do |rule|
62
+ body.css(rule.selector).each do |node|
63
+ nodes[node] ||= []
64
+ nodes[node].push rule
65
+ end
66
+ end
67
+
68
+ body.css('[style]').each do |node|
69
+ nodes[node] ||= []
70
+ nodes[node].push Rule.new ':inline', node['style'], '1000' # :inline is not really a pseudoclass
71
+ end
72
+
73
+ nodes
83
74
  end
84
75
 
85
- def html_already_parsed?
86
- @html.respond_to? :css
76
+ def pre_parsed?
77
+ @html == @dom
87
78
  end
88
79
 
89
80
  # Returns parsed CSS
90
- def css
91
- @css ||= CSSParser.new dom.css('style, link').collect { |e|
92
- next unless e['media'].nil? || ['screen', 'all'].include?(e['media'])
93
- next(e.remove and e.content) if e.name == 'style'
94
- next unless e['rel'] == 'stylesheet'
95
- e.remove
96
-
97
- uri = %r{^https?://} === e['href'] ? e['href'] : File.join(@stylesheets_path, e['href'].sub(/\?.+$/,''))
98
- open(uri).read rescue nil
99
- }.join("\n")
81
+ def extract_css
82
+ @dom.css('style, link[rel=stylesheet]').collect do |node|
83
+ next unless /^$|screen|all/ === node['media'].to_s
84
+ node.remove
85
+
86
+ if node.name == 'style'
87
+ node.content
88
+ else
89
+ uri = %r{^https?://} === node['href'] ? node['href'] : File.join(@stylesheets_path, node['href'].sub(/\?.+$/,''))
90
+ open(uri).read
91
+ end
92
+ end.join("\n")
93
+ end
94
+
95
+ def parse_css
96
+ CSSParser.new extract_css
100
97
  end
101
98
  end
@@ -2,26 +2,13 @@ require 'css_parser'
2
2
 
3
3
  class InlineStyle
4
4
  class CssParserWrapper
5
- def initialize(css_code)
6
- @parser = ::CssParser::Parser.new
7
- @parser.add_block! css_code
8
- end
9
-
10
- def each_rule_set(&blk)
11
- @parser.each_rule_set do |rule_set|
12
- yield Ruleset.new(rule_set)
13
- end
14
- end
15
-
16
- class Ruleset
17
- def initialize(ruleset)
18
- @ruleset = ruleset
19
- end
5
+ attr_accessor :rules
20
6
 
21
- def each_selector
22
- @ruleset.each_selector do |sel, dec, spe|
23
- yield InlineStyle::Selector.new(sel, dec, spe)
24
- end
7
+ def initialize(css_code)
8
+ parser, @rules = CssParser::Parser.new, []
9
+ parser.add_block! css_code
10
+ parser.each_rule_set do |rule_set|
11
+ rule_set.each_selector { |sel, dec, spec| @rules << Rule.new(sel, dec, '%04d' % spec.to_i) }
25
12
  end
26
13
  end
27
14
  end
@@ -1,29 +1,12 @@
1
1
  class InlineStyle
2
2
  class CSSPoolWrapper
3
+ attr_accessor :rules
3
4
 
4
- def initialize(css_code)
5
- @parser = CSSPool.CSS css_code
6
- end
7
-
8
- def each_rule_set
9
- @parser.rule_sets.each do |rule_set|
10
- yield Ruleset.new(rule_set)
11
- end
12
- end
13
-
14
- class Ruleset
15
-
16
- def initialize(ruleset)
17
- @ruleset = ruleset
18
- end
19
-
20
- def each_selector(&blk)
21
- @ruleset.selectors.each do |selector|
22
- yield InlineStyle::Selector.new(selector.to_s,
23
- selector.declarations.map{ |d| d.to_s.squeeze(' ') }.join.strip,
24
- selector.specificity.inject(0) {|t, s| t+s})
25
- end
26
- end
5
+ def initialize css_code
6
+ parser = CSSPool.CSS css_code
7
+ @rules = parser.rule_sets.map do |rule_set|
8
+ rule_set.selectors.map { |sel| Rule.new(sel.to_s, sel.declarations.join, "0#{sel.specificity.join}") }
9
+ end.flatten
27
10
  end
28
11
  end
29
12
  end
@@ -9,6 +9,7 @@
9
9
  #
10
10
  # ActionMailer::Base.register_interceptor \
11
11
  # InlineStyle::Mail::Interceptor.new(:stylesheets_path => 'public')
12
+ #
12
13
  module InlineStyle::Mail
13
14
  class Interceptor
14
15
  # The mime types we should inline. Basically HTML and XHTML.
@@ -0,0 +1,18 @@
1
+ class InlineStyle
2
+ # A simple abstraction of the data we get back from the parsers. CSSPool
3
+ # actually already does this for us but CSSParser does not so we need
4
+ # to create the abstraction ourselves.
5
+ class Rule
6
+ DYNAMIC_PSEUDO_CLASSES = %w(link visited active hover focus target enabled disabled checked)
7
+ DYNAMIC_PSEUDO_CLASSES_MATCHER = /:(#{DYNAMIC_PSEUDO_CLASSES.join('|')})$/
8
+
9
+ attr_reader :selector, :declarations, :specificity, :dynamic_pseudo_class
10
+
11
+ def initialize selector, declarations, specificity
12
+ @specificity = specificity
13
+ @selector, @dynamic_pseudo_class = selector.split DYNAMIC_PSEUDO_CLASSES_MATCHER
14
+ @selector.sub! /$^/, '*'
15
+ @declarations = declarations.scan /\s*([^:]+):\s*([^;]+);/
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  class InlineStyle
2
- VERSION = '0.4.10'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -3,7 +3,7 @@ require "spec_helper"
3
3
  describe InlineStyle do
4
4
  shared_examples_for 'inlines styles' do
5
5
  before do
6
- processed = InlineStyle.process File.read("#{FIXTURES}/boletin.html"), :pseudo => false, :stylesheets_path => FIXTURES
6
+ processed = InlineStyle.process File.read("#{FIXTURES}/boletin.html"), :stylesheets_path => FIXTURES
7
7
  @processed = Nokogiri.HTML(processed)
8
8
  end
9
9
 
@@ -16,7 +16,7 @@ describe InlineStyle do
16
16
  end
17
17
 
18
18
  it "should extract styles from linked stylesheet with media 'all'" do
19
- @processed.css('#izq').first['style'].should match_style /padding: 10.0px;/
19
+ @processed.css('#izq').first['style'].should match_style /border: none;/
20
20
  end
21
21
 
22
22
  it "should ignore styles from linked stylesheet with media other than screen" do
@@ -27,11 +27,6 @@ describe InlineStyle do
27
27
  @processed.css('a').first['style'].should_not match_style /^:hover \{background-color: #8ae0ea; color: #126b5d;\}$/
28
28
  end
29
29
 
30
- it "should should process pseudo classes" do
31
- processed = InlineStyle.process Nokogiri.HTML(File.read("#{FIXTURES}/boletin.html")), :pseudo => true
32
- processed.css('a').first['style'].should match_style /^:hover \{background-color: #8ae0ea; color: #126b5d;\}$/
33
- end
34
-
35
30
  it 'should process location-based pseudo classes' do
36
31
  @processed.at_css('#izq')['style'].should match_style /padding: 1.0px;/
37
32
  end
@@ -40,9 +35,13 @@ describe InlineStyle do
40
35
  @processed.css('#logos #der').first['style'].should match_style /float: right;/
41
36
  end
42
37
 
43
- # it 'should overwrite rule with less specificity'
44
- # it 'should overwrite rule previously defined'
45
- # it 'should not overwrite rules defined inline'
38
+ it 'should not override rules defined inline' do
39
+ @processed.css('#aviso').first['style'].should match_style /color: green;/
40
+ end
41
+
42
+ it 'should overwrite rule previously defined' do
43
+ @processed.css('#izq').first['style'].should_not match_style /padding: 0.0;/
44
+ end
46
45
 
47
46
  describe 'Box model' do
48
47
  before do
@@ -0,0 +1,146 @@
1
+ require "spec_helper"
2
+
3
+ describe 'CSS parsing' do
4
+ shared_examples_for 'parses css' do
5
+ describe 'parsing tag selector' do
6
+ before do
7
+ @wrapper = subject.new 'p {background-color: black; padding: 0.0 0.0 0.0 0.0}'
8
+ end
9
+
10
+ it { @wrapper.should have(1).rules }
11
+
12
+ describe 'rule' do
13
+ before { @rule = @wrapper.rules.first }
14
+ it { @rule.specificity.should == '0001' }
15
+ it { @rule.declarations.should == [['background-color', 'black'], ['padding', '0.0 0.0 0.0 0.0']] }
16
+ it { @rule.selector.should == 'p' }
17
+ it { @rule.dynamic_pseudo_class.should be_nil }
18
+ end
19
+ end
20
+
21
+ describe 'parsing body tag selector' do
22
+ before do
23
+ @wrapper = subject.new 'body {background-color: black; padding: 0.0 0.0 0.0 0.0}'
24
+ end
25
+
26
+ it { @wrapper.should have(1).rules }
27
+
28
+ describe 'rule' do
29
+ before { @rule = @wrapper.rules.first }
30
+ it { @rule.specificity.should == '0001' }
31
+ it { @rule.declarations.should == [['background-color', 'black'], ['padding', '0.0 0.0 0.0 0.0']] }
32
+ it { @rule.selector.should == 'body' }
33
+ it { @rule.dynamic_pseudo_class.should be_nil }
34
+ end
35
+ end
36
+
37
+ describe 'parsing tag and class selector' do
38
+ before do
39
+ @wrapper = subject.new 'div.article {background-color: black; padding: 0.0 0.0 0.0 0.0}'
40
+ end
41
+
42
+ it { @wrapper.should have(1).rules }
43
+
44
+ describe 'rule' do
45
+ before { @rule = @wrapper.rules.first }
46
+ it { @rule.specificity.should == '0011' }
47
+ it { @rule.declarations.should == [['background-color', 'black'], ['padding', '0.0 0.0 0.0 0.0']] }
48
+ it { @rule.selector.should == 'div.article' }
49
+ it { @rule.dynamic_pseudo_class.should be_nil }
50
+ end
51
+ end
52
+
53
+ describe 'parsing tag, class and id selector' do
54
+ before do
55
+ @wrapper = subject.new 'div#headline.article {background-color: black; padding: 0.0 0.0 0.0 0.0}'
56
+ end
57
+
58
+ it { @wrapper.should have(1).rules }
59
+
60
+ describe 'rule' do
61
+ before { @rule = @wrapper.rules.first }
62
+ it { @rule.specificity.should == '0111' }
63
+ it { @rule.declarations.should == [['background-color', 'black'], ['padding', '0.0 0.0 0.0 0.0']] }
64
+ it { @rule.selector.should == 'div#headline.article' }
65
+ it { @rule.dynamic_pseudo_class.should be_nil }
66
+ end
67
+ end
68
+
69
+ describe 'parsing tag selector' do
70
+ before do
71
+ @wrapper = subject.new 'p, div {background-color: black; padding: 0.0 0.0 0.0 0.0}'
72
+ end
73
+
74
+ it { @wrapper.should have(2).rules }
75
+
76
+ describe 'first rule' do
77
+ before { @rule = @wrapper.rules.first }
78
+ it { @rule.specificity.should == '0001' }
79
+ it { @rule.declarations.should == [['background-color', 'black'], ['padding', '0.0 0.0 0.0 0.0']] }
80
+ it { @rule.selector.should == 'p' }
81
+ it { @rule.dynamic_pseudo_class.should be_nil }
82
+ end
83
+
84
+ describe 'last rule' do
85
+ before { @rule = @wrapper.rules.last }
86
+ it { @rule.specificity.should == '0001' }
87
+ it { @rule.declarations.should == [['background-color', 'black'], ['padding', '0.0 0.0 0.0 0.0']] }
88
+ it { @rule.selector.should == 'div' }
89
+ it { @rule.dynamic_pseudo_class.should be_nil }
90
+ end
91
+ end
92
+
93
+ describe 'dynamic pseudo selectors' do
94
+ InlineStyle::Rule::DYNAMIC_PSEUDO_CLASSES.each do |pseudo_class|
95
+ describe "parsing tag with :#{pseudo_class}" do
96
+ before { @dynamic_pseudo_class = pseudo_class }
97
+ it_should_behave_like 'parses dynamic pseudo selector'
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ shared_examples_for 'parses dynamic pseudo selector' do
104
+ describe 'with tag' do
105
+ before do
106
+ @wrapper = subject.new "p:#{@dynamic_pseudo_class} {background-color: black; padding: 0.0 0.0 0.0 0.0}"
107
+ end
108
+
109
+ it { @wrapper.should have(1).rules }
110
+
111
+ describe 'rule' do
112
+ before { @rule = @wrapper.rules.first }
113
+ # it { @rule.specificity.should == '011' }
114
+ it { @rule.declarations.should == [['background-color', 'black'], ['padding', '0.0 0.0 0.0 0.0']] }
115
+ it { @rule.selector.should == 'p' }
116
+ it { @rule.dynamic_pseudo_class.should == @dynamic_pseudo_class }
117
+ end
118
+ end
119
+
120
+ describe 'without tag' do
121
+ before do
122
+ @wrapper = subject.new ":#{@dynamic_pseudo_class} {background-color: black; padding: 0.0 0.0 0.0 0.0}"
123
+ end
124
+
125
+ it { @wrapper.should have(1).rules }
126
+
127
+ describe 'rule' do
128
+ before { @rule = @wrapper.rules.first }
129
+ # it { @rule.specificity.should == '011' }
130
+ it { @rule.declarations.should == [['background-color', 'black'], ['padding', '0.0 0.0 0.0 0.0']] }
131
+ it { @rule.selector.should == '*' }
132
+ it { @rule.dynamic_pseudo_class.should == @dynamic_pseudo_class }
133
+ end
134
+ end
135
+ end
136
+
137
+ describe InlineStyle::CssParserWrapper do
138
+ subject { InlineStyle::CssParserWrapper }
139
+ it_should_behave_like 'parses css'
140
+ end
141
+
142
+ describe InlineStyle::CssParserWrapper do
143
+ subject { InlineStyle::CSSPoolWrapper }
144
+ it_should_behave_like 'parses css'
145
+ end
146
+ end
@@ -1,3 +1,3 @@
1
1
  #izq {
2
- padding: 10px;
3
- }
2
+ border: none;
3
+ }
@@ -52,6 +52,7 @@ p {
52
52
  #aviso {
53
53
  padding: 25px 0;
54
54
  text-align: center;
55
+ color: blue;
55
56
  }
56
57
 
57
58
  dl.categoria dt {
@@ -143,7 +144,7 @@ div#contacto a {
143
144
 
144
145
 
145
146
  <div id="header">
146
- <div id="aviso">Si usted no puede visualizar correctamente este boletín haga <a href="http://localhost:3000/boletines/noviembre-2009">click aquí</a></div>
147
+ <div id="aviso" style='color: green;'>Si usted no puede visualizar correctamente este boletín haga <a href="http://localhost:3000/boletines/noviembre-2009">click aquí</a></div>
147
148
  <div id="banner"><span id="cenart">CENART</span> Noviembre 2009</div>
148
149
  </div>
149
150
 
@@ -6,97 +6,97 @@
6
6
  </title>
7
7
  <link href="/print.css?1248460539" rel="stylesheet" media="print" type="text/css">
8
8
  </head>
9
- <body style='font: 13.0px "Lucida Grande", Lucida, Verdana, sans-serif; width: 680.0px; color: #373737; margin-left: auto; margin-right: auto;'>
10
- <div id="header" style="margin: 0.0; padding: 0.0;">
11
- <div id="aviso" style="margin: 0.0; padding: 0.0; padding: 25.0px 0.0; text-align: center;">Si usted no puede visualizar correctamente este boletín haga <a href="http://localhost:3000/boletines/noviembre-2009" style="margin: 0.0; padding: 0.0; color: #185d6b;">click aquí</a>
9
+ <body style='margin: 0; padding: 0; font: 13px "Lucida Grande", Lucida, Verdana, sans-serif; width: 680px; color: #373737; margin-left: auto; margin-right: auto;'>
10
+ <div id="header" style="margin: 0; padding: 0;">
11
+ <div id="aviso" style="margin: 0; padding: 25px 0; text-align: center; color: green;">Si usted no puede visualizar correctamente este boletín haga <a href="http://localhost:3000/boletines/noviembre-2009" style="margin: 0; padding: 0; color: #185d6b;">click aquí</a>
12
12
  </div>
13
- <div id="banner" style="margin: 0.0; padding: 0.0; margin: 15.0px; text-align: right; color: #639b22;">
14
- <span id="cenart" style="margin: 0.0; padding: 0.0; font-size: 20.0px;">CENART</span> Noviembre 2009</div>
13
+ <div id="banner" style="margin: 15px; padding: 0; text-align: right; color: #639b22;">
14
+ <span id="cenart" style="margin: 0; padding: 0; font-size: 20px;">CENART</span> Noviembre 2009</div>
15
15
  </div>
16
16
 
17
17
 
18
18
 
19
19
 
20
20
 
21
- <dl class="categoria" id="A" style="margin: 0.0; padding: 0.0;">
22
- <dt style="margin: 0.0; padding: 0.0; font-size: 20.0px; padding: 10.0px; background-color: #416517; border-bottom: 1.0px dashed #a6a6a6; color: #a0bf57;">A</dt>
23
- <dd style="margin: 0.0; padding: 0.0;">
21
+ <dl class="categoria" id="A" style="margin: 0; padding: 0;">
22
+ <dt style="margin: 0; padding: 10px; font-size: 20px; background-color: #416517; border-bottom: 1px dashed #a6a6a6; color: #a0bf57;">A</dt>
23
+ <dd style="margin: 0; padding: 0;">
24
24
 
25
25
 
26
- <dl class="evento non" style="margin: 0.0; padding: 0.0; padding: 30.0px 25.0px 20.0px 35.0px; border-bottom: 1.0px dashed #a6a6a6; background-color: #d9e3cf;">
27
- <dt style="margin: 0.0; padding: 0.0; font-size: 20.0px; padding: 10.0px; background-color: #416517; border-bottom: 1.0px dashed #a6a6a6; color: #a0bf57; padding: 0.0; font-size: 20.0px; background: none; font-weight: bold; border: none;"><a href="" style="margin: 0.0; padding: 0.0; color: #185d6b;">1</a></dt>
26
+ <dl class="evento non" style="margin: 0; padding: 30px 25px 20px 35px; border-bottom: 1px dashed #a6a6a6; background-color: #d9e3cf;">
27
+ <dt style="margin: 0; padding: 0; font-size: 20px; background-color: #416517; border-bottom: 1px dashed #a6a6a6; color: #a0bf57; background: none; font-weight: bold; border: none;"><a href="" style="margin: 0; padding: 0; color: #185d6b;">1</a></dt>
28
28
 
29
- <dd class="descripcion" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
30
- <p style="margin: 0.0; padding: 0.0; margin: 10.0px 0.0;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
29
+ <dd class="descripcion" style="margin: 10px 0; padding: 0; text-align: justify;">
30
+ <p style="margin: 10px 0; padding: 0;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
31
31
  </dd>
32
- <dd class="fechas" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
33
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Fechas: </b>Fecha</dd>
34
- <dd class="locacion" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
35
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Lugar: </b>Lugar</dd>
36
- <dd class="precio" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
37
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Público: </b>Público</dd>
38
- <dd class="precio" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
39
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Precio: </b>Precio</dd>
32
+ <dd class="fechas" style="margin: 10px 0; padding: 0; text-align: justify;">
33
+ <b style="margin: 0; padding: 0; color: #185d6b;">Fechas: </b>Fecha</dd>
34
+ <dd class="locacion" style="margin: 10px 0; padding: 0; text-align: justify;">
35
+ <b style="margin: 0; padding: 0; color: #185d6b;">Lugar: </b>Lugar</dd>
36
+ <dd class="precio" style="margin: 10px 0; padding: 0; text-align: justify;">
37
+ <b style="margin: 0; padding: 0; color: #185d6b;">Público: </b>Público</dd>
38
+ <dd class="precio" style="margin: 10px 0; padding: 0; text-align: justify;">
39
+ <b style="margin: 0; padding: 0; color: #185d6b;">Precio: </b>Precio</dd>
40
40
  </dl>
41
41
  </dd>
42
42
  </dl>
43
- <dl class="categoria" id="B" style="margin: 0.0; padding: 0.0;">
44
- <dt style="margin: 0.0; padding: 0.0; font-size: 20.0px; padding: 10.0px; background-color: #416517; border-bottom: 1.0px dashed #a6a6a6; color: #a0bf57;">B</dt>
45
- <dd style="margin: 0.0; padding: 0.0;">
43
+ <dl class="categoria" id="B" style="margin: 0; padding: 0;">
44
+ <dt style="margin: 0; padding: 10px; font-size: 20px; background-color: #416517; border-bottom: 1px dashed #a6a6a6; color: #a0bf57;">B</dt>
45
+ <dd style="margin: 0; padding: 0;">
46
46
 
47
47
 
48
- <dl class="evento par" style="margin: 0.0; padding: 0.0; padding: 30.0px 25.0px 20.0px 35.0px; border-bottom: 1.0px dashed #a6a6a6; background-color: #cfdfe3;">
49
- <dt style="margin: 0.0; padding: 0.0; font-size: 20.0px; padding: 10.0px; background-color: #416517; border-bottom: 1.0px dashed #a6a6a6; color: #a0bf57; padding: 0.0; font-size: 20.0px; background: none; font-weight: bold; border: none;"><a href="" style="margin: 0.0; padding: 0.0; color: #185d6b;">1</a></dt>
48
+ <dl class="evento par" style="margin: 0; padding: 30px 25px 20px 35px; border-bottom: 1px dashed #a6a6a6; background-color: #cfdfe3;">
49
+ <dt style="margin: 0; padding: 0; font-size: 20px; background-color: #416517; border-bottom: 1px dashed #a6a6a6; color: #a0bf57; background: none; font-weight: bold; border: none;"><a href="" style="margin: 0; padding: 0; color: #185d6b;">1</a></dt>
50
50
 
51
- <dd class="descripcion" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
52
- <p style="margin: 0.0; padding: 0.0; margin: 10.0px 0.0;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
51
+ <dd class="descripcion" style="margin: 10px 0; padding: 0; text-align: justify;">
52
+ <p style="margin: 10px 0; padding: 0;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
53
53
  </dd>
54
- <dd class="fechas" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
55
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Fechas: </b>Fecha</dd>
56
- <dd class="locacion" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
57
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Lugar: </b>Lugar</dd>
58
- <dd class="precio" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
59
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Público: </b>Público</dd>
60
- <dd class="precio" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
61
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Precio: </b>Precio</dd>
54
+ <dd class="fechas" style="margin: 10px 0; padding: 0; text-align: justify;">
55
+ <b style="margin: 0; padding: 0; color: #185d6b;">Fechas: </b>Fecha</dd>
56
+ <dd class="locacion" style="margin: 10px 0; padding: 0; text-align: justify;">
57
+ <b style="margin: 0; padding: 0; color: #185d6b;">Lugar: </b>Lugar</dd>
58
+ <dd class="precio" style="margin: 10px 0; padding: 0; text-align: justify;">
59
+ <b style="margin: 0; padding: 0; color: #185d6b;">Público: </b>Público</dd>
60
+ <dd class="precio" style="margin: 10px 0; padding: 0; text-align: justify;">
61
+ <b style="margin: 0; padding: 0; color: #185d6b;">Precio: </b>Precio</dd>
62
62
  </dl>
63
63
  </dd>
64
64
  </dl>
65
- <dl class="categoria" id="C" style="margin: 0.0; padding: 0.0;">
66
- <dt style="margin: 0.0; padding: 0.0; font-size: 20.0px; padding: 10.0px; background-color: #416517; border-bottom: 1.0px dashed #a6a6a6; color: #a0bf57;">C</dt>
67
- <dd style="margin: 0.0; padding: 0.0;">
65
+ <dl class="categoria" id="C" style="margin: 0; padding: 0;">
66
+ <dt style="margin: 0; padding: 10px; font-size: 20px; background-color: #416517; border-bottom: 1px dashed #a6a6a6; color: #a0bf57;">C</dt>
67
+ <dd style="margin: 0; padding: 0;">
68
68
 
69
69
 
70
- <dl class="evento non" style="margin: 0.0; padding: 0.0; padding: 30.0px 25.0px 20.0px 35.0px; border-bottom: 1.0px dashed #a6a6a6; background-color: #d9e3cf;">
71
- <dt style="margin: 0.0; padding: 0.0; font-size: 20.0px; padding: 10.0px; background-color: #416517; border-bottom: 1.0px dashed #a6a6a6; color: #a0bf57; padding: 0.0; font-size: 20.0px; background: none; font-weight: bold; border: none;"><a href="" style="margin: 0.0; padding: 0.0; color: #185d6b;">1</a></dt>
70
+ <dl class="evento non" style="margin: 0; padding: 30px 25px 20px 35px; border-bottom: 1px dashed #a6a6a6; background-color: #d9e3cf;">
71
+ <dt style="margin: 0; padding: 0; font-size: 20px; background-color: #416517; border-bottom: 1px dashed #a6a6a6; color: #a0bf57; background: none; font-weight: bold; border: none;"><a href="" style="margin: 0; padding: 0; color: #185d6b;">1</a></dt>
72
72
 
73
- <dd class="descripcion" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
74
- <p style="margin: 0.0; padding: 0.0; margin: 10.0px 0.0;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
73
+ <dd class="descripcion" style="margin: 10px 0; padding: 0; text-align: justify;">
74
+ <p style="margin: 10px 0; padding: 0;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
75
75
  </dd>
76
- <dd class="fechas" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
77
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Fechas: </b>Fecha</dd>
78
- <dd class="locacion" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
79
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Lugar: </b>Lugar</dd>
80
- <dd class="precio" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
81
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Público: </b>Público</dd>
82
- <dd class="precio" style="margin: 0.0; padding: 0.0; text-align: justify; margin: 10.0px 0.0;">
83
- <b style="margin: 0.0; padding: 0.0; color: #185d6b;">Precio: </b>Precio</dd>
76
+ <dd class="fechas" style="margin: 10px 0; padding: 0; text-align: justify;">
77
+ <b style="margin: 0; padding: 0; color: #185d6b;">Fechas: </b>Fecha</dd>
78
+ <dd class="locacion" style="margin: 10px 0; padding: 0; text-align: justify;">
79
+ <b style="margin: 0; padding: 0; color: #185d6b;">Lugar: </b>Lugar</dd>
80
+ <dd class="precio" style="margin: 10px 0; padding: 0; text-align: justify;">
81
+ <b style="margin: 0; padding: 0; color: #185d6b;">Público: </b>Público</dd>
82
+ <dd class="precio" style="margin: 10px 0; padding: 0; text-align: justify;">
83
+ <b style="margin: 0; padding: 0; color: #185d6b;">Precio: </b>Precio</dd>
84
84
  </dl>
85
85
  </dd>
86
86
  </dl>
87
- <div id="footer" style="margin: 0.0; padding: 0.0;">
88
- <div id="direccion" style="margin: 0.0; padding: 0.0; padding: 30.0px 25.0px 20.0px 35.0px;">
89
- <b style="margin: 0.0; padding: 0.0; color: #185d6b; color: #5f792d;">lorem</b><br style="margin: 0.0; padding: 0.0;">
90
- ipsum<br style="margin: 0.0; padding: 0.0;">
91
- dolor<br style="margin: 0.0; padding: 0.0;">
92
- sit<br style="margin: 0.0; padding: 0.0;">
87
+ <div id="footer" style="margin: 0; padding: 0;">
88
+ <div id="direccion" style="margin: 0; padding: 30px 25px 20px 35px;">
89
+ <b style="margin: 0; padding: 0; color: #5f792d;">lorem</b><br style="margin: 0; padding: 0;">
90
+ ipsum<br style="margin: 0; padding: 0;">
91
+ dolor<br style="margin: 0; padding: 0;">
92
+ sit<br style="margin: 0; padding: 0;">
93
93
  </div>
94
94
 
95
- <div id="contacto" style="margin: 0.0; padding: 0.0; padding: 30.0px 25.0px 20.0px 35.0px;">
96
- contacto <br style="margin: 0.0; padding: 0.0;"><a href="mailto:mail@host.org" style="margin: 0.0; padding: 0.0; color: #185d6b; font-weight: bold; font-size: 1.2em;">mail@host.org</a>
95
+ <div id="contacto" style="margin: 0; padding: 30px 25px 20px 35px;">
96
+ contacto <br style="margin: 0; padding: 0;"><a href="mailto:mail@host.org" style="margin: 0; padding: 0; color: #185d6b; font-weight: bold; font-size: 1.2em;">mail@host.org</a>
97
97
  </div>
98
- <div id="logos" style="margin: 0.0; padding: 0.0; width: 100.0%; margin-top: 40.0px; background-image: url(/images/boletines/Noviembre/logos_fondo.jpg);">
99
- <img src="A" id="izq" alt="A" style="margin: 0.0; padding: 0.0; float: left; margin: 30.0px; padding: 10.0px; color: red; padding: 1.0px;"><img src="B" id="der" alt="B" style="margin: 0.0; padding: 0.0; float: right;"><div class="clearer" style="margin: 0.0; padding: 0.0; clear: both;">
98
+ <div id="logos" style="margin: 0; padding: 0; width: 100%; margin-top: 40px; background-image: url('/images/boletines/Noviembre/logos_fondo.jpg');">
99
+ <img src="A" id="izq" alt="A" style="margin: 30px; padding: 1px; float: left; border: none; color: red;"><img src="B" id="der" alt="B" style="margin: 0; padding: 0; float: right;"><div class="clearer" style="margin: 0; padding: 0; clear: both;">
100
100
  </div>
101
101
  </div>
102
102
 
@@ -1,27 +1,16 @@
1
- require "spec_helper"
2
- require "inline-style/mail/interceptor"
3
- require "mail"
1
+ require "#{ File.dirname __FILE__ }/spec_helper"
4
2
 
3
+ require 'mail'
5
4
  Mail.defaults do
6
5
  delivery_method :test
7
6
  end
8
-
9
- Mail.register_interceptor InlineStyle::Mail::Interceptor.new(:stylesheets_path => FIXTURES)
7
+ Mail.register_interceptor \
8
+ InlineStyle::Mail::Interceptor.new(:stylesheets_path => FIXTURES)
10
9
 
11
10
  describe InlineStyle::Mail::Interceptor do
11
+
12
12
  before do
13
13
  Mail::TestMailer.deliveries.clear
14
- class InlineStyle
15
- remove_const :CSSParser
16
- CSSParser = InlineStyle::CSSPoolWrapper
17
- end
18
- end
19
-
20
- after do
21
- class InlineStyle
22
- remove_const :CSSParser
23
- CSSParser = InlineStyle::CssParserWrapper
24
- end
25
14
  end
26
15
 
27
16
  it 'should inline html e-mail' do
@@ -70,4 +59,6 @@ describe InlineStyle::Mail::Interceptor do
70
59
  Mail::TestMailer.deliveries.first.parts[1].body.to_s.
71
60
  should == File.read("#{ FIXTURES }/inline.html")
72
61
  end
62
+
73
63
  end
64
+
@@ -1,5 +1,5 @@
1
1
  require "spec_helper"
2
- require "inline-style/rack/middleware"
2
+ require "inline-style/rack-middleware"
3
3
 
4
4
  describe InlineStyle::Rack::Middleware do
5
5
  def get_response path, body, opts = {}
@@ -5,6 +5,8 @@ require 'rack/mock'
5
5
 
6
6
  require "inline-style"
7
7
  require "inline-style/csspool_wrapper"
8
+
9
+ gem 'maca-fork-csspool'
8
10
  require "csspool"
9
11
 
10
12
  FIXTURES = "#{File.dirname __FILE__}/fixtures"
@@ -40,11 +42,11 @@ module InlineStyleMatchers
40
42
  end
41
43
 
42
44
  def failure_message
43
- "expected #{@style} to match #{@actual}"
45
+ "expected #{@actual} to match #{@style}"
44
46
  end
45
47
 
46
48
  def negative_failure_message
47
- "expected #{@style} not to match #{@actual}"
49
+ "expected #{@actual} not to match #{@style}"
48
50
  end
49
51
  end
50
52
 
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inline-style
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
5
- prerelease:
4
+ prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 4
9
- - 10
10
- version: 0.4.10
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Macario Ortega
@@ -16,7 +15,7 @@ autorequire:
16
15
  bindir: bin
17
16
  cert_chain: []
18
17
 
19
- date: 2011-03-23 00:00:00 -06:00
18
+ date: 2011-03-24 00:00:00 -06:00
20
19
  default_executable:
21
20
  dependencies:
22
21
  - !ruby/object:Gem::Dependency
@@ -27,7 +26,6 @@ dependencies:
27
26
  requirements:
28
27
  - - ">="
29
28
  - !ruby/object:Gem::Version
30
- hash: 3
31
29
  segments:
32
30
  - 0
33
31
  version: "0"
@@ -41,7 +39,6 @@ dependencies:
41
39
  requirements:
42
40
  - - ">="
43
41
  - !ruby/object:Gem::Version
44
- hash: 3
45
42
  segments:
46
43
  - 0
47
44
  version: "0"
@@ -55,7 +52,6 @@ dependencies:
55
52
  requirements:
56
53
  - - ">="
57
54
  - !ruby/object:Gem::Version
58
- hash: 3
59
55
  segments:
60
56
  - 0
61
57
  version: "0"
@@ -69,7 +65,6 @@ dependencies:
69
65
  requirements:
70
66
  - - ">="
71
67
  - !ruby/object:Gem::Version
72
- hash: 3
73
68
  segments:
74
69
  - 0
75
70
  version: "0"
@@ -83,40 +78,50 @@ dependencies:
83
78
  requirements:
84
79
  - - ">="
85
80
  - !ruby/object:Gem::Version
86
- hash: 3
87
81
  segments:
88
82
  - 0
89
83
  version: "0"
90
84
  type: :runtime
91
85
  version_requirements: *id005
92
86
  - !ruby/object:Gem::Dependency
93
- name: css_parser
87
+ name: facets
94
88
  prerelease: false
95
89
  requirement: &id006 !ruby/object:Gem::Requirement
96
90
  none: false
97
91
  requirements:
98
92
  - - ">="
99
93
  - !ruby/object:Gem::Version
100
- hash: 3
101
94
  segments:
102
95
  - 0
103
96
  version: "0"
104
97
  type: :runtime
105
98
  version_requirements: *id006
106
99
  - !ruby/object:Gem::Dependency
107
- name: maca-fork-csspool
100
+ name: css_parser
108
101
  prerelease: false
109
102
  requirement: &id007 !ruby/object:Gem::Requirement
110
103
  none: false
111
104
  requirements:
112
105
  - - ">="
113
106
  - !ruby/object:Gem::Version
114
- hash: 3
115
107
  segments:
116
108
  - 0
117
109
  version: "0"
118
110
  type: :runtime
119
111
  version_requirements: *id007
112
+ - !ruby/object:Gem::Dependency
113
+ name: maca-fork-csspool
114
+ prerelease: false
115
+ requirement: &id008 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ type: :runtime
124
+ version_requirements: *id008
120
125
  description: Inlines CSS for html email delivery
121
126
  email:
122
127
  - macarui@gmail.com
@@ -140,12 +145,12 @@ files:
140
145
  - lib/inline-style.rb
141
146
  - lib/inline-style/css_parser_wrapper.rb
142
147
  - lib/inline-style/csspool_wrapper.rb
143
- - lib/inline-style/mail/interceptor.rb
144
- - lib/inline-style/rack/middleware.rb
145
- - lib/inline-style/selector.rb
148
+ - lib/inline-style/mail-interceptor.rb
149
+ - lib/inline-style/rack-middleware.rb
150
+ - lib/inline-style/rule.rb
146
151
  - lib/inline-style/version.rb
147
152
  - spec/css_inlining_spec.rb
148
- - spec/css_parsers_spec.rb
153
+ - spec/css_parsing_spec.rb
149
154
  - spec/fixtures/all.css
150
155
  - spec/fixtures/boletin.html
151
156
  - spec/fixtures/box-model.html
@@ -171,7 +176,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
171
176
  requirements:
172
177
  - - ">="
173
178
  - !ruby/object:Gem::Version
174
- hash: 3
175
179
  segments:
176
180
  - 0
177
181
  version: "0"
@@ -180,14 +184,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
184
  requirements:
181
185
  - - ">="
182
186
  - !ruby/object:Gem::Version
183
- hash: 3
184
187
  segments:
185
188
  - 0
186
189
  version: "0"
187
190
  requirements: []
188
191
 
189
192
  rubyforge_project:
190
- rubygems_version: 1.6.2
193
+ rubygems_version: 1.3.7
191
194
  signing_key:
192
195
  specification_version: 3
193
196
  summary: Inlines CSS for html email delivery
@@ -1,41 +0,0 @@
1
-
2
-
3
- # A simple abstraction of the data we get back from the parsers. CSSPool
4
- # actually already does this for us but CSSParser does not so we need
5
- # to create the abstraction ourselves.
6
- class InlineStyle
7
- class Selector < Struct.new :selector_text, :declarations, :specificity
8
- # A slightly adjusted version of the selector_text that should be
9
- # used for finding nodes. Will remove the pseudo selector and prepend
10
- # 'body '.
11
- def search
12
- selector_text.dup.tap do |s|
13
- state_based_pseudo_selectors.each {|p| s.gsub! /:#{p}$/, ''}
14
- s.insert(0, 'body ') unless s =~ /^body/
15
- end
16
- end
17
-
18
- # For the most part is just declarations unless a pseudo selector.
19
- # Then it uses the inline pseudo declarations
20
- def inline_declarations
21
- if pseudo?
22
- "\n#{ selector_text.gsub /\w(?=:)/, '' } {#{ declarations }}"
23
- else
24
- declarations
25
- end
26
- end
27
-
28
- # Is this selector using a pseudo class?
29
- def pseudo?
30
- state_based_pseudo_selectors.any? {|p| selector_text.end_with? ":#{p}"}
31
- end
32
-
33
- # A list of state based pseudo selectors (like hover) that should
34
- # be handled based on the pseudo option. Unlike position-based
35
- # pseudo selectors (like :first-child) which once resolved to the
36
- # correct node effectively get inlined like a normal selector.
37
- def state_based_pseudo_selectors
38
- %w(link visited active hover focus target enabled disabled checked)
39
- end
40
- end
41
- end
@@ -1,53 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe InlineStyle::CssParserWrapper do
4
-
5
- it 'should wrap css_parser' do
6
- rs_count = 0
7
- sel_count = 0
8
- selectors = %w(p b i)
9
- decs = ['color: black;', 'color: black;', 'color: green; text-decoration: none;']
10
- spes = [1, 1, 1]
11
- p = InlineStyle::CssParserWrapper.new "p, b {color: black}\ni {color: green; text-decoration: none}"
12
-
13
- p.each_rule_set do |rs|
14
- rs_count += 1
15
- rs.each_selector do |sel|
16
- sel_count += 1
17
- sel.selector_text.should == selectors.shift
18
- sel.declarations.should == decs.shift
19
- sel.specificity.should == spes.shift
20
- end
21
- end
22
-
23
- rs_count.should == 2
24
- sel_count.should == 3
25
- end
26
-
27
- end
28
-
29
- describe InlineStyle::CSSPoolWrapper do
30
-
31
- it 'should wrap csspool' do
32
- rs_count = 0
33
- sel_count = 0
34
- selectors = %w(p b i)
35
- decs = ['color: black;', 'color: black;', 'color: green; text-decoration: none;']
36
- spes = [1, 1, 1]
37
- p = InlineStyle::CSSPoolWrapper.new "p, b {color: black}\ni {color: green; text-decoration: none}"
38
-
39
- p.each_rule_set do |rs|
40
- rs_count += 1
41
- rs.each_selector do |sel|
42
- sel_count += 1
43
- sel.selector_text.should == selectors.shift
44
- sel.declarations.should == decs.shift
45
- sel.specificity.should == spes.shift
46
- end
47
- end
48
-
49
- rs_count.should == 2
50
- sel_count.should == 3
51
- end
52
-
53
- end