roda-component 0.0.4 → 0.0.5

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
  SHA1:
3
- metadata.gz: 3ef94d1cd1987c2500f1d353dbe75d281ff7a943
4
- data.tar.gz: 48dfe7a0593ca87b23a261c53e252f4befd276b5
3
+ metadata.gz: e07b2592555f0305b5ff63e7b1a5d0cdc595f337
4
+ data.tar.gz: a9292504e6a90f5aec922f3908a8abed452cbb23
5
5
  SHA512:
6
- metadata.gz: 85398abbd01f176710359312b133fb1da20161bb3193200aa60cacc00611353da2b9bc1086ae4a6c571001d488b0060e7cc65f9c21d41f60ea28b675b2043a83
7
- data.tar.gz: f6c9792ce59edc426c9ab32a33d877c509522554ee11ff807d616ea305398902b8ca61800c21cbce87faae42d48893104c6342e58ac99539b23b6d8f0f9428b5
6
+ metadata.gz: 7e3c511932310c7c1958b248944bd61b3507ce506191d4ced846618cc54a25b64ba955b1bd1c1cf83fbd140f3ac6d2f576f04b1e76f1a22b970532936e43cd70
7
+ data.tar.gz: 06c976af76747799ba76fe4661a21a00fa927a7614a8c4d7811f4261037ed53d31c05bab95a131a8da24f90861a2888557285c203e8675d86ff9dd096d06174c
@@ -2,24 +2,32 @@ class Roda
2
2
  class Component
3
3
  class Events < Struct.new(:klass, :component_opts, :scope)
4
4
  def on name, options = {}, &block
5
+ limit_if = options.delete(:if) || []
6
+ limit_if = [limit_if] unless limit_if.is_a? Array
7
+
5
8
  class_name = options.delete(:for) || klass._name
6
9
  class_events = (events[class_name] ||= {})
7
- event = (class_events[name] ||= [])
10
+ event = (class_events[name.to_s] ||= [])
11
+
12
+ # remove the type, if we have an on if and it isn't in the engine_type
13
+ if limit_if.any? && !limit_if.include?(engine_type.to_sym)
14
+ block = Proc.new {}
15
+ end
8
16
  event << [block, klass._name, options]
9
17
  end
10
18
 
11
19
  def trigger name, options = {}
12
20
  content = ''
13
21
 
14
- events[klass._name][name].each do |event|
22
+ events[klass._name][name.to_s].each do |event|
15
23
  block, comp, _ = event
16
24
 
17
- response = Instance.new(component(comp), scope).instance_exec options, &block
25
+ response = Component::Instance.new(component(comp), scope).instance_exec options, &block
18
26
 
19
27
  if response.is_a? Roda::Component::DOM
20
28
  content = response.to_html
21
29
  elsif response.is_a? String
22
- content = response.to_s
30
+ content = response
23
31
  end
24
32
  end
25
33
 
@@ -40,37 +48,19 @@ class Roda
40
48
  component_opts[:events]
41
49
  end
42
50
 
51
+ def engine_type
52
+ RUBY_ENGINE == 'ruby' ? 'server' : 'client'
53
+ end
54
+
43
55
  def server?
44
- RUBY_ENGINE == 'ruby'
56
+ RUBY_ENGINE == 'ruby' ? 'server' : false
45
57
  end
46
58
  alias :server :server?
47
59
 
48
60
  def client?
49
- RUBY_ENGINE == 'opal'
61
+ RUBY_ENGINE == 'opal' ? 'client' : false
50
62
  end
51
63
  alias :client :client?
52
-
53
- class Instance < Struct.new(:instance, :scope)
54
- def method_missing method, *args, &block
55
- if instance.respond_to? method, true
56
- instance.send method, *args, &block
57
- elsif server && scope.respond_to?(method, true)
58
- scope.send method, *args, &block
59
- else
60
- super
61
- end
62
- end
63
-
64
- def server?
65
- RUBY_ENGINE == 'ruby'
66
- end
67
- alias :server :server?
68
-
69
- def client?
70
- RUBY_ENGINE == 'opal'
71
- end
72
- alias :client :client?
73
- end
74
64
  end
75
65
  end
76
66
  end
