Module: Html2rss::Html::Probe

Defined in:
lib/html2rss/html/probe.rb

Overview

Case-insensitive DOM wire matching for MIME types, tag names, and link relations.

Constant Summary collapse

APPLICATION_LD_JSON =

Canonical MIME type strings for script and alternate link matching.

'application/ld+json'
APPLICATION_JSON =

See Also:

  • #mime_match?
'application/json'
APPLICATION_JSON_OEMBED =

See Also:

  • #mime_match?
'application/json+oembed'
APPLICATION_RSS_XML =

See Also:

  • #mime_match?
'application/rss+xml'
APPLICATION_ATOM_XML =

See Also:

  • #mime_match?
'application/atom+xml'

Class Method Summary collapse

Class Method Details

Parameters:

  • doc (Nokogiri::XML::Node)
  • rel (String)

    link rel token

  • mime (String, nil) (defaults to: nil)

    optional MIME filter

Returns:

  • (Array<Nokogiri::XML::Element>)


74
75
76
77
78
79
# File 'lib/html2rss/html/probe.rb', line 74

def alternate_links(doc, rel:, mime: nil)
  nodes = doc.css(%(link[rel~="#{rel}"][href]))
  return nodes if mime.nil?

  nodes.select { |node| mime_match?(node['type'], mime) }
end

.fold(string) ⇒ String

Returns folded comparison key.

Parameters:

  • string (String, Symbol, #to_s)

    wire value

Returns:

  • (String)

    folded comparison key



24
25
26
# File 'lib/html2rss/html/probe.rb', line 24

def fold(string)
  string.to_s.downcase
end

.mime_base(type) ⇒ String

Returns media type without parameters, folded.

Parameters:

  • type (String, Symbol, #to_s, nil)

    MIME type attribute value

Returns:

  • (String)

    media type without parameters, folded



42
43
44
45
46
47
# File 'lib/html2rss/html/probe.rb', line 42

def mime_base(type)
  raw = type.to_s
  return fold(raw) unless raw.include?(';') || raw.match?(/\A\s|\s\z/)

  fold(raw.split(';', 2).first.to_s.strip)
end

.mime_match?(actual, *expected) ⇒ Boolean

Parameters:

  • actual (String, Symbol, #to_s, nil)

    observed MIME type

  • expected (Array<String>)

    canonical MIME types to match

Returns:

  • (Boolean)


53
54
55
56
# File 'lib/html2rss/html/probe.rb', line 53

def mime_match?(actual, *expected)
  base = mime_base(actual)
  expected.any? { |candidate| base == candidate || base == mime_base(candidate) }
end

.scripts(doc, *mime_types) ⇒ Array<Nokogiri::XML::Element>

Parameters:

  • doc (Nokogiri::XML::Node)
  • mime_types (Array<String>)

    optional MIME filters (folded once per call)

Returns:

  • (Array<Nokogiri::XML::Element>)


62
63
64
65
66
67
# File 'lib/html2rss/html/probe.rb', line 62

def scripts(doc, *mime_types)
  return doc.css('script') if mime_types.empty?

  allowed = mime_types.to_set { |mime| mime_base(mime) }
  doc.css('script').select { |script| allowed.include?(mime_base(script['type'])) }
end

.tag(node) ⇒ String

Returns folded element name.

Parameters:

  • node (Nokogiri::XML::Node)

Returns:

  • (String)

    folded element name



31
32
33
34
35
36
37
# File 'lib/html2rss/html/probe.rb', line 31

def tag(node)
  name = node.name
  return fold(name) unless name.is_a?(String)
  return name if name.ascii_only? && !name.match?(/[A-Z]/)

  fold(name)
end