Module: Vapir::ElementClassAndModuleMethods

Included in:
ElementHelper, RadioCheckBoxCommon
Defined in:
lib/vapir-common/element_class_and_module.rb

Overview

this module is for methods that should go on both common element modules (ie, TextField) as well as browser-specific element classes (ie, Firefox::TextField).

Instance Method Summary collapse

Instance Method Details

#add_container_method_extra_args(*args) ⇒ Object



205
206
207
# File 'lib/vapir-common/element_class_and_module.rb', line 205

def add_container_method_extra_args(*args)
  class_array_append('container_method_extra_args', *args)
end

#all_dom_attr_aliasesObject



229
230
231
232
233
234
235
236
# File 'lib/vapir-common/element_class_and_module.rb', line 229

def all_dom_attr_aliases
  aliases=class_hash_get('dom_attr_aliases').dup
  super_aliases= parent_element_module ? parent_element_module.all_dom_attr_aliases : {}
  super_aliases.each_pair do |attr, alias_list|
    aliases[attr] = (aliases[attr] || Set.new) + alias_list
  end
  aliases
end

#all_dom_attrsObject



225
226
227
228
# File 'lib/vapir-common/element_class_and_module.rb', line 225

def all_dom_attrs
  super_attrs= parent_element_module ? parent_element_module.all_dom_attrs : []
  super_attrs + class_array_get('dom_attrs')
end

#class_array_append(name, *elements) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/vapir-common/element_class_and_module.rb', line 164

def class_array_append(name, *elements)
=begin
  name='@@'+name.to_s
  unless self.class_variable_defined?(name)
    class_variable_set(name, [])
  end
  class_variable_get(name).push(*elements)
=end
  name=name.to_s.capitalize
  unless self.const_defined?(name)
    self.const_set(name, [])
  end
  self.const_get(name).push(*elements)
end

#class_array_get(name) ⇒ Object



179
180
181
182
# File 'lib/vapir-common/element_class_and_module.rb', line 179

def class_array_get(name)
  # just return the value of appending nothing
  class_array_append(name) 
end

#class_hash_get(name) ⇒ Object



190
191
192
# File 'lib/vapir-common/element_class_and_module.rb', line 190

def class_hash_get(name)
  class_hash_merge(name, {})
end

#class_hash_merge(name, hash) ⇒ Object



183
184
185
186
187
188
189
# File 'lib/vapir-common/element_class_and_module.rb', line 183

def class_hash_merge(name, hash)
  name=name.to_s.capitalize
  unless self.const_defined?(name)
    self.const_set(name, {})
  end
  self.const_get(name).merge!(hash)
end

#container_collection_methodsObject



217
218
219
# File 'lib/vapir-common/element_class_and_module.rb', line 217

def container_collection_methods
  class_array_get 'container_collection_methods'
end

#container_method_extra_argsObject



208
209
210
# File 'lib/vapir-common/element_class_and_module.rb', line 208

def container_method_extra_args
  class_array_get('container_method_extra_args')
end

#container_single_methodsObject



214
215
216
# File 'lib/vapir-common/element_class_and_module.rb', line 214

def container_single_methods
  class_array_get 'container_single_methods'
end

#default_how(*arg) ⇒ Object



202
203
204
# File 'lib/vapir-common/element_class_and_module.rb', line 202

def default_how(*arg)
  set_or_get_class_var('@@default_how', *arg)
end

#dom_attr(*dom_attrs) ⇒ Object

takes any number of arguments, where each argument is either:

  • a symbol or strings representing a method that is the same in ruby and on the dom

  • or a hash of key/value pairs where each key is a dom attribute, and each value is a is a corresponding ruby method name or list of ruby method names.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/vapir-common/element_class_and_module.rb', line 44

def dom_attr(*dom_attrs)
  dom_attrs.each do |arg|
    hash=arg.is_a?(Hash) ? arg : arg.is_a?(Symbol) || arg.is_a?(String) ? {arg => arg} : raise(ArgumentError, "don't know what to do with arg #{arg.inspect} (#{arg.class})")
    hash.each_pair do |dom_attr, ruby_method_names|
      ruby_method_names= ruby_method_names.is_a?(Array) ? ruby_method_names : [ruby_method_names]
      class_array_append 'dom_attrs', dom_attr
      ruby_method_names.each do |ruby_method_name|
        dom_attr_locate_alias(dom_attr, ruby_method_name)
        define_method ruby_method_name do
          method_from_element_object(dom_attr)
        end
      end
    end
  end
