phlex-rails 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (225) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +4 -6
  3. data/Gemfile +3 -5
  4. data/lib/generators/phlex/component/USAGE +1 -1
  5. data/lib/generators/phlex/component/templates/component.rb.erb +1 -1
  6. data/lib/generators/phlex/install/install_generator.rb +1 -2
  7. data/lib/generators/phlex/install/templates/application_layout.rb +1 -1
  8. data/lib/generators/phlex/view/templates/view.rb.erb +1 -1
  9. data/lib/phlex/rails/csv.rb +16 -0
  10. data/lib/phlex/rails/fragment_finder.rb +28 -0
  11. data/lib/phlex/rails/helper_macros.rb +11 -31
  12. data/lib/phlex/rails/helpers/action_cable_meta_tag.rb +11 -0
  13. data/lib/phlex/rails/helpers/action_name.rb +10 -0
  14. data/lib/phlex/rails/helpers/asset_path.rb +15 -0
  15. data/lib/phlex/rails/helpers/asset_url.rb +8 -0
  16. data/lib/phlex/rails/helpers/audio_path.rb +8 -0
  17. data/lib/phlex/rails/helpers/audio_tag.rb +9 -0
  18. data/lib/phlex/rails/helpers/audio_url.rb +8 -0
  19. data/lib/phlex/rails/helpers/auto_discovery_link_tag.rb +9 -0
  20. data/lib/phlex/rails/helpers/build_tag_values.rb +8 -0
  21. data/lib/phlex/rails/helpers/button_tag.rb +9 -0
  22. data/lib/phlex/rails/helpers/button_to.rb +9 -0
  23. data/lib/phlex/rails/helpers/check_box.rb +9 -0
  24. data/lib/phlex/rails/helpers/check_box_tag.rb +9 -0
  25. data/lib/phlex/rails/helpers/class_names.rb +8 -0
  26. data/lib/phlex/rails/helpers/collection_check_boxes.rb +10 -0
  27. data/lib/phlex/rails/helpers/collection_radio_buttons.rb +10 -0
  28. data/lib/phlex/rails/helpers/collection_select.rb +9 -0
  29. data/lib/phlex/rails/helpers/color_field.rb +9 -0
  30. data/lib/phlex/rails/helpers/color_field_tag.rb +9 -0
  31. data/lib/phlex/rails/helpers/compute_asset_extname.rb +8 -0
  32. data/lib/phlex/rails/helpers/compute_asset_host.rb +8 -0
  33. data/lib/phlex/rails/helpers/compute_asset_path.rb +8 -0
  34. data/lib/phlex/rails/helpers/content_for.rb +11 -0
  35. data/lib/phlex/rails/helpers/content_tag.rb +9 -0
  36. data/lib/phlex/rails/helpers/controller_name.rb +8 -0
  37. data/lib/phlex/rails/helpers/controller_path.rb +8 -0
  38. data/lib/phlex/rails/helpers/csp_meta_tag.rb +9 -0
  39. data/lib/phlex/rails/helpers/csrf_meta_tags.rb +9 -0
  40. data/lib/phlex/rails/helpers/current_cycle.rb +8 -0
  41. data/lib/phlex/rails/helpers/current_page.rb +8 -0
  42. data/lib/phlex/rails/helpers/cycle.rb +8 -0
  43. data/lib/phlex/rails/helpers/date_field.rb +9 -0
  44. data/lib/phlex/rails/helpers/date_field_tag.rb +9 -0
  45. data/lib/phlex/rails/helpers/date_select.rb +9 -0
  46. data/lib/phlex/rails/helpers/datetime_field.rb +9 -0
  47. data/lib/phlex/rails/helpers/datetime_field_tag.rb +9 -0
  48. data/lib/phlex/rails/helpers/datetime_local_field.rb +9 -0
  49. data/lib/phlex/rails/helpers/datetime_local_field_tag.rb +9 -0
  50. data/lib/phlex/rails/helpers/datetime_select.rb +9 -0
  51. data/lib/phlex/rails/helpers/debug.rb +9 -0
  52. data/lib/phlex/rails/helpers/default_url_options.rb +8 -0
  53. data/lib/phlex/rails/helpers/distance_of_time_in_words.rb +8 -0
  54. data/lib/phlex/rails/helpers/distance_of_time_in_words_to_now.rb +8 -0
  55. data/lib/phlex/rails/helpers/dom_class.rb +8 -0
  56. data/lib/phlex/rails/helpers/dom_id.rb +8 -0
  57. data/lib/phlex/rails/helpers/email_field.rb +9 -0
  58. data/lib/phlex/rails/helpers/email_field_tag.rb +9 -0
  59. data/lib/phlex/rails/helpers/error_message.rb +8 -0
  60. data/lib/phlex/rails/helpers/error_wrapping.rb +9 -0
  61. data/lib/phlex/rails/helpers/escape_once.rb +8 -0
  62. data/lib/phlex/rails/helpers/excerpt.rb +8 -0
  63. data/lib/phlex/rails/helpers/favicon_link_tag.rb +9 -0
  64. data/lib/phlex/rails/helpers/field_id.rb +8 -0
  65. data/lib/phlex/rails/helpers/field_name.rb +8 -0
  66. data/lib/phlex/rails/helpers/field_set_tag.rb +9 -0
  67. data/lib/phlex/rails/helpers/fields.rb +10 -0
  68. data/lib/phlex/rails/helpers/fields_for.rb +10 -0
  69. data/lib/phlex/rails/helpers/file_field.rb +9 -0
  70. data/lib/phlex/rails/helpers/file_field_tag.rb +9 -0
  71. data/lib/phlex/rails/helpers/flash.rb +8 -0
  72. data/lib/phlex/rails/helpers/font_path.rb +8 -0
  73. data/lib/phlex/rails/helpers/font_url.rb +8 -0
  74. data/lib/phlex/rails/helpers/form_for.rb +10 -0
  75. data/lib/phlex/rails/helpers/form_tag.rb +9 -0
  76. data/lib/phlex/rails/helpers/form_with.rb +10 -0
  77. data/lib/phlex/rails/helpers/grouped_collection_select.rb +9 -0
  78. data/lib/phlex/rails/helpers/grouped_options_for_select.rb +9 -0
  79. data/lib/phlex/rails/helpers/hidden_field.rb +9 -0
  80. data/lib/phlex/rails/helpers/hidden_field_tag.rb +9 -0
  81. data/lib/phlex/rails/helpers/highlight.rb +9 -0
  82. data/lib/phlex/rails/helpers/image_path.rb +8 -0
  83. data/lib/phlex/rails/helpers/image_submit_tag.rb +9 -0
  84. data/lib/phlex/rails/helpers/image_tag.rb +9 -0
  85. data/lib/phlex/rails/helpers/image_url.rb +8 -0
  86. data/lib/phlex/rails/helpers/javascript_import_module_tag.rb +9 -0
  87. data/lib/phlex/rails/helpers/javascript_importmap_tags.rb +9 -0
  88. data/lib/phlex/rails/helpers/javascript_include_tag.rb +9 -0
  89. data/lib/phlex/rails/helpers/javascript_path.rb +8 -0
  90. data/lib/phlex/rails/helpers/javascript_tag.rb +9 -0
  91. data/lib/phlex/rails/helpers/javascript_url.rb +8 -0
  92. data/lib/phlex/rails/helpers/l.rb +8 -0
  93. data/lib/phlex/rails/helpers/label.rb +8 -0
  94. data/lib/phlex/rails/helpers/label_tag.rb +9 -0
  95. data/lib/phlex/rails/helpers/link_to.rb +9 -0
  96. data/lib/phlex/rails/helpers/link_to_if.rb +9 -0
  97. data/lib/phlex/rails/helpers/link_to_unless.rb +9 -0
  98. data/lib/phlex/rails/helpers/link_to_unless_current.rb +9 -0
  99. data/lib/phlex/rails/helpers/localize.rb +8 -0
  100. data/lib/phlex/rails/helpers/mail_to.rb +9 -0
  101. data/lib/phlex/rails/helpers/month_field.rb +9 -0
  102. data/lib/phlex/rails/helpers/month_field_tag.rb +9 -0
  103. data/lib/phlex/rails/helpers/number_field.rb +9 -0
  104. data/lib/phlex/rails/helpers/number_field_tag.rb +9 -0
  105. data/lib/phlex/rails/helpers/number_to_currency.rb +8 -0
  106. data/lib/phlex/rails/helpers/number_to_human.rb +8 -0
  107. data/lib/phlex/rails/helpers/number_to_human_size.rb +8 -0
  108. data/lib/phlex/rails/helpers/number_to_percentage.rb +8 -0
  109. data/lib/phlex/rails/helpers/number_to_phone.rb +8 -0
  110. data/lib/phlex/rails/helpers/number_with_delimiter.rb +8 -0
  111. data/lib/phlex/rails/helpers/number_with_precision.rb +8 -0
  112. data/lib/phlex/rails/helpers/object.rb +8 -0
  113. data/lib/phlex/rails/helpers/option_groups_from_collection_for_select.rb +9 -0
  114. data/lib/phlex/rails/helpers/options_for_select.rb +9 -0
  115. data/lib/phlex/rails/helpers/options_from_collection_for_select.rb +9 -0
  116. data/lib/phlex/rails/helpers/password_field.rb +9 -0
  117. data/lib/phlex/rails/helpers/password_field_tag.rb +9 -0
  118. data/lib/phlex/rails/helpers/path_to_asset.rb +8 -0
  119. data/lib/phlex/rails/helpers/path_to_audio.rb +8 -0
  120. data/lib/phlex/rails/helpers/path_to_font.rb +8 -0
  121. data/lib/phlex/rails/helpers/path_to_image.rb +8 -0
  122. data/lib/phlex/rails/helpers/path_to_javascript.rb +8 -0
  123. data/lib/phlex/rails/helpers/path_to_stylesheet.rb +8 -0
  124. data/lib/phlex/rails/helpers/path_to_video.rb +8 -0
  125. data/lib/phlex/rails/helpers/phone_field.rb +9 -0
  126. data/lib/phlex/rails/helpers/phone_field_tag.rb +9 -0
  127. data/lib/phlex/rails/helpers/phone_to.rb +9 -0
  128. data/lib/phlex/rails/helpers/pluralize.rb +9 -0
  129. data/lib/phlex/rails/helpers/preload_link_tag.rb +9 -0
  130. data/lib/phlex/rails/helpers/provide.rb +8 -0
  131. data/lib/phlex/rails/helpers/public_compute_asset_path.rb +8 -0
  132. data/lib/phlex/rails/helpers/radio_button.rb +9 -0
  133. data/lib/phlex/rails/helpers/radio_button_tag.rb +9 -0
  134. data/lib/phlex/rails/helpers/range_field.rb +9 -0
  135. data/lib/phlex/rails/helpers/range_field_tag.rb +9 -0
  136. data/lib/phlex/rails/helpers/request.rb +8 -0
  137. data/lib/phlex/rails/helpers/reset_cycle.rb +8 -0
  138. data/lib/phlex/rails/helpers/rich_text_area.rb +9 -0
  139. data/lib/phlex/rails/helpers/sanitize.rb +8 -0
  140. data/lib/phlex/rails/helpers/sanitize_css.rb +8 -0
  141. data/lib/phlex/rails/helpers/search_field.rb +9 -0
  142. data/lib/phlex/rails/helpers/search_field_tag.rb +9 -0
  143. data/lib/phlex/rails/helpers/select.rb +9 -0
  144. data/lib/phlex/rails/helpers/select_date.rb +9 -0
  145. data/lib/phlex/rails/helpers/select_datetime.rb +9 -0
  146. data/lib/phlex/rails/helpers/select_day.rb +9 -0
  147. data/lib/phlex/rails/helpers/select_hour.rb +9 -0
  148. data/lib/phlex/rails/helpers/select_minute.rb +9 -0
  149. data/lib/phlex/rails/helpers/select_month.rb +9 -0
  150. data/lib/phlex/rails/helpers/select_second.rb +9 -0
  151. data/lib/phlex/rails/helpers/select_tag.rb +9 -0
  152. data/lib/phlex/rails/helpers/select_time.rb +9 -0
  153. data/lib/phlex/rails/helpers/select_year.rb +9 -0
  154. data/lib/phlex/rails/helpers/simple_format.rb +9 -0
  155. data/lib/phlex/rails/helpers/sms_to.rb +9 -0
  156. data/lib/phlex/rails/helpers/strip_links.rb +8 -0
  157. data/lib/phlex/rails/helpers/strip_tags.rb +8 -0
  158. data/lib/phlex/rails/helpers/stylesheet_link_tag.rb +9 -0
  159. data/lib/phlex/rails/helpers/stylesheet_path.rb +8 -0
  160. data/lib/phlex/rails/helpers/stylesheet_url.rb +8 -0
  161. data/lib/phlex/rails/helpers/submit_tag.rb +9 -0
  162. data/lib/phlex/rails/helpers/t.rb +3 -0
  163. data/lib/phlex/rails/helpers/telephone_field.rb +9 -0
  164. data/lib/phlex/rails/helpers/telephone_field_tag.rb +9 -0
  165. data/lib/phlex/rails/helpers/text_area.rb +9 -0
  166. data/lib/phlex/rails/helpers/text_area_tag.rb +9 -0
  167. data/lib/phlex/rails/helpers/text_field.rb +9 -0
  168. data/lib/phlex/rails/helpers/text_field_tag.rb +9 -0
  169. data/lib/phlex/rails/helpers/time_ago_in_words.rb +8 -0
  170. data/lib/phlex/rails/helpers/time_field.rb +9 -0
  171. data/lib/phlex/rails/helpers/time_field_tag.rb +9 -0
  172. data/lib/phlex/rails/helpers/time_select.rb +9 -0
  173. data/lib/phlex/rails/helpers/time_tag.rb +9 -0
  174. data/lib/phlex/rails/helpers/time_zone_options_for_select.rb +9 -0
  175. data/lib/phlex/rails/helpers/time_zone_select.rb +9 -0
  176. data/lib/phlex/rails/helpers/token_list.rb +8 -0
  177. data/lib/phlex/rails/helpers/translate.rb +25 -0
  178. data/lib/phlex/rails/helpers/truncate.rb +8 -0
  179. data/lib/phlex/rails/helpers/turbo_frame_tag.rb +8 -0
  180. data/lib/phlex/rails/helpers/turbo_include_tags.rb +8 -0
  181. data/lib/phlex/rails/helpers/turbo_refresh_method_tag.rb +8 -0
  182. data/lib/phlex/rails/helpers/turbo_refresh_scroll_tag.rb +8 -0
  183. data/lib/phlex/rails/helpers/turbo_refreshes_with.rb +9 -0
  184. data/lib/phlex/rails/helpers/turbo_stream_from.rb +8 -0
  185. data/lib/phlex/rails/helpers/url_field.rb +9 -0
  186. data/lib/phlex/rails/helpers/url_field_tag.rb +9 -0
  187. data/lib/phlex/rails/helpers/url_for.rb +8 -0
  188. data/lib/phlex/rails/helpers/url_options.rb +8 -0
  189. data/lib/phlex/rails/helpers/url_to_asset.rb +8 -0
  190. data/lib/phlex/rails/helpers/url_to_audio.rb +8 -0
  191. data/lib/phlex/rails/helpers/url_to_font.rb +8 -0
  192. data/lib/phlex/rails/helpers/url_to_image.rb +8 -0
  193. data/lib/phlex/rails/helpers/url_to_javascript.rb +8 -0
  194. data/lib/phlex/rails/helpers/url_to_stylesheet.rb +8 -0
  195. data/lib/phlex/rails/helpers/url_to_video.rb +8 -0
  196. data/lib/phlex/rails/helpers/utf8_enforcer_tag.rb +9 -0
  197. data/lib/phlex/rails/helpers/video_path.rb +8 -0
  198. data/lib/phlex/rails/helpers/video_tag.rb +9 -0
  199. data/lib/phlex/rails/helpers/video_url.rb +8 -0
  200. data/lib/phlex/rails/helpers/week_field.rb +9 -0
  201. data/lib/phlex/rails/helpers/week_field_tag.rb +9 -0
  202. data/lib/phlex/rails/helpers/weekday_options_for_select.rb +9 -0
  203. data/lib/phlex/rails/helpers/weekday_select.rb +9 -0
  204. data/lib/phlex/rails/helpers/with_output_buffer.rb +9 -0
  205. data/lib/phlex/rails/helpers/word_wrap.rb +8 -0
  206. data/lib/phlex/rails/helpers.rb +243 -1458
  207. data/lib/phlex/rails/html/method_missing.rb +13 -0
  208. data/lib/phlex/rails/html.rb +11 -0
  209. data/lib/phlex/rails/layout.rb +33 -22
  210. data/lib/phlex/rails/{sgml/overrides.rb → sgml.rb} +26 -15
  211. data/lib/phlex/rails/streaming.rb +95 -7
  212. data/lib/phlex/rails/version.rb +1 -1
  213. data/lib/phlex/rails.rb +25 -22
  214. metadata +202 -29
  215. data/CONTRIBUTING.md +0 -23
  216. data/lib/generators/phlex/controller/USAGE +0 -10
  217. data/lib/generators/phlex/controller/controller_generator.rb +0 -74
  218. data/lib/generators/phlex/controller/templates/controller.rb.erb +0 -14
  219. data/lib/generators/phlex/controller/templates/view.rb.erb +0 -9
  220. data/lib/generators/rspec/view/templates/view_spec.rb.erb +0 -10
  221. data/lib/generators/rspec/view/view_generator.rb +0 -14
  222. data/lib/generators/test_unit/templates/view_test.rb.erb +0 -15
  223. data/lib/generators/test_unit/view_generator.rb +0 -12
  224. data/lib/phlex/rails/html/format.rb +0 -8
  225. data/lib/phlex/rails/sgml/class_methods.rb +0 -13
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlex::Rails::HTML::MethodMissing
4
+ def method_missing(name, *args, **kwargs, &block)
5
+ return super unless helpers.respond_to?(name)
6
+
7
+ const_name = name.to_s.gsub("?", "")
8
+ module_name = Phlex::Rails::Helpers.constants.find { |mod| mod.to_s.underscore.gsub("domid", "dom_id") == const_name }
9
+ return super unless module_name
10
+
11
+ raise NoMethodError, "Try including `Phlex::Rails::Helpers::#{module_name}` in #{self.class.name}."
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlex::Rails::HTML
4
+ autoload :MethodMissing, "phlex/rails/html/method_missing"
5
+
6
+ module Format
7
+ def format
8
+ :html
9
+ end
10
+ end
11
+ end
@@ -6,33 +6,19 @@ module Phlex::Rails
6
6
  include Helpers::CSRFMetaTags
