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 +4 -4
- data/Rakefile +0 -1
- data/lib/opal/connect/plugins/abilities.rb +79 -0
- data/lib/opal/connect/plugins/current_user.rb +43 -0
- data/lib/opal/connect/plugins/events.rb +12 -8
- data/lib/opal/connect/plugins/pjax.rb +48 -0
- data/lib/opal/connect/plugins/server.rb +32 -28
- data/lib/opal/connect/version.rb +1 -1
- data/lib/opal/connect.rb +34 -10
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b52883ea798fba1bc5ef8e7e3b77083fe082634e
|
4
|
+
data.tar.gz: 055c956583030f66affcd36a84e96f0cb498d0d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 872c395c0bdfbc176ee10d55374318f94ef063151af77143135f6d600c88e79651bebfb15d0c3d5f41406e1bd40a0ebf40834fdb1df052791f04f3959e3a477e
|
7
|
+
data.tar.gz: 88a527535fc13204d3d95588fd6f56692f405ee1b27a42d786da5e4d7cd565eb1f3ccce3ff7e36555081bed5db53bd92b06a4da0b4cc9edfe307288c0b221915
|
data/Rakefile
CHANGED
@@ -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
|
-
|
33
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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__(
|
21
|
-
|
20
|
+
def __server__(method = false, *args, &block)
|
21
|
+
if RUBY_ENGINE == 'opal'
|
22
|
+
klass_name = self.name
|
22
23
|
|
23
|
-
|
24
|
+
if Connect.server_methods[klass_name].include? method
|
25
|
+
promise = Promise.new
|
24
26
|
|
25
|
-
|
27
|
+
payload = {
|
28
|
+
method: method,
|
29
|
+
args: args,
|
30
|
+
klass: klass_name
|
31
|
+
}
|
26
32
|
|
27
|
-
|
28
|
-
|
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
|
-
|
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
|
data/lib/opal/connect/version.rb
CHANGED
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
|
-
|
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
|
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
|
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
|
-
|
198
|
-
|
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
|
-
|
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.
|
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-
|
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
|