end

#dom_attr_locate_alias(dom_attr, alias_name) ⇒ Object

creates aliases for locating by



61
62
63
64
65
# File 'lib/vapir-common/element_class_and_module.rb', line 61

def dom_attr_locate_alias(dom_attr, alias_name)
  dom_attr_aliases=class_hash_get('dom_attr_aliases')
  dom_attr_aliases[dom_attr] ||= Set.new
  dom_attr_aliases[dom_attr] << alias_name
end

#dom_function(*dom_functions) ⇒ Object

dom_function is about the same as dom_attr, but dom_attr doesn’t take arguments. also, dom_function methods call #wait; dom_attr ones don’t.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/vapir-common/element_class_and_module.rb', line 69

def dom_function(*dom_functions)
  dom_functions.each do |arg|
    hash=arg.is_a?(Hash) ? arg : arg.is_a?(Symbol) || arg.is_a?(String) ? {arg => arg} : raise(ArgumentError, "don't know what to do with arg #{arg.inspect} (#{arg.class})")
    hash.each_pair do |dom_function, ruby_method_names|
      ruby_method_names= ruby_method_names.is_a?(Array) ? ruby_method_names : [ruby_method_names]
      class_array_append 'dom_functions', dom_function
      ruby_method_names.each do |ruby_method_name|
        define_method ruby_method_name do |*args|
          result=method_from_element_object(dom_function, *args)
          wait
          result
        end
      end
    end
  end
end

#dom_setter(*dom_setters) ⇒ Object

dom_setter takes arguments in the same format as dom_attr, but sends the given setter method (plus = sign) to the element object. eg, module TextField

dom_setter :value
dom_setter :maxLength => :maxlength

end the #value= method in ruby will send to #value= on the element object the #maxlength= method in ruby will send to #maxLength= on the element object (note case difference).



94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/vapir-common/element_class_and_module.rb', line 94

def dom_setter(*dom_setters)
  dom_setters.each do |arg|
    hash=arg.is_a?(Hash) ? arg : arg.is_a?(Symbol) || arg.is_a?(String) ? {arg => arg} : raise(ArgumentError, "don't know what to do with arg #{arg.inspect} (#{arg.class})")
    hash.each_pair do |dom_setter, ruby_method_names|
      ruby_method_names= ruby_method_names.is_a?(Array) ? ruby_method_names : [ruby_method_names]
      class_array_append 'dom_setters', dom_setter
      ruby_method_names.each do |ruby_method_name|
        define_method(ruby_method_name.to_s+'=') do |value|
          element_object.send(dom_setter.to_s+'=', value)
        end
      end
    end
  end
end

#element_collection(dom_attr, ruby_method_name, element_class) ⇒ Object

defines an element collection method on the given element - such as SelectList#options or Table#rows. takes the name of the dom method that returns a collection of element objects, a ruby method name, and an element class - actually this is generally an Element module; this method goes ahead and finds the browser-specific class that will actually be instantiated. the defined method returns an ElementCollection.



115
116
117
118
119
120
121
# File 'lib/vapir-common/element_class_and_module.rb', line 115

def element_collection(dom_attr, ruby_method_name, element_class)
  define_method ruby_method_name do
    assert_exists do
      ElementCollection.new(self, element_class_for(element_class), extra_for_contained.merge(:candidates => dom_attr))
    end
  end
end

#factory(element_object, extra = {}, *howwhat) ⇒ Object

takes an element_object (JavascriptObject or WIN32OLE), and finds the most specific class that is < self whose specifiers match it. Returns an instance of that class using the given element_object.

second argument, extra, is passed as the ‘extra’ argument to the Element constructor (see its documentation).

if you give a different how/what (third and fourth arguments, optional), then those are passed to the Element constructor.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/vapir-common/element_class_and_module.rb', line 15

