Class: RichUrls::XMLHandler

Inherits:
Ox::Sax
  • Object
show all
Defined in:
lib/xml_handler.rb

Constant Summary collapse

WHITELISTED_EL_NAMES =
%i[
  title
  meta
  link
  img
  p
].freeze
WHITELISTED_ATTRS =
%i[
  property
  content
  rel
  href
  src
].freeze
FALLBACK_ELEMENTS =
{
  img: 'og:image',
  p: 'og:description',
  title: 'og:title'
}.freeze
FINDERS =
{
  Finders::MetaTitle => 'title',
  Finders::MetaDescription => 'description',
  Finders::MetaImage => 'image',
  Finders::Favicon => 'favicon',
  Finders::Title => 'title',
  Finders::Description => 'description',
  Finders::Image => 'image'
}.freeze
StopParsingError =
Class.new(StandardError)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filter = []) ⇒ XMLHandler

Returns a new instance of XMLHandler.



47
48
49
50
51
52
# File 'lib/xml_handler.rb', line 47

def initialize(filter = [])
  @filter = filter
  @elements = []
  @counts = Set.new
  @properties = filtered_properties(filter)
end

Instance Attribute Details

#elementsObject (readonly)

Returns the value of attribute elements.



45
46
47
# File 'lib/xml_handler.rb', line 45

def elements
  @elements
end

#propertiesObject (readonly)

Returns the value of attribute properties.



45
46
47
# File 'lib/xml_handler.rb', line 45

def properties
  @properties
end

Instance Method Details

#attr(key, value) ⇒ Object



80
81
82
83
84
85
# File 'lib/xml_handler.rb', line 80

def attr(key, value)
  return unless WHITELISTED_ATTRS.include?(key)

  el = @elements.last
  el&.add(key, value)
end

#end_element(tag) ⇒ Object

Raises:



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/xml_handler.rb', line 68

def end_element(tag)
  return unless WHITELISTED_EL_NAMES.include?(tag)

  el = @elements.reverse_each.detect { |e| e.open && e.tag == tag }
  return unless el

  el.close!
  find_element(el)

  raise StopParsingError if @properties.values.all?
end

#find(tag, attrs = {}) ⇒ Object



54
55
56
57
58
59
60
# File 'lib/xml_handler.rb', line 54

def find(tag, attrs = {})
  @elements.detect do |el|
    matching_attributes = attrs.all? { |k, v| el.attributes[k] == v }

    el.tag == tag && matching_attributes
  end
end

#start_element(tag) ⇒ Object



62
63
64
65
66
# File 'lib/xml_handler.rb', line 62

def start_element(tag)
  return unless WHITELISTED_EL_NAMES.include?(tag)

  @elements << El.new(tag) if add_element?(tag)
end

#text(str) ⇒ Object



87
88
89
90
# File 'lib/xml_handler.rb', line 87

def text(str)
  el = @elements.detect(&:open)
  el&.append_text(str)
end