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

Prevent prefix based conflicts when renaming #2914

Merged
merged 2 commits into from
Feb 26, 2013
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 4 additions & 4 deletions src/document/DocumentManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -1156,16 +1156,16 @@ define(function (require, exports, module) {
var keysToDelete = [];
for (path in _openDocuments) {
if (_openDocuments.hasOwnProperty(path)) {
if (path.indexOf(oldName) === 0) {
if (FileUtils.isAffectedWhenRenaming(path, oldName, newName, isFolder)) {
// Copy value to new key
var newKey = path.replace(oldName, newName);

_openDocuments[newKey] = _openDocuments[path];
keysToDelete.push(path);

// Update document file
FileUtils.updateFileEntryPath(_openDocuments[newKey].file, oldName, newName);
FileUtils.updateFileEntryPath(_openDocuments[newKey].file, oldName, newName, isFolder);

if (!isFolder) {
// If the path name is a file, there can only be one matched entry in the open document
// list, which we just updated. Break out of the for .. in loop.
Expand All @@ -1181,7 +1181,7 @@ define(function (require, exports, module) {

// Update working set
for (i = 0; i < _workingSet.length; i++) {
FileUtils.updateFileEntryPath(_workingSet[i], oldName, newName);
FileUtils.updateFileEntryPath(_workingSet[i], oldName, newName, isFolder);
}

// Send a "fileNameChanged" event. This will trigger the views to update.
Expand Down
23 changes: 20 additions & 3 deletions src/file/FileUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,14 +248,30 @@ define(function (require, exports, module) {
}

/**
* Checks wheter a path is affected by a rename operation.
* A path is affected if the object being renamed is a file and the given path refers
* to that file or if the object being renamed is a directory and a prefix of the path.
* Always checking for prefixes can create conflicts:
* renaming file "foo" should not affect file "foobar/baz" even though "foo" is a prefix of "foobar".
* @param {!string} path The path potentially affected
* @param {!string} oldName An object's name before renaming
* @param {!string} newName An object's name after renaming
* @param {?boolean} isFolder Whether the renamed object is a folder or not
*/
function isAffectedWhenRenaming(path, oldName, newName, isFolder) {
isFolder = isFolder || oldName.slice(-1) === "/";
return (isFolder && path.indexOf(oldName) === 0) || (!isFolder && path === oldName);
}

/**
* Update a file entry path after a file/folder name change.
* @param {FileEntry} entry The FileEntry or DirectoryEntry to update
* @param {string} oldName The full path of the old name
* @param {string} newName The full path of the new name
* @return {boolean} Returns true if the file entry was updated
*/
function updateFileEntryPath(entry, oldName, newName) {
if (entry.fullPath.indexOf(oldName) === 0) {
function updateFileEntryPath(entry, oldName, newName, isFolder) {
if (isAffectedWhenRenaming(entry.fullPath, oldName, newName, isFolder)) {
var fullPath = entry.fullPath.replace(oldName, newName);

entry.fullPath = fullPath;
Expand All @@ -276,7 +292,7 @@ define(function (require, exports, module) {

return false;
}

/** @const - hard-coded for now, but may want to make these preferences */
var _staticHtmlFileExts = ["htm", "html"],
_serverHtmlFileExts = ["php", "php3", "php4", "php5", "phtm", "phtml", "cfm", "cfml", "asp", "aspx", "jsp", "jspx", "shtm", "shtml"];
Expand Down Expand Up @@ -327,6 +343,7 @@ define(function (require, exports, module) {
exports.getNativeBracketsDirectoryPath = getNativeBracketsDirectoryPath;
exports.getNativeModuleDirectoryPath = getNativeModuleDirectoryPath;
exports.canonicalizeFolderPath = canonicalizeFolderPath;
exports.isAffectedWhenRenaming = isAffectedWhenRenaming;
exports.updateFileEntryPath = updateFileEntryPath;
exports.isStaticHtmlFileExt = isStaticHtmlFileExt;
exports.isServerHtmlFileExt = isServerHtmlFileExt;
Expand Down
6 changes: 4 additions & 2 deletions src/project/ProjectManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,7 @@ define(function (require, exports, module) {

for (i = 0; i < nodes.length; i++) {
var node = $(nodes[i]);
FileUtils.updateFileEntryPath(node.data("entry"), oldName, newName);
FileUtils.updateFileEntryPath(node.data("entry"), oldName, newName, isFolder);
}

// Notify that one of the project files has changed
Expand Down Expand Up @@ -1296,7 +1296,9 @@ define(function (require, exports, module) {
}

var oldName = selected.data("entry").fullPath;
var oldNameRegex = new RegExp(StringUtils.regexEscape(data.rslt.old_name) + "$");
// Folder paths have to end with a slash. Use look-head (?=...) to only replace the folder's name, not the slash as well
var oldNameEndPattern = isFolder ? "(?=\/$)" : "$";
var oldNameRegex = new RegExp(StringUtils.regexEscape(data.rslt.old_name) + oldNameEndPattern);
var newName = oldName.replace(oldNameRegex, data.rslt.new_name);

renameItem(oldName, newName, isFolder)
Expand Down