Class: InlineStyle

Inherits:
Object
  • Object
show all
Defined in:
lib/inline-style/selector.rb,
lib/inline-style.rb,
lib/inline-style/version.rb,
lib/inline-style/csspool_wrapper.rb,
lib/inline-style/css_parser_wrapper.rb

Overview

A simple abstraction of the data we get back from the parsers. CSSPool actually already does this for us but CSSParser does not so we need to create the abstraction ourselves.

Defined Under Namespace

Modules: Mail, Rack Classes: CSSPoolWrapper, CssParserWrapper, Selector

Constant Summary collapse

CSSParser =
if const_defined? :CSSPool
  require 'inline-style/csspool_wrapper'
  CSSPoolWrapper
else
  require 'inline-style/css_parser_wrapper'
  CssParserWrapper
end
VERSION =
'0.4.10'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(html, opts = {}) ⇒ InlineStyle

Returns a new instance of InlineStyle.



33
34
35
36
37
# File 'lib/inline-style.rb', line 33

def initialize html, opts = {}
  @html             = html
  @stylesheets_path = opts[:stylesheets_path] || ''
  @pseudo           = opts[:pseudo]
end

Class Method Details

.process(html, opts = {}) ⇒ Object

Parameters:

  • html (String, Nokogiri::HTML::Document)

    Html or Nokogiri html to be inlined

  • opts (Hash) (defaults to: {})

    Processing options

Options Hash (opts):

  • :stylesheets_path (String) — default: env['DOCUMENT_ROOT']

    Stylesheets root path or app’s public directory where the stylesheets are to be found

  • :pseudo (boolean) — default: false

    If set to true will inline style for pseudo classes according to the W3C specification: www.w3.org/TR/css-style-attr. 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
30
31
# File 'lib/inline-style.rb', line 29

def self.process html, opts = {}
  new(html, opts).process
end

Instance Method Details

#processObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/inline-style.rb', line 39

def process
  nodes = {}

  css.each_rule_set do |rule_set|
    rule_set.each_selector do |selector|
      dom.css(selector.search).each do |node|
        nodes[node] ||= []
        nodes[node].push selector
        
        next unless node['style']
        
        path = node.css_path
        path << "##{ node['id'] }" if node['id']
        path << ".#{ node['class'].scan(/\S+/).join('.') }" if node['class']

        CSSParser.new("#{path}{#{node['style']}}").each_rule_set do |rule|
          rule.each_selector do |selector_inner|
            nodes[node].push selector_inner
          end
        end
      end
    end
  end

  nodes.each_pair do |node, selectors|
    selectors = selectors.sort_by{ |sel| "#{ sel.specificity }%03d" % selectors.index(sel) }
    selectors = selectors.reject {|sel| !@pseudo && sel.pseudo? }
    using_pseudo = selectors.any? &:pseudo?
    
    node['style'] = selectors.collect do |selector|
      if using_pseudo && !selector.pseudo?
        "{#{selector.inline_declarations}}"
      else
        selector.inline_declarations
      end
    end.join(' ').strip
  end
  
  html_already_parsed? ? @dom : @dom.to_s
end