opal-connect 0.0.2 → 0.0.3

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: a8eb1755efb4187fb0fe313046b83862a7943ac3
4
- data.tar.gz: fd330a60e16e736d1e5cb29e402ef3b83233a761
3
+ metadata.gz: de60747b1ade488a697ae66c25931d1bad6dd5c5
4
+ data.tar.gz: 2bc80456910377dadeff20ebada2a9b8c3a3a13a
5
5
  SHA512:
6
- metadata.gz: bce04a189804b540bd3382d6de3722ce6e177dd9e7c8b98e2d1e720cc9f9dabf392bf14dd45f60eb7d1a9ec3ef3ed15f75dc47006b9b7e643532857e13cfdc3d
7
- data.tar.gz: fecc33e53a01ddffb92dea830892eee8f7578d216524011fe3a3f855ea46bfaee70c4086272f136ee287010dbddc83398f17d94bea00305ec56e5ca6c44efe52
6
+ metadata.gz: 4cbfab39d084eaaf3eb6848155bff391a3734efa802bb14a7ac90f48fd3cb69f28bdfe60acc16c48db63f461da2b8081f2a26446bb9c97ba744e4675676b0f3a
7
+ data.tar.gz: b6e9af69f0aa91683401b01788efecdd6b1cc13e55df4722a5197ae49ba3c4f1e781261a3d51a31c29c5660b5fcc1fc485dc330935e7848169685673c1452c1a
@@ -10,6 +10,8 @@ module Opal
10
10
  # each protected by a mutex.
11
11
  module Dom
12
12
  module ConnectClassMethods
13
+ attr_accessor :templates
14
+
13
15
  def templates
14
16
  @templates ||= ConnectCache.new
15
17
  end
@@ -42,14 +44,14 @@ module Opal
42
44
  end
43
45
  end
44
46
 
45
- def dom
47
+ def dom(selector = false)
46
48
  if RUBY_ENGINE == 'opal'
47
- selector = 'html'
49
+ selector ||= 'html'
50
+ Instance.new selector, cache
48
51
  else
49
- selector = false
52
+ selector ||= false
53
+ @dom ||= Instance.new selector, cache
50
54
  end
51
-
52
- @dom ||= Instance.new false, cache
53
55
  end
54
56
  end
55
57
 
@@ -58,18 +60,20 @@ module Opal
58
60
  self.class.cache
59
61
  end
60
62
 
61
- def dom
63
+ def dom(selector = false)
62
64
  if RUBY_ENGINE == 'opal'
63
- selector = 'html'
65
+ selector ||= 'html'
66
+ Instance.new selector, cache
64
67
  else
65
- selector = cache[:html]
68
+ selector ||= cache[:html]
69
+ @dom ||= Instance.new selector, cache
66
70
  end
67
-
68
- @dom ||= Instance.new selector, cache
69
71
  end
70
72
  end
71
73
 
72
74
  class Instance
75
+ RETURN_VALUE_FIELDS = %w'attr prop'
76
+
73
77
  attr_reader :selector, :cache, :dom
74
78
 
75
79
  def initialize(selector, cache)
@@ -98,6 +102,11 @@ module Opal
98
102
  end
99
103
  alias set! set
100
104
 
105
+ def load html
106
+ Instance.new(html, cache)
107
+ end
108
+ alias load! load
109
+
101
110
  def save template_name = false, remove = true
102
111
  if template_name
103
112
  cache[:"#{template_name}"] = self.to_html
@@ -146,6 +155,8 @@ module Opal
146
155
  else
147
156
  node.each { |n| n.set(key, value) }
148
157
  end
158
+
159
+ self
149
160
  else
150
161
  if node.respond_to? :get
151
162
  node.get(key)
@@ -153,8 +164,6 @@ module Opal
153
164
  node.first.get(key)
154
165
  end
155
166
  end
156
-
157
- self
158
167
  end
159
168
 
160
169
  def remove
@@ -176,7 +185,7 @@ module Opal
176
185
  end
177
186
  end
178
187
 
179
- def append(content, &block)
188
+ def append(content = false, &block)
180
189
  # content becomes scope in this case
181
190
  content = HTML::DSL.scope!(content).html(&block).to_html if block_given?
182
191
 
@@ -184,7 +193,7 @@ module Opal
184
193
  node.append(content)
185
194
  else
186
195
  if content.is_a? Dom::Instance
187
- content = content.children
196
+ content = content.node.children
188
197
  else
189
198
  content = Oga.parse_html(content).children
190
199
  end
@@ -192,14 +201,14 @@ module Opal
192
201
  if node.is_a?(Oga::XML::NodeSet)
193
202
  node.each { |n| n.children = (n.children + content) }
194
203
  else
195
- node.children = (children + content)
204
+ node.children = (node.children + content)
196
205
  end
