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="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.responseText = ""; | 19 this.responseArrayBuffer = null; |
| 20 this.responseText = null; // Cached to avoid re-decoding each access. |
20 } | 21 } |
21 } | 22 } |
22 | 23 |
| 24 // https://xhr.spec.whatwg.org |
23 class XMLHttpRequest { | 25 class XMLHttpRequest { |
24 constructor() { | 26 constructor() { |
25 this[kPrivate] = new Private; | 27 this[kPrivate] = new Private; |
| 28 this.responseType = ''; // Only text and arraybuffer support for now. |
26 } | 29 } |
27 | 30 |
28 onload() { | 31 onload() { |
29 } | 32 } |
30 | 33 |
31 onerror(error) { | 34 onerror(error) { |
32 } | 35 } |
33 | 36 |
34 get responseText() { | 37 get responseText() { |
| 38 if (this.responseType !== '' && this.responseType !== 'text') |
| 39 throw 'Non-text responseType ' + this.responseType; |
| 40 if (this[kPrivate].responseArrayBuffer === null) |
| 41 return null; |
| 42 if (this[kPrivate].responseText === null) { |
| 43 var intArray = new Uint8Array(this[kPrivate].responseArrayBuffer); |
| 44 this[kPrivate].responseText = unicode.decodeUtf8String(intArray); |
| 45 } |
35 return this[kPrivate].responseText; | 46 return this[kPrivate].responseText; |
36 } | 47 } |
37 | 48 |
| 49 get response() { |
| 50 if (this.responseType === 'text' || this.responseType == '') |
| 51 return this.responseText; |
| 52 else if (this.responseType === 'arraybuffer') |
| 53 return this[kPrivate].responseArrayBuffer; |
| 54 throw 'Unknown responseType ' + this.responseType; |
| 55 } |
| 56 |
38 open(method, url) { | 57 open(method, url) { |
39 var request = new loader.URLRequest(); | 58 var request = new loader.URLRequest(); |
40 request.url = new URL(url, document.URL); | 59 request.url = new URL(url, document.URL); |
41 request.method = method; | 60 request.method = method; |
42 request.auto_follow_redirects = true; | 61 request.auto_follow_redirects = true; |
43 | 62 |
44 var priv = this[kPrivate]; | 63 var priv = this[kPrivate]; |
45 priv.request = request; | 64 priv.request = request; |
46 priv.headers.clear(); | 65 priv.headers.clear(); |
47 } | 66 } |
(...skipping 13 matching lines...) Expand all Loading... |
61 // FIXME: Factor this into the JS bindings. | 80 // FIXME: Factor this into the JS bindings. |
62 var pipe = new core.createMessagePipe(); | 81 var pipe = new core.createMessagePipe(); |
63 priv.networkService.createURLLoader(pipe.handle1); | 82 priv.networkService.createURLLoader(pipe.handle1); |
64 priv.loader = shell.wrapHandle(pipe.handle0, loader.URLLoader); | 83 priv.loader = shell.wrapHandle(pipe.handle0, loader.URLLoader); |
65 | 84 |
66 var self = this; | 85 var self = this; |
67 outstandingRequests.add(this); | 86 outstandingRequests.add(this); |
68 priv.loader.start(priv.request).then(function(result) { | 87 priv.loader.start(priv.request).then(function(result) { |
69 return core.drainData(result.response.body).then(function(result) { | 88 return core.drainData(result.response.body).then(function(result) { |
70 outstandingRequests.delete(self); | 89 outstandingRequests.delete(self); |
71 priv.responseText = unicode.decodeUtf8String(new Uint8Array(result.buffe
r)); | 90 priv.responseArrayBuffer = result.buffer; |
| 91 // FIXME: Catch exceptions during onload so they don't trip onerror. |
72 self.onload(); | 92 self.onload(); |
73 }); | 93 }); |
74 }).catch(function(error) { | 94 }).catch(function(error) { |
75 outstandingRequests.delete(self); | 95 outstandingRequests.delete(self); |
76 self.onerror(error); | 96 self.onerror(error); |
77 }); | 97 }); |
78 } | 98 } |
79 } | 99 } |
80 | 100 |
81 module.exports = XMLHttpRequest; | 101 module.exports = XMLHttpRequest; |
82 </script> | 102 </script> |
OLD | NEW |