opal-browser 0.1.0.beta1
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 +7 -0
- data/.gitignore +5 -0
- data/.yardopts +1 -0
- data/Gemfile +11 -0
- data/README.md +106 -0
- data/Rakefile +5 -0
- data/config.ru +63 -0
- data/lib/opal/browser.rb +4 -0
- data/opal-browser.gemspec +23 -0
- data/opal/browser.rb +10 -0
- data/opal/browser/animation_frame.rb +29 -0
- data/opal/browser/canvas.rb +277 -0
- data/opal/browser/canvas/data.rb +73 -0
- data/opal/browser/canvas/gradient.rb +37 -0
- data/opal/browser/canvas/style.rb +123 -0
- data/opal/browser/canvas/text.rb +55 -0
- data/opal/browser/compatibility.rb +59 -0
- data/opal/browser/compatibility/animation_frame.rb +93 -0
- data/opal/browser/compatibility/dom/document/window.rb +15 -0
- data/opal/browser/compatibility/dom/element/css.rb +15 -0
- data/opal/browser/compatibility/dom/element/matches.rb +31 -0
- data/opal/browser/compatibility/dom/element/offset.rb +20 -0
- data/opal/browser/compatibility/dom/element/scroll.rb +25 -0
- data/opal/browser/compatibility/dom/element/style.rb +15 -0
- data/opal/browser/compatibility/dom/mutation_observer.rb +47 -0
- data/opal/browser/compatibility/http/request.rb +15 -0
- data/opal/browser/compatibility/immediate.rb +107 -0
- data/opal/browser/compatibility/window/scroll.rb +27 -0
- data/opal/browser/compatibility/window/size.rb +13 -0
- data/opal/browser/compatibility/window/view.rb +13 -0
- data/opal/browser/console.rb +137 -0
- data/opal/browser/cookies.rb +79 -0
- data/opal/browser/css.rb +24 -0
- data/opal/browser/css/declaration.rb +88 -0
- data/opal/browser/css/rule.rb +48 -0
- data/opal/browser/css/rule/style.rb +16 -0
- data/opal/browser/css/style_sheet.rb +83 -0
- data/opal/browser/css/unit.rb +188 -0
- data/opal/browser/dom.rb +95 -0
- data/opal/browser/dom/attribute.rb +19 -0
- data/opal/browser/dom/builder.rb +97 -0
- data/opal/browser/dom/cdata.rb +9 -0
- data/opal/browser/dom/character_data.rb +37 -0
- data/opal/browser/dom/comment.rb +9 -0
- data/opal/browser/dom/compatibility.rb +8 -0
- data/opal/browser/dom/document.rb +83 -0
- data/opal/browser/dom/document_fragment.rb +7 -0
- data/opal/browser/dom/element.rb +290 -0
- data/opal/browser/dom/element/input.rb +17 -0
- data/opal/browser/dom/element/offset.rb +67 -0
- data/opal/browser/dom/element/position.rb +37 -0
- data/opal/browser/dom/element/scroll.rb +49 -0
- data/opal/browser/dom/event.rb +240 -0
- data/opal/browser/dom/event/animation.rb +26 -0
- data/opal/browser/dom/event/audio_processing.rb +31 -0
- data/opal/browser/dom/event/base.rb +207 -0
- data/opal/browser/dom/event/before_unload.rb +13 -0
- data/opal/browser/dom/event/clipboard.rb +26 -0
- data/opal/browser/dom/event/close.rb +35 -0
- data/opal/browser/dom/event/composition.rb +38 -0
- data/opal/browser/dom/event/custom.rb +30 -0
- data/opal/browser/dom/event/device_light.rb +21 -0
- data/opal/browser/dom/event/device_motion.rb +38 -0
- data/opal/browser/dom/event/device_orientation.rb +36 -0
- data/opal/browser/dom/event/device_proximity.rb +31 -0
- data/opal/browser/dom/event/drag.rb +113 -0
- data/opal/browser/dom/event/focus.rb +23 -0
- data/opal/browser/dom/event/gamepad.rb +47 -0
- data/opal/browser/dom/event/hash_change.rb +26 -0
- data/opal/browser/dom/event/keyboard.rb +93 -0
- data/opal/browser/dom/event/message.rb +50 -0
- data/opal/browser/dom/event/mouse.rb +253 -0
- data/opal/browser/dom/event/page_transition.rb +21 -0
- data/opal/browser/dom/event/pop_state.rb +21 -0
- data/opal/browser/dom/event/progress.rb +31 -0
- data/opal/browser/dom/event/sensor.rb +13 -0
- data/opal/browser/dom/event/storage.rb +41 -0
- data/opal/browser/dom/event/touch.rb +69 -0
- data/opal/browser/dom/event/ui.rb +22 -0
- data/opal/browser/dom/event/wheel.rb +49 -0
- data/opal/browser/dom/mutation_observer.rb +118 -0
- data/opal/browser/dom/node.rb +317 -0
- data/opal/browser/dom/node_set.rb +88 -0
- data/opal/browser/dom/text.rb +21 -0
- data/opal/browser/effects.rb +39 -0
- data/opal/browser/event_source.rb +67 -0
- data/opal/browser/history.rb +54 -0
- data/opal/browser/http.rb +129 -0
- data/opal/browser/http/binary.rb +57 -0
- data/opal/browser/http/compatibility.rb +1 -0
- data/opal/browser/http/headers.rb +90 -0
- data/opal/browser/http/parameters.rb +8 -0
- data/opal/browser/http/request.rb +331 -0
- data/opal/browser/http/response.rb +115 -0
- data/opal/browser/immediate.rb +43 -0
- data/opal/browser/interval.rb +93 -0
- data/opal/browser/location.rb +77 -0
- data/opal/browser/navigator.rb +151 -0
- data/opal/browser/screen.rb +40 -0
- data/opal/browser/socket.rb +115 -0
- data/opal/browser/storage.rb +149 -0
- data/opal/browser/timeout.rb +60 -0
- data/opal/browser/utils.rb +56 -0
- data/opal/browser/version.rb +3 -0
- data/opal/browser/window.rb +113 -0
- data/opal/browser/window/compatibility.rb +3 -0
- data/opal/browser/window/scroll.rb +49 -0
- data/opal/browser/window/size.rb +35 -0
- data/opal/browser/window/view.rb +18 -0
- data/spec/dom/builder_spec.rb +69 -0
- data/spec/dom/document_spec.rb +40 -0
- data/spec/dom/element_spec.rb +46 -0
- data/spec/dom/event_spec.rb +127 -0
- data/spec/dom/mutation_observer_spec.rb +37 -0
- data/spec/dom/node_spec.rb +154 -0
- data/spec/dom_spec.rb +13 -0
- data/spec/event_source_spec.rb +42 -0
- data/spec/history_spec.rb +48 -0
- data/spec/http_spec.rb +87 -0
- data/spec/immediate_spec.rb +12 -0
- data/spec/json2.js +486 -0
- data/spec/sizzle.js +5 -0
- data/spec/socket_spec.rb +43 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/storage_spec.rb +26 -0
- data/spec/window_spec.rb +10 -0
- metadata +240 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'browser/compatibility/http/request'
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module Browser; module HTTP
|
|
2
|
+
|
|
3
|
+
# Represents a single HTTP header.
|
|
4
|
+
Header = Struct.new(:name, :value)
|
|
5
|
+
|
|
6
|
+
# Represents HTTP headers.
|
|
7
|
+
class Headers
|
|
8
|
+
# Parse HTTP headers from a string.
|
|
9
|
+
#
|
|
10
|
+
# @param string [String] the whole HTTP headers response
|
|
11
|
+
# @return [Headers] the parsed headers
|
|
12
|
+
def self.parse(string)
|
|
13
|
+
self[string.lines.map { |l| l.chomp.split(/\s*:\s*/) }]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Create {Headers} from a hash.
|
|
17
|
+
def self.[](hash)
|
|
18
|
+
result = new
|
|
19
|
+
|
|
20
|
+
hash.each {|name, value|
|
|
21
|
+
result[name] = value
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
result
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
include Enumerable
|
|
28
|
+
|
|
29
|
+
# Create an empty {Headers}.
|
|
30
|
+
def initialize
|
|
31
|
+
@hash = Hash.new
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Iterate over the headers.
|
|
35
|
+
#
|
|
36
|
+
# @yield [name, value] the header name and value
|
|
37
|
+
# @return [self]
|
|
38
|
+
def each(&block)
|
|
39
|
+
return enum_for :each unless block
|
|
40
|
+
|
|
41
|
+
@hash.each {|_, header|
|
|
42
|
+
block.call [header.name, header.value]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
self
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Get the value of a header.
|
|
49
|
+
def [](name)
|
|
50
|
+
@hash[name.downcase]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def []=(name, value)
|
|
54
|
+
header = Header.new(name, value)
|
|
55
|
+
|
|
56
|
+
@hash[name.downcase] = header
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Push a header.
|
|
60
|
+
#
|
|
61
|
+
# @param header [Header] the header to push
|
|
62
|
+
# @return [self]
|
|
63
|
+
def <<(header)
|
|
64
|
+
@hash[header.name.downcase] = header
|
|
65
|
+
|
|
66
|
+
self
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
alias push <<
|
|
70
|
+
|
|
71
|
+
# Merge in place other headers.
|
|
72
|
+
#
|
|
73
|
+
# @param other [Headers, Hash, #each] the headers to merge
|
|
74
|
+
# @return [self]
|
|
75
|
+
def merge!(other)
|
|
76
|
+
other.each {|name, value|
|
|
77
|
+
self[name] = value
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
self
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# @!attribute [r] length
|
|
84
|
+
# @return [Integer] the number of headers
|
|
85
|
+
def length
|
|
86
|
+
@hash.length
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end; end
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
module Browser; module HTTP
|
|
2
|
+
|
|
3
|
+
class Request
|
|
4
|
+
include Native
|
|
5
|
+
|
|
6
|
+
# Open and send a request.
|
|
7
|
+
#
|
|
8
|
+
# @param method [Symbol] the HTTP method to use
|
|
9
|
+
# @param url [String, #to_s] the URL to request
|
|
10
|
+
# @param parameters [String, Hash] the parameters to send
|
|
11
|
+
#
|
|
12
|
+
def self.open(method, url, parameters = nil, &block)
|
|
13
|
+
request = new(&block)
|
|
14
|
+
request.open(method, url)
|
|
15
|
+
request.send(*parameters)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
DEFAULT_HEADERS = {
|
|
19
|
+
'X-Requested-With' => 'XMLHttpRequest',
|
|
20
|
+
'X-Opal-Version' => RUBY_ENGINE_VERSION,
|
|
21
|
+
'Accept' => 'text/javascript, text/html, application/xml, text/xml, */*'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
# @!attribute [r] headers
|
|
25
|
+
# @return [Headers] the request headers
|
|
26
|
+
attr_reader :headers
|
|
27
|
+
|
|
28
|
+
# @!attribute [r] response
|
|
29
|
+
# @return [Response] the response associated with this request
|
|
30
|
+
attr_reader :response
|
|
31
|
+
|
|
32
|
+
# @!attribute [r] method
|
|
33
|
+
# @return [Symbol] the HTTP method for this request
|
|
34
|
+
attr_reader :method
|
|
35
|
+
|
|
36
|
+
# @!attribute [r] url
|
|
37
|
+
# @return [String, #to_s] the URL for this request
|
|
38
|
+
attr_reader :url
|
|
39
|
+
|
|
40
|
+
# Create a request with the optionally given configuration block.
|
|
41
|
+
#
|
|
42
|
+
# @yield [request] if the block has a parameter the request is passed
|
|
43
|
+
# otherwise it's instance_exec'd
|
|
44
|
+
def initialize(&block)
|
|
45
|
+
super(transport)
|
|
46
|
+
|
|
47
|
+
@headers = Headers[DEFAULT_HEADERS]
|
|
48
|
+
@method = :get
|
|
49
|
+
@asynchronous = true
|
|
50
|
+
@binary = false
|
|
51
|
+
@cacheable = true
|
|
52
|
+
@opened = false
|
|
53
|
+
@sent = false
|
|
54
|
+
@completed = false
|
|
55
|
+
@callbacks = Hash.new { |h, k| h[k] = [] }
|
|
56
|
+
|
|
57
|
+
if block.arity == 0
|
|
58
|
+
instance_exec(&block)
|
|
59
|
+
else
|
|
60
|
+
block.call(self)
|
|
61
|
+
end if block
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def transport
|
|
65
|
+
`new XMLHttpRequest()`
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Check if the request has been opened.
|
|
69
|
+
def opened?
|
|
70
|
+
@opened
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Check if the request has been sent.
|
|
74
|
+
def sent?
|
|
75
|
+
@sent
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Check if the request has completed.
|
|
79
|
+
def completed?
|
|
80
|
+
@completed
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Check the request is asynchronous.
|
|
84
|
+
def asynchronous?
|
|
85
|
+
@asynchronous
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Check the request is synchronous.
|
|
89
|
+
def synchronous?
|
|
90
|
+
!@asynchronous
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Make the request asynchronous.
|
|
94
|
+
#
|
|
95
|
+
# @return [self]
|
|
96
|
+
def asynchronous!
|
|
97
|
+
@asynchronous = true
|
|
98
|
+
|
|
99
|
+
self
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Make the request synchronous.
|
|
103
|
+
#
|
|
104
|
+
# @return [self]
|
|
105
|
+
def synchronous!
|
|
106
|
+
@asynchronous = false
|
|
107
|
+
|
|
108
|
+
self
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Check the request is binary.
|
|
112
|
+
def binary?
|
|
113
|
+
@binary
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Make the request binary.
|
|
117
|
+
def binary!
|
|
118
|
+
@binary = true
|
|
119
|
+
|
|
120
|
+
self
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Check if the request is cacheable.
|
|
124
|
+
def cacheable?
|
|
125
|
+
@cacheable
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Disable caching for this request.
|
|
129
|
+
#
|
|
130
|
+
# @return [self]
|
|
131
|
+
def no_cache!
|
|
132
|
+
@cacheable = false
|
|
133
|
+
|
|
134
|
+
self
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Get or set the user used for authentication.
|
|
138
|
+
#
|
|
139
|
+
# @param value [String] when passed it sets, when omitted it gets
|
|
140
|
+
#
|
|
141
|
+
# @return [String]
|
|
142
|
+
def user(value = nil)
|
|
143
|
+
value ? @user = value : @user
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Get or set the password used for authentication.
|
|
147
|
+
#
|
|
148
|
+
# @param value [String] when passed it sets, when omitted it gets
|
|
149
|
+
#
|
|
150
|
+
# @return [String]
|
|
151
|
+
def password(value = nil)
|
|
152
|
+
value ? @password = value : @password
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Get or set the MIME type of the request.
|
|
156
|
+
#
|
|
157
|
+
# @param value [String] when passed it sets, when omitted it gets
|
|
158
|
+
#
|
|
159
|
+
# @return [String]
|
|
160
|
+
def mime_type(value = nil)
|
|
161
|
+
value ? @mime_type = value : @mime_type
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Get or set the Content-Type of the request.
|
|
165
|
+
#
|
|
166
|
+
# @param value [String] when passed it sets, when omitted it gets
|
|
167
|
+
#
|
|
168
|
+
# @return [String]
|
|
169
|
+
def content_type(value = nil)
|
|
170
|
+
value ? @content_type = value : @content_type
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Get or set the encoding of the request.
|
|
174
|
+
#
|
|
175
|
+
# @param value [String] when passed it sets, when omitted it gets
|
|
176
|
+
#
|
|
177
|
+
# @return [String]
|
|
178
|
+
def encoding(value = nil)
|
|
179
|
+
value ? @encoding = value : @encoding
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Set the request parameters.
|
|
183
|
+
#
|
|
184
|
+
# @param hash [Hash] the parameters
|
|
185
|
+
#
|
|
186
|
+
# @return [self]
|
|
187
|
+
def parameters(hash)
|
|
188
|
+
@parameters = hash
|
|
189
|
+
|
|
190
|
+
self
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Register an event on the request.
|
|
194
|
+
#
|
|
195
|
+
# @param what [Symbol, String] the event name
|
|
196
|
+
# @yield [response] yields the {Response}
|
|
197
|
+
#
|
|
198
|
+
# @return [self]
|
|
199
|
+
def on(what, &block)
|
|
200
|
+
@callbacks[what] << block
|
|
201
|
+
|
|
202
|
+
self
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Open the request.
|
|
206
|
+
#
|
|
207
|
+
# @param method [Symbol] the HTTP method to use
|
|
208
|
+
# @param url [String, #to_s] the URL to send the request to
|
|
209
|
+
# @param asynchronous [Boolean] whether the request is asynchronous or not
|
|
210
|
+
# @param user [String] the user to use for authentication
|
|
211
|
+
# @param password [String] the password to use for authentication
|
|
212
|
+
#
|
|
213
|
+
# @return [self]
|
|
214
|
+
def open(method = nil, url = nil, asynchronous = nil, user = nil, password = nil)
|
|
215
|
+
raise 'the request has already been opened' if opened?
|
|
216
|
+
|
|
217
|
+
@method = method unless method.nil?
|
|
218
|
+
@url = url unless url.nil?
|
|
219
|
+
@asynchronous = asynchronous unless asynchronous.nil?
|
|
220
|
+
@user = user unless user.nil?
|
|
221
|
+
@password = password unless password.nil?
|
|
222
|
+
|
|
223
|
+
url = @url
|
|
224
|
+
|
|
225
|
+
unless cacheable?
|
|
226
|
+
url += (url.include?(??) ? ?& : ??) + "_=#{rand}"
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
`#@native.open(#{@method.to_s.upcase}, #{url.to_s}, #{@asynchronous}, #{@user.to_n}, #{@password.to_n})`
|
|
230
|
+
|
|
231
|
+
unless @callbacks.empty?
|
|
232
|
+
`#@native.onreadystatechange = #{callback}`
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
@opened = true
|
|
236
|
+
|
|
237
|
+
self
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Send the request with optional parameters.
|
|
241
|
+
#
|
|
242
|
+
# @param parameters [String, Hash] the data to send
|
|
243
|
+
#
|
|
244
|
+
# @return [Response] the response
|
|
245
|
+
def send(parameters = @parameters)
|
|
246
|
+
raise 'the request has not been opened' unless opened?
|
|
247
|
+
|
|
248
|
+
raise 'the request has already been sent' if sent?
|
|
249
|
+
|
|
250
|
+
unless cacheable?
|
|
251
|
+
`#@native.setRequestHeader("If-Modified-Since", "Tue, 11 Sep 2001 12:46:00 GMT")`
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
@headers.each {|name, value|
|
|
255
|
+
`#@native.setRequestHeader(#{name.to_s}, #{value.to_s})`
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if @content_type
|
|
259
|
+
header = @content_type
|
|
260
|
+
header += "; charset=#{@encoding}" if @encoding
|
|
261
|
+
|
|
262
|
+
`#@native.setRequestHeader('Content-Type', header)`
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
if binary?
|
|
266
|
+
if Buffer.supported?
|
|
267
|
+
`#@native.responseType = 'arraybuffer'`
|
|
268
|
+
else
|
|
269
|
+
`#@native.overrideMimeType('text/plain; charset=x-user-defined')`
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
if mime_type && !binary?
|
|
274
|
+
`#@native.overrideMimeType(#@mime_type)`
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
@sent = true
|
|
278
|
+
@response = Response.new(self)
|
|
279
|
+
|
|
280
|
+
if String === parameters
|
|
281
|
+
data = parameters
|
|
282
|
+
elsif Hash === parameters
|
|
283
|
+
data = parameters.map {|vals|
|
|
284
|
+
vals.map(&:encode_uri_component).join(?=)
|
|
285
|
+
}.join(?&)
|
|
286
|
+
|
|
287
|
+
unless @content_type
|
|
288
|
+
`#@native.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')`
|
|
289
|
+
end
|
|
290
|
+
else
|
|
291
|
+
data = `null`
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
`#@native.send(#{data})`
|
|
295
|
+
|
|
296
|
+
@response
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# Abort the request.
|
|
300
|
+
#
|
|
301
|
+
# @return [self]
|
|
302
|
+
def abort
|
|
303
|
+
`#@native.abort()`
|
|
304
|
+
|
|
305
|
+
self
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
private
|
|
309
|
+
def callback
|
|
310
|
+
proc {|event|
|
|
311
|
+
state = %w[uninitialized loading loaded interactive complete][`#@native.readyState`]
|
|
312
|
+
res = response
|
|
313
|
+
|
|
314
|
+
@callbacks[state].each { |b| b.(res) }
|
|
315
|
+
|
|
316
|
+
if state == :complete
|
|
317
|
+
@completed = true
|
|
318
|
+
|
|
319
|
+
@callbacks[res.status.code].each { |b| b.(res) }
|
|
320
|
+
|
|
321
|
+
if res.success?
|
|
322
|
+
@callbacks[:success].each { |b| b.(res) }
|
|
323
|
+
else
|
|
324
|
+
@callbacks[:failure].each { |b| b.(res) }
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
}.to_n
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
end; end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
module Browser; module HTTP
|
|
4
|
+
|
|
5
|
+
# Represents an HTTP response.
|
|
6
|
+
class Response
|
|
7
|
+
include Native
|
|
8
|
+
|
|
9
|
+
Status = Struct.new(:code, :text)
|
|
10
|
+
|
|
11
|
+
# @!attribute [r] request
|
|
12
|
+
# @return [Request] the request to this response
|
|
13
|
+
attr_reader :request
|
|
14
|
+
|
|
15
|
+
# Create a response from a request.
|
|
16
|
+
#
|
|
17
|
+
# @param request [Request] the request
|
|
18
|
+
def initialize(request)
|
|
19
|
+
super(request.to_n)
|
|
20
|
+
|
|
21
|
+
@request = request
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @!attribute [r] headers
|
|
25
|
+
# @return [Headers] the response headers
|
|
26
|
+
def headers
|
|
27
|
+
@headers ||= Headers.parse(`#@native.getAllResponseHeaders()`)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @!attribute [r] status
|
|
31
|
+
# @return [Status] the response status
|
|
32
|
+
def status
|
|
33
|
+
Status.new(`#@native.status || nil`, `#@native.statusText || nil`)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Checks if the response was successful
|
|
37
|
+
def success?
|
|
38
|
+
if code = status.code
|
|
39
|
+
code >= 200 && code < 300 || code == 304
|
|
40
|
+
else
|
|
41
|
+
false
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Check if the response failed
|
|
46
|
+
def failure?
|
|
47
|
+
!success?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @!attribute [r] text
|
|
51
|
+
# @return [String] the response body as text
|
|
52
|
+
def text
|
|
53
|
+
%x{
|
|
54
|
+
var result = #@native.responseText;
|
|
55
|
+
|
|
56
|
+
if (!result) {
|
|
57
|
+
return nil;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @!attribute [r] json
|
|
65
|
+
# @return [Hash, Array] the response body as JSON
|
|
66
|
+
def json
|
|
67
|
+
%x{
|
|
68
|
+
var result = #@native.responseText;
|
|
69
|
+
|
|
70
|
+
if (!result) {
|
|
71
|
+
return nil;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return #{JSON.parse(`result`)};
|
|
75
|
+
}
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @!attribute [r] xml
|
|
79
|
+
# @return [DOM::Document] the response body as DOM document
|
|
80
|
+
def xml
|
|
81
|
+
%x{
|
|
82
|
+
var result = #@native.responseXML;
|
|
83
|
+
|
|
84
|
+
if (!result) {
|
|
85
|
+
return nil;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
DOM(`result`)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @!attribute [r] binary
|
|
93
|
+
# @return [Binary] the response body as binary
|
|
94
|
+
def binary
|
|
95
|
+
return unless request.binary?
|
|
96
|
+
|
|
97
|
+
if Buffer.supported?
|
|
98
|
+
%x{
|
|
99
|
+
var result = #@native.response;
|
|
100
|
+
|
|
101
|
+
if (!result) {
|
|
102
|
+
return nil;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Binary.new(Buffer.new(`result`))
|
|
107
|
+
else
|
|
108
|
+
return unless text
|
|
109
|
+
|
|
110
|
+
Binary.new(text)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end; end
|