UNPKG

ares-ide

Version:

A browser-based code editor and UI designer for Enyo 2 projects

325 lines (303 loc) 10.5 kB
/*global ServiceRegistry, ProjectConfig, ares, ComponentsRegistry, async, enyo, Phonegap */ /** * This kind is the top kind of project handling. It contains: * - The project list * - the interface towards the user's file (harmonia) * - Popups to manage projects (create, scan, error ...) */ enyo.kind({ name: "ProjectView", kind: "FittableColumns", classes: "enyo-unselectable", debug: false, published: { // harcoded until ENYO-2755 is fixed panelIndex: 0 }, components: [ {kind: "ProjectList", onModifySettings: "modifySettingsAction", onCreateProject: "createProjectAction", onOpenProject: "openProjectAction", onSearchProjects: "searchProjectsAction", onDuplicateProject: "duplicateProjectAction", onProjectRemoved: "projectRemoved", name: "projectList" }, {kind: "ProjectWizardCreate", canGenerate: false, name: "projectWizardCreate", classes:"ares-masked-content-popup"}, {kind: "ProjectWizardScan", canGenerate: false, name: "projectWizardScan", classes:"ares-masked-content-popup"}, {kind: "ProjectWizardModify", canGenerate: false, name: "projectWizardModify" }, {kind: "ProjectWizardCopy", name: "projectWizardCopy", classes:"ares-masked-content-popup"} ], handlers: { onAddProjectInList: "addProjectInList", onPreview: "previewAction", onBuild: "buildAction", onInstall: "installAction", onRun: "runAction", onRunDebug: "runDebugAction" }, events: { onHideWaitPopup: "", onShowWaitPopup: "", onError: "", onProjectSelected: "", onRegisterMe: "" }, create: function() { ares.setupTraceLogger(this); this.inherited(arguments); this.doRegisterMe({name:"projectView", reference:this}); }, /** * Refresh the {ProjectView} (if relevant), following a change of the given file * @param {Object} toSelectId. Asynchronous */ refreshFileTree: function(toSelectId,next) { ComponentsRegistry.getComponent("harmonia").refreshFileTree(toSelectId,next); }, searchProjectsAction: function(inSender, inEvent) { this.$.projectWizardScan.setHeaderText('Select a folder hierarchy'); this.$.projectWizardScan.setRecurse(true); this.$.projectWizardScan.show(); return true; //Stop event propagation }, openProjectAction: function(inSender, inEvent) { this.$.projectWizardScan.setHeaderText('Select an existing Ares application folder (contains a project.json file)'); this.$.projectWizardScan.setRecurse(false); this.$.projectWizardScan.show(); return true; //Stop event propagation }, duplicateProjectAction: function(inSender, inEvent) { if(!this.currentProject()){ this.doError({msg: "Please project list select item."}); return false; } this.$.projectWizardCopy.start( this.currentProject() ); return true; //Stop event propagation }, createProjectAction: function(inSender, inEvent) { this.$.projectWizardCreate.start(); return true; //Stop event propagation }, modifySettingsAction: function(inSender, inEvent) { this.$.projectWizardModify.start( this.currentProject() ); return true; //Stop event propagation }, addProjectInList: function(inSender, inEvent) { this.doHideWaitPopup(); try { // Add an entry into the project list this.$.projectList.addProject(inEvent.name, inEvent.folderId, inEvent.service, inEvent.dontSelect); } catch(e) { var msg = e.toString(); this.error(msg); this.doError({msg: msg}); return false; } return true; //Stop event propagation }, currentProject: function() { return this.$.projectList.getSelectedProject() ; }, /** * * @param {Object} project * @param {Function} next */ setupProjectConfig: function(project, next) { ares.assertCb(next); var pname = project.getName(); if ( this.currentProject() && pname === this.currentProject().getName() ) { this.trace("skip setup of already selected project" + pname); next(); return; } // FIXME: temporary hack to create config.json on the // fly if needed... would be better to create/load it // when the workspace is loaded & when a new project // is created that would save per-click HTTP traffic // to the FileSystemService. var self = this; var config = new ProjectConfig(); this.trace("setup project config init on "+ project.getName() ); var initData = { service: project.getService(), folderId: project.getFolderId() }; async.series( [ // read default config from remote server config.init.bind(config, initData) , function (next) { self.trace("ProjectView: setup project set config on "+ project.getName() ); project.setConfig(config); self.initializeDownloadStatus(project, config.data.providers.phonegap.enabled); self.initializeValidPgbConf(project, config.data.providers.phonegap.enabled); next(); }, function (next) { // Pass service definition & configuration to Harmonia // & consequently to HermesFileTree self.trace("ProjectView: setup project on harmonia "+ project.getName() ); ComponentsRegistry.getComponent("harmonia").setProject(project, next); } ], function (err) { self.trace("ProjectView: setup project config done on " + project.getName() + " err is ",err ); if (err) { self.doError({msg: err.toString(), err: err}); } next(err); } ); }, /** * Initialize the attribute "downloadStatus" of the project * * this attribute is used only by Phonegap Build. * @private */ initializeDownloadStatus: function(inProject, inPhonegapEnabled) { if (inProject.getDownloadStatus() === undefined && inPhonegapEnabled) { var downloadStatus = {}; var index = 0; for (index in Phonegap.UIConfiguration.platformDrawersContent) { downloadStatus[Phonegap.UIConfiguration.platformDrawersContent[index].id] = "Ready for download"; } inProject.setDownloadStatus(downloadStatus); } }, initializeValidPgbConf: function(inProject, inPhonegapEnabled) { if (inProject.getValidPgbConf() === undefined && inPhonegapEnabled) { var pgbValidation = {}; var pgbUiData = Phonegap.UIConfiguration.commonDrawersContent.concat(Phonegap.UIConfiguration.platformDrawersContent); var index =0; for (index in pgbUiData) { //The creation of the pgbValidation drawer attribute and its initialization are done in the same time. pgbValidation[pgbUiData[index].id] = {}; for (var i=0, maxLength = pgbUiData[index].rows.length; i<maxLength; i++) { //The creation of the pgbValidation row attribute and its initialization are done in the same time. pgbValidation[pgbUiData[index].id][pgbUiData[index].rows[i].name] = true; } pgbValidation[pgbUiData[index].id]["validDrawer"] = true; } inProject.setValidPgbConf(pgbValidation); } }, projectRemoved: function(inSender, inEvent) { ComponentsRegistry.getComponent("harmonia").setProject(null, ares.noNext); }, /** * Event handler: handle build project action (select provider & run action) * @param {enyo.Component} inSender * @param {Object} inEvent * @property inEvent {Ares.Model.Project} project * @private */ buildAction: function(inSender, inEvent) { var project = inEvent && inEvent.project; if (project) { this.projectAction(project, 'build', 'build'); } return true; // stop bubble-up }, /** * Event handler: handle install application action (select provider & run action) * @param {enyo.Component} inSender * @param {Object} inEvent * @property inEvent {Ares.Model.Project} project * @private */ installAction: function(inSender, inEvent) { var project = inEvent && inEvent.project; if (project) { this.projectAction(project, 'test', 'install'); } return true; // stop bubble-up }, /** * Event handler: handle run application action (select provider & run action) * @param {enyo.Component} inSender * @param {Object} inEvent * @property inEvent {Ares.Model.Project} project * @private */ runAction: function(inSender, inEvent) { var project = inEvent && inEvent.project; if (project) { this.projectAction(project, 'test', 'run'); } return true; // stop bubble-up }, /** * Event handler: handle debug application action (select provider & run action) * @param {enyo.Component} inSender * @param {Object} inEvent * @property inEvent {Ares.Model.Project} project * @private */ runDebugAction: function(inSender, inEvent) { var project = inEvent && inEvent.project; if (project) { this.projectAction(project, 'test', 'runDebug'); } return true; // stop bubble-up }, /** * @private */ projectAction: function(project, serviceType, action) { var self = this; this.doShowWaitPopup({msg: "Starting: " + action, service: serviceType}); // TODO: Must be reworked to allow the selection of builder/tester in the UI - ENYO-2049 var services = ServiceRegistry.instance.getServicesByType(serviceType); var provider = services[services.length - 1]; if (!provider) { this.doError({msg: 'No ' + serviceType + ' service available'}); } else if (typeof provider[action] !== 'function') { this.doError({msg: 'Service ' + provider.name + ' does not provide action: ' + action}); } else { provider[action](project, function(inError) { self.doHideWaitPopup(); self.refreshFileTree(project.getFolderId()); if (inError) { self.doError({msg: inError.toString(), err: inError}); } }); } }, launchPreview: function (project) { var config = project.getConfig() ; var topFile = config.data.preview.top_file ; var projectUrl = project.getProjectUrl() + '/' + topFile ; // the last replace method is needed for test environment only var winLoc = window.location.toString().replace('ares','preview').replace('test', 'index') ; var previewUrl = winLoc + ( winLoc.indexOf('?') != -1 ? '&' : '?' ) + 'url=' + encodeURIComponent(projectUrl)+'&name=' + project.id; this.trace("preview on URL ", previewUrl) ; window.open( previewUrl, '_blank', // ensure that a new window is created each time preview is tapped 'scrollbars=0,menubar=1,resizable=1', false ); }, /** * Event handler: Launch a preview widget of the selected project in a separate frame * @param {enyo.Component} inSender * @param {Object} inEvent * @property inEvent {Ares.Model.Project} project * @private */ previewAction: function(inSender, inEvent) { var project = inEvent.project; if ( project) { this.launchPreview(project); } return true; // stop the bubble } });