actionpack 5.2.3

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.

Files changed (170) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +429 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +57 -0
  5. data/lib/abstract_controller.rb +27 -0
  6. data/lib/abstract_controller/asset_paths.rb +12 -0
  7. data/lib/abstract_controller/base.rb +265 -0
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/caching/fragments.rb +166 -0
  10. data/lib/abstract_controller/callbacks.rb +212 -0
  11. data/lib/abstract_controller/collector.rb +43 -0
  12. data/lib/abstract_controller/error.rb +6 -0
  13. data/lib/abstract_controller/helpers.rb +194 -0
  14. data/lib/abstract_controller/logger.rb +14 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +20 -0
  16. data/lib/abstract_controller/rendering.rb +127 -0
  17. data/lib/abstract_controller/translation.rb +31 -0
  18. data/lib/abstract_controller/url_for.rb +35 -0
  19. data/lib/action_controller.rb +66 -0
  20. data/lib/action_controller/api.rb +149 -0
  21. data/lib/action_controller/api/api_rendering.rb +16 -0
  22. data/lib/action_controller/base.rb +276 -0
  23. data/lib/action_controller/caching.rb +46 -0
  24. data/lib/action_controller/form_builder.rb +50 -0
  25. data/lib/action_controller/log_subscriber.rb +78 -0
  26. data/lib/action_controller/metal.rb +256 -0
  27. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  28. data/lib/action_controller/metal/conditional_get.rb +274 -0
  29. data/lib/action_controller/metal/content_security_policy.rb +52 -0
  30. data/lib/action_controller/metal/cookies.rb +16 -0
  31. data/lib/action_controller/metal/data_streaming.rb +152 -0
  32. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  33. data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
  34. data/lib/action_controller/metal/exceptions.rb +53 -0
  35. data/lib/action_controller/metal/flash.rb +61 -0
  36. data/lib/action_controller/metal/force_ssl.rb +99 -0
  37. data/lib/action_controller/metal/head.rb +60 -0
  38. data/lib/action_controller/metal/helpers.rb +123 -0
  39. data/lib/action_controller/metal/http_authentication.rb +519 -0
  40. data/lib/action_controller/metal/implicit_render.rb +73 -0
  41. data/lib/action_controller/metal/instrumentation.rb +107 -0
  42. data/lib/action_controller/metal/live.rb +312 -0
  43. data/lib/action_controller/metal/mime_responds.rb +313 -0
  44. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  45. data/lib/action_controller/metal/params_wrapper.rb +293 -0
  46. data/lib/action_controller/metal/redirecting.rb +133 -0
  47. data/lib/action_controller/metal/renderers.rb +181 -0
  48. data/lib/action_controller/metal/rendering.rb +122 -0
  49. data/lib/action_controller/metal/request_forgery_protection.rb +445 -0
  50. data/lib/action_controller/metal/rescue.rb +28 -0
  51. data/lib/action_controller/metal/streaming.rb +223 -0
  52. data/lib/action_controller/metal/strong_parameters.rb +1086 -0
  53. data/lib/action_controller/metal/testing.rb +16 -0
  54. data/lib/action_controller/metal/url_for.rb +58 -0
  55. data/lib/action_controller/railtie.rb +89 -0
  56. data/lib/action_controller/railties/helpers.rb +24 -0
  57. data/lib/action_controller/renderer.rb +117 -0
  58. data/lib/action_controller/template_assertions.rb +11 -0
  59. data/lib/action_controller/test_case.rb +629 -0
  60. data/lib/action_dispatch.rb +112 -0
  61. data/lib/action_dispatch/http/cache.rb +222 -0
  62. data/lib/action_dispatch/http/content_security_policy.rb +272 -0
  63. data/lib/action_dispatch/http/filter_parameters.rb +84 -0
  64. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  65. data/lib/action_dispatch/http/headers.rb +132 -0
  66. data/lib/action_dispatch/http/mime_negotiation.rb +175 -0
  67. data/lib/action_dispatch/http/mime_type.rb +342 -0
  68. data/lib/action_dispatch/http/mime_types.rb +50 -0
  69. data/lib/action_dispatch/http/parameter_filter.rb +86 -0
  70. data/lib/action_dispatch/http/parameters.rb +126 -0
  71. data/lib/action_dispatch/http/rack_cache.rb +63 -0
  72. data/lib/action_dispatch/http/request.rb +430 -0
  73. data/lib/action_dispatch/http/response.rb +519 -0
  74. data/lib/action_dispatch/http/upload.rb +84 -0
  75. data/lib/action_dispatch/http/url.rb +350 -0
  76. data/lib/action_dispatch/journey.rb +7 -0
  77. data/lib/action_dispatch/journey/formatter.rb +189 -0
  78. data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
  79. data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
  80. data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
  81. data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
  82. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  83. data/lib/action_dispatch/journey/nfa/simulator.rb +49 -0
  84. data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
  85. data/lib/action_dispatch/journey/nodes/node.rb +140 -0
  86. data/lib/action_dispatch/journey/parser.rb +199 -0
  87. data/lib/action_dispatch/journey/parser.y +50 -0
  88. data/lib/action_dispatch/journey/parser_extras.rb +31 -0
  89. data/lib/action_dispatch/journey/path/pattern.rb +198 -0
  90. data/lib/action_dispatch/journey/route.rb +203 -0
  91. data/lib/action_dispatch/journey/router.rb +156 -0
  92. data/lib/action_dispatch/journey/router/utils.rb +102 -0
  93. data/lib/action_dispatch/journey/routes.rb +82 -0
  94. data/lib/action_dispatch/journey/scanner.rb +64 -0
  95. data/lib/action_dispatch/journey/visitors.rb +268 -0
  96. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  97. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  98. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  99. data/lib/action_dispatch/middleware/callbacks.rb +36 -0
  100. data/lib/action_dispatch/middleware/cookies.rb +685 -0
  101. data/lib/action_dispatch/middleware/debug_exceptions.rb +205 -0
  102. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  103. data/lib/action_dispatch/middleware/exception_wrapper.rb +147 -0
  104. data/lib/action_dispatch/middleware/executor.rb +21 -0
  105. data/lib/action_dispatch/middleware/flash.rb +300 -0
  106. data/lib/action_dispatch/middleware/public_exceptions.rb +57 -0
  107. data/lib/action_dispatch/middleware/reloader.rb +12 -0
  108. data/lib/action_dispatch/middleware/remote_ip.rb +183 -0
  109. data/lib/action_dispatch/middleware/request_id.rb +43 -0
  110. data/lib/action_dispatch/middleware/session/abstract_store.rb +92 -0
  111. data/lib/action_dispatch/middleware/session/cache_store.rb +54 -0
  112. data/lib/action_dispatch/middleware/session/cookie_store.rb +118 -0
  113. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +28 -0
  114. data/lib/action_dispatch/middleware/show_exceptions.rb +62 -0
  115. data/lib/action_dispatch/middleware/ssl.rb +150 -0
  116. data/lib/action_dispatch/middleware/stack.rb +116 -0
  117. data/lib/action_dispatch/middleware/static.rb +130 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +22 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +27 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  123. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  125. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
  128. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +161 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  137. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  138. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  139. data/lib/action_dispatch/railtie.rb +55 -0
  140. data/lib/action_dispatch/request/session.rb +234 -0
  141. data/lib/action_dispatch/request/utils.rb +78 -0
  142. data/lib/action_dispatch/routing.rb +260 -0
  143. data/lib/action_dispatch/routing/endpoint.rb +17 -0
  144. data/lib/action_dispatch/routing/inspector.rb +225 -0
  145. data/lib/action_dispatch/routing/mapper.rb +2267 -0
  146. data/lib/action_dispatch/routing/polymorphic_routes.rb +352 -0
  147. data/lib/action_dispatch/routing/redirection.rb +201 -0
  148. data/lib/action_dispatch/routing/route_set.rb +890 -0
  149. data/lib/action_dispatch/routing/routes_proxy.rb +69 -0
  150. data/lib/action_dispatch/routing/url_for.rb +236 -0
  151. data/lib/action_dispatch/system_test_case.rb +147 -0
  152. data/lib/action_dispatch/system_testing/browser.rb +49 -0
  153. data/lib/action_dispatch/system_testing/driver.rb +59 -0
  154. data/lib/action_dispatch/system_testing/server.rb +31 -0
  155. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +96 -0
  156. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +31 -0
  157. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  158. data/lib/action_dispatch/testing/assertion_response.rb +47 -0
  159. data/lib/action_dispatch/testing/assertions.rb +24 -0
  160. data/lib/action_dispatch/testing/assertions/response.rb +107 -0
  161. data/lib/action_dispatch/testing/assertions/routing.rb +222 -0
  162. data/lib/action_dispatch/testing/integration.rb +652 -0
  163. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  164. data/lib/action_dispatch/testing/test_process.rb +50 -0
  165. data/lib/action_dispatch/testing/test_request.rb +71 -0
  166. data/lib/action_dispatch/testing/test_response.rb +53 -0
  167. data/lib/action_pack.rb +26 -0
  168. data/lib/action_pack/gem_version.rb +17 -0
  169. data/lib/action_pack/version.rb +10 -0
  170. metadata +318 -0
