opal-connect 0.0.3 → 0.0.4

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: de60747b1ade488a697ae66c25931d1bad6dd5c5
4
- data.tar.gz: 2bc80456910377dadeff20ebada2a9b8c3a3a13a
3
+ metadata.gz: b52883ea798fba1bc5ef8e7e3b77083fe082634e
4
+ data.tar.gz: 055c956583030f66affcd36a84e96f0cb498d0d6
5
5
  SHA512:
6
- metadata.gz: 4cbfab39d084eaaf3eb6848155bff391a3734efa802bb14a7ac90f48fd3cb69f28bdfe60acc16c48db63f461da2b8081f2a26446bb9c97ba744e4675676b0f3a
7
- data.tar.gz: b6e9af69f0aa91683401b01788efecdd6b1cc13e55df4722a5197ae49ba3c4f1e781261a3d51a31c29c5660b5fcc1fc485dc330935e7848169685673c1452c1a
6
+ metadata.gz: 872c395c0bdfbc176ee10d55374318f94ef063151af77143135f6d600c88e79651bebfb15d0c3d5f41406e1bd40a0ebf40834fdb1df052791f04f3959e3a477e
7
+ data.tar.gz: 88a527535fc13204d3d95588fd6f56692f405ee1b27a42d786da5e4d7cd565eb1f3ccce3ff7e36555081bed5db53bd92b06a4da0b4cc9edfe307288c0b221915
data/Rakefile CHANGED
@@ -1,2 +1 @@
1
1
  require "bundler/gem_tasks"
2
-
@@ -0,0 +1,79 @@
1
+ unless RUBY_ENGINE == 'opal'
2
+ require 'yaml'
3
+ Opal.use_gem 'ability_list'
4
+ end
5
+
6
+ require 'ability_list'
7
+
8
+ module Opal::Connect
9
+ module ConnectPlugins
10
+ module Abilities
11
+ def self.load_dependencies(connect, *args)
12
+ connect.plugin :current_user
13
+ end
14
+
15
+ def self.configure(connect, options = false)
16
+ if options
17
+ unless RUBY_ENGINE == 'opal'
18
+ if file = options[:file]
19
+ options[:list] = YAML.load_file file
20
+ end
21
+ end
22
+
23
+ connect.options[:abilities] = options
24
+ end
25
+ end
26
+
27
+ ConnectJavascript = -> do
28
+ if current_user.respond_to?(:id) && current_user.id
29
+ abilities = Opal::Connect.options[:abilities][:list][current_user.role]
30
+ "$current_user_abilities = Base64.decode64('#{Base64.encode64 abilities.to_json}')"
31
+ else
32
+ "$current_user_abilities = {}"
33
+ end
34
+ end
35
+
36
+ module InstanceMethods
37
+ def load_abilities(user, scope)
38
+ # make sure the user is logged in
39
+ return unless user.respond_to?(:id) && user.id
40
+
41
+ abilities = RUBY_ENGINE == 'opal' \
42
+ ? $current_user_abilities \
43
+ : Opal::Connect.options[:abilities][:list][user.role]
44
+
45
+ Abilities.process abilities['can'], :can, scope, user
46
+ Abilities.process abilities['cannot'], :can, scope, user
47
+ end
48
+ end
49
+
50
+ def self.process(abilities, type, scope, user)
51
+ (abilities || []).each do |ability|
52
+ obj = get_object(ability['object'])
53
+
54
+ if method = ability['method']
55
+ scope.send type, ability['action'].to_sym, obj do |record|
56
+ scope.send(method, record)
57
+ end
58
+ else
59
+ scope.send type, ability['action'].to_sym, obj
60
+ end
61
+ end
62
+ end
63
+
64
+ def self.get_object(obj)
65
+ if RUBY_ENGINE == 'opal'
66
+ obj.to_sym
67
+ else
68
+ if obj[0,1] == obj[0,1].upcase
69
+ Object.const_get(obj)
70
+ else
71
+ obj.to_sym
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ register_plugin :abilities, Abilities
78
+ end
79
+ end
@@ -0,0 +1,43 @@
1
+ require 'ostruct'
2
+
3
+ module Opal
4
+ module Connect
5
+ module ConnectPlugins
6
+ module CurrentUser
7
+ def self.load_dependencies(connect, *args)
8
+ connect.plugin :scope
9
+ end
10
+
11
+ def self.configure(connect, options = false)
12
+ if options
13
+ unless RUBY_ENGINE == 'opal'
14
+ Connect::CLIENT_OPTIONS << 'current_user'
15
+ connect.options[:plugin_requires] << options[:class_path]
16
+ require options[:class_path]
17
+ end
18
+
19
+ connect.options[:current_user] = options
20
+ end
21
+ end
22
+
23
+ ConnectJavascript = -> do
24
+ "$current_user = Base64.decode64('#{Base64.encode64 current_user.to_h.to_json}')"
25
+ end
26
+
27
+ module InstanceMethods
28
+ def current_user
29
+ @current_user ||= Object.const_get(Connect.options[:current_user][:class]).new(OpenStruct.new begin
30
+ if RUBY_ENGINE == 'opal'
31
+ $current_user || {}
32
+ else
33
+ scope.instance_exec(&Connect.options[:current_user][:authenticate]) || {}
34
+ end
35
+ end)
36
+ end
37
+ end
38
+ end
39
+
40
+ register_plugin :current_user, CurrentUser
41
+ end
42
+ end
43
+ end
@@ -29,8 +29,9 @@ module Opal
29
29
  selector = "#{events_dom} #{selector}"
