var MooEditable=new Class({Implements:[Events,Options],options:{toolbar:true,cleanup:true,xhtml:true,semantics:true,buttons:'bold,italic,underline,strikethrough,|,insertunorderedlist,insertorderedlist,indent,outdent,|,undo,redo,|,createlink,unlink,|,urlimage,|,toggleview',mode:'icons'},initialize:function(el,options){this.setOptions(options);this.textarea=el;this.build();},build:function(){var self=this;this.container=new Element('div',{'id':(this.textarea.id)?this.textarea.id+'-container':null,'class':'mooeditable-container','styles':{'width':this.textarea.getSize().x,'margin':this.textarea.getStyle('margin')}});this.container.wraps(this.textarea);if(Browser.Engine.trident)new Element('span').wraps(this.textarea);var pads=this.textarea.getStyle('padding').split(' ');pads=pads.map(function(p){return(p=='auto')?0:p.toInt();});this.iframe=new IFrame({'class':'mooeditable-iframe','styles':{'width':this.textarea.getStyle('width').toInt()+pads[1]+pads[3],'height':this.textarea.getStyle('height').toInt()+pads[0]+pads[2],'border-color':this.textarea.getStyle('border-color'),'border-width':this.textarea.getStyle('border-width'),'border-style':this.textarea.getStyle('border-style')}});this.textarea.setStyles({'margin':0,'display':'none','resize':'none','outline':'none'});this.iframe.inject(this.container,'top');this.win=this.iframe.contentWindow;this.doc=this.win.document;var documentTemplate='\
   <html style="cursor: text; height: 100%">\
    <head>'+(this.options.cssPath?"<link rel=\"stylesheet\" type=\"text/css\" href=\""+this.options.cssPath+"\" />":"")+'</head>\
    <body id=\"editable\"'+(this.options.cssClass?" class=\""+this.options.cssClass+"\"":"")+' style="font-family: sans-serif; border: 0">'+
this.cleanup(this.textarea.get('value'))+'</body>\
   </html>\
  ';this.doc.open();this.doc.write(documentTemplate);this.doc.close();(Browser.Engine.trident)?this.doc.body.contentEditable=true:this.doc.designMode='On';this.mode='iframe';if(this.textarea.id)$$('label[for="'+this.textarea.id+'"]').addEvent('click',function(e){if(self.mode=='iframe'){e=new Event(e).stop();self.focus();}});this.form=this.textarea.getParent('form').addEvent('submit',function(){if(self.mode=='iframe')self.saveContent();});if(Browser.Engine.trident)this.doc.window=this.win;if(!this.doc.$family)this.doc=new Document(this.doc);$(this.doc.body);this.doc.addEvents({'keypress':this.keyListener.bind(this),'focus':this.checkStates.bind(this),'click':this.checkStates.bind(this),'keyup':this.checkStates.bind(this)});this.textarea.addEvent('keypress',this.keyListener.bind(this));var styleCSS=function(){if(!['trident','presto'].contains(Browser.Engine.name))self.execute('styleWithCSS',false,false);self.doc.removeEvent('focus',styleCSS);}
this.doc.addEvent('focus',styleCSS);if(this.options.toolbar)this.buildToolbar();},buildToolbar:function(){var self=this;this.toolbar=new Element('div',{'class':'mooeditable-toolbar'}).inject(this.iframe,'before');this.keys=[];var toolbarButtons=this.options.buttons.split(',');toolbarButtons.each(function(command,idx){var b;if(command=='|')b=new Element('span',{'class':'toolbar-separator'});else{b=new Element('button',{'class':command+'-button toolbar-button','title':MooEditable.Actions[command]['title']+((MooEditable.Actions[command]['shortcut'])?' ( Ctrl+'+MooEditable.Actions[command]['shortcut'].toUpperCase()+' )':''),'events':{'click':function(e){e.stop();if(!this.hasClass('disabled')){self.focus();self.action(command);if(self.mode=='iframe')self.checkStates();}},'mousedown':function(e){e.stop();}}});b.addClass(MooEditable.Actions[command]['mode']||self.options.mode);if(Browser.Engine.trident)b.addEvents({'mouseenter':function(e){this.addClass('hover');},'mouseleave':function(e){this.removeClass('hover');}});var key=MooEditable.Actions[command]['shortcut'];if(key)self.keys[key]=b;b.set('text',MooEditable.Actions[command]['title']);}
b.inject(self.toolbar);});},keyListener:function(event){var event=new Event(event);if(event.control&&this.keys[event.key]){event.stop();this.keys[event.key].fireEvent('click',event);}},focus:function(){(this.mode=='iframe'?this.win:this.textarea).focus();},action:function(command){var action=MooEditable.Actions[command];var args=action.arguments||[];if(action.command)
($type(action.command)=='function')?action.command(this):this.execute(action.command,false,args);else
this.execute(command,false,args);},execute:function(command,param1,param2){if(!this.busy){this.busy=true;this.doc.execCommand(command,param1,param2);this.saveContent();this.busy=false;}
return false;},toggleView:function(){if(this.mode=='textarea'){this.mode='iframe';this.iframe.setStyle('display','');this.setContent(this.textarea.value);this.enableToolbar();this.textarea.setStyle('display','none');}else{this.saveContent();this.mode='textarea';this.textarea.setStyle('display','');this.disableToolbar('toggleview');this.iframe.setStyle('display','none');}
(function(){this.focus();}).bind(this).delay(10);},disableToolbar:function(b){this.toolbar.getElements('.toolbar-button').each(function(item){if(!item.hasClass(b+'-button'))
item.addClass('disabled').removeClass('active').set('opacity',0.4);else
item.addClass('onActive');});},enableToolbar:function(){this.toolbar.getElements('.toolbar-button').removeClass('disabled').removeClass('onActive').set('opacity',1);},getContent:function(){return this.cleanup(this.doc.getElementById('editable').innerHTML);},setContent:function(newContent){(function(){$(this.doc.getElementById('editable')).set('html',newContent);}).bind(this).delay(1);},saveContent:function(){if(this.mode=='iframe')this.textarea.set('value',this.getContent());},getSelection:function(){return(Browser.Engine.trident)?this.doc.selection.createRange().text:this.win.getSelection();},getSelectedNode:function(){var parentNode=null;if(Browser.Engine.trident)parentNode=this.doc.selection.createRange().parentElement();else{var sel=this.win.getSelection();if(!sel)return false;parentNode=sel.anchorNode.parentNode;}
while(parentNode.nodeType==3)parentNode=parentNode.parentNode;return parentNode;},createRange:function(){if(Browser.Engine.trident)return this.doc.selection.createRange();else{var sel=this.win.getSelection();if($type(sel)){try{return sel.getRangeAt(0);}catch(e){return this.doc.createRange();}}
else return this.doc.createRange();}},addRange:function(range){if(range.select)range.select();else{var s=this.getSelection();if(s.removeAllRanges&&s.addRange){s.removeAllRanges();s.addRange(range);}}},checkStates:function(){MooEditable.Actions.each(function(action,command){var button=this.toolbar.getElement('.'+command+'-button');if(!button)return;button.removeClass('active');if(action.tags){var el=this.getSelectedNode();do{if(el.nodeType!=1)break;if(action.tags.contains(el.tagName.toLowerCase()))
button.addClass('active');}
while(el=el.parentNode);}
if(action.css){var el=this.getSelectedNode();do{if(el.nodeType!=1)break;for(var prop in action.css)
if($(el).getStyle(prop).contains(action.css[prop]))
button.addClass('active');}
while(el=el.parentNode);}}.bind(this));},cleanup:function(source){if(!this.options.cleanup)return source.trim();source=source.replace(/<br class\="webkit-block-placeholder">/gi,"<br />");source=source.replace(/<span class="Apple-style-span">(.*)<\/span>/gi,'$1');source=source.replace(/ class="Apple-style-span"/gi,'');source=source.replace(/<span style="">/gi,'');source=source.replace(/<p>\s*<br ?\/?>\s*<\/p>/gi,'<p>\u00a0</p>');source=source.replace(/<p>(&nbsp;|\s)*<\/p>/gi,'<p>\u00a0</p>');source=source.replace(/\s*<br ?\/?>\s*<\/p>/gi,'</p>');if(this.options.xhtml){source=source.replace(/<br>/gi,"<br />");}
if(this.options.semantics){if(['gecko','presto'].contains(Browser.Engine.name)){source=source.replace(/(.+?)<br ?\/?>(?!\s*<\/li>)/g,'<p>$1</p>');}
if(Browser.Engine.webkit){source=source.replace(/^([\w\s]+.*?)<div>/i,'<p>$1</p><div>');source=source.replace(/<div>(.+?)<\/div>/ig,'<p>$1</p>');}
if(['gecko','presto','webkit'].contains(Browser.Engine.name)){source=source.replace(/<p>[\s\n]*(<(?:ul|ol)>.*?<\/(?:ul|ol)>)(.*?)<\/p>/ig,'$1<p>$2</p>');}
source=source.replace(/<p>\s*(<img[^>]+>)\s*<\/p>/ig,'$1\n');source=source.replace(/<p>(?!\n)/g,'<p>\n');source=source.replace(/<\/(ul|ol|p)>(?!\n)/g,'</$1>\n');source=source.replace(/><li>/g,'>\n\t<li>');source=source.replace(/([^\n])<\/(ol|ul|p)>/g,'$1\n</$2>');source=source.replace(/([^\n])<img/ig,'$1\n<img');}
source=source.replace(/<br ?\/?>$/gi,'');source=source.replace(/^<br ?\/?>/gi,'');source=source.replace(/><br ?\/?>/gi,'>');source=source.replace(/<br ?\/?>\s*<\/(h1|h2|h3|h4|h5|h6|li|p)/gi,'</$1');source=source.replace(/<span style="font-weight: bold;">(.*)<\/span>/gi,'<strong>$1</strong>');source=source.replace(/<span style="font-style: italic;">(.*)<\/span>/gi,'<em>$1</em>');source=source.replace(/<b(?!r)[^>]*>(.*?)<\/b[^>]*>/gi,'<strong>$1</strong>')
source=source.replace(/<i[^>]*>(.*?)<\/i[^>]*>/gi,'<em>$1</em>')
source=source.replace(/<u(?!l)[^>]*>(.*?)<\/u[^>]*>/gi,'<span style="text-decoration: underline;">$1</span>')
source=source.replace(/<[^> ]*/g,function(match){return match.toLowerCase();});source=source.replace(/<[^>]*>/g,function(match){match=match.replace(/ [^=]+=/g,function(match2){return match2.toLowerCase();});return match;});source=source.replace(/<[^>]*>/g,function(match){match=match.replace(/( [^=]+=)([^"][^ >]*)/g,"$1\"$2\"");return match;});source=source.replace(/<p><p>/g,'<p>');source=source.replace(/<\/p>\s*<\/p>/g,'</p>');source=source.replace(/<p>\W*<\/p>/g,'');source=source.trim();return source;}});MooEditable.Actions=new Hash({bold:{title:'Bold',shortcut:'b',tags:['b','strong'],css:{'font-weight':'bold'}},italic:{title:'Italic',shortcut:'i',tags:['i','em'],css:{'font-style':'italic'}},underline:{title:'Underline',shortcut:'u',tags:['u'],css:{'text-decoration':'underline'}},strikethrough:{title:'Strikethrough',shortcut:'s',tags:['s','strike'],css:{'text-decoration':'line-through'}},insertunorderedlist:{title:'Unordered List',tags:['ul']},insertorderedlist:{title:'Ordered List',tags:['ol']},indent:{title:'Indent',tags:['blockquote']},outdent:{title:'Outdent'},undo:{title:'Undo',shortcut:'z'},redo:{title:'Redo',shortcut:'y'},unlink:{title:'Remove Hyperlink'},createlink:{title:'Add Hyperlink',shortcut:'l',tags:['a'],command:function(me){if(me.getSelection()=='')
MooEditable.Dialogs.alert(me,'createlink','Please select the text you wish to hyperlink.');else
MooEditable.Dialogs.prompt(me,'createlink','Enter url','http://',function(url){me.execute('createlink',false,url.trim());});}},urlimage:{title:'Add Image',shortcut:'m',command:function(me){MooEditable.Dialogs.prompt(me,'urlimage','Enter image url','http://',function(url){me.execute("insertimage",false,url.trim());});}},toggleview:{title:'Toggle View',shortcut:'t',command:function(me){me.toggleView();}}});MooEditable.Dialogs=new Hash({alert:function(me,el,str){if(!me.alertbar){me.alertbar=new Element('div',{'class':'alertbar dialog-toolbar'});me.alertbar.inject(me.toolbar,'after');me.alertbar.strLabel=new Element('span',{'class':'alertbar-label'});me.alertbar.okButton=new Element('button',{'class':'formbutton alertbar-ok input-button','text':'OK','events':{'click':function(e){e.stop();me.alertbar.setStyle('display','none');me.enableToolbar();me.doc.removeEvents('mousedown');}}});new Element('div').adopt(me.alertbar.strLabel,me.alertbar.okButton).inject(me.alertbar);}
else if(me.alertbar.getStyle('display')=='none')me.alertbar.setStyle('display','');me.alertbar.strLabel.set('text',str);me.alertbar.okButton.focus();me.doc.addEvent('mousedown',function(e){e.stop();});me.disableToolbar(el);},prompt:function(me,el,q,a,fn){me.range=me.createRange();if(!me.promptbar){me.promptbar=new Element('div',{'class':'promptbar dialog-toolbar'});me.promptbar.inject(me.toolbar,'after');me.promptbar.qLabel=new Element('label',{'class':'promptbar-label','for':'promptbar-'+me.container.uid});me.promptbar.aInput=new Element('input',{'class':'formfield promptbar-input input-text','id':'promptbar-'+me.container.uid,'type':'text'});me.promptbar.okButton=new Element('button',{'class':'formbutton promptbar-ok input-button','text':'OK'});me.promptbar.cancelButton=new Element('button',{'class':'formbutton promptbar-cancel input-button','text':'Cancel','events':{'click':function(e){e.stop();me.promptbar.setStyle('display','none');me.enableToolbar();me.doc.removeEvents('mousedown');}}});new Element('div').adopt(me.promptbar.qLabel,me.promptbar.aInput,me.promptbar.okButton,me.promptbar.cancelButton).inject(me.promptbar);}
else if(me.promptbar.getStyle('display')=='none')me.promptbar.setStyle('display','');me.promptbar.okButton.addEvent('click',function(e){e.stop();me.addRange(me.range);fn(me.promptbar.aInput.value);me.promptbar.setStyle('display','none');me.enableToolbar();me.doc.removeEvents('mousedown');this.removeEvents('click');});me.promptbar.qLabel.set('text',q);me.promptbar.aInput.set('value',a);me.promptbar.aInput.focus();me.doc.addEvent('mousedown',function(e){e.stop();});me.disableToolbar(el);}});Element.implement({mooEditable:function(options){return new MooEditable(this,options);}});