7
7
  include Helpers::FaviconLinkTag
8
8
  include Helpers::PreloadLinkTag
9
- include Helpers::StyleSheetLinkTag
9
+ include Helpers::StylesheetLinkTag
10
10
  include Helpers::ActionCableMetaTag
11
11
  include Helpers::AutoDiscoveryLinkTag
12
- include Helpers::JavaScriptIncludeTag
13
- include Helpers::JavaScriptImportMapTags
14
- include Helpers::JavaScriptImportModuleTag
12
+ include Helpers::JavascriptIncludeTag
13
+ include Helpers::JavascriptImportmapTags
14
+ include Helpers::JavascriptImportModuleTag
15
+ include Helpers::TurboRefreshMethodTag
16
+ include Helpers::TurboRefreshScrollTag
15
17
 
16
18
  # @api private
17
19
  module Interface
18
- def render(view, _locals, &block)
19
- component = new
20
-
21
- component.call(view_context: view) do |yielded|
22
- case yielded
23
- when Symbol
24
- output = view.view_flow.get(yielded)
25
- else
26
- output = yield
27
- end
28
-
29
- case output
30
- when ActiveSupport::SafeBuffer
31
- component.unsafe_raw output
32
- end
33
-
34
- nil
35
- end
20
+ def render(view_context, _locals, &block)
21
+ new.render(view_context, &block)
36
22
  end