@@ -0,0 +1,13 @@
1
+ <%= @exception.class.to_s %><%
2
+ if @request.parameters['controller']
3
+ %> in <%= @request.parameters['controller'].camelize %>Controller<% if @request.parameters['action'] %>#<%= @request.parameters['action'] %><% end %>
4
+ <% end %>
5
+
6
+ <%= @exception.message %>
7
+ <% if %r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}.match?(@exception.message) %>
8
+ To resolve this issue run: bin/rails active_storage:install
9
+ <% end %>
10
+
11
+ <%= render template: "rescues/_source" %>
12
+ <%= render template: "rescues/_trace" %>
13
+ <%= render template: "rescues/_request_and_response" %>
@@ -0,0 +1,161 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Action Controller: Exception caught</title>
6
+ <style>
7
+ body {
8
+ background-color: #FAFAFA;
9
+ color: #333;
10
+ margin: 0px;
11
+ }
12
+
13
+ body, p, ol, ul, td {
14
+ font-family: helvetica, verdana, arial, sans-serif;
15
+ font-size: 13px;
16
+ line-height: 18px;
17
+ }
18
+
19
+ pre {
20
+ font-size: 11px;
21
+ white-space: pre-wrap;
22
+ }
23
+
24
+ pre.box {
25
+ border: 1px solid #EEE;
26
+ padding: 10px;
27
+ margin: 0px;
28
+ width: 958px;
29
+ }
30
+
31
+ header {
32
+ color: #F0F0F0;
33
+ background: #C52F24;
34
+ padding: 0.5em 1.5em;
35
+ }
36
+
37
+ h1 {
38
+ margin: 0.2em 0;
39
+ line-height: 1.1em;
40
+ font-size: 2em;
41
+ }
42
+
43
+ h2 {
44
+ color: #C52F24;
45
+ line-height: 25px;
46
+ }
47
+
48
+ .details {
49
+ border: 1px solid #D0D0D0;
50
+ border-radius: 4px;
51
+ margin: 1em 0px;
52
+ display: block;
53
+ width: 978px;
54
+ }
55
+
56
+ .summary {
57
+ padding: 8px 15px;
58
+ border-bottom: 1px solid #D0D0D0;
59
+ display: block;
60
+ }
61
+
62
+ .details pre {
63
+ margin: 5px;
64
+ border: none;
65
+ }
66
+
67
+ #container {
68
+ box-sizing: border-box;
69
+ width: 100%;
70
+ padding: 0 1.5em;
71
+ }
72
+
73
+ .source * {
74
+ margin: 0px;
75
+ padding: 0px;
76
+ }
77
+
78
+ .source {
79
+ border: 1px solid #D9D9D9;
80
+ background: #ECECEC;
81
+ width: 978px;
82
+ }
83
+
84
+ .source pre {
85
+ padding: 10px 0px;
86
+ border: none;
87
+ }
88
+
89
+ .source .data {
90
+ font-size: 80%;
91
+ overflow: auto;
92
+ background-color: #FFF;
93
+ }
94
+
95
+ .info {
96
+ padding: 0.5em;
97
+ }
98
+
99
+ .source .data .line_numbers {
100
+ background-color: #ECECEC;
101
+ color: #AAA;
102
+ padding: 1em .5em;
103
+ border-right: 1px solid #DDD;
104
+ text-align: right;
105
+ }
106
+
107
+ .line {
108
+ padding-left: 10px;
109
+ white-space: pre;
110
+ }
111
+
112
+ .line:hover {
113
+ background-color: #F6F6F6;
114
+ }
115
+
116
+ .line.active {
117
+ background-color: #FFCCCC;
118
+ }
119
+
120
+ .hidden {
121
+ display: none;
122
+ }
123
+
124
+ a { color: #980905; }
125
+ a:visited { color: #666; }
126
+ a.trace-frames { color: #666; }
127
+ a:hover { color: #C52F24; }
128
+ a.trace-frames.selected { color: #C52F24 }
129
+
130
+ <%= yield :style %>
131
+ </style>
132
+
133
+ <script>
134
+ var toggle = function(id) {
135
+ var s = document.getElementById(id).style;
136
+ s.display = s.display == 'none' ? 'block' : 'none';
137
+ return false;
138
+ }
139
+ var show = function(id) {
140
+ document.getElementById(id).style.display = 'block';
141
+ }
142
+ var hide = function(id) {
143
+ document.getElementById(id).style.display = 'none';
144
+ }
145
+ var toggleTrace = function() {
146
+ return toggle('blame_trace');
147
+ }
148
+ var toggleSessionDump = function() {
149
+ return toggle('session_dump');
150
+ }
151
+ var toggleEnvDump = function() {
152
+ return toggle('env_dump');
153
+ }
154
+ </script>
155
+ </head>
156
+ <body>
157
+
158
+ <%= yield %>
159
+
160
+ </body>
161
+ </html>
@@ -0,0 +1,11 @@
1
+ <header>
2
+ <h1>Template is missing</h1>
3
+ </header>
4
+
5
+ <div id="container">
6
+ <h2><%= h @exception.message %></h2>
7
+
8
+ <%= render template: "rescues/_source" %>
9
+ <%= render template: "rescues/_trace" %>
10
+ <%= render template: "rescues/_request_and_response" %>
11
+ </div>
@@ -0,0 +1,3 @@
1
+ Template is missing
2
+
3
+ <%= @exception.message %>
@@ -0,0 +1,32 @@
1
+ <header>
2
+ <h1>Routing Error</h1>
3
+ </header>
4
+ <div id="container">
5
+ <h2><%= h @exception.message %></h2>
6
+ <% unless @exception.failures.empty? %>
7
+ <p>
8
+ <h2>Failure reasons:</h2>
9
+ <ol>
10
+ <% @exception.failures.each do |route, reason| %>
11
+ <li><code><%= route.inspect.delete('\\') %></code> failed because <%= reason.downcase %></li>
12
+ <% end %>
13
+ </ol>
14
+ </p>
15
+ <% end %>
16
+
17
+ <%= render template: "rescues/_trace" %>
18
+
19
+ <% if @routes_inspector %>
20
+ <h2>
21
+ Routes
22
+ </h2>
23
+
24
+ <p>
25
+ Routes match in priority from top to bottom
26
+ </p>
27
+
28
+ <%= @routes_inspector.format(ActionDispatch::Routing::HtmlTableFormatter.new(self)) %>
29
+ <% end %>
30
+
31
+ <%= render template: "rescues/_request_and_response" %>
32
+ </div>
@@ -0,0 +1,11 @@
1
+ Routing Error
2
+
3
+ <%= @exception.message %>
4
+ <% unless @exception.failures.empty? %>
5
+ Failure reasons:
6
+ <% @exception.failures.each do |route, reason| %>
7
+ - <%= route.inspect.delete('\\') %></code> failed because <%= reason.downcase %>
8
+ <% end %>
9
+ <% end %>
10
+
11
+ <%= render template: "rescues/_trace", format: :text %>
@@ -0,0 +1,20 @@
1
+ <header>
2
+ <h1>
3
+ <%= @exception.cause.class.to_s %> in
4
+ <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
5
+ </h1>
6
+ </header>
7
+
8
+ <div id="container">
9
+ <p>
10
+ Showing <i><%= @exception.file_name %></i> where line <b>#<%= @exception.line_number %></b> raised:
11
+ </p>
12
+ <pre><code><%= h @exception.message %></code></pre>
13
+
14
+ <%= render template: "rescues/_source" %>
15
+
16
+ <p><%= @exception.sub_template_message %></p>
17
+
18
+ <%= render template: "rescues/_trace" %>
19
+ <%= render template: "rescues/_request_and_response" %>
20
+ </div>
@@ -0,0 +1,7 @@
1
+ <%= @exception.cause.class.to_s %> in <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
2
+
3
+ Showing <%= @exception.file_name %> where line #<%= @exception.line_number %> raised:
4
+ <%= @exception.message %>
5
+ <%= @exception.sub_template_message %>
6
+ <%= render template: "rescues/_trace", format: :text %>
7
+ <%= render template: "rescues/_request_and_response", format: :text %>
@@ -0,0 +1,6 @@
1
+ <header>
2
+ <h1>Unknown action</h1>
3
+ </header>
4
+ <div id="container">
5
+ <h2><%= h @exception.message %></h2>
6
+ </div>
@@ -0,0 +1,3 @@
1
+ Unknown action
2
+
3
+ <%= @exception.message %>
@@ -0,0 +1,16 @@
1
+ <tr class='route_row' data-helper='path'>
2
+ <td data-route-name='<%= route[:name] %>'>
3
+ <% if route[:name].present? %>
4
+ <%= route[:name] %><span class='helper'>_path</span>
5
+ <% end %>
6
+ </td>
7
+ <td>
8
+ <%= route[:verb] %>
9
+ </td>
10
+ <td data-route-path='<%= route[:path] %>'>
11
+ <%= route[:path] %>
12
+ </td>
13
+ <td>
14
+ <%=simple_format route[:reqs] %>
15
+ </td>
16
+ </tr>
@@ -0,0 +1,200 @@
1
+ <% content_for :style do %>
2
+ #route_table {
3
+ margin: 0;
4
+ border-collapse: collapse;
5
+ }
6
+
7
+ #route_table thead tr {
8
+ border-bottom: 2px solid #ddd;
9
+ }
10
+
11
+ #route_table thead tr.bottom {
12
+ border-bottom: none;
13
+ }
14
+
15
+ #route_table thead tr.bottom th {
16
+ padding: 10px 0;
17
+ line-height: 15px;
18
+ }
19
+
20
+ #route_table thead tr.bottom th input#search {
21
+ -webkit-appearance: textfield;
22
+ }
23
+
24
+ #route_table tbody tr {
25
+ border-bottom: 1px solid #ddd;
26
+ }
27
+
28
+ #route_table tbody tr:nth-child(odd) {
29
+ background: #f2f2f2;
30
+ }
31
+
32
+ #route_table tbody.exact_matches,
33
+ #route_table tbody.fuzzy_matches {
34
+ background-color: LightGoldenRodYellow;
35
+ border-bottom: solid 2px SlateGrey;
36
+ }
37
+
38
+ #route_table tbody.exact_matches tr,
39
+ #route_table tbody.fuzzy_matches tr {
40
+ background: none;
41
+ border-bottom: none;
42
+ }
43
+
44
+ #route_table td {
45
+ padding: 4px 30px;
46
+ }
47
+
48
+ #path_search {
49
+ width: 80%;
50
+ font-size: inherit;
51
+ }
52
+ <% end %>
53
+
54
+ <table id='route_table' class='route_table'>
55
+ <thead>
56
+ <tr>
57
+ <th>Helper</th>
58
+ <th>HTTP Verb</th>
59
+ <th>Path</th>
60
+ <th>Controller#Action</th>
61
+ </tr>
62
+ <tr class='bottom'>
63
+ <th><%# Helper %>
64
+ <%= link_to "Path", "#", 'data-route-helper' => '_path',
65
+ title: "Returns a relative path (without the http or domain)" %> /
66
+ <%= link_to "Url", "#", 'data-route-helper' => '_url',
67
+ title: "Returns an absolute URL (with the http and domain)" %>
68
+ </th>
69
+ <th><%# HTTP Verb %>
70
+ </th>
71
+ <th><%# Path %>
72
+ <%= search_field(:path, nil, id: 'search', placeholder: "Path Match") %>
73
+ </th>
74
+ <th><%# Controller#action %>
75
+ </th>
76
+ </tr>
77
+ </thead>
78
+ <tbody class='exact_matches' id='exact_matches'>
79
+ </tbody>
80
+ <tbody class='fuzzy_matches' id='fuzzy_matches'>
81
+ </tbody>
82
+ <tbody>
83
+ <%= yield %>
84
+ </tbody>
85
+ </table>
86
+
87
+ <script type='text/javascript'>
88
+ // support forEarch iterator on NodeList
89
+ NodeList.prototype.forEach = Array.prototype.forEach;
90
+
91
+ // Enables path search functionality
92
+ function setupMatchPaths() {
93
+ // Check if there are any matched results in a section
94
+ function checkNoMatch(section, noMatchText) {
95
+ if (section.children.length <= 1) {
96
+ section.innerHTML += noMatchText;
97
+ }
98
+ }
99
+
100
+ // get JSON from URL and invoke callback with result
101
+ function getJSON(url, success) {
102
+ var xhr = new XMLHttpRequest();
103
+ xhr.open('GET', url);
104
+ xhr.onload = function() {
105
+ if (this.status == 200)
106
+ success(JSON.parse(this.response));
107
+ };
108
+ xhr.send();
109
+ }
110
+
111
+ function delayedKeyup(input, callback) {
112
+ var timeout;
113
+ input.onkeyup = function(){
114
+ if (timeout) clearTimeout(timeout);
115
+ timeout = setTimeout(callback, 300);
116
+ }
117
+ }
118
+
119
+ // remove params or fragments
120
+ function sanitizePath(path) {
121
+ return path.replace(/[#?].*/, '');
122
+ }
123
+
124
+ var pathElements = document.querySelectorAll('#route_table [data-route-path]'),
125
+ searchElem = document.querySelector('#search'),
126
+ exactSection = document.querySelector('#exact_matches'),
127
+ fuzzySection = document.querySelector('#fuzzy_matches');
128
+
129
+ // Remove matches when no search value is present
130
+ searchElem.onblur = function(e) {
131
+ if (searchElem.value === "") {
132
+ exactSection.innerHTML = "";
133
+ fuzzySection.innerHTML = "";
134
+ }
135
+ }
136
+
137
+ // On key press perform a search for matching paths
138
+ delayedKeyup(searchElem, function() {
139
+ var path = sanitizePath(searchElem.value),
140
+ defaultExactMatch = '<tr><th colspan="4">Paths Matching (' + path +'):</th></tr>',
141
+ defaultFuzzyMatch = '<tr><th colspan="4">Paths Containing (' + path +'):</th></tr>',
142
+ noExactMatch = '<tr><th colspan="4">No Exact Matches Found</th></tr>',
143
+ noFuzzyMatch = '<tr><th colspan="4">No Fuzzy Matches Found</th></tr>';
144
+
145
+ if (!path)
146
+ return searchElem.onblur();
147
+
148
+ getJSON('/rails/info/routes?path=' + path, function(matches){
149
+ // Clear out results section
150
+ exactSection.innerHTML = defaultExactMatch;
151
+ fuzzySection.innerHTML = defaultFuzzyMatch;
152
+
153
+ // Display exact matches and fuzzy matches
154
+ pathElements.forEach(function(elem) {
155
+ var elemPath = elem.getAttribute('data-route-path');
156
+
157
+ if (matches['exact'].indexOf(elemPath) != -1)
158
+ exactSection.appendChild(elem.parentNode.cloneNode(true));
159
+
160
+ if (matches['fuzzy'].indexOf(elemPath) != -1)
161
+ fuzzySection.appendChild(elem.parentNode.cloneNode(true));
162
+ })
163
+
164
+ // Display 'No Matches' message when no matches are found
165
+ checkNoMatch(exactSection, noExactMatch);
166
+ checkNoMatch(fuzzySection, noFuzzyMatch);
167
+ })
168
+ })
169
+ }
170
+
171
+ // Enables functionality to toggle between `_path` and `_url` helper suffixes
172
+ function setupRouteToggleHelperLinks() {
173
+
174
+ // Sets content for each element
175
+ function setValOn(elems, val) {
176
+ elems.forEach(function(elem) {
177
+ elem.innerHTML = val;
178
+ });
179
+ }
180
+
181
+ // Sets onClick event for each element
182
+ function onClick(elems, func) {
183
+ elems.forEach(function(elem) {
184
+ elem.onclick = func;
185
+ });
186
+ }
187
+
188
+ var toggleLinks = document.querySelectorAll('#route_table [data-route-helper]');
189
+
190
+ onClick(toggleLinks, function(){
191
+ var helperTxt = this.getAttribute("data-route-helper"),
192
+ helperElems = document.querySelectorAll('[data-route-name] span.helper');
193
+
194
+ setValOn(helperElems, helperTxt);
195
+ });
196
+ }
197
+
198
+ setupMatchPaths();
199
+ setupRouteToggleHelperLinks();
200
+ </script>