diff --git a/src-node/package-lock.json b/src-node/package-lock.json index 6183efc95f..2a5b79a17a 100644 --- a/src-node/package-lock.json +++ b/src-node/package-lock.json @@ -1,12 +1,12 @@ { "name": "@phcode/node-core", - "version": "4.1.1-0", + "version": "4.1.2-0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@phcode/node-core", - "version": "4.1.1-0", + "version": "4.1.2-0", "license": "GNU-AGPL3.0", "dependencies": { "@phcode/fs": "^3.0.1", diff --git a/src/project/WorkingSetView.js b/src/project/WorkingSetView.js index 5807d52649..bfa4cb7b95 100644 --- a/src/project/WorkingSetView.js +++ b/src/project/WorkingSetView.js @@ -1001,26 +1001,69 @@ define(function (require, exports, module) { }; /** - * Adds full directory names to elements representing passed files in working tree + * adds the directory name to external project files + * when the directory length is more than 3, we show it in this format: `/.../` + * otherwise the full path * @private - * @param {Array.} filesPathList - list of fullPath strings + * @param {Array.} externalProjectFiles - the list of the external project files */ - WorkingSetView.prototype._addFullDirectoryNamesToWorkingTreeFiles = function (filesPathList) { - // filesList must have at least two files in it for this to make sense - if (!filesPathList.length) { + WorkingSetView.prototype._addDirectoryNameToExternalProjectFiles = function (externalProjectFiles) { + if(!externalProjectFiles.length) { return; } - // Go through open files and add directories to appropriate entries this.$openFilesContainer.find("ul > li").each(function () { const $li = $(this); let filePath = $li.data(_FILE_KEY).fullPath; - const io = filesPathList.indexOf(filePath); + const io = externalProjectFiles.indexOf(filePath); if (io !== -1) { + const displayPath = Phoenix.app.getDisplayPath(filePath); let dirPath = path.dirname(filePath); - dirPath = Phoenix.app.getDisplayPath(dirPath); - const $dir = $(``) - .html(" — " + dirPath); + // this will be displayed on hover GetDisplayPath returns + // windows: C://some/path , linux/mac: /some/path + // a relative path of the form `folder/file.txt` (no-leading slash) for fs access paths- /mnt/paths + // or virtual path if its a browser indexed db - backed path like /fs/virtual/path + const displayDirPath = Phoenix.app.getDisplayPath(dirPath); + + let sep; + if (Phoenix.isNativeApp && brackets.platform === "win") { + sep = "\\"; + } else { + sep = "/"; + } + + // Split the path and filter out empty segments + let dirSplit = displayDirPath.split(sep).filter(segment => segment !== ''); + + let truncatedPath = displayDirPath; // truncatedPath value will be shown in the UI + if (dirSplit.length > 3) { + const rootDirName = dirSplit[0]; + const secondLastSegment = dirSplit[dirSplit.length - 2]; + const lastSeg = dirSplit[dirSplit.length - 1]; + + if (Phoenix.isNativeApp && brackets.platform === "win") { + // Eg: C:\long\path\to\fileDir - > C:\...\to\fileDir -- [rootDirName = c: here] + truncatedPath = `${rootDirName}${sep}\u2026${sep}${secondLastSegment}${sep}${lastSeg}`; + } else if (Phoenix.isNativeApp) { + // an absolute path of the form /abs/path/to/file in linux/mac desktop + // Eg: /application/path/to/fileDir - > /application/.../to/fileDir + truncatedPath = `${sep}${rootDirName}${sep}\u2026${sep}${secondLastSegment}${sep}${lastSeg}`; + } else if (!Phoenix.isNativeApp && !displayDirPath.startsWith('/')){ + // browser fs access path: `folder/fileDir` (no-leading slash) fs access paths- /mnt/paths + // Eg: opened/folder/path/to/fileDir - > opened/.../to/fileDir (no-leading slash) + truncatedPath = `${rootDirName}${sep}\u2026${sep}${secondLastSegment}${sep}${lastSeg}`; + } else { + //this is an internal indexed db backed virtual path. This can only happen if we allow virtual + // project locations from one project to be opened in another. So just print the trim path + // path in this case. In future, when we add this support, the get display path fn should be + // modified to give somethings like what we do for fs access path. + // Eg: /application/path/to/fileDir - > /application/.../to/fileDir + truncatedPath = `${sep}${rootDirName}${sep}\u2026${sep}${secondLastSegment}${sep}${lastSeg}`; + } + } + + const $dir = $(``) + .html(" — " + truncatedPath); $li.children("a").append($dir); } }); @@ -1084,7 +1127,7 @@ define(function (require, exports, module) { } }); - self._addFullDirectoryNamesToWorkingTreeFiles(externalProjectFiles); + self._addDirectoryNameToExternalProjectFiles(externalProjectFiles); // Go through the map and solve the arrays with length over 1. Ignore the rest. _.forEach(map, function (value) { diff --git a/test/spec/WorkingSetView-integ-test.js b/test/spec/WorkingSetView-integ-test.js index 564daa0a9f..de04c7f32b 100644 --- a/test/spec/WorkingSetView-integ-test.js +++ b/test/spec/WorkingSetView-integ-test.js @@ -19,7 +19,7 @@ * */ -/*global describe, it, expect, beforeEach, afterEach, awaitsFor, awaitsForDone, beforeAll, afterAll, awaits */ +/*global describe, it, expect, beforeEach, afterEach, awaitsFor, awaitsForDone, beforeAll, afterAll, awaits, path */ define(function (require, exports, module) { @@ -37,7 +37,7 @@ define(function (require, exports, module) { describe("mainview:WorkingSetView", function () { var testPath = SpecRunnerUtils.getTestPath("/spec/WorkingSetView-test-files"), - externalProjectTestPath = SpecRunnerUtils.getTestPath("/spec/MainViewManager-test-files"), + externalProjectTestPath = SpecRunnerUtils.getTestPath("/spec/MainViewFactory-test-files/css"), testWindow, workingSetListItemCount; @@ -201,7 +201,9 @@ define(function (require, exports, module) { await awaits(ProjectManager._RENDER_DEBOUNCE_TIME + 50); - expect($("#project-files-container ul input").val()).toBe(fileName); + await awaitsFor(function () { + return $("#project-files-container ul input").val() === fileName; + }); }); it("should show a directory name next to the file name when two files with same names are opened", async function () { @@ -226,28 +228,52 @@ define(function (require, exports, module) { expect($list.find(".directory").length).toBe(0); }); - it("should show full path next to the file name when file is outside current project", async function () { - // Count currently opened files - var workingSetListItemCountBeforeTest = workingSetListItemCount; + it("should show ellipsis on external project files", async function () { + // empty the working set + await testWindow.closeAllFiles(); + workingSetListItemCount = 0; + const virtualPath = externalProjectTestPath + "/tablet.css"; + const hoverFullPath = Phoenix.app.getDisplayPath(virtualPath); + + let sep; + if (Phoenix.isNativeApp && brackets.platform === "win") { + sep = "\\"; + } else { + sep = "/"; + } + let dirSplit = Phoenix.app.getDisplayPath(virtualPath).split(sep).filter(segment => segment !== ''); + const root = dirSplit[0]; - // First we need to open another file - await openAndMakeDirty(externalProjectTestPath + "/test.js"); + await openAndMakeDirty(virtualPath); - // Wait for file to be added to the working set - await awaitsFor(function () { return workingSetListItemCount === workingSetListItemCountBeforeTest + 1; }); + // wait for the file to add to the working set + await awaitsFor(function () { return workingSetListItemCount === 1; }, "Open file count to be 1"); - // Two files with the same name file_one.js should be now opened + // get the directory path var $list = testWindow.$(".open-files-container > ul"); - const fullPathSpan = $list.find(".directory"); - expect(fullPathSpan.length).toBe(1); - expect(fullPathSpan[0].innerHTML.includes(Phoenix.app.getDisplayPath(externalProjectTestPath))).toBe(true); + const directorySpan = $list.find(".directory"); + expect(directorySpan.length).toBe(1); + + // get the text from the directory path + const directoryText = directorySpan[0].innerHTML; + + // check if the directory path has ellipsis + expect(directoryText.includes("\u2026")).toBe(true); + if (!Phoenix.isNativeApp) { + expect(directoryText).toBe(' — /test/…/MainViewFactory-test-files/css'); + } else if (brackets.platform === "linux" || brackets.platform === "mac") { + expect(directoryText).toBe(` — /${root}/…/MainViewFactory-test-files/css`); + } else { + // windows + expect(directoryText).toBe(` — ${root}\\…\\MainViewFactory-test-files\\css`); + } - // Now close last opened file to hide the directories again + // the title should contain the full path + expect(directorySpan.attr('title')).toBe(hoverFullPath); + + // Clean up DocumentManager.getCurrentDocument()._markClean(); // so we can close without a save dialog await awaitsForDone(CommandManager.execute(Commands.FILE_CLOSE), "timeout on FILE_CLOSE", 1000); - - // there should be no more directories shown - expect($list.find(".directory").length).toBe(0); }); it("should show different directory names, when two files of the same name are opened, located in folders with same name", async function () {