// 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/>. /** * File managament * * @package mod_vpl * @copyright 2013 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 Interpreter */ /* globals ace */ /* globals Blockly */ define(['jquery', 'jqueryui', 'mod_vpl/vplutil', ], function($, jqui , VPLUtil) { if ( typeof VPLFile != 'undefined') { return VPLFile; } var VPLFile = function(id, name, value, fileManager, vplIdeInstance, id_vpl) { var tid = "#vpl_file" + id; var tabnameid = "#vpl_tab_name" + id; var fileName = name; var modified = true; var opened = false; var self = this; var current_id_vpl = id_vpl; this.getCurrentIdVpl = function() { return current_id_vpl; }; this.getId = function() { return id; }; this.getTabNameId = function() { return tabnameid; }; this.getTId = function() { return tid; }; this.getFileName = function() { return fileName; }; this.resetModified = function() { modified = false; this.setFileName(fileName); }; this.getTabPos = function() { return fileManager.getTabPos(this); }; this.isOpen = function() { return opened; }; this.isModified = function() { return modified; }; this.change = function() { if (!modified) { modified = true; fileManager.generateFileList(); this.setFileName(fileName); // TODO update state of filename. } VPLUtil.longDelay('setModified', fileManager.setModified); }; this.setFileName = function(name) { if (!VPLUtil.validPath(name)) { return false; } if (name != fileName) { fileName = name; self.change(); } if (!opened) { return true; } var fn = VPLUtil.getFileName(name); if (fn.length > 20) { fn = fn.substring(0, 16) + '...'; } var html = (modified ? VPLUtil.iconModified() : '') + fn; if (this.getTabPos() < fileManager.minNumberOfFiles) { html = html + VPLUtil.iconRequired(); } else { html = html + VPLUtil.iconClose(); } $(tabnameid + ' a').html(html); if (fn != name) { $(tabnameid + ' a').attr('title', name); } if (modified) { fileManager.adjustTabsTitles(false); } this.langSelection(); return true; }; this.getContent = function() { return value; }; this.setContent = function(c) { value = c; }; this.destroy = function() { $(tabnameid).remove(); $(tid).remove(); }; this.adjustSize = function() { if (!opened) { return false; } var editTag = $(tid); var tabs = editTag.parent(); if (editTag.length === 0) { return; } var editorHeight = editTag.height(); var editorWidth = editTag.width(); var newHeight = tabs.height(); newHeight -= editTag.position().top; var newWidth = $('#vpl_tabs_scroll').width(); if (newHeight != editorHeight || newWidth != editorWidth) { $(editTag).height(newHeight); $(editTag).width(newWidth); return true; } return false; }; this.gotoLine = VPLUtil.doNothing; this.setReadOnly = VPLUtil.doNothing; this.focus = VPLUtil.doNothing; this.blur = VPLUtil.doNothing; this.undo = VPLUtil.doNothing; this.redo = VPLUtil.doNothing; this.selectAll = VPLUtil.doNothing; this.open = VPLUtil.doNothing; this.hasUndo = VPLUtil.returnFalse; this.hasRedo = VPLUtil.returnFalse; this.hasSelectAll = VPLUtil.returnFalse; this.hasFind = VPLUtil.returnFalse; this.hasFindReplace = VPLUtil.returnFalse; this.hasNext = VPLUtil.returnFalse; this.find = VPLUtil.doNothing; this.replace = VPLUtil.doNothing; this.next = VPLUtil.doNothing; this.getAnnotations = function() { return []; }; this.setAnnotations = VPLUtil.doNothing; this.setFontSize = VPLUtil.doNothing; this.setTheme = VPLUtil.doNothing; this.clearAnnotations = VPLUtil.doNothing; this.langSelection = VPLUtil.doNothing; this.isBinary = function() { return false; }; this.extendToCodeEditor = function() { var editor = null; var session = null; var readOnly = fileManager.readOnly; this.getContent = function() { if (!opened) { return value; } return editor.getValue(); }; this.setContent = function(c) { value = c; if (opened) { editor.setValue(c); } }; this.oldDestroy = this.destroy; this.destroy = function() { if (opened) { editor.destroy(); } this.oldDestroy(); }; this.setFontSize = function(size) { if (opened) { editor.setFontSize(size); } }; this.oldAdjustSize = this.adjustSize; this.adjustSize = function() { if (this.oldAdjustSize()) { editor.resize(); return true; } return false; }; this.gotoLine = function(line) { if (!opened) { return; } editor.gotoLine(line, 0); editor.scrollToLine(line, true); editor.focus(); }; this.setReadOnly = function(s) { readOnly = s; if (opened) { editor.setReadOnly(s); } }; this.focus = function() { if (!opened) { return; } $(tid).removeClass('ui-widget-content ui-tabs-panel'); $(tid).addClass('ui-corner-bottom'); this.adjustSize(); editor.focus(); }; this.blur = function() { if (!opened) { return; } editor.blur(); }; this.undo = function() { if (!opened) { return; } editor.undo(); editor.focus(); }; this.redo = function() { if (!opened) { return; } editor.redo(); editor.focus(); }; this.selectAll = function() { if (!opened) { return; } editor.selectAll(); editor.focus(); }; this.hasUndo = function() { if (!opened) { return false; } return session.getUndoManager().hasUndo(); }; this.hasRedo = function() { if (!opened) { return false; } return session.getUndoManager().hasRedo(); }; this.hasSelectAll = VPLUtil.returnTrue; this.hasFind = VPLUtil.returnTrue; this.hasFindReplace = VPLUtil.returnTrue; this.hasNext = VPLUtil.returnTrue; this.find = function() { if (!opened) { return; } editor.execCommand('find'); }; this.replace = function() { if (!opened) { return; } editor.execCommand('replace'); }; this.next = function() { if (!opened) { return; } editor.execCommand('findnext'); }; this.getAnnotations = function() { if (!opened) { return []; } return session.getAnnotations(); }; this.setAnnotations = function(a) { if (!opened) { return; } return session.setAnnotations(a); }; this.clearAnnotations = function() { if (!opened) { return; } return session.clearAnnotations(); }; this.langSelection = function() { if (!opened) { return; } var ext = VPLUtil.fileExtension(fileName); var lang = 'text'; if (ext !== '') { lang = VPLUtil.langType(ext); } session.setMode("ace/mode/" + lang); }; this.getEditor = function() { if (!opened) { return false; } return editor; }; this.setTheme = function(theme) { if (!opened) { return; } editor.setTheme("ace/theme/" + theme); }; this.$_GET = function(param) { var vars = {}; window.location.href.replace( location.hash, '' ).replace( /[?&]+([^=&]+)=?([^&]*)?/gi, // regexp function( m, key, value ) { // callback vars[key] = value !== undefined ? value : ''; } ); if ( param ) { return vars[param] ? vars[param] : null; } return vars; }; this.check_difference = function() { var URL; if (typeof VPLUtil.get_absolute_path() !== "undefined") { URL = VPLUtil.get_absolute_path() + "/similarity/diff_check_requested_files.php"; } else { URL = "../similarity/diff_check_requested_files.php"; } $.ajax({ method: "POST", url: URL, data: { id : current_id_vpl, name: fileName, val : editor.getValue() } }) .done(function( data ) { var modified = 'ace-changed'; // css class var i; for (i = 0; i < data.length; i++) { if(data[i].type != "=") { editor.session.removeGutterDecoration(data[i].ln2-1, modified); editor.session.addGutterDecoration(data[i].ln2-1, modified); } else { editor.session.removeGutterDecoration(data[i].ln2-1, modified); } } }); }; this.open = function() { if ( typeof ace === 'undefined' ) { var URL, URL2; if (typeof VPLUtil.get_absolute_path() !== "undefined") { URL = VPLUtil.get_absolute_path() + '/editor/ace9/ace.js'; URL2 = VPLUtil.get_absolute_path() + '/editor/ace9/ext-language_tools.js'; } else { URL = '../editor/ace9/ace.js'; URL2 = '../editor/ace9/ext-language_tools.js'; } VPLUtil.loadScript([URL, URL2], function() {self.open();}); return; } if (opened) { return false; } // Workaround to remove jquery-ui theme background color. $(tid).removeClass('ui-widget-content ui-tabs-panel'); $(tid).addClass('ui-corner-bottom'); ace.require("ext/language_tools"); opened = true; editor = ace.edit("vpl_file" + id); session = editor.getSession(); editor.setOptions({ enableBasicAutocompletion : true, enableSnippets : true, }); editor.setFontSize(fileManager.getFontSize()); editor.setTheme("ace/theme/" + fileManager.getTheme()); this.setFileName(fileName); editor.setValue(value); editor.gotoLine(0, 0); editor.setReadOnly(readOnly); session.setUseSoftTabs(true); session.setTabSize(4); // Avoid undo of editor initial content. session.setUndoManager(new ace.UndoManager()); // Code to control Paste and drop under restricted editing. editor.execCommand('replace'); function addEventDrop() { var tag = $(tid + ' div.ace_search'); if (tag.length) { tag.on('drop', fileManager.dropHandler); var button = $('button.ace_searchbtn_close'); button.css({ marginLeft : "1em", marginRight : "1em" }); button.trigger('click'); } else { setTimeout(addEventDrop, 50); } } this.check_difference(); editor.on('change', function() { self.change(); self.check_difference(); }); // Try to grant dropHandler installation. setTimeout(addEventDrop, 5); // Save previous onPaste and change for a new one. var prevOnPaste = editor.onPaste; editor.onPaste = function(s) { if (fileManager.restrictedEdit) { editor.insert(fileManager.getClipboard()); } else { prevOnPaste.call(editor, s); } }; // Control copy and cut (yes cut also use this) for localClipboard. editor.on('copy', function(t) { fileManager.setClipboard(t); }); $(tid).on('paste', '*', fileManager.restrictedPaste); $(tid + ' div.ace_content').on('drop', fileManager.dropHandler); $(tid + ' div.ace_content').on('dragover', fileManager.dragoverHandler); this.adjustSize(); return editor; }; this.close = function() { opened = false; if (editor === null) { return; } value = editor.getValue(); editor.destroy(); editor = null; session = null; }; }; this.adaptBlockly = function() { if (typeof Blockly.PHP.workspaceToCodeOld == 'undefined') { Blockly.PHP.workspaceToCodeOld = Blockly.PHP.workspaceToCode; Blockly.PHP.workspaceToCode = function(workspace) { return "<?\n" + Blockly.PHP.workspaceToCodeOld(workspace); }; } if (typeof Blockly.Python.workspaceToCodeOld == 'undefined') { Blockly.Python.workspaceToCodeOld = Blockly.Python.workspaceToCode; Blockly.Python.workspaceToCode = function(workspace) { return "# -*- coding: utf-8 -*-\n" + Blockly.Python.workspaceToCodeOld(workspace); }; } }; this.extendToBlockly = function() { this.firstFocus = true; this.workspacePlayground = false; this.focus = function() { if ( self.firstFocus ) { if ( self.workspacePlayground ) { self.firstFocus = false; Blockly.Events.disable(); self.setContent(value); VPLUtil.adjustBlockly(self.workspacePlayground, 10, 10); self.workspacePlayground.scrollX = 0; self.workspacePlayground.scrollY = 0; Blockly.svgResize(self.workspacePlayground); Blockly.resizeSvgContents(self.workspacePlayground); self.adjustSize(); Blockly.Events.enable(); } else { VPLUtil.longDelay('focus', self.focus); } } }; this.adjustSize = function() { if (!opened || !this.workspacePlayground) { return false; } var editTag = $(tid); if (editTag.length === 0) { return false; } var tabs = editTag.parent(); var newHeight = tabs.height(); newHeight -= editTag.position().top; editTag.height(newHeight); $('#' + this.bdiv).height(newHeight); $('#' + this.bdiv).width(editTag.width()); Blockly.svgResize(this.workspacePlayground); return false; }; this.undo = function() { if (opened) { this.workspacePlayground.undo(false); } }; this.redo = function() { if (opened) { this.workspacePlayground.undo(true); } }; this.interpreter = false; this.animateRun = false; this.RUNSTATE = 1; this.STEPSTATE = 2; this.STOPSTATE = 3; this.executionState = this.STOPSTATE; this.goNext = false; this.initRun = function(animate) { var ter = vplIdeInstance.getTerminal(); if (ter.isConnected()) { ter.closeLocal(); } this.animateRun = animate; Blockly.JavaScript.STATEMENT_PREFIX = 'highlightBlock(%1);\n'; Blockly.JavaScript.addReservedWords('highlightBlock'); var code = Blockly.JavaScript.workspaceToCode(self.workspacePlayground); function initApi(interpreter, scope) { // Add an API function for the alert() block. var wrapper = function(text) { text = text ? text.toString() + '\r\n' : text + '\r\n'; return interpreter.createPrimitive(ter.writeLocal(text)); }; interpreter.setProperty(scope, 'alert', interpreter.createNativeFunction(wrapper)); // Add an API function for the prompt() block. wrapper = function(text, callback) { text = text ? text.toString() : '' + text; ter.writeLocal(text); ter.setDataCallback(function(t) {ter.writeLocal('\n');callback(t);}); }; interpreter.setProperty(scope, 'prompt', interpreter.createAsyncFunction(wrapper)); wrapper = function(id) { if (id == self.breakpoint) { self.executionState = self.STEPSTATE; self.updateRunButtons(); vplIdeInstance.getTerminal().setMessage(VPLUtil.str('breakpoint')); } if (self.animateRun || self.executionState == self.STEPSTATE) { self.workspacePlayground.highlightBlock(id); } self.goNext = false; }; interpreter.setProperty(scope, 'highlightBlock', interpreter.createNativeFunction(wrapper)); } self.interpreter = new Interpreter(code, initApi); ter.connectLocal(self.stop,function(){}); }; this.reservedWords = {'Infinity': true, 'Array': true, 'Boolean': true, 'Date': true, 'Error': true, 'EvalError': true, 'Function': true, 'JSON': true, 'Math': true, 'NaN': true, 'Number': true, 'Object': true, 'RangeError': true, 'ReferenceError': true, 'RegExp': true, 'String': true, 'SyntaxError': true, 'TypeError': true, 'URIError': true, 'alert': true, 'arguments': true, 'constructor': true, 'eval': true, 'highlightBlock': true, 'isFinite': true, 'isNaN': true, 'parseFloat': true, 'parseInt' : true, 'prompt': true, 'self': true, 'this': true, 'window': true}; this.breakpoint = ''; this.getVarValue = function(val) { var HTML = ''; if ( val === null ) { HTML = "<b>null</b>"; } else if (val != undefined){ var type = typeof val; if (type == 'string' ) { HTML = '"' + VPLUtil.sanitizeText(val) + '"'; } else if (type == 'boolean') { HTML = "<b>" + val + "</b>"; } else if (type == 'object' && val.class === "Array") { HTML = '['; var ar = val.properties; for (var i = 0; i < ar.length; i++) { HTML += self.getVarValue(ar[i]); if ( i != ar.length - 1) { HTML += ', '; } } HTML += ']'; } else if (type == 'object') { HTML = "<b>" + val.toString() + "</b>"; } else { HTML += ''+ val; } } return HTML; }; this.getVariables = function(properties) { var HTML = ''; for (var proname in properties) { if ( this.reservedWords[proname] === true) { continue; } var pro = properties[proname]; if (pro != undefined && !(pro.class === "Function")){ HTML += '<b>' + proname + "</b>: " + self.getVarValue(pro) + "<br>\n"; } } return HTML; }; this.getParameters = function(args) { var HTML = '('; for ( var i = 0; i < args.length; i++) { HTML += '' + args[i]; if ( i < args.length - 1) { HTML += ', '; } } return HTML + ')'; }; this.showStack = function(interpreter) { var sn = 0; var HTML = '<table class="generaltable">'; var stack = interpreter.stateStack; var lastFunc = '<tr><td>0</td><td><b>Globals</b></td>'; for (var i = 0; i < stack.length; i++) { var level = stack[i]; if (lastFunc >'' && (level.node.type == 'CallExpression' || i == stack.length - 1)) { HTML += lastFunc + '<td>' + self.getVariables(level.scope.properties); HTML += '</td></tr>'; } if (level.node.type == 'CallExpression') { if (self.reservedWords[level.node.callee.name] !== true && level.node.callee.name != undefined) { sn++; lastFunc = '<tr><td>' + sn + '</td>'; lastFunc += '<td>' + level.node.callee.name + self.getParameters(level.arguments_) + '</td>'; } else { lastFunc = ''; } } } HTML += '</table>'; vplIdeInstance.setResult({variables:HTML}); }; this.runLoop = function() { if (! self.interpreter ) { return; } self.goNext = true; for (var i=0; i< 30000 && self.goNext; i++) { if (self.executionState == self.STOPSTATE){ break; } if ( ! self.interpreter || !self.interpreter.step() ) { self.executionState = self. STOPSTATE; self.updateRunButtons(); break; } } if ( self.executionState == self.STOPSTATE ) { self.workspacePlayground.highlightBlock(-1); vplIdeInstance.getTerminal().closeLocal(); vplIdeInstance.setResult({variables:''}); return; } if ( self.executionState == self.RUNSTATE) { setTimeout(self.runLoop, 0); } else { self.showStack(self.interpreter); } }; this.start = function() { self.initRun(false); self.executionState = self.RUNSTATE; self.updateRunButtons(); vplIdeInstance.getTerminal().setMessage(VPLUtil.str('start')); self.runLoop(); }; this.startAnimate = function() { self.initRun(true); self.executionState = self.RUNSTATE; self.updateRunButtons(); vplIdeInstance.getTerminal().setMessage(VPLUtil.str('startanimate')); self.runLoop(); }; this.stop = function() { self.executionState = self.STOPSTATE; self.updateRunButtons(); vplIdeInstance.getTerminal().setMessage(VPLUtil.str('stop')); vplIdeInstance.getTerminal().closeLocal(); self.interpreter = false; vplIdeInstance.setResult({variables:''}); }; this.pause = function() { self.executionState = self.STEPSTATE; vplIdeInstance.getTerminal().setMessage(VPLUtil.str('pause')); self.updateRunButtons(); }; this.resume = function() { self.executionState = self.RUNSTATE; vplIdeInstance.getTerminal().setMessage(VPLUtil.str('resume')); self.updateRunButtons(); self.runLoop(); }; this.step = function() { if (self.executionState == self.STOPSTATE) { self.initRun(true); } self.executionState = self.STEPSTATE; self.updateRunButtons(); vplIdeInstance.getTerminal().setMessage(VPLUtil.str('step')); self.runLoop(); }; this.hasUndo = function() { return true; }; this.hasRedo = function() { return true; }; this.oldSetFileName = this.setFileName; this.generatorMap = { py: 'Python', dart: 'Dart', js: 'JavaScript', lua: 'Lua', php: 'PHP' }; this.generator = ''; this.setFileName = function(name) { var regExt2 = /\.([^.]+)\.blockly[123]?$/; var regFn2 = /(.+)\.blockly[123]?$/; var oldExt = VPLUtil.fileExtension(fileName); self.oldSetFileName(name); var ext2 = regExt2.exec(fileName); var fn2 = regFn2.exec(fileName); if ( ext2 !== null && fn2 !== null && typeof this.generatorMap[ext2[1]] == 'string' ) { this.generator = this.generatorMap[ext2[1]]; this.generatedFilename = fn2[1]; } else { this.generator = ''; } if (fn2 !== null && oldExt != VPLUtil.fileExtension(fileName)) { this.setToolbox(); } }; this.changeCode = function(event) { if ( event.type == 'ui' && event.element == 'selected') { self.breakpoint = event.newValue; return; } if ( event.type == 'ui' && event.element == 'category' && event.newValue == VPLUtil.str('run')) { self.updateRunButtons(); return; } if ( ! event.recordUndo ) { return; } self.change(); if ( this.generator != '' ) { var code = Blockly[this.generator].workspaceToCode(self.workspacePlayground); var fid = fileManager.fileNameExists(this.generatedFilename); // Try to create generated code file if ( fid == -1 ) { fileManager.addFile({ name: this.generatedFilename, contents: ''}, false, VPLUtil.doNothing, VPLUtil.doNothing); fid = fileManager.fileNameExists(this.generatedFilename); } if ( fid != -1 ) { var fc = fileManager.getFile(fid); fc.setContent(code); fc.change(); fc.gotoLine(1); fc.setReadOnly(true); } } }; this.updateRunButtons = function() { switch (self.executionState) { case self.RUNSTATE: { $('.blocklyStartC').hide(); $('.blocklyStartAnimateC').hide(); $('.blocklyStopC').show(); $('.blocklyPauseC').show(); $('.blocklyResumeC').hide(); $('.blocklyStepC').hide(); break; } case self.STEPSTATE: { $('.blocklyStartC').hide(); $('.blocklyStartAnimateC').hide(); $('.blocklyStopC').show(); $('.blocklyPauseC').hide(); $('.blocklyResumeC').show(); $('.blocklyStepC').show(); break; } case self.STOPSTATE: { $('.blocklyStartC').show(); $('.blocklyStartAnimateC').show(); $('.blocklyStopC').hide(); $('.blocklyPauseC').hide(); $('.blocklyResumeC').hide(); $('.blocklyStepC').show(); break; } } }; this.setToolbox = function() { var ext = VPLUtil.fileExtension(fileName); var toolboxname = ext + 'Toolbox'; if (VPLFile[toolboxname] === false) { $.ajax({ url: '../editor/blocklytoolboxes/' + toolboxname + '.xml', dataType: 'text', success: function(data) { VPLFile[toolboxname] = VPLFile.blocklyIn18(data); self.setToolbox(); }, }); return; } this.workspacePlayground.updateToolbox(VPLFile[toolboxname]); this.workspacePlayground.registerButtonCallback('blocklyStartButton', this.start); this.workspacePlayground.registerButtonCallback('blocklyStartAnimateButton', this.startAnimate); this.workspacePlayground.registerButtonCallback('blocklyStopButton', this.stop); this.workspacePlayground.registerButtonCallback('blocklyPauseButton', this.pause); this.workspacePlayground.registerButtonCallback('blocklyResumeButton', this.resume); this.workspacePlayground.registerButtonCallback('blocklyStepButton', this.step); this.adjustSize(); }; this.open = function() { opened = true; this.setFileName(fileName); opened = false; if ( VPLFile.blocklyNotLoaded ){ VPLUtil.loadScript( [ '../editor/blockly/blockly_compressed.js', '../editor/blockly/msg/js/en.js', '../editor/blockly/blocks_compressed.js', '../editor/blockly/python_compressed.js', '../editor/blockly/javascript_compressed.js', '../editor/blockly/php_compressed.js', '../editor/blockly/lua_compressed.js', '../editor/blockly/dart_compressed.js', '../editor/acorn/acorn.js', '../editor/acorn/interpreter.js', ] , function() { self.adaptBlockly(); VPLFile.blocklyNotLoaded = false; self.open(); }); return; } opened = true; var horizantalMenu = false; if( /.*[0-9]$/.test(VPLUtil.fileExtension(fileName)) ) { var horizantalMenu = true; } // Workaround to remove jquery-ui theme background color. $(tid).removeClass('ui-widget-content ui-tabs-panel'); $(tid).addClass('ui-corner-bottom'); this.bdiv = 'bkdiv'+ id; $(tid).html('<div id="' + this.bdiv + '" style="height: 480px; width: 600px;"></div>'); var options = { toolbox: '<xml><category name=""><block type="math_number"></block></category></xml>', media: '../editor/blockly/media/', horizontalLayout: horizantalMenu, zoom: { controls: true, wheel: true, startScale: 1.0, maxScale: 3, minScale: 0.2, scaleSpeed: 1.15 } }; this.workspacePlayground = Blockly.inject( this.bdiv, options); this.workspacePlayground.addChangeListener(function (event) { self.changeCode(event); }); this.setToolbox(); return false; }; this.getContent = function() { if (!opened) { return value; } var xml = Blockly.Xml.workspaceToDom(this.workspacePlayground); var xmlText = Blockly.Xml.domToPrettyText (xml); return xmlText; }; this.setContent = function(c) { value = c; if (opened) { this.workspacePlayground.clear(); var xml = Blockly.Xml.textToDom(c); Blockly.Xml.domToWorkspace(xml, this.workspacePlayground); } }; this.close = function() { value = this.getContent(); this.workspacePlayground.dispose(); this.workspacePlayground = false; this.firstFocus = true; opened = false; }; }; this.extendToBinary = function() { this.isBinary = function() { return true; }; this.setContent = function(c) { modified = true; value = c; this.setFileName(fileName); this.updateDataURL(); }; this.updateDataURL = function() { if(VPLUtil.isImage(fileName)){ var prevalue = 'data:' + VPLUtil.getMIME(fileName) + ';base64,'; $(tid).find('img').attr('src', prevalue + value); } else { $(tid).find('img').attr('src', ''); } }; this.adjustSize = function() { if (!opened) { return false; } var editTag = $(tid); if (editTag.length === 0) { return; } var tabs = editTag.parent(); var newHeight = tabs.height(); newHeight -= editTag.position().top; if (newHeight != editTag.height()) { editTag.height(newHeight); return true; } return false; }; this.open = function() { opened = true; if (VPLUtil.isImage(fileName)) { $(tid).addClass('vpl_ide_img').append('<img />'); this.updateDataURL(); } else { $(tid).addClass('vpl_ide_binary').text(VPLUtil.str('binaryfile')); } this.setFileName(fileName); return false; }; this.close = function() { opened = false; }; }; }; VPLFile.blocklyNotLoaded = true; VPLFile.blocklyToolbox = false; VPLFile.blockly0Toolbox = false; VPLFile.blockly1Toolbox = false; VPLFile.blockly2Toolbox = false; VPLFile.blockly3Toolbox = false; VPLFile.blocklyStrs= [ 'basic', 'intermediate', 'advanced', 'variables', 'operatorsvalues', 'control', 'inputoutput', 'functions', 'lists', 'math', 'text', 'run', 'start', 'startanimate', 'stop', 'pause', 'resume', 'step' ]; VPLFile.blocklyIn18 = function(data) { var l = VPLFile.blocklyStrs.length; for ( var i = 0; i < l; i++) { var str = VPLFile.blocklyStrs[i]; var reg = new RegExp('\\[\\[' + str + '\\]\\]', 'g'); var rep = VPLUtil.str(str); data = data.replace(reg, rep); } return data; }; window.VPLFile = VPLFile; return VPLFile; });