|
@@ -787,56 +787,37 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
let filename = options.filenameTemplate;
|
|
let filename = options.filenameTemplate;
|
|
|
const date = new Date();
|
|
const date = new Date();
|
|
|
const url = new URL(options.url);
|
|
const url = new URL(options.url);
|
|
|
- filename = filename.replace(/{\s*title\s*}/g, options.title.replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*iso-datetime\s*}/g, date.toISOString().replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*iso-date\s*}/g, date.toISOString().split("T")[0].replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*iso-time\s*}/g, date.toISOString().split("T")[1].split("Z")[0].replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*locale-date\s*}/g, date.toLocaleDateString().replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*locale-time\s*}/g, date.toLocaleTimeString().replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*locale-day\s*}/g, String(date.getDate()).replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*locale-month\s*}/g, String(date.getMonth() + 1).replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*locale-year\s*}/g, String(date.getFullYear()).replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*locale-datetime\s*}/g, date.toLocaleString().replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*utc-datetime\s*}/g, date.toUTCString().replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*utc-day\s*}/g, String(date.getUTCDate()).replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*utc-month\s*}/g, String(date.getUTCMonth() + 1).replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*utc-year\s*}/g, String(date.getUTCFullYear()).replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*url-hash\s*}/g, url.hash.substring(1).replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*url-host\s*}/g, url.host.replace(/\/+/g, "_").replace(/\/$/, ""));
|
|
|
|
|
- filename = filename.replace(/{\s*url-hostname\s*}/g, url.hostname.replace(/\/+/g, "_").replace(/\/$/, ""));
|
|
|
|
|
- filename = filename.replace(/{\s*url-href\s*}/g, url.href.replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*url-password\s*}/g, url.password.replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*url-pathname\s*}/g, url.pathname.replace(/\/+/g, "_").replace(/\/$/, "").replace(/^\//, ""));
|
|
|
|
|
- filename = filename.replace(/{\s*url-port\s*}/g, url.port.replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*url-protocol\s*}/g, url.protocol.replace(/\/+/g, "_").replace(/\/$/, ""));
|
|
|
|
|
- filename = filename.replace(/{\s*url-search\s*}/g, url.search.substring(1).replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*url-username\s*}/g, url.username.replace(/\/+/g, "_"));
|
|
|
|
|
- filename = filename.replace(/{\s*tab-id\s*}/g, String(options.tabId || "unknown"));
|
|
|
|
|
- let lastSegmentMatch = url.pathname.match(/\/([^/]+)$/);
|
|
|
|
|
- let lastSegment = lastSegmentMatch && lastSegmentMatch[0];
|
|
|
|
|
- if (!lastSegment) {
|
|
|
|
|
- lastSegmentMatch = url.href.match(/([^/]+)\/?$/);
|
|
|
|
|
- lastSegment = lastSegmentMatch && lastSegmentMatch[0];
|
|
|
|
|
- }
|
|
|
|
|
- if (!lastSegment) {
|
|
|
|
|
- lastSegmentMatch = lastSegment.match(/(.*)<\.[^.]+$/);
|
|
|
|
|
- lastSegment = lastSegmentMatch && lastSegmentMatch[0];
|
|
|
|
|
- }
|
|
|
|
|
- if (!lastSegment) {
|
|
|
|
|
- lastSegment = url.hostname.replace(/\/+/g, "_").replace(/\/$/, "");
|
|
|
|
|
- }
|
|
|
|
|
- filename = filename.replace(/{\s*url-last-segment\s*}/g, lastSegment.replace(/\/+/g, "").replace(/\/$/, "").replace(/^\//, ""));
|
|
|
|
|
- if (filename.match(/{\s*digest-sha-256\s*}/g)) {
|
|
|
|
|
- filename = filename.replace(/{\s*digest-sha-256\s*}/g, await DOM.digest("SHA-256", content));
|
|
|
|
|
- }
|
|
|
|
|
- if (filename.match(/{\s*digest-sha-384\s*}/g)) {
|
|
|
|
|
- filename = filename.replace(/{\s*digest-sha-384\s*}/g, await DOM.digest("SHA-384", content));
|
|
|
|
|
- }
|
|
|
|
|
- if (filename.match(/{\s*digest-sha-512\s*}/g)) {
|
|
|
|
|
- filename = filename.replace(/{\s*digest-sha-512\s*}/g, await DOM.digest("SHA-512", content));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "page-title", () => options.title);
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "datetime-iso", () => date.toISOString());
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "date-iso", () => date.toISOString().split("T")[0]);
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "time-iso", () => date.toISOString().split("T")[1].split("Z")[0]);
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "date-locale", () => date.toLocaleDateString());
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "time-locale", () => date.toLocaleTimeString());
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "day-locale", () => String(date.getDate()));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "month-locale", () => String(date.getMonth()));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "year-locale", () => String(date.getFullYear()));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "datetime-locale", () => date.toLocaleString());
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "datetime-utc", () => date.toUTCString());
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "day-utc", () => String(date.getUTCDate()));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "month-utc", () => String(date.getUTCMonth()));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "year-utc", () => String(date.getUTCFullYear()));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "url-hash", () => url.hash.substring(1));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "url-host", () => url.host.replace(/\/$/, ""));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "url-hostname", () => url.hostname.replace(/\/$/, ""));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "url-href", () => url.href);
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "url-password", () => url.password);
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "url-pathname", () => url.pathname.replace(/^\//, "").replace(/\/$/, ""), true);
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "url-port", () => url.port);
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "url-protocol", () => url.protocol);
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "url-search", () => url.search.substring(1));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "url-username", () => url.username);
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "tab-id", () => String(options.tabId || ""));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "url-last-segment", () => DomUtil.getLastSegment(url));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "digest-sha-256", async () => DOM.digest("SHA-256", content));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "digest-sha-384", async () => DOM.digest("SHA-384", content));
|
|
|
|
|
+ filename = await DomUtil.evalTemplateVariable(filename, "digest-sha-512", async () => DOM.digest("SHA-512", content));
|
|
|
filename = filename.replace(/[~\\?%*:|"<>\x00-\x1f\x7F]+/g, "_"); // eslint-disable-line no-control-regex
|
|
filename = filename.replace(/[~\\?%*:|"<>\x00-\x1f\x7F]+/g, "_"); // eslint-disable-line no-control-regex
|
|
|
- filename = filename.replace(/\.\.\/?/g, "").replace(/^\/+/, "");
|
|
|
|
|
|
|
+ filename = filename.replace(/\.\.\//g, "").replace(/^\/+/, "");
|
|
|
if (filename.length > 192) {
|
|
if (filename.length > 192) {
|
|
|
const extensionMatch = filename.match(/(\.[^.]{3,4})$/);
|
|
const extensionMatch = filename.match(/(\.[^.]{3,4})$/);
|
|
|
const extension = extensionMatch && extensionMatch[0] && extensionMatch[0].length > 1 ? extensionMatch[0] : "";
|
|
const extension = extensionMatch && extensionMatch[0] && extensionMatch[0].length > 1 ? extensionMatch[0] : "";
|
|
@@ -1077,6 +1058,36 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ static async evalTemplateVariable(template, variableName, valueGetter, dontReplaceSlash) {
|
|
|
|
|
+ const replaceRegExp = new RegExp("{\\s*" + variableName + "\\s*}", "g");
|
|
|
|
|
+ if (template.match(replaceRegExp)) {
|
|
|
|
|
+ let value = await valueGetter();
|
|
|
|
|
+ if (!dontReplaceSlash) {
|
|
|
|
|
+ value = value.replace(/\/+/g, "_");
|
|
|
|
|
+ }
|
|
|
|
|
+ return template.replace(replaceRegExp, value);
|
|
|
|
|
+ }
|
|
|
|
|
+ return template;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ static getLastSegment(url) {
|
|
|
|
|
+ let lastSegmentMatch = url.pathname.match(/\/([^/]+)$/);
|
|
|
|
|
+ let lastSegment = lastSegmentMatch && lastSegmentMatch[0];
|
|
|
|
|
+ if (!lastSegment) {
|
|
|
|
|
+ lastSegmentMatch = url.href.match(/([^/]+)\/?$/);
|
|
|
|
|
+ lastSegment = lastSegmentMatch && lastSegmentMatch[0];
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!lastSegment) {
|
|
|
|
|
+ lastSegmentMatch = lastSegment.match(/(.*)<\.[^.]+$/);
|
|
|
|
|
+ lastSegment = lastSegmentMatch && lastSegmentMatch[0];
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!lastSegment) {
|
|
|
|
|
+ lastSegment = url.hostname.replace(/\/+/g, "_").replace(/\/$/, "");
|
|
|
|
|
+ }
|
|
|
|
|
+ lastSegment.replace(/\/$/, "").replace(/^\//, "");
|
|
|
|
|
+ return lastSegment;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
static getRegExp(string) {
|
|
static getRegExp(string) {
|
|
|
return new RegExp(string.replace(REGEXP_ESCAPE, "\\$1"), "gi");
|
|
return new RegExp(string.replace(REGEXP_ESCAPE, "\\$1"), "gi");
|
|
|
}
|
|
}
|