Module: Roda::RodaPlugins::Component::InstanceMethods

Defined in:
lib/roda/plugins/component.rb

Instance Method Summary collapse

Instance Method Details

#component(name, options = {}, &block) ⇒ Object Also known as: comp, roda_component



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/roda/plugins/component.rb', line 145

def component name, options = {}, &block
  action        = options.delete(:call)
  trigger       = options.delete(:trigger)
  js            = options.delete(:js)
  args          = options.delete(:args)

  action = :display if js && !action

  comp = load_component name, options

  # call action
  # TODO: make sure the single method parameter isn't a block
  if trigger
    if args
      comp_response = comp.trigger trigger, *args
    else
      comp_response = comp.trigger trigger, options
    end
  elsif action
    # We want to make sure it's not a method that already exists in ruba
    # otherwise that would give us a false positive.
    if comp.respond_to?(action) && !"#{comp.method(action)}"[/\(Kernel\)/]
      if comp.method(action).parameters.length > 0
        if args
          comp_response = comp.send(action, *args, &block)
        else
          comp_response = comp.send(action, options, &block)
        end
      else
        comp_response = comp.send(action, &block)
      end
    else
      fail "##{action} doesn't exist for #{comp.class}"
    end
  end

  if trigger || action
    load_component_js comp, action, options

    if js && comp_response.is_a?(Roda::Component::DOM)
      comp_response = comp_response.to_html
    end

    comp_response = '' if js && !comp_response.is_a?(String)

    if comp_response.is_a?(String) && js
      comp_response << component_js
    end

    comp_response
  else
    comp
  end
end

#component_jsObject



202
203
204
# File 'lib/roda/plugins/component.rb', line 202

def component_js
  loaded_component_js.join(' ').to_s
end

#component_optsObject



62
63
64
# File 'lib/roda/plugins/component.rb', line 62

def component_opts
  @_component_opts || self.class.component_opts.dup
end

#load_component(name, options = {}) ⇒ Object



70
71
72
73
74
75
76
# File 'lib/roda/plugins/component.rb', line 70

def load_component name, options = {}
  c = Object.const_get(
    component_opts[:class_name][name.to_s]
  )

  c.new self, options
end

#load_component_js(comp, action = false, options = {}) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/roda/plugins/component.rb', line 78

def load_component_js comp, action = false, options = {}
  if comp.is_a? Roda::Component
    comp.class.comp_requires.each do |c|
      load_component_js(load_component(c), false, js: true)
    end
  end

  # grab a copy of the cache
  cache = comp.cache.dup
  # remove html and dom cache as we don't need that for the client
  cache.delete :html
  cache.delete :dom
  cache.delete :cache

  cache      = Base64.encode64 cache.to_json
  options    = Base64.encode64 options.to_json
  comp_name  = comp.class._name
  class_name = Base64.encode64 component_opts[:class_name].to_json

  file_path = comp.class.file_location.gsub("#{Dir.pwd}/#{component_opts[:path]}", '').gsub(/\.rb\Z/, '.js')

  js = <<-EOF
    action = '#{action || 'false'}'

    unless $faye
      $faye = Roda::Component::Faye.new('/faye')
    end

    unless $component_opts[:class_name]
      $component_opts[:class_name] = JSON.parse(Base64.decode64('#{class_name}'))
    end

    if !$component_opts[:comp][:"#{comp_name}"]
      $component_opts[:faye] ||= {}
      $component_opts[:comp][:"#{comp_name}"] = {cache: {}}
      `jQuery.ajaxSetup({ cache: true })`
      `$.getScript("/#{component_opts[:assets_route]}#{file_path}").done(function(){`
        if action != 'false'
          c = $component_opts[:comp][:"#{comp_name}"][:class] = #{comp.class}.new
        else
          c = $component_opts[:comp][:"#{comp_name}"][:class] = #{comp.class}.new(JSON.parse(Base64.decode64('#{options}')))
        end
        c.instance_variable_set(:@_cache, ($component_opts[:comp][:"#{comp_name}"][:cache] = JSON.parse(Base64.decode64('#{cache}'))))

        Document.ready? do
          c.events.trigger_jquery_events
          c.#{action}(JSON.parse(Base64.decode64('#{options}'))) if !(c.class._on_server_methods || []).include?('#{action}') && action != 'false'
        end

        Document.on 'page:load' do
          c.#{action}(JSON.parse(Base64.decode64('#{options}'))) if !(c.class._on_server_methods || []).include?('#{action}') && action != 'false'
        end
      `}).fail(function(jqxhr, settings, exception){ window.console.log(exception); });`
    elsif $component_opts[:comp][:"#{comp_name}"] && $component_opts[:comp][:"#{comp_name}"][:class]
      if action != 'false'
        c = $component_opts[:comp][:"#{comp_name}"][:class] = #{comp.class}.new
      else
        c = $component_opts[:comp][:"#{comp_name}"][:class] = #{comp.class}.new(JSON.parse(Base64.decode64('#{options}')))
      end
      c.instance_variable_set(:@_cache, $component_opts[:comp][:"#{comp_name}"][:cache])
      c.#{action}(JSON.parse(Base64.decode64('#{options}'))) if !(c.class._on_server_methods || []).include?('#{action}') && action != 'false'
    end
  EOF

  loaded_component_js << ("<script>#{Opal.compile(js)}</script>")
end

#loaded_component_jsObject



66
67
68
# File 'lib/roda/plugins/component.rb', line 66

def loaded_component_js
  request ? (request.env['loaded_component_js'] ||= []) : (@_loaded_component_js ||= [])
end