37
23
 
38
24
  def identifier
@@ -58,5 +44,30 @@ module Phlex::Rails
58
44
 
59
45
  klass.extend(Interface)
60
46
  end
47
+
48
+ def render(view_context, *args, **kwargs, &block)
49
+ if @_context
50
+ super
51
+ else
52
+ call(view_context: view_context) do |yielded|
53
+ case yielded
54
+ when Symbol
55
+ output = view_context.view_flow.get(yielded)
56
+ else
57
+ output = view_context.capture(&block)
58
+ end
59
+
60
+ unsafe_raw output
61
+ end
62
+ end
63
+ end
64
+
65
+ def identifier
66
+ self.class.identifier
67
+ end
68
+
69
+ def virtual_path
70
+ self.class.virtual_path
71
+ end
61
72
  end
62
73
  end
@@ -3,6 +3,12 @@
3
3
  module Phlex
4
4
  module Rails
5
5
  module SGML
6
+ module ClassMethods
7
+ def render_in(...)
8
+ new.render_in(...)
9
+ end
10
+ end
11
+
6
12
  module Overrides
7
13
  def helpers
8
14
  if defined?(ViewComponent::Base) && @_view_context.is_a?(ViewComponent::Base)
@@ -16,7 +22,7 @@ module Phlex
16
22
  renderable = args[0]
