1
0
mirror of https://github.com/S2-/minifyfromhtml.git synced 2025-10-07 11:50:05 +02:00
This commit is contained in:
s2
2018-05-05 14:29:20 +02:00
parent 62dd054f83
commit d17c4fe70c
1809 changed files with 262593 additions and 219 deletions

View File

@@ -0,0 +1,92 @@
"use strict";
const { EOL } = require("os");
const Blob = require("../generated/Blob");
function convertLineEndingsToNative(s) {
return s.replace(/\r\n|\r|\n/g, EOL);
}
exports.implementation = class BlobImpl {
constructor(args) {
const parts = args[0];
const properties = args[1];
const buffers = [];
if (parts !== undefined) {
for (const part of parts) {
let buffer;
if (part instanceof ArrayBuffer) {
buffer = Buffer.from(part);
} else if (ArrayBuffer.isView(part)) {
buffer = Buffer.from(part.buffer, part.byteOffset, part.byteLength);
} else if (Blob.isImpl(part)) {
buffer = part._buffer;
} else {
let s = part;
if (properties.endings === "native") {
s = convertLineEndingsToNative(part);
}
buffer = Buffer.from(s);
}
buffers.push(buffer);
}
}
this._buffer = Buffer.concat(buffers);
this.type = properties.type;
if (/[^\u0020-\u007E]/.test(this.type)) {
this.type = "";
} else {
this.type = this.type.toLowerCase();
}
}
get size() {
return this._buffer.length;
}
slice(start, end, contentType) {
const { size } = this;
let relativeStart;
let relativeEnd;
let relativeContentType;
if (start === undefined) {
relativeStart = 0;
} else if (start < 0) {
relativeStart = Math.max(size + start, 0);
} else {
relativeStart = Math.min(start, size);
}
if (end === undefined) {
relativeEnd = size;
} else if (end < 0) {
relativeEnd = Math.max(size + end, 0);
} else {
relativeEnd = Math.min(end, size);
}
if (contentType === undefined) {
relativeContentType = "";
} else {
// sanitization (lower case and invalid char check) is done in the
// constructor
relativeContentType = contentType;
}
const span = Math.max(relativeEnd - relativeStart, 0);
const buffer = this._buffer;
const slicedBuffer = buffer.slice(
relativeStart,
relativeStart + span
);
const blob = Blob.createImpl([[], { type: relativeContentType }], {});
blob._buffer = slicedBuffer;
return blob;
}
};

View File

@@ -0,0 +1,15 @@
"use strict";
const BlobImpl = require("./Blob-impl").implementation;
exports.implementation = class FileImpl extends BlobImpl {
constructor(args, privateData) {
const fileBits = args[0];
const fileName = args[1];
const options = args[2];
super([fileBits, options], privateData);
this.name = fileName.replace(/\//g, ":");
this.lastModified = "lastModified" in options ? options.lastModified : Date.now();
}
};

View File

@@ -0,0 +1,15 @@
"use strict";
const idlUtils = require("../generated/utils.js");
exports.implementation = class FileListImpl extends Array {
constructor() {
super(0);
}
item(index) {
return this[index] || null;
}
get [idlUtils.supportedPropertyIndices]() {
return this.keys();
}
};

View File

@@ -0,0 +1,143 @@
"use strict";
const whatwgEncoding = require("whatwg-encoding");
const MIMEType = require("whatwg-mimetype");
const querystring = require("querystring");
const DOMException = require("domexception");
const EventTargetImpl = require("../events/EventTarget-impl").implementation;
const ProgressEvent = require("../generated/ProgressEvent");
const { setupForSimpleEventAccessors } = require("../helpers/create-event-accessor");
const READY_STATES = Object.freeze({
EMPTY: 0,
LOADING: 1,
DONE: 2
});
const events = ["loadstart", "progress", "load", "abort", "error", "loadend"];
class FileReaderImpl extends EventTargetImpl {
constructor(args, privateData) {
super([], privateData);
this.error = null;
this.readyState = READY_STATES.EMPTY;
this.result = null;
this._ownerDocument = privateData.window.document;
this._terminated = false;
}
readAsArrayBuffer(file) {
this._readFile(file, "buffer");
}
readAsBinaryString(file) {
this._readFile(file, "binaryString");
}
readAsDataURL(file) {
this._readFile(file, "dataURL");
}
readAsText(file, encoding) {
this._readFile(file, "text", whatwgEncoding.labelToName(encoding) || "UTF-8");
}
abort() {
if (this.readyState === READY_STATES.EMPTY || this.readyState === READY_STATES.DONE) {
this.result = null;
return;
}
if (this.readyState === READY_STATES.LOADING) {
this.readyState = READY_STATES.DONE;
this.result = null;
}
this._terminated = true;
this._fireProgressEvent("abort");
this._fireProgressEvent("loadend");
}
_fireProgressEvent(name, props) {
const event = ProgressEvent.createImpl([name, Object.assign({ bubbles: false, cancelable: false }, props)], {});
this.dispatchEvent(event);
}
_readFile(file, format, encoding) {
if (this.readyState === READY_STATES.LOADING) {
throw new DOMException("The object is in an invalid state.", "InvalidStateError");
}
this.readyState = READY_STATES.LOADING;
setImmediate(() => {
if (this._terminated) {
this._terminated = false;
return;
}
this._fireProgressEvent("loadstart");
let data = file._buffer;
if (!data) {
data = Buffer.alloc(0);
}
this._fireProgressEvent("progress", {
lengthComputable: !isNaN(file.size),
total: file.size,
loaded: data.length
});
setImmediate(() => {
if (this._terminated) {
this._terminated = false;
return;
}
switch (format) {
default:
case "buffer": {
this.result = (new Uint8Array(data)).buffer;
break;
}
case "binaryString": {
this.result = data.toString("binary");
break;
}
case "dataURL": {
// Spec seems very unclear here; see https://github.com/whatwg/fetch/issues/665#issuecomment-362930079.
let dataUrl = "data:";
const contentType = MIMEType.parse(file.type);
if (contentType && contentType.type === "text") {
const fallbackEncoding = whatwgEncoding.getBOMEncoding(data) ||
whatwgEncoding.labelToName(contentType.parameters.get("charset")) || "UTF-8";
const decoded = whatwgEncoding.decode(data, fallbackEncoding);
contentType.parameters.set("charset", encoding);
dataUrl += contentType.toString();
dataUrl += ",";
dataUrl += querystring.escape(decoded);
} else {
if (contentType) {
dataUrl += contentType.toString();
}
dataUrl += ";base64,";
dataUrl += data.toString("base64");
}
this.result = dataUrl;
break;
}
case "text": {
this.result = whatwgEncoding.decode(data, encoding);
break;
}
}
this.readyState = READY_STATES.DONE;
this._fireProgressEvent("load");
this._fireProgressEvent("loadend");
});
});
}
}
setupForSimpleEventAccessors(FileReaderImpl.prototype, events);
exports.implementation = FileReaderImpl;