fortitude 0.0.1

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 (332) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rspec-local +4 -0
  4. data/.travis.yml +26 -0
  5. data/Gemfile +5 -0
  6. data/LICENSE.txt +22 -0
  7. data/README-erector.md +246 -0
  8. data/README.md +15 -0
  9. data/Rakefile +67 -0
  10. data/ext/FortitudeJrubyNativeExtService.java +11 -0
  11. data/ext/com/fortituderuby/ext/fortitude/FortitudeNativeLibrary.java +223 -0
  12. data/ext/fortitude_native_ext/extconf.rb +4 -0
  13. data/ext/fortitude_native_ext/fortitude_native_ext.c +333 -0
  14. data/fortitude.gemspec +37 -0
  15. data/lib/fortitude/assign_locals_from_template.rb.smpl +22 -0
  16. data/lib/fortitude/assigns_proxy.rb +75 -0
  17. data/lib/fortitude/class_inheritable_attributes.rb +96 -0
  18. data/lib/fortitude/doctypes/base.rb +38 -0
  19. data/lib/fortitude/doctypes/html4.rb +20 -0
  20. data/lib/fortitude/doctypes/html4_frameset.rb +18 -0
  21. data/lib/fortitude/doctypes/html4_strict.rb +17 -0
  22. data/lib/fortitude/doctypes/html4_tags_frameset.rb +52 -0
  23. data/lib/fortitude/doctypes/html4_tags_strict.rb +273 -0
  24. data/lib/fortitude/doctypes/html4_tags_transitional.rb +114 -0
  25. data/lib/fortitude/doctypes/html4_transitional.rb +18 -0
  26. data/lib/fortitude/doctypes/html5.rb +372 -0
  27. data/lib/fortitude/doctypes/unknown_doctype.rb +19 -0
  28. data/lib/fortitude/doctypes/xhtml10.rb +19 -0
  29. data/lib/fortitude/doctypes/xhtml10_frameset.rb +17 -0
  30. data/lib/fortitude/doctypes/xhtml10_strict.rb +17 -0
  31. data/lib/fortitude/doctypes/xhtml10_transitional.rb +17 -0
  32. data/lib/fortitude/doctypes/xhtml11.rb +29 -0
  33. data/lib/fortitude/doctypes.rb +46 -0
  34. data/lib/fortitude/errors.rb +153 -0
  35. data/lib/fortitude/fortitude_ruby_ext.rb +71 -0
  36. data/lib/fortitude/instance_variable_set.rb +74 -0
  37. data/lib/fortitude/need_assignment_template.rb.smpl +16 -0
  38. data/lib/fortitude/need_method_template.rb.smpl +4 -0
  39. data/lib/fortitude/non_rails_widget_methods.rb +15 -0
  40. data/lib/fortitude/partial_tag_placeholder.rb +17 -0
  41. data/lib/fortitude/rails/helpers.rb +153 -0
  42. data/lib/fortitude/rails/renderer.rb +43 -0
  43. data/lib/fortitude/rails/template_handler.rb +23 -0
  44. data/lib/fortitude/rails/widget_methods.rb +17 -0
  45. data/lib/fortitude/rails/yielded_object_outputter.rb +31 -0
  46. data/lib/fortitude/railtie.rb +254 -0
  47. data/lib/fortitude/rendering_context.rb +205 -0
  48. data/lib/fortitude/simple_template.rb +45 -0
  49. data/lib/fortitude/staticized_method.rb +85 -0
  50. data/lib/fortitude/tag.rb +162 -0
  51. data/lib/fortitude/tag_method_template.rb.smpl +68 -0
  52. data/lib/fortitude/tag_return_value.rb +11 -0
  53. data/lib/fortitude/tag_store.rb +48 -0
  54. data/lib/fortitude/tag_support.rb +48 -0
  55. data/lib/fortitude/tags_module.rb +14 -0
  56. data/lib/fortitude/text_method_template.rb.smpl +17 -0
  57. data/lib/fortitude/tilt/fortitude_template.rb +169 -0
  58. data/lib/fortitude/version.rb +3 -0
  59. data/lib/fortitude/widget.rb +904 -0
  60. data/lib/fortitude/widgets/html4_frameset.rb +9 -0
  61. data/lib/fortitude/widgets/html4_strict.rb +9 -0
  62. data/lib/fortitude/widgets/html4_transitional.rb +9 -0
  63. data/lib/fortitude/widgets/html5.rb +9 -0
  64. data/lib/fortitude/widgets/xhtml10_frameset.rb +9 -0
  65. data/lib/fortitude/widgets/xhtml10_strict.rb +9 -0
  66. data/lib/fortitude/widgets/xhtml10_transitional.rb +9 -0
  67. data/lib/fortitude/widgets/xhtml11.rb +9 -0
  68. data/lib/fortitude.rb +93 -0
  69. data/lib/fortitude_jruby_native_ext.jar +0 -0
  70. data/spec/helpers/global_helper.rb +8 -0
  71. data/spec/helpers/rails_helpers.rb +85 -0
  72. data/spec/helpers/rails_server.rb +386 -0
  73. data/spec/helpers/system_helpers.rb +117 -0
  74. data/spec/rails/basic_rails_system_spec.rb +7 -0
  75. data/spec/rails/capture_system_spec.rb +75 -0
  76. data/spec/rails/class_loading_system_spec.rb +63 -0
  77. data/spec/rails/complex_helpers_system_spec.rb +33 -0
  78. data/spec/rails/data_passing_system_spec.rb +96 -0
  79. data/spec/rails/default_layout_system_spec.rb +15 -0
  80. data/spec/rails/development_mode_system_spec.rb +67 -0
  81. data/spec/rails/erb_integration_system_spec.rb +23 -0
  82. data/spec/rails/helpers_include_all_off_system_spec.rb +7 -0
  83. data/spec/rails/helpers_system_spec.rb +79 -0
  84. data/spec/rails/helpers_unrefined_system_spec.rb +7 -0
  85. data/spec/rails/layouts_system_spec.rb +60 -0
  86. data/spec/rails/localization_system_spec.rb +38 -0
  87. data/spec/rails/production_mode_system_spec.rb +13 -0
  88. data/spec/rails/rendering_context_system_spec.rb +64 -0
  89. data/spec/rails/rendering_system_spec.rb +158 -0
  90. data/spec/rails/rules_system_spec.rb +23 -0
  91. data/spec/rails/static_method_system_spec.rb +12 -0
  92. data/spec/rails/templates/base/app/controllers/application_controller.rb +15 -0
  93. data/spec/rails/templates/base/app/controllers/working_controller.rb +5 -0
  94. data/spec/rails/templates/base/app/views/layouts/application.html.erb +11 -0
  95. data/spec/rails/templates/base/config/routes.rb +4 -0
  96. data/spec/rails/templates/base/config/secrets.yml +22 -0
  97. data/spec/rails/templates/basic_rails_system_spec/app/controllers/basic_rails_system_spec_controller.rb +8 -0
  98. data/spec/rails/templates/basic_rails_system_spec/app/views/basic_rails_system_spec/trivial_widget.rb +5 -0
  99. data/spec/rails/templates/capture_system_spec/app/controllers/capture_system_spec_controller.rb +37 -0
  100. data/spec/rails/templates/capture_system_spec/app/views/capture_system_spec/_some_erb_partial.html.erb +1 -0
  101. data/spec/rails/templates/capture_system_spec/app/views/capture_system_spec/another_widget.rb +7 -0
  102. data/spec/rails/templates/capture_system_spec/app/views/capture_system_spec/capture_erb_from_widget.rb +11 -0
  103. data/spec/rails/templates/capture_system_spec/app/views/capture_system_spec/capture_widget_from_erb.html.erb +9 -0
  104. data/spec/rails/templates/capture_system_spec/app/views/capture_system_spec/capture_widget_from_widget.rb +17 -0
  105. data/spec/rails/templates/capture_system_spec/app/views/capture_system_spec/some_widget.rb +5 -0
  106. data/spec/rails/templates/capture_system_spec/app/views/capture_system_spec/widget_content_for.rb +19 -0
  107. data/spec/rails/templates/capture_system_spec/app/views/capture_system_spec/widget_layout_needing_content_yield_with_erb.html.erb +13 -0
  108. data/spec/rails/templates/capture_system_spec/app/views/capture_system_spec/widget_provide.rb +13 -0
  109. data/spec/rails/templates/capture_system_spec/app/views/layouts/erb_layout_needing_content.html.erb +15 -0
  110. data/spec/rails/templates/capture_system_spec/app/views/layouts/widget_layout_needing_content_content_for.rb +23 -0
  111. data/spec/rails/templates/capture_system_spec/app/views/layouts/widget_layout_needing_content_yield.rb +23 -0
  112. data/spec/rails/templates/class_loading_system_spec/app/controllers/class_loading_system_spec_controller.rb +74 -0
  113. data/spec/rails/templates/class_loading_system_spec/app/models/views/app_models_helper.rb +5 -0
  114. data/spec/rails/templates/class_loading_system_spec/app/models/views/models_widget.rb +5 -0
  115. data/spec/rails/templates/class_loading_system_spec/app/views/autoload_namespace/autoload_widget.rb +11 -0
  116. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/_loaded_underscore_widget.rb +11 -0
  117. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/_underscore_view.rb +5 -0
  118. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/_underscore_widget.rb +11 -0
  119. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/app_models.rb +6 -0
  120. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/autoload_one_widget_from_another.rb +7 -0
  121. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/class_should_not_load.rb +9 -0
  122. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/lib_views.rb +8 -0
  123. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/use_lib_widget_from_view_widget.rb +9 -0
  124. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/use_models_widget_from_view_widget.rb +7 -0
  125. data/spec/rails/templates/class_loading_system_spec/app/views/some_namespace/some_other_namespace/.git_keep +0 -0
  126. data/spec/rails/templates/class_loading_system_spec/app/views/sub_widget.rb +5 -0
  127. data/spec/rails/templates/class_loading_system_spec/lib/arbitrary_name/some_widget.rb +7 -0
  128. data/spec/rails/templates/class_loading_system_spec/lib/views/class_loading_system_spec/lib_views_helper.rb +5 -0
  129. data/spec/rails/templates/class_loading_system_spec/lib/views/class_loading_system_spec/widget_defined_outside_app_views.rb +5 -0
  130. data/spec/rails/templates/class_loading_system_spec/lib/views/lib_widget.rb +5 -0
  131. data/spec/rails/templates/complex_helpers_system_spec/app/controllers/complex_helpers_system_spec_controller.rb +14 -0
  132. data/spec/rails/templates/complex_helpers_system_spec/app/views/complex_helpers_system_spec/cache_test.rb +12 -0
  133. data/spec/rails/templates/complex_helpers_system_spec/app/views/complex_helpers_system_spec/fields_for_test.rb +14 -0
  134. data/spec/rails/templates/complex_helpers_system_spec/app/views/complex_helpers_system_spec/form_for_test.rb +14 -0
  135. data/spec/rails/templates/complex_helpers_system_spec/config/environments/development.rb +31 -0
  136. data/spec/rails/templates/data_passing_system_spec/app/controllers/data_passing_system_spec_controller.rb +101 -0
  137. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/_erb_to_parallel_widget_handoff_erb.html.erb +3 -0
  138. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/_implicit_erb_to_widget_handoff_erb.html.erb +3 -0
  139. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/_implicit_variable_write_erb.html.erb +1 -0
  140. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/_widget_to_parallel_erb_handoff_erb.html.erb +1 -0
  141. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/erb_copied_variables.html.erb +1 -0
  142. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/erb_to_parallel_widget_handoff.html.erb +2 -0
  143. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/erb_to_parallel_widget_handoff_widget.rb +5 -0
  144. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/explicit_controller_variable_read.rb +6 -0
  145. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/extra_variables.rb +23 -0
  146. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/extra_variables_requested.rb +24 -0
  147. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_erb_to_widget_handoff.html.erb +2 -0
  148. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_erb_to_widget_handoff_widget.rb +7 -0
  149. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_shared_variable_access.rb +5 -0
  150. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_shared_variable_access_inheritance.rb +6 -0
  151. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_shared_variable_access_inheritance_child_one.rb +7 -0
  152. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_shared_variable_access_inheritance_child_two.rb +5 -0
  153. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_shared_variable_access_inheritance_parent.rb +3 -0
  154. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_shared_variable_access_inner.rb +8 -0
  155. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_variable_read.rb +5 -0
  156. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_variable_read_inner.rb +7 -0
  157. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_variable_write.html.erb +2 -0
  158. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/implicit_variable_write_widget.rb +7 -0
  159. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/parent_to_child_passing.rb +7 -0
  160. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/parent_to_child_passing_child.rb +7 -0
  161. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/parent_to_child_passing_partial.rb +7 -0
  162. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/parent_to_child_passing_partial_child.rb +7 -0
  163. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/passing_data_widget.rb +8 -0
  164. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/passing_locals_and_controller_variables_widget.rb +9 -0
  165. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/passing_locals_widget.rb +8 -0
  166. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/variables_to_layout.rb +7 -0
  167. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/widget_copied_variables.rb +9 -0
  168. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/widget_to_parallel_erb_handoff.html.erb +2 -0
  169. data/spec/rails/templates/data_passing_system_spec/app/views/data_passing_system_spec/widget_to_parallel_erb_handoff_widget.rb +5 -0
  170. data/spec/rails/templates/data_passing_system_spec/app/views/layouts/data_layout.rb +14 -0
  171. data/spec/rails/templates/default_layout_system_spec/app/controllers/default_layout_system_spec_controller.rb +9 -0
  172. data/spec/rails/templates/default_layout_system_spec/app/views/default_layout_system_spec/erb_with_widget_default_layout.html.erb +1 -0
  173. data/spec/rails/templates/default_layout_system_spec/app/views/default_layout_system_spec/widget_with_widget_default_layout.rb +5 -0
  174. data/spec/rails/templates/default_layout_system_spec/app/views/layouts/application.rb +12 -0
  175. data/spec/rails/templates/development_mode_system_spec/app/controllers/development_mode_system_spec_controller.rb +9 -0
  176. data/spec/rails/templates/development_mode_system_spec/app/views/development_mode_system_spec/reload_widget.rb +7 -0
  177. data/spec/rails/templates/development_mode_system_spec/app/views/development_mode_system_spec/sample_output.rb +9 -0
  178. data/spec/rails/templates/erb_integration_system_spec/app/controllers/erb_integration_system_spec_controller.rb +10 -0
  179. data/spec/rails/templates/erb_integration_system_spec/app/views/erb_integration_system_spec/_erb_partial_from_widget_partial.html.erb +1 -0
  180. data/spec/rails/templates/erb_integration_system_spec/app/views/erb_integration_system_spec/_fortitude_partial_with_underscore_partial.rb +5 -0
  181. data/spec/rails/templates/erb_integration_system_spec/app/views/erb_integration_system_spec/_prefers_erb_partial_partial.html.erb +1 -0
  182. data/spec/rails/templates/erb_integration_system_spec/app/views/erb_integration_system_spec/erb_partial_from_widget.rb +7 -0
  183. data/spec/rails/templates/erb_integration_system_spec/app/views/erb_integration_system_spec/erb_to_widget_with_render_partial.html.erb +3 -0
  184. data/spec/rails/templates/erb_integration_system_spec/app/views/erb_integration_system_spec/erb_to_widget_with_render_partial_widget.rb +5 -0
  185. data/spec/rails/templates/erb_integration_system_spec/app/views/erb_integration_system_spec/fortitude_partial_with_underscore.html.erb +3 -0
  186. data/spec/rails/templates/erb_integration_system_spec/app/views/erb_integration_system_spec/prefers_erb_partial.html.erb +3 -0
  187. data/spec/rails/templates/erb_integration_system_spec/app/views/erb_integration_system_spec/prefers_erb_partial_partial.rb +5 -0
  188. data/spec/rails/templates/helpers_include_all_off_system_spec/app/controllers/helpers_include_all_off_system_spec_controller.rb +13 -0
  189. data/spec/rails/templates/helpers_include_all_off_system_spec/app/helpers/application_helper.rb +5 -0
  190. data/spec/rails/templates/helpers_include_all_off_system_spec/app/helpers/some_helper.rb +5 -0
  191. data/spec/rails/templates/helpers_include_all_off_system_spec/app/views/helpers_include_all_off_system_spec/include_all_off.rb +23 -0
  192. data/spec/rails/templates/helpers_include_all_off_system_spec/config/application.rb +28 -0
  193. data/spec/rails/templates/helpers_system_spec/app/controllers/helpers_system_spec_controller.rb +86 -0
  194. data/spec/rails/templates/helpers_system_spec/app/helpers/some_helper.rb +21 -0
  195. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/automatic_helpers_disabled.rb +37 -0
  196. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/automatic_helpers_inheritance.rb +6 -0
  197. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/automatic_helpers_inheritance_child_one.rb +34 -0
  198. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/automatic_helpers_inheritance_child_two.rb +36 -0
  199. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/automatic_helpers_inheritance_parent.rb +4 -0
  200. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/basic_helpers.rb +13 -0
  201. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/block_helpers.rb +7 -0
  202. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/built_in_outputting_helpers.rb +13 -0
  203. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/built_in_outputting_to_returning.rb +8 -0
  204. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/built_in_returning_to_outputting.rb +10 -0
  205. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/controller_helper_method.rb +5 -0
  206. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/controller_helper_module.rb +5 -0
  207. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/custom_helper_outputs.rb +6 -0
  208. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/custom_helpers_basic.rb +5 -0
  209. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/custom_helpers_with_a_block.rb +6 -0
  210. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/custom_outputting_to_returning.rb +7 -0
  211. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/custom_returning_to_outputting.rb +10 -0
  212. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/helper_settings_inheritance.rb +10 -0
  213. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/helper_settings_inheritance_parent.rb +4 -0
  214. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/helpers_that_output_when_refined.rb +9 -0
  215. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/private_helper_erb.html.erb +1 -0
  216. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/private_helper_fortitude.rb +5 -0
  217. data/spec/rails/templates/helpers_system_spec/lib/some_stuff.rb +5 -0
  218. data/spec/rails/templates/helpers_unrefined_system_spec/app/controllers/helpers_unrefined_system_spec_controller.rb +7 -0
  219. data/spec/rails/templates/helpers_unrefined_system_spec/app/views/helpers_unrefined_system_spec/helpers_that_output_when_refined.rb +9 -0
  220. data/spec/rails/templates/helpers_unrefined_system_spec/config/environments/production.rb +31 -0
  221. data/spec/rails/templates/layouts_system_spec/app/controllers/layouts_system_spec_controller.rb +31 -0
  222. data/spec/rails/templates/layouts_system_spec/app/views/layouts/alternate.html.erb +11 -0
  223. data/spec/rails/templates/layouts_system_spec/app/views/layouts/application.html.erb +26 -0
  224. data/spec/rails/templates/layouts_system_spec/app/views/layouts/explicit_yield.rb +12 -0
  225. data/spec/rails/templates/layouts_system_spec/app/views/layouts/widget_layout.rb +22 -0
  226. data/spec/rails/templates/layouts_system_spec/app/views/layouts_system_spec/erb_inside_widget_layout.html.erb +8 -0
  227. data/spec/rails/templates/layouts_system_spec/app/views/layouts_system_spec/the_render_widget.rb +5 -0
  228. data/spec/rails/templates/layouts_system_spec/app/views/layouts_system_spec/widget_inside_erb_layout.rb +8 -0
  229. data/spec/rails/templates/layouts_system_spec/app/views/layouts_system_spec/widget_inside_widget_layout.rb +8 -0
  230. data/spec/rails/templates/layouts_system_spec/app/views/layouts_system_spec/yield_from_widget_explicitly.rb +5 -0
  231. data/spec/rails/templates/localization_system_spec/app/controllers/localization_system_spec_controller.rb +31 -0
  232. data/spec/rails/templates/localization_system_spec/app/views/localization_system_spec/content_method.rb +13 -0
  233. data/spec/rails/templates/localization_system_spec/app/views/localization_system_spec/dot_notation.rb +5 -0
  234. data/spec/rails/templates/localization_system_spec/app/views/localization_system_spec/explicit_html.rb +13 -0
  235. data/spec/rails/templates/localization_system_spec/app/views/localization_system_spec/i18n_t.rb +5 -0
  236. data/spec/rails/templates/localization_system_spec/app/views/localization_system_spec/native_support.rb +7 -0
  237. data/spec/rails/templates/localization_system_spec/app/views/localization_system_spec/readjust_base.rb +7 -0
  238. data/spec/rails/templates/localization_system_spec/app/views/localization_system_spec/t.rb +5 -0
  239. data/spec/rails/templates/localization_system_spec/config/locales/en.yml +21 -0
  240. data/spec/rails/templates/localization_system_spec/config/locales/fr.yml +14 -0
  241. data/spec/rails/templates/localization_system_spec/config/locales/pt.yml +2 -0
  242. data/spec/rails/templates/production_mode_system_spec/app/controllers/production_mode_system_spec_controller.rb +5 -0
  243. data/spec/rails/templates/production_mode_system_spec/app/views/production_mode_system_spec/sample_output.rb +9 -0
  244. data/spec/rails/templates/rendering_context_system_spec/app/controllers/rendering_context_system_spec_controller.rb +72 -0
  245. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/_start_end_widget_through_partials_partial.html.erb +1 -0
  246. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/_uses_direct_context_for_all_widgets_partial.html.erb +1 -0
  247. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/_uses_specified_context_through_nesting_partial.html.erb +2 -0
  248. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/render_widget.rb +5 -0
  249. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/start_end_widget_basic.rb +12 -0
  250. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/start_end_widget_basic_inner.rb +7 -0
  251. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/start_end_widget_through_partials.rb +16 -0
  252. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/start_end_widget_through_partials_partial_widget.rb +7 -0
  253. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/uses_direct_context_for_all_widgets.rb +7 -0
  254. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/uses_direct_context_for_all_widgets_widget.rb +5 -0
  255. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/uses_direct_context_in_view.rb +5 -0
  256. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/uses_specified_context_in_partials.html.erb +3 -0
  257. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/uses_specified_context_in_partials_partial.rb +5 -0
  258. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/uses_specified_context_in_view.rb +5 -0
  259. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/uses_specified_context_through_nesting.rb +6 -0
  260. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/uses_specified_context_through_nesting_inner_partial.rb +5 -0
  261. data/spec/rails/templates/rendering_context_system_spec/lib/simple_rc.rb +17 -0
  262. data/spec/rails/templates/rendering_system_spec/app/controllers/rendering_system_spec_controller.rb +111 -0
  263. data/spec/rails/templates/rendering_system_spec/app/views/layouts/application.html.erb +19 -0
  264. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/_layout_for_partial.html.erb +3 -0
  265. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/_the_partial.html.erb +1 -0
  266. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/partial_with_layout.rb +5 -0
  267. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_collection.html.erb +3 -0
  268. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_collection_as.html.erb +3 -0
  269. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_file_from_widget.rb +7 -0
  270. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_html_safe_strings.rb +16 -0
  271. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_inline_from_widget.rb +11 -0
  272. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_object.html.erb +3 -0
  273. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_partial_from_widget.rb +7 -0
  274. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_partial_with_layout.html.erb +3 -0
  275. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_partial_with_widget_layout.html.erb +3 -0
  276. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_template_from_widget.rb +7 -0
  277. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/render_text_from_widget.rb +7 -0
  278. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/stream_widget.rb +13 -0
  279. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/trivial_widget.rb +5 -0
  280. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/widget_layout_for_partial.rb +7 -0
  281. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/widget_with_name.rb +7 -0
  282. data/spec/rails/templates/rendering_system_spec/app/views/rendering_system_spec/word.rb +7 -0
  283. data/spec/rails/templates/rendering_system_spec/app/views/widget_to_render.rb +7 -0
  284. data/spec/rails/templates/rules_system_spec/app/controllers/rules_system_spec_controller.rb +22 -0
  285. data/spec/rails/templates/rules_system_spec/app/views/layouts/fortitude_layout_with_p.rb +19 -0
  286. data/spec/rails/templates/rules_system_spec/app/views/rules_system_spec/_intervening_partial_erb_partial.html.erb +1 -0
  287. data/spec/rails/templates/rules_system_spec/app/views/rules_system_spec/intervening_partial.rb +9 -0
  288. data/spec/rails/templates/rules_system_spec/app/views/rules_system_spec/intervening_partial_fortitude_partial.rb +9 -0
  289. data/spec/rails/templates/rules_system_spec/app/views/rules_system_spec/invalid_start_tag_in_partial.html.erb +3 -0
  290. data/spec/rails/templates/rules_system_spec/app/views/rules_system_spec/invalid_start_tag_in_partial_partial.rb +9 -0
  291. data/spec/rails/templates/rules_system_spec/app/views/rules_system_spec/invalid_start_tag_in_view.rb +9 -0
  292. data/spec/rails/templates/rules_system_spec/app/views/rules_system_spec/invalidly_nested_tag.rb +11 -0
  293. data/spec/rails/templates/rules_system_spec/app/views/rules_system_spec/invalidly_nested_tag_in_partial.html.erb +3 -0
  294. data/spec/rails/templates/rules_system_spec/app/views/rules_system_spec/invalidly_nested_tag_in_partial_partial.rb +11 -0
  295. data/spec/rails/templates/static_method_system_spec/app/controllers/static_method_system_spec_controller.rb +15 -0
  296. data/spec/rails/templates/static_method_system_spec/app/helpers/some_helper.rb +10 -0
  297. data/spec/rails/templates/static_method_system_spec/app/views/static_method_system_spec/allows_helper_access.rb +8 -0
  298. data/spec/rails/templates/static_method_system_spec/app/views/static_method_system_spec/localization.rb +7 -0
  299. data/spec/rails/templates/static_method_system_spec/config/locales/en.yml +4 -0
  300. data/spec/rails/templates/static_method_system_spec/config/locales/fr.yml +4 -0
  301. data/spec/system/around_content_system_spec.rb +399 -0
  302. data/spec/system/assigns_system_spec.rb +316 -0
  303. data/spec/system/attribute_rules_system_spec.rb +227 -0
  304. data/spec/system/basic_system_spec.rb +9 -0
  305. data/spec/system/content_inheritance_system_spec.rb +13 -0
  306. data/spec/system/convenience_methods_system_spec.rb +30 -0
  307. data/spec/system/doctypes_system_spec.rb +213 -0
  308. data/spec/system/erector_compatibility_system_spec.rb +84 -0
  309. data/spec/system/escaping_system_spec.rb +43 -0
  310. data/spec/system/formatting_system_spec.rb +63 -0
  311. data/spec/system/helpers_system_spec.rb +235 -0
  312. data/spec/system/id_uniqueness_system_spec.rb +205 -0
  313. data/spec/system/localization_system_spec.rb +94 -0
  314. data/spec/system/method_precedence_system_spec.rb +48 -0
  315. data/spec/system/needs_system_spec.rb +368 -0
  316. data/spec/system/other_outputters_system_spec.rb +117 -0
  317. data/spec/system/rails_not_available_spec.rb +11 -0
  318. data/spec/system/rebuild_notifications_system_spec.rb +208 -0
  319. data/spec/system/rendering_context_system_spec.rb +83 -0
  320. data/spec/system/setting_inheritance_system_spec.rb +585 -0
  321. data/spec/system/shared_variable_system_spec.rb +120 -0
  322. data/spec/system/start_end_comments_system_spec.rb +363 -0
  323. data/spec/system/static_method_system_spec.rb +348 -0
  324. data/spec/system/tag_rendering_system_spec.rb +253 -0
  325. data/spec/system/tag_return_value_system_spec.rb +41 -0
  326. data/spec/system/tag_rules_system_spec.rb +196 -0
  327. data/spec/system/tag_updating_system_spec.rb +171 -0
  328. data/spec/system/tilt_system_spec.rb +378 -0
  329. data/spec/system/unparsed_data_system_spec.rb +16 -0
  330. data/spec/system/void_tags_system_spec.rb +51 -0
  331. data/spec/system/widget_return_values_system_spec.rb +89 -0
  332. metadata +736 -0
