Ext.define('amdaUI.CodeArea', { extend: 'extensions.SelectableTextArea', alias: 'widget.CodeArea', constructor: function(config) { var infotip = ' '; if(config.type ==="parameter"){ this.itemId = 'formParamConstructParameter'; this.fieldLabel = infotip+'Construct Parameter'; this.blankText = 'Construct Parameter is required'; this.name = 'buildchain'; this.flex = 0.5; } else if (config.type ==="search"){ this.itemId = 'formSearchCondition'; this.fieldLabel = infotip+'Data Mining Condition'; this.blankText = 'Condition expression is required'; this.name = 'expression'; this.flex = 2; } this.init(config); this.callParent(arguments); }, codeMirror:null, functionsRegex : new RegExp("(?:" + myDesktopApp.functionList.join("|") + ")\\b"), constantRegex : new RegExp("(?:" + myDesktopApp.constantList.join("|") + ")\\b"), parametersRegex : new RegExp("(?:" + myDesktopApp.parametersList.join("|") + ")\\b"), setValue : function(value){ if(this.codeMirror){ this.codeMirror.getDoc().setValue(value); } this.callParent(arguments); }, init : function(config) { var me = this; CodeMirror.defineSimpleMode("amda_mode", { start: [ { regex: me.functionsRegex, token: "amda_function" }, { regex: /tt_\w+|cat_\w+|shared(timeTable|catalog)_\w+/, token: "amda_ttCat" }, { regex: me.constantRegex, token: "amda_constant" }, { regex: me.parametersRegex, token: "amda_parameter" }, { regex: /0x[a-f\d]+|[-+]?(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/, token: "number" }, { regex: /[-+\/*=<>!]+/, token: "operator" }, ], comment: [], meta: {} }); CodeMirror.registerHelper("lint", "amda_mode", function(text) { var errors = []; var paranthesis = []; var crochets=[]; // Split the input text into lines var lines = text.split("\n"); // Loop over each line for (var i = 0; i < lines.length; i++) { var line = lines[i]; // Loop over each character in the line for (var j = 0; j < line.length; j++) { var ch = line.charAt(j); // Push opening parentheses onto the paranthesis if (ch === "(") { paranthesis.push({ type: "open", line: i, ch: j }); } // Push opening parentheses onto the crochets if (ch === "[") { crochets.push({ type: "open", line: i, ch: j }); } // Pop closing parentheses off the paranthesis if (ch === ")") { if (paranthesis.length === 0) { errors.push({ message: "Extra closing parenthesis", severity: "error", from: CodeMirror.Pos(i, j), to: CodeMirror.Pos(i, j + 1) }); } else { paranthesis.pop(); } } // Pop closing crochets off the crochets if (ch === "]") { if (crochets.length === 0) { errors.push({ message: "Extra closing crochets", severity: "error", from: CodeMirror.Pos(i, j), to: CodeMirror.Pos(i, j + 1) }); } else { crochets.pop(); } } } } // Check for unmatched opening parentheses for (var i = 0; i < paranthesis.length; i++) { var item = paranthesis[i]; errors.push({ message: "Missing closing parenthesis", severity: "error", from: CodeMirror.Pos(item.line, item.ch), to: CodeMirror.Pos(item.line, item.ch + 1) }); } // Check for unmatched opening parentheses for (var i = 0; i < crochets.length; i++) { var item = crochets[i]; errors.push({ message: "Missing closing crochets", severity: "error", from: CodeMirror.Pos(item.line, item.ch), to: CodeMirror.Pos(item.line, item.ch + 1) }); } return errors; }); var myConf = { labelAlign: 'top', labelPad: 0, validateOnChange: false, validateOnBlur: false, validator: this.isBalanced, listeners: { render: function (textArea, op) { var me = this; var meEl = me.bodyEl; var dropTarget = Ext.create('Ext.dd.DropTarget', meEl, { ddGroup: 'explorerTree', notifyEnter: function (ddSource, e, data) { }, notifyOver: function (ddSource, e, data) { if (data.records[0].get('nodeType') == 'localParam' && data.records[0].get('notyet')) { this.valid = false; return this.dropNotAllowed; } if (((data.records[0].get('nodeType') == 'localParam') || (data.records[0].get('nodeType') == 'remoteParam') || (data.records[0].get('nodeType') == 'remoteSimuParam') || (data.records[0].get('nodeType') == 'derivedParam') || (data.records[0].get('nodeType') == 'specialParam') || (data.records[0].get('nodeType') == 'myDataParam') || (data.records[0].get('nodeType') == 'timeTable') || (data.records[0].get('nodeType') == 'catalog') || (data.records[0].get('nodeType') == 'sharedtimeTable') || (data.records[0].get('nodeType') == 'sharedcatalog') || (data.records[0].get('nodeType') == 'alias')) && config.type === "parameter" && (data.records[0].isLeaf() || data.records[0].get('isParameter')) && !(data.records[0].data.disable)) { this.valid = true; return this.dropAllowed; } else if(((data.records[0].get('nodeType') == 'localParam') || (data.records[0].get('nodeType') == 'remoteParam') || (data.records[0].get('nodeType') == 'remoteSimuParam') || (data.records[0].get('nodeType') == 'derivedParam') || (data.records[0].get('nodeType') == 'specialParam') || (data.records[0].get('nodeType') == 'myDataParam') || (data.records[0].get('nodeType') == 'alias')) && config.type === "search" && (data.records[0].isLeaf() || data.records[0].get('isParameter')) && !(data.records[0].data.disable)) { this.valid = true; return this.dropAllowed; } this.valid = false; return this.dropNotAllowed; }, notifyDrop: function (ddSource, e, data) { if (!this.valid) return false; var nameToSent; var components = null; switch (data.records[0].get('nodeType')) { case 'localParam': case 'remoteParam': case 'remoteSimuParam': nameToSent = data.records[0].get('id'); if (data.records[0].get('alias') != "") var nameToSent = "#" + data.records[0].get('alias'); var component_info = data.records[0].get('component_info'); if (component_info && component_info.parentId) { if (component_info.index1 && component_info.index2) { nameToSent = component_info.parentId; components = []; if (component_info.index1) components['index1'] = component_info.index1; if (component_info.index2) components['index2'] = component_info.index2; } if (data.records[0].get('needsArgs')) { nameToSent = component_info.parentId; if (component_info.index1) { components = []; components['index1'] = component_info.index1; } } } break; case 'alias': nameToSent = "#" + data.records[0].get('text'); break; case 'derivedParam': nameToSent = "ws_" + data.records[0].get('text'); break; case 'specialParam': nameToSent = data.records[0].get('id'); break; case 'timeTable': nameToSent = "tt_"+data.records[0].get('text'); break; case 'catalog': nameToSent = "cat_"+data.records[0].get('text'); break; case 'sharedtimeTable': nameToSent = "sharedtimeTable"+data.records[0].get('text'); break; case 'sharedcatalog': nameToSent = "sharedcatalog_"+data.records[0].get('text'); break; case 'myDataParam': var name = data.records[0].get('text'); nameToSent = "wsd_" + name; break; default: return false; } var paramModule; if( config.type === "parameter") paramModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.param.id); else if (config.type === "search") paramModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.search.id); if (paramModule) { if (data.records[0].get('predefinedArgs')) { paramModule.parseTemplatedParam(nameToSent, function (param_info) { paramModule.addParam(param_info.paramid, data.records[0].get('leaf'), true, components, param_info.template_args, null); }); } else { paramModule.addParam(nameToSent, data.records[0].get('leaf'), data.records[0].get('needsArgs'), components,null,null); } } return true; } }); me.codeMirror = CodeMirror.fromTextArea(textArea.inputEl.dom, { lineNumbers: false, mode: 'amda_mode', gutters: ["CodeMirror-lint-markers"], extraKeys: {"Ctrl-Space": "autocomplete"}, autoCloseBrackets: true, styleActiveLine: true, lineWrapping: true, lint: true }); me.codeMirror.on('change', editor => { me.setRawValue(editor.getValue()); });; } } //TODO: ?validator on formula structure? // listener : { // valid : function(field) { // // } // } }; Ext.apply (this , Ext.apply (arguments, myConf)); } });