Module: Vapir::ElementHelper
- Includes:
- ElementClassAndModuleMethods
- Included in:
- Area, Button, CheckBox, Dd, Div, Dl, Dt, Element, Em, FileField, Form, Frame, H1, H2, H3, H4, H5, H6, Hidden, Image, InputElement, Label, Li, Link, Map, Ol, Option, P, Pre, Radio, SelectList, Span, Strong, TBody, Table, TableCell, TableRow, TextField, Ul
- Defined in:
- lib/vapir-common/element.rb
Instance Method Summary collapse
- #add_specifier(specifier) ⇒ Object
- #container_collection_method(*method_names) ⇒ Object
- #container_single_method(*method_names) ⇒ Object
- #included(including_class) ⇒ Object
Methods included from ElementClassAndModuleMethods
#add_container_method_extra_args, #all_dom_attr_aliases, #all_dom_attrs, #class_array_append, #class_array_get, #class_hash_get, #class_hash_merge, #container_collection_methods, #container_method_extra_args, #container_single_methods, #default_how, #dom_attr, #dom_attr_locate_alias, #dom_function, #dom_setter, #element_collection, #factory, #inspect_these, #inspect_this_if, #parent_element_module, #set_or_get_class_var, #specifiers
Instance Method Details
#add_specifier(specifier) ⇒ Object
249 250 251 |
# File 'lib/vapir-common/element.rb', line 249 def add_specifier(specifier) class_array_append 'specifiers', specifier end |
#container_collection_method(*method_names) ⇒ Object
279 280 281 |
# File 'lib/vapir-common/element.rb', line 279 def container_collection_method(*method_names) class_array_append 'container_collection_methods', *method_names end |
#container_single_method(*method_names) ⇒ Object
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/vapir-common/element.rb', line 253 def container_single_method(*method_names) class_array_append 'container_single_methods', *method_names element_module=self method_names.each do |method_name| Vapir::Element.module_eval do # these methods (Element#parent_table, Element#parent_div, etc) # iterate through parent nodes looking for a parent of the specified # type. if no element of that type is found which is a parent of # self, returns nil. define_method("parent_#{method_name}") do element_class=element_class_for(element_module) parentNode=element_object while true parentNode=parentNode.parentNode unless parentNode && parentNode != document_object # don't ascend up to the document. #TODO/Fix - for IE, comparing WIN32OLEs doesn't really work, this comparison is pointless. return nil end matched=Vapir::ElementObjectCandidates.match_candidates([parentNode], element_class.specifiers, element_class.all_dom_attr_aliases) if matched.size > 0 return element_class.new(:element_object, parentNode, extra_for_contained) # this is a little weird, passing extra_for_contained so that this is the container of its parent. end end end end end end |
#included(including_class) ⇒ Object
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 |
# File 'lib/vapir-common/element.rb', line 285 def included(including_class) including_class.send :extend, ElementClassAndModuleMethods # get Container modules that the including_class includes (ie, Vapir::Firefox::TextField includes the Vapir::Firefox::Container Container module) container_modules=including_class.included_modules.select do |mod| mod.included_modules.include?(Vapir::Container) end container_modules.each do |container_module| class_array_get('container_single_methods').each do |container_single_method| # define both bang-methods (like #text_field!) and not (#text_field) with corresponding :locate option for element_by_howwhat [ {:method_name => container_single_method, :locate => true}, {:method_name => container_single_method.to_s+'!', :locate => :assert}, {:method_name => container_single_method.to_s+'?', :locate => :nil_unless_exists}, ].each do |method_hash| unless container_module.method_defined?(method_hash[:method_name]) container_module.module_eval do define_method(method_hash[:method_name]) do |how, *what_args| # can't take how, what as args because blocks don't do default values so it will want 2 args #locate! # make sure self is located before trying contained stuff what=what_args.shift # what is the first what_arg other_attribute_keys=including_class.container_method_extra_args if what_args.size>other_attribute_keys.length raise ArgumentError, "\##{method_hash[:method_name]} takes 1 to #{2+other_attribute_keys.length} arguments! Got #{([how, what]+what_args).map{|a|a.inspect}.join(', ')}}" end if what_args.size == 0 other_attributes= nil else other_attributes={} what_args.each_with_index do |arg, i| other_attributes[other_attribute_keys[i]]=arg end end element_by_howwhat(including_class, how, what, :locate => method_hash[:locate], :other_attributes => other_attributes) end end end end end class_array_get('container_collection_methods').each do |container_multiple_method| container_module.module_eval do # returns an ElementCollection of Elements that are instances of the including class define_method(container_multiple_method) do ElementCollection.new(self, including_class, extra_for_contained) end end container_module.module_eval do define_method('child_'+container_multiple_method.to_s) do ElementCollection.new(self, including_class, extra_for_contained.merge(:candidates => :childNodes)) end define_method('show_'+container_multiple_method.to_s) do |*io| io=io.first||$stdout # io is a *array so that you don't have to give an arg (since procs don't do default args) element_collection=ElementCollection.new(self, including_class, extra_for_contained) io.write("There are #{element_collection.length} #{container_multiple_method}\n") element_collection.each do |element| io.write(element.to_s) end end alias_deprecated "show#{container_multiple_method.to_s.capitalize}", "show_"+container_multiple_method.to_s end end end # copy constants (like Specifiers) onto classes when inherited # this is here to set the constants of the Element modules below onto the actual classes that instantiate # per-browser (Vapir::IE::TextField, Vapir::Firefox::TextField, etc) so that calling #const_defined? on those # returns true, and so that the constants defined here clobber any inherited stuff from superclasses # which is unwanted. self.constants.each do |const| # copy all of its constants onto wherever it was included to_copy=self.const_get(const) to_copy=to_copy.dup if [Hash, Array, Set].any?{|klass| to_copy.is_a?(klass) } including_class.const_set(const, to_copy) end # now the constants (above) have switched away from constants to class variables, pretty much, so copy those. self.class_variables.each do |class_var| to_copy=class_variable_get(class_var) to_copy=to_copy.dup if [Hash, Array, Set].any?{|klass| to_copy.is_a?(klass) } including_class.send(:class_variable_set, class_var, to_copy) end class << including_class def attributes_to_inspect super_attrs=superclass.respond_to?(:attributes_to_inspect) ? superclass.attributes_to_inspect : [] super_attrs + class_array_get('attributes_to_inspect') end def all_dom_attrs super_attrs=superclass.respond_to?(:all_dom_attrs) ? superclass.all_dom_attrs : [] super_attrs + class_array_get('dom_attrs') end def all_dom_attr_aliases aliases=class_hash_get('dom_attr_aliases').dup super_aliases=superclass.respond_to?(:all_dom_attr_aliases) ? superclass.all_dom_attr_aliases : {} super_aliases.each_pair do |attr, alias_list| aliases[attr] = (aliases[attr] || Set.new) + alias_list end aliases end end end |