browserio 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,136 +0,0 @@
1
- module BrowserIO
2
- class Events
3
- attr_accessor :scope, :browser_events, :object_events
4
-
5
- VIP_ORDER_LIST = %w(history_change)
6
-
7
- def initialize
8
- @browser_events = []
9
- @object_events = {}
10
- end
11
-
12
- def add(*args, &block)
13
- event = {
14
- name: args.shift,
15
- block: block,
16
- options: {}
17
- }
18
-
19
- args.each do |arg|
20
- if arg.is_a?(String)
21
- event[:selector] = arg
22
- elsif arg.is_a? Class
23
- event[:klass] = arg
24
- else
25
- event[:options] = event[:options].merge(arg).indifferent.to_h
26
- end
27
- end
28
-
29
- if event[:name].to_s == 'ready' || event[:name] =~ /[:\s]/ || event[:selector]
30
- browser_events << event
31
- else
32
- event[:component] = scope.bio_opts.name
33
-
34
- if !scope.class.bio_opts.added_class_events && for_component = event[:options].delete(:for)
35
- bio_opts = BrowserIO.components[for_component].klass.bio_opts
36
- events = bio_opts.object_events[event.delete(:name)] ||= []
37
- events << event
38
- else
39
- events = object_events[event.delete(:name)] ||= []
40
- events << event
41
- end
42
- end
43
- end
44
-
45
- def trigger(name, options = {})
46
- name = name.to_s
47
- options = options.indifferent
48
-
49
- case name
50
- when 'browser_events'
51
- # We make sure anything in the VIP_ORDER_LIST goes first
52
- (browser_events.sort_by do |x|
53
- [VIP_ORDER_LIST.index(x[:name]) || VIP_ORDER_LIST.length, browser_events.index(x)]
54
- end).each do |event|
55
- trigger_browser_event event
56
- end
57
- else
58
- events = object_events[name] || []
59
- events.each do |event|
60
- BrowserIO[event[:component]].instance_exec options, &event[:block]
61
- end
62
- end
63
- end
64
-
65
- def trigger_browser_event event
66
- comp = BrowserIO[scope.bio_opts.name]
67
-
68
- case event[:name]
69
- when 'ready'
70
- el = Element.find(event[:selector] != '' ? event[:selector] : 'body')
71
-
72
- comp.instance_exec el, &event[:block]
73
- when 'history_change'
74
- $window.history.change do |he|
75
- comp.instance_exec he, &event[:block]
76
- end
77
- when 'form'
78
- warn 'missing form class option' unless event[:klass]
79
-
80
- Document.on :submit, event[:selector] do |evt|
81
- el = evt.current_target
82
- evt.prevent_default
83
-
84
- params = {}
85
-
86
- # loop through all the forum values
87
- el.serialize_array.each do |row|
88
- field, _ = row
89
-
90
- # we need to make it native to access it like ruby
91
- field = Native(field)
92
- name = field['name']
93
- value = field['value']
94
-
95
- params[name] = value
96
- end
97
-
98
- params_obj = {}
99
-
100
- params.each do |param, value|
101
- keys = param.gsub(/[^a-z0-9_]/, '|').gsub(/\|\|/, '|').gsub(/\|$/, '').split('|')
102
- params_obj = params_obj.deep_merge keys.reverse.inject(value) { |a, n| { n => a } }
103
- end
104
-
105
- opts[:dom] = el
106
-
107
- if opts && key = opts[:key]
108
- form = event[:klass].new params_obj[key], opts
109
- else
110
- form = event[:klass].new params_obj, opts
111
- end
112
-
113
- el.find(opts[:error_selector] || '.field-error').remove
114
-
115
- comp.instance_exec form, evt.current_target, evt, &event[:block]
116
- end
117
- else
118
- args = [event[:name]]
119
-
120
- if selector = event[:selector]
121
- args << selector
122
- end
123
-
124
- Document.on(*args) do |evt|
125
- el = evt.current_target
126
- comp.instance_exec el, evt, &event[:block]
127
- end
128
-
129
- if event[:name] =~ /ready/
130
- el = Element.find(event[:selector] != '' ? event[:selector] : 'body')
131
- comp.instance_exec el, &event[:block]
132
- end
133
- end
134
- end
135
- end
136
- end
@@ -1,29 +0,0 @@
1
- module BrowserIO
2
- module HTML
3
- include Methods
4
-
5
- class << self
6
- # Parse HTML into a Nokogiri object
7
- # @param raw_html [String]
8
- # @return parsed_html [Nokogiri]
9
- def [](raw_html)
10
- return unless server?
11
-
12
- # remove all the starting and trailing whitespace
13
- raw_html = raw_html.strip
14
-
15
- if raw_html[/\A<!DOCTYPE/] || raw_html[/\A<html/]
16
- Nokogiri::HTML(raw_html)
17
- else
18
- parsed_html = Nokogiri::HTML.fragment(raw_html)
19
-
20
- if parsed_html.children.length >= 1
21
- parsed_html.children.first
22
- else
23
- parsed_html
24
- end
25
- end
26
- end
27
- end
28
- end
29
- end
@@ -1,18 +0,0 @@
1
- require 'opal'
2
- require 'opal-jquery'
3
-
4
- if RUBY_ENGINE == 'ruby'
5
- module Opal
6
- class Builder
7
- # @return [String] Compiled javascript.
8
- def javascript
9
- to_s
10
- end
11
- end
12
- end
13
- end
14
-
15
- module BrowserIO
16
- # Create our own opal instance.
17
- Opal = ::Opal.dup
18
- end
@@ -1,343 +0,0 @@
1
- require 'browserio/plugins/validations'
2
- require 'forwardable'
3
-
4
- module BrowserIO
5
- module Plugins
6
- class Form < Component
7
- config.name :form_plugin
8
-
9
- include Methods
10
- include Validations
11
-
12
- module Delegates
13
- def _delegates(*names)
14
- accessors = Module.new do
15
- extend Forwardable # DISCUSS: do we really need Forwardable here?
16
- names.each do |name|
17
- delegate [name, "#{name}="] => :_attributes
18
- end
19
- end
20
- include accessors
21
- end
22
- end
23
-
24
- extend Delegates
25
-
26
- class Attributes
27
- def set_values(atts)
28
- @_attributes = []
29
-
30
- atts.each do |key, val|
31
- if respond_to?("#{key}=")
32
- send(:"#{key}=", val)
33
- @_attributes << key
34
- end
35
- end
36
- end
37
-
38
- def set_attr_accessors attrs
39
- attrs.each do |attr|
40
- define_singleton_method "#{attr}=" do |value|
41
- value = value.to_obj if value.is_a? Hash
42
- instance_variable_set(:"@#{attr}", value)
43
- @_attributes ||= []
44
- @_attributes << attr
45
- end
46
-
47
- define_singleton_method attr do
48
- instance_variable_get(:"@#{attr}")
49
- end
50
- end
51
- end
52
-
53
- def _attributes
54
- @_attributes ||= []
55
- end
56
-
57
- def empty?
58
- _attributes.empty?
59
- end
60
- end
61
-
62
- # Initialize with a hash of attributes and values.
63
- # If extra attributes are sent, a NoMethodError exception will be raised.
64
- #
65
- # @example
66
- #
67
- # class EditPost < Scrivener
68
- # attr_accessor :title
69
- # attr_accessor :body
70
- #
71
- # def validate
72
- # assert_present :title
73
- # assert_present :body
74
- # end
75
- # end
76
- #
77
- # edit = EditPost.new(title: "Software Tools")
78
- #
79
- # edit.valid? #=> false
80
- #
81
- # edit.errors[:title] #=> []
82
- # edit.errors[:body] #=> [:not_present]
83
- #
84
- # edit.body = "Recommended reading..."
85
- #
86
- # edit.valid? #=> true
87
- #
88
- # # Now it's safe to initialize the model.
89
- # post = Post.new(edit.attributes)
90
- # post.save
91
- def initialize(atts = {}, options = {})
92
- @_data = atts
93
- @_data = atts.to_obj if atts.is_a? Hash
94
- @_options = options
95
-
96
- # @_attributes = Class.new(Attributes).new
97
- @_attributes = Attributes.new
98
- @_attributes.set_attr_accessors _attr_accessors
99
- @_attributes.set_values _data
100
-
101
- _data.each do |key, val|
102
- send("#{key}=", val)
103
- end
104
-
105
- _form.each do |key, klass|
106
- opts = {}
107
- opts[key] = klass.new(_data.send(key)) if _data.respond_to?(key)
108
- @_attributes.set_values opts
109
-
110
- send("#{key}=", opts[key])
111
- end
112
- end
113
-
114
- def self.attr_accessor(*vars)
115
- @_attr_accessors ||= []
116
- @_form ||= {}
117
-
118
- vars.each do |v|
119
- if !v.is_a? Hash
120
- @_attr_accessors << v unless @_attr_accessors.include? v
121
- else
122
- v = v.first
123
-
124
- unless @_attr_accessors.include? v.first
125
- @_attr_accessors << v.first
126
- @_form[v.first] = v.last
127
- end
128
- end
129
- end
130
-
131
- _delegates(*_attr_accessors)
132
- end
133
-
134
- def method_missing method, *args, &block
135
- # respond_to?(symbol, include_all=false)
136
- if _data.respond_to? method, true
137
- _data.send method, *args, &block
138
- else
139
- return if method[/\=\z/]
140
-
141
- super
142
- end
143
- end
144
-
145
- # Return hash of attributes and values.
146
- def attributes
147
- Hash.new.tap do |atts|
148
- _attributes.instance_variables.each do |ivar|
149
- # todo: figure out why it's setting @constructor and @toString
150
- next if ivar == :@constructor || ivar == :@toString || ivar == :@_attributes || ivar == :@_data || ivar == :@_forms
151
-
152
- att = ivar[1..-1].to_sym
153
- atts[att] = _attributes.send(att)
154
-
155
- if klass = _form[att.to_s.to_sym]
156
- atts[att] = klass.new(atts[att]).attributes
157
- end
158
- end
159
- end
160
- end
161
-
162
- def model_attributes data = attributes
163
- hash = {}
164
-
165
- data.each do |k, v|
166
- if klass = _form[k.to_s.to_sym]
167
- d = data[k]
168
- d = d.attributes if d.is_a?(Form)
169
-
170
- f = klass.new d
171
- k = "#{k}_attributes"
172
- dt = f.model_attributes
173
-
174
- hash[k] = model_attributes dt
175
- elsif v.is_a? Hash
176
- hash[k] = model_attributes data[k]
177
- else
178
- hash[k] = v
179
- end
180
- end
181
-
182
- hash
183
- end
184
-
185
- def slice(*keys)
186
- Hash.new.tap do |atts|
187
- keys.each do |att|
188
- atts[att] = send(att)
189
- # atts[att] = _attributes.send(att)
190
- end
191
- end
192
- end
193
-
194
- def display_errors options = {}, &block
195
- dom = options.delete(:dom) || _dom
196
- d_errors = errors
197
-
198
- if override_errors = options[:override_errors]
199
- d_errors = override_errors
200
- end
201
-
202
- keys = options.delete(:keys) || (_options[:key] ? [_options[:key]] : [])
203
-
204
- if extra_errors = options.delete(:errors)
205
- extra_errors.each do |key, value|
206
- d_errors[key] = value
207
- end
208
- end
209
-
210
- d_errors.each do |key, error|
211
- d_keys = (keys.dup << key)
212
-
213
- error = error.first
214
-
215
- if error.is_a?(Hash)
216
- d_options = options.dup
217
- d_options[:keys] = d_keys
218
- d_options[:override_errors] = d_errors[key].first
219
-
220
- display_errors d_options, &block
221
- elsif !block_given? || block.call(d_keys, error) == false
222
- name = d_keys.each_with_index.map do |field, i|
223
- i != 0 ? "[#{field}]" : field
224
- end.join
225
-
226
- if tmpl = options[:tmpl]
227
- if client?
228
- field_error_dom = DOM.new(`#{tmpl.dom}[0].outerHTML`)
229
- else
230
- field_error_dom = DOM.new(tmpl.dom.to_html)
231
- end
232
- else
233
- field_error_dom = DOM.new('<span class="field-error"><span>')
234
- end
235
-
236
- field_error_dom.html _error_name(key, error)
237
-
238
- field = dom.find("[name='#{name}']")
239
- field.before field_error_dom.dom
240
- end
241
- end
242
- end
243
- alias_method :render_errors, :display_errors
244
-
245
- def render_values dom = false, key = false, data = false
246
- dom = _options[:dom] unless dom
247
- key = _options[:key] if !key && _options.key?(:key)
248
-
249
- dom.find('input, select, textarea') do |element|
250
- name = element['name']
251
- name = name.gsub(/\A#{key}/, '') if key
252
- keys = name.gsub(/\A\[/, '').gsub(/[^a-z0-9_]/, '|').gsub(/\|\|/, '|').gsub(/\|$/, '').split('|')
253
- value = false
254
-
255
- keys.each do |k|
256
- begin
257
- value = value ? value.send(k) : send(k)
258
- rescue
259
- value = ''
260
- end
261
- end
262
-
263
- case element.name
264
- when 'select'
265
- element.find('option') do |x|
266
- x['selected'] = true if x['value'] == value.to_s
267
- end
268
- when 'input'
269
- if %w(radio checkbox).include? element['type']
270
- if element['value'] == value.to_s
271
- element['checked'] = true
272
- else
273
- element.delete 'checked'
274
- end
275
- else
276
- value = sprintf('%.2f', value) if value.is_a? BigDecimal
277
- element['value'] = value.to_s
278
- end
279
- when 'textarea'
280
- element.val value.to_s
281
- end
282
- end
283
- end
284
-
285
- def _attributes
286
- @_attributes ||= {}
287
- end
288
-
289
- def validate_msg error, column
290
- false
291
- end
292
-
293
- protected
294
-
295
- def _data
296
- @_data ||= {}
297
- end
298
-
299
- def self._attr_accessors
300
- @_attr_accessors ||= []
301
- end
302
-
303
- def self._form
304
- @_form || {}
305
- end
306
-
307
- def _form
308
- self.class._form
309
- end
310
-
311
- def _attr_accessors
312
- self.class._attr_accessors
313
- end
314
-
315
- def _options
316
- @_options
317
- end
318
-
319
- def _dom
320
- @_dom ||= @_options[:dom]
321
- end
322
-
323
- def _error_name key, error
324
- validate_msg(error.to_sym, key.to_sym) || case error.to_s.to_sym
325
- when :not_email
326
- 'Email Isn\'t Valid.'
327
- when :not_present
328
- 'Required.'
329
- when :not_equal
330
- 'Password does not match.'
331
- else
332
- !error[/\s/] ? error.to_s.gsub(/_/, ' ').titleize : error
333
- end
334
- end
335
-
336
- def empty?
337
- _attributes.empty?
338
- end
339
- end
340
- end
341
- end
342
-
343
- BrowserIO::Form = BrowserIO::Plugins::Form