@@ -0,0 +1,254 @@
1
+ require 'fortitude/rendering_context'
2
+
3
+ if defined?(ActiveSupport)
4
+ ActiveSupport.on_load(:before_initialize) do
5
+ ActiveSupport.on_load(:action_view) do
6
+ require "fortitude/rails/template_handler"
7
+ end
8
+ end
9
+ end
10
+
11
+ module Fortitude
12
+ class << self
13
+ def refine_rails_helpers(on_or_off = :not_specified)
14
+ @refine_rails_helpers = !! on_or_off unless on_or_off == :not_specified
15
+ !! @refine_rails_helpers
16
+ end
17
+ end
18
+
19
+ refine_rails_helpers true
20
+ end
21
+
22
+ module Fortitude
23
+ class Railtie < ::Rails::Railtie
24
+ config.after_initialize do
25
+ if Fortitude.refine_rails_helpers
26
+ require 'fortitude/rails/helpers'
27
+ Fortitude::Rails::Helpers.apply_refined_helpers_to!(Fortitude::Widget)
28
+ end
29
+
30
+ if ::Rails.env.development?
31
+ ::Fortitude::Widget.class_eval do
32
+ format_output true
33
+ start_and_end_comments true
34
+ debug true
35
+ end
36
+ end
37
+ end
38
+
39
+ initializer :fortitude, :before => :set_autoload_paths do |app|
40
+ # All of this code is involved in setting up autoload_paths to work with Fortitude.
41
+ # Why so hard?
42
+ #
43
+ # We're trying to do something that ActiveSupport::Dependencies -- which is what Rails uses for
44
+ # class autoloading -- doesn't really support. We want app/views to be on the autoload path,
45
+ # because there are now Ruby classes living there. (It usually isn't just because all that's there
46
+ # are template source files, not actual Ruby code.) That isn't an issue, though -- adding it
47
+ # is trivial (just do
48
+ # <tt>ActiveSupport::Dependencies.autoload_paths << File.join(Rails.root, 'app/views')</tt>).
49
+ #
50
+ # The real issue is that we want the class <tt>app/views/foo/bar.rb</tt> to define a class called
51
+ # <tt>Views::Foo::Bar</tt>, not just plain <tt>Foo::Bar</tt>. This is what's different from what
52
+ # ActiveSupport::Dependencies normally supports; it expects the filesystem path underneath the
53
+ # root to be exactly identical to the fully-qualified class name.
54
+ #
55
+ # Why are we doing this crazy thing? Because we want you to be able to have a view called
56
+ # <tt>app/views/user/password.rb</tt>, and _not_ have that conflict with a module you just happen to define
57
+ # elsewhere called <tt>User::Password</tt>. If we don't prefix view classes with anything at all, then the
58
+ # potential for conflicts is enormous.
59
+ #
60
+ # As such, we have this code. We'll walk through it step-by-step; note that at the end we *do*
61
+ # add app/views/ to the autoload path, so all this code is doing is just dealing with the fact that
62
+ # the fully-qualified classname (<tt>Views::Foo::Bar</tt>) has one extra component on the front of it
63
+ # (<tt>Views::</tt>) when compared to the subpath (<tt>foo/bar.rb</tt>) underneath what's on the autoload
64
+ # path (<tt>app/views</tt>).
65
+
66
+ # Go compute our views root.
67
+ views_root = File.expand_path(File.join(::Rails.root, 'app', 'views'))
68
+
69
+ # Now, do all this work inside ::ActiveSupport::Dependencies...
70
+ ::ActiveSupport::Dependencies.module_eval do
71
+ @@_fortitude_views_root = views_root
72
+
73
+ # This is the method that gets called to auto-generate namespacing empty
74
+ # modules (_e.g._, the toplevel <tt>Views::</tt> module) for directories
75
+ # under an autoload path.
76
+ #
77
+ # The original method says:
78
+ #
79
+ # "Does the provided path_suffix correspond to an autoloadable module?
80
+ # Instead of returning a boolean, the autoload base for this module is
81
+ # returned."
82
+ #
83
+ # So, we just need to strip off the leading +views/+ from the +path_suffix+,
84
+ # and see if that maps to a directory underneath <tt>app/views/</tt>; if so,
85
+ # we'll return the path to <tt>.../app/views/</tt>. Otherwise, we just
86
+ # delegate back to the superclass method.
87
+ def autoloadable_module_with_fortitude?(path_suffix)
88
+ if path_suffix =~ %r{^views(/.*)?$}i
89
+ # If we got here, then we were passed a subpath of views/....
90
+ subpath = $1
91
+
92
+ if subpath.blank? || File.directory?(File.join(@@_fortitude_views_root, subpath))
93
+ return @@_fortitude_views_root
94
+ end
95
+ end
96
+
97
+ with_fortitude_views_removed_from_autoload_path do
98
+ autoloadable_module_without_fortitude?(path_suffix)
99
+ end
100
+ end
101
+
102
+ alias_method_chain :autoloadable_module?, :fortitude
103
+
104
+ # When we delegate back to original methods, we want them to act as if
105
+ # <tt>app/views/</tt> is _not_ on the autoload path. In order to be thread-safe
106
+ # about that, we couple this method with our override of the writer side of the
107
+ # <tt>mattr_accessor :autoload_paths</tt>, which simply prefers the thread-local
108
+ # that we set to the actual underlying variable.
109
+ def with_fortitude_views_removed_from_autoload_path
110
+ begin
111
+ Thread.current[:_fortitude_autoload_paths_override] = autoload_paths - [ @@_fortitude_views_root ]
112
+ yield
113
+ ensure
114
+ Thread.current[:_fortitude_autoload_paths_override] = nil
115
+ end
116
+ end
117
+
118
+ # The use of 'class_eval' here may seem funny, and I think it is, but, without it,
119
+ # the +@@autoload_paths+ gets interpreted as a class variable for this *Railtie*,
120
+ # rather than for ::ActiveSupport::Dependencies. (Why is that? Got me...)
121
+ class_eval <<-EOS
122
+ def self.autoload_paths
123
+ Thread.current[:_fortitude_autoload_paths_override] || @@autoload_paths
124
+ end
125
+ EOS
126
+
127
+ # The original method says:
128
+ #
129
+ # "Search for a file in autoload_paths matching the provided suffix."
130
+ #
131
+ # So, we just look to see if the given +path_suffix+ is specifying something like
132
+ # <tt>views/foo/bar</tt>; if so, we glue it together properly, removing the initial
133
+ # <tt>views/</tt> first. (Otherwise, the mechanism would expect
134
+ # <tt>Views::Foo::Bar</tt> to show up in <tt>app/views/views/foo/bar</tt> (yes, a double
135
+ # +views+), since <tt>app/views</tt> is on the autoload path.)
136
+ def search_for_file_with_fortitude(path_suffix)
137
+ # This just makes sure our path always ends in exactly one ".rb", whether it started
138
+ # with one or not.
139
+ new_path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb")
140
+
141
+ if new_path_suffix =~ %r{^views(/.*)$}i
142
+ path = File.join(@@_fortitude_views_root, $1)
143
+ return path if File.file?(path)
144
+ end
145
+
146
+ # Make sure that we remove the views autoload path before letting the rest of
147
+ # the dependency mechanism go searching for files, or else <tt>app/views/foo/bar.rb</tt>
148
+ # *will* be found when looking for just <tt>::Foo::Bar</tt>.
149
+ with_fortitude_views_removed_from_autoload_path { search_for_file_without_fortitude(path_suffix) }
150
+ end
151
+
152
+ alias_method_chain :search_for_file, :fortitude
153
+ end
154
+
155
+ # And, finally, this is where we add our root to the set of autoload paths.
156
+ ::ActiveSupport::Dependencies.autoload_paths << views_root
157
+
158
+ # This is our support for partials. Fortitude doesn't really have a distinction between
159
+ # partials and "full" templates -- everything is just a widget, which is much more elegant --
160
+ # but we still want you to be able to render a widget <tt>Views::Foo::Bar</tt> by saying
161
+ # <tt>render :partial => 'foo/bar'</tt> (from ERb, although you can do it from Fortitude if
162
+ # you want for some reason, too).
163
+ #
164
+ # Normally, ActionView only looks for partials in files starting with an underscore. We
165
+ # do want to allow this, too (in the above case, if you define the widget in the file
166
+ # <tt>app/views/foo/_bar.rb</tt>, it will still work fine); however, we also want to allow
167
+ # you to define it in a file that does _not_ start with an underscore ('cause these are
168
+ # Ruby classes, and that's just plain weird).
169
+ #
170
+ # So, we patch #find_templates: if it's looking for a partial, doesn't find one, and is
171
+ # searching Fortitude templates (the +.rb+ handler), then we try again, turning off the
172
+ # +partial+ flag, and return that instead.
173
+ ::ActionView::PathResolver.class_eval do
174
+ def find_templates_with_fortitude(name, prefix, partial, details)
175
+ templates = find_templates_without_fortitude(name, prefix, partial, details)
176
+ if partial && templates.empty? && details[:handlers] && details[:handlers].include?(:rb)
177
+ templates = find_templates_without_fortitude(name, prefix, false, details.merge(:handlers => [ :rb ]))
178
+ end
179
+ templates
180
+ end
181
+
182
+ alias_method_chain :find_templates, :fortitude
183
+ end
184
+
185
+ require "fortitude/rails/template_handler"
186
+
187
+ # This is our support for render :widget. Although, originally, it looked like creating a new subclass
188
+ # of ActionView::Template was going to be the correct thing to do here, it turns out it isn't: the entire
189
+ # template system is predicated around the idea that you have a template, which is compiled to output
190
+ # Ruby source code, and then that gets evaluated to actually generate output.
191
+ #
192
+ # Because <tt>render :widget => ...</tt> takes an already-instantiated widget as input, this simply isn't
193
+ # possible: you can't reverse-engineer an arbitrary Ruby object into source code, and, without source code,
194
+ # the whole templating paradigm doesn't make sense.
195
+ #
196
+ # So, instead, we simply transform <tt>render :widget => ...</tt> into a <tt>render :text => ...</tt> of the
197
+ # widget's output, and let Rails take it away from there.
198
+ ::ActionController::Base.class_eval do
199
+ def fortitude_rendering_context(options)
200
+ @_fortitude_rendering_context ||= create_fortitude_rendering_context(options)
201
+ end
202
+
203
+ def create_fortitude_rendering_context(options)
204
+ ::Fortitude::RenderingContext.new(options)
205
+ end
206
+
207
+ def render_with_fortitude(*args, &block)
208
+ if (options = args[0]).kind_of?(Hash)
209
+ if (widget = options[:widget])
210
+ rendering_context = fortitude_rendering_context(:delegate_object => self)
211
+ widget.to_html(rendering_context)
212
+
213
+ options = options.dup
214
+ options[:text] = rendering_context.output_buffer_holder.output_buffer.html_safe
215
+ options[:layout] = true unless options.has_key?(:layout)
216
+
217
+ new_args = [ options ] + args[1..-1]
218
+ return render_without_fortitude(*new_args, &block)
219
+ elsif (widget_block = options[:inline]) && (options[:type] == :fortitude)
220
+ options.delete(:inline)
221
+
222
+ rendering_context = fortitude_rendering_context(:delegate_object => self)
223
+ widget_class = Class.new(Fortitude::Widgets::Html5)
224
+ widget_class.use_instance_variables_for_assigns(true)
225
+ widget_class.extra_assigns(:use)
226
+ widget_class.send(:define_method, :content, &widget_block)
227
+
228
+ assigns = { }
229
+ instance_variables.each do |ivar_name|
230
+ value = instance_variable_get(ivar_name)
231
+ assigns[$1.to_sym] = value if ivar_name =~ /^@(.*)$/
232
+ end
233
+ assigns = assigns.merge(options[:locals] || { })
234
+
235
+ widget = widget_class.new(assigns)
236
+ widget.to_html(rendering_context)
237
+
238
+ options = options.dup
239
+ options[:text] = rendering_context.output_buffer_holder.output_buffer.html_safe
240
+ options[:layout] = true unless options.has_key?(:layout)
241
+
242
+ new_args = [ options ] + args[1..-1]
243
+ return render_without_fortitude(*new_args, &block)
244
+ end
245
+ end
246
+
247
+ return render_without_fortitude(*args, &block)
248
+ end
249
+
250
+ alias_method_chain :render, :fortitude
251
+ end
252
+ end
253
+ end
254
+ end
@@ -0,0 +1,205 @@
1
+ require 'fortitude/instance_variable_set'
2
+
3
+ module Fortitude
4
+ class RenderingContext
5
+ attr_reader :output_buffer_holder, :instance_variable_set, :helpers_object
6
+
7
+ def initialize(options)
8
+ options.assert_valid_keys(:delegate_object, :output_buffer_holder, :helpers_object, :instance_variables_object,
9
+ :yield_block, :render_yield_result)
10
+
11
+ @output_buffer_holder = options[:output_buffer_holder]
12
+ if (! @output_buffer_holder) && options[:delegate_object] && options[:delegate_object].respond_to?(:output_buffer)
13
+ @output_buffer_holder = options[:delegate_object]
14
+ end
15
+ @output_buffer_holder ||= OutputBufferHolder.new
16
+ @helpers_object = options[:helpers_object] || options[:delegate_object] || Object.new
17
+
18
+ instance_variables_object = options[:instance_variables_object] || options[:delegate_object] || Object.new
19
+ @instance_variable_set = Fortitude::InstanceVariableSet.new(instance_variables_object)
20
+
21
+ @render_yield_result = true unless options.has_key?(:render_yield_result) && (! options[:render_yield_result])
22
+
23
+ @indent = 0
24
+ @newline_needed = false
25
+ @have_output = false
26
+ @indenting_disabled = false
27
+
28
+ @current_element_nesting = [ ]
29
+ @current_widget_nesting = [ ]
30
+ @ids_used = { }
31
+
32
+ @yield_block = options[:yield_block]
33
+ end
34
+
35
+ def with_element_nesting_validation(value)
36
+ old_value = @element_nesting_validation_disabled
37
+ @element_nesting_validation_disabled = !value
38
+ begin
39
+ yield
40
+ ensure
41
+ @element_nesting_validation_disabled = old_value
42
+ end
43
+ end
44
+
45
+ def with_attribute_validation(value)
46
+ old_value = @attribute_validation_disabled
47
+ @attribute_validation_disabled = !value
48
+ begin
49
+ yield
50
+ ensure
51
+ @attribute_validation_disabled = old_value
52
+ end
53
+ end
54
+
55
+ def with_id_uniqueness(value)
56
+ old_value = @id_uniqueness_disabled
57
+ @id_uniqueness_disabled = !value
58
+ begin
59
+ yield
60
+ ensure
61
+ @id_uniqueness_disabled = old_value
62
+ end
63
+ end
64
+
65
+ def attribute_validation_disabled?
66
+ !! @attribute_validation_disabled
67
+ end
68
+
69
+ def record_widget(widget)
70
+ start_widget!(widget)
71
+ @current_widget_nesting << widget
72
+ begin
73
+ yield
74
+ ensure
75
+ last = @current_widget_nesting.pop
76
+ unless last.equal?(widget)
77
+ raise "Something horrible happened -- the last widget we started was #{last}, but now we're ending #{widget}?!?"
78
+ end
79
+ end_widget!(widget)
80
+ end
81
+ end
82
+
83
+ def start_widget!(widget)
84
+ # nothing here
85
+ end
86
+
87
+ def end_widget!(widget)
88
+ # nothing here
89
+ end
90
+
91
+ def current_widget_depth
92
+ @current_widget_nesting.length - 1
93
+ end
94
+
95
+ def record_tag(widget, tag_object)
96
+ validate_element_for_rules(widget, tag_object)
97
+ @current_element_nesting << tag_object
98
+
99
+ begin
100
+ yield
101
+ ensure
102
+ last = @current_element_nesting.pop
103
+ unless last.equal?(tag_object)
104
+ raise "Something horrible happened -- the last tag we started was #{last}, but now we're ending #{tag_object}?!?"
105
+ end
106
+ end
107
+ end
108
+
109
+ def format_output?
110
+ true
111
+ end
112
+
113
+ def increase_indent!
114
+ @indent += 1
115
+ end
116
+
117
+ def decrease_indent!
118
+ @indent -= 1
119
+ end
120
+
121
+ def needs_newline!
122
+ @newline_needed = true
123
+ end
124
+
125
+ def current_indent
126
+ (" " * @indent).freeze
127
+ end
128
+
129
+ def with_indenting_disabled
130
+ old_indenting_disabled = @indenting_disabled
131
+ @indenting_disabled = true
132
+ begin
133
+ yield
134
+ ensure
135
+ @indenting_disabled = old_indenting_disabled
136
+ end
137
+ end
138
+
139
+ def about_to_output_non_whitespace!
140
+ if @newline_needed
141
+ if @have_output
142
+ o = @output_buffer_holder.output_buffer
143
+ o.original_concat(NEWLINE)
144
+ o.original_concat(current_indent) unless @indenting_disabled
145
+ end
146
+
147
+ @newline_needed = false
148
+ end
149
+
150
+ @have_output = true
151
+ end
152
+
153
+ def with_yield_block(new_yield_block)
154
+ old_yield_block, @yield_block = @yield_block, new_yield_block
155
+ begin
156
+ yield
157
+ ensure
158
+ @yield_block = old_yield_block
159
+ end
160
+ end
161
+
162
+ NEWLINE = "\n"
163
+
164
+ def yield_from_widget(*args)
165
+ raise "No layout to yield to!" unless @yield_block
166
+ result = @yield_block.call(*args)
167
+ @output_buffer_holder.output_buffer << result if @render_yield_result
168
+ result
169
+ end
170
+
171
+ def flush!
172
+ # nothing here right now
173
+ end
174
+
175
+ def validate_id_uniqueness(widget, tag_name, id)
176
+ id = id.to_s
177
+ if @ids_used[id] && (! @id_uniqueness_disabled)
178
+ (already_used_widget, already_used_tag_name) = @ids_used[id]
179
+ raise Fortitude::Errors::DuplicateId.new(widget, id, already_used_widget, already_used_tag_name, tag_name)
180
+ else
181
+ @ids_used[id] = [ widget, tag_name ]
182
+ end
183
+ end
184
+
185
+ private
186
+ def validate_element_for_rules(widget, tag_object)
187
+ current = @current_element_nesting[-1]
188
+ current.validate_can_enclose!(widget, tag_object) if current && (! @element_nesting_validation_disabled)
189
+ end
190
+
191
+ class OutputBufferHolder
192
+ attr_accessor :output_buffer
193
+
194
+ def initialize
195
+ if defined?(::ActionView::OutputBuffer)
196
+ @output_buffer = ::ActionView::OutputBuffer.new
197
+ else
198
+ @output_buffer = ::ActiveSupport::SafeBuffer.new
199
+ end
200
+
201
+ @output_buffer.force_encoding(Encoding::UTF_8) if @output_buffer.respond_to?(:force_encoding)
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,45 @@
1
+ module Fortitude
2
+ class SimpleTemplate
3
+ class << self
4
+ def template(name)
5
+ @templates ||= { }
6
+ @templates[name] ||= new(File.join(File.dirname(__FILE__), "#{name}.rb.smpl"))
7
+ end
8
+ end
9
+
10
+ def initialize(source_file)
11
+ @lines = File.read(source_file).split(/\r\n|\r|\n/)
12
+ end
13
+
14
+ def result(bindings)
15
+ bindings = bindings.stringify_keys
16
+ bindings_target = Object.new
17
+ bindings.each do |key, value|
18
+ (class << bindings_target; self; end).send(:define_method, key) { value }
19
+ end
20
+
21
+ result_lines = [ ]
22
+ @lines.each do |l|
23
+ if l =~ /^(.*)\#\s*\:if\s*(.*?)\s*$/i
24
+ l, condition = $1, $2
25
+ next unless bindings_target.instance_eval(condition)
26
+ end
27
+
28
+ while l =~ /[^\\]\#\{([^}]+)\}/ || l =~ /^\#\{([^}]+)\}/
29
+ name = $1
30
+ begin
31
+ value = bindings_target.send($1)
32
+ rescue => e
33
+ raise "Failed when processing #{l.inspect}: #{e.inspect}"
34
+ end
35
+ l = l.gsub("\#\{#{$1}\}", value.to_s)
36
+ end
37
+ l = l.gsub(/\\\#\{/, "\#\{")
38
+
39
+ result_lines << l
40
+ end
41
+
42
+ result_lines.join("\n")
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,85 @@
1
+ module Fortitude
2
+ class StaticizedMethod
3
+ def initialize(widget_class, method_name, options = { })
4
+ @widget_class = widget_class
5
+ @method_name = method_name
6
+
7
+ @output_by_locale = { }
8
+ @has_yield = false
9
+
10
+ @options = options
11
+ @options.assert_valid_keys(:locale_support)
12
+
13
+ set_constant!
14
+ end
15
+
16
+ def run!(widget)
17
+ locale = locale_support? ? widget.widget_locale : nil
18
+ output = (@output_by_locale[locale] ||= generate_content!(widget))
19
+
20
+ if output.kind_of?(Array)
21
+ widget.rawtext(output[0])
22
+ yield
23
+ widget.rawtext(output[1])
24
+ else
25
+ widget.rawtext(output)
26
+ end
27
+ end
28
+
29
+ def create_method!
30
+ unless widget_class.instance_methods.map(&:to_s).include?(dynamic_method_name.to_s)
31
+ widget_class.send(:alias_method, dynamic_method_name, method_name)
32
+ end
33
+
34
+ widget_class.class_eval <<-EOS
35
+ def #{method_name}
36
+ #{constant_name}.run!(self) { yield }
37
+ end
38
+ EOS
39
+ end
40
+
41
+ private
42
+ attr_reader :widget_class, :method_name, :output_by_locale, :has_yield, :options
43
+
44
+ def locale_support?
45
+ ! (options.has_key?(:locale_support) && (! options[:locale_support]))
46
+ end
47
+
48
+ def generate_content!(widget)
49
+ yielded = false
50
+ pre_yield = nil
51
+
52
+ result = widget.capture do
53
+ widget.with_staticness_enforced(method_name) do
54
+ widget.send(dynamic_method_name) do
55
+ raise "This method yields more than once; you can't make it static" if yielded
56
+ pre_yield = widget.output_buffer.dup
57
+ yielded = true
58
+ widget.output_buffer.replace('')
59
+ end
60
+ end
61
+ end
62
+
63
+ @has_yield = yielded
64
+
65
+ if yielded
66
+ [ pre_yield, result ]
67
+ else
68
+ result
69
+ end
70
+ end
71
+
72
+ def set_constant!
73
+ widget_class.send(:remove_const, constant_name) if widget_class.const_defined?(constant_name)
74
+ widget_class.const_set(constant_name, self)
75
+ end
76
+
77
+ def constant_name
78
+ "FORTITUDE_STATICIZED_METHOD_#{method_name.to_s.upcase}"
79
+ end
80
+
81
+ def dynamic_method_name
82
+ "_#{method_name}_dynamic".to_sym
83
+ end
84
+ end
85
+ end