/** * Shopex OMS * * Copyright (c) 2025 Shopex (http://www.shopex.cn) * Licensed under Apache-2.0 with additional terms (See LICENSE file) */ function $cleanNull(){ var obj=arguments[0]; for(p in obj){ if(!obj[p]) delete(obj[p]); } return obj; }; var mceInstance = new Class({ Implements:[Events,Options], options:{ acitve:false, maskOpacity:0.5, autoHeight:false, cleanup:true, includeBase:true }, initialize:function(seri,options){ this.seri=seri; var name = 'mce_body_'+seri; this.el = $(name); this.setOptions(options); this.input = $E('textarea',this.el).setProperty('ishtml','true'); this.frmContainer=$(name+"_frm_container"); var that=this; var includeBase=this.options.includeBase; var state=0; var frm=this.frm=new Element('iframe',{'src':DESKTOPRESFULLURL+'/about.html','id':name+"_frm",'name':name+"_frm",'frameborder':0,'border':0}).addEvent('load',function(){ if(state)return; state=1; var editor=that; var frmWin=frm.contentWindow; var baseStr=''; var documentTemplate = '' +'' +''+(includeBase?baseStr:"") +'' +'' +'' +(editor.cleanup(editor.input.getProperty('value'))||' ') +''; frmWin.document.open(); frmWin.document.write(documentTemplate); frmWin.document.close(); frmWin.document.designMode = 'on'; if (frmWin.document.addEventListener) frmWin.document.addEventListener('mousedown', editor.active.bind(editor), false); else frmWin.document.attachEvent('on' + 'mousedown', editor.active.bind(editor)); editor.win=frmWin; editor.doc=frmWin.document; editor.input.setAttribute('filled','true'); this.removeEvent('load', arguments.callee); }); frm.inject(this.frmContainer); this.input.getValue=function(){ if(!this.input.getAttribute('filled')){ return 'textarea-unfilled'; } if('textarea'==this.editType){ return this.input.value; } var v=this.getValue(); this.input.value=v; return v; }.bind(this); if(this.options.autoHeight) this.autoHeight.call(this); if($(name))this.el = $(name).setStyle('visibility','visible'); }, autoHeight:function(){ try{ this.frm.setStyle('height',this.doc.body.offsetHeight+50); }catch(e){} }, setValue:function(){ this.doc.body.innerHTML=this.input.value; }, getValue:function(){ return this.cleanup(this.doc.body.innerHTML); }, regexpReplace:function(in_str, reg_exp, replace_str, opts) { if (in_str == null) return in_str; if (typeof(opts) == "undefined") opts = 'g'; var re = new RegExp(reg_exp, opts); return in_str.replace(re, replace_str); }, cleanup: function(html) { var br = '
'; var xhtml = [ [/(<(?:img|input)[^\/>]*)>/g, '$1 />'] // Greyed out - make img tags xhtml compatable #if (this.options.xhtml) ]; var semantic = [ [/
  • \s*
    (.+?)<\/div><\/li>/g, '
  • $1
  • '], // remove divs from
  • #if (Browser.Engine.trident) [/(.*)<\/span>/gi, '$1'], // [/(.*)<\/span>/gi, '$1'], // [/]*>(.*?)<\/b[^>]*>/gi, '$1'], // [/]*>(.*?)<\/i[^>]*>/gi, '$1'], // [/]*>(.*?)<\/u[^>]*>/gi, '$1'], // [/

    [\s\n]*(<(?:ul|ol)>.*?<\/(?:ul|ol)>)(.*?)<\/p>/ig, '$1

    $2

    '], //

    tags around a list will get moved to after the list. not working properly in safari? #if (['gecko', 'presto', 'webkit'].contains(Browser.Engine.name)) [/<\/(ol|ul)>\s*(?!<(?:p|ol|ul|img).*?>)((?:<[^>]*>)?\w.*)$/g, '

    $2

    '], // '' [/]*><\/p>/g, '

    '], // Remove
    's that end a paragraph here. [/

    \s*(]+>)\s*<\/p>/ig, '$1\n'], // If a

    only contains , remove the

    tags [/]*)>(.*?)<\/p>(?!\n)/g, '$2

    \n'], // Break after paragraphs [/<\/(ul|ol|p)>(?!\n)/g, '\n'], // Break after

    tags [/>
  • /g, '>\n\t
  • '], // Break and indent
  • [/([^\n])<\/(ol|ul)>/g, '$1\n'], // Break before tags [/([^\n])\s*<\/p>/gi, '

    '] // if (!this.options.semantics) - Remove padded paragraphs ]; var appleCleanup = [ [/
    /gi, "
    "], // Webkit cleanup - add an if(webkit) check [/(.*)<\/span>/gi, '$1'], // Webkit cleanup - should be corrected not to get messed over on nested spans - SG!!! [/ class="Apple-style-span"/gi, ''], // Webkit cleanup [//gi, ''], // Webkit cleanup [/^([\w\s]+.*?)
    /i, '

    $1

    '], // remove stupid apple divs #if (Browser.Engine.webkit) [/
    (.+?)<\/div>/ig, '

    $1

    '] // remove stupid apple divs #if (Browser.Engine.webkit) ]; var cleanup = [ [//gi, br], // Fix BRs, make it easier for next BR steps. // [/>/g, '>'], // Remove (arguably) useless BRs [/^/g, ''], // Remove leading BRs - perhaps combine with removing useless brs. [/$/g, ''], // Remove trailing BRs [/\s*<\/(h1|h2|h3|h4|h5|h6|li|p)/gi, '\s*\s*<\/p>/gi, '

    \u00a0

    '], // Remove padded paragraphs - replace with non breaking space [/

    ( |\s)*<\/p>/gi, '

    \u00a0

    '], // '' //[/

    \W*<\/p>/g, ''], // Remove ps with other stuff, may mess up some formatting. [/<\/p>\s*<\/p>/g, '

    '], // Remove empty

    tags [/<[^> ]*/g, function(match){return match.toLowerCase();}], // Replace uppercase element names with lowercase [/<[^>]*>/g, function(match){ // Replace uppercase attribute names with lowercase match = match.replace(/ [^=]+=/g, function(match2){return match2.toLowerCase();}); return match; }], [/<[^>]*>/g, function(match){ // Put quotes around unquoted attributes match = match.replace(/( [^=]+=)([^"][^ >]*)/g, "$1\"$2\""); return match; }] ]; var depracated = [ // The same except for BRs have had optional space removed [/

    \s*
    \s*<\/p>/gi, '

    \u00a0

    '], // modified as
    is handled previously [/
    /gi, "
    "], // Replace improper BRs if (this.options.xhtml) Handled at very beginning [/
    $/gi, ''], // Remove leading and trailing BRs [/^
    /gi, ''], // Remove trailing BRs [/>
    /gi,'>'], // Remove useless BRs [/
    \s*<\/(h1|h2|h3|h4|h5|h6|li|p)/gi, '(?:\s*)

    /g, '

    '] // Remove empty

    tags ]; cleanup.extend(xhtml); cleanup.extend(semantic); if(Browser.Engine.webkit)cleanup.extend(appleCleanup); cleanup.each(function(reg){ html = html.replace(reg[0], reg[1]); }); html = html.trim(); return html; }, active:function(){ if(!this.actived){ this.actived = true; var doc = this.doc; var _fn = function(e){ this.fireEvent('docClick',new Event(e)); }.bind(this); if (doc.addEventListener) doc.addEventListener('click', _fn, false); else doc.attachEvent('on' + 'click', _fn); } this.fireEvent('active',this); }, sleep:function(){} }); var mceHandler = new Class({ Implements:[Events,Options], initialize:function(name,instance,options){ try{ this.el = $(name); $ES('img',this.el).each(function(e){new DropMenu(e);}); this.setOptions(options); if(instance){ if(instance.length){ instance.each(this.addInstance.bind(this)); }else{ this.addInstance.call(this,instance); } } }catch(e){alert(e.message)} if('style_init' in this){this.style_init();} }, addInstance:function(inc){ inc.addEvent('active',this.active.bind(this)); inc.addEvent('docClick',this.docClick.bind(this)); }, active:function(e){ this.inc =e; if(this.inc){ this.inc.sleep.call(this.inc); } }, docClick:function(e){ var curEl =this.currentEl =e.target||e.srcElement; this.fireEvent('click',e); }, getRange:function(){ if(!this.inc)return false; if(this.range)return this.range; return window.ie?this.inc.doc.selection.createRange():this.inc.win.getSelection(); }, getSelection:function(){ return window.ie?this.inc.doc.selection:this.inc.win.getSelection(); }, getRangeText:function(){ return window.ie?this.inc.doc.selection.createRange().text:this.inc.win.getSelection().toString(); }, exec:function(cmd,arg){ if (!this.busy) { this.busy=true; if(!cmd || !this.inc){return} if(this.dlg){ if(window.ie){ if(this.range) this.range.select(); } this.dlg.hide(); this.dlg=null; } switch(cmd){ case "formatblock": this.inc.doc.execCommand("FormatBlock", false,'<'+arg+'>'); break; case "wrap": this.exec('insertHTML',arg[0]+this.getRangetext()+arg[1]); break; case "insertHTML": if(window.ie){ this.getSelection().clear(); } if(this.replaceEl&&this.replaceEl.tagName&&!this.replaceEl.tagName.match(/body/g)){ try{ var _tempDiv=this.inc.doc.createElement('div'); _tempDiv.innerHTML=arg; _tempDiv= _tempDiv.firstChild; this.replaceEl.parentNode.replaceChild(_tempDiv, this.replaceEl); }catch(e){ MessageBox.error(e); }finally{ this.replaceEl = null; } }else{ if(window.ie){ this.inc.win.focus(); if(!this.getRange().pasteHTML)return; this.getRange().pasteHTML(arg); }else{ this.inc.doc.execCommand('inserthtml', false,arg); } } break; default: try{ this.inc.doc.execCommand(cmd, false,arg); }catch(e){MessageBox.error(e)} } this.busy = false; } }, mklink:function(){ if(!this.inc)return; this.replaceEl = null; var curEl=this.currentEl; var data; if('body'==curEl.tagName.toLowerCase()&&!this.getRangeText()){ return; } if(curEl&&curEl.tagName&&curEl.tagName.toLowerCase()=='img'){ return MessageBox.error(LANG_Editor['error']); } if(curEl&&curEl.tagName&&curEl.tagName.toLowerCase()=='a'){ data={ text:this.currentEl.innerHTML, href:this.currentEl.href, alt:this.currentEl.alt, title:this.currentEl.title, target:this.currentEl.target }; this.replaceEl =curEl; }else{ data={'text':this.getRangeText()}; } this.dialog('link',{height:null,width:450,ajaxoptions:{method:'post','data':data}}); }, editHTML:function(){ var _this=this; if(!this.inc)return; var mhh=$('mce_handle_htmledit_'+this.inc.seri); var mh=$('mce_handle_'+this.inc.seri); this.inc.input.getValue(); mhh.show(); mh.hide(); var frmcis=this.inc.frm.getSize(); this.inc.input.show(); this.inc.frmContainer.hide(); mhh.getElement('.returnwyswyg').addEvent('click',function(){ mh.show(); mhh.hide(); _this.inc.doc.body.innerHTML=_this.inc.input.value.clean().trim(); _this.inc.input.hide(); _this.inc.frmContainer.show(); _this.inc.editType='wysiwyg'; this.removeEvent('click',arguments.callee); }) this.inc.editType='textarea'; /*var data={'htmls':this.inc.getValue(),'seri':this.inc.seri}; this.dialog('editHTML',{title:'HTML编辑模式',height:null,width:450,ajaxoptions:{method:'post','data':data}});*/ }, dialog:function(action,options){ if(!this.inc)return; this.inc.win.focus(); this.range=null; this.range = this.getRange(); var url=('image'==action)?'index.php?app=desktop&act=alertpages&goto='+encodeURIComponent("index.php?app=image&ctl=admin_manage&act=image_broswer&type=big"):'index.php?ctl=editor&act='+action; options=$cleanNull(options); var _this=this; if ('image'==action) return Ex_Loader('modedialog',function(){ new imgDialog(url,{onCallback:function(image_id,image_src){ _this.insertImg(image_id,image_src); }}); }); this.dlg =new Dialog(url,$merge(options,{modal:true})); window.curEditor = this; }, insertImg:function(image_id,image_src,center){ if(SHOPBASE&&image_src.contains(SHOPBASE)){ //image_src=image_src.replace(SHOPBASE,''); } var img=new Element('img',{src:image_src}),imgID='img'+$uid(img); img.set('id',imgID).set('turl',image_src); var d=new Element('div').adopt(img); var html=center?'

    '+d.get('html')+'
    ':d.get('html'); this.exec.bind(this)('insertHTML',html); var win_img=this.inc.doc.getElementById(imgID); if(!win_img)return; win_img.src=img.get('turl'); win_img.removeAttribute('turl','id'); }, queryValue:function(s,state){ if(s=='align'){ s = 'justifyRight'; } try{ if(state){ return this.inc.doc.queryCommandState(s); }else{ return this.inc.doc.queryCommandValue(s); } }catch(e){} }, queryValues:function(){ var ret={}; var stat = ['Bold','Italic','Underline','strikeThrough','subscript','superscript','insertOrderedList','insertUnorderedList']; for(var i=0;i