Ext.define('amdaUI.DescriptionField', { extend: 'Ext.form.field.TextArea', //extend: 'Ext.form.field.HtmlEditor', alias: 'widget.descriptionfield', fieldLabel: 'Description', flex:1, constructor: function() { this.init(); this.callParent(arguments); }, urlRegex : /(?:\b(?:https?|ftp):\/\/|www\.)(?:\S+(?::\S*)?@)?(?:\S+(?:\.\S+)+(?:[:\d]*)?)(?:\S+)?/gi, amdaRegex : /amda/i, setValue : function(value){ if(this.codeMirror){ this.codeMirror.getDoc().setValue(value); } this.callParent(arguments); }, init : function() { var me = this ; CodeMirror.defineSimpleMode("amda_description", { start: [ { regex: me.urlRegex, token: "amda_url" }, { regex: /\bamda\b/gi, token: "amda" } ], comment: [], meta: {} }); var myConf = { listeners: { render:function(textArea, op){ heightText = textArea.getHeight()-20; if (heightText <0) heightText = 50; me.codeMirror = CodeMirror.fromTextArea(textArea.inputEl.dom, { lineNumbers: false, mode: 'amda_description', styleActiveLine: true, lineWrapping: true, }); me.codeMirror.setSize(null, heightText); me.codeMirror.on('mousedown', function(cm, event) { var position = cm.coordsChar({ left: event.clientX, top: event.clientY }); var token = cm.getTokenAt(position); if(token.type === 'amda_url' && token.end > position.ch && position.outside !== 1){ var tokenText = token.string; window.open((tokenText.startsWith('www')) ? 'https://'+tokenText : tokenText, "_blank"); } }); me.codeMirror.on('change', function(a,e){ me.setRawValue(a.getValue()); }); } } }; Ext.apply (this , Ext.apply (arguments, myConf)); } });