mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
fix(op_crates/web): FileReader event handler order (#8348)
This commit is contained in:
parent
c7804c06ad
commit
a55e689e38
2 changed files with 65 additions and 31 deletions
|
@ -218,3 +218,25 @@ unitTest(async function fileReaderLoadBlobAbort(): Promise<void> {
|
||||||
fr.abort();
|
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);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
|
@ -51,9 +51,6 @@
|
||||||
// fire a progress event for loadstart
|
// fire a progress event for loadstart
|
||||||
const ev = new ProgressEvent("loadstart", {});
|
const ev = new ProgressEvent("loadstart", {});
|
||||||
fr.dispatchEvent(ev);
|
fr.dispatchEvent(ev);
|
||||||
if (fr.onloadstart !== null) {
|
|
||||||
fr.onloadstart(ev);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 3. Set isFirstChunk to false.
|
// 3. Set isFirstChunk to false.
|
||||||
|
@ -71,9 +68,6 @@
|
||||||
loaded: size,
|
loaded: size,
|
||||||
});
|
});
|
||||||
fr.dispatchEvent(ev);
|
fr.dispatchEvent(ev);
|
||||||
if (fr.onprogress !== null) {
|
|
||||||
fr.onprogress(ev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkPromise = reader.read();
|
chunkPromise = reader.read();
|
||||||
|
@ -118,9 +112,6 @@
|
||||||
total: size,
|
total: size,
|
||||||
});
|
});
|
||||||
fr.dispatchEvent(ev);
|
fr.dispatchEvent(ev);
|
||||||
if (fr.onload !== null) {
|
|
||||||
fr.onload(ev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. If fr’s state is not "loading", fire a progress event called loadend at the fr.
|
// 5. If fr’s state is not "loading", fire a progress event called loadend at the fr.
|
||||||
|
@ -132,9 +123,6 @@
|
||||||
total: size,
|
total: size,
|
||||||
});
|
});
|
||||||
fr.dispatchEvent(ev);
|
fr.dispatchEvent(ev);
|
||||||
if (fr.onloadend !== null) {
|
|
||||||
fr.onloadend(ev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -152,9 +140,6 @@
|
||||||
{
|
{
|
||||||
const ev = new ProgressEvent("error", {});
|
const ev = new ProgressEvent("error", {});
|
||||||
fr.dispatchEvent(ev);
|
fr.dispatchEvent(ev);
|
||||||
if (fr.onerror !== null) {
|
|
||||||
fr.onerror(ev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//If fr’s state is not "loading", fire a progress event called loadend at fr.
|
//If fr’s state is not "loading", fire a progress event called loadend at fr.
|
||||||
|
@ -162,9 +147,6 @@
|
||||||
if (fr.readyState !== FileReader.LOADING) {
|
if (fr.readyState !== FileReader.LOADING) {
|
||||||
const ev = new ProgressEvent("loadend", {});
|
const ev = new ProgressEvent("loadend", {});
|
||||||
fr.dispatchEvent(ev);
|
fr.dispatchEvent(ev);
|
||||||
if (fr.onloadend !== null) {
|
|
||||||
fr.onloadend(ev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -174,13 +156,6 @@
|
||||||
|
|
||||||
class FileReader extends EventTarget {
|
class FileReader extends EventTarget {
|
||||||
error = null;
|
error = null;
|
||||||
onabort = null;
|
|
||||||
onerror = null;
|
|
||||||
onload = null;
|
|
||||||
onloadend = null;
|
|
||||||
onloadstart = null;
|
|
||||||
onprogress = null;
|
|
||||||
|
|
||||||
readyState = FileReader.EMPTY;
|
readyState = FileReader.EMPTY;
|
||||||
result = null;
|
result = null;
|
||||||
aborting = false;
|
aborting = false;
|
||||||
|
@ -210,17 +185,11 @@
|
||||||
// Fire a progress event called abort at the context object.
|
// Fire a progress event called abort at the context object.
|
||||||
const ev = new ProgressEvent("abort", {});
|
const ev = new ProgressEvent("abort", {});
|
||||||
this.dispatchEvent(ev);
|
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 context object's state is not "loading", fire a progress event called loadend at the context object.
|
||||||
if (this.readyState !== FileReader.LOADING) {
|
if (this.readyState !== FileReader.LOADING) {
|
||||||
const ev = new ProgressEvent("loadend", {});
|
const ev = new ProgressEvent("loadend", {});
|
||||||
this.dispatchEvent(ev);
|
this.dispatchEvent(ev);
|
||||||
if (this.onloadend !== null) {
|
|
||||||
this.onloadend(ev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
readAsArrayBuffer(blob) {
|
readAsArrayBuffer(blob) {
|
||||||
|
@ -242,6 +211,49 @@
|
||||||
FileReader.LOADING = 1;
|
FileReader.LOADING = 1;
|
||||||
FileReader.DONE = 2;
|
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 = {
|
window.__bootstrap.fileReader = {
|
||||||
FileReader,
|
FileReader,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue