|
|
@@ -448,15 +448,24 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
|
|
|
this.stats.add("discarded", "HTML bytes", size - contentSize);
|
|
|
}
|
|
|
let filename = await ProcessorHelper.evalTemplate(this.options.filenameTemplate, this.options, content) || "";
|
|
|
- filename = filename.replace(/[~\\?%*:|"<>\x00-\x1f\x7F]+/g, "_"); // eslint-disable-line no-control-regex
|
|
|
- filename = filename.replace(/\.\.\//g, "").replace(/^\/+/, "").replace(/\/+/g, "/").replace(/\/$/, "").replace(/\.$/, "").replace(/\.\//g, "._").replace(/\/\./g, "/_");
|
|
|
+ const replacementCharacter = this.options.filenameReplacementCharacter;
|
|
|
+ filename = filename
|
|
|
+ .replace(/[~\\?%*:|"<>\x00-\x1f\x7F]+/g, replacementCharacter); // eslint-disable-line no-control-regex
|
|
|
+ filename = filename
|
|
|
+ .replace(/\.\.\//g, "")
|
|
|
+ .replace(/^\/+/, "")
|
|
|
+ .replace(/\/+/g, "/")
|
|
|
+ .replace(/\/$/, "")
|
|
|
+ .replace(/\.$/, "")
|
|
|
+ .replace(/\.\//g, "." + replacementCharacter)
|
|
|
+ .replace(/\/\./g, "/" + replacementCharacter);
|
|
|
if (!this.options.backgroundSave) {
|
|
|
- filename = filename.replace(/\//g, "_");
|
|
|
+ filename = filename.replace(/\//g, replacementCharacter);
|
|
|
}
|
|
|
- if (util.getContentSize(filename) > 192) {
|
|
|
+ if (util.getContentSize(filename) > this.options.filenameMaxLength) {
|
|
|
const extensionMatch = filename.match(/(\.[^.]{3,4})$/);
|
|
|
const extension = extensionMatch && extensionMatch[0] && extensionMatch[0].length > 1 ? extensionMatch[0] : "";
|
|
|
- filename = await util.truncateText(filename, 192 - extension.length);
|
|
|
+ filename = await util.truncateText(filename, this.options.filenameMaxLength - extension.length);
|
|
|
filename = filename + "…" + extension;
|
|
|
}
|
|
|
if (!filename) {
|
|
|
@@ -1249,7 +1258,7 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
|
|
|
template = await Util.evalTemplateVariable(template, "url-username", () => url.username || "No username", dontReplaceSlash);
|
|
|
template = await Util.evalTemplateVariable(template, "tab-id", () => String(options.tabId || "No tab id"), dontReplaceSlash);
|
|
|
template = await Util.evalTemplateVariable(template, "tab-index", () => String(options.tabIndex || "No tab index"), dontReplaceSlash);
|
|
|
- template = await Util.evalTemplateVariable(template, "url-last-segment", () => decodeURI(Util.getLastSegment(url)) || "No last segment", dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-last-segment", () => decodeURI(Util.getLastSegment(url, options.filenameReplacementCharacter)) || "No last segment", dontReplaceSlash);
|
|
|
if (content) {
|
|
|
template = await Util.evalTemplateVariable(template, "digest-sha-256", async () => util.digest("SHA-256", content), dontReplaceSlash);
|
|
|
template = await Util.evalTemplateVariable(template, "digest-sha-384", async () => util.digest("SHA-384", content), dontReplaceSlash);
|
|
|
@@ -1672,19 +1681,19 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
|
|
|
return attributeNames;
|
|
|
}
|
|
|
|
|
|
- static async evalTemplateVariable(template, variableName, valueGetter, dontReplaceSlash) {
|
|
|
+ static async evalTemplateVariable(template, variableName, valueGetter, dontReplaceSlash, replacementCharacter) {
|
|
|
const replaceRegExp = new RegExp("{\\s*" + variableName + "\\s*}", "g");
|
|
|
if (template && template.match(replaceRegExp)) {
|
|
|
let value = await valueGetter();
|
|
|
if (!dontReplaceSlash) {
|
|
|
- value = value.replace(/\/+/g, "_");
|
|
|
+ value = value.replace(/\/+/g, replacementCharacter);
|
|
|
}
|
|
|
return template.replace(replaceRegExp, value);
|
|
|
}
|
|
|
return template;
|
|
|
}
|
|
|
|
|
|
- static getLastSegment(url) {
|
|
|
+ static getLastSegment(url, replacementCharacter) {
|
|
|
let lastSegmentMatch = url.pathname.match(/\/([^/]+)$/), lastSegment = lastSegmentMatch && lastSegmentMatch[0];
|
|
|
if (!lastSegment) {
|
|
|
lastSegmentMatch = url.href.match(/([^/]+)\/?$/);
|
|
|
@@ -1695,7 +1704,7 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
|
|
|
lastSegment = lastSegmentMatch && lastSegmentMatch[0];
|
|
|
}
|
|
|
if (!lastSegment) {
|
|
|
- lastSegment = url.hostname.replace(/\/+/g, "_").replace(/\/$/, "");
|
|
|
+ lastSegment = url.hostname.replace(/\/+/g, replacementCharacter).replace(/\/$/, "");
|
|
|
}
|
|
|
lastSegmentMatch = lastSegment.match(/(.*)\.[^.]+$/);
|
|
|
if (lastSegmentMatch && lastSegmentMatch[1]) {
|