phlex-rails 2.3.1 → 2.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9833f000bf407634ea999f7b955fc28d07eac72c08bec5a5b24b3d130c316f7c
4
- data.tar.gz: 63a7fbadbb139a20b88bb29357ce0e7de92b7fdb646e6bb5725297f9d1a4da6c
3
+ metadata.gz: 33adc1537a92b2170cc8040445ee7a8653bb2e47a586f0200d6e36ca20c3f128
4
+ data.tar.gz: 941ba8c6cd5e2282e0b06d561eaaa9821d43f79876d106f09f7f471df1573f5a
5
5
  SHA512:
6
- metadata.gz: fd2f0e2c6617bbc1e8295797e3423cfa9ece08146615285a4a34d8151880eab8486c3fef8e7e95d5e00ff7cf59578a2bf10bed3b2a207a2e934d452c8afbdf82
7
- data.tar.gz: 216394696ba7284cdb784b15396d320a5cbfe87c95de53eadc0d489172fd20f14a89f24c8973f892973d806370cc5510ea7de4cb314ec480d7e696b2d472d42e
6
+ metadata.gz: 2ff027bf6d32ec61019afcc1d6570f31fff6f03095cf03a28e9e75db60068287b8341dcab4bff69f93b085ee6f13378faa554e983b742780cec0a8c3be75386b
7
+ data.tar.gz: adc5f5b72b7119cd996a6d38e8dc3f3de0e08b5926d33aeb57aafa3a5d874294ac468a5f2dfa4071a1cc05236619871aac278a6cafbafcfc56689f9f87bf9d45
@@ -6,4 +6,7 @@ class Views::Base < Components::Base
6
6
  # By default, it inherits from `Components::Base`, but you
7
7
  # can change that to `Phlex::HTML` if you want to keep views and
8
8
  # components independent.
9
+
10
+ # More caching options at https://www.phlex.fun/components/caching
11
+ def cache_store = Rails.cache
9
12
  end
@@ -1,10 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Phlex::Rails
4
- def Buffered(type)
5
- -> (value) { Phlex::Rails::Buffered === value && type === value.unwrap }
6
- end
7
-
8
4
  class Buffered < BasicObject
9
5
  def initialize(object, component:)
10
6
  @object = object
@@ -7,6 +7,16 @@ class Phlex::Rails::Builder < BasicObject
7
7
  end
8
8
 
9
9
  define_method :send, ::Kernel.instance_method(:send)
10
+ define_method :class, ::Kernel.instance_method(:class)
11
+ define_method :is_a?, ::Kernel.instance_method(:is_a?)
12
+
13
+ def inspect
14
+ "Phlex::Rails::Builder(#{@object.inspect})"
15
+ end
16
+
17
+ def unwrap
18
+ @object
19
+ end
10
20
 
11
21
  def respond_to_missing?(method_name, include_private = false)
12
22
  @object.respond_to?(method_name, include_private)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Phlex::Rails::HelperMacros
4
4
  # Register a Rails helper that returns safe HTML to be pushed to the output buffer.
5
- def register_output_helper(method_name)
5
+ def register_output_helper(method_name, mark_safe: false)
6
6
  class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
7
7
  # frozen_string_literal: true
8
8
 
@@ -13,7 +13,7 @@ module Phlex::Rails::HelperMacros
13
13
  view_context.#{method_name}(*args, **kwargs)
14
14
  end
15
15
 