197
206
  end
198
207
 
199
208
  self
200
209
  end
201
210
 
202
- def prepend(content, &block)
211
+ def prepend(content = false, &block)
203
212
  # content becomes scope in this case
204
213
  content = HTML::DSL.scope!(content).html(&block).to_html if block_given?
205
214
 
@@ -264,21 +273,31 @@ module Opal
264
273
  end
265
274
 
266
275
  def node
267
- if self.is_a?(Dom::Instance)
268
- self.dom
276
+ if self.dom.respond_to? :dom
277
+ self.dom.dom
269
278
  else
270
- dom
279
+ self.dom
271
280
  end
272
281
  end
273
282
 
274
283
  # This allows you to use all the oga or opal jquery methods if a
275
284
  # global one isn't set
276
285
  def method_missing(method, *args, &block)
277
- if dom.respond_to?(method, true)
278
- dom.send(method, *args, &block)
286
+ if RUBY_ENGINE == 'opal' && node.respond_to?(method, true)
287
+ n = node.send(method, *args, &block)
288
+ elsif RUBY_ENGINE != 'opal'
289
+ if node.is_a?(Oga::XML::NodeSet) && node.first.respond_to?(method, true)
290
+ n = node.first.send(method, *args, &block)
291
+ elsif node.respond_to?(method, true)
292
+ n = node.send(method, *args, &block)
293
+ else
294
+ super
295
+ end
279
296
  else
280
297
  super
281
298
  end
299
+
300
+ RETURN_VALUE_FIELDS.include?(method.to_s) ? n : Instance.new(n, cache)
282
301
  end
283
302
  end
284
303
  end
@@ -2,6 +2,8 @@ module Opal
2
2
  module Connect
3
3
  module ConnectPlugins
4
4
  module Events
5
+ $connect_events = ConnectCache.new if RUBY_ENGINE == 'opal'
6
+
5
7
  module ClassMethods
6
8
  if RUBY_ENGINE == 'opal'
7
9
  def connect_events
@@ -9,55 +11,66 @@ module Opal
9
11
  end
10
12
  end
11
13
 
12
- def __events_el__ el = false
13
- @connect_el = el if el
14
- @connect_el
15
- end
16
- alias events_el __events_el__
14
+ attr_accessor :events_dom
17
15
 
16
+ def events_dom(selector = false)
17
+ if selector
18
+ @events_dom = selector
19
+ else
20
+ @events_dom
21
+ end
22
+ end
18
23
 
19
- def __on__(name, selector = nil, method = nil, &handler)
24
+ def on(name, selector = nil, method = nil, &handler)
20
25
  if RUBY_ENGINE == 'opal'
26
+ return if $connect_events_started
27
+
28
+ if name.to_s != 'document' && events_dom
29
+ selector = "#{events_dom} #{selector}"
30
+ end
31
+
21
32
  handler = proc { |evt| __send__(method, evt) } if method
22
- event = [name, selector, handler]
33
+ event = [name, selector, handler]
23
34
  connect_events << event unless connect_events.include? event
24
35
  end
25
36
  end
26
- alias on __on__
27
37
  end
28
38
 
29
39
  if RUBY_ENGINE == 'opal'
30
40
  module ConnectClassMethods
31
- $connect_events = ConnectCache.new unless $connect_events
32
-
33
- def events_teardown
34
- if $connect_events
35
- $connect_events.each do |klass, events|
36
- el = Dom[klass.connect_el || 'body']
41
+ def teardown_events
42
+ $connect_events.each do |klass, events|
43
+ el = dom('html')
37
44
 
38
- events.each do |event|
39
- name, selector, wrapper = event
45
+ events.each do |event|
46
+ name, selector, wrapper = event
47
+ if name.to_s != 'document'
40
48
  el.off(name, selector, &wrapper)
49
+ else
50
+ Document.off(selector, &wrapper)
41
51
  end
42
52
  end
43
-
44
- $connect_events = ConnectCache.new
45
53
  end
46
54
  end
47
55
 
48
- def events_start
56
+ def start_events
57
+ $connect_events_started = true
49
58
  $connect_events.each do |klass, events|
50
- el = Dom[klass.connect_el || 'body']
59
+ el = dom('html')
51
60
 
52
61
  events.map! do |event|
53
62
  name, selector, handler = event
54
63
  wrapper = proc do |e|
55
64
  # gives you access to this, like jquery
56
- @this = Dom[e.target]
65
+ @this = dom(e.current_target)
57
66
  instance_exec(e, &handler)
58
67
  end
59
68
 
60
- el.on(name, selector, &wrapper)
69
+ if name.to_s != 'document'
70
+ el.on(name, selector, &wrapper)
71
+ else
72
+ Document.on(selector, &wrapper)
73
+ end
61
74
  [name, selector, wrapper]
