0
0
Fork 0
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:
Bartek Iwańczuk 2021-07-06 16:20:21 +02:00 committed by GitHub
parent 753fd1eacc
commit 672a88f272
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 107 additions and 48 deletions

View file

@ -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);

View file

@ -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 frs state to "done".
this[state] = "done";
// 2. Let result be the result of package data given bytes, type, blobs 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,