lib/iegrip.rb in iegrip-0.0.4 vs lib/iegrip.rb in iegrip-0.0.7

- old
+ new

@@ -37,203 +37,349 @@ wait_stable() end COMPLETE_STATE = 4 def wait_stable() - while @raw_object.Busy == true - sleep 0.5 - end + stable_counter = 0 loop do - break if @raw_object.ReadyState == COMPLETE_STATE - sleep 0.5 + break if stable_counter >= 3 + if (@raw_object.Busy != true) and (@raw_object.ReadyState == COMPLETE_STATE) + stable_counter += 1 + else + sleep 0.5 + stable_counter = 0 + end end end def export(href, filename) @urlDownloadToFile.call(0, href, filename, 0, 0) end end - # ======================== - # Node - # ======================== - class Node < GripWrapper - NODETYPE_DIC = { - 1 => :ELEMENT_NODE, - 2 => :ATTRIBUTE_NODE, - 3 => :TEXT_NODE, - 4 => :CDATA_SECTION_NODE, - 5 => :ENTITY_REFERENCE_NODE, - 6 => :ENTITY_NODE, - 7 => :PROCESSING_INSTRUCTION_NODE, - 8 => :COMMENT_NODE, - 9 => :DOCUMENT_NODE, - 10 => :DOCUMENT_TYPE_NODE, - 11 => :DOCUMENT_FRAGMENT_NODE, - 12 => :NOTATION_NODE, - } - def tagName - case self.nodeType - when 3 - @raw_object.nodeName - else - @raw_object.tagName.downcase - end + module ElementParent + def parentNode + raw_element = @raw_object.parentNode() + raw_element ? HTMLElement.new(raw_element, @ie_obj) : nil end - def nodeName - @raw_object.nodeName + def parentElement + raw_parent = @raw_object.parentElement + raw_parent ? HTMLElement.new(raw_parent, @ie_obj) : nil end - def nodeTypeName - nodetype = @raw_object.nodetype - NODETYPE_DIC[nodetype] || :UNKNOWN + def getParentForm() + parent_element = self.parentElement + loop do + if parent_element == nil + return nil + elsif parent_element.tagName == "form" + return parent_element + else + parent_element = parent_element.parentElement + end + end end - - def inspect - "<#{self.class}, Name:#{self.nodeName}>" - end - + end + + module ElementChild def childNodes raw_childNodes = @raw_object.childNodes raw_childNodes ? NodeList.new(raw_childNodes, @ie_obj) : nil end - def parentNode - raw_element = @raw_object.parentNode() - raw_element ? TagElement.new(raw_element, @ie_obj) : nil + def childElements + raw_childNodes = @raw_object.childNodes + raw_childNodes ? HTMLElementCollection.new(raw_childNodes, @ie_obj) : nil end def previousSibling raw_node = @raw_object.previousSibling() - raw_node ? Node.new(raw_node, @ie_obj) : nil + raw_node ? HTMLElement.new(raw_node, @ie_obj) : nil end def nextSibling raw_node = @raw_object.nextSibling() - raw_node ? Node.new(raw_node, @ie_obj) : nil + raw_node ? HTMLElement.new(raw_node, @ie_obj) : nil end def firstChild raw_node = @raw_object.firstChild() - raw_node ? Node.new(raw_node, @ie_obj) : nil + raw_node ? HTMLElement.new(raw_node, @ie_obj) : nil end def lastChild raw_node = @raw_object.lastChild() - raw_node ? Node.new(raw_node, @ie_obj) : nil + raw_node ? HTMLElement.new(raw_node, @ie_obj) : nil end def hasChildNodes() - #@raw_object.hasChildNodes() # This method return WIN32OLE object. not boolean @raw_object.childNodes.length > 0 end + def hasChildElements() + @raw_object.childNodes.each {|subnode| + return true if (subnode.nodeType != 3) and (subnode.nodeType != 8) + } + false + end + def contains(node) @raw_object.contains(toRaw(node)) end def isEqualNode(node) @raw_object.isEqualNode(toRaw(node)) end - def getElementById(tag_id) - raw_element = @raw_object.getElementById(tag_id) - raw_element ? TagElement.new(raw_element, @ie_obj) : nil + def struct(level=0) + struct = [] + self.childElements.each {|subelement| + inner,outer = get_inner(subelement) + if subelement.hasChildElements() + sub_struct = subelement.struct(level+1) + if sub_struct.size > 0 + struct.push (" " * level) + "<#{inner}>" + struct += sub_struct + struct.push (" " * level) + "</#{subelement.tagName}>" + else + struct.push (" " * level) + "<#{inner} />" + end + else + if outer + struct.push (" " * level) + "<#{inner}>#{outer}</#{subelement.tagName}>" + else + struct.push (" " * level) + "<#{inner} />" + end + end + } + return struct end + private + + def get_inner(tag) + inner = [tag.tagName] + outer = nil + inner.push "id='#{tag.ID}'" if tag.ID != "" + case tag.tagName + when "a" + href = tag.href + if href.size > 20 + href = href[0,19] + "..." + end + inner.push "href='#{href}'" + when "img" + inner.push "src='#{tag.src}'" + when "input" + inner.push "type='#{tag.Type}'" + when "form" + inner.push "action='#{tag.action}' method='#{tag.Method}'" + when "option" + inner.push "value='#{tag.value}'" + when "style" + inner.push "type='#{tag.Type}'" + end + unless tag.hasChildElements + innerText = tag.innerText + if innerText =~ /^<!--(.+)-->$/ + if $1.size > 20 + outer = "<!--#{$1[0,19]}...-->" + else + outer = innerText + end + innerText = "" + end + if innerText.size > 20 + innerText = innerText[0,19] + "..." + end + inner.push "text='#{innerText}'" if innerText != "" + end + return [inner.join(' '), outer] + end + end + + module GetElements def getElementsByName(name) raw_col = @raw_object.getElementsByName(name) - raw_col ? TagElementCollection.new(raw_col, @ie_obj) : nil + raw_col ? HTMLElementCollection.new(raw_col, @ie_obj) : nil end + def getElementsByTagName(tag_name) raw_col = @raw_object.getElementsByTagName(tag_name) - raw_col ? TagElementCollection.new(raw_col, @ie_obj) : nil + raw_col ? HTMLElementCollection.new(raw_col, @ie_obj) : nil end - alias tags getElementsByTagName + alias elements getElementsByTagName - def getStructure(level=0) - structure = [] - self.childNodes.each {|subnode| - next if (subnode.nodeType == 3) or (subnode.nodeType == 8) - if subnode.hasChildNodes() - sub_struct = subnode.getStructure(level+1) - if sub_struct.size > 0 - structure.push (" " * level) + "<#{subnode.tagName}>" - structure += sub_struct - structure.push (" " * level) + "</#{subnode.tagName}>" - else - structure.push (" " * level) + "<#{subnode.tagName}/>" - end + def getElementsByTitle(target_str) + get_elements_by_key(target_str, "VALUE") + end + def getElementsByValue(target_str) + get_elements_by_key(target_str, "VALUE") + end + def getElementsByText(target_str) + get_elements_by_key(target_str, "INNERTEXT") + end + + def getElementByTitle(target_str) + taglist = get_elements_by_key(target_str, "VALUE") + taglist[0] + end + def getElementByValue(target_str) + taglist = get_elements_by_key(target_str, "VALUE") + taglist[0] + end + def getElementByText(target_str) + taglist = get_elements_by_key(target_str, "INNERTEXT") + taglist[0] + end + def getElementByName(target_str) + taglist = get_elements_by_key(target_str, "NAME") + taglist[0] + end + + private + + def get_elements_by_key(target_str, key_type) + tag_list = [] + @raw_object.all.each {|tag_element| + case key_type + when "INNERTEXT" + key_string = tag_element.innerText + when "VALUE" + key_string = tag_element.value + when "NAME" + key_string = tag_element.name + when "ID" + key_string = tag_element.ID else - structure.push (" " * level) + "<#{subnode.tagName}/>" + return nil end + if key_string == target_str + tag_list.push HTMLElement.new(tag_element, @ie_obj) + end } - return structure + + return tag_list end end # ======================== - # IE.Document + # Node # ======================== - class Document < Node - def frames(index=nil) - if index - return(nil) if index >= @raw_object.Frames.length - Frames.new(@raw_object.frames, @ie_obj)[index] + class Node < GripWrapper + NODETYPE_DIC = { + 1 => :ELEMENT_NODE, + 2 => :ATTRIBUTE_NODE, + 3 => :TEXT_NODE, + 4 => :CDATA_SECTION_NODE, + 5 => :ENTITY_REFERENCE_NODE, + 6 => :ENTITY_NODE, + 7 => :PROCESSING_INSTRUCTION_NODE, + 8 => :COMMENT_NODE, + 9 => :DOCUMENT_NODE, + 10 => :DOCUMENT_TYPE_NODE, + 11 => :DOCUMENT_FRAGMENT_NODE, + 12 => :NOTATION_NODE, + } + + def nodeName + @raw_object.nodeName + end + + def nodeType + @raw_object.nodetype + end + + def nodeTypeName + nodetype = @raw_object.nodetype + NODETYPE_DIC[nodetype] || :UNKNOWN + end + + def inspect + case self.nodeType + when 3 + "<#{self.class}, Name:#{self.nodeName}, Text:#{self.wholeText.inspect}>" else - Frames.new(@raw_object.frames, @ie_obj) + "<#{self.class}, Name:#{self.nodeName}>" end end + end + + # ======================== + # IE.Document + # ======================== + class Document < Node + include ElementChild + include GetElements + def head() raw_head = @raw_object.head - raw_head ? TagElement.new(raw_head, @ie_obj) : nil + raw_head ? HTMLElement.new(raw_head, @ie_obj) : nil end def body() - #raw_body = @raw_object.getElementsByTagName("BODY") - #raw_body ? TagElementCollection.new(raw_body, @ie_obj)[0] : nil - TagElement.new(@raw_object.body, @ie_obj) + HTMLElement.new(@raw_object.body, @ie_obj) end def all raw_all = @raw_object.all - raw_all ? TagElementCollection.new(raw_all, @ie_obj) : nil + raw_all ? HTMLElementCollection.new(raw_all, @ie_obj) : nil end + def frames(index=nil) + if index + return(nil) if index >= @raw_object.Frames.length + Frames.new(@raw_object.frames, @ie_obj)[index] + else + Frames.new(@raw_object.frames, @ie_obj) + end + end + def getElementById(element_id) + raw_element = @raw_object.getElementById(element_id) + raw_element ? HTMLElement.new(raw_element, @ie_obj) : nil + end + def documentElement raw_element = @raw_object.documentElement() - raw_element ? TagElement.new(raw_element, @ie_obj) : nil + raw_element ? HTMLElement.new(raw_element, @ie_obj) : nil end def createElement(tag_name) raw_element = @raw_object.createElement(tag_name) - TagElement.new(raw_element, @ie_obj) + HTMLElement.new(raw_element, @ie_obj) end def createAttribute(attr_name) raw_attr = @raw_object.createAttribute(attr_name); Attr.new(raw_attr, @ie_obj) end end # ======================== - # TAG Element + # HTML Element # ======================== - class TagElement < Node + class HTMLElement < Node + include ElementParent + include ElementChild + include GetElements def tagname - @raw_object.tagName.downcase + if self.nodeType == 8 + "comment" + else + @raw_object.tagName.downcase + end end def text=(set_text) - case tagName - when "SELECT" - option_list = tags("OPTION") + case self.tagname + when "select" + option_list = elements("OPTION") option_list.each {|option_element| if option_element.innerText == set_text option_element.selected = true break end @@ -241,10 +387,11 @@ else @raw_object.value = set_text end end + def inspect() case tagName when "SELECT" innerHTML = replace_cr_code(self.innerHTML) "<#{self.class}, TAG:#{tagName}, [#{self.innerHTML}]" @@ -260,10 +407,14 @@ end def to_s @raw_object.value end + def value + @raw_object.value + end + alias text value def click if @ie_obj.version >= 10 case self.tagname.downcase when "a" @@ -294,40 +445,15 @@ @raw_object.click end @ie_obj.wait_stable() end - def getElementsByTagName(tag_name) - raw_collection = @raw_object.getElementsByTagName(tag_name) - raw_collection ? TagElementCollection.new(raw_collection, @ie_obj) : nil - end - alias tags getElementsByTagName - def all - TagElementCollection.new(@raw_object.all, @ie_obj) + HTMLElementCollection.new(@raw_object.all, @ie_obj) end - def parentElement - raw_parent = @raw_object.parentElement - raw_parent ? TagElement.new(raw_parent, @ie_obj) : nil - end - def getParentForm() - puts "getParentForm() is called." - parent_tag = self.parentElement - loop do - puts "parent_tag = #{parent_tag.inspect}" - if parent_tag == nil - return nil - elsif parent_tag.tagName == "form" - return parent_tag - else - parent_tag = parent_tag.parentElement - end - end - end - def export(filename) case self.tagName.downcase when "img" @ie_obj.export(self.src, filename) when "a" @@ -357,87 +483,129 @@ def removeAttributeNode( attr ) raw_attr = @raw_object.removeAttributeNode( toRaw(attr) ) raw_attr ? Attr.new(raw_attr, @ie_obj) : nil end + def insertBefore(newElement, anchor_element=nil) + @raw_object.insertBefore(toRaw(newElement), toRaw(anchor_element)) + end + + def appendChild(newElement) + @raw_object.appendChild(toRaw(newElement)) + end + + def removeChild(element) + @raw_object.removeChild(toRaw(element)) + end + + def replaceChild(newElement, oldElement) + @raw_object.replaceChild(toRaw(newElement), toRaw(oldElement)) + end + + def addElement(new_element) + parent = self.parentElement + next_element = self.nextSibling + if next_element + parent.insertBefore(new_element, next_element) + else + parent.appendChild(new_element) + end + end + private def replace_cr_code(text) replcae_text = text.gsub(/\r/, '\r') replcae_text.gsub!(/\n/, '\n') return replcae_text end end + # ======================== - # TAG Element Collection + # Node Collection # ======================== - class TagElementCollection < GripWrapper + class NodeList < GripWrapper def [](index) return(nil) if index >= @raw_object.length - TagElement.new(@raw_object.item(index), @ie_obj) + raw_node = @raw_object.item(index) + if raw_node.nodeType == 1 + HTMLElement.new(raw_node, @ie_obj) + else + Node.new(raw_node, @ie_obj) + end end def size @raw_object.length end def each + @raw_object.each {|raw_node| + if raw_node.nodeType == 1 + yield HTMLElement.new(raw_node, @ie_obj) + else + yield Node.new(raw_node, @ie_obj) + end + } + end + + def inspect() + "<#{self.class}>" + end + end + + # ======================== + # TAG Element Collection + # ======================== + class HTMLElementCollection < NodeList + def [](index) + return(nil) if index >= @raw_object.length + raw_node = @raw_object.item(index) + HTMLElement.new(raw_node, @ie_obj) + end + + def each @raw_object.each {|tag_element| - yield TagElement.new(tag_element, @ie_obj) + next if (tag_element.nodeType == 3) or (tag_element.nodeType == 8) + yield HTMLElement.new(tag_element, @ie_obj) } end - def getTagsByTitle(target_str) - get_tags_by_key(target_str, "VALUE") + def getElementsByTitle(target_str) + get_elements_by_key(target_str, "VALUE") end - def getTagsByValue(target_str) - get_tags_by_key(target_str, "VALUE") + def getElementsByValue(target_str) + get_elements_by_key(target_str, "VALUE") end - def getTagsByText(target_str) - get_tags_by_key(target_str, "INNERTEXT") + def getElementsByText(target_str) + get_elements_by_key(target_str, "INNERTEXT") end - def getTagsByName(target_str) - get_tags_by_key(target_str, "NAME") + def getElementsByName(target_str) + get_elements_by_key(target_str, "NAME") end - def getTagByTitle(target_str) - taglist = get_tags_by_key(target_str, "VALUE") + def getElementByTitle(target_str) + taglist = get_elements_by_key(target_str, "VALUE") taglist ? taglist[0]: nil end - def getTagByValue(target_str) - taglist = get_tags_by_key(target_str, "VALUE") + def getElementByValue(target_str) + taglist = get_elements_by_key(target_str, "VALUE") taglist ? taglist[0]: nil end - def getTagByText(target_str) - taglist = get_tags_by_key(target_str, "INNERTEXT") + def getElementByText(target_str) + taglist = get_elements_by_key(target_str, "INNERTEXT") taglist ? taglist[0]: nil end - def getTagByName(target_str) - taglist = get_tags_by_key(target_str, "NAME") + def getElementByName(target_str) + taglist = get_elements_by_key(target_str, "NAME") taglist ? taglist[0]: nil end - def getTagByID(target_id) - taglist = get_tags_by_key(target_id, "ID") - taglist ? taglist[0]: nil - end - def inspect() - tagname_list = [] - self.each {|tag_element| - tagname_list.push "<#{tag_element.tagName}>" - } - if tagname_list.size > 3 - "<#{self.class}: [#{tagname_list[0,3].join(', ')},...]" - else - "<#{self.class}: [#{tagname_list.join(', ')}]>" - end - end - private - def get_tags_by_key(target_str, key_type) + def get_elements_by_key(target_str, key_type) tag_list = [] @raw_object.each {|tag_element| case key_type when "INNERTEXT" key_string = tag_element.innerText @@ -449,24 +617,22 @@ key_string = tag_element.ID else return nil end if key_string == target_str - tag_list.push TagElement.new(tag_element, @ie_obj) + tag_list.push HTMLElement.new(tag_element, @ie_obj) end } case tag_list.size when 0 return nil else return tag_list end end - end - # ======================== # IE.Document.Frames # ======================== class Frames < GripWrapper @@ -496,44 +662,19 @@ def document Document.new(@raw_object.document, @ie_obj) end end - # ======================== - # NodeList - # ======================== - class NodeList < GripWrapper - def [](index) - return(nil) if index >= @raw_object.length - Node.new(@raw_object.item(index), @ie_obj) - end - - def size - @raw_object.length - end - - def each - index = 0 - loop do - break if index >= @raw_object.length - raw_node = @raw_object.item(index) - yield Node.new(raw_node, @ie_obj) - index += 1 - end - end - end - - class Attr < GripWrapper def value=(value_str) @raw_object.value = value_str end def value @raw_object.value end def ownerElement() - TagElement.new(@raw_object.ownerElement, @ie_obj) + HTMLElement.new(@raw_object.ownerElement, @ie_obj) end end end