Class: Kitchen::Document

Inherits:
Object show all
Extended by:
Forwardable
Defined in:
lib/kitchen/document.rb

Overview

Wrapper around a Nokogiri Document, adding search with Kitchen enumerators, clipboards, pantries, etc.

Direct Known Subclasses

BookDocument

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(nokogiri_document:, config: nil) ⇒ Document

Return a new instance of Document



48
49
50
51
52
53
54
55
56
# File 'lib/kitchen/document.rb', line 48

def initialize(nokogiri_document:, config: nil)
  @nokogiri_document = nokogiri_document
  @location = nil
  @config = config || Config.new
  @id_tracker = IdTracker.new

  # Nokogiri by default only recognizes the namespaces on the root node.  Add all others.
  raw&.add_all_namespaces! if @config.enable_all_namespaces
end

Instance Attribute Details

#config ⇒ Config (readonly)



15
16
17
# File 'lib/kitchen/document.rb', line 15

def config
  @config
end

#id_tracker ⇒ IdTracker (readonly)



17
18
19
# File 'lib/kitchen/document.rb', line 17

def id_tracker
  @id_tracker
end

#location ⇒ Element



13
14
15
# File 'lib/kitchen/document.rb', line 13

def location
  @location
end

Instance Method Details

#clipboard(name: :default) ⇒ Clipboard

Returns the document's clipboard with the given name.



87
88
89
# File 'lib/kitchen/document.rb', line 87

def clipboard(name: :default)
  (@clipboards ||= {})[name.to_sym] ||= Clipboard.new
end

#counter(name) ⇒ Counter

Returns the document's counter with the given name.



107
108
109
# File 'lib/kitchen/document.rb', line 107

def counter(name)
  (@counters ||= {})[name.to_sym] ||= Counter.new
end

#create_element(name, *args, &block) ⇒ Element

Create a new Element

TODO don't know if we need this

Examples:

div with a class

create_element("div", class: "foo") #=> <div class="foo"></div>

div with some content and a class

cretae_element("div", "contents", class: "foo") #=> <div class="foo">contents</div>

div created by block

create_element("div") {|elem| elem['class'] = 'foo'} #=> <div class="foo"></div>


127
128
129
130
131
132
133
# File 'lib/kitchen/document.rb', line 127

def create_element(name, *args, &block)
  Kitchen::Element.new(
    node: @nokogiri_document.create_element(name, *args, &block),
    document: self,
    short_type: "created_element_#{SecureRandom.hex(4)}"
  )
end

#create_element_from_string(string) ⇒ Element

Create a new Element from a string

Examples:

create_element_from_string("<div class='foo'>bar</div>") #=> <div class="foo">bar</div>


144
145
146
147
148
149
150
151
152
153
# File 'lib/kitchen/document.rb', line 144

def create_element_from_string(string)
  children = Nokogiri::XML("<foo>#{string}</foo>").search('foo').first.element_children
  raise('new_element must only make one top-level element') if children.many?

  node = children.first

  create_element(node.name, node.attributes).tap do |element|
    element.inner_html = node.children
  end
end

#encoding ⇒ String

Returns the document as an HTML string.



42
# File 'lib/kitchen/document.rb', line 42

def_delegators :@nokogiri_document, :to_xhtml, :to_s, :to_xml, :to_html, :encoding

#locale ⇒ Symbol

Returns the locale for this document, default to :en if no locale detected



167
168
169
170
171
172
# File 'lib/kitchen/document.rb', line 167

def locale
  raw.root['lang']&.to_sym || begin
    warn 'No `lang` attribute on this document so cannot detect its locale; defaulting to `:en`'
    :en
  end
end

#pantry(name: :default) ⇒ Pantry

Returns the document's pantry with the given name.



97
98
99
# File 'lib/kitchen/document.rb', line 97

def pantry(name: :default)
  (@pantries ||= {})[name.to_sym] ||= Pantry.new
end

#raw ⇒ Nokogiri::XML::Document

Returns the underlying Nokogiri Document object



159
160
161
# File 'lib/kitchen/document.rb', line 159

def raw
  @nokogiri_document
end

#search(*selector_or_xpath_args) ⇒ ElementEnumerator

Returns an enumerator that iterates over all children of this document that match the provided selector or XPath arguments. Updates location during iteration.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/kitchen/document.rb', line 65

def search(*selector_or_xpath_args)
  selector_or_xpath_args = [selector_or_xpath_args].flatten

  ElementEnumerator.new do |block|
    nokogiri_document.search(*selector_or_xpath_args).each do |inner_node|
      element = Kitchen::Element.new(
        node: inner_node,
        document: self,
        short_type: Utils.search_path_to_type(selector_or_xpath_args)
      )
      self.location = element
      block.yield(element)
    end
  end
end

#selectors ⇒ Selectors::Base

The document's selectors

See Also:



23
# File 'lib/kitchen/document.rb', line 23

def_delegators :config, :selectors

#to_html ⇒ String

Returns the document as an HTML string.



42
# File 'lib/kitchen/document.rb', line 42

def_delegators :@nokogiri_document, :to_xhtml, :to_s, :to_xml, :to_html, :encoding

#to_s ⇒ String

Turn this node in to a string. If the document is HTML, this method returns html. If the document is XML, this method returns XML.



42
# File 'lib/kitchen/document.rb', line 42

def_delegators :@nokogiri_document, :to_xhtml, :to_s, :to_xml, :to_html, :encoding

#to_xhtml ⇒ String

Returns the document as an XHTML string.



42
# File 'lib/kitchen/document.rb', line 42

def_delegators :@nokogiri_document, :to_xhtml, :to_s, :to_xml, :to_html, :encoding

#to_xml ⇒ String

Returns the document as an XML string.



42
# File 'lib/kitchen/document.rb', line 42

def_delegators :@nokogiri_document, :to_xhtml, :to_s, :to_xml, :to_html, :encoding