@@ -0,0 +1,61 @@
1
+ if RUBY_ENGINE == 'opal'
2
+ require 'native'
3
+
4
+ class Roda
5
+ class Component
6
+ class Faye
7
+ include Native
8
+
9
+ def initialize url
10
+ super `new Faye.Client(#{url})`
11
+ end
12
+
13
+ alias_native :subscribe
14
+ alias_native :publish
15
+ alias_native :set_header, :setHeader
16
+ alias_native :add_extension, :addExtension
17
+ end
18
+ end
19
+ end
20
+ else
21
+ class Roda
22
+ class Component
23
+ class Faye
24
+ class CsrfProtection
25
+ def incoming(m, request, callback)
26
+ # # fix due to opal and wrapping message in native like Native(message)
27
+ message = { '_id' => m['_id']}
28
+ message.merge! m['native']
29
+
30
+ ap '======================'
31
+ ap message
32
+ ap request.session
33
+ ap '======================'
34
+
35
+ session_token = request.session['csrf.token']
36
+ message_token = message['ext'] && message['ext'].delete('csrfToken')
37
+
38
+ unless session_token == message_token
39
+ message['error'] = '401::Access denied'
40
+ end
41
+
42
+ callback.call(message)
43
+ end
44
+ #
45
+ # def outgoing(m, request, callback)
46
+ # ap '======================'
47
+ # ap 'outgoing'
48
+ # ap m
49
+ # ap request.session
50
+ # ap '======================'
51
+ # #
52
+ # # unless session_token == message_token
53
+ # # message['error'] = '401::Access denied'
54
+ # # end
55
+ # callback.call(m)
56
+ # end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,38 @@
1
+ class Roda
2
+ class Component
3
+ class Instance
4
+ attr_accessor :instance, :scope
5
+
6
+ def initialize instance, scope = false
7
+ @instance = instance
8
+ @scope = scope
9
+ end
10
+
11
+ # this is a hack because it seems like display is a ruby object method
12
+ # when doing method(:display) it gives #<Method: # Roda::Component::Instance(Kernel)#display>
13
+ def display *args
14
+ method_missing(*args)
15
+ end
16
+
17
+ def method_missing method = 'display', *args, &block
18
+ if instance.respond_to? method, true
19
+ instance.send method, *args, &block
20
+ elsif server && scope && scope.respond_to?(method, true)
21
+ scope.send method, *args, &block
22
+ else
23
+ super
24
+ end
25
+ end
26
+
27
+ def server?
28
+ RUBY_ENGINE == 'ruby'
29
+ end
30
+ alias :server :server?
31
+
32
+ def client?
33
+ RUBY_ENGINE == 'opal'
34
+ end
35
+ alias :client :client?
36
+ end
37
+ end
38
+ end
@@ -1,5 +1,5 @@
1
1
  class Roda
2
2
  class Component
3
- VERSION = "0.0.4"
3
+ VERSION = "0.0.5"
4
4
  end
5
5
  end
@@ -1,6 +1,12 @@
1
+ unless RUBY_ENGINE == 'opal'
2
+ require 'tilt'
3
+ end
4
+
1
5
  require 'opal'
2
6
  require 'opal-jquery'
3
7
  require "base64"
8
+ require 'roda/component/faye'
9
+ require 'roda/component/instance'
4
10
  require 'roda/component/dom'
5
11
  require 'roda/component/events'
6
12
 
@@ -12,7 +18,6 @@ if RUBY_ENGINE == 'opal'
12
18
  }
13
19
  end
14
20
 
15
-
16
21
  class Roda
17
22
  class Component
18
23
  attr_accessor :scope
@@ -34,11 +39,11 @@ class Roda
34
39
 
35
40
  # The name of the component
36
41
  def name _name
42
+ @_name = _name.to_s
43
+
37
44
  if server?
38
- component_opts[:class_name][_name] = self.to_s
45
+ component_opts[:class_name][@_name] = self.to_s
39
46
  end
40
-
41
- @_name = _name
42
47
  end
43
48
 
44
49
  # The html source
@@ -109,6 +114,14 @@ class Roda
109
114
  end
110
115
  end
111
116
 
117
+ def method_missing method, *args, &block
118
+ if server && app.respond_to?(method, true)
119
+ app.send method, *args, &block
120
+ else
121
+ super
122
+ end
123
+ end
124
+
112
125
  private
113
126
 
114
127
  def server?
@@ -133,15 +146,13 @@ class Roda
133
146
  end
134
147
 
135
148
  def dom
136
- d = cache[:dom] || begin
149
+ @_dom ||= DOM.new cache[:dom].dup || begin
137
150
  if server?
138
151
  Nokogiri::HTML cache[:html]
139
152
  else
140
153
  Element
141
154
  end
142
155
  end
143
-
144
- DOM.new d
145
156
  end
146
157
 
147
158
  # Grab the template from the cache, use the nokogiri dom or create a
@@ -162,6 +173,14 @@ class Roda
162
173
  events.trigger(*args)
163
174
  end
164
175
 
176
+ def method_missing method, *args, &block
177
+ if server && scope.respond_to?(method, true)
178
+ scope.send method, *args, &block
179
+ else
180
+ super
181
+ end
182
+ end
183
+
165
184
  private
166
185
 
167
186
  def server?
@@ -1,11 +1,26 @@
1
1
  require 'tilt'
2
+ require 'faye'
3
+ require 'faye/redis'
2
4
  require 'roda/component'
5
+ require 'roda/component/faye'
3
6
  require 'json'
4
7
  require "base64"
5
8
 
6
9
  class Roda
7
10
  module RodaPlugins
8
11
  module Component
12
+ def self.load_dependencies(app, opts={})
13
+ Faye::WebSocket.load_adapter('thin')
14
+
15
+ app.plugin :csrf, header: 'X-CSRF-TOKEN'
16
+
17
+ app.use Faye::RackAdapter,
18
+ mount: '/faye',
19
+ timeout: 25,
20
+ extensions: [Roda::Component::Faye::CsrfProtection.new],
21
+ :engine => { :type => Faye::Redis }
22
+ end
23
+
9
24
  def self.configure(app, opts={})
