opal-connect 0.0.3 → 0.0.4

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: 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