MWF.xDesktop.requireApp("process.Xform", "$Module", null, false); /** @class Htmleditor HTML编辑器。 * @o2cn HTML编辑器 * @example * //可以在脚本中获取该组件 * //方法1: * var htmlEditor = this.form.get("name"); //获取组件 * //方法2 * var htmlEditor = this.target; //在组件事件脚本中获取 * @extends MWF.xApplication.process.Xform.$Module * @o2category FormComponents * @o2range {Process|CMS} * @hideconstructor */ MWF.xApplication.process.Xform.Htmleditor = MWF.APPHtmleditor = new Class( /** @lends MWF.xApplication.process.Xform.Htmleditor# */ { Extends: MWF.APP$Module, options: { /** * 组件异步加载后触发. * @event MWF.xApplication.process.Xform.Htmleditor#afterLoad * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明} */ "moduleEvents": ["queryLoad", "load", "postLoad", "afterLoad"] }, initialize: function(node, json, form, options){ this.node = $(node); this.node.store("module", this); this.json = json; this.form = form; this.field = true; this.fieldModuleLoaded = false; }, load: function(){ this._loadModuleEvents(); if (this.fireEvent("queryLoad")){ this._queryLoaded(); this._loadUserInterface(); this._loadStyles(); //this._loadEvents(); this._afterLoaded(); this.fireEvent("postLoad"); this.fireEvent("load"); } }, _loadUserInterface: function(){ this.node.empty(); if (this.isReadonly()){ // this.node.set("html", this._getBusinessData()); this.node.setStyles({ "-webkit-user-select": "text", "-moz-user-select": "text" }); if( layout.mobile ){ this.loadLazyImage(function () { //图片懒加载 var images = this.node.getElements("img"); //移动端设置图片宽度为100% images.each( function( img ){ if( img.hasClass("lozad") ){ img.setStyles({ "max-width" : "100%" }); }else{ img.setStyles({ "height": "auto", "max-width" : "100%" }); } }.bind(this)); this.fireEvent("afterLoad"); this.fieldModuleLoaded = true; }.bind(this)) }else{ this.loadLazyImage(function () { //图片懒加载 if(this.json.enablePreview !== "n"){ this.loadImageViewer(); //PC端点击显示大图 this.fireEvent("afterLoad"); this.fieldModuleLoaded = true; } }.bind(this)); } this.node.loadCss("../o2_lib/htmleditor/ckeditor4161/contents_o2.css"); }else{ var config = Object.clone(this.json.editorProperties); if (this.json.config){ if (this.json.config.code){ var obj = this.form.Macro.exec(this.json.config.code, this); Object.each(obj, function(v, k){ config[k] = v; }); } } this.loadCkeditor(config); } // this._loadValue(); }, loadLazyImage: function(callback){ o2.require("o2.widget.ImageLazyLoader", function(){ var loadder = new o2.widget.ImageLazyLoader(this.node, this._getBusinessData()); loadder.load(function(){ if(callback)callback(); }.bind(this)) }.bind(this)); }, loadImageViewer: function(){ o2.require("o2.widget.ImageViewer", function(){ var imageViewer = new o2.widget.ImageViewer(this.node); imageViewer.load(); }.bind(this)); }, loadCkeditor: function(config){ COMMON.AjaxModule.loadDom("ckeditor", function(){ CKEDITOR.disableAutoInline = true; var editorDiv = new Element("div").inject(this.node); var htmlData = this._getBusinessData(); if (htmlData){ editorDiv.set("html", htmlData); }else if (this.json.templateCode){ editorDiv.set("html", this.json.templateCode); } var height = this.node.getSize().y; var editorConfig = config || {}; if (this.form.json.mode==="Mobile"){ if (!editorConfig.toolbar && !editorConfig.toolbarGroups){ editorConfig.toolbar = [ { name: 'paragraph', items: [ 'Bold', 'Italic', "-" , 'TextColor', "BGColor", 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', "-", 'Undo', 'Redo' ] }, { name: 'basicstyles', items: [ 'Styles', 'FontSize']}, { name: 'insert', items : [ 'Image' ] } ]; } } editorConfig.base64Encode = !layout.mobile && (this.json.base64Encode === "y"); editorConfig.enablePreview = (this.json.enablePreview !== "n"); editorConfig.localImageMaxWidth = 2000; if(this.form.options.macro === "PageContext"){ editorConfig.reference = this.form.json.id; editorConfig.referenceType = "portalPage"; }else{ editorConfig.reference = this.form.businessData.work.job; editorConfig.referenceType = "processPlatformJob"; } if( editorConfig && editorConfig.extraPlugins ){ var extraPlugins = editorConfig.extraPlugins; extraPlugins = typeOf( extraPlugins ) === "array" ? extraPlugins : extraPlugins.split(","); extraPlugins.push( 'lineheight' ); extraPlugins.push( 'pagebreak' ); extraPlugins.push( 'o2image' ); extraPlugins.push( 'o2uploadimage' ); extraPlugins.push('o2uploadremoteimage'); editorConfig.extraPlugins = extraPlugins; }else{ editorConfig.extraPlugins = ['lineheight','pagebreak', 'o2image','o2uploadimage', 'o2uploadremoteimage']; } if( editorConfig && editorConfig.removePlugins ){ var removePlugins = editorConfig.removePlugins; removePlugins = typeOf( removePlugins ) === "array" ? removePlugins : removePlugins.split(","); editorConfig.removePlugins = removePlugins.concat(['image','easyimage','exportpdf','cloudservices']); }else{ editorConfig.removePlugins = ['image','easyimage','exportpdf','cloudservices']; } // CKEDITOR.basePath = COMMON.contentPath+"/res/framework/htmleditor/ckeditor/"; // CKEDITOR.plugins.basePath = COMMON.contentPath+"/res/framework/htmleditor/ckeditor/plugins/"; this.editor = CKEDITOR.replace(editorDiv, editorConfig); this.editor.addCommand("ecnet", { exec:function(editor){ this.ecnet(); }.bind(this) }); this.editor.ui.add('ecnet', CKEDITOR.UI_BUTTON, { label:MWF.xApplication.process.Xform.LP.intelligentCorrection, icon: '/x_component_process_Xform/$Form/default/icon/ecnet.png', command:"ecnet" }); this._loadEvents(); //this.editor.on("loaded", function(){ // this._loadEvents(); //}.bind(this)); //this.setData(data) this.editor.on("change", function(){ //this._setBusinessData(this.getData()); //在数据模板和数据表格中时 if( this.parentLine )this._setBusinessData(this.getData()); }.bind(this)); if (this.json.ecnet==="y"){ // this.editor.on( "key", function( evt ) { // // var char = evt.data.domEvent.$.char; // // if ([".", ",", "?", ";", "'", " "].indexOf(char)!==-1){ // // this.ecnet(evt.editor.getData()); // // } // }.bind(this)); // this.editor.on("blur", function(){ // if (!this.notEcnetFlag) this.ecnet(this.getData()); // }.bind(this)); } this.fireEvent("afterLoad"); this.fieldModuleLoaded = true; // this._loadEvents(); }.bind(this)); }, getEcnetString: function(node, nodes){ for (var i=0; inode.end+increment) e = node.end+increment; var length = html.length; var left = html.substring(0, s); var ecnetStr = html.substring(s, e); var right = html.substring(e, html.length); html = left+""+ecnetStr+""+right; increment += (html.length-length); }.bind(this)); newNode.innerHTML = html; node.pnode.replaceChild(newNode, node.node); node.pnode.textNode = node.node; node.pnode.ecnetNode = newNode; var _self = this; var editorFrame = this.editor.document.$.defaultView.frameElement; var spans = newNode.getElementsByTagName("span"); if (spans.length){ for (var i = 0; i"+node.ecnets[i].correct, "events": { "mouseover": function(){this.setStyle("background-color", "#dddddd")}, "mouseout": function(){this.setStyle("background-color", "#ffffff")}, "mousedown": function(){ var ecnetNode = this.getParent(); var node = ecnetNode.node; var item = ecnetNode.node.ecnets[ecnetNode.idx]; var textNode = node.node.ownerDocument.createTextNode(item.correct); ecnetNode.span.parentNode.replaceChild(textNode, ecnetNode.span); ecnetNode.destroy(); node.node.nodeValue = node.pnode.ecnetNode.innerText; node.ecnets.erase(item); if (!node.ecnets.length){ _self.ecnetNodes.erase(node); } } } }).inject(ecnetNode); var ignoreNode = new Element("div", { "styles": { "padding": "3px 10px", "font-size": "12px", "cursor": "pointer" }, "text": MWF.xApplication.process.Xform.LP.ignore, "events": { "mouseover": function(){this.setStyle("background-color", "#dddddd")}, "mouseout": function(){this.setStyle("background-color", "#ffffff")}, "mousedown": function(){ var ecnetNode = this.getParent(); var node = ecnetNode.node; var item = ecnetNode.node.ecnets[ecnetNode.idx]; var textNode = node.node.ownerDocument.createTextNode(ecnetNode.span.innerText); ecnetNode.span.parentNode.replaceChild(textNode, ecnetNode.span); ecnetNode.destroy(); node.node.nodeValue = node.pnode.ecnetNode.innerText; node.ecnets.erase(item); if (!node.ecnets.length){ _self.ecnetNodes.erase(node); } } } }).inject(ecnetNode); ecnetNode.node = node; ecnetNode.idx = i; span.ecnetNode = ecnetNode; ecnetNode.span = span; span.addEventListener("click", function(){ var ecnetNode = this.ecnetNode; ecnetNode.show(); var y = this.offsetTop; var x = this.offsetLeft; var w = this.offsetWidth; var h = this.offsetHeight; var p = editorFrame.getPosition(); var s = ecnetNode.getSize(); var top = y+p.y+h+5; var left = x+p.x-((s.x-w)/2); ecnetNode.style.left = ""+left+"px"; ecnetNode.style.top = ""+top+"px"; var _span = this; var hideEcnetNode = function(){ ecnetNode.hide(); _span.ownerDocument.removeEventListener("mousedown", hideEcnetNode); }; this.ownerDocument.addEventListener("mousedown", hideEcnetNode); }); } } } //node.pnode.ecnetInforNode = ecnetNode; // var spans = newNode.getElementsByTagName("span"); // if (spans.length){ // var span = spans[0]; // span.addEventListener("click", function(){ // ecnetNode.style.display = "block"; // var y = span.offsetTop; // var x = span.offsetLeft; // var w = span.offsetWidth; // var h = span.offsetHeight; // var p = editorFrame.getPosition(); // var s = ecnetNode.getSize(); // var top = y+p.y+h+5; // var left = x+p.x-((s.x-w)/2); // // ecnetNode.style.left = ""+left+"px"; // ecnetNode.style.top = ""+top+"px"; // }); // span.addEventListener("mouseout", function(){}); // } }, clearEcnetNodes: function(){ if (this.ecnetNodes && this.ecnetNodes.length){ this.ecnetNodes.each(function(node){ if (node.pnode.ecnetNode){ if (node.pnode.ecnetInforNode) node.pnode.ecnetInforNode.destroy(); node.pnode.ecnetInforNode = null; node.pnode.replaceChild(node.pnode.textNode, node.pnode.ecnetNode); } }.bind(this)); this.ecnetNodes = []; } }, ecnet: function(data){ //this.editor.document.$.body.innerText var editorFrame = this.editor.document.$.defaultView.frameElement; //var data = this.editor.getData(); var body = this.editor.document.$.body; if (!this.ecnetNodes) this.ecnetNodes = []; if (this.ecnetNodes.length) this.clearEcnetNodes(); var nodes = []; this.ecnetString = ""; this.getEcnetString(body, nodes); MWF.Actions.get("x_general_assemble_control").ecnetCheck({"value": this.ecnetString}, function(json){ if (json.data.itemList && json.data.itemList.length){ nodes.each(function(node){ var items = []; json.data.itemList.each(function(item){ if ((node.end<=item.end && node.end>item.begin) || (node.start>=item.begin && node.startitem.end)){ items.push(item); } }.bind(this)); if (items.length){ node.ecnets = items; this.ecnetNodes.push(node); } }.bind(this)); this.ecnetNodes.each(function(node){ this.createEcnetNode(node); }.bind(this)); // var item = json.data.itemList[0]; // var left = data.substring(0, item.begin); // var ecnetStr = data.substring(item.begin, item.end); // var right = data.substring(item.end, data.length); // // var newData = left+""+ecnetStr+""+right; //this.editor.document.$.body.setSelectionRange(item.begin, item.end); //this.editor.setData(newData); // var iframe = editorFrame.clone(); // iframe.inject(this.node); // iframe.position({ // "relativeTo": editorFrame, // "position": 'upperLeft', // "edge": 'upperLeft' // }); // iframe.contentWindow.document.body.set("html", newData); }else{ body = null; nodes = null; } }.bind(this)); }, _loadEvents: function(editorConfig){ Object.each(this.json.events, function(e, key){ if (e.code){ this.editor.on(key, function(event){ return this.form.Macro.fire(e.code, this, event); }.bind(this), this); } }.bind(this)); }, addModuleEvent: function(key, fun){ this.editor.on(key, function(event){ return (fun) ? fun(this, event) : null; }.bind(this), this); }, _loadValue: function(){ var data = this._getBusinessData(); }, // /** // * @summary 重置组件的值为默认值或置空。 // * @example // * this.form.get('fieldId').resetData(); // */ resetData: function(){ this.setData(this._getBusinessData()); }, /** * @summary 判断组件值是否为空. * @example * if( this.form.get('fieldId').isEmpty() ){ * this.form.notice('HTML编辑器不能为空', 'warn'); * } * @return {Boolean} 值是否为空. */ isEmpty : function(){ return !this.getData().trim(); }, /** * 当表单上没有对应组件的时候,可以使用this.data[fieldId]获取值,但是this.form.get('fieldId')无法获取到组件。 * @summary 获取组件值。 * @example * var data = this.form.get('fieldId').getData(); * @example * //如果无法确定表单上是否有组件,需要判断 * var data; * if( this.form.get('fieldId') ){ //判断表单是否有无对应组件 * data = this.form.get('fieldId').getData(); * }else{ * data = this.data['fieldId']; //直接从数据中获取字段值 * } * @return 组件的数据. */ getData: function(){ this.clearEcnetNodes(); return this.editor ? this.editor.getData() : this._getBusinessData(); }, /** * 当表单上没有对应组件的时候,可以使用this.data[fieldId] = data赋值。 * @summary 为组件赋值。 * @param data{String} . * @example * this.form.get("fieldId").setData("test"); //赋文本值 * @example * //如果无法确定表单上是否有组件,需要判断 * if( this.form.get('fieldId') ){ //判断表单是否有无对应组件 * this.form.get('fieldId').setData( data ); * }else{ * this.data['fieldId'] = data; * } */ setData: function(data){ this._setBusinessData(data); if (this.editor) this.editor.setData(data); }, destroy: function(){ if( this.editor )this.editor.destroy(); }, createErrorNode: function(text){ var node = new Element("div"); var iconNode = new Element("div", { "styles": { "width": "20px", "height": "20px", "float": "left", "background": "url("+"../x_component_process_Xform/$Form/default/icon/error.png) center center no-repeat" } }).inject(node); var textNode = new Element("div", { "styles": { "line-height": "20px", "margin-left": "20px", "color": "red", "word-break": "keep-all" }, "text": text }).inject(node); return node; }, notValidationMode: function(text){ if (!this.isNotValidationMode){ this.isNotValidationMode = true; this.node.store("borderStyle", this.node.getStyles("border-left", "border-right", "border-top", "border-bottom")); this.node.setStyle("border", "1px solid red"); this.errNode = this.createErrorNode(text).inject(this.node, "after"); this.showNotValidationMode(this.node); if (!this.errNode.isIntoView()) this.errNode.scrollIntoView(false); } }, showNotValidationMode: function(node){ var p = node.getParent("div"); if (p){ if (p.get("MWFtype") == "tab$Content"){ if (p.getParent("div").getStyle("display")=="none"){ var contentAreaNode = p.getParent("div").getParent("div"); var tabAreaNode = contentAreaNode.getPrevious("div"); var idx = contentAreaNode.getChildren().indexOf(p.getParent("div")); var tabNode = tabAreaNode.getLast().getFirst().getChildren()[idx]; tabNode.click(); p = tabAreaNode.getParent("div"); } } this.showNotValidationMode(p); } }, validationMode: function(){ if (this.isNotValidationMode){ this.isNotValidationMode = false; this.node.setStyles(this.node.retrieve("borderStyle")); if (this.errNode){ this.errNode.destroy(); this.errNode = null; } } }, validationConfigItem: function(routeName, data){ var flag = (data.status=="all") ? true: (routeName == data.decision); if (flag){ var n = this.getData(); var v = (data.valueType=="value") ? n : n.length; switch (data.operateor){ case "isnull": if (!v){ this.notValidationMode(data.prompt); return false; } break; case "notnull": if (v){ this.notValidationMode(data.prompt); return false; } break; case "gt": if (v>data.value){ this.notValidationMode(data.prompt); return false; } break; case "lt": if (v"); //excel字段换行是 this.excelData = data; this.setData(data, true); }, validationExcel: function () { if (!this.isReadonly()){ var errorList = this.validationConfigExcel(); if (errorList.length) return errorList; if (!this.json.validation) return []; if (!this.json.validation.code) return []; var flag = this.form.Macro.exec(this.json.validation.code, this); if (!flag) flag = MWF.xApplication.process.Xform.LP.notValidation; if (flag.toString() !== "true") { return [flag]; } } return []; }, validationConfigExcel: function () { var errorList = []; if (this.json.validationConfig){ if (this.json.validationConfig.length){ for (var i=0; idata.value)return data.prompt; break; case "lt": if (v