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,92 +0,0 @@
1
- module BrowserIO
2
- module Plugins
3
- class History < Component
4
- config.name :history_plugin
5
- end
6
- end
7
- end
8
-
9
- if RUBY_ENGINE == 'opal'
10
- require 'browserio/plugins/location'
11
-
12
- module Browser
13
- # {Window} instances are {Native} objects used to wrap native window instances.
14
- #
15
- # Generally, you will want to use the top level {::Window} instance, which
16
- # wraps `window` from the main page.
17
- class Window
18
- include Native
19
-
20
- # @!attribute [r] history
21
- # @return [History] the history for this window
22
- def history
23
- History.new(`#@native.history`) if `#@native.history`
24
- end
25
- end
26
-
27
- # {History} allows manipulation of the session history.
28
- #
29
- # @see https://developer.mozilla.org/en-US/docs/Web/API/History
30
- class History
31
- include Native
32
-
33
- # @!attribute [r] length
34
- # @return [Integer] how many items are in the history
35
- alias_native :length
36
-
37
- # Go back in the history.
38
- #
39
- # @param number [Integer] how many items to go back
40
- def back(number = 1)
41
- `History.go(-number)`
42
- end
43
-
44
- # Go forward in the history.
45
- #
46
- # @param number [Integer] how many items to go forward
47
- def forward(number = 1)
48
- `History.go(number)`
49
- end
50
-
51
- # Push an item in the history.
52
- #
53
- # @param item [String] the item to push in the history
54
- # @param data [Object] additional state to push
55
- def push(item, data = nil)
56
- data = `null` if data.nil?
57
-
58
- `History.pushState(jQuery.parseJSON(data.$to_json()), null, item)`
59
- end
60
-
61
- # Replace the current history item with another.
62
- #
63
- # @param item [String] the item to replace with
64
- # @param data [Object] additional state to replace
65
- def replace(item, data = nil)
66
- data = `null` if data.nil?
67
-
68
- `History.replaceState(data, null, item)`
69
- end
70
-
71
- def get_state
72
- Native(`History.getState()`)
73
- end
74
-
75
- # @!attribute [r] current
76
- # @return [String] the current item
77
- def current
78
- $window.location.path
79
- end
80
-
81
- def change &block
82
- %x{
83
- History.Adapter.bind(window,'statechange',function(e){
84
- var state = History.getState();
85
- state = #{Native(`state`)}
86
- return #{block.call(`state`)}
87
- });
88
- }
89
- end
90
- end
91
- end
92
- end
@@ -1,78 +0,0 @@
1
- module Browser
2
-
3
- # Allows manipulation of a location, usually from {Window} and {DOM::Document}.
4
- #
5
- # @see https://developer.mozilla.org/en-US/docs/Web/API/Location
6
- class Location
7
- include Native
8
-
9
- # Change the location.
10
- #
11
- # @param url [String, #to_s] the URL to go to
12
- def assign(url)
13
- `#@native.assign(#{url.to_s})`
14
- end
15
-
16
- # Replace the current URL.
17
- #
18
- # @param url [String, #to_s] the URL to go to
19
- def replace(url)
20
- `#@native.replace(#{url.to_s})`
21
- end
22
-
23
- # Reload the page.
24
- #
25
- # @param force [Boolean] whether to force the reload
26
- def reload(force = false)
27
- `#@native.reload(force)`
28
- end
29
-
30
- # Convert the location to a string.
31
- def to_s
32
- `#@native.toString()`
33
- end
34
-
35
- # @!attribute fragment
36
- # @return [String] the hash fragment of the location URI
37
- alias_native :fragment, :hash
38
- alias_native :fragment=, :hash=
39
-
40
- # @!attribute host
41
- # @return [String] the host part of the location URI
42
- alias_native :host
43
- alias_native :host=
44
-
45
- # @!attribute uri
46
- # @return [String] the whole location URI
47
- alias_native :uri, :href
48
- alias_native :uri=, :href=
49
-
50
- # @!attribute path
51
- # @return [String] the path part of the location URI
52
- alias_native :path, :pathname
53
- alias_native :path=, :pathname=
54
-
55
- # @!attribute port
56
- # @return [Integer] the port part of the location URI
57
- alias_native :port
58
- alias_native :port=
59
-
60
- # @!attribute scheme
61
- # @return [String] the scheme part of the location URI
62
- alias_native :scheme, :protocol
63
- alias_native :scheme=, :protocol=
64
-
65
- # @!attribute query
66
- # @return [String] the query part of the location URI
67
- alias_native :query, :search
68
- alias_native :query=, :search=
69
- end
70
-
71
- class Window
72
- # @!attribute [r] location
73
- # @return [Location] the location for the window
74
- def location
75
- Location.new(`#@native.location`) if `#@native.location`
76
- end
77
- end
78
- end
@@ -1,65 +0,0 @@
1
- module BrowserIO
2
- module Plugins
3
- class Pjax < Component
4
- config.name :pjax_plugin
5
- config.requires :history_plugin
6
-
7
- class Nanobar
8
- include Native
9
-
10
- alias_native :go
11
- alias_native :start
12
- alias_native :finish
13
-
14
- def initialize options = {}
15
- `var Nanobar=function(){"use strict";var t,i,e,s,h,n,o={width:"100%",height:"4px",zIndex:9999,top:"0"},a={width:0,height:"100%",clear:"both",transition:"height .3s"};return t=function(t,i){var e;for(e in i)t.style[e]=i[e];t.style["float"]="left"},s=function(){var t=this,i=this.width-this.here;.1>i&&i>-.1?(h.call(this,this.here),this.moving=!1,100==this.width&&(this.el.style.height=0,setTimeout(function(){t.cont.el.removeChild(t.el)},300))):(h.call(this,this.width-i/4),setTimeout(function(){t.go()},16))},h=function(t){this.width=t,this.el.style.width=this.width+"%"},n=function(){var t=new i(this);this.bars.unshift(t)},i=function(i){this.el=document.createElement("div"),this.el.style.backgroundColor=i.opts.bg,this.width=0,this.here=0,this.moving=!1,this.cont=i,t(this.el,a),i.el.appendChild(this.el)},i.prototype.go=function(t){t?(this.here=t,this.moving||(this.moving=!0,s.call(this))):this.moving&&s.call(this)},e=function(i){var e,s,h=this.opts=i||{};h.bg=h.bg||"#000",this.bars=[],e=this.el=document.createElement("div"),t(this.el,o),h.id&&(e.id=h.id),h.className&&(e.className=h.className),e.style.position=h.target?"relative":"fixed",h.target?(s=h.target,s.insertBefore(e,h.target.firstChild)):(s=document.getElementsByTagName("body")[0],s.appendChild(e)),s.className="nanobar-custom-parent",n.call(this)},e.prototype.go=function(t){this.bars[0].go(t),100==t&&n.call(this)},e.prototype.start=function(){(function(){var t=this.bars[0],i=function(){setTimeout(function(){var e=t.here+Math.round(10*Math.random());t.here>=99||(e>99&&(e=99),t.go(e),i())},500)};t.go(10),i()}).call(this)},e.prototype.finish=function(){this.go(100)},e}();`
16
- super `new Nanobar(options)`
17
- end
18
- end if client?
19
-
20
- def progress_bar
21
- $pjax_progress_bar
22
- end
23
-
24
- def get href = false
25
- $pjax_progress_bar = Nanobar.new({bg: '#f99f22'}.to_n)
26
- progress_bar.start
27
- `$(document).trigger('page:click')`
28
- $window.history.push href, pjax: true
29
- end
30
-
31
- on :click, 'a' do |el, evt|
32
- href = el.attr 'href'
33
-
34
- unless href =~ /^#/i || href =~ /^javascript:/i || el.attr('target') == '_blank'
35
- evt.prevent_default
36
- get href
37
- end
38
- end
39
-
40
- on :history_change do |e|
41
- if e.data.pjax
42
- progress_bar.start
43
- `$(document).trigger('page:request')`
44
- HTTP.get(e.url) do |response|
45
- res = Native(response.xhr)
46
- html = res.responseText
47
- # grab and add the body
48
- matches = html.match(/<body[^>]*>((.|[\n\r])*)<\/body>/im)
49
- dom.find('body').html matches[1]
50
- # grab and eval the scripts
51
- matches = html.match(/<script>((.|[\n\r])*)<\/script>/im)
52
- # `eval(#{matches[0]})`
53
- (matches[1] || '').split('</script>').each do |script|
54
- # script = script.sub('<script>', '')
55
- script = script.strip.sub('</html>', '').sub('<script>', '')
56
- `jQuery.globalEval(script);`
57
- end
58
- progress_bar.finish
59
- `$('html, body').animate({ scrollTop: 0 }, 0); $(document).trigger('page:load');`
60
- end
61
- end
62
- end
63
- end
64
- end
65
- end
@@ -1,251 +0,0 @@
1
- module BrowserIO
2
- module Plugins
3
- class Form < Component
4
- # Provides a base implementation for extensible validation routines.
5
- # {Scrivener::Validations} currently only provides the following assertions:
6
- #
7
- # * assert
8
- # * assert_present
9
- # * assert_format
10
- # * assert_numeric
11
- # * assert_url
12
- # * assert_email
13
- # * assert_member
14
- # * assert_length
15
- # * assert_decimal
16
- # * assert_equal
17
- #
18
- # The core tenets that Scrivener::Validations advocates can be summed up in a
19
- # few bullet points:
20
- #
21
- # 1. Validations are much simpler and better done using composition rather
22
- # than macros.
23
- # 2. Error messages should be kept separate and possibly in the view or
24
- # presenter layer.
25
- # 3. It should be easy to write your own validation routine.
26
- #
27
- # Other validations are simply added on a per-model or per-project basis.
28
- #
29
- # @example
30
- #
31
- # class Quote
32
- # attr_accessor :title
33
- # attr_accessor :price
34
- # attr_accessor :date
35
- #
36
- # def validate
37
- # assert_present :title
38
- # assert_numeric :price
39
- # assert_format :date, /\A[\d]{4}-[\d]{1,2}-[\d]{1,2}\z
40
- # end
41
- # end
42
- #
43
- # s = Quote.new
44
- # s.valid?
45
- # # => false
46
- #
47
- # s.errors
48
- # # => { :title => [:not_present],
49
- # :price => [:not_numeric],
50
- # :date => [:format] }
51
- #
52
- module Validations
53
- def server? &block
54
- RUBY_ENGINE == 'ruby'
55
- end
56
- alias :server :server?
57
-
58
- def client?
59
- RUBY_ENGINE == 'opal'
60
- end
61
- alias :client :client?
62
-
63
- def self.server? &block
64
- RUBY_ENGINE == 'ruby'
65
- end
66
- alias :server :server?
67
-
68
- def self.client?
69
- RUBY_ENGINE == 'opal'
70
- end
71
- alias :client :client?
72
-
73
- # Check if the current model state is valid. Each call to {#valid?} will
74
- # reset the {#errors} array.
75
- #
76
- # All validations should be declared in a `validate` method.
77
- #
78
- # @example
79
- #
80
- # class Login
81
- # attr_accessor :username
82
- # attr_accessor :password
83
- #
84
- # def validate
85
- # assert_present :user
86
- # assert_present :password
87
- # end
88
- # end
89
- #
90
- def valid?
91
- errors.clear
92
- validate
93
- errors.empty?
94
- end
95
-
96
- # Base validate implementation. Override this method in subclasses.
97
- def validate
98
- end
99
-
100
- # Hash of errors for each attribute in this model.
101
- def errors
102
- @errors ||= Hash.new { |hash, key| hash[key] = [] }
103
- end
104
-
105
- protected
106
-
107
- # Allows you to do a validation check against a regular expression.
108
- # It's important to note that this internally calls {#assert_present},
109
- # therefore you need not structure your regular expression to check
110
- # for a non-empty value.
111
- #
112
- # @param [Symbol] att The attribute you want to verify the format of.
113
- # @param [Regexp] format The regular expression with which to compare
114
- # the value of att with.
115
- # @param [Array<Symbol, Symbol>] error The error that should be returned
116
- # when the validation fails.
117
- def assert_format(att, format, error = [att, :format])
118
- if assert_present(att, error)
119
- assert(_attributes.send(att).to_s.match(format), error)
120
- end
121
- end
122
-
123
- # The most basic and highly useful assertion. Simply checks if the
124
- # value of the attribute is empty.
125
- #
126
- # @param [Symbol] att The attribute you wish to verify the presence of.
127
- # @param [Array<Symbol, Symbol>] error The error that should be returned
128
- # when the validation fails.
129
- def assert_present(att, error = [att, :not_present])
130
- if att.is_a? Array
131
- att.each { |a| assert_present(a, error = [a, :not_present])}
132
- else
133
- if klass = _form[att]
134
- options = {}
135
- options[:key] = _options[:key] if _options.key? :key
136
-
137
- f = klass.new(_attributes.send(att).attributes, options)
138
- assert(f.valid?, [att, f.errors])
139
- else
140
- assert(!_attributes.send(att).to_s.empty?, error)
141
- end
142
- end
143
- end
144
-
145
- # Checks if all the characters of an attribute is a digit.
146
- #
147
- # @param [Symbol] att The attribute you wish to verify the numeric format.
148
- # @param [Array<Symbol, Symbol>] error The error that should be returned
149
- # when the validation fails.
150
- def assert_numeric(att, error = [att, :not_numeric])
151
- if assert_present(att, error)
152
- if client?
153
- assert_format(att, /^\-?\d+$/, error)
154
- else
155
- assert_format(att, /\A\-?\d+\z/, error)
156
- end
157
- end
158
- end
159
-
160
- if client?
161
- URL = /^(http|https):\/\/([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}|(2 5[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3} |localhost)(:[0-9]{1,5})?(\/.*)?$/i
162
- else
163
- URL = /\A(http|https):\/\/([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}|(2 5[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3} |localhost)(:[0-9]{1,5})?(\/.*)?\z/i
164
- end
165
-
166
- def assert_url(att, error = [att, :not_url])
167
- if assert_present(att, error)
168
- assert_format(att, URL, error)
169
- end
170
- end
171
-
172
- if client?
173
- EMAIL = /^[a-z0-9!\#$%&'*\/=\?^{|}+_-]+(?:\.[a-z0-9!\#$%&'*\/=\?^{|}+_-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i
174
- else
175
- EMAIL = /\A[a-z0-9!\#$%&'*\/=\?^{|}+_-]+(?:\.[a-z0-9!\#$%&'*\/=\?^{|}+_-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\z/i
176
- end
177
-
178
- def assert_email(att, error = [att, :not_email])
179
- if assert_present(att, error)
180
- assert_format(att, EMAIL, error)
181
- end
182
- end
183
-
184
- def assert_member(att, set, err = [att, :not_valid])
185
- assert(set.include?(_attributes.send(att)), err)
186
- end
187
-
188
- def assert_length(att, range, error = [att, :not_in_range])
189
- if assert_present(att, error)
190
- val = _attributes.send(att).to_s
191
- assert range.include?(val.length), error
192
- end
193
- end
194
-
195
- if client?
196
- DECIMAL = /^\-?(\d+)?(\.\d+)?$/
197
- else
198
- DECIMAL = /\A\-?(\d+)?(\.\d+)?\z/
199
- end
200
-
201
- def assert_decimal(att, error = [att, :not_decimal])
202
- assert_format att, DECIMAL, error
203
- end
204
-
205
- # Check that the attribute has the expected value. It uses === for
206
- # comparison, so type checks are possible too. Note that in order
207
- # to make the case equality work, the check inverts the order of
208
- # the arguments: `assert_equal :foo, Bar` is translated to the
209
- # expression `Bar === send(:foo)`.
210
- #
211
- # @example
212
- #
213
- # def validate
214
- # assert_equal :status, "pending"
215
- # assert_equal :quantity, Fixnum
216
- # end
217
- #
218
- # @param [Symbol] att The attribute you wish to verify for equality.
219
- # @param [Object] value The value you want to test against.
220
- # @param [Array<Symbol, Symbol>] error The error that should be returned
221
- # when the validation fails.
222
- def assert_equal(att, value, error = [att, :not_equal])
223
- assert value === _attributes.send(att), error
224
- end
225
-
226
- # The grand daddy of all assertions. If you want to build custom
227
- # assertions, or even quick and dirty ones, you can simply use this method.
228
- #
229
- # @example
230
- #
231
- # class CreatePost
232
- # attr_accessor :slug
233
- # attr_accessor :votes
234
- #
235
- # def validate
236
- # assert_slug :slug
237
- # assert votes.to_i > 0, [:votes, :not_valid]
238
- # end
239
- #
240
- # protected
241
- # def assert_slug(att, error = [att, :not_slug])
242
- # assert send(att).to_s =~ /\A[a-z\-0-9]+\z/, error
243
- # end
244
- # end
245
- def assert(value, error)
246
- value or errors[error.first].push(error.last) && false
247
- end
248
- end
249
- end
250
- end
251
- end