mechanize 2.7.3 → 2.7.4

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -0
  3. data/.travis.yml +5 -6
  4. data/CHANGELOG.rdoc +22 -0
  5. data/EXAMPLES.rdoc +1 -1
  6. data/Gemfile +3 -0
  7. data/Manifest.txt +0 -1
  8. data/README.rdoc +11 -17
  9. data/Rakefile +22 -38
  10. data/examples/{rubyforge.rb → rubygems.rb} +5 -4
  11. data/lib/mechanize.rb +72 -31
  12. data/lib/mechanize/directory_saver.rb +14 -2
  13. data/lib/mechanize/element_matcher.rb +24 -13
  14. data/lib/mechanize/file_response.rb +1 -3
  15. data/lib/mechanize/form.rb +8 -2
  16. data/lib/mechanize/http/agent.rb +38 -30
  17. data/lib/mechanize/http/auth_store.rb +2 -0
  18. data/lib/mechanize/http/www_authenticate_parser.rb +1 -1
  19. data/lib/mechanize/page.rb +162 -54
  20. data/lib/mechanize/page/image.rb +2 -0
  21. data/lib/mechanize/page/link.rb +5 -0
  22. data/lib/mechanize/pluggable_parsers.rb +13 -1
  23. data/lib/mechanize/test_case.rb +5 -0
  24. data/lib/mechanize/unsupported_scheme_error.rb +4 -2
  25. data/lib/mechanize/util.rb +88 -43
  26. data/lib/mechanize/version.rb +3 -0
  27. data/mechanize.gemspec +61 -0
  28. data/test/test_mechanize.rb +55 -41
  29. data/test/test_mechanize_form.rb +19 -0
  30. data/test/test_mechanize_form_encoding.rb +2 -7
  31. data/test/test_mechanize_http_agent.rb +61 -12
  32. data/test/test_mechanize_http_www_authenticate_parser.rb +8 -0
  33. data/test/test_mechanize_link.rb +14 -1
  34. data/test/test_mechanize_page.rb +53 -6
  35. data/test/test_mechanize_page_encoding.rb +2 -3
  36. data/test/test_mechanize_page_link.rb +17 -2
  37. data/test/test_mechanize_util.rb +45 -10
  38. metadata +147 -72
  39. data/.gemtest +0 -0
  40. data/lib/mechanize/monkey_patch.rb +0 -17
@@ -16,7 +16,8 @@ class Mechanize::DirectorySaver < Mechanize::Download
16
16
  # Creates a DirectorySaver subclass that will save responses to the given
17
17
  # +directory+. If +options+ includes a +decode_filename+ value set to +true+
18
18
  # then the downloaded filename will be ran through +CGI.unescape+ before
19
- # being saved.
19
+ # being saved. If +options+ includes a +overwrite+ value set to +true+ then
20
+ # downloaded file will be overwritten if two files with the same names exist.
20
21
 
21
22
  def self.save_to directory, options = {}
22
23
  directory = File.expand_path directory
@@ -41,6 +42,13 @@ class Mechanize::DirectorySaver < Mechanize::Download
41
42
  @options[:decode_filename]
42
43
  end
43
44
 
45
+ ##
46
+ # Checks if +overwrite+ parameter is set to true
47
+
48
+ def self.overwrite?
49
+ @options[:overwrite]
50
+ end
51
+
44
52
  ##
45
53
  # Saves the +body_io+ into the directory specified for this DirectorySaver
46
54
  # by save_to. The filename is chosen by Mechanize::Parser#extract_filename.
@@ -58,7 +66,11 @@ class Mechanize::DirectorySaver < Mechanize::Download
58
66
  @filename = CGI.unescape(@filename) if self.class.decode_filename?
59
67
  path = File.join directory, @filename
60
68
 
61
- save path
69
+ if self.class.overwrite?
70
+ save! path
71
+ else
72
+ save path
73
+ end
62
74
  end
63
75
 
