stdweb/webapi/xml_http_request.rs
1use webapi::event_target::{IEventTarget, EventTarget};
2use webapi::dom_exception::{InvalidAccessError, InvalidStateError};
3use webcore::unsafe_typed_array::UnsafeTypedArray;
4use webcore::value::{
5 Reference,
6 Value,
7};
8use webcore::try_from::{TryFrom, TryInto};
9use private::TODO;
10
11/// Use XmlHttpRequest (XHR) objects to interact with servers.
12/// You can retrieve data from a URL without having to do a full page refresh.
13/// This enables a Web page to update just part of a page without disrupting
14/// what the user is doing. XmlHttpRequest is used heavily in Ajax programming.
15///
16/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XmlHttpRequest)
17// https://xhr.spec.whatwg.org/#xmlhttprequest
18#[derive(Clone, Debug, PartialEq, Eq, ReferenceType)]
19#[reference(instance_of = "XMLHttpRequest")]
20#[reference(subclass_of(EventTarget))]
21pub struct XmlHttpRequest( Reference );
22
23/// An enum indicating the state of the `XmlHttpRequest`.
24///
25/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState)
26// https://xhr.spec.whatwg.org/#dom-xmlhttprequest-readystate
27#[derive(Copy, Clone, PartialEq, Eq, Debug)]
28pub enum XhrReadyState {
29 /// Client has been created. [open()](struct.XmlHttpRequest.html#method.open) not called yet.
30 Unsent,
31 /// [open()](struct.XmlHttpRequest.html#method.open) has been called.
32 Opened,
33 /// [send()](struct.XmlHttpRequest.html#method.send) has been called, and headers and [status()](struct.XmlHttpRequest.html#method.status) are available.
34 HeadersReceived,
35 /// Downloading; [reponse_text()](struct.XmlHttpRequest.html#method.reponse_text) holds partial data.
36 Loading,
37 /// The operation is complete.
38 Done,
39}
40
41/// An enum describing the type of the response to `XmlHttpRequest`
42///
43/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType)
44// https://xhr.spec.whatwg.org/#dom-xmlhttprequest-responsetype
45#[derive(Copy, Clone, PartialEq, Eq, Debug)]
46pub enum XhrResponseType {
47 /// A JavaScript ArrayBuffer containing binary data
48 ArrayBuffer,
49 /// A Blob object container the binary data
50 Blob,
51 /// An HTML Document or XML XMLDocument
52 Document,
53 /// A JavaScript object parsed from JSON
54 Json,
55 /// Text in a String object
56 Text
57}
58
59impl IEventTarget for XmlHttpRequest {}
60
61error_enum_boilerplate! {
62 /// An error returned from `XmlHttpRequest::set_response_type`
63 XhrSetResponseTypeError,
64
65 #[allow(missing_docs)]
66 InvalidStateError,
67 #[allow(missing_docs)]
68 InvalidAccessError
69}
70
71impl XmlHttpRequest {
72 /// Creates new `XmlHttpRequest`.
73 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest
74 pub fn new() -> XmlHttpRequest {
75 js!( return new XMLHttpRequest(); ).try_into().unwrap()
76 }
77
78 /// Returns the current state of the request as a [XhrReadyState](enum.XhrReadyState.html).
79 ///
80 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState)
81 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-readystate
82 pub fn ready_state(&self) -> XhrReadyState {
83 use self::XhrReadyState::*;
84 let state: u16 = js!( return @{self}.readyState; ).try_into().unwrap();
85 match state {
86 0 => Unsent,
87 1 => Opened,
88 2 => HeadersReceived,
89 3 => Loading,
90 4 => Done,
91 _ => unreachable!( "Unexpected value of XMLHttpRequest::readyState: {}", state )
92 }
93 }
94
95 /// Returns the type of the request as a [XhrResponseType](enum.XhrResponseType.html)
96 ///
97 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType)
98 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-responsetype
99 pub fn response_type(&self) -> XhrResponseType {
100 use self::XhrResponseType::*;
101 let repsonse_type: String = js! ( return @{self}.responseType; ).try_into().unwrap();
102 match repsonse_type.as_str() {
103 "arraybuffer" => ArrayBuffer,
104 "blob" => Blob,
105 "document" => Document,
106 "json" => Json,
107 "text" | "" => Text,
108 x => unreachable!( "Unexpected value of XMLHttpRequest::responseType:: {}", x)
109 }
110 }
111
112 /// Set the type that the XmlHttpRequest should return
113 ///
114 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType)
115 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-responsetype
116 pub fn set_response_type(&self, kind: XhrResponseType) -> Result<(), XhrSetResponseTypeError> {
117 use self::XhrResponseType::*;
118 let response_type = match kind {
119 ArrayBuffer => "arraybuffer",
120 Blob => "blob",
121 Document => "document",
122 Json => "json",
123 Text => "text"
124 };
125
126 js_try!(
127 @{self}.responseType = @{response_type};
128 ).unwrap()
129 }
130
131 /// Returns a string that contains the response to the request as text, or None
132 /// if the request was unsuccessful or has not yet been sent.
133 ///
134 ///[(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText)
135 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-responsetext
136 pub fn response_text(&self) -> Result< Option< String >, TODO > {
137 let response = js!(return @{self}.responseText;);
138 match response {
139 Value::Null => Ok( None ),
140 Value::String( resp ) => Ok( Some( resp ) ),
141 _ => unreachable!(),
142 }
143 }
144
145 /// Returns the object representing the response
146 ///
147 ///[(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response)
148 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-response
149 pub fn raw_response(&self) -> Value {
150 js!(return @{self}.response;)
151 }
152
153 /// Returns an unsigned short with the status of the response of the request.
154 ///
155 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/status)
156 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-status
157 pub fn status(&self) -> u16 {
158 js!(return @{self}.status;).try_into().unwrap()
159 }
160
161 /// Open connection with given method (ie GET or POST), and the url to hit.
162 ///
163 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open)
164 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-open
165 pub fn open(&self, method: &str, url: &str) -> Result< (), TODO > {
166 js! { @(no_return)
167 @{self}.open(@{method}, @{url}, true);
168 };
169
170 Ok(())
171 }
172
173 /// Returns the string containing the text of the specified header. If there
174 /// are multiple response headers with the same name, then their values are
175 /// returned as a single concatenated string.
176 ///
177 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/getResponseHeader)
178 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-getresponseheader
179 pub fn get_response_header(&self, header: &str) -> Option<String> {
180 let header = js!( return @{self}.getResponseHeader(@{header}); );
181 match header {
182 Value::Null => None,
183 Value::String(text) => Some(text),
184 _ => unreachable!(),
185 }
186 }
187
188 /// Sets the value of an HTTP request header. Must be called after `open()`,
189 /// but before `send()`. If this method is called several times with the same
190 /// header, the values are merged into one single request header.
191 ///
192 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader)
193 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-setrequestheader
194 pub fn set_request_header(&self, header: &str, value: &str) -> Result< (), TODO > {
195 js! { @(no_return)
196 @{self}.setRequestHeader(@{header}, @{value});
197 };
198
199 Ok(())
200 }
201
202 /// Send request on an open connection with no data
203 ///
204 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send)
205 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-send
206 pub fn send(&self) -> Result< (), TODO > {
207 js! { @(no_return)
208 @{self}.send();
209 };
210
211 Ok(())
212 }
213
214 /// Send request on an open connection with string body
215 ///
216 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send)
217 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-send
218 pub fn send_with_string(&self, body: &str) -> Result< (), TODO > {
219 js! { @(no_return)
220 @{self}.send(@{body});
221 };
222
223 Ok(())
224 }
225
226 /// Send request on an open connection with a byte array body
227 ///
228 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send)
229 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-send
230 pub fn send_with_bytes(&self, body: &[u8]) -> Result< (), TODO > {
231 js! { @(no_return)
232 @{self}.send(@{UnsafeTypedArray(body)});
233 };
234
235 Ok(())
236 }
237
238 /// Aborts the request if it has already been sent.
239 /// When a request is aborted, its [ready_state](struct.XmlHttpRequest.html#method.ready_state) is changed to [Done](enum.XhrReadyState.html#variant.Done)
240 /// and the [status](struct.XmlHttpRequest.html#method.status) code is set to
241 /// [Unsent](enum.XhrReadyState.html#variant.Unsent).
242 ///
243 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/abort)
244 // https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest-abort
245 pub fn abort(&self) {
246 js! { @(no_return)
247 @{self}.abort();
248 };
249 }
250}