/** * @author Ryan Johnson * @copyright 2008 PersonalGrid Corporation * @package LivePipe UI * @license MIT * @url http://livepipe.net/control/textarea * @require prototype.js, livepipe.js */ /*global window, document, Prototype, Class, $, $A, Control */ if(typeof(Prototype) == "undefined") { throw "Control.TextArea requires Prototype to be loaded."; } if(typeof(Object.Event) == "undefined") { throw "Control.TextArea requires Object.Event to be loaded."; } Control.TextArea = Class.create({ initialize: function(textarea){ this.onChangeTimeout = false; this.element = $(textarea); $(this.element).observe('keyup',this.doOnChange.bindAsEventListener(this)); $(this.element).observe('paste',this.doOnChange.bindAsEventListener(this)); $(this.element).observe('input',this.doOnChange.bindAsEventListener(this)); if(!!document.selection){ $(this.element).observe('mouseup',this.saveRange.bindAsEventListener(this)); $(this.element).observe('keyup',this.saveRange.bindAsEventListener(this)); } }, doOnChange: function(event){ if(this.onChangeTimeout) { window.clearTimeout(this.onChangeTimeout); } this.onChangeTimeout = window.setTimeout(function(){ this.notify('change',this.getValue()); }.bind(this),Control.TextArea.onChangeTimeoutLength); }, saveRange: function(){ this.range = document.selection.createRange(); }, getValue: function(){ return this.element.value; }, getSelection: function(){ if(!!document.selection) { return document.selection.createRange().text; } else if(!!this.element.setSelectionRange) { return this.element.value.substring(this.element.selectionStart,this.element.selectionEnd); } else { return false; } }, replaceSelection: function(text){ var scroll_top = this.element.scrollTop; if(!!document.selection){ this.element.focus(); var range = (this.range) ? this.range : document.selection.createRange(); range.text = text; range.select(); }else if(!!this.element.setSelectionRange){ var selection_start = this.element.selectionStart; this.element.value = this.element.value.substring(0,selection_start) + text + this.element.value.substring(this.element.selectionEnd); this.element.setSelectionRange(selection_start + text.length,selection_start + text.length); } this.doOnChange(); this.element.focus(); this.element.scrollTop = scroll_top; }, wrapSelection: function(before,after){ var sel = this.getSelection(); // Remove the wrapping if the selection has the same before/after if (sel.indexOf(before) === 0 && sel.lastIndexOf(after) === (sel.length - after.length)) { this.replaceSelection(sel.substring(before.length, sel.length - after.length)); } else { this.replaceSelection(before + sel + after); } }, insertBeforeSelection: function(text){ this.replaceSelection(text + this.getSelection()); }, insertAfterSelection: function(text){ this.replaceSelection(this.getSelection() + text); }, collectFromEachSelectedLine: function(callback,before,after){ this.replaceSelection((before || '') + $A(this.getSelection().split("\n")).collect(callback).join("\n") + (after || '')); }, insertBeforeEachSelectedLine: function(text,before,after){ this.collectFromEachSelectedLine(function(line){ },before,after); } }); Object.extend(Control.TextArea,{ onChangeTimeoutLength: 500 }); Object.Event.extend(Control.TextArea); Control.TextArea.ToolBar = Class.create( { initialize: function(textarea,toolbar){ this.textarea = textarea; if(toolbar) { this.container = $(toolbar); } else{ this.container = $(document.createElement('ul')); this.textarea.element.parentNode.insertBefore(this.container,this.textarea.element); } }, attachButton: function(node,callback){ node.onclick = function(){return false;}; $(node).observe('click',callback.bindAsEventListener(this.textarea)); }, addButton: function(link_text,callback,attrs){ var li = document.createElement('li'); var a = document.createElement('a'); a.href = '#'; this.attachButton(a,callback); li.appendChild(a); Object.extend(a,attrs || {}); if(link_text){ var span = document.createElement('span'); span.innerHTML = link_text; a.appendChild(span); } this.container.appendChild(li); } });