10
25
  if app.opts[:component]
11
26
  app.opts[:component].merge!(opts)
@@ -35,7 +50,7 @@ class Roda
35
50
 
36
51
  def load_component name
37
52
  Object.const_get(
38
- component_opts[:class_name][name.to_sym]
53
+ component_opts[:class_name][name.to_s]
39
54
  ).new self
40
55
  end
41
56
 
@@ -51,8 +66,37 @@ class Roda
51
66
  options = Base64.encode64 options.to_json
52
67
  comp_name = comp.class._name
53
68
 
69
+ # client.addExtension({
70
+ # outgoing: function(message, callback) {
71
+ # message.ext = message.ext || {};
72
+ # message.ext.csrfToken = $('meta[name=csrf-token]').attr('content');
73
+ # callback(message);
74
+ # }
75
+ # });
54
76
  js = <<-EOF
55
77
  Document.ready? do
78
+ unless $faye
79
+ $faye = Roda::Component::Faye.new('/faye')
80
+
81
+ $faye.set_header 'X-CSRF-TOKEN', Element.find('meta[name=_csrf]').attr('content')
82
+
83
+ $faye.add_extension({
84
+ outgoing: ->(message, block) {
85
+ message = Native(message)
86
+ message.ext = message.ext || {}
87
+ message.ext.csrfToken = Element.find('meta[name=_csrf]').attr('content')
88
+
89
+ block.call message
90
+ }
91
+ })
92
+
93
+ $faye.subscribe '/foo' do |message|
94
+ puts '===================='
95
+ puts message
96
+ puts '===================='
97
+ end
98
+ end
99
+
56
100
  unless $component_opts[:comp][:"#{comp_name}"]
57
101
  c = $component_opts[:comp][:"#{comp_name}"] = #{comp.class}.new
58
102
  c.cache = JSON.parse Base64.decode64('#{cache}')
@@ -67,14 +111,19 @@ class Roda
67
111
  def component name, options = {}, &block
68
112
  comp = load_component name
69
113
 
70
- action = options[:call] || 'display'
114
+ action = options[:call] || :display
115
+ trigger = options[:trigger] || false
71
116
 
72
117
  # call action
73
118
  # TODO: make sure the single method parameter isn't a block
74
- if comp.method(action).parameters.length > 0
75
- comp_response = comp.send(action, options, &block)
119
+ if trigger
120
+ comp_response = comp.trigger trigger, options
76
121
  else
77
- comp_response = comp.send(action, &block)
122
+ if comp.method(action).parameters.length > 0
123
+ comp_response = comp.send(action, options, &block)
124
+ else
125
+ comp_response = comp.send(action, &block)
126
+ end
78
127
  end
79
128
 
80
129
  if comp_response.is_a? Roda::Component::DOM
@@ -84,6 +133,8 @@ class Roda
84
133
  end
85
134
 
86
135
  content += load_component_js comp, action
136
+
137
+ content
87
138
  end
88
139
  alias :comp :component
89
140
  alias :roda_component :component
@@ -143,16 +194,12 @@ class Roda
143
194
  end
144
195
 
145
196
  on self.class.component_route_regex do |comp, type, action|
146
- comp = scope.load_component(comp.to_sym)
147
-
148
197
  case type
149
198
  when 'call'
150
- response.write comp.public_send action
199
+ scope.roda_component(comp, call: action)
151
200
  when 'trigger'
152
- response.write scope.load_component(comp.to_sym).events.trigger action.to_sym
201
+ scope.roda_component(comp, trigger: action)
153
202
  end
154
-
155
- response.write scope.load_component_js comp, action
156
203
  end
157
204
  end
158
205
  end
@@ -21,7 +21,9 @@ Gem::Specification.new do |spec|
21
21
  spec.add_runtime_dependency "opal"
22
22
  spec.add_runtime_dependency "opal-jquery"
23
23
  spec.add_runtime_dependency "faye"
24
+ spec.add_runtime_dependency "faye-redis"
24
25
  spec.add_runtime_dependency "tilt"
26
+ spec.add_runtime_dependency "rack_csrf"
25
27
  spec.add_development_dependency "bundler", "~> 1.7"
26
28
  spec.add_development_dependency "rake", "~> 10.0"
27
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda-component
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - cj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-01 00:00:00.000000000 Z
11
+ date: 2014-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faye-redis
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: tilt
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rack_csrf
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: bundler
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -112,6 +140,8 @@ files:
112
140
  - lib/roda/component.rb
113
141
  - lib/roda/component/dom.rb
114
142
  - lib/roda/component/events.rb
143
+ - lib/roda/component/faye.rb
144
+ - lib/roda/component/instance.rb
115
145
  - lib/roda/component/version.rb
116
146
  - lib/roda/plugins/component.rb
117
147
  - roda-component.gemspec