import {parseYvanPropChangeVJson} from '../../CtlUtils' import webix from 'webix' import _ from 'lodash' import {CtlBase} from "../../CtlBase"; import {CtlInput} from "./CtlInput"; import {CtlEditorDefault} from "../../CtlDefaultValue"; import {YvEventDispatch} from "../../YvanEvent"; webix.protoUI( { name: 'editor', defaults: {}, $init: function (config: any) { this.$view.innerHTML = `` this.$ready.push(this._ready) _.extend(this.config, config) if (config.on && typeof config.on.onInited === 'function') { config.on.onInited.call(this) } }, _ready: function (this: any) { }, _set_inner_size: function () { }, _updateScrollSize: function () { }, $setSize: function (x: any, y: any) { if (webix.ui.view.prototype.$setSize.call(this, x, y)) { this._set_inner_size() } } }, webix.ui.view ) export interface DataType { id: string, name: string, objectType?: DataType[] arrayType?: DataType[] } export class CtlEditor extends CtlInput { editor: any = null static create(module: any, vjson: any): CtlEditor { const that = new CtlEditor(vjson) that._module = module _.defaultsDeep(vjson, CtlEditorDefault) const yvanProp = parseYvanPropChangeVJson(vjson, ['value', 'width', 'height', 'uploadPath', 'savePath', 'filePostName', "linkedData", "paramDataType"]) // 将 vjson 存至 _webixConfig that._webixConfig = vjson // 将 yvanProp 合并至当前 Ctl 对象, 期间会操作 _webixConfig _.assign(that, yvanProp) // 将 事件与 _webixConfig 一起存至 vjson 交给 webix 框架做渲染 _.merge(vjson, that._webixConfig, { on: { onInited(this: any) { that.attachHandle(this, {...vjson, ...yvanProp}) _.defer(() => { that.renderEditor() }) }, onAfterDelete() { that.removeHandle() } } }) return that } renderEditor() { const editor = this._webix.$view.getElementsByTagName('textarea')[0] const me = this; // @ts-ignore KindEditor.ready(function (K) { me.editor = K.create(editor, { handle: me, items : [ 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', //'multiimage', 'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak', 'anchor', 'link', 'unlink', '|', 'custominsert', 'replaceparam' ], paramDataType: me.paramDataType, width: editor.parentElement.style.width, height: editor.parentElement.style.height, uploadJson: me.uploadPath, filePostName: me.filePostName, fileManagerJson: me.savePath, allowFileManager: true, afterCreate: function () { if (me.vjson.afterCreate) { YvEventDispatch(me.vjson.afterCreate, editor, null); } } }); me.editor.html(me._value); }); } // 替换文本域 replaceparam() { if (this.isOriginal === true) { this._originalEditorHtml = this.editor.html(); const container = this.editor.container[0].getElementsByTagName("iframe")[0].contentWindow.document.body this.listParamInfoList = []; this.objectParamInfoList = []; this.getParam(container.innerText); for (let i = 0; i < this.listParamInfoList.length; i++) { const el = this.listParamInfoList[i]; const elements = $(container).find(":contains("+el.listPath+"[index])"); _.set(el, "node", elements); for (let j = 0; j < elements.length; j++) { const element = elements[j]; if (_.toUpper(element.tagName) === "TBODY") { let find = false; for (let n = 0; n < el.tables.length; n++) { if (el.tables[n].table === element) { find=true; break; } } if (find === false) { el.tables.push({table: element}) } } if (_.toUpper(element.tagName) === "TR") { let find = false; let t = null; for (let n = 0; n < el.tables.length; n++) { if (el.tables[n].table === element.parentElement && el.tables[n].paramRow === element) { find=true; break; } t = el.tables[n]; } if (find === false) { if (t && element.parentElement == t.table) { t.paramRow = element; } } } } } for (let i = 0; i < this.objectParamInfoList.length; i++) { const el: {param: string} = this.objectParamInfoList[i]; _.set(el, "node", $(container).find(":contains("+el.param+")")); } /** 替换object数据 */ for (let i = 0; i < this.objectParamInfoList.length; i++) { const el = this.objectParamInfoList[i]; const path = el.param.substring(3,el.param.length-2); if (el.node) { for(let j = el.node.length - 1; j >= 0; j--) { const node = el.node[j]; if (node.innerText.indexOf(el.param) >= 0) { // @ts-ignore node.innerHTML = node.innerHTML.replaceAll(el.param, _.get(this._linkedData, path)); } } } } /** 替换list数据 */ for (let i = 0; i < this.listParamInfoList.length; i++) { const el = this.listParamInfoList[i]; const listData: any[] = _.get(this._linkedData, el.listPath); for (let m = 0; m < el.tables.length; m++) { let nel = _.cloneDeep(el.tables[m].paramRow?.outerHTML); for (let n = 0; n < listData.length; n++) { if (nel) { let nelT = _.cloneDeep(nel); for (let x = 0; x < el.subPath.length; x++) { // @ts-ignore nelT = nelT.replaceAll("${{"+el.listPath+"[index]" + el.subPath[x]+"}}", _.get(this._linkedData, el.listPath+"["+n+"]" + el.subPath[x])) } const objE = document.createElement("tbody"); objE.innerHTML = nelT||""; el.tables[m].table?.append(objE.children[0]); } if (el.tables[m].table && el.tables[m].paramRow) { // @ts-ignore el.tables[m].table.removeChild(el.tables[m].paramRow); delete el.tables[m].paramRow } } } } this.isOriginal = false; // this.editor.readonly(true); } else { this.isOriginal = true; this.editor.html(this._originalEditorHtml); // this.editor.readonly(false); } } // 获取文本域 getParam(content: string, startIndex: number = 0, isOpened: boolean = false) { const index = content.indexOf(isOpened?"}}":"${{", startIndex); if (index < 0) { return } else { if (isOpened) { let param = content.substring(startIndex, index + 2); let listTagIndex = param.indexOf("[index]") if (listTagIndex > 0) { const listPath = param.substring(3, listTagIndex); const subPath = param.substring(listTagIndex+7, param.length-2); let has = false; for (let i = 0; i | null }[] = []; /** 记录文本域object表达式 */ private objectParamInfoList: { node: JQuery | null, param: string }[] = []; /** 文本域参数类型 */ private _paramDataType: DataType[] = []; }