Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit 254b01e

Browse files
committed
Refactor to create a new FileUtils method
1 parent 4549914 commit 254b01e

4 files changed

Lines changed: 87 additions & 16 deletions

File tree

src/file/FileUtils.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ define(function (require, exports, module) {
3434
require("utils/Global");
3535

3636
var FileSystemError = require("filesystem/FileSystemError"),
37+
LanguageManager = require("language/LanguageManager"),
3738
PerfUtils = require("utils/PerfUtils"),
3839
Dialogs = require("widgets/Dialogs"),
3940
DefaultDialogs = require("widgets/DefaultDialogs"),
@@ -309,6 +310,41 @@ define(function (require, exports, module) {
309310
return baseName.substr(idx + 1);
310311
}
311312

313+
/**
314+
* Get the file extension (excluding ".") given a path OR a bare filename.
315+
* Returns "" for names with no extension.
316+
* If the only `.` in the file is the first character,
317+
* returns "" as this is not considered an extension.
318+
* This method considers known extensions which include `.` in them.
319+
*
320+
* @param {string} fullPath full path to a file or directory
321+
* @return {string} Returns the extension of a filename or empty string if
322+
* the argument is a directory or a filename with no extension
323+
*/
324+
function getSmartFileExtension(fullPath) {
325+
var baseName = getBaseName(fullPath),
326+
parts = baseName.split(".");
327+
328+
// get rid of file name
329+
parts.shift();
330+
if (baseName[0] === ".") {
331+
// if starts with a `.`, then still consider it as file name
332+
parts.shift();
333+
}
334+
335+
// test all other parts of the baseName
336+
while (parts.length > 1) {
337+
var ext = parts.join(".");
338+
if (LanguageManager.getLanguageForExtension(ext)) {
339+
return ext;
340+
} else {
341+
parts.shift();
342+
}
343+
}
344+
345+
return parts[0] || "";
346+
}
347+
312348
/**
313349
* Computes filename as relative to the basePath. For example:
314350
* basePath: /foo/bar/, filename: /foo/bar/baz.txt
@@ -426,5 +462,6 @@ define(function (require, exports, module) {
426462
exports.getBaseName = getBaseName;
427463
exports.getRelativeFilename = getRelativeFilename;
428464
exports.getFileExtension = getFileExtension;
465+
exports.getSmartFileExtension = getSmartFileExtension;
429466
exports.compareFilenames = compareFilenames;
430467
});

src/language/LanguageManager.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,15 @@ define(function (require, exports, module) {
196196
return _languages[id];
197197
}
198198

199+
/**
200+
* Resolves a language to a file extension
201+
* @param {!string} extension Extension that language should be resolved for
202+
* @return {?Language} The language for the provided extension or null if none exists
203+
*/
204+
function getLanguageForExtension(extension) {
205+
return _fileExtensionToLanguageMap[extension.toLowerCase()];
206+
}
207+
199208
/**
200209
* Resolves a file path to a Language object.
201210
* @param {!string} path Path to the file to find a language for
@@ -804,5 +813,6 @@ define(function (require, exports, module) {
804813
exports.ready = _ready;
805814
exports.defineLanguage = defineLanguage;
806815
exports.getLanguage = getLanguage;
816+
exports.getLanguageForExtension = getLanguageForExtension;
807817
exports.getLanguageForPath = getLanguageForPath;
808818
});

src/project/ProjectManager.js

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,22 +1811,12 @@ define(function (require, exports, module) {
18111811
_projectTree.jstree("set_text", $selected, escapedName);
18121812
_projectTree.jstree("rename");
18131813

1814-
var indexOfExtension = escapedName.lastIndexOf("."),
1815-
language = LanguageManager.getLanguageForPath(entry.name);
1816-
if (language) {
1817-
language.getFileExtensions().forEach(function (ext) {
1818-
ext = "." + ext;
1819-
if (escapedName.match(ext + "$")) {
1820-
var io = escapedName.lastIndexOf(ext);
1821-
if (io < indexOfExtension) {
1822-
indexOfExtension = io;
1823-
}
1824-
}
1825-
});
1826-
}
1827-
1828-
if (indexOfExtension > 0) {
1829-
$selected.children(".jstree-rename-input")[0].setSelectionRange(0, indexOfExtension);
1814+
var extension = FileUtils.getSmartFileExtension(entry.name);
1815+
if (extension) {
1816+
var indexOfExtension = escapedName.length - extension.length - 1;
1817+
if (indexOfExtension > 0) {
1818+
$selected.children(".jstree-rename-input")[0].setSelectionRange(0, indexOfExtension);
1819+
}
18301820
}
18311821
});
18321822
// No fail handler: silently no-op if file doesn't exist in tree

test/spec/FileUtils-test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,39 @@ define(function (require, exports, module) {
125125
expect(FileUtils.getFileExtension("foo.bar.baz..jaz.txt")).toBe("txt");
126126
});
127127
});
128+
129+
describe("getSmartFileExtension", function () {
130+
131+
it("should get the extension of a normalized win file path", function () {
132+
expect(FileUtils.getSmartFileExtension("C:/foo/bar/baz.txt")).toBe("txt");
133+
});
134+
135+
it("should get the extension of a posix file path", function () {
136+
expect(FileUtils.getSmartFileExtension("/foo/bar/baz.txt")).toBe("txt");
137+
});
138+
139+
it("should return empty extension for a normalized win directory path", function () {
140+
expect(FileUtils.getSmartFileExtension("C:/foo/bar/")).toBe("");
141+
});
142+
143+
it("should return empty extension for a posix directory path", function () {
144+
expect(FileUtils.getSmartFileExtension("bar")).toBe("");
145+
});
146+
147+
it("should return the extension of a filename containing .", function () {
148+
expect(FileUtils.getSmartFileExtension("C:/foo/bar/.baz/jaz.txt")).toBe("txt");
149+
expect(FileUtils.getSmartFileExtension("foo/bar/baz/.jaz.txt")).toBe("txt");
150+
expect(FileUtils.getSmartFileExtension("foo.bar.baz..jaz.txt")).toBe("txt");
151+
});
152+
153+
it("should return no extension for files with only . as a first character", function () {
154+
expect(FileUtils.getSmartFileExtension("C:/foo/bar/.baz/.jaz")).toBe("");
155+
});
156+
157+
it("should return the extension containing . for known types", function () {
158+
expect(FileUtils.getSmartFileExtension("C:/foo/bar/.baz/jaz.scss.erb")).toBe("scss.erb");
159+
expect(FileUtils.getSmartFileExtension("foo/bar/baz/.jaz.js.erb")).toBe("js.erb");
160+
});
161+
});
128162
});
129163
});

0 commit comments

Comments
 (0)