mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This CL simplifies the sky_server to only map the build directory into /gen, which will make the deploy script simpler. This CL updates all the imports to use the /gen prefix when referring to generated files. TBR=eseidel@chromium.org Review URL: https://codereview.chromium.org/881093003
134 lines
4.4 KiB
Plaintext
134 lines
4.4 KiB
Plaintext
<import src="/gen/mojo/public/sky/core.sky" as="core" />
|
|
<import src="/gen/mojo/public/sky/unicode.sky" as="unicode" />
|
|
<import src="/gen/mojo/services/network/public/interfaces/network_service.mojom.sky" as="net" />
|
|
<import src="/gen/mojo/services/network/public/interfaces/url_loader.mojom.sky" as="loader" />
|
|
<import src="shell.sky" as="shell" />
|
|
<script>
|
|
// XHR keeps itself alive.
|
|
var outstandingRequests = new Set();
|
|
|
|
const kPrivate = Symbol("XMLHttpRequestPrivate");
|
|
|
|
class Private {
|
|
constructor() {
|
|
this.networkService = shell.connectToService(
|
|
"mojo:network_service", net.NetworkService);
|
|
this.request = null;
|
|
this.loader = null;
|
|
this.headers = new Map();
|
|
this.responseArrayBuffer = null;
|
|
this.responseText = null; // Cached to avoid re-decoding each access.
|
|
}
|
|
}
|
|
|
|
// https://xhr.spec.whatwg.org
|
|
class XMLHttpRequest {
|
|
constructor() {
|
|
this[kPrivate] = new Private;
|
|
this.responseType = ''; // Only text and arraybuffer support for now.
|
|
this.status = null;
|
|
this.statusText = null;
|
|
}
|
|
|
|
onload() {
|
|
}
|
|
|
|
onerror(error) {
|
|
}
|
|
|
|
get responseText() {
|
|
if (this.responseType !== '' && this.responseType !== 'text')
|
|
throw 'Non-text responseType ' + this.responseType;
|
|
if (this[kPrivate].responseArrayBuffer === null)
|
|
return null;
|
|
if (this[kPrivate].responseText === null) {
|
|
var intArray = new Uint8Array(this[kPrivate].responseArrayBuffer);
|
|
this[kPrivate].responseText = unicode.decodeUtf8String(intArray);
|
|
}
|
|
return this[kPrivate].responseText;
|
|
}
|
|
|
|
get response() {
|
|
if (this.responseType === 'text' || this.responseType == '')
|
|
return this.responseText;
|
|
else if (this.responseType === 'arraybuffer')
|
|
return this[kPrivate].responseArrayBuffer;
|
|
throw 'Unknown responseType ' + this.responseType;
|
|
}
|
|
|
|
open(method, url) {
|
|
var request = new loader.URLRequest();
|
|
request.url = String(new URL(url, document.URL));
|
|
request.method = method;
|
|
request.auto_follow_redirects = true;
|
|
|
|
var priv = this[kPrivate];
|
|
priv.request = request;
|
|
priv.headers.clear();
|
|
}
|
|
|
|
setRequestHeader(header, value) {
|
|
this[kPrivate].headers.set(header, value);
|
|
}
|
|
|
|
send(body) {
|
|
var priv = this[kPrivate];
|
|
// Handle the body before the headers as it can affect Content-Type.
|
|
if (body) {
|
|
var bodyAsBufferView = null;
|
|
if (typeof(body) === "string") {
|
|
this.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
|
|
var bodyAsBufferView = new Uint8Array(unicode.utf8Length(body));
|
|
unicode.encodeUtf8String(body, bodyAsBufferView);
|
|
} else {
|
|
bodyAsBufferView = new Uint8Array(body);
|
|
}
|
|
var dataPipe = new core.createDataPipe();
|
|
// FIXME: body is currently assumed to be an ArrayBuffer.
|
|
var writeResult = core.writeData(dataPipe.producerHandle,
|
|
bodyAsBufferView, core.WRITE_DATA_FLAG_ALL_OR_NONE);
|
|
core.close(dataPipe.producerHandle);
|
|
// FIXME: Much better error handling needed.
|
|
console.assert(writeResult.result === core.RESULT_OK);
|
|
console.assert(writeResult.numBytes === body.length);
|
|
// 'body' is actually an array of body segments.
|
|
priv.request.body = [dataPipe.consumerHandle];
|
|
}
|
|
|
|
var requestHeaders = [];
|
|
priv.headers.forEach(function(value, key) {
|
|
requestHeaders.push(key + ': ' + value);
|
|
});
|
|
priv.request.headers = requestHeaders;
|
|
|
|
// FIXME: Factor this into the JS bindings.
|
|
var pipe = new core.createMessagePipe();
|
|
priv.networkService.createURLLoader(pipe.handle1);
|
|
priv.loader = shell.wrapHandle(pipe.handle0, loader.URLLoader);
|
|
|
|
var self = this;
|
|
outstandingRequests.add(this);
|
|
priv.loader.start(priv.request).then(function(result) {
|
|
self.status = result.response.status_code;
|
|
self.statusText = result.response.status_line;
|
|
if (result.response.error)
|
|
throw new Error(result.response.error.description);
|
|
return core.drainData(result.response.body).then(function(result) {
|
|
outstandingRequests.delete(self);
|
|
priv.responseArrayBuffer = result.buffer;
|
|
// Use a setTimeout to avoid exceptions in onload tripping onerror.
|
|
window.setTimeout(function() {
|
|
self.onload();
|
|
});
|
|
});
|
|
}).catch(function(error) {
|
|
outstandingRequests.delete(self);
|
|
// Technically this should throw a ProgressEvent.
|
|
self.onerror(error);
|
|
});
|
|
}
|
|
}
|
|
|
|
module.exports = XMLHttpRequest;
|
|
</script>
|