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

Adds directory names to the files in working tree, ... #4419

Merged
merged 16 commits into from
Aug 6, 2013
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions src/project/WorkingSetView.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ define(function (require, exports, module) {
Commands = require("command/Commands"),
Menus = require("command/Menus"),
FileViewController = require("project/FileViewController"),
CollectionUtils = require("utils/CollectionUtils"),
ViewUtils = require("utils/ViewUtils");


Expand Down Expand Up @@ -88,6 +89,112 @@ define(function (require, exports, module) {
}
}

/**
* Adds directory names to elements representing passed files in working tree
* @private
* @param {Array.<FileEntry>} fileArray
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the @private above the description.
Rename fileArray to filesList and add a description since it kinds of expects FileEntries with the same filenames. Would work with any array of FileEntries but will not do the same stuff.

*/
function _addDirectoryNamesToWorkingTreeFiles(filesList) {
// filesList must have at least two files in it for this to make sense
if (filesList.length <= 1) {
return;
}

// First collect paths from the list of files and fill map with them
var map = {}, filePaths = [], displayPaths = [];
filesList.forEach(function (file, index) {
var fp = file.fullPath.split("/");
fp.pop(); // Remove the filename itself
displayPaths[index] = fp.pop();
filePaths[index] = fp;

if (!map[displayPaths[index]]) {
map[displayPaths[index]] = [index];
} else {
map[displayPaths[index]].push(index);
}
});

// This function is used to loop through map and resolve duplicate names
var processMap = function (map) {
var didSomething = false;
CollectionUtils.forEach(map, function (arr, key) {
// length > 1 means we have duplicates that need to be resolved
if (arr.length > 1) {
arr.forEach(function (index) {
if (filePaths[index].length !== 0) {
displayPaths[index] = filePaths[index].pop() + "/" + displayPaths[index];
didSomething = true;

if (!map[displayPaths[index]]) {
map[displayPaths[index]] = [index];
} else {
map[displayPaths[index]].push(index);
}
}
});
}
delete map[key];
});
return didSomething;
};

var repeat;
do {
repeat = processMap(map);
} while (repeat);

// Go through open files and add directories to appropriate entries
$openFilesContainer.find("ul > li").each(function () {
var $li = $(this);
var io = filesList.indexOf($li.data(_FILE_KEY));
if (io !== -1) {
var dirSplit = displayPaths[io].split("/");
if (dirSplit.length > 3) {
displayPaths[io] = dirSplit[0] + "/\u2026/" + dirSplit[dirSplit.length - 1];
}

var $dir = $("<span class='directory'/>").html(" &mdash; " + displayPaths[io]);
$li.children("a").append($dir);
}
});
}

/**
* Looks for files with the same name in the working set
* and adds a parent directory name to them
* @private
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move @Private above the description

*/
function _checkForDuplicatesInWorkingTree() {
var map = {},
fileList = DocumentManager.getWorkingSet();

// we need to always clear current directories as files could be removed from working tree
$openFilesContainer.find("ul > li > a > span.directory").remove();

// go through files and fill map with arrays of duplicates
fileList.forEach(function (file) {
// use the same function that is used to create html for file
var displayHtml = ViewUtils.getFileEntryDisplay(file);

if (map[displayHtml] === undefined) {
map[displayHtml] = file;
} else {
if (!(map[displayHtml] instanceof Array)) {
map[displayHtml] = [map[displayHtml]];
}
map[displayHtml].push(file);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code (lines 180 to 187) could be simplified to something like:

if (!map[displayHtml]) {
    map[displayHtml] = [];
}
map[displayHtml].push(file);

Then at line 192 just check for value.length > 1.

});

// go through map and solve arrays, ignore rest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better rewording (after the previous change): Go through the map and solve the arrays with length over 1. Ignore the rest.

CollectionUtils.forEach(map, function (value) {
if (value instanceof Array) {
_addDirectoryNamesToWorkingTreeFiles(value);
}
});
}

/**
* @private
* Shows/Hides open files list based on working set content.
Expand All @@ -99,6 +206,7 @@ define(function (require, exports, module) {
} else {
$openFilesContainer.show();
$workingSetHeader.show();
_checkForDuplicatesInWorkingTree();
}
_adjustForScrollbars();
_fireSelectionChanged();
Expand Down
6 changes: 5 additions & 1 deletion src/styles/brackets.less
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,13 @@ a, img {
padding: 3px (@sidebar-triangle-size * 2) 3px 0;

cursor: default;

.directory {
font-size: 11px;
}
}

.extension {
.extension, .directory {
color: @project-panel-text-2;
}
}
Expand Down
Empty file.
78 changes: 69 additions & 9 deletions test/spec/WorkingSetView-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ define(function (require, exports, module) {

var testPath = SpecRunnerUtils.getTestPath("/spec/WorkingSetView-test-files"),
testWindow,
workingSetCount;

workingSetCount;

function openAndMakeDirty(path) {
var doc, didOpen = false, gotError = false;
Expand Down Expand Up @@ -95,7 +94,6 @@ define(function (require, exports, module) {
SpecRunnerUtils.closeTestWindow();
}


beforeFirst(function () {
createTestWindow(this, true);
});
Expand All @@ -116,8 +114,6 @@ define(function (require, exports, module) {
testWindow.closeAllFiles();
});



it("should add a list item when a file is dirtied", function () {
// check if files are added to work set and dirty icons are present
runs(function () {
Expand Down Expand Up @@ -151,7 +147,7 @@ define(function (require, exports, module) {
runs(function () {
var $ = testWindow.$;
var secondItem = $($("#open-files-container > ul").children()[1]);
secondItem.trigger('click');
secondItem.trigger("click");

var $listItems = $("#open-files-container > ul").children();
expect($($listItems[0]).hasClass("selected")).not.toBeTruthy();
Expand Down Expand Up @@ -219,7 +215,7 @@ define(function (require, exports, module) {

// hover over and click on close icon of 2nd list item
var secondItem = $($("#open-files-container > ul").children()[1]);
secondItem.trigger('mouseover');
secondItem.trigger("mouseover");
var closeIcon = secondItem.find(".file-status-icon");
expect(closeIcon.length).toBe(1);

Expand All @@ -228,7 +224,7 @@ define(function (require, exports, module) {
didClose = true;
});

closeIcon.trigger('mousedown');
closeIcon.trigger("mousedown");
});

waitsFor(function () { return didClose; }, "click on working set close icon timeout", 1000);
Expand Down Expand Up @@ -257,7 +253,7 @@ define(function (require, exports, module) {
var $ = testWindow.$;
var secondItem = $("#open-files-container > ul").children().eq(1);
var fileName = secondItem.text();
secondItem.trigger('click');
secondItem.trigger("click");

// Calling FILE_RENAME synchronously works fine here since the item is already visible in project file tree.
// However, if the selected item is not already visible in the tree, this command will complete asynchronously.
Expand All @@ -269,6 +265,70 @@ define(function (require, exports, module) {
expect($projectFileItems.find("a.jstree-clicked").eq(0).siblings("input").eq(0).val()).toBe(fileName);
});
});

it("should show a directory name next to the file name when two files with same names are opened", function () {
runs(function() {
// Count currently opened files
var workingSetCountBeforeTest = workingSetCount;

// First we need to open another file
openAndMakeDirty(testPath + "/directory/file_one.js");

// Wait for file to be added to the working set
waitsFor(function () { return workingSetCount === workingSetCountBeforeTest + 1; }, 1000);

runs(function() {
// Two files with the same name file_one.js should be now opened
var $list = testWindow.$("#open-files-container > ul");
expect($list.find(".directory").length).toBe(2);

// Now close last opened file to hide the directories again
DocumentManager.getCurrentDocument()._markClean(); // so we can close without a save dialog
var didClose = false, gotError = false;
CommandManager.execute(Commands.FILE_CLOSE)
.done(function () { didClose = true; })
.fail(function () { gotError = true; });
waitsFor(function () { return didClose && !gotError; }, "timeout on FILE_CLOSE", 1000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can replace from line 287 to line 291 with:
waitsForDone(CommandManager.execute(Commands.FILE_CLOSE), "timeout on FILE_CLOSE", 1000);


// there should be no more directories shown
runs(function () {
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", function () {
runs(function () {
// Count currently opened files
var workingSetCountBeforeTest = workingSetCount;

// Open both files
openAndMakeDirty(testPath + "/directory/file_one.js");
openAndMakeDirty(testPath + "/directory/directory/file_one.js");

// Wait for them to load
waitsFor(function () { return workingSetCount === workingSetCountBeforeTest + 2; }, 1000);

runs(function() {
// Collect all directory names displayed
var $list = testWindow.$("#open-files-container > ul");
var names = $list.find(".directory").map(function () {
return $(this).text();
}).toArray();

// All directory names should be unique
var uniq = 0, map = {};
names.forEach(function(name) {
if (!map[name]) {
map[name] = true;
uniq++;
}
});
expect(uniq).toBe(names.length);
});
});
});

});
});