class Hiroiyomi::Html::Element
rubocop:disable Metrics/ClassLength Element
Constants
- EXCEPTIONAL_ELEMENT_NAME_LIST
Attributes
attributes[RW]
children[RW]
name[RW]
parent[RW]
Public Class Methods
new(name, parent: nil, attributes: [], children: [])
click to toggle source
# File lib/hiroiyomi/html/element.rb, line 147 def initialize(name, parent: nil, attributes: [], children: []) @name = name @parent = parent @attributes = attributes @children = children end
value_of(file, parent_element = nil)
click to toggle source
rubocop:disable Metrics/MethodLength
# File lib/hiroiyomi/html/element.rb, line 21 def value_of(file, parent_element = nil) # name name = extract_element_name(file) return parent_element if name.empty? # element element = Element.new(name, parent: parent_element) if parent_element.nil? parent_element = element else parent_element.element = element end # attributes element.attributes = extract_attributes(file) # exceptional elements if EXCEPTIONAL_ELEMENT_NAME_LIST.include?(name.downcase) element.element = extract_exceptional_element_text(file, name) return parent_element end # text if >..., close if /, or open element if >...< Text.add_text_to_element_or_parse(file, element) # close check. move element children to parent element if not closed. e.g. <img ...> element.move_children_to(parent_element) unless validate_closing_element?(file, element) parent_element end
Private Class Methods
extract_attributes(file)
click to toggle source
# File lib/hiroiyomi/html/element.rb, line 138 def extract_attributes(file) attributes = [] while (attribute = Attribute.value_of(file)) attributes.push(attribute) end attributes end
extract_element_name(file)
click to toggle source
# File lib/hiroiyomi/html/element.rb, line 129 def extract_element_name(file) while (c = file.getc) next unless c == '<' next if skip_comments(file) return DOMParserHelper.extract_string(file) end '' end
extract_exceptional_element_text(file, name)
click to toggle source
rubocop:disable Metrics/AbcSize, Metrics/MethodLength For script, style. First char must be > after attributes
# File lib/hiroiyomi/html/element.rb, line 97 def extract_exceptional_element_text(file, name) DOMParserHelper.skip_ignore_chars(file) file.getc # drop > string = '' while (c = file.getc) if c == '<' cur_pos = file.pos if file.getc == '/' && name == DOMParserHelper.extract_string(file) DOMParserHelper.skip_ignore_chars(file) file.getc # drop > break end file.pos = cur_pos end string += c end return Text.new(string) unless string.empty? nil end
skip_comments(file)
click to toggle source
rubocop:enable Metrics/AbcSize, Metrics/MethodLength
# File lib/hiroiyomi/html/element.rb, line 118 def skip_comments(file) cur_pos = file.pos if file.getc == '!' # Skip like <!document html>, <!-- DOMParserHelper.extract_comments(file) return true end file.pos = cur_pos false end
validate_closing_element?(file, element)
click to toggle source
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
# File lib/hiroiyomi/html/element.rb, line 58 def validate_closing_element?(file, element) open = false while (c = file.getc) # /> or </ if c == '/' open = false cur_pos = DOMParserHelper.cur_pos(file, c) next_c = file.getc return true if next_c == '>' # case of /> # Check whether name is the same or not file.ungetc(next_c) close_name = DOMParserHelper.extract_string(file) return false if close_name.empty? is_closed = close_name == element.name return true if is_closed # Try it again if name is not matched and next close element name does not exist in parent elements next unless element.parents?(close_name) file.pos = cur_pos return false elsif c == '<' # case of </ Text.add_text_to_element_or_parse(file, element) open = true elsif open file.ungetc(c) return false end end false end
Public Instance Methods
deep_select(search_name_list = [], searched = [])
click to toggle source
# File lib/hiroiyomi/html/element.rb, line 177 def deep_select(search_name_list = [], searched = []) searched.push(self) if search_name_list.include?(name.downcase) children.each do |child| next if child.text? if search_name_list.include?(child.name.downcase) searched.push(child) else child.deep_select(search_name_list, searched) end end searched end
each() { |child| ... }
click to toggle source
# File lib/hiroiyomi/html/element.rb, line 158 def each @children.each do |child| yield child end end
element=(element)
click to toggle source
# File lib/hiroiyomi/html/element.rb, line 154 def element=(element) @children.push(element) unless element.nil? end
inner_html()
click to toggle source
# File lib/hiroiyomi/html/element.rb, line 190 def inner_html children.map(&:to_s).join end
move_children_to(element)
click to toggle source
# File lib/hiroiyomi/html/element.rb, line 164 def move_children_to(element) each do |child| element.element = child end children.clear end
parents?(name)
click to toggle source
# File lib/hiroiyomi/html/element.rb, line 171 def parents?(name) return false if parent.nil? return true if parent.name == name parent.parents?(name) end
to_s()
click to toggle source
# File lib/hiroiyomi/html/element.rb, line 194 def to_s attrs = attributes.map(&:to_s).join(' ') attrs = ' ' + attrs unless attrs.empty? "<#{name}#{attrs}>#{inner_html}</#{name}>" end