diff options
-rw-r--r-- | components/script/dom/xmlhttprequest.rs | 48 | ||||
-rw-r--r-- | tests/wpt/metadata/XMLHttpRequest/response-json.htm.ini | 8 |
2 files changed, 38 insertions, 18 deletions
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 130cec9ecf1..42d1dc18ef1 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -17,7 +17,7 @@ use dom::bindings::conversions::{ToJSValConvertible}; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::{GlobalRef, GlobalRoot}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap}; +use dom::bindings::js::{JS, MutHeapJSVal, MutNullableHeap}; use dom::bindings::js::{Root, RootedReference}; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::{Reflectable, reflect_dom_object}; @@ -125,6 +125,8 @@ pub struct XMLHttpRequest { response_type: Cell<XMLHttpRequestResponseType>, response_xml: MutNullableHeap<JS<Document>>, response_blob: MutNullableHeap<JS<Blob>>, + #[ignore_heap_size_of = "Defined in rust-mozjs"] + response_json: MutHeapJSVal, #[ignore_heap_size_of = "Defined in hyper"] response_headers: DOMRefCell<Headers>, #[ignore_heap_size_of = "Defined in hyper"] @@ -165,6 +167,7 @@ impl XMLHttpRequest { response_type: Cell::new(XMLHttpRequestResponseType::_empty), response_xml: Default::default(), response_blob: Default::default(), + response_json: MutHeapJSVal::new(), response_headers: DOMRefCell::new(Headers::new()), override_mime_type: DOMRefCell::new(None), override_charset: DOMRefCell::new(None), @@ -720,15 +723,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest { } }, XMLHttpRequestResponseType::Json => { - let decoded = UTF_8.decode(&self.response.borrow(), DecoderTrap::Replace).unwrap().to_owned(); - let decoded: Vec<u16> = decoded.utf16_units().collect(); - if !JS_ParseJSON(cx, - decoded.as_ptr(), - decoded.len() as u32, - rval.handle_mut()) { - JS_ClearPendingException(cx); - return NullValue(); - } + self.json_response(cx).to_jsval(cx, rval.handle_mut()); }, XMLHttpRequestResponseType::Blob => { self.blob_response().to_jsval(cx, rval.handle_mut()); @@ -1093,6 +1088,39 @@ impl XMLHttpRequest { Some(temp_doc) } + #[allow(unsafe_code)] + // https://xhr.spec.whatwg.org/#json-response + fn json_response(&self, cx: *mut JSContext) -> JSVal { + // Step 1 + let response_json = self.response_json.get(); + if !response_json.is_null_or_undefined() { + return response_json; + } + // Step 2 + let bytes = self.response.borrow(); + // Step 3 + if bytes.len() == 0 { + return NullValue(); + } + // Step 4 + let json_text = UTF_8.decode(&bytes, DecoderTrap::Replace).unwrap().to_owned(); + let json_text: Vec<u16> = json_text.utf16_units().collect(); + // Step 5 + let mut rval = RootedValue::new(cx, UndefinedValue()); + unsafe { + if !JS_ParseJSON(cx, + json_text.as_ptr(), + json_text.len() as u32, + rval.handle_mut()) { + JS_ClearPendingException(cx); + return NullValue(); + } + } + // Step 6 + self.response_json.set(rval.ptr); + self.response_json.get() + } + fn document_text_html(&self) -> Root<Document>{ let charset = self.final_charset().unwrap_or(UTF_8); let wr = self.global(); diff --git a/tests/wpt/metadata/XMLHttpRequest/response-json.htm.ini b/tests/wpt/metadata/XMLHttpRequest/response-json.htm.ini deleted file mode 100644 index 9e2c61415ff..00000000000 --- a/tests/wpt/metadata/XMLHttpRequest/response-json.htm.ini +++ /dev/null @@ -1,8 +0,0 @@ -[response-json.htm] - type: testharness - [JSON object roundtrip] - expected: FAIL - - [JSON roundtrip with Japanese text] - expected: FAIL - |