|
@@ -33,9 +33,13 @@ this.singlefile.lib.util = this.singlefile.lib.util || (() => {
|
|
|
const DOMParser = window.DOMParser;
|
|
const DOMParser = window.DOMParser;
|
|
|
const Blob = window.Blob;
|
|
const Blob = window.Blob;
|
|
|
const FileReader = window.FileReader;
|
|
const FileReader = window.FileReader;
|
|
|
|
|
+ const fetch = window.fetch;
|
|
|
|
|
+ const crypto = window.crypto;
|
|
|
|
|
+ const TextDecoder = window.TextDecoder;
|
|
|
|
|
+ const TextEncoder = window.TextEncoder;
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
|
- getInstance: (modules, util) => {
|
|
|
|
|
|
|
+ getInstance: (modules, utilOptions) => {
|
|
|
if (modules.serializer === undefined) {
|
|
if (modules.serializer === undefined) {
|
|
|
modules.serializer = {
|
|
modules.serializer = {
|
|
|
process(doc) {
|
|
process(doc) {
|
|
@@ -58,6 +62,8 @@ this.singlefile.lib.util = this.singlefile.lib.util || (() => {
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ utilOptions = utilOptions || {};
|
|
|
|
|
+ utilOptions.fetch = utilOptions.fetch || fetch;
|
|
|
return {
|
|
return {
|
|
|
getContent,
|
|
getContent,
|
|
|
parseURL(resourceURL, baseURI) {
|
|
parseURL(resourceURL, baseURI) {
|
|
@@ -106,7 +112,8 @@ this.singlefile.lib.util = this.singlefile.lib.util || (() => {
|
|
|
return (new DOMParser()).parseFromString(content, "image/svg+xml");
|
|
return (new DOMParser()).parseFromString(content, "image/svg+xml");
|
|
|
},
|
|
},
|
|
|
async digest(algo, text) {
|
|
async digest(algo, text) {
|
|
|
- return util.digestText(algo, text);
|
|
|
|
|
|
|
+ const hash = await crypto.subtle.digest(algo, new TextEncoder("utf-8").encode(text));
|
|
|
|
|
+ return hex(hash);
|
|
|
},
|
|
},
|
|
|
getContentSize(content) {
|
|
getContentSize(content) {
|
|
|
return new Blob([content]).size;
|
|
return new Blob([content]).size;
|
|
@@ -187,7 +194,7 @@ this.singlefile.lib.util = this.singlefile.lib.util || (() => {
|
|
|
log(" // STARTED download url =", resourceURL, "asBinary =", options.asBinary);
|
|
log(" // STARTED download url =", resourceURL, "asBinary =", options.asBinary);
|
|
|
}
|
|
}
|
|
|
try {
|
|
try {
|
|
|
- resourceContent = await util.getResourceContent(resourceURL);
|
|
|
|
|
|
|
+ resourceContent = await getResourceContent(resourceURL, utilOptions.fetch);
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
return { data: options.asBinary ? "data:base64," : "", resourceURL };
|
|
return { data: options.asBinary ? "data:base64," : "", resourceURL };
|
|
|
}
|
|
}
|
|
@@ -251,10 +258,53 @@ this.singlefile.lib.util = this.singlefile.lib.util || (() => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ async function getResourceContent(resourceURL, fetchResource) {
|
|
|
|
|
+ const resourceContent = await fetchResource(resourceURL);
|
|
|
|
|
+ const buffer = await resourceContent.arrayBuffer();
|
|
|
|
|
+ return {
|
|
|
|
|
+ getUrl() {
|
|
|
|
|
+ return resourceContent.url || resourceURL;
|
|
|
|
|
+ },
|
|
|
|
|
+ getContentType() {
|
|
|
|
|
+ return resourceContent.headers && resourceContent.headers.get("content-type");
|
|
|
|
|
+ },
|
|
|
|
|
+ getStatusCode() {
|
|
|
|
|
+ return resourceContent.status;
|
|
|
|
|
+ },
|
|
|
|
|
+ getSize() {
|
|
|
|
|
+ return buffer.byteLength;
|
|
|
|
|
+ },
|
|
|
|
|
+ getText(charset) {
|
|
|
|
|
+ return new TextDecoder(charset).decode(buffer);
|
|
|
|
|
+ },
|
|
|
|
|
+ async getDataUri(contentType) {
|
|
|
|
|
+ const reader = new FileReader();
|
|
|
|
|
+ reader.readAsDataURL(new Blob([buffer], { type: contentType || this.getContentType() }));
|
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
|
+ reader.addEventListener("load", () => resolve(reader.result), false);
|
|
|
|
|
+ reader.addEventListener("error", reject, false);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
|
|
|
|
|
+ function hex(buffer) {
|
|
|
|
|
+ const hexCodes = [];
|
|
|
|
|
+ const view = new DataView(buffer);
|
|
|
|
|
+ for (let i = 0; i < view.byteLength; i += 4) {
|
|
|
|
|
+ const value = view.getUint32(i);
|
|
|
|
|
+ const stringValue = value.toString(16);
|
|
|
|
|
+ const padding = "00000000";
|
|
|
|
|
+ const paddedValue = (padding + stringValue).slice(-padding.length);
|
|
|
|
|
+ hexCodes.push(paddedValue);
|
|
|
|
|
+ }
|
|
|
|
|
+ return hexCodes.join("");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
function log(...args) {
|
|
function log(...args) {
|
|
|
console.log("S-File <browser>", ...args); // eslint-disable-line no-console
|
|
console.log("S-File <browser>", ...args); // eslint-disable-line no-console
|
|
|
}
|
|
}
|