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

INITIAL REVIEW: Update path to welcome project in newer builds #1639

Closed
wants to merge 1 commit into from
Closed
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/brackets.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ define(function (require, exports, module) {
PerfUtils.addMeasurement("Application Startup");

// finish UI initialization before loading extensions
var initialProjectPath = ProjectManager.getInitialProjectPath();
ProjectManager.openProject(initialProjectPath).done(function () {
var initialProjectInfo = ProjectManager.getInitialProjectInfo();
ProjectManager.openProject(initialProjectInfo.root, initialProjectInfo.type).done(function () {
_initTest();

// WARNING: AppInit.appReady won't fire if ANY extension fails to
Expand All @@ -252,8 +252,8 @@ define(function (require, exports, module) {
var prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID);
if (!params.get("skipSampleProjectLoad") && !prefs.getValue("afterFirstLaunch")) {
prefs.setValue("afterFirstLaunch", "true");
if (ProjectManager.isDefaultProjectPath(initialProjectPath)) {
var dirEntry = new NativeFileSystem.DirectoryEntry(initialProjectPath);
if (initialProjectInfo.type === ProjectManager.TYPE_WELCOME) {
var dirEntry = new NativeFileSystem.DirectoryEntry(initialProjectInfo.root);
dirEntry.getFile("index.html", {}, function (fileEntry) {
CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: fileEntry.fullPath });
});
Expand Down
63 changes: 48 additions & 15 deletions src/extensions/default/RecentProjects/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,51 @@ define(function (require, exports, module) {
var MAX_PROJECTS = 20;

/**
* Add a project to the stored list of recent projects, up to MAX_PROJECTS.
* Get the list of recent projects from preferences. If one of them is the welcome
* project, make sure to update it to the current path.
*/
function add() {
var root = ProjectManager.getProjectRoot().fullPath,
prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_KEY),
function getRecentProjects() {
var prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_KEY),
recentProjects = prefs.getValue("recentProjects") || [],
index = recentProjects.indexOf(root);
if (index !== -1) {
recentProjects.splice(index, 1);
i;
for (i = 0; i < recentProjects.length; i++) {
// Handle older versions (where only the path was stored)
if (typeof recentProjects[i] === "string") {
recentProjects[i] = {root: recentProjects[i], type: ProjectManager.TYPE_LOCAL_FOLDER};
}
if (recentProjects[i].type === ProjectManager.TYPE_WELCOME) {
recentProjects[i].root = ProjectManager.getWelcomeProjectPath();
}
}
return recentProjects;
}

/**
* Canonicalize a folder path to have no trailing slash.
*/
function canonicalize(path) {
if (path.length > 0 && path[path.length - 1] === "/") {
return path.slice(0, -1);
} else {
return path;
}
recentProjects.unshift(root);
}

/**
* Add a project to the stored list of recent projects, up to MAX_PROJECTS.
*/
function add(e, info) {
var prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_KEY),
recentProjects = getRecentProjects(),
canonRoot = canonicalize(info.root),
i;
for (i = 0; i < recentProjects.length; i++) {
if (canonicalize(recentProjects[i].root) === canonRoot) {
recentProjects.splice(i, 1);
break;
}
}
recentProjects.unshift(info);
if (recentProjects.length > MAX_PROJECTS) {
recentProjects = recentProjects.slice(0, MAX_PROJECTS);
}
Expand All @@ -67,9 +101,7 @@ define(function (require, exports, module) {
* @param {string} path The full path to the folder.
*/
function renderPath(path) {
if (path.length && path[path.length - 1] === "/") {
path = path.slice(0, path.length - 1);
}
path = canonicalize(path);

var lastSlash = path.lastIndexOf("/"), folder, rest;
if (lastSlash === path.length - 1) {
Expand Down Expand Up @@ -107,7 +139,7 @@ define(function (require, exports, module) {
e.stopPropagation();

var prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_KEY),
recentProjects = prefs.getValue("recentProjects") || [],
recentProjects = getRecentProjects(),
$dropdown = $("<ul id='project-dropdown' class='dropdown-menu'></ul>"),
toggleOffset = $dropdownToggle.offset();

Expand All @@ -126,11 +158,12 @@ define(function (require, exports, module) {

var currentProject = ProjectManager.getProjectRoot().fullPath,
hasProject = false;
recentProjects.forEach(function (root) {
if (root !== currentProject) {
recentProjects.forEach(function (projectInfo) {
var root = projectInfo.root;
if (canonicalize(root) !== canonicalize(currentProject)) {
var $link = renderPath(root)
.click(function () {
ProjectManager.openProject(root)
ProjectManager.openProject(root, projectInfo.type)
.fail(function () {
// Remove the project from the list.
var index = recentProjects.indexOf(root);
Expand Down
113 changes: 75 additions & 38 deletions src/project/ProjectManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ define(function (require, exports, module) {
Urls = require("i18n!nls/urls"),
KeyEvent = require("utils/KeyEvent");

var TYPE_LOCAL_FOLDER = "localFolder",
TYPE_WELCOME = "welcome";

/**
* @private
* Reference to the tree control container div. Initialized by
Expand Down Expand Up @@ -104,6 +107,12 @@ define(function (require, exports, module) {
* @see getProjectRoot()
*/
var _projectRoot = null;

/**
* @private
* The current project's metadata.
*/
var _projectInfo = null;

/**
* Unique PreferencesManager clientID
Expand Down Expand Up @@ -205,6 +214,15 @@ define(function (require, exports, module) {
return _projectRoot;
}

/**
* Returns the current project info, which has two fields:
* root -- the path to the root of the project
* type -- the type of project (one of the TYPE_* constants)
*/
function getProjectInfo() {
return _projectInfo;
}

/**
* Returns true if absPath lies within the project, false otherwise.
* Does not support paths containing ".."
Expand All @@ -224,11 +242,42 @@ define(function (require, exports, module) {
return absPath;
}

/** Returns the full path to the welcome project, which is the default startup project.
* @private
* @return {!string} fullPath reference
*/
function getWelcomeProjectPath() {
var srcPath = decodeURI(window.location.pathname),
initialPath = srcPath.substr(0, srcPath.lastIndexOf("/")),
sampleUrl = Urls.GETTING_STARTED;
if (sampleUrl) {
// Back up one more folder. The samples folder is assumed to be at the same level as
// the src folder, and the sampleUrl is relative to the samples folder.
initialPath = initialPath.substr(0, initialPath.lastIndexOf("/")) + "/samples/" + sampleUrl;
}

initialPath = FileUtils.convertToNativePath(initialPath);
return initialPath;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The above method was just moved verbatim from later in the file to prevent JSLint from complaining.


/**
* Initial project path is stored in prefs, which defaults to the getting started project
* Initial project path is stored in prefs. However, if we're reopening the welcome project,
* make sure we open the one for the current version, instead of one associated with an older
* install.
*/
function getInitialProjectPath() {
return _prefs.getValue("projectPath");
function getInitialProjectInfo() {
var info = _prefs.getValue("projectInfo");
if (!info) {
// Handle the pre-Sprint 14 prefs key, which was just a path
info = _prefs.getValue("projectPath");
if (info) {
info = { root: info, type: TYPE_LOCAL_FOLDER };
}
}
if (info && info.type === TYPE_WELCOME) {
info.root = getWelcomeProjectPath();
}
return info;
}

/**
Expand All @@ -253,7 +302,7 @@ define(function (require, exports, module) {
function _savePreferences() {

// save the current project
_prefs.setValue("projectPath", _projectRoot.fullPath);
_prefs.setValue("projectInfo", _projectInfo);

// save jstree state
var openNodes = [],
Expand Down Expand Up @@ -614,45 +663,21 @@ define(function (require, exports, module) {

}

/** Returns the full path to the default project folder. The path is currently the brackets src folder.
* @private
* @return {!string} fullPath reference
*/
function _getDefaultProjectPath() {
var srcPath = decodeURI(window.location.pathname),
initialPath = srcPath.substr(0, srcPath.lastIndexOf("/")),
sampleUrl = Urls.GETTING_STARTED;
if (sampleUrl) {
// Back up one more folder. The samples folder is assumed to be at the same level as
// the src folder, and the sampleUrl is relative to the samples folder.
initialPath = initialPath.substr(0, initialPath.lastIndexOf("/")) + "/samples/" + sampleUrl;
}

initialPath = FileUtils.convertToNativePath(initialPath);
return initialPath;
}

/**
* Returns true if the given path is the same as the one for the initial startup project.
*/
function isDefaultProjectPath(path) {
return path === _getDefaultProjectPath();
}

/**
* Loads the given folder as a project. Normally, you would call openProject() instead to let the
* user choose a folder.
*
* @param {string} rootPath Absolute path to the root folder of the project.
* If rootPath is undefined or null, the last open project will be restored.
* @param {string=} type Type of project. Defaults to local folder.
* @return {$.Promise} A promise object that will be resolved when the
* project is loaded and tree is rendered, or rejected if the project path
* fails to load.
*/
function _loadProject(rootPath) {
function _loadProject(rootPath, type) {
if (_projectRoot) {
// close current project
$(exports).triggerHandler("beforeProjectClose", _projectRoot);
$(exports).triggerHandler("beforeProjectClose", _projectInfo);
}

// close all the old files
Expand All @@ -679,6 +704,10 @@ define(function (require, exports, module) {
var perfTimerName = PerfUtils.markStart("Load Project: " + rootPath);

_projectRoot = rootEntry;
_projectInfo = {
root: _projectRoot.fullPath,
type: type || TYPE_LOCAL_FOLDER
};

// The tree will invoke our "data provider" function to populate the top-level items, then
// go idle until a node is expanded - at which time it'll call us again to fetch the node's
Expand All @@ -687,7 +716,7 @@ define(function (require, exports, module) {

resultRenderTree.done(function () {
if (projectRootChanged) {
$(exports).triggerHandler("projectOpen", _projectRoot);
$(exports).triggerHandler("projectOpen", _projectInfo);
}

result.resolve();
Expand Down Expand Up @@ -715,7 +744,7 @@ define(function (require, exports, module) {
// TODO (issue #267): When Brackets supports having no project directory
// defined this code will need to change
result.reject();
return _loadProject(_getDefaultProjectPath());
return _loadProject(getWelcomeProjectPath());
});
}
);
Expand All @@ -731,11 +760,13 @@ define(function (require, exports, module) {
* @param {string=} path Optional absolute path to the root folder of the project.
* If path is undefined or null, displays a dialog where the user can choose a
* folder to load. If the user cancels the dialog, nothing more happens.
* @param {string=} type Type of project. Only valid if path is specified.
* Defaults to local folder.
* @return {$.Promise} A promise object that will be resolved when the
* project is loaded and tree is rendered, or rejected if the project path
* fails to load.
*/
function openProject(path) {
function openProject(path, type) {

var result = new $.Deferred();

Expand All @@ -746,7 +777,7 @@ define(function (require, exports, module) {
.done(function () {
if (path) {
// use specified path
_loadProject(path).pipe(result.resolve, result.reject);
_loadProject(path, type).pipe(result.resolve, result.reject);
} else {
// Pop up a folder browse dialog
NativeFileSystem.showOpenDialog(false, true, Strings.CHOOSE_FOLDER, _projectRoot.fullPath, null,
Expand Down Expand Up @@ -959,7 +990,10 @@ define(function (require, exports, module) {

// Init PreferenceStorage
var defaults = {
projectPath: _getDefaultProjectPath() /* initialize to brackets source */
projectInfo: {
root: getWelcomeProjectPath(), /* initialize to brackets source */
type: TYPE_WELCOME
}
};
_prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID, defaults);

Expand All @@ -977,8 +1011,11 @@ define(function (require, exports, module) {
exports.shouldShow = shouldShow;
exports.openProject = openProject;
exports.getSelectedItem = getSelectedItem;
exports.getInitialProjectPath = getInitialProjectPath;
exports.isDefaultProjectPath = isDefaultProjectPath;
exports.getInitialProjectInfo = getInitialProjectInfo;
exports.getWelcomeProjectPath = getWelcomeProjectPath;
exports.createNewItem = createNewItem;
exports.forceFinishRename = forceFinishRename;

exports.TYPE_LOCAL_FOLDER = TYPE_LOCAL_FOLDER;
exports.TYPE_WELCOME = TYPE_WELCOME;
});