0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 17:34:47 -05: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 // @ts-check
/// <reference no-default-lib="true" /> /// <reference no-default-lib="true" />
/// <reference path="../../core/lib.deno_core.d.ts" /> /// <reference path="../../core/lib.deno_core.d.ts" />
/// <reference path="../../core/internal.d.ts" />
/// <reference path="../webidl/internal.d.ts" /> /// <reference path="../webidl/internal.d.ts" />
/// <reference path="../web/internal.d.ts" /> /// <reference path="../web/internal.d.ts" />
/// <reference path="../web/lib.deno_web.d.ts" /> /// <reference path="../web/lib.deno_web.d.ts" />
@ -13,6 +14,26 @@
((window) => { ((window) => {
const core = window.Deno.core; const core = window.Deno.core;
const webidl = window.__bootstrap.webidl; 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 // TODO(lucacasonato): this needs to not be hardcoded and instead depend on
// host os. // host os.
@ -28,11 +49,11 @@
// https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points // https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points
const start = position; const start = position;
for ( for (
let c = input.charAt(position); let c = StringPrototypeCharAt(input, position);
position < input.length && !(c === "\r" || c === "\n"); 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); let { result, position } = collectCodepointsNotCRLF(s, 0);
while (position < s.length) { while (position < s.length) {
const codePoint = s.charAt(position); const codePoint = StringPrototypeCharAt(s, position);
if (codePoint === "\r") { if (codePoint === "\r") {
result += nativeLineEnding; result += nativeLineEnding;
position++; position++;
if (position < s.length && s.charAt(position) === "\n") { if (
position < s.length && StringPrototypeCharAt(s, position) === "\n"
) {
position++; position++;
} }
} else if (codePoint === "\n") { } else if (codePoint === "\n") {
@ -87,26 +110,26 @@
let size = 0; let size = 0;
for (const element of parts) { for (const element of parts) {
if (element instanceof ArrayBuffer) { if (element instanceof ArrayBuffer) {
const chunk = new Uint8Array(element.slice(0)); const chunk = new Uint8Array(ArrayBufferPrototypeSlice(element, 0));
processedParts.push(BlobReference.fromUint8Array(chunk)); ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
size += element.byteLength; size += element.byteLength;
} else if (ArrayBuffer.isView(element)) { } else if (ArrayBufferIsView(element)) {
const chunk = new Uint8Array( const chunk = new Uint8Array(
element.buffer, element.buffer,
element.byteOffset, element.byteOffset,
element.byteLength, element.byteLength,
); );
size += element.byteLength; size += element.byteLength;
processedParts.push(BlobReference.fromUint8Array(chunk)); ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
} else if (element instanceof Blob) { } else if (element instanceof Blob) {
processedParts.push(element); ArrayPrototypePush(processedParts, element);
size += element.size; size += element.size;
} else if (typeof element === "string") { } else if (typeof element === "string") {
const chunk = core.encode( const chunk = core.encode(
endings == "native" ? convertLineEndingsToNative(element) : element, endings == "native" ? convertLineEndingsToNative(element) : element,
); );
size += chunk.byteLength; size += chunk.byteLength;
processedParts.push(BlobReference.fromUint8Array(chunk)); ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk));
} else { } else {
throw new TypeError("Unreachable code (invalid element type)"); throw new TypeError("Unreachable code (invalid element type)");
} }
@ -120,10 +143,10 @@
*/ */
function normalizeType(str) { function normalizeType(str) {
let normalizedType = str; let normalizedType = str;
if (!/^[\x20-\x7E]*$/.test(str)) { if (!RegExpPrototypeTest(/^[\x20-\x7E]*$/, str)) {
normalizedType = ""; normalizedType = "";
} }
return normalizedType.toLowerCase(); return StringPrototypeToLowerCase(normalizedType);
} }
/** /**
@ -137,7 +160,7 @@
if (part instanceof Blob) { if (part instanceof Blob) {
getParts(part, bag); getParts(part, bag);
} else { } else {
bag.push(part._id); ArrayPrototypePush(bag, part._id);
} }
} }
return bag; return bag;
@ -228,9 +251,9 @@
relativeStart = 0; relativeStart = 0;
} else { } else {
if (start < 0) { if (start < 0) {
relativeStart = Math.max(O.size + start, 0); relativeStart = MathMax(O.size + start, 0);
} else { } else {
relativeStart = Math.min(start, O.size); relativeStart = MathMin(start, O.size);
} }
} }
/** @type {number} */ /** @type {number} */
@ -239,13 +262,13 @@
relativeEnd = O.size; relativeEnd = O.size;
} else { } else {
if (end < 0) { if (end < 0) {
relativeEnd = Math.max(O.size + end, 0); relativeEnd = MathMax(O.size + end, 0);
} else { } 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 = []; const blobParts = [];
let added = 0; let added = 0;
@ -265,11 +288,11 @@
} else { } else {
const chunk = part.slice( const chunk = part.slice(
relativeStart, relativeStart,
Math.min(part.size, relativeEnd), MathMin(part.size, relativeEnd),
); );
added += chunk.size; added += chunk.size;
relativeEnd -= part.size; relativeEnd -= part.size;
blobParts.push(chunk); ArrayPrototypePush(blobParts, chunk);
relativeStart = 0; // All next sequential parts should start at 0 relativeStart = 0; // All next sequential parts should start at 0
} }
} }
@ -328,17 +351,17 @@
const bytes = new Uint8Array(this.size); const bytes = new Uint8Array(this.size);
let offset = 0; let offset = 0;
for await (const chunk of stream) { for await (const chunk of stream) {
bytes.set(chunk, offset); TypedArrayPrototypeSet(bytes, chunk, offset);
offset += chunk.byteLength; offset += chunk.byteLength;
} }
return bytes.buffer; return bytes.buffer;
} }
get [Symbol.toStringTag]() { get [SymbolToStringTag]() {
return "Blob"; return "Blob";
} }
[Symbol.for("Deno.customInspect")](inspect) { [SymbolFor("Deno.customInspect")](inspect) {
return `Blob ${inspect({ size: this.size, type: this.#type })}`; return `Blob ${inspect({ size: this.size, type: this.#type })}`;
} }
} }
@ -355,7 +378,7 @@
if (V instanceof ArrayBuffer || V instanceof SharedArrayBuffer) { if (V instanceof ArrayBuffer || V instanceof SharedArrayBuffer) {
return webidl.converters["ArrayBuffer"](V, opts); return webidl.converters["ArrayBuffer"](V, opts);
} }
if (ArrayBuffer.isView(V)) { if (ArrayBufferIsView(V)) {
return webidl.converters["ArrayBufferView"](V, opts); return webidl.converters["ArrayBufferView"](V, opts);
} }
} }
@ -422,7 +445,7 @@
this[_Name] = fileName; this[_Name] = fileName;
if (options.lastModified === undefined) { if (options.lastModified === undefined) {
/** @type {number} */ /** @type {number} */
this[_LastModified] = new Date().getTime(); this[_LastModified] = DatePrototypeGetTime(new Date());
} else { } else {
/** @type {number} */ /** @type {number} */
this[_LastModified] = options.lastModified; this[_LastModified] = options.lastModified;
@ -441,7 +464,7 @@
return this[_LastModified]; return this[_LastModified];
} }
get [Symbol.toStringTag]() { get [SymbolToStringTag]() {
return "File"; return "File";
} }
} }
@ -522,7 +545,7 @@
// let position = 0; // let position = 0;
// const end = this.size; // const end = this.size;
// while (position !== end) { // while (position !== end) {
// const size = Math.min(end - position, 65536); // const size = MathMin(end - position, 65536);
// const chunk = this.slice(position, position + size); // const chunk = this.slice(position, position + size);
// position += chunk.size; // position += chunk.size;
// yield core.opAsync("op_blob_read_part", chunk._id); // yield core.opAsync("op_blob_read_part", chunk._id);

