class StyleInliner::Document

Constants

UNMERGEABLE_PSEUDO_CLASS_NAMES

Public Class Methods

new(html, replace_properties_to_attributes: true) click to toggle source

@param html [String] @param replace_properties_to_attributes [false, true]

# File lib/style_inliner/document.rb, line 23
def initialize(html, replace_properties_to_attributes: true)
  @html = html
  @replace_properties_to_attributes = replace_properties_to_attributes
end

Public Instance Methods

inline() click to toggle source

@return [Nokogiri::XML::Node]

# File lib/style_inliner/document.rb, line 29
def inline
  load_styles_from_html
  merge_styles_into_each_element
  fold_style_attributes
  append_style_element_for_unmergeable_rule_sets
  root
end

Private Instance Methods

add_unmergeable_rule_set(selector, declarations, media_types) click to toggle source

@param selector [Stirng] @param declarations [String] @param media_types [Array<Symbol>]

# File lib/style_inliner/document.rb, line 42
def add_unmergeable_rule_set(selector, declarations, media_types)
  css_parser_for_unmergeable_rules.add_rule_set!(
    ::CssParser::RuleSet.new(selector, declarations),
    media_types,
  )
end
append_style_element_for_unmergeable_rule_sets() click to toggle source
# File lib/style_inliner/document.rb, line 49
def append_style_element_for_unmergeable_rule_sets
  rule_set_string = css_parser_for_unmergeable_rules.to_s
  unless rule_set_string.empty?
    if (body_node = root.at("body"))
      body_node.prepend_child(
        ::Nokogiri::XML.fragment("<style>\n#{rule_set_string}</style>")
      )
    end
  end
end
check_node_stylability(node) click to toggle source

@param node [Nokogiri::XML::Node] @return [false, true]

# File lib/style_inliner/document.rb, line 62
def check_node_stylability(node)
  node.element? && node.name != "head" && node.parent.name != "head"
end
check_selector_mergeability(selector) click to toggle source

@param selector [String] @return [false, true]

# File lib/style_inliner/document.rb, line 68
def check_selector_mergeability(selector)
  !selector.start_with?("@") && !UNMERGEABLE_PSEUDO_CLASS_NAMES.any? { |name| selector.include?(":#{name}") }
end
css_parser_for_mergeable_rules() click to toggle source

@return [CssParser::Parser]

# File lib/style_inliner/document.rb, line 73
def css_parser_for_mergeable_rules
  @css_parser_for_mergeable_rules ||= ::CssParser::Parser.new
end
css_parser_for_unmergeable_rules() click to toggle source

@return [CssParser::Parser]

# File lib/style_inliner/document.rb, line 78
def css_parser_for_unmergeable_rules
  @css_parser_for_unmergeable_rules ||= ::CssParser::Parser.new
end
fold_style_attributes() click to toggle source
# File lib/style_inliner/document.rb, line 82
def fold_style_attributes
  root.search("*[@style]").each do |node|
    NodeStyleFolding.new(node, replace_properties_to_attributes: @replace_properties_to_attributes).call
  end
end
load_styles_from_html() click to toggle source

Load styles from <style> and <link> elements from a given HTML document.

# File lib/style_inliner/document.rb, line 89
def load_styles_from_html
  load_styles_from_link_elements
  load_styles_from_style_elements
end
load_styles_from_style_elements() click to toggle source
# File lib/style_inliner/document.rb, line 98
def load_styles_from_style_elements
  root.search("style").each do |style_node|
    css_parser_for_mergeable_rules.add_block!(style_node.inner_html)
    style_node.remove
  end
end
merge_styles_into_each_element() click to toggle source
# File lib/style_inliner/document.rb, line 105
def merge_styles_into_each_element
  css_parser_for_mergeable_rules.each_selector(:all) do |selector, declarations, specificity, media_types|
    if check_selector_mergeability(selector)
      root.search(strip_link_pseudo_class(selector)).each do |node|
        if check_node_stylability(node)
          push_encoded_rule_set_into_style_attribute(node, declarations, specificity)
        end
      end
    else
      add_unmergeable_rule_set(selector, declarations, media_types)
    end
  end
end
push_encoded_rule_set_into_style_attribute(node, declarations, specificity) click to toggle source

@param node [Nokogiri::XML::Node] @param declarations [String] @param specificity [Integer]

# File lib/style_inliner/document.rb, line 122
def push_encoded_rule_set_into_style_attribute(node, declarations, specificity)
  rule_set = RuleSet.new(declarations: declarations, specificity: specificity)
  node["style"] = "#{node['style']} #{rule_set.encode}"
end
root() click to toggle source

@return [Nokogiri::XML::Node]

# File lib/style_inliner/document.rb, line 128
def root
  @root ||= ::Nokogiri.HTML(@html)
end