gecko/toolkit/mozapps/downloads/DownloadPaths.jsm
Jim Blandy 4d6a633bba Bug 914753: Make Emacs file variable header lines correct, or at least consistent. DONTBUILD r=ehsan
The -*- file variable lines -*- establish per-file settings that Emacs will
pick up. This patch makes the following changes to those lines (and touches
nothing else):

 - Never set the buffer's mode.

   Years ago, Emacs did not have a good JavaScript mode, so it made sense
   to use Java or C++ mode in .js files. However, Emacs has had js-mode for
   years now; it's perfectly serviceable, and is available and enabled by
   default in all major Emacs packagings.

   Selecting a mode in the -*- file variable line -*- is almost always the
   wrong thing to do anyway. It overrides Emacs's default choice, which is
   (now) reasonable; and even worse, it overrides settings the user might
   have made in their '.emacs' file for that file extension. It's only
   useful when there's something specific about that particular file that
   makes a particular mode appropriate.

 - Correctly propagate settings that establish the correct indentation
   level for this file: c-basic-offset and js2-basic-offset should be
   js-indent-level. Whatever value they're given should be preserved;
   different parts of our tree use different indentation styles.

 - We don't use tabs in Mozilla JS code. Always set indent-tabs-mode: nil.
   Remove tab-width: settings, at least in files that don't contain tab
   characters.

 - Remove js2-mode settings that belong in the user's .emacs file, like
   js2-skip-preprocessor-directives.
2014-06-24 22:12:07 -07:00

90 lines
3.9 KiB
JavaScript

/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
this.EXPORTED_SYMBOLS = [
"DownloadPaths",
];
/**
* This module provides the DownloadPaths object which contains methods for
* giving names and paths to files being downloaded.
*
* List of methods:
*
* nsILocalFile
* createNiceUniqueFile(nsILocalFile aLocalFile)
*
* [string base, string ext]
* splitBaseNameAndExtension(string aLeafName)
*/
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
this.DownloadPaths = {
/**
* Creates a uniquely-named file starting from the name of the provided file.
* If a file with the provided name already exists, the function attempts to
* create nice alternatives, like "base(1).ext" (instead of "base-1.ext").
*
* If a unique name cannot be found, the function throws the XPCOM exception
* NS_ERROR_FILE_TOO_BIG. Other exceptions, like NS_ERROR_FILE_ACCESS_DENIED,
* can also be expected.
*
* @param aTemplateFile
* nsILocalFile whose leaf name is going to be used as a template. The
* provided object is not modified.
* @returns A new instance of an nsILocalFile object pointing to the newly
* created empty file. On platforms that support permission bits, the
* file is created with permissions 644.
*/
createNiceUniqueFile: function DP_createNiceUniqueFile(aTemplateFile) {
// Work on a clone of the provided template file object.
var curFile = aTemplateFile.clone().QueryInterface(Ci.nsILocalFile);
var [base, ext] = DownloadPaths.splitBaseNameAndExtension(curFile.leafName);
// Try other file names, for example "base(1).txt" or "base(1).tar.gz",
// only if the file name initially set already exists.
for (let i = 1; i < 10000 && curFile.exists(); i++) {
curFile.leafName = base + "(" + i + ")" + ext;
}
// At this point we hand off control to createUnique, which will create the
// file with the name we chose, if it is valid. If not, createUnique will
// attempt to modify it again, for example it will shorten very long names
// that can't be created on some platforms, and for which a normal call to
// nsIFile.create would result in NS_ERROR_FILE_NOT_FOUND. This can result
// very rarely in strange names like "base(9999).tar-1.gz" or "ba-1.gz".
curFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0644);
return curFile;
},
/**
* Separates the base name from the extension in a file name, recognizing some
* double extensions like ".tar.gz".
*
* @param aLeafName
* The full leaf name to be parsed. Be careful when processing names
* containing leading or trailing dots or spaces.
* @returns [base, ext]
* The base name of the file, which can be empty, and its extension,
* which always includes the leading dot unless it's an empty string.
* Concatenating the two items always results in the original name.
*/
splitBaseNameAndExtension: function DP_splitBaseNameAndExtension(aLeafName) {
// The following regular expression is built from these key parts:
// .*? Matches the base name non-greedily.
// \.[A-Z0-9]{1,3} Up to three letters or numbers preceding a
// double extension.
// \.(?:gz|bz2|Z) The second part of common double extensions.
// \.[^.]* Matches any extension or a single trailing dot.
var [, base, ext] = /(.*?)(\.[A-Z0-9]{1,3}\.(?:gz|bz2|Z)|\.[^.]*)?$/i
.exec(aLeafName);
// Return an empty string instead of undefined if no extension is found.
return [base, ext || ""];
}
};