lib/watir/locator.rb in watir-1.6.2 vs lib/watir/locator.rb in watir-1.6.5
- old
+ new
@@ -1,161 +1,176 @@
-module Watir
- class TaggedElementLocator
- include Watir
- include Watir::Exception
-
- def initialize(container, tag)
- @container = container
- @tag = tag
- end
-
- def set_specifier(how, what)
- if how.class == Hash and what.nil?
- specifiers = how
- else
- specifiers = {how => what}
- end
-
- @specifiers = {:index => 1} # default if not specified
-
- specifiers.each do |how, what|
- what = what.to_i if how == :index
- how = :href if how == :url
- how = :class_name if how == :class
-
- @specifiers[how] = what
- end
-
- end
-
- def each_element tag
- @container.document.getElementsByTagName(tag).each do |ole_element|
- yield Element.new(ole_element)
- end
- end
-
- def locate
- count = 0
- each_element(@tag) do |element|
-
- catch :next_element do
- @specifiers.each do |how, what|
- next if how == :index
- unless match? element, how, what
- throw :next_element
- end
- end
- count += 1
- unless count == @specifiers[:index]
- throw :next_element
- end
- return element.ole_object
- end
-
- end # elements
- nil
- end
-
- def match?(element, how, what)
- begin
- method = element.method(how)
- rescue NameError
- raise MissingWayOfFindingObjectException,
- "#{how} is an unknown way of finding a <#{@tag}> element (#{what})"
- end
- case method.arity
- when 0
- what.matches method.call
- when 1
- method.call(what)
- else
- raise MissingWayOfFindingObjectException,
- "#{how} is an unknown way of finding a <#{@tag}> element (#{what})"
- end
- end
-
- end
- class InputElementLocator
- attr_accessor :document, :element, :elements
- def initialize container, types
- @container = container
- @types = types
- @elements = nil
- end
- def specifier= arg
- how, what, value = arg
-
- if how.class == Hash and what.nil?
- specifiers = how
- else
- specifiers = {how => what}
- end
-
- @specifiers = {:index => 1} # default if not specified
- @specifiers[:value] = value.to_s if value
- specifiers.each do | how, what |
- how = :value if how == :caption
- how = :class_name if how == :class
- what = what.to_i if how == :index
- @specifiers[how] = what
- end
- end
-
- def locate
- count = 0
- @elements.each do |object|
- element = Element.new(object)
-
- catch :next_element do
- throw :next_element unless @types.include?(element.type)
- @specifiers.each do |how, what|
- next if how == :index
- unless match? element, how, what
- throw :next_element
- end
- end
- count += 1
- throw :next_element unless count == @specifiers[:index]
- return object
- end
-
- end
- nil
- end
- # return true if the element matches the provided how and what
- def match? element, how, what
- begin
- attribute = element.send(how)
- rescue NoMethodError
- raise MissingWayOfFindingObjectException,
- "#{how} is an unknown way of finding an <INPUT> element (#{what})"
- end
-
- what.matches(attribute)
- end
-
- def fast_locate
- # Searching through all elements returned by ole_inner_elements
- # is *significantly* slower than IE's getElementById() and
- # getElementsByName() calls when how is :id or :name. However
- # IE doesn't match Regexps, so first we make sure what is a String.
- # In addition, IE's getElementById() will also return an element
- # where the :name matches, so we will only return the results of
- # getElementById() if the matching element actually HAS a matching
- # :id.
-
- the_id = @specifiers[:id]
- if the_id && the_id.class == String &&
- @specifiers[:index] == 1 && @specifiers.length == 2
- @element = @document.getElementById(the_id) rescue nil
- # Return if our fast match really HAS a matching :id
- return true if @element && @element.invoke('id') == the_id
- end
-
- the_name = @specifiers[:name]
- if the_name && the_name.class == String
- @elements = @document.getElementsByName(the_name) rescue nil
- end
- false
- end
- end
-end
+module Watir
+ class Locator
+ include Watir
+ include Watir::Exception
+
+ def normalize_specifiers!(specifiers)
+ specifiers.each do |how, what|
+ case how
+ when :index
+ what = what.to_i
+ when :url
+ how = :href
+ when :class
+ how = :class_name
+ when :caption
+ how = :value
+ end
+
+ @specifiers[how] = what
+ end
+ end
+
+
+ end
+
+ class TaggedElementLocator < Locator
+ def initialize(container, tag)
+ @container = container
+ @tag = tag
+ end
+
+ def set_specifier(how, what)
+ if how.class == Hash and what.nil?
+ specifiers = how
+ else
+ specifiers = {how => what}
+ end
+
+ @specifiers = {:index => 1} # default if not specified
+ normalize_specifiers! specifiers
+ end
+
+ def each_element tag
+ @container.document.getElementsByTagName(tag).each do |ole_element|
+ yield Element.new(ole_element)
+ end
+ end
+
+ def locate
+ count = 0
+ each_element(@tag) do |element|
+
+ catch :next_element do
+ @specifiers.each do |how, what|
+ next if how == :index
+ unless match? element, how, what
+ throw :next_element
+ end
+ end
+ count += 1
+ unless count == @specifiers[:index]
+ throw :next_element
+ end
+ return element.ole_object
+ end
+
+ end # elements
+ nil
+ end
+
+ def match?(element, how, what)
+ begin
+ method = element.method(how)
+ rescue NameError
+ raise MissingWayOfFindingObjectException,
+ "#{how} is an unknown way of finding a <#{@tag}> element (#{what})"
+ end
+ case method.arity
+ when 0
+ what.matches method.call
+ when 1
+ method.call(what)
+ else
+ raise MissingWayOfFindingObjectException,
+ "#{how} is an unknown way of finding a <#{@tag}> element (#{what})"
+ end
+ end
+
+ end
+ class InputElementLocator < Locator
+
+ attr_accessor :document, :element, :elements
+
+ def initialize container, types
+ @container = container
+ @types = types
+ @elements = nil
+ end
+
+ def specifier= arg
+ how, what, value = arg
+
+ if how.class == Hash and what.nil?
+ specifiers = how
+ else
+ specifiers = {how => what}
+ end
+
+ @specifiers = {:index => 1} # default if not specified
+ if value
+ @specifiers[:value] = value.is_a?(Regexp) ? value : value.to_s
+ end
+
+ normalize_specifiers! specifiers
+ end
+
+ def locate
+ count = 0
+ @elements.each do |object|
+ element = Element.new(object)
+
+ catch :next_element do
+ throw :next_element unless @types.include?(element.type)
+ @specifiers.each do |how, what|
+ next if how == :index
+ unless match? element, how, what
+ throw :next_element
+ end
+ end
+ count += 1
+ throw :next_element unless count == @specifiers[:index]
+ return object
+ end
+
+ end
+ nil
+ end
+ # return true if the element matches the provided how and what
+ def match? element, how, what
+ begin
+ attribute = element.send(how)
+ rescue NoMethodError
+ raise MissingWayOfFindingObjectException,
+ "#{how} is an unknown way of finding an <INPUT> element (#{what})"
+ end
+
+ what.matches(attribute)
+ end
+
+ def fast_locate
+ # Searching through all elements returned by ole_inner_elements
+ # is *significantly* slower than IE's getElementById() and
+ # getElementsByName() calls when how is :id or :name. However
+ # IE doesn't match Regexps, so first we make sure what is a String.
+ # In addition, IE's getElementById() will also return an element
+ # where the :name matches, so we will only return the results of
+ # getElementById() if the matching element actually HAS a matching
+ # :id.
+
+ the_id = @specifiers[:id]
+ if the_id && the_id.class == String &&
+ @specifiers[:index] == 1 && @specifiers.length == 2
+ @element = @document.getElementById(the_id) rescue nil
+ # Return if our fast match really HAS a matching :id
+ return true if @element && @element.invoke('id') == the_id
+ end
+
+ the_name = @specifiers[:name]
+ if the_name && the_name.class == String
+ @elements = @document.getElementsByName(the_name) rescue nil
+ end
+ false
+ end
+
+ end
+end