Zhiqim UI是一套集成Javascript库、Css库、Font库、常用ico图标等,并在其上开发的大量UI组件组成的前端开发套件。
森中灵 最后提交于3月前 整理V8.0.6
zhiqim_text_editor.js66KB
/*
* 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙,邂逅框架梦]
*
* https://zhiqim.org/project/zhiqim_framework/zhiqim_ui.htm
*
* Zhiqim UI is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/************************************************************************/
//富文本编辑器,属性和方法
/************************************************************************/
// 1、配置方式,var editor = new Z.TextEditor();
// 2、属性设置 editor.set***("value");;或者 editor.*** = "value";
// 3、支持的参数值
// 1)id 表示初始化的编辑器对象,<textarea>的id
// 2)tools 表示工具菜单,定义格式为数组:[];“|”表示分割标签;“allTools”为可用参数值;“defaultTools”为默认值
// 3)fontFamily 表示“字体”可选项,定义格式为数组:[];“allFamilies”为可用参数值;“defaultFamily”为默认值
// 4)fontSize 表示“字号”可选项,定义格式为数组:[];
// 4、举例如下:
// <div>
// <textarea id="test"></textarea>
// </div>
// Z.onload(function()
// {
// var editor = new Z.TextEditor();
// editor.setId("test");
// editor.setFontSize([12,13,16,18,24,32,48]);
// editor.execute();
// }
//============待解决的问题:===============【2017-10-26】更新
// 1)精简、排版代码;不需要的功能、方法进行剔除
// 1)自定义上标(superscript)、下标(subscript)的实现:
// 1)字体大小修改时,格式统一
// 1)回车换行,统一换行格式;<pre><code>标签下回车的特殊处理;方法:doNewline
// 2)定位光标;方法:saveHistory、loadHistory
// 3)
//
//============可能存在的问题:===============【2017-10-20】更新
// 1)浏览器兼容:用execcommand实现对齐方式;方法:tool_justify****、doCommandMain
// 2)浏览器兼容:有序列表(insertorderedlist)、无序列表(insertunorderedlist)在换行无内容执行时,执行对象不同
// 3)
// 参考网址
//https://developer.mozilla.org/zh-CN/docs/Web/API/Document/execCommand
+(function(F)
{
/***********************************************************************************************/
//静态参数定义
/***********************************************************************************************/
var defaultFamily = ["宋体","微软雅黑","楷体","黑体","隶体","andale mono","arial","arial black","comic sans ms","impact","times new roman","sans-serif"];
var defaultTools = ["html","|","undo","redo","|","bold","italic","underline","|","superscript","subscript","|",
"foreColor","backColor","|","removeFormat","|","insertorderedlist","insertunorderedlist","|","selectAll","clearAll",
"paragraph","fontName","fontSize","|","justifyLeft","justifyCenter","justifyRight","|","createLink","unlink","|","insertImage","symbol"];
var allFamilies = [
"宋体,SimSun", //01
"微软雅黑,Microsoft YaHei", //02
"楷体,楷体_GB2312, SimKai", //03
"黑体,SimHei", //04
"隶书,SimLi", //05
"andale mono", //06
"arial, helvetica,sans-serif", //07
"arial black,avant garde", //08
"comic sans ms", //09
"impact,chicago", //10
"times new roman", //11
"sans-serif", //12
];
var allTools = [
{attr:"html",title:"源码",font:"sourcecode"}, //01
{attr:"undo",title:"撤销",font:"undo"}, //02
{attr:"redo",title:"重做",font:"redo"}, //03
{attr:"bold",title:"加粗",font:"bold"}, //04
{attr:"italic",title:"斜体",font:"italic"}, //05
{attr:"underline",title:"下划线",font:"underline"}, //06
{attr:"strikethrough",title:"删除线",font:"strikethrough"}, //07
{attr:"superscript",title:"上标",font:"superscript"}, //08
{attr:"subscript",title:"下标",font:"subscript"}, //09
{attr:"foreColor",title:"字体颜色",font:"fontcolor"}, //10
{attr:"backColor",title:"背景颜色",font:"background"}, //11
{attr:"removeFormat",title:"清除格式",font:"clearformat"}, //12
{attr:"insertorderedlist",title:"有序列表",font:"orderedlist"}, //13
{attr:"insertunorderedlist",title:"无序列表",font:"unorderedlist"}, //14
{attr:"selectAll",title:"全选",font:"selectall"}, //15
{attr:"clearAll",title:"清空",font:"clearall"}, //16
{attr:"paragraph",title:"段落格式"}, //17
{attr:"fontName",title:"字体"}, //18
{attr:"fontSize",title:"字号"}, //19
{attr:"justifyLeft",title:"左对齐",font:"alignleft"}, //20
{attr:"justifyCenter",title:"居中",font:"aligncenter"}, //21
{attr:"justifyRight",title:"右对齐",font:"alignright"}, //22
{attr:"createLink",title:"超链接",font:"hyperlink"}, //23
{attr:"unlink",title:"取消超链接",font:"unhyperlink"}, //24
{attr:"insertImage",title:"图片",font:"image"}, //25
{attr:"symbol",title:"特殊符号",font:"symbol"}, //26
];
var paragraph = ["p","h1","h2","h3","h4","h5","h6",];
//特殊字符
var symbolObj = {};
symbolObj.math = ["¼","½","¾","⅐","⅑","⅒","⅓","⅔","⅕","⅖","⅗","⅘","⅙","⅚","⅛","⅜","⅝","⅞","﹢","﹣","×","÷","±","=","≡","≠","≤","≦","≥","≧","√","✕","%","‰","‱","⊥","π","∑","℃","℉","㎎","㎏","㎜","㎝","㎞","㎡","㏄","㏎","°"];
symbolObj.index = ["←","↑","→","↓","⇠","⇡","⇢","⇣","↚","↛","⇄","⇆","⇋","⇌","⇎","⇍","⇏","Ⅰ","Ⅱ","Ⅲ","Ⅳ","Ⅴ","Ⅵ","Ⅶ","Ⅷ","Ⅸ","Ⅹ","ⅰ","ⅱ","ⅲ","ⅳ","ⅴ","ⅵ","ⅶ","ⅷ","ⅸ","ⅹ","⓪","①","②","③","④","⑤","⑥","⑦","⑧","⑨","⑩","⓿","❶","❷","❸","❹","❺","❻","❼","❽","❾","❿","㊀","㊁","㊂","㊃","㊄","㊅","㊆","㊇","㊈","㊉"];
symbolObj.language = ["α","β","χ","δ","ε","η","γ","ι","κ","λ","μ","ν","ω","ο","φ","π","ψ","ρ","σ","τ","θ","υ","ξ","ζ","á","â","æ","à","å","ã","ä","ç","é","ê","è","ð","ë","í","î","ì","ñ","ó","ô","ò","ø","õ","ö","ß","þ","ú","û","ü","ý","ÿ","㊎","㊍","㊌","㊋","㊏","㊤","㊦","㊧","㊨","㊥","㊚","㊛","㊐","㊰"];
symbolObj.other = ["★","☆","✦","✧","✡","✪","✯","♡","♢","♤","♧","♥","♦","♠","♣","☐","☑","☒","⁂","☸","✱","✿","❀","❃","⌚","☎","☏","✂","✄","✈","✉","✎","☀","☁","☂","☃","☼","☽","☾","♨","❄","☚","☛","☜","☞","☟","♩","♪","♫","♬","♭","♮"];
/***********************************************************************************************/
//编辑器定义开始
/***********************************************************************************************/
Z.TextEditor = Z.Class.newInstance();
Z.TextEditor.AJAX_CLASS = "org.zhiqim.httpd.context.service.UploadService";
Z.TextEditor.AJAX_UPLOAD = "upload";
Z.TextEditor.AJAX_UPLOADWWW = "uploadwww";
Z.TextEditor.prototype =
{
defaults:
{
id: null,
contextPath: null,
origin: true,
fileDir : "",
maxSize: 0,
tools: null,
fontFamily: null,
fontSize: [12,13,16,18,24,32,48]
},
setId: function(id){this.id = id;return this;},
setContextPath(contextPath){this.contextPath = contextPath;return this;},
setOriginFalse: function(origin){this.origin = false;return this;},
setFileDir: function(fileDir){this.fileDir = fileDir;return this;},
setMaxSize: function(maxSize){this.maxSize = maxSize;return this;},
setTools: function(tools){this.tools = tools;return this;},
setFontFamily: function(fontFamily){this.fontFamily = fontFamily;return this},
setFontSize: function(fontSize){this.fontSize = fontSize;return this;},
setZUIFix: function(){this.$editor.addClass("ZUI-fix");return this;},
/***********************************************************************************************/
//初始化函数 & 执行函数
/***********************************************************************************************/
init: function()
{
//dialog用到的插入HTML字符串集合
this.dialogHtml = {}
//功能按钮对象
this.$$tools = {};
//定义容器
this.$container = Z('<div class="zte-container"></div>');
this.$toolbar = Z('<div class="zte-toolbar"></div>');
this.$buttonBar = Z('<div class="zte-btn-toolbar"></div>');
this.$dialogContainer = Z('<div class="zte-dialog-container"></div>');
this.$editor = Z('<div class="zte-editor" contenteditable="true" spellcheck="false"></div>');
this.$zoomToolWrap = Z('<div class="zte-zoomTool-wrap"></div>');
this.$zoomToolCover = Z('<div class="zte-zoomTool-cover"><div class="zte-zoomTool-e"></div><div class="zte-zoomTool-se"></div><div class="zte-zoomTool-s"></div></div>');
//颜色选择器
this.$$colorPicker = [];
},
execute: function()
{
/******************************************************************/
//1、检查属性
/******************************************************************/
/* 上传最大值限制 */
if (this.maxSize)
this.maxSize = this.maxSize * 1024 * 1024;
else
this.maxSize = Infinity;
/*如果没有自定义菜单,则赋值为默认菜单*/
if (this.tools == null)
this.tools = defaultTools;
/*如果没有自定义字体,则赋值为默认字体*/
if (this.fontFamily == null)
this.fontFamily = defaultFamily;
for (var i = 0;i < this.fontFamily.length;i++)
{//定义字体用的是简称,譬如“微软雅黑,Microsoft YaHei”,只用“微软雅黑”定义,重新赋值 this.fontFamily 为完整定义
var ff = this.fontFamily[i];
for (var j = 0;j < allFamilies.length;j++)
{
var ffFull = allFamilies[j];
if (ff == ffFull.split(",")[0])
{
this.fontFamily[i] = ffFull;
break;
}
}
}
/******************************************************************/
//2、替换编辑器
/******************************************************************/
//原始编辑器
this.$textarea = Z("#" + this.id);
//编辑器生成唯一ID;格式为“zte_editor、zte_editor1、zte_editor2···”
this.editorId = function()
{
var id = "zte_editor",num = 1;
while (Z.D.has(id))
id = "zte_editor" + num++;
return id;
}();
this.$editor.attr("id",this.editorId);
// 插入编辑器,隐藏原来的 <textarea>
var width = this.$textarea.offsetWidth();
var height = this.$textarea.offsetHeight();
this.$toolbar.append(this.$buttonBar).append(this.$dialogContainer);
this.$container.append(this.$toolbar).append(this.$editor).append(this.$zoomToolWrap)
.insertAfter(this.$textarea).append(this.$textarea)
.css({ width: width});
this.$zoomToolWrap.append(this.$zoomToolCover);
// 插入工具栏,定义编辑器高度
this.initToolBar();
var editorHeight = height - this.$toolbar.offsetHeight();
this.$container.css({ height: height,});
this.$editor.css({ height: editorHeight,});
this.$zoomToolWrap.css({ height: editorHeight,});
//把 <textarea> 定位在新的编辑器区域上,用于“源码”显示功能
this.$textarea.hide().css(
{
position: "absolute",left: 0,bottom: 0,
width: "100%",border: "none",
paddingLeft: this.$editor.css("paddingLeft"),
paddingTop: this.$editor.css("paddingTop"),
paddingRight: this.$editor.css("paddingRight"),
paddingBottom: this.$editor.css("paddingBottom"),
})
//所有的功能按钮,列表
this.$$btnList = this.$buttonBar.find(".zte-btn");
//下拉菜单dropdown
this.$$dropdownBtn = this.$buttonBar.find("span.zte-btn-dropdown");
this.$$dropdown = this.$buttonBar.find("ul.zte-btn-dropdown");
this.$$dropdownItem = this.$buttonBar.find("ul.zte-btn-dropdown > li");
//定义某些功能按钮样式,如“撤销”、“重做”
this.$$tools.undo.addClass("zte-btn-disable");
this.$$tools.redo.addClass("zte-btn-disable");
//定义Z.dialog弹窗时,用到的HTML字符串
if (Z.AR.contains(this.tools, "createLink"))
{//添加超连接
this.dialogHtml.createLink = '<div class="z-h100p z-pd-t20 z-pd-b20"><table class="z-table z-w100p z-h100p">'
+ '<tr><td class="z-w30p zi-pd-l20 z-px14">链接标题:</td><td><input type="text" id="zte-linkCreater-title" class="z-input z-w300" placeholder="输入链接标题..."></td></tr>'
+ '<tr><td class="z-w30p zi-pd-l20 z-px14">链接地址:</td><td><input type="text" id="zte-linkCreater-link" class="z-input z-w300" placeholder="输入完整链接地址..."></td></tr>'
+ '<tr><td class="z-w30p zi-pd-l20 z-px14">是否新窗口打开:</td><td><input type="checkbox" id="zte-linkCreater-blank" class="z-checkbox"></td></tr>'
+ '<tr><td colspan=2 class="z-text-center zi-pd-l20 zi-pd-r20"><button id="zte-linkCreater-confirm" class="z-button z-large zi-pd-t4 zi-pd-b4 z-blue z-mg-r20">确定</button><button class="z-button z-large zi-pd-t4 zi-pd-b4 z-mg-l20" onclick="Z.Dialog.close();">取消</button></td></tr>'
+ '</table></div>';
}
if (Z.AR.contains(this.tools, "insertImage"))
{//插入图片
this.dialogHtml.insertImage = '<div class="z-h100p z-pd-t20 z-pd-b20"><table class="z-text-center z-table z-w100p z-h100p">'
+ '<tr><td class="z-text-left zi-pd-l20 zi-pd-r20 z-px14"><div class="zte-dialogSwitchBtn"><span data-target="zte-imgInsertor-conLoc" class="zte-active">本地图片</span><span data-target="zte-imgInsertor-conWeb">网络图片</span></div></td></tr>'
+ '<tr><td class="zte-dialogContent z-h300">'
+ '<div class="zte-imgInsertor-conLoc zte-active"><input name="zte-imgInsertor-fileInput" id="zte-imgInsertor-fileInput" type="file" accept="image/png, image/jpeg, image/gif, image/jpg" style="width:0;overflow:hide;"><button id="zte-imgInsertor-btnLoc" class="z-button z-large">+ 添加本地图片</button></div>'
+ '<div class="zte-imgInsertor-conWeb"><input class="z-input z-w300" id="zte-imgInsertor-webUrl" type=text placeholder="输入网络图片地址..."><button id="zte-imgInsertor-btnWeb" class="z-button z-mg-l10">添加</button></div>'
+ '<div class="zte-imgInsertor-conShow"><div class="zte-imgInsertor-imgWrap"><img id="zte-imgInsertor-imgSourse" src=""></div><div class="z-mg-t5"><a id="zte-imgInsertor-Redo" class="z-px12 z-text-red"><u>重新添加</u></a></div></div>'
+ '</td></tr>'
+ '<tr><td class="z-text-center zi-pd-l20 zi-pd-r20"><button id="zte-imgInsertor-confirm" class="z-button z-large zi-pd-t4 zi-pd-b4 z-blue z-mg-r20">确定</button><button class="z-button z-large zi-pd-t4 zi-pd-b4 z-mg-l20" onclick="Z.Dialog.close();">取消</button></td></tr>'
+ '</table></div>';
}
if (Z.AR.contains(this.tools, "symbol"))
{//插入特殊符号
this.dialogHtml.symbol = '<div class="z-h100p z-pd-t20 z-pd-b20"><table class="z-text-center z-table z-w100p z-h100p">'
+ '<tr><td class="z-text-left zi-pd-l20 zi-pd-r20 z-px14"><div class="zte-dialogSwitchBtn">'
+ '<span data-target="zte-symbolPicker-math" class="zte-active">数学符号</span>'
+ '<span data-target="zte-symbolPicker-index"">索引符号</span>'
+ '<span data-target="zte-symbolPicker-language">语言符号</span>'
+ '<span data-target="zte-symbolPicker-other">其他</span></div></td></tr>'
+ '<tr><td class="zte-dialogContent zte-dialogContent-symbol">'
+ '<div class="zte-symbolPicker-math zte-active">' + this.insertSymbolHtml(symbolObj.math) + '</div>'
+ '<div class="zte-symbolPicker-index">' + this.insertSymbolHtml(symbolObj.index) + '</div>'
+ '<div class="zte-symbolPicker-language">' + this.insertSymbolHtml(symbolObj.language) + '</div>'
+ '<div class="zte-symbolPicker-other">' + this.insertSymbolHtml(symbolObj.other) + '</div>'
+ '</td></tr>'
+ '<tr><td class="z-text-center zi-pd-l20 zi-pd-r20"><button class="z-button z-large zi-pd-t4 zi-pd-b4" onclick="Z.Dialog.close();">取消</button></td></tr>'
+ '</table></div>';
}
/******************************************************************/
//3、加入已有内容
/******************************************************************/
this.saveEditorHtml(this.$textarea.val());
//编辑选区对象
this.selection = window.getSelection();
this.range = document.createRange();
this.htmlHistory = [{html: this.html,range: this.range}];
this.historyIndex = 0;
/******************************************************************/
//4、事件绑定
/******************************************************************/
//1:原编辑器修改时,修改zteditor内容
this.$textarea.on("input",this.editorSynContent,this);
//2:工具栏按钮,标题提示语的显示和隐藏
this.$$btnList.on("mouseenter",this.btnMouseEnter,this);
this.$$btnList.on("mouseleave",this.btnMouseLeave,this);
//3.1:功能按钮,统一处理的click事件:(隐藏已显示的提示语)
this.$$btnList.on("click",this.btnDefaultClick,this);
//3.2:禁用mousedown默认操作
this.$$btnList.on("mousedown",function (e){Z.E.forbidden(e)},this)
//3.3:点击显示dropdown
this.$$dropdownBtn.on("click",this.showDropdown,this)
//3.4:dropdown 选项点击事件
this.$$dropdownItem.on("click",this.dropdownSelect,this)
//4.1:编辑器,键盘操作事件
this.$editor.on("keydown",this.doKeydown,this);
//4.2:鼠标滚动事件
this.$editor.on("scroll",this.locationToolCover,this);
//4.3:编辑结束的几种触发事件:(blur keyup cut paste drop dragend)
this.$editor.on("blur keyup cut paste drop dragend",this.editorCheck,this);
//4.4:编辑器选区判断,标注已实现功能的按钮;几种触发事件:(keyup mouseup)
this.$editor.on("keyup mouseup",this.setCommandedTool,this);
//4.5:存储选区的几种触发事件:(keyup mouseup mouseleave);keyup、mouseup 在 this.setCommandedTool 中实现存储
this.$editor.on("mouseleave",this.saveSelection,this);
//4.6:编辑器鼠标 mousedown,隐藏图片缩放
this.$editor.on("mousedown",this.doKeydown,this);
//5:颜色选择器,选中颜色操作
this.$dialogContainer.find(".zte-colorPicker a").on("mousedown",function (e){Z.E.forbidden(e)},this);
this.$dialogContainer.find(".zte-colorPicker a").on("click",this.doColorPicker,this);
//6:图片缩放工具事件绑定
this.$zoomToolCover.children("div").on("mousedown",this.zoomToolMousedown,this);
Z(document).on("mousemove",this.zoomToolMousemove,this);
Z(document).on("mouseup",this.zoomToolMouseup,this);
//7:点击页面初始化所有弹窗
Z(document).on("click",this.initDialogList,this);
},
initToolBar: function(e)
{//初始化工具栏
var html = "";
for (var i = 0;i < this.tools.length;i++)
{
var attr = this.tools[i];
if (attr == "|")
{//值为“|”,插入分隔符
this.$buttonBar.append(Z('<span class="zte-btn-separator"></span>'));
}
else
{//不是“|”,判断是不是有效工具
var obj = this.getToolObj(attr);
if (obj)
{//有效工具
this.$buttonBar.append(this.getToolHtml(obj.attr,obj.title,obj.font));
}
}
}
},
getToolObj: function(tool)
{//获取工具对象
for (var i = 0;i < allTools.length;i++)
{
if (allTools[i].attr == tool)
return allTools[i];
}
return null;
},
getToolHtml: function(attr, title, font)
{//获取菜单工具的html
if (attr != "paragraph" && attr != "fontName" && attr != "fontSize")
{//非下拉列表
var html = '<span class="zte-btn" data-attr="' + attr + '">'
+ '<i class="z-font z-f-' + font + ' z-px18"></i>'
+ '<div class="zte-btn-title"><div class="zte-btn-title-arrow"></div>'
+ '<div class="zte-btn-title-text">' + title + '</div></div>';
if (attr == "foreColor" || attr == "backColor")
{//为颜色选择器,添加弹窗代码
var bgColor = (attr == "foreColor")?("#000000"):("#FFFFFF");
html += '<i class="z-px10 z-mg-l5 z-mg-r5 z-font z-arrow-down zte-pickerBtn" style="bottom:2px;"></i></div><div class="zte-pickedColor" style="background-color:' + bgColor + '"></div>';
this.insertColorPicker(attr);
}
html += '</span>';
this.$$tools[attr] = Z(html);
return this.$$tools[attr];
}
else
{//三个下拉列表
var html = '<span class="zte-btn zte-btn-dropdown" data-attr="' + attr + '">';
switch (attr)
{//“段落格式”、“字体”、“字号”,dropdown
case "paragraph":
html += '<div class="zte-dropdown-selected z-text-ellipsis"><i class="z-font z-arrowhead-down z-float-right z-px10"></i>' + paragraph[0]
+ '</div><ul class="zte-btn-dropdown" data-type="' + attr + '">';
for (var i = 0;i < paragraph.length;i++)
html += '<li data-value="' + paragraph[i] + '"><' + paragraph[i] + '>' + paragraph[i] + '</' + paragraph[i] + '></li>';
break;
case "fontName":
html += '<div class="zte-dropdown-selected z-text-ellipsis"><i class="z-font z-arrowhead-down z-float-right z-px10"></i>' + this.fontFamily[0].split(",")[0]
+ '</div><ul class="zte-btn-dropdown" data-type="' + attr + '">';
for (var i = 0;i < this.fontFamily.length;i++)
html += '<li style="font-family:' + this.fontFamily[i] + ';" data-value="' + this.fontFamily[i] + '">' + this.fontFamily[i].split(",")[0] + '</li>';
break;
case "fontSize":
html += '<div class="zte-dropdown-selected z-text-ellipsis"><i class="z-font z-arrowhead-down z-float-right z-px10"></i>' + this.fontSize[0]
+ '</div><ul class="zte-btn-dropdown" data-type="' + attr + '">';
for (var i = 0;i < this.fontSize.length;i++)
html += '<li style="font-size:' + this.fontSize[i] + 'px;" data-value="' + this.fontSize[i] + '">' + this.fontSize[i] + '</li>';
break;
}
html += '</ul><div class="zte-btn-title"><div class="zte-btn-title-arrow"></div>'
+ '<div class="zte-btn-title-text">' + title + '</div></div></span>';
this.$$tools[attr] = Z(html);
return this.$$tools[attr];
}
},
/***********************************************************************************************/
//一:编辑器功能
/***********************************************************************************************/
tool_html: function(command,e)
{//01源码
if (this.$textarea.isHide())
{//显示源码
//存储当前选区
this.saveSelection();
//按钮组样式替换
this.$$tools.html.addClass("zte-active");
this.$$tools.html.$$btnListNormal = this.$buttonBar.find(".zte-btn:not(.zte-btn-disable):not([data-attr=html])");
this.$$tools.html.$$btnListActive = this.$buttonBar.find(".zte-btn.zte-active:not([data-attr=html])");
this.$$tools.html.$$btnListNormal.addClass("zte-btn-disable");
this.$$tools.html.$$btnListActive.removeClass("zte-active");
this.$textarea.css("height",parseInt(this.$editor.css("height"))).show();
this.$editor.css('visibility', 'hidden');
}
else
{//显示内容
this.$$tools.html.removeClass("zte-active");
this.$$tools.html.$$btnListNormal.removeClass("zte-btn-disable");
this.$$tools.html.$$btnListActive.addClass("zte-active");
this.$textarea.hide();
this.$editor.css('visibility', 'visible');
//存储选区、存储历史
this.saveHistory();
}
},
tool_undo: function(e)
{//02撤销
//读取历史纪录
this.loadHistory(-1);
//按钮样式
if (this.$$tools.redo[0])
{
this.$$tools.redo.removeClass("zte-btn-disable");
if (this.historyIndex == 0)
this.$$tools.undo.addClass("zte-btn-disable");
}
this.setCommandedTool();
},
tool_redo: function(e)
{//03重做
//读取历史纪录
this.loadHistory(1);
//按钮样式
if (this.$$tools.undo[0])
{
this.$$tools.undo.removeClass("zte-btn-disable");
if (this.historyIndex == this.htmlHistory.length - 1)
this.$$tools.redo.addClass("zte-btn-disable");
}
this.setCommandedTool();
},
tool_bold: function(command)
{//04加粗
this.doCommandMain(command);
},
tool_italic: function(command)
{//05斜体
this.doCommandMain(command);
},
tool_underline: function(command)
{//06下划线
this.doCommandMain(command);
},
tool_strikethrough: function(command)
{//07删除线
this.doCommandMain(command);
},
tool_superscript: function(command)
{//08上标
this.doCommandSupSub(command);
},
tool_subscript: function(command)
{//09下标
this.doCommandSupSub(command);
},
tool_foreColor: function(command,e)
{//10字体颜色
this.doCommandPicker(command,e);
},
tool_backColor: function(command,e)
{//11背景颜色
this.doCommandPicker(command,e);
},
tool_removeFormat: function(command)
{//12清除格式
this.doCommandMain(command,null,false);
this.$$btnList.removeClass("zte-active");
},
tool_insertorderedlist: function(command)
{//13有序列表
this.doCommandInsertlist(command);
},
tool_insertunorderedlist: function(command)
{//14无序列表
this.doCommandInsertlist(command);
},
tool_selectAll: function(command)
{//15全选
this.doCommandMain(command,null,false);
},
tool_clearAll: function()
{//16清空
this.saveEditorHtml();
this.setCursorEnd();
//存储选区、存储历史
this.saveHistory();
},
tool_paragraph: function(command,value)
{//17段落格式
this.doCommandMain("formatBlock",value,false);
},
tool_fontName: function(command,value)
{//18字体
this.doCommandMain(command,value,false);
},
tool_fontSize: function(command,value)
{//19字号
//载入选区
this.loadSelection();
var size = 7;
if (value <= 12) size = 1;
if (value == 13) size = 2;
if (value == 16) size = 3;
if (value == 18) size = 4;
if (value == 24) size = 5;
if (value == 32) size = 6;
//如果选区没内容,则调用insertHTML插入代码;有选区,则直接调用doCommandMain
if (this.range.collapsed)
{
value = '<span style="font-size:' + value + 'px">​</span>';
this.doCommandMain("insertHTML", value, false, true);
}
else
{
this.doCommandMain(command,size,false,true);
//获取选区元素<font>
var $startEle = Z(this.getSelectionEle());
//不是预选的前6个,则手动修改
if ($startEle.attr("size") == 7) $startEle.removeAttr("size").css("fontSize",value + "px");
}
//存储选区、存储历史
this.saveHistory();
},
tool_justifyLeft: function(command)
{//20左对齐
this.removeSiblingsActive(command);
this.doCommandMain(command, null, true);
},
tool_justifyCenter: function(command)
{//21居中
this.removeSiblingsActive(command);
this.doCommandMain(command, null, true);
},
tool_justifyRight: function(command)
{//22右对齐
this.removeSiblingsActive(command);
this.doCommandMain(command, null, true);
},
tool_createLink: function(command,e)
{//23超链接
var dialog = new Z.Dialog();
dialog.id = "createLink";
dialog.title = "添加超链接";
dialog.text = this.dialogHtml.createLink;
dialog.width = 500;
dialog.height = 240;
dialog.fixed = true;
dialog.execute();
Z("#zte-linkCreater-confirm").on("click", this.doLinkCreat,this);
},
tool_unlink: function(command)
{//24取消超链接
this.doCommandMain(command, null, false);
},
tool_insertImage: function(command)
{//25插入图片
var dialog = new Z.Dialog();
dialog.id = "insertImage";
dialog.title = "添加图片";
dialog.text = this.dialogHtml.insertImage;
dialog.width = 500;
dialog.height = 450;
dialog.fixed = true;
dialog.execute();
//添加图片方式切换
Z(".zte-dialogSwitchBtn > span").on("click",this.insertHtmlSwitch,this);
//按钮触发事件
Z("#zte-imgInsertor-btnLoc").on("click",this.insertImgLocClick,this);
Z("#zte-imgInsertor-fileInput").on("change",this.insertImgLoc,this);
Z("#zte-imgInsertor-btnWeb").on("click",this.insertImgWeb,this);
Z("#zte-imgInsertor-Redo").on("click",this.insertImgRedo,this);
//确认插入
Z("#zte-imgInsertor-confirm").on("click",this.insertImgConfirm,this);
},
tool_symbol: function(command)
{//26特殊符号
var dialog = new Z.Dialog();
dialog.id = "symbol";
dialog.title = "插入特殊符号";
dialog.text = this.dialogHtml.symbol;
dialog.width = 500;
dialog.height = 300;
dialog.fixed = true;
dialog.execute();
Z(".zte-dialogSwitchBtn > span").on("click",this.insertHtmlSwitch,this);
Z(".zte-dialogContent-symbol a").on("click",this.insertSymbolConfirm,this);
},
/***********************************************************************************************/
//二:事件处理方法
/***********************************************************************************************/
editorSynContent: function()
{//1:原编辑器内容修改(input事件),实现zteditor内容同步
this.saveEditorHtml(this.$textarea.val());
},
btnMouseEnter: function(e)
{//2.1:按钮提示说明,鼠标进入显示
var $target = Z(Z.E.current(e));
if ($target.hasClass("zte-btn"))
{
var btnWidth = $target.offsetWidth();
var btnHeight = $target.offsetHeight();
var $title = $target.children(".zte-btn-title").show();
var titleWidth = $title.offsetWidth();
var setWidth = (btnWidth - titleWidth)/2;
$title.css({left: setWidth,top:btnHeight});
}
},
btnMouseLeave: function(e)
{//2.2:按钮提示说明,鼠标离开隐藏
var $target = Z(Z.E.current(e));
if ($target.hasClass("zte-btn"))
$target.children(".zte-btn-title").hide();
},
btnDefaultClick: function(e)
{//3.1:所有按钮统一的click事件
var $target = null;
if (e.nodeType == 1) $target = Z(e);
else $target = Z(Z.E.current(e));
//隐藏标题提示浮框
var $btnTitle = $target.children(".zte-btn-title");
if ($btnTitle.length > 0 && !$btnTitle.isHide())
$btnTitle.hide();
//隐藏颜色选择器
this.colorPickerHide();
//非dropdown列表则隐藏所有dropdown,并执行按钮功能
if (!$target.hasClass("zte-btn-dropdown"))
{
this.$$dropdown.hide();
this["tool_" + $target.attr("data-attr")]($target.attr("data-attr"),e);
}
},
showDropdown: function(e)
{//3.2:特别按钮:展示dropdown列表
Z.E.forbidden(e);
var thisBtn = Z.E.current(e);
//执行按钮默认操作
this.btnDefaultClick(thisBtn);
//显示dropdown列表
var dropdown = Z(thisBtn).children("ul.zte-btn-dropdown");
this.$$dropdown.hide();
if (Z(dropdown).isHide())
Z(dropdown).show();
},
dropdownSelect: function(e)
{//3.3:dropdown 选项点击事件
Z.E.forbidden(e);
var $target = Z(Z.E.current(e));
var $parent = $target.parent();
var $show = Z($parent[0].previousElementSibling);
var showVal = $target.text();
var dataType = $target.parent().attr("data-type");
var dataVal = $target.attr("data-value");
//填入选中值,显示
$show.html('<i class="z-font z-arrowhead-down z-float-right z-px10"></i>' + showVal);
//判断是否存在选中,光标位置
//根据类型,执行不同处理
this["tool_" + dataType](dataType,dataVal);
//隐藏列表
$parent.hide();
},
doKeydown: function(e)
{//4.1:键盘keydown事件,编辑过程,统一格式
var keyCode = Z.E.key(e);
//回车换行
if (keyCode == 13)
this.doNewline();
if (e.ctrlKey)
{//Ctrl组合键
if (e.keyCode == 89)
{// Ctrl + Y
Z.E.forbidden(e);
this.tool_redo(e);
}
if (e.keyCode == 90)
{// Ctrl + Z
Z.E.forbidden(e);
this.tool_undo(e);
}
}
//隐藏图片缩放框
this.zoomCoverHide();
},
doNewline: function(e)
{//4.2:统一“回车”、“换行”格式;针对<pre><code>标签特殊处理;TODO 待处理
return;
//等待编辑
/*
var startEle = this.getSelectionEle();
var startEleTag = startEle.tagName;
if (startEleTag == "PRE" || startEleTag == "NODE")
{//如果是<pre>、或<code>标签内容
//禁用默认操作
//Z.E.forbidden();
//var insertEle = document.createDocumentFragment();
//insertEle.appendChild(Z("<p><br></p>")[0]);
//this.range.insertNode(insertEle);
//定位光标
}
//顶级元素
var topEle = this.getSelectionTopEle(startEle);
if (topEle)
{
var topEleTag = topEle.tagName;
var closestBlock = this.getClosestBlock(startEle);
if (closestBlock)
{//存在最近的块级元素,修改为p标签
if (topEle != closestBlock && Z(topEle).css("display") == "block" && Z.AR.indexOf(paragraph, topEleTag) == -1)
{//顶级标签为非p,直接去掉
var $newP = Z("<p></p>");
$newP.html(Z(topEle).html()).insertBefore(Z(topEle));
Z(topEle).remove();
}
var $newP2 = Z("<p></p>");
$newP2.html(Z(closestBlock).html()).insertBefore(Z(closestBlock));
Z(closestBlock).remove();
}
else
{//没有块级元素的情况
var $newP = Z("<p></p>");
$newP.html(Z(closestBlock).html()).insertBefore(Z(closestBlock));
Z(closestBlock).remove();
}
}
var $newP = Z("<p></p>");
$newP.html(Z(closestBlock).html()).insertBefore(Z(closestBlock));
Z(closestBlock).remove();
*/
},
editorCheck: function(e)
{//5.1:几种编辑结束判断:(blur keyup cut paste drop dragend),对编辑器进行检查
var ev = e || window.event;
if (ev.type == "cut" || ev.type == "paste" || ev.type == "drop")
{//drop事件处理,用settimeout延时获取编辑器内容
var _this = this;
var dropTimeout = setTimeout(function()
{
_this.editorCheck_action(_this);
_this = null;
clearTimeout(dropTimeout);
},50);
return;
}
this.editorCheck_action();
},
editorCheck_action: function(obj)
{//5.2:操作结束后的处理,编辑器内容对比
var _this = obj || this;
var html = _this.$editor.html();
if (html == "")
_this.saveEditorHtml();
_this.html = html;
_this.saveTextareaValue(_this.$editor.html());
//存储选取、存储历史记录
_this.saveHistory();
},
setCommandedTool: function()
{//6:选区变换,标注以实现功能的按钮;定时器延时处理
var _this = this;
var setTime = setTimeout(function()
{
//存储选区
_this.saveSelection();
//遍历查找,看有没有已编辑对象
var tools = _this.tools;
for (var i = 0;i < tools.length;i++)
{
if (tools[i] == "|") continue;
if (document.queryCommandState(tools[i]))
_this.$$tools[tools[i]].addClass("zte-active");
else
_this.$$tools[tools[i]].removeClass("zte-active");
}
//释放定时器、对象
clearTimeout(setTime);
_this = null;
},50)
},
initDialogList: function()
{//7:隐藏所有弹窗、列表
this.$$dropdown.hide();
this.colorPickerHide();
},
/***********************************************************************************************/
//三:
/***********************************************************************************************/
saveEditorHtml: function(html)
{//3:赋值给编辑器
if (html && Z.V.isNotEmptyBlank(html))
this.$editor.html(html);
else
this.$editor.html("<p><br></p>");
this.html = this.$editor.html();
},
saveTextareaValue: function(html)
{//3.1:有内容,才赋值textarea
var html = Z.S.trim(html).replace(/\s/gi,"").replace(/ /gi,"").replace(/<p><\/p>/gi,"").replace(/<p><br><\/p>/gi,"");
if (Z.V.isNotEmptyBlank(html))
this.$textarea.val(this.html);
else
this.$textarea.val("");
},
setCursorEnd: function()
{//4:设置光标,到编辑器末尾
var sel = window.getSelection();
var range = document.createRange();
//找到最后的文本节点对象
var node = this.getLastTextNode(this.$editor[0]);
//添加选区为内容末尾
range.collapse(true);
range.setStart(node,node.length);
range.setEnd(node,node.length);
sel.removeAllRanges();
sel.addRange(range);
//存储选区
this.selection = sel;
this.range = range;
},
/***********************************************************************************************/
//四:自定义get方法/获取
/***********************************************************************************************/
getClosetParent: function(ele,target)
{//2:获取最近的祖先元素,从自己开始
var $parent = Z(ele);
if (!$parent[0]) return null;
var allTarget = Z(document).find(target);
while ($parent[0] && $parent[0].tagName != "BODY")
{//没找到就继续找,除非找到了根目录
for (var i = 0;i < allTarget.length;i++)
{
if (allTarget[i] == $parent[0])
return allTarget[i]
}
$parent = $parent.parent();
}
return null;
},
getSelectionEle: function()
{//3.1:获取编辑区选中对象的元素节点;不存在则返回NULL
var anchorEle = (this.selection.anchorNode)?
((this.selection.anchorNode.type == 1)?(this.selection.anchorNode):(this.selection.anchorNode.parentNode)):(null);
if (anchorEle == this.$editor[0])
return null;
return anchorEle;
},
getSelectionTopEle: function(ele)
{//3.2:获取编辑区选中对象的最高节点,不存在则返回NULL
var children = this.$editor.children();
var parent = ele;
while (parent != this.$editor[0])
{
for (var i = 0;i < children.length;i++)
{
if (children[i] == parent)
return parent;
}
parent = parent.parentNode;
}
return null;
},
getCursortPos: function()
{//3.3:获取选区光标位置
var CaretPos = 0;
// IE Support
if (document.selection) {
ctrl.focus (); // 获取焦点
var Sel = document.selection.createRange (); // 创建选定区域
Sel.moveStart('character', -ctrl.value.length); // 移动开始点到最左边位置
CaretPos = Sel.text.length; // 获取当前选定区的文本内容长度
}
// Firefox support
else if (ctrl.selectionStart || ctrl.selectionStart == '0'){
CaretPos =ctrl.selectionStart; // 获取选定区的开始点
}
return CaretPos;
},
getClosestBlock: function(ele)
{//3.4:获取最近的block元素
while (Z(ele).css("display") != "block" && ele.tagName != "P" && Z(ele) != this.$editor)
ele = ele.parentNode;
if (Z(ele) == this.$editor || ele.tagName == "P")
return null;
return ele;
},
getLastTextNode: function(ele)
{//3.5:内容中最后的文本节点
var ignoreName = ["BR","IMG","INPUT"];
var node = ele.lastChild;
var eleParent = ele.parentElement;
if (node)
{
if (node.nodeType == 1)
{//元素节点,重复查找
node = this.getLastTextNode(node);
}
if (node.nodeType == 3)
{//文本节点,直接返回
return node;
}
if (node.nodeType == 8)
{//注释节点,添加非占位字符
ele.insertAdjacentHTML("beforeend","​");
node = ele.lastChild;
}
}
else if (eleParent)
{
var newEle = ele;
if (Z.AR.contains(ignoreName, ele.nodeName))
newEle = eleParent;
ele.insertAdjacentHTML("beforeend","​");
node = ele.lastChild;
}
return node;
},
/***********************************************************************************************/
//五:自定义方法
/***********************************************************************************************/
insertColorPicker: function(attr)
{//1.2:插入颜色选择器
var colorAlternatived =[
"EB3D00","EC3A3E","F25F61","FA9D99","F67D6F","C28482","C26A74","976D6B","C16B61","955942",
"F48000","F47E36","F99F3D","F99F61","D76F4C","F99E7E","FCC78C","FEC7AF","BF6C35","C18557",
"FDC800","FDFA00","FDFC72","FDFE99","FEFEC6","C1A25F","C0C165","94946A","968064","71624E",
"009049","1E8F6E","6AC334","AADC7D","8FAE6B","8FAE84","75886C","75887E","95947E","72635B",
"AADBC7","62C2A1","90AD9F","00AEC4","218E9E","1E8F85","2B726C","567C7E","455F60","4D4A42",
"340C70","0074C5","0089E1","60BFF3","90ABBD","758792","5C676E","5F6D84","706F61","414548",
"EF2F72","FD9CB9","C4A0AB","C38296","C371A0","C3538B","A14875","A06186","97576D","824275",
"653B73","774389","97679F","C18DB8","BBB0D4","9081B6","715D9D","7A6F95","977F87","73545D",
"9B2575","9E7996","495577","6476B3","624F5D","4F495C","684B6C","7F647A","FFFFFF","000000",
];
//定义列数,计算行数
var columns = 10;
var lines = Math.ceil(colorAlternatived.length / columns);
//计算灰度色值
var grayNum = 16 / lines;
//通用颜色变量
var color = "";
var html = '<div class="zte-colorPicker" data-target="' + attr + '"><div class="zte-colorPicker-arrow"></div><div class="zte-colorPick-table"><table><tr><td colspan=12 class="zte-colorPicker-title">选择颜色</td></tr>';
//循环,所有颜色
for (var i = 0;i < lines;i++) { //行 i
html += '<tr>';
var hexNum = Math.abs(Math.ceil(16 - (i+1) * grayNum)).toString(16);
var grayColor = new Array(7).join(hexNum);
html += '<td><a style="background:#' + grayColor + ';" data-value="#' + grayColor + '" title="#' + grayColor + '"></a></td>';
html += '<td style="border:none;"></td>';
for (var j = 0;j < columns;j++) { //列 j
color = colorAlternatived[i*columns + j];
if (!color) {
break;
}
html += '<td><a style="background:#' + color + ';" data-value="#' + color + '" title="#' + color + '"></a></td>';
}
html += '</tr>';
}
html += '</tr></table></div>';
html += '</div></div>';
var $thisPicker = (this["$colorPicker_" + attr] = Z(html));
this.$$colorPicker.push($thisPicker)
this.$dialogContainer.append($thisPicker);
},
saveSelection: function()
{//2.1:选区Selection,存储
var sel = window.getSelection();
if(sel.rangeCount > 0 && sel.anchorNode.tagName != "BODY")
{
var anchorEle = (sel.anchorNode.type == 1)?(sel.anchorNode):(sel.anchorNode.parentNode);
if (!anchorEle) return;
var editor = this.getClosetParent(anchorEle,".zte-editor");
if (editor == this.$editor[0])
{//选区在编辑器内,赋值 this.selection、this.range
this.selection = sel;
this.range = sel.getRangeAt(0);
}
}
else this.setCursorEnd();
},
loadSelection: function()
{//2.2:选区Selection,读取
var container = this.range.endContainer;
if (container == this.$editor[0] || container == document)
this.setCursorEnd();
else
{
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(this.range);
}
},
saveHistory: function()
{//3.1:添加历史记录
this.html = this.$editor.html();
this.saveTextareaValue(this.$editor.html());
//判断当前是否存在修改
if (this.html == this.htmlHistory[this.historyIndex].html)
return;
this.saveSelection();
if (this.historyIndex < this.htmlHistory.length - 1)
{//判断 this.historyIndex 的位置,去掉后面多余的部分
var num = this.htmlHistory.length - 1 - this.historyIndex;
while (num > 0)
{
this.htmlHistory.pop();
num--;
}
}
this.htmlHistory.push({html: this.html,range: this.range});
this.historyIndex = this.htmlHistory.length - 1;
//按钮样式
if (this.$buttonBar.find("[data-attr=html]").hasClass("zte-active"))
return;
this.$$tools.undo.removeClass("zte-btn-disable");
this.$$tools.redo.addClass("zte-btn-disable");
//遍历所有<img>标签,添加缩放功能
this.addImgZoom();
},
loadHistory: function(type)
{//3.2:读取历史记录
this.historyIndex += type;
if (this.historyIndex < 0)
this.historyIndex = 0;
if (this.historyIndex > this.htmlHistory.length - 1)
this.historyIndex = this.htmlHistory.length - 1;
//赋值编辑器
var html = this.htmlHistory[this.historyIndex].html;
this.saveEditorHtml(html);
//载入选区
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(this.htmlHistory[this.historyIndex].range);
//遍历所有<img>标签,添加缩放功能
this.addImgZoom();
},
//4.1:按钮执行功能
//command 用于:bold、italic、underline、strikethrough、insertorderedlist、insertrderedlist、justifyLeft、justifyCenter、justifyRight
//activeOrNot:表示保持激活状态或非激活状态;noSave:不保存选区&历史
doCommandMain: function(command,value,activeOrNot,noSave)
{
//载入选区
this.loadSelection();
//判断是否已执行,添加相应样式
if (typeof activeOrNot === "boolean")
{
if (activeOrNot === true) this.$$tools[command].addClass("zte-active");
}
else
{
var hasDone = document.queryCommandState(command);
if (hasDone) this.$$tools[command].removeClass("zte-active");
else this.$$tools[command].addClass("zte-active");
}
//执行功能
document.execCommand(command,false,value);
//存储选区、存储历史
if (!noSave)
this.saveHistory();
},
doCommandSupSub: function(command)
{//4.2:按钮执行功能,command 用于:superscript、subscript
//载入选区
this.loadSelection();
//判断是否已执行,添加相应样式
var hasDone = document.queryCommandState(command);
//已执行功能的选区
if (hasDone)
{
this.$$tools[command].removeClass("zte-active");
//去除
document.execCommand(command,false,null);
}
//未执行功能的选区
else
{
this.$$tools[command].addClass("zte-active");
//执行
document.execCommand(command,false,null);
}
//存储选区、存储历史
this.saveHistory();
},
doCommandInsertlist: function(command)
{//4.3:列表插入功能,添加额外样式,command 用于:insertorderedlist、insertunorderedlist
this.removeSiblingsActive(command);
//载入选区
this.loadSelection();
//先判断执行状态
var hasDone = document.queryCommandState(command);
//再执行功能
document.execCommand(command,false);
if (!hasDone)
{
this.$$tools[command].addClass("zte-active");
var startEle = this.getSelectionEle();
var liEle = this.getClosetParent(startEle,"li");
var listTag = command.substring("6","7") + "l";
var listEle = this.getClosetParent(startEle,listTag);
var liAttr = liEle.getAttribute("style");
var listAttr = listEle.getAttribute("style");
var listStyle = (listTag == "ol")?("decimal"):("disc");
if (!liAttr)
Z(liEle).css({"list-style":listStyle});
if (!listAttr)
Z(listEle).css({"padding":"0 0 0 40px","margin":"15px 0","list-style":listStyle});
}
else
this.$$tools[command].removeClass("zte-active");
//存储选区、存储历史
this.saveHistory();
},
doCommandPicker: function(command,e)
{//4.4:颜色选择器功能
var target = Z.E.target(e);
var $btn = this.$$tools[command]
if (target == $btn.find(".zte-pickerBtn")[0])
{//如果点击对象是三角图标,触发显示选则框
Z.E.forbidden(e);
var left = $btn.offsetLeft();
var top = $btn.offsetTop() + $btn.offsetHeight() + 3;
this["$colorPicker_" + command].show().css({left:left,top:top});
}
else
{//应用当前已选择的颜色
var color = this.$$tools[command].find(".zte-pickedColor").css("backgroundColor");
color = this.color2hex(color);
this.doCommandMain(command,color,false);
}
},
doColorPicker: function(e)
{//5.1:颜色选择器选中颜色
Z.E.forbidden(e);
//载入选区
this.loadSelection();
var $target = Z(Z.E.target(e));
var color = $target.attr("data-value");
var command = Z(this.getClosetParent($target[0],".zte-colorPicker")).attr("data-target");
this.$$tools[command].find(".zte-pickedColor").css("backgroundColor",color);
document.execCommand(command,false,color);
this.colorPickerHide();
//存储选区、存储历史
this.saveHistory();
},
colorPickerHide: function()
{//5.2:颜色选择器隐藏
for (var i = 0;i < this.$$colorPicker.length;i++)
this.$$colorPicker[i].hide();
},
color2hex: function(str)
{//5.3:颜色统一转换为 #000000 的格式
var strHex = "#";
if (/^(rgba|RGBA|rgb|RGB)/.test(str))
{
var colorArr = str.replace(/(?:\(|\)|rgba|RGBA|rgb|RGB)*/g, "").split(",");
for(var i = 0;i < 3;i++){
var hex = Number(colorArr[i]).toString(16);
if (hex === "0") hex += hex;
strHex += hex;
}
return strHex;
}
return strHex;
},
removeSiblingsActive: function(conmand)
{//6:取消同类型功能其他功能激活样式,去除"zte-active"
var thisEle = this.$$tools[conmand][0];
//向上查找
var $preSibling = Z(thisEle.previousElementSibling);
while ($preSibling[0] && !$preSibling.hasClass("zte-btn-separator"))
{
$preSibling.removeClass("zte-active");
$preSibling = Z($preSibling[0].previousElementSibling);
}
//向下查找
var $nextSibling = Z(thisEle.nextElementSibling);
while ($nextSibling[0] && !$nextSibling.hasClass("zte-btn-separator"))
{
$nextSibling.removeClass("zte-active");
$nextSibling = Z($nextSibling[0].nextElementSibling);
}
},
doLinkCreat: function(e)
{//7:实现链接添加操作
var $createrTable = Z(this.getClosetParent(Z.E.target(e),"table"));
var createrTitle = $createrTable.find("#zte-linkCreater-title").val();
var createrLink = $createrTable.find("#zte-linkCreater-link").val();
var createrBlank = $createrTable.find("#zte-linkCreater-blank")[0].checked;
//去除遮罩
Z.Dialog.close();
//插入链接
this.doCommandMain("createLink",createrLink,true,false);
//添加title、blank信息
var $aLinkEle = Z(this.getSelectionEle());
$aLinkEle.attr("title",createrTitle).attr("target",(createrBlank)?("_blank"):(""));
//存储选区、存储历史
this.saveHistory();
},
/***********************************************************************************************/
//图片添加功能(1、本地图片上传后保存,2、网络图片通过HTTP下载后保存)
/***********************************************************************************************/
insertHtmlSwitch: function(e)
{//8.1:图片添加功能,切换添加方式
var $thisBtn = Z(Z.E.target(e));
var $targetEle = Z("." + $thisBtn.attr("data-target"));
$thisBtn.addClass("zte-active").siblings("span").removeClass("zte-active");
$targetEle.addClass("zte-active").siblings("div").removeClass("zte-active");
},
insertImgLocClick: function(e)
{//8.2:本地图片添加
Z("#zte-imgInsertor-fileInput")[0].click();
},
insertImgLoc: function(e)
{//8.3:图片读取上传
var file = Z.E.target(e).files[0];
var fileSize = file.size;
if (fileSize > this.maxSize)
return Z.failure("上传图片超出最大限制,请重新选择图片!");
var _this = this;
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function()
{
var ajax = new Z.Ajax();
ajax.setContextPath(_this.contextPath);
ajax.setClassName(Z.TextEditor.AJAX_CLASS);
ajax.setMethodName(Z.TextEditor.AJAX_UPLOAD);
ajax.addParam("fileData", reader.result);
ajax.addParam("fileDir", _this.fileDir);
ajax.addParam("fileName", file.name);
ajax.setFailureAlert();
ajax.setCallback(function()
{
var src = (_this.origin?location.origin:"") + Z.rootPath(_this.contextPath, this.responseText);
Z("#zte-imgInsertor-imgSourse").attr("src", src);
Z(".zte-imgInsertor-conShow").addClass("zte-active").siblings("div").removeClass("zte-active");
Z(".zte-dialogSwitchBtn > span,.zte-imgInsertor-conUrl").addClass("zte-disable");
});
ajax.execute();
};
},
insertImgWeb: function(e)
{//8.4:网络图片添加
var fileUrl =Z("#zte-imgInsertor-webUrl").val();
//检测是否为有效地址
var urlReg = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?/;
if (!urlReg.test(fileUrl))
return Z.failure("请输入正确的图片地址");
//禁用二次点击
Z(".zte-imgInsertor-conWeb").addClass("zte-disable");
var _this = this;
var ajax = new Z.Ajax();
ajax.setContextPath(this.contextPath);
ajax.setClassName(Z.TextEditor.AJAX_CLASS);
ajax.setMethodName(Z.TextEditor.AJAX_UPLOADWWW);
ajax.addParam("fileDir", this.fileDir);
ajax.addParam("fileUrl", fileUrl);
ajax.setCallback(function()
{
Z(".zte-imgInsertor-conWeb").removeClass("zte-disable");
if (this.responseStatus != 0)
return Z.failure(this.responseText);
var src = (_this.origin?location.origin:"") + Z.rootPath(_this.contextPath, this.responseText);
Z("#zte-imgInsertor-imgSourse").attr("src", src);
Z(".zte-imgInsertor-conShow").addClass("zte-active").siblings("div").removeClass("zte-active");
Z(".zte-dialogSwitchBtn > span,.zte-imgInsertor-conUrl").addClass("zte-disable");
});
ajax.execute();
},
insertImgRedo: function(e)
{//8.5:重新添加图片
var $targetEle = Z("." + Z(".zte-dialogSwitchBtn > span.zte-active").attr("data-target"));
Z(".zte-dialogSwitchBtn > span,.zte-imgInsertor-conUrl").removeClass("zte-disable");
Z(".zte-imgInsertor-conShow").removeClass("zte-active");
$targetEle.addClass("zte-active");
//重置input的值
Z("#zte-imgInsertor-fileInput")[0].value = "";
Z("#zte-imgInsertor-webUrl").val("");
},
insertImgConfirm: function(e)
{//8.6:确定添加到编辑内容,执行添加
//载入选区
this.loadSelection();
var imgSrc = Z("#zte-imgInsertor-imgSourse")[0].getAttribute("src");
var value = '<img width="" height="" src="' + imgSrc + '">';
this.doCommandMain("insertHTML",value,false);
//去除遮罩
Z.Dialog.close();
//编辑器检查
this.editorCheck_action(this);
},
addImgZoom: function()
{//9.1:为编辑内容中图片,添加缩放功能
var $$imgs = this.$editor.find("img");
for (var i = 0;i < $$imgs.length;i++)
{
var $img = Z($$imgs[i]);
if (!$img.hasOn)
{
$img.hasOn = true;
$img.on("click",this.zoomCoverShow,this);
$img.on("mousedown mouseup mousemove dragstart click dblclick",function(e){Z.E.forbidden(e)},this);
}
}
},
zoomCoverShow: function(e)
{//9.2:显示缩放编辑容器 mouseenter
var thisImg = Z.E.target(e);
this.$zoomToolCover.show();
this.locationToolCover(e,thisImg);
},
zoomCoverHide: function(e)
{//9.3:隐藏缩放编辑容器 mouseleave
this.$zoomToolCover.hide();
},
zoomToolMousedown: function(e)
{//10.1:编辑器内容图片,缩放操作:mousedown
//可缩放标识
this.$zoomToolCover.canZoom = true;
//存储点击对象、鼠标点下的坐标、原始图片大小
var $img = Z(this.$zoomToolCover.targetImg);
this.$zoomToolCover.mouseType = Z.E.target(e).className.substring(13);
this.$zoomToolCover.mouseLocation = {x: e.pageX, y: e.pageY};
this.$zoomToolCover.sourseSize = {width: $img.offsetWidth(), height: $img.offsetHeight()};
},
zoomToolMousemove: function(e)
{//10.2:编辑器内容图片,缩放操作:mousemove
if (!this.$zoomToolCover.canZoom)
return;
Z.E.forbidden(e);
//执行缩放操作
var $img = Z(this.$zoomToolCover.targetImg);
var oldLoc = this.$zoomToolCover.mouseLocation;
var oldSize = this.$zoomToolCover.sourseSize;
var newWidth = oldSize.width + (e.pageX - oldLoc.x);
var newHeight = oldSize.height + (e.pageY - oldLoc.y);
switch (this.$zoomToolCover.mouseType)
{
case "e": newHeight = oldSize.height;break;
case "se":
var oldRadio = oldSize.width/oldSize.height;
var newRadio = newWidth/newHeight;
if (oldRadio > newRadio)
newWidth = newHeight * oldRadio;
else
newHeight = newWidth / oldRadio;
break;
case "s": newWidth = oldSize.width;break;
}
$img.css({"width": newWidth,"height": newHeight});
this.locationToolCover(e,$img[0]);
},
zoomToolMouseup: function(e)
{//10.3:编辑器内容图片,缩放操作:mouseup
if (this.$zoomToolCover.canZoom)
{//结束图片缩放操作,并存储历史纪录
this.$zoomToolCover.canZoom = false;
//存储选区、存储历史
this.saveHistory();
}
},
locationToolCover: function(e,ele)
{//10.4:编辑图片,更新缩放工具定位,保持和图片重合
if (this.$zoomToolCover.isHide())
return;
var scrollTop, top;
if (e.type == "scroll")
{//执行滚动事件时,只修改高度值
scrollTop = this.$editor[0].scrollTop;
top = this.$zoomToolCover.sourseTop - scrollTop;
console.log(scrollTop,this.$zoomToolCover[0].sourseTop,top);
this.$zoomToolCover.css("top",top);
return;
}
//固定高度:sourseTop,指定对象:targetImg
this.$zoomToolCover.sourseTop = Z(ele).offsetTop();
this.$zoomToolCover.targetImg = ele;
//确定缩放容器的大小和位置
scrollTop = this.$editor[0].scrollTop;
var width = Z(ele).offsetWidth();
var height = Z(ele).offsetHeight();
var left = Z(ele).offsetLeft();
top = Z(ele).offsetTop() - scrollTop;
this.$zoomToolCover.css({"width":width,"height":height,"left":left,"top":top,});
},
insertSymbolHtml: function(symbolArr)
{//11.1:插入特殊字符;返回表格字符串
var symbolNum = symbolArr.length, colNum = 15, rowNum = Math.ceil(symbolNum / colNum);
var html = '<table class="z-table"><tr>';
for (var i = 0;i < symbolNum;i++)
{//colNum 为列数;rowNum 为行数
if (i != 0 && i % colNum == 0)
html += '</tr><tr>';
html += '<td><a>' + symbolArr[i] + '</a></td>';
}
html += '</tr></table>';
return html;
},
insertSymbolConfirm: function(e)
{//11.2:插入特殊符号,执行插入功能
//载入选区
this.loadSelection();
var insertSymbol = Z(Z.E.target(e)).text();
document.execCommand("insertText",false,insertSymbol);
//去除遮罩
Z.Dialog.close();
//存储选区、存储历史
this.saveHistory();
},
}
//end
})(zhiqim)