62
75
  end
63
76
  end
@@ -13,6 +13,12 @@ module Opal
13
13
  script section select small source span strike strong style sub summary sup table tbody
14
14
  td textarea tfoot th thead time title tr track tt u ul var video wbr}
15
15
 
16
+ module InstanceMethods
17
+ def html(&block)
18
+ HTML::DSL.scope!(self).html(&block).to_html
19
+ end
20
+ end
21
+
16
22
  # http://erikonrails.snowedin.net/?p=379
17
23
  class DSL
18
24
  def initialize(tag, *args, &block)
@@ -21,6 +21,12 @@ module Opal
21
21
  end
22
22
  end
23
23
  end
24
+
25
+ module ClassMethods
26
+ def scope(scope, *args)
27
+ new(*args).scope(scope)
28
+ end
29
+ end
24
30
  end
25
31
 
26
32
  register_plugin :scope, Scope
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  module Connect
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
data/lib/opal/connect.rb CHANGED
@@ -13,7 +13,6 @@ end
13
13
  # Opal corelib is already loaded from CDN
14
14
  module Opal
15
15
  module Connect
16
-
17
16
  CLIENT_OPTIONS = %w'url plugins' unless RUBY_ENGINE == 'opal'
18
17
 
19
18
  class << self
@@ -21,7 +20,8 @@ module Opal
21
20
  @options ||= Connect::ConnectCache.new(
22
21
  hot_reload: false,
23
22
  url: '/connect',
24
- plugins: []
23
+ plugins: [],
24
+ setup_ran: false
25
25
  )
26
26
  end
27
27
 
@@ -33,7 +33,7 @@ module Opal
33
33
  yield(options) if block_given?
34
34
 
35
35
  # make sure we include the default plugins with connect
36
- options[:plugins].each { |plug| Connect.plugin plug.to_sym }
36
+ options[:plugins].each { |plug| Connect.plugin plug }
37
37
 
38
38
  unless RUBY_ENGINE == 'opal'
39
39
  write_plugins_file
@@ -49,8 +49,7 @@ module Opal
49
49
 
50
50
  klass.extend ConnectPlugins::Base::ClassMethods
51
51
 
52
- # include default plugins
53
- Connect.options[:plugins].each { |plug| klass.plugin plug.to_sym }
52
+ Connect.options[:plugins].each { |plug| klass.plugin plug, :included }
54
53
  end
55
54
 
56
55
  # We need to wripte a plugins.rb file which has all the plugins required
@@ -61,7 +60,13 @@ module Opal
61
60
  FileUtils.mkdir_p(File.dirname(path))
62
61
  File.open(path, 'w+') do |file|
63
62
  ConnectPlugins.plugins.each do |name, _|
64
- file.puts "require 'opal/connect/plugins/#{name}'"
63
+ plugins_path = Connect.options[:plugins_path]
64
+
65
+ if plugins_path && File.exist?("#{plugins_path}/#{name}.rb")
66
+ file.puts "require '#{plugins_path}/#{name}'"
67
+ else
68
+ file.puts "require 'opal/connect/plugins/#{name}'"
69
+ end
65
70
  end
66
71
  end
67
72
  end
@@ -128,7 +133,14 @@ module Opal
128
133
  h = @plugins
129
134
  unless plugin = h[name]
130
135
  unless RUBY_ENGINE == 'opal'
131
- require "opal/connect/plugins/#{name}"
136
+ plugins_path = Connect.options[:plugins_path]
137
+
138
+ if plugins_path && File.exists?("#{plugins_path}/#{name}.rb")
139
+ require "#{plugins_path}/#{name}"
140
+ else
141
+ require "opal/connect/plugins/#{name}"
142
+ end
143
+
132
144
  raise ConnectError, "Plugin #{name} did not register itself correctly in Roda::RodaPlugins" unless plugin = h[name]
133
145
  end
134
146
  end
@@ -146,24 +158,28 @@ module Opal
146
158
  module Base
147
159
  module InstanceMethods
148
160
  if RUBY_ENGINE != 'opal'
149
- def to_js(method, *options)
161
+ def render(method, *options, &block)
150
162
  if hl = Connect.options[:hot_reload]
151
163
  hl = {} unless hl.is_a? Hash
152
164
  hl = { host: 'http://localhost', port: 8080 }.merge hl
153
165
 
154
166
  Connect.write_entry_file(self.class, method, *options)
155
167
 
156
- "#{__send__(method, *options)}<script src='#{hl[:host]}:#{hl[:port]}/main.js'></script>"
168
+ "#{public_send(method, *options, &block)}<script src='#{hl[:host]}:#{hl[:port]}/main.js'></script>"
157
169
  else
