| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727 | /***编辑使用区域,*格式定义:1、行元素为div*          2、里面样式元素为span元素设置style*          3、编辑功能点击按钮为button按钮 统一设置样式 padding: 0; background: 0 0; outline: 0; -moz-outline: 0; border: 0; display: block; cursor: pointer; margin: 0;*/Namespace.register("U.UF.E");/* 初始化编辑器,让编辑器的格式符合* * @param el  {element} 编辑的元素* @param callback {function} 非必传 操作处理函数*        操作处理函数 该函数默认第一个参数为操作记录。*        格式形如 : { updateLine : [ 修改行ID, 修改行ID,], addLine : [添加行ID], deleteLine : [删除行ID] }* @param content {string} 默认添加的内容* @param stylestate {function}  非必传 光标所在行样式状态处理*/U.UF.E.initEditor = function (el, synergy, content, stylestate) {    //el是编辑器加载到哪个元素下必须传的元素 第二个是编辑器触发的回调函数 第三个是编辑器需要加载的内容 第四个是编辑器内容变化的时候的回调函数    //这个函数主要的逻辑内容是实现编辑器初始化内容,如果内容为空的时候那么初始化首行    //编辑器需要初始化内容的时候    if (content) {        //先加载内容        el.innerHTML = content;  //设置内容        el.focus(); //编辑器编辑区域聚焦        //判断加载的内容是否是通过1473编辑器初始化过的内容,如果是没有初始化过的内容,那么重新初始化        if (!$("div", el)[0] || U.selectEl("div", el)[0].id.length != "37") {            el.innerHTML = ""; //清理内容            U.UF.E.textFormat(content, el); //重新加载内容            U.selectEl("div", el)[0].focus(); //聚焦        }        //暂时先注释掉,去除外部引入的内容有包含可编辑元素,还有设置了不可编辑状态,导致文档不能流畅使用        //        U.selectEl("textarea", el).remove(); //去除textarea        //        U.selectEl("div", el).addAttrArray({ "contentEditable": "" }); //设置可编辑    }    //没有内容的初始化    else {        //创建行元素        var _div = $$("div", { "id": "e" + Guid.newGuid(), "innerHTML": content || "<span><br /></span>" }, el); //创建一个编辑的div进行编辑处理        el.focus(); //编辑器编辑区域聚焦    }    //上面处理内容后,下面初始化    U.UF.E.variable(el, synergy, stylestate); //初始化全局变量    //事件监听    U.UF.E.key(el); //键盘监听    //设置样式    U.UF.E.formatBrush(el, false); //格式刷工具未启用状态 记录当前光标所在位置的文字样式    //创建图片拉伸控件    U.UF.E.picture.stretch(el); //加载图片拉伸控件    //得到现在编辑器使用的行    el.idarr = U.UF.E.key.getLineIdArr(el);    //设计前进后退行记录    el.editor.recordOpera = { "line": el.idarr }    return U.UF.E.getRangeAt(); //得到光标}/* 初始化编辑器全局变量* * @param el  {element} 编辑的元素*/U.UF.E.variable = function (el, synergy, stylestate) {    var _range = U.UF.E.getRangeAt(); //得到光标    //编辑器全局区域    el.editor = {        "isrecord": true,        "idarr": [], //删除或者添加变化的数组        //格式刷全局变量        "brushStyle": {            "font-family": {},            "font-size": {},            "font-weight": {},            "font-style": {},            "text-decoration": {},            "color": {},            "backgroundColor": {}        },        //外部引入的内容需要保留的对象        "recordRangeStyle": {            "font-family": "",            "font-size": "",            "font-weight": "",            "font-style": "",            "text-decoration": "",            "color": "",            "backgroundColor": ""        },        "styleState": stylestate, //样式状态管理回调        "maxWidth": U.selectEl(el)[0].offsetWidth, //记录最大宽度        "operaNotice": synergy,  //设置编辑器处理的回调函数        "recordRange": _range, //当前使用的光标        "recordHTML": "", //当前操作行的内容        "recordOpera": {}, //记录行内容        "dpi": U.UF.CI.getDPI()[0], //获取屏幕分辨率        "log": true, //是否输出日志        "recordsEditor": [], //操作记录数组        "recordsEditorIndex": 0 //当前操作记录位置    };}/* 粘贴的处理** @param e       {event}  操作对象* @param editor  {element}  编辑器* @param text    {string}  需要处理的文字*/U.UF.E.onpaste = function (e, editor, text) {    var _content, event = e || window.event;    if (text != undefined) {        _text = text;    }    else {        _text = U.UF.C.pasteText();    }    _content = _text.SplitAngleBrackets();    if (_content && _content.length < 2) {        //普通文本替换的处理        _text = "<div>" + _text.replaceAngleBrackets().replace(/\r\n/g, "</div><div>").replace(/  /g, "  ") + "</div>";    }    //进行br标签的正则替换  br标签做为独立行标签    _text = _text.replace(/<(BR)[^<>]*>/ig, "</div></br><div>").replace(/ /g, " ");    _text.trim() != "" && U.UF.E.textFormat(_text, editor); //文字格式化处理    U.UF.EV.stopDefault(); //去除默认事件    return _text.trim();}/* 粘贴的处理* * @param text  {string}  需要处理的文字* @param range {object}  光标对象**/U.UF.E.textFormat = function (text, editor) {    var _editor = editor || this.editor;    var _range = U.UF.E.getRangeAt(), //获取光标选取        _div = $$("div", { "innerHTML": text, "style": { "display": "none"} }, U.selectEl("body")[0]), //内容        _frag = U.UF.E.unifiedFormat(_div); //获取拆分的值    U.UF.E.insertContent(_frag, _range, _editor); //调用指定位置插入内容的函数    //获取table进行初始化    var _table = U.selectEl('table', _editor);    //表格处理 写在这里    for (var i = _table.length - 1; i >= 0; i--) {        U.UF.E.table.load(_table[i]);    }    U.selectEl(_div).remove(); //删除div元素}/* 在指定位置插入内容* * @param el    {element} 插入的元素 frag临时标签* @param range {object}  光标对象**/U.UF.E.insertContent = function (el, range, editor) {    range = range || U.UF.E.getRangeAt(); //获取光标选取    //html5浏览器.此处添加了&& el.textContent会导致论坛上传不了图片,需要再次研究    if (window.getSelection) {    //if (window.getSelection && el.textContent) {        var _i, //循环变量            _frag,            _stylecsstext,            _span,            _child = el.childNodes, //获取插入元素的所有孩子节点            _lastchild, //记录最后一个孩子节点变量            _extractcontent, //记录删除选区内容            _record,            _focusel,            _frag = $$("frag"), //创建frag 临时标签            _startline = range.startContainer == editor ? editor.children[0] : U.UF.E.getLineElement(range.startContainer), //选择的行            _endline = range.endContainer == editor ? editor.children[0] : U.UF.E.getLineElement(range.endContainer), //选择的列            _selection = window.getSelection()//获取选区函数        ;        if (editor.innerHTML == "") {            _record = { addLine: [] };            for (_i = 0; _i < _child.length; ) {                _record.addLine.push(_child[_i].id);                //循环把选区内容元素插入到临时标签中                editor.appendChild(_child[_i]);            }            U.UF.E.elementFocus(range, editor.children[0], true); //重新聚焦元素            editor.editor.recordHTML = editor.children[editor.children.length - 1].outerHTML;        }        else {            _record = { updateLine: [_startline.id], addLine: [] };            //移除选取的内容            range.deleteContents(); //移除文字            _selection.removeAllRanges(); //移除选取            //剪切区域移除br标签,反正br导致多次换行            //            U.selectEl("br", _startline).remove(); //移除所有的br标签            //            U.selectEl("br", _endline).remove(); //移除所有的br标签            _lastchild = _endline.lastChild; //获取结束行最后一个元素            //粘贴的第一行有内容的处理            if (_lastchild && (_lastchild.innerHTML != undefined || _lastchild.data != undefined)) {                _stylecsstext = (_lastchild.style || _lastchild.parentNode.style).cssText;    //首行的样式处理                _focusel = _child[_child.length - 1].childNodes[_child[_child.length - 1].childNodes.length - 1] || _child[_child.length - 1];  //剪切后最后聚焦的元素                //结束行是向前插入,先把结束好的文字剪切走                try {                    range.setEnd(_lastchild, _lastchild.innerHTML != undefined ? 1 : _lastchild.data.length); //设置光标结束的位置                }                catch (e) {                    range.setEnd(_lastchild, 0); //设置光标结束的位置                }                _extractcontent = range.extractContents(); //记录删除选区内容                //把最后一行选取的内容如果是文本那么转化成span标签 _extractcontent.childNodes[0].nodeType == 3  && U.UF.E.validElement(_extractcontent)                if (_extractcontent.childNodes[0] && _extractcontent.childNodes[0].nodeType != 1) {                    //重新创建一个新的粘贴信息                    _frag = $$("frag");                    _span = $$("span", { "style": { "cssText": _stylecsstext} }, _frag);                    _span.appendChild(_extractcontent);                    _extractcontent = _frag;                }                //如果选取最后一行的内容是div说明是整行的处理                if (_extractcontent.childNodes[0] && _extractcontent.childNodes[0].tagName == "DIV") {                    //把行元素所有的元素添加到粘贴元素李                    for (_i = 0; _i < _extractcontent.childNodes[0].childNodes.length; _i) {                        //样式的设置                        _extractcontent.childNodes[0].childNodes[_i].style.cssText = _extractcontent.childNodes[0].style.cssText + ";" + _extractcontent.childNodes[0].childNodes[_i].style.cssText;                        _child[_child.length - 1].appendChild(_extractcontent.childNodes[0].childNodes[_i]);                    }                }                //否则就是内容                else {                    _child[_child.length - 1].appendChild(_extractcontent); //将选区内容元素插入到选区最后一个节点                }                //第一行添加                for (_i = 0; _i < el.childNodes[0].childNodes.length; _i) {                    _startline.appendChild(el.childNodes[0].childNodes[_i]); //设置第一行的内容为插入元素的内容                }            }            //否则其他的情况            else if (_child[0]) {                //设置起始行的样式为选区孩子节点的第一个元素的样式                _startline.style.cssText += " " + U.UF.E.getRemainAttr(_child[0]);                //设置起始行的内容为插入元素的第一个孩子节点的内容                _startline.innerHTML = _child[0].innerHTML;                _focusel = _startline;            }            //循环中间行添加处理            for (_i = 1; _i < _child.length; ) {                _record.addLine.push(_child[_i].id);                //循环把选区内容元素插入到临时标签中                _frag.appendChild(_child[_i]);            }            U.selectEl(_startline.parentNode).append(_frag, 0, U.selectEl(_startline).next()[0]); //添加到选择行的后面            U.UF.E.elementFocus(range, _focusel, true); //重新聚焦元素            var _focusline = U.UF.E.getLineElement(_focusel);            if (_focusline != _startline) {                editor.editor.recordRange = range;            }            editor.editor.recordHTML = _focusline.outerHTML;        }        U.UF.E.operationNotice(_record, editor);        clearTimeout(editor.editor.interval); //取消计时更新    }    //低版本的ie兼容    else {        range.pasteHTML(el.outerHTML); //添加选取文字    }};/* 元素全选聚焦* * @param  range {object}  range光标对象* @param  el     {element} 编辑的元素**/U.UF.E.elementFocus = function (range, el, islast) {    //html5得到光标的处理    if (window.getSelection) {        var _selection = window.getSelection(); //选择选取的处理        range.selectNodeContents(el); //添加选取的光标        _selection.removeAllRanges(); //移除所有的光标        _selection.addRange(range); //把聚焦元素的光标添加进去        //判断光标是否放在最后面        if (islast) {            range.collapse(false);        }    }    //ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性    else {        range.moveToElementText(el); //光标移动到指定的元素位置        range.select(); //聚焦选择    }};/* 创建贯标* **/U.UF.E.createRnage = function () {    //html5得到光标的处理    if (window.getSelection) {        return document.createRange();    }    //ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性    else {        return document.body.createTextRange();    }}/* 初始化光标处理,要求光标必须聚焦到编辑区域里,否则这里获取就会失败* * @param  win {window} 编辑的域* @return  {object} 光标编辑对象**/U.UF.E.getRangeAt = function (win) {    var _selection, //选取对象        _range //光标对象    ;    win = win || window; //获取创建光标的域    //html5得到光标的处理    if (win.getSelection) {        _selection = win.getSelection(); //获取选取对象        //当获取选取中有光标的处理        if (_selection.rangeCount) {            _range = _selection.getRangeAt(0); //返回选区的处理        }    }    //ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性    else {        _selection = win.document.selection; //获取选取对象        _range = _selection.createRange(); //光标对象    }    return _range; //光标的处理};/* 替换选区内容处理,可添加元素html代码。* * @param str     {string} 需要插入的文字* @param range   {object} range光标对象* @param islast  {boolean} 是否聚焦到最后* @return  {object} 光标编辑对象*/U.UF.E.addRange = function (str, range, islast) {    range = range || U.UF.E.getRangeAt(); //获取光标处理    //html5得到光标的处理    if (window.getSelection) {        var _selection = window.getSelection(), //获取选取对象            _frag = range.createContextualFragment(str); //创建选取        range.deleteContents(); //移除文字        _selection.removeAllRanges(); //移除选取        range.insertNode(_frag); //插入需要写入的内容        //判断光标是否放在最后面        if (islast) {            range.collapse(false);        }        _selection.addRange(range); //把替换的文章添加到当前指定的选取中    }    //ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性    else {        range.select(); //选取聚焦        range.pasteHTML(str); //添加选取文字        //判断光标是否放在最后面        if (islast) {            range.collapse(false);        }    }    //上面重新操作光标后,需要重新聚焦    return U.UF.E.getRangeAt();};/* 在光标中获取现在聚焦的元素* * @param range {object} range光标对象*/U.UF.E.getRangeElement = function (range) {    //html5得到光标的处理    if (range.commonAncestorContainer) {        return range.commonAncestorContainer;    }    //ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性    else {        //正常选择元素获取元素的处理        if (range.parentElement) {            return range.parentElement();        }        //图片无法像上面的方法一样获取元素,需要通过commonParentElement获取元素        else {            return range.commonParentElement();        }    }};/* 重新选中指定的光标* * @param  range {object} range光标对象*/U.UF.E.reSelectRange = function (range) {    //html5得到光标的处理    if (window.getSelection) {        var _selection = window.getSelection(); //获取选取对象        _selection.removeAllRanges(); //移除选取        _selection.addRange(range); //光标重新聚焦处理    }    //ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性    else {        range.select(); //选取聚焦    }};/* 设置编辑样式* * @param attr {object}  给指定的光标设置样式* @param range {object} 非必传参数 range光标对象* */U.UF.E.setRangeStyle = function (attr, range, editor) {    range = range || U.UF.E.getRangeAt(); //获取光标处理    if (range.startContainer == range.endContainer && range.startOffset == range.endOffset) {        return true;    }    var _i, //循环变量定义        _textstyle, //记录文本样式        _isdel, //是否删除        _start = range.startContainer, //选区起始元素        _end = range.endContainer, //选区结束元素        _startoffset = range.startOffset, //开始位置        _endoffset = range.endOffset, //结束位置        _startline = U.UF.E.getLineElement(_start), //获取选区起始行元素        _endline = U.UF.E.getLineElement(_end), //获取选区结束行元素        _frag = $$("frag") //创建临时元素 用于做记录d    ;    editor = editor || _startline.parentNode; //编辑区域元素    if (!editor.editor) { return; }    var _record = U.UF.E.getUpdateLine(_startline, _endline, editor); //得到修改记录    //判断是否选区在同一行    if (_startline != _endline) {        //不同行处理        var _rangselect = range.extractContents().childNodes; //获取选区的所有元素        //记录新选区的起始元素        _start = _rangselect[0].childNodes[0];        //记录文字装饰样式        _textstyle = attr["text-decoration"] || attr["textDecoration"];        //第一行样式设置        U.UF.E.setStyle(attr, _rangselect[0], true);        if (attr.cssText == "") {            _startline.style.cssText = "";        }        //设置样式后的元素循环添加到第一行中        while (_rangselect[0].childNodes[0]) {            _startline.appendChild(_rangselect[0].childNodes[0]);        }        //如果存在文字装饰样式        if (_textstyle) {            //标记设置的样式中是否已存在 存在为1 不存在为 0            _isdel = (attr["text-decoration"] || attr["textDecoration"] || "").indexOf(_textstyle) > -1 ? 1 : 0;            attr["text-decoration"] = _textstyle;        }        //循环除第一行和最后一行的每一行的处理        for (_i = 1; _i < _rangselect.length - 1; ) {            //设置每一行的样式            U.UF.E.setStyle(attr, _rangselect[_i], _isdel);            if (_textstyle) {                attr["text-decoration"] = _textstyle;            }            if (attr.cssText == "") {                _rangselect[_i].style.cssText = "";            }            //追加到临时标签中            _frag.appendChild(_rangselect[_i]);        }        //最后一行样式设置        U.UF.E.setStyle(attr, _rangselect[_rangselect.length - 1], _isdel);        //获取选区最后一行元素        var _end = _rangselect[_rangselect.length - 1].childNodes[_rangselect[_rangselect.length - 1].childNodes.length - 1];        //设置样式后的元素循环添加到最后一行中        while (_rangselect[_rangselect.length - 1].childNodes[0]) {            U.selectEl(_endline).append(_rangselect[_rangselect.length - 1].childNodes[_rangselect[_rangselect.length - 1].childNodes.length - 1], 0, _endline.firstChild);        }        if (attr.cssText == "") {            _endline.style.cssText = "";        }        range.insertNode(_frag); //插入需要写入的内容        U.UF.E.setRange(_start, _end || _start, 0, 1, range);  //设置选区 重新聚焦    }    //同行处理    //同行且选择的父级为块级元素    else if (_start == _end && (_start.parentNode.tagName.toLowerCase() == "span" || _start.parentNode.tagName.toLowerCase() == "a")) {        var _parentspan = _start.parentNode; //获取起始标签的上级元素        var _tagname = _parentspan.tagName.toLowerCase() == "a" ? "a" : "span"; //判断创建的块级元素TagName        var _startsplitel = U.UF.E.splitText(_start, _startoffset); //将起始标签拆分成新的起始文本标签  返回剩余的标签        var _endsplitel = U.UF.E.splitText(_startsplitel, _endoffset - _startoffset); //在剩余标签中拆分成选中和结束两块文本标签        //如果第一个文本标签存在内容则创建新的span标签        if (_start.data) {            //创建新的span标签 该标签为起始span标签(选区前的span标签)            var _span = $$(_tagname, {                "style": { "cssText": U.UF.E.getRemainAttr(_parentspan) },                "innerHTML": _start.data            });            //如果为a标签则设置href属性            if (_tagname == "a") {                _span.href = _parentspan.href;            }            //替换起始文本标签为起始span标签            _parentspan.replaceChild(_span, _start);        }        //创建新的块级元素  该标签为选区的span标签        var _rangspan = $$(_tagname, {            "style": { "cssText": U.UF.E.getRemainAttr(_parentspan) },            "innerHTML": _startsplitel.data        });        //处理样式后进行设置块级元素中        U.selectEl(_rangspan).css(U.UF.E.setSpecialAttr(_rangspan, attr));        //如果为a标签则设置href属性        if (_tagname == "a") {            _rangspan.href = _parentspan.href;        }        //替换选区文本标签为选区span标签        _parentspan.replaceChild(_rangspan, _startsplitel);        //如果结束文本标签存在内容则创建新的span标签        if (_endsplitel.data) {            //创建新的span标签 该标签为结束span标签(选区后的span标签)            var _span1 = $$(_tagname, {                "style": { "cssText": U.UF.E.getRemainAttr(_parentspan) },                "innerHTML": _endsplitel.data            });            //如果为a标签则设置href属性            if (_tagname == "a") {                _span1.href = _parentspan.href;            }            //替换结束文本标签为结束span标签            _parentspan.replaceChild(_span1, _endsplitel);        }        //将替换的元素追加到临时元素中        for (i = 0; i < _parentspan.childNodes.length; ) {            _frag.appendChild(_parentspan.childNodes[i]);        }        //替换原有元素为修改的元素        _parentspan.parentNode.replaceChild(_frag, _parentspan);        //设置选区        U.UF.E.setRange(_rangspan, _rangspan, 0, _startsplitel.data ? 1 : 0, range);    }    //起始元素和结束元素相等 且本身就为块级元素的处理    else if (_end == _start && _start.tagName && (_start.tagName.toLowerCase() == "span" || _start.tagName.toLowerCase() == "a")) {        //记录原有的样式属性        U.UF.E.getRemainAttr(_start);        //处理样式后设置到起始元素中        U.selectEl(_start).css(U.UF.E.setSpecialAttr(_start, attr));    }    //当行跨元素    else {        var _rangselect = range.extractContents(); //获取选区的所有元素        U.UF.E.setStyle(attr, _rangselect, true); //直接调用设置样式函数 true表示为第一层        range.insertNode(_rangselect); //将设置的元素插入到光标位置    }    //获取修改行的信息处理    U.UF.E.operationNotice(_record, editor);};/* 设置样式* * @param startline  {element}  修改样式修改行* @param endline    {element}  修改样式结束行*/U.UF.E.getUpdateLine = function (startline, endline, edit) {    var _record = { updateLine: [] }; //记录    //循环找所有影响的行    while (startline) {        _record.updateLine.push(startline.id); //修改行记录        //向下寻找        if (startline != endline) {            startline = startline.nextElementSibling;        }        else {            startline = false;        }    }    //返回修改记录    return _record;};/* 设置样式* * @param attr  {object}  给指定的光标设置样式* @param el    {object}  设置样式的元素* @param istop {boolean} 是否为第一层标记*/U.UF.E.setStyle = function (attr, el, istop) {    var _nowattr, //记录当前属性 该变量的作用主要用于记录新的样式        _nowspan, //记录当前元素的span元素        _newspan, //记录新的span元素        _textstyle = attr["text-decoration"] || attr["textDecoration"],        _span = U.UF.E.getTagNameElement(el); //获取块级元素    var _spanText = _span && _span.innerHTML; //获取行级元素的innerHTML    //根据内容是否相等  判断是否选择整个span标签                      if (_span && _spanText == el.data) {        _nowattr = U.UF.E.setSpecialAttr(_span, attr); //整理特殊样式        U.selectEl(_span).css(_nowattr);  //设置样式    }    //如果设置样式的元素不为整个span标签    else {        var _rangselect = el.childNodes; //获取设置样式元素下的所有子级        //循环给每一个子级添加样式        for (var i = 0; i < _rangselect.length; i++) {            //是第一层且为第一个元素是处理样式            if (istop === true && !i) {                U.UF.E.setSpecialAttr(_rangselect[i], attr); //设置最后需要设置的值                //设置istop  设置后的功能为判断是否需要设置                istop = (attr["text-decoration"] || attr["textDecoration"] || "").indexOf(_textstyle) > -1 ? 1 : 0;            }            //如果存在文字装饰属性            if (attr["text-decoration"] || attr["textDecoration"]) {                //需要添加样式的处理                if (istop === 1) {                    //如果为元素节点且存在文字装饰属性 并且不等于inherit和node                    if (_rangselect[i].style && _rangselect[i].style["text-decoration"] && _rangselect[i].style["text-decoration"] != "inherit" && _rangselect[i].style["text-decoration"] != "none") {                        //修改设置的属性为原有样式加当前样式                        attr["text-decoration"] = _rangselect[i].style["text-decoration"].replace(_textstyle, "") + " " + _textstyle;                    }                    //否则则直接设置为当前样式                    else {                        attr["text-decoration"] = _textstyle;                    }                }                //需要删除的处理                else if (istop === 0) {                    //判断是否为元素节点                    //如果是元素节点                    if (_rangselect[i].style) {                        //判断是否存在当前样式                        //如果存在则去除当前样式                        if (_rangselect[i].style["text-decoration"].indexOf(_textstyle) > -1) {                            //去除当前样式                            attr["text-decoration"] = _rangselect[i].style["text-decoration"].replace(_textstyle, "");                            //去除完毕后如果为空则设置为inherit                            if (attr["text-decoration"] == "") {                                attr["text-decoration"] = "inherit";                            }                        }                        //不存在时直接替换                        else {                            attr["text-decoration"] = _rangselect[i].style["text-decoration"];                        }                    }                    //否则直接设置为inherit(继承父级属性)                    else {                        attr["text-decoration"] = "inherit";                    }                }            }            //根据是否存在tagName(标签名) 判断是否为元素节点            //如果为元素节点则直接设置样式            if (_rangselect[i].tagName) {                U.selectEl(_rangselect[i]).css(attr); //设置样式            }            //否则则创建新的span标签 并替换原有是元素            else if (_rangselect[i].nodeValue) {                //创建新的span标签                _newspan = $$("span", {                    "innerHTML": _rangselect[i].nodeValue,                    "style": attr                });                //替换原有是元素                _rangselect[i].parentNode.replaceChild(_newspan, _rangselect[i]);            }        }    }};/*  特殊样式处理** @param element {element} 被继承样式的元素* @param attr    {object}    当前的样式属性*/U.UF.E.setSpecialAttr = function (element, attr) {    var _key, //for in 循环的key值        _newvalue, //新的值        _value; //当前值    if (element.style) {        //循环没个样式        for (_key in attr) {            if (attr[_key] == "") {                attr[_key] = "";            }            else {                //判断是否为文字装饰样式属性                if (_key == "text-decoration" || _key == "textDecoration") {                    //获取当前元素该样式的值                    _value = element.style[_key];                    //获取的样式有值且不为继承属性时                    if (_value && _value != "inherit" && _value != 'none') {                        //删除样式中的属性                        _newvalue = _value.replace(attr[_key], "");                        //如果替换后为空则设置为继承                        if (_newvalue == "") {                            attr[_key] = "inherit";                        }                        //否则如果替换后的值相等则将值设置进去                        else if (_newvalue == _value) {                            attr[_key] = attr[_key] + " " + _value;                        }                        //如果不等于则设置为新的值                        else {                            attr[_key] = _newvalue;                        }                    }                }                //否则如果设置的样式等于原本的样式 则设置为继承属性                else if (attr[_key] == element.style[_key] && "font-weight|fontWeight|font-style|fontStyle|".indexOf(_key) > -1) {                    attr[_key] = "inherit";                }            }        }    }    //返回处理好后的属性    return attr;};/* 把一个text标签进行拆分** @param  node {element} 元素节点* @param  offset  {number} 拆分的位置*/U.UF.E.splitText = function (node, offset) {    //如果拆分文字的位置等于总的长度,那么就在最后面添加空文本。    if (offset == node.nodeValue.length) {        var next = document.createTextNode('');        U.selectEl(node.parentNode).append(next, null, node);        return next;    }    var retval = node.splitText(offset);    return retval;};/* 获取到行元素* * @param  el {element} 选取元素*/U.UF.E.getLineElement = function (el) {    var _mel = el,        _tagname = el.tagName ? el.tagName.toLowerCase() : ""; //获取元素的标签名    //循环得到行元素    while (el && _tagname != "body" && (_tagname != "div" || !(el.id && el.id.length == "37"))) {        el = el.parentNode;        if (el) {            _tagname = el.tagName ? el.tagName.toLowerCase() : ""; //标签名        }    };    return (el && el.id) ? el : null;};/* 获取到块级元素* * @param   {element} 选取元素*/U.UF.E.getTagNameElement = function (node, tagname) {    tagname = tagname || 'span';    while (node) {        if (node.nodeName.toLocaleLowerCase() === tagname) {            return node;        } else if (node.nodeName.toLocaleLowerCase() === 'div' && !node.inline) {            return null;        }        node = node.parentNode;    }};/* 设置行的样式,如居中,局左,局右,设置编号等等功能* * @param   {object} range光标对象* @param   {object} 给指定的光标设置样式*/U.UF.E.setLineStyle = function (style, range) {    if ($('.U_UF_E_Picture_dragDot')[0]) {//清除图片拉伸的的虚拟框        U.selectEl('.U_UF_E_Picture_dragDot')[0].style.display = "none";    }    range = range || U.UF.E.getRangeAt(); //获取光标处理    var _rangeline,        _start = range.startContainer    _td = U.selectEl(_start).Parent({ "tagName": "TD" }); //起始选区    //判断居中的元素是不是td标签    if (_td && _td.tagName == "TD") {        _rangeline = [_td];    }    else {        _rangeline = U.UF.E.getRangeLineElement(range);    }    var i = 0; //设置循环变量    for (i = 0; i < _rangeline.length; i++) {  //循环设置样式        U.selectEl(_rangeline[i]).css(style); //设置样式    }    U.UF.E.reSelectRange(range);    return range; //返回选区对象};/* 获取选区行元素* * @param range  {object} range光标对象* */U.UF.E.getRangeLineElement = function (range) {    range = range || U.UF.E.getRangeAt(); //获取光标处理    var _start = range.startContainer, //起始选区        _end = range.endContainer, //结束选区        _stratline = U.UF.E.getLineElement(_start), //起始选行        _endline = U.UF.E.getLineElement(_end), //结束选行        _nextline = U.selectEl(_stratline).next()[0], //下一行        _rangeline = [_stratline]; //选中行记录    if (_stratline != _endline) { //如果起始行不等于结束行则证明选择多行        while (_nextline) { //循环记录选择的每一行            _rangeline.push(_nextline); //添加到选择行记录中            if (_nextline != _endline) { //如果依旧不等于结束行 则证明未获取完毕                _nextline = U.selectEl(_nextline).next()[0]; //修改下一行变量            } else { //直至等于为止                _nextline = false;            }        }    }    return _rangeline;}/* 设置字体方向* * @param direction {string}  方向 left center right* */U.UF.E.textAlign = function (direction) {    U.UF.E.setLineStyle({ 'text-align': direction });};/* 设置光标位置** @param   {element} 选区起始元素* @param   {element} 选区结束元素* @param   {number}  起始位置* @param   {number}  结束位置* @param   {number}  光标对象*/U.UF.E.setRange = function (startel, endel, start, end, range) {    range = range || U.UF.E.getRangeAt(); //获取光标处理    //html5处理光标选取的处理    if (window.getSelection) {        //判断光标没有聚焦到制定的元素上,就无法设置焦点,这里需要处理聚焦问题。        if (startel == endel && range.startContainer != startel) {            range.selectNodeContents(startel); //由于位置要还原制定span标签中             }        range.setStart(startel, start); //设置光标开始的位置        range.setEnd(endel, end); //设置光标结束的位置    }    //ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性    else {        var _range1 = document.body.createTextRange(), //创建一个光标1            _range2 = document.body.createTextRange(); //创建一个光标2        _range1.moveToElementText(startel); //光标放在开始的地方        _range1.moveStart("character", startel); //给光标设置        _range2.moveToElementText(endel); //光标放在结束的地方        _range2.moveStart("character", end); //设置光标结束区域的位置        _range1.setEndPoint("EndToStart", _range2); //光标1和光标2接连在一起形成选取        _range1.select(); //选择        range = _range1;    }    return range;}/* 格式整理,只整理第一层和第二层* * @param el {element} 整理的内容元素*/U.UF.E.unifiedFormat = function (el) {    var _i, //循环        _float,        _tagname,        _removeTagName = ['head', 'meta', 'script', 'link', 'style', 'title'], //需要移除的的标签        _frag = $$("frag"), //创建临时记录内容标签        _div, //行        _child = el.childNodes; //获取子级,改子级全部为行    //清除多余的元素    U.UF.E.unifiedFormat.remove(el);    //循环处理每一行    for (_i = 0; _i < _child.length; _i++) {        _display = _child[_i].currentStyle ? _child[_i].currentStyle.display : ""; //是否为行标签的处理        _tagname = _child[_i].tagName ? _child[_i].tagName.toLowerCase() : ""; //标签名        _float = _child[_i].currentStyle ? _child[_i].currentStyle.float : ""; //是否为行标签的处理        //附件不进行过滤        if (_child[_i].className == "U_MD_O_attachment") {            U.selectEl(_child[_i]).appendTo(_frag);            continue;        }        //行元素的处理        if (!_div || (_display != "" && _display != "inline") && (_float != "left" || _float != "right")) {            //所有的行标签的处理            //创建行标签            _div = $$("div", { "id": "e" + Guid.newGuid(), "style": { "cssText": U.UF.E.getRemainAttr(_child[_i])} }, _frag);        }        //调用非行元素处理函数 即不为第一层的处理        U.UF.E.unifiedFormat.next(_child[_i], true, _div);        if (!_div.childNodes.length && _frag.childNodes.length > 1) {            U.selectEl(_div).remove();        }    }    //返回处理后的临时元素    return _frag;};/* 格式整理,过滤标签* * @param el {element} 整理的内容元素*/U.UF.E.unifiedFormat.remove = function (el) {    var _i, //循环        _tagname, //标题名        _removeTagName = ['head', 'meta', 'script', 'link', 'style', 'title'], //需要移除的的标签        _child = el.childNodes; //获取子级,改子级全部为行    //循环处理每一行    for (_i = 0; _i < _child.length; _i++) {        _tagname = _child[_i].tagName ? _child[_i].tagName.toLowerCase() : ""; //标签名        //过去注释标签 nodeType为8 则为注释标签        if (_child[_i].nodeType === 8 || (_child[_i].nodeType == 3 && _child[_i].data.trim() == "")) {            _child[_i].remove();            _i--;            continue;        }        //删除过滤的标签        if (_removeTagName.indexOf(_tagname) >= 0) {            U.selectEl(_child[_i]).remove();            _i--;            continue;        }    }}/* 非第一行之后的所有内容处理* * @param el {element} 处理的元素* @param top {boolean}  是否为第二层标记 如果为第二层则所有标签直接修改为span标签  否则需要进行拆分* @return 处理后的结果集* */U.UF.E.unifiedFormat.next = function (el, top, fragel) {    var _i, _j, //循环变量        _float,        _display, //记录元素真实的display属性 用于判断是否为行级元素        _tagname, //记录元素的tagName        _nowspan, //记录当前span        _tdchild, //用于子级        _fraga = $$("frag"),        _frag = fragel, //$$("frag"), //用于记录整理后的内容的临时标签        _span, //用于记录块级整理后的内容        _childcsstext, //用于记录获取到的自己的样式        _child = el.childNodes, //获取处理元素子级        _tagname = el.tagName ? el.tagName.toLowerCase() : "",        _cssText = (top.style ? top.style.cssText : "") + ";" + fragel.style.cssText + (_tagname == "img" ? "" : U.UF.E.getRemainAttr(el)); //获取处理元素的样式 用户继承当前样式使用    //清除多余的元素    U.UF.E.unifiedFormat.remove(el);    //如果存在子级的处理    if (_child.length) {        //循环处理每一个子级        for (_i = 0; _i < _child.length; _i++) {            _span = null; //循环重新赋值            //整理当前元素需继承的样式  父级样式 + 当前元素原有样式            _childcsstext = _cssText + ";" + (_child[_i].tagName == "IMG" ? "" : U.UF.E.getRemainAttr(_child[_i]));            _display = _child[_i].currentStyle ? _child[_i].currentStyle.display : ""; //是否为行标签的处理            _float = _child[_i].currentStyle ? _child[_i].currentStyle.float : ""; //是否为行标签的处理            //特殊标签添加样式            //加粗            if (_tagname == "b") {                _childcsstext += ";font-weight: bold;";            }            //斜体            else if (_tagname == "i") {                _childcsstext += ";font-style: italic;";            }            //下划线            else if (_tagname == "u") {                _childcsstext += ";text-decoration: underline;";            }            //删除线            else if (_tagname == "s") {                _childcsstext += ";text-decoration: line-through;";            }            //如果是附件的处理            if (el.className == "U_MD_O_attachment_wrapper") {            }            //如果当前标签为a标签或者top为字符串(当top为字符串时表明存在href属性需要替换为a标签)            else if (_tagname == "a" || (U.UF.C.isElement(top) && top.tagName == "A")) {                //重新设置top值                //    top = U.UF.C.isString(top) ? top : el.href;                //设置name属性 用于传递使用                _child[_i].name = _child[_i].name || top.name || el.name || "";                //设置href属性 用于传递使用                _child[_i].href = _child[_i].href || top.href || el.href;                //创建a标签 并设置属性                _span = $$("a", {                    "name": _child[_i].name,                    "href": _child[_i].href || "javascript:void(0)",                    "style": { "cssText": _childcsstext }                }, _fraga);            }            //style样式标签处理            else if (_tagname == "style") {                el = U.selectEl(el).clone(true); //克隆style标签                el.appendTo(_frag); //天机到临时记录标签中                //创建新的行                arguments[2] = _frag = fragel = $$("div", {                    "id": "e" + Guid.newGuid(),                    "style": { "cssText": _childcsstext }                }, fragel.parentNode);                break; //终止整个循环            }            //table表格标签处理 表格固定为行标签            else if (_tagname == "table") {                if (_frag.innerHTML) {                    //创建新的行标签                    _span = $$("div", {                        "id": "e" + Guid.newGuid(),                        "style": { "cssText": _childcsstext }                    }, fragel.parentNode);                }                else {                    _span = _frag;                }                //克隆当前表格元素                el = U.selectEl(el).clone(true);                //将表格添加到行中                el.appendTo(_span);                //获取所有td节点                _tdchild = U.selectEl("td", el[0]);                //循环保存td节点的内容 过滤表格内的样式                for (_j = 0; _j < _tdchild.length; _j++) {                    _tdchild[_j].innerHTML = _tdchild[_j].innerText;                }                //创建新的行                arguments[2] = _frag = fragel = $$("div", {                    "id": "e" + Guid.newGuid(),                    "style": { "cssText": _childcsstext }                }, fragel.parentNode);                break; //终止整个循环            }            //行元素的处理            else if ((_display != "" && _display != "inline") && (_float != "left" || _float != "right") && _child[_i].innerHTML.trim() != "") {                if (_frag.innerHTML) {                    //创建新的行                    arguments[2] = _frag = fragel = $$("div", {                        "id": "e" + Guid.newGuid(),                        "style": { "cssText": _childcsstext }                    }, fragel.parentNode);                }                else {                    fragel.style.cssText += _childcsstext;                }            }            //否则则为块级元素            else {                _span = $$("span", { "style": { "cssText": _childcsstext} }, _fraga);            }            //进入判断是否依然存在子级 直到处理所有元素为止            var _nowspan = U.UF.E.unifiedFormat.next(_child[_i], _span || top, fragel);            //如果span元素的处理,说明下面只有文本元素的处理            if (_span) {                if (_nowspan.children.length) {                    //替换记录标签中的块级标签元素                    _fraga.replaceChild(_nowspan, _span);                    _frag.appendChild(_fraga);                }                //如果有下级元素的处理                else if (_nowspan.childNodes.length) {                    _span.appendChild(_nowspan);                    _frag.appendChild(_fraga);                }                else {                    U.selectEl(_span).remove();                }            }            else if (_nowspan) {                //替换记录标签中的块级标签元素                _fraga.appendChild(_nowspan);                _frag.appendChild(_fraga);            }        }    }    //如果不存在子级的处理    else {        //是否为第二层标记        if (top == true) {            if (_tagname == "img") {                var _img = U.selectEl(el).clone(true)[0];                _img.style.maxWidth = "100%";                _img.onerror = function () {                    this.src = "/img/editorError.png";                    this.width = 150;                    this.height = 112;                }                _span = $$("span", {                    "style": { "cssText": top.style.cssText }, //继承处理元素的样式                    //判断是否为a标签如果是则将a标签直接记录 不是则获取内容 !!!!!!!!!注释有问题                    "innerHTML": el.innerHTML != null ? el.innerHTML : el.data                });                _span.appendChild(_img);                _frag.appendChild(_span);            }            else {                //如果是则直接创建span块级标签,并添加到记录标签中                $$("span", {                    "style": { "cssText": _cssText }, //继承处理元素的样式                    //判断是否为a标签如果是则将a标签直接记录 不是则获取内容                    "innerHTML": el.innerHTML != null ? el.innerHTML : el.data                }, _frag);            }        }        //如果不为第二层标记        else {            //且存在内容则直接创建文本节点,并添加到记录标签中            if (el.data) {                _fraga.appendChild(document.createTextNode(el.data));            }            //否则则直接克隆该元素,并添加到记录标签中 不做处理  该情况出现在img标签            else if (_tagname == "img") {                var _img = U.selectEl(el).clone(true)[0];                _img.style.maxWidth = "100%";                _img.onerror = function () {                    this.src = "/img/editorError.png";                    this.width = 150;                    this.height = 112;                }                _span = $$("span", {                    "style": { "cssText": top.style.cssText }, //继承处理元素的样式                    //判断是否为a标签如果是则将a标签直接记录 不是则获取内容                    "innerHTML": el.innerHTML != null ? el.innerHTML : el.data                });                _span.appendChild(_img);                _fraga.appendChild(_span);            }        }    }    //返回处理后的元素集合    return _fraga;};/* 获取指定的css元素 暂无使用** @param ele {element} 被获取的元素* */U.UF.E.getRemainAttr = function (ele) {    //如果存在不存在样式 则返回空    if (!ele || !ele.style) {        return '';    }    //需要删除的属性    var _removeattr = ['position', 'width', 'height', 'background-image', 'border', 'min-height', 'float', 'min-width', 'display', 'padding', 'margin']; //     var _i; //循环变量定义    //循环将需要删除的属性的值设置为空    for (_i = 0; _i < _removeattr.length; _i++) {        //设置为空        ele.style[_removeattr[_i]] = "";    }    //返回设置后的样式    return ele.style.cssText;};/* 清除格式** @param range {object} range光标对象* */U.UF.E.clearStyle = function (range) {    range = range || U.UF.E.getRangeAt();   //获取光标    var _start = range.startContainer, //选区起始元素        _end = range.endContainer, //选区结束元素        _startline = U.UF.E.getLineElement(_start), //获取选区起始行元素        _endline = U.UF.E.getLineElement(_end); //获取选区结束行元素    //同行相同的样式    if (_startline == _endline && range.toString() == _startline.innerText) {        for (var i = 0; i < _startline.childNodes.length; i++) {            if (_startline.childNodes[i].nodeName !== "#text") {                _startline.childNodes[i].style.cssText = "font-family: 微软雅黑; font-weight: normal; font-size: 10.5pt; line-height: 2;";            }        }    } else {        U.UF.E.setRangeStyle({ "cssText": "" }, range); //设置清空样式    }    U.UF.E.reSelectRange(range);};/* 添加超链接* * @param el    {object} a标签对象* @param range {object} range光标对象* */U.UF.E.addHref = function (el, range) {    U.selectEl("#U_UF_E_herfAlert").remove();    range = range || U.UF.E.getRangeAt();  //获取光标    var _start = range.startContainer, //获取选区起始元素        _end = range.endContainer, //获取选区结束元素        _selectel = range.cloneContents(), //获取选区的所有元素        _startline = U.UF.E.getLineElement(_start), //获取选区起始行元素        _endline = U.UF.E.getLineElement(_end); //获取选区结束行元素    el = el || U.UF.E.getTagNameElement(range.startContainer, "a");    //判断是否跨行选择    if (_startline !== _endline || U.selectEl('img', _selectel)[0]) {        //如果是则提示无法添加A标签        U.UF.UI.alertClick('选择范围横跨多个段落或存在图片,因此无法编辑');    } else {        var _box = $$('div'); //创建Confirm最大层div        if (el) {//判断是否有el            _text = el.innerHTML; //获取文本            _href = el.href; //获取超链接            var _textinput = $$('div', { innerHTML: '<span style="margin-right:7px;">文本</span> <input class="U_MD_O_H_Inputactive" placeholder="输入文本" value="' + _text + '" style="width:210px;height:25px;border:1px solid rgba(169,169,169,1);border-radius:2px;text-indent: 3px;" />', "style": { "line-height": "25px", "margin": "40px 41px 17px"} }, _box); //创建文本区域            var _hrefinput = $$('div', { innerHTML: '<span style="margin-right:7px;">链接</span> <input class="U_MD_O_H_Inputactive" placeholder="请输入网页链接地址" value="' + _href + '" style="width:210px;height:25px;border:1px solid rgba(169,169,169,1);border-radius:2px;text-indent: 3px;"/>', "style": { "margin": "0px 41px 27px", "line-height": "25px"} }, _box); //创建链接区域            U.UF.UI.confirm(_box, U.UF.C.closure(U.UF.E.addHref.confirm, [range, _hrefinput, _textinput, _text, el])); //创建Confirm        } else {            //否则执行添加A标签操作            _a = U.selectEl('a', _selectel)[0], //获取选区中的第一个a标签            _href = _a ? _a.href : '', //如果存在则已第一个a标签做为href            _text = range.toString(); //获取选区的文字            var _textinput = $$('div', { innerHTML: '<span style="margin-right:7px;">文本</span> <input class="U_MD_O_H_Inputactive" placeholder="输入文本" value="' + _text + '" style="width:210px;height:25px;border:1px solid rgba(169,169,169,1);border-radius:2px;text-indent: 3px;"/>', "style": { "line-height": "25px", "margin": "40px 41px 17px"} }, _box); //创建文本区域            var _hrefinput = $$('div', { innerHTML: '<span style="margin-right:7px;">链接</span> <input class="U_MD_O_H_Inputactive" placeholder="请输入网页链接地址" value="http://' + _href + '" style="width:210px;height:25px;border:1px solid rgba(169,169,169,1);border-radius:2px;text-indent: 3px;"/>', "style": { "margin": "0px 41px 27px", "line-height": "25px"} }, _box); //创建链接区域            U.UF.UI.confirm(_box, U.UF.C.closure(U.UF.E.addHref.confirm, [range, _hrefinput, _textinput, _text])); //创建Confirm        }    }};/*** Excel确定添加A标签* @param _cellList 为选中的单元集合* @param hrefinput {element} 链接区域元素* @param textinput {element} 文本区域元素* @param text      {string}  选区文本记录*/U.UF.E.addHref.excelConfirm = function (_cellList, hrefinput, textinput, text) {    href = U.selectEl('input', hrefinput)[0].value; //获取输入的href    if (U.UF.S.Url.test(href)) { //判断链接是否合理        var _newtext = U.selectEl('input', textinput)[0].value; //获取当前文本        //被修改则直接删除选区 创建a标签直接添加        if (_cellList[0]) {            $$('a', { href: href, innerHTML: _newtext, target: "_blank" }, _cellList[0]); //创建A标签            _cellList[0].removeChild(_cellList[0].children[0]); //删除原来的文本,由创建的A标签代替        } else {            $$('a', { href: href, innerHTML: _newtext, target: "_blank" }, _cellList[0]); //创建A标签        }    }    else {        //提示链接存在有误        U.alert('输入的链接有误,无法添加');    }};/*** 确定添加A标签* @param range     {object}  range光标对象* @param hrefinput {element} 链接区域元素* @param textinput {element} 文本区域元素* @param text      {string}  选区文本记录* @param el        {object}  a标签对象*/U.UF.E.addHref.confirm = function (range, hrefinput, textinput, text, el) {    href = U.selectEl('input', hrefinput)[0].value; //获取输入的href    if (new RegExp(/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/).test(href)) { //判断链接是否合理        var _newtext = U.selectEl('input', textinput)[0].value; //获取当前文本        var _start = range.startContainer, //获取选区起始元素            _end = range.endContainer, //获取选区起始元素            _startspan = U.UF.E.getTagNameElement(_start, 'span'),            _endspan = U.UF.E.getTagNameElement(_end, 'span');        if (el) {//判断是否有el参数(修改)            el.innerHTML = _newtext; //替换文本            el.href = href; //替换超链接        } else {            var _frag = $$('frag');            if (_newtext !== text) { //判断文本是否被修改                //被修改则直接删除选区 创建a标签直接添加                _frag = $$('a', { href: href, innerHTML: _newtext, target: "_blank" }); //创建A标签            } else {                var _selectel = range.extractContents(), //获取选区的所有元素                    _rangselect = _selectel.childNodes; //获取选区的子级                var _text = _rangselect.innerHTML || _rangselect.data;                if (_newtext.trim() == "") {                    $$('a', { href: href, innerHTML: href, style: { cssText: _startspan.style.cssText }, target: "_blank" }, _frag); //创建A标签                } else {                    var i, _csstext;                    //循环处理每一个元素                    for (i = 0; i < _rangselect.length; i++) {                        if (_rangselect[i].nodeType == 3) {                            _csstext = i == _rangselect.length ? U.UF.E.getTagNameElement(_startspan, 'span').style.cssText : U.UF.E.getTagNameElement(_end, 'span').style.cssText;                            $$("a", { href: href, innerHTML: _rangselect[i].data, style: { cssText: _csstext }, target: "_blank" }, _frag);                        } else {                            $$("a", { href: href, innerHTML: _rangselect[i].innerHTML, style: { cssText: _rangselect[i].style.cssText }, target: "_blank" }, _frag);                        }                    }                }            }            _frag = U.UF.E.unifiedFormat(_frag); //进行格式整理            _frag.firstChild.firstChild.setAttribute("target", "_blank");            if (_startspan.innerHTML == "") {                U.selectEl(_startspan).remove();            }            if (_endspan.innerHTML == "") {                U.selectEl(_startspan).remove();            }            U.UF.E.insertContent(_frag, range, U.selectEl('#U_MD_O_H_wordEditor')[0]); //调用指定位置插入内容的函数        }    }    else {        //提示链接存在有误        U.alert('输入的链接有误,无法添加');        return false;    }};/* 超链接点击**/U.UF.E.addHref.click = function (e) {    if (document.getElementById('U_UF_E_herfAlert')) {//如果有弹框则删除        document.getElementById('U_UF_E_herfAlert').remove();    }    U.UF.EV.stopBubble(e);    var parent = U.selectEl("#U_MD_O_R_Parent")[0]; //获取编辑区    var _hyperlinkalert = $$('div', {        id: "U_UF_E_herfAlert",        style: {            "min-width": "250px", "max-width": "360px", height: "34px", background: "rgba(255,255,255,1)", border: "1px solid rgba(243,243,243,1)", "box-shadow": "0px 5px 5px 0px rgba(45,45,45,0.1)",            "border-radius": "2px", "line-height": "34px", "font-size": "12px", "font-family": "MicrosoftYaHei", "font-weight": "400", color: "rgba(48,126,209,1)", width: "fit-content",            width: "-webkit-fit-content", width: "-moz-fit-content", position: "absolute", zIndex: "999"        }    }, parent); //创建超链接弹框    var _link = $$('a', {        innerHTML: e.target.href,        style: {            "overflow": "hidden", "text-overflow": "ellipsis", "white-space": "nowrap", cursor: "pointer",            "max-width": "212px", "float": "left", "margin-left": "10px", "font-size": "14px"        }    }, _hyperlinkalert); //超链接按钮    var _rightButton = $$('div', { classname: "out_2", style: { "float": "right"} }, _hyperlinkalert);    var _unlink = $$('div', { innerHTML: "取消链接", style: { "float": "left", "margin-left": "20px", "margin-right": "10px", cursor: "pointer"} }, _rightButton); //取消链接按钮    var _modify = $$('div', { innerHTML: "修改", style: { "float": "left", "margin-left": "10px", "margin-right": "10px", cursor: "pointer"} }, _rightButton); //修改按钮    _link.onclick = function () {//链接的点击事件        U.UF.EV.stopBubble(e);        parent.blur();        window.open(e.target.href); //打开目标路径    }    _unlink.onclick = function () {//取消链接的点击事件        U.UF.EV.stopBubble(e);        e.target.parentElement.replaceChild($$('span', { innerText: e.target.innerText }), e.target);        _hyperlinkalert.remove(); //删除超链接弹框        parent.blur();    }    _modify.onclick = function () {//修改的点击事件        U.UF.EV.stopBubble(e);        U.UF.E.addHref(e.target); //修改弹框        parent.blur();        _hyperlinkalert.remove(); //删除超链接弹框    }    /*_hyperlinkalert.style.left = e.target.offsetLeft + "px";    _hyperlinkalert.style.top = e.target.offsetTop + 20 + "px"; //弹框的定位*/    //弹框的定位    console.log("超链接的位置", e.target.offsetLeft, e.target.offsetTop);    console.log("光标的位置", e.clientX, e.clientY);    console.log("滚动过的高度", U.selectEl('#U_MD_O_W_E_body')[0].offsetTop);    var EditorScrollTop = U.selectEl('#U_MD_O_R_Parent')[0].parentNode.scrollTop; //滚动高度    var EditorOffsetTop = U.selectEl('#U_MD_O_W_E_body')[0].offsetTop; //编辑器距窗口顶端的距离    _hyperlinkalert.style.left = e.clientX + "px";    _hyperlinkalert.style.top = e.clientY + EditorScrollTop - EditorOffsetTop + 12 + "px";}/* 在键盘输入的过程中处理* * @param editor {element}  编辑器的对象*/U.UF.E.key = function (editor) {    editor.editor.idarr = U.UF.E.key.getLineIdArr(editor); //初始化默认的行    //将定义的//将定义的方法做为对象的onkeydown方法    editor.onkeydown = function (e) {        if (!editor.editor.recordOpera.range) {            U.UF.E.recordRangeIndex(editor); //记录range处理        }        U.UF.E.key.keyDown(e, editor);    };    //失焦处理    editor.onblur = function (e) {        U.UF.E.key.blur(e, editor);    };    //将定义的方法做为对象的onkeyup方法    editor.onkeyup = function (e) {        U.UF.E.key.keyUp(e, editor);    };    //点击事件的处理    editor.onmouseup = function (e) {        U.UF.E.key.keyUp(e, editor, true);    };    editor.onclick = function (e) {        setTimeout(function () {            U.UF.E.key.click(e, editor);        }, 0);    };    //点击记录    editor.onmousedown = function (e) {        setTimeout(function () {            U.UF.E.recordRangeIndex(editor); //记录range处理        }, 0);    };    //粘贴处理    editor.onpaste = function (e) {        var _text = U.UF.E.onpaste(e, editor); //获取text的处理        //如果text有值则不粘贴图片        if (!_text) {            U.UF.E.pasteImage(e, editor);        }    };    editor.ondragenter = U.UF.E.pasteImage.ignoreDrag;    editor.ondragover = U.UF.E.pasteImage.ignoreDrag;    editor.ondrop = U.UF.E.pasteImage.drop;    //    U.selectEl(editor).bind({  });};/* 定义click方法* * @param e      {event}   event对象* @param editor {element} 编辑器对象* */U.UF.E.key.click = function (e, edit) {    var _nowel, _range = U.UF.E.getRangeAt(), //获取处理的光标        _startel = U.UF.E.getLineElement(_range.startContainer) //开始元素    if (_startel != (_nowel = U.UF.E.getLineElement(edit.editor.recordRange.startContainer))) {        edit.editor.recordHTML = _startel.outerHTML;    }    edit.editor.recordRange = _range;    U.selectEl('#U_UF_E_herfAlert').remove();    if (e.target.tagName == "A") { //如果点击标签为A标签        if (e.ctrlKey == true) { //Ctrl键是否按下            window.open(e.target.href); //打开超链接        } else {            U.UF.E.addHref.click(e);        }    }    else if (e.target.tagName == "IMG" && e.target.offsetParent.className != "U_MD_F_D") { //如果点击的元素为图片元素,且不是好友聊天状态中        edit.imgStretch.img = e.target; //记录当前图片到拉伸对象中        U.UF.E.picture.stretch.setPosition(edit.imgStretch, e); //定位显示拉伸区域    } else {//其余情况        edit.imgStretch.stretch.style.display = "none"; //影藏拉伸框    }}/* 定义blur方法* * @param e      {event}   event对象* @param editor {element} 编辑器对象* */U.UF.E.key.blur = function (e, edit) {    var _range = U.UF.E.getRangeAt(); //获取处理的光标    if (_range) {        var _startel = U.UF.E.getLineElement(_range.startContainer); //开始元素        _oldstartel = U.UF.E.getLineElement(edit.editor.recordRange.startContainer); //获取上一步操作所在的行        if (_startel) {            edit.editor.recordRange = _range; //记录光标对象            edit.editor.recordHTML = _startel.outerHTML; //记录内容  以此判断内容是否发送变化            edit.editor.log && console.log({ updateLine: [_startel.id] }, "在哪行失焦的");            if (_oldstartel && _oldstartel.id != "U_MD_O_H_wordEditor" && _startel == _oldstartel && _oldstartel.outerHTML != edit.editor.recordHTML) {                U.UF.E.operationNotice({ updateLine: [_startel.id] }, edit);                clearTimeout(edit.editor.interval); //取消计时更新            }        }    }}/* 定义onkey方法* * @param e {event} event对象* */U.UF.E.key.keyDown = function (e, edit) {    var _range = U.UF.E.getRangeAt(); //获取处理的光标    if (!_range) { return; }    var _el,        _oldstartel,        _line,        _result,        _startel = U.UF.E.getLineElement(_range.startContainer), //开始元素        _endel = U.UF.E.getLineElement(_range.endContainer); //结束元素     var _code = e.keyCode || e.which || e.charCode; //键盘码    if (_startel && _endel) {        if (e.ctrlKey || e.metaKey) {            edit.editor.recordRange = _range; //记录光标对象            switch (_code) {                case 90: //撤销(后退)                    U.UF.E.key.undo(e, edit);                    return;                case 89: //重做(前进)                    U.UF.E.key.redo(e, edit);                    return;            }        }        //判断光标是否存在的处理        clearTimeout(edit.editor.interval); //继续编辑的话直接取消计时器        //可能一直按着删除键,那么第一行给删除就添加第一行        if (edit.childNodes.length == 0) {            _result = U.UF.E.key.addDelLine(edit, _range); //删除最后一行后添加删除元素            //判断选区中是否有内容,那么就会处理删除操作            edit.editor.idarr = U.UF.E.key.getLineIdArr(edit); //获取当前文档的id集合            //记录关闭记录            edit.editor.log && console.log(_result, "内容被情况默认添加行");            //记录最新的行            edit.editor.recordRange = _range; //记录光标对象            edit.editor.recordHTML = U.UF.E.getLineElement(_range.startContainer).outerHTML; //记录内容  以此判断内容是否发送变化            //添加新行的处理            U.UF.E.operationNotice(_result, edit);            return;        }        //如果是删除行的处理        if (_code == 9) {            _range.deleteContents(); //移除文字            var _frag = $$("frag");            var _fragel = $$('div', { innerHTML: "      " });            _frag.appendChild(_fragel.childNodes[0]);            U.selectEl(_fragel).remove();            _range.insertNode(_frag); //插入需要写入的内容            U.UF.E.setRange(_range.endContainer, _range.endContainer, _range.endOffset, _range.endOffset, _range);  //设置选区 重新聚焦            U.UF.EV.stopDefault(); //阻止浏览器默认行为            return;        }        //回车处理        if (_code === 13) {            if (!U.UF.E.getTagNameElement(_range.commonAncestorContainer, 'table')) {                _result = U.UF.E.key.addLine(_range); //调用方法,新建行                //判断选区中是否有内容,那么就会处理删除操作                edit.editor.idarr = U.UF.E.key.getLineIdArr(edit); //获取当前文档的id集合                U.UF.EV.stopDefault(); //阻止浏览器默认行为                //记录关闭记录                edit.editor.log && console.log(_result, "更新换行的行,添加新的行");                //记录最新的行                edit.editor.recordRange = _range; //记录光标对象                edit.editor.recordHTML = U.UF.E.getLineElement(_range.startContainer).outerHTML; //记录内容  以此判断内容是否发送变化                //添加新行的处理                U.UF.E.operationNotice(_result, edit);            }        }        else {            edit.editor.recordDownHTML = _startel.outerHTML; //记录内容  以此判断内容是否发送变化                    if (_startel == _endel && edit.editor.recordRange.endOffset != edit.editor.recordRange.startOffset) {                setTimeout(U.UF.C.closure(function (startel, edit) {                    if (edit.editor.recordHTML != startel.outerHTML) {                        var _result = { updateLine: [_startel.id] };                        U.UF.E.operationNotice(_result, edit);                        edit.editor.log && console.log(_result, "存在选区的输入,即时更新");                        edit.editor.recordHTML = startel.outerHTML;                        edit.editor.recordRange = U.UF.E.getRangeAt();                    }                }, [_startel, edit]), 0);                clearTimeout(edit.editor.interval); //取消计时更新            }            _line = U.UF.E.key.getLineIdArr(edit); //获取            _result = U.UF.E.diff(_line, edit.editor.idarr); //对比得到删除的值            edit.editor.idarr = _line; //删除信息            //换行后回调的处理            if (_result.deleteLine.length) {                U.UF.E.operationNotice(_result, edit);                edit.editor.log && console.log(_result, "未松开删除按钮时,删除了行");                if (_result.updateLine[0]) {                    edit.editor.recordHTML = U.selectEl("#" + _result.updateLine[0])[0].outerHTML;                    edit.editor.recordRange = _range;                }            }            //没有任何特殊处理等待一点五秒的处理            else {                //普通的编辑那边等待记录,1.5秒后告诉用户修改信息                edit.editor.interval = setTimeout(function () {                    if (edit.editor.recordHTML != _startel.outerHTML) {                        //回调处理                        U.UF.E.operationNotice({ updateLine: [_startel.id] }, edit);                        edit.editor.log && console.log({ updateLine: [_startel.id] }, "超时更新行");                        //记录当前的行                        edit.editor.recordRange = _range; //记录光标对象                        edit.editor.recordHTML = _startel.outerHTML; //记录内容  以此判断内容是否发送变化                    }                }, 1000);            }        }    }};/* 定义键盘离开事件* * @param e {event} event对象* */U.UF.E.key.keyUp = function (e, edit, click) {    var _range = U.UF.E.getRangeAt(); //获取处理的光标    var _code = e.keyCode || e.which || e.charCode; //键盘码    if (e.ctrlKey == false) {        U.selectEl(edit).removeClass('U_MD_O_ctrlPress');    }    if (_range) {        var _line,            _result,            _oldstartel,            _startel = U.UF.E.getLineElement(_range.startContainer), //开始元素            _endel = U.UF.E.getLineElement(_range.startContainer); //结束元素        //判断第一层是否被删除掉,如果不是        if (edit.childNodes.length == 0) {            _result = U.UF.E.key.addDelLine(edit, _range); //删除最后一行后添加删除元素            //判断选区中是否有内容,那么就会处理删除操作            edit.editor.idarr = U.UF.E.key.getLineIdArr(edit); //获取当前文档的id集合            //记录关闭记录            edit.editor.log && console.log(_result, "内容被情况默认添加行");            //记录最新的行            edit.editor.recordRange = _range; //记录光标对象            edit.editor.recordHTML = U.UF.E.getLineElement(_range.startContainer).outerHTML; //记录内容  以此判断内容是否发送变化            //添加新行的处理            U.UF.E.operationNotice(_result, edit);            return;        }        _oldstartel = U.UF.E.getLineElement(edit.editor.recordRange.startContainer); //记录之前开始的行        //开始位置切换了,那么就要把开始位置作为修改行        if (_oldstartel && (_oldstartel != edit && _oldstartel != _startel || (_startel == _oldstartel && _startel.outerHTML != edit.editor.recordDownHTML))) {            if (edit.editor.recordHTML != _oldstartel.outerHTML) {                var _result = { "updateLine": [_oldstartel.id] };                U.UF.E.operationNotice(_result, edit);                edit.editor.log && console.log(_result, "光标切换且内容发送变化时");                clearTimeout(edit.editor.interval); //取消计时更新            }            edit.editor.recordRange = _range;            edit.editor.recordHTML = _startel.outerHTML;        }        if (_code > 36 && _code < 41) {            U.UF.E.recordRangeIndex(edit); //记录range处理        }        _line = U.UF.E.key.getLineIdArr(edit); //获取        _result = U.UF.E.diff(_line, edit.editor.idarr);        edit.editor.idarr = _line;        //删除行的处理        if (_result.deleteLine.length) {            U.UF.E.operationNotice(_result, edit);            edit.editor.log && console.log(_result, "删除了行");            var _range = U.UF.E.getRangeAt();            edit.editor.recordRange = _range;            edit.editor.recordHTML = U.UF.E.getLineElement(_range.commonAncestorContainer).outerHTML;            clearTimeout(edit.editor.interval); //取消计时更新        }        U.UF.E.formatBrush(edit, false); //格式刷工具未启用状态 记录当前光标所在位置的文字样式    }};/* 把编辑器里面的内容转换为数组,数组的id为div的id。* * @param edit {element} 编辑器元素* @return 数组* */U.UF.E.key.getLineIdArr = function (edit) {    var _i,        _arr = [];    //循环添加子元素    for (_i = 0; _i < edit.childNodes.length; _i++) {        //判断是否是行元素,只有行元素才记录        if (edit.childNodes[_i].tagName && edit.childNodes[_i].tagName.toLowerCase() === "div") {            //记录id和innerHTML            _arr.push({ "id": edit.childNodes[_i].id, "innerHTML": edit.childNodes[_i].outerHTML });        }    }    return _arr;};/* 比较编辑器列删除方法* * @param   arr 进行比较的数组一* @param   arr 进行比较的数组二*/U.UF.E.diff = function (arr1, arr2) {    var temp = []; //临时数组1    var temparray = []; //临时数组2    var _i, _j; //循环变量    var _updateLine = [];    for (_i = 0; _i < arr1.length; _i++) {        temp[arr1[_i].id] = true; //把数组B的值当成临时数组1的键并赋值为真    }    for (_j = 0; _j < arr2.length; _j++) {        //同时把数组A的值当成临时数组1的键并判断是否为真,如果不为真说明没重复,就合并到一个新数组里,这样就可以得到一个全新并无重复的数组        if (!temp[arr2[_j].id]) {            if (_updateLine.length == 0) {                _updateLine.push(arr2[_j - 1].id);            }            temparray.push(arr2[_j].id);        }    }    return {        updateLine: _updateLine,        deleteLine: temparray    }; //返回差异值}/* 添加删除后的空行* * @param 编辑器元素* @param range 可选* @returns {*} 返回id*/U.UF.E.key.addDelLine = function (edit, range) {    var _range = range || U.UF.E.getRangeAt(), //获得光标的位置        _el = $$("div", { id: edit.editor.idarr[0] ? edit.editor.idarr[0].id : "e" + Guid.newGuid(), innerHTML: "<span><br></span>" }, edit); //重新创建第一行,值为原第一行的id    _range.selectNodeContents(_el);  //将光标重选中添加的内容    _range.collapse(true); //向右折叠光标选区,设置结束点和开始点相同地方    return { addLine: [_el.id] };}/* 添加行* * @param range 可选* @returns {*} 返回id*/U.UF.E.key.addLine = function (range) {    var _txtnode, //换行后的文本内容        _range = range || U.UF.E.getRangeAt(), //获得光标的位置        _startline = U.UF.E.getLineElement(_range.startContainer), //得到起始行的div        _el = $$('div', { id: "e" + Guid.newGuid(), style: { cssText: _startline.style.cssText} }), //需要添加的新元素        _result = {} //添加行后会影响变化的值    ;    //删除已经选中的内容    if (_range.startOffset != _range.endOffset && _range.startContainer.innerHTML !== "<br>") {        _range.deleteContents();    }    _range.setEnd(_startline, _startline.childNodes.length); //设置光标结束点的位置    _txt = _range.extractContents(); //剪切文本处理    if ($("img", _txt)[0]) {        _txtnode = _txt;    }    //判断选取是否有内容,若有返回内容,反之添加一个br标签占位    else if (_txt.textContent.trim() === '') { //如果没有内容那么就添加一个br标签        _txtnode = $$('span', { style: { cssText: (_startline.lastChild && _startline.lastChild.style) ? _startline.lastChild.style.cssText : "" }, innerHTML: "<br>" });    }    //设置内容    else {        _txtnode = _txt;    }    //如果回车行的内容为"",且没有存在有效元素 那么就记录原有样式创建默认行    if (_startline.innerText == '' && !U.UF.E.validElement(_startline)) {        var _clone = _txtnode.nodeName == "SPAN" ? _txtnode : U.selectEl('span', _txtnode)[0]; //获取可克隆样式元素        var _content = _clone ? U.selectEl(_clone).clone()[0] : $$('span', { innerHTML: "<br>" });  //创建内容        _content.innerHTML = "<br>"; //设置默认内容        U.selectEl(_content).appendTo(_startline); //追加    }    _el.appendChild(_txtnode); //添加到创建的div里面    U.UF.E.insertAfter(_el, _startline); //添加到选中的div下面    _range.selectNodeContents(_el);  //将光标重选中添加的内容    _range.collapse(true); //向右折叠光标选区,设置结束点和开始点相同地方    _result.addLine = [_el.id]; //添加新的行    _result.updateLine = [_startline.id]; //结束新的行    return _result; //返回添加的id};/* 判断某个元素内是否存在有效元素(存在内容、存在图片等),过滤无用元素(空span)  ** @param el {element} 父级元素* @returns {boole} 返回是否存在有效元素*/U.UF.E.validElement = function (el) {    var i, //定义循环变量        _children = el.children,  //获取子级        _valid = false; //默认为没有有效元素    for (i = 0; i < _children.length; i++) { //循环处理        if (_children[i].nodeName == "BR") {            continue; //BR标签默认不做处理        }        else if (_children[i].nodeName == "IMG" || _children[i].innerText.length > 0 || ($('img', _children[i])[0] && _children[i].innerText.length == 0)) { //存在内容、存在图片则为有效元素            _valid = true;        }        else { //过滤无用标题            U.selectEl(_children[i]).remove();            i--;        }    }    return _valid; //返回结果}/* 在元素之后插入* * @param newEl    {element}  插入的元素* @param targetEl {element}  插入比对位置的元素* */U.UF.E.insertAfter = function (newEl, targetEl) {    //插入比对位置的元素的父级元素    var parentEl = targetEl.parentNode;    //如果当前元素的父级元素的最后一个元素为插入比对位置的元素    if (parentEl.lastChild === targetEl) {        //则使用appendChild直接添加到最后        parentEl.appendChild(newEl);    } else {        //否则则采用insertBefore 添加到插入比对位置的元素的上一个元素后        parentEl.insertBefore(newEl, targetEl.nextSibling);    }    //返回插入的元素    return newEl;};/* 复制格式** 效果:把选区内的第一个或开始位置的字体样式复制,赋值到常量里* */U.UF.E.formatBrush = function (el, pattern) {    el = el || U.selectEl('#U_MD_O_H_wordEditor')[0];    if (U.UF.E.formatBrush.callBack && U.UF.E.formatBrush.pattern) {        U.UF.E.formatBrush.pattern = undefined;        U.selectEl(el).bind('mouseup', U.UF.E.formatBrush.callBack);        return;    }    var _style = pattern == false ? el.editor.recordRangeStyle : el.editor.brushStyle;    var range = U.UF.E.getRangeAt();    //获取选区    var _start = range.startContainer;    //选区开始位置    if (_start.nodeName == "DIV") {        //如果选区开始节点是div的话,代表添加过样式之类的        if (!range.cloneContents().children[0]) { //如果光标不能存在元素            _style = {  // 情况格式刷数据                "font-family": "",                "font-size": "",                "font-weight": "",                "font-style": "",                "text-decoration": "",                "color": "",                "background-color": ""            };            pattern == false && (_style["text-align"] = "", _style["name"] = "");            return;        }        //获取选区内的第一个块状节点,的第一个文档节点        //_start = range.cloneContents().children[0].firstChild;    }    //循环常量brushstyle 刷子样式    var _value;    _start = _start.nodeType == 1 ? _start : _start.parentElement;    for (var name in _style) {        //把相应的样式名字,内容,赋值给相应的常量值        if (name == "font-size") {            _value = (parseFloat(_start.currentStyle[name]) * 72 / el.editor.dpi).toFixed(1) + "pt";        } else {            _value = _start.currentStyle[name];        }        _style[name] = _value;    }    if (pattern !== false) { //判断是否为默认记录样式处理        U.UF.E.formatBrush.pattern = pattern;        if (pattern !== true) {            U.selectEl(el).unbind("mouseup", U.UF.E.formatBrush.callBack); //是否单次取消            U.UF.E.formatBrush.callBack = function () {  //设置鼠标起开处理                U.UF.E.fomatBrushNext(el); //设置样式                U.UF.E.formatBrush.pattern == undefined && U.selectEl(el).unbind("mouseup", U.UF.E.formatBrush.callBack); //是否单次取消            };            U.selectEl(el).bind('mouseup', U.UF.E.formatBrush.callBack);        }    }    else {        _style["text-align"] = U.UF.E.getLineElement(_start).currentStyle.textAlign;        _style["name"] = U.UF.E.getLineElement(_start).getAttribute('name');        U.UF.C.isFunction(el.editor.styleState) && el.editor.styleState(el.editor.recordRangeStyle);    }};/* 粘贴复制的样式** 效果: 把常量复制到样式,粘贴到编辑器中* */U.UF.E.fomatBrushNext = function (el) {    U.UF.E.setRangeStyle({ "cssText": '' });    //在赋值相应的样式    U.UF.E.setRangeStyle(el.editor.brushStyle);};/* 附件功能* * @param input  {element} input文件域元素* @param editor {element} 编辑器元素*/U.UF.E.attachment = function (input, editor) {    if (input.files.length) { //判断是否存在文件        var _range = U.UF.E.getRangeAt(); //获取光标处理        U.UF.UP.inputUpload([input], 'http://upload.1473.cn/upload', function (r) { //调用统一上传处理            var _file, _filetype, _input = r.context[0];            var _imgtype = /.*(jpg|png|gif|jpeg|JPG|PNG|GIF|JPEG|bmp|BMP)$/;            var _filearray = []; //记录上传图片的数组            if (Object.prototype.toString.call(r.value[0]) != "[object Array]") { //根据返回值类型判断是否多图上传                _filearray = [r.value]; //单图用数组则直接记录            } else {                _filearray = r.value; //多图则直接替换即可            }            var _el, _frag = $$('frag');            for (i = 0; i < _filearray.length; i++) { //循环评接拼接                _file = _input.files[i];                _filetype = _file.name.substring(_file.name.lastIndexOf('.') + 1, _file.name.length); //获取文件后缀名                if (_filetype.match(_imgtype)) {//图片类型处理                    _el = $$("div", {}, _frag); ;                    $$('span', { innerHTML: ' <img src="http://fs.1473.cn/' + _filearray[i][0] + '">' }, _el);                }                else { //其余文件类型处理                    _el = U.UF.E.attachment.create(_file, _filearray[i][0], _filetype);                    U.selectEl(_el).appendTo(_frag);                }            }            _frag = U.UF.E.unifiedFormat(_frag); //进行格式整理            U.UF.E.insertContent(_frag, _range, editor || U.selectEl('#U_MD_O_H_wordEditor')[0]); //调用指定位置插入内容的函数        }, [input]);    }}/* 创建附件* * @param input  {element} input文件域元素* @param editor {element} 编辑器元素*/U.UF.E.attachment.create = function (file, fileinfo, type) {    //, style: { "text-align": "center"}    var _attachment = $$("div", { className: "U_MD_O_attachment", id: "e" + Guid.newGuid(), contenteditable: "false" }),        _wrapper;    var _imgtype = /.*(jpg|png|gif|jpeg|bmp)$/;    //图片类型处理          if (type.match(_imgtype)) {        $$('span', { innerHTML: ' <img src="http://fs.1473.cn/' + fileinfo[0] + '">' }, _attachment);    } else {        var _videotype = /.*(mp4|avi|wmv|ogg|webm|mpg|mpeg)$/;        var _musictype = /.*(mp3|wav|mid|midi)$/;        $$("span", { innerHTML: "​" }, _attachment);        _wrapper = $$("span", { contenteditable: "false" }, _attachment);        //音乐类型处理             if (type.match(_videotype)) {            $$('video', { src: "http://fs.1473.cn/" + fileinfo, controls: "controls", style: { "width": "530px", "height": "300px"} }, _wrapper);        }        //视频类型处理             else if (type.match(_musictype)) {            $$('audio', { src: "http://fs.1473.cn/" + fileinfo, controls: "controls" }, _wrapper);        }        //其余文件类型处理              else {            _wrapper.className = "U_MD_O_attachment_wrapper";            $$('span', { "className": "U_MD_O_attachment_wrapper_img", contenteditable: "false" }, _wrapper);            var _info = $$("span", { className: "U_MD_O_attachment_fileinfo", contenteditable: "false" }, _wrapper);            $$("span", { innerHTML: U.UF.E.attachment.fileNameSplice(file.name), contenteditable: "false" }, _info);            $$("span", { innerHTML: U.UF.C.computeFileSize(file.size), contenteditable: "false" }, _info);            $$("a", {                "href": "/Pages/Download.htm?id=" + fileinfo[2], //下载路径地址                fileid: fileinfo[2], //文件id                name: file.name, //文件名称                type: file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length), //文件后缀名                target: "_blank",                innerHTML: "打开",                contenteditable: "false"            }, _wrapper);        }        $$("span", { innerHTML: "​" }, _attachment);    }    return _attachment;}/* 获取附件名* * @param input  {string} 文件名字* @param editor {number} 最大长度*/U.UF.E.attachment.fileNameSplice = function (name, maxlength) {    maxlength = maxlength || 30;    var i, _index = 0, _gblen = 0, _start = "", _end = "";    for (i = 0; i < name.length; i++) {        if (name.charCodeAt(i) > 127 || name.charCodeAt(i) == 94) {            _gblen += 2;        } else {            _gblen++;        }        _gblen < maxlength / 2 - 2 && (_start += name[i]);    }    if (_gblen > maxlength) {        i = name.length;        while (_index < maxlength / 2 - 2) {            if (name.charCodeAt(i) > 127 || name.charCodeAt(i) == 94) {                _index += 2;            } else {                _index++;            }            _end = name[name.length - _index] + _end;            i--;        }        name = _start + "..." + _end;    }    return name;}/* 图片插入控件  效果:插入图片* * @param input  {element} input文件域元素* @param editor {element} 编辑器元素*/U.UF.E.picture = function (input, editor) {    if (input.files.length) { //判断是否存在文件        //给最后一个input以标识,在完成上传后更改input的value值为空,解决第二次上传onchange不响应的问题。        //按道理,如果能够精准判断到谁是最后一个上传最保险,但难以判断,此做法已经生效,有问题以后再考虑。        //js上传好像是数组最后一个最先上传,所以设置第0位进行传值。        input.files[0].input = input;        for (var i = 0; i < input.files.length;i++) {            U.UF.UP.HTML5.upload("http://upload.1473.cn/upload", input.files[i], function (r) {                //document.getElementById("product_u_i_displayImg").src = "http://fs.1473.cn/" + r.fileServerName;                //如需要生成缩略图,则调用                //调用上传图片控件                var _img = ''; //设置img元素字符串                //for (i = 0; i < _imgarray.length; i++) { //循环评接拼接                    //                $$("span", { innerHTML: "​" }, _attachment);                _img += '<span>  <img src="http://fs.1473.cn/' + r.fileServerName + '"> </span>'; //图片元素拼接                //}                //$('#U_MD_O_H_wordEditor')[0],为什么要用或者?并且多条语句连写调试好困难,需要分开。                //找到编辑器                var _editor = editor || U.selectEl('#U_MD_O_H_wordEditor')[0];                U.UF.E.textFormat(_img, _editor); //生成img元素                //获取input控件,清空其值,解决第二次上传onchange不触发的问题。                var _input = r.input;                if (_input) {                    _input.value = "";                }            }, function (r) {  }, function (r) {  });        }    }}// U.UF.E.picture = function (input, editor) {//     if (input.files.length) { //判断是否存在文件//         var _range = U.UF.E.getRangeAt(); //获取光标处理//         U.UF.UP.inputUpload([input], 'http://upload.1473.cn/upload', function (r) { //调用统一上传处理//             var _input = r.context[0];//             var _imgarray = []; //记录上传图片的数组//             if (Object.prototype.toString.call(r.value[0]) != "[object Array]") { //根据返回值类型判断是否多图上传//                 _imgarray = [r.value]; //单图用数组则直接记录//             } else {//                 _imgarray = r.value; //多图则直接替换即可//             }//             //调用上传图片控件//             var _img = ''; //设置img元素字符串//             for (i = 0; i < _imgarray.length; i++) { //循环评接拼接//                 //                $$("span", { innerHTML: "​" }, _attachment);//                 _img += '<span>  <img src="http://fs.1473.cn/' + _imgarray[i][0] + '"> </span>'; //图片元素拼接//             }//             //$('#U_MD_O_H_wordEditor')[0],为什么要用或者?并且多条语句连写调试好困难,需要分开。//             //找到编辑器//             var _editor = editor || U.selectEl('#U_MD_O_H_wordEditor')[0];//             U.UF.E.textFormat(_img, _editor); //生成img元素//         }, [input]);//     }// }/* word复制粘贴图片及拖拽图片函数* * @param e      {event}   事件对象* @param editor {element} 编辑器元素*/U.UF.E.pasteImage = function (e, editor) {    e.preventDefault(); //阻止默认事件    var files = e.clipboardData.files; //获取文件列表    if (files.length && e.clipboardData.types.indexOf('Files') > -1) {        var filebtn = $$('input', { type: "file" }) //新建文件域        filebtn.files = files; //获取文件列表        U.UF.E.picture(filebtn); //上传图片        filebtn.remove(); //删除文件域    }    else {        return true;    }}/* 阻止拖拽默认事件** @param e {event} 事件对象*/U.UF.E.pasteImage.ignoreDrag = function (e) {    //因为我们在处理拖放,所以应该确保没有其他元素会取得这个事件    e.stopPropagation();    e.preventDefault();}/* 拖拽上传处理* * @param e {event} 事件对象*/U.UF.E.pasteImage.drop = function (e) {    //取消事件传播及默认行为    e.stopPropagation();    e.preventDefault();    //取得拖进来的文件    var data = e.dataTransfer;    var files = data.files;    //将其传给真正的处理文件的函数    var filebtn = $$('input', { type: "file" })    filebtn.files = files;    U.UF.E.picture(filebtn, this);    filebtn.remove();}/* 拉伸处理* * @param el {element} 编辑器元素*/U.UF.E.picture.stretch = function (el) {    var _breadth = 12;    if (!el.imgStretch) {        var _img = $$("div", {            style: { display: "none", border: "1px dashed #535353", position: "absolute", minWidth: "30px", minHeight: "30px" }        }, document.body);        var _csstext = "width:" + _breadth + "px; height:" + _breadth + "px;position:absolute;z-index:999;background:url('/EditorImage/yuan1.png') no-repeat";        var _deviant = -_breadth / 2;        //创建虚拟框        el.imgStretch = {            //拉伸区域            stretch: _img,            //左上的按钮            nw: $$("div", { name: "nw", style: { cssText: _csstext, top: _deviant + "px", left: _deviant + "px", cursor: "nw-resize"} }, _img),            //右上的按钮            ne: $$("div", { name: "ne", style: { cssText: _csstext, top: _deviant + "px", right: _deviant + "px", cursor: "ne-resize"} }, _img),            //左下的按钮            sw: $$("div", { name: "sw", style: { cssText: _csstext, bottom: _deviant + "px", left: _deviant + "px", cursor: "sw-resize"} }, _img),            //右下的按钮            se: $$("div", { name: "se", style: { cssText: _csstext, bottom: _deviant + "px", right: _deviant + "px", cursor: "se-resize"} }, _img),            //上的按钮            n: $$("div", { name: "n", style: { cssText: _csstext, top: _deviant + "px", left: "calc(50% - " + -_deviant + "px)", cursor: "n-resize"} }, _img),            //下的按钮            s: $$("div", { name: "s", style: { cssText: _csstext, bottom: _deviant + "px", left: "calc(50% - " + -_deviant + "px)", cursor: "s-resize"} }, _img),            //左的按钮            w: $$("div", { name: "w", style: { cssText: _csstext, left: _deviant + "px", top: "calc(50% - " + -_deviant + "px)", cursor: "w-resize"} }, _img),            //右的按钮            e: $$("div", { name: "e", style: { cssText: _csstext, right: _deviant + "px", top: "calc(50% - " + -_deviant + "px)", cursor: "e-resize"} }, _img),            //左边的拖动虚拟线            l: $$("div", { name: "l", style: { position: "absolute", cursor: "e-resize", left: "-1px", width: "3px", height: "100%"} }, _img),            //右边的拖动虚拟线            r: $$("div", { name: "r", style: { position: "absolute", cursor: "e-resize", right: "-1px", width: "3px", height: "100%"} }, _img),            //顶部的拖动虚拟线            t: $$("div", { name: "t", style: { position: "absolute", cursor: "n-resize", top: "-1px", width: "100%", height: "3px"} }, _img),            //底部的拖动虚拟线            b: $$("div", { name: "b", style: { position: "absolute", cursor: "n-resize", bottom: "-1px", width: "100%", height: "3px"} }, _img),            maxWidth: U.selectEl(el)[0].offsetWidth        };    }    //绑定拖拽事件    new U.UF.E.picture.stretch.bindEvent(el);};/* 拉伸事件绑定* * @param el {element} 编辑器元素*/U.UF.E.picture.stretch.bindEvent = function (el) {    this.el = el; //设置编辑器元素    this.init(); //初始化设置}/* 拖拽方法* */U.UF.E.picture.stretch.bindEvent.prototype = {    //初始化    init: function () {        for (key in this.el.imgStretch) { //绑定所有可拉伸区域事件            key !== "stretch" && key !== "maxWidth" && this.el.imgStretch[key].addEventListener('mousedown', this.mouseDown.bind(this)); //绑定事件        }        document.body.addEventListener('mousemove', this.mouseMove.bind(this)); //绑定事件        document.body.addEventListener('mouseup', this.mouseUp.bind(this)); //绑定事件    },    //鼠标按下事件    mouseDown: function (e) {        this.name = e.target.name; //记录元素标识        this.stratX = e.clientX; //起始位置X        this.stratY = e.clientY; //起始位置Y        this.down = true; //按下标识    },    //鼠标移动事件    mouseMove: function (e) {        if (this.down) { //如果鼠标按下            //计算移动的坐标距离            var _moveX = e.clientX - this.stratX;            var _moveY = this.stratY - e.clientY;            var _click = this.name; //获取点击名称            //判断是否可以拉伸            window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();            //清空移动的数据            if (_click.length == 2 || _click == "w" || _click == "e" || _click == "l" || _click == "r") {                //如果是右方的拖动就移动距离相反                (_click == "w" || _click == "sw" || _click == "nw" || _click == "l") && (_moveX = -_moveX);                //处理虚拟框的宽高,和圆圈位置                U.UF.E.picture.stretch.moveX(this.el, this.el.imgStretch, _moveX);            }            if (_click.length == 2 || _click == "n" || _click == "s" || _click == "t" || _click == "b") {                //如果是上方的拖动就移动距离相反                (_click == "n" || _click == "nw" || _click == "ne" || _click == "t") && (_moveY = -_moveY)                //处理虚拟框的宽高,和圆圈位置                U.UF.E.picture.stretch.moveY(this.el.imgStretch, _moveY);            }            //设置新的对比起始位置            this.stratX = e.clientX;            this.stratY = e.clientY;        }    },    //鼠标松开事件    mouseUp: function (e) {        if (this.down) { //如果鼠标已按下            var _imgstretch = this.el.imgStretch; //获取拉伸元素集合            _imgstretch.img.style.width = _imgstretch.stretch.offsetWidth + "px"; //赋值            _imgstretch.img.style.height = _imgstretch.stretch.offsetHeight + "px"; //赋值            U.UF.E.picture.stretch.setPosition(_imgstretch, e); //执行点击事件重新定位            this.down = false; //设置按下标识结束        }    }}/* 设置拉伸框位置* * @param obj   {object}  拉伸对象* @param event [event}   事件对象*/U.UF.E.picture.stretch.setPosition = function (obj, event) {    var _stretch = obj.stretch; //拉伸盒子元素    var _imgel = obj.img; //被拉伸图片    //显示虚拟框,设置虚拟框的位置,大小    _stretch.style.display = "block";  //显示拉伸元素    var _imgelattr = _imgel.getBoundingClientRect(); //获取位置大小属性    if (event.clientX == event.pageX && event.clientY == event.pageY) { //当页面没有滚动时        _stretch.style.left = _imgelattr.left + "px"; //设置值        _stretch.style.top = _imgelattr.top + U.selectEl('body')[0].scrollTop + "px"; //设置值    } else {        var _offset = U.UF.E.picture.parentOfferset(_imgel, { "offsetLeft": 0, "offsetTop": 0 }); //获取父亲层的边距        _stretch.style.left = _imgel.offsetLeft + _offset.offsetLeft + parseInt($(_imgel).css("padding-left")) + "px"; //设置值        _stretch.style.top = _imgel.offsetTop + _offset.offsetTop + parseInt($(_imgel).css("padding-top")) + "px";  //设置值    }    _stretch.style.width = _imgelattr.width - 2 + "px"; //设置宽度    _stretch.style.height = _imgelattr.height - 2 + "px"; //设置高度    var _objattr = _stretch.getBoundingClientRect(); //获取位置大小属性    var _breadth = obj.n.offsetWidth / 2; //计算远点大小偏移值    obj.n.style.left = _objattr.width / 2 - _breadth + "px"; //设置顶部中心原点居中    obj.w.style.top = _objattr.height / 2 - _breadth + "px"; //设置底部中心原点居中    obj.s.style.left = _objattr.width / 2 - _breadth + "px"; //设置左部中心原点居中    obj.e.style.top = _objattr.height / 2 - _breadth + "px"; //设置右部中心原点居中}/* 左右拖拽方法* * @param el    [element} 编辑器对象* @param obj   {object}  拉伸对象* @param moveX [int}     移动距离*/U.UF.E.picture.stretch.moveX = function (el, obj, moveX) {    var _stretch = obj.stretch; //拉伸盒子元素     if ((parseInt(_stretch.style.width) + moveX < obj.maxWidth && parseInt(_stretch.style.width) + moveX > 30)) { //判断拉伸后是否超出限制        var _align = el.editor ? el.editor.recordRangeStyle["text-align"] : ""; //获取对齐方式        switch (_align) { //判断对齐方式            case "end": //end 为 right            case "right": //居右处理                _stretch.style.left = _stretch.offsetLeft - moveX + 'px'; //设置left值                U.selectEl(_stretch)[0].style.width = parseInt(_stretch.style.width) + moveX + "px"; //设置宽度                break;            case "center": //居中处理                _stretch.style.width = parseInt(_stretch.style.width) + moveX + 'px'; //设置宽度                _stretch.style.left = parseFloat(_stretch.style.left) - moveX / 2 + 'px'; //设置偏左值                break;            default: //居左处理                _stretch.style.width = parseInt(_stretch.style.width) + moveX + "px"; //设置宽度        }        obj.n.style.left = obj.s.style.left = _stretch.offsetWidth / 2 - obj.s.offsetWidth / 2 + "px";  //设置顶部 底部原点居中    }};/* 上下拖拽方法* * @param obj   {object}  拉伸对象* @param moveX [int}     移动距离*/U.UF.E.picture.stretch.moveY = function (obj, moveY) {    var _stretch = obj.stretch; //拉伸盒子元素     //变化虚拟框的宽度    _stretch.style.height = _stretch.offsetHeight - 2 - moveY + "px";    //变化左、右按钮的位置    obj.w.style.top = obj.e.style.top = _stretch.offsetHeight / 2 - obj.w.offsetWidth / 2 + 'px';};/* 得到父亲层的边距* * @param obj   {object}  拉伸对象* @param moveX [int}     移动距离* @return {object}  返回父亲层的边距*/U.UF.E.picture.parentOfferset = function (obj, json) {    var _offset = {};    //判断父亲层的左边距是否为空    if (obj.offsetParent.offsetLeft != 0) {        //如果有就赋值                                                _offset.offsetLeft = obj.offsetParent.offsetLeft;    } else {        //没有就赋值0        _offset.offsetLeft = 0;    }    //判断父亲层的上边距是否为空    if (obj.offsetParent.offsetTop != 0) {        //如果有就赋值        _offset.offsetTop = obj.offsetParent.offsetTop;    } else {        //没有就赋值0        _offset.offsetTop = 0;    }    json.offsetLeft = _offset.offsetLeft + json.offsetLeft;    json.offsetTop = _offset.offsetTop + json.offsetTop;    //如果 父亲层的左边距和上边距都为0 代表,没有边距了可以返回了    if (_offset.offsetTop == 0 && _offset.offsetLeft == 0) {        return json;    } else {        return U.UF.E.picture.parentOfferset(obj.offsetParent, json);    }}//#region 协同的处理/** word 消息类   * 参数一 : id 行id  * 参数二 :  type 操作类型* 参数三 : content 行内容* 参数四 : next 下一行*/U.UF.E.editInfo = function (id, content, next) {    var _data = {        id: id,  //操作ID        content: content,  //内容        nextId: next //下一行ID    };    return _data;};/** 协同的处理* @param e      {event}   event对象* @param e      {element}   编辑器对象*/U.UF.E.operationNotice = function (operaRecord, editor) {    var _opera = {}; //记录操作记录    //是否有添加行的处理    if (operaRecord.addLine) {        _opera.addLine = U.UF.E.addLineMessage(operaRecord.addLine, editor); //得到操作行的协同记录    }    //是否有修改行的处理    if (operaRecord.updateLine) {        _opera.updateLine = U.UF.E.updateLineMessage(operaRecord.updateLine, editor); //得到修改行的协同记录    }    //是否有删除行的处理    if (operaRecord.deleteLine) {        _opera.deleteLine = U.UF.E.deleteLineMessage(operaRecord.deleteLine, editor); //得到删除行的协同记录    }    //记录前进后退    U.UF.E.setRecord(operaRecord, editor);    //协同回调    if (U.UF.C.isFunction(editor.editor.operaNotice)) {        editor.editor.operaNotice(_opera);    }}/** 添加行* @param      {array}   添加行的对象* @param      {element}   编辑器对象*/U.UF.E.addLineMessage = function (array, edit) {    var _i,        _nextlineid,        _el,        _editinfo,        _message = []    ;    //循环添加行,获取数据    for (_i = 0; _i < array.length; _i++) {        _el = U.selectEl('#' + array[_i])[0]; //获取添加行的元素        _nextlineid = (_nextlineid = U.selectEl('#' + array[_i])[0].nextElementSibling) ? _nextlineid.id : null; //判断是否有下一行有返回id ,没有返回null        _editinfo = U.UF.E.editInfo(array[_i], _el.outerHTML, _nextlineid); //初始化word信息处理        _message.push(_editinfo);   //添加数据    }    return _message;};/** 修改行内容* @param      {array}   添加行的对象* @param      {element}   编辑器对象*/U.UF.E.updateLineMessage = function (array, edit) {    var _i,        _el,        _editinfo,        _message = [];    for (_i = 0; _i < array.length; _i++) {        _el = U.selectEl('#' + array[_i])[0]; //获取修改行的信息        _editinfo = U.UF.E.editInfo(array[_i], _el.outerHTML, null); //初始化word信息处理        _message.push(_editinfo);   //添加数据    }    return _message;};/** 删除行* @param      {array}   删除的行* @param      {element}   编辑器对象*/U.UF.E.deleteLineMessage = function (array, edit) {    var _i,        _editinfo,        _message = []    ;    for (_i = 0; _i < array.length; _i++) {        _editinfo = U.UF.E.editInfo(array[_i], "", null); //初始化word信息处理        _message.push(_editinfo);   //添加数据    }    return _message;};//#endregion//#region 前进后退方案/** 添加前进后退内容(当)* @param      {array}   添加行的对象* @param      {element}   编辑器对象*/U.UF.E.setRecord = function (opera, editor) {    if (editor.editor.isrecord && editor.editor.recordOpera && editor.editor.recordOpera.range) {        editor.editor.recordsEditor.splice(editor.editor.recordsEditorIndex, editor.editor.recordsEditor.length - editor.editor.recordsEditorIndex);        editor.editor.recordsEditorIndex = editor.editor.recordsEditor.length;        //插入记录        editor.editor.recordsEditor.push({            "opera": opera,            "recordLine": editor.editor.recordOpera        });        editor.editor.recordsEditorIndex++;        //重新记录        editor.editor.recordOpera = { "line": U.UF.E.key.getLineIdArr(editor) };        U.UF.E.recordRangeIndex(editor);    }    editor.editor.isrecord = true;}/** 记录光标位置和内容* @param      {array}   添加行的对象* @param      {element}   编辑器对象*/U.UF.E.recordRangeIndex = function (editor) {    //编辑器的光标处理    var _range = U.UF.E.getRangeAt(); //得到光标    if (_range) {        var _startel = U.UF.E.getLineElement(_range.startContainer), //开始行            _endel = U.UF.E.getLineElement(_range.endContainer) //结束行        ;        if (_startel && _endel) {            //开始和结束行的处理            editor.editor.recordOpera.range = {                "startid": _startel.id,                "endid": _endel.id,                "endOffset": _range.endOffset, //                "startOffset": _range.startOffset,                "start": U.UF.E.getElementByAncestorsIndex(_startel, _range.startContainer),                "end": U.UF.E.getElementByAncestorsIndex(_endel, _range.endContainer)            };        }    }}/** 记录* @param  {Element}   祖先元素* @param  {Element}   子元素*/U.UF.E.getElementByAncestorsIndex = function (el, childel) {    var i, j, _child, _cindex;    //获取开始位置的处理    if (el !== childel) {        _child = el.childNodes;        for (i = 0; i < _child.length; i++) {            //聚焦到子元素下的处理            if (_child[i] == childel) {                _cindex = i;                break;            }            //聚焦到子子元素的处理            else if (U.UF.EL.isChild(_child[i], childel)) {                _child = _child[i].childNodes;                //循环子元素得到位置                for (j = 0; j < _child.length; j++) {                    if (_child[j] == childel) {                        _cindex = [i, j];                        break;                    }                }            }        }    }    return _cindex;}/* 定义撤销(后退)函数* * @param e      {event}   event对象* @param editor {element} 编辑器对象* */U.UF.E.key.undo = function (e, editor) {    var i, j, k,        _info,        _operarecord = {},        _index = editor.editor.recordsEditorIndex - 1,        _record,        _line;    if (_index > -1 && editor.editor.recordsEditor.length >= _index) {        _record = editor.editor.recordsEditor[_index];        _line = _record.recordLine.line;        //如果存在记录        if (_record.recordLine) {            for (i in _record.opera) {                switch (i) {                    //添加行的处理,如果是                                                                                                                                                                                                                               case "addLine":                        //如果是后退添加行,那么直接删除                        for (j = 0; j < _record.opera[i].length; j++) {                            U.UF.E.deleteEditorLine(_record.opera[i][j]);                        }                        break;                    case "updateLine":                        //如果是后退添加行,那么直接删除                        for (j = 0; j < _record.opera[i].length; j++) {                            U.UF.E.updateEditorLine({ "id": _record.opera[i][j], "content": U.UF.E.getLineContentById(_line, _record.opera[i][j]) });                        }                        break;                    case "deleteLine":                        //如果是后退添加行,那么直接删除                        for (j = 0; j < _record.opera[i].length; j++) {                            _info = U.UF.E.getLineInfoById(_line, _record.opera[i][j]); //获取行信息                            U.UF.E.addEditorLine({ "nextId": _info.next ? _info.next.id : null, "content": _info.info.innerHTML }, editor); //删除后添加回信息                        }                        break;                }            }            U.UF.E.setRecordRange(_record.recordLine.range); //设置光标            //如果是最后的测回,那么添加一个可前进的记录            if (editor.editor.recordsEditor.length == _index + 1) {                U.UF.E.setRecord(_record.opera, editor); //重新记录            }            editor.editor.recordsEditorIndex--;            editor.editor.isrecord = false;        }    }    //取消浏览器默认事件    U.UF.EV.stopDefault();}/* 定义重做(前进)函数 * * @param e      {event}   event对象* @param editor {element} 编辑器对象* */U.UF.E.key.redo = function (e, editor) {    var i, j, k,        _info,        _operarecord = {},        _index = editor.editor.recordsEditorIndex,        _record,        _line;    if (_index > -1 && _index < editor.editor.recordsEditor.length) {        _record = editor.editor.recordsEditor[_index];        _line = _record.recordLine.line;        //如果存在记录        if (_record.recordLine) {            for (i in _record.opera) {                switch (i) {                    //添加行的处理,如果是                                                                                                                                                                                                                            case "addLine":                        //如果是后退添加行,那么直接删除                        for (j = 0; j < _record.opera[i].length; j++) {                            _info = U.UF.E.getLineInfoById(_line, _record.opera[i][j]); //获取行信息                            U.UF.E.addEditorLine({ "nextId": _info.next ? _info.next.id : null, "content": _info.info.innerHTML }, editor); //删除后添加回信息                        }                        break;                    case "updateLine":                        //如果是后退添加行,那么直接删除                        for (j = 0; j < _record.opera[i].length; j++) {                            U.UF.E.updateEditorLine({ "id": _record.opera[i][j], "content": U.UF.E.getLineContentById(_line, _record.opera[i][j]) });                        }                        break;                    case "deleteLine":                        //如果是后退添加行,那么直接删除                        for (j = 0; j < _record.opera[i].length; j++) {                            U.UF.E.deleteEditorLine(_record.opera[i][j]);                        }                        break;                }            }            U.UF.E.setRecordRange(_record.recordLine.range); //设置光标            editor.editor.isrecord = false;            editor.editor.recordsEditorIndex++;        }    }    //取消浏览器默认事件    U.UF.EV.stopDefault();}/* 光标聚焦* * @param e      {object}   自定义光标对象*/U.UF.E.setRecordRange = function (range) {    var _startel,        _start,        _endel,        _end;    //光标开始位置和开始元素的处理    if (range.startid && U.selectEl("#" + range.startid)[0]) {        _start = range.startOffset; //开始位置        //开始元素的获取        if (range.start.length) { //如果是#text标签的处理            _startel = U.selectEl("#" + range.startid)[0].childNodes[range.start[0]].childNodes[range.start[1]];        }        else { //如果是span标签的处理            _startel = U.selectEl("#" + range.startid)[0].childNodes[range.start];        }    }    //光标结束位置的处理    if (range.endid && U.selectEl("#" + range.endid)[0]) {        _end = range.endOffset; //结束的位置        //结束元素的获取        if (range.start.length) { //如果是#text标签的处理            _endel = U.selectEl("#" + range.endid)[0].childNodes[range.end[0]].childNodes[range.end[1]];        }        else {//如果是span标签的处理            _endel = U.selectEl("#" + range.endid)[0].childNodes[range.end];        }    }    //选择光区聚焦    U.UF.E.setRange(_startel, _endel, _start, _end)}/* 设置记录内容* * @param e      {event}   event对象* @param editor {element} 编辑器对象*/U.UF.E.getLineContentById = function (line, id) {    for (var i = 0; i < line.length; i++) {        if (line[i].id == id) {            return line[i].innerHTML;        }    }    return "";}/* 获取行信息* * @param e      {array}   行数组* @param editor {string} id*/U.UF.E.getLineInfoById = function (line, id) {    for (var i = 0; i < line.length; i++) {        if (line[i].id == id) {            return { "pre": line[i - 1], "next": line[i + 1], "info": line[i] }        }    }    return null;}/**  根据操作记录撤回或者前进修改信息* @param      {object}   操作的行*/U.UF.E.updateEditorLine = function (opera) {    //判断修改的元素是否存在    if ($('#' + opera.id)[0]) {        U.selectEl('#' + opera.id)[0].outerHTML = opera.content;    }    else {        console.log('updateError', opera.id);    }};/**  根据操作记录撤回或者前进删除信息* @param   {object}   操作的行*/U.UF.E.deleteEditorLine = function (opera) {    //删除行的处理    U.selectEl('#' + opera.id).remove();};/** 根据操作记录撤回或者前进添加信息* @param   {object}   操作的行* @param   {element}  编辑器元素*/U.UF.E.addEditorLine = function (opera, editor) {    editor = editor || U.selectEl('#U_MD_O_H_wordEditor')[0]; //    var _next,        _line = $$("div", {}, editor);    //判断有没有nextid,nextid是否存在    if (opera.nextId && (_next = U.selectEl('#' + opera.nextId))[0]) {        _next.Parent().insertBefore(_line, _next[0]); //有的话插入在nexid 元素前    }    U.selectEl(_line)[0].outerHTML = opera.content; //替换内容}//#endregion
 |