roda-component 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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