17
23
 
18
24
  case renderable
19
- when Phlex::SGML, Proc
25
+ when Phlex::SGML, Proc, Method
20
26
  return super
21
27
  when Class
22
28
  return super if renderable < Phlex::SGML
@@ -31,9 +37,13 @@ module Phlex
31
37
  end
32
38
 
33
39
  def render_in(view_context, &block)
40
+ fragments = if view_context.request && (fragment_header = view_context.request.headers["X-Fragment"])
41
+ fragment_header.split
42
+ end
43
+
34
44
  if block_given?
35
- call(view_context: view_context) do |*args|
36
- original_length = @_context.target.length
45
+ call(view_context: view_context, fragments: fragments) do |*args|
46
+ original_length = @_context.target.bytesize
37
47
 
38
48
  if args.length == 1 && Phlex::SGML === args[0] && !block.source_location&.[](0)&.end_with?(".rb")
39
49
  output = view_context.capture(
@@ -43,7 +53,7 @@ module Phlex
43
53
  output = view_context.capture(*args, &block)
44
54
  end
45
55
 
46
- unchanged = (original_length == @_context.target.length)
56
+ unchanged = (original_length == @_context.target.bytesize)
47
57
 
48
58
  if unchanged
49
59
  case output
@@ -53,7 +63,7 @@ module Phlex
53
63
  end
54
64
  end.html_safe
55
65
  else
56
- call(view_context: view_context).html_safe
66
+ call(view_context: view_context, fragments: fragments).html_safe
57
67
  end
58
68
  end
59
69
 
@@ -71,16 +81,17 @@ module Phlex
71
81
  end
72
82
  end
73
83
 
74
- # @api private
75
- def await(task)
76
- if task.is_a?(ActiveRecord::Relation)
77
- flush unless task.loaded?
78
-
79
- task
80
- else
81
- super
82
- end
83
- end
84
+ # TODO: Re-introduce this when we can figure out how to test it
85
+ # def await(task)
86
+ # case task
87
+ # when ActiveRecord::Relation
88
+ # future = task.instance_variable_get(:@future_result)
89
+ # flush if future && future.pending?
90
+ # task
91
+ # else
92
+ # super
93
+ # end
94
+ # end
84
95
 
85
96
  # Trick ViewComponent into thinking we're a ViewComponent to fix rendering output
86
97
  # @api private
@@ -2,25 +2,113 @@
2
2
 
3
3
  # @api private
4
4
  module Phlex::Rails::Streaming
5
+ include ActionController::Live
6
+
5
7
  private
6
8
 
7
- def stream(view)
9
+ def stream(view, last_modified: Time.now.httpdate, filename: nil)
10
+ set_stream_headers(last_modified: last_modified)
11
+
12
+ case view
13
+ when Phlex::HTML
14
+ stream_html(view)
15
+ when Phlex::CSV
16
+ stream_csv(view, filename: filename)
17
+ end
18
+ end
19
+
20
+ def set_stream_headers(last_modified:)
8
21
  headers.delete("Content-Length")
9
22
 
10
23
  headers["X-Accel-Buffering"] = "no"
11
- headers["Cache-Control"] = "no-cache"
24
+ headers["Cache-Control"] = "no-transform"
25
+ headers["Last-Modified"] = last_modified
26
+ end
27
+
28
+ def stream_csv(view, filename:)
29
+ headers["Content-Type"] = "text/csv; charset=utf-8"
30
+ headers["Content-Disposition"] = "attachment; filename=\"#{filename || view.filename}\""
31
+
32
+ self.response_body = Enumerator.new do |buffer|
33
+ view.call(buffer, view_context: view_context)
34
+ end
35
+ end
36
+
37
+ def stream_html(view)
12
38
  headers["Content-Type"] = "text/html; charset=utf-8"
13
- headers["Last-Modified"] = Time.zone.now.ctime.to_s
14
39
 
15
- response.status = 200
40
+ # Ensure we have a session id.
41
+ # See https://github.com/rails/rails/issues/51424
42
+ if session.id.nil?
43
+ session[:phlex_init_session] = 1
44
+ session.delete(:phlex_init_session)
45
+ end
16
46
 
17
47
  self.response_body = Enumerator.new do |buffer|
18
48
  view.call(buffer, view_context: view_context)
19
49
  rescue => e
20
- buffer << %('">)
21
- buffer << view_context.javascript_tag(nonce: true) { %(window.location = "/500.html").html_safe }
50
+ raise(e) if Rails.env.test?
51
+
52
+ debug_middleware = ActionDispatch::DebugExceptions.new(
53
+ proc { |_env| raise(e) },
54
+ response_format: :html
55
+ )
56
+
57
+ _debug_status, _debug_headers, debug_body = debug_middleware.call(request.env)
58
+
59
+ if Rails.env.development?
60
+ js = <<~JAVASCRIPT
61
+ document.documentElement.innerHTML = "#{view_context.j(debug_body.join)}";
62
+
63
+ // Re-evaluate all script tags
64
+ document.querySelectorAll("script").forEach((script) => {
65
+ const newScript = document.createElement("script");
66
+ newScript.text = script.text;
67
+ newScript.nonce = "#{view_context.content_security_policy_nonce}";
68
+ script.replaceWith(newScript);
69
+ });
70
+
71
+ // Re-evaluate all style tags
72
+ document.querySelectorAll("style").forEach((style) => {
73
+ const newStyle = document.createElement("style");
74
+ newStyle.textContent = style.textContent;
75
+ newStyle.nonce = "#{view_context.content_security_policy_nonce}";
76
+ style.replaceWith(newStyle);
77
+ });
78
+
79
+ // Map onclick events to event listeners
80
+ document.querySelectorAll("[onclick]").forEach((element) => {
81
+ const action = element.getAttribute("onclick");
82
+ const newScript = document.createElement("script")
83
+
84
+ element.dataset.onclick = action;
85
+ element.removeAttribute("onclick");
86
+
87
+ newScript.text = `
88
+ (function() {
89
+ const action = () => { ${action} };
90
+ document.addEventListener("click", (event) => {
91
+ const element = event.target;
92
+
93
+ if (element.dataset.onclick === "${action}") {
94
+ action.bind(element)();
95
+ };
96
+ });
97
+ })();
98
+ `;
99
+
100
+ newScript.nonce = "#{view_context.content_security_policy_nonce}";
101
+ document.body.appendChild(newScript);
102
+ });
103
+ JAVASCRIPT
104
+ else
105
+ js = <<~JAVASCRIPT
106
+ window.location = "/500.html";
107
+ JAVASCRIPT
108
+ end
22
109
 
23
- raise e
110
+ buffer << %(-->"'>)
111
+ buffer << view_context.javascript_tag(js, nonce: true)
24
112
  end
25
113
  end
26
114
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Phlex
4
4
  module Rails
5
- VERSION = "1.1.2"
5
+ VERSION = "1.2.0"
6
6
  end
7
7
  end
data/lib/phlex/rails.rb CHANGED
@@ -5,31 +5,34 @@ require "phlex/rails/engine"
5
5
 
6
6
  module Phlex
7
7
  module Rails
8
- Loader = Zeitwerk::Loader.new.tap do |loader|
9
- loader.push_dir("#{__dir__}/rails", namespace: Phlex::Rails)
10
- loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
11
- loader.inflector.inflect(
12
- "html" => "HTML",
13
- "sgml" => "SGML"
14
- )
15
- loader.setup
16
- end
8
+ autoload :Buffered, "phlex/rails/buffered"
9
+ autoload :BufferedCheckboxBuilder, "phlex/rails/buffered_checkbox_builder"
10
+ autoload :BufferedFormBuilder, "phlex/rails/buffered_form_builder"
11
+ autoload :BufferedLabelBuilder, "phlex/rails/buffered_label_builder"
12
+ autoload :BufferedRadioButtonBuilder, "phlex/rails/buffered_radio_button_builder"
13
+ autoload :CSV, "phlex/rails/csv"
14
+ autoload :HTML, "phlex/rails/html"
15
+ autoload :HelperMacros, "phlex/rails/helper_macros"
16
+ autoload :Helpers, "phlex/rails/helpers"
17
+ autoload :Layout, "phlex/rails/layout"
18
+ autoload :SGML, "phlex/rails/sgml"
19
+ autoload :UnbufferedOverrides, "phlex/rails/unbuffered_overrides"
20
+ autoload :Streaming, "phlex/rails/streaming"
21
+ autoload :FragmentFinder, "phlex/rails/fragment_finder"
22
+
23
+ Deprecation = ActiveSupport::Deprecation.new("2.0", "Phlex::Rails")
17
24
  end
18
25
 
19
- class SGML
20
- extend Phlex::Rails::SGML::ClassMethods
26
+ CSV.extend Phlex::Rails::HelperMacros
27
+ CSV.prepend Phlex::Rails::CSV::Overrides
21
28
 
22
- prepend Phlex::Rails::SGML::Overrides
23
- end
29
+ SGML.extend Phlex::Rails::SGML::ClassMethods
30
+ SGML.extend Phlex::Rails::HelperMacros
31
+ SGML.prepend Phlex::Rails::SGML::Overrides
24
32
 
25
- # @api private
26
- class HTML
27
- extend Phlex::Rails::HTML::Format
28
- include Phlex::Rails::HTML::Format
29
- end
33
+ HTML.extend Phlex::Rails::HTML::Format
34
+ HTML.include Phlex::Rails::HTML::Format
35
+ HTML.include Phlex::Rails::HTML::MethodMissing
30
36
 
31
- # @api private
32
- class Unbuffered
33
- prepend ::Phlex::Rails::UnbufferedOverrides
34
- end
37
+ Unbuffered.prepend Phlex::Rails::UnbufferedOverrides
35
38
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlex-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Drapper
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.9.1
19
+ version: 1.10.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.9.1
26
+ version: 1.10.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: railties
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,20 +44,6 @@ dependencies:
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '8'
47
- - !ruby/object:Gem::Dependency
48
- name: zeitwerk
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: '2.6'
54
- type: :runtime
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '2.6'
61
47
  description: A high-performance view framework optimised for developer happiness.
62
48
  email:
63
49
  - joel@drapper.me
@@ -72,7 +58,6 @@ files:
72
58
  - Appraisals
73
59
  - CHANGELOG.md
74
60
  - CODE_OF_CONDUCT.md
75
- - CONTRIBUTING.md
76
61
  - Gemfile
77
62
  - LICENSE.txt
78
63
  - README.md
@@ -81,10 +66,6 @@ files:
81
66
  - lib/generators/phlex/component/USAGE
82
67
  - lib/generators/phlex/component/component_generator.rb
83
68
  - lib/generators/phlex/component/templates/component.rb.erb
84
- - lib/generators/phlex/controller/USAGE
85
- - lib/generators/phlex/controller/controller_generator.rb
86
- - lib/generators/phlex/controller/templates/controller.rb.erb
87
- - lib/generators/phlex/controller/templates/view.rb.erb
88
69
  - lib/generators/phlex/install/USAGE
89
70
  - lib/generators/phlex/install/install_generator.rb
90
71
  - lib/generators/phlex/install/templates/application_component.rb
@@ -93,10 +74,6 @@ files:
93
74
  - lib/generators/phlex/view/USAGE
94
75
  - lib/generators/phlex/view/templates/view.rb.erb
95
76
  - lib/generators/phlex/view/view_generator.rb
96
- - lib/generators/rspec/view/templates/view_spec.rb.erb
97
- - lib/generators/rspec/view/view_generator.rb
98
- - lib/generators/test_unit/templates/view_test.rb.erb
99
- - lib/generators/test_unit/view_generator.rb
100
77
  - lib/phlex-rails.rb
101
78
  - lib/phlex/rails.rb
102
79
  - lib/phlex/rails/buffered.rb
@@ -104,16 +81,212 @@ files:
104
81
  - lib/phlex/rails/buffered_form_builder.rb
105
82
  - lib/phlex/rails/buffered_label_builder.rb
106
83
  - lib/phlex/rails/buffered_radio_button_builder.rb
84
+ - lib/phlex/rails/csv.rb
107
85
  - lib/phlex/rails/engine.rb
86
+ - lib/phlex/rails/fragment_finder.rb
108
87
  - lib/phlex/rails/helper_macros.rb
109
88
  - lib/phlex/rails/helpers.rb
89
+ - lib/phlex/rails/helpers/action_cable_meta_tag.rb
90
+ - lib/phlex/rails/helpers/action_name.rb
91
+ - lib/phlex/rails/helpers/asset_path.rb
92
+ - lib/phlex/rails/helpers/asset_url.rb
93
+ - lib/phlex/rails/helpers/audio_path.rb
94
+ - lib/phlex/rails/helpers/audio_tag.rb
95
+ - lib/phlex/rails/helpers/audio_url.rb
96
+ - lib/phlex/rails/helpers/auto_discovery_link_tag.rb
97
+ - lib/phlex/rails/helpers/build_tag_values.rb
98
+ - lib/phlex/rails/helpers/button_tag.rb
99
+ - lib/phlex/rails/helpers/button_to.rb
100
+ - lib/phlex/rails/helpers/check_box.rb
101
+ - lib/phlex/rails/helpers/check_box_tag.rb
102
+ - lib/phlex/rails/helpers/class_names.rb
103
+ - lib/phlex/rails/helpers/collection_check_boxes.rb
104
+ - lib/phlex/rails/helpers/collection_radio_buttons.rb
105
+ - lib/phlex/rails/helpers/collection_select.rb
106
+ - lib/phlex/rails/helpers/color_field.rb
107
+ - lib/phlex/rails/helpers/color_field_tag.rb
108
+ - lib/phlex/rails/helpers/compute_asset_extname.rb
109
+ - lib/phlex/rails/helpers/compute_asset_host.rb
110
+ - lib/phlex/rails/helpers/compute_asset_path.rb
111
+ - lib/phlex/rails/helpers/content_for.rb
112
+ - lib/phlex/rails/helpers/content_tag.rb
113
+ - lib/phlex/rails/helpers/controller_name.rb
114
+ - lib/phlex/rails/helpers/controller_path.rb
115
+ - lib/phlex/rails/helpers/csp_meta_tag.rb
116
+ - lib/phlex/rails/helpers/csrf_meta_tags.rb
117
+ - lib/phlex/rails/helpers/current_cycle.rb
118
+ - lib/phlex/rails/helpers/current_page.rb
119
+ - lib/phlex/rails/helpers/cycle.rb
120
+ - lib/phlex/rails/helpers/date_field.rb
121
+ - lib/phlex/rails/helpers/date_field_tag.rb
122
+ - lib/phlex/rails/helpers/date_select.rb
123
+ - lib/phlex/rails/helpers/datetime_field.rb
124
+ - lib/phlex/rails/helpers/datetime_field_tag.rb
125
+ - lib/phlex/rails/helpers/datetime_local_field.rb
126
+ - lib/phlex/rails/helpers/datetime_local_field_tag.rb
127
+ - lib/phlex/rails/helpers/datetime_select.rb
128
+ - lib/phlex/rails/helpers/debug.rb
129
+ - lib/phlex/rails/helpers/default_url_options.rb
130
+ - lib/phlex/rails/helpers/distance_of_time_in_words.rb
131
+ - lib/phlex/rails/helpers/distance_of_time_in_words_to_now.rb
132
+ - lib/phlex/rails/helpers/dom_class.rb
133
+ - lib/phlex/rails/helpers/dom_id.rb
134
+ - lib/phlex/rails/helpers/email_field.rb
135
+ - lib/phlex/rails/helpers/email_field_tag.rb
136
+ - lib/phlex/rails/helpers/error_message.rb
137
+ - lib/phlex/rails/helpers/error_wrapping.rb
138
+ - lib/phlex/rails/helpers/escape_once.rb
139
+ - lib/phlex/rails/helpers/excerpt.rb
140
+ - lib/phlex/rails/helpers/favicon_link_tag.rb
141
+ - lib/phlex/rails/helpers/field_id.rb
142
+ - lib/phlex/rails/helpers/field_name.rb
143
+ - lib/phlex/rails/helpers/field_set_tag.rb
144
+ - lib/phlex/rails/helpers/fields.rb
145
+ - lib/phlex/rails/helpers/fields_for.rb
146
+ - lib/phlex/rails/helpers/file_field.rb
147
+ - lib/phlex/rails/helpers/file_field_tag.rb
148
+ - lib/phlex/rails/helpers/flash.rb
149
+ - lib/phlex/rails/helpers/font_path.rb
150
+ - lib/phlex/rails/helpers/font_url.rb
151
+ - lib/phlex/rails/helpers/form_for.rb
152
+ - lib/phlex/rails/helpers/form_tag.rb
153
+ - lib/phlex/rails/helpers/form_with.rb
154
+ - lib/phlex/rails/helpers/grouped_collection_select.rb
155
+ - lib/phlex/rails/helpers/grouped_options_for_select.rb
156
+ - lib/phlex/rails/helpers/hidden_field.rb
157
+ - lib/phlex/rails/helpers/hidden_field_tag.rb
158
+ - lib/phlex/rails/helpers/highlight.rb
159
+ - lib/phlex/rails/helpers/image_path.rb
160
+ - lib/phlex/rails/helpers/image_submit_tag.rb
161
+ - lib/phlex/rails/helpers/image_tag.rb
162
+ - lib/phlex/rails/helpers/image_url.rb
163
+ - lib/phlex/rails/helpers/javascript_import_module_tag.rb
164
+ - lib/phlex/rails/helpers/javascript_importmap_tags.rb
165
+ - lib/phlex/rails/helpers/javascript_include_tag.rb
166
+ - lib/phlex/rails/helpers/javascript_path.rb
167
+ - lib/phlex/rails/helpers/javascript_tag.rb
168
+ - lib/phlex/rails/helpers/javascript_url.rb
169
+ - lib/phlex/rails/helpers/l.rb
170
+ - lib/phlex/rails/helpers/label.rb
171
+ - lib/phlex/rails/helpers/label_tag.rb
172
+ - lib/phlex/rails/helpers/link_to.rb
173
+ - lib/phlex/rails/helpers/link_to_if.rb
174
+ - lib/phlex/rails/helpers/link_to_unless.rb
175
+ - lib/phlex/rails/helpers/link_to_unless_current.rb
176
+ - lib/phlex/rails/helpers/localize.rb
177
+ - lib/phlex/rails/helpers/mail_to.rb
178
+ - lib/phlex/rails/helpers/month_field.rb
179
+ - lib/phlex/rails/helpers/month_field_tag.rb
180
+ - lib/phlex/rails/helpers/number_field.rb
181
+ - lib/phlex/rails/helpers/number_field_tag.rb
182
+ - lib/phlex/rails/helpers/number_to_currency.rb
183
+ - lib/phlex/rails/helpers/number_to_human.rb
184
+ - lib/phlex/rails/helpers/number_to_human_size.rb
185
+ - lib/phlex/rails/helpers/number_to_percentage.rb
186
+ - lib/phlex/rails/helpers/number_to_phone.rb
187
+ - lib/phlex/rails/helpers/number_with_delimiter.rb
188
+ - lib/phlex/rails/helpers/number_with_precision.rb
189
+ - lib/phlex/rails/helpers/object.rb
190
+ - lib/phlex/rails/helpers/option_groups_from_collection_for_select.rb
191
+ - lib/phlex/rails/helpers/options_for_select.rb
192
+ - lib/phlex/rails/helpers/options_from_collection_for_select.rb
193
+ - lib/phlex/rails/helpers/password_field.rb
194
+ - lib/phlex/rails/helpers/password_field_tag.rb
195
+ - lib/phlex/rails/helpers/path_to_asset.rb
196
+ - lib/phlex/rails/helpers/path_to_audio.rb
197
+ - lib/phlex/rails/helpers/path_to_font.rb
198
+ - lib/phlex/rails/helpers/path_to_image.rb
199
+ - lib/phlex/rails/helpers/path_to_javascript.rb
200
+ - lib/phlex/rails/helpers/path_to_stylesheet.rb
201
+ - lib/phlex/rails/helpers/path_to_video.rb
202
+ - lib/phlex/rails/helpers/phone_field.rb
203
+ - lib/phlex/rails/helpers/phone_field_tag.rb
204
+ - lib/phlex/rails/helpers/phone_to.rb
205
+ - lib/phlex/rails/helpers/pluralize.rb
206
+ - lib/phlex/rails/helpers/preload_link_tag.rb
207
+ - lib/phlex/rails/helpers/provide.rb
208
+ - lib/phlex/rails/helpers/public_compute_asset_path.rb
209
+ - lib/phlex/rails/helpers/radio_button.rb
210
+ - lib/phlex/rails/helpers/radio_button_tag.rb
211
+ - lib/phlex/rails/helpers/range_field.rb
212
+ - lib/phlex/rails/helpers/range_field_tag.rb
213
+ - lib/phlex/rails/helpers/request.rb
214
+ - lib/phlex/rails/helpers/reset_cycle.rb
215
+ - lib/phlex/rails/helpers/rich_text_area.rb
110
216
  - lib/phlex/rails/helpers/routes.rb
217
+ - lib/phlex/rails/helpers/sanitize.rb
218
+ - lib/phlex/rails/helpers/sanitize_css.rb
219
+ - lib/phlex/rails/helpers/search_field.rb
220
+ - lib/phlex/rails/helpers/search_field_tag.rb
221
+ - lib/phlex/rails/helpers/select.rb
222
+ - lib/phlex/rails/helpers/select_date.rb
223
+ - lib/phlex/rails/helpers/select_datetime.rb
224
+ - lib/phlex/rails/helpers/select_day.rb
225
+ - lib/phlex/rails/helpers/select_hour.rb
226
+ - lib/phlex/rails/helpers/select_minute.rb
227
+ - lib/phlex/rails/helpers/select_month.rb
228
+ - lib/phlex/rails/helpers/select_second.rb
229
+ - lib/phlex/rails/helpers/select_tag.rb
230
+ - lib/phlex/rails/helpers/select_time.rb
231
+ - lib/phlex/rails/helpers/select_year.rb
232
+ - lib/phlex/rails/helpers/simple_format.rb
233
+ - lib/phlex/rails/helpers/sms_to.rb
234
+ - lib/phlex/rails/helpers/strip_links.rb
235
+ - lib/phlex/rails/helpers/strip_tags.rb
236
+ - lib/phlex/rails/helpers/stylesheet_link_tag.rb
237
+ - lib/phlex/rails/helpers/stylesheet_path.rb
238
+ - lib/phlex/rails/helpers/stylesheet_url.rb
239
+ - lib/phlex/rails/helpers/submit_tag.rb
240
+ - lib/phlex/rails/helpers/t.rb
111
241
  - lib/phlex/rails/helpers/tag.rb
242
+ - lib/phlex/rails/helpers/telephone_field.rb
243
+ - lib/phlex/rails/helpers/telephone_field_tag.rb
244
+ - lib/phlex/rails/helpers/text_area.rb
245
+ - lib/phlex/rails/helpers/text_area_tag.rb
246
+ - lib/phlex/rails/helpers/text_field.rb
247
+ - lib/phlex/rails/helpers/text_field_tag.rb
248
+ - lib/phlex/rails/helpers/time_ago_in_words.rb
249
+ - lib/phlex/rails/helpers/time_field.rb
250
+ - lib/phlex/rails/helpers/time_field_tag.rb
251
+ - lib/phlex/rails/helpers/time_select.rb
252
+ - lib/phlex/rails/helpers/time_tag.rb
253
+ - lib/phlex/rails/helpers/time_zone_options_for_select.rb
254
+ - lib/phlex/rails/helpers/time_zone_select.rb
255
+ - lib/phlex/rails/helpers/token_list.rb
256
+ - lib/phlex/rails/helpers/translate.rb
257
+ - lib/phlex/rails/helpers/truncate.rb
258
+ - lib/phlex/rails/helpers/turbo_frame_tag.rb
259
+ - lib/phlex/rails/helpers/turbo_include_tags.rb
260
+ - lib/phlex/rails/helpers/turbo_refresh_method_tag.rb
261
+ - lib/phlex/rails/helpers/turbo_refresh_scroll_tag.rb
262
+ - lib/phlex/rails/helpers/turbo_refreshes_with.rb
112
263
  - lib/phlex/rails/helpers/turbo_stream.rb
113
- - lib/phlex/rails/html/format.rb
264
+ - lib/phlex/rails/helpers/turbo_stream_from.rb
265
+ - lib/phlex/rails/helpers/url_field.rb
266
+ - lib/phlex/rails/helpers/url_field_tag.rb
267
+ - lib/phlex/rails/helpers/url_for.rb
268
+ - lib/phlex/rails/helpers/url_options.rb
269
+ - lib/phlex/rails/helpers/url_to_asset.rb
270
+ - lib/phlex/rails/helpers/url_to_audio.rb
271
+ - lib/phlex/rails/helpers/url_to_font.rb
272
+ - lib/phlex/rails/helpers/url_to_image.rb
273
+ - lib/phlex/rails/helpers/url_to_javascript.rb
274
+ - lib/phlex/rails/helpers/url_to_stylesheet.rb
275
+ - lib/phlex/rails/helpers/url_to_video.rb
276
+ - lib/phlex/rails/helpers/utf8_enforcer_tag.rb
277
+ - lib/phlex/rails/helpers/video_path.rb
278
+ - lib/phlex/rails/helpers/video_tag.rb
279
+ - lib/phlex/rails/helpers/video_url.rb
280
+ - lib/phlex/rails/helpers/week_field.rb
281
+ - lib/phlex/rails/helpers/week_field_tag.rb
282
+ - lib/phlex/rails/helpers/weekday_options_for_select.rb
283
+ - lib/phlex/rails/helpers/weekday_select.rb
284
+ - lib/phlex/rails/helpers/with_output_buffer.rb
285
+ - lib/phlex/rails/helpers/word_wrap.rb
286
+ - lib/phlex/rails/html.rb
287
+ - lib/phlex/rails/html/method_missing.rb
114
288
  - lib/phlex/rails/layout.rb
115
- - lib/phlex/rails/sgml/class_methods.rb
116
- - lib/phlex/rails/sgml/overrides.rb
289
+ - lib/phlex/rails/sgml.rb
117
290
  - lib/phlex/rails/streaming.rb
118
291
  - lib/phlex/rails/unbuffered_overrides.rb
119
292
  - lib/phlex/rails/version.rb