Newer
Older
// This file is part of VPL for Moodle - http://vpl.dis.ulpgc.es/
//
// VPL for Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// VPL for Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with VPL for Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* IDE Control
* @package mod_vpl
* @copyright 2017 Juan Carlos Rodríguez-del-Pino
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Juan Carlos Rodríguez-del-Pino <jcrodriguez@dis.ulpgc.es>
*/
/* globals MathJax */
define(
[
'jquery',
'jqueryui',
'mod_vpl/vplutil',
'mod_vpl/vplidefile',
'mod_vpl/vplidebutton',
'mod_vpl/vplterminal',
'mod_vpl/vplvnc',
],
function($, jqui, VPLUtil, VPLFile, VPLIDEButtons, VPLTerminal, VPLVNCClient) {
if (typeof VPLIDE !== 'undefined') {
return VPLIDE;
}
var vplIdeInstance;
var VPLIDE = function(rootId, options) {
var self = this;
var fileManager;
var adjustTabsTitles;
var autoResizeTab;
var showErrorMessage;
var updateMenu;
var minNumberOfFiles = options.minfiles || 0;
var maxNumberOfFiles = options.maxfiles || 0;
var restrictedEdit = options.restrictededitor || options.example;
var readOnly = options.example;
var fullScreen = false;
var scrollBarWidth = VPLUtil.scrollBarWidth();
VPLUtil.setStr({...M.str.mod_vpl, ...M.str.moodle, ...options.str});
var rootObj = $('#' + rootId);
$("head").append('<meta name="viewport" content="initial-scale=1">')
.append('<meta name="viewport" width="device-width">');
throw new Error("VPL: constructor tag_id not found");
'new': true,
'rename': true,
'delete': true,
'save': true,
'run': true,
'edit': true,
'debug': true,
'evaluate': true,
'import': true,
'resetfiles': true,
'correctedfiles': true,
'sort': true,
'multidelete': true,
'theme': true,
'console': true,
'comments': true
if ((typeof options.loadajaxurl) == 'undefined') {
options.loadajaxurl = options.ajaxurl;
}
(function() {
var activateModification = (minNumberOfFiles < maxNumberOfFiles);
options.new = activateModification;
options.rename = activateModification;
options.delete = activateModification;
options.comments = options.comments && !options.example;
})();
options.sort = (maxNumberOfFiles - minNumberOfFiles >= 2);
options.multidelete = options.sort;
options.import = !restrictedEdit;
var isOptionAllowed = function(op) {
if (!optionsToCheck[op]) {
return true;
}
return options[op];
};
options.console = isOptionAllowed('run') || isOptionAllowed('debug');
if ((typeof options.fontSize) == 'undefined') {
options.fontSize = 12;
}
options.fontSize = parseInt(options.fontSize);
/**
* Handler for dragover event.
* @param {object} e event.
*/
function dragoverHandler(e) {
if (restrictedEdit) {
e.originalEvent.dataTransfer.dropEffect = 'none';
} else {
e.originalEvent.dataTransfer.dropEffect = 'copy';
}
e.preventDefault();
}
/**
* Handler for drop event.
* @param {object} e event.
* @returns {boolean}
*/
function dropHandler(e) {
if (restrictedEdit) { // No drop allowed.
e.stopImmediatePropagation();
return false;
}
var droppedFiles = [];
// Function that lists all files and subfiles of given entry into droppedFiles.
var listDroppedFiles = function(entry, path="") {
return new Promise(function(resolve) {
if (entry.isFile) {
// Current entry is a file : add it to the list.
entry.file(function(file) {
// Change its name s.t. it preserves directories structure.
var fullName = path + file.name;
Object.defineProperty(file, "name", {
get: function() { return fullName; }
});
droppedFiles.push(file);
resolve();
});
} else if (entry.isDirectory) {
// Current entry is a directory : process its content.
var dirReader = entry.createReader();
dirReader.readEntries(function(entries) {
var dirPromises = [];
for (var i=0; i<entries.length; i++) {
dirPromises.push(listDroppedFiles(entries[i], path + entry.name + "/"));
}
Promise.all(dirPromises).then(resolve);
});
} else {
// This is neither a directory nor a file : ignore it.
resolve();
}
});
};
var dt = e.originalEvent.dataTransfer;
// List every element of the drop event.
var promises = [];
for (var i=0; i<dt.items.length; i++) {
promises.push(listDroppedFiles(dt.items[i].webkitGetAsEntry()));
}
// Drop files.
if (dt.files.length > 0) {
.then(function() {
VPLUtil.readSelectedFiles(droppedFiles, function(file) {
return fileManager.addFile(file, true, updateMenu, showErrorMessage);
},
function() {
fileManager.fileListVisibleIfNeeded();
});
return;
});
e.stopImmediatePropagation();
return false;
}
return false;
}
rootObj.on('drop', dropHandler);
rootObj.on('dragover', dragoverHandler);
/**
* Handler for paste limited by restrictedEdit var.
* @param {object} e event.
* @returns {boolean}
*/
function restrictedPaste(e) {
if (restrictedEdit) {
e.stopPropagation();
return false;
}
return true;
}
// Init editor vars.
var menu = $('#vpl_menu');
var menuButtons = new VPLIDEButtons(menu, isOptionAllowed);
var tr = $('#vpl_tr');
var fileListContainer = $('#vpl_filelist');
var fileList = $('#vpl_filelist_header');
var fileListContent = $('#vpl_filelist_content');
var tabsUl = $('#vpl_tabs_ul');
var tabs = $('#vpl_tabs');
var resultContainer = $('#vpl_results');
var result = $('#vpl_results_accordion');
fileListContainer.vplMinWidth = 80;
/**
* Avoids selecting grade.
* @param {object} event Unuse.
* @param {object} ui UI origen.
* @returns {boolean}
*/
function avoidSelectGrade(event, ui) {
if ("newHeader" in ui) {
if (ui.newHeader.hasClass('vpl_ide_accordion_t_grade')) {
return false;
}
}
return true;
/**
* Constructor of FileManager objects
*/
function FileManager() {
var tabsUl = $('#vpl_tabs_ul');
$('#vpl_tabs').tabs();
var tabs = $('#vpl_tabs').tabs("widget");
var files = [];
var openFiles = [];
var modified = true;
var self = this;
(function() {
var version;
self.setVersion = function(v) {
version = v;
};
self.getVersion = function() {
return version;
};
})();
this.updateFileList = function() {
self.generateFileList();
};
this.fileNameExists = function(name) {
var checkName = name.toLowerCase();
for (var i = 0; i < files.length; i++) {
if (files[i].getFileName().toLowerCase() == checkName) {
return i;
}
}
return -1;
};
/**
* Checks if name is included in current files names
* @param {string} name Name of file
* @returns {boolean} if found or not found
*/
function fileNameIncluded(name) {
var checkName = name.toLowerCase() + '/';
for (var i = 0; i < files.length; i++) {
var nameMod = files[i].getFileName().toLowerCase() + '/';
// Check for name as directory existent.
if (nameMod.indexOf(checkName) === 0 || checkName.indexOf(nameMod) === 0) {
return true;
}
}
return false;
}
/**
* Checks if changing file name results in two blovkly files
* @param {string} oldname The old file name
* @param {string} newname The new file name
* @returns {boolean} if results two two blovkly files
*/
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
function twoBlockly(oldname, newname) {
if (VPLUtil.isBlockly(oldname)) {
return false;
}
if (VPLUtil.isBlockly(newname)) {
for (var i = 0; i < files.length; i++) {
if (VPLUtil.isBlockly(files[i].getFileName())) {
return true;
}
}
}
return false;
}
this.restrictedPaste = restrictedPaste;
this.dropHandler = dropHandler;
this.dragoverHandler = dragoverHandler;
this.readOnly = readOnly;
this.restrictedEdit = restrictedEdit;
this.adjustTabsTitles = adjustTabsTitles;
this.minNumberOfFiles = minNumberOfFiles;
this.scrollBarWidth = scrollBarWidth;
var localClipboard = "";
this.setClipboard = function(t) {
localClipboard = t;
};
this.getClipboard = function() {
return localClipboard;
};
this.getTabPos = function(file) {
for (var i = 0; i < openFiles.length; i++) {
if (openFiles[i] == file) {
return i;
}
}
return openFiles.length;
};
this.getTheme = function() {
this.setTheme = function(theme) {
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
options.theme = theme;
for (var i = 0; i < files.length; i++) {
files[i].setTheme(theme);
}
};
this.addTab = function(fid) {
var hlink = '<a href="#vpl_file' + fid + '"></a>';
tabsUl.append('<li id="vpl_tab_name' + fid + '">' + hlink + '</li>');
tabs.append('<div id="vpl_file' + fid + '" class="vpl_ide_file"></div>');
};
this.removeTab = function(fid) {
tabsUl.find('#vpl_tab_name' + fid).remove();
tabs.find('#vpl_file' + fid).remove();
};
this.open = function(pos) {
var file;
if (typeof pos == 'object') {
file = pos;
} else {
file = files[pos];
}
if (file.isOpen()){
return;
}
var fid = file.getId();
self.addTab(fid);
openFiles.push(file);
menuButtons.setGetkeys(file.open());
tabs.tabs('refresh');
adjustTabsTitles(false);
VPLUtil.delay('updateFileList', self.updateFileList);
VPLUtil.delay('updateMenu', updateMenu);
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
};
this.close = function(file) {
if (!file.isOpen()) {
return;
}
var pos;
var fid = file.getId();
file.close();
self.removeTab(fid);
var ptab = self.getTabPos(file);
openFiles.splice(ptab, 1);
tabs.tabs('refresh');
adjustTabsTitles(false);
self.fileListVisible(true);
VPLUtil.delay('updateFileList', self.updateFileList);
VPLUtil.delay('adjustTabsTitles', adjustTabsTitles, false);
if (openFiles.length > ptab) {
pos = self.getFilePosById(openFiles[ptab].getId());
self.gotoFile(pos, 'c');
return;
}
if (ptab > 0) {
pos = self.getFilePosById(openFiles[ptab - 1].getId());
self.gotoFile(pos, 'c');
return;
}
};
this.isClosed = function(pos) {
return !files[pos].isOpen();
};
this.fileListVisible = function(b) {
if (b === fileListContainer.vplVisible){
VPLUtil.delay('fileListVisible', function() {
fileListContainer.vplVisible = true;
self.updateFileList();
fileListContainer.show();
autoResizeTab();
});
VPLUtil.delay('fileListVisible', function() {
fileListContainer.vplVisible = false;
fileListContainer.hide();
autoResizeTab();
});
}
};
this.isFileListVisible = function() {
return fileListContainer.vplVisible;
};
this.fileListVisibleIfNeeded = function() {
if (this.isFileListVisible()){
return;
}
for (var i = 0; i < files.length; i++) {
if (!files[i].isOpen()) {
this.fileListVisible(true);
return;
}
}
};
this.setFontSize = function(size) {
options.fontSize = size;
for (var i = 0; i < files.length; i++) {
files[i].setFontSize(size);
}
terminal.setFontSize(size);
};
this.getFontSize = function() {
return options.fontSize;
};
this.addFile = function(file, replace, ok, showError) {
if ((typeof file.name != 'string') || !VPLUtil.validPath(file.name)) {
showError(str('incorrect_file_name') + ' (' + file.name + ')');
return false;
}
if (replace !== true) {
replace = false;
}
var pos = this.fileNameExists(file.name);
if (pos != -1) {
if (replace) {
files[pos].setContent(file.contents);
self.setModified();
ok();
VPLUtil.delay('updateFileList', self.updateFileList);
return file;
} else {
showError(str('filenotadded', file.name));
return false;
}
}
if (fileNameIncluded(file.name) || twoBlockly('', file.name)) {
showError(str('filenotadded', file.name));
return false;
}
if (files.length >= maxNumberOfFiles) {
showError(str('maxfilesexceeded') + ' (' + maxNumberOfFiles + ')');
return false;
}
var fid = VPLUtil.getUniqueId();
var newfile = new VPLFile(fid, file.name, file.contents, this, vplIdeInstance, options.id);
if (file.encoding == 1) {
newfile.extendToBinary();
} else {
if (VPLUtil.isBlockly(file.name)) {
newfile.extendToBlockly();
} else {
newfile.extendToCodeEditor();
}
}
newfile.setFileName(file.name);
files.push(newfile);
self.setModified();
if (files.length > 5) {
self.fileListVisible(true);
}
ok();
return newfile;
};
this.renameFile = function(oldname, newname, showError) {
var pos = this.fileNameExists(oldname);
try {
if (pos == -1) {
throw new Error("Internal error: File name not found");
if (pos < minNumberOfFiles) {
throw new Error("Internal error: Renaming required filename");
if (files[pos].getFileName() == newname) {
return true; // Equals name file.
}
if (!VPLUtil.validPath(newname) ||
fileNameIncluded(newname) ||
twoBlockly(oldname, newname)) {
throw str('incorrect_file_name');
}
if (VPLUtil.isBinary(oldname) && VPLUtil.fileExtension(oldname) != VPLUtil.fileExtension(newname)) {
throw str('incorrect_file_name');
}
if (VPLUtil.isBlockly(oldname) != VPLUtil.isBlockly(newname)) {
throw str('incorrect_file_name');
}
files[pos].setFileName(newname);
} catch (e) {
showError(str('filenotrenamed', newname) + ': ' + e);
return false;
}
self.setModified();
adjustTabsTitles(false);
VPLUtil.delay('updateFileList', self.updateFileList);
return true;
};
this.deleteFile = function(name, ok, showError) {
var pos = this.fileNameExists(name);
if (pos == -1) {
showError(str('filenotdeleted', name));
return false;
}
if (pos < minNumberOfFiles) {
showError(str('filenotdeleted', name));
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
return false;
}
self.setModified();
self.close(files[pos]);
files.splice(pos, 1);
VPLUtil.delay('updateFileList', self.updateFileList);
return true;
};
this.currentFile = function() {
var id = tabs.tabs('option', 'active');
if (id in openFiles) {
var file = openFiles[id];
if (arguments.length === 0) {
return file;
}
var action = arguments[0];
if (typeof file[action] === 'function') {
var fun = file[action];
var args = Array.prototype.slice(arguments);
args.shift();
return fun.apply(file, args);
}
}
return false;
};
this.currentPos = function() {
return tabs.tabs('option', 'active');
};
this.getFileTab = function(id) {
for (var i = 0; i < openFiles.length; i++) {
if (openFiles[i].getId() == id) {
return i;
}
}
return -1;
};
this.getFilePosById = function(id) {
for (var i = 0; i < files.length; i++) {
if (files[i].getId() == id) {
return i;
}
}
return -1;
};
this.gotoFile = function(pos, l) {
var file = files[pos];
self.open(file);
tabs.tabs('option', 'active', self.getFileTab(file.getId()));
if (l !== 'c') {
file.gotoLine(parseInt(l, 10));
}
file.focus();
};
this.gotoFileLink = function(a) {
var tag = $(a);
var fname = tag.data('file');
var fpos = -1;
if (fname > '') {
fpos = this.fileNameExists(fname);
fpos = self.getFilePosById(tag.data('fileid'));
}
if (fpos >= 0) {
var line = tag.data('line');
if (typeof line == 'undefined') {
line = 'c';
}
self.gotoFile(fpos, line);
return true;
return false;
};
this.getFilesToSave = function() {
var ret = [];
for (var i = 0; i < files.length; i++) {
var file = {};
file.name = files[i].getFileName();
file.contents = files[i].getContent();
file.encoding = files[i].isBinary() ? 1 : 0;
ret.push(file);
}
return ret;
};
this.resetModified = function() {
modified = false;
for (var i = 0; i < files.length; i++) {
files[i].resetModified();
}
VPLUtil.delay('updateMenu', updateMenu);
VPLUtil.delay('updateFileList', self.updateFileList);
};
this.setModified = function() {
modified = true;
VPLUtil.delay('updateFileList', self.updateFileList);
VPLUtil.delay('updateMenu', updateMenu);
};
this.isModified = function() {
return modified;
};
this.length = function() {
return files.length;
};
this.clearAnnotations = function() {
for (var i = 0; i < files.length; i++) {
files[i].clearAnnotations();
}
};
this.getFile = function(i) {
return files[i];
};
this.getFiles = function() {
return files;
};
this.getDirectoryStructure = function() {
var structure = {
isDir: true,
content: {}
/**
* Adds a new file the structure of directories
* @param {int} i Index of file to add in the file array
*/
function addFilePath(i) {
var file = files[i];
var fileName = file.getFileName();
var path = fileName.split("/");
var curdir = structure;
for (var p in path) {
if (path.hasOwnProperty(p)) {
var part = path[p];
if (p == path.length - 1) { // File.
curdir.content[part] = {
isDir: false,
content: file,
pos: i
};
} else {
if (!curdir.content[part]) { // New dir.
isDir: true,
content: {}
// Descend Dir.
curdir = curdir.content[part];
for (var i in files) {
if (files.hasOwnProperty(i)) {
addFilePath(i);
}
}
return structure;
};
this.generateFileList = function() {
if (!self.isFileListVisible()) {
return;
}
var dirIndent = '<span class="vpl_ide_dirindent"></span>';
/**
* Generates an array of string with the HTML code to represent the list of IDE files
* @param {Object} dir Current directory
* @param {int} indent Html code to indent subdirectories
* @param {Array} lines Output. Each line contains the HTML to represent an IDE file
*/
function lister(dir, indent, lines) {
if (dir.content.hasOwnProperty(name)) {
var fd = dir.content[name];
if (fd.isDir) {
lines.push(indent + VPLUtil.iconFolder() + VPLUtil.sanitizeText(name));
lister(fd, indent + dirIndent, lines);
} else {
var file = fd.content;
var sname = VPLUtil.sanitizeText(name);
var path = VPLUtil.sanitizeText(file.getFileName());
if (file.isOpen()) {
sname = '<b>' + sname + '</b>';
}
var attrs = 'href="#" data-fileid="' + file.getId() + '" title="' + path + '"';
var line = '<a ' + attrs + '>' + sname + '</a>';
if (file.isModified()) {
line = VPLUtil.iconModified() + line;
}
if (fd.pos < minNumberOfFiles) {
line = line + VPLUtil.iconRequired();
}
lines.push(indent + line);
}
}
}
}
var structure = self.getDirectoryStructure();
var lines = [];
var html = '';
lister(structure, '', lines);
for (var i = 0; i < lines.length; i++) {
html += lines[i] + '<br>';
}
fileListContent.html('<div>' + html + '</div>');
};
tabsUl.on('click', 'span.vpl_ide_closeicon', function() {
fileManager.close(fileManager.currentFile());
});
tabsUl.on('dblclick', 'span.vpl_ide_closeicon', menuButtons.getAction('delete'));
tabsUl.on('dblclick', 'a', menuButtons.getAction('rename'));
fileListContent.on('dblclick', 'a', menuButtons.getAction('rename'));
}
this.updateEvaluationNumber = function(res) {
if (typeof res.nevaluations != 'undefined') {
if (typeof res.reductionbyevaluation != 'undefined'
&& res.reductionbyevaluation > ''
&& res.reductionbyevaluation != 0) {
if (res.freeevaluations != 0) {
text = text + '/' + res.freeevaluations;
}
text = text + ' -' + res.reductionbyevaluation;
}
menuButtons.setExtracontent('evaluate', text);
}
};
this.lastResult = null;
this.getTerminal = function() {
return terminal;
};
this.setResultGrade = function(content, raw) {
var name = 'grade';
var titleclass = 'vpl_ide_accordion_t_' + name;
var contentclass = 'vpl_ide_accordion_c_' + name;
if (result.find('.' + contentclass).length == 0) {
result.append('<div class="' + titleclass + '"></div>');
result.append('<div class="' + contentclass + '"></div>');
}
if (typeof raw == 'undefined') {
return result.find('h4.' + titleclass).length > 0;
}
var titleTag = result.find('.' + titleclass);
if (content > '') {
titleTag.replaceWith('<h4 class="' + titleclass + '">' + content + '</h4>');
return true;
} else {
titleTag.replaceWith('<div class="' + titleclass + '"></div>');
return false;
}
};
this.setResultTab = function(name, content, raw) {
var titleclass = 'vpl_ide_accordion_t_' + name;
var contentclass = 'vpl_ide_accordion_c_' + name;
if (result.find('.' + contentclass).length == 0) {
result.append('<div class="' + titleclass + '"></div>');
result.append('<div class="' + contentclass + '"></div>');
}
if (typeof raw == 'undefined') {
return result.find('h4.' + titleclass).length > 0;
}
var titleTag = result.find('.' + titleclass);
var contentTag = result.find('.' + contentclass);
var HTMLcontent = $('<div>' + content + '</div>');
HTMLcontent.find('h4').replaceWith(function() {
return $("<h5>").append($(this).contents());
});
if (contentTag.html() == HTMLcontent.html()) {
if (content > '') {
titleTag.replaceWith('<h4 class="' + titleclass + '">' + str(name) + '</h4>');
contentTag.replaceWith('<div class="ui-widget ' + contentclass + '">' + HTMLcontent.html() + '</div>');
return true;
} else {
titleTag.replaceWith('<div class="' + titleclass + '"></div>');
contentTag.replaceWith('<div class="' + contentclass + '"></div>');
return false;
}
};
this.setResult = function(res, go) {
self.updateEvaluationNumber(res);
var files = fileManager.getFiles();
var fileNames = [];
var i;
for (i = 0; i < files.length; i++) {
fileNames[i] = files[i].getFileName();
files[i].clearAnnotations();
}
var show = false;
var hasContent;
var grade = VPLUtil.sanitizeText(res.grade);
var gradeShow;
var formated;
gradeShow = self.setResultGrade(grade, res.grade);
show = show || gradeShow;
hasContent = self.setResultTab('variables', res.variables, res.variables);
show = show || hasContent;
formated = VPLUtil.processResult(res.compilation, fileNames, files, true, false);
hasContent = self.setResultTab('compilation', formated, res.compilation);
show = show || hasContent;
formated = VPLUtil.processResult(res.evaluation, fileNames, files, false, false);
hasContent = self.setResultTab('comments', formated, res.evaluation);
show = show || hasContent;
formated = VPLUtil.sanitizeText(res.execution);
hasContent = self.setResultTab('execution', formated, res.execution);
show = show || hasContent;
hasContent = self.setResultTab('description', options.description, options.description);
if (hasContent && typeof MathJax == 'object') { // MathJax workaround.
var math = result.find(".vpl_ide_accordion_c_description")[0];
MathJax.Hub.Queue(["Typeset", MathJax.Hub, math]);
}
show = show || hasContent;
if ( show ) {
resultContainer.show();
resultContainer.vplVisible = true;
result.accordion("refresh");
result.accordion('option', 'active', gradeShow ? 1 : 0);
for (i = 0; i < files.length; i++) {
var anot = files[i].getAnnotations();
for (var j = 0; j < anot.length; j++) {
if (go || anot[j].type == 'error') {
fileManager.gotoFile(i, anot[j].row + 1);
break;
}
}
}
} else {
resultContainer.hide();
resultContainer.vplVisible = false;
}
VPLUtil.delay('autoResizeTab', autoResizeTab);
};
result.accordion({
heightStyle: 'fill',
header: 'h4',
beforeActivate: avoidSelectGrade,
});
result.on('click', 'a', function(event) {
if (fileManager.gotoFileLink(event.currentTarget)) {
event.preventDefault();
}
resultContainer.vplVisible = false;
resultContainer.hide();
fileListContainer.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all');
fileList.text(str('filelist'));
fileList.html(VPLUtil.iconFolder() + fileList.html());
fileList.addClass("ui-widget-header ui-button-text-only ui-corner-all");
fileListContent.addClass("ui-widget ui-corner-all");
fileListContainer.width(2 * fileListContainer.vplMinWidth);
fileListContainer.on('click', 'a', function(event) {
event.preventDefault();
fileManager.gotoFileLink(event.currentTarget);
});
fileListContainer.vplVisible = false;
fileListContainer.hide();
var tabsAir = false;
/**
* Returns separation space
* @returns {int} size in pixels
*/
function getTabsAir() {
if (tabsAir === false) {
tabsAir = (tabs.outerWidth(true) - tabs.width()) / 2;
}
return tabsAir;
}
/**
* Resize tab width
* @param {Event} e Unused
* @param {Object} ui UI object
*/
function resizeTabWidth(e, ui) {
var diffLeft = ui.position.left - ui.originalPosition.left;
var maxWidth;
if (diffLeft !== 0) {
maxWidth = tabs.width() + fileListContainer.width() - fileListContainer.vplMinWidth;
tabs.resizable('option', 'maxWidth', maxWidth);
fileListContainer.width(fileListContainer.vplOriginalWidth + diffLeft);
} else {
var diff_width = ui.size.width - ui.originalSize.width;
resultContainer.width(resultContainer.vplOriginalWidth - diff_width);
}
fileManager.currentFile('adjustSize');
}
var resizableOptions = {
containment: 'parent',
resize: resizeTabWidth,
start: function() {
$(window).off('resize', autoResizeTab);
tabs.resizable('option', 'minWidth', 100);
if (resultContainer.vplVisible) {
resultContainer.vplOriginalWidth = resultContainer.width();
if (fileListContainer.vplVisible) {
fileListContainer.vplOriginalWidth = fileListContainer.width();
stop: function(e, ui) {
resizeTabWidth(e, ui);
tabs.resizable('option', 'maxWidth', 100000);
tabs.resizable('option', 'minWidth', 0);
autoResizeTab();
$(window).on('resize', autoResizeTab);
},
handles : ""
};
tabs.resizable(resizableOptions);
/**
* Updates handles for internal IDE resize
*/
var handles = ['e', 'w', 'e', 'e, w'];
index += fileListContainer.vplVisible ? 1 : 0;
index += resultContainer.vplVisible ? 2 : 0;
tabs.resizable('destroy');
resizableOptions.handles = handles[index];
resizableOptions.disable = index === 0;
tabs.resizable(resizableOptions);
}
/**
* Resize the IDE height
*/
var newHeight = (fullScreen ? 1 : 0.7) * ($(window).innerHeight() - menu.height() - getTabsAir());
if (newHeight < 150) {
newHeight = 150;
}
tr.height(newHeight);
var panelHeight = newHeight - 3 * getTabsAir();
tabs.height(panelHeight);
if (resultContainer.vplVisible) {
resultContainer.height(panelHeight + getTabsAir());
result.accordion('refresh');
if (fileListContainer.vplVisible) {
fileListContent.height(panelHeight - (fileList.outerHeight() + getTabsAir()));
fileListContainer.height(panelHeight);
}
}
adjustTabsTitles = function(center) {
var newWidth = tabs.width();
var tabsUlWidth = 0;
tabsUl.width(100000);
var last = tabsUl.children('li:visible').last();
if (last.length) {
var parentScrollLeft = tabsUl.parent().scrollLeft();
tabsUlWidth = parentScrollLeft + last.position().left + last.width() + tabsAir;
tabsUl.width(tabsUlWidth);
var file = fileManager.currentFile();
if (file && center) {
var fileTab = $(file.getTabNameId());
var scroll = parentScrollLeft + fileTab.position().left;
scroll -= (newWidth - fileTab.outerWidth()) / 2;
if (scroll < 0) {
scroll = 0;
}
tabsUl.parent().finish().animate({
scrollLeft: scroll
}, 'slow');
}
}
if (tabsUlWidth < newWidth) {
tabsUl.width('');
}
};
autoResizeTab = function() {
var oldWidth = tabs.width();
var newWidth = menu.width();
var planb = false;
updateTabsHandles();
tr.width(menu.outerWidth());
if (fileListContainer.vplVisible) {