64
76
  end
@@ -3,17 +3,28 @@ module Mechanize::ElementMatcher
3
3
  def elements_with singular, plural = "#{singular}s"
4
4
  class_eval <<-CODE
5
5
  def #{plural}_with criteria = {}
6
- criteria = if String === criteria then
7
- {:name => criteria}
8
- else
9
- Hash[criteria.map do |k, v|
10
- k = :dom_id if k.to_sym == :id
11
- k = :dom_class if k.to_sym == :class
12
- [k, v]
13
- end]
14
- end
15
-
16
- f = select_#{plural}(criteria.delete(:search)).find_all do |thing|
6
+ selector = method = nil
7
+ if String === criteria then
8
+ criteria = {:name => criteria}
9
+ else
10
+ criteria = criteria.each_with_object({}) { |(k, v), h|
11
+ case k = k.to_sym
12
+ when :id
13
+ h[:dom_id] = v
14
+ when :class
15
+ h[:dom_class] = v
16
+ when :search, :xpath, :css
17
+ if v
18
+ selector = v
19
+ method = k
20
+ end
21
+ else
22
+ h[k] = v
23
+ end
24
+ }
25
+ end
26
+
27
+ f = select_#{plural}(selector, method).find_all do |thing|
17
28
  criteria.all? do |k,v|
18
29
  v === thing.send(k)
19
30
  end
@@ -35,11 +46,11 @@ module Mechanize::ElementMatcher
35
46
  f
36
47
  end
37
48
 
38
- def select_#{plural} selector
49
+ def select_#{plural} selector, method = :search
39
50
  if selector.nil? then
40
51
  #{plural}
41
52
  else
42
- nodes = search(selector)
53
+ nodes = __send__(method, selector)
43
54
  #{plural}.find_all do |element|
44
55
  nodes.include?(element.node)
45
56
  end
@@ -69,9 +69,7 @@ class Mechanize::FileResponse
69
69
  }
70
70
  body << %w[</body></html>]
71
71
 
72
- body = body.join "\n"
73
- body.force_encoding Encoding::BINARY if body.respond_to? :force_encoding
74
- body
72
+ body.join("\n").force_encoding(Encoding::BINARY)
75
73
  end
76
74
 
77
75
  def directory?
@@ -330,6 +330,13 @@ class Mechanize::Form
330
330
  @clicked_buttons << button
331
331
  end
332
332
 
333
+ # This method allows the same form to be submitted second time
334
+ # with the different submit button being clicked.
335
+ def reset
336
+ # In the future, should add more functionality here to reset the form values to their defaults.
337
+ @clicked_buttons = []
338
+ end
339
+
333
340
  # This method calculates the request data to be sent back to the server
334
341
  # for this form, depending on if this is a regular post, get, or a
335
342
  # multi-part post,
@@ -348,8 +355,7 @@ class Mechanize::Form
348
355
  params.concat @file_uploads.map { |f| file_to_multipart(f) }
349
356
 
350
357
  params.map do |part|
351
- part.force_encoding('ASCII-8BIT') if part.respond_to? :force_encoding
352
- "--#{boundary}\r\n#{part}"
358
+ "--#{boundary}\r\n#{part.force_encoding(Encoding::ASCII_8BIT)}"
353
359
  end.join('') +
354
360
  "--#{boundary}--\r\n"
355
361
  else
@@ -167,7 +167,7 @@ class Mechanize::HTTP::Agent
167
167
 
168
168
  @scheme_handlers = Hash.new { |h, scheme|
169
169
  h[scheme] = lambda { |link, page|
170
- raise Mechanize::UnsupportedSchemeError, scheme
170
+ raise Mechanize::UnsupportedSchemeError.new(scheme, link)
171
171
  }
172
172
  }
173
173
 
@@ -213,6 +213,10 @@ class Mechanize::HTTP::Agent
213
213
  # +method+ is used to retrieve it, along with the HTTP +headers+, request