def factory(element_object, extra={}, *howwhat)
  curr_klass=self
  # since this gets included in the Element modules, too, check where we are 
  unless self.is_a?(Class) && self < Vapir::Element
    raise TypeError, "factory was called on #{self} (#{self.class}), which is not a Class that is < Element"
  end
  how, what = *case howwhat.length
  when 0
    [:element_object, element_object]
  when 2
    howwhat
  else
    raise ArgumentError, "There should be either no how/what arguments, or two (one how, one what); got #{howwhat.length}: #{howwhat.inspect}"
  end
  ObjectSpace.each_object(Class) do |klass|
    if klass < curr_klass
      Vapir::ElementObjectCandidates.match_candidates([element_object], klass.specifiers, klass.all_dom_attr_aliases) do |match|
        curr_klass=klass
        break
      end
    end
  end
  curr_klass.new(how, what, extra.merge(:element_object => element_object, :locate => false))
end

#inspect_these(*inspect_these) ⇒ Object Also known as: inspect_this

notes the given arguments to be inspected by #inspect and #to_s on each inheriting element. each argument may be a symbol, in which case the corresponding method is called on the element, or a hash, with the following keys:

  • :label - how the the attribute is labeled in the string returned by #inspect or #to_s.

    should be a string or symbol (but anything works; #to_s is called on the label).
    
  • :value - can be one of:

    • String starting with ‘@’ - assumes this is an instance variable; gets the value of that instance variable

    • Symbol - assumes it is a method name, gives this to #send on the element. this is most commonly-used.

    • Proc - calls the proc, giving this element as an argument. should return a string. #to_s is called on its return value.

    • anything else - just assumes that that is the value that is wanted in the string. (see Element#attributes_for_stringifying)

  • :if - if defined, should be a proc that returns false/nil if this should not be included in the string, or anything else (that is, any value considered ‘true’) if it should. this element is passed as an argument to the proc.



137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/vapir-common/element_class_and_module.rb', line 137

def inspect_these(*inspect_these)
  inspect_these.each do |inspect_this|
    attribute_to_inspect=case inspect_this
    when Hash
      inspect_this
    when Symbol
      {:label => inspect_this, :value => inspect_this}
    else
      raise ArgumentError, "unrecognized thing to inspect: #{inspect_this} (#{inspect_this.class})"
    end
    class_array_append 'attributes_to_inspect', attribute_to_inspect
  end
end

#inspect_this_if(inspect_this, &block) ⇒ Object

inspect_this_if(inspect_this, &block) is shorthand for inspect_this({:label => inspect_this, :value => inspect_this, :if => block) if a block isn’t given, the :if proc is the result of sending the inspect_this symbol to the element. if inspect_this isn’t a symbol, and no block is given, raises ArgumentError.



155
156
157
158
159
160
161
162
# File 'lib/vapir-common/element_class_and_module.rb', line 155

def inspect_this_if inspect_this, &block
  unless inspect_this.is_a?(Symbol) || block
    raise ArgumentError, "Either give a block, or specify a symbol as the first argument, instead of #{inspect_this.inspect} (#{inspect_this.class})"
  end
  to_inspect={:label => inspect_this, :value => inspect_this}
  to_inspect[:if]= block || proc {|element| element.send(inspect_this) }
  class_array_append 'attributes_to_inspect', to_inspect
end

#parent_element_module(*arg) ⇒ Object



221
222
223
224
# File 'lib/vapir-common/element_class_and_module.rb', line 221

def parent_element_module(*arg)
  defined_parent=set_or_get_class_var('@@parent_element_module', *arg)
  defined_parent || (self==Watir::Element ? nil : Watir::Element)
end

#set_or_get_class_var(class_var, *arg) ⇒ Object



193
194
195
196
197
198
199
200
201
# File 'lib/vapir-common/element_class_and_module.rb', line 193

def set_or_get_class_var(class_var, *arg)
  if arg.length==0
    class_variable_defined?(class_var) ? class_variable_get(class_var) : nil
  elsif arg.length==1
    class_variable_set(class_var, arg.first)
  else
    raise ArgumentError, "#{arg.length} arguments given; expected one or two. arguments were #{arg.inspect}"
  end
end

#specifiersObject



211
212
213
# File 'lib/vapir-common/element_class_and_module.rb', line 211

def specifiers
  class_array_get 'specifiers'
end