| OLD | NEW |
| 1 <import src="/mojo/public/sky/core.sky" as="core" /> | 1 <import src="/mojo/public/sky/core.sky" as="core" /> |
| 2 <import src="/mojo/public/sky/unicode.sky" as="unicode" /> | 2 <import src="/mojo/public/sky/unicode.sky" as="unicode" /> |
| 3 <import src="/mojo/services/network/public/interfaces/network_service.mojom.sky"
as="net" /> | 3 <import src="/mojo/services/network/public/interfaces/network_service.mojom.sky"
as="net" /> |
| 4 <import src="/mojo/services/network/public/interfaces/url_loader.mojom.sky" as="
loader" /> | 4 <import src="/mojo/services/network/public/interfaces/url_loader.mojom.sky" as="
loader" /> |
| 5 <import src="/sky/framework/shell.sky" as="shell" /> | 5 <import src="/sky/framework/shell.sky" as="shell" /> |
| 6 <script> | 6 <script> |
| 7 // XHR keeps itself alive. | 7 // XHR keeps itself alive. |
| 8 var outstandingRequests = new Set(); | 8 var outstandingRequests = new Set(); |
| 9 | 9 |
| 10 const kPrivate = Symbol("XMLHttpRequestPrivate"); | 10 const kPrivate = Symbol("XMLHttpRequestPrivate"); |
| 11 | 11 |
| 12 class Private { | 12 class Private { |
| 13 constructor() { | 13 constructor() { |
| 14 this.networkService = shell.connectToService( | 14 this.networkService = shell.connectToService( |
| 15 "mojo:network_service", net.NetworkService); | 15 "mojo:network_service", net.NetworkService); |
| 16 this.request = null; | 16 this.request = null; |
| 17 this.loader = null; | 17 this.loader = null; |
| 18 this.headers = new Map(); | 18 this.headers = new Map(); |
| 19 this.responseArrayBuffer = null; | 19 this.responseArrayBuffer = null; |
| 20 this.responseText = null; // Cached to avoid re-decoding each access. | 20 this.responseText = null; // Cached to avoid re-decoding each access. |
| 21 } | 21 } |
| 22 } | 22 } |
| 23 | 23 |
| 24 // Somewhat hacky, but works. | |
| 25 function stringToUTF8Buffer(string) { | |
| 26 var string = unescape(encodeURIComponent(string)); | |
| 27 var charList = string.split(''); | |
| 28 var uintArray = []; | |
| 29 for (var i = 0; i < charList.length; i++) { | |
| 30 uintArray.push(charList[i].charCodeAt(0)); | |
| 31 } | |
| 32 return new Uint8Array(uintArray); | |
| 33 } | |
| 34 | |
| 35 // https://xhr.spec.whatwg.org | 24 // https://xhr.spec.whatwg.org |
| 36 class XMLHttpRequest { | 25 class XMLHttpRequest { |
| 37 constructor() { | 26 constructor() { |
| 38 this[kPrivate] = new Private; | 27 this[kPrivate] = new Private; |
| 39 this.responseType = ''; // Only text and arraybuffer support for now. | 28 this.responseType = ''; // Only text and arraybuffer support for now. |
| 40 this.status = null; | 29 this.status = null; |
| 41 this.statusText = null; | 30 this.statusText = null; |
| 42 } | 31 } |
| 43 | 32 |
| 44 onload() { | 33 onload() { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 this[kPrivate].headers.set(header, value); | 71 this[kPrivate].headers.set(header, value); |
| 83 } | 72 } |
| 84 | 73 |
| 85 send(body) { | 74 send(body) { |
| 86 var priv = this[kPrivate]; | 75 var priv = this[kPrivate]; |
| 87 // Handle the body before the headers as it can affect Content-Type. | 76 // Handle the body before the headers as it can affect Content-Type. |
| 88 if (body) { | 77 if (body) { |
| 89 var bodyAsBufferView = null; | 78 var bodyAsBufferView = null; |
| 90 if (typeof(body) === "string") { | 79 if (typeof(body) === "string") { |
| 91 this.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); | 80 this.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); |
| 92 bodyAsBufferView = stringToUTF8Buffer(body); | 81 var bodyAsBufferView = new Uint8Array(unicode.utf8Length(body)); |
| 82 unicode.encodeUtf8String(body, bodyAsBufferView); |
| 93 } else { | 83 } else { |
| 94 bodyAsBufferView = new Uint8Array(body); | 84 bodyAsBufferView = new Uint8Array(body); |
| 95 } | 85 } |
| 96 var dataPipe = new core.createDataPipe(); | 86 var dataPipe = new core.createDataPipe(); |
| 97 // FIXME: body is currently assumed to be an ArrayBuffer. | 87 // FIXME: body is currently assumed to be an ArrayBuffer. |
| 98 var writeResult = core.writeData(dataPipe.producerHandle, | 88 var writeResult = core.writeData(dataPipe.producerHandle, |
| 99 bodyAsBufferView, core.WRITE_DATA_FLAG_ALL_OR_NONE); | 89 bodyAsBufferView, core.WRITE_DATA_FLAG_ALL_OR_NONE); |
| 100 core.close(dataPipe.producerHandle); | 90 core.close(dataPipe.producerHandle); |
| 101 // FIXME: Much better error handling needed. | 91 // FIXME: Much better error handling needed. |
| 102 console.assert(writeResult.result === core.RESULT_OK); | 92 console.assert(writeResult.result === core.RESULT_OK); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 }).catch(function(error) { | 124 }).catch(function(error) { |
| 135 outstandingRequests.delete(self); | 125 outstandingRequests.delete(self); |
| 136 // Technically this should throw a ProgressEvent. | 126 // Technically this should throw a ProgressEvent. |
| 137 self.onerror(error); | 127 self.onerror(error); |
| 138 }); | 128 }); |
| 139 } | 129 } |
| 140 } | 130 } |
| 141 | 131 |
| 142 module.exports = XMLHttpRequest; | 132 module.exports = XMLHttpRequest; |
| 143 </script> | 133 </script> |
| OLD | NEW |