actionpack 3.2.19 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +850 -401
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -288
  5. data/lib/abstract_controller/asset_paths.rb +2 -2
  6. data/lib/abstract_controller/base.rb +39 -37
  7. data/lib/abstract_controller/callbacks.rb +101 -82
  8. data/lib/abstract_controller/collector.rb +7 -3
  9. data/lib/abstract_controller/helpers.rb +25 -13
  10. data/lib/abstract_controller/layouts.rb +74 -74
  11. data/lib/abstract_controller/logger.rb +1 -2
  12. data/lib/abstract_controller/rendering.rb +30 -13
  13. data/lib/abstract_controller/translation.rb +16 -1
  14. data/lib/abstract_controller/url_for.rb +6 -6
  15. data/lib/abstract_controller/view_paths.rb +1 -1
  16. data/lib/abstract_controller.rb +1 -8
  17. data/lib/action_controller/base.rb +46 -22
  18. data/lib/action_controller/caching/fragments.rb +23 -53
  19. data/lib/action_controller/caching.rb +46 -33
  20. data/lib/action_controller/deprecated/integration_test.rb +3 -0
  21. data/lib/action_controller/deprecated.rb +5 -1
  22. data/lib/action_controller/log_subscriber.rb +16 -8
  23. data/lib/action_controller/metal/conditional_get.rb +76 -32
  24. data/lib/action_controller/metal/data_streaming.rb +20 -26
  25. data/lib/action_controller/metal/exceptions.rb +19 -6
  26. data/lib/action_controller/metal/flash.rb +24 -9
  27. data/lib/action_controller/metal/force_ssl.rb +70 -12
  28. data/lib/action_controller/metal/head.rb +25 -4
  29. data/lib/action_controller/metal/helpers.rb +5 -9
  30. data/lib/action_controller/metal/hide_actions.rb +0 -1
  31. data/lib/action_controller/metal/http_authentication.rb +107 -83
  32. data/lib/action_controller/metal/implicit_render.rb +1 -1
  33. data/lib/action_controller/metal/instrumentation.rb +2 -1
  34. data/lib/action_controller/metal/live.rb +175 -0
  35. data/lib/action_controller/metal/mime_responds.rb +161 -47
  36. data/lib/action_controller/metal/params_wrapper.rb +112 -74
  37. data/lib/action_controller/metal/rack_delegation.rb +9 -3
  38. data/lib/action_controller/metal/redirecting.rb +15 -20
  39. data/lib/action_controller/metal/renderers.rb +11 -9
  40. data/lib/action_controller/metal/rendering.rb +9 -1
  41. data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
  42. data/lib/action_controller/metal/responder.rb +20 -19
  43. data/lib/action_controller/metal/streaming.rb +12 -18
  44. data/lib/action_controller/metal/strong_parameters.rb +520 -0
  45. data/lib/action_controller/metal/testing.rb +13 -18
  46. data/lib/action_controller/metal/url_for.rb +28 -25
  47. data/lib/action_controller/metal.rb +17 -32
  48. data/lib/action_controller/model_naming.rb +12 -0
  49. data/lib/action_controller/railtie.rb +33 -17
  50. data/lib/action_controller/railties/helpers.rb +22 -0
  51. data/lib/action_controller/record_identifier.rb +18 -72
  52. data/lib/action_controller/test_case.rb +251 -131
  53. data/lib/action_controller/vendor/html-scanner.rb +4 -19
  54. data/lib/action_controller.rb +15 -6
  55. data/lib/action_dispatch/http/cache.rb +63 -11
  56. data/lib/action_dispatch/http/filter_parameters.rb +18 -8
  57. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  58. data/lib/action_dispatch/http/headers.rb +49 -17
  59. data/lib/action_dispatch/http/mime_negotiation.rb +24 -1
  60. data/lib/action_dispatch/http/mime_type.rb +154 -100
  61. data/lib/action_dispatch/http/mime_types.rb +1 -1
  62. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  63. data/lib/action_dispatch/http/parameters.rb +28 -28
  64. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  65. data/lib/action_dispatch/http/request.rb +64 -18
  66. data/lib/action_dispatch/http/response.rb +130 -35
  67. data/lib/action_dispatch/http/upload.rb +63 -20
  68. data/lib/action_dispatch/http/url.rb +98 -35
  69. data/lib/action_dispatch/journey/backwards.rb +5 -0
  70. data/lib/action_dispatch/journey/formatter.rb +146 -0
  71. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  72. data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
  73. data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
  74. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  75. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  76. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  77. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  78. data/lib/action_dispatch/journey/nodes/node.rb +124 -0
  79. data/lib/action_dispatch/journey/parser.rb +206 -0
  80. data/lib/action_dispatch/journey/parser.y +47 -0
  81. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  82. data/lib/action_dispatch/journey/path/pattern.rb +196 -0
  83. data/lib/action_dispatch/journey/route.rb +124 -0
  84. data/lib/action_dispatch/journey/router/strexp.rb +24 -0
  85. data/lib/action_dispatch/journey/router/utils.rb +54 -0
  86. data/lib/action_dispatch/journey/router.rb +166 -0
  87. data/lib/action_dispatch/journey/routes.rb +75 -0
  88. data/lib/action_dispatch/journey/scanner.rb +61 -0
  89. data/lib/action_dispatch/journey/visitors.rb +197 -0
  90. data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
  91. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  92. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  93. data/lib/action_dispatch/journey.rb +5 -0
  94. data/lib/action_dispatch/middleware/callbacks.rb +9 -4
  95. data/lib/action_dispatch/middleware/cookies.rb +259 -114
  96. data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
  97. data/lib/action_dispatch/middleware/exception_wrapper.rb +29 -3
  98. data/lib/action_dispatch/middleware/flash.rb +58 -58
  99. data/lib/action_dispatch/middleware/params_parser.rb +14 -29
  100. data/lib/action_dispatch/middleware/public_exceptions.rb +30 -14
  101. data/lib/action_dispatch/middleware/reloader.rb +6 -6
  102. data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
  103. data/lib/action_dispatch/middleware/request_id.rb +2 -6
  104. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  105. data/lib/action_dispatch/middleware/session/cookie_store.rb +82 -28
  106. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  107. data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
  108. data/lib/action_dispatch/middleware/ssl.rb +70 -0
  109. data/lib/action_dispatch/middleware/stack.rb +6 -1
  110. data/lib/action_dispatch/middleware/static.rb +2 -1
  111. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
  112. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
  113. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +7 -9
  114. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
  115. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +127 -5
  116. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
  117. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
  118. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
  119. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
  120. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  121. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
  122. data/lib/action_dispatch/railtie.rb +16 -6
  123. data/lib/action_dispatch/request/session.rb +181 -0
  124. data/lib/action_dispatch/routing/inspector.rb +240 -0
  125. data/lib/action_dispatch/routing/mapper.rb +540 -291
  126. data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
  127. data/lib/action_dispatch/routing/redirection.rb +46 -29
  128. data/lib/action_dispatch/routing/route_set.rb +207 -164
  129. data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
  130. data/lib/action_dispatch/routing/url_for.rb +48 -33
  131. data/lib/action_dispatch/routing.rb +48 -83
  132. data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
  133. data/lib/action_dispatch/testing/assertions/response.rb +32 -40
  134. data/lib/action_dispatch/testing/assertions/routing.rb +42 -41
  135. data/lib/action_dispatch/testing/assertions/selector.rb +17 -22
  136. data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
  137. data/lib/action_dispatch/testing/integration.rb +65 -51
  138. data/lib/action_dispatch/testing/test_process.rb +9 -6
  139. data/lib/action_dispatch/testing/test_request.rb +7 -3
  140. data/lib/action_dispatch.rb +21 -15
  141. data/lib/action_pack/version.rb +7 -6
  142. data/lib/action_pack.rb +1 -1
  143. data/lib/action_view/base.rb +15 -34
  144. data/lib/action_view/buffers.rb +7 -1
  145. data/lib/action_view/context.rb +4 -4
  146. data/lib/action_view/dependency_tracker.rb +93 -0
  147. data/lib/action_view/digestor.rb +85 -0
  148. data/lib/action_view/flows.rb +1 -4
  149. data/lib/action_view/helpers/active_model_helper.rb +3 -4
  150. data/lib/action_view/helpers/asset_tag_helper.rb +215 -352
  151. data/lib/action_view/helpers/asset_url_helper.rb +355 -0
  152. data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
  153. data/lib/action_view/helpers/cache_helper.rb +150 -18
  154. data/lib/action_view/helpers/capture_helper.rb +44 -31
  155. data/lib/action_view/helpers/csrf_helper.rb +0 -2
  156. data/lib/action_view/helpers/date_helper.rb +269 -248
  157. data/lib/action_view/helpers/debug_helper.rb +10 -11
  158. data/lib/action_view/helpers/form_helper.rb +931 -537
  159. data/lib/action_view/helpers/form_options_helper.rb +341 -166
  160. data/lib/action_view/helpers/form_tag_helper.rb +190 -90
  161. data/lib/action_view/helpers/javascript_helper.rb +23 -16
  162. data/lib/action_view/helpers/number_helper.rb +148 -329
  163. data/lib/action_view/helpers/output_safety_helper.rb +3 -3
  164. data/lib/action_view/helpers/record_tag_helper.rb +17 -22
  165. data/lib/action_view/helpers/rendering_helper.rb +2 -2
  166. data/lib/action_view/helpers/sanitize_helper.rb +3 -6
  167. data/lib/action_view/helpers/tag_helper.rb +46 -33
  168. data/lib/action_view/helpers/tags/base.rb +147 -0
  169. data/lib/action_view/helpers/tags/check_box.rb +64 -0
  170. data/lib/action_view/helpers/tags/checkable.rb +16 -0
  171. data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
  172. data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
  173. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
  174. data/lib/action_view/helpers/tags/collection_select.rb +28 -0
  175. data/lib/action_view/helpers/tags/color_field.rb +25 -0
  176. data/lib/action_view/helpers/tags/date_field.rb +13 -0
  177. data/lib/action_view/helpers/tags/date_select.rb +72 -0
  178. data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
  179. data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
  180. data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
  181. data/lib/action_view/helpers/tags/email_field.rb +8 -0
  182. data/lib/action_view/helpers/tags/file_field.rb +8 -0
  183. data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
  184. data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
  185. data/lib/action_view/helpers/tags/label.rb +65 -0
  186. data/lib/action_view/helpers/tags/month_field.rb +13 -0
  187. data/lib/action_view/helpers/tags/number_field.rb +18 -0
  188. data/lib/action_view/helpers/tags/password_field.rb +12 -0
  189. data/lib/action_view/helpers/tags/radio_button.rb +31 -0
  190. data/lib/action_view/helpers/tags/range_field.rb +8 -0
  191. data/lib/action_view/helpers/tags/search_field.rb +24 -0
  192. data/lib/action_view/helpers/tags/select.rb +40 -0
  193. data/lib/action_view/helpers/tags/tel_field.rb +8 -0
  194. data/lib/action_view/helpers/tags/text_area.rb +18 -0
  195. data/lib/action_view/helpers/tags/text_field.rb +29 -0
  196. data/lib/action_view/helpers/tags/time_field.rb +13 -0
  197. data/lib/action_view/helpers/tags/time_select.rb +8 -0
  198. data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
  199. data/lib/action_view/helpers/tags/url_field.rb +8 -0
  200. data/lib/action_view/helpers/tags/week_field.rb +13 -0
  201. data/lib/action_view/helpers/tags.rb +39 -0
  202. data/lib/action_view/helpers/text_helper.rb +130 -114
  203. data/lib/action_view/helpers/translation_helper.rb +32 -16
  204. data/lib/action_view/helpers/url_helper.rb +211 -270
  205. data/lib/action_view/helpers.rb +2 -4
  206. data/lib/action_view/locale/en.yml +1 -105
  207. data/lib/action_view/log_subscriber.rb +6 -4
  208. data/lib/action_view/lookup_context.rb +15 -28
  209. data/lib/action_view/model_naming.rb +12 -0
  210. data/lib/action_view/path_set.rb +8 -20
  211. data/lib/action_view/railtie.rb +6 -22
  212. data/lib/action_view/record_identifier.rb +84 -0
  213. data/lib/action_view/renderer/abstract_renderer.rb +25 -19
  214. data/lib/action_view/renderer/partial_renderer.rb +158 -81
  215. data/lib/action_view/renderer/renderer.rb +8 -12
  216. data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
  217. data/lib/action_view/renderer/template_renderer.rb +12 -10
  218. data/lib/action_view/routing_url_for.rb +107 -0
  219. data/lib/action_view/template/error.rb +22 -12
  220. data/lib/action_view/template/handlers/builder.rb +1 -1
  221. data/lib/action_view/template/handlers/erb.rb +40 -19
  222. data/lib/action_view/template/handlers/raw.rb +11 -0
  223. data/lib/action_view/template/handlers.rb +12 -9
  224. data/lib/action_view/template/resolver.rb +107 -53
  225. data/lib/action_view/template/text.rb +12 -8
  226. data/lib/action_view/template/types.rb +57 -0
  227. data/lib/action_view/template.rb +25 -23
  228. data/lib/action_view/test_case.rb +67 -42
  229. data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
  230. data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
  231. data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +13 -2
  232. data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +9 -9
  233. data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
  234. data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
  235. data/lib/action_view/vendor/html-scanner.rb +20 -0
  236. data/lib/action_view.rb +17 -8
  237. metadata +184 -214
  238. data/lib/action_controller/caching/actions.rb +0 -185
  239. data/lib/action_controller/caching/pages.rb +0 -187
  240. data/lib/action_controller/caching/sweeping.rb +0 -97
  241. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  242. data/lib/action_controller/metal/compatibility.rb +0 -65
  243. data/lib/action_controller/metal/session_management.rb +0 -14
  244. data/lib/action_controller/railties/paths.rb +0 -25
  245. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  246. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  247. data/lib/action_dispatch/middleware/head.rb +0 -18
  248. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  249. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  250. data/lib/action_view/asset_paths.rb +0 -142
  251. data/lib/action_view/helpers/asset_paths.rb +0 -7
  252. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  253. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  254. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  255. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  256. data/lib/sprockets/assets.rake +0 -99
  257. data/lib/sprockets/bootstrap.rb +0 -37
  258. data/lib/sprockets/compressors.rb +0 -83
  259. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  260. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  261. data/lib/sprockets/helpers.rb +0 -6
  262. data/lib/sprockets/railtie.rb +0 -62
  263. data/lib/sprockets/static_compiler.rb +0 -56