View file

@ -3,6 +3,7 @@
// @ts-check // @ts-check
/// <reference no-default-lib="true" /> /// <reference no-default-lib="true" />
/// <reference path="../../core/lib.deno_core.d.ts" /> /// <reference path="../../core/lib.deno_core.d.ts" />
/// <reference path="../../core/internal.d.ts" />
/// <reference path="../webidl/internal.d.ts" /> /// <reference path="../webidl/internal.d.ts" />
/// <reference path="../web/internal.d.ts" /> /// <reference path="../web/internal.d.ts" />
/// <reference path="../web/lib.deno_web.d.ts" /> /// <reference path="../web/lib.deno_web.d.ts" />
@ -17,6 +18,23 @@
const { decode, TextDecoder } = window.__bootstrap.encoding; const { decode, TextDecoder } = window.__bootstrap.encoding;
const { parseMimeType } = window.__bootstrap.mimesniff; const { parseMimeType } = window.__bootstrap.mimesniff;
const { DOMException } = window.__bootstrap.domException; 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 state = Symbol("[[state]]");
const result = Symbol("[[result]]"); const result = Symbol("[[result]]");
@ -24,7 +42,7 @@
const aborted = Symbol("[[aborted]]"); const aborted = Symbol("[[aborted]]");
class FileReader extends EventTarget { class FileReader extends EventTarget {
get [Symbol.toStringTag]() { get [SymbolToStringTag]() {
return "FileReader"; return "FileReader";
} }
@ -96,11 +114,15 @@
// 4. If chunkPromise is fulfilled with an object whose done property is false // 4. If chunkPromise is fulfilled with an object whose done property is false
// and whose value property is a Uint8Array object, run these steps: // and whose value property is a Uint8Array object, run these steps:
if (!chunk.done && chunk.value instanceof Uint8Array) { 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 // 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", { const ev = new ProgressEvent("progress", {
loaded: size, loaded: size,
}); });
@ -120,11 +142,15 @@
// 1. Set frs state to "done". // 1. Set frs state to "done".
this[state] = "done"; this[state] = "done";
// 2. Let result be the result of package data given bytes, type, blobs type, and encodingName. // 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); const bytes = new Uint8Array(size);
let offs = 0; let offs = 0;
for (const chunk of chunks) { for (const chunk of chunks) {
bytes.set(chunk, offs); TypedArrayPrototypeSet(bytes, chunk, offs);
offs += chunk.byteLength; offs += chunk.byteLength;
} }
switch (readtype.kind) { switch (readtype.kind) {
@ -133,9 +159,13 @@
break; break;
} }
case "BinaryString": case "BinaryString":
this[result] = [...new Uint8Array(bytes.buffer)].map((v) => this[result] = ArrayPrototypeJoin(
String.fromCodePoint(v) ArrayPrototypeMap(
).join(""); [...new Uint8Array(bytes.buffer)],
(v) => StringFromCodePoint(v),
),
"",
);
break; break;
case "Text": { case "Text": {
let decoder = undefined; let decoder = undefined;
@ -149,7 +179,10 @@
if (decoder === undefined) { if (decoder === undefined) {
const mimeType = parseMimeType(blob.type); const mimeType = parseMimeType(blob.type);
if (mimeType) { if (mimeType) {
const charset = mimeType.parameters.get("charset"); const charset = MapPrototypeGet(
mimeType.parameters,
"charset",
);
if (charset) { if (charset) {
try { try {
decoder = new TextDecoder(charset); decoder = new TextDecoder(charset);
@ -330,37 +363,37 @@
webidl.configurePrototype(FileReader); webidl.configurePrototype(FileReader);
Object.defineProperty(FileReader, "EMPTY", { ObjectDefineProperty(FileReader, "EMPTY", {
writable: false, writable: false,
enumerable: true, enumerable: true,
configurable: false, configurable: false,
value: 0, value: 0,
}); });
Object.defineProperty(FileReader, "LOADING", { ObjectDefineProperty(FileReader, "LOADING", {
writable: false, writable: false,
enumerable: true, enumerable: true,
configurable: false, configurable: false,
value: 1, value: 1,
}); });
Object.defineProperty(FileReader, "DONE", { ObjectDefineProperty(FileReader, "DONE", {
writable: false, writable: false,
enumerable: true, enumerable: true,
configurable: false, configurable: false,
value: 2, value: 2,
}); });
Object.defineProperty(FileReader.prototype, "EMPTY", { ObjectDefineProperty(FileReader.prototype, "EMPTY", {
writable: false, writable: false,
enumerable: true, enumerable: true,
configurable: false, configurable: false,
value: 0, value: 0,
}); });
Object.defineProperty(FileReader.prototype, "LOADING", { ObjectDefineProperty(FileReader.prototype, "LOADING", {
writable: false, writable: false,
enumerable: true, enumerable: true,
configurable: false, configurable: false,
value: 1, value: 1,
}); });
Object.defineProperty(FileReader.prototype, "DONE", { ObjectDefineProperty(FileReader.prototype, "DONE", {
writable: false, writable: false,
enumerable: true, enumerable: true,
configurable: false, configurable: false,
@ -374,7 +407,7 @@
if (typeof wrappedHandler.handler !== "function") { if (typeof wrappedHandler.handler !== "function") {
return; return;
} }
return wrappedHandler.handler.call(this, ...args); return FunctionPrototypeCall(wrappedHandler.handler, this, ...args);
} }
wrappedHandler.handler = handler; wrappedHandler.handler = handler;
return wrappedHandler; return wrappedHandler;
@ -382,22 +415,25 @@
// TODO(benjamingr) reuse when we can reuse code between web crates // TODO(benjamingr) reuse when we can reuse code between web crates
function defineEventHandler(emitter, name) { function defineEventHandler(emitter, name) {
// HTML specification section 8.1.5.1 // HTML specification section 8.1.5.1
Object.defineProperty(emitter, `on${name}`, { ObjectDefineProperty(emitter, `on${name}`, {
get() { get() {
return this[handlerSymbol]?.get(name)?.handler ?? null; const maybeMap = this[handlerSymbol];
if (!maybeMap) return null;
return MapPrototypeGet(maybeMap, name)?.handler ?? null;
}, },
set(value) { set(value) {
if (!this[handlerSymbol]) { if (!this[handlerSymbol]) {
this[handlerSymbol] = new Map(); this[handlerSymbol] = new Map();
} }
let handlerWrapper = this[handlerSymbol]?.get(name); let handlerWrapper = MapPrototypeGet(this[handlerSymbol], name);
if (handlerWrapper) { if (handlerWrapper) {
handlerWrapper.handler = value; handlerWrapper.handler = value;
} else { } else {
handlerWrapper = makeWrappedHandler(value); handlerWrapper = makeWrappedHandler(value);
this.addEventListener(name, handlerWrapper); this.addEventListener(name, handlerWrapper);
} }
this[handlerSymbol].set(name, handlerWrapper); MapPrototypeSet(this[handlerSymbol], name, handlerWrapper);
}, },
configurable: true, configurable: true,
enumerable: true, enumerable: true,