mechanize 0.6.11 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mechanize might be problematic. Click here for more details.

Files changed (91) hide show
  1. data/CHANGELOG.txt +8 -0
  2. data/Manifest.txt +31 -22
  3. data/lib/mechanize.rb +2 -652
  4. data/lib/www/mechanize.rb +635 -0
  5. data/lib/www/mechanize/content_type_error.rb +16 -0
  6. data/lib/www/mechanize/cookie.rb +64 -0
  7. data/lib/{mechanize/cookie.rb → www/mechanize/cookie_jar.rb} +0 -60
  8. data/lib/www/mechanize/file.rb +73 -0
  9. data/lib/www/mechanize/file_saver.rb +39 -0
  10. data/lib/{mechanize → www/mechanize}/form.rb +119 -137
  11. data/lib/www/mechanize/form/button.rb +8 -0
  12. data/lib/www/mechanize/form/check_box.rb +13 -0
  13. data/lib/www/mechanize/form/field.rb +28 -0
  14. data/lib/www/mechanize/form/file_upload.rb +24 -0
  15. data/lib/www/mechanize/form/image_button.rb +23 -0
  16. data/lib/www/mechanize/form/multi_select_list.rb +69 -0
  17. data/lib/www/mechanize/form/option.rb +51 -0
  18. data/lib/www/mechanize/form/radio_button.rb +38 -0
  19. data/lib/www/mechanize/form/select_list.rb +41 -0
  20. data/lib/www/mechanize/headers.rb +12 -0
  21. data/lib/{mechanize → www/mechanize}/history.rb +0 -0
  22. data/lib/{mechanize → www/mechanize}/inspect.rb +21 -28
  23. data/lib/{mechanize → www/mechanize}/list.rb +0 -0
  24. data/lib/{mechanize → www/mechanize}/monkey_patch.rb +19 -0
  25. data/lib/www/mechanize/page.rb +121 -0
  26. data/lib/www/mechanize/page/base.rb +10 -0
  27. data/lib/www/mechanize/page/frame.rb +22 -0
  28. data/lib/www/mechanize/page/link.rb +50 -0
  29. data/lib/www/mechanize/page/meta.rb +10 -0
  30. data/lib/www/mechanize/pluggable_parsers.rb +93 -0
  31. data/lib/{mechanize/errors.rb → www/mechanize/response_code_error.rb} +1 -13
  32. data/test/{test_includes.rb → helper.rb} +4 -18
  33. data/test/{test_servlets.rb → servlets.rb} +0 -0
  34. data/test/tc_authenticate.rb +1 -8
  35. data/test/tc_bad_links.rb +3 -10
  36. data/test/tc_blank_form.rb +1 -8
  37. data/test/tc_checkboxes.rb +1 -8
  38. data/test/tc_cookie_class.rb +1 -6
  39. data/test/tc_cookie_jar.rb +1 -7
  40. data/test/tc_cookies.rb +10 -17
  41. data/test/tc_encoded_links.rb +5 -12
  42. data/test/tc_errors.rb +4 -11
  43. data/test/tc_follow_meta.rb +1 -8
  44. data/test/tc_form_action.rb +6 -14
  45. data/test/tc_form_as_hash.rb +1 -9
  46. data/test/tc_form_button.rb +5 -8
  47. data/test/tc_form_no_inputname.rb +1 -8
  48. data/test/tc_forms.rb +16 -24
  49. data/test/tc_frames.rb +3 -10
  50. data/test/tc_gzipping.rb +2 -9
  51. data/test/tc_history.rb +5 -12
  52. data/test/tc_html_unscape_forms.rb +8 -15
  53. data/test/tc_if_modified_since.rb +1 -6
  54. data/test/tc_keep_alive.rb +1 -8
  55. data/test/tc_links.rb +12 -19
  56. data/test/tc_mech.rb +26 -34
  57. data/test/{test_mechanize_file.rb → tc_mechanize_file.rb} +1 -6
  58. data/test/tc_multi_select.rb +10 -17
  59. data/test/tc_no_attributes.rb +1 -8
  60. data/test/tc_page.rb +3 -10
  61. data/test/tc_pluggable_parser.rb +8 -15
  62. data/test/tc_post_form.rb +3 -10
  63. data/test/tc_pretty_print.rb +3 -10
  64. data/test/tc_radiobutton.rb +2 -9
  65. data/test/tc_referer.rb +13 -20
  66. data/test/tc_relative_links.rb +1 -8
  67. data/test/tc_response_code.rb +14 -21
  68. data/test/tc_save_file.rb +1 -9
  69. data/test/tc_select.rb +3 -10
  70. data/test/tc_select_all.rb +2 -10
  71. data/test/tc_select_none.rb +2 -10
  72. data/test/tc_select_noopts.rb +2 -9
  73. data/test/tc_set_fields.rb +2 -9
  74. data/test/tc_ssl_server.rb +5 -12
  75. data/test/tc_subclass.rb +2 -9
  76. data/test/tc_textarea.rb +2 -9
  77. data/test/tc_upload.rb +2 -9
  78. data/test/test_all.rb +4 -43
  79. metadata +96 -80
  80. data/lib/mechanize/form_elements.rb +0 -254
  81. data/lib/mechanize/net-overrides/net/http.rb +0 -2107
  82. data/lib/mechanize/net-overrides/net/https.rb +0 -172
  83. data/lib/mechanize/net-overrides/net/protocol.rb +0 -380
  84. data/lib/mechanize/page.rb +0 -138
  85. data/lib/mechanize/page_elements.rb +0 -77
  86. data/lib/mechanize/parsers/rexml_page.rb +0 -35
  87. data/lib/mechanize/pluggable_parsers.rb +0 -204
  88. data/lib/mechanize/rexml.rb +0 -236
  89. data/setup.rb +0 -1585
  90. data/test/tc_proxy.rb +0 -25
  91. data/test/tc_watches.rb +0 -32
