/** * A code editor * @constructor */ hui.ui.CodeInput = function(options) { this.options = hui.override({},options); this.name = options.name; var e = this.element = hui.get(options.element); this.textarea = hui.get.firstByTag(e,'textarea'); if (options.value) { this.textarea.value = options.value; } this.value = this.textarea.value; hui.ui.extend(this); this._addBehavior(); }; hui.ui.CodeInput.create = function(options) { options = options || {}; options.element = hui.build('div',{ 'class' : 'hui_codeinput', html : '<textarea class="hui_codeinput_input" spellcheck="false"></textarea>' }); if (options.height) { options.element.style.height = hui.style.length(options.height); } return new hui.ui.CodeInput(options); }; hui.ui.CodeInput.prototype = { _addBehavior : function() { hui.listen(this.textarea, 'keydown', this._onKeyDown.bind(this)); hui.listen(this.textarea, 'keyup', this._onKeyUp.bind(this)); }, getValue : function() { return this.textarea.value; }, setValue : function(value) { this.textarea.value = value; this.value = value; }, addLine : function(line) { if (this.value==='') { this.setValue(line); } else { this.setValue(this.value+"\n"+line); } }, reset : function() { this.setValue(''); }, _onKeyUp : function() { if (this.textarea.value !== this.value) { this.value = this.textarea.value; this.fireValueChange(); } }, _onKeyDown: function(evt) { var tab = String.fromCharCode(9); var e = window.event || evt; var t = e.target ? e.target : e.srcElement ? e.srcElement : e.which; var scrollTop = t.scrollTop; var k = e.keyCode ? e.keyCode : e.charCode ? e.charCode : e.which; var ch, a, i, rt, nr; if (k == 9 && !e.ctrlKey && !e.altKey) { if (t.setSelectionRange) { e.preventDefault(); var ss = t.selectionStart; var se = t.selectionEnd; // Multi line selection if (ss != se && t.value.slice(ss, se).indexOf("\n") != -1) { if (ss > 0) { ss = t.value.slice(0, ss).lastIndexOf("\n") + 1; } var pre = t.value.slice(0, ss); var sel = t.value.slice(ss, se); var post = t.value.slice(se, t.value.length); if (e.shiftKey) { a = sel.split("\n"); for (i = 0; i < a.length; i++) { if (a[i].slice(0, 1) == tab || a[i].slice(0, 1) == ' ') { a[i] = a[i].slice(1, a[i].length); } } sel = a.join("\n"); t.value = pre.concat(sel, post); t.selectionStart = ss; t.selectionEnd = pre.length + sel.length; } else { sel = sel.replace(/\n/g, "\n" + tab); pre = pre.concat(tab); t.value = pre.concat(sel, post); t.selectionStart = ss; t.selectionEnd = se + (tab.length * sel.split("\n").length); } } // Single line selection else { if (e.shiftKey) { var brt = t.value.slice(0, ss); ch = brt.slice(brt.length - 1, brt.length); if (ch == tab || ch == ' ') { t.value = brt.slice(0, brt.length - 1).concat(t.value.slice(ss, t.value.length)); t.selectionStart = ss - 1; t.selectionEnd = se - 1; } } else { t.value = t.value.slice(0, ss).concat(tab).concat(t.value.slice(ss, t.value.length)); if (ss == se) { t.selectionStart = t.selectionEnd = ss + tab.length; } else { t.selectionStart = ss + tab.length; t.selectionEnd = se + tab.length; } } } } else { e.returnValue = false; var r = document.selection.createRange(); var br = document.body.createTextRange(); br.moveToElementText(t); br.setEndPoint("EndToStart", r); //Single line selection if (r.text.length === 0 || r.text.indexOf("\n") === -1) { if (e.shiftKey) { ch = br.text.slice(br.text.length - 1, br.text.length); if (ch == tab || ch == ' ') { br.text = br.text.slice(0, br.text.length - 1); r.setEndPoint("StartToEnd", br); } } else { var rtn = t.value.slice(br.text.length, br.text.length + 1); if (rtn != r.text.slice(0, 1)) { br.text = br.text.concat(rtn); } br.text = br.text.concat(tab); } nr = document.body.createTextRange(); nr.setEndPoint("StartToEnd", br); nr.setEndPoint("EndToEnd", r); nr.select(); } //Multi line selection else { var p; if (e.shiftKey) { a = r.text.split("\r\n"); rt = t.value.slice(br.text.length, br.text.length + 2); if (rt == r.text.slice(0, 2)) { p = br.text.lastIndexOf("\r\n".concat(tab)); if (p != -1) { br.text = br.text.slice(0, p + 2).concat(br.text.slice(p + 3, br.text.length)); } } for (i = 0; i < a.length; i++) { ch = a[i].length > 0 && a[i].slice(0, 1); if (ch == tab || ch == ' ') { a[i] = a[i].slice(1, a[i].length); } } r.text = a.join("\r\n"); } else { if (br.text.length > 0) { rt = t.value.slice(br.text.length, br.text.length + 2); if (rt != r.text.slice(0, 2)) { r.text = tab.concat(r.text.split("\r\n").join("\r\n".concat(tab))); } else { var selectionStart; // TODO: what is this about? p = br.text.slice(0, selectionStart).lastIndexOf("\r\n") + 2; br.text = br.text.slice(0, p).concat(tab, br.text.slice(p, br.text.length)); r.text = r.text.split("\r\n").join("\r\n".concat(tab)); } } else { r.text = tab.concat(r.text).split("\r\n").join("\r\n".concat(tab)); } } nr = document.body.createTextRange(); nr.setEndPoint("StartToEnd", br); nr.setEndPoint("EndToEnd", r); nr.select(); } } } t.scrollTop = scrollTop; } };