
/* - kupueditor.js - */
// http://artesliberales.spbu.ru/portal_javascripts/kupueditor.js?original=1
function KupuDocument(iframe){this.editable=iframe;this.window=this.editable.contentWindow;this.document=this.window.document;this._browser=_SARISSA_IS_IE?'IE':'Mozilla';var DEPRECATED={'contentReadOnly':'readonly','styleWithCSS':'useCSS'};this.execCommand=function(command,arg){if(arg===undefined) arg=null;try{this.document.execCommand(command,false,arg)} catch(e){command=DEPRECATED[command];if(command){this.document.execCommand(command,false,!arg)}}};this.reloadSource=function(){document.location=document.location};this.getDocument=function(){return this.document};this.getWindow=function(){return this.window};this.getSelection=function(){if(this._browser=='Mozilla'){return new MozillaSelection(this)} else{return new IESelection(this)}};this.getEditable=function(){return this.editable}};
function KupuEditor(document,config,logger){this.document=document;this.config=config;this.log=logger;this.tools={};this.filters=[];this.serializer=new XMLSerializer();this._designModeSetAttempts=0;this._initialized=false;this._wantDesignMode=false;this._previous_range=null;this.content_changed=false;this.initialize=function(){this._initializeEventHandlers();if(this.getBrowserName()=="IE"){var body=this.getInnerDocument().getElementsByTagName('body')[0];body.setAttribute('contentEditable','true');this._initialized=true;if(this.afterInit){this.afterInit()};this._saveSelection()} else{this._setDesignModeWhenReady()}};this.setContextMenu=function(menu){menu.initialize(this)};this.registerTool=function(id,tool){this.tools[id]=tool;tool.initialize(this)};this.getTool=function(id){return this.tools[id]};this.registerFilter=function(filter){this.filters.push(filter);filter.initialize(this)};this.updateStateHandler=function(event){var interesting_codes=[8,13,37,38,39,40,46];this._saveSelection();if(event.type=='click'||(event.type=='keyup'&&interesting_codes.contains(event.keyCode))){this.updateState(event)}};this.updateState=function(event){var selNode=this.getSelectedNode();for(var id in this.tools){try{this.tools[id].updateState(selNode,event)} catch(e){if(e==UpdateStateCancelBubble){this.updateState(event);break} else{this.logMessage('Exception while processing updateState on '+'${id}: ${msg}',{'id':id,'msg':e},2)}}}};this.saveDocument=function(redirect,synchronous){if(!this.config.dst){this.logMessage(_('No destination URL available!'),2);return}
var sourcetool=this.getTool('sourceedittool');if(sourcetool){sourcetool.cancelSourceMode()};if(!this._initialized){return}
this._initialized=false;window.status=_("Please wait while saving document...");for(var id in this.tools){var tool=this.tools[id];if(tool.beforeSave){try{tool.beforeSave()} catch(e){alert(e);this._initialized=true;return}}};this.logMessage(_("Starting HTML cleanup"));var transform=this._filterContent(this.getInnerDocument().documentElement);var contents=this._serializeOutputToString(transform);this.logMessage(_("Cleanup done, sending document to server"));var request=new XMLHttpRequest();if(!synchronous){request.onreadystatechange=(new ContextFixer(this._saveCallback,this,request,redirect)).execute;request.open("PUT",this.config.dst,true);request.setRequestHeader("Content-type",this.config.content_type);request.send(contents);this.logMessage(_("Request sent to server"))} else{this.logMessage(_('Sending request to server'));request.open("PUT",this.config.dst,false);request.setRequestHeader("Content-type",this.config.content_type);request.send(contents);this.handleSaveResponse(request,redirect)}};this.prepareForm=function(form,id){var sourcetool=this.getTool('sourceedittool');if(sourcetool){sourcetool.cancelSourceMode()};if(!this._initialized){return}
this._initialized=false;window.status=_("Please wait while saving document...");for(var tid in this.tools){var tool=this.tools[tid];if(tool.beforeSave){try{tool.beforeSave()} catch(e){alert(e);this._initialized=true;return}}};if(!id){id='kupu'};this.logMessage(_("Starting HTML cleanup"));var transform=this._filterContent(this.getInnerDocument().documentElement);var contents=this._serializeOutputToString(transform);this.logMessage(_("Cleanup done, sending document to server"));var document=form.ownerDocument?form.ownerDocument:window.document;var ta=document.createElement('textarea');ta.style.visibility='hidden';var text=document.createTextNode(contents);ta.appendChild(text);ta.setAttribute('name',id);form.appendChild(ta);return true};this.execCommand=function(command,param){if(!this._initialized){this.logMessage(_('Editor not initialized yet!'));return};if(this.getBrowserName()=="IE"){this._restoreSelection()} else{this.focusDocument();if(command!='styleWithCSS'){this.content_changed=true;this.getDocument().execCommand('styleWithCSS',false)}};this.getDocument().execCommand(command,param);this.updateState()};this.getSelection=function(){this._restoreSelection();return this.getDocument().getSelection()};this.getSelectedNode=function(allowmulti){return this.getSelection().parentElement(allowmulti)};this.getNearestParentOfType=function(node,type){var type=type.toLowerCase();while(node){if(node.nodeName.toLowerCase()==type){return node}
var node=node.parentNode}
return false};this.removeNearestParentOfType=function(node,type){var nearest=this.getNearestParentOfType(node,type);if(!nearest){return false};var parent=nearest.parentNode;while(nearest.childNodes.length){var child=nearest.firstChild;child=nearest.removeChild(child);parent.insertBefore(child,nearest)};parent.removeChild(nearest)};this.getDocument=function(){return this.document};this.getInnerDocument=function(){return this.getDocument().getDocument()};this.insertNodeAtSelection=function(insertNode,selectNode){if(!this._initialized){this.logMessage(_('Editor not initialized yet!'));return};this.content_changed=true;var browser=this.getBrowserName();if(browser!="IE"){this.focusDocument()};var ret=this.getSelection().replaceWithNode(insertNode,selectNode);this._saveSelection();return ret};this.focusDocument=function(){this.getDocument().getWindow().focus()};this.logMessage=function(message,severity){this.log.log(message,severity)};this.registerContentChanger=function(element){addEventHandler(element,'change', function(){this.content_changed=true},this)};this.getBrowserName=function(){if(_SARISSA_IS_MOZ){return "Mozilla"} else if(_SARISSA_IS_IE){return "IE"} else{throw _("Browser not supported!")}};this.handleSaveResponse=function(request,redirect){if(request.status!='200'&&request.status!='204'&&request.status!='1223'){var msg=_('Error saving your data.\nResponse status: '+'${status}.\nCheck your server log for more '+'information.',{'status':request.status});alert(msg);window.status=_("Error saving document")} else if(redirect){window.document.location=redirect;this.content_changed=false} else{this.content_changed=false;if(this.config.reload_after_save){this.reloadSrc()};window.status=_("Document saved")};this._initialized=true};this._addEventHandler=addEventHandler;this._saveCallback=function(request,redirect){if(request.readyState==4){this.handleSaveResponse(request,redirect)}};this.reloadSrc=function(){this.getDocument().reloadSource();if(this.getBrowserName()=="Mozilla"){this.getInnerDocument().designMode="On"}};this.imageInserted=function(event){var node=event.target;if(node&&node.nodeType==1){var nodes=(/^img$/i.test(node.nodeName))?[node]:node.getElementsByTagName('img');for(var i=0;i<nodes.length;i++){node=nodes[i];var src=node.getAttribute('kupu-src');if(src){node.src=src}}}};this.imageModified=function(event){var node=event.target;if(node&&(/^img$/i.test(node.nodeName))){if(event.attrName=="style"&&event.attrChange==1&&(/height|width/.test(event.newValue))){timer_instance.registerFunction(this,this._clearStyle,1,node)}}};this._clearStyle=function(node){var w=node.width;var h=node.height;node.style.width="";node.style.height="";if(this.okresize){if(w){node.width=w};if(h){node.height=h}}};this._cancelResize=function(evt){return false};this._initializeEventHandlers=function(){var win=this.getDocument().getWindow();var idoc=this.getInnerDocument();var e=this._addEventHandler;var validattrs=this.xhtmlvalid.tagAttributes.img;this.okresize=validattrs.contains('width')&&validattrs.contains('height');e(win,'resize',this._resizeHandler,this);e(idoc,"click",this.updateStateHandler,this);e(idoc,"dblclick",this.updateStateHandler,this);e(idoc,"keyup",this.updateStateHandler,this);e(idoc,"keyup", function(){this.content_changed=true},this);e(idoc,"mouseup",this.updateStateHandler,this);if(this.getBrowserName()=="IE"){e(idoc,"selectionchange",this.onSelectionChange,this);if(!this.okresize){e(idoc.documentElement,"resizestart",this._cancelResize,this)}} else{e(idoc,"DOMNodeInserted",this.imageInserted,this);e(idoc,"DOMAttrModified",this.imageModified,this)}};this._resizeHandler=function(){if(this._wantDesignMode){this._setDesignModeWhenReady()}};this._setDesignModeWhenReady=function(){var success=false;try{this._setDesignMode();success=true} catch(e){};if(success){this._wantDesignMode=false;if(this.afterInit){this.afterInit()}} else{this._wantDesignMode=true}};this._setDesignMode=function(){this.getInnerDocument().designMode="On";this.execCommand("undo");this._initialized=true};this._saveSelection=function(){if(this._isDocumentSelected()){var cursel=this.getInnerDocument().selection;var currange=cursel.createRange();if(cursel.type=="Control"&&currange.item(0).nodeName.toLowerCase()=="body"){this._restoreSelection(true);return}
this._previous_range=currange}};this._restoreSelection=function(force){if(this._previous_range&&(force||!this._isDocumentSelected())){try{this._previous_range.select()} catch(e){}}};if(this.getBrowserName()!="IE"){this._saveSelection=function(){};this._restoreSelection=function(){}}
this.onSelectionChange=function(event){this._saveSelection()};this._isDocumentSelected=function(){if(this.suspended) return false;var editable_body=this.getInnerDocument().getElementsByTagName('body')[0];try{var selrange=this.getInnerDocument().selection.createRange()} catch(e){return false}
var someelement=selrange.parentElement?selrange.parentElement():selrange.item(0);while(someelement.nodeName.toLowerCase()!='body'){someelement=someelement.parentNode};return someelement==editable_body};this._clearSelection=function(){this._previous_range=null};this._filterContent=function(documentElement){var xhtmldoc=Sarissa.getDomDocument();var doc=this._convertToSarissaNode(xhtmldoc,documentElement);for(var i=0;i<this.filters.length;i++){var doc=this.filters[i].filter(xhtmldoc,doc)};this._fixXML(doc,xhtmldoc);return doc};this.getXMLBody=function(transform){var bodies=transform.getElementsByTagName('body');var data='';for(var i=0;i<bodies.length;i++){data+=this.serializer.serializeToString(bodies[i])}
return this.layoutsource(this.escapeEntities(data))};this.getHTMLBody=function(){var doc=this.getInnerDocument();var docel=doc.documentElement;var bodies=docel.getElementsByTagName('body');var data='';for(var i=0;i<bodies.length;i++){data+=bodies[i].innerHTML}
return this.layoutsource(this.escapeEntities(data))};this.setHTMLBody=function(text){var doc=this.getInnerDocument().documentElement;var bodies=doc.getElementsByTagName('body');for(var i=0;i<bodies.length-1;i++){bodies[i].parentNode.removeChild(bodies[i])}
if(_SARISSA_IS_IE){text=text.replace(/<!--\[.*?-->/g,'')} else{var fixups={'strong':'b','em':'i'};text=text.replace(/<(\/?)(strong|em)\b([^>]*)>/gi, function(all,close,tag,attrs){tag=fixups[tag.toLowerCase()];return '<'+close+tag+attrs+'>'})};text=text.replace(/<p>(<hr.*?>)<\/p>/g,'$1');bodies[bodies.length-1].innerHTML=text;var nodes=doc.getElementsByTagName('img');for(var i=0;i<nodes.length;i++){var node=nodes[i];node.setAttribute('kupu-src',node.src)}};this._fixXML=function(doc,document){var heads=doc.getElementsByTagName('head');var titles=doc.getElementsByTagName('title');if(!heads.length){var body=doc.getElementsByTagName('body')[0];var head=document.createElement('head');body.parentNode.insertBefore(head,body);var title=document.createElement('title');var titletext=document.createTextNode('');head.appendChild(title);title.appendChild(titletext)} else if(!titles.length){var head=heads[0];var title=document.createElement('title');var titletext=document.createTextNode('');head.appendChild(title);title.appendChild(titletext)};var dualtons=['a','abbr','acronym','address','applet','b','bdo','big','blink','blockquote','button','caption','center','cite','comment','del','dfn','dir','div','dl','dt','em','embed','fieldset','font','form','frameset','h1','h2','h3','h4','h5','h6','i','iframe','ins','kbd','label','legend','li','listing','map','marquee','menu','multicol','nobr','noembed','noframes','noscript','object','ol','optgroup','option','p','pre','q','s','script','select','small','span','strike','strong','style','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','u','ul','xmp'];for(var i=0;i<dualtons.length;i++){var elname=dualtons[i];var els=doc.getElementsByTagName(elname);for(var j=0;j<els.length;j++){var el=els[j];if(!el.hasChildNodes()){var child=document.createTextNode('');el.appendChild(child)}}}};this.xhtmlvalid=new XhtmlValidation(this);this._convertToSarissaNode=function(ownerdoc,htmlnode){return this.xhtmlvalid._convertToSarissaNode(ownerdoc,htmlnode)};this._fixupSingletons=function(xml){return xml.replace(/<([^>]+)\/>/g,"<$1 />")};this._serializeOutputToString=function(transform){if(this.config.strict_output){var contents='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" '+'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'+'<html xmlns="http://www.w3.org/1999/xhtml">'+this.serializer.serializeToString(transform.getElementsByTagName("head")[0])+this.serializer.serializeToString(transform.getElementsByTagName("body")[0])+'</html>'} else{var contents='<html>'+this.serializer.serializeToString(transform.getElementsByTagName("head")[0])+this.serializer.serializeToString(transform.getElementsByTagName("body")[0])+'</html>'};contents=this.escapeEntities(contents);if(this.config.compatible_singletons){contents=this._fixupSingletons(contents)};return contents};this.layoutsource=function(data){data=data.replace(/\s*(<(p|div|h.|ul|ol|dl|menu|dir|pre|blockquote|address|center|table|thead|tbody|tfoot|tr|th|td))\b/ig,'\n$1');data=data.replace(/\s*(<\/(p|div|h.|ul|ol|dl|menu|dir|pre|blockquote|address|center|table|thead|tbody|tfoot|tr|th|td)>)\s*/ig,'$1\n');data=data.replace(/\<pre\>((?:.|\n)*?)\<\/pre\>/gm, function(s){return s.replace(/<br\b[^>]*>/gi,'\n')});return data.strip()};this.escapeEntities=function(xml){xml=xml.replace(/\xa0/g,'&nbsp;');return xml};this.getFullEditor=function(){var fulleditor=this.getDocument().getEditable();while(!(/kupu-fulleditor/.test(fulleditor.className))){fulleditor=fulleditor.parentNode}
return fulleditor};this.setClass=function(name){this.getFullEditor().className+=' '+name};this.clearClass=function(name){var fulleditor=this.getFullEditor();fulleditor.className=fulleditor.className.replace(' '+name,'')};var busycount=0;this.busy=function(){if(busycount<=0){this.setClass('kupu-busy')}
busycount++};this.notbusy=function(force){busycount=force?0:busycount?busycount-1:0;if(busycount<=0){this.clearClass('kupu-busy')}};this.suspendEditing=function(){this._previous_range=this.getSelection().getRange();this.setClass('kupu-modal');for(var id in this.tools){this.tools[id].disable()}
if(this.getBrowserName()=="IE"){var body=this.getInnerDocument().getElementsByTagName('body')[0];body.setAttribute('contentEditable','false')} else{this.getDocument().execCommand('contentReadOnly','true')}
this.suspended=true};this.resumeEditing=function(){if(!this.suspended){return}
this.clearClass('kupu-modal');for(var id in this.tools){this.tools[id].enable()}
if(this.getBrowserName()=="IE"){var body=this.getInnerDocument().getElementsByTagName('body')[0];body.setAttribute('contentEditable','true');this._restoreSelection()} else{var doc=this.getInnerDocument();this.getDocument().execCommand('contentReadOnly','false');doc.designMode="On";this.focusDocument();this.getSelection().restoreRange(this._previous_range)}
this.suspended=false};this.newElement=function(tagName){return newDocumentElement(this.getInnerDocument(),tagName,arguments)};this.newText=function(text){return this.getInnerDocument().createTextNode(text)}}

