summaryrefslogtreecommitdiffstats
path: root/browser/components/screenshots/fileHelpers.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/screenshots/fileHelpers.mjs')
-rw-r--r--browser/components/screenshots/fileHelpers.mjs67
1 files changed, 44 insertions, 23 deletions
diff --git a/browser/components/screenshots/fileHelpers.mjs b/browser/components/screenshots/fileHelpers.mjs
index 4fd2e77561..f416ca195a 100644
--- a/browser/components/screenshots/fileHelpers.mjs
+++ b/browser/components/screenshots/fileHelpers.mjs
@@ -7,11 +7,15 @@ const { AppConstants } = ChromeUtils.importESModule(
);
const lazy = {};
+// The maximum length of a pathanme - calculated as MAX_PATH minus the null terminator character
+export const MAX_PATHNAME = AppConstants.platform == "win" ? 259 : 1023;
+export const MAX_LEAFNAME = MAX_PATHNAME - 32;
+export const FALLBACK_MAX_LEAFNAME = 64;
ChromeUtils.defineESModuleGetters(lazy, {
+ Downloads: "resource://gre/modules/Downloads.sys.mjs",
DownloadLastDir: "resource://gre/modules/DownloadLastDir.sys.mjs",
DownloadPaths: "resource://gre/modules/DownloadPaths.sys.mjs",
- Downloads: "resource://gre/modules/Downloads.sys.mjs",
FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
ScreenshotsUtils: "resource:///modules/ScreenshotsUtils.sys.mjs",
});
@@ -29,6 +33,15 @@ export async function getFilename(filenameTitle, browser) {
);
}
const date = new Date();
+ const knownDownloadsDir = await getDownloadDirectory();
+ // if we know the download directory, we can subtract that plus the separator from MAX_PATHNAME to get a length limit
+ // otherwise we just use a conservative length
+ const maxFilenameLength = Math.min(
+ knownDownloadsDir
+ ? MAX_PATHNAME - new Blob([knownDownloadsDir]).size - 1
+ : FALLBACK_MAX_LEAFNAME,
+ MAX_LEAFNAME
+ );
/* eslint-disable no-control-regex */
filenameTitle = filenameTitle
.replace(/[\\/]/g, "_")
@@ -44,43 +57,37 @@ export async function getFilename(filenameTitle, browser) {
const filenameTime = currentDateTime.substring(11, 19).replace(/:/g, "-");
let clipFilename = `Screenshot ${filenameDate} at ${filenameTime} ${filenameTitle}`;
- // Crop the filename size at less than 246 bytes, so as to leave
+ // allow space for a potential ellipsis and the extension
+ let maxNameStemLength = maxFilenameLength - "[...].png".length;
+
+ // Crop the filename size so as to leave
// room for the extension and an ellipsis [...]. Note that JS
// strings are UTF16 but the filename will be converted to UTF8
// when saving which could take up more space, and we want a
- // maximum of 255 bytes (not characters). Here, we iterate
+ // maximum of maxFilenameLength bytes (not characters). Here, we iterate
// and crop at shorter and shorter points until we fit into
- // 255 bytes.
+ // our max number of bytes.
let suffix = "";
- for (let cropSize = 246; cropSize >= 0; cropSize -= 32) {
- if (new Blob([clipFilename]).size > 246) {
+ for (let cropSize = maxNameStemLength; cropSize >= 0; cropSize -= 32) {
+ if (new Blob([clipFilename]).size > maxNameStemLength) {
clipFilename = clipFilename.substring(0, cropSize);
suffix = "[...]";
} else {
break;
}
}
-
clipFilename += suffix;
let extension = ".png";
let filename = clipFilename + extension;
- let useDownloadDir = Services.prefs.getBoolPref(
- "browser.download.useDownloadDir"
- );
- if (useDownloadDir) {
- const downloadsDir = await lazy.Downloads.getPreferredDownloadsDirectory();
- const downloadsDirExists = await IOUtils.exists(downloadsDir);
- if (downloadsDirExists) {
- // If filename is absolute, it will override the downloads directory and
- // still be applied as expected.
- filename = PathUtils.join(downloadsDir, filename);
- }
+ if (knownDownloadsDir) {
+ // If filename is absolute, it will override the downloads directory and
+ // still be applied as expected.
+ filename = PathUtils.join(knownDownloadsDir, filename);
} else {
let fileInfo = new FileInfo(filename);
let file;
-
let fpParams = {
fpTitleKey: "SaveImageTitle",
fileInfo,
@@ -88,16 +95,30 @@ export async function getFilename(filenameTitle, browser) {
saveAsType: 0,
file,
};
-
let accepted = await promiseTargetFile(fpParams, browser.ownerGlobal);
if (!accepted) {
- return null;
+ return { filename: null, accepted };
}
-
filename = fpParams.file.path;
}
+ return { filename, accepted: true };
+}
- return filename;
+/**
+ * Gets the path to the download directory if "browser.download.useDownloadDir" is true
+ * @returns Path to download directory or null if not available
+ */
+export async function getDownloadDirectory() {
+ let useDownloadDir = Services.prefs.getBoolPref(
+ "browser.download.useDownloadDir"
+ );
+ if (useDownloadDir) {
+ const downloadsDir = await lazy.Downloads.getPreferredDownloadsDirectory();
+ if (await IOUtils.exists(downloadsDir)) {
+ return downloadsDir;
+ }
+ }
+ return null;
}
// The below functions are a modified copy from toolkit/content/contentAreaUtils.js