@@ -0,0 +1,16 @@
1
+ module WWW
2
+ class Mechanize
3
+ # =Synopsis
4
+ # This class contains an error for when a pluggable parser tries to
5
+ # parse a content type that it does not know how to handle. For example
6
+ # if WWW::Mechanize::Page were to try to parse a PDF, a ContentTypeError
7
+ # would be thrown.
8
+ class ContentTypeError < RuntimeError
9
+ attr_reader :content_type
10
+
11
+ def initialize(content_type)
12
+ @content_type = content_type
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,64 @@
1
+ require 'time'
2
+ require 'webrick/cookie'
3
+
4
+ module WWW
5
+ class Mechanize
6
+ # This class is used to represent an HTTP Cookie.
7
+ class Cookie < WEBrick::Cookie
8
+ def self.parse(uri, str, log = nil)
9
+ return str.split(/,(?=[^;,]*=)|,$/).collect { |c|
10
+ cookie_elem = c.split(/;/)
11
+ first_elem = cookie_elem.shift
12
+ first_elem.strip!
13
+ key, value = first_elem.split(/=/, 2)
14
+ cookie = new(key, WEBrick::HTTPUtils.dequote(value))
15
+ cookie_elem.each{|pair|
16
+ pair.strip!
17
+ key, value = pair.split(/=/, 2)
18
+ if value
19
+ value = WEBrick::HTTPUtils.dequote(value.strip)
20
+ end
21
+ case key.downcase
22
+ when "domain" then cookie.domain = value.sub(/^\./, '')
23
+ when "path" then cookie.path = value
24
+ when 'expires'
25
+ begin
26
+ cookie.expires = Time::parse(value)
27
+ rescue
28
+ if log
29
+ log.warn("Couldn't parse expires: #{value}")
30
+ end
31
+ end
32
+ when "max-age" then
33
+ begin
34
+ cookie.max_age = Integer(value)
35
+ rescue
36
+ log.warn("Couldn't parse max age '#{value}'") if log
37
+ cookie.max_age = nil
38
+ end
39
+ when "comment" then cookie.comment = value
40
+ when "version" then
41
+ begin
42
+ cookie.version = Integer(value)
43
+ rescue
44
+ log.warn("Couldn't parse version '#{value}'") if log
45
+ cookie.version = nil
46
+ end
47
+ when "secure" then cookie.secure = true
48
+ end
49
+ }
50
+
51
+ cookie.path ||= uri.path.to_s.sub(/[^\/]*$/, '')
52
+ cookie.secure ||= false
53
+ cookie.domain ||= uri.host
54
+ # Move this in to the cookie jar
55
+ yield cookie if block_given?
56
+ }
57
+ end
58
+
59
+ def to_s
60
+ "#{@name}=#{@value}"
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,67 +1,7 @@
1
1
  require 'yaml'