30
30
  end
31
31
 
32
- handler = proc { |evt| __send__(method, evt) } if method
33
- event = [name, selector, handler]
32
+ klass = self
33
+ handler = proc { |evt| klass.new.__send__(method, evt) } if method
34
+ event = [klass, name, selector, handler]
34
35
  connect_events << event unless connect_events.include? event
35
36
  end
36
37
  end
@@ -43,7 +44,7 @@ module Opal
43
44
  el = dom('html')
44
45
 
45
46
  events.each do |event|
46
- name, selector, wrapper = event
47
+ _, name, selector, wrapper = event
47
48
  if name.to_s != 'document'
48
49
  el.off(name, selector, &wrapper)
49
50
  else
@@ -59,11 +60,13 @@ module Opal
59
60
  el = dom('html')
60
61
 
61
62
  events.map! do |event|
62
- name, selector, handler = event
63
- wrapper = proc do |e|
63
+ klass, name, selector, handler = event
64
+ c = klass.name == 'Opal::Connect' ? klass : klass.new
65
+
66
+ wrapper = ->(e) do
64
67
  # gives you access to this, like jquery
65
- @this = dom(e.current_target)
66
- instance_exec(e, &handler)
68
+ c.instance_variable_set(:@this, dom(e.current_target))
69
+ c.instance_exec(e, &handler)
67
70
  end
68
71
 
69
72
  if name.to_s != 'document'
@@ -71,7 +74,8 @@ module Opal
71
74
  else
72
75
  Document.on(selector, &wrapper)
73
76
  end
74
- [name, selector, wrapper]
77
+
78
+ [klass, name, selector, wrapper]
75
79
  end
76
80
  end
77
81
  end
@@ -0,0 +1,48 @@
1
+ module Opal::Connect
2
+ module ConnectPlugins
3
+ module Pjax
4
+ def self.load_dependencies(connect)
5
+ connect.plugin :events
6
+ end
7
+
8
+ if RUBY_ENGINE == 'opal'
9
+ `require('expose?$!expose?Pjax!pjax')`
10
+ `require('expose?$!expose?NProgress!nprogress')`
11
+ `require('nprogress/nprogress.css')`
12
+
13
+ ConnectSetup = -> do
14
+ on(:document, 'pjax:send') { `NProgress.start(); NProgress.inc()` }
15
+ on(:document, 'pjax:complete') { `NProgress.done()` }
16
+
17
+ $pjax = Native(`new Pjax({elements: 'a', selectors: ['#k-menu', '.container']})`)
18
+ end
19
+ end
20
+
21
+ if RUBY_ENGINE == 'opal'
22
+ module InstanceMethods
23
+ def pjax_load(url)
24
+ $pjax.loadUrl(url, $pjax.options.to_n)
25
+ end
26
+ end
27
+ else
28
+ module InstanceMethods
29
+ def render_pjax(method, *options, &block)
30
+ js = Opal::Connect.build Opal::Connect.javascript(self, method, *options)
31
+ content = dom.load! public_send(method, *options, &block)
32
+ content.find('#pjax-inline-script').remove
33
+ content.find('body > div').first.append "<script id='pjax-inline-script'>#{js}</script>"
34
+ content.to_html
35
+ end
36
+ end
37
+
38
+ module ClassMethods
39
+ def render_pjax(method, *args, &block)
40
+ new.render_pjax(method, *args, &block)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ register_plugin :pjax, Pjax
47
+ end
48
+ end
@@ -17,15 +17,40 @@ module Opal
17
17
  Connect.server_methods[self.name] ||= []
