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.
@@ -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