actionpack 1.9.1 → 1.10.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +237 -0
- data/README +12 -12
- data/lib/action_controller.rb +17 -12
- data/lib/action_controller/assertions.rb +119 -67
- data/lib/action_controller/base.rb +184 -102
- data/lib/action_controller/benchmarking.rb +35 -6
- data/lib/action_controller/caching.rb +115 -58
- data/lib/action_controller/cgi_ext/cgi_methods.rb +54 -21
- data/lib/action_controller/cgi_ext/cookie_performance_fix.rb +39 -35
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +34 -21
- data/lib/action_controller/cgi_process.rb +23 -20
- data/lib/action_controller/components.rb +11 -2
- data/lib/action_controller/dependencies.rb +0 -5
- data/lib/action_controller/deprecated_redirects.rb +17 -0
- data/lib/action_controller/filters.rb +13 -9
- data/lib/action_controller/flash.rb +7 -7
- data/lib/action_controller/helpers.rb +1 -14
- data/lib/action_controller/layout.rb +40 -29
- data/lib/action_controller/macros/auto_complete.rb +52 -0
- data/lib/action_controller/macros/in_place_editing.rb +32 -0
- data/lib/action_controller/pagination.rb +44 -28
- data/lib/action_controller/request.rb +54 -40
- data/lib/action_controller/rescue.rb +8 -6
- data/lib/action_controller/routing.rb +77 -28
- data/lib/action_controller/scaffolding.rb +10 -14
- data/lib/action_controller/session/active_record_store.rb +36 -7
- data/lib/action_controller/session_management.rb +126 -0
- data/lib/action_controller/streaming.rb +14 -5
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +1 -1
- data/lib/action_controller/templates/rescues/_trace.rhtml +24 -0
- data/lib/action_controller/templates/rescues/diagnostics.rhtml +2 -13
- data/lib/action_controller/templates/rescues/template_error.rhtml +4 -2
- data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
- data/lib/action_controller/test_process.rb +35 -17
- data/lib/action_controller/upload_progress.rb +52 -0
- data/lib/action_controller/url_rewriter.rb +21 -16
- data/lib/action_controller/vendor/html-scanner/html/document.rb +2 -2
- data/lib/action_controller/vendor/html-scanner/html/node.rb +30 -3
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +1 -1
- data/lib/action_view/base.rb +204 -60
- data/lib/action_view/compiled_templates.rb +70 -0
- data/lib/action_view/helpers/active_record_helper.rb +7 -3
- data/lib/action_view/helpers/asset_tag_helper.rb +22 -12
- data/lib/action_view/helpers/capture_helper.rb +2 -10
- data/lib/action_view/helpers/date_helper.rb +21 -13
- data/lib/action_view/helpers/form_helper.rb +14 -10
- data/lib/action_view/helpers/form_options_helper.rb +4 -4
- data/lib/action_view/helpers/form_tag_helper.rb +59 -25
- data/lib/action_view/helpers/java_script_macros_helper.rb +188 -0
- data/lib/action_view/helpers/javascript_helper.rb +68 -133
- data/lib/action_view/helpers/javascripts/controls.js +427 -165
- data/lib/action_view/helpers/javascripts/dragdrop.js +256 -277
- data/lib/action_view/helpers/javascripts/effects.js +766 -277
- data/lib/action_view/helpers/javascripts/prototype.js +906 -218
- data/lib/action_view/helpers/javascripts/slider.js +258 -0
- data/lib/action_view/helpers/number_helper.rb +4 -3
- data/lib/action_view/helpers/pagination_helper.rb +42 -27
- data/lib/action_view/helpers/tag_helper.rb +25 -11
- data/lib/action_view/helpers/text_helper.rb +119 -13
- data/lib/action_view/helpers/upload_progress_helper.rb +2 -2
- data/lib/action_view/helpers/url_helper.rb +68 -21
- data/lib/action_view/partials.rb +17 -6
- data/lib/action_view/template_error.rb +19 -24
- data/rakefile +4 -3
- data/test/abstract_unit.rb +2 -1
- data/test/controller/action_pack_assertions_test.rb +62 -2
- data/test/controller/active_record_assertions_test.rb +5 -6
- data/test/controller/active_record_store_test.rb +23 -1
- data/test/controller/addresses_render_test.rb +4 -0
- data/test/controller/{base_tests.rb → base_test.rb} +4 -3
- data/test/controller/benchmark_test.rb +36 -0
- data/test/controller/caching_filestore.rb +22 -40
- data/test/controller/capture_test.rb +10 -1
- data/test/controller/cgi_test.rb +145 -23
- data/test/controller/components_test.rb +50 -0
- data/test/controller/custom_handler_test.rb +3 -3
- data/test/controller/fake_controllers.rb +24 -0
- data/test/controller/filters_test.rb +6 -6
- data/test/controller/flash_test.rb +6 -6
- data/test/controller/fragment_store_setting_test.rb +45 -0
- data/test/controller/helper_test.rb +1 -3
- data/test/controller/new_render_test.rb +119 -7
- data/test/controller/redirect_test.rb +11 -1
- data/test/controller/render_test.rb +34 -1
- data/test/controller/request_test.rb +14 -5
- data/test/controller/routing_test.rb +238 -42
- data/test/controller/send_file_test.rb +11 -10
- data/test/controller/session_management_test.rb +94 -0
- data/test/controller/test_test.rb +194 -5
- data/test/controller/url_rewriter_test.rb +46 -0
- data/test/fixtures/layouts/talk_from_action.rhtml +2 -0
- data/test/fixtures/layouts/yield.rhtml +2 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/large_text_file +10 -0
- data/test/fixtures/multipart/mixed_files +0 -0
- data/test/fixtures/multipart/single_parameter +5 -0
- data/test/fixtures/multipart/text_file +10 -0
- data/test/fixtures/test/_customer_greeting.rhtml +1 -0
- data/test/fixtures/test/_hash_object.rhtml +1 -0
- data/test/fixtures/test/_person.rhtml +2 -0
- data/test/fixtures/test/action_talk_to_layout.rhtml +2 -0
- data/test/fixtures/test/content_for.rhtml +2 -0
- data/test/fixtures/test/potential_conflicts.rhtml +4 -0
- data/test/template/active_record_helper_test.rb +15 -8
- data/test/template/asset_tag_helper_test.rb +40 -16
- data/test/template/compiled_templates_tests.rb +63 -0
- data/test/template/date_helper_test.rb +80 -4
- data/test/template/form_helper_test.rb +48 -42
- data/test/template/form_options_helper_test.rb +40 -40
- data/test/template/form_tag_helper_test.rb +21 -15
- data/test/template/java_script_macros_helper_test.rb +56 -0
- data/test/template/javascript_helper_test.rb +70 -47
- data/test/template/number_helper_test.rb +2 -0
- data/test/template/tag_helper_test.rb +9 -0
- data/test/template/text_helper_test.rb +146 -1
- data/test/template/upload_progress_helper_testx.rb +11 -147
- data/test/template/url_helper_test.rb +90 -22
- data/test/testing_sandbox.rb +26 -0
- metadata +37 -7
- data/lib/action_controller/auto_complete.rb +0 -47
- data/lib/action_controller/deprecated_renders_and_redirects.rb +0 -76
- data/lib/action_controller/session.rb +0 -14
@@ -61,20 +61,20 @@ module ActionController #:nodoc:
|
|
61
61
|
@performed_render = false
|
62
62
|
|
63
63
|
if options[:stream]
|
64
|
-
render :text => Proc.new {
|
64
|
+
render :text => Proc.new { |response, output|
|
65
65
|
logger.info "Streaming file #{path}" unless logger.nil?
|
66
66
|
len = options[:buffer_size] || 4096
|
67
67
|
File.open(path, 'rb') do |file|
|
68
|
-
if
|
68
|
+
if output.respond_to?(:syswrite)
|
69
69
|
begin
|
70
70
|
while true
|
71
|
-
|
71
|
+
output.syswrite(file.sysread(len))
|
72
72
|
end
|
73
73
|
rescue EOFError
|
74
74
|
end
|
75
75
|
else
|
76
76
|
while buf = file.read(len)
|
77
|
-
|
77
|
+
output.write(buf)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -120,6 +120,7 @@ module ActionController #:nodoc:
|
|
120
120
|
end
|
121
121
|
|
122
122
|
disposition = options[:disposition].dup || 'attachment'
|
123
|
+
|
123
124
|
disposition <<= %(; filename="#{options[:filename]}") if options[:filename]
|
124
125
|
|
125
126
|
@headers.update(
|
@@ -127,7 +128,15 @@ module ActionController #:nodoc:
|
|
127
128
|
'Content-Type' => options[:type].strip, # fixes a problem with extra '\r' with some browsers
|
128
129
|
'Content-Disposition' => disposition,
|
129
130
|
'Content-Transfer-Encoding' => 'binary'
|
130
|
-
)
|
131
|
+
)
|
132
|
+
|
133
|
+
# Fix a problem with IE 6.0 on opening downloaded files:
|
134
|
+
# If Cache-Control: no-cache is set (which Rails does by default),
|
135
|
+
# IE removes the file it just downloaded from its cache immediately
|
136
|
+
# after it displays the "open/save" dialog, which means that if you
|
137
|
+
# hit "open" the file isn't there anymore when the application that
|
138
|
+
# is called for handling the download is run, so let's workaround that
|
139
|
+
@headers['Cache-Control'] = 'private' if @headers['Cache-Control'] == 'no-cache'
|
131
140
|
end
|
132
141
|
end
|
133
142
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<pre id="blame_trace" <%='style="display:none"' if hide %>><code><%=h @exception.describe_blame %></code></pre>
|
6
6
|
<% end %>
|
7
7
|
|
8
|
-
<% if
|
8
|
+
<% if false %>
|
9
9
|
<br /><br />
|
10
10
|
<% begin %>
|
11
11
|
<%= form_tag(@request.request_uri, "method" => @request.method) %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%
|
2
|
+
traces = [
|
3
|
+
["Application Trace", @exception.application_backtrace],
|
4
|
+
["Framework Trace", @exception.framework_backtrace],
|
5
|
+
["Full Trace", @exception.clean_backtrace]
|
6
|
+
]
|
7
|
+
names = traces.collect {|name, trace| name}
|
8
|
+
%>
|
9
|
+
|
10
|
+
<div id="traces">
|
11
|
+
<% names.each do |name| -%>
|
12
|
+
<%
|
13
|
+
show = "document.getElementById('#{name.gsub /\s/, '-'}').style.display='block';"
|
14
|
+
hide = (names - [name]).collect {|hide_name| "document.getElementById('#{hide_name.gsub /\s/, '-'}').style.display='none';"}
|
15
|
+
%>
|
16
|
+
<a href="#" onclick="<%= hide %><%= show %>; return false;"><%= name %></a> <%= '|' unless names.last == name %>
|
17
|
+
<% end -%>
|
18
|
+
|
19
|
+
<% traces.each do |name, trace| -%>
|
20
|
+
<div id="<%= name.gsub /\s/, '-' %>" style="display: <%= name == "Application Trace" ? 'block' : 'none' %>;">
|
21
|
+
<pre><code><%= trace.join "\n" %></code></pre>
|
22
|
+
</div>
|
23
|
+
<% end -%>
|
24
|
+
</div>
|
@@ -1,20 +1,9 @@
|
|
1
|
-
<%
|
2
|
-
clean_backtrace = @exception.backtrace.collect { |line| Object.const_defined?(:RAILS_ROOT) ? line.gsub(RAILS_ROOT, "") : line }
|
3
|
-
app_trace = clean_backtrace.reject { |line| line =~ /(vendor|dispatch|ruby)/ }
|
4
|
-
framework_trace = clean_backtrace - app_trace
|
5
|
-
%>
|
6
|
-
|
7
1
|
<h1>
|
8
2
|
<%=h @exception.class.to_s %> in
|
9
3
|
<%=h (@request.parameters["controller"] || "<controller not set>").capitalize %>#<%=h @request.parameters["action"] || "<action not set>" %>
|
10
4
|
</h1>
|
11
|
-
<pre><%=h
|
12
|
-
|
13
|
-
<% unless app_trace.empty? %><pre><code><%=h app_trace.join("\n") %></code></pre><% end %>
|
5
|
+
<pre><%=h @exception.clean_message %></pre>
|
14
6
|
|
15
|
-
|
16
|
-
<a href="#" onclick="document.getElementById('framework_trace').style.display='block'; return false;">Show framework trace</a>
|
17
|
-
<pre id="framework_trace" style="display:none"><code><%=h framework_trace.join("\n") %></code></pre>
|
18
|
-
<% end %>
|
7
|
+
<%= render_file(@rescues_path + "/_trace.rhtml", false) %>
|
19
8
|
|
20
9
|
<%= render_file(@rescues_path + "/_request_and_response.rhtml", false) %>
|
@@ -13,7 +13,9 @@
|
|
13
13
|
|
14
14
|
<p><%=h @exception.sub_template_message %></p>
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
<% @real_exception = @exception
|
17
|
+
@exception = @exception.original_exception || @exception %>
|
18
|
+
<%= render_file(@rescues_path + "/_trace.rhtml", false) %>
|
19
|
+
<% @exception = @real_exception %>
|
18
20
|
|
19
21
|
<%= render_file(@rescues_path + "/_request_and_response.rhtml", false) %>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
<% end %>
|
15
15
|
<td><%= link_to "Show", :action => "show#{@scaffold_suffix}", :id => entry %></td>
|
16
16
|
<td><%= link_to "Edit", :action => "edit#{@scaffold_suffix}", :id => entry %></td>
|
17
|
-
<td><%= link_to "Destroy", :action => "destroy#{@scaffold_suffix}", :id => entry, :confirm => "Are you sure?" %></td>
|
17
|
+
<td><%= link_to "Destroy", {:action => "destroy#{@scaffold_suffix}", :id => entry}, {:confirm => "Are you sure?"} %></td>
|
18
18
|
</tr>
|
19
19
|
<% end %>
|
20
20
|
</table>
|
@@ -11,10 +11,19 @@ module ActionController #:nodoc:
|
|
11
11
|
def process_test(request) #:nodoc:
|
12
12
|
process(request, TestResponse.new)
|
13
13
|
end
|
14
|
+
|
15
|
+
def process_with_test(*args)
|
16
|
+
returning process_without_test(*args) do
|
17
|
+
add_variables_to_assigns
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
alias_method :process_without_test, :process
|
22
|
+
alias_method :process, :process_with_test
|
14
23
|
end
|
15
24
|
|
16
25
|
class TestRequest < AbstractRequest #:nodoc:
|
17
|
-
attr_accessor :cookies
|
26
|
+
attr_accessor :cookies, :session_options
|
18
27
|
attr_accessor :query_parameters, :request_parameters, :path, :session, :env
|
19
28
|
attr_accessor :host
|
20
29
|
|
@@ -35,6 +44,7 @@ module ActionController #:nodoc:
|
|
35
44
|
|
36
45
|
def port=(number)
|
37
46
|
@env["SERVER_PORT"] = number.to_i
|
47
|
+
@port_as_int = nil
|
38
48
|
end
|
39
49
|
|
40
50
|
def action=(action_name)
|
@@ -59,6 +69,10 @@ module ActionController #:nodoc:
|
|
59
69
|
@env['REMOTE_ADDR'] = addr
|
60
70
|
end
|
61
71
|
|
72
|
+
def remote_addr
|
73
|
+
@env['REMOTE_ADDR']
|
74
|
+
end
|
75
|
+
|
62
76
|
def request_uri
|
63
77
|
@request_uri || super()
|
64
78
|
end
|
@@ -102,6 +116,7 @@ module ActionController #:nodoc:
|
|
102
116
|
@request_uri = "/"
|
103
117
|
self.remote_addr = "0.0.0.0"
|
104
118
|
@env["SERVER_PORT"] = 80
|
119
|
+
@env['REQUEST_METHOD'] = "GET"
|
105
120
|
end
|
106
121
|
end
|
107
122
|
|
@@ -110,6 +125,15 @@ module ActionController #:nodoc:
|
|
110
125
|
def response_code
|
111
126
|
headers['Status'][0,3].to_i rescue 0
|
112
127
|
end
|
128
|
+
|
129
|
+
# returns a String to ensure compatibility with Net::HTTPResponse
|
130
|
+
def code
|
131
|
+
headers['Status'].to_s.split(' ')[0]
|
132
|
+
end
|
133
|
+
|
134
|
+
def message
|
135
|
+
headers['Status'].to_s.split(' ',2)[1]
|
136
|
+
end
|
113
137
|
|
114
138
|
# was the response successful?
|
115
139
|
def success?
|
@@ -255,13 +279,14 @@ module Test
|
|
255
279
|
private
|
256
280
|
# execute the request and set/volley the response
|
257
281
|
def process(action, parameters = nil, session = nil, flash = nil)
|
258
|
-
|
259
|
-
|
260
|
-
# Sanity check for required instance variables so we can give an understandable error message.
|
282
|
+
# Sanity check for required instance variables so we can give an
|
283
|
+
# understandable error message.
|
261
284
|
%w(controller request response).each do |iv_name|
|
262
|
-
|
285
|
+
raise "@#{iv_name} is nil: make sure you set it in your test's setup method." if instance_variable_get("@#{iv_name}").nil?
|
263
286
|
end
|
264
287
|
|
288
|
+
@request.recycle!
|
289
|
+
|
265
290
|
@html_document = nil
|
266
291
|
@request.env['REQUEST_METHOD'] ||= "GET"
|
267
292
|
@request.action = action.to_s
|
@@ -277,9 +302,9 @@ module Test
|
|
277
302
|
|
278
303
|
# execute the request simulating a specific http method and set/volley the response
|
279
304
|
%w( get post put delete head ).each do |method|
|
280
|
-
class_eval <<-EOV
|
305
|
+
class_eval <<-EOV, __FILE__, __LINE__
|
281
306
|
def #{method}(action, parameters = nil, session = nil, flash = nil)
|
282
|
-
@request.env['REQUEST_METHOD'] = "#{method.upcase}"
|
307
|
+
@request.env['REQUEST_METHOD'] = "#{method.upcase}" if @request
|
283
308
|
process(action, parameters, session, flash)
|
284
309
|
end
|
285
310
|
EOV
|
@@ -287,7 +312,9 @@ module Test
|
|
287
312
|
|
288
313
|
def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
|
289
314
|
@request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
|
290
|
-
self.send(request_method, action, parameters, session, flash)
|
315
|
+
returning self.send(request_method, action, parameters, session, flash) do
|
316
|
+
@request.env.delete 'HTTP_X_REQUESTED_WITH'
|
317
|
+
end
|
291
318
|
end
|
292
319
|
alias xhr :xml_http_request
|
293
320
|
|
@@ -334,7 +361,6 @@ module Test
|
|
334
361
|
end
|
335
362
|
|
336
363
|
def html_document
|
337
|
-
require_html_scanner
|
338
364
|
@html_document ||= HTML::Document.new(@response.body)
|
339
365
|
end
|
340
366
|
|
@@ -346,14 +372,6 @@ module Test
|
|
346
372
|
html_document.find_all(conditions)
|
347
373
|
end
|
348
374
|
|
349
|
-
def require_html_scanner
|
350
|
-
return true if defined?(HTML::Document)
|
351
|
-
require 'html/document'
|
352
|
-
rescue LoadError
|
353
|
-
$:.unshift File.dirname(__FILE__) + "/vendor/html-scanner"
|
354
|
-
require 'html/document'
|
355
|
-
end
|
356
|
-
|
357
375
|
def method_missing(selector, *args)
|
358
376
|
return @controller.send(selector, *args) if ActionController::Routing::NamedRoutes::Helpers.include?(selector)
|
359
377
|
return super
|
@@ -13,6 +13,9 @@ module ActionController #:nodoc:
|
|
13
13
|
# fully on all the systems that is a part of your environment. Consider this an extended
|
14
14
|
# preview.
|
15
15
|
#
|
16
|
+
# To enable this module, add <tt>ActionController::Base.enable_upload_progress</tt> to your
|
17
|
+
# config/environment.rb file.
|
18
|
+
#
|
16
19
|
# == Action Pack Upload Progress for multipart uploads
|
17
20
|
#
|
18
21
|
# The UploadProgress module aids in the process of viewing an Ajax driven
|
@@ -131,6 +134,55 @@ module ActionController #:nodoc:
|
|
131
134
|
# def custom_status
|
132
135
|
# render :inline => '<%= upload_progress_status %> <div>Updated at <%= Time.now %></div>', :layout => false
|
133
136
|
# end
|
137
|
+
#
|
138
|
+
# ==== Environment checklist
|
139
|
+
#
|
140
|
+
# This is an experimental feature that requires a specific webserver environment. Use the following checklist
|
141
|
+
# to confirm that you have an environment that supports upload progress.
|
142
|
+
#
|
143
|
+
# ===== Ruby:
|
144
|
+
#
|
145
|
+
# * Running the command `ruby -v` should print "ruby 1.8.2 (2004-12-25)" or older
|
146
|
+
#
|
147
|
+
# ===== Web server:
|
148
|
+
#
|
149
|
+
# * Apache 1.3, Apache 2.0 or Lighttpd *1.4* (need to build lighttpd from CVS)
|
150
|
+
#
|
151
|
+
# ===== FastCGI bindings:
|
152
|
+
#
|
153
|
+
# * > 0.8.6 and must be the compiled C version of the bindings
|
154
|
+
# * The command `ruby -e "p require('fcgi.so')"` should print "true"
|
155
|
+
#
|
156
|
+
# ===== Apache/Lighttpd FastCGI directives:
|
157
|
+
#
|
158
|
+
# * You must allow more than one FCGI server process to allow concurrent requests.
|
159
|
+
# * If there is only a single FCGI process you will not get the upload status updates.
|
160
|
+
# * You can check this by taking a look for running FCGI servers in your process list during a progress upload.
|
161
|
+
# * Apache directive: FastCGIConfig -minProcesses 2
|
162
|
+
# * Lighttpd directives taken from config/lighttpd.conf (min-procs):
|
163
|
+
#
|
164
|
+
# fastcgi.server = (
|
165
|
+
# ".fcgi" => (
|
166
|
+
# "APP_NAME" => (
|
167
|
+
# "socket" => "/tmp/APP_NAME1.socket",
|
168
|
+
# "bin-path" => "RAILS_ROOT/public/dispatch.fcgi",
|
169
|
+
# "min-procs" => 2
|
170
|
+
# )
|
171
|
+
# )
|
172
|
+
# )
|
173
|
+
#
|
174
|
+
# ===== config/environment.rb:
|
175
|
+
#
|
176
|
+
# * Add the following line to your config/environment.rb and restart your web server.
|
177
|
+
# * <tt>ActionController::Base.enable_upload_progress</tt>
|
178
|
+
#
|
179
|
+
# ===== Development log:
|
180
|
+
#
|
181
|
+
# * When the upload progress is enabled by you will find something the following lines:
|
182
|
+
# * "Multipart upload with progress (id: 1, size: 85464)"
|
183
|
+
# * "Finished processing multipart upload in 0.363729s"
|
184
|
+
# * If you are properly running multiple FCGI processes, then you will see multiple entries for rendering the "upload_status" action before the "Finish processing..." log entry. This is a *good thing* :)
|
185
|
+
#
|
134
186
|
module UploadProgress
|
135
187
|
def self.append_features(base) #:nodoc:
|
136
188
|
super
|
@@ -20,8 +20,10 @@ module ActionController
|
|
20
20
|
private
|
21
21
|
def rewrite_url(path, options)
|
22
22
|
rewritten_url = ""
|
23
|
-
|
24
|
-
|
23
|
+
unless options[:only_path]
|
24
|
+
rewritten_url << (options[:protocol] || @request.protocol)
|
25
|
+
rewritten_url << (options[:host] || @request.host_with_port)
|
26
|
+
end
|
25
27
|
|
26
28
|
rewritten_url << @request.relative_url_root.to_s unless options[:skip_relative_url_root]
|
27
29
|
rewritten_url << path
|
@@ -33,32 +35,35 @@ module ActionController
|
|
33
35
|
|
34
36
|
def rewrite_path(options)
|
35
37
|
options = options.symbolize_keys
|
36
|
-
options.update(
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
if extras[:overwrite_params]
|
41
|
-
params_copy = @request.parameters.reject { |k,v| %w(controller action).include? k }
|
42
|
-
params_copy.update extras[:overwrite_params]
|
43
|
-
extras.delete(:overwrite_params)
|
44
|
-
extras.update(params_copy)
|
38
|
+
options.update(options[:params].symbolize_keys) if options[:params]
|
39
|
+
if (overwrite = options.delete(:overwrite_params))
|
40
|
+
options.update(@parameters.symbolize_keys)
|
41
|
+
options.update(overwrite)
|
45
42
|
end
|
43
|
+
RESERVED_OPTIONS.each {|k| options.delete k}
|
44
|
+
path, extra_keys = Routing::Routes.generate(options.dup, @request) # Warning: Routes will mutate and violate the options hash
|
46
45
|
|
47
|
-
path <<
|
46
|
+
path << build_query_string(options, extra_keys) unless extra_keys.empty?
|
48
47
|
|
49
48
|
path
|
50
49
|
end
|
51
50
|
|
52
51
|
# Returns a query string with escaped keys and values from the passed hash. If the passed hash contains an "id" it'll
|
53
52
|
# be added as a path element instead of a regular parameter pair.
|
54
|
-
def build_query_string(hash)
|
53
|
+
def build_query_string(hash, only_keys = nil)
|
55
54
|
elements = []
|
56
55
|
query_string = ""
|
56
|
+
|
57
|
+
only_keys ||= hash.keys
|
57
58
|
|
58
|
-
|
59
|
+
only_keys.each do |key|
|
60
|
+
value = hash[key]
|
59
61
|
key = CGI.escape key.to_s
|
60
|
-
|
61
|
-
|
62
|
+
if value.class == Array
|
63
|
+
key << '[]'
|
64
|
+
else
|
65
|
+
value = [ value ]
|
66
|
+
end
|
62
67
|
value.each { |val| elements << "#{key}=#{Routing.extract_parameter_value(val)}" }
|
63
68
|
end
|
64
69
|
|
@@ -11,7 +11,7 @@ module HTML #:nodoc:
|
|
11
11
|
attr_reader :root
|
12
12
|
|
13
13
|
# Create a new Document from the given text.
|
14
|
-
def initialize(text, strict=false)
|
14
|
+
def initialize(text, strict=false, xml=false)
|
15
15
|
tokenizer = Tokenizer.new(text)
|
16
16
|
@root = Node.new(nil)
|
17
17
|
node_stack = [ @root ]
|
@@ -38,7 +38,7 @@ ignoring attempt to close #{node_stack.last.name} with #{node.name}
|
|
38
38
|
EOF
|
39
39
|
strict ? raise(msg) : warn(msg)
|
40
40
|
end
|
41
|
-
elsif !node.childless? && node.closing != :close
|
41
|
+
elsif !node.childless?(xml) && node.closing != :close
|
42
42
|
node_stack.push node
|
43
43
|
end
|
44
44
|
end
|
@@ -122,6 +122,18 @@ module HTML #:nodoc:
|
|
122
122
|
def validate_conditions(conditions)
|
123
123
|
Conditions === conditions ? conditions : Conditions.new(conditions)
|
124
124
|
end
|
125
|
+
|
126
|
+
def ==(node)
|
127
|
+
return false unless self.class == node.class && children.size == node.children.size
|
128
|
+
|
129
|
+
equivalent = true
|
130
|
+
|
131
|
+
children.size.times do |i|
|
132
|
+
equivalent &&= children[i] == node.children[i]
|
133
|
+
end
|
134
|
+
|
135
|
+
equivalent
|
136
|
+
end
|
125
137
|
|
126
138
|
class <<self
|
127
139
|
def parse(parent, line, pos, content, strict=true)
|
@@ -238,6 +250,11 @@ module HTML #:nodoc:
|
|
238
250
|
nil
|
239
251
|
end
|
240
252
|
end
|
253
|
+
|
254
|
+
def ==(node)
|
255
|
+
return false unless super
|
256
|
+
content == node.content
|
257
|
+
end
|
241
258
|
end
|
242
259
|
|
243
260
|
# A Tag is any node that represents markup. It may be an opening tag, a
|
@@ -271,7 +288,8 @@ module HTML #:nodoc:
|
|
271
288
|
end
|
272
289
|
|
273
290
|
# Returns non-+nil+ if this tag can contain child nodes.
|
274
|
-
def childless?
|
291
|
+
def childless?(xml = false)
|
292
|
+
return false if xml && @closing.nil?
|
275
293
|
!@closing.nil? ||
|
276
294
|
@name =~ /^(img|br|hr|link|meta|area|base|basefont|
|
277
295
|
col|frame|input|isindex|param)$/ox
|
@@ -417,7 +435,11 @@ module HTML #:nodoc:
|
|
417
435
|
|
418
436
|
# count children
|
419
437
|
if opts = conditions[:children]
|
420
|
-
matches = children
|
438
|
+
matches = children.select do |c|
|
439
|
+
c.match(/./) or
|
440
|
+
(c.kind_of?(HTML::Tag) and (c.closing == :self or ! c.childless?))
|
441
|
+
end
|
442
|
+
|
421
443
|
matches = matches.select { |c| c.match(opts[:only]) } if opts[:only]
|
422
444
|
opts.each do |key, value|
|
423
445
|
next if key == :only
|
@@ -464,8 +486,13 @@ module HTML #:nodoc:
|
|
464
486
|
true
|
465
487
|
end
|
466
488
|
|
489
|
+
def ==(node)
|
490
|
+
return false unless super
|
491
|
+
return false unless closing == node.closing && self.name == node.name
|
492
|
+
attributes == node.attributes
|
493
|
+
end
|
494
|
+
|
467
495
|
private
|
468
|
-
|
469
496
|
# Match the given value to the given condition.
|
470
497
|
def match_condition(value, condition)
|
471
498
|
case condition
|