214
214
  # +params+ and HTTP +referer+.
215
215
  #
216
+ # The final URI to access is built with +uri+ and +params+, the
217
+ # latter of which is formatted into a string using
218
+ # Mechanize::Util.build_query_string, which see.
219
+ #
216
220
  # +redirects+ tracks the number of redirects experienced when retrieving the
217
221
  # page. If it is over the redirection_limit an error will be raised.
218
222
 
@@ -246,9 +250,13 @@ class Mechanize::HTTP::Agent
246
250
  request['If-Modified-Since'] = last_modified
247
251
  end if @conditional_requests
248
252
 
249
- # Specify timeouts if given
250
- connection.open_timeout = @open_timeout if @open_timeout
251
- connection.read_timeout = @read_timeout if @read_timeout
253
+ # Specify timeouts if supplied and our connection supports them
254
+ if @open_timeout && connection.respond_to?(:open_timeout=)
255
+ connection.open_timeout = @open_timeout
256
+ end
257
+ if @read_timeout && connection.respond_to?(:read_timeout=)
258
+ connection.read_timeout = @read_timeout
259
+ end
252
260
 
253
261
  request_log request
254
262
 
@@ -515,6 +523,8 @@ class Mechanize::HTTP::Agent
515
523
 
516
524
  def request_auth request, uri
517
525
  base_uri = uri + '/'
526
+ base_uri.user = nil
527
+ base_uri.password = nil
518
528
  schemes = @authenticate_methods[base_uri]
519
529
 
520
530
  if realm = schemes[:digest].find { |r| r.uri == base_uri } then
@@ -530,9 +540,7 @@ class Mechanize::HTTP::Agent
530
540
  def request_auth_digest request, uri, realm, base_uri, iis
531
541
  challenge = @digest_challenges[realm]
532
542
 
533
- user, password, = @auth_store.credentials_for uri, realm.realm
534
- uri.user = user
535
- uri.password = password
543
+ uri.user, uri.password, = @auth_store.credentials_for uri, realm.realm
536
544
 
537
545
  auth = @digest_auth.auth_header uri, challenge.to_s, request.method, iis
538
546
  request['Authorization'] = auth
@@ -608,17 +616,7 @@ class Mechanize::HTTP::Agent
608
616
  end
609
617
 