18
18
  end
19
19
 
20
- def __server__(m = false, &block)
21
- return if RUBY_ENGINE == 'opal'
20
+ def __server__(method = false, *args, &block)
21
+ if RUBY_ENGINE == 'opal'
22
+ klass_name = self.name
22
23
 
23
- m ||= Module.new(&block)
24
+ if Connect.server_methods[klass_name].include? method
25
+ promise = Promise.new
24
26
 
25
- yield if block_given?
27
+ payload = {
28
+ method: method,
29
+ args: args,
30
+ klass: klass_name
31
+ }
26
32
 
27
- m.public_instance_methods(false).each do |meth|
28
- connect_server_methods << meth unless connect_server_methods.include? meth
33
+ HTTP.post(Connect.options[:url], payload: payload) do |response|
34
+ if response.ok?
35
+ res = JSON.from_object(`response`)
36
+ promise.resolve res[:body], response
37
+ else
38
+ promise.reject response
39
+ end
40
+ end
41
+
42
+ promise
43
+ else
44
+ raise "#{method} is not a server method"
45
+ end
46
+ else
47
+ method ||= Module.new(&block)
48
+
49
+ yield if block_given?
50
+
51
+ method.public_instance_methods(false).each do |meth|
52
+ connect_server_methods << meth unless connect_server_methods.include? meth
53
+ end
29
54
  end
30
55
  end
31
56
  alias server __server__
@@ -33,28 +58,7 @@ module Opal
33
58
 
34
59
  module InstanceMethods
35
60
  def __server__(method, *args)
36
- if Connect.server_methods[self.class.name].include? method
37
- promise = Promise.new
38
-
39
- payload = {
40
- method: method,
41
- args: args,
42
- klass: self.class.name
43
- }
44
-
45
- HTTP.post(Connect.options[:url], payload: payload) do |response|
46
- if response.ok?
47
- res = JSON.from_object(`response`)
48
- promise.resolve res[:body], response
49
- else
50
- promise.reject response
51
- end
52
- end
53
-
54
- promise
55
- else
56
- raise "#{method} is not a server method"
57
- end
61
+ self.class.server(method, *args)
58
62
  end
59
63
  alias server __server__
60
64
  end
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  module Connect
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
4
4
  end
5
5
  end
data/lib/opal/connect.rb CHANGED
@@ -21,7 +21,9 @@ module Opal
21
21
  hot_reload: false,
22
22
  url: '/connect',
23
23
  plugins: [],
24
- setup_ran: false
24
+ setup_ran: false,
25
+ javascript: [],
26
+ plugin_requires: []
25
27
  )
26
28
  end
27
29
 
@@ -29,8 +31,8 @@ module Opal
29
31
  @options = opts
30
32
  end if RUBY_ENGINE == 'opal'
31
33
 
32
- def setup
33
- yield(options) if block_given?
34
+ def setup(&block)
35
+ instance_exec(&block) if block_given?
34
36
 
35
37
  # make sure we include the default plugins with connect
36
38
  options[:plugins].each { |plug| Connect.plugin plug }
@@ -68,6 +70,10 @@ module Opal
68
70
  file.puts "require 'opal/connect/plugins/#{name}'"
69
71
  end
70
72
  end
73
+
74
+ Connect.options[:plugin_requires].each do |require_path|
75
+ file.puts "require '#{require_path}'"
76
+ end
71
77
  end
72
78
  end
73
79
  end
@@ -163,11 +169,11 @@ module Opal
163
169
  hl = {} unless hl.is_a? Hash
164
170
  hl = { host: 'http://localhost', port: 8080 }.merge hl
165
171
 
166
- Connect.write_entry_file(self.class, method, *options)
172
+ Connect.write_entry_file(self, method, *options)
167
173
 
