0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-10-29 08:58:01 -04:00

fix(op_crates/web): FileReader event handler order (#8348)

This commit is contained in:
Benjamin Gruenbaum 2020-11-11 17:59:49 +02:00 committed by GitHub
parent c7804c06ad
commit a55e689e38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 31 deletions

View file

@ -218,3 +218,25 @@ unitTest(async function fileReaderLoadBlobAbort(): Promise<void> {
fr.abort();
});
});
unitTest(
async function fileReaderDispatchesEventsInCorrectOrder(): Promise<void> {
await new Promise<void>((resolve) => {
const fr = new FileReader();
const b1 = new Blob(["Hello World"]);
let out = "";
fr.addEventListener("loadend", () => {
out += "1";
});
fr.onloadend = (ev): void => {
out += "2";
};
fr.addEventListener("loadend", () => {
assertEquals(out, "12");
resolve();
});
fr.readAsDataURL(b1);
});
},
);

View file

@ -51,9 +51,6 @@
// fire a progress event for loadstart
const ev = new ProgressEvent("loadstart", {});
fr.dispatchEvent(ev);
if (fr.onloadstart !== null) {
fr.onloadstart(ev);
}
});
}
// 3. Set isFirstChunk to false.
@ -71,9 +68,6 @@
loaded: size,
});
fr.dispatchEvent(ev);
if (fr.onprogress !== null) {
fr.onprogress(ev);
}
}
chunkPromise = reader.read();
@ -118,9 +112,6 @@
total: size,
});
fr.dispatchEvent(ev);
if (fr.onload !== null) {
fr.onload(ev);
}
}
// 5. If frs state is not "loading", fire a progress event called loadend at the fr.
@ -132,9 +123,6 @@
total: size,
});
fr.dispatchEvent(ev);
if (fr.onloadend !== null) {
fr.onloadend(ev);
}
}
});
@ -152,9 +140,6 @@
{
const ev = new ProgressEvent("error", {});
fr.dispatchEvent(ev);
if (fr.onerror !== null) {
fr.onerror(ev);
}
}
//If frs state is not "loading", fire a progress event called loadend at fr.
@ -162,9 +147,6 @@
if (fr.readyState !== FileReader.LOADING) {
const ev = new ProgressEvent("loadend", {});
fr.dispatchEvent(ev);
if (fr.onloadend !== null) {
fr.onloadend(ev);
}
}
break;
@ -174,13 +156,6 @@
class FileReader extends EventTarget {
error = null;
onabort = null;
onerror = null;
onload = null;
onloadend = null;
onloadstart = null;
onprogress = null;
readyState = FileReader.EMPTY;
result = null;
aborting = false;
@ -210,17 +185,11 @@
// Fire a progress event called abort at the context object.
const ev = new ProgressEvent("abort", {});
this.dispatchEvent(ev);
if (this.onabort !== null) {
this.onabort(ev);
}
// If context object's state is not "loading", fire a progress event called loadend at the context object.
if (this.readyState !== FileReader.LOADING) {
const ev = new ProgressEvent("loadend", {});
this.dispatchEvent(ev);
if (this.onloadend !== null) {
this.onloadend(ev);
}
}
}
readAsArrayBuffer(blob) {
@ -242,6 +211,49 @@
FileReader.LOADING = 1;
FileReader.DONE = 2;
const handlerSymbol = Symbol("eventHandlers");
function makeWrappedHandler(handler) {
function wrappedHandler(...args) {
if (typeof wrappedHandler.handler !== "function") {
return;
}
return wrappedHandler.handler.call(this, ...args);
}
wrappedHandler.handler = handler;
return wrappedHandler;
}
// TODO(benjamingr) reuse when we can reuse code between web crates
function defineEventHandler(emitter, name) {
// HTML specification section 8.1.5.1
Object.defineProperty(emitter, `on${name}`, {
get() {
return this[handlerSymbol]?.get(name)?.handler;
},
set(value) {
if (!this[handlerSymbol]) {
this[handlerSymbol] = new Map();
}
let handlerWrapper = this[handlerSymbol]?.get(name);
if (handlerWrapper) {
handlerWrapper.handler = value;
} else {
handlerWrapper = makeWrappedHandler(value);
this.addEventListener(name, handlerWrapper);
}
this[handlerSymbol].set(name, handlerWrapper);
},
configurable: true,
enumerable: true,
});
}
defineEventHandler(FileReader.prototype, "error");
defineEventHandler(FileReader.prototype, "loadstart");
defineEventHandler(FileReader.prototype, "load");
defineEventHandler(FileReader.prototype, "loadend");
defineEventHandler(FileReader.prototype, "progress");
defineEventHandler(FileReader.prototype, "abort");
window.__bootstrap.fileReader = {
FileReader,
};