158
170
  js = Connect.build Connect.javascript(self.class, method, *options)
159
171
 
160
- "#{send(method, *options)}<script>#{js}</script>"
172
+ "#{public_send(method, *options, &block)}<script>#{js}</script>"
161
173
  end
162
174
  end
163
175
  end
164
176
  end
165
177
 
166
178
  module ClassMethods
179
+ def render(method, *args, &block)
180
+ new.render(method, *args, &block)
181
+ end
182
+
167
183
  def setup(&block)
168
184
  yield
169
185
  end
@@ -175,13 +191,19 @@ module Opal
175
191
  # Connect.plugin PluginModule
176
192
  # Connect.plugin :csrf
177
193
  def plugin(plugin, *args, &block)
194
+ included = (args.first == :included) ? args.shift : false
195
+
178
196
  raise ConnectError, "Cannot add a plugin to a frozen Connect class" if RUBY_ENGINE != 'opal' && frozen?
179
197
  plugin = ConnectPlugins.load_plugin(plugin) if plugin.is_a?(Symbol)
180
198
  plugin.load_dependencies(self, *args, &block) if plugin.respond_to?(:load_dependencies)
199
+ return unless plugin
181
200
  include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
182
201
  extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
183
- Connect.extend(plugin::ConnectClassMethods) if defined?(plugin::ConnectClassMethods)
184
- Connect.include(plugin::ConnectInstanceMethods) if defined?(plugin::ConnectInstanceMethods)
202
+ unless included
203
+ Connect.extend(plugin::ConnectClassMethods) if defined?(plugin::ConnectClassMethods)
204
+ Connect.include(plugin::ConnectInstanceMethods) if defined?(plugin::ConnectInstanceMethods)
205
+ Connect.instance_exec(plugin, &plugin::ConnectSetup) if defined?(plugin::ConnectSetup)
206
+ end
185
207
  plugin.configure(self, *args, &block) if plugin.respond_to?(:configure)
186
208
  nil
187
209
  end
@@ -201,10 +223,6 @@ module Opal
201
223
  return unless klass
202
224
 
203
225
  %{
204
- Opal::Connect.server_methods = JSON.parse(
205
- Base64.decode64('#{Base64.encode64 Connect.server_methods.to_json}')
206
- )
207
-
208
226
  Document.ready? do
209
227
  klass = #{klass.name}.new
210
228
 
@@ -212,7 +230,7 @@ module Opal
212
230
  klass.__send__(:#{method}, *JSON.parse(Base64.decode64('#{Base64.encode64 options.to_json}')))
213
231
  end
214
232
 
215
- Opal::Connect.events_start
233
+ Opal::Connect.start_events
216
234
  end
217
235
  }
218
236
  end
@@ -222,8 +240,8 @@ module Opal
222
240
 
223
241
  path = "#{Dir.pwd}/.connect/entry.js"
224
242
 
225
- required_files = Connect.files.map do |file|
226
- "`require('#{file}')`"
243
+ required_files = Connect.files.uniq.map do |file|
244
+ !Connect.options[:hot_reload] ? "require('#{file}')" : "`require('#{file}')`"
227
245
  end.join(';')
228
246
 
229
247
  client_options = Connect.options.hash.select do |key, _|
@@ -236,6 +254,10 @@ module Opal
236
254
  code = "Opal::Connect.options = JSON.parse(Base64.decode64('#{client_options}'));"
237
255
  code = "#{code} Opal::Connect.setup;"
238
256
  code = "#{code} Opal::Connect.templates = JSON.parse(Base64.decode64('#{templates}'));"
257
+ code = %{#{code} Opal::Connect.server_methods = JSON.parse(
258
+ Base64.decode64('#{Base64.encode64 Connect.server_methods.to_json}')
259
+ );}
260
+
239
261
 
240
262
  if !Connect.options[:hot_reload]
241
263
  code = "#{code} #{required_files}"
@@ -243,8 +265,20 @@ module Opal
243
265
  code << %{
244
266
  `if (module.hot) {`
245
267
  `module.hot.accept()`
268
+
269
+ if Opal::Connect.respond_to? :teardown_events
270
+ Opal::Connect.teardown_events
271
+ connect_events = $connect_events[Opal::Connect]
272
+ $connect_events = Opal::Connect::ConnectCache.new
273
+
274
+ if connect_events
275
+ $connect_events[Opal::Connect] = connect_events
276
+ end
277
+
278
+ $connect_events_started = false
279
+ end
280
+
246
281
  #{required_files}
247
- Opal::Connect.events_teardown
248
282
  #{Connect.javascript(klass, method, *options)}
249
283
  `}`
250
284
  }
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.2
4
+ version: 0.0.3
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-20 00:00:00.000000000 Z
11
+ date: 2016-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal