{"version":3,"sources":["wangEditor.js"],"names":["global","factory","exports","module","define","amd","wangEditor","this","createElemByHTML","html","div","document","createElement","innerHTML","children","isDOMList","selector","HTMLCollection","NodeList","querySelectorAll","result","DomElement","selectorResult","nodeType","replace","trim","indexOf","length","i","$","objForEach","obj","fn","key","hasOwnProperty","call","arrForEach","fakeArr","item","getRandom","prefix","Math","random","toString","slice","replaceHtmlSymbol","Bold","editor","$elem","type","_active","DropList","menu","opt","_this","$container","$title","addClass","append","list","onClick","_emptyFn","$list","forEach","value","$li","on","e","hideTimeoutId","setTimeout","hide","_rendered","_show","Head","droplist","width","_command","Panel","Link","Italic","Redo","StrikeThrough","Underline","Undo","List","Justify","BackColor","ForeColor$1","Quote","Code","Emoticon","Table","Video","Image","Menus","menus","getPasteText","clipboardData","originalEvent","pasteText","window","getData","getPasteHtml","pasteHtml","docSplitHtml","split","getPasteImgs","items","test","push","getAsFile","Text","Command","API","_currentRange","Progress","_time","_isShow","_isRender","_timeoutId","$textContainer","$textContainerElem","$bar","UploadImg","Editor","toolbarSelector","textSelector","Error","id","editorId","customConfig","prototype","constructor","elem","get","index","first","last","types","addEventListener","target","matches","off","removeEventListener","attr","val","getAttribute","setAttribute","className","arr","filter","join","removeClass","css","currentStyle","style","styleArr","resultArr","map","show","$children","child","appendChild","remove","parent","parentElement","removeChild","isContain","$child","contains","getSizeData","getBoundingClientRect","getNodeName","nodeName","find","text","focus","parentUntil","_currentElem","results","equal","insertBefore","$referenceNode","referenceNode","parentNode","insertAfter","lastChild","nextSibling","config","zIndex","debug","showLinkImg","uploadImgMaxSize","uploadImgShowBase64","uploadFileName","uploadImgParams","token","uploadImgHeaders","withCredentials","uploadImgTimeout","uploadImgHooks","before","xhr","files","success","fail","error","timeout","UA","_ua","navigator","userAgent","isWebkit","isIE","isSeleEmpty","selection","isSelectionEmpty","createEmptyRange","cmd","do","collapseRange","restoreSelection","tryChangeActive","queryCommandState","clearTimeout","$menuELem","menuHeight","height","showTimeoutId","reg","cmdValue","queryCommandValue","emptyFn","_isCreatedPanelMenus","$body","$closeBtn","$tabTitleContainer","$tabContentContainer","tabs","tabTitleArr","tabContentArr","tab","tabIndex","title","tpl","$content","_index","stopPropagation","events","event","$inputs","_hideOtherPanels","panel","$linkelem","getSelectionContainerElem","createRangeByElem","_createPanel","getSelectionText","link","inputLinkId","inputTextId","btnOkId","btnDelId","delBtnDisplay","$link","$text","_insertLink","_delLink","selectionText","$selectionELem","$textElem","$selectionElem","$parent","$startElem","getSelectionStartElem","$endElem","getSelectionEndElem","$code","textId","btnId","_insertCode","_updateCode","$parentElem","faceHtml","handHtml","_insert","emoji","_createEditPanel","_createInsertPanel","btnInsertId","textRowNum","textColNum","rowNum","parseInt","colNum","r","c","_this2","addRowBtnId","addColBtnId","delRowBtnId","delColBtnId","delTableBtnId","_addRow","_addCol","_delRow","_delCol","_delTable","_getLocationData","$tr","$tds","tdLength","td","$tbody","$trs","trLength","tr","locationData","trData","$currentTr","tdData","newTr","tdIndex","$currentTd","name","toLowerCase","$table","textValId","width30","width50","width100","delBtn","tabsConfig","$img","_selectedImg","uploadImg","upTriggerId","upFileId","linkUrlId","linkBtnId","$file","fileElem","click","fileList","$linkUrl","url","insertLinkImg","tabsConfigResult","uploadImgServer","FileReader","MenuConstructors","bold","head","italic","redo","strikeThrough","underline","undo","justify","foreColor","backColor","quote","code","emoticon","table","video","image","init","menuKey","MenuConstructor","_addToToolbar","_bindEvent","$toolbarElem","getRange","changeActive","clear","initSelection","_saveRangeRealTime","_enterKeyHandle","_clearHandle","_pasteHandle","_tabHandle","_imgHandle","saveRange","pHandle","$p","codeHandle","selectionNodeName","parentNodeName","queryCommandSupported","_startOffset","startOffset","preventDefault","keyCode","txtHtml","ex","pasteFiles","img","_name","_execCommand","change","_insertHTML","range","insertNode","deleteContents","pasteHTML","_insertElem","execCommand","_range","getSelection","rangeCount","getRangeAt","$containerElem","toStart","collapse","commonAncestorContainer","startContainer","endContainer","endOffset","removeAllRanges","addRange","setEnd","isContent","createRange","selectNodeContents","selectNode","progress","Date","now","timeoutId","_hide","_typeof","Symbol","iterator","_alert","alertInfo","debugInfo","alert","onload","onerror","onabort","src","_this3","maxSize","maxSizeM","maxLength","uploadImgMaxLength","hooks","resultFiles","errInfo","file","size","formdata","FormData","uploadImgServerArr","uploadImgServerHash","encodeURIComponent","XMLHttpRequest","open","ontimeout","upload","onprogress","percent","progressBar","lengthComputable","loaded","total","onreadystatechange","readyState","status","responseText","JSON","parse","customInsert","errno","bind","data","setRequestHeader","send","reader","readAsDataURL","_initConfig","Object","assign","_initDom","$toolbarSelector","config$$1","_initCommand","_initSelectionAPI","_initUploadImg","_initMenus","_initText","txt","$last","onChangeTimeoutId","beforeChangeHtml","onchange","currentHtml","create","varArgs","TypeError","to","arguments","nextSource","nextKey","Element","matchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","webkitMatchesSelector","s","ownerDocument","getElementsByTagName"],"mappings":"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","file":"wangEditor.min.js","sourcesContent":["(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n\ttypeof define === 'function' && define.amd ? define(factory) :\n\t(global.wangEditor = factory());\n}(this, (function () { 'use strict';\n\n/*\n poly-fill\n*/\n\nvar polyfill = function () {\n\n // Object.assign\n if (typeof Object.assign != 'function') {\n Object.assign = function (target, varArgs) {\n // .length of function is 2\n if (target == null) {\n // TypeError if undefined or null\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n var to = Object(target);\n\n for (var index = 1; index < arguments.length; index++) {\n var nextSource = arguments[index];\n\n if (nextSource != null) {\n // Skip over if undefined or null\n for (var nextKey in nextSource) {\n // Avoid bugs when hasOwnProperty is shadowed\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n }\n\n // IE 中兼容 Element.prototype.matches\n if (!Element.prototype.matches) {\n Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector || function (s) {\n var matches = (this.document || this.ownerDocument).querySelectorAll(s),\n i = matches.length;\n while (--i >= 0 && matches.item(i) !== this) {}\n return i > -1;\n };\n }\n};\n\n/*\n DOM 操作 API\n*/\n\n// 根据 html 代码片段创建 dom 对象\nfunction createElemByHTML(html) {\n var div = void 0;\n div = document.createElement('div');\n div.innerHTML = html;\n return div.children;\n}\n\n// 是否是 DOM List\nfunction isDOMList(selector) {\n if (!selector) {\n return false;\n }\n if (selector instanceof HTMLCollection || selector instanceof NodeList) {\n return true;\n }\n return false;\n}\n\n// 封装 document.querySelectorAll\nfunction querySelectorAll(selector) {\n var result = document.querySelectorAll(selector);\n if (isDOMList(result)) {\n return result;\n } else {\n return [result];\n }\n}\n\n// 创建构造函数\nfunction DomElement(selector) {\n if (!selector) {\n return;\n }\n\n // selector 本来就是 DomElement 对象,直接返回\n if (selector instanceof DomElement) {\n return selector;\n }\n\n this.selector = selector;\n\n // 根据 selector 得出的结果(如 DOM,DOM List)\n var selectorResult = [];\n if (selector.nodeType === 1) {\n // 单个 DOM 节点\n selectorResult = [selector];\n } else if (isDOMList(selector)) {\n // DOM List\n selectorResult = selector;\n } else if (typeof selector === 'string') {\n // 字符串\n selector = selector.replace('/\\n/mg', '').trim();\n if (selector.indexOf('<') === 0) {\n // 如
\n selectorResult = createElemByHTML(selector);\n } else {\n // 如 #id .class\n selectorResult = querySelectorAll(selector);\n }\n }\n\n var length = selectorResult.length;\n if (!length) {\n // 空数组\n return this;\n }\n\n // 加入 DOM 节点\n var i = void 0;\n for (i = 0; i < length; i++) {\n this[i] = selectorResult[i];\n }\n this.length = length;\n}\n\n// 修改原型\nDomElement.prototype = {\n constructor: DomElement,\n\n // 类数组,forEach\n forEach: function forEach(fn) {\n var i = void 0;\n for (i = 0; i < this.length; i++) {\n var elem = this[i];\n var result = fn.call(elem, elem, i);\n if (result === false) {\n break;\n }\n }\n return this;\n },\n\n // 获取第几个元素\n get: function get(index) {\n var length = this.length;\n if (index >= length) {\n index = index % length;\n }\n return $(this[index]);\n },\n\n // 第一个\n first: function first() {\n return this.get(0);\n },\n\n // 最后一个\n last: function last() {\n var length = this.length;\n return this.get(length - 1);\n },\n\n // 绑定事件\n on: function on(type, selector, fn) {\n // selector 不为空,证明绑定事件要加代理\n if (!fn) {\n fn = selector;\n selector = null;\n }\n\n // type 是否有多个\n var types = [];\n types = type.split(/\\s+/);\n\n return this.forEach(function (elem) {\n types.forEach(function (type) {\n if (!type) {\n return;\n }\n\n if (!selector) {\n // 无代理\n elem.addEventListener(type, fn, false);\n return;\n }\n\n // 有代理\n elem.addEventListener(type, function (e) {\n var target = e.target;\n if (target.matches(selector)) {\n fn.call(target, e);\n }\n }, false);\n });\n });\n },\n\n // 取消事件绑定\n off: function off(type, fn) {\n return this.forEach(function (elem) {\n elem.removeEventListener(type, fn, false);\n });\n },\n\n // 获取/设置 属性\n attr: function attr(key, val) {\n if (val == null) {\n // 获取值\n return this[0].getAttribute(key);\n } else {\n // 设置值\n return this.forEach(function (elem) {\n elem.setAttribute(key, val);\n });\n }\n },\n\n // 添加 class\n addClass: function addClass(className) {\n if (!className) {\n return this;\n }\n return this.forEach(function (elem) {\n var arr = void 0;\n if (elem.className) {\n // 解析当前 className 转换为数组\n arr = elem.className.split(/\\s/);\n arr = arr.filter(function (item) {\n return !!item.trim();\n });\n // 添加 class\n if (arr.indexOf(className) < 0) {\n arr.push(className);\n }\n // 修改 elem.class\n elem.className = arr.join(' ');\n } else {\n elem.className = className;\n }\n });\n },\n\n // 删除 class\n removeClass: function removeClass(className) {\n if (!className) {\n return this;\n }\n return this.forEach(function (elem) {\n var arr = void 0;\n if (elem.className) {\n // 解析当前 className 转换为数组\n arr = elem.className.split(/\\s/);\n arr = arr.filter(function (item) {\n item = item.trim();\n // 删除 class\n if (!item || item === className) {\n return false;\n }\n return true;\n });\n // 修改 elem.class\n elem.className = arr.join(' ');\n }\n });\n },\n\n // 修改 css\n css: function css(key, val) {\n var currentStyle = key + ':' + val + ';';\n return this.forEach(function (elem) {\n var style = (elem.getAttribute('style') || '').trim();\n var styleArr = void 0,\n resultArr = [];\n if (style) {\n // 将 style 按照 ; 拆分为数组\n styleArr = style.split(';');\n styleArr.forEach(function (item) {\n // 对每项样式,按照 : 拆分为 key 和 value\n var arr = item.split(':').map(function (i) {\n return i.trim();\n });\n if (arr.length === 2) {\n resultArr.push(arr[0] + ':' + arr[1]);\n }\n });\n // 替换或者新增\n resultArr = resultArr.map(function (item) {\n if (item.indexOf(key) === 0) {\n return currentStyle;\n } else {\n return item;\n }\n });\n if (resultArr.indexOf(currentStyle) < 0) {\n resultArr.push(currentStyle);\n }\n // 结果\n elem.setAttribute('style', resultArr.join('; '));\n } else {\n // style 无值\n elem.setAttribute('style', currentStyle);\n }\n });\n },\n\n // 显示\n show: function show() {\n return this.css('display', 'block');\n },\n\n // 隐藏\n hide: function hide() {\n return this.css('display', 'none');\n },\n\n // 获取子节点\n children: function children() {\n var elem = this[0];\n if (!elem) {\n return null;\n }\n\n return $(elem.children);\n },\n\n // 增加子节点\n append: function append($children) {\n return this.forEach(function (elem) {\n $children.forEach(function (child) {\n elem.appendChild(child);\n });\n });\n },\n\n // 移除当前节点\n remove: function remove() {\n return this.forEach(function (elem) {\n if (elem.remove) {\n elem.remove();\n } else {\n var parent = elem.parentElement;\n parent && parent.removeChild(elem);\n }\n });\n },\n\n // 是否包含某个子节点\n isContain: function isContain($child) {\n var elem = this[0];\n var child = $child[0];\n return elem.contains(child);\n },\n\n // 尺寸数据\n getSizeData: function getSizeData() {\n var elem = this[0];\n return elem.getBoundingClientRect(); // 可得到 bottom height left right top width 的数据\n },\n\n // 封装 nodeName\n getNodeName: function getNodeName() {\n var elem = this[0];\n return elem.nodeName;\n },\n\n // 从当前元素查找\n find: function find(selector) {\n var elem = this[0];\n return $(elem.querySelectorAll(selector));\n },\n\n // 获取当前元素的 text\n text: function text(val) {\n if (!val) {\n // 获取 text\n var elem = this[0];\n return elem.innerHTML.replace(/<.*?>/g, function () {\n return '';\n });\n } else {\n // 设置 text\n return this.forEach(function (elem) {\n elem.innerHTML = val;\n });\n }\n },\n\n // 获取 html\n html: function html(value) {\n var elem = this[0];\n if (value == null) {\n return elem.innerHTML;\n } else {\n elem.innerHTML = value;\n return this;\n }\n },\n\n // 获取 value\n val: function val() {\n var elem = this[0];\n return elem.value.trim();\n },\n\n // focus\n focus: function focus() {\n return this.forEach(function (elem) {\n elem.focus();\n });\n },\n\n // parent\n parent: function parent() {\n var elem = this[0];\n return $(elem.parentElement);\n },\n\n // parentUntil 找到符合 selector 的父节点\n parentUntil: function parentUntil(selector, _currentElem) {\n var results = document.querySelectorAll(selector);\n var length = results.length;\n if (!length) {\n // 传入的 selector 无效\n return null;\n }\n\n var elem = _currentElem || this[0];\n if (elem.nodeName === 'BODY') {\n return null;\n }\n\n var parent = elem.parentElement;\n var i = void 0;\n for (i = 0; i < length; i++) {\n if (parent === results[i]) {\n // 找到,并返回\n return $(parent);\n }\n }\n\n // 继续查找\n return this.parentUntil(selector, parent);\n },\n\n // 判断两个 elem 是否相等\n equal: function equal($elem) {\n if ($elem.nodeType === 1) {\n return this[0] === $elem;\n } else {\n return this[0] === $elem[0];\n }\n },\n\n // 将该元素插入到某个元素前面\n insertBefore: function insertBefore(selector) {\n var $referenceNode = $(selector);\n var referenceNode = $referenceNode[0];\n if (!referenceNode) {\n return this;\n }\n return this.forEach(function (elem) {\n var parent = referenceNode.parentNode;\n parent.insertBefore(elem, referenceNode);\n });\n },\n\n // 将该元素插入到某个元素后面\n insertAfter: function insertAfter(selector) {\n var $referenceNode = $(selector);\n var referenceNode = $referenceNode[0];\n if (!referenceNode) {\n return this;\n }\n return this.forEach(function (elem) {\n var parent = referenceNode.parentNode;\n if (parent.lastChild === referenceNode) {\n // 最后一个元素\n parent.appendChild(elem);\n } else {\n // 不是最后一个元素\n parent.insertBefore(elem, referenceNode.nextSibling);\n }\n });\n }\n};\n\n// new 一个对象\nfunction $(selector) {\n return new DomElement(selector);\n}\n\n/*\n 配置信息\n*/\n\nvar config = {\n\n // 默认菜单配置\n menus: ['head', 'bold', 'italic', 'underline', 'strikeThrough', 'foreColor', 'backColor', 'link', 'list', 'justify', 'quote', 'emoticon', 'image', 'table', 'video', 'code', 'undo', 'redo'],\n\n // 编辑区域的 z-index\n zIndex: 10000,\n\n // 是否开启 debug 模式(debug 模式下错误会 throw error 形式抛出)\n debug: false,\n\n // onchange 事件\n // onchange: function (html) {\n // // html 即变化之后的内容\n // console.log(html)\n // },\n\n // 是否显示添加网络图片的 tab\n showLinkImg: true,\n\n // 默认上传图片 max size: 5M\n uploadImgMaxSize: 5 * 1024 * 1024,\n\n // 配置一次最多上传几个图片\n // uploadImgMaxLength: 5,\n\n // 上传图片,是否显示 base64 格式\n uploadImgShowBase64: false,\n\n // 上传图片,server 地址(如果有值,则 base64 格式的配置则失效)\n // uploadImgServer: '/upload',\n\n // 自定义配置 filename\n uploadFileName: '',\n\n // 上传图片的自定义参数\n uploadImgParams: {\n token: 'abcdef12345'\n },\n\n // 上传图片的自定义header\n uploadImgHeaders: {\n // 'Accept': 'text/x-json'\n },\n\n // 配置 XHR withCredentials\n withCredentials: false,\n\n // 自定义上传图片超时时间 ms\n uploadImgTimeout: 5000,\n\n // 上传图片 hook \n uploadImgHooks: {\n // customInsert: function (insertLinkImg, result, editor) {\n // console.log('customInsert')\n // // 图片上传并返回结果,自定义插入图片的事件,而不是编辑器自动插入图片\n // const data = result.data1 || []\n // data.forEach(link => {\n // insertLinkImg(link)\n // })\n // },\n before: function before(xhr, editor, files) {\n // 图片上传之前触发\n },\n success: function success(xhr, editor, result) {\n // 图片上传并返回结果,图片插入成功之后触发\n },\n fail: function fail(xhr, editor, result) {\n // 图片上传并返回结果,但图片插入错误时触发\n },\n error: function error(xhr, editor) {\n // 图片上传出错时触发\n },\n timeout: function timeout(xhr, editor) {\n // 图片上传超时时触发\n }\n }\n};\n\n/*\n 工具\n*/\n\n// 和 UA 相关的属性\nvar UA = {\n _ua: navigator.userAgent,\n\n // 是否 webkit\n isWebkit: function isWebkit() {\n var reg = /webkit/i;\n return reg.test(this._ua);\n },\n\n // 是否 IE\n isIE: function isIE() {\n return 'ActiveXObject' in window;\n }\n};\n\n// 遍历对象\nfunction objForEach(obj, fn) {\n var key = void 0,\n result = void 0;\n for (key in obj) {\n if (obj.hasOwnProperty(key)) {\n result = fn.call(obj, key, obj[key]);\n if (result === false) {\n break;\n }\n }\n }\n}\n\n// 遍历类数组\nfunction arrForEach(fakeArr, fn) {\n var i = void 0,\n item = void 0,\n result = void 0;\n var length = fakeArr.length || 0;\n for (i = 0; i < length; i++) {\n item = fakeArr[i];\n result = fn.call(fakeArr, item, i);\n if (result === false) {\n break;\n }\n }\n}\n\n// 获取随机数\nfunction getRandom(prefix) {\n return prefix + Math.random().toString().slice(2);\n}\n\n// 替换 html 特殊字符\nfunction replaceHtmlSymbol(html) {\n if (html == null) {\n return '';\n }\n return html.replace(//gm, '>').replace(/\"/gm, '"');\n}\n\n// 返回百分比的格式\n\n/*\n bold-menu\n*/\n// 构造函数\nfunction Bold(editor) {\n this.editor = editor;\n this.$elem = $('
\\n \\n
');\n this.type = 'click';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nBold.prototype = {\n constructor: Bold,\n\n // 点击事件\n onClick: function onClick(e) {\n // 点击菜单将触发这里\n\n var editor = this.editor;\n var isSeleEmpty = editor.selection.isSelectionEmpty();\n\n if (isSeleEmpty) {\n // 选区是空的,插入并选中一个“空白”\n editor.selection.createEmptyRange();\n }\n\n // 执行 bold 命令\n editor.cmd.do('bold');\n\n if (isSeleEmpty) {\n // 需要将选取折叠起来\n editor.selection.collapseRange();\n editor.selection.restoreSelection();\n }\n },\n\n // 试图改变 active 状态\n tryChangeActive: function tryChangeActive(e) {\n var editor = this.editor;\n var $elem = this.$elem;\n if (editor.cmd.queryCommandState('bold')) {\n this._active = true;\n $elem.addClass('w-e-active');\n } else {\n this._active = false;\n $elem.removeClass('w-e-active');\n }\n }\n};\n\n/*\n droplist\n*/\nvar _emptyFn = function _emptyFn() {};\n\n// 构造函数\nfunction DropList(menu, opt) {\n var _this = this;\n\n // droplist 所依附的菜单\n this.menu = menu;\n this.opt = opt;\n // 容器\n var $container = $('
');\n\n // 标题\n var $title = opt.$title;\n if ($title) {\n $title.addClass('w-e-dp-title');\n $container.append($title);\n }\n\n var list = opt.list || [];\n var type = opt.type || 'list'; // 'list' 列表形式(如“标题”菜单) / 'inline-block' 块状形式(如“颜色”菜单)\n var onClick = opt.onClick || _emptyFn;\n\n // 加入 DOM 并绑定事件\n var $list = $('
    ');\n $container.append($list);\n list.forEach(function (item) {\n var $elem = item.$elem;\n var value = item.value;\n var $li = $('
  • ');\n if ($elem) {\n $li.append($elem);\n $list.append($li);\n $elem.on('click', function (e) {\n onClick(value);\n\n // 隐藏\n _this.hideTimeoutId = setTimeout(function () {\n _this.hide();\n }, 0);\n });\n }\n });\n\n // 绑定隐藏事件\n $container.on('mouseleave', function (e) {\n _this.hideTimeoutId = setTimeout(function () {\n _this.hide();\n }, 0);\n });\n\n // 记录属性\n this.$container = $container;\n\n // 基本属性\n this._rendered = false;\n this._show = false;\n}\n\n// 原型\nDropList.prototype = {\n constructor: DropList,\n\n // 显示(插入DOM)\n show: function show() {\n if (this.hideTimeoutId) {\n // 清除之前的定时隐藏\n clearTimeout(this.hideTimeoutId);\n }\n\n var menu = this.menu;\n var $menuELem = menu.$elem;\n var $container = this.$container;\n if (this._show) {\n return;\n }\n if (this._rendered) {\n // 显示\n $container.show();\n } else {\n // 加入 DOM 之前先定位位置\n var menuHeight = $menuELem.getSizeData().height || 0;\n var width = this.opt.width || 100; // 默认为 100\n $container.css('margin-top', menuHeight + 'px').css('width', width + 'px');\n\n // 加入到 DOM\n $menuELem.append($container);\n this._rendered = true;\n }\n\n // 修改属性\n this._show = true;\n },\n\n // 隐藏(移除DOM)\n hide: function hide() {\n if (this.showTimeoutId) {\n // 清除之前的定时显示\n clearTimeout(this.showTimeoutId);\n }\n\n var $container = this.$container;\n if (!this._show) {\n return;\n }\n // 隐藏并需改属性\n $container.hide();\n this._show = false;\n }\n};\n\n/*\n menu - header\n*/\n// 构造函数\nfunction Head(editor) {\n var _this = this;\n\n this.editor = editor;\n this.$elem = $('
    ');\n this.type = 'droplist';\n\n // 当前是否 active 状态\n this._active = false;\n\n // 初始化 droplist\n this.droplist = new DropList(this, {\n width: 100,\n $title: $('

    设置标题

    '),\n type: 'list', // droplist 以列表形式展示\n list: [{ $elem: $('

    H1

    '), value: '

    ' }, { $elem: $('

    H2

    '), value: '

    ' }, { $elem: $('

    H3

    '), value: '

    ' }, { $elem: $('

    H4

    '), value: '

    ' }, { $elem: $('

    H5
    '), value: '
    ' }, { $elem: $('

    正文

    '), value: '

    ' }],\n onClick: function onClick(value) {\n // 注意 this 是指向当前的 Head 对象\n _this._command(value);\n }\n });\n}\n\n// 原型\nHead.prototype = {\n constructor: Head,\n\n // 执行命令\n _command: function _command(value) {\n var editor = this.editor;\n editor.cmd.do('formatBlock', value);\n },\n\n // 试图改变 active 状态\n tryChangeActive: function tryChangeActive(e) {\n var editor = this.editor;\n var $elem = this.$elem;\n var reg = /^h/i;\n var cmdValue = editor.cmd.queryCommandValue('formatBlock');\n if (reg.test(cmdValue)) {\n this._active = true;\n $elem.addClass('w-e-active');\n } else {\n this._active = false;\n $elem.removeClass('w-e-active');\n }\n }\n};\n\n/*\n panel\n*/\n\nvar emptyFn = function emptyFn() {};\n\n// 记录已经显示 panel 的菜单\nvar _isCreatedPanelMenus = [];\n\n// 构造函数\nfunction Panel(menu, opt) {\n this.menu = menu;\n this.opt = opt;\n}\n\n// 原型\nPanel.prototype = {\n constructor: Panel,\n\n // 显示(插入DOM)\n show: function show() {\n var _this = this;\n\n var menu = this.menu;\n if (_isCreatedPanelMenus.indexOf(menu) >= 0) {\n // 该菜单已经创建了 panel 不能再创建\n return;\n }\n\n var editor = menu.editor;\n var $body = $('body');\n var $textContainerElem = editor.$textContainerElem;\n var opt = this.opt;\n\n // panel 的容器\n var $container = $('

    ');\n var width = opt.width || 300; // 默认 300px\n $container.css('width', width + 'px').css('margin-left', (0 - width) / 2 + 'px');\n\n // 添加关闭按钮\n var $closeBtn = $('');\n $container.append($closeBtn);\n $closeBtn.on('click', function () {\n _this.hide();\n });\n\n // 准备 tabs 容器\n var $tabTitleContainer = $('
      ');\n var $tabContentContainer = $('
      ');\n $container.append($tabTitleContainer).append($tabContentContainer);\n\n // 设置高度\n var height = opt.height;\n if (height) {\n $tabContentContainer.css('height', height + 'px').css('overflow-y', 'auto');\n }\n\n // tabs\n var tabs = opt.tabs || [];\n var tabTitleArr = [];\n var tabContentArr = [];\n tabs.forEach(function (tab, tabIndex) {\n if (!tab) {\n return;\n }\n var title = tab.title || '';\n var tpl = tab.tpl || '';\n\n // 添加到 DOM\n var $title = $('
    • ' + title + '
    • ');\n $tabTitleContainer.append($title);\n var $content = $(tpl);\n $tabContentContainer.append($content);\n\n // 记录到内存\n $title._index = tabIndex;\n tabTitleArr.push($title);\n tabContentArr.push($content);\n\n // 设置 active 项\n if (tabIndex === 0) {\n $title._active = true;\n $title.addClass('w-e-active');\n } else {\n $content.hide();\n }\n\n // 绑定 tab 的事件\n $title.on('click', function (e) {\n if ($title._active) {\n return;\n }\n // 隐藏所有的 tab\n tabTitleArr.forEach(function ($title) {\n $title._active = false;\n $title.removeClass('w-e-active');\n });\n tabContentArr.forEach(function ($content) {\n $content.hide();\n });\n\n // 显示当前的 tab\n $title._active = true;\n $title.addClass('w-e-active');\n $content.show();\n });\n });\n\n // 绑定关闭事件\n $container.on('click', function (e) {\n // 点击时阻止冒泡\n e.stopPropagation();\n });\n $body.on('click', function (e) {\n _this.hide();\n });\n\n // 添加到 DOM\n $textContainerElem.append($container);\n\n // 绑定 opt 的事件,只有添加到 DOM 之后才能绑定成功\n tabs.forEach(function (tab, index) {\n if (!tab) {\n return;\n }\n var events = tab.events || [];\n events.forEach(function (event) {\n var selector = event.selector;\n var type = event.type;\n var fn = event.fn || emptyFn;\n var $content = tabContentArr[index];\n $content.find(selector).on(type, function (e) {\n e.stopPropagation();\n var needToHide = fn(e);\n // 执行完事件之后,是否要关闭 panel\n if (needToHide) {\n _this.hide();\n }\n });\n });\n });\n\n // focus 第一个 elem\n var $inputs = $container.find('input[type=text],textarea');\n if ($inputs.length) {\n $inputs.get(0).focus();\n }\n\n // 添加到属性\n this.$container = $container;\n\n // 隐藏其他 panel\n this._hideOtherPanels();\n // 记录该 menu 已经创建了 panel\n _isCreatedPanelMenus.push(menu);\n },\n\n // 隐藏(移除DOM)\n hide: function hide() {\n var menu = this.menu;\n var $container = this.$container;\n if ($container) {\n $container.remove();\n }\n\n // 将该 menu 记录中移除\n _isCreatedPanelMenus = _isCreatedPanelMenus.filter(function (item) {\n if (item === menu) {\n return false;\n } else {\n return true;\n }\n });\n },\n\n // 一个 panel 展示时,隐藏其他 panel\n _hideOtherPanels: function _hideOtherPanels() {\n if (!_isCreatedPanelMenus.length) {\n return;\n }\n _isCreatedPanelMenus.forEach(function (menu) {\n var panel = menu.panel || {};\n if (panel.hide) {\n panel.hide();\n }\n });\n }\n};\n\n/*\n menu - link\n*/\n// 构造函数\nfunction Link(editor) {\n this.editor = editor;\n this.$elem = $('
      ');\n this.type = 'panel';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nLink.prototype = {\n constructor: Link,\n\n // 点击事件\n onClick: function onClick(e) {\n var editor = this.editor;\n var $linkelem = void 0;\n\n if (this._active) {\n // 当前选区在链接里面\n $linkelem = editor.selection.getSelectionContainerElem();\n if (!$linkelem) {\n return;\n }\n // 将该元素都包含在选取之内,以便后面整体替换\n editor.selection.createRangeByElem($linkelem);\n editor.selection.restoreSelection();\n // 显示 panel\n this._createPanel($linkelem.text(), $linkelem.attr('href'));\n } else {\n // 当前选区不在链接里面\n if (editor.selection.isSelectionEmpty()) {\n // 选区是空的,未选中内容\n this._createPanel('', '');\n } else {\n // 选中内容了\n this._createPanel(editor.selection.getSelectionText(), '');\n }\n }\n },\n\n // 创建 panel\n _createPanel: function _createPanel(text, link) {\n var _this = this;\n\n // panel 中需要用到的id\n var inputLinkId = getRandom('input-link');\n var inputTextId = getRandom('input-text');\n var btnOkId = getRandom('btn-ok');\n var btnDelId = getRandom('btn-del');\n\n // 是否显示“删除链接”\n var delBtnDisplay = this._active ? 'inline-block' : 'none';\n\n // 初始化并显示 panel\n var panel = new Panel(this, {\n width: 300,\n // panel 中可包含多个 tab\n tabs: [{\n // tab 的标题\n title: '链接',\n // 模板\n tpl: '
      \\n \\n \\n
      \\n \\n \\n
      \\n
      ',\n // 事件绑定\n events: [\n // 插入链接\n {\n selector: '#' + btnOkId,\n type: 'click',\n fn: function fn() {\n // 执行插入链接\n var $link = $('#' + inputLinkId);\n var $text = $('#' + inputTextId);\n var link = $link.val();\n var text = $text.val();\n _this._insertLink(text, link);\n\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n },\n // 删除链接\n {\n selector: '#' + btnDelId,\n type: 'click',\n fn: function fn() {\n // 执行删除链接\n _this._delLink();\n\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }]\n } // tab end\n ] // tabs end\n });\n\n // 显示 panel\n panel.show();\n\n // 记录属性\n this.panel = panel;\n },\n\n // 删除当前链接\n _delLink: function _delLink() {\n if (!this._active) {\n return;\n }\n var editor = this.editor;\n var $selectionELem = editor.selection.getSelectionContainerElem();\n if (!$selectionELem) {\n return;\n }\n var selectionText = editor.selection.getSelectionText();\n editor.cmd.do('insertHTML', '' + selectionText + '');\n },\n\n // 插入链接\n _insertLink: function _insertLink(text, link) {\n if (!text || !link) {\n return;\n }\n var editor = this.editor;\n editor.cmd.do('insertHTML', '' + text + '');\n },\n\n // 试图改变 active 状态\n tryChangeActive: function tryChangeActive(e) {\n var editor = this.editor;\n var $elem = this.$elem;\n var $selectionELem = editor.selection.getSelectionContainerElem();\n if (!$selectionELem) {\n return;\n }\n if ($selectionELem.getNodeName() === 'A') {\n this._active = true;\n $elem.addClass('w-e-active');\n } else {\n this._active = false;\n $elem.removeClass('w-e-active');\n }\n }\n};\n\n/*\n italic-menu\n*/\n// 构造函数\nfunction Italic(editor) {\n this.editor = editor;\n this.$elem = $('
      \\n \\n
      ');\n this.type = 'click';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nItalic.prototype = {\n constructor: Italic,\n\n // 点击事件\n onClick: function onClick(e) {\n // 点击菜单将触发这里\n\n var editor = this.editor;\n var isSeleEmpty = editor.selection.isSelectionEmpty();\n\n if (isSeleEmpty) {\n // 选区是空的,插入并选中一个“空白”\n editor.selection.createEmptyRange();\n }\n\n // 执行 italic 命令\n editor.cmd.do('italic');\n\n if (isSeleEmpty) {\n // 需要将选取折叠起来\n editor.selection.collapseRange();\n editor.selection.restoreSelection();\n }\n },\n\n // 试图改变 active 状态\n tryChangeActive: function tryChangeActive(e) {\n var editor = this.editor;\n var $elem = this.$elem;\n if (editor.cmd.queryCommandState('italic')) {\n this._active = true;\n $elem.addClass('w-e-active');\n } else {\n this._active = false;\n $elem.removeClass('w-e-active');\n }\n }\n};\n\n/*\n redo-menu\n*/\n// 构造函数\nfunction Redo(editor) {\n this.editor = editor;\n this.$elem = $('
      \\n \\n
      ');\n this.type = 'click';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nRedo.prototype = {\n constructor: Redo,\n\n // 点击事件\n onClick: function onClick(e) {\n // 点击菜单将触发这里\n\n var editor = this.editor;\n\n // 执行 redo 命令\n editor.cmd.do('redo');\n }\n};\n\n/*\n strikeThrough-menu\n*/\n// 构造函数\nfunction StrikeThrough(editor) {\n this.editor = editor;\n this.$elem = $('
      \\n \\n
      ');\n this.type = 'click';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nStrikeThrough.prototype = {\n constructor: StrikeThrough,\n\n // 点击事件\n onClick: function onClick(e) {\n // 点击菜单将触发这里\n\n var editor = this.editor;\n var isSeleEmpty = editor.selection.isSelectionEmpty();\n\n if (isSeleEmpty) {\n // 选区是空的,插入并选中一个“空白”\n editor.selection.createEmptyRange();\n }\n\n // 执行 strikeThrough 命令\n editor.cmd.do('strikeThrough');\n\n if (isSeleEmpty) {\n // 需要将选取折叠起来\n editor.selection.collapseRange();\n editor.selection.restoreSelection();\n }\n },\n\n // 试图改变 active 状态\n tryChangeActive: function tryChangeActive(e) {\n var editor = this.editor;\n var $elem = this.$elem;\n if (editor.cmd.queryCommandState('strikeThrough')) {\n this._active = true;\n $elem.addClass('w-e-active');\n } else {\n this._active = false;\n $elem.removeClass('w-e-active');\n }\n }\n};\n\n/*\n underline-menu\n*/\n// 构造函数\nfunction Underline(editor) {\n this.editor = editor;\n this.$elem = $('
      \\n \\n
      ');\n this.type = 'click';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nUnderline.prototype = {\n constructor: Underline,\n\n // 点击事件\n onClick: function onClick(e) {\n // 点击菜单将触发这里\n\n var editor = this.editor;\n var isSeleEmpty = editor.selection.isSelectionEmpty();\n\n if (isSeleEmpty) {\n // 选区是空的,插入并选中一个“空白”\n editor.selection.createEmptyRange();\n }\n\n // 执行 underline 命令\n editor.cmd.do('underline');\n\n if (isSeleEmpty) {\n // 需要将选取折叠起来\n editor.selection.collapseRange();\n editor.selection.restoreSelection();\n }\n },\n\n // 试图改变 active 状态\n tryChangeActive: function tryChangeActive(e) {\n var editor = this.editor;\n var $elem = this.$elem;\n if (editor.cmd.queryCommandState('underline')) {\n this._active = true;\n $elem.addClass('w-e-active');\n } else {\n this._active = false;\n $elem.removeClass('w-e-active');\n }\n }\n};\n\n/*\n undo-menu\n*/\n// 构造函数\nfunction Undo(editor) {\n this.editor = editor;\n this.$elem = $('
      \\n \\n
      ');\n this.type = 'click';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nUndo.prototype = {\n constructor: Undo,\n\n // 点击事件\n onClick: function onClick(e) {\n // 点击菜单将触发这里\n\n var editor = this.editor;\n\n // 执行 undo 命令\n editor.cmd.do('undo');\n }\n};\n\n/*\n menu - list\n*/\n// 构造函数\nfunction List(editor) {\n var _this = this;\n\n this.editor = editor;\n this.$elem = $('
      ');\n this.type = 'droplist';\n\n // 当前是否 active 状态\n this._active = false;\n\n // 初始化 droplist\n this.droplist = new DropList(this, {\n width: 120,\n $title: $('

      设置列表

      '),\n type: 'list', // droplist 以列表形式展示\n list: [{ $elem: $(' 有序列表'), value: 'insertOrderedList' }, { $elem: $(' 无序列表'), value: 'insertUnorderedList' }],\n onClick: function onClick(value) {\n // 注意 this 是指向当前的 List 对象\n _this._command(value);\n }\n });\n}\n\n// 原型\nList.prototype = {\n constructor: List,\n\n // 执行命令\n _command: function _command(value) {\n var editor = this.editor;\n var $textElem = editor.$textElem;\n editor.selection.restoreSelection();\n if (editor.cmd.queryCommandState(value)) {\n return;\n }\n editor.cmd.do(value);\n\n // 验证列表是否被包裹在

      之内\n var $selectionElem = editor.selection.getSelectionContainerElem();\n if ($selectionElem.getNodeName() === 'LI') {\n $selectionElem = $selectionElem.parent();\n }\n if (/^ol|ul$/i.test($selectionElem.getNodeName()) === false) {\n return;\n }\n if ($selectionElem.equal($textElem)) {\n // 证明是顶级标签,没有被

      包裹\n return;\n }\n var $parent = $selectionElem.parent();\n if ($parent.equal($textElem)) {\n // $parent 是顶级标签,不能删除\n return;\n }\n\n $selectionElem.insertAfter($parent);\n $parent.remove();\n },\n\n // 试图改变 active 状态\n tryChangeActive: function tryChangeActive(e) {\n var editor = this.editor;\n var $elem = this.$elem;\n if (editor.cmd.queryCommandState('insertUnOrderedList') || editor.cmd.queryCommandState('insertOrderedList')) {\n this._active = true;\n $elem.addClass('w-e-active');\n } else {\n this._active = false;\n $elem.removeClass('w-e-active');\n }\n }\n};\n\n/*\n menu - justify\n*/\n// 构造函数\nfunction Justify(editor) {\n var _this = this;\n\n this.editor = editor;\n this.$elem = $('

      ');\n this.type = 'droplist';\n\n // 当前是否 active 状态\n this._active = false;\n\n // 初始化 droplist\n this.droplist = new DropList(this, {\n width: 100,\n $title: $('

      对齐方式

      '),\n type: 'list', // droplist 以列表形式展示\n list: [{ $elem: $(' 靠左'), value: 'justifyLeft' }, { $elem: $(' 居中'), value: 'justifyCenter' }, { $elem: $(' 靠右'), value: 'justifyRight' }],\n onClick: function onClick(value) {\n // 注意 this 是指向当前的 List 对象\n _this._command(value);\n }\n });\n}\n\n// 原型\nJustify.prototype = {\n constructor: Justify,\n\n // 执行命令\n _command: function _command(value) {\n var editor = this.editor;\n editor.cmd.do(value);\n }\n};\n\n/*\n menu - backcolor\n*/\n// 构造函数\nfunction BackColor(editor) {\n var _this = this;\n\n this.editor = editor;\n this.$elem = $('
      ');\n this.type = 'droplist';\n\n // 当前是否 active 状态\n this._active = false;\n\n // 初始化 droplist\n this.droplist = new DropList(this, {\n width: 120,\n $title: $('

      文字颜色

      '),\n type: 'inline-block', // droplist 内容以 block 形式展示\n list: [{ $elem: $(''), value: '#000000' }, { $elem: $(''), value: '#eeece0' }, { $elem: $(''), value: '#1c487f' }, { $elem: $(''), value: '#4d80bf' }, { $elem: $(''), value: '#c24f4a' }, { $elem: $(''), value: '#8baa4a' }, { $elem: $(''), value: '#7b5ba1' }, { $elem: $(''), value: '#46acc8' }, { $elem: $(''), value: '#f9963b' }, { $elem: $(''), value: '#ffffff' }],\n onClick: function onClick(value) {\n // 注意 this 是指向当前的 BackColor 对象\n _this._command(value);\n }\n });\n}\n\n// 原型\nBackColor.prototype = {\n constructor: BackColor,\n\n // 执行命令\n _command: function _command(value) {\n var editor = this.editor;\n editor.cmd.do('foreColor', value);\n }\n};\n\n/*\n menu - forecolor\n*/\n// 构造函数\nfunction ForeColor$1(editor) {\n var _this = this;\n\n this.editor = editor;\n this.$elem = $('
      ');\n this.type = 'droplist';\n\n // 当前是否 active 状态\n this._active = false;\n\n // 初始化 droplist\n this.droplist = new DropList(this, {\n width: 120,\n $title: $('

      背景色

      '),\n type: 'inline-block', // droplist 内容以 block 形式展示\n list: [{ $elem: $(''), value: '#000000' }, { $elem: $(''), value: '#eeece0' }, { $elem: $(''), value: '#1c487f' }, { $elem: $(''), value: '#4d80bf' }, { $elem: $(''), value: '#c24f4a' }, { $elem: $(''), value: '#8baa4a' }, { $elem: $(''), value: '#7b5ba1' }, { $elem: $(''), value: '#46acc8' }, { $elem: $(''), value: '#f9963b' }, { $elem: $(''), value: '#ffffff' }],\n onClick: function onClick(value) {\n // 注意 this 是指向当前的 ForeColor 对象\n _this._command(value);\n }\n });\n}\n\n// 原型\nForeColor$1.prototype = {\n constructor: ForeColor$1,\n\n // 执行命令\n _command: function _command(value) {\n var editor = this.editor;\n editor.cmd.do('backColor', value);\n }\n};\n\n/*\n menu - quote\n*/\n// 构造函数\nfunction Quote(editor) {\n this.editor = editor;\n this.$elem = $('
      \\n \\n
      ');\n this.type = 'click';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nQuote.prototype = {\n constructor: Quote,\n\n onClick: function onClick(e) {\n var editor = this.editor;\n editor.cmd.do('formatBlock', '
      ');\n },\n\n tryChangeActive: function tryChangeActive(e) {\n var editor = this.editor;\n var $elem = this.$elem;\n var reg = /^BLOCKQUOTE$/i;\n var cmdValue = editor.cmd.queryCommandValue('formatBlock');\n if (reg.test(cmdValue)) {\n this._active = true;\n $elem.addClass('w-e-active');\n } else {\n this._active = false;\n $elem.removeClass('w-e-active');\n }\n }\n};\n\n/*\n menu - code\n*/\n// 构造函数\nfunction Code(editor) {\n this.editor = editor;\n this.$elem = $('
      \\n \\n
      ');\n this.type = 'panel';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nCode.prototype = {\n constructor: Code,\n\n onClick: function onClick(e) {\n var editor = this.editor;\n var $startElem = editor.selection.getSelectionStartElem();\n var $endElem = editor.selection.getSelectionEndElem();\n var isSeleEmpty = editor.selection.isSelectionEmpty();\n var selectionText = editor.selection.getSelectionText();\n var $code = void 0;\n\n if (!$startElem.equal($endElem)) {\n // 跨元素选择,不做处理\n editor.selection.restoreSelection();\n return;\n }\n if (!isSeleEmpty) {\n // 选取不是空,用 包裹即可\n $code = $('' + selectionText + '');\n editor.cmd.do('insertElem', $code);\n editor.selection.createRangeByElem($code, false);\n editor.selection.restoreSelection();\n return;\n }\n\n // 选取是空,且没有夸元素选择,则插入
      \n        if (this._active) {\n            // 选中状态,将编辑内容\n            this._createPanel($startElem.html());\n        } else {\n            // 未选中状态,将创建内容\n            this._createPanel();\n        }\n    },\n\n    _createPanel: function _createPanel(value) {\n        var _this = this;\n\n        // value - 要编辑的内容\n        value = value || '';\n        var type = !value ? 'new' : 'edit';\n        var textId = getRandom('texxt');\n        var btnId = getRandom('btn');\n\n        var panel = new Panel(this, {\n            width: 500,\n            // 一个 Panel 包含多个 tab\n            tabs: [{\n                // 标题\n                title: '插入代码',\n                // 模板\n                tpl: '
      \\n \\n
      \\n \\n
      \\n
      ',\n // 事件绑定\n events: [\n // 插入代码\n {\n selector: '#' + btnId,\n type: 'click',\n fn: function fn() {\n var $text = $('#' + textId);\n var text = $text.val() || $text.html();\n text = replaceHtmlSymbol(text);\n if (type === 'new') {\n // 新插入\n _this._insertCode(text);\n } else {\n // 编辑更新\n _this._updateCode(text);\n }\n\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }]\n } // first tab end\n ] // tabs end\n }); // new Panel end\n\n // 显示 panel\n panel.show();\n\n // 记录属性\n this.panel = panel;\n },\n\n // 插入代码\n _insertCode: function _insertCode(value) {\n var editor = this.editor;\n editor.cmd.do('insertHTML', '
      ' + value + '


      ');\n },\n\n // 更新代码\n _updateCode: function _updateCode(value) {\n var editor = this.editor;\n var $selectionELem = editor.selection.getSelectionContainerElem();\n if (!$selectionELem) {\n return;\n }\n $selectionELem.html(value);\n editor.selection.restoreSelection();\n },\n\n // 试图改变 active 状态\n tryChangeActive: function tryChangeActive(e) {\n var editor = this.editor;\n var $elem = this.$elem;\n var $selectionELem = editor.selection.getSelectionContainerElem();\n if (!$selectionELem) {\n return;\n }\n var $parentElem = $selectionELem.parent();\n if ($selectionELem.getNodeName() === 'CODE' && $parentElem.getNodeName() === 'PRE') {\n this._active = true;\n $elem.addClass('w-e-active');\n } else {\n this._active = false;\n $elem.removeClass('w-e-active');\n }\n }\n};\n\n/*\n menu - emoticon\n*/\n// 构造函数\nfunction Emoticon(editor) {\n this.editor = editor;\n this.$elem = $('
      \\n \\n
      ');\n this.type = 'panel';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nEmoticon.prototype = {\n constructor: Emoticon,\n\n onClick: function onClick() {\n this._createPanel();\n },\n\n _createPanel: function _createPanel() {\n var _this = this;\n\n // 拼接表情字符串\n var faceHtml = '';\n var faceStr = '😀 😃 😄 😁 😆 😅 😂 😊 😇 🙂 🙃 😉 😌 😍 😘 😗 😙 😚 😋 😜 😝 😛 🤑 🤗 🤓 😎 😏 😒 😞 😔 😟 😕 🙁 😣 😖 😫 😩 😤 😠 😡 😶 😐 😑 😯 😦 😧 😮 😲 😵 😳 😱 😨 😰 😢 😥 😭 😓 😪 😴 🙄 🤔 😬 🤐';\n faceStr.split(/\\s/).forEach(function (item) {\n if (item) {\n faceHtml += '' + item + '';\n }\n });\n\n var handHtml = '';\n var handStr = '🙌 👏 👋 👍 👎 👊 ✊ ️👌 ✋ 👐 💪 🙏 ️👆 👇 👈 👉 🖕 🖐 🤘 🖖';\n handStr.split(/\\s/).forEach(function (item) {\n if (item) {\n handHtml += '' + item + '';\n }\n });\n\n var panel = new Panel(this, {\n width: 300,\n height: 200,\n // 一个 Panel 包含多个 tab\n tabs: [{\n // 标题\n title: '表情',\n // 模板\n tpl: '
      ' + faceHtml + '
      ',\n // 事件绑定\n events: [{\n selector: 'span.w-e-item',\n type: 'click',\n fn: function fn(e) {\n var target = e.target;\n _this._insert(target.innerHTML);\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }]\n }, // first tab end\n {\n // 标题\n title: '手势',\n // 模板\n tpl: '
      ' + handHtml + '
      ',\n // 事件绑定\n events: [{\n selector: 'span.w-e-item',\n type: 'click',\n fn: function fn(e) {\n var target = e.target;\n _this._insert(target.innerHTML);\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }]\n } // second tab end\n ] // tabs end\n });\n\n // 显示 panel\n panel.show();\n\n // 记录属性\n this.panel = panel;\n },\n\n // 插入表情\n _insert: function _insert(emoji) {\n var editor = this.editor;\n editor.cmd.do('insertHTML', '' + emoji + '');\n }\n};\n\n/*\n menu - table\n*/\n// 构造函数\nfunction Table(editor) {\n this.editor = editor;\n this.$elem = $('
      ');\n this.type = 'panel';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nTable.prototype = {\n constructor: Table,\n\n onClick: function onClick() {\n if (this._active) {\n // 编辑现有表格\n this._createEditPanel();\n } else {\n // 插入新表格\n this._createInsertPanel();\n }\n },\n\n // 创建插入新表格的 panel\n _createInsertPanel: function _createInsertPanel() {\n var _this = this;\n\n // 用到的 id\n var btnInsertId = getRandom('btn');\n var textRowNum = getRandom('row');\n var textColNum = getRandom('col');\n\n var panel = new Panel(this, {\n width: 250,\n // panel 包含多个 tab\n tabs: [{\n // 标题\n title: '插入表格',\n // 模板\n tpl: '
      \\n

      \\n \\u521B\\u5EFA\\n \\n \\u884C\\n \\n \\u5217\\u7684\\u8868\\u683C\\n

      \\n
      \\n \\n
      \\n
      ',\n // 事件绑定\n events: [{\n // 点击按钮,插入表格\n selector: '#' + btnInsertId,\n type: 'click',\n fn: function fn() {\n var rowNum = parseInt($('#' + textRowNum).val());\n var colNum = parseInt($('#' + textColNum).val());\n\n if (rowNum && colNum && rowNum > 0 && colNum > 0) {\n // form 数据有效\n _this._insert(rowNum, colNum);\n }\n\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }]\n } // first tab end\n ] // tabs end\n }); // panel end\n\n // 展示 panel\n panel.show();\n\n // 记录属性\n this.panel = panel;\n },\n\n // 插入表格\n _insert: function _insert(rowNum, colNum) {\n // 拼接 table 模板\n var r = void 0,\n c = void 0;\n var html = '';\n for (r = 0; r < rowNum; r++) {\n html += '';\n if (r === 0) {\n for (c = 0; c < colNum; c++) {\n html += '';\n }\n } else {\n for (c = 0; c < colNum; c++) {\n html += '';\n }\n }\n html += '';\n }\n html += '
        


      ';\n\n // 执行命令\n var editor = this.editor;\n editor.cmd.do('insertHTML', html);\n\n // 防止 firefox 下出现 resize 的控制点\n editor.cmd.do('enableObjectResizing', false);\n editor.cmd.do('enableInlineTableEditing', false);\n },\n\n // 创建编辑表格的 panel\n _createEditPanel: function _createEditPanel() {\n var _this2 = this;\n\n // 可用的 id\n var addRowBtnId = getRandom('add-row');\n var addColBtnId = getRandom('add-col');\n var delRowBtnId = getRandom('del-row');\n var delColBtnId = getRandom('del-col');\n var delTableBtnId = getRandom('del-table');\n\n // 创建 panel 对象\n var panel = new Panel(this, {\n width: 320,\n // panel 包含多个 tab\n tabs: [{\n // 标题\n title: '编辑表格',\n // 模板\n tpl: '
      \\n
      \\n \\n \\n \\n \\n
      \\n
      \\n \\n \\n
      ',\n // 事件绑定\n events: [{\n // 增加行\n selector: '#' + addRowBtnId,\n type: 'click',\n fn: function fn() {\n _this2._addRow();\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }, {\n // 增加列\n selector: '#' + addColBtnId,\n type: 'click',\n fn: function fn() {\n _this2._addCol();\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }, {\n // 删除行\n selector: '#' + delRowBtnId,\n type: 'click',\n fn: function fn() {\n _this2._delRow();\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }, {\n // 删除列\n selector: '#' + delColBtnId,\n type: 'click',\n fn: function fn() {\n _this2._delCol();\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }, {\n // 删除表格\n selector: '#' + delTableBtnId,\n type: 'click',\n fn: function fn() {\n _this2._delTable();\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }]\n }]\n });\n // 显示 panel\n panel.show();\n },\n\n // 获取选中的单元格的位置信息\n _getLocationData: function _getLocationData() {\n var result = {};\n var editor = this.editor;\n var $selectionELem = editor.selection.getSelectionContainerElem();\n if (!$selectionELem) {\n return;\n }\n var nodeName = $selectionELem.getNodeName();\n if (nodeName !== 'TD' && nodeName !== 'TH') {\n return;\n }\n\n // 获取 td index\n var $tr = $selectionELem.parent();\n var $tds = $tr.children();\n var tdLength = $tds.length;\n $tds.forEach(function (td, index) {\n if (td === $selectionELem[0]) {\n // 记录并跳出循环\n result.td = {\n index: index,\n elem: td,\n length: tdLength\n };\n return false;\n }\n });\n\n // 获取 tr index\n var $tbody = $tr.parent();\n var $trs = $tbody.children();\n var trLength = $trs.length;\n $trs.forEach(function (tr, index) {\n if (tr === $tr[0]) {\n // 记录并跳出循环\n result.tr = {\n index: index,\n elem: tr,\n length: trLength\n };\n return false;\n }\n });\n\n // 返回结果\n return result;\n },\n\n // 增加行\n _addRow: function _addRow() {\n // 获取当前单元格的位置信息\n var locationData = this._getLocationData();\n if (!locationData) {\n return;\n }\n var trData = locationData.tr;\n var $currentTr = $(trData.elem);\n var tdData = locationData.td;\n var tdLength = tdData.length;\n\n // 拼接即将插入的字符串\n var newTr = document.createElement('tr');\n var tpl = '',\n i = void 0;\n for (i = 0; i < tdLength; i++) {\n tpl += ' ';\n }\n newTr.innerHTML = tpl;\n // 插入\n $(newTr).insertAfter($currentTr);\n },\n\n // 增加列\n _addCol: function _addCol() {\n // 获取当前单元格的位置信息\n var locationData = this._getLocationData();\n if (!locationData) {\n return;\n }\n var trData = locationData.tr;\n var tdData = locationData.td;\n var tdIndex = tdData.index;\n var $currentTr = $(trData.elem);\n var $trParent = $currentTr.parent();\n var $trs = $trParent.children();\n\n // 遍历所有行\n $trs.forEach(function (tr) {\n var $tr = $(tr);\n var $tds = $tr.children();\n var $currentTd = $tds.get(tdIndex);\n var name = $currentTd.getNodeName().toLowerCase();\n\n // new 一个 td,并插入\n var newTd = document.createElement(name);\n $(newTd).insertAfter($currentTd);\n });\n },\n\n // 删除行\n _delRow: function _delRow() {\n // 获取当前单元格的位置信息\n var locationData = this._getLocationData();\n if (!locationData) {\n return;\n }\n var trData = locationData.tr;\n var $currentTr = $(trData.elem);\n $currentTr.remove();\n },\n\n // 删除列\n _delCol: function _delCol() {\n // 获取当前单元格的位置信息\n var locationData = this._getLocationData();\n if (!locationData) {\n return;\n }\n var trData = locationData.tr;\n var tdData = locationData.td;\n var tdIndex = tdData.index;\n var $currentTr = $(trData.elem);\n var $trParent = $currentTr.parent();\n var $trs = $trParent.children();\n\n // 遍历所有行\n $trs.forEach(function (tr) {\n var $tr = $(tr);\n var $tds = $tr.children();\n var $currentTd = $tds.get(tdIndex);\n // 删除\n $currentTd.remove();\n });\n },\n\n // 删除表格\n _delTable: function _delTable() {\n var editor = this.editor;\n var $selectionELem = editor.selection.getSelectionContainerElem();\n if (!$selectionELem) {\n return;\n }\n var $table = $selectionELem.parentUntil('table');\n if (!$table) {\n return;\n }\n $table.remove();\n },\n\n // 试图改变 active 状态\n tryChangeActive: function tryChangeActive(e) {\n var editor = this.editor;\n var $elem = this.$elem;\n var $selectionELem = editor.selection.getSelectionContainerElem();\n if (!$selectionELem) {\n return;\n }\n var nodeName = $selectionELem.getNodeName();\n if (nodeName === 'TD' || nodeName === 'TH') {\n this._active = true;\n $elem.addClass('w-e-active');\n } else {\n this._active = false;\n $elem.removeClass('w-e-active');\n }\n }\n};\n\n/*\n menu - video\n*/\n// 构造函数\nfunction Video(editor) {\n this.editor = editor;\n this.$elem = $('
      ');\n this.type = 'panel';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nVideo.prototype = {\n constructor: Video,\n\n onClick: function onClick() {\n this._createPanel();\n },\n\n _createPanel: function _createPanel() {\n var _this = this;\n\n // 创建 id\n var textValId = getRandom('text-val');\n var btnId = getRandom('btn');\n\n // 创建 panel\n var panel = new Panel(this, {\n width: 350,\n // 一个 panel 多个 tab\n tabs: [{\n // 标题\n title: '插入视频',\n // 模板\n tpl: '
      \\n \"/>\\n
      \\n \\n
      \\n
      ',\n // 事件绑定\n events: [{\n selector: '#' + btnId,\n type: 'click',\n fn: function fn() {\n var $text = $('#' + textValId);\n var val = $text.val().trim();\n\n // 测试用视频地址\n // \n\n if (val) {\n // 插入视频\n _this._insert(val);\n }\n\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }]\n } // first tab end\n ] // tabs end\n }); // panel end\n\n // 显示 panel\n panel.show();\n\n // 记录属性\n this.panel = panel;\n },\n\n // 插入视频\n _insert: function _insert(val) {\n var editor = this.editor;\n editor.cmd.do('insertHTML', val + '


      ');\n }\n};\n\n/*\n menu - img\n*/\n// 构造函数\nfunction Image(editor) {\n this.editor = editor;\n this.$elem = $('
      ');\n this.type = 'panel';\n\n // 当前是否 active 状态\n this._active = false;\n}\n\n// 原型\nImage.prototype = {\n constructor: Image,\n\n onClick: function onClick() {\n if (this._active) {\n this._createEditPanel();\n } else {\n this._createInsertPanel();\n }\n },\n\n _createEditPanel: function _createEditPanel() {\n var editor = this.editor;\n\n // id\n var width30 = getRandom('width-30');\n var width50 = getRandom('width-50');\n var width100 = getRandom('width-100');\n var delBtn = getRandom('del-btn');\n\n // tab 配置\n var tabsConfig = [{\n title: '编辑图片',\n tpl: '
      \\n
      \\n \\u6700\\u5927\\u5BBD\\u5EA6\\uFF1A\\n \\n \\n \\n
      \\n
      \\n \\n \\n
      ',\n events: [{\n selector: '#' + width30,\n type: 'click',\n fn: function fn() {\n var $img = editor._selectedImg;\n if ($img) {\n $img.css('max-width', '30%');\n }\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }, {\n selector: '#' + width50,\n type: 'click',\n fn: function fn() {\n var $img = editor._selectedImg;\n if ($img) {\n $img.css('max-width', '50%');\n }\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }, {\n selector: '#' + width100,\n type: 'click',\n fn: function fn() {\n var $img = editor._selectedImg;\n if ($img) {\n $img.css('max-width', '100%');\n }\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }, {\n selector: '#' + delBtn,\n type: 'click',\n fn: function fn() {\n var $img = editor._selectedImg;\n if ($img) {\n $img.remove();\n }\n // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭\n return true;\n }\n }]\n }];\n\n // 创建 panel 并显示\n var panel = new Panel(this, {\n width: 300,\n tabs: tabsConfig\n });\n panel.show();\n\n // 记录属性\n this.panel = panel;\n },\n\n _createInsertPanel: function _createInsertPanel() {\n var editor = this.editor;\n var uploadImg = editor.uploadImg;\n var config = editor.config;\n\n // id\n var upTriggerId = getRandom('up-trigger');\n var upFileId = getRandom('up-file');\n var linkUrlId = getRandom('link-url');\n var linkBtnId = getRandom('link-btn');\n\n // tabs 的配置\n var tabsConfig = [{\n title: '上传图片',\n tpl: '
      \\n
      \\n \\n
      \\n
      \\n \\n
      \\n
      ',\n events: [{\n // 触发选择图片\n selector: '#' + upTriggerId,\n type: 'click',\n fn: function fn() {\n var $file = $('#' + upFileId);\n var fileElem = $file[0];\n if (fileElem) {\n fileElem.click();\n } else {\n // 返回 true 可关闭 panel\n return true;\n }\n }\n }, {\n // 选择图片完毕\n selector: '#' + upFileId,\n type: 'change',\n fn: function fn() {\n var $file = $('#' + upFileId);\n var fileElem = $file[0];\n if (!fileElem) {\n // 返回 true 可关闭 panel\n return true;\n }\n\n // 获取选中的 file 对象列表\n var fileList = fileElem.files;\n if (fileList.length) {\n uploadImg.uploadImg(fileList);\n }\n\n // 返回 true 可关闭 panel\n return true;\n }\n }]\n }, // first tab end\n {\n title: '网络图片',\n tpl: '
      \\n \\n
      \\n \\n
      \\n
      ',\n events: [{\n selector: '#' + linkBtnId,\n type: 'click',\n fn: function fn() {\n var $linkUrl = $('#' + linkUrlId);\n var url = $linkUrl.val().trim();\n\n if (url) {\n uploadImg.insertLinkImg(url);\n }\n\n // 返回 true 表示函数执行结束之后关闭 panel\n return true;\n }\n }]\n } // second tab end\n ]; // tabs end\n\n // 判断 tabs 的显示\n var tabsConfigResult = [];\n if ((config.uploadImgShowBase64 || config.uploadImgServer) && window.FileReader) {\n // 显示“上传图片”\n tabsConfigResult.push(tabsConfig[0]);\n }\n if (config.showLinkImg) {\n // 显示“网络图片”\n tabsConfigResult.push(tabsConfig[1]);\n }\n\n // 创建 panel 并显示\n var panel = new Panel(this, {\n width: 300,\n tabs: tabsConfigResult\n });\n panel.show();\n\n // 记录属性\n this.panel = panel;\n },\n\n // 试图改变 active 状态\n tryChangeActive: function tryChangeActive(e) {\n var editor = this.editor;\n var $elem = this.$elem;\n if (editor._selectedImg) {\n this._active = true;\n $elem.addClass('w-e-active');\n } else {\n this._active = false;\n $elem.removeClass('w-e-active');\n }\n }\n};\n\n/*\n 所有菜单的汇总\n*/\n\n// 存储菜单的构造函数\nvar MenuConstructors = {};\n\nMenuConstructors.bold = Bold;\n\nMenuConstructors.head = Head;\n\nMenuConstructors.link = Link;\n\nMenuConstructors.italic = Italic;\n\nMenuConstructors.redo = Redo;\n\nMenuConstructors.strikeThrough = StrikeThrough;\n\nMenuConstructors.underline = Underline;\n\nMenuConstructors.undo = Undo;\n\nMenuConstructors.list = List;\n\nMenuConstructors.justify = Justify;\n\nMenuConstructors.foreColor = BackColor;\n\nMenuConstructors.backColor = ForeColor$1;\n\nMenuConstructors.quote = Quote;\n\nMenuConstructors.code = Code;\n\nMenuConstructors.emoticon = Emoticon;\n\nMenuConstructors.table = Table;\n\nMenuConstructors.video = Video;\n\nMenuConstructors.image = Image;\n\n/*\n 菜单集合\n*/\n// 构造函数\nfunction Menus(editor) {\n this.editor = editor;\n this.menus = {};\n}\n\n// 修改原型\nMenus.prototype = {\n constructor: Menus,\n\n // 初始化菜单\n init: function init() {\n var _this = this;\n\n var editor = this.editor;\n var config = editor.config || {};\n var configMenus = config.menus || []; // 获取配置中的菜单\n\n // 根据配置信息,创建菜单\n configMenus.forEach(function (menuKey) {\n var MenuConstructor = MenuConstructors[menuKey];\n if (MenuConstructor && typeof MenuConstructor === 'function') {\n // 创建单个菜单\n _this.menus[menuKey] = new MenuConstructor(editor);\n }\n });\n\n // 添加到菜单栏\n this._addToToolbar();\n\n // 绑定事件\n this._bindEvent();\n },\n\n // 添加到菜单栏\n _addToToolbar: function _addToToolbar() {\n var editor = this.editor;\n var $toolbarElem = editor.$toolbarElem;\n var menus = this.menus;\n objForEach(menus, function (key, menu) {\n var $elem = menu.$elem;\n if ($elem) {\n $toolbarElem.append($elem);\n }\n });\n },\n\n // 绑定菜单 click mouseenter 事件\n _bindEvent: function _bindEvent() {\n var menus = this.menus;\n var editor = this.editor;\n objForEach(menus, function (key, menu) {\n var type = menu.type;\n if (!type) {\n return;\n }\n var $elem = menu.$elem;\n var droplist = menu.droplist;\n var panel = menu.panel;\n\n // 点击类型,例如 bold\n if (type === 'click' && menu.onClick) {\n $elem.on('click', function (e) {\n if (editor.selection.getRange() == null) {\n return;\n }\n menu.onClick(e);\n });\n }\n\n // 下拉框,例如 head\n if (type === 'droplist' && droplist) {\n $elem.on('mouseenter', function (e) {\n if (editor.selection.getRange() == null) {\n return;\n }\n // 显示\n droplist.showTimeoutId = setTimeout(function () {\n droplist.show();\n }, 200);\n }).on('mouseleave', function (e) {\n // 隐藏\n droplist.hideTimeoutId = setTimeout(function () {\n droplist.hide();\n }, 0);\n });\n }\n\n // 弹框类型,例如 link\n if (type === 'panel' && menu.onClick) {\n $elem.on('click', function (e) {\n e.stopPropagation();\n if (editor.selection.getRange() == null) {\n return;\n }\n // 在自定义事件中显示 panel\n menu.onClick(e);\n });\n }\n });\n },\n\n // 尝试修改菜单状态\n changeActive: function changeActive() {\n var menus = this.menus;\n objForEach(menus, function (key, menu) {\n if (menu.tryChangeActive) {\n setTimeout(function () {\n menu.tryChangeActive();\n }, 100);\n }\n });\n }\n};\n\n/*\n 粘贴信息的处理\n*/\n\n// 获取粘贴的纯文本\nfunction getPasteText(e) {\n var clipboardData = e.clipboardData || e.originalEvent && e.originalEvent.clipboardData;\n var pasteText = void 0;\n if (clipboardData == null) {\n pasteText = window.clipboardData && window.clipboardData.getData('text');\n } else {\n pasteText = clipboardData.getData('text/plain');\n }\n\n return replaceHtmlSymbol(pasteText);\n}\n\n// 获取粘贴的html\nfunction getPasteHtml(e) {\n var clipboardData = e.clipboardData || e.originalEvent && e.originalEvent.clipboardData;\n var pasteText = void 0,\n pasteHtml = void 0;\n if (clipboardData == null) {\n pasteText = window.clipboardData && window.clipboardData.getData('text');\n } else {\n pasteText = clipboardData.getData('text/plain');\n pasteHtml = clipboardData.getData('text/html');\n }\n if (!pasteHtml && pasteText) {\n pasteHtml = '

      ' + replaceHtmlSymbol(pasteText) + '

      ';\n }\n if (!pasteHtml) {\n return;\n }\n\n // 过滤word中状态过来的无用字符\n var docSplitHtml = pasteHtml.split('');\n if (docSplitHtml.length === 2) {\n pasteHtml = docSplitHtml[0];\n }\n\n // 过滤无用标签\n pasteHtml = pasteHtml.replace(/<(meta|script|link).+?>/igm, '');\n\n // 过滤样式\n pasteHtml = pasteHtml.replace(/\\s?(class|style)=('|\").+?('|\")/igm, '');\n\n return pasteHtml;\n}\n\n// 获取粘贴的图片文件\nfunction getPasteImgs(e) {\n var result = [];\n var txt = getPasteText(e);\n if (txt) {\n // 有文字,就忽略图片\n return result;\n }\n\n var clipboardData = e.clipboardData || e.originalEvent && e.originalEvent.clipboardData || {};\n var items = clipboardData.items;\n if (!items) {\n return result;\n }\n\n objForEach(items, function (key, value) {\n var type = value.type;\n if (/image/i.test(type)) {\n result.push(value.getAsFile());\n }\n });\n\n return result;\n}\n\n/*\n 编辑区域\n*/\n\n// 构造函数\nfunction Text(editor) {\n this.editor = editor;\n}\n\n// 修改原型\nText.prototype = {\n constructor: Text,\n\n // 初始化\n init: function init() {\n // 绑定事件\n this._bindEvent();\n },\n\n // 清空内容\n clear: function clear() {\n this.html('


      ');\n },\n\n // 获取 设置 html\n html: function html(val) {\n var editor = this.editor;\n var $textElem = editor.$textElem;\n if (val == null) {\n return $textElem.html();\n } else {\n $textElem.html(val);\n\n // 初始化选取,将光标定位到内容尾部\n editor.initSelection();\n }\n },\n\n // 获取 设置 text\n text: function text(val) {\n var editor = this.editor;\n var $textElem = editor.$textElem;\n if (val == null) {\n return $textElem.text();\n } else {\n $textElem.text('

      ' + val + '

      ');\n\n // 初始化选取,将光标定位到内容尾部\n editor.initSelection();\n }\n },\n\n // 追加内容\n append: function append(html) {\n var editor = this.editor;\n var $textElem = editor.$textElem;\n $textElem.append($(html));\n\n // 初始化选取,将光标定位到内容尾部\n editor.initSelection();\n },\n\n // 绑定事件\n _bindEvent: function _bindEvent() {\n // 实时保存选取\n this._saveRangeRealTime();\n\n // 按回车建时的特殊处理\n this._enterKeyHandle();\n\n // 清空时保留


      \n this._clearHandle();\n\n // 粘贴事件(粘贴文字,粘贴图片)\n this._pasteHandle();\n\n // tab 特殊处理\n this._tabHandle();\n\n // img 点击\n this._imgHandle();\n },\n\n // 实时保存选取\n _saveRangeRealTime: function _saveRangeRealTime() {\n var editor = this.editor;\n var $textElem = editor.$textElem;\n\n // 保存当前的选区\n function saveRange(e) {\n // 随时保存选区\n editor.selection.saveRange();\n // 更新按钮 ative 状态\n editor.menus.changeActive();\n }\n // 按键后保存\n $textElem.on('keyup', saveRange);\n $textElem.on('mousedown', function (e) {\n // mousedown 状态下,鼠标滑动到编辑区域外面,也需要保存选区\n $textElem.on('mouseleave', saveRange);\n });\n $textElem.on('mouseup', function (e) {\n saveRange();\n // 在编辑器区域之内完成点击,取消鼠标滑动到编辑区外面的事件\n $textElem.off('mouseleave', saveRange);\n });\n },\n\n // 按回车键时的特殊处理\n _enterKeyHandle: function _enterKeyHandle() {\n var editor = this.editor;\n var $textElem = editor.$textElem;\n\n // 将回车之后生成的非

      的顶级标签,改为

      \n function pHandle(e) {\n var $selectionElem = editor.selection.getSelectionContainerElem();\n var $parentElem = $selectionElem.parent();\n if (!$parentElem.equal($textElem)) {\n // 不是顶级标签\n return;\n }\n var nodeName = $selectionElem.getNodeName();\n if (nodeName === 'P') {\n // 当前的标签是 P ,不用做处理\n return;\n }\n\n if ($selectionElem.text()) {\n // 有内容,不做处理\n return;\n }\n\n // 插入

      ,并将选取定位到

      ,删除当前标签\n var $p = $('


      ');\n $p.insertBefore($selectionElem);\n editor.selection.createRangeByElem($p, true);\n editor.selection.restoreSelection();\n $selectionElem.remove();\n }\n\n $textElem.on('keyup', function (e) {\n if (e.keyCode !== 13) {\n // 不是回车键\n return;\n }\n // 将回车之后生成的非

      的顶级标签,改为

      \n pHandle(e);\n });\n\n //

      回车时 特殊处理\n function codeHandle(e) {\n var $selectionElem = editor.selection.getSelectionContainerElem();\n if (!$selectionElem) {\n return;\n }\n var $parentElem = $selectionElem.parent();\n var selectionNodeName = $selectionElem.getNodeName();\n var parentNodeName = $parentElem.getNodeName();\n\n if (selectionNodeName !== 'CODE' || parentNodeName !== 'PRE') {\n // 不符合要求 忽略\n return;\n }\n\n if (!editor.cmd.queryCommandSupported('insertHTML')) {\n // 必须原生支持 insertHTML 命令\n return;\n }\n\n var _startOffset = editor.selection.getRange().startOffset;\n editor.cmd.do('insertHTML', '\\n');\n editor.selection.saveRange();\n if (editor.selection.getRange().startOffset === _startOffset) {\n // 没起作用,再来一遍\n editor.cmd.do('insertHTML', '\\n');\n }\n\n // 阻止默认行为\n e.preventDefault();\n }\n\n $textElem.on('keydown', function (e) {\n if (e.keyCode !== 13) {\n // 不是回车键\n return;\n }\n //
      回车时 特殊处理\n codeHandle(e);\n });\n },\n\n // 清空时保留


      \n _clearHandle: function _clearHandle() {\n var editor = this.editor;\n var $textElem = editor.$textElem;\n\n $textElem.on('keydown', function (e) {\n if (e.keyCode !== 8) {\n return;\n }\n var txtHtml = $textElem.html().toLowerCase().trim();\n if (txtHtml === '


      ') {\n // 最后剩下一个空行,就不再删除了\n e.preventDefault();\n return;\n }\n });\n\n $textElem.on('keyup', function (e) {\n if (e.keyCode !== 8) {\n return;\n }\n var $p = void 0;\n var txtHtml = $textElem.html().toLowerCase().trim();\n\n // firefox 时用 txtHtml === '
      ' 判断,其他用 !txtHtml 判断\n if (!txtHtml || txtHtml === '
      ') {\n // 内容空了\n $p = $('


      ');\n $textElem.html(''); // 一定要先清空,否则在 firefox 下有问题\n $textElem.append($p);\n editor.selection.createRangeByElem($p, false, true);\n editor.selection.restoreSelection();\n }\n });\n },\n\n // 粘贴事件(粘贴文字 粘贴图片)\n _pasteHandle: function _pasteHandle() {\n var editor = this.editor;\n var $textElem = editor.$textElem;\n\n // 粘贴文字\n $textElem.on('paste', function (e) {\n if (UA.isIE()) {\n // IE 下放弃下面的判断\n return;\n }\n\n // 阻止默认行为,使用 execCommand 的粘贴命令\n e.preventDefault();\n\n // 获取粘贴的文字\n var pasteHtml = getPasteHtml(e);\n var pasteText = getPasteText(e);\n pasteText = pasteText.replace(/\\n/gm, '
      ');\n\n var $selectionElem = editor.selection.getSelectionContainerElem();\n if (!$selectionElem) {\n return;\n }\n var nodeName = $selectionElem.getNodeName();\n\n // code 中粘贴忽略\n if (nodeName === 'CODE' || nodeName === 'PRE') {\n return;\n }\n\n // 表格中忽略,可能会出现异常问题\n if (nodeName === 'TD' || nodeName === 'TH') {\n return;\n }\n\n if (nodeName === 'DIV' || $textElem.html() === '


      ') {\n // 是 div,可粘贴过滤样式的文字和链接\n if (!pasteHtml) {\n return;\n }\n try {\n // firefox 中,获取的 pasteHtml 可能是没有
        包裹的
      • \n // 因此执行 insertHTML 会报错\n editor.cmd.do('insertHTML', pasteHtml);\n } catch (ex) {\n // 此时使用 pasteText 来兼容一下\n editor.cmd.do('insertHTML', '

        ' + pasteText + '

        ');\n }\n } else {\n // 不是 div,证明在已有内容的元素中粘贴,只粘贴纯文本\n if (!pasteText) {\n return;\n }\n editor.cmd.do('insertHTML', '

        ' + pasteText + '

        ');\n }\n });\n\n // 粘贴图片\n $textElem.on('paste', function (e) {\n e.preventDefault();\n\n // 获取粘贴的图片\n var pasteFiles = getPasteImgs(e);\n if (!pasteFiles || !pasteFiles.length) {\n return;\n }\n\n // 获取当前的元素\n var $selectionElem = editor.selection.getSelectionContainerElem();\n if (!$selectionElem) {\n return;\n }\n var nodeName = $selectionElem.getNodeName();\n\n // code 中粘贴忽略\n if (nodeName === 'CODE' || nodeName === 'PRE') {\n return;\n }\n\n // 上传图片\n var uploadImg = editor.uploadImg;\n uploadImg.uploadImg(pasteFiles);\n });\n },\n\n // tab 特殊处理\n _tabHandle: function _tabHandle() {\n var editor = this.editor;\n var $textElem = editor.$textElem;\n\n $textElem.on('keydown', function (e) {\n if (e.keyCode !== 9) {\n return;\n }\n if (!editor.cmd.queryCommandSupported('insertHTML')) {\n // 必须原生支持 insertHTML 命令\n return;\n }\n var $selectionElem = editor.selection.getSelectionContainerElem();\n if (!$selectionElem) {\n return;\n }\n var $parentElem = $selectionElem.parent();\n var selectionNodeName = $selectionElem.getNodeName();\n var parentNodeName = $parentElem.getNodeName();\n\n if (selectionNodeName === 'CODE' && parentNodeName === 'PRE') {\n //
         里面\n                editor.cmd.do('insertHTML', '    ');\n            } else {\n                // 普通文字\n                editor.cmd.do('insertHTML', '    ');\n            }\n\n            e.preventDefault();\n        });\n    },\n\n    // img 点击\n    _imgHandle: function _imgHandle() {\n        var editor = this.editor;\n        var $textElem = editor.$textElem;\n        var selectedClass = 'w-e-selected';\n\n        // 为图片增加 selected 样式\n        $textElem.on('click', 'img', function (e) {\n            var img = this;\n            var $img = $(img);\n\n            // 去掉所有图片的 selected 样式\n            $textElem.find('img').removeClass(selectedClass);\n\n            // 为点击的图片增加样式,并记录当前图片\n            $img.addClass(selectedClass);\n            editor._selectedImg = $img;\n\n            // 修改选取\n            editor.selection.createRangeByElem($img);\n        });\n\n        // 去掉图片的 selected 样式\n        $textElem.on('click  keyup', function (e) {\n            if (e.target.matches('img')) {\n                // 点击的是图片,忽略\n                return;\n            }\n            // 取消掉 selected 样式,并删除记录\n            $textElem.find('img').removeClass(selectedClass);\n            editor._selectedImg = null;\n        });\n    }\n};\n\n/*\n    命令,封装 document.execCommand\n*/\n\n// 构造函数\nfunction Command(editor) {\n    this.editor = editor;\n}\n\n// 修改原型\nCommand.prototype = {\n    constructor: Command,\n\n    // 执行命令\n    do: function _do(name, value) {\n        var editor = this.editor;\n\n        // 如果无选区,忽略\n        if (!editor.selection.getRange()) {\n            return;\n        }\n\n        // 恢复选取\n        editor.selection.restoreSelection();\n\n        // 执行\n        var _name = '_' + name;\n        if (this[_name]) {\n            // 有自定义事件\n            this[_name](value);\n        } else {\n            // 默认 command\n            this._execCommand(name, value);\n        }\n\n        // 修改菜单状态\n        editor.menus.changeActive();\n\n        // 最后,恢复选取保证光标在原来的位置闪烁\n        editor.selection.saveRange();\n        editor.selection.restoreSelection();\n\n        // 触发 onchange\n        editor.change && editor.change();\n    },\n\n    // 自定义 insertHTML 事件\n    _insertHTML: function _insertHTML(html) {\n        var editor = this.editor;\n        var range = editor.selection.getRange();\n\n        // 保证传入的参数是 html 代码\n        var test = /^<.+>$/.test(html);\n        if (!test && !UA.isWebkit()) {\n            // webkit 可以插入非 html 格式的文字\n            throw new Error('执行 insertHTML 命令时传入的参数必须是 html 格式');\n        }\n\n        if (this.queryCommandSupported('insertHTML')) {\n            // W3C\n            this._execCommand('insertHTML', html);\n        } else if (range.insertNode) {\n            // IE\n            range.deleteContents();\n            range.insertNode($(html)[0]);\n        } else if (range.pasteHTML) {\n            // IE <= 10\n            range.pasteHTML(html);\n        }\n    },\n\n    // 插入 elem\n    _insertElem: function _insertElem($elem) {\n        var editor = this.editor;\n        var range = editor.selection.getRange();\n\n        if (range.insertNode) {\n            range.deleteContents();\n            range.insertNode($elem[0]);\n        }\n    },\n\n    // 封装 execCommand\n    _execCommand: function _execCommand(name, value) {\n        document.execCommand(name, false, value);\n    },\n\n    // 封装 document.queryCommandValue\n    queryCommandValue: function queryCommandValue(name) {\n        return document.queryCommandValue(name);\n    },\n\n    // 封装 document.queryCommandState\n    queryCommandState: function queryCommandState(name) {\n        return document.queryCommandState(name);\n    },\n\n    // 封装 document.queryCommandSupported\n    queryCommandSupported: function queryCommandSupported(name) {\n        return document.queryCommandSupported(name);\n    }\n};\n\n/*\n    selection range API\n*/\n\n// 构造函数\nfunction API(editor) {\n    this.editor = editor;\n    this._currentRange = null;\n}\n\n// 修改原型\nAPI.prototype = {\n    constructor: API,\n\n    // 获取 range 对象\n    getRange: function getRange() {\n        return this._currentRange;\n    },\n\n    // 保存选区\n    saveRange: function saveRange(_range) {\n        if (_range) {\n            // 保存已有选区\n            this._currentRange = _range;\n            return;\n        }\n\n        // 获取当前的选区\n        var selection = window.getSelection();\n        if (selection.rangeCount === 0) {\n            return;\n        }\n        var range = selection.getRangeAt(0);\n\n        // 判断选区内容是否在编辑内容之内\n        var $containerElem = this.getSelectionContainerElem(range);\n        if (!$containerElem) {\n            return;\n        }\n        var editor = this.editor;\n        var $textElem = editor.$textElem;\n        if ($textElem.isContain($containerElem)) {\n            // 是编辑内容之内的\n            this._currentRange = range;\n        }\n    },\n\n    // 折叠选区\n    collapseRange: function collapseRange(toStart) {\n        if (toStart == null) {\n            // 默认为 false\n            toStart = false;\n        }\n        var range = this._currentRange;\n        if (range) {\n            range.collapse(toStart);\n        }\n    },\n\n    // 选中区域的文字\n    getSelectionText: function getSelectionText() {\n        var range = this._currentRange;\n        if (range) {\n            return this._currentRange.toString();\n        } else {\n            return '';\n        }\n    },\n\n    // 选区的 $Elem\n    getSelectionContainerElem: function getSelectionContainerElem(range) {\n        range = range || this._currentRange;\n        var elem = void 0;\n        if (range) {\n            elem = range.commonAncestorContainer;\n            return $(elem.nodeType === 1 ? elem : elem.parentNode);\n        }\n    },\n    getSelectionStartElem: function getSelectionStartElem(range) {\n        range = range || this._currentRange;\n        var elem = void 0;\n        if (range) {\n            elem = range.startContainer;\n            return $(elem.nodeType === 1 ? elem : elem.parentNode);\n        }\n    },\n    getSelectionEndElem: function getSelectionEndElem(range) {\n        range = range || this._currentRange;\n        var elem = void 0;\n        if (range) {\n            elem = range.endContainer;\n            return $(elem.nodeType === 1 ? elem : elem.parentNode);\n        }\n    },\n\n    // 选区是否为空\n    isSelectionEmpty: function isSelectionEmpty() {\n        var range = this._currentRange;\n        if (range && range.startContainer) {\n            if (range.startContainer === range.endContainer) {\n                if (range.startOffset === range.endOffset) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    },\n\n    // 恢复选区\n    restoreSelection: function restoreSelection() {\n        var selection = window.getSelection();\n        selection.removeAllRanges();\n        selection.addRange(this._currentRange);\n    },\n\n    // 创建一个空白(即 ​ 字符)选区\n    createEmptyRange: function createEmptyRange() {\n        var editor = this.editor;\n        var range = this.getRange();\n        var $elem = void 0;\n\n        if (!range) {\n            // 当前无 range\n            return;\n        }\n        if (!this.isSelectionEmpty()) {\n            // 当前选区必须没有内容才可以\n            return;\n        }\n\n        // 目前只支持 webkit 内核\n        if (UA.isWebkit()) {\n            // 插入 ​\n            editor.cmd.do('insertHTML', '​');\n            // 修改 offset 位置\n            range.setEnd(range.endContainer, range.endOffset + 1);\n            // 存储\n            this.saveRange(range);\n        } else {\n            $elem = $('');\n            editor.cmd.do('insertElem', $elem);\n            this.createRangeByElem($elem, true);\n        }\n    },\n\n    // 根据 $Elem 设置选区\n    createRangeByElem: function createRangeByElem($elem, toStart, isContent) {\n        // $elem - 经过封装的 elem\n        // toStart - true 开始位置,false 结束位置\n        // isContent - 是否选中Elem的内容\n        if (!$elem.length) {\n            return;\n        }\n\n        var elem = $elem[0];\n        var range = document.createRange();\n\n        if (isContent) {\n            range.selectNodeContents(elem);\n        } else {\n            range.selectNode(elem);\n        }\n\n        if (typeof toStart === 'boolean') {\n            range.collapse(toStart);\n        }\n\n        // 存储 range\n        this.saveRange(range);\n    }\n};\n\n/*\n    上传进度条\n*/\n\nfunction Progress(editor) {\n    this.editor = editor;\n    this._time = 0;\n    this._isShow = false;\n    this._isRender = false;\n    this._timeoutId = 0;\n    this.$textContainer = editor.$textContainerElem;\n    this.$bar = $('
        ');\n}\n\nProgress.prototype = {\n constructor: Progress,\n\n show: function show(progress) {\n var _this = this;\n\n // 状态处理\n if (this._isShow) {\n return;\n }\n this._isShow = true;\n\n // 渲染\n var $bar = this.$bar;\n if (!this._isRender) {\n var $textContainer = this.$textContainer;\n $textContainer.append($bar);\n } else {\n this._isRender = true;\n }\n\n // 改变进度(节流,100ms 渲染一次)\n if (Date.now() - this._time > 100) {\n if (progress <= 1) {\n $bar.css('width', progress * 100 + '%');\n this._time = Date.now();\n }\n }\n\n // 隐藏\n var timeoutId = this._timeoutId;\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(function () {\n _this._hide();\n }, 500);\n },\n\n _hide: function _hide() {\n var $bar = this.$bar;\n $bar.remove();\n\n // 修改状态\n this._time = 0;\n this._isShow = false;\n this._isRender = false;\n }\n};\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n return typeof obj;\n} : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n};\n\n/*\n 上传图片\n*/\n\n// 构造函数\nfunction UploadImg(editor) {\n this.editor = editor;\n}\n\n// 原型\nUploadImg.prototype = {\n constructor: UploadImg,\n\n // 根据 debug 弹出不同的信息\n _alert: function _alert(alertInfo, debugInfo) {\n var editor = this.editor;\n var debug = editor.config.debug;\n\n if (debug) {\n throw new Error('wangEditor: ' + (debugInfo || alertInfo));\n } else {\n alert(alertInfo);\n }\n },\n\n // 根据链接插入图片\n insertLinkImg: function insertLinkImg(link) {\n var _this2 = this;\n\n if (!link) {\n return;\n }\n var editor = this.editor;\n\n var img = document.createElement('img');\n img.onload = function () {\n img = null;\n editor.cmd.do('insertHTML', '');\n };\n img.onerror = function () {\n img = null;\n // 无法成功下载图片\n _this2._alert('插入图片错误', 'wangEditor: \\u63D2\\u5165\\u56FE\\u7247\\u51FA\\u9519\\uFF0C\\u56FE\\u7247\\u94FE\\u63A5\\u662F \"' + link + '\"\\uFF0C\\u4E0B\\u8F7D\\u8BE5\\u94FE\\u63A5\\u5931\\u8D25');\n return;\n };\n img.onabort = function () {\n img = null;\n };\n img.src = link;\n },\n\n // 上传图片\n uploadImg: function uploadImg(files) {\n var _this3 = this;\n\n if (!files || !files.length) {\n return;\n }\n\n // ------------------------------ 获取配置信息 ------------------------------\n var editor = this.editor;\n var config = editor.config;\n var maxSize = config.uploadImgMaxSize;\n var maxSizeM = maxSize / 1000 / 1000;\n var maxLength = config.uploadImgMaxLength || 10000;\n var uploadImgServer = config.uploadImgServer;\n var uploadImgShowBase64 = config.uploadImgShowBase64;\n var uploadFileName = config.uploadFileName || '';\n var uploadImgParams = config.uploadImgParams || {};\n var uploadImgHeaders = config.uploadImgHeaders || {};\n var hooks = config.uploadImgHooks || {};\n var timeout = config.uploadImgTimeout || 3000;\n var withCredentials = config.withCredentials;\n if (withCredentials == null) {\n withCredentials = false;\n }\n\n // ------------------------------ 验证文件信息 ------------------------------\n var resultFiles = [];\n var errInfo = [];\n arrForEach(files, function (file) {\n var name = file.name;\n var size = file.size;\n if (/\\.(jpg|jpeg|png|bmp|gif)$/i.test(name) === false) {\n // 后缀名不合法,不是图片\n errInfo.push('\\u3010' + name + '\\u3011\\u4E0D\\u662F\\u56FE\\u7247');\n return;\n }\n if (maxSize < size) {\n // 上传图片过大\n errInfo.push('\\u3010' + name + '\\u3011\\u5927\\u4E8E ' + maxSizeM + 'M');\n return;\n }\n\n // 验证通过的加入结果列表\n resultFiles.push(file);\n });\n // 抛出验证信息\n if (errInfo.length) {\n this._alert('图片验证未通过: \\n' + errInfo.join('\\n'));\n return;\n }\n if (resultFiles.length > maxLength) {\n this._alert('一次最多上传' + maxLength + '张图片');\n return;\n }\n\n // 添加图片数据\n var formdata = new FormData();\n arrForEach(resultFiles, function (file) {\n var name = uploadFileName || file.name;\n formdata.append(name, file);\n });\n\n // ------------------------------ 上传图片 ------------------------------\n if (uploadImgServer && typeof uploadImgServer === 'string') {\n // 添加参数\n var uploadImgServerArr = uploadImgServer.split('#');\n uploadImgServer = uploadImgServerArr[0];\n var uploadImgServerHash = uploadImgServerArr[1] || '';\n objForEach(uploadImgParams, function (key, val) {\n val = encodeURIComponent(val);\n\n // 第一,将参数拼接到 url 中\n if (uploadImgServer.indexOf('?') > 0) {\n uploadImgServer += '&';\n } else {\n uploadImgServer += '?';\n }\n uploadImgServer = uploadImgServer + key + '=' + val;\n\n // 第二,将参数添加到 formdata 中\n formdata.append(key, val);\n });\n if (uploadImgServerHash) {\n uploadImgServer += '#' + uploadImgServerHash;\n }\n\n // 定义 xhr\n var xhr = new XMLHttpRequest();\n xhr.open('POST', uploadImgServer);\n\n // 设置超时\n xhr.timeout = timeout;\n xhr.ontimeout = function () {\n // hook - timeout\n if (hooks.timeout && typeof hooks.timeout === 'function') {\n hooks.timeout(xhr, editor);\n }\n\n _this3._alert('上传图片超时');\n };\n\n // 监控 progress\n if (xhr.upload) {\n xhr.upload.onprogress = function (e) {\n var percent = void 0;\n // 进度条\n var progressBar = new Progress(editor);\n if (e.lengthComputable) {\n percent = e.loaded / e.total;\n progressBar.show(percent);\n }\n };\n }\n\n // 返回数据\n xhr.onreadystatechange = function () {\n var result = void 0;\n if (xhr.readyState === 4) {\n if (xhr.status < 200 || xhr.status >= 300) {\n // hook - error\n if (hooks.error && typeof hooks.error === 'function') {\n hooks.error(xhr, editor);\n }\n\n // xhr 返回状态错误\n _this3._alert('上传图片发生错误', '\\u4E0A\\u4F20\\u56FE\\u7247\\u53D1\\u751F\\u9519\\u8BEF\\uFF0C\\u670D\\u52A1\\u5668\\u8FD4\\u56DE\\u72B6\\u6001\\u662F ' + xhr.status);\n return;\n }\n\n result = xhr.responseText;\n if ((typeof result === 'undefined' ? 'undefined' : _typeof(result)) !== 'object') {\n try {\n result = JSON.parse(result);\n } catch (ex) {\n // hook - fail\n if (hooks.fail && typeof hooks.fail === 'function') {\n hooks.fail(xhr, editor, result);\n }\n\n _this3._alert('上传图片失败', '上传图片返回结果错误,返回结果是: ' + result);\n return;\n }\n }\n if (!hooks.customInsert && result.errno != '0') {\n // hook - fail\n if (hooks.fail && typeof hooks.fail === 'function') {\n hooks.fail(xhr, editor, result);\n }\n\n // 数据错误\n _this3._alert('上传图片失败', '上传图片返回结果错误,返回结果 errno=' + result.errno);\n } else {\n if (hooks.customInsert && typeof hooks.customInsert === 'function') {\n // 使用者自定义插入方法\n hooks.customInsert(_this3.insertLinkImg.bind(_this3), result, editor);\n } else {\n // 将图片插入编辑器\n var data = result.data || [];\n data.forEach(function (link) {\n _this3.insertLinkImg(link);\n });\n }\n\n // hook - success\n if (hooks.success && typeof hooks.success === 'function') {\n hooks.success(xhr, editor, result);\n }\n }\n }\n };\n\n // hook - before\n if (hooks.before && typeof hooks.before === 'function') {\n hooks.before(xhr, editor, resultFiles);\n }\n\n // 自定义 headers\n objForEach(uploadImgHeaders, function (key, val) {\n xhr.setRequestHeader(key, val);\n });\n\n // 跨域传 cookie\n xhr.withCredentials = withCredentials;\n\n // 发送请求\n xhr.send(formdata);\n\n // 注意,要 return 。不去操作接下来的 base64 显示方式\n return;\n }\n\n // 显示 base64 格式\n if (uploadImgShowBase64) {\n arrForEach(files, function (file) {\n var _this = _this3;\n var reader = new FileReader();\n reader.readAsDataURL(file);\n reader.onload = function () {\n _this.insertLinkImg(this.result);\n };\n });\n }\n }\n};\n\n/*\n 编辑器构造函数\n*/\n\n// id,累加\nvar editorId = 1;\n\n// 构造函数\nfunction Editor(toolbarSelector, textSelector) {\n if (toolbarSelector == null) {\n // 没有传入任何参数,报错\n throw new Error('错误:初始化编辑器时候未传入任何参数,请查阅文档');\n }\n // id,用以区分单个页面不同的编辑器对象\n this.id = 'wangEditor-' + editorId++;\n\n this.toolbarSelector = toolbarSelector;\n this.textSelector = textSelector;\n\n // 自定义配置\n this.customConfig = {};\n}\n\n// 修改原型\nEditor.prototype = {\n constructor: Editor,\n\n // 初始化配置\n _initConfig: function _initConfig() {\n // _config 是默认配置,this.customConfig 是用户自定义配置,将它们 merge 之后再赋值\n var target = {};\n this.config = Object.assign(target, config, this.customConfig);\n },\n\n // 初始化 DOM\n _initDom: function _initDom() {\n var _this = this;\n\n var toolbarSelector = this.toolbarSelector;\n var $toolbarSelector = $(toolbarSelector);\n var textSelector = this.textSelector;\n\n var config$$1 = this.config;\n var zIndex = config$$1.zIndex || '10000';\n\n // 定义变量\n var $toolbarElem = void 0,\n $textContainerElem = void 0,\n $textElem = void 0,\n $children = void 0;\n\n if (textSelector == null) {\n // 只传入一个参数,即是容器的选择器或元素,toolbar 和 text 的元素自行创建\n $toolbarElem = $('
        ');\n $textContainerElem = $('
        ');\n\n // 将编辑器区域原有的内容,暂存起来\n $children = $toolbarSelector.children();\n\n // 添加到 DOM 结构中\n $toolbarSelector.append($toolbarElem).append($textContainerElem);\n\n // 自行创建的,需要配置默认的样式\n $toolbarElem.css('background-color', '#f1f1f1').css('border', '1px solid #ccc');\n $textContainerElem.css('border', '1px solid #ccc').css('border-top', 'none').css('height', '300px');\n } else {\n // toolbar 和 text 的选择器都有值,记录属性\n $toolbarElem = $toolbarSelector;\n $textContainerElem = $(textSelector);\n // 将编辑器区域原有的内容,暂存起来\n $children = $textContainerElem.children();\n }\n\n // 编辑区域\n $textElem = $('
        ');\n $textElem.attr('contenteditable', 'true').css('width', '100%').css('height', '100%');\n\n // 初始化编辑区域内容\n if ($children && $children.length) {\n $textElem.append($children);\n } else {\n $textElem.append($('


        '));\n }\n\n // 编辑区域加入DOM\n $textContainerElem.append($textElem);\n\n // 设置通用的 class\n $toolbarElem.addClass('w-e-toolbar');\n $textContainerElem.addClass('w-e-text-container');\n $textContainerElem.css('z-index', zIndex);\n $textElem.addClass('w-e-text');\n\n // 记录属性\n this.$toolbarElem = $toolbarElem;\n this.$textContainerElem = $textContainerElem;\n this.$textElem = $textElem;\n\n // 绑定 onchange\n $textContainerElem.on('click keyup', function () {\n _this.change && _this.change();\n });\n $toolbarElem.on('click', function () {\n this.change && this.change();\n });\n },\n\n // 封装 command\n _initCommand: function _initCommand() {\n this.cmd = new Command(this);\n },\n\n // 封装 selection range API\n _initSelectionAPI: function _initSelectionAPI() {\n this.selection = new API(this);\n },\n\n // 添加图片上传\n _initUploadImg: function _initUploadImg() {\n this.uploadImg = new UploadImg(this);\n },\n\n // 初始化菜单\n _initMenus: function _initMenus() {\n this.menus = new Menus(this);\n this.menus.init();\n },\n\n // 添加 text 区域\n _initText: function _initText() {\n this.txt = new Text(this);\n this.txt.init();\n },\n\n // 初始化选区,将光标定位到内容尾部\n initSelection: function initSelection() {\n var $textElem = this.$textElem;\n var $children = $textElem.children();\n if (!$children.length) {\n // 如果编辑器区域无内容,添加一个空行,重新设置选区\n $textElem.append($('


        '));\n this.initSelection();\n return;\n }\n\n var $last = $children.last();\n var html = $last.html().toLowerCase();\n var nodeName = $last.getNodeName();\n if (html !== '
        ' && html !== '' || nodeName !== 'P') {\n // 最后一个元素不是


        ,添加一个空行,重新设置选区\n $textElem.append($('


        '));\n this.initSelection();\n return;\n }\n\n this.selection.createRangeByElem($last, true);\n this.selection.restoreSelection();\n },\n\n // 绑定事件\n _bindEvent: function _bindEvent() {\n // -------- 绑定 onchange 事件 --------\n var onChangeTimeoutId = 0;\n var beforeChangeHtml = this.txt.html();\n var config$$1 = this.config;\n var onchange = config$$1.onchange;\n if (onchange && typeof onchange === 'function') {\n // 触发 change 的有三个场景:\n // 1. $textContainerElem.on('click keyup')\n // 2. $toolbarElem.on('click')\n // 3. editor.cmd.do()\n this.change = function () {\n // 判断是否有变化\n var currentHtml = this.txt.html();\n if (currentHtml.length === beforeChangeHtml.length) {\n return;\n }\n\n // 执行,使用节流\n if (onChangeTimeoutId) {\n clearTimeout(onChangeTimeoutId);\n }\n onChangeTimeoutId = setTimeout(function () {\n // 触发配置的 onchange 函数\n onchange(currentHtml);\n beforeChangeHtml = currentHtml;\n }, 200);\n };\n }\n },\n\n // 创建编辑器\n create: function create() {\n // 初始化配置信息\n this._initConfig();\n\n // 初始化 DOM\n this._initDom();\n\n // 封装 command API\n this._initCommand();\n\n // 封装 selection range API\n this._initSelectionAPI();\n\n // 添加 text\n this._initText();\n\n // 初始化菜单\n this._initMenus();\n\n // 添加 图片上传\n this._initUploadImg();\n\n // 初始化选区,将光标定位到内容尾部\n this.initSelection();\n\n // 绑定事件\n this._bindEvent();\n }\n};\n\n// 检验是否浏览器环境\ntry {\n document;\n} catch (ex) {\n throw new Error('请在浏览器环境下运行');\n}\n\n// polyfill\npolyfill();\n\n// 这里的 `inlinecss` 将被替换成 css 代码的内容,详情可去 ./gulpfile.js 中搜索 `inlinecss` 关键字\nvar inlinecss = '.w-e-toolbar,.w-e-text-container,.w-e-menu-panel { padding: 0; margin: 0; box-sizing: border-box;}.w-e-toolbar *,.w-e-text-container *,.w-e-menu-panel * { padding: 0; margin: 0; box-sizing: border-box;}.w-e-clear-fix:after { content: \"\"; display: table; clear: both;}.w-e-toolbar .w-e-droplist { position: absolute; left: 0; top: 0; background-color: #fff; border: 1px solid #f1f1f1; border-right-color: #ccc; border-bottom-color: #ccc;}.w-e-toolbar .w-e-droplist .w-e-dp-title { text-align: center; color: #999; line-height: 2; border-bottom: 1px solid #f1f1f1; font-size: 13px;}.w-e-toolbar .w-e-droplist ul.w-e-list { list-style: none; line-height: 1;}.w-e-toolbar .w-e-droplist ul.w-e-list li.w-e-item { color: #333; padding: 5px 0;}.w-e-toolbar .w-e-droplist ul.w-e-list li.w-e-item:hover { background-color: #f1f1f1;}.w-e-toolbar .w-e-droplist ul.w-e-block { list-style: none; text-align: left; padding: 5px;}.w-e-toolbar .w-e-droplist ul.w-e-block li.w-e-item { display: inline-block; *display: inline; *zoom: 1; padding: 3px 5px;}.w-e-toolbar .w-e-droplist ul.w-e-block li.w-e-item:hover { background-color: #f1f1f1;}@font-face { font-family: \\'icomoon\\'; src: url(data:application/x-font-woff;charset=utf-8;base64,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) format(\\'truetype\\'); font-weight: normal; font-style: normal;}[class^=\"w-e-icon-\"],[class*=\" w-e-icon-\"] { /* use !important to prevent issues with browser extensions that change fonts */ font-family: \\'icomoon\\' !important; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;}.w-e-icon-close:before { content: \"\\\\f00d\";}.w-e-icon-upload2:before { content: \"\\\\e9c6\";}.w-e-icon-trash-o:before { content: \"\\\\f014\";}.w-e-icon-header:before { content: \"\\\\f1dc\";}.w-e-icon-pencil2:before { content: \"\\\\e906\";}.w-e-icon-paint-brush:before { content: \"\\\\f1fc\";}.w-e-icon-image:before { content: \"\\\\e90d\";}.w-e-icon-play:before { content: \"\\\\e912\";}.w-e-icon-location:before { content: \"\\\\e947\";}.w-e-icon-undo:before { content: \"\\\\e965\";}.w-e-icon-redo:before { content: \"\\\\e966\";}.w-e-icon-quotes-left:before { content: \"\\\\e977\";}.w-e-icon-list-numbered:before { content: \"\\\\e9b9\";}.w-e-icon-list2:before { content: \"\\\\e9bb\";}.w-e-icon-link:before { content: \"\\\\e9cb\";}.w-e-icon-happy:before { content: \"\\\\e9df\";}.w-e-icon-bold:before { content: \"\\\\ea62\";}.w-e-icon-underline:before { content: \"\\\\ea63\";}.w-e-icon-italic:before { content: \"\\\\ea64\";}.w-e-icon-strikethrough:before { content: \"\\\\ea65\";}.w-e-icon-table2:before { content: \"\\\\ea71\";}.w-e-icon-paragraph-left:before { content: \"\\\\ea77\";}.w-e-icon-paragraph-center:before { content: \"\\\\ea78\";}.w-e-icon-paragraph-right:before { content: \"\\\\ea79\";}.w-e-icon-terminal:before { content: \"\\\\f120\";}.w-e-icon-page-break:before { content: \"\\\\ea68\";}.w-e-icon-cancel-circle:before { content: \"\\\\ea0d\";}.w-e-toolbar { display: -webkit-box; display: -ms-flexbox; display: flex; padding: 0 5px; /* 单个菜单 */}.w-e-toolbar .w-e-menu { position: relative; z-index: 10001; text-align: center; padding: 5px 10px; cursor: pointer;}.w-e-toolbar .w-e-menu i { color: #999;}.w-e-toolbar .w-e-menu:hover i { color: #333;}.w-e-toolbar .w-e-active i { color: #1e88e5;}.w-e-toolbar .w-e-active:hover i { color: #1e88e5;}.w-e-text-container .w-e-panel-container { position: absolute; top: 0; left: 50%; border: 1px solid #ccc; border-top: 0; box-shadow: 1px 1px 2px #ccc; color: #333; background-color: #fff; /* 为 emotion panel 定制的样式 */ /* 上传图片的 panel 定制样式 */}.w-e-text-container .w-e-panel-container .w-e-panel-close { position: absolute; right: 0; top: 0; padding: 5px; margin: 2px 5px 0 0; cursor: pointer; color: #999;}.w-e-text-container .w-e-panel-container .w-e-panel-close:hover { color: #333;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-title { list-style: none; display: -webkit-box; display: -ms-flexbox; display: flex; font-size: 14px; margin: 2px 10px 0 10px; border-bottom: 1px solid #f1f1f1;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-title .w-e-item { padding: 3px 5px; color: #999; cursor: pointer; margin: 0 3px; position: relative; top: 1px;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-title .w-e-active { color: #333; border-bottom: 1px solid #333; cursor: default; font-weight: 700;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content { padding: 10px 15px 10px 15px; font-size: 16px; /* 输入框的样式 */ /* 按钮的样式 */}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content input:focus,.w-e-text-container .w-e-panel-container .w-e-panel-tab-content textarea:focus,.w-e-text-container .w-e-panel-container .w-e-panel-tab-content button:focus { outline: none;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content textarea { width: 100%; border: 1px solid #ccc; padding: 5px;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content textarea:focus { border-color: #1e88e5;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content input[type=text] { border: none; border-bottom: 1px solid #ccc; font-size: 14px; height: 20px; color: #333; text-align: left;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content input[type=text].small { width: 30px; text-align: center;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content input[type=text].block { display: block; width: 100%; margin: 10px 0;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content input[type=text]:focus { border-bottom: 2px solid #1e88e5;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button { font-size: 14px; color: #1e88e5; border: none; padding: 5px 10px; background-color: #fff; cursor: pointer; border-radius: 3px;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button.left { float: left; margin-right: 10px;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button.right { float: right; margin-left: 10px;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button.gray { color: #999;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button.red { color: #c24f4a;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button:hover { background-color: #f1f1f1;}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container:after { content: \"\"; display: table; clear: both;}.w-e-text-container .w-e-panel-container .w-e-emoticon-container .w-e-item { cursor: pointer; font-size: 18px; padding: 0 3px; display: inline-block; *display: inline; *zoom: 1;}.w-e-text-container .w-e-panel-container .w-e-up-img-container { text-align: center;}.w-e-text-container .w-e-panel-container .w-e-up-img-container .w-e-up-btn { display: inline-block; *display: inline; *zoom: 1; color: #999; cursor: pointer; font-size: 60px; line-height: 1;}.w-e-text-container .w-e-panel-container .w-e-up-img-container .w-e-up-btn:hover { color: #333;}.w-e-text-container { position: relative;}.w-e-text-container .w-e-progress { position: absolute; background-color: #1e88e5; bottom: 0; left: 0; height: 1px;}.w-e-text { padding: 0 10px; overflow-y: scroll;}.w-e-text p,.w-e-text h1,.w-e-text h2,.w-e-text h3,.w-e-text h4,.w-e-text h5,.w-e-text table,.w-e-text pre { margin: 10px 0; line-height: 1.5;}.w-e-text ul,.w-e-text ol { margin: 10px 0 10px 20px;}.w-e-text blockquote { display: block; border-left: 8px solid #d0e5f2; padding: 5px 10px; margin: 10px 0; line-height: 1.4; font-size: 100%; background-color: #f1f1f1;}.w-e-text code { display: inline-block; *display: inline; *zoom: 1; background-color: #f1f1f1; border-radius: 3px; padding: 3px 5px; margin: 0 3px;}.w-e-text pre code { display: block;}.w-e-text table { border-top: 1px solid #ccc; border-left: 1px solid #ccc;}.w-e-text table td,.w-e-text table th { border-bottom: 1px solid #ccc; border-right: 1px solid #ccc; padding: 3px 5px;}.w-e-text table th { border-bottom: 2px solid #ccc; text-align: center;}.w-e-text:focus { outline: none;}.w-e-text img { cursor: pointer;}.w-e-text img:hover { box-shadow: 0 0 5px #333;}.w-e-text img.w-e-selected { border: 2px solid #1e88e5;}.w-e-text img.w-e-selected:hover { box-shadow: none;}';\n\n// 将 css 代码添加到