16
- raw(output)
16
+ raw(#{mark_safe ? 'safe(output)' : 'output'})
17
17
  end
18
18
  RUBY
19
19
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlex::Rails::Helpers::JavaScriptImportmapModulePreloadTags
4
+ extend Phlex::Rails::HelperMacros
5
+
6
+ # [Docs](https://www.rubydoc.info/gems/importmap-rails/Importmap%2FImportmapTagsHelper:javascript_importmap_module_preload_tags)
7
+ register_output_helper def javascript_importmap_module_preload_tags(...) = nil
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlex::Rails::Helpers::JavaScriptInlineImportmapTag
4
+ extend Phlex::Rails::HelperMacros
5
+
6
+ # [Docs](https://www.rubydoc.info/gems/importmap-rails/Importmap%2FImportmapTagsHelper:javascript_inline_importmap_tag)
7
+ register_output_helper def javascript_inline_importmap_tag(...) = nil
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlex::Rails::Helpers::PictureTag
4
+ extend Phlex::Rails::HelperMacros
5
+
6
+ # [Rails Docs](https://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#method-i-picture_tag)
7
+ register_output_helper def picture_tag(...) = nil
8
+ end
@@ -10,8 +10,10 @@ module Phlex::Rails
10
10
  include Helpers::ActionCableMetaTag
11
11
  include Helpers::AutoDiscoveryLinkTag
12
12
  include Helpers::JavaScriptIncludeTag
13
+ include Helpers::JavaScriptImportmapModulePreloadTags
13
14
  include Helpers::JavaScriptImportmapTags
14
15
  include Helpers::JavaScriptImportModuleTag
16
+ include Helpers::JavaScriptInlineImportmapTag
15
17
  include Helpers::TurboRefreshMethodTag
16
18
  include Helpers::TurboRefreshScrollTag
17
19
  include Helpers::TurboRefreshesWith
@@ -21,7 +21,10 @@ module Phlex::Rails::SGML
21
21
  # otherwise re-raise the original error.
22
22
  if module_name
23
23
  raise NoMethodError.new(<<~MESSAGE)
24
- Try including `Phlex::Rails::Helpers::#{module_name}` in #{self.class.name}.
24
+ Try including `Phlex::Rails::Helpers::#{module_name}` in #{self.class.name}, like so:
25
+ ```ruby
26
+ include Phlex::Rails::Helpers::#{module_name}
27
+ ```
25
28
  MESSAGE
26
29
  else
27
30
  raise e
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlex
4
+ module Rails
5
+ module Types
6
+ def Buffered(type)
7
+ -> (value) { Phlex::Rails::Buffered === value && type === value.unwrap }
8
+ end
9
+
10
+ def Builder(type)
11
+ -> (value) { Phlex::Rails::Builder === value && type === value.unwrap }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Phlex
4
4
  module Rails
5
- VERSION = "2.3.1"
5
+ VERSION = "2.4.0"
6
6
  end
7
7
  end
data/lib/phlex/rails.rb CHANGED
@@ -22,8 +22,10 @@ module Phlex
22
22
  "font_url" => "FontURL",
23
23
  "image_url" => "ImageURL",
24
24
  "javascript_import_module_tag" => "JavaScriptImportModuleTag",
25
+ "javascript_importmap_module_preload_tags" => "JavaScriptImportmapModulePreloadTags",
25
26
  "javascript_importmap_tags" => "JavaScriptImportmapTags",
26
27
  "javascript_include_tag" => "JavaScriptIncludeTag",
28
+ "javascript_inline_importmap_tag" => "JavaScriptInlineImportmapTag",
27
29
  "javascript_path" => "JavaScriptPath",
28
30
  "javascript_tag" => "JavaScriptTag",
29
31
  "javascript_url" => "JavaScriptURL",
@@ -56,6 +58,8 @@ module Phlex
56
58
  loader.collapse("#{__dir__}/phlex/errors")
57
59
  loader.setup
58
60
  end
61
+
62
+ extend Phlex::Rails::Types
59
63
  end
60
64
 
61
65
  CSV.prepend(Phlex::Rails::CSV)
@@ -37,6 +37,8 @@ module RubyLsp
37
37
  RubyIndexer::Entry::ForwardingParameter.new,
38
38
  ]),
39
39
  ], visibility: :public)
40
+ else
41
+ # no-op
40
42
  end
41
43
  end
42
44
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlex-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Drapper
8
8
  - Will Cosgrove
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-06 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.3.0
19
+ version: 2.4.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: 2.3.0
26
+ version: 2.4.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: railties
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -163,8 +163,10 @@ files:
163
163
  - lib/phlex/rails/helpers/image_tag.rb
164
164
  - lib/phlex/rails/helpers/image_url.rb
165
165
  - lib/phlex/rails/helpers/javascript_import_module_tag.rb
166
+ - lib/phlex/rails/helpers/javascript_importmap_module_preload_tags.rb
166
167
  - lib/phlex/rails/helpers/javascript_importmap_tags.rb
167
168
  - lib/phlex/rails/helpers/javascript_include_tag.rb
169
+ - lib/phlex/rails/helpers/javascript_inline_importmap_tag.rb
168
170
  - lib/phlex/rails/helpers/javascript_path.rb
169
171
  - lib/phlex/rails/helpers/javascript_tag.rb
170
172
  - lib/phlex/rails/helpers/javascript_url.rb
@@ -205,6 +207,7 @@ files:
205
207
  - lib/phlex/rails/helpers/phone_field.rb
206
208
  - lib/phlex/rails/helpers/phone_field_tag.rb
207
209
  - lib/phlex/rails/helpers/phone_to.rb
210
+ - lib/phlex/rails/helpers/picture_tag.rb
208
211
  - lib/phlex/rails/helpers/pluralize.rb
209
212
  - lib/phlex/rails/helpers/preload_link_tag.rb
210
213
  - lib/phlex/rails/helpers/provide.rb
@@ -291,7 +294,7 @@ files:
291
294
  - lib/phlex/rails/partial.rb
