ares-ide
Version:
A browser-based code editor and UI designer for Enyo 2 projects
997 lines (886 loc) • 29 kB
JavaScript
/*global enyo, Ares, ares, async, ProjectConfig, ServiceRegistry, $L */
enyo.kind({
name: "ProjectWizardCreate",
kind: "onyx.Popup",
modal: true,
centered: true,
floating: true,
autoDismiss: false,
classes: "enyo-unselectable",
events: {
onAddProjectInList: "",
onShowWaitPopup: "",
onHideWaitPopup: ""
},
handlers: {
onFileChosen: "_folderSelectedAction",
onModifiedConfig: "createProject" ,
// can be canceled by either of the included components
onDone: "hideMe"
},
published: {
projectHermesNode: "",
projectFiles: ""
},
components: [
{kind: "ProjectProperties", name: "propertiesWidget", onApplyAddSource: "notifyChangeSource"},
{kind: "Ares.FileChooser", header: "Select a directory containing the new project", canGenerate: false, name: "selectDirectoryPopup", classes:"ares-masked-content-popup", folderChooser: true, allowCreateFolder: true, serverSelectable: false},
{kind: "Ares.ErrorPopup", name: "errorPopup", msg: $L("unknown error")},
{kind: "Ares.ActionPopup", name: "confirmOverwriteOrLoadPopup", title: $L("Non-empty folder"), message: $L("Use existing folder content or overwrite it?"), actionButton: $L("Overwrite"), onConfirmActionPopup: "_confirmedOverwriteAction", action1Button: $L("Use"), onConfirmAction1Popup: "_confirmedUseAction", cancelButton: $L("Cancel")}
],
debug: false,
projectName: "",
config: null,
create: function() {
ares.setupTraceLogger(this); // Setup this.trace() function according to this.debug value
this.inherited(arguments);
},
/**
* start project creation by showing direction selection widget
*/
start: function() {
this.projectHermesNode = null;
this.projectFiles = {};
this.show();
this.$.propertiesWidget.setDefaultTab();
this.hide();
this._selectFolder();
},
_selectFolder: function() {
this.trace();
this.$.selectDirectoryPopup.show();
},
_folderSelectedAction: function(inSender, inEvent) {
this.trace("inSender:", inSender, "inEvent:", inEvent);
this.projectHermesNode = this.$.selectDirectoryPopup.$.hermesFileTree.selectedNode;
if (this.projectHermesNode) {
var req = this.projectHermesNode.updateNodes();
req.response(this, function() {
var projectNodes = this.projectHermesNode.getNodeFiles();
enyo.forEach(projectNodes, function(node) {
this.projectFiles[node.content] = node.file;
}, this);
if (enyo.keys(this.projectFiles).length > 0) {
this.$.confirmOverwriteOrLoadPopup.show();
} else {
this._createProject();
}
});
req.error(this, function(inSender, inError) {
this._waitOk(new Error(inError.toString()));
});
}
return true;
},
_confirmedUseAction: function(inSender, inEvent) {
this.trace("inSender:", inSender, "inEvent:", inEvent);
this._loadProject();
},
_confirmedOverwriteAction: function(inSender, inEvent) {
this.trace("inSender:", inSender, "inEvent:", inEvent);
this._createProject();
},
_loadProject: function() {
this.trace();
var conf = ares.clone(ProjectConfig.PREFILLED_CONFIG_FOR_UI);
async.waterfall([
_loadProjectJson.bind(this, conf),
_loadAppInfoJson.bind(this), // XXX move into webOS plugin
this._fillProjectPropPopup.bind(this, false /*isCreation*/),
this._showProjectPropPopup.bind(this)
], this._waitOk.bind(this));
function _loadProjectJson(conf, next) {
var file = this.projectFiles['project.json'];
if (!file) {
next(null, conf);
} else {
var req = this.projectHermesNode.service.getFile(file.id);
req.response(this, function(inSender, inResponse) {
try {
conf = ares.extend(conf, enyo.json.parse(inResponse.content));
next(null, conf);
} catch(err) {
//req.fail(new Error("Unable to parse 'project.json'"));
this.warn(new Error("Unable to parse 'project.json', skipping it..."));
next(null, conf);
}
});
req.error(this, function(inSender, inError) {
next(new Error(inError.toString));
});
}
}
function _loadAppInfoJson(conf, next) {
var file = this.projectFiles['appinfo.json'];
if (!file) {
next(null, conf);
} else {
var req = this.projectHermesNode.service.getFile(file.id);
req.response(this, function(inSender, inResponse) {
try {
var appinfo = enyo.json.parse(inResponse.content);
conf.id = appinfo.id || conf.id;
conf.version = appinfo.version || conf.version;
conf.title = appinfo.title || conf.title;
next(null, conf);
} catch(err) {
//req.fail(new Error("Unable to parse 'appinfo.json'"));
this.warn(new Error("Unable to parse 'appinfo.json', skipping it..."));
next(null, conf);
}
});
req.error(this, function(inSender, inError) {
next(new Error(inError.toString));
});
}
}
},
_createProject: function() {
this.trace();
var conf = ares.clone(ProjectConfig.PREFILLED_CONFIG_FOR_UI);
async.waterfall([
this._fillProjectPropPopup.bind(this, true /*isCreation*/, conf),
this._getSources.bind(this, 'template'),
this._showProjectPropPopup.bind(this)
], this._waitOk.bind(this));
},
_fillProjectPropPopup: function(isCreation, conf, next) {
this.trace("conf:", conf);
var propW = this.$.propertiesWidget;
this.selectedDir = this.projectHermesNode.file;
if (isCreation) {
propW.setupCreate();
} else {
propW.setupModif();
}
// Pre-fill project properties widget
propW.preFill(conf);
propW.$.projectPathLabel.setContent($L("Project path: "));
propW.$.projectPathValue.setContent(this.selectedDir.path);
propW.$.projectName.setValue(this.selectedDir.name);
propW.activateFileChoosers(false);
next();
},
_getSources: function(type, next) {
this.trace("type:", type);
var propW = this.$.propertiesWidget;
// Getting template list
var service = ServiceRegistry.instance.getServicesByType('generate')[0];
if (service) {
var req = service.getSources(type);
req.response(this, function(inSender, inResponse) {
propW.setTemplateList(inResponse);
next();
});
req.error(this, function(inSender, inError) {
next(new Error("Unable to get list for type: " + type + " (" + inError.toString() + ")"));
});
} else {
next(new Error("No application templating service ('generate')) defined"));
}
},
_showProjectPropPopup: function(next) {
this.$.selectDirectoryPopup.hide();
this.$.selectDirectoryPopup.reset();
this.$.propertiesWidget.hideVersions();
this.show();
next();
},
_waitOk:function(err) {
this.trace("err:", err);
this.doHideWaitPopup();
if (err) {
this.hideMe();
this.warn("An error occured: ", err);
this.$.errorPopup.raise(err.toString());
}
},
// step 3: actually create project in ares data structure
createProject: function (inSender, inEvent) {
this.trace("inSender:", inSender, "inEvent:", inEvent);
var conf = inEvent.data;
this.projectName = conf.name;
var folderId = this.selectedDir.id ;
var template = inEvent.template;
var addedSources = inEvent.addedSources.length !==0 ? true : false;
this.trace("Creating new project ", this.projectName, " in folderId=", folderId, " (template: ", template, ")");
async.waterfall([
this.createProjectJson.bind(this, conf),
this.instanciateTemplate.bind(this, template, addedSources, conf),
this.populateProject.bind(this),
this.projectReady.bind(this)
], this._waitOk.bind(this));
return true ; // stop bubble
},
/**
* @param {Object} data as found in {project.json}
* @param {Function} next common-JS callback, when {project.json} is saved
* @private
*/
createProjectJson: function(data, next) {
var config = new ProjectConfig();
config.service = this.selectedDir.service;
config.folderId = this.selectedDir.id;
config.setData(data) ;
config.save(next);
},
// step 4: populate the project with the selected template
instanciateTemplate: function (template, addedSources, conf, next) {
this.trace("template:", template, "addedSources:", addedSources, "conf:", conf);
if (!template) {
next(null, null);
return;
}
var sources = [];
this.doShowWaitPopup({msg: "Creating project from template '" + template + "'"});
// XXX webOS-specific substitution
var substitutions = [{
fileRegexp: "appinfo.json",
json: {
id: conf.id,
version: conf.version,
title: conf.title
}
}];
var genService = ServiceRegistry.instance.getServicesByType('generate')[0];
sources.push(template);
(addedSources || []).forEach(function(source) {
sources.push(source);
});
var req = genService.generate({
sourceIds: sources,
substitutions: substitutions
});
req.response(this, function(inSender, inData) {
var propW = this.$.propertiesWidget;
propW.setTemplateList([]);
this.trace("generate response:", inData);
next(null, inData);
});
req.error(this, function(inSender, inError) {
var err = new Error("Unable to instanciate projet content from the template '" + template + "': " + inError.toString());
next(err);
});
},
// step 5: populate the project with the retrieved template files
populateProject: function(inData, next) {
this.trace("inData:", inData);
if (!inData) {
next();
return;
}
var folderId = this.selectedDir.id;
var service = this.selectedDir.service;
// Copy the template files into the new project
var req = service.createFiles(folderId, {content: inData.content, ctype: inData.ctype});
req.response(this, function(inSender, inData) {
next();
});
req.error(this, function(inEvent, inError) {
var err = new Error("Unable to create projet content from the template (" + inError.toString() + ")");
next(err);
});
},
// step 6: we're done
projectReady: function(next) {
this.trace();
this.doAddProjectInList({
name: this.projectName,
folderId: this.selectedDir.id,
service: this.selectedDir.service
});
next();
},
/**
* Hide the whole widget. Typically called when ok or cancel is clicked
*/
hideMe: function() {
this.$.selectDirectoryPopup.hide();
this.$.selectDirectoryPopup.reset();
this.hide() ;
return true;
},
/** @private */
$LS: function(msg, params) {
var tmp = new enyo.g11n.Template($L(msg));
return tmp.evaluate(params);
}
});
/**
* This kind handles the project modifications treatment (extracted from ProjectView)
*/
enyo.kind({
name: "ProjectWizardModify",
kind: "onyx.Popup",
modal: true,
centered: true,
floating: true,
autoDismiss: false,
handlers: {
onDone: "hide",
onModifiedConfig: "saveProjectConfig",
onModifiedSource: "populateProject",
onSelectFile: "selectFile",
onCheckPath: "checkPath",
onPathChecked: "pathChecked"
},
classes:"ares-masked-content-popup",
components: [
{kind: "ProjectProperties", name: "propertiesWidget", onApplyAddSource: "notifyChangeSource", onFileChoosersChecked: "fileChoosersChecked"},
{name: "selectFilePopup", kind: "Ares.FileChooser", classes:"ares-masked-content-popup", showing: false, folderChooser: false, allowToolbar: false, onFileChosen: "selectFileChosen"}
],
debug: false,
targetProject: null,
chooser: null,
checker: null,
displayedTab: null,
versions: [],
create: function() {
ares.setupTraceLogger(this); // Setup this.trace() function according to this.debug value
this.inherited(arguments);
},
/**
* Step 1: start the modification by showing project properties widget
*/
start: function(target) {
if (target) {
var config = target.getConfig();
var serviceConfig = config.service.config;
var home = serviceConfig.origin+serviceConfig.pathname+"/file";
this.targetProject = target ;
this.$.propertiesWidget.setTargetProject(target);
this.$.propertiesWidget.setupModif();
this.$.propertiesWidget.preFill(config.data);
this.$.propertiesWidget.$.projectPathLabel.setContent($L("Project path: "));
this.$.propertiesWidget.$.projectPathValue.setContent("");
var req = config.service.propfind(config.folderId, 3);
req.response(this, function(inSender, inFile) {
this.$.propertiesWidget.$.projectPathValue.setContent(inFile.path);
//read path to version's file from deploy.json file
this.readDeployFile(inFile.path, home);
});
this.$.propertiesWidget.activateFileChoosers(true);
this.$.propertiesWidget.checkFileChoosers();
}
},
/**
* @private
* Read deploy.json file
* @param {String} pathProject, path to project
* @param {String} urlHome, home url
*/
readDeployFile: function(pathProject, urlHome){
var url = urlHome + pathProject + "/deploy.json";
var req = new enyo.Ajax({url: url, handleAs: "json"});
req.response(this, function(inSender, inValue) {
this.searchForVersions(inValue, pathProject, urlHome);
});
req.error(this, function(err){
this.searchForVersions(null, pathProject, urlHome);
});
req.go();
},
/**
* @private
* Read version.js files for enyo and other libs
* @param {Object} pathDeploy, paths read from deploy.json file
* @param {String} pathProject, path to project
* @param {String} urlHome, home url
*/
searchForVersions: function(pathDeploy, pathProject, urlHome){
this.trace(pathDeploy, pathProject, urlHome);
var pathArray = [],
urls = [],
urlObject = {},
serviceHome = urlHome+pathProject,
enyoVersionFile = "/source/boot/version.js",
versionFile = "/version.js",
parrallelReads = [];
//define the default path to use if the deploy.json file doesn't exists
if(!pathDeploy){
// doesn't work for added libs
pathDeploy = {enyo: "./enyo", libs: ["./lib/onyx", "./lib/layout"]};
}
pathArray.push(pathDeploy["enyo"]);
enyo.forEach(pathDeploy["libs"], function(path){
pathArray.push(path);
}, this);
enyo.forEach(pathArray, function(path){
if(path){
//a path can be started with ./ or nothing
path = path.replace(/^\.\//, ""); //if the path starts with ./, it is replaced by nothing
var lib = path.replace(/^lib\//, "");
urlObject = {"lib" : lib, "url": serviceHome + "/" + path + (path.match(/^enyo/) ? enyoVersionFile : versionFile)};
urls.push(urlObject);
}
}, this);
this.trace("found urls", urls);
if(urls.length){
this.versions = [];
enyo.forEach(urls, function(url){
var readFunction = this.readVersionFileFromUrl.bind(this,url);
parrallelReads.push(readFunction);
}, this);
async.parallel(parrallelReads, this.setVersionLabel.bind(this));
}
},
/**
* @private
* Read file's content from a url
* @param {String} url, url for version.js file
* @param {[Function]} next
*/
readVersionFileFromUrl: function(url, next){
var req = new enyo.Ajax({url: url["url"], handleAs: "text"});
var content = "";
var version = "";
var expr = new RegExp("enyo.version.|=|:|\"", "g");
req.response(this, function(inSender, inValue) {
if(inValue){
content = inValue.match(/{\s*(enyo[^\n,;]+)/);
version = content[1].replace(expr, "").replace(/[\w\.]+/,"$&:");
this.versions.push(version);
}
next();
});
req.error(this, function(err){
this.versions.push( url["lib"]+ ": not found");
next();
});
req.go();
},
/**
* Display version label
*/
setVersionLabel: function(){
this.versions.sort(this.compareLibs);
this.$.propertiesWidget.setVersionLabel(this.versions.join(", "));
},
/**
* @private
* Used to set the enyo version at the top of the array
* @param {String} libA
* @param {String} libB
*/
compareLibs: function (libA, libB){
var re = new RegExp("^enyo:");
if(libA.match(re) && libB.match(re)){
return 0;
} else if (libA.match(re)) {
return -1;
} else if (libB.match(re)) {
return 1;
}
return 0;
},
/**
* @private
* Add content to version repeater item
*/
addVersions: function(inSender, inEvent){
var item = inEvent.item.$.item,
index = inEvent.item.index;
item.setContent(this.versions[index]);
return true;
},
/**
* Function used to display the Edit Pop-up with the specification of the defaut tab to be displayed
* @param {Object} target Object contains meta-data of the selected project.
* @param {in} inDisplayedTab index of the defaut displayed tab (0: Project, 1: Preview, 2: Phonegap Build)
* @private
*/
showEditPopUp: function(target, inDisplayedTab) {
if(target) {
this.start(target);
// Define the tab that will be shown when the Pop-up is displayed
this.displayedTab = inDisplayedTab;
}
},
// step 2:
saveProjectConfig: function(inSender, inEvent) {
this.trace("saving project config");
if (! this.targetProject) {
this.warn("internal error: saveProjectConfig was called without a target project.") ;
return true ; // stop bubble
}
// Save the data to project.json
var config = this.targetProject.getConfig();
config.setData(inEvent.data);
config.save();
// selected project name was modified
if (inEvent.data.name !== this.targetProject.getName()) {
// project name has changed, update project model list
var oldName = this.targetProject.getName();
Ares.Workspace.projects.renameProject(oldName, inEvent.data.name);
}
return true ; // stop bubble
},
/** @private */
selectFile: function(inSender, inData) {
this.trace(inSender, "=>", inData);
this.chooser = inData.input;
this.$.selectFilePopup.reset();
this.$.selectFilePopup.connectProject(this.targetProject, (function() {
this.$.selectFilePopup.setHeaderText(inData.header);
this.$.selectFilePopup.pointSelectedName(inData.value, inData.status);
this.$.selectFilePopup.show();
}).bind(this));
return true;
},
/** @private */
selectFileChosen: function(inSender, inEvent) {
this.trace(inSender, "=>", inEvent);
var chooser = this.chooser;
this.chooser = null;
if (!inEvent.file) {
// no file or folder chosen
return true;
}
this.$.propertiesWidget.updateFileInput(chooser, inEvent.name);
this.$.selectFilePopup.reset();
return true;
},
populateProject: function(inSender, inData) {
this.trace("inData:", inData);
var selectedDir = this.targetProject.getConfig();
var folderId = selectedDir.folderId;
var service = selectedDir.service;
// Copy the template files into the new project
var req = service.createFiles(folderId, {content: inData.content, ctype: inData.ctype});
req.response(this, this.projectRefresh);
req.error(this, function(inEvent, inError) {
this.$.errorPopup.raise($L("Unable to create projet content from the template"));
this.doHideWaitPopup();
});
return true;
},
projectRefresh: function(inSender, inData) {
this.owner.setupProjectConfig(this.targetProject);
this.hideMe();
},
/**
* Hide the whole widget. Typically called when ok or cancel is clicked
*/
hideMe: function() {
this.hide() ;
return true;
},
/** @private */
checkPath: function (inSender, inData) {
this.trace(inSender, "=>", inData);
this.checker = inData.input;
// FIXME ENYO-2761: this is a workaround that shows the developer that the path is not
// valid because it doesn't begin with an "/".
if (inData.value.indexOf("/") !== 0) {
this.pathChecked(inSender, {status: false});
return true;
}
this.$.selectFilePopup.connectProject(this.targetProject, (function() {
this.$.selectFilePopup.checkSelectedName(inData.value);
}).bind(this));
},
/** @private */
pathChecked: function (inSender, inData) {
this.trace(inSender, "=>", inData);
var checker = this.checker;
this.checker = null;
this.$.selectFilePopup.reset();
this.$.propertiesWidget.updatePathCheck(checker, inData.status);
},
/** @private */
fileChoosersChecked: function (inSender, inEvent) {
this.trace(inSender, "=>", inEvent);
this.show();
if (this.displayedTab) {
this.$.propertiesWidget.setDisplayedTab(this.displayedTab);
} else {
this.$.propertiesWidget.setDefaultTab();
}
return true;
}
});
/**
* This kind will scan a directory. It will create a new project for each project.json found.
*/
enyo.kind({
name: "ProjectWizardScan",
kind: "Ares.FileChooser",
modal: true,
centered: true,
floating: true,
autoDismiss: false,
folderChooser: true,
classes: "enyo-unselectable",
events: {
onAddProjectInList: "",
onError: "",
onShowWaitPopup: "",
onHideWaitPopup: ""
},
handlers: {
onFileChosen: "searchProjects"
},
published: {
recurse: true
},
debug: false,
create: function() {
ares.setupTraceLogger(this); // Setup this.trace() function according to this.debug value
this.inherited(arguments);
},
/** @public */
importProject: function(service, parentDir, child) {
this.trace('importing project from folder ', parentDir.name ) ;
throw new Error("Not implemented - XXX ENYO-3543");
},
/**
* Open an existing project
*
* Load the project from the given folder & requests Ares to
* add it to the list of the known projects
*
* @param {FileSystemService} service is the file-system
* @param {ares.Filesystem.Node} folderNode is the folder node
* @param {ares.Filesystem.Node} [projectNode] is the <pre>project.json</pre> node
* @public
*/
openProject: function(service, folderNode, projectNode, next) {
this.trace('opening project.json from ', folderNode.name ) ;
async.waterfall([
_list.bind(this),
_fetch.bind(this),
_load.bind(this)
], next);
function _list(next) {
if (projectNode && projectNode.id) {
next(null, projectNode);
} else {
var req = service.propfind(folderNode.id, 1 /*depth*/);
req.response(this, function(inSender, inResponse) {
this.trace(inResponse);
projectNode = inResponse.children.filter(function(child) {
return child.name === "project.json";
})[0];
next(null, projectNode);
});
req.error(_handleError);
}
}
function _fetch(projectNode, next) {
var req = service.getFile(projectNode.id);
req.error(_handleError);
req.response(function(inSender, fileStuff) {
next(null, fileStuff);
});
}
function _load(fileStuff, next) {
var projectData;
try {
this.trace( "file contents: '", fileStuff.content, "'" ) ;
projectData = enyo.json.parse(fileStuff.content) ;
this.trace('Opened project ', projectData && projectData.name, " from ", folderNode.path) ;
this.doAddProjectInList({
name: (projectData && projectData.name) || folderNode.name,
folderId: folderNode.id,
service: service,
dontSelect: true // do not open projects found by search
});
next();
} catch(e) {
this.warn("Error parsing project data: ", e.toString());
next(e);
}
}
function _handleError(inSender, inError) {
this.warning(inError);
next(new Error(inError.toString()));
}
},
/**
* Search for Ares projects in the currently selected folder
* @param {Object} inSender
* @param {Object} inEvent
* @public
*/
searchProjects: function (inSender, inEvent) {
this.trace("inSender:", inSender, "inEvent:", inEvent);
if (!inEvent.file) {
this.hide();
this.reset();
return;
}
var service = inEvent.file.service;
var topDir = this.$.hermesFileTree.selectedNode.file ;
var projects = [];
async.series([
_walk.bind(this, topDir),
_add.bind(this),
_finish.bind(this)
], _next.bind(this));
function _walk(folderNode, next) {
this.trace('Searching in ', folderNode.path) ;
this.doShowWaitPopup({msg: "Scanning: " + folderNode.name + "..."});
var req = service.listFiles(folderNode.id);
req.response(this, function(inSender, inFiles) {
// First look for a `project.json`...
var fileNode = enyo.filter(inFiles, function(v) {
return v.name === 'project.json';
}, this)[0];
if (fileNode) {
this.trace('Found:', fileNode.path) ;
this.doShowWaitPopup({msg: "Found: " + folderNode.name + "..."});
projects.push({
folder: folderNode,
file: fileNode
});
next();
} else if (!this.recurse) {
next();
} else {
// ... and recurse only if
// none if found in the
// children.
var subDirs = enyo.filter(inFiles, function(file) {
return file.isDir;
});
async.forEachSeries(subDirs, _walk.bind(this), next);
}
});
}
function _add(next) {
this.trace('Adding found projects:', projects) ;
async.forEachSeries(projects, (function(project, next) {
this.doShowWaitPopup({msg: "Adding: " + project.folder.name + " ..."});
this.openProject(service, project.folder, project.file, next);
}).bind(this), next);
}
function _finish(next) {
this.reset();
next();
}
function _next(err) {
this.doHideWaitPopup();
if (err) {
this.warn("Unable to open project:", err);
if (!this.recurse) {
this.doError({msg: "Unable to open project", err: err});
}
}
}
}
});
enyo.kind({
name: "ProjectWizardCopy",
kind: "onyx.Popup",
modal: true,
centered: true,
floating: true,
autoDismiss: false,
handlers: {
onDone: "hide",
onModifiedConfig: "copyProject"
},
events: {
onError: "",
onShowWaitPopup: "",
onHideWaitPopup: ""
},
components: [
{kind: "ProjectProperties", name: "propertiesWidget"}
],
debug: false,
targetProject: null,
create: function() {
ares.setupTraceLogger(this); // Setup this.trace() function according to this.debug value
this.inherited(arguments);
},
/**
* Step 1: start the modification by showing project properties widget
*/
start: function(target) {
if (target) {
var data = enyo.clone(target.getConfig().data);
// TODO: Verify that the project name and dir does not exist
data.name = data.name + "-Copy";
this.targetProject = target;
this.$.propertiesWidget.setupModif() ;
this.$.propertiesWidget.preFill(data);
this.$.propertiesWidget.$.projectPathLabel.setContent($L("Parent project path: "));
this.$.propertiesWidget.$.projectPathValue.setContent("");
//TO DO: hide versions label for copy not tested, copy isn't working
this.$.propertiesWidget.hideVersions();
var config = target.getConfig();
var req = config.service.propfind(config.folderId, 3);
req.response(this, function(inSender, inFile) {
var parentFolderPath = inFile.path.slice(0, -(inFile.name.length));
this.$.propertiesWidget.$.projectPathValue.setContent(parentFolderPath);
});
this.$.propertiesWidget.activateFileChoosers(false);
this.show();
}
},
// step 2:
copyProject: function(inSender, inEvent) {
this.trace("Copying project", this.targetProject.getConfig().data.name);
this.doShowWaitPopup({msg: "Duplicating project"});
var service = this.targetProject.getService();
var folderId = this.targetProject.getFolderId();
this.newConfigData = inEvent.data;
var destination = inEvent.data.name;
var known = Ares.Workspace.projects.get(destination);
if (known) {
this.doError({msg: this.$LS("Unable to duplicate the project, the project '#{destination}' already exists", {destination: destination})});
return true ; // stop bubble
}
var req = service.copy(folderId, {name: destination});
req.response(this, this.saveProjectJson);
req.error(this, function(inSender, status) {
var msg = $L("Unable to duplicate the project");
if (status === 412 /*Precondition-Failed*/) {
this.warn("Unable to duplicate the project, directory '", destination, "' already exists", status);
msg = this.$LS("Unable to duplicate the project, directory '#{destination}' already exists", {destination: destination});
} else {
this.warn("Unable to duplicate the project", status);
}
this.doError({msg: msg});
});
return true ; // stop bubble
},
saveProjectJson: function(inSender, inData) {
this.trace(inData);
var folderId = inData.id;
this.newFolderId = folderId;
var service = this.targetProject.getService();
var fileId;
enyo.forEach(inData.children, function(entry) {
if (entry.name === "project.json") {
fileId = entry.id;
}
});
if (! fileId) {
this.warn("Unable to duplicate the project, no 'project.json' found", inData);
this.doError({msg: $L("Unable to duplicate the project, no 'project.json' found")});
return;
}
var req = service.putFile(fileId, enyo.json.stringify(this.newConfigData, null, 2));
req.response(this, this.createProjectEntry);
req.error(this, function(inSender, inError) {
this.warn("Unable to duplicate the project, unable to update 'project.json'", inError);
this.doError({msg: $L("Unable to duplicate the project, unable to update 'project.json'")});
});
},
createProjectEntry: function(inSender, inData) {
this.trace(inData);
var serviceId = this.targetProject.getServiceId();
// Create the project entry in the project list
var project = Ares.Workspace.projects.createProject(this.newConfigData.name, this.newFolderId, serviceId);
if(project){
this.owner.$.projectList.selectProject(project, ares.noNext);
}
this.doHideWaitPopup();
},
$LS: function(msg, params) {
var tmp = new enyo.g11n.Template($L(msg));
return tmp.evaluate(params);
}
});