mirror of
https://github.com/denoland/deno.git
synced 2024-10-29 08:58:01 -04:00
refactor: use primordials in extensions/web, part2 (#11299)
This commit is contained in:
parent
753fd1eacc
commit
672a88f272
2 changed files with 107 additions and 48 deletions
|
@ -3,6 +3,7 @@
|
|||
// @ts-check
|
||||
/// <reference no-default-lib="true" />
|
||||
/// <reference path="../../core/lib.deno_core.d.ts" />
|
||||
/// <reference path="../../core/internal.d.ts" />
|
||||
/// <reference path="../webidl/internal.d.ts" />
|
||||
/// <reference path="../web/internal.d.ts" />
|
||||
/// <reference path="../web/lib.deno_web.d.ts" />
|
||||
|
@ -13,6 +14,26 @@
|
|||
((window) => {
|
||||
const core = window.Deno.core;
|
||||
const webidl = window.__bootstrap.webidl;
|
||||
const {
|
||||
ArrayBuffer,
|
||||
ArrayBufferPrototypeSlice,
|
||||
ArrayBufferIsView,
|
||||
ArrayPrototypePush,
|
||||
Date,
|
||||
DatePrototypeGetTime,
|
||||
MathMax,
|
||||
MathMin,
|
||||
RegExpPrototypeTest,
|
||||
StringPrototypeCharAt,
|
||||
StringPrototypeToLowerCase,
|
||||
StringPrototypeSlice,
|
||||
Symbol,
|
||||
SymbolFor,
|
||||
TypedArrayPrototypeSet,
|
||||
SymbolToStringTag,
|
||||
TypeError,
|
||||
Uint8Array,
|
||||
} = window.__bootstrap.primordials;
|
||||
|
||||
// TODO(lucacasonato): this needs to not be hardcoded and instead depend on
|
||||
// host os.
|
||||
|
@ -28,11 +49,11 @@
|
|||
// https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points
|
||||
const start = position;
|
||||
for (
|
||||
let c = input.charAt(position);
|
||||
let c = StringPrototypeCharAt(input, position);
|
||||
position < input.length && !(c === "\r" || c === "\n");
|
||||
c = input.charAt(++position)
|
||||
c = StringPrototypeCharAt(input, ++position)
|
||||
);
|
||||
return { result: input.slice(start, position), position };
|
||||
return { result: StringPrototypeSlice(input, start, position), position };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,11 +66,13 @@
|
|||
let { result, position } = collectCodepointsNotCRLF(s, 0);
|
||||
|
||||
while (position < s.length) {
|
||||
const codePoint = s.charAt(position);
|
||||
const codePoint = StringPrototypeCharAt(s, position);
|
||||
if (codePoint === "\r") {
|
||||
result += nativeLineEnding;
|
||||
position++;
|
||||
if (position < s.length && s.charAt(position) === "\n") {
|
||||
if (
|
||||
position < s.length && StringPrototypeCharAt(s, position) === "\n"
|
||||
) {
|
||||
position++;
|
||||
}
|
||||
} else if (codePoint === "\n") {
|
||||
|
@ -87,26 +110,26 @@
|
|||
let size = 0;
|
||||
for (const element of parts) {
|
||||
if (element instanceof ArrayBuffer) {
|
||||
const chunk = new Uint8Array(element.slice(0));
|
||||
processedParts.push(BlobReference.fromUint8Array(chunk));
|
||||
const chunk = new Uint8Array(ArrayBufferPrototypeSlice(element, 0));
|
||||
ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
|
||||
size += element.byteLength;
|
||||
} else if (ArrayBuffer.isView(element)) {
|
||||
} else if (ArrayBufferIsView(element)) {
|
||||
const chunk = new Uint8Array(
|
||||
element.buffer,
|
||||
element.byteOffset,
|
||||
element.byteLength,
|
||||
);
|
||||
size += element.byteLength;
|
||||
processedParts.push(BlobReference.fromUint8Array(chunk));
|
||||
ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
|
||||
} else if (element instanceof Blob) {
|
||||
processedParts.push(element);
|
||||
ArrayPrototypePush(processedParts, element);
|
||||
size += element.size;
|
||||
} else if (typeof element === "string") {
|
||||
const chunk = core.encode(
|
||||
endings == "native" ? convertLineEndingsToNative(element) : element,
|
||||
);
|
||||
size += chunk.byteLength;
|
||||
processedParts.push(BlobReference.fromUint8Array(chunk));
|
||||
ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
|
||||
} else {
|
||||
throw new TypeError("Unreachable code (invalid element type)");
|
||||
}
|
||||
|
@ -120,10 +143,10 @@
|
|||
*/
|
||||
function normalizeType(str) {
|
||||
let normalizedType = str;
|
||||
if (!/^[\x20-\x7E]*$/.test(str)) {
|
||||
if (!RegExpPrototypeTest(/^[\x20-\x7E]*$/, str)) {
|
||||
normalizedType = "";
|
||||
}
|
||||
return normalizedType.toLowerCase();
|
||||
return StringPrototypeToLowerCase(normalizedType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,7 +160,7 @@
|
|||
if (part instanceof Blob) {
|
||||
getParts(part, bag);
|
||||
} else {
|
||||
bag.push(part._id);
|
||||
ArrayPrototypePush(bag, part._id);
|
||||
}
|
||||
}
|
||||
return bag;
|
||||
|
@ -228,9 +251,9 @@
|
|||
relativeStart = 0;
|
||||
} else {
|
||||
if (start < 0) {
|
||||
relativeStart = Math.max(O.size + start, 0);
|
||||
relativeStart = MathMax(O.size + start, 0);
|
||||
} else {
|
||||
relativeStart = Math.min(start, O.size);
|
||||
relativeStart = MathMin(start, O.size);
|
||||
}
|
||||
}
|
||||
/** @type {number} */
|
||||
|
@ -239,13 +262,13 @@
|
|||
relativeEnd = O.size;
|
||||
} else {
|
||||
if (end < 0) {
|
||||
relativeEnd = Math.max(O.size + end, 0);
|
||||
relativeEnd = MathMax(O.size + end, 0);
|
||||
} else {
|
||||
relativeEnd = Math.min(end, O.size);
|
||||
relativeEnd = MathMin(end, O.size);
|
||||
}
|
||||
}
|
||||
|
||||
const span = Math.max(relativeEnd - relativeStart, 0);
|
||||
const span = MathMax(relativeEnd - relativeStart, 0);
|
||||
const blobParts = [];
|
||||
let added = 0;
|
||||
|
||||
|
@ -265,11 +288,11 @@
|
|||
} else {
|
||||
const chunk = part.slice(
|
||||
relativeStart,
|
||||
Math.min(part.size, relativeEnd),
|
||||
MathMin(part.size, relativeEnd),
|
||||
);
|
||||
added += chunk.size;
|
||||
relativeEnd -= part.size;
|
||||
blobParts.push(chunk);
|
||||
ArrayPrototypePush(blobParts, chunk);
|
||||
relativeStart = 0; // All next sequential parts should start at 0
|
||||
}
|
||||
}
|
||||
|
@ -328,17 +351,17 @@
|
|||
const bytes = new Uint8Array(this.size);
|
||||
let offset = 0;
|
||||
for await (const chunk of stream) {
|
||||
bytes.set(chunk, offset);
|
||||
TypedArrayPrototypeSet(bytes, chunk, offset);
|
||||
offset += chunk.byteLength;
|
||||
}
|
||||
return bytes.buffer;
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
get [SymbolToStringTag]() {
|
||||
return "Blob";
|
||||
}
|
||||
|
||||
[Symbol.for("Deno.customInspect")](inspect) {
|
||||
[SymbolFor("Deno.customInspect")](inspect) {
|
||||
return `Blob ${inspect({ size: this.size, type: this.#type })}`;
|
||||
}
|
||||
}
|
||||
|
@ -355,7 +378,7 @@
|
|||
if (V instanceof ArrayBuffer || V instanceof SharedArrayBuffer) {
|
||||
return webidl.converters["ArrayBuffer"](V, opts);
|
||||
}
|
||||
if (ArrayBuffer.isView(V)) {
|
||||
if (ArrayBufferIsView(V)) {
|
||||
return webidl.converters["ArrayBufferView"](V, opts);
|
||||
}
|
||||
}
|
||||
|
@ -422,7 +445,7 @@
|
|||
this[_Name] = fileName;
|
||||
if (options.lastModified === undefined) {
|
||||
/** @type {number} */
|
||||
this[_LastModified] = new Date().getTime();
|
||||
this[_LastModified] = DatePrototypeGetTime(new Date());
|
||||
} else {
|
||||
/** @type {number} */
|
||||
this[_LastModified] = options.lastModified;
|
||||
|
@ -441,7 +464,7 @@
|
|||
return this[_LastModified];
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
get [SymbolToStringTag]() {
|
||||
return "File";
|
||||
}
|
||||
}
|
||||
|
@ -522,7 +545,7 @@
|
|||
// let position = 0;
|
||||
// const end = this.size;
|
||||
// while (position !== end) {
|
||||
// const size = Math.min(end - position, 65536);
|
||||
// const size = MathMin(end - position, 65536);
|
||||
// const chunk = this.slice(position, position + size);
|
||||
// position += chunk.size;
|
||||
// yield core.opAsync("op_blob_read_part", chunk._id);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// @ts-check
|
||||
/// <reference no-default-lib="true" />
|
||||
/// <reference path="../../core/lib.deno_core.d.ts" />
|
||||
/// <reference path="../../core/internal.d.ts" />
|
||||
/// <reference path="../webidl/internal.d.ts" />
|
||||
/// <reference path="../web/internal.d.ts" />
|
||||
/// <reference path="../web/lib.deno_web.d.ts" />
|
||||
|
@ -17,6 +18,23 @@
|
|||
const { decode, TextDecoder } = window.__bootstrap.encoding;
|
||||
const { parseMimeType } = window.__bootstrap.mimesniff;
|
||||
const { DOMException } = window.__bootstrap.domException;
|
||||
const {
|
||||
ArrayPrototypeJoin,
|
||||
ArrayPrototypeMap,
|
||||
ArrayPrototypePush,
|
||||
ArrayPrototypeReduce,
|
||||
FunctionPrototypeCall,
|
||||
Map,
|
||||
MapPrototypeGet,
|
||||
MapPrototypeSet,
|
||||
ObjectDefineProperty,
|
||||
StringFromCodePoint,
|
||||
Symbol,
|
||||
SymbolToStringTag,
|
||||
TypedArrayPrototypeSet,
|
||||
TypeError,
|
||||
Uint8Array,
|
||||
} = window.__bootstrap.primordials;
|
||||
|
||||
const state = Symbol("[[state]]");
|
||||
const result = Symbol("[[result]]");
|
||||
|
@ -24,7 +42,7 @@
|
|||
const aborted = Symbol("[[aborted]]");
|
||||
|
||||
class FileReader extends EventTarget {
|
||||
get [Symbol.toStringTag]() {
|
||||
get [SymbolToStringTag]() {
|
||||
return "FileReader";
|
||||
}
|
||||
|
||||
|
@ -96,11 +114,15 @@
|
|||
// 4. If chunkPromise is fulfilled with an object whose done property is false
|
||||
// and whose value property is a Uint8Array object, run these steps:
|
||||
if (!chunk.done && chunk.value instanceof Uint8Array) {
|
||||
chunks.push(chunk.value);
|
||||
ArrayPrototypePush(chunks, chunk.value);
|
||||
|
||||
// TODO(bartlomieju): (only) If roughly 50ms have passed since last progress
|
||||
{
|
||||
const size = chunks.reduce((p, i) => p + i.byteLength, 0);
|
||||
const size = ArrayPrototypeReduce(
|
||||
chunks,
|
||||
(p, i) => p + i.byteLength,
|
||||
0,
|
||||
);
|
||||
const ev = new ProgressEvent("progress", {
|
||||
loaded: size,
|
||||
});
|
||||
|
@ -120,11 +142,15 @@
|
|||
// 1. Set fr’s state to "done".
|
||||
this[state] = "done";
|
||||
// 2. Let result be the result of package data given bytes, type, blob’s type, and encodingName.
|
||||
const size = chunks.reduce((p, i) => p + i.byteLength, 0);
|
||||
const size = ArrayPrototypeReduce(
|
||||
chunks,
|
||||
(p, i) => p + i.byteLength,
|
||||
0,
|
||||
);
|
||||
const bytes = new Uint8Array(size);
|
||||
let offs = 0;
|
||||
for (const chunk of chunks) {
|
||||
bytes.set(chunk, offs);
|
||||
TypedArrayPrototypeSet(bytes, chunk, offs);
|
||||
offs += chunk.byteLength;
|
||||
}
|
||||
switch (readtype.kind) {
|
||||
|
@ -133,9 +159,13 @@
|
|||
break;
|
||||
}
|
||||
case "BinaryString":
|
||||
this[result] = [...new Uint8Array(bytes.buffer)].map((v) =>
|
||||
String.fromCodePoint(v)
|
||||
).join("");
|
||||
this[result] = ArrayPrototypeJoin(
|
||||
ArrayPrototypeMap(
|
||||
[...new Uint8Array(bytes.buffer)],
|
||||
(v) => StringFromCodePoint(v),
|
||||
),
|
||||
"",
|
||||
);
|
||||
break;
|
||||
case "Text": {
|
||||
let decoder = undefined;
|
||||
|
@ -149,7 +179,10 @@
|
|||
if (decoder === undefined) {
|
||||
const mimeType = parseMimeType(blob.type);
|
||||
if (mimeType) {
|
||||
const charset = mimeType.parameters.get("charset");
|
||||
const charset = MapPrototypeGet(
|
||||
mimeType.parameters,
|
||||
"charset",
|
||||
);
|
||||
if (charset) {
|
||||
try {
|
||||
decoder = new TextDecoder(charset);
|
||||
|
@ -330,37 +363,37 @@
|
|||
|
||||
webidl.configurePrototype(FileReader);
|
||||
|
||||
Object.defineProperty(FileReader, "EMPTY", {
|
||||
ObjectDefineProperty(FileReader, "EMPTY", {
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
value: 0,
|
||||
});
|
||||
Object.defineProperty(FileReader, "LOADING", {
|
||||
ObjectDefineProperty(FileReader, "LOADING", {
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
value: 1,
|
||||
});
|
||||
Object.defineProperty(FileReader, "DONE", {
|
||||
ObjectDefineProperty(FileReader, "DONE", {
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
value: 2,
|
||||
});
|
||||
Object.defineProperty(FileReader.prototype, "EMPTY", {
|
||||
ObjectDefineProperty(FileReader.prototype, "EMPTY", {
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
value: 0,
|
||||
});
|
||||
Object.defineProperty(FileReader.prototype, "LOADING", {
|
||||
ObjectDefineProperty(FileReader.prototype, "LOADING", {
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
value: 1,
|
||||
});
|
||||
Object.defineProperty(FileReader.prototype, "DONE", {
|
||||
ObjectDefineProperty(FileReader.prototype, "DONE", {
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
|
@ -374,7 +407,7 @@
|
|||
if (typeof wrappedHandler.handler !== "function") {
|
||||
return;
|
||||
}
|
||||
return wrappedHandler.handler.call(this, ...args);
|
||||
return FunctionPrototypeCall(wrappedHandler.handler, this, ...args);
|
||||
}
|
||||
wrappedHandler.handler = handler;
|
||||
return wrappedHandler;
|
||||
|
@ -382,22 +415,25 @@
|
|||
// 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}`, {
|
||||
ObjectDefineProperty(emitter, `on${name}`, {
|
||||
get() {
|
||||
return this[handlerSymbol]?.get(name)?.handler ?? null;
|
||||
const maybeMap = this[handlerSymbol];
|
||||
if (!maybeMap) return null;
|
||||
|
||||
return MapPrototypeGet(maybeMap, name)?.handler ?? null;
|
||||
},
|
||||
set(value) {
|
||||
if (!this[handlerSymbol]) {
|
||||
this[handlerSymbol] = new Map();
|
||||
}
|
||||
let handlerWrapper = this[handlerSymbol]?.get(name);
|
||||
let handlerWrapper = MapPrototypeGet(this[handlerSymbol], name);
|
||||
if (handlerWrapper) {
|
||||
handlerWrapper.handler = value;
|
||||
} else {
|
||||
handlerWrapper = makeWrappedHandler(value);
|
||||
this.addEventListener(name, handlerWrapper);
|
||||
}
|
||||
this[handlerSymbol].set(name, handlerWrapper);
|
||||
MapPrototypeSet(this[handlerSymbol], name, handlerWrapper);
|
||||
},
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
|
|
Loading…
Reference in a new issue