2
- require 'time'
3
- require 'webrick/cookie'
4
2
 
5
3
  module WWW
6
4
  class Mechanize
7
- # This class is used to represent an HTTP Cookie.
8
- class Cookie < WEBrick::Cookie
9
- def self.parse(uri, str, log = nil)
10
- return str.split(/,(?=[^;,]*=)|,$/).collect { |c|
11
- cookie_elem = c.split(/;/)
12
- first_elem = cookie_elem.shift
13
- first_elem.strip!
14
- key, value = first_elem.split(/=/, 2)
15
- cookie = new(key, WEBrick::HTTPUtils.dequote(value))
16
- cookie_elem.each{|pair|
17
- pair.strip!
18
- key, value = pair.split(/=/, 2)
19
- if value
20
- value = WEBrick::HTTPUtils.dequote(value.strip)
21
- end
22
- case key.downcase
23
- when "domain" then cookie.domain = value.sub(/^\./, '')
24
- when "path" then cookie.path = value
25
- when 'expires'
26
- begin
27
- cookie.expires = Time::parse(value)
28
- rescue
29
- if log
30
- log.warn("Couldn't parse expires: #{value}")
31
- end
32
- end
33
- when "max-age" then
34
- begin
35
- cookie.max_age = Integer(value)
36
- rescue
37
- log.warn("Couldn't parse max age '#{value}'") if log
38
- cookie.max_age = nil
39
- end
40
- when "comment" then cookie.comment = value
41
- when "version" then
42
- begin
43
- cookie.version = Integer(value)
44
- rescue
45
- log.warn("Couldn't parse version '#{value}'") if log
46
- cookie.version = nil
47
- end
48
- when "secure" then cookie.secure = true
49
- end
50
- }
51
-
52
- cookie.path ||= uri.path.to_s.sub(/[^\/]*$/, '')
53
- cookie.secure ||= false
54
- cookie.domain ||= uri.host
55
- # Move this in to the cookie jar
56
- yield cookie if block_given?
57
- }
58
- end
59
-
60
- def to_s
61
- "#{@name}=#{@value}"
62
- end
63
- end
64
-
65
5
  # This class is used to manage the Cookies that have been returned from
66
6
  # any particular website.
67
7
  class CookieJar
@@ -0,0 +1,73 @@
1
+ module WWW
2
+ class Mechanize
3
+ # = Synopsis
4
+ # This is the default (and base) class for the Pluggable Parsers. If
5
+ # Mechanize cannot find an appropriate class to use for the content type,
6
+ # this class will be used. For example, if you download a JPG, Mechanize
7
+ # will not know how to parse it, so this class will be instantiated.
8
+ #
9
+ # This is a good class to use as the base class for building your own
10
+ # pluggable parsers.
11
+ #
12
+ # == Example
13
+ # require 'rubygems'
14
+ # require 'mechanize'
15
+ #
16
+ # agent = WWW::Mechanize.new
17
+ # agent.get('http://example.com/foo.jpg').class #=> WWW::Mechanize::File
18
+ #
19
+ class File
20
+ attr_accessor :uri, :response, :body, :code, :filename
21
+ alias :header :response
22
+
23
+ alias :content :body
24
+
25
+ def initialize(uri=nil, response=nil, body=nil, code=nil)
26
+ @uri, @body, @code = uri, body, code
27
+ @response = Headers.new
28
+
29
+ # Copy the headers in to a hash to prevent memory leaks
30
+ if response
31
+ response.each { |k,v|
32
+ @response[k] = v
33
+ }
34
+ end
35
+
36
+ @filename = 'index.html'
37
+
38
+ # Set the filename
39
+ if disposition = @response['content-disposition']
40
+ disposition.split(/;\s*/).each do |pair|
41
+ k,v = pair.split(/=/, 2)
42
+ @filename = v if k.downcase == 'filename'
43
+ end
44
+ else
45
+ if @uri
46
+ @filename = @uri.path.split(/\//).last || 'index.html'
47
+ @filename << ".html" unless @filename =~ /\./
48
+ end
49
+ end
50
+
51
+ yield self if block_given?
52
+ end
53
+
54
+ # Use this method to save the content of this object to filename
55
+ def save_as(filename = nil)
56
+ if filename.nil?
57
+ filename = @filename
58
+ number = 1
59
+ while(::File.exists?(filename))
60
+ filename = "#{@filename}.#{number}"
61
+ number += 1
62
+ end
63
+ end
64
+
65
+ ::File::open(filename, "wb") { |f|
66
+ f.write body
67
+ }
68
+ end
69
+
70
+ alias :save :save_as
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,39 @@
1
+ module WWW
2
+ class Mechanize
3
+ # = Synopsis
4
+ # This is a pluggable parser that automatically saves every file
5
+ # it encounters. It saves the files as a tree, reflecting the
6
+ # host and file path.
7
+ #
8
+ # == Example to save all PDF's
9
+ # require 'rubygems'
10
+ # require 'mechanize'
11
+ #
12
+ # agent = WWW::Mechanize.new
13
+ # agent.pluggable_parser.pdf = WWW::Mechanize::FileSaver
14
+ # agent.get('http://example.com/foo.pdf')
15
+ #
16
+ class FileSaver < File
17
+ attr_reader :filename
18
+
19
+ def initialize(uri=nil, response=nil, body=nil, code=nil)
20
+ super(uri, response, body, code)
21
+ path = uri.path.empty? ? 'index.html' : uri.path.gsub(/^[\/]*/, '')
22
+ path += 'index.html' if path =~ /\/$/
23
+
24
+ split_path = path.split(/\//)
25
+ filename = split_path.length > 0 ? split_path.pop : 'index.html'
26
+ joined_path = split_path.join(::File::SEPARATOR)
27
+ path = if joined_path.empty?
28
+ uri.host
29
+ else
30
+ "#{uri.host}#{::File::SEPARATOR}#{joined_path}"
31
+ end
32
+
33
+ @filename = "#{path}#{::File::SEPARATOR}#{filename}"
34
+ FileUtils.mkdir_p(path)
35
+ save_as(@filename)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,27 +1,28 @@
1
+ require 'www/mechanize/form/field'
2
+ require 'www/mechanize/form/file_upload'
3
+ require 'www/mechanize/form/button'
4
+ require 'www/mechanize/form/image_button'
5
+ require 'www/mechanize/form/radio_button'
6
+ require 'www/mechanize/form/check_box'
7
+ require 'www/mechanize/form/multi_select_list'
8
+ require 'www/mechanize/form/select_list'
9
+ require 'www/mechanize/form/option'
10
+
1
11
  module WWW
2
12
  class Mechanize
3
13
  # =Synopsis
4
- # GlobalForm provides all access to form fields, such as the buttons,
5
- # check boxes, and text input.
6
- #
7
- # GlobalForm takes two nodes, the node where the form tag is located
8
- # (form_node), and another node, from which to start looking for form
9
- # elements (elements_node) like buttons and the like. For class Form
10
- # both fall together into one and the same node.
11
- #
12
- # Class Form does not work in the case there is some invalid (unbalanced)
13
- # html involved, such as:
14
+ # This class encapsulates a form parsed out of an HTML page. Each type
15
+ # of input fields available in a form can be accessed through this object.
16
+ # See GlobalForm for more methods.
14
17
  #
15
- # <td>
16
- # <form>
17
- # </td>
18
- # <td>
19
- # <input .../>
20
- # </form>
21
- # </td>
22
- #
23
- class GlobalForm
24
- attr_reader :form_node, :elements_node
18
+ # ==Example
19
+ # Find a form and print out its fields
20
+ # form = page.forms.first # => WWW::Mechanize::Form
21
+ # form.fields.each { |f| puts f.name }
22
+ # Set the input field 'name' to "Aaron"
23
+ # form['name'] = 'Aaron'
24
+ # puts form['name']
25
+ class Form
25
26
  attr_accessor :method, :action, :name
26
27
 
27
28
  attr_reader :fields, :buttons, :file_uploads, :radiobuttons, :checkboxes
@@ -29,18 +30,104 @@ module WWW
29
30
 
30
31
  alias :elements :fields
31
32
 
32
- def initialize(form_node, elements_node)
33
- @form_node, @elements_node = form_node, elements_node
34
-
35
- @method = (@form_node['method'] || 'GET').upcase
36
- @action = Util::html_unescape(@form_node['action'])
37
- @name = @form_node['name']
38
- @enctype = @form_node['enctype'] || 'application/x-www-form-urlencoded'
39
- @clicked_buttons = []
33
+ attr_reader :form_node
34
+ attr_reader :page
40
35
 
36
+ def initialize(node, mech=nil, page=nil)
37
+ @enctype = node['enctype'] || 'application/x-www-form-urlencoded'
38
+ @form_node = node
39
+ @action = Mechanize.html_unescape(node['action'])
40
+ @method = (node['method'] || 'GET').upcase
41
+ @name = node['name']
42
+ @clicked_buttons = []
43
+ @page = page
44
+ @mech = mech
45
+
41
46
  parse
42
47
  end
43
-
48
+
49
+ # Returns whether or not the form contains a field with +field_name+
50
+ def has_field?(field_name)
51
+ ! fields.find { |f| f.name.eql? field_name }.nil?
52
+ end
53
+
54
+ alias :has_key? :has_field?
55
+
56
+ def has_value?(value)
57
+ ! fields.find { |f| f.value.eql? value }.nil?
58
+ end
59
+
60
+ def keys; fields.map { |f| f.name }; end
61
+
62
+ def values; fields.map { |f| f.value }; end
63
+
64
+ # Fetch the first field whose name is equal to +field_name+
65
+ def field(field_name)
66
+ fields.find { |f| f.name.eql? field_name }
67
+ end
68
+
69
+ # Add a field with +field_name+ and +value+
70
+ def add_field!(field_name, value = nil)
71
+ fields << Field.new(field_name, value)
72
+ end
73
+
74
+ # This method sets multiple fields on the form. It takes a list of field
75
+ # name, value pairs. If there is more than one field found with the
76
+ # same name, this method will set the first one found. If you want to
77
+ # set the value of a duplicate field, use a value which is an Array with
78
+ # the second value of the array as the index in to the form. The index
79
+ # is zero based. For example, to set the second field named 'foo', you
80
+ # could do the following:
81
+ # form.set_fields( :foo => ['bar', 1] )
82
+ def set_fields(fields = {})
83
+ fields.each do |k,v|
84
+ value = nil
85
+ index = 0
86
+ v.each do |val|
87
+ index = val.to_i unless value.nil?
88
+ value = val if value.nil?
89
+ end
90
+ self.fields.name(k.to_s).[](index).value = value
91
+ end
92
+ end
93
+
94
+ # Fetch the value of the first input field with the name passed in
95
+ # ==Example
96
+ # Fetch the value set in the input field 'name'
97
+ # puts form['name']
98
+ def [](field_name)
99
+ f = field(field_name)
100
+ f && f.value
101
+ end
102
+
103
+ # Set the value of the first input field with the name passed in
104
+ # ==Example
105
+ # Set the value in the input field 'name' to "Aaron"
106
+ # form['name'] = 'Aaron'
107
+ def []=(field_name, value)
108
+ f = field(field_name)
109
+ if f.nil?
110
+ add_field!(field_name, value)
111
+ else
112
+ f.value = value
113
+ end
114
+ end
115
+
116
+ # Treat form fields like accessors.
117
+ def method_missing(id,*args)
118
+ method = id.to_s.gsub(/=$/, '')
119
+ if field(method)
120
+ return field(method).value if args.empty?
121
+ return field(method).value = args[0]
122
+ end
123
+ super
124
+ end
125
+
126
+ # Submit this form with the button passed in
127
+ def submit(button=nil)
128
+ @mech.submit(self, button)
129
+ end
130
+
44
131
  # This method builds an array of arrays that represent the query
45
132
  # parameters to be used with this form. The return value can then
46
133
  # be used to create a query string for this form.
@@ -119,7 +206,7 @@ module WWW
119
206
  @checkboxes = WWW::Mechanize::List.new
120
207
 
121
208
  # Find all input tags
122
- (@elements_node/'input').each do |node|
209
+ (form_node/'input').each do |node|
123
210
  type = (node['type'] || 'text').downcase
124
211
  name = node['name']
125
212
  next if name.nil? && !(type == 'submit' || type =='button')
@@ -142,13 +229,13 @@ module WWW
142
229
  end
143
230
 
144
231
  # Find all textarea tags
145
- (@elements_node/'textarea').each do |node|
232
+ (form_node/'textarea').each do |node|
146
233
  next if node['name'].nil?
147
234
  @fields << Field.new(node['name'], node.inner_text)
148
235
  end
149
236
 
150
237
  # Find all select tags
151
- (@elements_node/'select').each do |node|
238
+ (form_node/'select').each do |node|
152
239
  next if node['name'].nil?
153
240
  if node.has_attribute? 'multiple'
154
241
  @fields << MultiSelectList.new(node['name'], node)
@@ -202,110 +289,5 @@ module WWW
202
289
  body
203
290
  end
204
291
  end
205
-
206
- # =Synopsis
207
- # This class encapsulates a form parsed out of an HTML page. Each type
208
- # of input fields available in a form can be accessed through this object.
209
- # See GlobalForm for more methods.
210
- #
211
- # ==Example
212
- # Find a form and print out its fields
213
- # form = page.forms.first # => WWW::Mechanize::Form
214
- # form.fields.each { |f| puts f.name }
215
- # Set the input field 'name' to "Aaron"
216
- # form['name'] = 'Aaron'
217
- # puts form['name']
218
- class Form < GlobalForm
219
- attr_reader :node
220
- attr_reader :page
221
-
222
- def initialize(node, mech=nil, page=nil)
223
- super(node, node)
224
- @page = page
225
- @mech = mech
226
- end
227
-
228
- # Returns whether or not the form contains a field with +field_name+
229
- def has_field?(field_name)
230
- ! fields.find { |f| f.name.eql? field_name }.nil?
231
- end
232
-
233
- alias :has_key? :has_field?
234
-
235
- def has_value?(value)
236
- ! fields.find { |f| f.value.eql? value }.nil?
237
- end
238
-
239
- def keys; fields.map { |f| f.name }; end
240
-
241
- def values; fields.map { |f| f.value }; end
242
-
243
- # Fetch the first field whose name is equal to +field_name+
244
- def field(field_name)
245
- fields.find { |f| f.name.eql? field_name }
246
- end
247
-
248
- # Add a field with +field_name+ and +value+
249
- def add_field!(field_name, value = nil)
250
- fields << WWW::Mechanize::Field.new(field_name, value)
251
- end
252
-
253
- # This method sets multiple fields on the form. It takes a list of field
254
- # name, value pairs. If there is more than one field found with the
255
- # same name, this method will set the first one found. If you want to
256
- # set the value of a duplicate field, use a value which is an Array with
257
- # the second value of the array as the index in to the form. The index
258
- # is zero based. For example, to set the second field named 'foo', you
259
- # could do the following:
260
- # form.set_fields( :foo => ['bar', 1] )
261
- def set_fields(fields = {})
262
- fields.each do |k,v|
263
- value = nil
264
- index = 0
265
- v.each do |val|
266
- index = val.to_i unless value.nil?
267
- value = val if value.nil?
268
- end
269
- self.fields.name(k.to_s).[](index).value = value
270
- end
271
- end
272
-
273
- # Fetch the value of the first input field with the name passed in
274
- # ==Example
275
- # Fetch the value set in the input field 'name'
276
- # puts form['name']
277
- def [](field_name)
278
- f = field(field_name)
279
- f && f.value
280
- end
281
-
282
- # Set the value of the first input field with the name passed in
283
- # ==Example
284
- # Set the value in the input field 'name' to "Aaron"
285
- # form['name'] = 'Aaron'
286
- def []=(field_name, value)
287
- f = field(field_name)
288
- if f.nil?
289
- add_field!(field_name, value)
290
- else
291
- f.value = value
292
- end
293
- end
294
-
295
- # Treat form fields like accessors.
296
- def method_missing(id,*args)
297
- method = id.to_s.gsub(/=$/, '')
298
- if field(method)
299
- return field(method).value if args.empty?
300
- return field(method).value = args[0]
301
- end
302
- super
303
- end
304
-
305
- # Submit this form with the button passed in
306
- def submit(button=nil)
307
- @mech.submit(self, button)
308
- end
309
- end
310
292
  end
311
293
  end