@@ -0,0 +1,197 @@
1
+ # encoding: utf-8
2
+ module ActionDispatch
3
+ module Journey # :nodoc:
4
+ module Visitors # :nodoc:
5
+ class Visitor # :nodoc:
6
+ DISPATCH_CACHE = Hash.new { |h,k|
7
+ h[k] = "visit_#{k}"
8
+ }
9
+
10
+ def accept(node)
11
+ visit(node)
12
+ end
13
+
14
+ private
15
+
16
+ def visit node
17
+ send(DISPATCH_CACHE[node.type], node)
18
+ end
19
+
20
+ def binary(node)
21
+ visit(node.left)
22
+ visit(node.right)
23
+ end
24
+ def visit_CAT(n); binary(n); end
25
+
26
+ def nary(node)
27
+ node.children.each { |c| visit(c) }
28
+ end
29
+ def visit_OR(n); nary(n); end
30
+
31
+ def unary(node)
32
+ visit(node.left)
33
+ end
34
+ def visit_GROUP(n); unary(n); end
35
+ def visit_STAR(n); unary(n); end
36
+
37
+ def terminal(node); end
38
+ %w{ LITERAL SYMBOL SLASH DOT }.each do |t|
39
+ class_eval %{ def visit_#{t}(n); terminal(n); end }, __FILE__, __LINE__
40
+ end
41
+ end
42
+
43
+ # Loop through the requirements AST
44
+ class Each < Visitor # :nodoc:
45
+ attr_reader :block
46
+
47
+ def initialize(block)
48
+ @block = block
49
+ end
50
+
51
+ def visit(node)
52
+ super
53
+ block.call(node)
54
+ end
55
+ end
56
+
57
+ class String < Visitor # :nodoc:
58
+ private
59
+
60
+ def binary(node)
61
+ [visit(node.left), visit(node.right)].join
62
+ end
63
+
64
+ def nary(node)
65
+ node.children.map { |c| visit(c) }.join '|'
66
+ end
67
+
68
+ def terminal(node)
69
+ node.left
70
+ end
71
+
72
+ def visit_GROUP(node)
73
+ "(#{visit(node.left)})"
74
+ end
75
+ end
76
+
77
+ class OptimizedPath < String # :nodoc:
78
+ private
79
+
80
+ def visit_GROUP(node)
81
+ ""
82
+ end
83
+ end
84
+
85
+ # Used for formatting urls (url_for)
86
+ class Formatter < Visitor # :nodoc:
87
+ attr_reader :options, :consumed
88
+
89
+ def initialize(options)
90
+ @options = options
91
+ @consumed = {}
92
+ end
93
+
94
+ private
95
+
96
+ def visit_GROUP(node)
97
+ if consumed == options
98
+ nil
99
+ else
100
+ route = visit(node.left)
101
+ route.include?("\0") ? nil : route
102
+ end
103
+ end
104
+
105
+ def terminal(node)
106
+ node.left
107
+ end
108
+
109
+ def binary(node)
110
+ [visit(node.left), visit(node.right)].join
111
+ end
112
+
113
+ def nary(node)
114
+ node.children.map { |c| visit(c) }.join
115
+ end
116
+
117
+ def visit_SYMBOL(node)
118
+ key = node.to_sym
119
+
120
+ if value = options[key]
121
+ consumed[key] = value
122
+ Router::Utils.escape_path(value)
123
+ else
124
+ "\0"
125
+ end
126
+ end
127
+ end
128
+
129
+ class Dot < Visitor # :nodoc:
130
+ def initialize
131
+ @nodes = []
132
+ @edges = []
133
+ end
134
+
135
+ def accept(node)
136
+ super
137
+ <<-eodot
138
+ digraph parse_tree {
139
+ size="8,5"
140
+ node [shape = none];
141
+ edge [dir = none];
142
+ #{@nodes.join "\n"}
143
+ #{@edges.join("\n")}
144
+ }
145
+ eodot
146
+ end
147
+
148
+ private
149
+
150
+ def binary(node)
151
+ node.children.each do |c|
152
+ @edges << "#{node.object_id} -> #{c.object_id};"
153
+ end
154
+ super
155
+ end
156
+
157
+ def nary(node)
158
+ node.children.each do |c|
159
+ @edges << "#{node.object_id} -> #{c.object_id};"
160
+ end
161
+ super
162
+ end
163
+
164
+ def unary(node)
165
+ @edges << "#{node.object_id} -> #{node.left.object_id};"
166
+ super
167
+ end
168
+
169
+ def visit_GROUP(node)
170
+ @nodes << "#{node.object_id} [label=\"()\"];"
171
+ super
172
+ end
173
+
174
+ def visit_CAT(node)
175
+ @nodes << "#{node.object_id} [label=\"○\"];"
176
+ super
177
+ end
178
+
179
+ def visit_STAR(node)
180
+ @nodes << "#{node.object_id} [label=\"*\"];"
181
+ super
182
+ end
183
+
184
+ def visit_OR(node)
185
+ @nodes << "#{node.object_id} [label=\"|\"];"
186
+ super
187
+ end
188
+
189
+ def terminal(node)
190
+ value = node.left
191
+
192
+ @nodes << "#{node.object_id} [label=\"#{value}\"];"
193
+ end
194
+ end
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,34 @@
1
+ body {
2
+ font-family: "Helvetica Neue", Helvetica, Arial, Sans-Serif;
3
+ margin: 0;
4
+ }
5
+
6
+ h1 {
7
+ font-size: 2.0em; font-weight: bold; text-align: center;
8
+ color: white; background-color: black;
9
+ padding: 5px 0;
10
+ margin: 0 0 20px;
11
+ }
12
+
13
+ h2 {
14
+ text-align: center;
15
+ display: none;
16
+ font-size: 0.5em;
17
+ }
18
+
19
+ div#chart-2 {
20
+ height: 350px;
21
+ }
22
+
23
+ .clearfix {display: inline-block; }
24
+ .input { overflow: show;}
25
+ .instruction { color: #666; padding: 0 30px 20px; font-size: 0.9em}
26
+ .instruction p { padding: 0 0 5px; }
27
+ .instruction li { padding: 0 10px 5px; }
28
+
29
+ .form { background: #EEE; padding: 20px 30px; border-radius: 5px; margin-left: auto; margin-right: auto; width: 500px; margin-bottom: 20px}
30
+ .form p, .form form { text-align: center }
31
+ .form form {padding: 0 10px 5px; }
32
+ .form .fun_routes { font-size: 0.9em;}
33
+ .form .fun_routes a { margin: 0 5px 0 0; }
34
+
@@ -0,0 +1,134 @@
1
+ function tokenize(input, callback) {
2
+ while(input.length > 0) {
3
+ callback(input.match(/^[\/\.\?]|[^\/\.\?]+/)[0]);
4
+ input = input.replace(/^[\/\.\?]|[^\/\.\?]+/, '');
5
+ }
6
+ }
7
+
8
+ var graph = d3.select("#chart-2 svg");
9
+ var svg_edges = {};
10
+ var svg_nodes = {};
11
+
12
+ graph.selectAll("g.edge").each(function() {
13
+ var node = d3.select(this);
14
+ var index = node.select("title").text().split("->");
15
+ var left = parseInt(index[0]);
16
+ var right = parseInt(index[1]);
17
+
18
+ if(!svg_edges[left]) { svg_edges[left] = {} }
19
+ svg_edges[left][right] = node;
20
+ });
21
+
22
+ graph.selectAll("g.node").each(function() {
23
+ var node = d3.select(this);
24
+ var index = parseInt(node.select("title").text());
25
+ svg_nodes[index] = node;
26
+ });
27
+
28
+ function reset_graph() {
29
+ for(var key in svg_edges) {
30
+ for(var mkey in svg_edges[key]) {
31
+ var node = svg_edges[key][mkey];
32
+ var path = node.select("path");
33
+ var arrow = node.select("polygon");
34
+ path.style("stroke", "black");
35
+ arrow.style("stroke", "black").style("fill", "black");
36
+ }
37
+ }
38
+
39
+ for(var key in svg_nodes) {
40
+ var node = svg_nodes[key];
41
+ node.select('ellipse').style("fill", "white");
42
+ node.select('polygon').style("fill", "white");
43
+ }
44
+ return false;
45
+ }
46
+
47
+ function highlight_edge(from, to) {
48
+ var node = svg_edges[from][to];
49
+ var path = node.select("path");
50
+ var arrow = node.select("polygon");
51
+
52
+ path
53
+ .transition().duration(500)
54
+ .style("stroke", "green");
55
+
56
+ arrow
57
+ .transition().duration(500)
58
+ .style("stroke", "green").style("fill", "green");
59
+ }
60
+
61
+ function highlight_state(index, color) {
62
+ if(!color) { color = "green"; }
63
+
64
+ svg_nodes[index].select('ellipse')
65
+ .style("fill", "white")
66
+ .transition().duration(500)
67
+ .style("fill", color);
68
+ }
69
+
70
+ function highlight_finish(index) {
71
+ svg_nodes[index].select('polygon')
72
+ .style("fill", "while")
73
+ .transition().duration(500)
74
+ .style("fill", "blue");
75
+ }
76
+
77
+ function match(input) {
78
+ reset_graph();
79
+ var table = tt();
80
+ var states = [0];
81
+ var regexp_states = table['regexp_states'];
82
+ var string_states = table['string_states'];
83
+ var accepting = table['accepting'];
84
+
85
+ highlight_state(0);
86
+
87
+ tokenize(input, function(token) {
88
+ var new_states = [];
89
+ for(var key in states) {
90
+ var state = states[key];
91
+
92
+ if(string_states[state] && string_states[state][token]) {
93
+ var new_state = string_states[state][token];
94
+ highlight_edge(state, new_state);
95
+ highlight_state(new_state);
96
+ new_states.push(new_state);
97
+ }
98
+
99
+ if(regexp_states[state]) {
100
+ for(var key in regexp_states[state]) {
101
+ var re = new RegExp("^" + key + "$");
102
+ if(re.test(token)) {
103
+ var new_state = regexp_states[state][key];
104
+ highlight_edge(state, new_state);
105
+ highlight_state(new_state);
106
+ new_states.push(new_state);
107
+ }
108
+ }
109
+ }
110
+ }
111
+
112
+ if(new_states.length == 0) {
113
+ return;
114
+ }
115
+ states = new_states;
116
+ });
117
+
118
+ for(var key in states) {
119
+ var state = states[key];
120
+ if(accepting[state]) {
121
+ for(var mkey in svg_edges[state]) {
122
+ if(!regexp_states[mkey] && !string_states[mkey]) {
123
+ highlight_edge(state, mkey);
124
+ highlight_finish(mkey);
125
+ }
126
+ }
127
+ } else {
128
+ highlight_state(state, "red");
129
+ }
130
+ }
131
+
132
+ return false;
133
+ }
134
+
@@ -0,0 +1,52 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= title %></title>
5
+ <link rel="stylesheet" href="https://raw.github.com/gist/1706081/af944401f75ea20515a02ddb3fb43d23ecb8c662/reset.css" type="text/css">
6
+ <style>
7
+ <% stylesheets.each do |style| %>
8
+ <%= style %>
9
+ <% end %>
10
+ </style>
11
+ <script src="https://raw.github.com/gist/1706081/df464722a05c3c2bec450b7b5c8240d9c31fa52d/d3.min.js" type="text/javascript"></script>
12
+ </head>
13
+ <body>
14
+ <div id="wrapper">
15
+ <h1>Routes FSM with NFA simulation</h1>
16
+ <div class="instruction form">
17
+ <p>
18
+ Type a route in to the box and click "simulate".
19
+ </p>
20
+ <form onsubmit="return match(this.route.value);">
21
+ <input type="text" size="30" name="route" value="/articles/new" />
22
+ <button>simulate</button>
23
+ <input type="reset" value="reset" onclick="return reset_graph();"/>
24
+ </form>
25
+ <p class="fun_routes">
26
+ Some fun routes to try:
27
+ <% fun_routes.each do |path| %>
28
+ <a href="#" onclick="document.forms[0].elements[0].value=this.text.replace(/^\s+|\s+$/g,''); return match(this.text.replace(/^\s+|\s+$/g,''));">
29
+ <%= path %>
30
+ </a>
31
+ <% end %>
32
+ </p>
33
+ </div>
34
+ <div class='chart' id='chart-2'>
35
+ <%= svg %>
36
+ </div>
37
+ <div class="instruction">
38
+ <p>
39
+ This is a FSM for a system that has the following routes:
40
+ </p>
41
+ <ul>
42
+ <% paths.each do |route| %>
43
+ <li><%= route %></li>
44
+ <% end %>
45
+ </ul>
46
+ </div>
47
+ </div>
48
+ <% javascripts.each do |js| %>
49
+ <script><%= js %></script>
50
+ <% end %>
51
+ </body>
52
+ </html>
@@ -0,0 +1,5 @@
1
+ require 'action_dispatch/journey/router'
2
+ require 'action_dispatch/journey/gtg/builder'
3
+ require 'action_dispatch/journey/gtg/simulator'
4
+ require 'action_dispatch/journey/nfa/builder'
5
+ require 'action_dispatch/journey/nfa/simulator'
@@ -1,11 +1,10 @@
1
- require 'active_support/core_ext/module/delegation'
2
1
 
3
2
  module ActionDispatch
4
3
  # Provide callbacks to be executed before and after the request dispatch.
5
4
  class Callbacks
6
5
  include ActiveSupport::Callbacks
7
6
 
8
- define_callbacks :call, :rescuable => true
7
+ define_callbacks :call
9
8
 
10
9
  class << self
11
10
  delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader"
@@ -24,9 +23,15 @@ module ActionDispatch
24
23
  end
25
24
 
26
25
  def call(env)
27
- run_callbacks :call do
28
- @app.call(env)
26
+ error = nil
27
+ result = run_callbacks :call do
28
+ begin
29
+ @app.call(env)
30
+ rescue => error
31
+ end
29
32
  end
33
+ raise error if error
34
+ result
30
35
  end
31
36
  end
32
37
  end