diff --git a/chrome/content/zotero/xpcom/file.js b/chrome/content/zotero/xpcom/file.js index 9d05876f1e..9405af4c73 100644 --- a/chrome/content/zotero/xpcom/file.js +++ b/chrome/content/zotero/xpcom/file.js @@ -32,7 +32,6 @@ Zotero.File = new function(){ Components.utils.import("resource://gre/modules/FileUtils.jsm"); this.getExtension = getExtension; - this.getClosestDirectory = getClosestDirectory; this.getContentsFromURL = getContentsFromURL; this.putContents = putContents; this.getValidFileName = getValidFileName; @@ -88,21 +87,31 @@ Zotero.File = new function(){ } - /* + /** * Traverses up the filesystem from a file until it finds an existing * directory, or false if it hits the root */ - function getClosestDirectory(file) { - var dir = file.parent; - - while (dir && !dir.exists()) { - var dir = dir.parent; + this.getClosestDirectory = async function (file) { + try { + let stat = await OS.File.stat(file); + // If file is an existing directory, return it + if (stat.isDir) { + return file; + } + } + catch (e) { + if (e.becauseNoSuchFile) {} + else { + throw e; + } } - if (dir && dir.exists()) { - return dir; + var dir = OS.Path.dirname(file); + while (dir && !await OS.File.exists(dir)) { + dir = OS.Path.dirname(dir); } - return false; + + return dir || false; } diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js index 49a62c00cb..fd28cc62a5 100644 --- a/chrome/content/zotero/zoteroPane.js +++ b/chrome/content/zotero/zoteroPane.js @@ -4569,10 +4569,10 @@ var ZoteroPane = new function() Zotero.debug("Invalid path", 2); break; } - var dir = Zotero.File.getClosestDirectory(file); + + var dir = yield Zotero.File.getClosestDirectory(file); if (dir) { - dir.QueryInterface(Components.interfaces.nsILocalFile); - fp.displayDirectory = dir; + fp.displayDirectory = Zotero.File.pathToFile(dir); } fp.appendFilters(Components.interfaces.nsIFilePicker.filterAll); diff --git a/test/tests/fileTest.js b/test/tests/fileTest.js index 939076c529..8568d7f813 100644 --- a/test/tests/fileTest.js +++ b/test/tests/fileTest.js @@ -96,6 +96,32 @@ describe("Zotero.File", function () { }); }); + + describe("#getClosestDirectory()", function () { + it("should return directory for file that exists", function* () { + var tmpDir = yield getTempDirectory(); + var closest = yield Zotero.File.getClosestDirectory(tmpDir); + assert.equal(closest, tmpDir); + }); + + it("should return parent directory for missing file", function* () { + var tmpDir = yield getTempDirectory(); + var closest = yield Zotero.File.getClosestDirectory(OS.Path.join(tmpDir, 'a')); + assert.equal(closest, tmpDir); + }); + + it("should find an existing directory three levels up from a missing file", function* () { + var tmpDir = yield getTempDirectory(); + var closest = yield Zotero.File.getClosestDirectory(OS.Path.join(tmpDir, 'a', 'b', 'c')); + assert.equal(closest, tmpDir); + }); + + it("should return false for a path that doesn't exist at all", function* () { + assert.isFalse(yield Zotero.File.getClosestDirectory('/a/b/c')); + }); + }); + + describe("#copyDirectory()", function () { it("should copy all files within a directory", function* () { var tmpDir = Zotero.getTempDirectory().path;