Module: Glimmer::Web::Component
Defined Under Namespace
Modules: ClassMethods, GlimmerSupersedable
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
-
#add_observer(observer, attribute_name) ⇒ Object
-
#attribute_setter(attribute_name) ⇒ Object
-
#can_add_observer?(attribute_name) ⇒ Boolean
-
#can_handle_observation_request?(observation_request) ⇒ Boolean
-
#content(&block) ⇒ Object
Returns content block if used as an attribute reader (no args) Otherwise, if a block is passed, it adds it as content to this Glimmer web component.
-
#get_attribute(attribute_name) ⇒ Object
-
#handle_observation_request(observation_request, block) ⇒ Object
-
#has_attribute?(attribute_name, *args) ⇒ Boolean
-
#has_instance_method?(method_name) ⇒ Boolean
This method ensures it has an instance method not coming from Glimmer DSL.
-
#initialize(parent, args, options, &content) ⇒ Object
-
#local_respond_to? ⇒ Object
-
#method_missing(method_name, *args, &block) ⇒ Object
-
#observer_registrations ⇒ Object
This stores observe keyword registrations of model/attribute observers.
-
#post_add_content ⇒ Object
-
#post_initialize_child(child) ⇒ Object
Subclasses may override to perform post initialization work on an added child.
-
#render(parent: nil, custom_parent_dom_element: nil, brand_new: false) ⇒ Object
-
#respond_to_missing?(method_name, include_private = false) ⇒ Boolean
-
#set_attribute(attribute_name, *args) ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &block) ⇒ Object
327
328
329
330
331
332
333
334
335
|
# File 'lib/glimmer/web/component.rb', line 327
def method_missing(method_name, *args, &block)
if can_handle_observation_request?(method_name)
handle_observation_request(method_name, block)
elsif markup_root.respond_to?(method_name, true)
markup_root.send(method_name, *args, &block)
else
super(method_name, *args, &block)
end
end
|
Instance Attribute Details
#args ⇒ Object
Returns the value of attribute args.
194
195
196
|
# File 'lib/glimmer/web/component.rb', line 194
def args
@args
end
|
#markup_root ⇒ Object
Returns the value of attribute markup_root.
194
195
196
|
# File 'lib/glimmer/web/component.rb', line 194
def markup_root
@markup_root
end
|
#options ⇒ Object
Returns the value of attribute options.
194
195
196
|
# File 'lib/glimmer/web/component.rb', line 194
def options
@options
end
|
#parent ⇒ Object
Also known as:
parent_proxy
Returns the value of attribute parent.
194
195
196
|
# File 'lib/glimmer/web/component.rb', line 194
def parent
@parent
end
|
Class Method Details
.add_component_namespaces_for(klass) ⇒ Object
.component_namespaces ⇒ Object
179
180
181
|
# File 'lib/glimmer/web/component.rb', line 179
def component_namespaces
@component_namespaces ||= reset_component_namespaces
end
|
.for(underscored_component_name) ⇒ Object
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
# File 'lib/glimmer/web/component.rb', line 130
def for(underscored_component_name)
= underscored_component_name.
to_s.
split(/__/).map do |namespace|
namespace.camelcase(:upper)
end
Glimmer::Web::Component.component_namespaces.each do |base|
.reduce(base) do |result, namespace|
if !result.constants.include?(namespace)
namespace = result.constants.detect {|c| c.to_s.upcase == namespace.to_s.upcase } || namespace
end
begin
constant = result.const_get(namespace)
return constant if constant&.respond_to?(:ancestors) &&
(
constant&.ancestors&.to_a.include?(Glimmer::Web::Component) ||
constant&.ancestors&.to_a.include?(GlimmerSupersedable)
)
constant
rescue => e
result
end
end
end
raise "#{underscored_component_name} has no Glimmer web component class!"
rescue => e
Glimmer::Config.logger.debug {e.message}
Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
nil
end
|
.included(klass) ⇒ Object
.interpretation_stack ⇒ Object
187
188
189
|
# File 'lib/glimmer/web/component.rb', line 187
def interpretation_stack
@interpretation_stack ||= []
end
|
.namespaces_for_class(m) ⇒ Object
171
172
173
174
175
176
177
|
# File 'lib/glimmer/web/component.rb', line 171
def namespaces_for_class(m)
return [m] if m.name.nil?
namespace_constants = m.name.split(/::/).map(&:to_sym)
namespace_constants.reduce([Object]) do |output, namespace_constant|
output += [output.last.const_get(namespace_constant)]
end[1..-1].uniq.reverse
end
|
.reset_component_namespaces ⇒ Object
183
184
185
|
# File 'lib/glimmer/web/component.rb', line 183
def reset_component_namespaces
@component_namespaces = Set[Object, Glimmer::Web]
end
|
Instance Method Details
#add_observer(observer, attribute_name) ⇒ Object
271
272
273
274
275
276
277
|
# File 'lib/glimmer/web/component.rb', line 271
def add_observer(observer, attribute_name)
if has_instance_method?(attribute_name)
super(observer, attribute_name)
else
@markup_root.add_observer(observer, attribute_name)
end
end
|
#attribute_setter(attribute_name) ⇒ Object
308
309
310
|
# File 'lib/glimmer/web/component.rb', line 308
def attribute_setter(attribute_name)
"#{attribute_name}="
end
|
#can_add_observer?(attribute_name) ⇒ Boolean
267
268
269
|
# File 'lib/glimmer/web/component.rb', line 267
def can_add_observer?(attribute_name)
has_instance_method?(attribute_name) || has_instance_method?("#{attribute_name}?") || @markup_root.can_add_observer?(attribute_name)
end
|
#can_handle_observation_request?(observation_request) ⇒ Boolean
247
248
249
250
251
252
253
254
255
|
# File 'lib/glimmer/web/component.rb', line 247
def can_handle_observation_request?(observation_request)
observation_request = observation_request.to_s
result = false
if observation_request.start_with?('on_updated_')
property = observation_request.sub(/^on_updated_/, '')
result = can_add_observer?(property)
end
result || markup_root&.can_handle_observation_request?(observation_request)
end
|
#content(&block) ⇒ Object
Returns content block if used as an attribute reader (no args) Otherwise, if a block is passed, it adds it as content to this Glimmer web component
319
320
321
322
323
324
325
|
# File 'lib/glimmer/web/component.rb', line 319
def content(&block)
if block_given?
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Web::ComponentExpression.new, self.class.keyword, &block)
else
@content
end
end
|
#get_attribute(attribute_name) ⇒ Object
300
301
302
303
304
305
306
|
# File 'lib/glimmer/web/component.rb', line 300
def get_attribute(attribute_name)
if has_instance_method?(attribute_name)
send(attribute_name)
else
@markup_root.get_attribute(attribute_name)
end
end
|
#handle_observation_request(observation_request, block) ⇒ Object
257
258
259
260
261
262
263
264
265
|
# File 'lib/glimmer/web/component.rb', line 257
def handle_observation_request(observation_request, block)
observation_request = observation_request.to_s
if observation_request.start_with?('on_updated_')
property = observation_request.sub(/^on_updated_/, '') add_observer(DataBinding::Observer.proc(&block), property) if can_add_observer?(property)
else
markup_root.handle_observation_request(observation_request, block)
end
end
|
#has_attribute?(attribute_name, *args) ⇒ Boolean
279
280
281
282
|
# File 'lib/glimmer/web/component.rb', line 279
def has_attribute?(attribute_name, *args)
has_instance_method?(attribute_setter(attribute_name)) ||
@markup_root.has_attribute?(attribute_name, *args)
end
|
#has_instance_method?(method_name) ⇒ Boolean
This method ensures it has an instance method not coming from Glimmer DSL
293
294
295
296
297
298
|
# File 'lib/glimmer/web/component.rb', line 293
def has_instance_method?(method_name)
respond_to?(method_name) and
!markup_root&.respond_to?(method_name) and
!method(method_name)&.source_location&.first&.include?('glimmer/dsl/engine.rb') and
!method(method_name)&.source_location&.first&.include?('glimmer/web/element_proxy.rb')
end
|
#initialize(parent, args, options, &content) ⇒ Object
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
# File 'lib/glimmer/web/component.rb', line 197
def initialize(parent, args, options, &content)
Component.interpretation_stack.push(self)
@parent = parent
options = args.delete_at(-1) if args.is_a?(Array) && args.last.is_a?(Hash)
if args.is_a?(Hash)
options = args
args = []
end
options ||= {}
@args = args
options ||= {}
@options = self.class.options.merge(options)
@content = Util::ProcTracker.new(content) if content
execute_hooks('before_render')
markup_block = self.class.instance_variable_get("@markup_block")
raise Glimmer::Error, 'Invalid Glimmer web component for having no markup! Please define markup block!' if markup_block.nil?
@markup_root = instance_exec(&markup_block)
@markup_root.options[:parent] = options[:parent] if !options[:parent].nil?
@parent ||= @markup_root.parent
raise Glimmer::Error, 'Invalid Glimmer web component for having an empty markup! Please fill markup block!' if @markup_root.nil?
if options[:render] != false
execute_hooks('after_render')
else
on_render_listener = proc { execute_hooks('after_render') }
@markup_root.handle_observation_request('on_render', on_render_listener)
end
observer_registration_cleanup_listener = proc do
observer_registrations.compact.each(&:deregister)
observer_registrations.clear
end
@markup_root.handle_observation_request('on_remove', observer_registration_cleanup_listener)
post_add_content if content.nil?
end
|
#local_respond_to? ⇒ Object
337
|
# File 'lib/glimmer/web/component.rb', line 337
alias local_respond_to? respond_to_missing?
|
#observer_registrations ⇒ Object
This stores observe keyword registrations of model/attribute observers
243
244
245
|
# File 'lib/glimmer/web/component.rb', line 243
def observer_registrations
@observer_registrations ||= []
end
|
#post_add_content ⇒ Object
#post_initialize_child(child) ⇒ Object
Subclasses may override to perform post initialization work on an added child
234
235
236
|
# File 'lib/glimmer/web/component.rb', line 234
def post_initialize_child(child)
end
|
#render(parent: nil, custom_parent_dom_element: nil, brand_new: false) ⇒ Object
312
313
314
315
|
# File 'lib/glimmer/web/component.rb', line 312
def render(parent: nil, custom_parent_dom_element: nil, brand_new: false)
@markup_root&.render(parent: parent, custom_parent_dom_element: custom_parent_dom_element, brand_new: brand_new)
end
|
#respond_to_missing?(method_name, include_private = false) ⇒ Boolean
338
339
340
341
342
|
# File 'lib/glimmer/web/component.rb', line 338
def respond_to_missing?(method_name, include_private = false)
super(method_name, include_private) or
can_handle_observation_request?(method_name) or
markup_root.respond_to?(method_name, include_private)
end
|
#set_attribute(attribute_name, *args) ⇒ Object
284
285
286
287
288
289
290
|
# File 'lib/glimmer/web/component.rb', line 284
def set_attribute(attribute_name, *args)
if has_instance_method?(attribute_setter(attribute_name))
send(attribute_setter(attribute_name), *args)
else
@markup_root.set_attribute(attribute_name, *args)
end
end
|