has_stimulus_attrs 0.3.0 → 0.5.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: 0d92df61326364a67fd89516850b87e5dfe9e85cbbc1982f6f5815978f033c18
4
- data.tar.gz: d7cfcb016ff83d8aa53c43527cb6753b587958e075f071f0261cf16044365ac1
3
+ metadata.gz: 238aa5e7d35e278fce195e7fe5cd224f3577b1f23f42eb1ae73004fb8ea7bcd5
4
+ data.tar.gz: 4cd400602a164201ef84d0e69abf124fcd9afba82e8d3e30871e3bcd6df68fa1
5
5
  SHA512:
6
- metadata.gz: eb72b769b5aa0ed1eadb3bb7dfaac561c987ff2d11acc9273fa80ec71284fcd790ec42bf7a78c82b607561062981b97b1fad3c611e6e57dd3662b439b584cb8d
7
- data.tar.gz: 58afec2f65b664ce1a424931e7b987e0bf210343f6d782407f04514df651995107a22e8f09d9a5e9b21950caf27390f3eb88a23a8702274009a6041567ef960d
6
+ metadata.gz: 3db6f7a6c2b9e665061fa2daa9c21b75afafc3bc125744ee36ab19af78a47a47fad2df37ecf45e61acfd6963bd13933a5f8d1e9302f2db07a9aa6daf01556984
7
+ data.tar.gz: 03135bbc513eb5fd81576ef6aa6a6bd5da878fa06b49aa121ddbc037c6719d9fef015b298791834d4836c7c8d2e4b1ff08a2908f48e7ac2bd23ea4b2088d9cb0
data/.rubocop.yml CHANGED
@@ -1,6 +1,8 @@
1
- inherit_gem:
2
- rubocop-rails_config:
3
- - config/rails.yml
1
+ inherit_gem: { rubocop-rails-omakase: rubocop.yml }
2
+
3
+ Style/HashSyntax:
4
+ EnforcedShorthandSyntax: always
4
5
 
5
6
  AllCops:
6
- TargetRubyVersion: 3.1
7
+ NewCops: enable
8
+ TargetRubyVersion: 4.0.1
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.3.5
1
+ 4.0.1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.0](https://github.com/tomasc/has_stimulus_attrs/compare/v0.4.1...v0.5.0) (2026-04-18)
4
+
5
+ ### Bug Fixes
6
+
7
+ * **Non-mutating prepend pattern**: `prepend___has_stimulus___method` now builds a new Hash via `super().merge(k => v)` instead of mutating the Hash returned by super via `.tap { |d| d[k] = v }`. Required for compatibility with has_dom_attrs ≥ 0.3 (tomasc/has_dom_attrs#2), where `HasDomAttrs#dom_data` returns a shared frozen `EMPTY_HASH` constant to cut allocations. No behavioral change for existing consumers; works against both old-mutable and new-frozen bases.
8
+
9
+ ## [0.4.1](https://github.com/tomasc/has_stimulus_attrs/compare/v0.3.0...v0.4.1) (2025-02-13)
10
+
11
+ ### Bug Fixes
12
+
13
+ * **Defer Proc controller evaluation to runtime**: Fixed `controller:` option with Proc values in `has_stimulus_action`, `has_stimulus_class`, `has_stimulus_outlet`, `has_stimulus_param`, `has_stimulus_target`, and `has_stimulus_value` — Procs were incorrectly evaluated at class definition time via `instance_exec`, causing failures when referencing instance methods. Controller Procs are now resolved inside runtime lambdas, matching the existing behavior of `has_stimulus_controller`.
14
+
3
15
  ## [0.3.0](https://github.com/tomasc/has_stimulus_attrs/compare/v0.2.2...v0.3.0) (2025-01-02)
4
16
 
5
17
  ### Performance
@@ -5,8 +5,8 @@ require_relative "lib/has_stimulus_attrs/version"
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "has_stimulus_attrs"
7
7
  spec.version = HasStimulusAttrs::VERSION
8
- spec.authors = ["Tomas Celizna", "Asger Behncke Jacobsen"]
9
- spec.email = ["tomas.celizna@gmail.com", "a@asgerbehnckejacobsen.dk"]
8
+ spec.authors = [ "Tomas Celizna", "Asger Behncke Jacobsen" ]
9
+ spec.email = [ "tomas.celizna@gmail.com", "a@asgerbehnckejacobsen.dk" ]
10
10
 
11
11
  spec.summary = "Helper methods for dealing with stimulus attributes."
12
12
  spec.description = "Helper methods for dealing with stimulus attributes."
@@ -24,16 +24,17 @@ Gem::Specification.new do |spec|
24
24
  end
25
25
  spec.bindir = "exe"
26
26
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
27
- spec.require_paths = ["lib"]
27
+ spec.require_paths = [ "lib" ]
28
28
 
29
29
  spec.add_dependency "stimulus_helpers", "~> 0.1"
30
- spec.add_dependency "has_dom_attrs", "~> 0.1"
30
+ spec.add_dependency "has_dom_attrs", "~> 0.3"
31
31
  spec.add_dependency "activesupport", ">= 7.0"
32
32
 
33
+ spec.add_development_dependency "benchmark"
33
34
  spec.add_development_dependency "bundler"
34
35
  spec.add_development_dependency "rake"
35
- spec.add_development_dependency "minitest", "~> 5.0"
36
+ spec.add_development_dependency "minitest", "~> 6.0"
36
37
 
37
38
  spec.add_development_dependency "lefthook"
38
- spec.add_development_dependency "rubocop-rails_config"
39
+ spec.add_development_dependency "rubocop-rails-omakase"
39
40
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HasStimulusAttrs
4
- VERSION = "0.3.0"
4
+ VERSION = "0.5.0"
5
5
  end
@@ -33,106 +33,99 @@ module HasStimulusAttrs
33
33
  end
34
34
 
35
35
  def has_stimulus_action(event, action, controller: nil, **options)
36
- controller = case controller
37
- when Proc then instance_exec(&controller)
38
- else controller
39
- end
40
-
41
36
  key = :action
42
37
  val = -> {
38
+ c = controller.is_a?(Proc) ? instance_exec(&controller) : controller
43
39
  a = case action
44
- when Proc then instance_exec(&action)
45
- else action.to_s
40
+ when Proc then instance_exec(&action)
41
+ else action.to_s
46
42
  end
47
- stimulus_action((controller || controller_name), event, a).values.first
43
+ stimulus_action((c || controller_name), event, a).values.first
48
44
  }
49
45
 
50
46
  prepend___has_stimulus___method(key, val, **options)
51
47
  end
52
48
 
53
49
  def has_stimulus_class(name, value, controller: nil, **options)
54
- controller = case controller
55
- when Proc then instance_exec(&controller)
56
- else controller
57
- end
58
-
59
- key = -> { stimulus_class((controller || controller_name), name, "N/A").keys.first }
50
+ key = -> {
51
+ c = controller.is_a?(Proc) ? instance_exec(&controller) : controller
52
+ stimulus_class((c || controller_name), name, "N/A").keys.first
53
+ }
60
54
  val = -> {
55
+ c = controller.is_a?(Proc) ? instance_exec(&controller) : controller
61
56
  v = case value
62
- when Proc then instance_exec(&value)
63
- else value.to_s
57
+ when Proc then instance_exec(&value)
58
+ else value.to_s
64
59
  end
65
- stimulus_class((controller || controller_name), name, v).values.first
60
+ stimulus_class((c || controller_name), name, v).values.first
66
61
  }
67
62
 
68
63
  prepend___has_stimulus___method(key, val, **options)
69
64
  end
70
65
 
71
66
  def has_stimulus_outlet(name, value, controller: nil, **options)
72
- controller = case controller
73
- when Proc then instance_exec(&controller)
74
- else controller
75
- end
76
-
77
- key = -> { stimulus_outlet((controller || controller_name), name, "N/A").keys.first }
67
+ key = -> {
68
+ c = controller.is_a?(Proc) ? instance_exec(&controller) : controller
69
+ stimulus_outlet((c || controller_name), name, "N/A").keys.first
70
+ }
78
71
  val = -> {
72
+ c = controller.is_a?(Proc) ? instance_exec(&controller) : controller
79
73
  v = case value
80
- when Proc then instance_exec(&value)
81
- when Symbol then send(value)
82
- else value
74
+ when Proc then instance_exec(&value)
75
+ when Symbol then send(value)
76
+ else value
83
77
  end
84
- stimulus_outlet((controller || controller_name), name, v).values.first
78
+ stimulus_outlet((c || controller_name), name, v).values.first
85
79
  }
86
80
 
87
81
  prepend___has_stimulus___method(key, val, **options)
88
82
  end
89
83
 
90
84
  def has_stimulus_param(name, value, controller: nil, **options)
91
- controller = case controller
92
- when Proc then instance_exec(&controller)
93
- else controller
94
- end
95
-
96
- key = -> { stimulus_param((controller || controller_name), name, "N/A").keys.first }
85
+ key = -> {
86
+ c = controller.is_a?(Proc) ? instance_exec(&controller) : controller
87
+ stimulus_param((c || controller_name), name, "N/A").keys.first
88
+ }
97
89
  val = -> {
90
+ c = controller.is_a?(Proc) ? instance_exec(&controller) : controller
98
91
  v = case value
99
- when Proc then instance_exec(&value)
100
- when Symbol then send(value)
101
- else value
92
+ when Proc then instance_exec(&value)
93
+ when Symbol then send(value)
94
+ else value
102
95
  end
103
- stimulus_param((controller || controller_name), name, v).values.first
96
+ stimulus_param((c || controller_name), name, v).values.first
104
97
  }
105
98
 
106
99
  prepend___has_stimulus___method(key, val, **options)
107
100
  end
108
101
 
109
102
  def has_stimulus_target(name, controller: nil, **options)
110
- controller = case controller
111
- when Proc then instance_exec(&controller)
112
- else controller
113
- end
114
-
115
- key = -> { stimulus_target((controller || controller_name), name).keys.first }
116
- val = -> { stimulus_target((controller || controller_name), name).values.first }
103
+ key = -> {
104
+ c = controller.is_a?(Proc) ? instance_exec(&controller) : controller
105
+ stimulus_target((c || controller_name), name).keys.first
106
+ }
107
+ val = -> {
108
+ c = controller.is_a?(Proc) ? instance_exec(&controller) : controller
109
+ stimulus_target((c || controller_name), name).values.first
110
+ }
117
111
 
118
112
  prepend___has_stimulus___method(key, val, **options)
119
113
  end
120
114
 
121
115
  def has_stimulus_value(name, value = nil, controller: nil, **options)
122
- controller = case controller
123
- when Proc then instance_exec(&controller)
124
- else controller
125
- end
126
-
127
- key = -> { stimulus_value((controller || controller_name), name, "N/A").keys.first }
116
+ key = -> {
117
+ c = controller.is_a?(Proc) ? instance_exec(&controller) : controller
118
+ stimulus_value((c || controller_name), name, "N/A").keys.first
119
+ }
128
120
  val = -> {
121
+ c = controller.is_a?(Proc) ? instance_exec(&controller) : controller
129
122
  v = case value
130
- when Proc then instance_exec(&value)
131
- when Symbol then send(value)
132
- when NilClass then send(name)
133
- else value
123
+ when Proc then instance_exec(&value)
124
+ when Symbol then send(value)
125
+ when NilClass then send(name)
126
+ else value
134
127
  end
135
- stimulus_value((controller || controller_name), name, v).values.first
128
+ stimulus_value((c || controller_name), name, v).values.first
136
129
  }
137
130
 
138
131
  prepend___has_stimulus___method(key, val, **options)
@@ -148,64 +141,64 @@ module HasStimulusAttrs
148
141
  if options.key?(:if)
149
142
  cond = options[:if]
150
143
  cond_value = case cond
151
- when Proc then instance_exec(&cond)
152
- when Symbol, String then send(cond)
153
- else cond
154
- end
144
+ when Proc then instance_exec(&cond)
145
+ when Symbol, String then send(cond)
146
+ else cond
147
+ end
155
148
  return super() unless cond_value
156
149
  end
157
150
 
158
151
  if options.key?(:unless)
159
152
  cond = options[:unless]
160
153
  cond_value = case cond
161
- when Proc then instance_exec(&cond)
162
- when Symbol, String then send(cond)
163
- else cond
164
- end
154
+ when Proc then instance_exec(&cond)
155
+ when Symbol, String then send(cond)
156
+ else cond
157
+ end
165
158
  return super() if cond_value
166
159
  end
167
160
 
168
161
  # Only evaluate key and value if conditions pass
169
162
  k = case key
170
- when Proc then instance_exec(&key)
171
- else key
163
+ when Proc then instance_exec(&key)
164
+ else key
172
165
  end
173
166
 
174
167
  v = case value
175
- when Proc then instance_exec(&value)
176
- else value
168
+ when Proc then instance_exec(&value)
169
+ else value
177
170
  end
178
171
 
179
- super().tap do |data|
180
- data[k] = [data[k], v].reject(&:blank?).uniq.join(" ")
181
- end
172
+ current = super()
173
+ merged_value = [ current[k], v ].reject(&:blank?).uniq.join(" ")
174
+ current.merge(k => merged_value)
182
175
  end
183
176
  end
184
177
  )
185
-
178
+
186
179
  # Then, ensure memoization is always at the top
187
180
  ensure_memoization_at_top
188
181
  end
189
-
182
+
190
183
  def ensure_memoization_at_top
191
184
  # Remove any existing memoization module
192
185
  if const_defined?(:StimulusMemoization, false)
193
186
  remove_const(:StimulusMemoization)
194
187
  end
195
-
188
+
196
189
  # Create a new memoization module at the top
197
190
  memoization_module = Module.new do
198
191
  def dom_data
199
192
  return @_stimulus_dom_data if defined?(@_stimulus_dom_data)
200
193
  @_stimulus_dom_data = super
201
194
  end
202
-
195
+
203
196
  def reset_dom_data_cache!
204
197
  remove_instance_variable(:@_stimulus_dom_data) if defined?(@_stimulus_dom_data)
205
198
  super if defined?(super)
206
199
  end
207
200
  end
208
-
201
+
209
202
  const_set(:StimulusMemoization, memoization_module)
210
203
  prepend(memoization_module)
211
204
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: has_stimulus_attrs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomas Celizna
8
8
  - Asger Behncke Jacobsen
9
- autorequire:
10
9
  bindir: exe
11
10
  cert_chain: []
12
- date: 2025-06-02 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: stimulus_helpers
@@ -31,14 +30,14 @@ dependencies:
31
30
  requirements:
32
31
  - - "~>"
33
32
  - !ruby/object:Gem::Version
34
- version: '0.1'
33
+ version: '0.3'
35
34
  type: :runtime
36
35
  prerelease: false
37
36
  version_requirements: !ruby/object:Gem::Requirement
38
37
  requirements:
39
38
  - - "~>"
40
39
  - !ruby/object:Gem::Version
41
- version: '0.1'
40
+ version: '0.3'
42
41
  - !ruby/object:Gem::Dependency
43
42
  name: activesupport
44
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,6 +52,20 @@ dependencies:
53
52
  - - ">="
54
53
  - !ruby/object:Gem::Version
55
54
  version: '7.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: benchmark
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
56
69
  - !ruby/object:Gem::Dependency
57
70
  name: bundler
58
71
  requirement: !ruby/object:Gem::Requirement
@@ -87,14 +100,14 @@ dependencies:
87
100
  requirements:
88
101
  - - "~>"
89
102
  - !ruby/object:Gem::Version
90
- version: '5.0'
103
+ version: '6.0'
91
104
  type: :development
92
105
  prerelease: false
93
106
  version_requirements: !ruby/object:Gem::Requirement
94
107
  requirements:
95
108
  - - "~>"
96
109
  - !ruby/object:Gem::Version
97
- version: '5.0'
110
+ version: '6.0'
98
111
  - !ruby/object:Gem::Dependency
99
112
  name: lefthook
100
113
  requirement: !ruby/object:Gem::Requirement
@@ -110,7 +123,7 @@ dependencies:
110
123
  - !ruby/object:Gem::Version
111
124
  version: '0'
112
125
  - !ruby/object:Gem::Dependency
113
- name: rubocop-rails_config
126
+ name: rubocop-rails-omakase
114
127
  requirement: !ruby/object:Gem::Requirement
115
128
  requirements:
116
129
  - - ">="
@@ -150,7 +163,6 @@ metadata:
150
163
  homepage_uri: https://github.com/tomasc/has_stimulus_attrs
151
164
  source_code_uri: https://github.com/tomasc/has_stimulus_attrs
152
165
  changelog_uri: https://github.com/tomasc/has_stimulus_attrs/CHANGELOG.md
153
- post_install_message:
154
166
  rdoc_options: []
155
167
  require_paths:
156
168
  - lib
@@ -165,8 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
177
  - !ruby/object:Gem::Version
166
178
  version: '0'
167
179
  requirements: []
168
- rubygems_version: 3.5.16
169
- signing_key:
180
+ rubygems_version: 4.0.5
170
181
  specification_version: 4
171
182
  summary: Helper methods for dealing with stimulus attributes.
172
183
  test_files: []