# frozen_string_literal: true module ProxyFetcher class Document # Abstract class for storing HTML elements that was parsed by # one of the ProxyFetcher::Document adapters class. class Node # @!attribute [r] node # @return [Object] original DOM node, parsed by adapter backend attr_reader :node # Initialize new HTML node # # @return [Node] # def initialize(node) @node = node end # Searches for node in children using some selector (CSS or XPath). # # @param selector [String] selector (CSS or XPath) # # @return [Node] child node # def find(selector, method = :at_xpath) self.class.new(node.public_send(method, selector)) end # Searches exact HTML element by XPath. Returns only one element. # # @return [ProxyFetcher::Document::Node] # node # def at_xpath(*args) self.class.new(node.at_xpath(*args)) end # Searches exact HTML element by CSS. Returns only one element. # # @return [ProxyFetcher::Document::Node] # node # def at_css(*args) self.class.new(node.at_css(*args)) end # Returns clean content (text) for the specific element. # # @return [String] # HTML node content # def content_at(*args) clear(find(*args).content) end # Returns HTML node content. # # Abstract method, must be implemented for specific adapter class. # def content raise "`#{__method__}` must be implemented for specific adapter class!" end # Returns HTML node inner HTML. # # Abstract method, must be implemented for specific adapter class. # def html raise "`#{__method__}` must be implemented for specific adapter class!" end protected # Removes whitespaces, tabulation and other "garbage" for the text. # # @param text [String] # text to clear # # @return [String] # clean text # def clear(text) return if text.nil? || text.empty? text.strip.gsub(/[ \t]/i, '') end end end end