Class: Kitchen::ElementBase
Overview
Abstract base class for all elements. If you are looking for a simple concrete element class, use ‘Element`.
Direct Known Subclasses
BookElement, ChapterElement, CompositeChapterElement, CompositePageElement, Element, ExampleElement, ExerciseElement, FigureElement, InjectedExerciseElement, InjectedQuestionElement, MetadataElement, NoteElement, PageElement, ReferenceElement, SectionElement, TableElement, TermElement, UnitElement
Instance Attribute Summary collapse
-
#ancestors ⇒ Array<Ancestor>
readonly
Returns the element’s ancestors.
-
#document(: clipboard) ⇒ Clipboard
readonly
Access the clipboard for this element’s document.
-
#enumerator_class ⇒ Class
readonly
The enumerator class for this element.
-
#search_query_that_found_me ⇒ SearchQuery
The search query that located this element in the DOM.
-
#short_type ⇒ Symbol, String
readonly
The element’s type, e.g.
Class Method Summary collapse
-
.descendant(type) ⇒ Class
Returns ElementBase descendent type or nil if none found.
-
.descendant!(type) ⇒ Class
Returns ElementBase descendent type or Error if none found.
-
.is_the_element_class_for?(node, config:) ⇒ Boolean
Returns true if this class represents the element for the given node.
Instance Method Summary collapse
-
#[] ⇒ String
Get an element attribute.
-
#[]= ⇒ Object
Set an element attribute.
-
#add_ancestor(ancestor) ⇒ Object
Adds one ancestor, incrementing its descendant counts for this element type.
-
#add_ancestors(*args) ⇒ Object
Adds ancestors to this element, for each incrementing descendant counts for this type.
-
#add_class ⇒ Object
Add a class to the element.
-
#ancestor(type) ⇒ Ancestor
Returns this element’s ancestor of the given type.
-
#ancestor_elements ⇒ Array<ElementBase>
Return the elements in all of the ancestors.
-
#append(child: nil, sibling: nil) ⇒ Object
If child argument given, appends it after the element’s current children.
-
#as_enumerator ⇒ ElementEnumeratorBase
Returns this element as an enumerator (over only one element, itself).
-
#children ⇒ Nokogiri::XML::NodeSet
Get the element’s children.
-
#classes ⇒ Array<String>
Gets the element’s classes.
-
#clone ⇒ Object
Returns a clone of this object.
-
#config ⇒ Config
Get the config for this element’s document.
-
#contains?(*selector_or_xpath_args) ⇒ Boolean
Returns true if this element has a child matching the provided selector.
-
#content(*selector_or_xpath_args) ⇒ String
Get the content of children matching the provided selector.
-
#copied_id ⇒ Object
Copy the element’s id.
-
#copy(to: nil) ⇒ Element
Makes a copy of the element and places it on the specified clipboard.
-
#count_in(ancestor_type) ⇒ Object
Returns the count of this element’s type in the given ancestor type.
-
#cut(to: nil) ⇒ Element
Removes the element from its parent and places it on the specified clipboard.
-
#data_type ⇒ String
Returns the element’s data-type.
-
#element_children ⇒ TypeCastingElementEnumerator
Returns an enumerator over the direct child elements of this element, with the specific type (e.g.
TermElement
) if such type is available. -
#first(*selector_or_xpath_args, reload: false) {|the| ... } ⇒ Element?
(also: #at)
Yields and returns the first child element that matches the provided selector or XPath arguments.
-
#first!(*selector_or_xpath_args, reload: false) {|the| ... } ⇒ Element
Yields and returns the first child element that matches the provided selector or XPath arguments.
-
#has_ancestor?(type) ⇒ Boolean
Returns true iff this element has an ancestor of the given type.
-
#has_class?(klass) ⇒ Boolean
Returns true if this element has the given class.
-
#href ⇒ String
Returns the element’s href.
-
#href=(value) ⇒ Object
Sets the element’s href.
-
#id ⇒ String
Returns the element’s ID.
-
#id=(value) ⇒ Object
Sets the element’s ID.
-
#initialize(node:, document:, enumerator_class:, short_type: nil) ⇒ ElementBase
constructor
Creates a new instance.
-
#inner_html= ⇒ Object
Set the inner HTML for this element.
-
#inspect ⇒ String
Returns a string version of this element.
-
#is?(type) ⇒ Boolean
Returns true if this element is the given type.
-
#key?(attribute) ⇒ Object
Returns true if attribute is set.
-
#mark_as_current_location! ⇒ Object
Mark the location so that if there’s an error we can show the developer where.
-
#name ⇒ String
Get the element name (the tag).
-
#name= ⇒ Object
Set the element name (the tag).
-
#pages ⇒ Object
Returns a pages enumerator.
-
#pantry ⇒ Pantry
Access the pantry for this element’s document.
- #parent ⇒ Object
-
#paste ⇒ Object
When an element is cut or copied, use this method to get the element’s content; keeps IDs unique.
-
#path ⇒ String
Get the path for this element.
-
#preceded_by_text ⇒ Object
Returns true if the immediately preceding sibling is text.
-
#prepend(child: nil, sibling: nil) ⇒ Object
If child argument given, prepends it before the element’s current children.
-
#previous ⇒ Object
returns previous element sibling (only returns elements or nil) nil if there’s no previous sibling.
-
#raw ⇒ Nokogiri::XML::Node
Returns the underlying Nokogiri object.
- #raw_search(*selector_or_xpath_args, reload: false) ⇒ Object
-
#remember_that_a_sub_element_was_counted(search_query, type) ⇒ Object
Track that a sub element found by the given query has been counted.
-
#remove_attribute ⇒ Object
Removes an attribute from the element.
-
#remove_class ⇒ Object
Remove a class from the element.
-
#replace_children(with:) ⇒ Object
Replaces this element’s children.
-
#search(*selector_or_xpath_args, only: nil, except: nil, reload: false) ⇒ ElementEnumerator
Returns an ElementEnumerator that iterates over the provided selector or xpath queries.
-
#search_history ⇒ SearchHistory
Returns the search history that found this element.
-
#selectors ⇒ Selectors::Base
Get the selectors for this element’s document.
-
#set(property, value) ⇒ Object
A way to set values and chain them.
-
#sub_header_name ⇒ String
Returns the header tag name that is one level under the first header tag in this element, e.g.
-
#target_label(label_text: nil, custom_content: nil, cases: false) ⇒ Pantry
Creates labels for links to inside elements like Figures, Tables, Equations, Exercises, Notes.
-
#text ⇒ String
Get the element text.
-
#to_html ⇒ String
Get the element as HTML.
-
#to_s ⇒ String
Returns a string version of this element.
-
#to_xhtml ⇒ String
Returns a string version of this element as XHTML.
-
#to_xml ⇒ String
Returns a string version of this element as XML.
-
#trash ⇒ Object
Delete the element.
-
#uncount(search_query) ⇒ Object
Undo the counts from a prior search query (so that they can be counted again).
-
#wrap ⇒ Nokogiri::XML::Node
Add HTML around this element.
-
#wrap_children(name = 'div', attributes = {}) {|the| ... } ⇒ Element
Wraps the element’s children in a new element.
Methods included from Mixins::BlockErrorIf
Constructor Details
#initialize(node:, document:, enumerator_class:, short_type: nil) ⇒ ElementBase
Creates a new instance
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/kitchen/element_base.rb', line 120 def initialize(node:, document:, enumerator_class:, short_type: nil) raise(ArgumentError, 'node cannot be nil') if node.nil? @node = node raise(ArgumentError, 'enumerator_class cannot be nil') if enumerator_class.nil? @enumerator_class = enumerator_class @short_type = short_type || self.class.try(:short_type) || "unknown_type_#{SecureRandom.hex(4)}" @document = case document when Kitchen::Document document else raise(ArgumentError, '`document` is not a known document type') end @ancestors = HashWithIndifferentAccess.new @search_query_matches_that_have_been_counted = {} @is_a_clone = false @search_cache = {} end |
Instance Attribute Details
#ancestors ⇒ Array<Ancestor> (readonly)
Returns the element’s ancestors
283 284 285 |
# File 'lib/kitchen/element_base.rb', line 283 def ancestors @ancestors end |
#document(: clipboard) ⇒ Clipboard (readonly)
Access the clipboard for this element’s document
17 18 19 |
# File 'lib/kitchen/element_base.rb', line 17 def document @document end |
#enumerator_class ⇒ Class (readonly)
The enumerator class for this element
25 26 27 |
# File 'lib/kitchen/element_base.rb', line 25 def enumerator_class @enumerator_class end |
#search_query_that_found_me ⇒ SearchQuery
The search query that located this element in the DOM
29 30 31 |
# File 'lib/kitchen/element_base.rb', line 29 def search_query_that_found_me @search_query_that_found_me end |
#short_type ⇒ Symbol, String (readonly)
The element’s type, e.g. :page
21 22 23 |
# File 'lib/kitchen/element_base.rb', line 21 def short_type @short_type end |
Class Method Details
.descendant(type) ⇒ Class
Returns ElementBase descendent type or nil if none found
152 153 154 155 156 157 158 159 160 161 |
# File 'lib/kitchen/element_base.rb', line 152 def self.descendant(type) @types_to_descendants ||= descendants.each_with_object({}) do |descendant, hash| next unless descendant.try(:short_type) hash[descendant.short_type] = descendant end @types_to_descendants[type] end |
.descendant!(type) ⇒ Class
Returns ElementBase descendent type or Error if none found
169 170 171 |
# File 'lib/kitchen/element_base.rb', line 169 def self.descendant!(type) descendant(type) || raise("Unknown ElementBase descendant type '#{type}'") end |
Instance Method Details
#[] ⇒ String
Get an element attribute
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#[]= ⇒ Object
Set an element attribute
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#add_ancestor(ancestor) ⇒ Object
Adds one ancestor, incrementing its descendant counts for this element type
311 312 313 314 315 316 317 318 319 |
# File 'lib/kitchen/element_base.rb', line 311 def add_ancestor(ancestor) if @ancestors[ancestor.type].present? raise "Trying to add an ancestor of type '#{ancestor.type}' but one of that " \ "type is already present" end ancestor.increment_descendant_count(short_type) @ancestors[ancestor.type] = ancestor end |
#add_ancestors(*args) ⇒ Object
Adds ancestors to this element, for each incrementing descendant counts for this type
291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/kitchen/element_base.rb', line 291 def add_ancestors(*args) args.each do |arg| case arg when Hash add_ancestors(*arg.values) when Ancestor add_ancestor(arg) when Element, Document add_ancestor(Ancestor.new(arg)) else raise "Unsupported ancestor type `#{arg.class}`" end end end |
#add_class ⇒ Object
Add a class to the element
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#ancestor(type) ⇒ Ancestor
Returns this element’s ancestor of the given type
266 267 268 |
# File 'lib/kitchen/element_base.rb', line 266 def ancestor(type) @ancestors[type.to_sym]&.element || raise("No ancestor of type '#{type}'") end |
#ancestor_elements ⇒ Array<ElementBase>
Return the elements in all of the ancestors
325 326 327 |
# File 'lib/kitchen/element_base.rb', line 325 def ancestor_elements @ancestors.values.map(&:element) end |
#append(child: nil, sibling: nil) ⇒ Object
If child argument given, appends it after the element’s current children. If sibling is given, appends it as a sibling to this element.
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 |
# File 'lib/kitchen/element_base.rb', line 572 def append(child: nil, sibling: nil) require_one_of_child_or_sibling(child, sibling) if child if node.children.empty? node.children = child.to_s else node.add_child(child) end else node.next = sibling end self end |
#as_enumerator ⇒ ElementEnumeratorBase
Returns this element as an enumerator (over only one element, itself)
783 784 785 |
# File 'lib/kitchen/element_base.rb', line 783 def as_enumerator enumerator_class.new(search_query: search_query_that_found_me) { |block| block.yield(self) } end |
#children ⇒ Nokogiri::XML::NodeSet
Get the element’s children
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#classes ⇒ Array<String>
Gets the element’s classes
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#clone ⇒ Object
Returns a clone of this object
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 |
# File 'lib/kitchen/element_base.rb', line 713 def clone super.tap do |element| # When we call dup, the dup gets a bunch of default namespace stuff that # the original doesn't have. Why? Unclear, but hard to get rid of nicely. # So here we mark that the element is a clone and then all of the `to_s`-like # methods gsub out the default namespace gunk. Clones are mostly used for # clipboards and are accessed using `paste` methods, so modifying the `to_s` # behavior works for us. If we end up using `clone` in a way that doesn't # eventually get converted to string, we may have to investigate other # options. # # An alternative is to remove the `xmlns` attribute in the `html` tag before # the input file is parse into a Nokogiri document and then to add it back # in when the baked file is written out. # # Nokogiri::XML::Document.remove_namespaces! is not an option because that blows # away our MathML namespace. # # I may not fully understand why the extra default namespace stuff is happening # FWIW :-) # element.node = node.dup element.is_a_clone = true end end |
#config ⇒ Config
Get the config for this element’s document
96 |
# File 'lib/kitchen/element_base.rb', line 96 def_delegators :document, :config |
#contains?(*selector_or_xpath_args) ⇒ Boolean
Returns true if this element has a child matching the provided selector
643 644 645 |
# File 'lib/kitchen/element_base.rb', line 643 def contains?(*selector_or_xpath_args) !node.at(*selector_or_xpath_args).nil? end |
#content(*selector_or_xpath_args) ⇒ String
Get the content of children matching the provided selector. Mostly useful when there is one child with text you want to extract.
634 635 636 |
# File 'lib/kitchen/element_base.rb', line 634 def content(*selector_or_xpath_args) node.search(*selector_or_xpath_args).children.to_s end |
#copied_id ⇒ Object
Copy the element’s id
509 510 511 512 |
# File 'lib/kitchen/element_base.rb', line 509 def copied_id id_tracker.record_id_copied(id) id_tracker.modified_id_to_paste(id) end |
#copy(to: nil) ⇒ Element
Makes a copy of the element and places it on the specified clipboard.
477 478 479 480 481 482 483 484 485 486 487 488 489 |
# File 'lib/kitchen/element_base.rb', line 477 def copy(to: nil) # See `clone` method for a note about namespaces block_error_if(block_given?) the_copy = clone the_copy.raw.traverse do |node| next if node.text? || node.document? id_tracker.record_id_copied(node[:id]) end get_clipboard(to).add(the_copy) if to.present? the_copy end |
#count_in(ancestor_type) ⇒ Object
Returns the count of this element’s type in the given ancestor type
333 334 335 336 |
# File 'lib/kitchen/element_base.rb', line 333 def count_in(ancestor_type) @ancestors[ancestor_type]&.get_descendant_count(short_type) || raise("No ancestor of type '#{ancestor_type}'") end |
#cut(to: nil) ⇒ Element
Removes the element from its parent and places it on the specified clipboard
457 458 459 460 461 462 463 464 465 466 467 468 |
# File 'lib/kitchen/element_base.rb', line 457 def cut(to: nil) block_error_if(block_given?) raw.traverse do |node| next if node.text? || node.document? id_tracker.record_id_cut(node[:id]) end node.remove get_clipboard(to).add(self) if to.present? self end |
#data_type ⇒ String
Returns the element’s data-type
222 223 224 |
# File 'lib/kitchen/element_base.rb', line 222 def data_type self[:'data-type'] end |
#element_children ⇒ TypeCastingElementEnumerator
Returns an enumerator over the direct child elements of this element, with the specific type (e.g. TermElement
) if such type is available.
442 443 444 445 446 447 448 |
# File 'lib/kitchen/element_base.rb', line 442 def element_children block_error_if(block_given?) TypeCastingElementEnumerator.factory.build_within( self, search_query: SearchQuery.new(css_or_xpath: './*') ) end |
#first(*selector_or_xpath_args, reload: false) {|the| ... } ⇒ Element? Also known as: at
Yields and returns the first child element that matches the provided selector or XPath arguments.
412 413 414 415 416 |
# File 'lib/kitchen/element_base.rb', line 412 def first(*selector_or_xpath_args, reload: false) search(*selector_or_xpath_args, reload: reload).first.tap do |element| yield(element) if block_given? end end |
#first!(*selector_or_xpath_args, reload: false) {|the| ... } ⇒ Element
Yields and returns the first child element that matches the provided selector or XPath arguments.
427 428 429 430 431 |
# File 'lib/kitchen/element_base.rb', line 427 def first!(*selector_or_xpath_args, reload: false) search(*selector_or_xpath_args, reload: reload).first!.tap do |element| yield(element) if block_given? end end |
#has_ancestor?(type) ⇒ Boolean
Returns true iff this element has an ancestor of the given type
275 276 277 |
# File 'lib/kitchen/element_base.rb', line 275 def has_ancestor?(type) @ancestors[type.to_sym].present? end |
#has_class?(klass) ⇒ Boolean
Returns true if this element has the given class
198 199 200 |
# File 'lib/kitchen/element_base.rb', line 198 def has_class?(klass) (self[:class] || '').include?(klass) end |
#href ⇒ String
Returns the element’s href
230 231 232 |
# File 'lib/kitchen/element_base.rb', line 230 def href self[:href] end |
#href=(value) ⇒ Object
Sets the element’s href
238 239 240 |
# File 'lib/kitchen/element_base.rb', line 238 def href=(value) self[:href] = value end |
#id ⇒ String
Returns the element’s ID
206 207 208 |
# File 'lib/kitchen/element_base.rb', line 206 def id self[:id] end |
#id=(value) ⇒ Object
Sets the element’s ID
214 215 216 |
# File 'lib/kitchen/element_base.rb', line 214 def id=(value) self[:id] = value end |
#inner_html= ⇒ Object
Set the inner HTML for this element
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#inspect ⇒ String
Returns a string version of this element
683 684 685 |
# File 'lib/kitchen/element_base.rb', line 683 def inspect to_s end |
#is?(type) ⇒ Boolean
Returns true if this element is the given type
179 180 181 |
# File 'lib/kitchen/element_base.rb', line 179 def is?(type) ElementBase.descendant!(type).is_the_element_class_for?(raw, config: config) end |
#key?(attribute) ⇒ Object
Returns true if attribute is set
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#mark_as_current_location! ⇒ Object
Mark the location so that if there’s an error we can show the developer where.
667 668 669 |
# File 'lib/kitchen/element_base.rb', line 667 def mark_as_current_location! document.location = self end |
#name ⇒ String
Get the element name (the tag)
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#name= ⇒ Object
Set the element name (the tag)
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#pages ⇒ Object
Returns a pages enumerator
774 775 776 777 |
# File 'lib/kitchen/element_base.rb', line 774 def_delegators :as_enumerator, :pages, :chapters, :terms, :figures, :notes, :tables, :examples, :metadatas, :non_introduction_pages, :units, :titles, :exercises, :references, :composite_pages, :composite_chapters, :solutions, :injected_questions, :search_with, :sections, :injected_exercises |
#pantry ⇒ Pantry
Access the pantry for this element’s document
109 |
# File 'lib/kitchen/element_base.rb', line 109 def_delegators :document, :pantry, :clipboard |
#parent ⇒ Object
521 522 523 |
# File 'lib/kitchen/element_base.rb', line 521 def parent Element.new(node: raw.parent, document: document, short_type: "parent(#{short_type})") end |
#paste ⇒ Object
When an element is cut or copied, use this method to get the element’s content; keeps IDs unique
493 494 495 496 497 498 499 500 501 502 503 504 505 506 |
# File 'lib/kitchen/element_base.rb', line 493 def paste # See `clone` method for a note about namespaces block_error_if(block_given?) temp_copy = clone temp_copy.raw.traverse do |node| next if node.text? || node.document? if node[:id].present? id_tracker.record_id_pasted(node[:id]) node[:id] = id_tracker.modified_id_to_paste(node[:id]) end end temp_copy.to_s end |
#path ⇒ String
Get the path for this element
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#preceded_by_text ⇒ Object
Returns true if the immediately preceding sibling is text
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#prepend(child: nil, sibling: nil) ⇒ Object
If child argument given, prepends it before the element’s current children. If sibling is given, prepends it as a sibling to this element.
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 |
# File 'lib/kitchen/element_base.rb', line 549 def prepend(child: nil, sibling: nil) require_one_of_child_or_sibling(child, sibling) if child if node.children.empty? node.children = child.to_s else node.children.first.add_previous_sibling(child) end else node.add_previous_sibling(sibling) end self end |
#previous ⇒ Object
returns previous element sibling (only returns elements or nil) nil if there’s no previous sibling
529 530 531 532 533 534 535 536 537 538 |
# File 'lib/kitchen/element_base.rb', line 529 def previous prev = raw.previous_element return prev if prev.nil? Element.new( node: prev, document: document, short_type: "previous(#{short_type})" ) end |
#raw ⇒ Nokogiri::XML::Node
Returns the underlying Nokogiri object
675 676 677 |
# File 'lib/kitchen/element_base.rb', line 675 def raw node end |
#raw_search(*selector_or_xpath_args, reload: false) ⇒ Object
396 397 398 399 400 401 402 |
# File 'lib/kitchen/element_base.rb', line 396 def raw_search(*selector_or_xpath_args, reload: false) key = selector_or_xpath_args @search_cache[key] = nil if reload || !config.enable_search_cache # cache nil search results with a fake -1 value @search_cache[key] ||= raw.search(*selector_or_xpath_args) || -1 @search_cache[key] == -1 ? nil : @search_cache[key] end |
#remember_that_a_sub_element_was_counted(search_query, type) ⇒ Object
Track that a sub element found by the given query has been counted
343 344 345 346 |
# File 'lib/kitchen/element_base.rb', line 343 def remember_that_a_sub_element_was_counted(search_query, type) @search_query_matches_that_have_been_counted[search_query.to_s] ||= Hash.new(0) @search_query_matches_that_have_been_counted[search_query.to_s][type] += 1 end |
#remove_attribute ⇒ Object
Removes an attribute from the element
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#remove_class ⇒ Object
Remove a class from the element
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#replace_children(with:) ⇒ Object
Replaces this element’s children
592 593 594 595 |
# File 'lib/kitchen/element_base.rb', line 592 def replace_children(with:) node.children = with self end |
#search(*selector_or_xpath_args, only: nil, except: nil, reload: false) ⇒ ElementEnumerator
Returns an ElementEnumerator that iterates over the provided selector or xpath queries
382 383 384 385 386 387 388 389 390 391 392 393 394 |
# File 'lib/kitchen/element_base.rb', line 382 def search(*selector_or_xpath_args, only: nil, except: nil, reload: false) block_error_if(block_given?) ElementEnumerator.factory.build_within( self, search_query: SearchQuery.new( css_or_xpath: selector_or_xpath_args, only: only, except: except ), reload: reload ) end |
#search_history ⇒ SearchHistory
Returns the search history that found this element
364 365 366 367 368 369 |
# File 'lib/kitchen/element_base.rb', line 364 def search_history SearchHistory.new( ancestor_elements.last&.search_history || SearchHistory.empty, search_query_that_found_me ) end |
#selectors ⇒ Selectors::Base
Get the selectors for this element’s document
101 |
# File 'lib/kitchen/element_base.rb', line 101 def_delegators :config, :selectors |
#set(property, value) ⇒ Object
A way to set values and chain them
250 251 252 253 254 255 256 257 258 |
# File 'lib/kitchen/element_base.rb', line 250 def set(property, value) case property.to_sym when :name self.name = value else self[property.to_sym] = value end self end |
#sub_header_name ⇒ String
Returns the header tag name that is one level under the first header tag in this element, e.g. if this element is a “div” whose first header is “h1”, this will return “h2”
TODO this method may not be needed.
655 656 657 658 659 660 661 662 663 |
# File 'lib/kitchen/element_base.rb', line 655 def sub_header_name first_header = node.search('h1, h2, h3, h4, h5, h6').first if first_header.nil? 'h1' else first_header.name.gsub(/\d/) { |num| (num.to_i + 1).to_s } end end |
#target_label(label_text: nil, custom_content: nil, cases: false) ⇒ Pantry
Creates labels for links to inside elements like Figures, Tables, Equations, Exercises, Notes.
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 |
# File 'lib/kitchen/element_base.rb', line 750 def target_label(label_text: nil, custom_content: nil, cases: false) if cases cases = %w[nominative genitive dative accusative instrumental locative vocative] element_labels = {} cases.each do |label_case| element_labels[label_case] = "#{I18n.t("#{label_text}.#{label_case}")} #{custom_content}" element_label_case = element_labels[label_case] pantry(name: "#{label_case}_link_text").store element_label_case, label: id if id end else element_label = if label_text "#{I18n.t(label_text.to_s)} #{custom_content}" else custom_content end pantry(name: :link_text).store element_label, label: id if id end end |
#text ⇒ String
Get the element text
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#to_html ⇒ String
Get the element as HTML
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#to_s ⇒ String
Returns a string version of this element
691 692 693 |
# File 'lib/kitchen/element_base.rb', line 691 def to_s remove_default_namespaces_if_clone(node.to_s) end |
#to_xhtml ⇒ String
Returns a string version of this element as XHTML
707 708 709 |
# File 'lib/kitchen/element_base.rb', line 707 def to_xhtml remove_default_namespaces_if_clone(node.to_xhtml) end |
#to_xml ⇒ String
Returns a string version of this element as XML
699 700 701 |
# File 'lib/kitchen/element_base.rb', line 699 def to_xml remove_default_namespaces_if_clone(node.to_xml) end |
#trash ⇒ Object
Delete the element
516 517 518 519 |
# File 'lib/kitchen/element_base.rb', line 516 def trash node.remove self end |
#uncount(search_query) ⇒ Object
Undo the counts from a prior search query (so that they can be counted again)
352 353 354 355 356 357 358 |
# File 'lib/kitchen/element_base.rb', line 352 def uncount(search_query) @search_query_matches_that_have_been_counted.delete(search_query.to_s)&.each do |type, count| ancestors.each_value do |ancestor| ancestor.decrement_descendant_count(type, by: count) end end end |
#wrap ⇒ Nokogiri::XML::Node
Add HTML around this element
88 89 90 91 |
# File 'lib/kitchen/element_base.rb', line 88 def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class, :text, :wrap, :children, :to_html, :remove_attribute, :key?, :classes, :path, :inner_html=, :add_previous_sibling, :preceded_by_text? |
#wrap_children(name = 'div', attributes = {}) {|the| ... } ⇒ Element
Wraps the element’s children in a new element. Yields the new wrapper element to a block, if provided.
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 |
# File 'lib/kitchen/element_base.rb', line 608 def wrap_children(name='div', attributes={}) if name.is_a?(Hash) attributes = name name = 'div' end node.children = node.document.create_element(name) do |new_node| # For some reason passing attributes to create_element doesn't work, so doing here attributes.each do |k, v| new_node[k.to_s.gsub(/([^_])_([^_])/, '\1-\2').gsub('__', '_')] = v end new_node.children = children yield Element.new(node: new_node, document: document, short_type: nil) if block_given? end self end |