292
295
  - lib/phlex/rails/sgml.rb
293
296
  - lib/phlex/rails/sgml/state.rb
294
- - lib/phlex/rails/streaming.rb
297
+ - lib/phlex/rails/types.rb
295
298
  - lib/phlex/rails/version.rb
296
299
  - lib/ruby_lsp/phlex_rails/addon.rb
297
300
  homepage: https://www.phlex.fun
@@ -317,7 +320,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
317
320
  - !ruby/object:Gem::Version
318
321
  version: '0'
319
322
  requirements: []
320
- rubygems_version: 3.6.6
323
+ rubygems_version: 4.0.3
321
324
  specification_version: 4
322
325
  summary: A Phlex adapter for Rails
323
326
  test_files: []
@@ -1,113 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlex::Rails::Streaming
4
- include ActionController::Live
5
-
6
- private def stream(view, last_modified: Time.now.httpdate, filename: nil)
7
- __phlex_set_stream_headers__(last_modified:)
8
-
9
- case view
10
- when Phlex::HTML
11
- __phlex_stream_html__(view)
12
- when Phlex::CSV
13
- __phlex_stream_csv__(view, filename:)
14
- else
15
- raise Phlex::ArgumentError
16
- end
17
- end
18
-
19
- private def __phlex_set_stream_headers__(last_modified:)
20
- headers.delete("Content-Length")
21
-
22
- headers["X-Accel-Buffering"] = "no"
23
- headers["Cache-Control"] = "no-transform"
24
- headers["Last-Modified"] = last_modified
25
- end
26
-
27
- private def __phlex_stream_csv__(view, filename:)
28
- headers["Content-Type"] = "text/csv; charset=utf-8"
29
- headers["Content-Disposition"] = "attachment; filename=\"#{filename || view.filename}\""
30
-
31
- self.response_body = Enumerator.new do |buffer|
32
- view.call(buffer, context: { rails_view_context: view_context })
33
- end
34
- end
35
-
36
- private def __phlex_stream_html__(view)
37
- headers["Content-Type"] = "text/html; charset=utf-8"
38
-
39
- # Ensure we have a session id.
40
- # See https://github.com/rails/rails/issues/51424
41
- if session.id.nil?
42
- session[:phlex_init_session] = 1
43
- session.delete(:phlex_init_session)
44
- end
45
-
46
- self.response_body = Enumerator.new do |buffer|
47
- view.call(buffer, context: { rails_view_context: view_context })
48
- rescue => e
49
- raise(e) if Rails.env.test?
50
-
51
- debug_middleware = ActionDispatch::DebugExceptions.new(
52
- proc { |_env| raise(e) },
53
- response_format: :html,
54
- )
55
-
56
- _debug_status, _debug_headers, debug_body = debug_middleware.call(request.env)
57
-
58
- if Rails.env.development?
59
- js = <<~JAVASCRIPT
60
- document.documentElement.innerHTML = "#{view_context.j(debug_body.join)}";
61
-
62
- // Re-evaluate all script tags
63
- document.querySelectorAll("script").forEach((script) => {
64
- const newScript = document.createElement("script");
65
- newScript.text = script.text;
66
- newScript.nonce = "#{view_context.content_security_policy_nonce}";
67
- script.replaceWith(newScript);
68
- });
69
-
70
- // Re-evaluate all style tags
71
- document.querySelectorAll("style").forEach((style) => {
72
- const newStyle = document.createElement("style");
73
- newStyle.textContent = style.textContent;
74
- newStyle.nonce = "#{view_context.content_security_policy_nonce}";
75
- style.replaceWith(newStyle);
76
- });
77
-
78
- // Map onclick events to event listeners
79
- document.querySelectorAll("[onclick]").forEach((element) => {
80
- const action = element.getAttribute("onclick");
81
- const newScript = document.createElement("script")
82
-
83
- element.dataset.onclick = action;
84
- element.removeAttribute("onclick");
85
-
86
- newScript.text = `
87
- (function() {
88
- const action = () => { ${action} };
89
- document.addEventListener("click", (event) => {
90
- const element = event.target;
91
-
92
- if (element.dataset.onclick === "${action}") {
93
- action.bind(element)();
94
- };
95
- });
96
- })();
97
- `;
98
-
99
- newScript.nonce = "#{view_context.content_security_policy_nonce}";
100
- document.body.appendChild(newScript);
101
- });
102
- JAVASCRIPT
103
- else
104
- js = <<~JAVASCRIPT
105
- window.location = "/500.html";
106
- JAVASCRIPT
107
- end
108
-
109
- buffer << %(-->"'>)
110
- buffer << view_context.javascript_tag(js, nonce: true)
111
- end
112
- end
113
- end