610
618
  url.gsub!(/[^#{0.chr}-#{126.chr}]/o) { |match|
611
- if RUBY_VERSION >= "1.9.0"
612
- Mechanize::Util.uri_escape(match)
613
- else
614
- begin
615
- sprintf('%%%X', match.unpack($KCODE == 'UTF8' ? 'U' : 'C').first)
616
- rescue ArgumentError
617
- # workaround for ruby 1.8 with -Ku but ISO-8859-1 characters in
618
- # URIs. See #227. I can't wait to drop 1.8 support
619
- sprintf('%%%X', match.unpack('C').first)
620
- end
621
- end
619
+ Mechanize::Util.uri_escape(match)
622
620
  }
623
621
 
624
622
  escaped_url = Mechanize::Util.html_unescape(
@@ -679,6 +677,18 @@ class Mechanize::HTTP::Agent
679
677
  uri
680
678
  end
681
679
 
680
+ def secure_resolve!(uri, referer = current_page)
681
+ new_uri = resolve(uri, referer)
682
+
683
+ if (referer_uri = referer && referer.uri) &&
684
+ referer_uri.scheme != 'file'.freeze &&
685
+ new_uri.scheme == 'file'.freeze
686
+ raise Mechanize::Error, "insecure redirect to a file URI"
687
+ end
688
+
689
+ new_uri
690
+ end
691
+
682
692
  def resolve_parameters uri, method, parameters
683
693
  case method
684
694
  when :head, :get, :delete, :trace then
@@ -740,7 +750,7 @@ class Mechanize::HTTP::Agent
740
750
 
741
751
  if existing_realms.include? realm
742
752
  message = 'Digest authentication failed'
743
- raise Mechanize::UnauthorizedError.new(page, challeges, message)
753
+ raise Mechanize::UnauthorizedError.new(page, challenges, message)
744
754
  end
745
755
 
746
756
  existing_realms << realm
@@ -822,7 +832,7 @@ class Mechanize::HTTP::Agent
822
832
  ensure
823
833
  begin
824
834
  if Tempfile === body_io and
825
- (StringIO === out_io or out_io.path != body_io.path) then
835
+ (StringIO === out_io or (out_io and out_io.path != body_io.path)) then
826
836
  body_io.close!
827
837
  end
828
838
  rescue IOError
@@ -861,7 +871,7 @@ class Mechanize::HTTP::Agent
861
871
  def response_follow_meta_refresh response, uri, page, redirects
862
872
  delay, new_url = get_meta_refresh(response, uri, page)
863
873
  return nil unless delay
864
- new_url = new_url ? resolve(new_url, page) : uri
874
+ new_url = new_url ? secure_resolve!(new_url, page) : uri
865
875
 
866
876
  raise Mechanize::RedirectLimitReachedError.new(page, redirects) if
867
877
  redirects + 1 > @redirection_limit
@@ -893,10 +903,9 @@ class Mechanize::HTTP::Agent
893
903
  if use_tempfile? content_length then
894
904
  body_io = make_tempfile 'mechanize-raw'
895
905
  else
896
- body_io = StringIO.new
906
+ body_io = StringIO.new.set_encoding(Encoding::BINARY)
897
907
  end
898
908
 
899
- body_io.set_encoding Encoding::BINARY if body_io.respond_to? :set_encoding
900
909
  total = 0
901
910
 
902
911
  begin
@@ -970,8 +979,9 @@ class Mechanize::HTTP::Agent
970
979
  headers.delete key
971
980
  end
972
981
 
982
+ new_uri = secure_resolve! response['Location'].to_s, page
983
+
973
984
  @history.push(page, page.uri)
974
- new_uri = resolve response['Location'].to_s, page
975
985
 
976
986
  fetch new_uri, redirect_method, headers, [], referer, redirects + 1
977
987
  end
@@ -1086,12 +1096,12 @@ class Mechanize::HTTP::Agent
1086
1096
  # SSL version to use
1087
1097
  def ssl_version
1088
1098
  @http.ssl_version
1089
- end if RUBY_VERSION > '1.9'
1099
+ end
1090
1100
 
1091
1101
  # Sets the SSL version to use
1092
1102
  def ssl_version= ssl_version
1093
1103
  @http.ssl_version = ssl_version
1094
- end if RUBY_VERSION > '1.9'
1104
+ end
1095
1105
 
1096
1106
  # A callback for additional certificate verification. See
1097
1107
  # OpenSSL::SSL::SSLContext#verify_callback
@@ -1141,9 +1151,7 @@ class Mechanize::HTTP::Agent
1141
1151
  # processing.
1142
1152
 
1143
1153
  def auto_io name, read_size, input_io
1144
- out_io = StringIO.new
1145
-
1146
- out_io.set_encoding Encoding::BINARY if out_io.respond_to? :set_encoding
1154
+ out_io = StringIO.new.set_encoding(Encoding::BINARY)
1147
1155
 
1148
1156
  until input_io.eof? do
1149
1157
  if StringIO === out_io and use_tempfile? out_io.size then
@@ -1216,7 +1224,7 @@ class Mechanize::HTTP::Agent
1216
1224
  def make_tempfile name
1217
1225
  io = Tempfile.new name
1218
1226
  io.unlink
1219
- io.binmode if io.respond_to? :binmode
1227
+ io.binmode
1220
1228
  io
1221
1229
  end
1222
1230
 
@@ -93,6 +93,8 @@ only to a particular server you specify.
93
93
  uri = URI uri unless URI === uri
94
94
 
95
95
  uri += '/'
96
+ uri.user = nil
97
+ uri.password = nil
96
98
 
97
99
  realms = @auth_accounts[uri]
98
100
 
@@ -128,7 +128,7 @@ class Mechanize::HTTP::WWWAuthenticateParser
128
128
 
129
129
  def auth_param
130
130
  return nil unless name = token
131
- return nil unless @scanner.scan(/=/)
131
+ return nil unless @scanner.scan(/ *= */)
132
132
 
133
133
  value = if @scanner.peek(1) == '"' then
134
134
  quoted_string
@@ -42,7 +42,7 @@ class Mechanize::Page < Mechanize::File
42
42
  if body
43
43
  # Force the encoding to be 8BIT so we can perform regular expressions.
44
44
  # We'll set it to the detected encoding later
45
- body.force_encoding 'ASCII-8BIT' if body.respond_to? :force_encoding
45
+ body.force_encoding(Encoding::ASCII_8BIT)
46
46
 
47
47
  @encodings.concat self.class.meta_charset body
48
48
 
@@ -92,7 +92,9 @@ class Mechanize::Page < Mechanize::File
92
92
  end
93
93
 
94
94
  def encoding
95
- parser.respond_to?(:encoding) ? parser.encoding : nil
95
+ parser.encoding
96
+ rescue NoMethodError
97
+ nil
96
98
  end
97
99
 
98
100
  # Return whether parser result has errors related to encoding or not.
@@ -109,15 +111,17 @@ class Mechanize::Page < Mechanize::File
109
111
 
110
112
  def parser
111
113
  return @parser if @parser
112
- return nil unless @body
114
+ return unless @body
115
+
116
+ url = @uri && @uri.to_s
113
117
 
114
- if @encoding then
115
- @parser = @mech.html_parser.parse html_body, nil, @encoding
116
- elsif mech.force_default_encoding then
117
- @parser = @mech.html_parser.parse html_body, nil, @mech.default_encoding
118
+ if @encoding
119
+ @parser = mech.html_parser.parse html_body, url, @encoding
120
+ elsif mech.force_default_encoding
121
+ @parser = mech.html_parser.parse html_body, url, @mech.default_encoding
118
122
  else
119
123
  @encodings.reverse_each do |encoding|
120
- @parser = @mech.html_parser.parse html_body, nil, encoding
124
+ @parser = mech.html_parser.parse html_body, url, encoding
121
125
 
122
126
  break unless encoding_error? @parser
123
127
  end
@@ -192,39 +196,71 @@ class Mechanize::Page < Mechanize::File
192
196
  ##
193
197
  # :method: search
194
198
  #
195
- # Search for +paths+ in the page using Nokogiri's #search. The +paths+ can
196
- # be XPath or CSS and an optional Hash of namespaces may be appended.
199
+ # Shorthand for +parser.search+.
197
200
  #
198
- # See Nokogiri::XML::Node#search for further details.
201
+ # See Nokogiri::XML::Node#search for details.
199
202
 
200
- def_delegator :parser, :search, :search
203
+ ##
204
+ # :method: css
205
+ #
206
+ # Shorthand for +parser.css+.
207
+ #
208
+ # See also Nokogiri::XML::Node#css for details.
201
209
 
202
- alias / search
210
+ ##
211
+ # :method: xpath
212
+ #
213
+ # Shorthand for +parser.xpath+.
214
+ #
215
+ # See also Nokogiri::XML::Node#xpath for details.
203
216
 
204
217
  ##
205
218
  # :method: at
206
219
  #
207
- # Search through the page for +path+ under +namespace+ using Nokogiri's #at.
208
- # The +path+ may be either a CSS or XPath expression.
220
+ # Shorthand for +parser.at+.
221
+ #
222
+ # See also Nokogiri::XML::Node#at for details.
223
+
224
+ ##
225
+ # :method: at_css
226
+ #
227
+ # Shorthand for +parser.at_css+.
228
+ #
229
+ # See also Nokogiri::XML::Node#at_css for details.
230
+
231
+ ##
232
+ # :method: at_xpath
209
233
  #
210
- # See also Nokogiri::XML::Node#at
234
+ # Shorthand for +parser.at_xpath+.
235
+ #
236
+ # See also Nokogiri::XML::Node#at_xpath for details.
211
237
 
212
- def_delegator :parser, :at, :at
238
+ def_delegators :parser, :search, :css, :xpath, :at, :at_css, :at_xpath
239
+
240
+ alias / search
241
+ alias % at
213
242
 
214
243
  ##
215
244
  # :method: form_with
216
245
  #
217
246
  # :call-seq:
218
247
  # form_with(criteria)
248
+ # form_with(criteria) { |form| ... }
219
249
  #
220
- # Find a single form matching +criteria+.
221
- # Example:
222
- # page.form_with(:action => '/post/login.php') do |f|
250
+ # Find a single form matching +criteria+. See +forms_with+ for
251
+ # details of +criteria+.
252
+ #
253
+ # Examples:
254
+ # page.form_with(action: '/post/login.php') do |f|
223
255
  # ...
224
256
  # end
225
257
 
226
258
  ##
227
- # :mehtod: form_with!(criteria)
259
+ # :method: form_with!(criteria)
260
+ #
261
+ # :call-seq:
262
+ # form_with!(criteria)
263
+ # form_with!(criteria) { |form| ... }
228
264
  #
229
265
  # Same as +form_with+ but raises an ElementNotFoundError if no button matches
230
266
  # +criteria+
@@ -232,11 +268,33 @@ class Mechanize::Page < Mechanize::File
232
268
  ##
233
269
  # :method: forms_with
234
270
  #
235
- # :call-seq: forms_with(criteria)
271
+ # :call-seq:
272
+ # forms_with(name)
273
+ # forms_with(name: name_matcher, id: id_matcher, class: class_matcher,
274
+ # search: search_expression, xpath: xpath_expression, css: css_expression,
275
+ # action: action_matcher, ...)
276
+ #
277
+ # Find all forms form matching criteria. If a string is given, it
278
+ # is taken as a name attribute value. If a hash is given, forms
279
+ # are narrowed by the key-value pairs as follows.
280
+ #
281
+ # :id, :dom_id: selects forms with a #dom_id value that matches this
282
+ # value.
283
+ #
284
+ # :class, :dom_class: selects forms with a #dom_class value that
285
+ # matches this value.
286
+ #
287
+ # :search: only selects forms matching this selector expression.
288
+ #
289
+ # :xpath: only selects forms matching this XPath expression.
290
+ #
291
+ # :css: only selects forms matching this CSS selector expression.
292
+ #
293
+ # :action, :method, etc.: narrows forms by a given attribute value
294
+ # using the === operator.
236
295
  #
237
- # Find all forms form matching +criteria+.
238
296
  # Example:
239
- # page.forms_with(:action => '/post/login.php').each do |f|
297
+ # page.forms_with(css: '#content table.login_box form', method: /\APOST\z/i, ).each do |f|
240
298
  # ...
241
299
  # end
242
300
 
@@ -245,14 +303,22 @@ class Mechanize::Page < Mechanize::File
245
303
  ##
246
304
  # :method: link_with
247
305
  #
248
- # :call-seq: link_with(criteria)
306
+ # :call-seq:
307
+ # link_with(criteria)
308
+ # link_with(criteria) { |link| ... }
309
+ #
310
+ # Find a single link matching +criteria+. See +forms_with+ for
311
+ # details of +criteria+, where for "form(s)" read "link(s)".
249
312
  #
250
- # Find a single link matching +criteria+.
251
313
  # Example:
252
- # page.link_with(:href => /foo/).click
314
+ # page.link_with(href: /foo/).click
253
315
 
254
316
  ##
255
- # :mehtod: link_with!(criteria)
317
+ # :method: link_with!
318
+ #
319
+ # :call-seq:
320
+ # link_with!(criteria)
321
+ # link_with!(criteria) { |link| ... }
256
322
  #
257
323
  # Same as +link_with+ but raises an ElementNotFoundError if no button matches
258
324
  # +criteria+
@@ -263,9 +329,11 @@ class Mechanize::Page < Mechanize::File
263
329
  # :call-seq:
264
330
  # links_with(criteria)
265
331
  #
266
- # Find all links matching +criteria+.
332
+ # Find all links matching +criteria+. See +forms_with+ for details
333
+ # of +criteria+, where for "form(s)" read "link(s)".
334
+ #
267
335
  # Example:
268
- # page.links_with(:href => /foo/).each do |link|
336
+ # page.links_with(href: /foo/).each do |link|
269
337
  # puts link.href
270
338
  # end
271
339
 
@@ -274,14 +342,22 @@ class Mechanize::Page < Mechanize::File
274
342
  ##
275
343
  # :method: base_with
276
344
  #
277
- # :call-seq: base_with(criteria)
345
+ # :call-seq:
346
+ # base_with(criteria)
347
+ # base_with(criteria) { |base| ... }
348
+ #
349
+ # Find a single base tag matching +criteria+. See +forms_with+ for
350
+ # details of +criteria+, where for "form(s)" read "base tag(s)".
278
351
  #
279
- # Find a single base tag matching +criteria+.
280
352
  # Example:
281
- # page.base_with(:href => /foo/).click
353
+ # page.base_with(href: /foo/).click
282
354
 
283
355
  ##
284
- # :mehtod: base_with!(criteria)
356
+ # :method: base_with!(criteria)
357
+ #
358
+ # :call-seq:
359
+ # base_with!(criteria)
360
+ # base_with!(criteria) { |base| ... }
285
361
  #
286
362
  # Same as +base_with+ but raises an ElementNotFoundError if no button matches
287
363
  # +criteria+
@@ -291,9 +367,11 @@ class Mechanize::Page < Mechanize::File
291
367
  #
292
368
  # :call-seq: bases_with(criteria)
293
369
  #
294
- # Find all base tags matching +criteria+.
370
+ # Find all base tags matching +criteria+. See +forms_with+ for
371
+ # details of +criteria+, where for "form(s)" read "base tag(s)".
372
+ #
295
373
  # Example:
296
- # page.bases_with(:href => /foo/).each do |base|
374
+ # page.bases_with(href: /foo/).each do |base|
297
375
  # puts base.href
298
376
  # end
299
377
 
@@ -302,14 +380,22 @@ class Mechanize::Page < Mechanize::File
302
380
  ##
303
381
  # :method: frame_with
304
382
  #
305
- # :call-seq: frame_with(criteria)
383
+ # :call-seq:
384
+ # frame_with(criteria)
385
+ # frame_with(criteria) { |frame| ... }
386
+ #
387
+ # Find a single frame tag matching +criteria+. See +forms_with+ for
388
+ # details of +criteria+, where for "form(s)" read "frame tag(s)".
306
389
  #
307
- # Find a single frame tag matching +criteria+.
308
390
  # Example:
309
- # page.frame_with(:src => /foo/).click
391
+ # page.frame_with(src: /foo/).click
310
392
 
311
393
  ##
312
- # :mehtod: frame_with!(criteria)
394
+ # :method: frame_with!
395
+ #
396
+ # :call-seq:
397
+ # frame_with!(criteria)
398
+ # frame_with!(criteria) { |frame| ... }
313
399
  #
314
400
  # Same as +frame_with+ but raises an ElementNotFoundError if no button matches
315
401
  # +criteria+
@@ -319,9 +405,11 @@ class Mechanize::Page < Mechanize::File
319
405
  #
320
406
  # :call-seq: frames_with(criteria)
321
407
  #
322
- # Find all frame tags matching +criteria+.
408
+ # Find all frame tags matching +criteria+. See +forms_with+ for
409
+ # details of +criteria+, where for "form(s)" read "frame tag(s)".
410
+ #
323
411
  # Example:
324
- # page.frames_with(:src => /foo/).each do |frame|
412
+ # page.frames_with(src: /foo/).each do |frame|
325
413
  # p frame.src
326
414
  # end
327
415
 
@@ -330,14 +418,22 @@ class Mechanize::Page < Mechanize::File
330
418
  ##
331
419
  # :method: iframe_with
332
420
  #
333
- # :call-seq: iframe_with(criteria)
421
+ # :call-seq:
422
+ # iframe_with(criteria)
423
+ # iframe_with(criteria) { |iframe| ... }
424
+ #
425
+ # Find a single iframe tag matching +criteria+. See +forms_with+ for
426
+ # details of +criteria+, where for "form(s)" read "iframe tag(s)".
334
427
  #
335
- # Find a single iframe tag matching +criteria+.
336
428
  # Example:
337
- # page.iframe_with(:src => /foo/).click
429
+ # page.iframe_with(src: /foo/).click
338
430
 
339
431
  ##
340
- # :mehtod: iframe_with!(criteria)
432
+ # :method: iframe_with!
433
+ #
434
+ # :call-seq:
435
+ # iframe_with!(criteria)
436
+ # iframe_with!(criteria) { |iframe| ... }
341
437
  #
342
438
  # Same as +iframe_with+ but raises an ElementNotFoundError if no button
343
439
  # matches +criteria+
@@ -347,9 +443,11 @@ class Mechanize::Page < Mechanize::File
347
443
  #
348
444
  # :call-seq: iframes_with(criteria)
349
445
  #
350
- # Find all iframe tags matching +criteria+.
446
+ # Find all iframe tags matching +criteria+. See +forms_with+ for
447
+ # details of +criteria+, where for "form(s)" read "iframe tag(s)".
448
+ #
351
449
  # Example:
352
- # page.iframes_with(:src => /foo/).each do |iframe|
450
+ # page.iframes_with(src: /foo/).each do |iframe|
353
451
  # p iframe.src
354
452
  # end
355
453
 
@@ -358,14 +456,22 @@ class Mechanize::Page < Mechanize::File
358
456
  ##
359
457
  # :method: image_with
360
458
  #
361
- # :call-seq: image_with(criteria)
459
+ # :call-seq:
460
+ # image_with(criteria)
461
+ # image_with(criteria) { |image| ... }
462
+ #
463
+ # Find a single image matching +criteria+. See +forms_with+ for
464
+ # details of +criteria+, where for "form(s)" read "image(s)".
362
465
  #
363
- # Find a single image matching +criteria+.
364
466
  # Example:
365
- # page.image_with(:alt => /main/).fetch.save
467
+ # page.image_with(alt: /main/).fetch.save
366
468
 
367
469
  ##
368
- # :mehtod: image_with!(criteria)
470
+ # :method: image_with!
471
+ #
472
+ # :call-seq:
473
+ # image_with!(criteria)
474
+ # image_with!(criteria) { |image| ... }
369
475
  #
370
476
  # Same as +image_with+ but raises an ElementNotFoundError if no button matches
371
477
  # +criteria+
@@ -375,9 +481,11 @@ class Mechanize::Page < Mechanize::File
375
481
  #
376
482
  # :call-seq: images_with(criteria)
377
483
  #
378
- # Find all images matching +criteria+.
484
+ # Find all images matching +criteria+. See +forms_with+ for
485
+ # details of +criteria+, where for "form(s)" read "image(s)".
486
+ #
379
487
  # Example:
380
- # page.images_with(:src => /jpg\Z/).each do |img|
488
+ # page.images_with(src: /jpg\Z/).each do |img|
381
489
  # img.fetch.save
382
490
  # end
383
491