opal-jquery 0.3.0.beta1 → 0.3.0.beta2
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/.gitignore +1 -0
- data/.travis.yml +1 -2
- data/.yardopts +3 -0
- data/CHANGELOG.md +21 -8
- data/Gemfile +2 -2
- data/README.md +85 -68
- data/lib/opal/jquery.rb +12 -3
- data/{opal/opal-jquery → lib/opal/jquery}/constants.rb +0 -0
- data/lib/opal/jquery/document.rb +93 -0
- data/lib/opal/jquery/element.rb +669 -0
- data/lib/opal/jquery/event.rb +205 -0
- data/lib/opal/jquery/http.rb +270 -0
- data/lib/opal/jquery/kernel.rb +11 -0
- data/lib/opal/jquery/local_storage.rb +87 -0
- data/lib/opal/jquery/rspec.rb +65 -0
- data/lib/opal/jquery/version.rb +1 -1
- data/lib/opal/jquery/window.rb +40 -0
- data/opal-jquery.gemspec +2 -2
- data/spec/element/after_spec.rb +10 -10
- data/spec/element/animations_spec.rb +34 -13
- data/spec/element/attributes_spec.rb +27 -14
- data/spec/element/to_s_spec.rb +14 -0
- data/spec/http_spec.rb +25 -22
- data/spec/local_storage_spec.rb +1 -1
- data/spec/spec_helper.rb +6 -28
- metadata +19 -16
- data/opal/opal-jquery.rb +0 -6
- data/opal/opal-jquery/document.rb +0 -31
- data/opal/opal-jquery/element.rb +0 -339
- data/opal/opal-jquery/event.rb +0 -96
- data/opal/opal-jquery/http.rb +0 -164
- data/opal/opal-jquery/kernel.rb +0 -6
- data/opal/opal-jquery/local_storage.rb +0 -31
- data/opal/opal-jquery/window.rb +0 -4
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'opal/jquery/constants'
|
2
|
+
|
3
|
+
# {Event} wraps native jQuery events into a ruby api. Instances of events
|
4
|
+
# can be accessed by {#to_n}.
|
5
|
+
#
|
6
|
+
# {Event} instances should not be created directly, as they are usually
|
7
|
+
# created by one of the dom event handlers in {Element}.
|
8
|
+
#
|
9
|
+
# element.on :click do |event|
|
10
|
+
# puts event
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# # => #<Event:0x0000000>
|
14
|
+
#
|
15
|
+
# ## Usage
|
16
|
+
#
|
17
|
+
# {Event} exposes a slightly different API than jQuery, as {Event} tries to
|
18
|
+
# add some more ruby flavour to the object.
|
19
|
+
#
|
20
|
+
# ### Accessing element triggering event
|
21
|
+
#
|
22
|
+
# Unlike jQuery, the context of an event handler is not set to the triggering
|
23
|
+
# element. Instead, the element triggering the event can be accessed from the
|
24
|
+
# {Event} instance.
|
25
|
+
#
|
26
|
+
# #### Current Target
|
27
|
+
#
|
28
|
+
# To access the current element in the bubbling phase, {#element} or
|
29
|
+
# {#current_target} can be used which is the same as `currentTarget` or `this`
|
30
|
+
# from jQuery.
|
31
|
+
#
|
32
|
+
# element.on :click do |event|
|
33
|
+
# puts "element clicked: #{event.element}
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# # => "element clicked: #<Element: [<div>]>
|
37
|
+
#
|
38
|
+
# #### Target
|
39
|
+
#
|
40
|
+
# The {#target} of an event is the actual dom element that triggered the event,
|
41
|
+
# and this will be the same element through all phases of event bubbling. This
|
42
|
+
# is the same as the `event.target` jQuery property.
|
43
|
+
#
|
44
|
+
# element.on :click do |event|
|
45
|
+
# puts "actual element: #{event.target}"
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# # => "actual element: #<Element: [<div>]>
|
49
|
+
#
|
50
|
+
# ### Controlling Event Bubbling
|
51
|
+
#
|
52
|
+
# Propagation and default behaviour can be controlled on events using {#prevent}
|
53
|
+
# and {#stop}, which will prevent the browser default and stop event propagation
|
54
|
+
# respectively.
|
55
|
+
#
|
56
|
+
# element.on :click do |event|
|
57
|
+
# event.prevent # prevent browser default
|
58
|
+
# event.stop # stop event propagation
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# If you want to trigger both methods, which is usually the case, then {#kill}
|
62
|
+
# can be used as a shorthand.
|
63
|
+
#
|
64
|
+
# element.on :click do |event|
|
65
|
+
# event.kill
|
66
|
+
# puts event.prevented?
|
67
|
+
# puts event.stopped?
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# # => true
|
71
|
+
# # => true
|
72
|
+
#
|
73
|
+
class Event
|
74
|
+
`var $ = #{JQUERY_SELECTOR.to_n}` # cache $ for SPEED
|
75
|
+
|
76
|
+
# @private
|
77
|
+
# @param native [JSObject] native jquery/javascript event
|
78
|
+
def initialize(native)
|
79
|
+
@native = native
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns native javascript event created by jQuery.
|
83
|
+
#
|
84
|
+
# @return [JSObject]
|
85
|
+
def to_n
|
86
|
+
@native
|
87
|
+
end
|
88
|
+
|
89
|
+
def [](name)
|
90
|
+
`#@native[name]`
|
91
|
+
end
|
92
|
+
|
93
|
+
def type
|
94
|
+
`#@native.type`
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns the current element in the bubbling cycle of the event. This is
|
98
|
+
# not the same as the actual dom event that triggered the event, but is
|
99
|
+
# usually the context element the event was registered with, or the target
|
100
|
+
# of the css selector used in newer event styles.
|
101
|
+
#
|
102
|
+
# @return [Element]
|
103
|
+
def element
|
104
|
+
`$(#@native.currentTarget)`
|
105
|
+
end
|
106
|
+
|
107
|
+
alias current_target element
|
108
|
+
|
109
|
+
# Returns the actual element that triggered the dom event.
|
110
|
+
#
|
111
|
+
# @return [Element]
|
112
|
+
def target
|
113
|
+
`$(#@native.target)`
|
114
|
+
end
|
115
|
+
|
116
|
+
# Returns `true` if this event has had its default browser behaviour
|
117
|
+
# prevented, `false` otherwise.
|
118
|
+
#
|
119
|
+
# @return [Boolean]
|
120
|
+
def prevented?
|
121
|
+
`#@native.isDefaultPrevented()`
|
122
|
+
end
|
123
|
+
|
124
|
+
# Prevent this event from triggering its default browser behaviour.
|
125
|
+
def prevent
|
126
|
+
`#@native.preventDefault()`
|
127
|
+
end
|
128
|
+
|
129
|
+
# Returns `true` if the propagation/bubbling of this event has been stopped,
|
130
|
+
# `false` otherwise.
|
131
|
+
#
|
132
|
+
# @return [Boolean]
|
133
|
+
def stopped?
|
134
|
+
`#@native.isPropagationStopped()`
|
135
|
+
end
|
136
|
+
|
137
|
+
# Stop further propagaion of this event.
|
138
|
+
def stop
|
139
|
+
`#@native.stopPropagation()`
|
140
|
+
end
|
141
|
+
|
142
|
+
def stop_immediate
|
143
|
+
`#@native.stopImmediatePropagation()`
|
144
|
+
end
|
145
|
+
|
146
|
+
# Stops propagation and prevents default action.
|
147
|
+
#
|
148
|
+
# @see {#prevent}
|
149
|
+
# @see {#stop}
|
150
|
+
def kill
|
151
|
+
stop
|
152
|
+
prevent
|
153
|
+
end
|
154
|
+
|
155
|
+
##
|
156
|
+
# Keyboard/Mouse/Touch
|
157
|
+
|
158
|
+
def page_x
|
159
|
+
`#@native.pageX`
|
160
|
+
end
|
161
|
+
|
162
|
+
def page_y
|
163
|
+
`#@native.pageY`
|
164
|
+
end
|
165
|
+
|
166
|
+
def touch_x
|
167
|
+
`#@native.originalEvent.touches[0].pageX`
|
168
|
+
end
|
169
|
+
|
170
|
+
def touch_y
|
171
|
+
`#@native.originalEvent.touches[0].pageY`
|
172
|
+
end
|
173
|
+
|
174
|
+
def ctrl_key
|
175
|
+
`#@native.ctrlKey`
|
176
|
+
end
|
177
|
+
|
178
|
+
def meta_key
|
179
|
+
`#@native.metaKey`
|
180
|
+
end
|
181
|
+
|
182
|
+
def alt_key
|
183
|
+
`#@native.altKey`
|
184
|
+
end
|
185
|
+
|
186
|
+
def shift_key
|
187
|
+
`#@native.shiftKey`
|
188
|
+
end
|
189
|
+
|
190
|
+
def key_code
|
191
|
+
`#@native.keyCode`
|
192
|
+
end
|
193
|
+
|
194
|
+
def which
|
195
|
+
`#@native.which`
|
196
|
+
end
|
197
|
+
|
198
|
+
# @deprecated These will be removed soon
|
199
|
+
alias default_prevented? prevented?
|
200
|
+
alias prevent_default prevent
|
201
|
+
alias propagation_stopped? stopped?
|
202
|
+
alias stop_propagation stop
|
203
|
+
alias stop_immediate_propagation stop_immediate
|
204
|
+
|
205
|
+
end
|
@@ -0,0 +1,270 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'native'
|
3
|
+
require 'promise'
|
4
|
+
require 'opal/jquery/constants'
|
5
|
+
|
6
|
+
# {HTTP} is used to perform a `XMLHttpRequest` in ruby. It is a simple wrapper
|
7
|
+
# around jQuerys' `$.ajax` call. `XMLHttpRequest` is not wrapped directly as
|
8
|
+
# jquery provides some cross browser fixes.
|
9
|
+
#
|
10
|
+
# # Making requests
|
11
|
+
#
|
12
|
+
# To create a simple request, {HTTP} exposes class level methods to specify
|
13
|
+
# the HTTP action you wish to perform. Each action accepts the url for the
|
14
|
+
# request, as well as optional arguments passed as a hash:
|
15
|
+
#
|
16
|
+
# HTTP.get("/users/1.json")
|
17
|
+
# HTTP.post("/users", payload: data)
|
18
|
+
#
|
19
|
+
# The supported `HTTP` actions are:
|
20
|
+
#
|
21
|
+
# * {HTTP.get}
|
22
|
+
# * {HTTP.post}
|
23
|
+
# * {HTTP.put}
|
24
|
+
# * {HTTP.delete}
|
25
|
+
# * {HTTP.patch}
|
26
|
+
# * {HTTP.head}
|
27
|
+
#
|
28
|
+
# # Handling responses
|
29
|
+
#
|
30
|
+
# Responses can be handled using either a simple block callback, or using a
|
31
|
+
# {Promise} returned by the request.
|
32
|
+
#
|
33
|
+
# ## Using a block
|
34
|
+
#
|
35
|
+
# All HTTP action methods accept a block which can be used as a simple
|
36
|
+
# handler for the request. The block will be called for both successful as well
|
37
|
+
# as unsuccessful requests.
|
38
|
+
#
|
39
|
+
# HTTP.get("/users/1") do |request|
|
40
|
+
# puts "the request has completed!"
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# This `request` object will simply be the instance of the {HTTP} class which
|
44
|
+
# wraps the native `XMLHttpRequest`. {HTTP#ok?} can be used to quickly determine
|
45
|
+
# if the request was successful.
|
46
|
+
#
|
47
|
+
# HTTP.get("/users/1") do |request|
|
48
|
+
# if request.ok?
|
49
|
+
# puts "request was success"
|
50
|
+
# else
|
51
|
+
# puts "something went wrong with request"
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# The {HTTP} instance will always be the only object passed to the block.
|
56
|
+
#
|
57
|
+
# ## Using a Promise
|
58
|
+
#
|
59
|
+
# If no block is given to one of the action methods, then a {Promise} is
|
60
|
+
# returned instead. See the standard library for more information on Promises.
|
61
|
+
#
|
62
|
+
# HTTP.get("/users/1").then do |req|
|
63
|
+
# puts "response ok!"
|
64
|
+
# end.fail do |req|
|
65
|
+
# puts "response was not ok"
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# When using a {Promise}, both success and failure handlers will be passed the
|
69
|
+
# {HTTP} instance.
|
70
|
+
#
|
71
|
+
# # Accessing Response Data
|
72
|
+
#
|
73
|
+
# All data returned from an HTTP request can be accessed via the {HTTP} object
|
74
|
+
# passed into the block or promise handlers.
|
75
|
+
#
|
76
|
+
# - {#ok?} - returns `true` or `false`, if request was a success (or not).
|
77
|
+
# - {#body} - returns the raw text response of the request
|
78
|
+
# - {#status_code} - returns the raw {HTTP} status code as integer
|
79
|
+
# - {#json} - tries to convert the body response into a JSON object
|
80
|
+
class HTTP
|
81
|
+
`var $ = #{JQUERY_SELECTOR.to_n}` # cache $ for SPEED
|
82
|
+
|
83
|
+
# All valid {HTTP} action methods this class accepts.
|
84
|
+
#
|
85
|
+
# @see HTTP.get
|
86
|
+
# @see HTTP.post
|
87
|
+
# @see HTTP.put
|
88
|
+
# @see HTTP.delete
|
89
|
+
# @see HTTP.patch
|
90
|
+
# @see HTTP.head
|
91
|
+
ACTIONS = %w[get post put delete patch head]
|
92
|
+
|
93
|
+
# @!method self.get(url, options = {}, &block)
|
94
|
+
#
|
95
|
+
# Create a {HTTP} `get` request.
|
96
|
+
#
|
97
|
+
# @example
|
98
|
+
# HTTP.get("/foo") do |req|
|
99
|
+
# puts "got data: #{req.data}"
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# @param url [String] url for request
|
103
|
+
# @param options [Hash] any request options
|
104
|
+
# @yield [self] optional block to handle response
|
105
|
+
# @return [Promise, nil] optionally returns a promise
|
106
|
+
|
107
|
+
# @!method self.post(url, options = {}, &block)
|
108
|
+
#
|
109
|
+
# Create a {HTTP} `post` request. Post data can be supplied using the
|
110
|
+
# `payload` options. Usually this will be a hash which will get serialized
|
111
|
+
# into a native javascript object.
|
112
|
+
#
|
113
|
+
# @example
|
114
|
+
# HTTP.post("/bar", payload: data) do |req|
|
115
|
+
# puts "got response"
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# @param url [String] url for request
|
119
|
+
# @param options [Hash] optional request options
|
120
|
+
# @yield [self] optional block to yield for response
|
121
|
+
# @return [Promise, nil] returns a {Promise} unless block given
|
122
|
+
|
123
|
+
# @!method self.put(url, options = {}, &block)
|
124
|
+
|
125
|
+
# @!method self.delete(url, options = {}, &block)
|
126
|
+
|
127
|
+
# @!method self.patch(url, options = {}, &block)
|
128
|
+
|
129
|
+
# @!method self.head(url, options = {}, &block)
|
130
|
+
|
131
|
+
ACTIONS.each do |action|
|
132
|
+
define_singleton_method(action) do |url, options = {}, &block|
|
133
|
+
new.send(action, url, options, block)
|
134
|
+
end
|
135
|
+
|
136
|
+
define_method(action) do |url, options = {}, &block|
|
137
|
+
send(action, url, options, block)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.setup
|
142
|
+
Hash.new(`$.ajaxSetup()`)
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.setup= settings
|
146
|
+
`$.ajaxSetup(#{settings.to_n})`
|
147
|
+
end
|
148
|
+
|
149
|
+
attr_reader :body, :error_message, :method, :status_code, :url, :xhr
|
150
|
+
|
151
|
+
def initialize
|
152
|
+
@settings = {}
|
153
|
+
@ok = true
|
154
|
+
end
|
155
|
+
|
156
|
+
def send(method, url, options, block)
|
157
|
+
@method = method
|
158
|
+
@url = url
|
159
|
+
@payload = options.delete :payload
|
160
|
+
@handler = block
|
161
|
+
|
162
|
+
@settings.update options
|
163
|
+
|
164
|
+
settings, payload = @settings.to_n, @payload
|
165
|
+
|
166
|
+
%x{
|
167
|
+
if (typeof(#{payload}) === 'string') {
|
168
|
+
#{settings}.data = payload;
|
169
|
+
}
|
170
|
+
else if (payload != nil) {
|
171
|
+
settings.data = payload.$to_json();
|
172
|
+
settings.contentType = 'application/json';
|
173
|
+
}
|
174
|
+
|
175
|
+
settings.url = #@url;
|
176
|
+
settings.type = #{@method.upcase};
|
177
|
+
|
178
|
+
settings.success = function(data, status, xhr) {
|
179
|
+
return #{ succeed `data`, `status`, `xhr` };
|
180
|
+
};
|
181
|
+
|
182
|
+
settings.error = function(xhr, status, error) {
|
183
|
+
return #{ fail `xhr`, `status`, `error` };
|
184
|
+
};
|
185
|
+
|
186
|
+
$.ajax(settings);
|
187
|
+
}
|
188
|
+
|
189
|
+
@handler ? self : promise
|
190
|
+
end
|
191
|
+
|
192
|
+
# Parses the http response body through json. If the response is not
|
193
|
+
# valid JSON then an error will very likely be thrown.
|
194
|
+
#
|
195
|
+
# @example Getting JSON content
|
196
|
+
# HTTP.get("api.json") do |response|
|
197
|
+
# puts response.json
|
198
|
+
# end
|
199
|
+
#
|
200
|
+
# # => {"key" => 1, "bar" => 2, ... }
|
201
|
+
#
|
202
|
+
# @return [Hash, Array] returns the parsed json
|
203
|
+
def json
|
204
|
+
@json ||= JSON.parse(@body)
|
205
|
+
end
|
206
|
+
|
207
|
+
# Returns true if the request succeeded, false otherwise.
|
208
|
+
#
|
209
|
+
# @example
|
210
|
+
# HTTP.get("/some/url") do |response|
|
211
|
+
# if response.ok?
|
212
|
+
# alert "Yay!"
|
213
|
+
# else
|
214
|
+
# alert "Aww :("
|
215
|
+
# end
|
216
|
+
#
|
217
|
+
# @return [true, false] true if request was successful
|
218
|
+
def ok?
|
219
|
+
@ok
|
220
|
+
end
|
221
|
+
|
222
|
+
# Returns the value of the specified response header.
|
223
|
+
#
|
224
|
+
# @param key [String] name of the header to get
|
225
|
+
# @return [String] value of the header
|
226
|
+
def get_header(key)
|
227
|
+
`#@xhr.getResponseHeader(#{key});`
|
228
|
+
end
|
229
|
+
|
230
|
+
private
|
231
|
+
|
232
|
+
def promise
|
233
|
+
return @promise if @promise
|
234
|
+
|
235
|
+
@promise = Promise.new.tap { |promise|
|
236
|
+
@handler = proc { |res|
|
237
|
+
if res.ok?
|
238
|
+
promise.resolve res
|
239
|
+
else
|
240
|
+
promise.reject res
|
241
|
+
end
|
242
|
+
}
|
243
|
+
}
|
244
|
+
end
|
245
|
+
|
246
|
+
def succeed(data, status, xhr)
|
247
|
+
%x{
|
248
|
+
#@body = data;
|
249
|
+
#@xhr = xhr;
|
250
|
+
#@status_code = xhr.status;
|
251
|
+
|
252
|
+
if (typeof(data) === 'object') {
|
253
|
+
#@json = #{ JSON.from_object `data` };
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
@handler.call self if @handler
|
258
|
+
end
|
259
|
+
|
260
|
+
def fail(xhr, status, error)
|
261
|
+
%x{
|
262
|
+
#@body = xhr.responseText;
|
263
|
+
#@xhr = xhr;
|
264
|
+
#@status_code = xhr.status;
|
265
|
+
}
|
266
|
+
|
267
|
+
@ok = false
|
268
|
+
@handler.call self if @handler
|
269
|
+
end
|
270
|
+
end
|