168
174
  "#{public_send(method, *options, &block)}<script src='#{hl[:host]}:#{hl[:port]}/main.js'></script>"
169
175
  else
170
- js = Connect.build Connect.javascript(self.class, method, *options)
176
+ js = Connect.build Connect.javascript(self, method, *options)
171
177
 
172
178
  "#{public_send(method, *options, &block)}<script>#{js}</script>"
173
179
  end
@@ -194,8 +200,11 @@ module Opal
194
200
  included = (args.first == :included) ? args.shift : false
195
201
 
196
202
  raise ConnectError, "Cannot add a plugin to a frozen Connect class" if RUBY_ENGINE != 'opal' && frozen?
197
- plugin = ConnectPlugins.load_plugin(plugin) if plugin.is_a?(Symbol)
198
- plugin.load_dependencies(self, *args, &block) if plugin.respond_to?(:load_dependencies)
203
+ if plugin.is_a?(Symbol)
204
+ Connect.options[:plugins] << plugin unless Connect.options[:plugins].include? plugin
205
+ plugin = ConnectPlugins.load_plugin(plugin)
206
+ end
207
+ plugin.load_dependencies(self, *args, &block) if !included && plugin.respond_to?(:load_dependencies)
199
208
  return unless plugin
200
209
  include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
201
210
  extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
@@ -203,8 +212,11 @@ module Opal
203
212
  Connect.extend(plugin::ConnectClassMethods) if defined?(plugin::ConnectClassMethods)
204
213
  Connect.include(plugin::ConnectInstanceMethods) if defined?(plugin::ConnectInstanceMethods)
205
214
  Connect.instance_exec(plugin, &plugin::ConnectSetup) if defined?(plugin::ConnectSetup)
215
+ unless RUBY_ENGINE == 'opal'
216
+ Connect.options[:javascript] << plugin::ConnectJavascript if defined?(plugin::ConnectJavascript)
217
+ end
206
218
  end
207
- plugin.configure(self, *args, &block) if plugin.respond_to?(:configure)
219
+ plugin.configure(self, *args, &block) if !included && plugin.respond_to?(:configure)
208
220
  nil
209
221
  end
210
222
 
@@ -222,15 +234,26 @@ module Opal
222
234
  def javascript(klass, method, *options)
223
235
  return unless klass
224
236
 
237
+ js = []
238
+ javascript = Connect.options[:javascript]
239
+
240
+ if javascript.length
241
+ javascript.each do |block|
242
+ js << klass.instance_exec(&block)
243
+ end
244
+ end
245
+
225
246
  %{
226
247
  Document.ready? do
227
- klass = #{klass.name}.new
248
+ klass = #{klass.class.name}.new
228
249
 
229
250
  if klass.respond_to?(:#{method})
230
251
  klass.__send__(:#{method}, *JSON.parse(Base64.decode64('#{Base64.encode64 options.to_json}')))
231
252
  end
232
253
 
233
- Opal::Connect.start_events
254
+ #{js.join(';')}
255
+
256
+ Opal::Connect.start_events unless $connect_events_started
234
257
  end
235
258
  }
236
259
  end
@@ -257,6 +280,7 @@ module Opal
257
280
  code = %{#{code} Opal::Connect.server_methods = JSON.parse(
258
281
  Base64.decode64('#{Base64.encode64 Connect.server_methods.to_json}')
259
282
  );}
283
+ code = "#{code} #{Connect.options[:entry]}" if Connect.options[:entry]
260
284
 
261
285
 
262
286
  if !Connect.options[:hot_reload]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - cj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-22 00:00:00.000000000 Z
11
+ date: 2016-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
@@ -93,9 +93,12 @@ files:
93
93
  - README.md
94
94
  - Rakefile
95
95
  - lib/opal/connect.rb
96
+ - lib/opal/connect/plugins/abilities.rb
97
+ - lib/opal/connect/plugins/current_user.rb
96
98
  - lib/opal/connect/plugins/dom.rb
97
99
  - lib/opal/connect/plugins/events.rb
98
100
  - lib/opal/connect/plugins/html.rb
101
+ - lib/opal/connect/plugins/pjax.rb
99
102
  - lib/opal/connect/plugins/scope.rb
100
103
  - lib/opal/connect/plugins/server.rb
101
104
  - lib/opal/connect/version.rb