/*! * UEditorPlus * version: 2.0.0 */ (function () { // editor.js UEDITOR_CONFIG = window.UEDITOR_CONFIG || {}; var baidu = window.baidu || {}; window.baidu = baidu; window.UE = baidu.editor = { plugins: {}, commands: {}, instants: {}, I18N: {}, _customizeUI: {}, version: "3.9.0", constants: { STATEFUL: { DISABLED: -1, OFF: 0, ON: 1, }, } }; var dom = (UE.dom = {}); // core/browser.js /** * 浏览器判断模块 * @file * @module UE.browser * @since 1.2.6.1 */ /** * 提供浏览器检测的模块 * @unfile * @module UE.browser */ var browser = (UE.browser = (function () { var agent = navigator.userAgent.toLowerCase(), opera = window.opera, browser = { /** * @property {boolean} ie 检测当前浏览器是否为IE * @example * ```javascript * if ( UE.browser.ie ) { * console.log( '当前浏览器是IE' ); * } * ``` */ ie: /(msie\s|trident.*rv:)([\w.]+)/i.test(agent), /** * @property {boolean} opera 检测当前浏览器是否为Opera * @example * ```javascript * if ( UE.browser.opera ) { * console.log( '当前浏览器是Opera' ); * } * ``` */ opera: !!opera && opera.version, /** * @property {boolean} webkit 检测当前浏览器是否是webkit内核的浏览器 * @example * ```javascript * if ( UE.browser.webkit ) { * console.log( '当前浏览器是webkit内核浏览器' ); * } * ``` */ webkit: agent.indexOf(" applewebkit/") > -1, /** * @property {boolean} mac 检测当前浏览器是否是运行在mac平台下 * @example * ```javascript * if ( UE.browser.mac ) { * console.log( '当前浏览器运行在mac平台下' ); * } * ``` */ mac: agent.indexOf("macintosh") > -1, /** * @property {boolean} quirks 检测当前浏览器是否处于“怪异模式”下 * @example * ```javascript * if ( UE.browser.quirks ) { * console.log( '当前浏览器运行处于“怪异模式”' ); * } * ``` */ quirks: document.compatMode == "BackCompat" }; /** * @property {boolean} gecko 检测当前浏览器内核是否是gecko内核 * @example * ```javascript * if ( UE.browser.gecko ) { * console.log( '当前浏览器内核是gecko内核' ); * } * ``` */ browser.gecko = navigator.product == "Gecko" && !browser.webkit && !browser.opera && !browser.ie; var version = 0; // Internet Explorer 6.0+ if (browser.ie) { var v1 = agent.match(/(?:msie\s([\w.]+))/); var v2 = agent.match(/(?:trident.*rv:([\w.]+))/); if (v1 && v2 && v1[1] && v2[1]) { version = Math.max(v1[1] * 1, v2[1] * 1); } else if (v1 && v1[1]) { version = v1[1] * 1; } else if (v2 && v2[1]) { version = v2[1] * 1; } else { version = 0; } browser.ie11Compat = document.documentMode == 11; /** * @property { boolean } ie9Compat 检测浏览器模式是否为 IE9 兼容模式 * @warning 如果浏览器不是IE, 则该值为undefined * @example * ```javascript * if ( UE.browser.ie9Compat ) { * console.log( '当前浏览器运行在IE9兼容模式下' ); * } * ``` */ browser.ie9Compat = document.documentMode == 9; /** * @property { boolean } ie8 检测浏览器是否是IE8浏览器 * @warning 如果浏览器不是IE, 则该值为undefined * @example * ```javascript * if ( UE.browser.ie8 ) { * console.log( '当前浏览器是IE8浏览器' ); * } * ``` */ browser.ie8 = !!document.documentMode; /** * @property { boolean } ie8Compat 检测浏览器模式是否为 IE8 兼容模式 * @warning 如果浏览器不是IE, 则该值为undefined * @example * ```javascript * if ( UE.browser.ie8Compat ) { * console.log( '当前浏览器运行在IE8兼容模式下' ); * } * ``` */ browser.ie8Compat = document.documentMode == 8; /** * @property { boolean } ie7Compat 检测浏览器模式是否为 IE7 兼容模式 * @warning 如果浏览器不是IE, 则该值为undefined * @example * ```javascript * if ( UE.browser.ie7Compat ) { * console.log( '当前浏览器运行在IE7兼容模式下' ); * } * ``` */ browser.ie7Compat = (version == 7 && !document.documentMode) || document.documentMode == 7; /** * @property { boolean } ie6Compat 检测浏览器模式是否为 IE6 模式 或者怪异模式 * @warning 如果浏览器不是IE, 则该值为undefined * @example * ```javascript * if ( UE.browser.ie6Compat ) { * console.log( '当前浏览器运行在IE6模式或者怪异模式下' ); * } * ``` */ browser.ie6Compat = version < 7 || browser.quirks; browser.ie9above = version > 8; browser.ie9below = version < 9; browser.ie11above = version > 10; browser.ie11below = version < 11; } // Gecko. if (browser.gecko) { var geckoRelease = agent.match(/rv:([\d\.]+)/); if (geckoRelease) { geckoRelease = geckoRelease[1].split("."); version = geckoRelease[0] * 10000 + (geckoRelease[1] || 0) * 100 + (geckoRelease[2] || 0) * 1; } } /** * @property { Number } chrome 检测当前浏览器是否为Chrome, 如果是,则返回Chrome的大版本号 * @warning 如果浏览器不是chrome, 则该值为undefined * @example * ```javascript * if ( UE.browser.chrome ) { * console.log( '当前浏览器是Chrome' ); * } * ``` */ if (/chrome\/(\d+\.\d)/i.test(agent)) { browser.chrome = +RegExp["\x241"]; } /** * @property { Number } safari 检测当前浏览器是否为Safari, 如果是,则返回Safari的大版本号 * @warning 如果浏览器不是safari, 则该值为undefined * @example * ```javascript * if ( UE.browser.safari ) { * console.log( '当前浏览器是Safari' ); * } * ``` */ if ( /(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) && !/chrome/i.test(agent) ) { browser.safari = +(RegExp["\x241"] || RegExp["\x242"]); } // Opera 9.50+ if (browser.opera) version = parseFloat(opera.version()); // WebKit 522+ (Safari 3+) if (browser.webkit) version = parseFloat(agent.match(/ applewebkit\/(\d+)/)[1]); /** * @property { Number } version 检测当前浏览器版本号 * @remind *
* console.log( wrapNode.innerHTML ); * * * UE.dom.domUtils.breakParent( node, parent ); * //拆分后 * //output: * console.log( wrapNode.innerHTML ); * * ``` */ breakParent: function (node, parent) { var tmpNode, parentClone = node, clone = node, leftNodes, rightNodes; do { parentClone = parentClone.parentNode; if (leftNodes) { tmpNode = parentClone.cloneNode(false); tmpNode.appendChild(leftNodes); leftNodes = tmpNode; tmpNode = parentClone.cloneNode(false); tmpNode.appendChild(rightNodes); rightNodes = tmpNode; } else { leftNodes = parentClone.cloneNode(false); rightNodes = leftNodes.cloneNode(false); } while ((tmpNode = clone.previousSibling)) { leftNodes.insertBefore(tmpNode, leftNodes.firstChild); } while ((tmpNode = clone.nextSibling)) { rightNodes.appendChild(tmpNode); } clone = parentClone; } while (parent !== parentClone); tmpNode = parent.parentNode; tmpNode.insertBefore(leftNodes, parent); tmpNode.insertBefore(rightNodes, parent); tmpNode.insertBefore(node, rightNodes); domUtils.remove(parent); return node; }, /** * 检查节点node是否是空inline节点 * @method isEmptyInlineElement * @param { Node } node 需要检测的节点对象 * @return { Number } 如果给定的节点是空的inline节点, 则返回1, 否则返回0。 * @example * ```html * => 1 * => 1 * => 1 * xx => 0 * ``` */ isEmptyInlineElement: function (node) { if (node.nodeType != 1 || !dtd.$removeEmpty[node.tagName]) { return 0; } node = node.firstChild; while (node) { //如果是创建的bookmark就跳过 if (domUtils.isBookmarkNode(node)) { return 0; } if ( (node.nodeType == 1 && !domUtils.isEmptyInlineElement(node)) || (node.nodeType == 3 && !domUtils.isWhitespace(node)) ) { return 0; } node = node.nextSibling; } return 1; }, /** * 删除node节点下首尾两端的空白文本子节点 * @method trimWhiteTextNode * @param { Element } node 需要执行删除操作的元素对象 * @example * ```javascript * var node = document.createElement("div"); * * node.appendChild( document.createTextNode( "" ) ); * * node.appendChild( document.createElement("div") ); * * node.appendChild( document.createTextNode( "" ) ); * * //3 * console.log( node.childNodes.length ); * * UE.dom.domUtils.trimWhiteTextNode( node ); * * //1 * console.log( node.childNodes.length ); * ``` */ trimWhiteTextNode: function (node) { function remove (dir) { var child; while ( (child = node[dir]) && child.nodeType == 3 && domUtils.isWhitespace(child) ) { node.removeChild(child); } } remove("firstChild"); remove("lastChild"); }, /** * 合并node节点下相同的子节点 * @name mergeChild * @desc * UE.dom.domUtils.mergeChild(node,tagName) //tagName要合并的子节点的标签 * @example *
xxaaxx
* ==> UE.dom.domUtils.mergeChild(node,'span') *xxaaxx
*/ mergeChild: function (node, tagName, attrs) { var list = domUtils.getElementsByTagName(node, node.tagName.toLowerCase()); for (var i = 0, ci; (ci = list[i++]);) { if (!ci.parentNode || domUtils.isBookmarkNode(ci)) { continue; } //span单独处理 if (ci.tagName.toLowerCase() == "span") { if (node === ci.parentNode) { domUtils.trimWhiteTextNode(node); if (node.childNodes.length == 1) { node.style.cssText = ci.style.cssText + ";" + node.style.cssText; domUtils.remove(ci, true); continue; } } ci.style.cssText = node.style.cssText + ";" + ci.style.cssText; if (attrs) { var style = attrs.style; if (style) { style = style.split(";"); for (var j = 0, s; (s = style[j++]);) { ci.style[utils.cssStyleToDomStyle(s.split(":")[0])] = s.split( ":" )[1]; } } } if (domUtils.isSameStyle(ci, node)) { domUtils.remove(ci, true); } continue; } if (domUtils.isSameElement(node, ci)) { domUtils.remove(ci, true); } } }, /** * 原生方法getElementsByTagName的封装 * @method getElementsByTagName * @param { Node } node 目标节点对象 * @param { String } tagName 需要查找的节点的tagName, 多个tagName以空格分割 * @return { Array } 符合条件的节点集合 */ getElementsByTagName: function (node, tagName, filter) { if (filter && utils.isString(filter)) { var className = filter; filter = function (node) { return domUtils.hasClass(node, className); }; } tagName = utils.trim(tagName).replace(/[ ]{2,}/g, " ").split(" "); var arr = []; for (var n = 0, ni; (ni = tagName[n++]);) { var list = node.getElementsByTagName(ni); for (var i = 0, ci; (ci = list[i++]);) { if (!filter || filter(ci)) arr.push(ci); } } return arr; }, /** * 将节点node提取到父节点上 * @method mergeToParent * @param { Element } node 需要提取的元素对象 * @example * ```html *xxxx[xxxx]x
==> range.applyInlineStyle("strong") ==>xxxx[xxxx]x
* ``` */ /** * 给range选区中的内容添加给定的inline标签, 并且为标签附加上一些初始化属性。 * @method applyInlineStyle * @param { String } tagName 需要添加的标签名 * @param { Object } attrs 跟随新添加的标签的属性 * @return { UE.dom.Range } 当前选区 * @example * ```html *xxxx[xxxx]x
* * ==> * * * range.applyInlineStyle("strong",{"style":"font-size:12px"}) * * ==> * *xxxx[xxxx]x
* ``` */ applyInlineStyle: function (tagName, attrs, list) { if (this.collapsed) return this; this.trimBoundary() .enlarge(false, function (node) { return node.nodeType == 1 && domUtils.isBlockElm(node); }) .adjustmentBoundary(); var bookmark = this.createBookmark(), end = bookmark.end, filterFn = function (node) { return node.nodeType == 1 ? node.tagName.toLowerCase() != "br" : !domUtils.isWhitespace(node); }, current = domUtils.getNextDomNode(bookmark.start, false, filterFn), node, pre, range = this.cloneRange(); while ( current && domUtils.getPosition(current, end) & domUtils.POSITION_PRECEDING ) { if (current.nodeType == 3 || dtd[tagName][current.tagName]) { range.setStartBefore(current); node = current; while ( node && (node.nodeType == 3 || dtd[tagName][node.tagName]) && node !== end ) { pre = node; node = domUtils.getNextDomNode( node, node.nodeType == 1, null, function (parent) { return dtd[tagName][parent.tagName]; } ); } var frag = range.setEndAfter(pre).extractContents(), elm; if (list && list.length > 0) { var level, top; top = level = list[0].cloneNode(false); for (var i = 1, ci; (ci = list[i++]);) { level.appendChild(ci.cloneNode(false)); level = level.firstChild; } elm = level; } else { elm = range.document.createElement(tagName); } if (attrs) { domUtils.setAttributes(elm, attrs); } elm.appendChild(frag); //针对嵌套span的全局样式指定,做容错处理 if (elm.tagName == "SPAN" && attrs && attrs.style) { utils.each(elm.getElementsByTagName("span"), function (s) { s.style.cssText = s.style.cssText + ";" + attrs.style; }); } range.insertNode(list ? top : elm); //处理下滑线在a上的情况 var aNode; if ( tagName == "span" && attrs.style && /text\-decoration/.test(attrs.style) && (aNode = domUtils.findParentByTagName(elm, "a", true)) ) { domUtils.setAttributes(aNode, attrs); domUtils.remove(elm, true); elm = aNode; } else { domUtils.mergeSibling(elm); domUtils.clearEmptySibling(elm); } //去除子节点相同的 domUtils.mergeChild(elm, attrs); current = domUtils.getNextDomNode(elm, false, filterFn); domUtils.mergeToParent(elm); if (node === end) { break; } } else { current = domUtils.getNextDomNode(current, true, filterFn); } } return this.moveToBookmark(bookmark); }, /** * 移除当前选区内指定的inline标签,但保留其中的内容 * @method removeInlineStyle * @param { String } tagName 需要移除的标签名 * @return { UE.dom.Range } 当前的range对象 * @example * ```html * xx[xxxxyyyzz]z => range.removeInlineStyle(["em"]) => xx[xxxxyyyzz]z * ``` */ /** * 移除当前选区内指定的一组inline标签,但保留其中的内容 * @method removeInlineStyle * @param { Array } tagNameArr 需要移除的标签名的数组 * @return { UE.dom.Range } 当前的range对象 * @see UE.dom.Range:removeInlineStyle(String) */ removeInlineStyle: function (tagNames) { if (this.collapsed) return this; tagNames = utils.isArray(tagNames) ? tagNames : [tagNames]; this.shrinkBoundary().adjustmentBoundary(); var start = this.startContainer, end = this.endContainer; while (1) { if (start.nodeType == 1) { if (utils.indexOf(tagNames, start.tagName.toLowerCase()) > -1) { break; } if (start.tagName.toLowerCase() == "body") { start = null; break; } } start = start.parentNode; } while (1) { if (end.nodeType == 1) { if (utils.indexOf(tagNames, end.tagName.toLowerCase()) > -1) { break; } if (end.tagName.toLowerCase() == "body") { end = null; break; } } end = end.parentNode; } var bookmark = this.createBookmark(), frag, tmpRange; if (start) { tmpRange = this.cloneRange() .setEndBefore(bookmark.start) .setStartBefore(start); frag = tmpRange.extractContents(); tmpRange.insertNode(frag); domUtils.clearEmptySibling(start, true); start.parentNode.insertBefore(bookmark.start, start); } if (end) { tmpRange = this.cloneRange() .setStartAfter(bookmark.end) .setEndAfter(end); frag = tmpRange.extractContents(); tmpRange.insertNode(frag); domUtils.clearEmptySibling(end, false, true); end.parentNode.insertBefore(bookmark.end, end.nextSibling); } var current = domUtils.getNextDomNode(bookmark.start, false, function ( node ) { return node.nodeType == 1; }), next; while (current && current !== bookmark.end) { next = domUtils.getNextDomNode(current, true, function (node) { return node.nodeType == 1; }); if (utils.indexOf(tagNames, current.tagName.toLowerCase()) > -1) { domUtils.remove(current, true); } current = next; } return this.moveToBookmark(bookmark); }, /** * 获取当前选中的自闭合的节点 * @method getClosedNode * @return { Node | NULL } 如果当前选中的是自闭合节点, 则返回该节点, 否则返回NULL */ getClosedNode: function () { var node; if (!this.collapsed) { var range = this.cloneRange().adjustmentBoundary().shrinkBoundary(); if (selectOneNode(range)) { var child = range.startContainer.childNodes[range.startOffset]; if ( child && child.nodeType === 1 && (dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName]) ) { node = child; } } } return node; }, /** * 在页面上高亮range所表示的选区 * @method select * @return { UE.dom.Range } 返回当前Range对象 */ //这里不区分ie9以上,trace:3824 select: browser.ie ? function (noFillData, textRange) { var nativeRange; if (!this.collapsed) this.shrinkBoundary(); var node = this.getClosedNode(); if (node && !textRange) { try { nativeRange = this.document.body.createControlRange(); nativeRange.addElement(node); nativeRange.select(); } catch (e) { } return this; } var bookmark = this.createBookmark(), start = bookmark.start, end; nativeRange = this.document.body.createTextRange(); nativeRange.moveToElementText(start); nativeRange.moveStart("character", 1); if (!this.collapsed) { var nativeRangeEnd = this.document.body.createTextRange(); end = bookmark.end; nativeRangeEnd.moveToElementText(end); nativeRange.setEndPoint("EndToEnd", nativeRangeEnd); } else { if (!noFillData && this.startContainer.nodeType != 3) { //使用|x固定住光标 var tmpText = this.document.createTextNode(fillChar), tmp = this.document.createElement("span"); tmp.appendChild(this.document.createTextNode(fillChar)); start.parentNode.insertBefore(tmp, start); start.parentNode.insertBefore(tmpText, start); //当点b,i,u时,不能清除i上边的b removeFillData(this.document, tmpText); fillData = tmpText; mergeSibling(tmp, "previousSibling"); mergeSibling(start, "nextSibling"); nativeRange.moveStart("character", -1); nativeRange.collapse(true); } } this.moveToBookmark(bookmark); tmp && domUtils.remove(tmp); //IE在隐藏状态下不支持range操作,catch一下 try { nativeRange.select(); } catch (e) { } return this; } : function (notInsertFillData) { function checkOffset (rng) { function check (node, offset, dir) { if (node.nodeType == 3 && node.nodeValue.length < offset) { rng[dir + "Offset"] = node.nodeValue.length; } } check(rng.startContainer, rng.startOffset, "start"); check(rng.endContainer, rng.endOffset, "end"); } var win = domUtils.getWindow(this.document), sel = win.getSelection(), txtNode; //FF下关闭自动长高时滚动条在关闭dialog时会跳 //ff下如果不body.focus将不能定位闭合光标到编辑器内 browser.gecko ? this.document.body.focus() : win.focus(); if (sel) { sel.removeAllRanges(); // trace:870 chrome/safari后边是br对于闭合得range不能定位 所以去掉了判断 // this.startContainer.nodeType != 3 &&! ((child = this.startContainer.childNodes[this.startOffset]) && child.nodeType == 1 && child.tagName == 'BR' if (this.collapsed && !notInsertFillData) { // //opear如果没有节点接着,原生的不能够定位,不能在body的第一级插入空白节点 // if (notInsertFillData && browser.opera && !domUtils.isBody(this.startContainer) && this.startContainer.nodeType == 1) { // var tmp = this.document.createTextNode(''); // this.insertNode(tmp).setStart(tmp, 0).collapse(true); // } // //处理光标落在文本节点的情况 //处理以下的情况 //|xxxx //xxxx|xxxx //xxxx| var start = this.startContainer, child = start; if (start.nodeType == 1) { child = start.childNodes[this.startOffset]; } if ( !(start.nodeType == 3 && this.startOffset) && (child ? !child.previousSibling || child.previousSibling.nodeType != 3 : !start.lastChild || start.lastChild.nodeType != 3) ) { txtNode = this.document.createTextNode(fillChar); //跟着前边走 this.insertNode(txtNode); removeFillData(this.document, txtNode); mergeSibling(txtNode, "previousSibling"); mergeSibling(txtNode, "nextSibling"); fillData = txtNode; this.setStart(txtNode, browser.webkit ? 1 : 0).collapse(true); } } var nativeRange = this.document.createRange(); if ( this.collapsed && browser.opera && this.startContainer.nodeType == 1 ) { var child = this.startContainer.childNodes[this.startOffset]; if (!child) { //往前靠拢 child = this.startContainer.lastChild; if (child && domUtils.isBr(child)) { this.setStartBefore(child).collapse(true); } } else { //向后靠拢 while (child && domUtils.isBlockElm(child)) { if (child.nodeType == 1 && child.childNodes[0]) { child = child.childNodes[0]; } else { break; } } child && this.setStartBefore(child).collapse(true); } } //是createAddress最后一位算的不准,现在这里进行微调 checkOffset(this); nativeRange.setStart(this.startContainer, this.startOffset); nativeRange.setEnd(this.endContainer, this.endOffset); sel.addRange(nativeRange); } return this; }, /** * 滚动到当前range开始的位置 * @method scrollToView * @param { Window } win 当前range对象所属的window对象 * @return { UE.dom.Range } 当前Range对象 */ /** * 滚动到距离当前range开始位置 offset 的位置处 * @method scrollToView * @param { Window } win 当前range对象所属的window对象 * @param { Number } offset 距离range开始位置处的偏移量, 如果为正数, 则向下偏移, 反之, 则向上偏移 * @return { UE.dom.Range } 当前Range对象 */ scrollToView: function (win, offset) { win = win ? window : domUtils.getWindow(this.document); offset = offset || (win.innerHeight - 100); // console.log('xxx',win, offset); var me = this, span = me.document.createElement("span"); //trace:717 span.innerHTML = " "; me.cloneRange().insertNode(span); domUtils.scrollToView(span, win, offset); domUtils.remove(span); return me; }, /** * 判断当前选区内容是否占位符 * @private * @method inFillChar * @return { Boolean } 如果是占位符返回true,否则返回false */ inFillChar: function () { var start = this.startContainer; if ( this.collapsed && start.nodeType == 3 && start.nodeValue.replace(new RegExp("^" + domUtils.fillChar), "") .length + 1 == start.nodeValue.length ) { return true; } return false; }, /** * 保存 * @method createAddress * @private * @return { Boolean } 返回开始和结束的位置 * @example * ```html * ** aaaa * * * bbbb * * *
* * * * ``` */ createAddress: function (ignoreEnd, ignoreTxt) { var addr = {}, me = this; function getAddress (isStart) { var node = isStart ? me.startContainer : me.endContainer; var parents = domUtils.findParents(node, true, function (node) { return !domUtils.isBody(node); }), addrs = []; for (var i = 0, ci; (ci = parents[i++]);) { addrs.push(domUtils.getNodeIndex(ci, ignoreTxt)); } var firstIndex = 0; if (ignoreTxt) { if (node.nodeType == 3) { var tmpNode = node.previousSibling; while (tmpNode && tmpNode.nodeType == 3) { firstIndex += tmpNode.nodeValue.replace(fillCharReg, "").length; tmpNode = tmpNode.previousSibling; } firstIndex += isStart ? me.startOffset : me.endOffset; // - (fillCharReg.test(node.nodeValue) ? 1 : 0 ) } else { node = node.childNodes[isStart ? me.startOffset : me.endOffset]; if (node) { firstIndex = domUtils.getNodeIndex(node, ignoreTxt); } else { node = isStart ? me.startContainer : me.endContainer; var first = node.firstChild; while (first) { if (domUtils.isFillChar(first)) { first = first.nextSibling; continue; } firstIndex++; if (first.nodeType == 3) { while (first && first.nodeType == 3) { first = first.nextSibling; } } else { first = first.nextSibling; } } } } } else { firstIndex = isStart ? domUtils.isFillChar(node) ? 0 : me.startOffset : me.endOffset; } if (firstIndex < 0) { firstIndex = 0; } addrs.push(firstIndex); return addrs; } addr.startAddress = getAddress(true); if (!ignoreEnd) { addr.endAddress = me.collapsed ? [].concat(addr.startAddress) : getAddress(); } return addr; }, /** * 保存 * @method createAddress * @private * @return { Boolean } 返回开始和结束的位置 * @example * ```html * ** aaaa * * * bbbb * * *
* * * * ``` */ moveToAddress: function (addr, ignoreEnd) { var me = this; function getNode (address, isStart) { var tmpNode = me.document.body, parentNode, offset; for (var i = 0, ci, l = address.length; i < l; i++) { ci = address[i]; parentNode = tmpNode; tmpNode = tmpNode.childNodes[ci]; if (!tmpNode) { offset = ci; break; } } if (isStart) { if (tmpNode) { me.setStartBefore(tmpNode); } else { me.setStart(parentNode, offset); } } else { if (tmpNode) { me.setEndBefore(tmpNode); } else { me.setEnd(parentNode, offset); } } } getNode(addr.startAddress, true); !ignoreEnd && addr.endAddress && getNode(addr.endAddress); return me; }, /** * 判断给定的Range对象是否和当前Range对象表示的是同一个选区 * @method equals * @param { UE.dom.Range } 需要判断的Range对象 * @return { Boolean } 如果给定的Range对象与当前Range对象表示的是同一个选区, 则返回true, 否则返回false */ equals: function (rng) { for (var p in this) { if (this.hasOwnProperty(p)) { if (this[p] !== rng[p]) return false; } } return true; }, /** * 遍历range内的节点。每当遍历一个节点时, 都会执行参数项 doFn 指定的函数, 该函数的接受当前遍历的节点 * 作为其参数。 * @method traversal * @param { Function } doFn 对每个遍历的节点要执行的方法, 该方法接受当前遍历的节点作为其参数 * @return { UE.dom.Range } 当前range对象 * @example * ```html * * * * * * * * * * * ``` */ /** * 遍历range内的节点。 * 每当遍历一个节点时, 都会执行参数项 doFn 指定的函数, 该函数的接受当前遍历的节点 * 作为其参数。 * 可以通过参数项 filterFn 来指定一个过滤器, 只有符合该过滤器过滤规则的节点才会触 * 发doFn函数的执行 * @method traversal * @param { Function } doFn 对每个遍历的节点要执行的方法, 该方法接受当前遍历的节点作为其参数 * @param { Function } filterFn 过滤器, 该函数接受当前遍历的节点作为参数, 如果该节点满足过滤 * 规则, 请返回true, 该节点会触发doFn, 否则, 请返回false, 则该节点不 * 会触发doFn。 * @return { UE.dom.Range } 当前range对象 * @see UE.dom.Range:traversal(Function) * @example * ```html * * * * * * * * * * * ``` */ traversal: function (doFn, filterFn) { if (this.collapsed) return this; var bookmark = this.createBookmark(), end = bookmark.end, current = domUtils.getNextDomNode(bookmark.start, false, filterFn); while ( current && current !== end && domUtils.getPosition(current, end) & domUtils.POSITION_PRECEDING ) { var tmpNode = domUtils.getNextDomNode(current, false, filterFn); doFn(current); current = tmpNode; } return this.moveToBookmark(bookmark); } }; })(); // core/Selection.js /** * 选集 * @file * @module UE.dom * @class Selection * @since 1.2.6.1 */ /** * 选区集合 * @unfile * @module UE.dom * @class Selection */ (function () { function getBoundaryInformation (range, start) { var getIndex = domUtils.getNodeIndex; range = range.duplicate(); range.collapse(start); var parent = range.parentElement(); //如果节点里没有子节点,直接退出 if (!parent.hasChildNodes()) { return { container: parent, offset: 0 }; } var siblings = parent.children, child, testRange = range.duplicate(), startIndex = 0, endIndex = siblings.length - 1, index = -1, distance; while (startIndex <= endIndex) { index = Math.floor((startIndex + endIndex) / 2); child = siblings[index]; testRange.moveToElementText(child); var position = testRange.compareEndPoints("StartToStart", range); if (position > 0) { endIndex = index - 1; } else if (position < 0) { startIndex = index + 1; } else { //trace:1043 return { container: parent, offset: getIndex(child) }; } } if (index == -1) { testRange.moveToElementText(parent); testRange.setEndPoint("StartToStart", range); distance = testRange.text.replace(/(\r\n|\r)/g, "\n").length; siblings = parent.childNodes; if (!distance) { child = siblings[siblings.length - 1]; return { container: child, offset: child.nodeValue.length }; } var i = siblings.length; while (distance > 0) { distance -= siblings[--i].nodeValue.length; } return { container: siblings[i], offset: -distance }; } testRange.collapse(position > 0); testRange.setEndPoint(position > 0 ? "StartToStart" : "EndToStart", range); distance = testRange.text.replace(/(\r\n|\r)/g, "\n").length; if (!distance) { return dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName] ? { container: parent, offset: getIndex(child) + (position > 0 ? 0 : 1) } : { container: child, offset: position > 0 ? 0 : child.childNodes.length }; } while (distance > 0) { try { var pre = child; child = child[position > 0 ? "previousSibling" : "nextSibling"]; distance -= child.nodeValue.length; } catch (e) { return { container: parent, offset: getIndex(pre) }; } } return { container: child, offset: position > 0 ? -distance : child.nodeValue.length + distance }; } /** * 将ieRange转换为Range对象 * @param {Range} ieRange ieRange对象 * @param {Range} range Range对象 * @return {Range} range 返回转换后的Range对象 */ function transformIERangeToRange (ieRange, range) { if (ieRange.item) { range.selectNode(ieRange.item(0)); } else { var bi = getBoundaryInformation(ieRange, true); range.setStart(bi.container, bi.offset); if (ieRange.compareEndPoints("StartToEnd", ieRange) != 0) { bi = getBoundaryInformation(ieRange, false); range.setEnd(bi.container, bi.offset); } } return range; } /** * 获得ieRange * @param {Selection} sel Selection对象 * @return {ieRange} 得到ieRange */ function _getIERange (sel) { var ieRange; //ie下有可能报错 try { ieRange = sel.getNative().createRange(); } catch (e) { return null; } var el = ieRange.item ? ieRange.item(0) : ieRange.parentElement(); if ((el.ownerDocument || el) === sel.document) { return ieRange; } return null; } var Selection = (dom.Selection = function (doc) { var me = this, iframe; me.document = doc; if (browser.ie9below) { iframe = domUtils.getWindow(doc).frameElement; domUtils.on(iframe, "beforedeactivate", function () { me._bakIERange = me.getIERange(); }); domUtils.on(iframe, "activate", function () { try { if (!_getIERange(me) && me._bakIERange) { me._bakIERange.select(); } } catch (ex) { } me._bakIERange = null; }); } iframe = doc = null; }); Selection.prototype = { rangeInBody: function (rng, txtRange) { var node = browser.ie9below || txtRange ? rng.item ? rng.item() : rng.parentElement() : rng.startContainer; return node === this.document.body || domUtils.inDoc(node, this.document); }, /** * 获取原生seleciton对象 * @method getNative * @return { Object } 获得selection对象 * @example * ```javascript * editor.selection.getNative(); * ``` */ getNative: function () { var doc = this.document; try { return !doc ? null : browser.ie9below ? doc.selection : domUtils.getWindow(doc).getSelection(); } catch (e) { return null; } }, /** * 获得ieRange * @method getIERange * @return { Object } 返回ie原生的Range * @example * ```javascript * editor.selection.getIERange(); * ``` */ getIERange: function () { var ieRange = _getIERange(this); if (!ieRange) { if (this._bakIERange) { return this._bakIERange; } } return ieRange; }, /** * 缓存当前选区的range和选区的开始节点 * @method cache */ cache: function () { this.clear(); this._cachedRange = this.getRange(); this._cachedStartElement = this.getStart(); this._cachedStartElementPath = this.getStartElementPath(); }, /** * 获取选区开始位置的父节点到body * @method getStartElementPath * @return { Array } 返回父节点集合 * @example * ```javascript * editor.selection.getStartElementPath(); * ``` */ getStartElementPath: function () { if (this._cachedStartElementPath) { return this._cachedStartElementPath; } var start = this.getStart(); if (start) { return domUtils.findParents(start, true, null, true); } return []; }, /** * 清空缓存 * @method clear */ clear: function () { this._cachedStartElementPath = this._cachedRange = this._cachedStartElement = null; }, /** * 编辑器是否得到了选区 * @method isFocus */ isFocus: function () { try { if (browser.ie9below) { var nativeRange = _getIERange(this); return !!(nativeRange && this.rangeInBody(nativeRange)); } else { return !!this.getNative().rangeCount; } } catch (e) { return false; } }, /** * 获取选区对应的Range * @method getRange * @return { Object } 得到Range对象 * @example * ```javascript * editor.selection.getRange(); * ``` */ getRange: function () { var me = this; function optimze (range) { var child = me.document.body.firstChild, collapsed = range.collapsed; while (child && child.firstChild) { range.setStart(child, 0); child = child.firstChild; } if (!range.startContainer) { range.setStart(me.document.body, 0); } if (collapsed) { range.collapse(true); } } if (me._cachedRange != null) { return this._cachedRange; } var range = new baidu.editor.dom.Range(me.document); if (browser.ie9below) { var nativeRange = me.getIERange(); if (nativeRange) { //备份的_bakIERange可能已经实效了,dom树发生了变化比如从源码模式切回来,所以try一下,实效就放到body开始位置 try { transformIERangeToRange(nativeRange, range); } catch (e) { optimze(range); } } else { optimze(range); } } else { var sel = me.getNative(); if (sel && sel.rangeCount) { var firstRange = sel.getRangeAt(0); var lastRange = sel.getRangeAt(sel.rangeCount - 1); range .setStart(firstRange.startContainer, firstRange.startOffset) .setEnd(lastRange.endContainer, lastRange.endOffset); if ( range.collapsed && domUtils.isBody(range.startContainer) && !range.startOffset ) { optimze(range); } } else { //trace:1734 有可能已经不在dom树上了,标识的节点 if ( this._bakRange && domUtils.inDoc(this._bakRange.startContainer, this.document) ) { return this._bakRange; } optimze(range); } } return (this._bakRange = range); }, /** * 获取开始元素,用于状态反射 * @method getStart * @return { Element } 获得开始元素 * @example * ```javascript * editor.selection.getStart(); * ``` */ getStart: function () { if (this._cachedStartElement) { return this._cachedStartElement; } var range = browser.ie9below ? this.getIERange() : this.getRange(), tmpRange, start, tmp, parent; if (browser.ie9below) { if (!range) { //todo 给第一个值可能会有问题 return this.document.body.firstChild; } //control元素 if (range.item) { return range.item(0); } tmpRange = range.duplicate(); //修正ie下x[xx] 闭合后 x|xx tmpRange.text.length > 0 && tmpRange.moveStart("character", 1); tmpRange.collapse(1); start = tmpRange.parentElement(); parent = tmp = range.parentElement(); while ((tmp = tmp.parentNode)) { if (tmp == start) { start = parent; break; } } } else { range.shrinkBoundary(); start = range.startContainer; if (start.nodeType == 1 && start.hasChildNodes()) { start = start.childNodes[ Math.min(start.childNodes.length - 1, range.startOffset) ]; } if (start.nodeType == 3) { return start.parentNode; } } return start; }, /** * 得到选区中的文本 * @method getText * @return { String } 选区中包含的文本 * @example * ```javascript * editor.selection.getText(); * ``` */ getText: function () { var nativeSel, nativeRange; if (this.isFocus() && (nativeSel = this.getNative())) { nativeRange = browser.ie9below ? nativeSel.createRange() : nativeSel.getRangeAt(0); return browser.ie9below ? nativeRange.text : nativeRange.toString(); } return ""; }, /** * 清除选区 * @method clearRange * @example * ```javascript * editor.selection.clearRange(); * ``` */ clearRange: function () { this.getNative()[browser.ie9below ? "empty" : "removeAllRanges"](); } }; })(); // core/Editor.js /** * 编辑器主类,包含编辑器提供的大部分公用接口 * @file * @module UE * @class Editor * @since 1.2.6.1 */ /** * UEditor公用空间,UEditor所有的功能都挂载在该空间下 * @unfile * @module UE */ /** * UEditor的核心类,为用户提供与编辑器交互的接口。 * @unfile * @module UE * @class Editor */ (function () { var uid = 0, _selectionChangeTimer; /** * 获取编辑器的html内容,赋值到编辑器所在表单的textarea文本域里面 * @private * @method setValue * @param { UE.Editor } editor 编辑器事例 */ function setValue (form, editor) { if (!editor.options.textarea) { return; } var textarea; textarea = editor.textarea; if (!textarea) { textarea = domUtils.getElementsByTagName(form, "textarea", function (node) { return node.id === 'ueditor_textarea_' + editor.options.textarea; })[0]; } if (!textarea) { textarea = domUtils.getElementsByTagName(form, "textarea", function (node) { return node.name === editor.options.textarea; })[0]; } if (!textarea) { form.appendChild( (textarea = domUtils.createElement(document, "textarea", { name: editor.options.textarea, id: "ueditor_textarea_" + editor.options.textarea, style: "display:none" })) ); } if (textarea && !editor.textarea) { editor.textarea = textarea; } !textarea.getAttribute("name") && textarea.setAttribute("name", editor.options.textarea); textarea.value = editor.hasContents() ? editor.options.allHtmlEnabled ? editor.getAllHtml() : editor.getContent(null, null, true) : ""; } function loadPlugins (me) { //初始化插件 for (var pi in UE.plugins) { UE.plugins[pi].call(me); } } function checkCurLang (I18N) { for (var lang in I18N) { return lang; } } function langReadied (me) { me.langIsReady = true; me.fireEvent("langReady"); } /** * 编辑器准备就绪后会触发该事件 * @module UE * @class Editor * @event ready * @remind render方法执行完成之后,会触发该事件 * @remind * @example * ```javascript * editor.addListener( 'ready', function( editor ) { * editor.execCommand( 'focus' ); //编辑器家在完成后,让编辑器拿到焦点 * } ); * ``` */ /** * 执行destroy方法,会触发该事件 * @module UE * @class Editor * @event destroy * @see UE.Editor:destroy() */ /** * 执行reset方法,会触发该事件 * @module UE * @class Editor * @event reset * @see UE.Editor:reset() */ /** * 执行focus方法,会触发该事件 * @module UE * @class Editor * @event focus * @see UE.Editor:focus(Boolean) */ /** * 语言加载完成会触发该事件 * @module UE * @class Editor * @event langReady */ /** * 运行命令之后会触发该命令 * @module UE * @class Editor * @event beforeExecCommand */ /** * 运行命令之后会触发该命令 * @module UE * @class Editor * @event afterExecCommand */ /** * 运行命令之前会触发该命令 * @module UE * @class Editor * @event firstBeforeExecCommand */ /** * 在getContent方法执行之前会触发该事件 * @module UE * @class Editor * @event beforeGetContent * @see UE.Editor:getContent() */ /** * 在getContent方法执行之后会触发该事件 * @module UE * @class Editor * @event afterGetContent * @see UE.Editor:getContent() */ /** * 在getAllHtml方法执行时会触发该事件 * @module UE * @class Editor * @event getAllHtml * @see UE.Editor:getAllHtml() */ /** * 在setContent方法执行之前会触发该事件 * @module UE * @class Editor * @event beforeSetContent * @see UE.Editor:setContent(String) */ /** * 在setContent方法执行之后会触发该事件 * @module UE * @class Editor * @event afterSetContent * @see UE.Editor:setContent(String) */ /** * 每当编辑器内部选区发生改变时,将触发该事件 * @event selectionchange * @warning 该事件的触发非常频繁,不建议在该事件的处理过程中做重量级的处理 * @example * ```javascript * editor.addListener( 'selectionchange', function( editor ) { * console.log('选区发生改变'); * } */ /** * 在所有selectionchange的监听函数执行之前,会触发该事件 * @module UE * @class Editor * @event beforeSelectionChange * @see UE.Editor:selectionchange */ /** * 在所有selectionchange的监听函数执行完之后,会触发该事件 * @module UE * @class Editor * @event afterSelectionChange * @see UE.Editor:selectionchange */ /** * 编辑器内容发生改变时会触发该事件 * @module UE * @class Editor * @event contentChange */ /** * 以默认参数构建一个编辑器实例 * @constructor * @remind 通过 改构造方法实例化的编辑器,不带ui层.需要render到一个容器,编辑器实例才能正常渲染到页面 * @example * ```javascript * var editor = new UE.Editor(); * editor.execCommand('blod'); * ``` * @see UE.Config */ /** * 以给定的参数集合创建一个编辑器实例,对于未指定的参数,将应用默认参数。 * @constructor * @remind 通过 改构造方法实例化的编辑器,不带ui层.需要render到一个容器,编辑器实例才能正常渲染到页面 * @param { Object } setting 创建编辑器的参数 * @example * ```javascript * var editor = new UE.Editor(); * editor.execCommand('blod'); * ``` * @see UE.Config */ var Editor = (UE.Editor = function (options) { var me = this; me.uid = uid++; EventBase.call(me); me.commands = {}; me.options = utils.extend(utils.clone(options || {}), UEDITOR_CONFIG, true); me.shortcutkeys = {}; me.inputRules = []; me.outputRules = []; //设置默认的常用属性 me.setOpt(Editor.defaultOptions(me)); /* 尝试异步加载后台配置 */ me.loadServerConfig(); if (!utils.isEmptyObject(UE.I18N)) { //修改默认的语言类型 me.options.lang = checkCurLang(UE.I18N); UE.plugin.load(me); langReadied(me); } else { utils.loadFile( document, { src: me.options.langPath + me.options.lang + "/" + me.options.lang + ".js?7a537435", tag: "script", type: "text/javascript", defer: "defer" }, function () { UE.plugin.load(me); langReadied(me); } ); } UE.instants["ueditorInstant" + me.uid] = me; }); Editor.prototype = { registerCommand: function (name, obj) { this.commands[name] = obj; }, /** * 编辑器对外提供的监听ready事件的接口, 通过调用该方法,达到的效果与监听ready事件是一致的 * @method ready * @param { Function } fn 编辑器ready之后所执行的回调, 如果在注册事件之前编辑器已经ready,将会 * 立即触发该回调。 * @remind 需要等待编辑器加载完成后才能执行的代码,可以使用该方法传入 * @example * ```javascript * editor.ready( function( editor ) { * editor.setContent('初始化完毕'); * } ); * ``` * @see UE.Editor.event:ready */ ready: function (fn) { var me = this; if (fn) { me.isReady ? fn.apply(me) : me.addListener("ready", fn); } }, /** * 该方法是提供给插件里面使用,设置配置项默认值 * @method setOpt * @warning 三处设置配置项的优先级: 实例化时传入参数 > setOpt()设置 > config文件里设置 * @warning 该方法仅供编辑器插件内部和编辑器初始化时调用,其他地方不能调用。 * @param { String } key 编辑器的可接受的选项名称 * @param { * } val 该选项可接受的值 * @example * ```javascript * editor.setOpt( 'initContent', '欢迎使用编辑器' ); * ``` */ /** * 该方法是提供给插件里面使用,以{key:value}集合的方式设置插件内用到的配置项默认值 * @method setOpt * @warning 三处设置配置项的优先级: 实例化时传入参数 > setOpt()设置 > config文件里设置 * @warning 该方法仅供编辑器插件内部和编辑器初始化时调用,其他地方不能调用。 * @param { Object } options 将要设置的选项的键值对对象 * @example * ```javascript * editor.setOpt( { * 'initContent': '欢迎使用编辑器' * } ); * ``` */ setOpt: function (key, val) { var obj = {}; if (utils.isString(key)) { obj[key] = val; } else { obj = key; } utils.extend(this.options, obj, true); }, getOpt: function (key) { return this.options[key]; }, /** * 销毁编辑器实例,使用textarea代替 * @method destroy * @example * ```javascript * editor.destroy(); * ``` */ destroy: function () { var me = this; me.fireEvent("destroy"); var container = me.container.parentNode; var textarea = me.textarea; if (!textarea) { textarea = document.createElement("textarea"); container.parentNode.insertBefore(textarea, container); } else { textarea.style.display = ""; } textarea.style.width = me.iframe.offsetWidth + "px"; textarea.style.height = me.iframe.offsetHeight + "px"; textarea.value = me.getContent(); textarea.id = me.key; container.innerHTML = ""; domUtils.remove(container); var key = me.key; //trace:2004 for (var p in me) { if (me.hasOwnProperty(p)) { delete this[p]; } } UE.delEditor(key); }, /** * 渲染编辑器的DOM到指定容器 * @method render * @param { String } containerId 指定一个容器ID * @remind 执行该方法,会触发ready事件 * @warning 必须且只能调用一次 */ /** * 渲染编辑器的DOM到指定容器 * @method render * @param { Element } containerDom 直接指定容器对象 * @remind 执行该方法,会触发ready事件 * @warning 必须且只能调用一次 */ render: function (container) { var me = this, options = me.options, getStyleValue = function (attr) { return parseInt(domUtils.getComputedStyle(container, attr)); }; if (utils.isString(container)) { container = document.getElementById(container); } if (container) { if (options.initialFrameWidth) { options.minFrameWidth = options.initialFrameWidth; } else { options.minFrameWidth = options.initialFrameWidth = container.offsetWidth; } if (options.initialFrameHeight) { options.minFrameHeight = options.initialFrameHeight; } else { options.initialFrameHeight = options.minFrameHeight = container.offsetHeight; } container.style.width = /%$/.test(options.initialFrameWidth) ? "100%" : options.initialFrameWidth - getStyleValue("padding-left") - getStyleValue("padding-right") + "px"; container.style.height = /%$/.test(options.initialFrameHeight) ? "100%" : options.initialFrameHeight - getStyleValue("padding-top") - getStyleValue("padding-bottom") + "px"; container.style.zIndex = options.zIndex; var additionCssHtml = []; for (var i in options.iframeCssUrlsAddition) { additionCssHtml.push("") } var html = (ie && browser.version < 9 ? "" : "") + "" + "" + "" + (options.iframeCssUrl ? "" : "") + (options.initialStyle ? "" : "") + additionCssHtml.join("") + "" + "" + "" + (options.iframeJsUrl ? "" : "") + ""; container.appendChild( domUtils.createElement(document, "iframe", { id: "ueditor_" + me.uid, width: "100%", height: "100%", frameborder: "0", //先注释掉了,加的原因忘记了,但开启会直接导致全屏模式下内容多时不会出现滚动条 // scrolling :'no', src: "javascript:void(function(){document.open();" + (options.customDomain && document.domain != location.hostname ? 'document.domain="' + document.domain + '";' : "") + 'document.write("' + html + '");document.close();}())' }) ); container.style.overflow = "hidden"; //解决如果是给定的百分比,会导致高度算不对的问题 setTimeout(function () { if (/%$/.test(options.initialFrameWidth)) { options.minFrameWidth = options.initialFrameWidth = container.offsetWidth; //如果这里给定宽度,会导致ie在拖动窗口大小时,编辑区域不随着变化 // container.style.width = options.initialFrameWidth + 'px'; } if (/%$/.test(options.initialFrameHeight)) { options.minFrameHeight = options.initialFrameHeight = container.offsetHeight; container.style.height = options.initialFrameHeight + "px"; } }); } }, /** * 编辑器初始化 * @method _setup * @private * @param { Element } doc 编辑器Iframe中的文档对象 */ _setup: function (doc) { var me = this, options = me.options; if (ie) { doc.body.disabled = true; doc.body.contentEditable = true; doc.body.disabled = false; } else { doc.body.contentEditable = true; } doc.body.spellcheck = false; me.document = doc; me.window = doc.defaultView || doc.parentWindow; me.iframe = me.window.frameElement; me.body = doc.body; me.selection = new dom.Selection(doc); //gecko初始化就能得到range,无法判断isFocus了 var geckoSel; if (browser.gecko && (geckoSel = this.selection.getNative())) { geckoSel.removeAllRanges(); } this._initEvents(); //为form提交提供一个隐藏的textarea for ( var form = this.iframe.parentNode; !domUtils.isBody(form); form = form.parentNode ) { if (form.tagName === "FORM") { me.form = form; if (me.options.autoSyncData) { domUtils.on(me.window, "blur", function () { setValue(form, me); }); domUtils.on(form, "submit", function () { me.fireEvent("beforesubmit"); }); } else { domUtils.on(form, "submit", function () { setValue(this, me); me.fireEvent("beforesubmit"); }); } break; } } if (options.initialContent) { if (options.autoClearinitialContent) { var oldExecCommand = me.execCommand; me.execCommand = function () { me.fireEvent("firstBeforeExecCommand"); return oldExecCommand.apply(me, arguments); }; this._setDefaultContent(options.initialContent); } else this.setContent(options.initialContent, false, true); } //编辑器不能为空内容 if (domUtils.isEmptyNode(me.body)) { me.body.innerHTML = "" + (browser.ie ? "" : "
") + "
123456
* var content = editor.getContent(); //返回值:123456
* ``` */ /** * 获取编辑器的内容。 可以通过参数定义编辑器内置的判空规则 * @method getContent * @param { Function } fn 自定的判空规则, 要求该方法返回一个boolean类型的值, * 代表当前编辑器的内容是否空, * 如果返回true, 则该方法将直接返回空字符串;如果返回false,则编辑器将返回 * 经过内置过滤规则处理后的内容。 * @remind 该方法在处理包含有初始化内容的时候能起到很好的作用。 * @warning 该方法获取到的是经过编辑器内置的过滤规则进行过滤后得到的内容 * @return { String } 编辑器的内容字符串 * @example * ```javascript * // editor 是一个编辑器的实例 * var content = editor.getContent( function ( editor ) { * return editor.body.innerHTML === '欢迎使用UEditor'; //返回空字符串 * } ); * ``` */ getContent: function (cmd, fn, notSetCursor, ignoreBlank, formatter) { var me = this; if (cmd && utils.isFunction(cmd)) { fn = cmd; cmd = ""; } if (fn ? !fn() : !this.hasContents()) { return ""; } me.fireEvent("beforegetcontent"); var root = UE.htmlparser(me.body.innerHTML, ignoreBlank); me.filterOutputRule(root); me.fireEvent("aftergetcontent", cmd, root); return root.toHtml(formatter); }, /** * 取得完整的html代码,可以直接显示成完整的html文档 * @method getAllHtml * @return { String } 编辑器的内容html文档字符串 * @eaxmple * ```javascript * editor.getAllHtml(); //返回格式大致是: ...... * ``` */ getAllHtml: function () { var me = this, headHtml = [], html = ""; me.fireEvent("getAllHtml", headHtml); if (browser.ie && browser.version > 8) { var headHtmlForIE9 = ""; utils.each(me.document.styleSheets, function (si) { headHtmlForIE9 += si.href ? '' : ""; }); utils.each(me.document.getElementsByTagName("script"), function (si) { headHtmlForIE9 += si.outerHTML; }); } return ( "" + (me.options.charset ? '' : "") + (headHtmlForIE9 || me.document.getElementsByTagName("head")[0].innerHTML) + headHtml.join("\n") + "" + "" + me.getContent(null, null, true) + "" ); }, /** * 得到编辑器的纯文本内容,但会保留段落格式 * @method getPlainTxt * @return { String } 编辑器带段落格式的纯文本内容字符串 * @example * ```javascript * //编辑器html内容:1
2
* console.log(editor.getPlainTxt()); //输出:"1\n2\n * ``` */ getPlainTxt: function () { var reg = new RegExp(domUtils.fillChar, "g"), html = this.body.innerHTML.replace(/[\n\r]/g, ""); //ie要先去了\n在处理 html = html .replace(/<(p|div)[^>]*>(1
2
* console.log(editor.getPlainTxt()); //输出:"12 * ``` */ getContentTxt: function () { var reg = new RegExp(domUtils.fillChar, "g"); //取出来的空格会有c2a0会变成乱码,处理这种情况\u00a0 return this.body[browser.ie ? "innerText" : "textContent"] .replace(reg, "") .replace(/\u00a0/g, " "); }, /** * 设置编辑器的内容,可修改编辑器当前的html内容 * @method setContent * @warning 通过该方法插入的内容,是经过编辑器内置的过滤规则进行过滤后得到的内容 * @warning 该方法会触发selectionchange事件 * @param { String } html 要插入的html内容 * @example * ```javascript * editor.getContent('test
'); * ``` */ /** * 设置编辑器的内容,可修改编辑器当前的html内容 * @method setContent * @warning 通过该方法插入的内容,是经过编辑器内置的过滤规则进行过滤后得到的内容 * @warning 该方法会触发selectionchange事件 * @param { String } html 要插入的html内容 * @param { Boolean } isAppendTo 若传入true,不清空原来的内容,在最后插入内容,否则,清空内容再插入 * @param { Boolean } notFireSelectionchange 是否阻止触发选区变化,true为阻止,false为不阻止 * @example * ```javascript * //假设设置前的编辑器内容是old text
* editor.setContent('new text
', true); //插入的结果是old text
new text
* ``` */ setContent: function (html, isAppendTo, notFireSelectionchange) { var me = this; me.fireEvent("beforesetcontent", html); var root = UE.htmlparser(html); me.filterInputRule(root); html = root.toHtml(); me.body.innerHTML = (isAppendTo ? me.body.innerHTML : "") + html; function isCdataDiv (node) { return node.tagName == "DIV" && node.getAttribute("cdata_tag"); } //给文本或者inline节点套p标签 if (me.options.enterTag == "p") { var child = this.body.firstChild, tmpNode; if ( !child || (child.nodeType == 1 && (dtd.$cdata[child.tagName] || isCdataDiv(child) || domUtils.isCustomeNode(child)) && child === this.body.lastChild) ) { this.body.innerHTML = "" +
(browser.ie ? " " : "
") +
"
" + (ie ? "" : "
") + "
' + cont + "
"; me.addListener("firstBeforeExecCommand focus", clear); }; })(), /** * 显示编辑器 * @method setShow * @example * ```javascript * editor.setShow() * ``` */ setShow: function () { var me = this, range = me.selection.getRange(); if (me.container.style.display == "none") { //有可能内容丢失了 try { range.moveToBookmark(me.lastBk); delete me.lastBk; } catch (e) { range.setStartAtFirst(me.body).collapse(true); } //ie下focus实效,所以做了个延迟 setTimeout(function () { range.select(true); }, 100); me.container.style.display = ""; } }, show: function () { return this.setShow(); }, /** * 隐藏编辑器 * @method setHide * @example * ```javascript * editor.setHide() * ``` */ setHide: function () { var me = this; if (!me.lastBk) { me.lastBk = me.selection.getRange().createBookmark(true); } me.container.style.display = "none"; }, hide: function () { return this.setHide(); }, /** * 根据指定的路径,获取对应的语言资源 * @method getLang * @param { String } path 路径根据的是lang目录下的语言文件的路径结构 * @return { Object | String } 根据路径返回语言资源的Json格式对象或者语言字符串 * @example * ```javascript * editor.getLang('contextMenu.delete'); //如果当前是中文,那返回是的是'删除' * ``` */ getLang: function (path) { var lang = UE.I18N[this.options.lang]; if (!lang) { throw Error("not import language file"); } path = (path || "").split("."); for (var i = 0, ci; (ci = path[i++]);) { lang = lang[ci]; if (!lang) break; } return lang; }, /** * 计算编辑器html内容字符串的长度 * @method getContentLength * @return { Number } 返回计算的长度 * @example * ```javascript * //编辑器html内容132
* editor.getContentLength() //返回27 * ``` */ /** * 计算编辑器当前纯文本内容的长度 * @method getContentLength * @param { Boolean } ingoneHtml 传入true时,只按照纯文本来计算 * @return { Number } 返回计算的长度,内容中有hr/img/iframe标签,长度加1 * @example * ```javascript * //编辑器html内容132
* editor.getContentLength() //返回3 * ``` */ getContentLength: function (ingoneHtml, tagNames) { var count = this.getContent(false, false, true).length; if (ingoneHtml) { tagNames = (tagNames || []).concat(["hr", "img", "iframe"]); count = this.getContentTxt().replace(/[\t\r\n]+/g, "").length; for (var i = 0, ci; (ci = tagNames[i++]);) { count += this.document.getElementsByTagName(ci).length; } } return count; }, getScrollTop: function () { return Math.max(this.document.documentElement.scrollTop, this.document.body.scrollTop); }, getScrollLeft: function () { return Math.max(this.document.documentElement.scrollLeft, this.document.body.scrollLeft); }, /** * 注册输入过滤规则 * @method addInputRule * @param { Function } rule 要添加的过滤规则 * @example * ```javascript * editor.addInputRule(function(root){ * $.each(root.getNodesByTagName('div'),function(i,node){ * node.tagName="p"; * }); * }); * ``` */ addInputRule: function (rule) { this.inputRules.push(rule); }, /** * 执行注册的过滤规则 * @method filterInputRule * @param { UE.uNode } root 要过滤的uNode节点 * @remind 执行editor.setContent方法和执行'inserthtml'命令后,会运行该过滤函数 * @example * ```javascript * editor.filterInputRule(editor.body); * ``` * @see UE.Editor:addInputRule */ filterInputRule: function (root) { for (var i = 0, ci; (ci = this.inputRules[i++]);) { ci.call(this, root); } }, /** * 注册输出过滤规则 * @method addOutputRule * @param { Function } rule 要添加的过滤规则 * @example * ```javascript * editor.addOutputRule(function(root){ * $.each(root.getNodesByTagName('p'),function(i,node){ * node.tagName="div"; * }); * }); * ``` */ addOutputRule: function (rule) { this.outputRules.push(rule); }, /** * 根据输出过滤规则,过滤编辑器内容 * @method filterOutputRule * @remind 执行editor.getContent方法的时候,会先运行该过滤函数 * @param { UE.uNode } root 要过滤的uNode节点 * @example * ```javascript * editor.filterOutputRule(editor.body); * ``` * @see UE.Editor:addOutputRule */ filterOutputRule: function (root) { for (var i = 0, ci; (ci = this.outputRules[i++]);) { ci.call(this, root); } }, /** * 根据action名称获取请求的路径 * @method getActionUrl * @remind 假如没有设置serverUrl,会根据imageUrl设置默认的controller路径 * @param { String } action action名称 * @example * ```javascript * editor.getActionUrl('config'); //返回 "/ueditor/php/controller.php?action=config" * editor.getActionUrl('image'); //返回 "/ueditor/php/controller.php?action=uplaodimage" * editor.getActionUrl('scrawl'); //返回 "/ueditor/php/controller.php?action=uplaodscrawl" * editor.getActionUrl('imageManager'); //返回 "/ueditor/php/controller.php?action=listimage" * ``` */ getActionUrl: function (action) { var serverUrl = this.getOpt("serverUrl") if (!action) { return serverUrl; } var actionName = this.getOpt(action) || action, imageUrl = this.getOpt("imageUrl"); if (!serverUrl && imageUrl) { serverUrl = imageUrl.replace(/^(.*[\/]).+([\.].+)$/, "$1controller$2"); } if (serverUrl) { serverUrl = serverUrl + (serverUrl.indexOf("?") === -1 ? "?" : "&") + "action=" + (actionName || ""); return utils.formatUrl(serverUrl); } else { return ""; } } }; utils.inherits(Editor, EventBase); })(); // core/Editor.defaultoptions.js //维护编辑器一下默认的不在插件中的配置项 UE.Editor.defaultOptions = function (editor) { var _url = editor.options.UEDITOR_HOME_URL; return { isShow: true, initialContent: "", initialStyle: "", autoClearinitialContent: false, iframeCssUrl: _url + "themes/iframe.css?c20ec247", iframeCssUrlsAddition: [], textarea: '', focus: false, focusInEnd: true, autoClearEmptyNode: true, fullscreen: false, readonly: false, zIndex: 999, imagePopup: true, enterTag: "p", customDomain: false, lang: "zh-cn", langPath: _url + "lang/", theme: "default", themePath: _url + "themes/", allHtmlEnabled: false, scaleEnabled: false, tableNativeEditInFF: false, autoSyncData: true, fileNameFormat: "{time}{rand:6}" }; }; // core/loadconfig.js (function () { UE.Editor.prototype.loadServerConfig = function () { var me = this; setTimeout(function () { try { me.options.imageUrl && me.setOpt( "serverUrl", me.options.imageUrl.replace( /^(.*[\/]).+([\.].+)$/, "$1controller$2" ) ); var configUrl = me.getActionUrl("config"), isJsonp = utils.isCrossDomainUrl(configUrl); /* 发出ajax请求 */ me._serverConfigLoaded = false; configUrl && UE.ajax.request(configUrl, { method: "GET", // dataType: isJsonp ? "jsonp" : "", headers: me.options.serverHeaders || {}, onsuccess: function (r) { try { var config = isJsonp ? r : eval("(" + r.responseText + ")"); // config = me.options.serverResponsePrepare(config) // console.log('me.options.before', me.options.audioConfig); me.options = utils.merge(me.options, config); // console.log('server.config', config.audioConfig); // console.log('me.options.after', me.options.audioConfig); me.fireEvent("serverConfigLoaded"); me._serverConfigLoaded = true; } catch (e) { showErrorMsg(me.getLang("loadconfigFormatError")); } }, onerror: function () { showErrorMsg(me.getLang("loadconfigHttpError")); } }); } catch (e) { showErrorMsg(me.getLang("loadconfigError")); } }); function showErrorMsg (msg) { console.log("🚀 ~ showErrorMsg ~ msg:", msg) console && console.error(msg); //me.fireEvent('showMessage', { // 'title': msg, // 'type': 'error' //}); } }; UE.Editor.prototype.isServerConfigLoaded = function () { var me = this; return me._serverConfigLoaded || false; }; UE.Editor.prototype.afterConfigReady = function (handler) { if (!handler || !utils.isFunction(handler)) return; var me = this; var readyHandler = function () { handler.apply(me, arguments); me.removeListener("serverConfigLoaded", readyHandler); }; if (me.isServerConfigLoaded()) { handler.call(me, "serverConfigLoaded"); } else { me.addListener("serverConfigLoaded", readyHandler); } }; })(); // core/ajax.js /** * @file * @module UE.ajax * @since 1.2.6.1 */ /** * 提供对ajax请求的支持 * @module UE.ajax */ UE.ajax = (function () { //创建一个ajaxRequest对象 var fnStr = "XMLHttpRequest()"; try { new ActiveXObject("Msxml2.XMLHTTP"); fnStr = "ActiveXObject('Msxml2.XMLHTTP')"; } catch (e) { try { new ActiveXObject("Microsoft.XMLHTTP"); fnStr = "ActiveXObject('Microsoft.XMLHTTP')"; } catch (e) { } } var creatAjaxRequest = new Function("return new " + fnStr); /** * 将json参数转化成适合ajax提交的参数列表 * @param json */ function json2str (json) { var strArr = []; for (var i in json) { //忽略默认的几个参数 if ( i == "method" || i == "timeout" || i == "async" || i == "dataType" || i == "callback" ) continue; //忽略控制 if (json[i] == undefined || json[i] == null) continue; //传递过来的对象和函数不在提交之列 if ( !( (typeof json[i]).toLowerCase() == "function" || (typeof json[i]).toLowerCase() == "object" ) ) { strArr.push(encodeURIComponent(i) + "=" + encodeURIComponent(json[i])); } else if (utils.isArray(json[i])) { //支持传数组内容 for (var j = 0; j < json[i].length; j++) { strArr.push( encodeURIComponent(i) + "[]=" + encodeURIComponent(json[i][j]) ); } } } return strArr.join("&"); } function doAjax (url, ajaxOptions) { var xhr = creatAjaxRequest(), //是否超时 timeIsOut = false, //默认参数 defaultAjaxOptions = { method: "POST", timeout: 5000, async: true, headers: {}, data: {}, //需要传递对象的话只能覆盖 onsuccess: function () { }, onerror: function () { } }; if (typeof url === "object") { ajaxOptions = url; url = ajaxOptions.url; } if (!xhr || !url) return; var ajaxOpts = ajaxOptions ? utils.extend(defaultAjaxOptions, ajaxOptions) : defaultAjaxOptions; // console.log('ajaxOpts',ajaxOpts); var submitStr = json2str(ajaxOpts); // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing" //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串 if (!utils.isEmptyObject(ajaxOpts.data)) { submitStr += (submitStr ? "&" : "") + json2str(ajaxOpts.data); } //超时检测 var timerID = setTimeout(function () { if (xhr.readyState !== 4) { timeIsOut = true; xhr.abort(); clearTimeout(timerID); } }, ajaxOpts.timeout); var method = ajaxOpts.method.toUpperCase(); var str = url + (url.indexOf("?") === -1 ? "?" : "&") + (method === "POST" ? "" : submitStr + "&noCache=" + +new Date()); xhr.open(method, str, ajaxOpts.async); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (!timeIsOut && xhr.status === 200) { ajaxOpts.onsuccess(xhr); } else { ajaxOpts.onerror(xhr); } } }; if (ajaxOpts.headers) { for (var key in ajaxOpts.headers) { xhr.setRequestHeader(key, ajaxOpts.headers[key]); } } if (method === "POST") { xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send(submitStr); } else { xhr.send(null); } } function doJsonp (url, opts) { var successhandler = opts.onsuccess || function () { }, scr = document.createElement("SCRIPT"), options = opts || {}, charset = options["charset"], callbackField = options["jsonp"] || "callback", callbackFnName, timeOut = options["timeOut"] || 0, timer, reg = new RegExp("(\\?|&)" + callbackField + "=([^&]*)"), matches; if (utils.isFunction(successhandler)) { callbackFnName = "bd__editor__" + Math.floor(Math.random() * 2147483648).toString(36); window[callbackFnName] = getCallBack(0); } else if (utils.isString(successhandler)) { callbackFnName = successhandler; } else { if ((matches = reg.exec(url))) { callbackFnName = matches[2]; } } url = url.replace(reg, "\x241" + callbackField + "=" + callbackFnName); if (url.search(reg) < 0) { url += (url.indexOf("?") < 0 ? "?" : "&") + callbackField + "=" + callbackFnName; } var queryStr = json2str(opts); // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing" //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串 if (!utils.isEmptyObject(opts.data)) { queryStr += (queryStr ? "&" : "") + json2str(opts.data); } if (queryStr) { url = url.replace(/\?/, "?" + queryStr + "&"); } scr.onerror = getCallBack(1); if (timeOut) { timer = setTimeout(getCallBack(1), timeOut); } createScriptTag(scr, url, charset); function createScriptTag (scr, url, charset) { scr.setAttribute("type", "text/javascript"); scr.setAttribute("defer", "defer"); charset && scr.setAttribute("charset", charset); scr.setAttribute("src", url); document.getElementsByTagName("head")[0].appendChild(scr); } function getCallBack (onTimeOut) { return function () { try { if (onTimeOut) { options.onerror && options.onerror(); } else { try { clearTimeout(timer); successhandler.apply(window, arguments); } catch (e) { } } } catch (exception) { options.onerror && options.onerror.call(window, exception); } finally { options.oncomplete && options.oncomplete.apply(window, arguments); scr.parentNode && scr.parentNode.removeChild(scr); window[callbackFnName] = null; try { delete window[callbackFnName]; } catch (e) { } } }; } } return { /** * 根据给定的参数项,向指定的url发起一个ajax请求。 ajax请求完成后,会根据请求结果调用相应回调: 如果请求 * 成功, 则调用onsuccess回调, 失败则调用 onerror 回调 * @method request * @param { URLString } url ajax请求的url地址 * @param { Object } ajaxOptions ajax请求选项的键值对,支持的选项如下: * @example * ```javascript * //向sayhello.php发起一个异步的Ajax GET请求, 请求超时时间为10s, 请求完成后执行相应的回调。 * UE.ajax.requeset( 'sayhello.php', { * * //请求方法。可选值: 'GET', 'POST',默认值是'POST' * method: 'GET', * * //超时时间。 默认为5000, 单位是ms * timeout: 10000, * * //是否是异步请求。 true为异步请求, false为同步请求 * async: true, * * //请求携带的数据。如果请求为GET请求, data会经过stringify后附加到请求url之后。 * data: { * name: 'ueditor' * }, * * //请求成功后的回调, 该回调接受当前的XMLHttpRequest对象作为参数。 * onsuccess: function ( xhr ) { * console.log( xhr.responseText ); * }, * * //请求失败或者超时后的回调。 * onerror: function ( xhr ) { * alert( 'Ajax请求失败' ); * } * * } ); * ``` */ /** * 根据给定的参数项发起一个ajax请求, 参数项里必须包含一个url地址。 ajax请求完成后,会根据请求结果调用相应回调: 如果请求 * 成功, 则调用onsuccess回调, 失败则调用 onerror 回调。 * @method request * @warning 如果在参数项里未提供一个key为“url”的地址值,则该请求将直接退出。 * @param { Object } ajaxOptions ajax请求选项的键值对,支持的选项如下: * @example * ```javascript * * //向sayhello.php发起一个异步的Ajax POST请求, 请求超时时间为5s, 请求完成后不执行任何回调。 * UE.ajax.requeset( 'sayhello.php', { * * //请求的地址, 该项是必须的。 * url: 'sayhello.php' * * } ); * ``` */ request: function (url, opts) { if (opts && opts.dataType === "jsonp") { doJsonp(url, opts); } else { doAjax(url, opts); } }, getJSONP: function (url, data, fn) { var opts = { data: data, oncomplete: fn }; doJsonp(url, opts); } }; })(); // core/api.js UE.api = (function () { // axios import var axios = null; !function (e, t) { axios = t() }(this, (function () { "use strict"; function e (t) { return e = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (e) { return typeof e } : function (e) { return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e }, e(t) } function t (e, t) { if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") } function n (e, t) { for (var n = 0; n < t.length; n++) { var r = t[n]; r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) } } function r (e, t, r) { return t && n(e.prototype, t), r && n(e, r), Object.defineProperty(e, "prototype", { writable: !1 }), e } function o (e, t) { return function (e) { if (Array.isArray(e)) return e }(e) || function (e, t) { var n = null == e ? null : "undefined" != typeof Symbol && e[Symbol.iterator] || e["@@iterator"]; if (null == n) return; var r, o, i = [], a = !0, s = !1; try { for (n = n.call(e); !(a = (r = n.next()).done) && (i.push(r.value), !t || i.length !== t); a = !0); } catch (e) { s = !0, o = e } finally { try { a || null == n.return || n.return() } finally { if (s) throw o } } return i }(e, t) || function (e, t) { if (!e) return; if ("string" == typeof e) return i(e, t); var n = Object.prototype.toString.call(e).slice(8, -1); "Object" === n && e.constructor && (n = e.constructor.name); if ("Map" === n || "Set" === n) return Array.from(e); if ("Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return i(e, t) }(e, t) || function () { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.") }() } function i (e, t) { (null == t || t > e.length) && (t = e.length); for (var n = 0, r = new Array(t); n < t; n++) r[n] = e[n]; return r } function a (e, t) { return function () { return e.apply(t, arguments) } } var s, u = Object.prototype.toString, c = Object.getPrototypeOf, f = (s = Object.create(null), function (e) { var t = u.call(e); return s[t] || (s[t] = t.slice(8, -1).toLowerCase()) }), l = function (e) { return e = e.toLowerCase(), function (t) { return f(t) === e } }, d = function (t) { return function (n) { return e(n) === t } }, p = Array.isArray, h = d("undefined"); var m = l("ArrayBuffer"); var y = d("string"), v = d("function"), b = d("number"), g = function (t) { return null !== t && "object" === e(t) }, w = function (e) { if ("object" !== f(e)) return !1; var t = c(e); return !(null !== t && t !== Object.prototype && null !== Object.getPrototypeOf(t) || Symbol.toStringTag in e || Symbol.iterator in e) }, E = l("Date"), O = l("File"), S = l("Blob"), R = l("FileList"), A = l("URLSearchParams"); function T (t, n) { var r, o, i = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, a = i.allOwnKeys, s = void 0 !== a && a; if (null != t) if ("object" !== e(t) && (t = [t]), p(t)) for (r = 0, o = t.length; r < o; r++) n.call(null, t[r], r, t); else { var u, c = s ? Object.getOwnPropertyNames(t) : Object.keys(t), f = c.length; for (r = 0; r < f; r++) u = c[r], n.call(null, t[u], u, t) } } function j (e, t) { t = t.toLowerCase(); for (var n, r = Object.keys(e), o = r.length; o-- > 0;) if (t === (n = r[o]).toLowerCase()) return n; return null } var N = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : "undefined" != typeof window ? window : global, C = function (e) { return !h(e) && e !== N }; var x, P = (x = "undefined" != typeof Uint8Array && c(Uint8Array), function (e) { return x && e instanceof x }), k = l("HTMLFormElement"), U = function (e) { var t = Object.prototype.hasOwnProperty; return function (e, n) { return t.call(e, n) } }(), _ = l("RegExp"), F = function (e, t) { var n = Object.getOwnPropertyDescriptors(e), r = {}; T(n, (function (n, o) { !1 !== t(n, o, e) && (r[o] = n) })), Object.defineProperties(e, r) }, B = "abcdefghijklmnopqrstuvwxyz", L = "0123456789", D = { DIGIT: L, ALPHA: B, ALPHA_DIGIT: B + B.toUpperCase() + L }; var I = l("AsyncFunction"), q = { isArray: p, isArrayBuffer: m, isBuffer: function (e) { return null !== e && !h(e) && null !== e.constructor && !h(e.constructor) && v(e.constructor.isBuffer) && e.constructor.isBuffer(e) }, isFormData: function (e) { var t; return e && ("function" == typeof FormData && e instanceof FormData || v(e.append) && ("formdata" === (t = f(e)) || "object" === t && v(e.toString) && "[object FormData]" === e.toString())) }, isArrayBufferView: function (e) { return "undefined" != typeof ArrayBuffer && ArrayBuffer.isView ? ArrayBuffer.isView(e) : e && e.buffer && m(e.buffer) }, isString: y, isNumber: b, isBoolean: function (e) { return !0 === e || !1 === e }, isObject: g, isPlainObject: w, isUndefined: h, isDate: E, isFile: O, isBlob: S, isRegExp: _, isFunction: v, isStream: function (e) { return g(e) && v(e.pipe) }, isURLSearchParams: A, isTypedArray: P, isFileList: R, forEach: T, merge: function e () { for (var t = C(this) && this || {}, n = t.caseless, r = {}, o = function (t, o) { var i = n && j(r, o) || o; w(r[i]) && w(t) ? r[i] = e(r[i], t) : w(t) ? r[i] = e({}, t) : p(t) ? r[i] = t.slice() : r[i] = t }, i = 0, a = arguments.length; i < a; i++) arguments[i] && T(arguments[i], o); return r }, extend: function (e, t, n) { var r = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {}, o = r.allOwnKeys; return T(t, (function (t, r) { n && v(t) ? e[r] = a(t, n) : e[r] = t }), { allOwnKeys: o }), e }, trim: function (e) { return e.trim ? e.trim() : e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "") }, stripBOM: function (e) { return 65279 === e.charCodeAt(0) && (e = e.slice(1)), e }, inherits: function (e, t, n, r) { e.prototype = Object.create(t.prototype, r), e.prototype.constructor = e, Object.defineProperty(e, "super", { value: t.prototype }), n && Object.assign(e.prototype, n) }, toFlatObject: function (e, t, n, r) { var o, i, a, s = {}; if (t = t || {}, null == e) return t; do { for (i = (o = Object.getOwnPropertyNames(e)).length; i-- > 0;) a = o[i], r && !r(a, e, t) || s[a] || (t[a] = e[a], s[a] = !0); e = !1 !== n && c(e) } while (e && (!n || n(e, t)) && e !== Object.prototype); return t }, kindOf: f, kindOfTest: l, endsWith: function (e, t, n) { e = String(e), (void 0 === n || n > e.length) && (n = e.length), n -= t.length; var r = e.indexOf(t, n); return -1 !== r && r === n }, toArray: function (e) { if (!e) return null; if (p(e)) return e; var t = e.length; if (!b(t)) return null; for (var n = new Array(t); t-- > 0;) n[t] = e[t]; return n }, forEachEntry: function (e, t) { for (var n, r = (e && e[Symbol.iterator]).call(e); (n = r.next()) && !n.done;) { var o = n.value; t.call(e, o[0], o[1]) } }, matchAll: function (e, t) { for (var n, r = []; null !== (n = e.exec(t));) r.push(n); return r }, isHTMLForm: k, hasOwnProperty: U, hasOwnProp: U, reduceDescriptors: F, freezeMethods: function (e) { F(e, (function (t, n) { if (v(e) && -1 !== ["arguments", "caller", "callee"].indexOf(n)) return !1; var r = e[n]; v(r) && (t.enumerable = !1, "writable" in t ? t.writable = !1 : t.set || (t.set = function () { throw Error("Can not rewrite read-only method '" + n + "'") })) })) }, toObjectSet: function (e, t) { var n = {}, r = function (e) { e.forEach((function (e) { n[e] = !0 })) }; return p(e) ? r(e) : r(String(e).split(t)), n }, toCamelCase: function (e) { return e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, (function (e, t, n) { return t.toUpperCase() + n })) }, noop: function () { }, toFiniteNumber: function (e, t) { return e = +e, Number.isFinite(e) ? e : t }, findKey: j, global: N, isContextDefined: C, ALPHABET: D, generateString: function () { for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 16, t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : D.ALPHA_DIGIT, n = "", r = t.length; e--;) n += t[Math.random() * r | 0]; return n }, isSpecCompliantForm: function (e) { return !!(e && v(e.append) && "FormData" === e[Symbol.toStringTag] && e[Symbol.iterator]) }, toJSONObject: function (e) { var t = new Array(10); return function e (n, r) { if (g(n)) { if (t.indexOf(n) >= 0) return; if (!("toJSON" in n)) { t[r] = n; var o = p(n) ? [] : {}; return T(n, (function (t, n) { var i = e(t, r + 1); !h(i) && (o[n] = i) })), t[r] = void 0, o } } return n }(e, 0) }, isAsyncFn: I, isThenable: function (e) { return e && (g(e) || v(e)) && v(e.then) && v(e.catch) } }; function M (e, t, n, r, o) { Error.call(this), Error.captureStackTrace ? Error.captureStackTrace(this, this.constructor) : this.stack = (new Error).stack, this.message = e, this.name = "AxiosError", t && (this.code = t), n && (this.config = n), r && (this.request = r), o && (this.response = o) } q.inherits(M, Error, { toJSON: function () { return { message: this.message, name: this.name, description: this.description, number: this.number, fileName: this.fileName, lineNumber: this.lineNumber, columnNumber: this.columnNumber, stack: this.stack, config: q.toJSONObject(this.config), code: this.code, status: this.response && this.response.status ? this.response.status : null } } }); var z = M.prototype, H = {}; ["ERR_BAD_OPTION_VALUE", "ERR_BAD_OPTION", "ECONNABORTED", "ETIMEDOUT", "ERR_NETWORK", "ERR_FR_TOO_MANY_REDIRECTS", "ERR_DEPRECATED", "ERR_BAD_RESPONSE", "ERR_BAD_REQUEST", "ERR_CANCELED", "ERR_NOT_SUPPORT", "ERR_INVALID_URL"].forEach((function (e) { H[e] = { value: e } })), Object.defineProperties(M, H), Object.defineProperty(z, "isAxiosError", { value: !0 }), M.from = function (e, t, n, r, o, i) { var a = Object.create(z); return q.toFlatObject(e, a, (function (e) { return e !== Error.prototype }), (function (e) { return "isAxiosError" !== e })), M.call(a, e.message, t, n, r, o), a.cause = e, a.name = e.name, i && Object.assign(a, i), a }; function J (e) { return q.isPlainObject(e) || q.isArray(e) } function W (e) { return q.endsWith(e, "[]") ? e.slice(0, -2) : e } function K (e, t, n) { return e ? e.concat(t).map((function (e, t) { return e = W(e), !n && t ? "[" + e + "]" : e })).join(n ? "." : "") : t } var V = q.toFlatObject(q, {}, null, (function (e) { return /^is[A-Z]/.test(e) })); function G (t, n, r) { if (!q.isObject(t)) throw new TypeError("target must be an object"); n = n || new FormData; var o = (r = q.toFlatObject(r, { metaTokens: !0, dots: !1, indexes: !1 }, !1, (function (e, t) { return !q.isUndefined(t[e]) }))).metaTokens, i = r.visitor || f, a = r.dots, s = r.indexes, u = (r.Blob || "undefined" != typeof Blob && Blob) && q.isSpecCompliantForm(n); if (!q.isFunction(i)) throw new TypeError("visitor must be a function"); function c (e) { if (null === e) return ""; if (q.isDate(e)) return e.toISOString(); if (!u && q.isBlob(e)) throw new M("Blob is not supported. Use a Buffer instead."); return q.isArrayBuffer(e) || q.isTypedArray(e) ? u && "function" == typeof Blob ? new Blob([e]) : Buffer.from(e) : e } function f (t, r, i) { var u = t; if (t && !i && "object" === e(t)) if (q.endsWith(r, "{}")) r = o ? r : r.slice(0, -2), t = JSON.stringify(t); else if (q.isArray(t) && function (e) { return q.isArray(e) && !e.some(J) }(t) || (q.isFileList(t) || q.endsWith(r, "[]")) && (u = q.toArray(t))) return r = W(r), u.forEach((function (e, t) { !q.isUndefined(e) && null !== e && n.append(!0 === s ? K([r], t, a) : null === s ? r : r + "[]", c(e)) })), !1; return !!J(t) || (n.append(K(i, r, a), c(t)), !1) } var l = [], d = Object.assign(V, { defaultVisitor: f, convertValue: c, isVisitable: J }); if (!q.isObject(t)) throw new TypeError("data must be an object"); return function e (t, r) { if (!q.isUndefined(t)) { if (-1 !== l.indexOf(t)) throw Error("Circular reference detected in " + r.join(".")); l.push(t), q.forEach(t, (function (t, o) { !0 === (!(q.isUndefined(t) || null === t) && i.call(n, t, q.isString(o) ? o.trim() : o, r, d)) && e(t, r ? r.concat(o) : [o]) })), l.pop() } }(t), n } function $ (e) { var t = { "!": "%21", "'": "%27", "(": "%28", ")": "%29", "~": "%7E", "%20": "+", "%00": "\0" }; return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g, (function (e) { return t[e] })) } function X (e, t) { this._pairs = [], e && G(e, this, t) } var Q = X.prototype; function Z (e) { return encodeURIComponent(e).replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",").replace(/%20/g, "+").replace(/%5B/gi, "[").replace(/%5D/gi, "]") } function Y (e, t, n) { if (!t) return e; var r, o = n && n.encode || Z, i = n && n.serialize; if (r = i ? i(t, n) : q.isURLSearchParams(t) ? t.toString() : new X(t, n).toString(o)) { var a = e.indexOf("#"); -1 !== a && (e = e.slice(0, a)), e += (-1 === e.indexOf("?") ? "?" : "&") + r } return e } Q.append = function (e, t) { this._pairs.push([e, t]) }, Q.toString = function (e) { var t = e ? function (t) { return e.call(this, t, $) } : $; return this._pairs.map((function (e) { return t(e[0]) + "=" + t(e[1]) }), "").join("&") }; var ee, te = function () { function e () { t(this, e), this.handlers = [] } return r(e, [{ key: "use", value: function (e, t, n) { return this.handlers.push({ fulfilled: e, rejected: t, synchronous: !!n && n.synchronous, runWhen: n ? n.runWhen : null }), this.handlers.length - 1 } }, { key: "eject", value: function (e) { this.handlers[e] && (this.handlers[e] = null) } }, { key: "clear", value: function () { this.handlers && (this.handlers = []) } }, { key: "forEach", value: function (e) { q.forEach(this.handlers, (function (t) { null !== t && e(t) })) } }]), e }(), ne = { silentJSONParsing: !0, forcedJSONParsing: !0, clarifyTimeoutError: !1 }, re = { isBrowser: !0, classes: { URLSearchParams: "undefined" != typeof URLSearchParams ? URLSearchParams : X, FormData: "undefined" != typeof FormData ? FormData : null, Blob: "undefined" != typeof Blob ? Blob : null }, isStandardBrowserEnv: ("undefined" == typeof navigator || "ReactNative" !== (ee = navigator.product) && "NativeScript" !== ee && "NS" !== ee) && "undefined" != typeof window && "undefined" != typeof document, isStandardBrowserWebWorkerEnv: "undefined" != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope && "function" == typeof self.importScripts, protocols: ["http", "https", "file", "blob", "url", "data"] }; function oe (e) { function t (e, n, r, o) { var i = e[o++], a = Number.isFinite(+i), s = o >= e.length; return i = !i && q.isArray(r) ? r.length : i, s ? (q.hasOwnProp(r, i) ? r[i] = [r[i], n] : r[i] = n, !a) : (r[i] && q.isObject(r[i]) || (r[i] = []), t(e, n, r[i], o) && q.isArray(r[i]) && (r[i] = function (e) { var t, n, r = {}, o = Object.keys(e), i = o.length; for (t = 0; t < i; t++) r[n = o[t]] = e[n]; return r }(r[i])), !a) } if (q.isFormData(e) && q.isFunction(e.entries)) { var n = {}; return q.forEachEntry(e, (function (e, r) { t(function (e) { return q.matchAll(/\w+|\[(\w*)]/g, e).map((function (e) { return "[]" === e[0] ? "" : e[1] || e[0] })) }(e), r, n, 0) })), n } return null } var ie = { "Content-Type": void 0 }; var ae = { transitional: ne, adapter: ["xhr", "http"], transformRequest: [function (e, t) { var n, r = t.getContentType() || "", o = r.indexOf("application/json") > -1, i = q.isObject(e); if (i && q.isHTMLForm(e) && (e = new FormData(e)), q.isFormData(e)) return o && o ? JSON.stringify(oe(e)) : e; if (q.isArrayBuffer(e) || q.isBuffer(e) || q.isStream(e) || q.isFile(e) || q.isBlob(e)) return e; if (q.isArrayBufferView(e)) return e.buffer; if (q.isURLSearchParams(e)) return t.setContentType("application/x-www-form-urlencoded;charset=utf-8", !1), e.toString(); if (i) { if (r.indexOf("application/x-www-form-urlencoded") > -1) return function (e, t) { return G(e, new re.classes.URLSearchParams, Object.assign({ visitor: function (e, t, n, r) { return re.isNode && q.isBuffer(e) ? (this.append(t, e.toString("base64")), !1) : r.defaultVisitor.apply(this, arguments) } }, t)) }(e, this.formSerializer).toString(); if ((n = q.isFileList(e)) || r.indexOf("multipart/form-data") > -1) { var a = this.env && this.env.FormData; return G(n ? { "files[]": e } : e, a && new a, this.formSerializer) } } return i || o ? (t.setContentType("application/json", !1), function (e, t, n) { if (q.isString(e)) try { return (t || JSON.parse)(e), q.trim(e) } catch (e) { if ("SyntaxError" !== e.name) throw e } return (n || JSON.stringify)(e) }(e)) : e }], transformResponse: [function (e) { var t = this.transitional || ae.transitional, n = t && t.forcedJSONParsing, r = "json" === this.responseType; if (e && q.isString(e) && (n && !this.responseType || r)) { var o = !(t && t.silentJSONParsing) && r; try { return JSON.parse(e) } catch (e) { if (o) { if ("SyntaxError" === e.name) throw M.from(e, M.ERR_BAD_RESPONSE, this, null, this.response); throw e } } } return e }], timeout: 0, xsrfCookieName: "XSRF-TOKEN", xsrfHeaderName: "X-XSRF-TOKEN", maxContentLength: -1, maxBodyLength: -1, env: { FormData: re.classes.FormData, Blob: re.classes.Blob }, validateStatus: function (e) { return e >= 200 && e < 300 }, headers: { common: { Accept: "application/json, text/plain, */*" } } }; q.forEach(["delete", "get", "head"], (function (e) { ae.headers[e] = {} })), q.forEach(["post", "put", "patch"], (function (e) { ae.headers[e] = q.merge(ie) })); var se = ae, ue = q.toObjectSet(["age", "authorization", "content-length", "content-type", "etag", "expires", "from", "host", "if-modified-since", "if-unmodified-since", "last-modified", "location", "max-forwards", "proxy-authorization", "referer", "retry-after", "user-agent"]), ce = Symbol("internals"); function fe (e) { return e && String(e).trim().toLowerCase() } function le (e) { return !1 === e || null == e ? e : q.isArray(e) ? e.map(le) : String(e) } function de (e, t, n, r, o) { return q.isFunction(r) ? r.call(this, t, n) : (o && (t = n), q.isString(t) ? q.isString(r) ? -1 !== t.indexOf(r) : q.isRegExp(r) ? r.test(t) : void 0 : void 0) } var pe = function (e, n) { function i (e) { t(this, i), e && this.set(e) } return r(i, [{ key: "set", value: function (e, t, n) { var r = this; function o (e, t, n) { var o = fe(t); if (!o) throw new Error("header name must be a non-empty string"); var i = q.findKey(r, o); (!i || void 0 === r[i] || !0 === n || void 0 === n && !1 !== r[i]) && (r[i || t] = le(e)) } var i, a, s, u, c, f = function (e, t) { return q.forEach(e, (function (e, n) { return o(e, n, t) })) }; return q.isPlainObject(e) || e instanceof this.constructor ? f(e, t) : q.isString(e) && (e = e.trim()) && !/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim()) ? f((c = {}, (i = e) && i.split("\n").forEach((function (e) { u = e.indexOf(":"), a = e.substring(0, u).trim().toLowerCase(), s = e.substring(u + 1).trim(), !a || c[a] && ue[a] || ("set-cookie" === a ? c[a] ? c[a].push(s) : c[a] = [s] : c[a] = c[a] ? c[a] + ", " + s : s) })), c), t) : null != e && o(t, e, n), this } }, { key: "get", value: function (e, t) { if (e = fe(e)) { var n = q.findKey(this, e); if (n) { var r = this[n]; if (!t) return r; if (!0 === t) return function (e) { for (var t, n = Object.create(null), r = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g; t = r.exec(e);) n[t[1]] = t[2]; return n }(r); if (q.isFunction(t)) return t.call(this, r, n); if (q.isRegExp(t)) return t.exec(r); throw new TypeError("parser must be boolean|regexp|function") } } } }, { key: "has", value: function (e, t) { if (e = fe(e)) { var n = q.findKey(this, e); return !(!n || void 0 === this[n] || t && !de(0, this[n], n, t)) } return !1 } }, { key: "delete", value: function (e, t) { var n = this, r = !1; function o (e) { if (e = fe(e)) { var o = q.findKey(n, e); !o || t && !de(0, n[o], o, t) || (delete n[o], r = !0) } } return q.isArray(e) ? e.forEach(o) : o(e), r } }, { key: "clear", value: function (e) { for (var t = Object.keys(this), n = t.length, r = !1; n--;) { var o = t[n]; e && !de(0, this[o], o, e, !0) || (delete this[o], r = !0) } return r } }, { key: "normalize", value: function (e) { var t = this, n = {}; return q.forEach(this, (function (r, o) { var i = q.findKey(n, o); if (i) return t[i] = le(r), void delete t[o]; var a = e ? function (e) { return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g, (function (e, t, n) { return t.toUpperCase() + n })) }(o) : String(o).trim(); a !== o && delete t[o], t[a] = le(r), n[a] = !0 })), this } }, { key: "concat", value: function () { for (var e, t = arguments.length, n = new Array(t), r = 0; r < t; r++) n[r] = arguments[r]; return (e = this.constructor).concat.apply(e, [this].concat(n)) } }, { key: "toJSON", value: function (e) { var t = Object.create(null); return q.forEach(this, (function (n, r) { null != n && !1 !== n && (t[r] = e && q.isArray(n) ? n.join(", ") : n) })), t } }, { key: Symbol.iterator, value: function () { return Object.entries(this.toJSON())[Symbol.iterator]() } }, { key: "toString", value: function () { return Object.entries(this.toJSON()).map((function (e) { var t = o(e, 2); return t[0] + ": " + t[1] })).join("\n") } }, { key: Symbol.toStringTag, get: function () { return "AxiosHeaders" } }], [{ key: "from", value: function (e) { return e instanceof this ? e : new this(e) } }, { key: "concat", value: function (e) { for (var t = new this(e), n = arguments.length, r = new Array(n > 1 ? n - 1 : 0), o = 1; o < n; o++) r[o - 1] = arguments[o]; return r.forEach((function (e) { return t.set(e) })), t } }, { key: "accessor", value: function (e) { var t = (this[ce] = this[ce] = { accessors: {} }).accessors, n = this.prototype; function r (e) { var r = fe(e); t[r] || (!function (e, t) { var n = q.toCamelCase(" " + t); ["get", "set", "has"].forEach((function (r) { Object.defineProperty(e, r + n, { value: function (e, n, o) { return this[r].call(this, t, e, n, o) }, configurable: !0 }) })) }(n, e), t[r] = !0) } return q.isArray(e) ? e.forEach(r) : r(e), this } }]), i }(); pe.accessor(["Content-Type", "Content-Length", "Accept", "Accept-Encoding", "User-Agent", "Authorization"]), q.freezeMethods(pe.prototype), q.freezeMethods(pe); var he = pe; function me (e, t) { var n = this || se, r = t || n, o = he.from(r.headers), i = r.data; return q.forEach(e, (function (e) { i = e.call(n, i, o.normalize(), t ? t.status : void 0) })), o.normalize(), i } function ye (e) { return !(!e || !e.__CANCEL__) } function ve (e, t, n) { M.call(this, null == e ? "canceled" : e, M.ERR_CANCELED, t, n), this.name = "CanceledError" } q.inherits(ve, M, { __CANCEL__: !0 }); var be = re.isStandardBrowserEnv ? { write: function (e, t, n, r, o, i) { var a = []; a.push(e + "=" + encodeURIComponent(t)), q.isNumber(n) && a.push("expires=" + new Date(n).toGMTString()), q.isString(r) && a.push("path=" + r), q.isString(o) && a.push("domain=" + o), !0 === i && a.push("secure"), document.cookie = a.join("; ") }, read: function (e) { var t = document.cookie.match(new RegExp("(^|;\\s*)(" + e + ")=([^;]*)")); return t ? decodeURIComponent(t[3]) : null }, remove: function (e) { this.write(e, "", Date.now() - 864e5) } } : { write: function () { }, read: function () { return null }, remove: function () { } }; function ge (e, t) { return e && !/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t) ? function (e, t) { return t ? e.replace(/\/+$/, "") + "/" + t.replace(/^\/+/, "") : e }(e, t) : t } var we = re.isStandardBrowserEnv ? function () { var e, t = /(msie|trident)/i.test(navigator.userAgent), n = document.createElement("a"); function r (e) { var r = e; return t && (n.setAttribute("href", r), r = n.href), n.setAttribute("href", r), { href: n.href, protocol: n.protocol ? n.protocol.replace(/:$/, "") : "", host: n.host, search: n.search ? n.search.replace(/^\?/, "") : "", hash: n.hash ? n.hash.replace(/^#/, "") : "", hostname: n.hostname, port: n.port, pathname: "/" === n.pathname.charAt(0) ? n.pathname : "/" + n.pathname } } return e = r(window.location.href), function (t) { var n = q.isString(t) ? r(t) : t; return n.protocol === e.protocol && n.host === e.host } }() : function () { return !0 }; function Ee (e, t) { var n = 0, r = function (e, t) { e = e || 10; var n, r = new Array(e), o = new Array(e), i = 0, a = 0; return t = void 0 !== t ? t : 1e3, function (s) { var u = Date.now(), c = o[a]; n || (n = u), r[i] = s, o[i] = u; for (var f = a, l = 0; f !== i;) l += r[f++], f %= e; if ((i = (i + 1) % e) === a && (a = (a + 1) % e), !(u - n < t)) { var d = c && u - c; return d ? Math.round(1e3 * l / d) : void 0 } } }(50, 250); return function (o) { var i = o.loaded, a = o.lengthComputable ? o.total : void 0, s = i - n, u = r(s); n = i; var c = { loaded: i, total: a, progress: a ? i / a : void 0, bytes: s, rate: u || void 0, estimated: u && a && i <= a ? (a - i) / u : void 0, event: o }; c[t ? "download" : "upload"] = !0, e(c) } } var Oe = { http: null, xhr: "undefined" != typeof XMLHttpRequest && function (e) { return new Promise((function (t, n) { var r, o = e.data, i = he.from(e.headers).normalize(), a = e.responseType; function s () { e.cancelToken && e.cancelToken.unsubscribe(r), e.signal && e.signal.removeEventListener("abort", r) } q.isFormData(o) && (re.isStandardBrowserEnv || re.isStandardBrowserWebWorkerEnv ? i.setContentType(!1) : i.setContentType("multipart/form-data;", !1)); var u = new XMLHttpRequest; if (e.auth) { var c = e.auth.username || "", f = e.auth.password ? unescape(encodeURIComponent(e.auth.password)) : ""; i.set("Authorization", "Basic " + btoa(c + ":" + f)) } var l = ge(e.baseURL, e.url); function d () { if (u) { var r = he.from("getAllResponseHeaders" in u && u.getAllResponseHeaders()); !function (e, t, n) { var r = n.config.validateStatus; n.status && r && !r(n.status) ? t(new M("Request failed with status code " + n.status, [M.ERR_BAD_REQUEST, M.ERR_BAD_RESPONSE][Math.floor(n.status / 100) - 4], n.config, n.request, n)) : e(n) }((function (e) { t(e), s() }), (function (e) { n(e), s() }), { data: a && "text" !== a && "json" !== a ? u.response : u.responseText, status: u.status, statusText: u.statusText, headers: r, config: e, request: u }), u = null } } if (u.open(e.method.toUpperCase(), Y(l, e.params, e.paramsSerializer), !0), u.timeout = e.timeout, "onloadend" in u ? u.onloadend = d : u.onreadystatechange = function () { u && 4 === u.readyState && (0 !== u.status || u.responseURL && 0 === u.responseURL.indexOf("file:")) && setTimeout(d) }, u.onabort = function () { u && (n(new M("Request aborted", M.ECONNABORTED, e, u)), u = null) }, u.onerror = function () { n(new M("Network Error", M.ERR_NETWORK, e, u)), u = null }, u.ontimeout = function () { var t = e.timeout ? "timeout of " + e.timeout + "ms exceeded" : "timeout exceeded", r = e.transitional || ne; e.timeoutErrorMessage && (t = e.timeoutErrorMessage), n(new M(t, r.clarifyTimeoutError ? M.ETIMEDOUT : M.ECONNABORTED, e, u)), u = null }, re.isStandardBrowserEnv) { var p = (e.withCredentials || we(l)) && e.xsrfCookieName && be.read(e.xsrfCookieName); p && i.set(e.xsrfHeaderName, p) } void 0 === o && i.setContentType(null), "setRequestHeader" in u && q.forEach(i.toJSON(), (function (e, t) { u.setRequestHeader(t, e) })), q.isUndefined(e.withCredentials) || (u.withCredentials = !!e.withCredentials), a && "json" !== a && (u.responseType = e.responseType), "function" == typeof e.onDownloadProgress && u.addEventListener("progress", Ee(e.onDownloadProgress, !0)), "function" == typeof e.onUploadProgress && u.upload && u.upload.addEventListener("progress", Ee(e.onUploadProgress)), (e.cancelToken || e.signal) && (r = function (t) { u && (n(!t || t.type ? new ve(null, e, u) : t), u.abort(), u = null) }, e.cancelToken && e.cancelToken.subscribe(r), e.signal && (e.signal.aborted ? r() : e.signal.addEventListener("abort", r))); var h, m = (h = /^([-+\w]{1,25})(:?\/\/|:)/.exec(l)) && h[1] || ""; m && -1 === re.protocols.indexOf(m) ? n(new M("Unsupported protocol " + m + ":", M.ERR_BAD_REQUEST, e)) : u.send(o || null) })) } }; q.forEach(Oe, (function (e, t) { if (e) { try { Object.defineProperty(e, "name", { value: t }) } catch (e) { } Object.defineProperty(e, "adapterName", { value: t }) } })); var Se = function (e) { for (var t, n, r = (e = q.isArray(e) ? e : [e]).length, o = 0; o < r && (t = e[o], !(n = q.isString(t) ? Oe[t.toLowerCase()] : t)); o++); if (!n) { if (!1 === n) throw new M("Adapter ".concat(t, " is not supported by the environment"), "ERR_NOT_SUPPORT"); throw new Error(q.hasOwnProp(Oe, t) ? "Adapter '".concat(t, "' is not available in the build") : "Unknown adapter '".concat(t, "'")) } if (!q.isFunction(n)) throw new TypeError("adapter is not a function"); return n }; function Re (e) { if (e.cancelToken && e.cancelToken.throwIfRequested(), e.signal && e.signal.aborted) throw new ve(null, e) } function Ae (e) { return Re(e), e.headers = he.from(e.headers), e.data = me.call(e, e.transformRequest), -1 !== ["post", "put", "patch"].indexOf(e.method) && e.headers.setContentType("application/x-www-form-urlencoded", !1), Se(e.adapter || se.adapter)(e).then((function (t) { return Re(e), t.data = me.call(e, e.transformResponse, t), t.headers = he.from(t.headers), t }), (function (t) { return ye(t) || (Re(e), t && t.response && (t.response.data = me.call(e, e.transformResponse, t.response), t.response.headers = he.from(t.response.headers))), Promise.reject(t) })) } var Te = function (e) { return e instanceof he ? e.toJSON() : e }; function je (e, t) { t = t || {}; var n = {}; function r (e, t, n) { return q.isPlainObject(e) && q.isPlainObject(t) ? q.merge.call({ caseless: n }, e, t) : q.isPlainObject(t) ? q.merge({}, t) : q.isArray(t) ? t.slice() : t } function o (e, t, n) { return q.isUndefined(t) ? q.isUndefined(e) ? void 0 : r(void 0, e, n) : r(e, t, n) } function i (e, t) { if (!q.isUndefined(t)) return r(void 0, t) } function a (e, t) { return q.isUndefined(t) ? q.isUndefined(e) ? void 0 : r(void 0, e) : r(void 0, t) } function s (n, o, i) { return i in t ? r(n, o) : i in e ? r(void 0, n) : void 0 } var u = { url: i, method: i, data: i, baseURL: a, transformRequest: a, transformResponse: a, paramsSerializer: a, timeout: a, timeoutMessage: a, withCredentials: a, adapter: a, responseType: a, xsrfCookieName: a, xsrfHeaderName: a, onUploadProgress: a, onDownloadProgress: a, decompress: a, maxContentLength: a, maxBodyLength: a, beforeRedirect: a, transport: a, httpAgent: a, httpsAgent: a, cancelToken: a, socketPath: a, responseEncoding: a, validateStatus: s, headers: function (e, t) { return o(Te(e), Te(t), !0) } }; return q.forEach(Object.keys(Object.assign({}, e, t)), (function (r) { var i = u[r] || o, a = i(e[r], t[r], r); q.isUndefined(a) && i !== s || (n[r] = a) })), n } var Ne = "1.4.0", Ce = {}; ["object", "boolean", "number", "function", "string", "symbol"].forEach((function (t, n) { Ce[t] = function (r) { return e(r) === t || "a" + (n < 1 ? "n " : " ") + t } })); var xe = {}; Ce.transitional = function (e, t, n) { function r (e, t) { return "[Axios v1.4.0] Transitional option '" + e + "'" + t + (n ? ". " + n : "") } return function (n, o, i) { if (!1 === e) throw new M(r(o, " has been removed" + (t ? " in " + t : "")), M.ERR_DEPRECATED); return t && !xe[o] && (xe[o] = !0, console.warn(r(o, " has been deprecated since v" + t + " and will be removed in the near future"))), !e || e(n, o, i) } }; var Pe = { assertOptions: function (t, n, r) { if ("object" !== e(t)) throw new M("options must be an object", M.ERR_BAD_OPTION_VALUE); for (var o = Object.keys(t), i = o.length; i-- > 0;) { var a = o[i], s = n[a]; if (s) { var u = t[a], c = void 0 === u || s(u, a, t); if (!0 !== c) throw new M("option " + a + " must be " + c, M.ERR_BAD_OPTION_VALUE) } else if (!0 !== r) throw new M("Unknown option " + a, M.ERR_BAD_OPTION) } }, validators: Ce }, ke = Pe.validators, Ue = function () { function e (n) { t(this, e), this.defaults = n, this.interceptors = { request: new te, response: new te } } return r(e, [{ key: "request", value: function (e, t) { "string" == typeof e ? (t = t || {}).url = e : t = e || {}; var n, r = t = je(this.defaults, t), o = r.transitional, i = r.paramsSerializer, a = r.headers; void 0 !== o && Pe.assertOptions(o, { silentJSONParsing: ke.transitional(ke.boolean), forcedJSONParsing: ke.transitional(ke.boolean), clarifyTimeoutError: ke.transitional(ke.boolean) }, !1), null != i && (q.isFunction(i) ? t.paramsSerializer = { serialize: i } : Pe.assertOptions(i, { encode: ke.function, serialize: ke.function }, !0)), t.method = (t.method || this.defaults.method || "get").toLowerCase(), (n = a && q.merge(a.common, a[t.method])) && q.forEach(["delete", "get", "head", "post", "put", "patch", "common"], (function (e) { delete a[e] })), t.headers = he.concat(n, a); var s = [], u = !0; this.interceptors.request.forEach((function (e) { "function" == typeof e.runWhen && !1 === e.runWhen(t) || (u = u && e.synchronous, s.unshift(e.fulfilled, e.rejected)) })); var c, f = []; this.interceptors.response.forEach((function (e) { f.push(e.fulfilled, e.rejected) })); var l, d = 0; if (!u) { var p = [Ae.bind(this), void 0]; for (p.unshift.apply(p, s), p.push.apply(p, f), l = p.length, c = Promise.resolve(t); d < l;) c = c.then(p[d++], p[d++]); return c } l = s.length; var h = t; for (d = 0; d < l;) { var m = s[d++], y = s[d++]; try { h = m(h) } catch (e) { y.call(this, e); break } } try { c = Ae.call(this, h) } catch (e) { return Promise.reject(e) } for (d = 0, l = f.length; d < l;) c = c.then(f[d++], f[d++]); return c } }, { key: "getUri", value: function (e) { return Y(ge((e = je(this.defaults, e)).baseURL, e.url), e.params, e.paramsSerializer) } }]), e }(); q.forEach(["delete", "get", "head", "options"], (function (e) { Ue.prototype[e] = function (t, n) { return this.request(je(n || {}, { method: e, url: t, data: (n || {}).data })) } })), q.forEach(["post", "put", "patch"], (function (e) { function t (t) { return function (n, r, o) { return this.request(je(o || {}, { method: e, headers: t ? { "Content-Type": "multipart/form-data" } : {}, url: n, data: r })) } } Ue.prototype[e] = t(), Ue.prototype[e + "Form"] = t(!0) })); var _e = Ue, Fe = function () { function e (n) { if (t(this, e), "function" != typeof n) throw new TypeError("executor must be a function."); var r; this.promise = new Promise((function (e) { r = e })); var o = this; this.promise.then((function (e) { if (o._listeners) { for (var t = o._listeners.length; t-- > 0;) o._listeners[t](e); o._listeners = null } })), this.promise.then = function (e) { var t, n = new Promise((function (e) { o.subscribe(e), t = e })).then(e); return n.cancel = function () { o.unsubscribe(t) }, n }, n((function (e, t, n) { o.reason || (o.reason = new ve(e, t, n), r(o.reason)) })) } return r(e, [{ key: "throwIfRequested", value: function () { if (this.reason) throw this.reason } }, { key: "subscribe", value: function (e) { this.reason ? e(this.reason) : this._listeners ? this._listeners.push(e) : this._listeners = [e] } }, { key: "unsubscribe", value: function (e) { if (this._listeners) { var t = this._listeners.indexOf(e); -1 !== t && this._listeners.splice(t, 1) } } }], [{ key: "source", value: function () { var t; return { token: new e((function (e) { t = e })), cancel: t } } }]), e }(); var Be = { Continue: 100, SwitchingProtocols: 101, Processing: 102, EarlyHints: 103, Ok: 200, Created: 201, Accepted: 202, NonAuthoritativeInformation: 203, NoContent: 204, ResetContent: 205, PartialContent: 206, MultiStatus: 207, AlreadyReported: 208, ImUsed: 226, MultipleChoices: 300, MovedPermanently: 301, Found: 302, SeeOther: 303, NotModified: 304, UseProxy: 305, Unused: 306, TemporaryRedirect: 307, PermanentRedirect: 308, BadRequest: 400, Unauthorized: 401, PaymentRequired: 402, Forbidden: 403, NotFound: 404, MethodNotAllowed: 405, NotAcceptable: 406, ProxyAuthenticationRequired: 407, RequestTimeout: 408, Conflict: 409, Gone: 410, LengthRequired: 411, PreconditionFailed: 412, PayloadTooLarge: 413, UriTooLong: 414, UnsupportedMediaType: 415, RangeNotSatisfiable: 416, ExpectationFailed: 417, ImATeapot: 418, MisdirectedRequest: 421, UnprocessableEntity: 422, Locked: 423, FailedDependency: 424, TooEarly: 425, UpgradeRequired: 426, PreconditionRequired: 428, TooManyRequests: 429, RequestHeaderFieldsTooLarge: 431, UnavailableForLegalReasons: 451, InternalServerError: 500, NotImplemented: 501, BadGateway: 502, ServiceUnavailable: 503, GatewayTimeout: 504, HttpVersionNotSupported: 505, VariantAlsoNegotiates: 506, InsufficientStorage: 507, LoopDetected: 508, NotExtended: 510, NetworkAuthenticationRequired: 511 }; Object.entries(Be).forEach((function (e) { var t = o(e, 2), n = t[0], r = t[1]; Be[r] = n })); var Le = Be; var De = function e (t) { var n = new _e(t), r = a(_e.prototype.request, n); return q.extend(r, _e.prototype, n, { allOwnKeys: !0 }), q.extend(r, n, null, { allOwnKeys: !0 }), r.create = function (n) { return e(je(t, n)) }, r }(se); return De.Axios = _e, De.CanceledError = ve, De.CancelToken = Fe, De.isCancel = ye, De.VERSION = Ne, De.toFormData = G, De.AxiosError = M, De.Cancel = De.CanceledError, De.all = function (e) { return Promise.all(e) }, De.spread = function (e) { return function (t) { return e.apply(null, t) } }, De.isAxiosError = function (e) { return q.isObject(e) && !0 === e.isAxiosError }, De.mergeConfig = je, De.AxiosHeaders = he, De.formToJSON = function (e) { return oe(q.isHTMLForm(e) ? new FormData(e) : e) }, De.HttpStatusCode = Le, De.default = De, De })); return { requestAction: function (me, action, config) { // config.url = me.getOpt('serverUrl'); config.url = me.getActionUrl(); config.method = 'post'; config.params = config.params || {}; config.params = Object.assign(config.params, me.getOpt('serverparam')); config.params.action = action; return this.request(me, config); }, request: function (me, config) { config.headers = config.headers || {}; var customHeaders = me.getOpt('serverHeaders'); if (customHeaders) { for (var key in customHeaders) { config.headers[key] = customHeaders[key]; } } return axios(config); } } })(); // core/image.js UE.image = (function () { // import browser-image-compression // https://www.npmjs.com/package/browser-image-compression var imageCompression = null; !function (e, t) { imageCompression = t(); }(this, (function () { "use strict"; function _mergeNamespaces (e, t) { return t.forEach((function (t) { t && "string" != typeof t && !Array.isArray(t) && Object.keys(t).forEach((function (r) { if ("default" !== r && !(r in e)) { var i = Object.getOwnPropertyDescriptor(t, r); Object.defineProperty(e, r, i.get ? i : { enumerable: !0, get: function () { return t[r] } }) } })) })), Object.freeze(e) } function copyExifWithoutOrientation (e, t) { return new Promise((function (r, i) { let o; return getApp1Segment(e).then((function (e) { try { return o = e, r(new Blob([t.slice(0, 2), o, t.slice(2)], { type: "image/jpeg" })) } catch (e) { return i(e) } }), i) })) } const getApp1Segment = e => new Promise(((t, r) => { const i = new FileReader; i.addEventListener("load", (({ target: { result: e } }) => { const i = new DataView(e); let o = 0; if (65496 !== i.getUint16(o)) return r("not a valid JPEG"); for (o += 2; ;) { const a = i.getUint16(o); if (65498 === a) break; const s = i.getUint16(o + 2); if (65505 === a && 1165519206 === i.getUint32(o + 4)) { const a = o + 10; let f; switch (i.getUint16(a)) { case 18761: f = !0; break; case 19789: f = !1; break; default: return r("TIFF header contains invalid endian") } if (42 !== i.getUint16(a + 2, f)) return r("TIFF header contains invalid version"); const l = i.getUint32(a + 4, f), c = a + l + 2 + 12 * i.getUint16(a + l, f); for (let e = a + l + 2; e < c; e += 12) { if (274 == i.getUint16(e, f)) { if (3 !== i.getUint16(e + 2, f)) return r("Orientation data type is invalid"); if (1 !== i.getUint32(e + 4, f)) return r("Orientation data count is invalid"); i.setUint16(e + 8, 1, f); break } } return t(e.slice(o, o + 2 + s)) } o += 2 + s } return t(new Blob) })), i.readAsArrayBuffer(e) })); var e = {}; !function (e) { var t, r, UZIP = {}; e.exports = UZIP, UZIP.parse = function (e, t) { for (var r = UZIP.bin.readUshort, i = UZIP.bin.readUint, o = 0, a = {}, s = new Uint8Array(e), f = s.length - 4; 101010256 != i(s, f);) f--; o = f; o += 4; var l = r(s, o += 4); r(s, o += 2); var c = i(s, o += 2), u = i(s, o += 4); o += 4, o = u; for (var h = 0; h < l; h++) { i(s, o), o += 4, o += 4, o += 4, i(s, o += 4); c = i(s, o += 4); var d = i(s, o += 4), A = r(s, o += 4), g = r(s, o + 2), p = r(s, o + 4); o += 6; var m = i(s, o += 8); o += 4, o += A + g + p, UZIP._readLocal(s, m, a, c, d, t) } return a }, UZIP._readLocal = function (e, t, r, i, o, a) { var s = UZIP.bin.readUshort, f = UZIP.bin.readUint; f(e, t), s(e, t += 4), s(e, t += 2); var l = s(e, t += 2); f(e, t += 2), f(e, t += 4), t += 4; var c = s(e, t += 8), u = s(e, t += 2); t += 2; var h = UZIP.bin.readUTF8(e, t, c); if (t += c, t += u, a) r[h] = { size: o, csize: i }; else { var d = new Uint8Array(e.buffer, t); if (0 == l) r[h] = new Uint8Array(d.buffer.slice(t, t + i)); else { if (8 != l) throw "unknown compression method: " + l; var A = new Uint8Array(o); UZIP.inflateRaw(d, A), r[h] = A } } }, UZIP.inflateRaw = function (e, t) { return UZIP.F.inflate(e, t) }, UZIP.inflate = function (e, t) { return e[0], e[1], UZIP.inflateRaw(new Uint8Array(e.buffer, e.byteOffset + 2, e.length - 6), t) }, UZIP.deflate = function (e, t) { null == t && (t = { level: 6 }); var r = 0, i = new Uint8Array(50 + Math.floor(1.1 * e.length)); i[r] = 120, i[r + 1] = 156, r += 2, r = UZIP.F.deflateRaw(e, i, r, t.level); var o = UZIP.adler(e, 0, e.length); return i[r + 0] = o >>> 24 & 255, i[r + 1] = o >>> 16 & 255, i[r + 2] = o >>> 8 & 255, i[r + 3] = o >>> 0 & 255, new Uint8Array(i.buffer, 0, r + 4) }, UZIP.deflateRaw = function (e, t) { null == t && (t = { level: 6 }); var r = new Uint8Array(50 + Math.floor(1.1 * e.length)), i = UZIP.F.deflateRaw(e, r, i, t.level); return new Uint8Array(r.buffer, 0, i) }, UZIP.encode = function (e, t) { null == t && (t = !1); var r = 0, i = UZIP.bin.writeUint, o = UZIP.bin.writeUshort, a = {}; for (var s in e) { var f = !UZIP._noNeed(s) && !t, l = e[s], c = UZIP.crc.crc(l, 0, l.length); a[s] = { cpr: f, usize: l.length, crc: c, file: f ? UZIP.deflateRaw(l) : l } } for (var s in a) r += a[s].file.length + 30 + 46 + 2 * UZIP.bin.sizeUTF8(s); r += 22; var u = new Uint8Array(r), h = 0, d = []; for (var s in a) { var A = a[s]; d.push(h), h = UZIP._writeHeader(u, h, s, A, 0) } var g = 0, p = h; for (var s in a) { A = a[s]; d.push(h), h = UZIP._writeHeader(u, h, s, A, 1, d[g++]) } var m = h - p; return i(u, h, 101010256), h += 4, o(u, h += 4, g), o(u, h += 2, g), i(u, h += 2, m), i(u, h += 4, p), h += 4, h += 2, u.buffer }, UZIP._noNeed = function (e) { var t = e.split(".").pop().toLowerCase(); return -1 != "png,jpg,jpeg,zip".indexOf(t) }, UZIP._writeHeader = function (e, t, r, i, o, a) { var s = UZIP.bin.writeUint, f = UZIP.bin.writeUshort, l = i.file; return s(e, t, 0 == o ? 67324752 : 33639248), t += 4, 1 == o && (t += 2), f(e, t, 20), f(e, t += 2, 0), f(e, t += 2, i.cpr ? 8 : 0), s(e, t += 2, 0), s(e, t += 4, i.crc), s(e, t += 4, l.length), s(e, t += 4, i.usize), f(e, t += 4, UZIP.bin.sizeUTF8(r)), f(e, t += 2, 0), t += 2, 1 == o && (t += 2, t += 2, s(e, t += 6, a), t += 4), t += UZIP.bin.writeUTF8(e, t, r), 0 == o && (e.set(l, t), t += l.length), t }, UZIP.crc = { table: function () { for (var e = new Uint32Array(256), t = 0; t < 256; t++) { for (var r = t, i = 0; i < 8; i++) 1 & r ? r = 3988292384 ^ r >>> 1 : r >>>= 1; e[t] = r } return e }(), update: function (e, t, r, i) { for (var o = 0; o < i; o++) e = UZIP.crc.table[255 & (e ^ t[r + o])] ^ e >>> 8; return e }, crc: function (e, t, r) { return 4294967295 ^ UZIP.crc.update(4294967295, e, t, r) } }, UZIP.adler = function (e, t, r) { for (var i = 1, o = 0, a = t, s = t + r; a < s;) { for (var f = Math.min(a + 5552, s); a < f;) o += i += e[a++]; i %= 65521, o %= 65521 } return o << 16 | i }, UZIP.bin = { readUshort: function (e, t) { return e[t] | e[t + 1] << 8 }, writeUshort: function (e, t, r) { e[t] = 255 & r, e[t + 1] = r >> 8 & 255 }, readUint: function (e, t) { return 16777216 * e[t + 3] + (e[t + 2] << 16 | e[t + 1] << 8 | e[t]) }, writeUint: function (e, t, r) { e[t] = 255 & r, e[t + 1] = r >> 8 & 255, e[t + 2] = r >> 16 & 255, e[t + 3] = r >> 24 & 255 }, readASCII: function (e, t, r) { for (var i = "", o = 0; o < r; o++) i += String.fromCharCode(e[t + o]); return i }, writeASCII: function (e, t, r) { for (var i = 0; i < r.length; i++) e[t + i] = r.charCodeAt(i) }, pad: function (e) { return e.length < 2 ? "0" + e : e }, readUTF8: function (e, t, r) { for (var i, o = "", a = 0; a < r; a++) o += "%" + UZIP.bin.pad(e[t + a].toString(16)); try { i = decodeURIComponent(o) } catch (i) { return UZIP.bin.readASCII(e, t, r) } return i }, writeUTF8: function (e, t, r) { for (var i = r.length, o = 0, a = 0; a < i; a++) { var s = r.charCodeAt(a); if (0 == (4294967168 & s)) e[t + o] = s, o++; else if (0 == (4294965248 & s)) e[t + o] = 192 | s >> 6, e[t + o + 1] = 128 | s >> 0 & 63, o += 2; else if (0 == (4294901760 & s)) e[t + o] = 224 | s >> 12, e[t + o + 1] = 128 | s >> 6 & 63, e[t + o + 2] = 128 | s >> 0 & 63, o += 3; else { if (0 != (4292870144 & s)) throw "e"; e[t + o] = 240 | s >> 18, e[t + o + 1] = 128 | s >> 12 & 63, e[t + o + 2] = 128 | s >> 6 & 63, e[t + o + 3] = 128 | s >> 0 & 63, o += 4 } } return o }, sizeUTF8: function (e) { for (var t = e.length, r = 0, i = 0; i < t; i++) { var o = e.charCodeAt(i); if (0 == (4294967168 & o)) r++; else if (0 == (4294965248 & o)) r += 2; else if (0 == (4294901760 & o)) r += 3; else { if (0 != (4292870144 & o)) throw "e"; r += 4 } } return r } }, UZIP.F = {}, UZIP.F.deflateRaw = function (e, t, r, i) { var o = [[0, 0, 0, 0, 0], [4, 4, 8, 4, 0], [4, 5, 16, 8, 0], [4, 6, 16, 16, 0], [4, 10, 16, 32, 0], [8, 16, 32, 32, 0], [8, 16, 128, 128, 0], [8, 32, 128, 256, 0], [32, 128, 258, 1024, 1], [32, 258, 258, 4096, 1]][i], a = UZIP.F.U, s = UZIP.F._goodIndex; UZIP.F._hash; var f = UZIP.F._putsE, l = 0, c = r << 3, u = 0, h = e.length; if (0 == i) { for (; l < h;) { f(t, c, l + (_ = Math.min(65535, h - l)) == h ? 1 : 0), c = UZIP.F._copyExact(e, l, _, t, c + 8), l += _ } return c >>> 3 } var d = a.lits, A = a.strt, g = a.prev, p = 0, m = 0, w = 0, v = 0, b = 0, y = 0; for (h > 2 && (A[y = UZIP.F._hash(e, 0)] = 0), l = 0; l < h; l++) { if (b = y, l + 1 < h - 2) { y = UZIP.F._hash(e, l + 1); var E = l + 1 & 32767; g[E] = A[y], A[y] = E } if (u <= l) { (p > 14e3 || m > 26697) && h - l > 100 && (u < l && (d[p] = l - u, p += 2, u = l), c = UZIP.F._writeBlock(l == h - 1 || u == h ? 1 : 0, d, p, v, e, w, l - w, t, c), p = m = v = 0, w = l); var F = 0; l < h - 2 && (F = UZIP.F._bestMatch(e, l, g, b, Math.min(o[2], h - l), o[3])); var _ = F >>> 16, B = 65535 & F; if (0 != F) { B = 65535 & F; var U = s(_ = F >>> 16, a.of0); a.lhst[257 + U]++; var C = s(B, a.df0); a.dhst[C]++, v += a.exb[U] + a.dxb[C], d[p] = _ << 23 | l - u, d[p + 1] = B << 16 | U << 8 | C, p += 2, u = l + _ } else a.lhst[e[l]]++; m++ } } for (w == l && 0 != e.length || (u < l && (d[p] = l - u, p += 2, u = l), c = UZIP.F._writeBlock(1, d, p, v, e, w, l - w, t, c), p = 0, m = 0, p = m = v = 0, w = l); 0 != (7 & c);) c++; return c >>> 3 }, UZIP.F._bestMatch = function (e, t, r, i, o, a) { var s = 32767 & t, f = r[s], l = s - f + 32768 & 32767; if (f == s || i != UZIP.F._hash(e, t - l)) return 0; for (var c = 0, u = 0, h = Math.min(32767, t); l <= h && 0 != --a && f != s;) { if (0 == c || e[t + c] == e[t + c - l]) { var d = UZIP.F._howLong(e, t, l); if (d > c) { if (u = l, (c = d) >= o) break; l + 2 < d && (d = l + 2); for (var A = 0, g = 0; g < d - 2; g++) { var p = t - l + g + 32768 & 32767, m = p - r[p] + 32768 & 32767; m > A && (A = m, f = p) } } } l += (s = f) - (f = r[s]) + 32768 & 32767 } return c << 16 | u }, UZIP.F._howLong = function (e, t, r) { if (e[t] != e[t - r] || e[t + 1] != e[t + 1 - r] || e[t + 2] != e[t + 2 - r]) return 0; var i = t, o = Math.min(e.length, t + 258); for (t += 3; t < o && e[t] == e[t - r];) t++; return t - i }, UZIP.F._hash = function (e, t) { return (e[t] << 8 | e[t + 1]) + (e[t + 2] << 4) & 65535 }, UZIP.saved = 0, UZIP.F._writeBlock = function (e, t, r, i, o, a, s, f, l) { var c, u, h, d, A, g, p, m, w, v = UZIP.F.U, b = UZIP.F._putsF, y = UZIP.F._putsE; v.lhst[256]++, u = (c = UZIP.F.getTrees())[0], h = c[1], d = c[2], A = c[3], g = c[4], p = c[5], m = c[6], w = c[7]; var E = 32 + (0 == (l + 3 & 7) ? 0 : 8 - (l + 3 & 7)) + (s << 3), F = i + UZIP.F.contSize(v.fltree, v.lhst) + UZIP.F.contSize(v.fdtree, v.dhst), _ = i + UZIP.F.contSize(v.ltree, v.lhst) + UZIP.F.contSize(v.dtree, v.dhst); _ += 14 + 3 * p + UZIP.F.contSize(v.itree, v.ihst) + (2 * v.ihst[16] + 3 * v.ihst[17] + 7 * v.ihst[18]); for (var B = 0; B < 286; B++) v.lhst[B] = 0; for (B = 0; B < 30; B++) v.dhst[B] = 0; for (B = 0; B < 19; B++) v.ihst[B] = 0; var U = E < F && E < _ ? 0 : F < _ ? 1 : 2; if (b(f, l, e), b(f, l + 1, U), l += 3, 0 == U) { for (; 0 != (7 & l);) l++; l = UZIP.F._copyExact(o, a, s, f, l) } else { var C, I; if (1 == U && (C = v.fltree, I = v.fdtree), 2 == U) { UZIP.F.makeCodes(v.ltree, u), UZIP.F.revCodes(v.ltree, u), UZIP.F.makeCodes(v.dtree, h), UZIP.F.revCodes(v.dtree, h), UZIP.F.makeCodes(v.itree, d), UZIP.F.revCodes(v.itree, d), C = v.ltree, I = v.dtree, y(f, l, A - 257), y(f, l += 5, g - 1), y(f, l += 5, p - 4), l += 4; for (var Q = 0; Q < p; Q++) y(f, l + 3 * Q, v.itree[1 + (v.ordr[Q] << 1)]); l += 3 * p, l = UZIP.F._codeTiny(m, v.itree, f, l), l = UZIP.F._codeTiny(w, v.itree, f, l) } for (var M = a, x = 0; x < r; x += 2) { for (var T = t[x], S = T >>> 23, R = M + (8388607 & T); M < R;) l = UZIP.F._writeLit(o[M++], C, f, l); if (0 != S) { var O = t[x + 1], P = O >> 16, H = O >> 8 & 255, L = 255 & O; y(f, l = UZIP.F._writeLit(257 + H, C, f, l), S - v.of0[H]), l += v.exb[H], b(f, l = UZIP.F._writeLit(L, I, f, l), P - v.df0[L]), l += v.dxb[L], M += S } } l = UZIP.F._writeLit(256, C, f, l) } return l }, UZIP.F._copyExact = function (e, t, r, i, o) { var a = o >>> 3; return i[a] = r, i[a + 1] = r >>> 8, i[a + 2] = 255 - i[a], i[a + 3] = 255 - i[a + 1], a += 4, i.set(new Uint8Array(e.buffer, t, r), a), o + (r + 4 << 3) }, UZIP.F.getTrees = function () { for (var e = UZIP.F.U, t = UZIP.F._hufTree(e.lhst, e.ltree, 15), r = UZIP.F._hufTree(e.dhst, e.dtree, 15), i = [], o = UZIP.F._lenCodes(e.ltree, i), a = [], s = UZIP.F._lenCodes(e.dtree, a), f = 0; f < i.length; f += 2) e.ihst[i[f]]++; for (f = 0; f < a.length; f += 2) e.ihst[a[f]]++; for (var l = UZIP.F._hufTree(e.ihst, e.itree, 7), c = 19; c > 4 && 0 == e.itree[1 + (e.ordr[c - 1] << 1)];) c--; return [t, r, l, o, s, c, i, a] }, UZIP.F.getSecond = function (e) { for (var t = [], r = 0; r < e.length; r += 2) t.push(e[r + 1]); return t }, UZIP.F.nonZero = function (e) { for (var t = "", r = 0; r < e.length; r += 2) 0 != e[r + 1] && (t += (r >> 1) + ","); return t }, UZIP.F.contSize = function (e, t) { for (var r = 0, i = 0; i < t.length; i++) r += t[i] * e[1 + (i << 1)]; return r }, UZIP.F._codeTiny = function (e, t, r, i) { for (var o = 0; o < e.length; o += 2) { var a = e[o], s = e[o + 1]; i = UZIP.F._writeLit(a, t, r, i); var f = 16 == a ? 2 : 17 == a ? 3 : 7; a > 15 && (UZIP.F._putsE(r, i, s, f), i += f) } return i }, UZIP.F._lenCodes = function (e, t) { for (var r = e.length; 2 != r && 0 == e[r - 1];) r -= 2; for (var i = 0; i < r; i += 2) { var o = e[i + 1], a = i + 3 < r ? e[i + 3] : -1, s = i + 5 < r ? e[i + 5] : -1, f = 0 == i ? -1 : e[i - 1]; if (0 == o && a == o && s == o) { for (var l = i + 5; l + 2 < r && e[l + 2] == o;) l += 2; (c = Math.min(l + 1 - i >>> 1, 138)) < 11 ? t.push(17, c - 3) : t.push(18, c - 11), i += 2 * c - 2 } else if (o == f && a == o && s == o) { for (l = i + 5; l + 2 < r && e[l + 2] == o;) l += 2; var c = Math.min(l + 1 - i >>> 1, 6); t.push(16, c - 3), i += 2 * c - 2 } else t.push(o, 0) } return r >>> 1 }, UZIP.F._hufTree = function (e, t, r) { var i = [], o = e.length, a = t.length, s = 0; for (s = 0; s < a; s += 2) t[s] = 0, t[s + 1] = 0; for (s = 0; s < o; s++) 0 != e[s] && i.push({ lit: s, f: e[s] }); var f = i.length, l = i.slice(0); if (0 == f) return 0; if (1 == f) { var c = i[0].lit; l = 0 == c ? 1 : 0; return t[1 + (c << 1)] = 1, t[1 + (l << 1)] = 1, 1 } i.sort((function (e, t) { return e.f - t.f })); var u = i[0], h = i[1], d = 0, A = 1, g = 2; for (i[0] = { lit: -1, f: u.f + h.f, l: u, r: h, d: 0 }; A != f - 1;) u = d != A && (g == f || i[d].f < i[g].f) ? i[d++] : i[g++], h = d != A && (g == f || i[d].f < i[g].f) ? i[d++] : i[g++], i[A++] = { lit: -1, f: u.f + h.f, l: u, r: h }; var p = UZIP.F.setDepth(i[A - 1], 0); for (p > r && (UZIP.F.restrictDepth(l, r, p), p = r), s = 0; s < f; s++) t[1 + (l[s].lit << 1)] = l[s].d; return p }, UZIP.F.setDepth = function (e, t) { return -1 != e.lit ? (e.d = t, t) : Math.max(UZIP.F.setDepth(e.l, t + 1), UZIP.F.setDepth(e.r, t + 1)) }, UZIP.F.restrictDepth = function (e, t, r) { var i = 0, o = 1 << r - t, a = 0; for (e.sort((function (e, t) { return t.d == e.d ? e.f - t.f : t.d - e.d })), i = 0; i < e.length && e[i].d > t; i++) { var s = e[i].d; e[i].d = t, a += o - (1 << r - s) } for (a >>>= r - t; a > 0;) { (s = e[i].d) < t ? (e[i].d++, a -= 1 << t - s - 1) : i++ } for (; i >= 0; i--) e[i].d == t && a < 0 && (e[i].d--, a++); 0 != a && console.log("debt left") }, UZIP.F._goodIndex = function (e, t) { var r = 0; return t[16 | r] <= e && (r |= 16), t[8 | r] <= e && (r |= 8), t[4 | r] <= e && (r |= 4), t[2 | r] <= e && (r |= 2), t[1 | r] <= e && (r |= 1), r }, UZIP.F._writeLit = function (e, t, r, i) { return UZIP.F._putsF(r, i, t[e << 1]), i + t[1 + (e << 1)] }, UZIP.F.inflate = function (e, t) { var r = Uint8Array; if (3 == e[0] && 0 == e[1]) return t || new r(0); var i = UZIP.F, o = i._bitsF, a = i._bitsE, s = i._decodeTiny, f = i.makeCodes, l = i.codes2map, c = i._get17, u = i.U, h = null == t; h && (t = new r(e.length >>> 2 << 3)); for (var d, A, g = 0, p = 0, m = 0, w = 0, v = 0, b = 0, y = 0, E = 0, F = 0; 0 == g;) if (g = o(e, F, 1), p = o(e, F + 1, 2), F += 3, 0 != p) { if (h && (t = UZIP.F._check(t, E + (1 << 17))), 1 == p && (d = u.flmap, A = u.fdmap, b = 511, y = 31), 2 == p) { m = a(e, F, 5) + 257, w = a(e, F + 5, 5) + 1, v = a(e, F + 10, 4) + 4, F += 14; for (var _ = 0; _ < 38; _ += 2) u.itree[_] = 0, u.itree[_ + 1] = 0; var B = 1; for (_ = 0; _ < v; _++) { var U = a(e, F + 3 * _, 3); u.itree[1 + (u.ordr[_] << 1)] = U, U > B && (B = U) } F += 3 * v, f(u.itree, B), l(u.itree, B, u.imap), d = u.lmap, A = u.dmap, F = s(u.imap, (1 << B) - 1, m + w, e, F, u.ttree); var C = i._copyOut(u.ttree, 0, m, u.ltree); b = (1 << C) - 1; var I = i._copyOut(u.ttree, m, w, u.dtree); y = (1 << I) - 1, f(u.ltree, C), l(u.ltree, C, d), f(u.dtree, I), l(u.dtree, I, A) } for (; ;) { var Q = d[c(e, F) & b]; F += 15 & Q; var M = Q >>> 4; if (M >>> 8 == 0) t[E++] = M; else { if (256 == M) break; var x = E + M - 254; if (M > 264) { var T = u.ldef[M - 257]; x = E + (T >>> 3) + a(e, F, 7 & T), F += 7 & T } var S = A[c(e, F) & y]; F += 15 & S; var R = S >>> 4, O = u.ddef[R], P = (O >>> 4) + o(e, F, 15 & O); for (F += 15 & O, h && (t = UZIP.F._check(t, E + (1 << 17))); E < x;) t[E] = t[E++ - P], t[E] = t[E++ - P], t[E] = t[E++ - P], t[E] = t[E++ - P]; E = x } } } else { 0 != (7 & F) && (F += 8 - (7 & F)); var H = 4 + (F >>> 3), L = e[H - 4] | e[H - 3] << 8; h && (t = UZIP.F._check(t, E + L)), t.set(new r(e.buffer, e.byteOffset + H, L), E), F = H + L << 3, E += L } return t.length == E ? t : t.slice(0, E) }, UZIP.F._check = function (e, t) { var r = e.length; if (t <= r) return e; var i = new Uint8Array(Math.max(r << 1, t)); return i.set(e, 0), i }, UZIP.F._decodeTiny = function (e, t, r, i, o, a) { for (var s = UZIP.F._bitsE, f = UZIP.F._get17, l = 0; l < r;) { var c = e[f(i, o) & t]; o += 15 & c; var u = c >>> 4; if (u <= 15) a[l] = u, l++; else { var h = 0, d = 0; 16 == u ? (d = 3 + s(i, o, 2), o += 2, h = a[l - 1]) : 17 == u ? (d = 3 + s(i, o, 3), o += 3) : 18 == u && (d = 11 + s(i, o, 7), o += 7); for (var A = l + d; l < A;) a[l] = h, l++ } } return o }, UZIP.F._copyOut = function (e, t, r, i) { for (var o = 0, a = 0, s = i.length >>> 1; a < r;) { var f = e[a + t]; i[a << 1] = 0, i[1 + (a << 1)] = f, f > o && (o = f), a++ } for (; a < s;) i[a << 1] = 0, i[1 + (a << 1)] = 0, a++; return o }, UZIP.F.makeCodes = function (e, t) { for (var r, i, o, a, s = UZIP.F.U, f = e.length, l = s.bl_count, c = 0; c <= t; c++) l[c] = 0; for (c = 1; c < f; c += 2) l[e[c]]++; var u = s.next_code; for (r = 0, l[0] = 0, i = 1; i <= t; i++) r = r + l[i - 1] << 1, u[i] = r; for (o = 0; o < f; o += 2) 0 != (a = e[o + 1]) && (e[o] = u[a], u[a]++) }, UZIP.F.codes2map = function (e, t, r) { for (var i = e.length, o = UZIP.F.U.rev15, a = 0; a < i; a += 2) if (0 != e[a + 1]) for (var s = a >> 1, f = e[a + 1], l = s << 4 | f, c = t - f, u = e[a] << c, h = u + (1 << c); u != h;) { r[o[u] >>> 15 - t] = l, u++ } }, UZIP.F.revCodes = function (e, t) { for (var r = UZIP.F.U.rev15, i = 15 - t, o = 0; o < e.length; o += 2) { var a = e[o] << t - e[o + 1]; e[o] = r[a] >>> i } }, UZIP.F._putsE = function (e, t, r) { r <<= 7 & t; var i = t >>> 3; e[i] |= r, e[i + 1] |= r >>> 8 }, UZIP.F._putsF = function (e, t, r) { r <<= 7 & t; var i = t >>> 3; e[i] |= r, e[i + 1] |= r >>> 8, e[i + 2] |= r >>> 16 }, UZIP.F._bitsE = function (e, t, r) { return (e[t >>> 3] | e[1 + (t >>> 3)] << 8) >>> (7 & t) & (1 << r) - 1 }, UZIP.F._bitsF = function (e, t, r) { return (e[t >>> 3] | e[1 + (t >>> 3)] << 8 | e[2 + (t >>> 3)] << 16) >>> (7 & t) & (1 << r) - 1 }, UZIP.F._get17 = function (e, t) { return (e[t >>> 3] | e[1 + (t >>> 3)] << 8 | e[2 + (t >>> 3)] << 16) >>> (7 & t) }, UZIP.F._get25 = function (e, t) { return (e[t >>> 3] | e[1 + (t >>> 3)] << 8 | e[2 + (t >>> 3)] << 16 | e[3 + (t >>> 3)] << 24) >>> (7 & t) }, UZIP.F.U = (t = Uint16Array, r = Uint32Array, { next_code: new t(16), bl_count: new t(16), ordr: [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15], of0: [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 999, 999, 999], exb: [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0], ldef: new t(32), df0: [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 65535, 65535], dxb: [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0], ddef: new r(32), flmap: new t(512), fltree: [], fdmap: new t(32), fdtree: [], lmap: new t(32768), ltree: [], ttree: [], dmap: new t(32768), dtree: [], imap: new t(512), itree: [], rev15: new t(32768), lhst: new r(286), dhst: new r(30), ihst: new r(19), lits: new r(15e3), strt: new t(65536), prev: new t(32768) }), function () { for (var e = UZIP.F.U, t = 0; t < 32768; t++) { var r = t; r = (4278255360 & (r = (4042322160 & (r = (3435973836 & (r = (2863311530 & r) >>> 1 | (1431655765 & r) << 1)) >>> 2 | (858993459 & r) << 2)) >>> 4 | (252645135 & r) << 4)) >>> 8 | (16711935 & r) << 8, e.rev15[t] = (r >>> 16 | r << 16) >>> 17 } function pushV (e, t, r) { for (; 0 != t--;) e.push(0, r) } for (t = 0; t < 32; t++) e.ldef[t] = e.of0[t] << 3 | e.exb[t], e.ddef[t] = e.df0[t] << 4 | e.dxb[t]; pushV(e.fltree, 144, 8), pushV(e.fltree, 112, 9), pushV(e.fltree, 24, 7), pushV(e.fltree, 8, 8), UZIP.F.makeCodes(e.fltree, 9), UZIP.F.codes2map(e.fltree, 9, e.flmap), UZIP.F.revCodes(e.fltree, 9), pushV(e.fdtree, 32, 5), UZIP.F.makeCodes(e.fdtree, 5), UZIP.F.codes2map(e.fdtree, 5, e.fdmap), UZIP.F.revCodes(e.fdtree, 5), pushV(e.itree, 19, 0), pushV(e.ltree, 286, 0), pushV(e.dtree, 30, 0), pushV(e.ttree, 320, 0) }() }({ get exports () { return e }, set exports (t) { e = t } }); var UZIP = _mergeNamespaces({ __proto__: null, default: e }, [e]); const UPNG = function () { var e = { nextZero (e, t) { for (; 0 != e[t];) t++; return t }, readUshort: (e, t) => e[t] << 8 | e[t + 1], writeUshort (e, t, r) { e[t] = r >> 8 & 255, e[t + 1] = 255 & r }, readUint: (e, t) => 16777216 * e[t] + (e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3]), writeUint (e, t, r) { e[t] = r >> 24 & 255, e[t + 1] = r >> 16 & 255, e[t + 2] = r >> 8 & 255, e[t + 3] = 255 & r }, readASCII (e, t, r) { let i = ""; for (let o = 0; o < r; o++) i += String.fromCharCode(e[t + o]); return i }, writeASCII (e, t, r) { for (let i = 0; i < r.length; i++) e[t + i] = r.charCodeAt(i) }, readBytes (e, t, r) { const i = []; for (let o = 0; o < r; o++) i.push(e[t + o]); return i }, pad: e => e.length < 2 ? `0${e}` : e, readUTF8 (t, r, i) { let o, a = ""; for (let o = 0; o < i; o++) a += `%${e.pad(t[r + o].toString(16))}`; try { o = decodeURIComponent(a) } catch (o) { return e.readASCII(t, r, i) } return o } }; function decodeImage (t, r, i, o) { const a = r * i, s = _getBPP(o), f = Math.ceil(r * s / 8), l = new Uint8Array(4 * a), c = new Uint32Array(l.buffer), { ctype: u } = o, { depth: h } = o, d = e.readUshort; if (6 == u) { const e = a << 2; if (8 == h) for (var A = 0; A < e; A += 4) l[A] = t[A], l[A + 1] = t[A + 1], l[A + 2] = t[A + 2], l[A + 3] = t[A + 3]; if (16 == h) for (A = 0; A < e; A++) l[A] = t[A << 1] } else if (2 == u) { const e = o.tabs.tRNS; if (null == e) { if (8 == h) for (A = 0; A < a; A++) { var g = 3 * A; c[A] = 255 << 24 | t[g + 2] << 16 | t[g + 1] << 8 | t[g] } if (16 == h) for (A = 0; A < a; A++) { g = 6 * A; c[A] = 255 << 24 | t[g + 4] << 16 | t[g + 2] << 8 | t[g] } } else { var p = e[0]; const r = e[1], i = e[2]; if (8 == h) for (A = 0; A < a; A++) { var m = A << 2; g = 3 * A; c[A] = 255 << 24 | t[g + 2] << 16 | t[g + 1] << 8 | t[g], t[g] == p && t[g + 1] == r && t[g + 2] == i && (l[m + 3] = 0) } if (16 == h) for (A = 0; A < a; A++) { m = A << 2, g = 6 * A; c[A] = 255 << 24 | t[g + 4] << 16 | t[g + 2] << 8 | t[g], d(t, g) == p && d(t, g + 2) == r && d(t, g + 4) == i && (l[m + 3] = 0) } } } else if (3 == u) { const e = o.tabs.PLTE, s = o.tabs.tRNS, c = s ? s.length : 0; if (1 == h) for (var w = 0; w < i; w++) { var v = w * f, b = w * r; for (A = 0; A < r; A++) { m = b + A << 2; var y = 3 * (E = t[v + (A >> 3)] >> 7 - ((7 & A) << 0) & 1); l[m] = e[y], l[m + 1] = e[y + 1], l[m + 2] = e[y + 2], l[m + 3] = E < c ? s[E] : 255 } } if (2 == h) for (w = 0; w < i; w++) for (v = w * f, b = w * r, A = 0; A < r; A++) { m = b + A << 2, y = 3 * (E = t[v + (A >> 2)] >> 6 - ((3 & A) << 1) & 3); l[m] = e[y], l[m + 1] = e[y + 1], l[m + 2] = e[y + 2], l[m + 3] = E < c ? s[E] : 255 } if (4 == h) for (w = 0; w < i; w++) for (v = w * f, b = w * r, A = 0; A < r; A++) { m = b + A << 2, y = 3 * (E = t[v + (A >> 1)] >> 4 - ((1 & A) << 2) & 15); l[m] = e[y], l[m + 1] = e[y + 1], l[m + 2] = e[y + 2], l[m + 3] = E < c ? s[E] : 255 } if (8 == h) for (A = 0; A < a; A++) { var E; m = A << 2, y = 3 * (E = t[A]); l[m] = e[y], l[m + 1] = e[y + 1], l[m + 2] = e[y + 2], l[m + 3] = E < c ? s[E] : 255 } } else if (4 == u) { if (8 == h) for (A = 0; A < a; A++) { m = A << 2; var F = t[_ = A << 1]; l[m] = F, l[m + 1] = F, l[m + 2] = F, l[m + 3] = t[_ + 1] } if (16 == h) for (A = 0; A < a; A++) { var _; m = A << 2, F = t[_ = A << 2]; l[m] = F, l[m + 1] = F, l[m + 2] = F, l[m + 3] = t[_ + 2] } } else if (0 == u) for (p = o.tabs.tRNS ? o.tabs.tRNS : -1, w = 0; w < i; w++) { const e = w * f, i = w * r; if (1 == h) for (var B = 0; B < r; B++) { var U = (F = 255 * (t[e + (B >>> 3)] >>> 7 - (7 & B) & 1)) == 255 * p ? 0 : 255; c[i + B] = U << 24 | F << 16 | F << 8 | F } else if (2 == h) for (B = 0; B < r; B++) { U = (F = 85 * (t[e + (B >>> 2)] >>> 6 - ((3 & B) << 1) & 3)) == 85 * p ? 0 : 255; c[i + B] = U << 24 | F << 16 | F << 8 | F } else if (4 == h) for (B = 0; B < r; B++) { U = (F = 17 * (t[e + (B >>> 1)] >>> 4 - ((1 & B) << 2) & 15)) == 17 * p ? 0 : 255; c[i + B] = U << 24 | F << 16 | F << 8 | F } else if (8 == h) for (B = 0; B < r; B++) { U = (F = t[e + B]) == p ? 0 : 255; c[i + B] = U << 24 | F << 16 | F << 8 | F } else if (16 == h) for (B = 0; B < r; B++) { F = t[e + (B << 1)], U = d(t, e + (B << 1)) == p ? 0 : 255; c[i + B] = U << 24 | F << 16 | F << 8 | F } } return l } function _decompress (e, r, i, o) { const a = _getBPP(e), s = Math.ceil(i * a / 8), f = new Uint8Array((s + 1 + e.interlace) * o); return r = e.tabs.CgBI ? t(r, f) : _inflate(r, f), 0 == e.interlace ? r = _filterZero(r, e, 0, i, o) : 1 == e.interlace && (r = function _readInterlace (e, t) { const r = t.width, i = t.height, o = _getBPP(t), a = o >> 3, s = Math.ceil(r * o / 8), f = new Uint8Array(i * s); let l = 0; const c = [0, 0, 4, 0, 2, 0, 1], u = [0, 4, 0, 2, 0, 1, 0], h = [8, 8, 8, 4, 4, 2, 2], d = [8, 8, 4, 4, 2, 2, 1]; let A = 0; for (; A < 7;) { const p = h[A], m = d[A]; let w = 0, v = 0, b = c[A]; for (; b < i;) b += p, v++; let y = u[A]; for (; y < r;) y += m, w++; const E = Math.ceil(w * o / 8); _filterZero(e, t, l, w, v); let F = 0, _ = c[A]; for (; _ < i;) { let t = u[A], i = l + F * E << 3; for (; t < r;) { var g; if (1 == o) g = (g = e[i >> 3]) >> 7 - (7 & i) & 1, f[_ * s + (t >> 3)] |= g << 7 - ((7 & t) << 0); if (2 == o) g = (g = e[i >> 3]) >> 6 - (7 & i) & 3, f[_ * s + (t >> 2)] |= g << 6 - ((3 & t) << 1); if (4 == o) g = (g = e[i >> 3]) >> 4 - (7 & i) & 15, f[_ * s + (t >> 1)] |= g << 4 - ((1 & t) << 2); if (o >= 8) { const r = _ * s + t * a; for (let t = 0; t < a; t++) f[r + t] = e[(i >> 3) + t] } i += o, t += m } F++, _ += p } w * v != 0 && (l += v * (1 + E)), A += 1 } return f }(r, e)), r } function _inflate (e, r) { return t(new Uint8Array(e.buffer, 2, e.length - 6), r) } var t = function () { const e = { H: {} }; return e.H.N = function (t, r) { const i = Uint8Array; let o, a, s = 0, f = 0, l = 0, c = 0, u = 0, h = 0, d = 0, A = 0, g = 0; if (3 == t[0] && 0 == t[1]) return r || new i(0); const p = e.H, m = p.b, w = p.e, v = p.R, b = p.n, y = p.A, E = p.Z, F = p.m, _ = null == r; for (_ && (r = new i(t.length >>> 2 << 5)); 0 == s;) if (s = m(t, g, 1), f = m(t, g + 1, 2), g += 3, 0 != f) { if (_ && (r = e.H.W(r, A + (1 << 17))), 1 == f && (o = F.J, a = F.h, h = 511, d = 31), 2 == f) { l = w(t, g, 5) + 257, c = w(t, g + 5, 5) + 1, u = w(t, g + 10, 4) + 4, g += 14; let e = 1; for (var B = 0; B < 38; B += 2) F.Q[B] = 0, F.Q[B + 1] = 0; for (B = 0; B < u; B++) { const r = w(t, g + 3 * B, 3); F.Q[1 + (F.X[B] << 1)] = r, r > e && (e = r) } g += 3 * u, b(F.Q, e), y(F.Q, e, F.u), o = F.w, a = F.d, g = v(F.u, (1 << e) - 1, l + c, t, g, F.v); const r = p.V(F.v, 0, l, F.C); h = (1 << r) - 1; const i = p.V(F.v, l, c, F.D); d = (1 << i) - 1, b(F.C, r), y(F.C, r, o), b(F.D, i), y(F.D, i, a) } for (; ;) { const e = o[E(t, g) & h]; g += 15 & e; const i = e >>> 4; if (i >>> 8 == 0) r[A++] = i; else { if (256 == i) break; { let e = A + i - 254; if (i > 264) { const r = F.q[i - 257]; e = A + (r >>> 3) + w(t, g, 7 & r), g += 7 & r } const o = a[E(t, g) & d]; g += 15 & o; const s = o >>> 4, f = F.c[s], l = (f >>> 4) + m(t, g, 15 & f); for (g += 15 & f; A < e;) r[A] = r[A++ - l], r[A] = r[A++ - l], r[A] = r[A++ - l], r[A] = r[A++ - l]; A = e } } } } else { 0 != (7 & g) && (g += 8 - (7 & g)); const o = 4 + (g >>> 3), a = t[o - 4] | t[o - 3] << 8; _ && (r = e.H.W(r, A + a)), r.set(new i(t.buffer, t.byteOffset + o, a), A), g = o + a << 3, A += a } return r.length == A ? r : r.slice(0, A) }, e.H.W = function (e, t) { const r = e.length; if (t <= r) return e; const i = new Uint8Array(r << 1); return i.set(e, 0), i }, e.H.R = function (t, r, i, o, a, s) { const f = e.H.e, l = e.H.Z; let c = 0; for (; c < i;) { const e = t[l(o, a) & r]; a += 15 & e; const i = e >>> 4; if (i <= 15) s[c] = i, c++; else { let e = 0, t = 0; 16 == i ? (t = 3 + f(o, a, 2), a += 2, e = s[c - 1]) : 17 == i ? (t = 3 + f(o, a, 3), a += 3) : 18 == i && (t = 11 + f(o, a, 7), a += 7); const r = c + t; for (; c < r;) s[c] = e, c++ } } return a }, e.H.V = function (e, t, r, i) { let o = 0, a = 0; const s = i.length >>> 1; for (; a < r;) { const r = e[a + t]; i[a << 1] = 0, i[1 + (a << 1)] = r, r > o && (o = r), a++ } for (; a < s;) i[a << 1] = 0, i[1 + (a << 1)] = 0, a++; return o }, e.H.n = function (t, r) { const i = e.H.m, o = t.length; let a, s, f; let l; const c = i.j; for (var u = 0; u <= r; u++) c[u] = 0; for (u = 1; u < o; u += 2) c[t[u]]++; const h = i.K; for (a = 0, c[0] = 0, s = 1; s <= r; s++) a = a + c[s - 1] << 1, h[s] = a; for (f = 0; f < o; f += 2) l = t[f + 1], 0 != l && (t[f] = h[l], h[l]++) }, e.H.A = function (t, r, i) { const o = t.length, a = e.H.m.r; for (let e = 0; e < o; e += 2) if (0 != t[e + 1]) { const o = e >> 1, s = t[e + 1], f = o << 4 | s, l = r - s; let c = t[e] << l; const u = c + (1 << l); for (; c != u;) { i[a[c] >>> 15 - r] = f, c++ } } }, e.H.l = function (t, r) { const i = e.H.m.r, o = 15 - r; for (let e = 0; e < t.length; e += 2) { const a = t[e] << r - t[e + 1]; t[e] = i[a] >>> o } }, e.H.M = function (e, t, r) { r <<= 7 & t; const i = t >>> 3; e[i] |= r, e[i + 1] |= r >>> 8 }, e.H.I = function (e, t, r) { r <<= 7 & t; const i = t >>> 3; e[i] |= r, e[i + 1] |= r >>> 8, e[i + 2] |= r >>> 16 }, e.H.e = function (e, t, r) { return (e[t >>> 3] | e[1 + (t >>> 3)] << 8) >>> (7 & t) & (1 << r) - 1 }, e.H.b = function (e, t, r) { return (e[t >>> 3] | e[1 + (t >>> 3)] << 8 | e[2 + (t >>> 3)] << 16) >>> (7 & t) & (1 << r) - 1 }, e.H.Z = function (e, t) { return (e[t >>> 3] | e[1 + (t >>> 3)] << 8 | e[2 + (t >>> 3)] << 16) >>> (7 & t) }, e.H.i = function (e, t) { return (e[t >>> 3] | e[1 + (t >>> 3)] << 8 | e[2 + (t >>> 3)] << 16 | e[3 + (t >>> 3)] << 24) >>> (7 & t) }, e.H.m = function () { const e = Uint16Array, t = Uint32Array; return { K: new e(16), j: new e(16), X: [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15], S: [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 999, 999, 999], T: [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0], q: new e(32), p: [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 65535, 65535], z: [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0], c: new t(32), J: new e(512), _: [], h: new e(32), $: [], w: new e(32768), C: [], v: [], d: new e(32768), D: [], u: new e(512), Q: [], r: new e(32768), s: new t(286), Y: new t(30), a: new t(19), t: new t(15e3), k: new e(65536), g: new e(32768) } }(), function () { const t = e.H.m; for (var r = 0; r < 32768; r++) { let e = r; e = (2863311530 & e) >>> 1 | (1431655765 & e) << 1, e = (3435973836 & e) >>> 2 | (858993459 & e) << 2, e = (4042322160 & e) >>> 4 | (252645135 & e) << 4, e = (4278255360 & e) >>> 8 | (16711935 & e) << 8, t.r[r] = (e >>> 16 | e << 16) >>> 17 } function n (e, t, r) { for (; 0 != t--;) e.push(0, r) } for (r = 0; r < 32; r++) t.q[r] = t.S[r] << 3 | t.T[r], t.c[r] = t.p[r] << 4 | t.z[r]; n(t._, 144, 8), n(t._, 112, 9), n(t._, 24, 7), n(t._, 8, 8), e.H.n(t._, 9), e.H.A(t._, 9, t.J), e.H.l(t._, 9), n(t.$, 32, 5), e.H.n(t.$, 5), e.H.A(t.$, 5, t.h), e.H.l(t.$, 5), n(t.Q, 19, 0), n(t.C, 286, 0), n(t.D, 30, 0), n(t.v, 320, 0) }(), e.H.N }(); function _getBPP (e) { return [1, null, 3, 1, 2, null, 4][e.ctype] * e.depth } function _filterZero (e, t, r, i, o) { let a = _getBPP(t); const s = Math.ceil(i * a / 8); let f, l; a = Math.ceil(a / 8); let c = e[r], u = 0; if (c > 1 && (e[r] = [0, 0, 1][c - 2]), 3 == c) for (u = a; u < s; u++) e[u + 1] = e[u + 1] + (e[u + 1 - a] >>> 1) & 255; for (let t = 0; t < o; t++) if (f = r + t * s, l = f + t + 1, c = e[l - 1], u = 0, 0 == c) for (; u < s; u++) e[f + u] = e[l + u]; else if (1 == c) { for (; u < a; u++) e[f + u] = e[l + u]; for (; u < s; u++) e[f + u] = e[l + u] + e[f + u - a] } else if (2 == c) for (; u < s; u++) e[f + u] = e[l + u] + e[f + u - s]; else if (3 == c) { for (; u < a; u++) e[f + u] = e[l + u] + (e[f + u - s] >>> 1); for (; u < s; u++) e[f + u] = e[l + u] + (e[f + u - s] + e[f + u - a] >>> 1) } else { for (; u < a; u++) e[f + u] = e[l + u] + _paeth(0, e[f + u - s], 0); for (; u < s; u++) e[f + u] = e[l + u] + _paeth(e[f + u - a], e[f + u - s], e[f + u - a - s]) } return e } function _paeth (e, t, r) { const i = e + t - r, o = i - e, a = i - t, s = i - r; return o * o <= a * a && o * o <= s * s ? e : a * a <= s * s ? t : r } function _IHDR (t, r, i) { i.width = e.readUint(t, r), r += 4, i.height = e.readUint(t, r), r += 4, i.depth = t[r], r++, i.ctype = t[r], r++, i.compress = t[r], r++, i.filter = t[r], r++, i.interlace = t[r], r++ } function _copyTile (e, t, r, i, o, a, s, f, l) { const c = Math.min(t, o), u = Math.min(r, a); let h = 0, d = 0; for (let r = 0; r < u; r++) for (let a = 0; a < c; a++) if (s >= 0 && f >= 0 ? (h = r * t + a << 2, d = (f + r) * o + s + a << 2) : (h = (-f + r) * t - s + a << 2, d = r * o + a << 2), 0 == l) i[d] = e[h], i[d + 1] = e[h + 1], i[d + 2] = e[h + 2], i[d + 3] = e[h + 3]; else if (1 == l) { var A = e[h + 3] * (1 / 255), g = e[h] * A, p = e[h + 1] * A, m = e[h + 2] * A, w = i[d + 3] * (1 / 255), v = i[d] * w, b = i[d + 1] * w, y = i[d + 2] * w; const t = 1 - A, r = A + w * t, o = 0 == r ? 0 : 1 / r; i[d + 3] = 255 * r, i[d + 0] = (g + v * t) * o, i[d + 1] = (p + b * t) * o, i[d + 2] = (m + y * t) * o } else if (2 == l) { A = e[h + 3], g = e[h], p = e[h + 1], m = e[h + 2], w = i[d + 3], v = i[d], b = i[d + 1], y = i[d + 2]; A == w && g == v && p == b && m == y ? (i[d] = 0, i[d + 1] = 0, i[d + 2] = 0, i[d + 3] = 0) : (i[d] = g, i[d + 1] = p, i[d + 2] = m, i[d + 3] = A) } else if (3 == l) { A = e[h + 3], g = e[h], p = e[h + 1], m = e[h + 2], w = i[d + 3], v = i[d], b = i[d + 1], y = i[d + 2]; if (A == w && g == v && p == b && m == y) continue; if (A < 220 && w > 20) return !1 } return !0 } return { decode: function decode (r) { const i = new Uint8Array(r); let o = 8; const a = e, s = a.readUshort, f = a.readUint, l = { tabs: {}, frames: [] }, c = new Uint8Array(i.length); let u, h = 0, d = 0; const A = [137, 80, 78, 71, 13, 10, 26, 10]; for (var g = 0; g < 8; g++) if (i[g] != A[g]) throw "The input is not a PNG file!"; for (; o < i.length;) { const e = a.readUint(i, o); o += 4; const r = a.readASCII(i, o, 4); if (o += 4, "IHDR" == r) _IHDR(i, o, l); else if ("iCCP" == r) { for (var p = o; 0 != i[p];) p++; a.readASCII(i, o, p - o), i[p + 1]; const s = i.slice(p + 2, o + e); let f = null; try { f = _inflate(s) } catch (e) { f = t(s) } l.tabs[r] = f } else if ("CgBI" == r) l.tabs[r] = i.slice(o, o + 4); else if ("IDAT" == r) { for (g = 0; g < e; g++) c[h + g] = i[o + g]; h += e } else if ("acTL" == r) l.tabs[r] = { num_frames: f(i, o), num_plays: f(i, o + 4) }, u = new Uint8Array(i.length); else if ("fcTL" == r) { if (0 != d) (E = l.frames[l.frames.length - 1]).data = _decompress(l, u.slice(0, d), E.rect.width, E.rect.height), d = 0; const e = { x: f(i, o + 12), y: f(i, o + 16), width: f(i, o + 4), height: f(i, o + 8) }; let t = s(i, o + 22); t = s(i, o + 20) / (0 == t ? 100 : t); const r = { rect: e, delay: Math.round(1e3 * t), dispose: i[o + 24], blend: i[o + 25] }; l.frames.push(r) } else if ("fdAT" == r) { for (g = 0; g < e - 4; g++) u[d + g] = i[o + g + 4]; d += e - 4 } else if ("pHYs" == r) l.tabs[r] = [a.readUint(i, o), a.readUint(i, o + 4), i[o + 8]]; else if ("cHRM" == r) { l.tabs[r] = []; for (g = 0; g < 8; g++) l.tabs[r].push(a.readUint(i, o + 4 * g)) } else if ("tEXt" == r || "zTXt" == r) { null == l.tabs[r] && (l.tabs[r] = {}); var m = a.nextZero(i, o), w = a.readASCII(i, o, m - o), v = o + e - m - 1; if ("tEXt" == r) y = a.readASCII(i, m + 1, v); else { var b = _inflate(i.slice(m + 2, m + 2 + v)); y = a.readUTF8(b, 0, b.length) } l.tabs[r][w] = y } else if ("iTXt" == r) { null == l.tabs[r] && (l.tabs[r] = {}); m = 0, p = o; m = a.nextZero(i, p); w = a.readASCII(i, p, m - p); const t = i[p = m + 1]; var y; i[p + 1], p += 2, m = a.nextZero(i, p), a.readASCII(i, p, m - p), p = m + 1, m = a.nextZero(i, p), a.readUTF8(i, p, m - p); v = e - ((p = m + 1) - o); if (0 == t) y = a.readUTF8(i, p, v); else { b = _inflate(i.slice(p, p + v)); y = a.readUTF8(b, 0, b.length) } l.tabs[r][w] = y } else if ("PLTE" == r) l.tabs[r] = a.readBytes(i, o, e); else if ("hIST" == r) { const e = l.tabs.PLTE.length / 3; l.tabs[r] = []; for (g = 0; g < e; g++) l.tabs[r].push(s(i, o + 2 * g)) } else if ("tRNS" == r) 3 == l.ctype ? l.tabs[r] = a.readBytes(i, o, e) : 0 == l.ctype ? l.tabs[r] = s(i, o) : 2 == l.ctype && (l.tabs[r] = [s(i, o), s(i, o + 2), s(i, o + 4)]); else if ("gAMA" == r) l.tabs[r] = a.readUint(i, o) / 1e5; else if ("sRGB" == r) l.tabs[r] = i[o]; else if ("bKGD" == r) 0 == l.ctype || 4 == l.ctype ? l.tabs[r] = [s(i, o)] : 2 == l.ctype || 6 == l.ctype ? l.tabs[r] = [s(i, o), s(i, o + 2), s(i, o + 4)] : 3 == l.ctype && (l.tabs[r] = i[o]); else if ("IEND" == r) break; o += e, a.readUint(i, o), o += 4 } var E; return 0 != d && ((E = l.frames[l.frames.length - 1]).data = _decompress(l, u.slice(0, d), E.rect.width, E.rect.height)), l.data = _decompress(l, c, l.width, l.height), delete l.compress, delete l.interlace, delete l.filter, l }, toRGBA8: function toRGBA8 (e) { const t = e.width, r = e.height; if (null == e.tabs.acTL) return [decodeImage(e.data, t, r, e).buffer]; const i = []; null == e.frames[0].data && (e.frames[0].data = e.data); const o = t * r * 4, a = new Uint8Array(o), s = new Uint8Array(o), f = new Uint8Array(o); for (let c = 0; c < e.frames.length; c++) { const u = e.frames[c], h = u.rect.x, d = u.rect.y, A = u.rect.width, g = u.rect.height, p = decodeImage(u.data, A, g, e); if (0 != c) for (var l = 0; l < o; l++) f[l] = a[l]; if (0 == u.blend ? _copyTile(p, A, g, a, t, r, h, d, 0) : 1 == u.blend && _copyTile(p, A, g, a, t, r, h, d, 1), i.push(a.buffer.slice(0)), 0 == u.dispose); else if (1 == u.dispose) _copyTile(s, A, g, a, t, r, h, d, 0); else if (2 == u.dispose) for (l = 0; l < o; l++) a[l] = f[l] } return i }, _paeth: _paeth, _copyTile: _copyTile, _bin: e } }(); !function () { const { _copyTile: e } = UPNG, { _bin: t } = UPNG, r = UPNG._paeth; var i = { table: function () { const e = new Uint32Array(256); for (let t = 0; t < 256; t++) { let r = t; for (let e = 0; e < 8; e++) 1 & r ? r = 3988292384 ^ r >>> 1 : r >>>= 1; e[t] = r } return e }(), update (e, t, r, o) { for (let a = 0; a < o; a++) e = i.table[255 & (e ^ t[r + a])] ^ e >>> 8; return e }, crc: (e, t, r) => 4294967295 ^ i.update(4294967295, e, t, r) }; function addErr (e, t, r, i) { t[r] += e[0] * i >> 4, t[r + 1] += e[1] * i >> 4, t[r + 2] += e[2] * i >> 4, t[r + 3] += e[3] * i >> 4 } function N (e) { return Math.max(0, Math.min(255, e)) } function D (e, t) { const r = e[0] - t[0], i = e[1] - t[1], o = e[2] - t[2], a = e[3] - t[3]; return r * r + i * i + o * o + a * a } function dither (e, t, r, i, o, a, s) { null == s && (s = 1); const f = i.length, l = []; for (var c = 0; c < f; c++) { const e = i[c]; l.push([e >>> 0 & 255, e >>> 8 & 255, e >>> 16 & 255, e >>> 24 & 255]) } for (c = 0; c < f; c++) { let e = 4294967295; for (var u = 0, h = 0; h < f; h++) { var d = D(l[c], l[h]); h != c && d < e && (e = d, u = h) } } const A = new Uint32Array(o.buffer), g = new Int16Array(t * r * 4), p = [0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5]; for (c = 0; c < p.length; c++) p[c] = 255 * ((p[c] + .5) / 16 - .5); for (let o = 0; o < r; o++) for (let w = 0; w < t; w++) { var m; c = 4 * (o * t + w); if (2 != s) m = [N(e[c] + g[c]), N(e[c + 1] + g[c + 1]), N(e[c + 2] + g[c + 2]), N(e[c + 3] + g[c + 3])]; else { d = p[4 * (3 & o) + (3 & w)]; m = [N(e[c] + d), N(e[c + 1] + d), N(e[c + 2] + d), N(e[c + 3] + d)] } u = 0; let v = 16777215; for (h = 0; h < f; h++) { const e = D(m, l[h]); e < v && (v = e, u = h) } const b = l[u], y = [m[0] - b[0], m[1] - b[1], m[2] - b[2], m[3] - b[3]]; 1 == s && (w != t - 1 && addErr(y, g, c + 4, 7), o != r - 1 && (0 != w && addErr(y, g, c + 4 * t - 4, 3), addErr(y, g, c + 4 * t, 5), w != t - 1 && addErr(y, g, c + 4 * t + 4, 1))), a[c >> 2] = u, A[c >> 2] = i[u] } } function _main (e, r, o, a, s) { null == s && (s = {}); const { crc: f } = i, l = t.writeUint, c = t.writeUshort, u = t.writeASCII; let h = 8; const d = e.frames.length > 1; let A, g = !1, p = 33 + (d ? 20 : 0); if (null != s.sRGB && (p += 13), null != s.pHYs && (p += 21), null != s.iCCP && (A = pako.deflate(s.iCCP), p += 21 + A.length + 4), 3 == e.ctype) { for (var m = e.plte.length, w = 0; w < m; w++) e.plte[w] >>> 24 != 255 && (g = !0); p += 8 + 3 * m + 4 + (g ? 8 + 1 * m + 4 : 0) } for (var v = 0; v < e.frames.length; v++) { d && (p += 38), p += (F = e.frames[v]).cimg.length + 12, 0 != v && (p += 4) } p += 12; const b = new Uint8Array(p), y = [137, 80, 78, 71, 13, 10, 26, 10]; for (w = 0; w < 8; w++) b[w] = y[w]; if (l(b, h, 13), h += 4, u(b, h, "IHDR"), h += 4, l(b, h, r), h += 4, l(b, h, o), h += 4, b[h] = e.depth, h++, b[h] = e.ctype, h++, b[h] = 0, h++, b[h] = 0, h++, b[h] = 0, h++, l(b, h, f(b, h - 17, 17)), h += 4, null != s.sRGB && (l(b, h, 1), h += 4, u(b, h, "sRGB"), h += 4, b[h] = s.sRGB, h++, l(b, h, f(b, h - 5, 5)), h += 4), null != s.iCCP) { const e = 13 + A.length; l(b, h, e), h += 4, u(b, h, "iCCP"), h += 4, u(b, h, "ICC profile"), h += 11, h += 2, b.set(A, h), h += A.length, l(b, h, f(b, h - (e + 4), e + 4)), h += 4 } if (null != s.pHYs && (l(b, h, 9), h += 4, u(b, h, "pHYs"), h += 4, l(b, h, s.pHYs[0]), h += 4, l(b, h, s.pHYs[1]), h += 4, b[h] = s.pHYs[2], h++, l(b, h, f(b, h - 13, 13)), h += 4), d && (l(b, h, 8), h += 4, u(b, h, "acTL"), h += 4, l(b, h, e.frames.length), h += 4, l(b, h, null != s.loop ? s.loop : 0), h += 4, l(b, h, f(b, h - 12, 12)), h += 4), 3 == e.ctype) { l(b, h, 3 * (m = e.plte.length)), h += 4, u(b, h, "PLTE"), h += 4; for (w = 0; w < m; w++) { const t = 3 * w, r = e.plte[w], i = 255 & r, o = r >>> 8 & 255, a = r >>> 16 & 255; b[h + t + 0] = i, b[h + t + 1] = o, b[h + t + 2] = a } if (h += 3 * m, l(b, h, f(b, h - 3 * m - 4, 3 * m + 4)), h += 4, g) { l(b, h, m), h += 4, u(b, h, "tRNS"), h += 4; for (w = 0; w < m; w++) b[h + w] = e.plte[w] >>> 24 & 255; h += m, l(b, h, f(b, h - m - 4, m + 4)), h += 4 } } let E = 0; for (v = 0; v < e.frames.length; v++) { var F = e.frames[v]; d && (l(b, h, 26), h += 4, u(b, h, "fcTL"), h += 4, l(b, h, E++), h += 4, l(b, h, F.rect.width), h += 4, l(b, h, F.rect.height), h += 4, l(b, h, F.rect.x), h += 4, l(b, h, F.rect.y), h += 4, c(b, h, a[v]), h += 2, c(b, h, 1e3), h += 2, b[h] = F.dispose, h++, b[h] = F.blend, h++, l(b, h, f(b, h - 30, 30)), h += 4); const t = F.cimg; l(b, h, (m = t.length) + (0 == v ? 0 : 4)), h += 4; const r = h; u(b, h, 0 == v ? "IDAT" : "fdAT"), h += 4, 0 != v && (l(b, h, E++), h += 4), b.set(t, h), h += m, l(b, h, f(b, r, h - r)), h += 4 } return l(b, h, 0), h += 4, u(b, h, "IEND"), h += 4, l(b, h, f(b, h - 4, 4)), h += 4, b.buffer } function compressPNG (e, t, r) { for (let i = 0; i < e.frames.length; i++) { const o = e.frames[i]; o.rect.width; const a = o.rect.height, s = new Uint8Array(a * o.bpl + a); o.cimg = _filterZero(o.img, a, o.bpp, o.bpl, s, t, r) } } function compress (t, r, i, o, a) { const s = a[0], f = a[1], l = a[2], c = a[3], u = a[4], h = a[5]; let d = 6, A = 8, g = 255; for (var p = 0; p < t.length; p++) { const e = new Uint8Array(t[p]); for (var m = e.length, w = 0; w < m; w += 4) g &= e[w + 3] } const v = 255 != g, b = function framize (t, r, i, o, a, s) { const f = []; for (var l = 0; l < t.length; l++) { const h = new Uint8Array(t[l]), A = new Uint32Array(h.buffer); var c; let g = 0, p = 0, m = r, w = i, v = o ? 1 : 0; if (0 != l) { const b = s || o || 1 == l || 0 != f[l - 2].dispose ? 1 : 2; let y = 0, E = 1e9; for (let e = 0; e < b; e++) { var u = new Uint8Array(t[l - 1 - e]); const o = new Uint32Array(t[l - 1 - e]); let s = r, f = i, c = -1, h = -1; for (let e = 0; e < i; e++) for (let t = 0; t < r; t++) { A[d = e * r + t] != o[d] && (t < s && (s = t), t > c && (c = t), e < f && (f = e), e > h && (h = e)) } -1 == c && (s = f = c = h = 0), a && (1 == (1 & s) && s--, 1 == (1 & f) && f--); const v = (c - s + 1) * (h - f + 1); v < E && (E = v, y = e, g = s, p = f, m = c - s + 1, w = h - f + 1) } u = new Uint8Array(t[l - 1 - y]); 1 == y && (f[l - 1].dispose = 2), c = new Uint8Array(m * w * 4), e(u, r, i, c, m, w, -g, -p, 0), v = e(h, r, i, c, m, w, -g, -p, 3) ? 1 : 0, 1 == v ? _prepareDiff(h, r, i, c, { x: g, y: p, width: m, height: w }) : e(h, r, i, c, m, w, -g, -p, 0) } else c = h.slice(0); f.push({ rect: { x: g, y: p, width: m, height: w }, img: c, blend: v, dispose: 0 }) } if (o) for (l = 0; l < f.length; l++) { if (1 == (A = f[l]).blend) continue; const e = A.rect, o = f[l - 1].rect, s = Math.min(e.x, o.x), c = Math.min(e.y, o.y), u = { x: s, y: c, width: Math.max(e.x + e.width, o.x + o.width) - s, height: Math.max(e.y + e.height, o.y + o.height) - c }; f[l - 1].dispose = 1, l - 1 != 0 && _updateFrame(t, r, i, f, l - 1, u, a), _updateFrame(t, r, i, f, l, u, a) } let h = 0; if (1 != t.length) for (var d = 0; d < f.length; d++) { var A; h += (A = f[d]).rect.width * A.rect.height } return f }(t, r, i, s, f, l), y = {}, E = [], F = []; if (0 != o) { const e = []; for (w = 0; w < b.length; w++) e.push(b[w].img.buffer); const t = function concatRGBA (e) { let t = 0; for (var r = 0; r < e.length; r++) t += e[r].byteLength; const i = new Uint8Array(t); let o = 0; for (r = 0; r < e.length; r++) { const t = new Uint8Array(e[r]), a = t.length; for (let e = 0; e < a; e += 4) { let r = t[e], a = t[e + 1], s = t[e + 2]; const f = t[e + 3]; 0 == f && (r = a = s = 0), i[o + e] = r, i[o + e + 1] = a, i[o + e + 2] = s, i[o + e + 3] = f } o += a } return i.buffer }(e), r = quantize(t, o); for (w = 0; w < r.plte.length; w++) E.push(r.plte[w].est.rgba); let i = 0; for (w = 0; w < b.length; w++) { const e = (B = b[w]).img.length; var _ = new Uint8Array(r.inds.buffer, i >> 2, e >> 2); F.push(_); const t = new Uint8Array(r.abuf, i, e); h && dither(B.img, B.rect.width, B.rect.height, E, t, _), B.img.set(t), i += e } } else for (p = 0; p < b.length; p++) { var B = b[p]; const e = new Uint32Array(B.img.buffer); var U = B.rect.width; m = e.length, _ = new Uint8Array(m); F.push(_); for (w = 0; w < m; w++) { const t = e[w]; if (0 != w && t == e[w - 1]) _[w] = _[w - 1]; else if (w > U && t == e[w - U]) _[w] = _[w - U]; else { let e = y[t]; if (null == e && (y[t] = e = E.length, E.push(t), E.length >= 300)) break; _[w] = e } } } const C = E.length; C <= 256 && 0 == u && (A = C <= 2 ? 1 : C <= 4 ? 2 : C <= 16 ? 4 : 8, A = Math.max(A, c)); for (p = 0; p < b.length; p++) { (B = b[p]).rect.x, B.rect.y; U = B.rect.width; const e = B.rect.height; let t = B.img; new Uint32Array(t.buffer); let r = 4 * U, i = 4; if (C <= 256 && 0 == u) { r = Math.ceil(A * U / 8); var I = new Uint8Array(r * e); const o = F[p]; for (let t = 0; t < e; t++) { w = t * r; const e = t * U; if (8 == A) for (var Q = 0; Q < U; Q++) I[w + Q] = o[e + Q]; else if (4 == A) for (Q = 0; Q < U; Q++) I[w + (Q >> 1)] |= o[e + Q] << 4 - 4 * (1 & Q); else if (2 == A) for (Q = 0; Q < U; Q++) I[w + (Q >> 2)] |= o[e + Q] << 6 - 2 * (3 & Q); else if (1 == A) for (Q = 0; Q < U; Q++) I[w + (Q >> 3)] |= o[e + Q] << 7 - 1 * (7 & Q) } t = I, d = 3, i = 1 } else if (0 == v && 1 == b.length) { I = new Uint8Array(U * e * 3); const o = U * e; for (w = 0; w < o; w++) { const e = 3 * w, r = 4 * w; I[e] = t[r], I[e + 1] = t[r + 1], I[e + 2] = t[r + 2] } t = I, d = 2, i = 3, r = 3 * U } B.img = t, B.bpl = r, B.bpp = i } return { ctype: d, depth: A, plte: E, frames: b } } function _updateFrame (t, r, i, o, a, s, f) { const l = Uint8Array, c = Uint32Array, u = new l(t[a - 1]), h = new c(t[a - 1]), d = a + 1 < t.length ? new l(t[a + 1]) : null, A = new l(t[a]), g = new c(A.buffer); let p = r, m = i, w = -1, v = -1; for (let e = 0; e < s.height; e++) for (let t = 0; t < s.width; t++) { const i = s.x + t, f = s.y + e, l = f * r + i, c = g[l]; 0 == c || 0 == o[a - 1].dispose && h[l] == c && (null == d || 0 != d[4 * l + 3]) || (i < p && (p = i), i > w && (w = i), f < m && (m = f), f > v && (v = f)) } -1 == w && (p = m = w = v = 0), f && (1 == (1 & p) && p--, 1 == (1 & m) && m--), s = { x: p, y: m, width: w - p + 1, height: v - m + 1 }; const b = o[a]; b.rect = s, b.blend = 1, b.img = new Uint8Array(s.width * s.height * 4), 0 == o[a - 1].dispose ? (e(u, r, i, b.img, s.width, s.height, -s.x, -s.y, 0), _prepareDiff(A, r, i, b.img, s)) : e(A, r, i, b.img, s.width, s.height, -s.x, -s.y, 0) } function _prepareDiff (t, r, i, o, a) { e(t, r, i, o, a.width, a.height, -a.x, -a.y, 2) } function _filterZero (e, t, r, i, o, a, s) { const f = []; let l, c = [0, 1, 2, 3, 4]; -1 != a ? c = [a] : (t * i > 5e5 || 1 == r) && (c = [0]), s && (l = { level: 0 }); const u = UZIP; for (var h = 0; h < c.length; h++) { for (let a = 0; a < t; a++) _filterLine(o, e, a, i, r, c[h]); f.push(u.deflate(o, l)) } let d, A = 1e9; for (h = 0; h < f.length; h++) f[h].length < A && (d = h, A = f[h].length); return f[d] } function _filterLine (e, t, i, o, a, s) { const f = i * o; let l = f + i; if (e[l] = s, l++, 0 == s) if (o < 500) for (var c = 0; c < o; c++) e[l + c] = t[f + c]; else e.set(new Uint8Array(t.buffer, f, o), l); else if (1 == s) { for (c = 0; c < a; c++) e[l + c] = t[f + c]; for (c = a; c < o; c++) e[l + c] = t[f + c] - t[f + c - a] + 256 & 255 } else if (0 == i) { for (c = 0; c < a; c++) e[l + c] = t[f + c]; if (2 == s) for (c = a; c < o; c++) e[l + c] = t[f + c]; if (3 == s) for (c = a; c < o; c++) e[l + c] = t[f + c] - (t[f + c - a] >> 1) + 256 & 255; if (4 == s) for (c = a; c < o; c++) e[l + c] = t[f + c] - r(t[f + c - a], 0, 0) + 256 & 255 } else { if (2 == s) for (c = 0; c < o; c++) e[l + c] = t[f + c] + 256 - t[f + c - o] & 255; if (3 == s) { for (c = 0; c < a; c++) e[l + c] = t[f + c] + 256 - (t[f + c - o] >> 1) & 255; for (c = a; c < o; c++) e[l + c] = t[f + c] + 256 - (t[f + c - o] + t[f + c - a] >> 1) & 255 } if (4 == s) { for (c = 0; c < a; c++) e[l + c] = t[f + c] + 256 - r(0, t[f + c - o], 0) & 255; for (c = a; c < o; c++) e[l + c] = t[f + c] + 256 - r(t[f + c - a], t[f + c - o], t[f + c - a - o]) & 255 } } } function quantize (e, t) { const r = new Uint8Array(e), i = r.slice(0), o = new Uint32Array(i.buffer), a = getKDtree(i, t), s = a[0], f = a[1], l = r.length, c = new Uint8Array(l >> 2); let u; if (r.length < 2e7) for (var h = 0; h < l; h += 4) { u = getNearest(s, d = r[h] * (1 / 255), A = r[h + 1] * (1 / 255), g = r[h + 2] * (1 / 255), p = r[h + 3] * (1 / 255)), c[h >> 2] = u.ind, o[h >> 2] = u.est.rgba } else for (h = 0; h < l; h += 4) { var d = r[h] * (1 / 255), A = r[h + 1] * (1 / 255), g = r[h + 2] * (1 / 255), p = r[h + 3] * (1 / 255); for (u = s; u.left;) u = planeDst(u.est, d, A, g, p) <= 0 ? u.left : u.right; c[h >> 2] = u.ind, o[h >> 2] = u.est.rgba } return { abuf: i.buffer, inds: c, plte: f } } function getKDtree (e, t, r) { null == r && (r = 1e-4); const i = new Uint32Array(e.buffer), o = { i0: 0, i1: e.length, bst: null, est: null, tdst: 0, left: null, right: null }; o.bst = stats(e, o.i0, o.i1), o.est = estats(o.bst); const a = [o]; for (; a.length < t;) { let t = 0, o = 0; for (var s = 0; s < a.length; s++) a[s].est.L > t && (t = a[s].est.L, o = s); if (t < r) break; const f = a[o], l = splitPixels(e, i, f.i0, f.i1, f.est.e, f.est.eMq255); if (f.i0 >= l || f.i1 <= l) { f.est.L = 0; continue } const c = { i0: f.i0, i1: l, bst: null, est: null, tdst: 0, left: null, right: null }; c.bst = stats(e, c.i0, c.i1), c.est = estats(c.bst); const u = { i0: l, i1: f.i1, bst: null, est: null, tdst: 0, left: null, right: null }; u.bst = { R: [], m: [], N: f.bst.N - c.bst.N }; for (s = 0; s < 16; s++) u.bst.R[s] = f.bst.R[s] - c.bst.R[s]; for (s = 0; s < 4; s++) u.bst.m[s] = f.bst.m[s] - c.bst.m[s]; u.est = estats(u.bst), f.left = c, f.right = u, a[o] = c, a.push(u) } a.sort(((e, t) => t.bst.N - e.bst.N)); for (s = 0; s < a.length; s++) a[s].ind = s; return [o, a] } function getNearest (e, t, r, i, o) { if (null == e.left) return e.tdst = function dist (e, t, r, i, o) { const a = t - e[0], s = r - e[1], f = i - e[2], l = o - e[3]; return a * a + s * s + f * f + l * l }(e.est.q, t, r, i, o), e; const a = planeDst(e.est, t, r, i, o); let s = e.left, f = e.right; a > 0 && (s = e.right, f = e.left); const l = getNearest(s, t, r, i, o); if (l.tdst <= a * a) return l; const c = getNearest(f, t, r, i, o); return c.tdst < l.tdst ? c : l } function planeDst (e, t, r, i, o) { const { e: a } = e; return a[0] * t + a[1] * r + a[2] * i + a[3] * o - e.eMq } function splitPixels (e, t, r, i, o, a) { for (i -= 4; r < i;) { for (; vecDot(e, r, o) <= a;) r += 4; for (; vecDot(e, i, o) > a;) i -= 4; if (r >= i) break; const s = t[r >> 2]; t[r >> 2] = t[i >> 2], t[i >> 2] = s, r += 4, i -= 4 } for (; vecDot(e, r, o) > a;) r -= 4; return r + 4 } function vecDot (e, t, r) { return e[t] * r[0] + e[t + 1] * r[1] + e[t + 2] * r[2] + e[t + 3] * r[3] } function stats (e, t, r) { const i = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], o = [0, 0, 0, 0], a = r - t >> 2; for (let a = t; a < r; a += 4) { const t = e[a] * (1 / 255), r = e[a + 1] * (1 / 255), s = e[a + 2] * (1 / 255), f = e[a + 3] * (1 / 255); o[0] += t, o[1] += r, o[2] += s, o[3] += f, i[0] += t * t, i[1] += t * r, i[2] += t * s, i[3] += t * f, i[5] += r * r, i[6] += r * s, i[7] += r * f, i[10] += s * s, i[11] += s * f, i[15] += f * f } return i[4] = i[1], i[8] = i[2], i[9] = i[6], i[12] = i[3], i[13] = i[7], i[14] = i[11], { R: i, m: o, N: a } } function estats (e) { const { R: t } = e, { m: r } = e, { N: i } = e, a = r[0], s = r[1], f = r[2], l = r[3], c = 0 == i ? 0 : 1 / i, u = [t[0] - a * a * c, t[1] - a * s * c, t[2] - a * f * c, t[3] - a * l * c, t[4] - s * a * c, t[5] - s * s * c, t[6] - s * f * c, t[7] - s * l * c, t[8] - f * a * c, t[9] - f * s * c, t[10] - f * f * c, t[11] - f * l * c, t[12] - l * a * c, t[13] - l * s * c, t[14] - l * f * c, t[15] - l * l * c], h = u, d = o; let A = [Math.random(), Math.random(), Math.random(), Math.random()], g = 0, p = 0; if (0 != i) for (let e = 0; e < 16 && (A = d.multVec(h, A), p = Math.sqrt(d.dot(A, A)), A = d.sml(1 / p, A), !(0 != e && Math.abs(p - g) < 1e-9)); e++) g = p; const m = [a * c, s * c, f * c, l * c]; return { Cov: u, q: m, e: A, L: g, eMq255: d.dot(d.sml(255, m), A), eMq: d.dot(A, m), rgba: (Math.round(255 * m[3]) << 24 | Math.round(255 * m[2]) << 16 | Math.round(255 * m[1]) << 8 | Math.round(255 * m[0]) << 0) >>> 0 } } var o = { multVec: (e, t) => [e[0] * t[0] + e[1] * t[1] + e[2] * t[2] + e[3] * t[3], e[4] * t[0] + e[5] * t[1] + e[6] * t[2] + e[7] * t[3], e[8] * t[0] + e[9] * t[1] + e[10] * t[2] + e[11] * t[3], e[12] * t[0] + e[13] * t[1] + e[14] * t[2] + e[15] * t[3]], dot: (e, t) => e[0] * t[0] + e[1] * t[1] + e[2] * t[2] + e[3] * t[3], sml: (e, t) => [e * t[0], e * t[1], e * t[2], e * t[3]] }; UPNG.encode = function encode (e, t, r, i, o, a, s) { null == i && (i = 0), null == s && (s = !1); const f = compress(e, t, r, i, [!1, !1, !1, 0, s, !1]); return compressPNG(f, -1), _main(f, t, r, o, a) }, UPNG.encodeLL = function encodeLL (e, t, r, i, o, a, s, f) { const l = { ctype: 0 + (1 == i ? 0 : 2) + (0 == o ? 0 : 4), depth: a, frames: [] }, c = (i + o) * a, u = c * t; for (let i = 0; i < e.length; i++) l.frames.push({ rect: { x: 0, y: 0, width: t, height: r }, img: new Uint8Array(e[i]), blend: 0, dispose: 1, bpp: Math.ceil(c / 8), bpl: Math.ceil(u / 8) }); return compressPNG(l, 0, !0), _main(l, t, r, s, f) }, UPNG.encode.compress = compress, UPNG.encode.dither = dither, UPNG.quantize = quantize, UPNG.quantize.getKDtree = getKDtree, UPNG.quantize.getNearest = getNearest }(); const t = { toArrayBuffer (e, r) { const i = e.width, o = e.height, a = i << 2, s = e.getContext("2d").getImageData(0, 0, i, o), f = new Uint32Array(s.data.buffer), l = (32 * i + 31) / 32 << 2, c = l * o, u = 122 + c, h = new ArrayBuffer(u), d = new DataView(h), A = 1 << 20; let g, p, m, w, v = A, b = 0, y = 0, E = 0; function set16 (e) { d.setUint16(y, e, !0), y += 2 } function set32 (e) { d.setUint32(y, e, !0), y += 4 } function seek (e) { y += e } set16(19778), set32(u), seek(4), set32(122), set32(108), set32(i), set32(-o >>> 0), set16(1), set16(32), set32(3), set32(c), set32(2835), set32(2835), seek(8), set32(16711680), set32(65280), set32(255), set32(4278190080), set32(1466527264), function convert () { for (; b < o && v > 0;) { for (w = 122 + b * l, g = 0; g < a;) v--, p = f[E++], m = p >>> 24, d.setUint32(w + g, p << 8 | m), g += 4; b++ } E < f.length ? (v = A, setTimeout(convert, t._dly)) : r(h) }() }, toBlob (e, t) { this.toArrayBuffer(e, (e => { t(new Blob([e], { type: "image/bmp" })) })) }, _dly: 9 }; var r = { CHROME: "CHROME", FIREFOX: "FIREFOX", DESKTOP_SAFARI: "DESKTOP_SAFARI", IE: "IE", IOS: "IOS", ETC: "ETC" }, i = { [r.CHROME]: 16384, [r.FIREFOX]: 11180, [r.DESKTOP_SAFARI]: 16384, [r.IE]: 8192, [r.IOS]: 4096, [r.ETC]: 8192 }; const o = "undefined" != typeof window, a = "undefined" != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope, s = o && window.cordova && window.cordova.require && window.cordova.require("cordova/modulemapper"), CustomFile = (o || a) && (s && s.getOriginalSymbol(window, "File") || "undefined" != typeof File && File), CustomFileReader = (o || a) && (s && s.getOriginalSymbol(window, "FileReader") || "undefined" != typeof FileReader && FileReader); function getFilefromDataUrl (e, t, r = Date.now()) { return new Promise((i => { const o = e.split(","), a = o[0].match(/:(.*?);/)[1], s = globalThis.atob(o[1]); let f = s.length; const l = new Uint8Array(f); for (; f--;) l[f] = s.charCodeAt(f); const c = new Blob([l], { type: a }); c.name = t, c.lastModified = r, i(c) })) } function getDataUrlFromFile (e) { return new Promise(((t, r) => { const i = new CustomFileReader; i.onload = () => t(i.result), i.onerror = e => r(e), i.readAsDataURL(e) })) } function loadImage (e) { return new Promise(((t, r) => { const i = new Image; i.onload = () => t(i), i.onerror = e => r(e), i.src = e })) } function getBrowserName () { if (void 0 !== getBrowserName.cachedResult) return getBrowserName.cachedResult; let e = r.ETC; const { userAgent: t } = navigator; return /Chrom(e|ium)/i.test(t) ? e = r.CHROME : /iP(ad|od|hone)/i.test(t) && /WebKit/i.test(t) ? e = r.IOS : /Safari/i.test(t) ? e = r.DESKTOP_SAFARI : /Firefox/i.test(t) ? e = r.FIREFOX : (/MSIE/i.test(t) || !0 == !!document.documentMode) && (e = r.IE), getBrowserName.cachedResult = e, getBrowserName.cachedResult } function approximateBelowMaximumCanvasSizeOfBrowser (e, t) { const r = getBrowserName(), o = i[r]; let a = e, s = t, f = a * s; const l = a > s ? s / a : a / s; for (; f > o * o;) { const e = (o + a) / 2, t = (o + s) / 2; e < t ? (s = t, a = t * l) : (s = e * l, a = e), f = a * s } return { width: a, height: s } } function getNewCanvasAndCtx (e, t) { let r, i; try { if (r = new OffscreenCanvas(e, t), i = r.getContext("2d"), null === i) throw new Error("getContext of OffscreenCanvas returns null") } catch (e) { r = document.createElement("canvas"), i = r.getContext("2d") } return r.width = e, r.height = t, [r, i] } function drawImageInCanvas (e, t) { const { width: r, height: i } = approximateBelowMaximumCanvasSizeOfBrowser(e.width, e.height), [o, a] = getNewCanvasAndCtx(r, i); return t && /jpe?g/.test(t) && (a.fillStyle = "white", a.fillRect(0, 0, o.width, o.height)), a.drawImage(e, 0, 0, o.width, o.height), o } function isIOS () { return void 0 !== isIOS.cachedResult || (isIOS.cachedResult = ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"].includes(navigator.platform) || navigator.userAgent.includes("Mac") && "undefined" != typeof document && "ontouchend" in document), isIOS.cachedResult } function drawFileInCanvas (e, t = {}) { return new Promise((function (i, o) { let a, s; var $Try_2_Post = function () { try { return s = drawImageInCanvas(a, t.fileType || e.type), i([a, s]) } catch (e) { return o(e) } }, $Try_2_Catch = function (t) { try { 0; var $Try_3_Catch = function (e) { try { throw e } catch (e) { return o(e) } }; try { let t; return getDataUrlFromFile(e).then((function (e) { try { return t = e, loadImage(t).then((function (e) { try { return a = e, function () { try { return $Try_2_Post() } catch (e) { return o(e) } }() } catch (e) { return $Try_3_Catch(e) } }), $Try_3_Catch) } catch (e) { return $Try_3_Catch(e) } }), $Try_3_Catch) } catch (e) { $Try_3_Catch(e) } } catch (e) { return o(e) } }; try { if (isIOS() || [r.DESKTOP_SAFARI, r.MOBILE_SAFARI].includes(getBrowserName())) throw new Error("Skip createImageBitmap on IOS and Safari"); return createImageBitmap(e).then((function (e) { try { return a = e, $Try_2_Post() } catch (e) { return $Try_2_Catch() } }), $Try_2_Catch) } catch (e) { $Try_2_Catch() } })) } function canvasToFile (e, r, i, o, a = 1) { return new Promise((function (s, f) { let l; if ("image/png" === r) { let c, u, h; return c = e.getContext("2d"), ({ data: u } = c.getImageData(0, 0, e.width, e.height)), h = UPNG.encode([u.buffer], e.width, e.height, 4096 * a), l = new Blob([h], { type: r }), l.name = i, l.lastModified = o, $If_4.call(this) } { if ("image/bmp" === r) return new Promise((r => t.toBlob(e, r))).then(function (e) { try { return l = e, l.name = i, l.lastModified = o, $If_5.call(this) } catch (e) { return f(e) } }.bind(this), f); { if ("function" == typeof OffscreenCanvas && e instanceof OffscreenCanvas) return e.convertToBlob({ type: r, quality: a }).then(function (e) { try { return l = e, l.name = i, l.lastModified = o, $If_6.call(this) } catch (e) { return f(e) } }.bind(this), f); { let d; return d = e.toDataURL(r, a), getFilefromDataUrl(d, i, o).then(function (e) { try { return l = e, $If_6.call(this) } catch (e) { return f(e) } }.bind(this), f) } function $If_6 () { return $If_5.call(this) } } function $If_5 () { return $If_4.call(this) } } function $If_4 () { return s(l) } })) } function cleanupCanvasMemory (e) { e.width = 0, e.height = 0 } function isAutoOrientationInBrowser () { return new Promise((function (e, t) { let r, i, o, a, s; return void 0 !== isAutoOrientationInBrowser.cachedResult ? e(isAutoOrientationInBrowser.cachedResult) : (r = "data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==", getFilefromDataUrl("data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==", "test.jpg", Date.now()).then((function (r) { try { return i = r, drawFileInCanvas(i).then((function (r) { try { return o = r[1], canvasToFile(o, i.type, i.name, i.lastModified).then((function (r) { try { return a = r, cleanupCanvasMemory(o), drawFileInCanvas(a).then((function (r) { try { return s = r[0], isAutoOrientationInBrowser.cachedResult = 1 === s.width && 2 === s.height, e(isAutoOrientationInBrowser.cachedResult) } catch (e) { return t(e) } }), t) } catch (e) { return t(e) } }), t) } catch (e) { return t(e) } }), t) } catch (e) { return t(e) } }), t)) })) } function getExifOrientation (e) { return new Promise(((t, r) => { const i = new CustomFileReader; i.onload = e => { const r = new DataView(e.target.result); if (65496 != r.getUint16(0, !1)) return t(-2); const i = r.byteLength; let o = 2; for (; o < i;) { if (r.getUint16(o + 2, !1) <= 8) return t(-1); const e = r.getUint16(o, !1); if (o += 2, 65505 == e) { if (1165519206 != r.getUint32(o += 2, !1)) return t(-1); const e = 18761 == r.getUint16(o += 6, !1); o += r.getUint32(o + 4, e); const i = r.getUint16(o, e); o += 2; for (let a = 0; a < i; a++) if (274 == r.getUint16(o + 12 * a, e)) return t(r.getUint16(o + 12 * a + 8, e)) } else { if (65280 != (65280 & e)) break; o += r.getUint16(o, !1) } } return t(-1) }, i.onerror = e => r(e), i.readAsArrayBuffer(e) })) } function handleMaxWidthOrHeight (e, t) { const { width: r } = e, { height: i } = e, { maxWidthOrHeight: o } = t; let a, s = e; return isFinite(o) && (r > o || i > o) && ([s, a] = getNewCanvasAndCtx(r, i), r > i ? (s.width = o, s.height = i / r * o) : (s.width = r / i * o, s.height = o), a.drawImage(e, 0, 0, s.width, s.height), cleanupCanvasMemory(e)), s } function followExifOrientation (e, t) { const { width: r } = e, { height: i } = e, [o, a] = getNewCanvasAndCtx(r, i); switch (t > 4 && t < 9 ? (o.width = i, o.height = r) : (o.width = r, o.height = i), t) { case 2: a.transform(-1, 0, 0, 1, r, 0); break; case 3: a.transform(-1, 0, 0, -1, r, i); break; case 4: a.transform(1, 0, 0, -1, 0, i); break; case 5: a.transform(0, 1, 1, 0, 0, 0); break; case 6: a.transform(0, 1, -1, 0, i, 0); break; case 7: a.transform(0, -1, -1, 0, i, r); break; case 8: a.transform(0, -1, 1, 0, 0, r) } return a.drawImage(e, 0, 0, r, i), cleanupCanvasMemory(e), o } function compress (e, t, r = 0) { return new Promise((function (i, o) { let a, s, f, l, c, u, h, d, A, g, p, m, w, v, b, y, E, F, _, B; function incProgress (e = 5) { if (t.signal && t.signal.aborted) throw t.signal.reason; a += e, t.onProgress(Math.min(a, 100)) } function setProgress (e) { if (t.signal && t.signal.aborted) throw t.signal.reason; a = Math.min(Math.max(e, a), 100), t.onProgress(a) } return a = r, s = t.maxIteration || 10, f = 1024 * t.maxSizeMB * 1024, incProgress(), drawFileInCanvas(e, t).then(function (r) { try { return [, l] = r, incProgress(), c = handleMaxWidthOrHeight(l, t), incProgress(), new Promise((function (r, i) { var o; if (!(o = t.exifOrientation)) return getExifOrientation(e).then(function (e) { try { return o = e, $If_2.call(this) } catch (e) { return i(e) } }.bind(this), i); function $If_2 () { return r(o) } return $If_2.call(this) })).then(function (r) { try { return u = r, incProgress(), isAutoOrientationInBrowser().then(function (r) { try { return h = r ? c : followExifOrientation(c, u), incProgress(), d = t.initialQuality || 1, A = t.fileType || e.type, canvasToFile(h, A, e.name, e.lastModified, d).then(function (r) { try { { if (g = r, incProgress(), p = g.size > f, m = g.size > e.size, !p && !m) return setProgress(100), i(g); var a; function $Loop_3 () { if (s-- && (b > f || b > w)) { let t, r; return t = B ? .95 * _.width : _.width, r = B ? .95 * _.height : _.height, [E, F] = getNewCanvasAndCtx(t, r), F.drawImage(_, 0, 0, t, r), d *= "image/png" === A ? .85 : .95, canvasToFile(E, A, e.name, e.lastModified, d).then((function (e) { try { return y = e, cleanupCanvasMemory(_), _ = E, b = y.size, setProgress(Math.min(99, Math.floor((v - b) / (v - f) * 100))), $Loop_3 } catch (e) { return o(e) } }), o) } return [1] } return w = e.size, v = g.size, b = v, _ = h, B = !t.alwaysKeepResolution && p, (a = function (e) { for (; e;) { if (e.then) return void e.then(a, o); try { if (e.pop) { if (e.length) return e.pop() ? $Loop_3_exit.call(this) : e; e = $Loop_3 } else e = e.call(this) } catch (e) { return o(e) } } }.bind(this))($Loop_3); function $Loop_3_exit () { return cleanupCanvasMemory(_), cleanupCanvasMemory(E), cleanupCanvasMemory(c), cleanupCanvasMemory(h), cleanupCanvasMemory(l), setProgress(100), i(y) } } } catch (u) { return o(u) } }.bind(this), o) } catch (e) { return o(e) } }.bind(this), o) } catch (e) { return o(e) } }.bind(this), o) } catch (e) { return o(e) } }.bind(this), o) })) } const f = "\nlet scriptImported = false\nself.addEventListener('message', async (e) => {\n const { file, id, imageCompressionLibUrl, options } = e.data\n options.onProgress = (progress) => self.postMessage({ progress, id })\n try {\n if (!scriptImported) {\n // console.log('[worker] importScripts', imageCompressionLibUrl)\n self.importScripts(imageCompressionLibUrl)\n scriptImported = true\n }\n // console.log('[worker] self', self)\n const compressedFile = await imageCompression(file, options)\n self.postMessage({ file: compressedFile, id })\n } catch (e) {\n // console.error('[worker] error', e)\n self.postMessage({ error: e.message + '\\n' + e.stack, id })\n }\n})\n"; let l; function compressOnWebWorker (e, t) { return new Promise(((r, i) => { l || (l = function createWorkerScriptURL (e) { const t = []; return "function" == typeof e ? t.push(`(${e})()`) : t.push(e), URL.createObjectURL(new Blob(t)) }(f)); const o = new Worker(l); o.addEventListener("message", (function handler (e) { if (t.signal && t.signal.aborted) o.terminate(); else if (void 0 === e.data.progress) { if (e.data.error) return i(new Error(e.data.error)), void o.terminate(); r(e.data.file), o.terminate() } else t.onProgress(e.data.progress) })), o.addEventListener("error", i), t.signal && t.signal.addEventListener("abort", (() => { i(t.signal.reason), o.terminate() })), o.postMessage({ file: e, imageCompressionLibUrl: t.libURL, options: { ...t, onProgress: void 0, signal: void 0 } }) })) } function imageCompression (e, t) { return new Promise((function (r, i) { let o, a, s, f, l, c; if (o = { ...t }, s = 0, ({ onProgress: f } = o), o.maxSizeMB = o.maxSizeMB || Number.POSITIVE_INFINITY, l = "boolean" != typeof o.useWebWorker || o.useWebWorker, delete o.useWebWorker, o.onProgress = e => { s = e, "function" == typeof f && f(s) }, !(1 || e instanceof Blob || e instanceof CustomFile)) return i(new Error("The file given is not an instance of Blob or File")); if (!/^image/.test(e.type)) return i(new Error("The file given is not an image")); if (c = "undefined" != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope, !l || "function" != typeof Worker || c) return compress(e, o).then(function (e) { try { return a = e, $If_4.call(this) } catch (e) { return i(e) } }.bind(this), i); var u = function () { try { return $If_4.call(this) } catch (e) { return i(e) } }.bind(this), $Try_1_Catch = function (t) { try { return compress(e, o).then((function (e) { try { return a = e, u() } catch (e) { return i(e) } }), i) } catch (e) { return i(e) } }; try { return o.libURL = o.libURL || "https://cdn.bootcdn.net/ajax/libs/browser-image-compression/2.0.2/browser-image-compression.js", compressOnWebWorker(e, o).then((function (e) { try { return a = e, u() } catch (e) { return $Try_1_Catch() } }), $Try_1_Catch) } catch (e) { $Try_1_Catch() } function $If_4 () { try { a.name = e.name, a.lastModified = e.lastModified } catch (e) { } try { o.preserveExif && "image/jpeg" === e.type && (!o.fileType || o.fileType && o.fileType === e.type) && (a = copyExifWithoutOrientation(e, a)) } catch (e) { } return r(a) } })) } return imageCompression.getDataUrlFromFile = getDataUrlFromFile, imageCompression.getFilefromDataUrl = getFilefromDataUrl, imageCompression.loadImage = loadImage, imageCompression.drawImageInCanvas = drawImageInCanvas, imageCompression.drawFileInCanvas = drawFileInCanvas, imageCompression.canvasToFile = canvasToFile, imageCompression.getExifOrientation = getExifOrientation, imageCompression.handleMaxWidthOrHeight = handleMaxWidthOrHeight, imageCompression.followExifOrientation = followExifOrientation, imageCompression.cleanupCanvasMemory = cleanupCanvasMemory, imageCompression.isAutoOrientationInBrowser = isAutoOrientationInBrowser, imageCompression.approximateBelowMaximumCanvasSizeOfBrowser = approximateBelowMaximumCanvasSizeOfBrowser, imageCompression.copyExifWithoutOrientation = copyExifWithoutOrientation, imageCompression.getBrowserName = getBrowserName, imageCompression.version = "2.0.2", imageCompression })); return { // { // maxSizeMB: number, // (default: Number.POSITIVE_INFINITY) // maxWidthOrHeight: number, // compressedFile will scale down by ratio to a point that width or height is smaller than maxWidthOrHeight (default: undefined) // // but, automatically reduce the size to smaller than the maximum Canvas size supported by each browser. // // Please check the Caveat part for details. // onProgress: Function, // optional, a function takes one progress argument (percentage from 0 to 100) // useWebWorker: boolean, // optional, use multi-thread web worker, fallback to run in main-thread (default: true) // libURL: string, // optional, the libURL of this library for importing script in Web Worker (default: https://cdn.jsdelivr.net/npm/browser-image-compression/dist/browser-image-compression.js) // preserveExif: boolean, // optional, use preserve Exif metadata for JPEG image e.g., Camera model, Focal length, etc (default: false) // // signal: AbortSignal, // optional, to abort / cancel the compression // // // following options are for advanced users // maxIteration: number, // optional, max number of iteration to compress the image (default: 10) // exifOrientation: number, // optional, see https://stackoverflow.com/a/32490603/10395024 // fileType: string, // optional, fileType override e.g., 'image/jpeg', 'image/png' (default: file.type) // initialQuality: number, // optional, initial quality value between 0 and 1 (default: 1) // alwaysKeepResolution: boolean // optional, only reduce quality, always keep width and height (default: false) // } compress: function (file, option) { return imageCompression(file, option); } }; })(); // core/dialog.js UE.dialog = (function () { return { loadingPlaceholder: function (me) { var loadingId = "loading_" + (+new Date()).toString(36); me.focus(); me.execCommand( "inserthtml", '' ); return loadingId; }, removeLoadingPlaceholder: function (me, loadingId) { var loader = me.document.getElementById(loadingId); if (loader) { domUtils.remove(loader, false); } }, tipError: function (me, title) { me.fireEvent("showmessage", { content: title, type: "error", timeout: 4000 }); } } })(); // core/filterword.js /** * UE过滤word的静态方法 * @file */ /** * UEditor公用空间,UEditor所有的功能都挂载在该空间下 * @module UE */ /** * 根据传入html字符串过滤word * @module UE * @since 1.2.6.1 * @method filterWord * @param { String } html html字符串 * @return { String } 已过滤后的结果字符串 * @example * ```javascript * UE.filterWord(html); * ``` */ var filterWord = (UE.filterWord = (function () { //是否是word过来的内容 function isWordDocument (str) { return /(class="?Mso|style="[^"]*\bmso\-|w:WordDocument|<(v|o):|lang=)/gi.test( str ); } //去掉小数 function transUnit (v) { v = v.replace(/[\d.]+\w+/g, function (m) { return utils.transUnitToPx(m); }); return v; } function filterPasteWord (str) { return ( str .replace(/[\t\r\n]+/g, " ") .replace(//gi, "") //转换图片 .replace(/]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi, "
$1
" ) //去掉多余的属性 .replace(/\s+(class|lang|align)\s*=\s*(['"]?)([\w-]+)\2/gi, function ( str, name, marks, val ) { //保留list的标示 return name == "class" && val == "MsoListParagraph" ? str : ""; }) //清除多余的font/span不能匹配 有可能是空格 .replace(/<(font|span)[^>]*>(\s*)<\/\1>/gi, function (a, b, c) { return c.replace(/[\t\r\n ]+/g, " "); }) //处理style的问题 .replace(/(<[a-z][^>]*)\sstyle=(["'])([^\2]*?)\2/gi, function ( str, tag, tmp, style ) { var n = [], s = style .replace(/^\s+|\s+$/, "") .replace(/'/g, "'") .replace(/"/gi, "'") .replace(/[\d.]+(cm|pt)/g, function (str) { return utils.transUnitToPx(str); }) .split(/;\s*/g); for (var i = 0, v; (v = s[i]); i++) { var name, value, parts = v.split(":"); if (parts.length == 2) { name = parts[0].toLowerCase(); value = parts[1].toLowerCase(); if ( (/^(background)\w*/.test(name) && value.replace(/(initial|\s)/g, "").length == 0) || (/^(margin)\w*/.test(name) && /^0\w+$/.test(value)) ) { continue; } switch (name) { case "mso-padding-alt": case "mso-padding-top-alt": case "mso-padding-right-alt": case "mso-padding-bottom-alt": case "mso-padding-left-alt": case "mso-margin-alt": case "mso-margin-top-alt": case "mso-margin-right-alt": case "mso-margin-bottom-alt": case "mso-margin-left-alt": //ie下会出现挤到一起的情况 //case "mso-table-layout-alt": case "mso-height": case "mso-width": case "mso-vertical-align-alt": //trace:1819 ff下会解析出padding在table上 if (!/ 这样的标签了
//先去掉了,加上的原因忘了,这里先记录
//var re_tag = /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\s\/<>]+)\s*((?:(?:"[^"]*")|(?:'[^']*')|[^"'<>])*)\/?>))/g,
//以上的正则表达式无法匹配: "); } break; case "div": if (node.getAttr("cdata_tag")) { break; } //针对代码这里不处理插入代码的div val = node.getAttr("class"); if (val && /^line number\d+/.test(val)) { break; } if (!allowDivTransToP) { break; } var tmpNode, p = UE.uNode.createElement("p"); while ((tmpNode = node.firstChild())) { if ( tmpNode.type == "text" || !UE.dom.dtd.$block[tmpNode.tagName] ) { p.appendChild(tmpNode); } else { if (p.firstChild()) { node.parentNode.insertBefore(p, node); p = UE.uNode.createElement("p"); } else { node.parentNode.insertBefore(tmpNode, node); } } } if (p.firstChild()) { node.parentNode.insertBefore(p, node); } node.parentNode.removeChild(node); break; case "dl": node.tagName = "ul"; break; case "dt": case "dd": node.tagName = "li"; break; case "li": var className = node.getAttr("class"); if (!className || !/list\-/.test(className)) { node.setAttr(); } var tmpNodes = node.getNodesByTagName("ol ul"); UE.utils.each(tmpNodes, function (n) { node.parentNode.insertAfter(n, node); }); break; case "td": case "th": case "caption": if (!node.children || !node.children.length) { node.appendChild( browser.ie11below ? UE.uNode.createText(" ") : UE.uNode.createElement("br") ); } break; case "table": if (me.options.disabledTableInTable && tdParent(node)) { node.parentNode.insertBefore( UE.uNode.createText(node.innerText()), node ); node.parentNode.removeChild(node); } } } // if(node.type == 'comment'){ // node.parentNode.removeChild(node); // } }); }); //从编辑器出去的内容处理 me.addOutputRule(function (root) { var val; root.traversal(function (node) { if (node.type == "element") { if ( me.options.autoClearEmptyNode && dtd.$inline[node.tagName] && !dtd.$empty[node.tagName] && (!node.attrs || utils.isEmptyObject(node.attrs)) ) { if (!node.firstChild()) node.parentNode.removeChild(node); else if ( node.tagName == "span" && (!node.attrs || utils.isEmptyObject(node.attrs)) ) { node.parentNode.removeChild(node, true); } return; } switch (node.tagName) { case "div": if ((val = node.getAttr("cdata_tag"))) { node.tagName = val; node.appendChild(UE.uNode.createText(node.getAttr("cdata_data"))); node.setAttr({ cdata_tag: "", cdata_data: "", _ue_custom_node_: "" }); } break; case "a": if ((val = node.getAttr("_href"))) { node.setAttr({ href: utils.html(val), _href: "" }); } break; break; case "span": val = node.getAttr("id"); if (val && /^_baidu_bookmark_/i.test(val)) { node.parentNode.removeChild(node); } //将color的rgb格式转换为#16进制格式 if (me.getOpt("rgb2Hex")) { var cssStyle = node.getAttr("style"); if (cssStyle) { node.setAttr( "style", cssStyle.replace(/rgba?\(([\d,\s]+)\)/g, function (a, value) { var array = value.split(","); if (array.length > 3) return ""; value = "#"; for (var i = 0, color; (color = array[i++]);) { color = parseInt( color.replace(/[^\d]/gi, ""), 10 ).toString(16); value += color.length == 1 ? "0" + color : color; } return value.toUpperCase(); }) ); } } break; case "img": if ((val = node.getAttr("_src"))) { node.setAttr({ src: node.getAttr("_src"), _src: "" }); } } } }); }); }; // plugins/inserthtml.js /** * 插入html字符串插件 * @file * @since 1.2.6.1 */ /** * 插入html代码 * @command inserthtml * @method execCommand * @param { String } cmd 命令字符串 * @param { String } html 插入的html字符串 * @remaind 插入的标签内容是在当前的选区位置上插入,如果当前是闭合状态,那直接插入内容, 如果当前是选中状态,将先清除当前选中内容后,再做插入 * @warning 注意:该命令会对当前选区的位置,对插入的内容进行过滤转换处理。 过滤的规则遵循html语意化的原则。 * @example * ```javascript * //xxx[BB]xxx 当前选区为非闭合选区,选中BB这两个文本 * //执行命令,插入CC * //插入后的效果 xxxCCxxx * // xx|xxx 当前选区为闭合状态 * //插入CC * //结果xx CC xxx * //xxxx |xxx 当前选区在两个p标签之间 * //插入 xxxx * //结果xxxx xxxx xxx * ``` */ UE.commands["inserthtml"] = { execCommand: function (command, html, notNeedFilter) { var me = this, range, div; if (!html) { return; } if (me.fireEvent("beforeinserthtml", html) === true) { return; } range = me.selection.getRange(); div = range.document.createElement("div"); div.style.display = "inline"; if (!notNeedFilter) { var root = UE.htmlparser(html); //如果给了过滤规则就先进行过滤 if (me.options.filterRules) { UE.filterNode(root, me.options.filterRules); } //执行默认的处理 me.filterInputRule(root); html = root.toHtml(); } div.innerHTML = utils.trim(html); if (!range.collapsed) { var tmpNode = range.startContainer; if (domUtils.isFillChar(tmpNode)) { range.setStartBefore(tmpNode); } tmpNode = range.endContainer; if (domUtils.isFillChar(tmpNode)) { range.setEndAfter(tmpNode); } range.txtToElmBoundary(); //结束边界可能放到了br的前边,要把br包含进来 // x[xxx]if (range.endContainer && range.endContainer.nodeType == 1) { tmpNode = range.endContainer.childNodes[range.endOffset]; if (tmpNode && domUtils.isBr(tmpNode)) { range.setEndAfter(tmpNode); } } if (range.startOffset == 0) { tmpNode = range.startContainer; if (domUtils.isBoundaryNode(tmpNode, "firstChild")) { tmpNode = range.endContainer; if ( range.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode, "lastChild") ) { me.body.innerHTML = " " + (browser.ie ? "" : " |<[p> ==> | var pre = child.previousSibling; domUtils.trimWhiteTextNode(pre); if (!pre.childNodes.length) { domUtils.remove(pre); } //trace:2012,在非ie的情况,切开后剩下的节点有可能不能点入光标添加br占位 if ( !browser.ie && (next = child.nextSibling) && domUtils.isBlockElm(next) && next.lastChild && !domUtils.isBr(next.lastChild) ) { next.appendChild(me.document.createElement("br")); } hadBreak = 1; } } var next = child.nextSibling; if (!div.firstChild && next && domUtils.isBlockElm(next)) { range.setStart(next, 0).collapse(true); break; } range.setEndAfter(child).collapse(); } child = range.startContainer; if (nextNode && domUtils.isBr(nextNode)) { domUtils.remove(nextNode); } //用chrome可能有空白展位符 if (domUtils.isBlockElm(child) && domUtils.isEmptyNode(child)) { if ((nextNode = child.nextSibling)) { domUtils.remove(child); if (nextNode.nodeType == 1 && dtd.$block[nextNode.tagName]) { range.setStart(nextNode, 0).collapse(true).shrinkBoundary(); } } else { try { child.innerHTML = browser.ie ? domUtils.fillChar : ""; } catch (e) { range.setStartBefore(child); domUtils.remove(child); } } } //加上true因为在删除表情等时会删两次,第一次是删的fillData try { range.select(true); } catch (e) { } } setTimeout(function () { range = me.selection.getRange(); range.scrollToView( me.autoHeightEnabled, me.autoHeightEnabled ? domUtils.getXY(me.iframe).y : 0 ); me.fireEvent("afterinserthtml", html); }, 200); } }; // plugins/autotypeset.js /** * 自动排版 * @file * @since 1.2.6.1 */ /** * 对当前编辑器的内容执行自动排版, 排版的行为根据config配置文件里的“autotypeset”选项进行控制。 * @command autotypeset * @method execCommand * @param { String } cmd 命令字符串 * @example * ```javascript * editor.execCommand( 'autotypeset' ); * ``` */ UE.plugins["autotypeset"] = function () { this.setOpt({ // 自动排版参数 autotypeset: { // 合并空行 mergeEmptyline: true, // 去掉冗余的class removeClass: true, // 去掉空行 removeEmptyline: false, // 段落的排版方式,可以是 left,right,center,justify 去掉这个属性表示不执行排版 textAlign: "left", // 图片的浮动方式,独占一行剧中,左右浮动,默认: center,left,right,none 去掉这个属性表示不执行排版 imageBlockLine: "center", // 根据规则过滤没事粘贴进来的内容 pasteFilter: false, // 去掉所有的内嵌字号,使用编辑器默认的字号 clearFontSize: false, // 去掉所有的内嵌字体,使用编辑器默认的字体 clearFontFamily: false, // 去掉空节点 removeEmptyNode: false, // 可以去掉的标签 removeTagNames: utils.extend({ div: 1 }, dtd.$removeEmpty), // 行首缩进 indent: false, // 行首缩进的大小 indentValue: "2em", // 全角转半角 bdc2sb: false, // 半角转全角 tobdc: false } }); var me = this, opt = me.options.autotypeset, remainClass = { selectTdClass: 1, pagebreak: 1, anchorclass: 1 }, remainTag = { li: 1 }, tags = { div: 1, p: 1, //trace:2183 这些也认为是行 blockquote: 1, center: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, span: 1 }, highlightCont; //升级了版本,但配置项目里没有autotypeset if (!opt) { return; } readLocalOpts(); function isLine (node, notEmpty) { if (!node || node.nodeType == 3) return 0; if (domUtils.isBr(node)) return 1; if (node && node.parentNode && tags[node.tagName.toLowerCase()]) { if ( (highlightCont && highlightCont.contains(node)) || node.getAttribute("pagebreak") ) { return 0; } return notEmpty ? !domUtils.isEmptyBlock(node) : domUtils.isEmptyBlock( node, new RegExp("[\\s" + domUtils.fillChar + "]", "g") ); } } function removeNotAttributeSpan (node) { if (!node.style.cssText) { domUtils.removeAttributes(node, ["style"]); if ( node.tagName.toLowerCase() == "span" && domUtils.hasNoAttributes(node) ) { domUtils.remove(node, true); } } } function autotype (type, html) { var me = this, cont; if (html) { if (!opt.pasteFilter) { return; } cont = me.document.createElement("div"); cont.innerHTML = html.html; } else { cont = me.document.body; } var nodes = domUtils.getElementsByTagName(cont, "*"); // 行首缩进,段落方向,段间距,段内间距 for (var i = 0, ci; (ci = nodes[i++]);) { if (me.fireEvent("excludeNodeinautotype", ci) === true) { continue; } //font-size if (opt.clearFontSize && ci.style.fontSize) { domUtils.removeStyle(ci, "font-size"); removeNotAttributeSpan(ci); } //font-family if (opt.clearFontFamily && ci.style.fontFamily) { domUtils.removeStyle(ci, "font-family"); removeNotAttributeSpan(ci); } if (isLine(ci)) { //合并空行 if (opt.mergeEmptyline) { var next = ci.nextSibling, tmpNode, isBr = domUtils.isBr(ci); while (isLine(next)) { tmpNode = next; next = tmpNode.nextSibling; if (isBr && (!next || (next && !domUtils.isBr(next)))) { break; } domUtils.remove(tmpNode); } } //去掉空行,保留占位的空行 if ( opt.removeEmptyline && domUtils.inDoc(ci, cont) && !remainTag[ci.parentNode.tagName.toLowerCase()] ) { if (domUtils.isBr(ci)) { next = ci.nextSibling; if (next && !domUtils.isBr(next)) { continue; } } domUtils.remove(ci); continue; } } if (isLine(ci, true) && ci.tagName != "SPAN") { if (opt.indent) { ci.style.textIndent = opt.indentValue; } if (opt.textAlign) { ci.style.textAlign = opt.textAlign; } // if(opt.lineHeight) // ci.style.lineHeight = opt.lineHeight + 'cm'; } //去掉class,保留的class不去掉 if ( opt.removeClass && ci.className && !remainClass[ci.className.toLowerCase()] ) { if (highlightCont && highlightCont.contains(ci)) { continue; } domUtils.removeAttributes(ci, ["class"]); } //表情不处理 if ( opt.imageBlockLine && ci.tagName.toLowerCase() == "img" && !ci.getAttribute("emotion") ) { if (html) { var img = ci; switch (opt.imageBlockLine) { case "left": case "right": case "none": var pN = img.parentNode, tmpNode, pre, next; while (dtd.$inline[pN.tagName] || pN.tagName == "A") { pN = pN.parentNode; } tmpNode = pN; if ( tmpNode.tagName == "P" && domUtils.getStyle(tmpNode, "text-align") == "center" ) { if ( !domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode, function (node) { return !domUtils.isBr(node) && !domUtils.isWhitespace(node); }) == 1 ) { pre = tmpNode.previousSibling; next = tmpNode.nextSibling; if ( pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre) ) { pre.appendChild(tmpNode.firstChild); while (next.firstChild) { pre.appendChild(next.firstChild); } domUtils.remove(tmpNode); domUtils.remove(next); } else { domUtils.setStyle(tmpNode, "text-align", ""); } } } domUtils.setStyle(img, "float", opt.imageBlockLine); break; case "center": if (me.queryCommandValue("imagefloat") != "center") { pN = img.parentNode; domUtils.setStyle(img, "float", "none"); tmpNode = img; while ( pN && domUtils.getChildCount(pN, function (node) { return !domUtils.isBr(node) && !domUtils.isWhitespace(node); }) == 1 && (dtd.$inline[pN.tagName] || pN.tagName == "A") ) { tmpNode = pN; pN = pN.parentNode; } var pNode = me.document.createElement("p"); domUtils.setAttributes(pNode, { style: "text-align:center" }); tmpNode.parentNode.insertBefore(pNode, tmpNode); pNode.appendChild(tmpNode); domUtils.setStyle(tmpNode, "float", ""); } } } else { var range = me.selection.getRange(); range.selectNode(ci).select(); me.execCommand("imagefloat", opt.imageBlockLine); } } //去掉冗余的标签 if (opt.removeEmptyNode) { if ( opt.removeTagNames[ci.tagName.toLowerCase()] && domUtils.hasNoAttributes(ci) && domUtils.isEmptyBlock(ci) ) { domUtils.remove(ci); } } } if (opt.tobdc) { var root = UE.htmlparser(cont.innerHTML); root.traversal(function (node) { if (node.type == "text") { node.data = ToDBC(node.data); } }); cont.innerHTML = root.toHtml(); } if (opt.bdc2sb) { var root = UE.htmlparser(cont.innerHTML); root.traversal(function (node) { if (node.type == "text") { node.data = DBC2SB(node.data); } }); cont.innerHTML = root.toHtml(); } if (html) { html.html = cont.innerHTML; } } if (opt.pasteFilter) { me.addListener("beforepaste", autotype); } function DBC2SB (str) { var result = ""; for (var i = 0; i < str.length; i++) { var code = str.charCodeAt(i); //获取当前字符的unicode编码 if (code >= 65281 && code <= 65373) { //在这个unicode编码范围中的是所有的英文字母已经各种字符 result += String.fromCharCode(str.charCodeAt(i) - 65248); //把全角字符的unicode编码转换为对应半角字符的unicode码 } else if (code == 12288) { //空格 result += String.fromCharCode(str.charCodeAt(i) - 12288 + 32); } else { result += str.charAt(i); } } return result; } function ToDBC (txtstring) { txtstring = utils.html(txtstring); var tmp = ""; var mark = ""; /*用于判断,如果是html尖括里的标记,则不进行全角的转换*/ for (var i = 0; i < txtstring.length; i++) { if (txtstring.charCodeAt(i) == 32) { tmp = tmp + String.fromCharCode(12288); } else if (txtstring.charCodeAt(i) < 127) { tmp = tmp + String.fromCharCode(txtstring.charCodeAt(i) + 65248); } else { tmp += txtstring.charAt(i); } } return tmp; } function readLocalOpts () { var cookieOpt = me.getPreferences("autotypeset"); utils.extend(me.options.autotypeset, cookieOpt); } me.commands["autotypeset"] = { execCommand: function () { me.removeListener("beforepaste", autotype); if (opt.pasteFilter) { me.addListener("beforepaste", autotype); } autotype.call(me); } }; }; // plugins/autosubmit.js /** * 快捷键提交 * @file * @since 1.2.6.1 */ /** * 提交表单 * @command autosubmit * @method execCommand * @param { String } cmd 命令字符串 * @example * ```javascript * editor.execCommand( 'autosubmit' ); * ``` */ UE.plugin.register("autosubmit", function () { return { shortcutkey: { autosubmit: "ctrl+13" //手动提交 }, commands: { autosubmit: { execCommand: function () { var me = this, form = domUtils.findParentByTagName(me.iframe, "form", false); if (form) { if (me.fireEvent("beforesubmit") === false) { return; } me.sync(); form.submit(); } } } } }; }); // plugins/background.js /** * 背景插件,为UEditor提供设置背景功能 * @file * @since 1.2.6.1 */ UE.plugin.register("background", function () { var me = this, cssRuleId = "editor_background", isSetColored, reg = new RegExp("body[\\s]*\\{(.+)\\}", "i"); function stringToObj (str) { var obj = {}, styles = str.split(";"); utils.each(styles, function (v) { var index = v.indexOf(":"), key = utils.trim(v.substr(0, index)).toLowerCase(); key && (obj[key] = utils.trim(v.substr(index + 1) || "")); }); return obj; } function setBackground (obj) { if (obj) { var styles = []; for (var name in obj) { if (obj.hasOwnProperty(name)) { styles.push(name + ":" + obj[name] + "; "); } } utils.cssRule( cssRuleId, styles.length ? "body{" + styles.join("") + "}" : "", me.document ); } else { utils.cssRule(cssRuleId, "", me.document); } } //重写editor.hasContent方法 var orgFn = me.hasContents; me.hasContents = function () { if (me.queryCommandValue("background")) { return true; } return orgFn.apply(me, arguments); }; return { bindEvents: { getAllHtml: function (type, headHtml) { var body = this.body, su = domUtils.getComputedStyle(body, "background-image"), url = ""; if (su.indexOf(me.options.imagePath) > 0) { url = su .substring(su.indexOf(me.options.imagePath), su.length - 1) .replace(/"|\(|\)/gi, ""); } else { url = su != "none" ? su.replace(/url\("?|"?\)/gi, "") : ""; } var html = ' "; headHtml.push(html); }, aftersetcontent: function () { if (isSetColored == false) setBackground(); } }, inputRule: function (root) { isSetColored = false; utils.each(root.getNodesByTagName("p"), function (p) { var styles = p.getAttr("data-background"); if (styles) { isSetColored = true; setBackground(stringToObj(styles)); p.parentNode.removeChild(p); } }); }, outputRule: function (root) { var me = this, styles = (utils.cssRule(cssRuleId, me.document) || "") .replace(/[\n\r]+/g, "") .match(reg); if (styles) { root.appendChild( UE.uNode.createElement( ' ' ) ); } }, commands: { background: { execCommand: function (cmd, obj) { setBackground(obj); }, queryCommandValue: function () { var me = this, styles = (utils.cssRule(cssRuleId, me.document) || "") .replace(/[\n\r]+/g, "") .match(reg); return styles ? stringToObj(styles[1]) : null; }, notNeedUndo: true } } }; }); // plugins/image.js /** * 图片插入、排版插件 * @file * @since 1.2.6.1 */ /** * 图片对齐方式 * @command imagefloat * @method execCommand * @remind 值center为独占一行居中 * @param { String } cmd 命令字符串 * @param { String } align 对齐方式,可传left、right、none、center * @remaind center表示图片独占一行 * @example * ```javascript * editor.execCommand( 'imagefloat', 'center' ); * ``` */ /** * 如果选区所在位置是图片区域 * @command imagefloat * @method queryCommandValue * @param { String } cmd 命令字符串 * @return { String } 返回图片对齐方式 * @example * ```javascript * editor.queryCommandValue( 'imagefloat' ); * ``` */ UE.commands["imagefloat"] = { execCommand: function (cmd, align) { var me = this, range = me.selection.getRange(); if (!range.collapsed) { var img = range.getClosedNode(); if (img && img.tagName === "IMG") { switch (align) { case "left": case "right": case "none": var pN = img.parentNode, tmpNode, pre, next; while (dtd.$inline[pN.tagName] || pN.tagName == "A") { pN = pN.parentNode; } tmpNode = pN; if ( tmpNode.tagName == "P" && domUtils.getStyle(tmpNode, "text-align") == "center" ) { if ( !domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode, function (node) { return !domUtils.isBr(node) && !domUtils.isWhitespace(node); }) == 1 ) { pre = tmpNode.previousSibling; next = tmpNode.nextSibling; if ( pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre) ) { pre.appendChild(tmpNode.firstChild); while (next.firstChild) { pre.appendChild(next.firstChild); } domUtils.remove(tmpNode); domUtils.remove(next); } else { domUtils.setStyle(tmpNode, "text-align", ""); } } range.selectNode(img).select(); } domUtils.setStyle(img, "float", align == "none" ? "" : align); if (align == "none") { domUtils.removeAttributes(img, "align"); } break; case "center": if (me.queryCommandValue("imagefloat") != "center") { pN = img.parentNode; domUtils.setStyle(img, "float", ""); domUtils.removeAttributes(img, "align"); tmpNode = img; while ( pN && domUtils.getChildCount(pN, function (node) { return !domUtils.isBr(node) && !domUtils.isWhitespace(node); }) == 1 && (dtd.$inline[pN.tagName] || pN.tagName == "A") ) { tmpNode = pN; pN = pN.parentNode; } range.setStartBefore(tmpNode).setCursor(false); pN = me.document.createElement("div"); pN.appendChild(tmpNode); domUtils.setStyle(tmpNode, "float", ""); me.execCommand( "insertHtml", ' ' + pN.innerHTML + " " ); tmpNode = me.document.getElementById("_img_parent_tmp"); tmpNode.removeAttribute("id"); tmpNode = tmpNode.firstChild; range.selectNode(tmpNode).select(); //去掉后边多余的元素 next = tmpNode.parentNode.nextSibling; if (next && domUtils.isEmptyNode(next)) { domUtils.remove(next); } } break; } } } }, queryCommandValue: function () { var range = this.selection.getRange(), startNode, floatStyle; if (range.collapsed) { return "none"; } startNode = range.getClosedNode(); if (startNode && startNode.nodeType == 1 && startNode.tagName == "IMG") { floatStyle = domUtils.getComputedStyle(startNode, "float") || startNode.getAttribute("align"); if (floatStyle == "none") { floatStyle = domUtils.getComputedStyle( startNode.parentNode, "text-align" ) == "center" ? "center" : floatStyle; } return { left: 1, right: 1, center: 1 }[floatStyle] ? floatStyle : "none"; } return "none"; }, queryCommandState: function () { var range = this.selection.getRange(), startNode; if (range.collapsed) return -1; startNode = range.getClosedNode(); if (startNode && startNode.nodeType === 1 && startNode.tagName === "IMG") { return 0; } return -1; } }; /** * 插入图片 * @command insertimage * @method execCommand * @param { String } cmd 命令字符串 * @param { Object } opt 属性键值对,这些属性都将被复制到当前插入图片 * @remind 该命令第二个参数可接受一个图片配置项对象的数组,可以插入多张图片, * 此时数组的每一个元素都是一个Object类型的图片属性集合。 * @example * ```javascript * editor.execCommand( 'insertimage', { * src:'a/b/c.jpg', * width:'100', * height:'100' * } ); * ``` * @example * ```javascript * editor.execCommand( 'insertimage', [{ * src:'a/b/c.jpg', * width:'100', * height:'100' * },{ * src:'a/b/d.jpg', * width:'100', * height:'100' * }] ); * ``` */ UE.commands["insertimage"] = { execCommand: function (cmd, opt) { opt = utils.isArray(opt) ? opt : [opt]; if (!opt.length) { return; } var me = this, range = me.selection.getRange(), img = range.getClosedNode(); if (me.fireEvent("beforeinsertimage", opt) === true) { return; } if ( img && /img/i.test(img.tagName) && (img.className != "edui-faked-video" || img.className.indexOf("edui-upload-video") != -1) && !img.getAttribute("data-word-image") ) { var first = opt.shift(); var floatStyle = first["floatStyle"]; delete first["floatStyle"]; //// img.style.border = (first.border||0) +"px solid #000"; //// img.style.margin = (first.margin||0) +"px"; // img.style.cssText += ';margin:' + (first.margin||0) +"px;" + 'border:' + (first.border||0) +"px solid #000"; domUtils.setAttributes(img, first); me.execCommand("imagefloat", floatStyle); if (opt.length > 0) { range.setStartAfter(img).setCursor(false, true); me.execCommand("insertimage", opt); } } else { var html = [], str = "", ci; ci = opt[0]; if (opt.length == 1) { str = '"; if (ci["floatStyle"] == "center") { str = '' + str + " "; } html.push(str); } else { for (var i = 0; (ci = opt[i++]);) { str = ""; html.push(str); } } me.execCommand("insertHtml", html.join("")); } me.fireEvent("afterinsertimage", opt); } }; // plugins/justify.js /** * 段落格式 * @file * @since 1.2.6.1 */ /** * 段落对齐方式 * @command justify * @method execCommand * @param { String } cmd 命令字符串 * @param { String } align 对齐方式:left => 居左,right => 居右,center => 居中,justify => 两端对齐 * @example * ```javascript * editor.execCommand( 'justify', 'center' ); * ``` */ /** * 如果选区所在位置是段落区域,返回当前段落对齐方式 * @command justify * @method queryCommandValue * @param { String } cmd 命令字符串 * @return { String } 返回段落对齐方式 * @example * ```javascript * editor.queryCommandValue( 'justify' ); * ``` */ UE.plugins["justify"] = function () { var me = this, block = domUtils.isBlockElm, defaultValue = { left: 1, right: 1, center: 1, justify: 1 }, doJustify = function (range, style) { var bookmark = range.createBookmark(), filterFn = function (node) { return node.nodeType == 1 ? node.tagName.toLowerCase() != "br" && !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node); }; range.enlarge(true); var bookmark2 = range.createBookmark(), current = domUtils.getNextDomNode(bookmark2.start, false, filterFn), tmpRange = range.cloneRange(), tmpNode; while ( current && !( domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING ) ) { if (current.nodeType == 3 || !block(current)) { tmpRange.setStartBefore(current); while (current && current !== bookmark2.end && !block(current)) { tmpNode = current; current = domUtils.getNextDomNode(current, false, null, function ( node ) { return !block(node); }); } tmpRange.setEndAfter(tmpNode); var common = tmpRange.getCommonAncestor(); if (!domUtils.isBody(common) && block(common)) { domUtils.setStyles( common, utils.isString(style) ? { "text-align": style } : style ); current = common; } else { var p = range.document.createElement("p"); domUtils.setStyles( p, utils.isString(style) ? { "text-align": style } : style ); var frag = tmpRange.extractContents(); p.appendChild(frag); tmpRange.insertNode(p); current = p; } current = domUtils.getNextDomNode(current, false, filterFn); } else { current = domUtils.getNextDomNode(current, true, filterFn); } } return range.moveToBookmark(bookmark2).moveToBookmark(bookmark); }; UE.commands["justify"] = { execCommand: function (cmdName, align) { var range = this.selection.getRange(), txt; //闭合时单独处理 if (range.collapsed) { txt = this.document.createTextNode("p"); range.insertNode(txt); } doJustify(range, align); if (txt) { range.setStartBefore(txt).collapse(true); domUtils.remove(txt); } range.select(); return true; }, queryCommandValue: function () { var startNode = this.selection.getStart(), value = domUtils.getComputedStyle(startNode, "text-align"); return defaultValue[value] ? value : "left"; }, queryCommandState: function () { var start = this.selection.getStart(), cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true); return cell ? -1 : 0; } }; }; // plugins/font.js /** * 字体颜色,背景色,字号,字体,下划线,删除线 * @file * @since 1.2.6.1 */ /** * 字体颜色 * @command forecolor * @method execCommand * @param { String } cmd 命令字符串 * @param { String } value 色值(必须十六进制) * @example * ```javascript * editor.execCommand( 'forecolor', '#000' ); * ``` */ /** * 返回选区字体颜色 * @command forecolor * @method queryCommandValue * @param { String } cmd 命令字符串 * @return { String } 返回字体颜色 * @example * ```javascript * editor.queryCommandValue( 'forecolor' ); * ``` */ /** * 字体背景颜色 * @command backcolor * @method execCommand * @param { String } cmd 命令字符串 * @param { String } value 色值(必须十六进制) * @example * ```javascript * editor.execCommand( 'backcolor', '#000' ); * ``` */ /** * 返回选区字体颜色 * @command backcolor * @method queryCommandValue * @param { String } cmd 命令字符串 * @return { String } 返回字体背景颜色 * @example * ```javascript * editor.queryCommandValue( 'backcolor' ); * ``` */ /** * 字体大小 * @command fontsize * @method execCommand * @param { String } cmd 命令字符串 * @param { String } value 字体大小 * @example * ```javascript * editor.execCommand( 'fontsize', '14px' ); * ``` */ /** * 返回选区字体大小 * @command fontsize * @method queryCommandValue * @param { String } cmd 命令字符串 * @return { String } 返回字体大小 * @example * ```javascript * editor.queryCommandValue( 'fontsize' ); * ``` */ /** * 字体样式 * @command fontfamily * @method execCommand * @param { String } cmd 命令字符串 * @param { String } value 字体样式 * @example * ```javascript * editor.execCommand( 'fontfamily', '微软雅黑' ); * ``` */ /** * 返回选区字体样式 * @command fontfamily * @method queryCommandValue * @param { String } cmd 命令字符串 * @return { String } 返回字体样式 * @example * ```javascript * editor.queryCommandValue( 'fontfamily' ); * ``` */ /** * 字体下划线,与删除线互斥 * @command underline * @method execCommand * @param { String } cmd 命令字符串 * @example * ```javascript * editor.execCommand( 'underline' ); * ``` */ /** * 字体删除线,与下划线互斥 * @command strikethrough * @method execCommand * @param { String } cmd 命令字符串 * @example * ```javascript * editor.execCommand( 'strikethrough' ); * ``` */ /** * 字体边框 * @command fontborder * @method execCommand * @param { String } cmd 命令字符串 * @example * ```javascript * editor.execCommand( 'fontborder' ); * ``` */ UE.plugins["font"] = function () { var me = this, fonts = { forecolor: "color", backcolor: "background-color", fontsize: "font-size", fontfamily: "font-family", underline: "text-decoration", strikethrough: "text-decoration", fontborder: "border" }, lang = me.getLang(), needCmd = { underline: 1, strikethrough: 1, fontborder: 1 }, needSetChild = { forecolor: "color", backcolor: "background-color", fontsize: "font-size", fontfamily: "font-family" }; me.setOpt({ fontfamily: [ { name: "default", val: "default" }, { name: "songti", val: "宋体,SimSun" }, { name: "yahei", val: "微软雅黑,Microsoft YaHei" }, { name: "kaiti", val: "楷体,楷体_GB2312,SimKai" }, { name: "heiti", val: "黑体,SimHei" }, { name: "lishu", val: "隶书,SimLi" }, // { name: "andaleMono", val: "andale mono" }, { name: "arial", val: "arial,helvetica,sans-serif" }, // { name: "arialBlack", val: "arial black,avant garde" }, // { name: "comicSansMs", val: "comic sans ms" }, // { name: "impact", val: "impact,chicago" }, { name: "timesNewRoman", val: "times new roman" } ], fontsize: [10, 11, 12, 14, 16, 18, 20, 24, 36] }); function mergeWithParent (node) { var parent; while ((parent = node.parentNode)) { if ( parent.tagName == "SPAN" && domUtils.getChildCount(parent, function (child) { return !domUtils.isBookmarkNode(child) && !domUtils.isBr(child); }) == 1 ) { parent.style.cssText += node.style.cssText; domUtils.remove(node, true); node = parent; } else { break; } } } function mergeChild (rng, cmdName, value) { if (needSetChild[cmdName]) { rng.adjustmentBoundary(); if (!rng.collapsed && rng.startContainer.nodeType == 1) { var start = rng.startContainer.childNodes[rng.startOffset]; if (start && domUtils.isTagNode(start, "span")) { var bk = rng.createBookmark(); utils.each(domUtils.getElementsByTagName(start, "span"), function ( span ) { if (!span.parentNode || domUtils.isBookmarkNode(span)) return; if ( cmdName == "backcolor" && domUtils .getComputedStyle(span, "background-color") .toLowerCase() === value ) { return; } domUtils.removeStyle(span, needSetChild[cmdName]); if (span.style.cssText.replace(/^\s+$/, "").length == 0) { domUtils.remove(span, true); } }); rng.moveToBookmark(bk); } } } } function mergesibling (rng, cmdName, value) { var collapsed = rng.collapsed, bk = rng.createBookmark(), common; if (collapsed) { common = bk.start.parentNode; while (dtd.$inline[common.tagName]) { common = common.parentNode; } } else { common = domUtils.getCommonAncestor(bk.start, bk.end); } utils.each(domUtils.getElementsByTagName(common, "span"), function (span) { if (!span.parentNode || domUtils.isBookmarkNode(span)) return; if (/\s*border\s*:\s*none;?\s*/i.test(span.style.cssText)) { if (/^\s*border\s*:\s*none;?\s*$/.test(span.style.cssText)) { domUtils.remove(span, true); } else { domUtils.removeStyle(span, "border"); } return; } if ( /border/i.test(span.style.cssText) && span.parentNode.tagName == "SPAN" && /border/i.test(span.parentNode.style.cssText) ) { span.style.cssText = span.style.cssText.replace( /border[^:]*:[^;]+;?/gi, "" ); } if (!(cmdName == "fontborder" && value == "none")) { var next = span.nextSibling; while (next && next.nodeType == 1 && next.tagName == "SPAN") { if (domUtils.isBookmarkNode(next) && cmdName == "fontborder") { span.appendChild(next); next = span.nextSibling; continue; } if (next.style.cssText == span.style.cssText) { domUtils.moveChild(next, span); domUtils.remove(next); } if (span.nextSibling === next) break; next = span.nextSibling; } } mergeWithParent(span); if (browser.ie && browser.version > 8) { //拷贝父亲们的特别的属性,这里只做背景颜色的处理 var parent = domUtils.findParent(span, function (n) { return ( n.tagName == "SPAN" && /background-color/.test(n.style.cssText) ); }); if (parent && !/background-color/.test(span.style.cssText)) { span.style.backgroundColor = parent.style.backgroundColor; } } }); rng.moveToBookmark(bk); mergeChild(rng, cmdName, value); } me.addInputRule(function (root) { utils.each(root.getNodesByTagName("u s del font strike"), function (node) { if (node.tagName == "font") { var cssStyle = []; for (var p in node.attrs) { switch (p) { case "size": cssStyle.push( "font-size:" + ({ "1": "10", "2": "12", "3": "16", "4": "18", "5": "24", "6": "32", "7": "48" }[node.attrs[p]] || node.attrs[p]) + "px" ); break; case "color": cssStyle.push("color:" + node.attrs[p]); break; case "face": cssStyle.push("font-family:" + node.attrs[p]); break; case "style": cssStyle.push(node.attrs[p]); } } node.attrs = { style: cssStyle.join(";") }; } else { var val = node.tagName == "u" ? "underline" : "line-through"; node.attrs = { style: (node.getAttr("style") || "") + "text-decoration:" + val + ";" }; } node.tagName = "span"; }); // utils.each(root.getNodesByTagName('span'), function (node) { // var val; // if(val = node.getAttr('class')){ // if(/fontstrikethrough/.test(val)){ // node.setStyle('text-decoration','line-through'); // if(node.attrs['class']){ // node.attrs['class'] = node.attrs['class'].replace(/fontstrikethrough/,''); // }else{ // node.setAttr('class') // } // } // if(/fontborder/.test(val)){ // node.setStyle('border','1px solid #000'); // if(node.attrs['class']){ // node.attrs['class'] = node.attrs['class'].replace(/fontborder/,''); // }else{ // node.setAttr('class') // } // } // } // }); }); // me.addOutputRule(function(root){ // utils.each(root.getNodesByTagName('span'), function (node) { // var val; // if(val = node.getStyle('text-decoration')){ // if(/line-through/.test(val)){ // if(node.attrs['class']){ // node.attrs['class'] += ' fontstrikethrough'; // }else{ // node.setAttr('class','fontstrikethrough') // } // } // // node.setStyle('text-decoration') // } // if(val = node.getStyle('border')){ // if(/1px/.test(val) && /solid/.test(val)){ // if(node.attrs['class']){ // node.attrs['class'] += ' fontborder'; // // }else{ // node.setAttr('class','fontborder') // } // } // node.setStyle('border') // // } // }); // }); for (var p in fonts) { (function (cmd, style) { UE.commands[cmd] = { execCommand: function (cmdName, value) { // console.log("execCommand", cmdName, value); value = value || (this.queryCommandState(cmdName) ? "none" : cmdName === "underline" ? "underline" : cmdName === "fontborder" ? "1px solid #000" : "line-through"); var me = this, range = this.selection.getRange(), text; if (value === "default") { if (range.collapsed) { text = me.document.createTextNode("font"); range.insertNode(text).select(); } me.execCommand("removeFormat", "span,a", style); if (text) { range.setStartBefore(text).collapse(true); domUtils.remove(text); } mergesibling(range, cmdName, value); range.select(); } else { if (!range.collapsed) { if (needCmd[cmd] && me.queryCommandValue(cmd)) { me.execCommand("removeFormat", "span,a", style); } range = me.selection.getRange(); range.applyInlineStyle("span", { style: style + ":" + value }); mergesibling(range, cmdName, value); range.select(); } else { var span = domUtils.findParentByTagName( range.startContainer, "span", true ); text = me.document.createTextNode("font"); if ( span && !span.children.length && !span[browser.ie ? "innerText" : "textContent"].replace( fillCharReg, "" ).length ) { //for ie hack when enter range.insertNode(text); if (needCmd[cmd]) { range.selectNode(text).select(); me.execCommand("removeFormat", "span,a", style, null); span = domUtils.findParentByTagName(text, "span", true); range.setStartBefore(text); } span && (span.style.cssText += ";" + style + ":" + value); range.collapse(true).select(); } else { range.insertNode(text); range.selectNode(text).select(); span = range.document.createElement("span"); if (needCmd[cmd]) { //a标签内的不处理跳过 if (domUtils.findParentByTagName(text, "a", true)) { range.setStartBefore(text).setCursor(); domUtils.remove(text); return; } me.execCommand("removeFormat", "span,a", style); } span.style.cssText = style + ":" + value; text.parentNode.insertBefore(span, text); //修复,span套span 但样式不继承的问题 if (!browser.ie || (browser.ie && browser.version === 9)) { var spanParent = span.parentNode; while (!domUtils.isBlockElm(spanParent)) { if (spanParent.tagName === "SPAN") { //opera合并style不会加入";" span.style.cssText = spanParent.style.cssText + ";" + span.style.cssText; } spanParent = spanParent.parentNode; } } if (opera) { setTimeout(function () { range.setStart(span, 0).collapse(true); mergesibling(range, cmdName, value); range.select(); }); } else { range.setStart(span, 0).collapse(true); mergesibling(range, cmdName, value); range.select(); } //trace:981 //domUtils.mergeToParent(span) } domUtils.remove(text); } } return true; }, queryCommandValue: function (cmdName) { var startNode = this.selection.getStart(); var styleVal; //trace:946 if (cmdName === "underline" || cmdName === "strikethrough") { var tmpNode = startNode, value; while ( tmpNode && !domUtils.isBlockElm(tmpNode) && !domUtils.isBody(tmpNode) ) { if (tmpNode.nodeType === 1) { value = domUtils.getComputedStyle(tmpNode, style); if (value !== "none") { return value; } } tmpNode = tmpNode.parentNode; } return "none"; } else if (cmdName === "fontborder") { var tmp = startNode, val; while (tmp && dtd.$inline[tmp.tagName]) { if ((val = domUtils.getComputedStyle(tmp, "border"))) { if (/1px/.test(val) && /solid/.test(val)) { return val; } } tmp = tmp.parentNode; } return ""; } else if (cmdName === "FontSize") { styleVal = domUtils.getComputedStyle(startNode, style); tmp = /^([\d\.]+)(\w+)$/.exec(styleVal); if (tmp) { return Math.floor(tmp[1]) + tmp[2]; } return styleVal; } else if (cmdName === 'FontFamily') { styleVal = domUtils.getComputedStyle(startNode, style) // 移除左右引号 styleVal = styleVal.replace(/['"]/g, ''); // 移除字体 宋体, SimSun 转为 宋体,SimSun,否则以下的判断会出错 styleVal = styleVal.replace(/\s*,\s*/g, ','); var fontFamily = lang.fontfamily.default; var fontList = me.options["fontfamily"] || []; for (var i = 0; i < fontList.length; i++) { var v = fontList[i]; // console.log('FontFamily', styleVal, v.val); if (v.val === styleVal) { fontFamily = styleVal; break; } } // console.log('fontList', fontList); // console.log('FontFamily', styleVal, fontFamily); return fontFamily; } value = domUtils.getComputedStyle(startNode, style); return value; }, queryCommandState: function (cmdName) { if (!needCmd[cmdName]) return 0; var val = this.queryCommandValue(cmdName); if (cmdName === "fontborder") { return /1px/.test(val) && /solid/.test(val); } else { return cmdName === "underline" ? /underline/.test(val) : /line\-through/.test(val); } } }; })(p, fonts[p]); } }; // plugins/link.js /** * 超链接 * @file * @since 1.2.6.1 */ /** * 插入超链接 * @command link * @method execCommand * @param { String } cmd 命令字符串 * @param { Object } options 设置自定义属性,例如:url、title、target * @example * ```javascript * editor.execCommand( 'link', '{ * url:'ueditor.baidu.com', * title:'ueditor', * target:'_blank' * }' ); * ``` */ /** * 返回当前选中的第一个超链接节点 * @command link * @method queryCommandValue * @param { String } cmd 命令字符串 * @return { Element } 超链接节点 * @example * ```javascript * editor.queryCommandValue( 'link' ); * ``` */ /** * 取消超链接 * @command unlink * @method execCommand * @param { String } cmd 命令字符串 * @example * ```javascript * editor.execCommand( 'unlink'); * ``` */ UE.plugins["link"] = function () { function optimize (range) { var start = range.startContainer, end = range.endContainer; if ((start = domUtils.findParentByTagName(start, "a", true))) { range.setStartBefore(start); } if ((end = domUtils.findParentByTagName(end, "a", true))) { range.setEndAfter(end); } } UE.commands["unlink"] = { execCommand: function () { var range = this.selection.getRange(), bookmark; if ( range.collapsed && !domUtils.findParentByTagName(range.startContainer, "a", true) ) { return; } bookmark = range.createBookmark(); optimize(range); range.removeInlineStyle("a").moveToBookmark(bookmark).select(); }, queryCommandState: function () { return !this.highlight && this.queryCommandValue("link") ? 0 : -1; } }; function doLink (range, opt, me) { var rngClone = range.cloneRange(), link = me.queryCommandValue("link"); optimize((range = range.adjustmentBoundary())); var start = range.startContainer; if (start.nodeType == 1 && link) { start = start.childNodes[range.startOffset]; if ( start && start.nodeType == 1 && start.tagName == "A" && /^(?:https?|ftp|file)\s*:\s*\/\//.test( start[browser.ie ? "innerText" : "textContent"] ) ) { start[browser.ie ? "innerText" : "textContent"] = utils.html( opt.textValue || opt.href ); } } if (!rngClone.collapsed || link) { range.removeInlineStyle("a"); rngClone = range.cloneRange(); } if (rngClone.collapsed) { var a = range.document.createElement("a"), text = ""; if (opt.textValue) { text = utils.html(opt.textValue); delete opt.textValue; } else { text = utils.html(opt.href); } domUtils.setAttributes(a, opt); start = domUtils.findParentByTagName(rngClone.startContainer, "a", true); if (start && domUtils.isInNodeEndBoundary(rngClone, start)) { range.setStartAfter(start).collapse(true); } a[browser.ie ? "innerText" : "textContent"] = text; range.insertNode(a).selectNode(a); } else { range.applyInlineStyle("a", opt); } } UE.commands["link"] = { execCommand: function (cmdName, opt) { var range; opt._href && (opt._href = utils.unhtml(opt._href, /[<">]/g)); opt.href && (opt.href = utils.unhtml(opt.href, /[<">]/g)); opt.textValue && (opt.textValue = utils.unhtml(opt.textValue, /[<">]/g)); doLink((range = this.selection.getRange()), opt, this); //闭合都不加占位符,如果加了会在a后边多个占位符节点,导致a是图片背景组成的列表,出现空白问题 range.collapse().select(true); }, queryCommandValue: function () { var range = this.selection.getRange(), node; if (range.collapsed) { // node = this.selection.getStart(); //在ie下getstart()取值偏上了 node = range.startContainer; node = node.nodeType == 1 ? node : node.parentNode; if ( node && (node = domUtils.findParentByTagName(node, "a", true)) && !domUtils.isInNodeEndBoundary(range, node) ) { return node; } } else { //trace:1111 如果是 startContainer是p就会找不到a range.shrinkBoundary(); var start = range.startContainer.nodeType == 3 || !range.startContainer.childNodes[range.startOffset] ? range.startContainer : range.startContainer.childNodes[range.startOffset], end = range.endContainer.nodeType == 3 || range.endOffset == 0 ? range.endContainer : range.endContainer.childNodes[range.endOffset - 1], common = range.getCommonAncestor(); node = domUtils.findParentByTagName(common, "a", true); if (!node && common.nodeType == 1) { var as = common.getElementsByTagName("a"), ps, pe; for (var i = 0, ci; (ci = as[i++]);) { (ps = domUtils.getPosition(ci, start)), (pe = domUtils.getPosition( ci, end )); if ( (ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS) && (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS) ) { node = ci; break; } } } return node; } }, queryCommandState: function () { //判断如果是视频的话连接不可用 //fix 853 var img = this.selection.getRange().getClosedNode(), flag = img && (img.className == "edui-faked-video" || img.className.indexOf("edui-upload-video") != -1); return flag ? -1 : 0; } }; }; // plugins/iframe.js ///import core ///import plugins\inserthtml.js ///commands 插入框架 ///commandsName InsertFrame ///commandsTitle 插入Iframe ///commandsDialog dialogs\insertframe UE.plugins["insertframe"] = function () { var me = this; function deleteIframe () { me._iframe && delete me._iframe; } me.addListener("selectionchange", function () { deleteIframe(); }); }; // plugins/scrawl.js ///import core ///commands 涂鸦 ///commandsName Scrawl ///commandsTitle 涂鸦 ///commandsDialog dialogs\scrawl UE.commands["scrawl"] = { queryCommandState: function () { return browser.ie && browser.version <= 8 ? -1 : 0; } }; // plugins/removeformat.js /** * 清除格式 * @file * @since 1.2.6.1 */ /** * 清除文字样式 * @command removeformat * @method execCommand * @param { String } cmd 命令字符串 * @param {String} tags 以逗号隔开的标签。如:strong * @param {String} style 样式如:color * @param {String} attrs 属性如:width * @example * ```javascript * editor.execCommand( 'removeformat', 'strong','color','width' ); * ``` */ UE.plugins["removeformat"] = function () { var me = this; me.setOpt({ removeFormatTags: "b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var", removeFormatAttributes: "class,style,lang,width,height,align,hspace,valign" }); me.commands["removeformat"] = { execCommand: function (cmdName, tags, style, attrs, notIncludeA) { var tagReg = new RegExp( "^(?:" + (tags || this.options.removeFormatTags).replace(/,/g, "|") + ")$", "i" ), removeFormatAttributes = style ? [] : (attrs || this.options.removeFormatAttributes).split(","), range = new dom.Range(this.document), bookmark, node, parent, filter = function (node) { return node.nodeType == 1; }; function isRedundantSpan (node) { if (node.nodeType == 3 || node.tagName.toLowerCase() != "span") { return 0; } if (browser.ie) { //ie 下判断实效,所以只能简单用style来判断 //return node.style.cssText == '' ? 1 : 0; var attrs = node.attributes; if (attrs.length) { for (var i = 0, l = attrs.length; i < l; i++) { if (attrs[i].specified) { return 0; } } return 1; } } return !node.attributes.length; } function doRemove (range) { var bookmark1 = range.createBookmark(); if (range.collapsed) { range.enlarge(true); } //不能把a标签切了 if (!notIncludeA) { var aNode = domUtils.findParentByTagName( range.startContainer, "a", true ); if (aNode) { range.setStartBefore(aNode); } aNode = domUtils.findParentByTagName(range.endContainer, "a", true); if (aNode) { range.setEndAfter(aNode); } } bookmark = range.createBookmark(); node = bookmark.start; //切开始 while ((parent = node.parentNode) && !domUtils.isBlockElm(parent)) { domUtils.breakParent(node, parent); domUtils.clearEmptySibling(node); } if (bookmark.end) { //切结束 node = bookmark.end; while ((parent = node.parentNode) && !domUtils.isBlockElm(parent)) { domUtils.breakParent(node, parent); domUtils.clearEmptySibling(node); } //开始去除样式 var current = domUtils.getNextDomNode(bookmark.start, false, filter), next; while (current) { if (current == bookmark.end) { break; } next = domUtils.getNextDomNode(current, true, filter); if ( !dtd.$empty[current.tagName.toLowerCase()] && !domUtils.isBookmarkNode(current) ) { if (tagReg.test(current.tagName)) { if (style) { domUtils.removeStyle(current, style); if (isRedundantSpan(current) && style != "text-decoration") { domUtils.remove(current, true); } } else { domUtils.remove(current, true); } } else { //trace:939 不能把list上的样式去掉 // 清除格式时,默认移除Table、List上的样式 if ( true // !dtd.$tableContent[current.tagName] && !dtd.$list[current.tagName] ) { domUtils.removeAttributes(current, removeFormatAttributes); if (isRedundantSpan(current)) { domUtils.remove(current, true); } } else { // console.log('current.ignore',current); } } } current = next; } } //trace:1035 //trace:1096 不能把td上的样式去掉,比如边框 var pN = bookmark.start.parentNode; if ( domUtils.isBlockElm(pN) && !dtd.$tableContent[pN.tagName] && !dtd.$list[pN.tagName] ) { domUtils.removeAttributes(pN, removeFormatAttributes); } pN = bookmark.end.parentNode; if ( bookmark.end && domUtils.isBlockElm(pN) && !dtd.$tableContent[pN.tagName] && !dtd.$list[pN.tagName] ) { domUtils.removeAttributes(pN, removeFormatAttributes); } range.moveToBookmark(bookmark).moveToBookmark(bookmark1); //清除冗余的代码" +
this.getContent(null, null, true) +
" "
);
d.close();
},
notNeedUndo: 1
};
// plugins/selectall.js
/**
* 全选
* @file
* @since 1.2.6.1
*/
/**
* 选中所有内容
* @command selectall
* @method execCommand
* @param { String } cmd 命令字符串
* @example
* ```javascript
* editor.execCommand( 'selectall' );
* ```
*/
UE.plugins["selectall"] = function () {
var me = this;
me.commands["selectall"] = {
execCommand: function () {
//去掉了原生的selectAll,因为会出现报错和当内容为空时,不能出现闭合状态的光标
var me = this,
body = me.body,
range = me.selection.getRange();
range.selectNodeContents(body);
if (domUtils.isEmptyBlock(body)) {
//opera不能自动合并到元素的里边,要手动处理一下
if (browser.opera && body.firstChild && body.firstChild.nodeType == 1) {
range.setStartAtFirst(body.firstChild);
}
range.collapse(true);
}
range.select(true);
},
notNeedUndo: 1
};
//快捷键
me.addshortcutkey({
selectAll: "ctrl+65"
});
};
// plugins/paragraph.js
/**
* 段落样式
* @file
* @since 1.2.6.1
*/
/**
* 段落格式
* @command paragraph
* @method execCommand
* @param { String } cmd 命令字符串
* @param {String} style 标签值为:'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
* @param {Object} attrs 标签的属性
* @example
* ```javascript
* editor.execCommand( 'Paragraph','h1','{
* class:'test'
* }' );
* ```
*/
/**
* 返回选区内节点标签名
* @command paragraph
* @method queryCommandValue
* @param { String } cmd 命令字符串
* @return { String } 节点标签名
* @example
* ```javascript
* editor.queryCommandValue( 'Paragraph' );
* ```
*/
UE.plugins["paragraph"] = function () {
var me = this,
block = domUtils.isBlockElm,
notExchange = ["TD", "LI", "PRE"],
doParagraph = function (range, style, attrs, sourceCmdName) {
var bookmark = range.createBookmark(),
filterFn = function (node) {
return node.nodeType == 1
? node.tagName.toLowerCase() != "br" &&
!domUtils.isBookmarkNode(node)
: !domUtils.isWhitespace(node);
},
para;
range.enlarge(true);
var bookmark2 = range.createBookmark(),
current = domUtils.getNextDomNode(bookmark2.start, false, filterFn),
tmpRange = range.cloneRange(),
tmpNode;
while (
current &&
!(
domUtils.getPosition(current, bookmark2.end) &
domUtils.POSITION_FOLLOWING
)
) {
if (current.nodeType === 3 || !block(current)) {
tmpRange.setStartBefore(current);
while (current && current !== bookmark2.end && !block(current)) {
tmpNode = current;
current = domUtils.getNextDomNode(current, false, null, function (
node
) {
return !block(node);
});
}
tmpRange.setEndAfter(tmpNode);
para = range.document.createElement(style);
if (attrs) {
domUtils.setAttributes(para, attrs);
if (
sourceCmdName &&
sourceCmdName === "customstyle" &&
attrs.style
) {
para.style.cssText = attrs.style;
}
}
para.appendChild(tmpRange.extractContents());
//需要内容占位
if (domUtils.isEmptyNode(para)) {
domUtils.fillChar(range.document, para);
}
tmpRange.insertNode(para);
var parent = para.parentNode;
//如果para上一级是一个block元素且不是body,td就删除它
if (
block(parent) &&
!domUtils.isBody(para.parentNode) &&
utils.indexOf(notExchange, parent.tagName) === -1
) {
//存储dir,style
if (!(sourceCmdName && sourceCmdName === "customstyle")) {
parent.getAttribute("dir") &&
para.setAttribute("dir", parent.getAttribute("dir"));
//trace:1070
parent.style.cssText &&
(para.style.cssText =
parent.style.cssText + ";" + para.style.cssText);
//trace:1030
parent.style.textAlign &&
!para.style.textAlign &&
(para.style.textAlign = parent.style.textAlign);
parent.style.textIndent &&
!para.style.textIndent &&
(para.style.textIndent = parent.style.textIndent);
parent.style.padding &&
!para.style.padding &&
(para.style.padding = parent.style.padding);
}
//trace:1706 选择的就是h1-6要删除
if (
attrs &&
/h\d/i.test(parent.tagName) &&
!/h\d/i.test(para.tagName)
) {
domUtils.setAttributes(parent, attrs);
if (
sourceCmdName &&
sourceCmdName === "customstyle" &&
attrs.style
) {
parent.style.cssText = attrs.style;
}
domUtils.remove(para.parentNode, true);
para = parent;
} else {
domUtils.remove(para.parentNode, true);
}
}
if (utils.indexOf(notExchange, parent.tagName) !== -1) {
current = parent;
} else {
current = para;
}
current = domUtils.getNextDomNode(current, false, filterFn);
} else {
current = domUtils.getNextDomNode(current, true, filterFn);
}
}
return range.moveToBookmark(bookmark2).moveToBookmark(bookmark);
};
me.setOpt("paragraph", {
p: "",
h1: "",
h2: "",
h3: "",
h4: "",
h5: "",
h6: ""
});
me.commands["paragraph"] = {
execCommand: function (cmdName, style, attrs, sourceCmdName) {
var range = this.selection.getRange();
//闭合时单独处理
if (range.collapsed) {
var txt = this.document.createTextNode("p");
range.insertNode(txt);
//去掉冗余的fillchar
if (browser.ie) {
var node = txt.previousSibling;
if (node && domUtils.isWhitespace(node)) {
domUtils.remove(node);
}
node = txt.nextSibling;
if (node && domUtils.isWhitespace(node)) {
domUtils.remove(node);
}
}
}
range = doParagraph(range, style, attrs, sourceCmdName);
if (txt) {
range.setStartBefore(txt).collapse(true);
pN = txt.parentNode;
domUtils.remove(txt);
if (domUtils.isBlockElm(pN) && domUtils.isEmptyNode(pN)) {
domUtils.fillNode(this.document, pN);
}
}
if (
browser.gecko &&
range.collapsed &&
range.startContainer.nodeType === 1
) {
var child = range.startContainer.childNodes[range.startOffset];
if (
child &&
child.nodeType === 1 &&
child.tagName.toLowerCase() === style
) {
range.setStart(child, 0).collapse(true);
}
}
//trace:1097 原来有true,原因忘了,但去了就不能清除多余的占位符了
range.select();
return true;
},
queryCommandValue: function () {
var node = domUtils.filterNodeList(
this.selection.getStartElementPath(),
"p h1 h2 h3 h4 h5 h6"
);
return node ? node.tagName.toLowerCase() : "";
}
};
};
// plugins/directionality.js
/**
* 设置文字输入的方向的插件
* @file
* @since 1.2.6.1
*/
(function () {
var block = domUtils.isBlockElm,
getObj = function (editor) {
// var startNode = editor.selection.getStart(),
// parents;
// if ( startNode ) {
// //查找所有的是block的父亲节点
// parents = domUtils.findParents( startNode, true, block, true );
// for ( var i = 0,ci; ci = parents[i++]; ) {
// if ( ci.getAttribute( 'dir' ) ) {
// return ci;
// }
// }
// }
return domUtils.filterNodeList(
editor.selection.getStartElementPath(),
function (n) {
return n && n.nodeType == 1 && n.getAttribute("dir");
}
);
},
doDirectionality = function (range, editor, forward) {
var bookmark,
filterFn = function (node) {
return node.nodeType == 1
? !domUtils.isBookmarkNode(node)
: !domUtils.isWhitespace(node);
},
obj = getObj(editor);
if (obj && range.collapsed) {
obj.setAttribute("dir", forward);
return range;
}
bookmark = range.createBookmark();
range.enlarge(true);
var bookmark2 = range.createBookmark(),
current = domUtils.getNextDomNode(bookmark2.start, false, filterFn),
tmpRange = range.cloneRange(),
tmpNode;
while (
current &&
!(
domUtils.getPosition(current, bookmark2.end) &
domUtils.POSITION_FOLLOWING
)
) {
if (current.nodeType == 3 || !block(current)) {
tmpRange.setStartBefore(current);
while (current && current !== bookmark2.end && !block(current)) {
tmpNode = current;
current = domUtils.getNextDomNode(current, false, null, function (
node
) {
return !block(node);
});
}
tmpRange.setEndAfter(tmpNode);
var common = tmpRange.getCommonAncestor();
if (!domUtils.isBody(common) && block(common)) {
//遍历到了block节点
common.setAttribute("dir", forward);
current = common;
} else {
//没有遍历到,添加一个block节点
var p = range.document.createElement("p");
p.setAttribute("dir", forward);
var frag = tmpRange.extractContents();
p.appendChild(frag);
tmpRange.insertNode(p);
current = p;
}
current = domUtils.getNextDomNode(current, false, filterFn);
} else {
current = domUtils.getNextDomNode(current, true, filterFn);
}
}
return range.moveToBookmark(bookmark2).moveToBookmark(bookmark);
};
/**
* 文字输入方向
* @command directionality
* @method execCommand
* @param { String } cmdName 命令字符串
* @param { String } forward 传入'ltr'表示从左向右输入,传入'rtl'表示从右向左输入
* @example
* ```javascript
* editor.execCommand( 'directionality', 'ltr');
* ```
*/
/**
* 查询当前选区的文字输入方向
* @command directionality
* @method queryCommandValue
* @param { String } cmdName 命令字符串
* @return { String } 返回'ltr'表示从左向右输入,返回'rtl'表示从右向左输入
* @example
* ```javascript
* editor.queryCommandValue( 'directionality');
* ```
*/
UE.commands["directionality"] = {
execCommand: function (cmdName, forward) {
var range = this.selection.getRange();
//闭合时单独处理
if (range.collapsed) {
var txt = this.document.createTextNode("d");
range.insertNode(txt);
}
doDirectionality(range, this, forward);
if (txt) {
range.setStartBefore(txt).collapse(true);
domUtils.remove(txt);
}
range.select();
return true;
},
queryCommandValue: function () {
var node = getObj(this);
return node ? node.getAttribute("dir") : "ltr";
}
};
})();
// plugins/horizontal.js
/**
* 插入分割线插件
* @file
* @since 1.2.6.1
*/
/**
* 插入分割线
* @command horizontal
* @method execCommand
* @param { String } cmdName 命令字符串
* @example
* ```javascript
* editor.execCommand( 'horizontal' );
* ```
*/
UE.plugins["horizontal"] = function () {
var me = this;
me.commands["horizontal"] = {
execCommand: function (cmdName) {
var me = this;
if (me.queryCommandState(cmdName) !== -1) {
me.execCommand("insertHtml", ""); var range = me.selection.getRange(), start = range.startContainer; if (start.nodeType == 1 && !start.childNodes[range.startOffset]) { var tmp; if ((tmp = start.childNodes[range.startOffset - 1])) { if (tmp.nodeType == 1 && tmp.tagName == "HR") { if (me.options.enterTag == "p") { tmp = me.document.createElement("p"); range.insertNode(tmp); range.setStart(tmp, 0).setCursor(); } else { tmp = me.document.createElement("br"); range.insertNode(tmp); range.setStartBefore(tmp).setCursor(); } } } } return true; } }, //边界在table里不能加分隔线 queryCommandState: function () { return domUtils.filterNodeList( this.selection.getStartElementPath(), "table" ) ? -1 : 0; } }; // me.addListener('delkeyup',function(){ // var rng = this.selection.getRange(); // if(browser.ie && browser.version > 8){ // rng.txtToElmBoundary(true); // if(domUtils.isStartInblock(rng)){ // var tmpNode = rng.startContainer; // var pre = tmpNode.previousSibling; // if(pre && domUtils.isTagNode(pre,'hr')){ // domUtils.remove(pre); // rng.select(); // return; // } // } // } // if(domUtils.isBody(rng.startContainer)){ // var hr = rng.startContainer.childNodes[rng.startOffset -1]; // if(hr && hr.nodeName == 'HR'){ // var next = hr.nextSibling; // if(next){ // rng.setStart(next,0) // }else if(hr.previousSibling){ // rng.setStartAtLast(hr.previousSibling) // }else{ // var p = this.document.createElement('p'); // hr.parentNode.insertBefore(p,hr); // domUtils.fillNode(this.document,p); // rng.setStart(p,0); // } // domUtils.remove(hr); // rng.setCursor(false,true); // } // } // }) me.addListener("delkeydown", function (name, evt) { var rng = this.selection.getRange(); rng.txtToElmBoundary(true); if (domUtils.isStartInblock(rng)) { var tmpNode = rng.startContainer; var pre = tmpNode.previousSibling; if (pre && domUtils.isTagNode(pre, "hr")) { domUtils.remove(pre); rng.select(); domUtils.preventDefault(evt); return true; } } }); }; // plugins/time.js /** * 插入时间和日期 * @file * @since 1.2.6.1 */ /** * 插入时间,默认格式:12:59:59 * @command time * @method execCommand * @param { String } cmd 命令字符串 * @example * ```javascript * editor.execCommand( 'time'); * ``` */ /** * 插入日期,默认格式:2013-08-30 * @command date * @method execCommand * @param { String } cmd 命令字符串 * @example * ```javascript * editor.execCommand( 'date'); * ``` */ UE.commands["time"] = UE.commands["date"] = { execCommand: function (cmd, format) { var date = new Date(); function formatTime (date, format) { var hh = ("0" + date.getHours()).slice(-2), ii = ("0" + date.getMinutes()).slice(-2), ss = ("0" + date.getSeconds()).slice(-2); format = format || "hh:ii:ss"; return format.replace(/hh/gi, hh).replace(/ii/gi, ii).replace(/ss/gi, ss); } function formatDate (date, format) { var yyyy = ("000" + date.getFullYear()).slice(-4), yy = yyyy.slice(-2), mm = ("0" + (date.getMonth() + 1)).slice(-2), dd = ("0" + date.getDate()).slice(-2); format = format || "yyyy-mm-dd"; return format .replace(/yyyy/gi, yyyy) .replace(/yy/gi, yy) .replace(/mm/gi, mm) .replace(/dd/gi, dd); } this.execCommand( "insertHtml", cmd == "time" ? formatTime(date, format) : formatDate(date, format) ); } }; // plugins/rowspacing.js /** * 段前段后间距插件 * @file * @since 1.2.6.1 */ /** * 设置段间距 * @command rowspacing * @method execCommand * @param { String } cmd 命令字符串 * @param { String } value 段间距的值,以px为单位 * @param { String } dir 间距位置,top或bottom,分别表示段前和段后 * @example * ```javascript * editor.execCommand( 'rowspacing', '10', 'top' ); * ``` */ UE.plugins["rowspacing"] = function () { var me = this; me.setOpt({ rowspacingtop: ["5", "10", "15", "20", "25"], rowspacingbottom: ["5", "10", "15", "20", "25"] }); me.commands["rowspacing"] = { execCommand: function (cmdName, value, dir) { this.execCommand("paragraph", "p", { style: "margin-" + dir + ":" + value + "px" }); return true; }, queryCommandValue: function (cmdName, dir) { var pN = domUtils.filterNodeList( this.selection.getStartElementPath(), function (node) { return domUtils.isBlockElm(node); } ), value; //trace:1026 if (pN) { value = domUtils .getComputedStyle(pN, "margin-" + dir) .replace(/[^\d]/g, ""); return !value ? 0 : value; } return 0; } }; }; // plugins/lineheight.js /** * 设置行内间距 * @file * @since 1.2.6.1 */ UE.plugins["lineheight"] = function () { var me = this; me.setOpt({ lineheight: ["1", "1.5", "1.75", "2", "3", "4", "5"] }); /** * 行距 * @command lineheight * @method execCommand * @param { String } cmdName 命令字符串 * @param { String } value 传入的行高值, 该值是当前字体的倍数, 例如: 1.5, 1.75 * @example * ```javascript * editor.execCommand( 'lineheight', 1.5); * ``` */ /** * 查询当前选区内容的行高大小 * @command lineheight * @method queryCommandValue * @param { String } cmd 命令字符串 * @return { String } 返回当前行高大小 * @example * ```javascript * editor.queryCommandValue( 'lineheight' ); * ``` */ me.commands["lineheight"] = { execCommand: function (cmdName, value) { this.execCommand("paragraph", "p", { style: "line-height:" + (value == "1" ? "normal" : value + "em") }); return true; }, queryCommandValue: function () { var pN = domUtils.filterNodeList( this.selection.getStartElementPath(), function (node) { return domUtils.isBlockElm(node); } ); if (pN) { var value = domUtils.getComputedStyle(pN, "line-height"); return value == "normal" ? 1 : value.replace(/[^\d.]*/gi, ""); } } }; }; // plugins/insertcode.js /** * 插入代码插件 * @file * @since 1.2.6.1 */ UE.plugins["insertcode"] = function () { var me = this; me.setOpt("insertcode", { as3: "ActionScript3", bash: "Bash/Shell", cpp: "C/C++", css: "Css", // cf: "CodeFunction", "c#": "C#", delphi: "Delphi", // diff: "Diff", erlang: "Erlang", groovy: "Groovy", html: "Html", java: "Java", // jfx: "JavaFx", js: "Javascript", pl: "Perl", php: "PHP", plain: "Text", ps: "PowerShell", python: "Python", ruby: "Ruby", scala: "Scala", sql: "SQL", vb: "VB", xml: "XML", mind: "Mind", }); /** * 插入代码 * @command insertcode * @method execCommand * @param { String } cmd 命令字符串 * @param { String } lang 插入代码的语言 * @example * ```javascript * editor.execCommand( 'insertcode', 'javascript' ); * ``` */ /** * 如果选区所在位置是插入插入代码区域,返回代码的语言 * @command insertcode * @method queryCommandValue * @param { String } cmd 命令字符串 * @return { String } 返回代码的语言 * @example * ```javascript * editor.queryCommandValue( 'insertcode' ); * ``` */ me.commands["insertcode"] = { execCommand: function (cmd, lang) { var me = this, rng = me.selection.getRange(), pre = domUtils.findParentByTagName(rng.startContainer, "pre", true); if (pre) { pre.className = "brush:" + lang + ";toolbar:false;"; } else { var code = ""; if (rng.collapsed) { code = browser.ie && browser.ie11below ? browser.version <= 8 ? " " : "" : " "; } else { var frag = rng.extractContents(); var div = me.document.createElement("div"); div.appendChild(frag); utils.each( UE.filterNode( UE.htmlparser(div.innerHTML.replace(/[\r\t]/g, "")), me.options.filterTxtRules ).children, function (node) { if (browser.ie && browser.ie11below && browser.version > 8) { if (node.type == "element") { if (node.tagName == "br") { code += "\n"; } else if (!dtd.$empty[node.tagName]) { utils.each(node.children, function (cn) { if (cn.type == "element") { if (cn.tagName == "br") { code += "\n"; } else if (!dtd.$empty[node.tagName]) { code += cn.innerText(); } } else { code += cn.data; } }); if (!/\n$/.test(code)) { code += "\n"; } } } else { code += node.data + "\n"; } if (!node.nextSibling() && /\n$/.test(code)) { code = code.replace(/\n$/, ""); } } else { if (browser.ie && browser.ie11below) { if (node.type == "element") { if (node.tagName == "br") { code += " "; } else if (!dtd.$empty[node.tagName]) { utils.each(node.children, function (cn) { if (cn.type == "element") { if (cn.tagName == "br") { code += " "; } else if (!dtd.$empty[node.tagName]) { code += cn.innerText(); } } else { code += cn.data; } }); if (!/br>$/.test(code)) { code += " "; } } } else { code += node.data + " "; } if (!node.nextSibling() && / $/.test(code)) { code = code.replace(/ $/, ""); } } else { code += node.type == "element" ? dtd.$empty[node.tagName] ? "" : node.innerText() : node.data; if (!/br\/?\s*>$/.test(code)) { if (!node.nextSibling()) return; code += " "; } } } } ); } me.execCommand( "inserthtml", ' ' + code + "", true ); pre = me.document.getElementById("coder"); domUtils.removeAttributes(pre, "id"); var tmpNode = pre.previousSibling; if ( tmpNode && ((tmpNode.nodeType == 3 && tmpNode.nodeValue.length == 1 && browser.ie && browser.version == 6) || domUtils.isEmptyBlock(tmpNode)) ) { domUtils.remove(tmpNode); } var rng = me.selection.getRange(); if (domUtils.isEmptyBlock(pre)) { rng.setStart(pre, 0).setCursor(false, true); } else { rng.selectNodeContents(pre).select(); } } }, queryCommandValue: function () { var path = this.selection.getStartElementPath(); var lang = ""; utils.each(path, function (node) { if (node.nodeName == "PRE") { var match = node.className.match(/brush:([^;]+)/); lang = match && match[1] ? match[1] : ""; return false; } }); return lang; } }; me.addInputRule(function (root) { utils.each(root.getNodesByTagName("pre"), function (pre) { var brs = pre.getNodesByTagName("br"); if (brs.length) { browser.ie && browser.ie11below && browser.version > 8 && utils.each(brs, function (br) { var txt = UE.uNode.createText("\n"); br.parentNode.insertBefore(txt, br); br.parentNode.removeChild(br); }); return; } if (browser.ie && browser.ie11below && browser.version > 8) return; var code = pre.innerText().split(/\n/); pre.innerHTML(""); utils.each(code, function (c) { if (c.length) { pre.appendChild(UE.uNode.createText(c)); } pre.appendChild(UE.uNode.createElement("br")); }); }); }); me.addOutputRule(function (root) { utils.each(root.getNodesByTagName("pre"), function (pre) { var code = ""; utils.each(pre.children, function (n) { if (n.type == "text") { //在ie下文本内容有可能末尾带有\n要去掉 //trace:3396 code += n.data.replace(/[ ]/g, " ").replace(/\n$/, ""); } else { if (n.tagName == "br") { code += "\n"; } else { code += !dtd.$empty[n.tagName] ? "" : n.innerText(); } } }); pre.innerText(code.replace(/( |\n)+$/, "")); }); }); //不需要判断highlight的command列表 me.notNeedCodeQuery = { help: 1, undo: 1, redo: 1, source: 1, print: 1, searchreplace: 1, fullscreen: 1, preview: 1, insertparagraph: 1, elementpath: 1, insertcode: 1, inserthtml: 1, selectall: 1 }; //将queyCommamndState重置 var orgQuery = me.queryCommandState; me.queryCommandState = function (cmd) { var me = this; if ( !me.notNeedCodeQuery[cmd.toLowerCase()] && me.selection && me.queryCommandValue("insertcode") ) { return -1; } return UE.Editor.prototype.queryCommandState.apply(this, arguments); }; me.addListener("beforeenterkeydown", function () { var rng = me.selection.getRange(); var pre = domUtils.findParentByTagName(rng.startContainer, "pre", true); if (pre) { me.fireEvent("saveScene"); if (!rng.collapsed) { rng.deleteContents(); } if (!browser.ie || browser.ie9above) { var tmpNode = me.document.createElement("br"), pre; rng.insertNode(tmpNode).setStartAfter(tmpNode).collapse(true); var next = tmpNode.nextSibling; if (!next && (!browser.ie || browser.version > 10)) { rng.insertNode(tmpNode.cloneNode(false)); } else { rng.setStartAfter(tmpNode); } pre = tmpNode.previousSibling; var tmp; while (pre) { tmp = pre; pre = pre.previousSibling; if (!pre || pre.nodeName == "BR") { pre = tmp; break; } } if (pre) { var str = ""; while ( pre && pre.nodeName != "BR" && new RegExp("^[\\s" + domUtils.fillChar + "]*$").test(pre.nodeValue) ) { str += pre.nodeValue; pre = pre.nextSibling; } if (pre.nodeName != "BR") { var match = pre.nodeValue.match( new RegExp("^([\\s" + domUtils.fillChar + "]+)") ); if (match && match[1]) { str += match[1]; } } if (str) { str = me.document.createTextNode(str); rng.insertNode(str).setStartAfter(str); } } rng.collapse(true).select(true); } else { if (browser.version > 8) { var txt = me.document.createTextNode("\n"); var start = rng.startContainer; if (rng.startOffset == 0) { var preNode = start.previousSibling; if (preNode) { rng.insertNode(txt); var fillchar = me.document.createTextNode(" "); rng .setStartAfter(txt) .insertNode(fillchar) .setStart(fillchar, 0) .collapse(true) .select(true); } } else { rng.insertNode(txt).setStartAfter(txt); var fillchar = me.document.createTextNode(" "); start = rng.startContainer.childNodes[rng.startOffset]; if (start && !/^\n/.test(start.nodeValue)) { rng.setStartBefore(txt); } rng .insertNode(fillchar) .setStart(fillchar, 0) .collapse(true) .select(true); } } else { var tmpNode = me.document.createElement("br"); rng.insertNode(tmpNode); rng.insertNode(me.document.createTextNode(domUtils.fillChar)); rng.setStartAfter(tmpNode); pre = tmpNode.previousSibling; var tmp; while (pre) { tmp = pre; pre = pre.previousSibling; if (!pre || pre.nodeName == "BR") { pre = tmp; break; } } if (pre) { var str = ""; while ( pre && pre.nodeName != "BR" && new RegExp("^[ " + domUtils.fillChar + "]*$").test(pre.nodeValue) ) { str += pre.nodeValue; pre = pre.nextSibling; } if (pre.nodeName != "BR") { var match = pre.nodeValue.match( new RegExp("^([ " + domUtils.fillChar + "]+)") ); if (match && match[1]) { str += match[1]; } } str = me.document.createTextNode(str); rng.insertNode(str).setStartAfter(str); } rng.collapse(true).select(); } } me.fireEvent("saveScene"); return true; } }); me.addListener("tabkeydown", function (cmd, evt) { var rng = me.selection.getRange(); var pre = domUtils.findParentByTagName(rng.startContainer, "pre", true); if (pre) { me.fireEvent("saveScene"); if (evt.shiftKey) { } else { if (!rng.collapsed) { var bk = rng.createBookmark(); var start = bk.start.previousSibling; while (start) { if (pre.firstChild === start && !domUtils.isBr(start)) { pre.insertBefore(me.document.createTextNode(" "), start); break; } if (domUtils.isBr(start)) { pre.insertBefore( me.document.createTextNode(" "), start.nextSibling ); break; } start = start.previousSibling; } var end = bk.end; start = bk.start.nextSibling; if (pre.firstChild === bk.start) { pre.insertBefore( me.document.createTextNode(" "), start.nextSibling ); } while (start && start !== end) { if (domUtils.isBr(start) && start.nextSibling) { if (start.nextSibling === end) { break; } pre.insertBefore( me.document.createTextNode(" "), start.nextSibling ); } start = start.nextSibling; } rng.moveToBookmark(bk).select(); } else { var tmpNode = me.document.createTextNode(" "); rng .insertNode(tmpNode) .setStartAfter(tmpNode) .collapse(true) .select(true); } } me.fireEvent("saveScene"); return true; } }); me.addListener("beforeinserthtml", function (evtName, html) { var me = this, rng = me.selection.getRange(), pre = domUtils.findParentByTagName(rng.startContainer, "pre", true); if (pre) { if (!rng.collapsed) { rng.deleteContents(); } var htmlstr = ""; if (browser.ie && browser.version > 8) { utils.each( UE.filterNode(UE.htmlparser(html), me.options.filterTxtRules) .children, function (node) { if (node.type == "element") { if (node.tagName == "br") { htmlstr += "\n"; } else if (!dtd.$empty[node.tagName]) { utils.each(node.children, function (cn) { if (cn.type == "element") { if (cn.tagName == "br") { htmlstr += "\n"; } else if (!dtd.$empty[node.tagName]) { htmlstr += cn.innerText(); } } else { htmlstr += cn.data; } }); if (!/\n$/.test(htmlstr)) { htmlstr += "\n"; } } } else { htmlstr += node.data + "\n"; } if (!node.nextSibling() && /\n$/.test(htmlstr)) { htmlstr = htmlstr.replace(/\n$/, ""); } } ); var tmpNode = me.document.createTextNode( utils.html(htmlstr.replace(/ /g, " ")) ); rng.insertNode(tmpNode).selectNode(tmpNode).select(); } else { var frag = me.document.createDocumentFragment(); utils.each( UE.filterNode(UE.htmlparser(html), me.options.filterTxtRules) .children, function (node) { if (node.type == "element") { if (node.tagName == "br") { frag.appendChild(me.document.createElement("br")); } else if (!dtd.$empty[node.tagName]) { utils.each(node.children, function (cn) { if (cn.type == "element") { if (cn.tagName == "br") { frag.appendChild(me.document.createElement("br")); } else if (!dtd.$empty[node.tagName]) { frag.appendChild( me.document.createTextNode( utils.html(cn.innerText().replace(/ /g, " ")) ) ); } } else { frag.appendChild( me.document.createTextNode( utils.html(cn.data.replace(/ /g, " ")) ) ); } }); if (frag.lastChild.nodeName != "BR") { frag.appendChild(me.document.createElement("br")); } } } else { frag.appendChild( me.document.createTextNode( utils.html(node.data.replace(/ /g, " ")) ) ); } if (!node.nextSibling() && frag.lastChild.nodeName == "BR") { frag.removeChild(frag.lastChild); } } ); rng.insertNode(frag).select(); } return true; } }); //方向键的处理 me.addListener("keydown", function (cmd, evt) { var me = this, keyCode = evt.keyCode || evt.which; if (keyCode == 40) { var rng = me.selection.getRange(), pre, start = rng.startContainer; if ( rng.collapsed && (pre = domUtils.findParentByTagName(rng.startContainer, "pre", true)) && !pre.nextSibling ) { var last = pre.lastChild; while (last && last.nodeName == "BR") { last = last.previousSibling; } if ( last === start || (rng.startContainer === pre && rng.startOffset == pre.childNodes.length) ) { me.execCommand("insertparagraph"); domUtils.preventDefault(evt); } } } }); //trace:3395 me.addListener("delkeydown", function (type, evt) { var rng = this.selection.getRange(); rng.txtToElmBoundary(true); var start = rng.startContainer; if ( domUtils.isTagNode(start, "pre") && rng.collapsed && domUtils.isStartInblock(rng) ) { var p = me.document.createElement("p"); domUtils.fillNode(me.document, p); start.parentNode.insertBefore(p, start); domUtils.remove(start); rng.setStart(p, 0).setCursor(false, true); domUtils.preventDefault(evt); return true; } }); }; // plugins/cleardoc.js /** * 清空文档插件 * @file * @since 1.2.6.1 */ /** * 清空文档 * @command cleardoc * @method execCommand * @param { String } cmd 命令字符串 * @example * ```javascript * //editor 是编辑器实例 * editor.execCommand('cleardoc'); * ``` */ UE.commands["cleardoc"] = { execCommand: function (cmdName) { var me = this, enterTag = me.options.enterTag, range = me.selection.getRange(); if (enterTag == "br") { me.body.innerHTML = " "; range.setStart(me.body, 0).setCursor(); } else { me.body.innerHTML = " " + (ie ? "" : " ' ); node.parentNode.insertBefore(hr, node); node.parentNode.removeChild(node); } }); }); me.addOutputRule(function (node) { utils.each(node.getNodesByTagName("hr"), function (n) { if (n.getAttr("class") == "pagebreak") { var txt = UE.uNode.createText(me.options.pageBreakTag); n.parentNode.insertBefore(txt, n); n.parentNode.removeChild(n); } }); }); /** * 插入分页符 * @command pagebreak * @method execCommand * @param { String } cmd 命令字符串 * @remind 在表格中插入分页符会把表格切分成两部分 * @remind 获取编辑器内的数据时, 编辑器会把分页符转换成“_ueditor_page_break_tag_”字符串, * 以便于提交数据到服务器端后处理分页。 * @example * ```javascript * editor.execCommand( 'pagebreak'); //插入一个hr标签,带有样式类名pagebreak * ``` */ me.commands["pagebreak"] = { execCommand: function () { var range = me.selection.getRange(), hr = me.document.createElement("hr"); domUtils.setAttributes(hr, { class: "pagebreak", noshade: "noshade", size: "5" }); domUtils.unSelectable(hr); //table单独处理 var node = domUtils.findParentByTagName( range.startContainer, notBreakTags, true ), parents = [], pN; if (node) { switch (node.tagName) { case "TD": pN = node.parentNode; if (!pN.previousSibling) { var table = domUtils.findParentByTagName(pN, "table"); // var tableWrapDiv = table.parentNode; // if(tableWrapDiv && tableWrapDiv.nodeType == 1 // && tableWrapDiv.tagName == 'DIV' // && tableWrapDiv.getAttribute('dropdrag') // ){ // domUtils.remove(tableWrapDiv,true); // } table.parentNode.insertBefore(hr, table); parents = domUtils.findParents(hr, true); } else { pN.parentNode.insertBefore(hr, pN); parents = domUtils.findParents(hr); } pN = parents[1]; if (hr !== pN) { domUtils.breakParent(hr, pN); } //table要重写绑定一下拖拽 me.fireEvent("afteradjusttable", me.document); } } else { if (!range.collapsed) { range.deleteContents(); var start = range.startContainer; while ( !domUtils.isBody(start) && domUtils.isBlockElm(start) && domUtils.isEmptyNode(start) ) { range.setStartBefore(start).collapse(true); domUtils.remove(start); start = range.startContainer; } } range.insertNode(hr); var pN = hr.parentNode, nextNode; while (!domUtils.isBody(pN)) { domUtils.breakParent(hr, pN); nextNode = hr.nextSibling; if (nextNode && domUtils.isEmptyBlock(nextNode)) { domUtils.remove(nextNode); } pN = hr.parentNode; } nextNode = hr.nextSibling; var pre = hr.previousSibling; if (isHr(pre)) { domUtils.remove(pre); } else { pre && fillNode(pre); } if (!nextNode) { var p = me.document.createElement("p"); hr.parentNode.appendChild(p); domUtils.fillNode(me.document, p); range.setStart(p, 0).collapse(true); } else { if (isHr(nextNode)) { domUtils.remove(nextNode); } else { fillNode(nextNode); } range.setEndAfter(hr).collapse(false); } range.select(true); } } }; }; // plugins/wordimage.js ///import core ///commands 本地图片引导上传 ///commandsName WordImage ///commandsTitle 本地图片引导上传 ///commandsDialog dialogs\wordimage UE.plugin.register("wordimage", function () { var me = this, images = []; this.addListener("click", function (type, evt) { var el = evt.target || evt.srcElement; if ('IMG' == el.tagName && el.getAttribute('data-word-image')) { me.ui._dialogs.wordimageDialog && me.ui._dialogs.wordimageDialog.open(); } }); return { commands: { wordimage: { execCommand: function () { var images = domUtils.getElementsByTagName(me.body, "img"); var urlList = []; for (var i = 0, ci; (ci = images[i++]);) { var url = ci.getAttribute("data-word-image"); url && urlList.push(url); } return urlList; }, queryCommandState: function () { images = domUtils.getElementsByTagName(me.body, "img"); for (var i = 0, ci; (ci = images[i++]);) { if (ci.getAttribute("data-word-image")) { return 1; } } return -1; }, notNeedUndo: true } }, inputRule: function (root) { utils.each(root.getNodesByTagName("img"), function (img) { var attrs = img.attrs, flag = parseInt(attrs.width) < 128 || parseInt(attrs.height) < 43, opt = me.options, src = opt.UEDITOR_HOME_URL + "themes/default/images/spacer.gif"; if (attrs["src"] && /^(?:(file:\/+))/.test(attrs["src"])) { img.setAttr({ width: attrs.width, height: attrs.height, alt: attrs.alt, 'data-word-image': attrs.src, src: src, style: "background:url(" + (flag ? opt.themePath + opt.theme + "/images/word.gif" : opt.langPath + opt.lang + "/images/localimage.png") + ") no-repeat center center;border:1px solid #ddd" }); } }); } }; }); // plugins/autosave.js UE.plugin.register("autosave", function () { var me = this, saveKey = null; function save (editor) { var saveData; if (!editor.hasContents()) { //这里不能调用命令来删除, 会造成事件死循环 saveKey && me.removePreferences(saveKey); return; } editor._autoSaveTimer = null; saveData = me.body.innerHTML; if ( editor.fireEvent("beforeautosave", { content: saveData }) === false ) { return; } // console.log('autosave', saveKey, saveData); me.setPreferences(saveKey, saveData); editor.fireEvent("afterautosave", { content: saveData }); } return { defaultOptions: { autoSaveEnable: true, autoSaveRestore: false, autoSaveKey: null, }, bindEvents: { ready: function () { saveKey = me.getOpt('autoSaveKey'); if (!saveKey) { var _suffix = "_DraftsData", key = null; if (me.key) { key = me.key + _suffix; } else { key = (me.container.parentNode.id || "ue-common") + _suffix; } saveKey = (location.protocol + location.host + location.pathname).replace( /[.:\/]/g, "_" ) + key; } if (me.getOpt('autoSaveRestore')) { var data = me.getPreferences(saveKey); // console.log('saveKey', saveKey, data); if (data) { me.body.innerHTML = data; me.fireEvent('showmessage', { type: 'info', content: me.getLang('autosave').autoRestoreTip }) } } // console.log('saveKey', saveKey); }, beforesubmit: function () { if (!me.getOpt("autoSaveEnable") || !saveKey) { return; } me.execCommand('clear_auto_save_content'); }, contentchange: function () { if (!me.isReady) { return; } if (!me.getOpt("autoSaveEnable") || !saveKey) { return; } if (me._autoSaveTimer) { window.clearTimeout(me._autoSaveTimer); } me._autoSaveTimer = window.setTimeout(function () { save(me); }, 1000); } }, commands: { clear_auto_save_content: { execCommand: function (cmd, name) { if (saveKey && me.getPreferences(saveKey)) { me.removePreferences(saveKey); } }, notNeedUndo: true, ignoreContentChange: true }, set_auto_save_content: { execCommand: function (cmd, name) { save(me); }, notNeedUndo: true, ignoreContentChange: true }, get_auto_save_content: { execCommand: function (cmd, name) { return me.getPreferences(saveKey) || ""; }, notNeedUndo: true, ignoreContentChange: true }, auto_save_restore: { execCommand: function (cmd, name) { if (saveKey) { me.body.innerHTML = me.getPreferences(saveKey) || " " + domUtils.fillHtml + " "; me.focus(true); } }, queryCommandState: function () { return saveKey ? (me.getPreferences(saveKey) === null ? -1 : 0) : -1; }, notNeedUndo: true, ignoreContentChange: true } } }; }); // plugins/formula.js UE.plugin.register("formula", function () { var me = this, images = []; return { commands: { formula: { execCommand: function (cmdName, value) { var range = me.selection.getRange(), img = range.getClosedNode(); value = encodeURIComponent(value); var formulaConfig = me.getOpt('formulaConfig'); var src = formulaConfig.imageUrlTemplate.replace(/\{\}/, value); if (img) { img.setAttribute("src", src); } else { me.execCommand("insertHtml", ''); } }, } }, }; }); // plugins/dragdrop.js UE.plugins["dragdrop"] = function () { var me = this; me.ready(function () { domUtils.on(this.body, "dragend", function () { var rng = me.selection.getRange(); var node = rng.getClosedNode() || me.selection.getStart(); if (node && node.tagName == "IMG") { var pre = node.previousSibling, next; while ((next = node.nextSibling)) { if ( next.nodeType == 1 && next.tagName == "SPAN" && !next.firstChild ) { domUtils.remove(next); } else { break; } } if ( ((pre && pre.nodeType == 1 && !domUtils.isEmptyBlock(pre)) || !pre) && (!next || (next && !domUtils.isEmptyBlock(next))) ) { if (pre && pre.tagName == "P" && !domUtils.isEmptyBlock(pre)) { pre.appendChild(node); domUtils.moveChild(next, pre); domUtils.remove(next); } else if ( next && next.tagName == "P" && !domUtils.isEmptyBlock(next) ) { next.insertBefore(node, next.firstChild); } if (pre && pre.tagName == "P" && domUtils.isEmptyBlock(pre)) { domUtils.remove(pre); } if (next && next.tagName == "P" && domUtils.isEmptyBlock(next)) { domUtils.remove(next); } rng.selectNode(node).select(); me.fireEvent("saveScene"); } } }); }); me.addListener("keyup", function (type, evt) { var keyCode = evt.keyCode || evt.which; if (keyCode == 13) { var rng = me.selection.getRange(), node; if ( (node = domUtils.findParentByTagName(rng.startContainer, "p", true)) ) { if (domUtils.getComputedStyle(node, "text-align") == "center") { domUtils.removeStyle(node, "text-align"); } } } }); }; // plugins/undo.js /** * undo redo * @file * @since 1.2.6.1 */ /** * 撤销上一次执行的命令 * @command undo * @method execCommand * @param { String } cmd 命令字符串 * @example * ```javascript * editor.execCommand( 'undo' ); * ``` */ /** * 重做上一次执行的命令 * @command redo * @method execCommand * @param { String } cmd 命令字符串 * @example * ```javascript * editor.execCommand( 'redo' ); * ``` */ UE.plugins["undo"] = function () { var saveSceneTimer; var me = this, maxUndoCount = me.options.maxUndoCount || 20, maxInputCount = me.options.maxInputCount || 20, fillchar = new RegExp(domUtils.fillChar + "|", "gi"); // ie会产生多余的 var noNeedFillCharTags = { ol: 1, ul: 1, table: 1, tbody: 1, tr: 1, body: 1 }; var orgState = me.options.autoClearEmptyNode; function compareAddr (indexA, indexB) { if (indexA.length != indexB.length) return 0; for (var i = 0, l = indexA.length; i < l; i++) { if (indexA[i] != indexB[i]) return 0; } return 1; } function compareRangeAddress (rngAddrA, rngAddrB) { if (rngAddrA.collapsed != rngAddrB.collapsed) { return 0; } if ( !compareAddr(rngAddrA.startAddress, rngAddrB.startAddress) || !compareAddr(rngAddrA.endAddress, rngAddrB.endAddress) ) { return 0; } return 1; } function UndoManager () { this.list = []; this.index = 0; this.hasUndo = false; this.hasRedo = false; this.undo = function () { if (this.hasUndo) { if (!this.list[this.index - 1] && this.list.length == 1) { this.reset(); return; } while ( this.list[this.index].content == this.list[this.index - 1].content ) { this.index--; if (this.index == 0) { return this.restore(0); } } this.restore(--this.index); } }; this.redo = function () { if (this.hasRedo) { while ( this.list[this.index].content == this.list[this.index + 1].content ) { this.index++; if (this.index == this.list.length - 1) { return this.restore(this.index); } } this.restore(++this.index); } }; this.restore = function () { var me = this.editor; var scene = this.list[this.index]; var root = UE.htmlparser(scene.content.replace(fillchar, "")); me.options.autoClearEmptyNode = false; me.filterInputRule(root); me.options.autoClearEmptyNode = orgState; //trace:873 //去掉展位符 me.document.body.innerHTML = root.toHtml(); me.fireEvent("afterscencerestore"); //处理undo后空格不展位的问题 if (browser.ie) { utils.each( domUtils.getElementsByTagName(me.document, "td th caption p"), function (node) { if (domUtils.isEmptyNode(node)) { domUtils.fillNode(me.document, node); } } ); } try { var rng = new dom.Range(me.document).moveToAddress(scene.address); rng.select( noNeedFillCharTags[rng.startContainer.nodeName.toLowerCase()] ); } catch (e) { } this.update(); this.clearKey(); //不能把自己reset了 me.fireEvent("reset", true); }; this.getScene = function () { var me = this.editor; var rng = me.selection.getRange(), rngAddress = rng.createAddress(false, true); me.fireEvent("beforegetscene"); var root = UE.htmlparser(me.body.innerHTML); me.options.autoClearEmptyNode = false; me.filterOutputRule(root); me.options.autoClearEmptyNode = orgState; var cont = root.toHtml(); //trace:3461 //这个会引起回退时导致空格丢失的情况 // browser.ie && (cont = cont.replace(/> <').replace(/\s*\s*/g, '>')); me.fireEvent("aftergetscene"); return { address: rngAddress, content: cont }; }; this.save = function (notCompareRange, notSetCursor) { clearTimeout(saveSceneTimer); var currentScene = this.getScene(notSetCursor), lastScene = this.list[this.index]; if (!lastScene || (lastScene && lastScene.content != currentScene.content)) { // 使用异步避免直接在事件中取值滞后一个字符 setTimeout(function () { me.trigger("contentchange"); }, 0); } //内容相同位置相同不存 if ( lastScene && lastScene.content == currentScene.content && (notCompareRange ? 1 : compareRangeAddress(lastScene.address, currentScene.address)) ) { return; } this.list = this.list.slice(0, this.index + 1); this.list.push(currentScene); //如果大于最大数量了,就把最前的剔除 if (this.list.length > maxUndoCount) { this.list.shift(); } this.index = this.list.length - 1; this.clearKey(); //跟新undo/redo状态 this.update(); }; this.update = function () { this.hasRedo = !!this.list[this.index + 1]; this.hasUndo = !!this.list[this.index - 1]; }; this.reset = function () { this.list = []; this.index = 0; this.hasUndo = false; this.hasRedo = false; this.clearKey(); }; this.clearKey = function () { keycont = 0; lastKeyCode = null; }; } me.undoManger = new UndoManager(); me.undoManger.editor = me; function saveScene () { this.undoManger.save(); } me.addListener("saveScene", function () { var args = Array.prototype.splice.call(arguments, 1); this.undoManger.save.apply(this.undoManger, args); }); // me.addListener('beforeexeccommand', saveScene); // me.addListener('afterexeccommand', saveScene); me.addListener("reset", function (type, exclude) { if (!exclude) { this.undoManger.reset(); } }); me.commands["redo"] = me.commands["undo"] = { execCommand: function (cmdName) { this.undoManger[cmdName](); }, queryCommandState: function (cmdName) { return this.undoManger[ "has" + (cmdName.toLowerCase() == "undo" ? "Undo" : "Redo") ] ? 0 : -1; }, notNeedUndo: 1 }; var keys = { // /*Backspace*/ 8:1, /*Delete*/ 46:1, /*Shift*/ 16: 1, /*Ctrl*/ 17: 1, /*Alt*/ 18: 1, 37: 1, 38: 1, 39: 1, 40: 1 }, keycont = 0, lastKeyCode; //输入法状态下不计算字符数 var inputType = false; me.addListener("ready", function () { domUtils.on(this.body, "compositionstart", function () { inputType = true; }); domUtils.on(this.body, "compositionend", function () { inputType = false; }); }); //快捷键 me.addshortcutkey({ Undo: "ctrl+90", //undo Redo: "ctrl+89" //redo }); var isCollapsed = true; me.addListener("keyup", function (type, evt) { var me = this; var keyCode = evt.keyCode || evt.which; if ( !keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey ) { if (inputType) return; if (!me.selection.getRange().collapsed) { me.undoManger.save(false, true); isCollapsed = false; return; } if (me.undoManger.list.length === 0) { me.undoManger.save(true); } clearTimeout(saveSceneTimer); function save (cont) { cont.undoManger.save(false, true); cont.fireEvent("selectionchange"); } saveSceneTimer = setTimeout(function () { if (inputType) { var intervalTimer = setInterval(function () { if (!inputType) { save(me); clearInterval(intervalTimer); } }, 300); return; } save(me); }, 200); lastKeyCode = keyCode; keycont++; if (keycont >= maxInputCount) { save(me); } } }); me.addListener("keyup", function (type, evt) { var keyCode = evt.keyCode || evt.which; if ( !keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey ) { if (inputType) return; if (!isCollapsed) { this.undoManger.save(false, true); isCollapsed = true; } } }); //扩展实例,添加关闭和开启命令undo me.stopCmdUndo = function () { me.__hasEnterExecCommand = true; }; me.startCmdUndo = function () { me.__hasEnterExecCommand = false; }; }; // plugins/copy.js UE.plugin.register("copy", function () { var me = this; function initZeroClipboard () { ZeroClipboard.config({ debug: false, swfPath: me.options.UEDITOR_HOME_URL + "third-party/zeroclipboard/ZeroClipboard.swf" }); var client = (me.zeroclipboard = new ZeroClipboard()); // 复制内容 client.on("copy", function (e) { var client = e.client, rng = me.selection.getRange(), div = document.createElement("div"); div.appendChild(rng.cloneContents()); client.setText(div.innerText || div.textContent); client.setHtml(div.innerHTML); rng.select(); }); // hover事件传递到target client.on("mouseover mouseout", function (e) { var target = e.target; if (target) { if (e.type == "mouseover") { domUtils.addClass(target, "edui-state-hover"); } else if (e.type == "mouseout") { domUtils.removeClasses(target, "edui-state-hover"); } } }); // flash加载不成功 client.on("wrongflash noflash", function () { ZeroClipboard.destroy(); }); // 触发事件 me.fireEvent("zeroclipboardready", client); } return { bindEvents: { ready: function () { if (!browser.ie) { if (window.ZeroClipboard) { initZeroClipboard(); } else { utils.loadFile( document, { src: me.options.UEDITOR_HOME_URL + "third-party/zeroclipboard/ZeroClipboard.js", tag: "script", type: "text/javascript", defer: "defer" }, function () { initZeroClipboard(); } ); } } } }, commands: { copy: { execCommand: function (cmd) { if (!me.document.execCommand("copy")) { alert(me.getLang("copymsg")); } } } } }; }); // plugins/paste.js ///import core ///import plugins/inserthtml.js ///import plugins/undo.js ///import plugins/serialize.js ///commands 粘贴 ///commandsName PastePlain ///commandsTitle 纯文本粘贴模式 /** * @description 粘贴 * @author zhanyi */ UE.plugins["paste"] = function () { function getClipboardData (callback) { var doc = this.document; if (doc.getElementById("baidu_pastebin")) { return; } var range = this.selection.getRange(), bk = range.createBookmark(), //创建剪贴的容器div pastebin = doc.createElement("div"); pastebin.id = "baidu_pastebin"; // Safari 要求div必须有内容,才能粘贴内容进来 browser.webkit && pastebin.appendChild( doc.createTextNode(domUtils.fillChar + domUtils.fillChar) ); doc.body.appendChild(pastebin); //trace:717 隐藏的span不能得到top //bk.start.innerHTML = ' '; bk.start.style.display = ""; pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:" + //要在现在光标平行的位置加入,否则会出现跳动的问题 domUtils.getXY(bk.start).y + "px"; range.selectNodeContents(pastebin).select(true); setTimeout(function () { if (browser.webkit) { for ( var i = 0, pastebins = doc.querySelectorAll("#baidu_pastebin"), pi; (pi = pastebins[i++]); ) { if (domUtils.isEmptyNode(pi)) { domUtils.remove(pi); } else { pastebin = pi; break; } } } try { pastebin.parentNode.removeChild(pastebin); } catch (e) { } range.moveToBookmark(bk).select(true); callback(pastebin); }, 0); } var me = this; me.setOpt({ retainOnlyLabelPasted: false }); var txtContent, htmlContent, address; function getPureHtml (html) { return html.replace(/<(\/?)([\w\-]+)([^>]*)>/gi, function ( a, b, tagName, attrs ) { tagName = tagName.toLowerCase(); if ({ img: 1 }[tagName]) { return a; } attrs = attrs.replace( /([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi, function (str, atr, val) { if ( { src: 1, href: 1, name: 1 }[atr.toLowerCase()] ) { return atr + "=" + val + " "; } return ""; } ); if ( { span: 1, div: 1 }[tagName] ) { return ""; } else { return "<" + b + tagName + " " + utils.trim(attrs) + ">"; } }); } function filter (div) { var html; if (div.firstChild) { //去掉cut中添加的边界值 var nodes = domUtils.getElementsByTagName(div, "span"); for (var i = 0, ni; (ni = nodes[i++]);) { if (ni.id == "_baidu_cut_start" || ni.id == "_baidu_cut_end") { domUtils.remove(ni); } } if (browser.webkit) { var brs = div.querySelectorAll("div br"); for (var i = 0, bi; (bi = brs[i++]);) { var pN = bi.parentNode; if (pN.tagName == "DIV" && pN.childNodes.length == 1) { pN.innerHTML = ""); } //去掉末尾的空白 var p = li.firstChild(); var lastChild = p.lastChild(); if ( lastChild && lastChild.type === "text" && /^\s*$/.test(lastChild.data) ) { p.removeChild(lastChild); } }); if (me.options.autoTransWordToList) { var orderlisttype = { num1: /^\d+\)/, decimal: /^\d+\./, "lower-alpha": /^[a-z]+\)/, "upper-alpha": /^[A-Z]+\./, cn: /^[\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+[\u3001]/, cn2: /^\([\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+\)/ }, unorderlisttype = { square: "n" }; function checkListType (content, container) { var span = container.firstChild(); if ( span && span.type === "element" && span.tagName === "span" && /Wingdings|Symbol/.test(span.getStyle("font-family")) ) { for (var p in unorderlisttype) { if (unorderlisttype[p] == span.data) { return p; } } return "disc"; } for (var p in orderlisttype) { if (orderlisttype[p].test(content)) { return p; } } } utils.each(root.getNodesByTagName("p"), function (node) { if (node.getAttr("class") !== "MsoListParagraph") { return; } //word粘贴过来的会带有margin要去掉,但这样也可能会误命中一些央视 node.setStyle("margin", ""); node.setStyle("margin-left", ""); node.setAttr("class", ""); function appendLi (list, p, type) { if (list.tagName === "ol") { if (browser.ie) { var first = p.firstChild(); if ( first.type === "element" && first.tagName === "span" && orderlisttype[type].test(first.innerText()) ) { p.removeChild(first); } } else { p.innerHTML(p.innerHTML().replace(orderlisttype[type], "")); } } else { p.removeChild(p.firstChild()); } var li = UE.uNode.createElement("li"); li.appendChild(p); list.appendChild(li); } var tmp = node, type, cacheNode = node; if ( node.parentNode.tagName !== "li" && (type = checkListType(node.innerText(), node)) ) { var list = UE.uNode.createElement( me.options.insertorderedlist.hasOwnProperty(type) ? "ol" : "ul" ); // if (customStyle[type]) { // list.setAttr("class", "custom_" + type); // } else { list.setStyle("list-style-type", type); // } while ( node && node.parentNode.tagName !== "li" && checkListType(node.innerText(), node) ) { tmp = node.nextSibling(); if (!tmp) { node.parentNode.insertBefore(list, node); } appendLi(list, node, type); node = tmp; } if (!list.parentNode && node && node.parentNode) { node.parentNode.insertBefore(list, node); } } var span = cacheNode.firstChild(); if ( span && span.type == "element" && span.tagName == "span" && /^\s*( )+\s*$/.test(span.innerText()) ) { span.parentNode.removeChild(span); } }); } }); //调整索引标签 me.addListener("contentchange", function () { adjustListStyle(me.document); }); function adjustListStyle (doc, ignore) { utils.each(domUtils.getElementsByTagName(doc, "ol ul"), function (node) { if (!domUtils.inDoc(node, doc)) return; var parent = node.parentNode; if (parent.tagName === node.tagName) { var nodeStyleType = getStyle(node) || (node.tagName === "OL" ? "decimal" : "disc"), parentStyleType = getStyle(parent) || (parent.tagName === "OL" ? "decimal" : "disc"); if (nodeStyleType === parentStyleType) { var styleIndex = utils.indexOf( listStyle[node.tagName], nodeStyleType ); styleIndex = styleIndex + 1 === listStyle[node.tagName].length ? 0 : styleIndex + 1; setListStyle(node, listStyle[node.tagName][styleIndex]); } } var index = 0, type = 2; if (domUtils.hasClass(node, /custom_/)) { if ( !( /[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent, /custom_/) ) ) { type = 1; } } else { if ( /[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent, /custom_/) ) { type = 3; } } var style = domUtils.getStyle(node, "list-style-type"); style && (node.style.cssText = "list-style-type:" + style); node.className = utils.trim(node.className.replace(/list-paddingleft-\w+/, "")) + " list-paddingleft-" + type; utils.each(domUtils.getElementsByTagName(node, "li"), function (li) { li.style.cssText && (li.style.cssText = ""); if (!li.firstChild) { domUtils.remove(li); return; } if (li.parentNode !== node) { return; } index++; if (domUtils.hasClass(node, /custom_/)) { var paddingLeft = 1, currentStyle = getStyle(node); if (node.tagName === "OL") { if (currentStyle) { switch (currentStyle) { case "cn": case "cn1": case "cn2": if ( index > 10 && (index % 10 === 0 || (index > 10 && index < 20)) ) { paddingLeft = 2; } else if (index > 20) { paddingLeft = 3; } break; case "num2": if (index > 9) { paddingLeft = 2; } } } li.className = // "list-" + // customStyle[currentStyle] + // index + // " " + "list-" + currentStyle + "-paddingleft-" + paddingLeft; } else { li.className = // "list-" + // customStyle[currentStyle] + // " " + "list-" + currentStyle + "-paddingleft"; } } else { li.className = li.className.replace(/list-[\w\-]+/gi, ""); } var className = li.getAttribute("class"); if (className !== null && !className.replace(/\s/g, "")) { domUtils.removeAttributes(li, "class"); } }); !ignore && adjustList( node, node.tagName.toLowerCase(), getStyle(node) || domUtils.getStyle(node, "list-style-type"), true ); }); } function adjustList (list, tag, style, ignoreEmpty) { var nextList = list.nextSibling; if ( nextList && nextList.nodeType === 1 && nextList.tagName.toLowerCase() === tag && (getStyle(nextList) || domUtils.getStyle(nextList, "list-style-type") || (tag == "ol" ? "decimal" : "disc")) == style ) { domUtils.moveChild(nextList, list); if (nextList.childNodes.length === 0) { domUtils.remove(nextList); } } if (nextList && domUtils.isFillChar(nextList)) { domUtils.remove(nextList); } var preList = list.previousSibling; if ( preList && preList.nodeType === 1 && preList.tagName.toLowerCase() == tag && (getStyle(preList) || domUtils.getStyle(preList, "list-style-type") || (tag == "ol" ? "decimal" : "disc")) === style ) { domUtils.moveChild(list, preList); } if (preList && domUtils.isFillChar(preList)) { domUtils.remove(preList); } !ignoreEmpty && domUtils.isEmptyBlock(list) && domUtils.remove(list); if (getStyle(list)) { adjustListStyle(list.ownerDocument, true); } } function setListStyle (list, style) { // if (customStyle[style]) { // list.className = "custom_" + style; // } try { domUtils.setStyle(list, "list-style-type", style); } catch (e) { } } function clearEmptySibling (node) { var tmpNode = node.previousSibling; if (tmpNode && domUtils.isEmptyBlock(tmpNode)) { domUtils.remove(tmpNode); } tmpNode = node.nextSibling; if (tmpNode && domUtils.isEmptyBlock(tmpNode)) { domUtils.remove(tmpNode); } } me.addListener("keydown", function (type, evt) { function preventAndSave () { evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false); me.fireEvent("contentchange"); me.undoManger && me.undoManger.save(); } function findList (node, filterFn) { while (node && !domUtils.isBody(node)) { if (filterFn(node)) { return null; } if (node.nodeType === 1 && /[ou]l/i.test(node.tagName)) { return node; } node = node.parentNode; } return null; } var keyCode = evt.keyCode || evt.which; if (keyCode === 13 && !evt.shiftKey) { //回车 var rng = me.selection.getRange(), parent = domUtils.findParent( rng.startContainer, function (node) { return domUtils.isBlockElm(node); }, true ), li = domUtils.findParentByTagName(rng.startContainer, "li", true); if (parent && parent.tagName !== "PRE" && !li) { var html = parent.innerHTML.replace( new RegExp(domUtils.fillChar, "g"), "" ); if (/^\s*1\s*\.[^\d]/.test(html)) { parent.innerHTML = html.replace(/^\s*1\s*\./, ""); rng.setStartAtLast(parent).collapse(true).select(); me.__hasEnterExecCommand = true; me.execCommand("insertorderedlist"); me.__hasEnterExecCommand = false; } } var range = me.selection.getRange(), start = findList(range.startContainer, function (node) { return node.tagName === "TABLE"; }), end = range.collapsed ? start : findList(range.endContainer, function (node) { return node.tagName === "TABLE"; }); if (start && end && start === end) { if (!range.collapsed) { start = domUtils.findParentByTagName( range.startContainer, "li", true ); end = domUtils.findParentByTagName(range.endContainer, "li", true); if (start && end && start === end) { range.deleteContents(); li = domUtils.findParentByTagName(range.startContainer, "li", true); if (li && domUtils.isEmptyBlock(li)) { pre = li.previousSibling; next = li.nextSibling; p = me.document.createElement("p"); domUtils.fillNode(me.document, p); parentList = li.parentNode; if (pre && next) { range.setStart(next, 0).collapse(true).select(true); domUtils.remove(li); } else { if ((!pre && !next) || !pre) { parentList.parentNode.insertBefore(p, parentList); } else { li.parentNode.parentNode.insertBefore( p, parentList.nextSibling ); } domUtils.remove(li); if (!parentList.firstChild) { domUtils.remove(parentList); } range.setStart(p, 0).setCursor(); } preventAndSave(); return; } } else { var tmpRange = range.cloneRange(), bk = tmpRange.collapse(false).createBookmark(); range.deleteContents(); tmpRange.moveToBookmark(bk); var li = domUtils.findParentByTagName( tmpRange.startContainer, "li", true ); clearEmptySibling(li); tmpRange.select(); preventAndSave(); return; } } li = domUtils.findParentByTagName(range.startContainer, "li", true); if (li) { if (domUtils.isEmptyBlock(li)) { bk = range.createBookmark(); var parentList = li.parentNode; if (li !== parentList.lastChild) { domUtils.breakParent(li, parentList); clearEmptySibling(li); } else { parentList.parentNode.insertBefore(li, parentList.nextSibling); if (domUtils.isEmptyNode(parentList)) { domUtils.remove(parentList); } } //嵌套不处理 if (!dtd.$list[li.parentNode.tagName]) { if (!domUtils.isBlockElm(li.firstChild)) { p = me.document.createElement("p"); li.parentNode.insertBefore(p, li); while (li.firstChild) { p.appendChild(li.firstChild); } domUtils.remove(li); } else { domUtils.remove(li, true); } } range.moveToBookmark(bk).select(); } else { var first = li.firstChild; if (!first || !domUtils.isBlockElm(first)) { var p = me.document.createElement("p"); !li.firstChild && domUtils.fillNode(me.document, p); while (li.firstChild) { p.appendChild(li.firstChild); } li.appendChild(p); first = p; } var span = me.document.createElement("span"); range.insertNode(span); domUtils.breakParent(span, li); var nextLi = span.nextSibling; first = nextLi.firstChild; if (!first) { p = me.document.createElement("p"); domUtils.fillNode(me.document, p); nextLi.appendChild(p); first = p; } if (domUtils.isEmptyNode(first)) { first.innerHTML = ""; domUtils.fillNode(me.document, first); } range.setStart(first, 0).collapse(true).shrinkBoundary().select(); domUtils.remove(span); var pre = nextLi.previousSibling; if (pre && domUtils.isEmptyBlock(pre)) { pre.innerHTML = ""; domUtils.fillNode(me.document, pre.firstChild); } } // } preventAndSave(); } } } if (keyCode === 8) { //修中ie中li下的问题 range = me.selection.getRange(); if (range.collapsed && domUtils.isStartInblock(range)) { tmpRange = range.cloneRange().trimBoundary(); li = domUtils.findParentByTagName(range.startContainer, "li", true); //要在li的最左边,才能处理 if (li && domUtils.isStartInblock(tmpRange)) { start = domUtils.findParentByTagName(range.startContainer, "p", true); if (start && start !== li.firstChild) { var parentList = domUtils.findParentByTagName(start, ["ol", "ul"]); domUtils.breakParent(start, parentList); clearEmptySibling(start); me.fireEvent("contentchange"); range.setStart(start, 0).setCursor(false, true); me.fireEvent("saveScene"); domUtils.preventDefault(evt); return; } if (li && (pre = li.previousSibling)) { if (keyCode === 46 && li.childNodes.length) { return; } //有可能上边的兄弟节点是个2级菜单,要追加到2级菜单的最后的li if (dtd.$list[pre.tagName]) { pre = pre.lastChild; } me.undoManger && me.undoManger.save(); first = li.firstChild; if (domUtils.isBlockElm(first)) { if (domUtils.isEmptyNode(first)) { // range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true); pre.appendChild(first); range.setStart(first, 0).setCursor(false, true); //first不是唯一的节点 while (li.firstChild) { pre.appendChild(li.firstChild); } } else { span = me.document.createElement("span"); range.insertNode(span); //判断pre是否是空的节点,如果是 " + (browser.ie ? "" : " " + (browser.ie ? "" : " " + (browser.ie ? "" : " "); doSave = 1; } } else { //chrome remove div if (start.nodeType == 1) { var tmp = me.document.createTextNode(""), div; range.insertNode(tmp); div = domUtils.findParentByTagName(tmp, "div", true); if (div) { var p = me.document.createElement("p"); while (div.firstChild) { p.appendChild(div.firstChild); } div.parentNode.insertBefore(p, div); domUtils.remove(div); range.setStartBefore(tmp).setCursor(); doSave = 1; } domUtils.remove(tmp); } } if (me.undoManger && doSave) { me.undoManger.save(); } } //没有站位符,会出现多行的问题 browser.opera && range.select(); } else { me.fireEvent("saveScene", true, true); } } }); me.addListener("keydown", function (type, evt) { var keyCode = evt.keyCode || evt.which; if (keyCode == 13) { //回车 if (me.fireEvent("beforeenterkeydown")) { domUtils.preventDefault(evt); return; } me.fireEvent("saveScene", true, true); hTag = ""; var range = me.selection.getRange(); if (!range.collapsed) { //跨td不能删 var start = range.startContainer, end = range.endContainer, startTd = domUtils.findParentByTagName(start, "td", true), endTd = domUtils.findParentByTagName(end, "td", true); if ( (startTd && endTd && startTd !== endTd) || (!startTd && endTd) || (startTd && !endTd) ) { evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false); return; } } if (tag == "p") { if (!browser.ie) { start = domUtils.findParentByTagName( range.startContainer, [ "ol", "ul", "p", "h1", "h2", "h3", "h4", "h5", "h6", "blockquote", "caption" ], true ); //opera下执行formatblock会在table的场景下有问题,回车在opera原生支持很好,所以暂时在opera去掉调用这个原生的command //trace:2431 if (!start && !browser.opera) { me.document.execCommand("formatBlock", false, " ");
if (browser.gecko) {
range = me.selection.getRange();
start = domUtils.findParentByTagName(
range.startContainer,
"p",
true
);
start && domUtils.removeDirtyAttr(start);
}
} else {
hTag = start.tagName;
start.tagName.toLowerCase() == "p" &&
browser.gecko &&
domUtils.removeDirtyAttr(start);
}
}
} else {
evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false);
if (!range.collapsed) {
range.deleteContents();
start = range.startContainer;
if (
start.nodeType == 1 &&
(start = start.childNodes[range.startOffset])
) {
while (start.nodeType == 1) {
if (dtd.$empty[start.tagName]) {
range.setStartBefore(start).setCursor();
if (me.undoManger) {
me.undoManger.save();
}
return false;
}
if (!start.firstChild) {
var br = range.document.createElement("br");
start.appendChild(br);
range.setStart(start, 0).setCursor();
if (me.undoManger) {
me.undoManger.save();
}
return false;
}
start = start.firstChild;
}
if (start === range.startContainer.childNodes[range.startOffset]) {
br = range.document.createElement("br");
range.insertNode(br).setCursor();
} else {
range.setStart(start, 0).setCursor();
}
} else {
br = range.document.createElement("br");
range.insertNode(br).setStartAfter(br).setCursor();
}
} else {
br = range.document.createElement("br");
range.insertNode(br);
var parent = br.parentNode;
if (parent.lastChild === br) {
br.parentNode.insertBefore(br.cloneNode(true), br);
range.setStartBefore(br);
} else {
range.setStartAfter(br);
}
range.setCursor();
}
}
}
});
};
// plugins/keystrokes.js
/* 处理特殊键的兼容性问题 */
UE.plugins["keystrokes"] = function () {
var me = this;
var collapsed = true;
me.addListener("keydown", function (type, evt) {
var keyCode = evt.keyCode || evt.which,
rng = me.selection.getRange();
//处理全选的情况
if (
!rng.collapsed &&
!(evt.ctrlKey || evt.shiftKey || evt.altKey || evt.metaKey) &&
((keyCode >= 65 && keyCode <= 90) ||
(keyCode >= 48 && keyCode <= 57) ||
(keyCode >= 96 && keyCode <= 111) ||
{
13: 1,
8: 1,
46: 1
}[keyCode])
) {
var tmpNode = rng.startContainer;
if (domUtils.isFillChar(tmpNode)) {
rng.setStartBefore(tmpNode);
}
tmpNode = rng.endContainer;
if (domUtils.isFillChar(tmpNode)) {
rng.setEndAfter(tmpNode);
}
rng.txtToElmBoundary();
//结束边界可能放到了br的前边,要把br包含进来
// x[xxx] " + (browser.ie ? "" : " " }); rng.insertNode(tmpNode).setStart(tmpNode, 0).setCursor(false, true); } } //chrome下如果删除了inline标签,浏览器会有记忆,在输入文字还是会套上刚才删除的标签,所以这里再选一次就不会了 if ( !collapsed && (rng.startContainer.nodeType == 3 || (rng.startContainer.nodeType == 1 && domUtils.isEmptyBlock(rng.startContainer))) ) { if (browser.ie) { var span = rng.document.createElement("span"); rng.insertNode(span).setStartBefore(span).collapse(true); rng.select(); domUtils.remove(span); } else { rng.select(); } } } }); }; // plugins/fiximgclick.js ///import core ///commands 修复chrome下图片不能点击的问题,出现八个角可改变大小 ///commandsName FixImgClick ///commandsTitle 修复chrome下图片不能点击的问题,出现八个角可改变大小 //修复chrome下图片不能点击的问题,出现八个角可改变大小 UE.plugins["fiximgclick"] = (function () { var elementUpdated = false; function Scale () { this.editor = null; this.resizer = null; this.cover = null; this.doc = document; this.prePos = { x: 0, y: 0 }; this.startPos = { x: 0, y: 0 }; } (function () { var rect = [ //[left, top, width, height] [0, 0, -1, -1], [0, 0, 0, -1], [0, 0, 1, -1], [0, 0, -1, 0], [0, 0, 1, 0], [0, 0, -1, 1], [0, 0, 0, 1], [0, 0, 1, 1] ]; Scale.prototype = { init: function (editor) { var me = this; me.editor = editor; me.startPos = this.prePos = { x: 0, y: 0 }; me.dragId = -1; var hands = [], cover = (me.cover = document.createElement("div")), resizer = (me.resizer = document.createElement("div")); cover.id = me.editor.ui.id + "_imagescale_cover"; cover.style.cssText = "position:absolute;display:none;z-index:" + me.editor.options.zIndex + ";filter:alpha(opacity=0); opacity:0;background:#CCC;"; domUtils.on(cover, "mousedown", function (e) { me.hide(); }); for (var i = 0; i < 8; i++) { hands.push( '' ); } resizer.id = me.editor.ui.id + "_imagescale"; resizer.className = "edui-editor-imagescale"; resizer.innerHTML = hands.join(""); resizer.style.cssText += ";display:none;border:1px solid #3b77ff;z-index:" + me.editor.options.zIndex + ";"; me.editor.ui.getDom().appendChild(cover); me.editor.ui.getDom().appendChild(resizer); me.initStyle(); me.initEvents(); }, initStyle: function () { utils.cssRule( "imagescale", ".edui-editor-imagescale{display:none;position:absolute;border:1px solid #38B2CE;cursor:hand;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;}" + ".edui-editor-imagescale span{position:absolute;width:6px;height:6px;overflow:hidden;font-size:0px;display:block;background-color:#3C9DD0;}" + ".edui-editor-imagescale .edui-editor-imagescale-hand0{cursor:nw-resize;top:0;margin-top:-4px;left:0;margin-left:-4px;}" + ".edui-editor-imagescale .edui-editor-imagescale-hand1{cursor:n-resize;top:0;margin-top:-4px;left:50%;margin-left:-4px;}" + ".edui-editor-imagescale .edui-editor-imagescale-hand2{cursor:ne-resize;top:0;margin-top:-4px;left:100%;margin-left:-3px;}" + ".edui-editor-imagescale .edui-editor-imagescale-hand3{cursor:w-resize;top:50%;margin-top:-4px;left:0;margin-left:-4px;}" + ".edui-editor-imagescale .edui-editor-imagescale-hand4{cursor:e-resize;top:50%;margin-top:-4px;left:100%;margin-left:-3px;}" + ".edui-editor-imagescale .edui-editor-imagescale-hand5{cursor:sw-resize;top:100%;margin-top:-3px;left:0;margin-left:-4px;}" + ".edui-editor-imagescale .edui-editor-imagescale-hand6{cursor:s-resize;top:100%;margin-top:-3px;left:50%;margin-left:-4px;}" + ".edui-editor-imagescale .edui-editor-imagescale-hand7{cursor:se-resize;top:100%;margin-top:-3px;left:100%;margin-left:-3px;}" ); }, initEvents: function () { var me = this; me.startPos.x = me.startPos.y = 0; me.isDraging = false; }, _eventHandler: function (e) { var me = this; switch (e.type) { case "mousedown": var hand = e.target || e.srcElement, hand; if ( hand.className.indexOf("edui-editor-imagescale-hand") !== -1 && me.dragId === -1 ) { me.dragId = hand.className.slice(-1); me.startPos.x = me.prePos.x = e.clientX; me.startPos.y = me.prePos.y = e.clientY; domUtils.on(me.doc, "mousemove", me.proxy(me._eventHandler, me)); } break; case "mousemove": if (me.dragId !== -1) { me.updateContainerStyle(me.dragId, { x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y }); me.prePos.x = e.clientX; me.prePos.y = e.clientY; elementUpdated = true; me.updateTargetElement(); } break; case "mouseup": if (me.dragId !== -1) { me.updateContainerStyle(me.dragId, { x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y }); me.updateTargetElement(); if (me.target.parentNode) { me.attachTo(me.target); } me.dragId = -1; } domUtils.un(me.doc, "mousemove", me.proxy(me._eventHandler, me)); //修复只是点击挪动点,但没有改变大小,不应该触发contentchange if (elementUpdated) { elementUpdated = false; me.editor.fireEvent("contentchange"); } break; default: break; } }, updateTargetElement: function () { var me = this; domUtils.setStyles(me.target, { width: me.resizer.style.width, height: me.resizer.style.height }); me.target.width = parseInt(me.resizer.style.width); me.target.height = parseInt(me.resizer.style.height); me.attachTo(me.target); }, updateContainerStyle: function (dir, offset) { var me = this, dom = me.resizer, tmp; if (rect[dir][0] != 0) { tmp = parseInt(dom.style.left) + offset.x; dom.style.left = me._validScaledProp("left", tmp) + "px"; } if (rect[dir][1] != 0) { tmp = parseInt(dom.style.top) + offset.y; dom.style.top = me._validScaledProp("top", tmp) + "px"; } if (rect[dir][2] != 0) { tmp = dom.clientWidth + rect[dir][2] * offset.x; dom.style.width = me._validScaledProp("width", tmp) + "px"; } if (rect[dir][3] != 0) { tmp = dom.clientHeight + rect[dir][3] * offset.y; dom.style.height = me._validScaledProp("height", tmp) + "px"; } }, _validScaledProp: function (prop, value) { var ele = this.resizer, wrap = document; value = isNaN(value) ? 0 : value; switch (prop) { case "left": return value < 0 ? 0 : value + ele.clientWidth > wrap.clientWidth ? wrap.clientWidth - ele.clientWidth : value; case "top": return value < 0 ? 0 : value + ele.clientHeight > wrap.clientHeight ? wrap.clientHeight - ele.clientHeight : value; case "width": return value <= 0 ? 1 : value + ele.offsetLeft > wrap.clientWidth ? wrap.clientWidth - ele.offsetLeft : value; case "height": return value <= 0 ? 1 : value + ele.offsetTop > wrap.clientHeight ? wrap.clientHeight - ele.offsetTop : value; } }, hideCover: function () { this.cover.style.display = "none"; }, showCover: function () { var me = this, editorPos = domUtils.getXY(me.editor.ui.getDom()), iframePos = domUtils.getXY(me.editor.iframe); domUtils.setStyles(me.cover, { width: me.editor.iframe.offsetWidth + "px", height: me.editor.iframe.offsetHeight + "px", top: iframePos.y - editorPos.y + "px", left: iframePos.x - editorPos.x + "px", position: "absolute", display: "" }); }, show: function (targetObj) { var me = this; me.resizer.style.display = "block"; if (targetObj) { me.attachTo(targetObj); } domUtils.on(this.resizer, "mousedown", me.proxy(me._eventHandler, me)); domUtils.on(me.doc, "mouseup", me.proxy(me._eventHandler, me)); me.showCover(); me.editor.fireEvent("afterscaleshow", me); me.editor.fireEvent("saveScene"); }, hide: function () { var me = this; me.hideCover(); me.resizer.style.display = "none"; domUtils.un(me.resizer, "mousedown", me.proxy(me._eventHandler, me)); domUtils.un(me.doc, "mouseup", me.proxy(me._eventHandler, me)); me.editor.fireEvent("afterscalehide", me); }, proxy: function (fn, context) { return function (e) { return fn.apply(context || this, arguments); }; }, attachTo: function (targetObj) { var me = this, target = (me.target = targetObj), resizer = this.resizer, imgPos = domUtils.getXY(target), iframePos = domUtils.getXY(me.editor.iframe), editorPos = domUtils.getXY(resizer.parentNode); domUtils.setStyles(resizer, { width: target.width + "px", height: target.height + "px", left: iframePos.x + imgPos.x - me.editor.getScrollLeft() - editorPos.x - parseInt(resizer.style.borderLeftWidth) + "px", top: iframePos.y + imgPos.y - me.editor.getScrollTop() - editorPos.y - parseInt(resizer.style.borderTopWidth) + "px" }); } }; })(); return function () { var me = this, imageScale; me.setOpt("imageScaleEnabled", true); if (!browser.ie && me.options.imageScaleEnabled) { me.addListener("click", function (type, e) { var range = me.selection.getRange(), img = range.getClosedNode(); if (img && img.tagName === "IMG" && me.body.contentEditable !== "false" && img === e.target ) { if ( img.getAttribute("anchorname") || domUtils.hasClass(img, "uep-loading") || domUtils.hasClass(img, "uep-loading-error") ) { return; } if (!imageScale) { imageScale = new Scale(); imageScale.init(me); me.ui.getDom().appendChild(imageScale.resizer); var _keyDownHandler = function (e) { imageScale.hide(); if (imageScale.target) { me.selection.getRange().selectNode(imageScale.target).select(); } }, _mouseDownHandler = function (e) { var ele = e.target || e.srcElement; if ( ele && (ele.className === undefined || ele.className.indexOf("edui-editor-imagescale") === -1) ) { _keyDownHandler(e); } }, timer; me.addListener("afterscaleshow", function (e) { me.addListener("beforekeydown", _keyDownHandler); me.addListener("beforemousedown", _mouseDownHandler); domUtils.on(document, "keydown", _keyDownHandler); domUtils.on(document, "mousedown", _mouseDownHandler); me.selection.getNative().removeAllRanges(); }); me.addListener("afterscalehide", function (e) { me.removeListener("beforekeydown", _keyDownHandler); me.removeListener("beforemousedown", _mouseDownHandler); domUtils.un(document, "keydown", _keyDownHandler); domUtils.un(document, "mousedown", _mouseDownHandler); var target = imageScale.target; if (target.parentNode) { me.selection.getRange().selectNode(target).select(); } }); //TODO 有iframe的情况,mousedown不能往下传。。 domUtils.on(imageScale.resizer, "mousedown", function (e) { me.selection.getNative().removeAllRanges(); var ele = e.target || e.srcElement; if ( ele && ele.className.indexOf("edui-editor-imagescale-hand") === -1 ) { timer = setTimeout(function () { imageScale.hide(); if (imageScale.target) me.selection.getRange().selectNode(ele).select(); }, 200); } }); domUtils.on(imageScale.resizer, "mouseup", function (e) { var ele = e.target || e.srcElement; if ( ele && ele.className.indexOf("edui-editor-imagescale-hand") === -1 ) { clearTimeout(timer); } }); } imageScale.show(img); } else { if (imageScale && imageScale.resizer.style.display !== "none") { imageScale.hide(); } } }); } if (browser.webkit) { me.addListener("click", function (type, e) { if (e.target.tagName === "IMG" && me.body.contentEditable !== "false") { var range = new dom.Range(me.document); range.selectNode(e.target).select(); } }); } }; })(); // plugins/autolink.js ///import core ///commands 为非ie浏览器自动添加a标签 ///commandsName AutoLink ///commandsTitle 自动增加链接 /** * @description 为非ie浏览器自动添加a标签 * @author zhanyi */ UE.plugin.register( "autolink", function () { var cont = 0; return !browser.ie ? { bindEvents: { reset: function () { cont = 0; }, keydown: function (type, evt) { var me = this; var keyCode = evt.keyCode || evt.which; if (keyCode == 32 || keyCode == 13) { var sel = me.selection.getNative(), range = sel.getRangeAt(0).cloneRange(), offset, charCode; var start = range.startContainer; while (start.nodeType == 1 && range.startOffset > 0) { start = range.startContainer.childNodes[range.startOffset - 1]; if (!start) { break; } range.setStart( start, start.nodeType == 1 ? start.childNodes.length : start.nodeValue.length ); range.collapse(true); start = range.startContainer; } do { if (range.startOffset == 0) { start = range.startContainer.previousSibling; while (start && start.nodeType == 1) { start = start.lastChild; } if (!start || domUtils.isFillChar(start)) { break; } offset = start.nodeValue.length; } else { start = range.startContainer; offset = range.startOffset; } range.setStart(start, offset - 1); charCode = range.toString().charCodeAt(0); } while (charCode != 160 && charCode != 32); if ( range .toString() .replace(new RegExp(domUtils.fillChar, "g"), "") .match(/(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i) ) { while (range.toString().length) { if ( /^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i.test( range.toString() ) ) { break; } try { range.setStart( range.startContainer, range.startOffset + 1 ); } catch (e) { //trace:2121 var start = range.startContainer; while (!(next = start.nextSibling)) { if (domUtils.isBody(start)) { return; } start = start.parentNode; } range.setStart(next, 0); } } //range的开始边界已经在a标签里的不再处理 if ( domUtils.findParentByTagName( range.startContainer, "a", true ) ) { return; } var a = me.document.createElement("a"), text = me.document.createTextNode(" "), href; me.undoManger && me.undoManger.save(); a.appendChild(range.extractContents()); a.href = a.innerHTML = a.innerHTML.replace(/<[^>]+>/g, ""); href = a .getAttribute("href") .replace(new RegExp(domUtils.fillChar, "g"), ""); href = /^(?:https?:\/\/)/gi.test(href) ? href : "http://" + href; a.setAttribute("_src", utils.html(href)); a.href = utils.html(href); range.insertNode(a); a.parentNode.insertBefore(text, a.nextSibling); range.setStart(text, 0); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); me.undoManger && me.undoManger.save(); } } } } } : {}; }, function () { var keyCodes = { 37: 1, 38: 1, 39: 1, 40: 1, 13: 1, 32: 1 }; function checkIsCludeLink (node) { if (node.nodeType == 3) { return null; } if (node.nodeName == "A") { return node; } var lastChild = node.lastChild; while (lastChild) { if (lastChild.nodeName == "A") { return lastChild; } if (lastChild.nodeType == 3) { if (domUtils.isWhitespace(lastChild)) { lastChild = lastChild.previousSibling; continue; } return null; } lastChild = lastChild.lastChild; } } browser.ie && this.addListener("keyup", function (cmd, evt) { var me = this, keyCode = evt.keyCode; if (keyCodes[keyCode]) { var rng = me.selection.getRange(); var start = rng.startContainer; if (keyCode == 13) { while ( start && !domUtils.isBody(start) && !domUtils.isBlockElm(start) ) { start = start.parentNode; } if (start && !domUtils.isBody(start) && start.nodeName == "P") { var pre = start.previousSibling; if (pre && pre.nodeType == 1) { var pre = checkIsCludeLink(pre); if (pre && !pre.getAttribute("_href")) { domUtils.remove(pre, true); } } } } else if (keyCode == 32) { if (start.nodeType == 3 && /^\s$/.test(start.nodeValue)) { start = start.previousSibling; if ( start && start.nodeName == "A" && !start.getAttribute("_href") ) { domUtils.remove(start, true); } } } else { start = domUtils.findParentByTagName(start, "a", true); if (start && !start.getAttribute("_href")) { var bk = rng.createBookmark(); domUtils.remove(start, true); rng.moveToBookmark(bk).select(true); } } } }); } ); // plugins/autoheight.js ///import core ///commands 当输入内容超过编辑器高度时,编辑器自动增高 ///commandsName AutoHeight,autoHeightEnabled ///commandsTitle 自动增高 /** * @description 自动伸展 * @author zhanyi */ UE.plugins["autoheight"] = function () { var me = this; //提供开关,就算加载也可以关闭 me.autoHeightEnabled = me.options.autoHeightEnabled !== false; if (!me.autoHeightEnabled) { return; } var bakOverflow, lastHeight = 0, options = me.options, currentHeight, timer; function adjustHeight () { var me = this; clearTimeout(timer); if (isFullscreen) return; if ( !me.queryCommandState || (me.queryCommandState && me.queryCommandState("source") != 1) ) { timer = setTimeout(function () { var node = me.body.lastChild; while (node && node.nodeType != 1) { node = node.previousSibling; } if (node && node.nodeType == 1) { node.style.clear = "both"; currentHeight = Math.max( domUtils.getXY(node).y + node.offsetHeight + 25, Math.max(options.minFrameHeight, options.initialFrameHeight) ); if (currentHeight !== lastHeight) { me.iframe.parentNode.style.transition = 'width 0.3s, height 0.3s, easy-in-out'; if (currentHeight !== parseInt(me.iframe.parentNode.style.height)) { me.iframe.parentNode.style.height = currentHeight + "px"; } me.body.style.height = currentHeight + "px"; lastHeight = currentHeight; } domUtils.removeStyle(node, "clear"); } }, 50); } } var isFullscreen; me.addListener("fullscreenchanged", function (cmd, f) { isFullscreen = f; }); me.addListener("destroy", function () { domUtils.un(me.window, "scroll", fixedScrollTop); me.removeListener( "contentchange afterinserthtml keyup mouseup", adjustHeight ); }); me.enableAutoHeight = function () { var me = this; if (!me.autoHeightEnabled) { return; } var doc = me.document; me.autoHeightEnabled = true; bakOverflow = doc.body.style.overflowY; doc.body.style.overflowY = "hidden"; me.addListener("contentchange afterinserthtml keyup mouseup", adjustHeight); //ff不给事件算得不对 setTimeout(function () { adjustHeight.call(me); }, browser.gecko ? 100 : 0); me.fireEvent("autoheightchanged", me.autoHeightEnabled); }; me.disableAutoHeight = function () { me.body.style.overflowY = bakOverflow || ""; me.removeListener("contentchange", adjustHeight); me.removeListener("keyup", adjustHeight); me.removeListener("mouseup", adjustHeight); me.autoHeightEnabled = false; me.fireEvent("autoheightchanged", me.autoHeightEnabled); }; me.on("setHeight", function () { me.disableAutoHeight(); }); me.addListener("ready", function () { me.enableAutoHeight(); //trace:1764 var timer; domUtils.on( browser.ie ? me.body : me.document, browser.webkit ? "dragover" : "drop", function () { clearTimeout(timer); timer = setTimeout(function () { //trace:3681 adjustHeight.call(me); }, 100); } ); //修复内容过多时,回到顶部,顶部内容被工具栏遮挡问题 domUtils.on(me.window, "scroll", fixedScrollTop); }); var lastScrollY; function fixedScrollTop () { if (!me.window) return; if (lastScrollY === null) { lastScrollY = me.window.scrollY; } else if (me.window.scrollY == 0 && lastScrollY != 0) { me.window.scrollTo(0, 0); lastScrollY = null; } } }; // plugins/autofloat.js ///import core ///commands 悬浮工具栏 ///commandsName AutoFloat,autoFloatEnabled ///commandsTitle 悬浮工具栏 /** * modified by chengchao01 * 注意: 引入此功能后,在IE6下会将body的背景图片覆盖掉! */ UE.plugins["autofloat"] = function () { var me = this, lang = me.getLang(); me.setOpt({ topOffset: 0 }); var optsAutoFloatEnabled = me.options.autoFloatEnabled !== false, topOffset = me.options.topOffset; //如果不固定toolbar的位置,则直接退出 if (!optsAutoFloatEnabled) { return; } var uiUtils = UE.ui.uiUtils, LteIE6 = browser.ie && browser.version <= 6, quirks = browser.quirks; function checkHasUI () { if (!UE.ui) { alert(lang.autofloatMsg); return 0; } return 1; } function fixIE6FixedPos () { var docStyle = document.body.style; docStyle.backgroundImage = 'url("about:blank")'; docStyle.backgroundAttachment = "fixed"; } var bakCssText, placeHolder = document.createElement("div"), toolbarBox, orgTop, getPosition, flag = true; //ie7模式下需要偏移 function setFloating () { var toobarBoxPos = domUtils.getXY(toolbarBox), origalFloat = domUtils.getComputedStyle(toolbarBox, "position"), origalLeft = domUtils.getComputedStyle(toolbarBox, "left"); toolbarBox.style.width = toolbarBox.offsetWidth + "px"; toolbarBox.style.zIndex = me.options.zIndex * 1 + 1; toolbarBox.parentNode.insertBefore(placeHolder, toolbarBox); if (LteIE6 || (quirks && browser.ie)) { if (toolbarBox.style.position != "absolute") { toolbarBox.style.position = "absolute"; } toolbarBox.style.top = (document.body.scrollTop || document.documentElement.scrollTop) - orgTop + topOffset + "px"; } else { if (browser.ie7Compat && flag) { flag = false; toolbarBox.style.left = domUtils.getXY(toolbarBox).x - document.documentElement.getBoundingClientRect().left + 2 + "px"; } if (toolbarBox.style.position != "fixed") { toolbarBox.style.position = "fixed"; toolbarBox.style.top = topOffset + "px"; (origalFloat == "absolute" || origalFloat == "relative") && parseFloat(origalLeft) && (toolbarBox.style.left = toobarBoxPos.x + "px"); } } } function unsetFloating () { flag = true; if (placeHolder.parentNode) { placeHolder.parentNode.removeChild(placeHolder); } toolbarBox.style.cssText = bakCssText; } me.unsetFloating = unsetFloating; function updateFloating () { var rect3 = getPosition(me.container); var offset = me.options.toolbarTopOffset || 0; if (rect3.top < 0 && rect3.bottom - toolbarBox.offsetHeight > offset) { setFloating(); } else { unsetFloating(); } } var defer_updateFloating = utils.defer( function () { updateFloating(); }, browser.ie ? 200 : 100, true ); me.addListener("destroy", function () { domUtils.un(window, ["scroll", "resize"], updateFloating); me.removeListener("keydown", defer_updateFloating); }); me.addListener("ready", function () { if (checkHasUI(me)) { //加载了ui组件,但在new时,没有加载ui,导致编辑器实例上没有ui类,所以这里做判断 if (!me.ui) { return; } getPosition = uiUtils.getClientRect; toolbarBox = me.ui.getDom("toolbarbox"); orgTop = getPosition(toolbarBox).top; bakCssText = toolbarBox.style.cssText; placeHolder.style.height = toolbarBox.offsetHeight + "px"; if (LteIE6) { fixIE6FixedPos(); } domUtils.on(window, ["scroll", "resize"], updateFloating); me.addListener("keydown", defer_updateFloating); me.addListener("beforefullscreenchange", function (t, enabled) { if (enabled) { unsetFloating(); } }); me.addListener("fullscreenchanged", function (t, enabled) { if (!enabled) { updateFloating(); } }); me.addListener("sourcemodechanged", function (t, enabled) { setTimeout(function () { updateFloating(); }, 0); }); me.addListener("clearDoc", function () { setTimeout(function () { updateFloating(); }, 0); }); } }); }; // plugins/video.js /** * video插件, 为UEditor提供视频插入支持 * @file * @since 1.2.6.1 */ UE.plugins["video"] = function () { var me = this; /** * 创建插入视频字符窜 * @param url 视频地址 * @param width 视频宽度 * @param height 视频高度 * @param align 视频对齐 * @param toEmbed 是否以flash代替显示 * @param addParagraph 是否需要添加P 标签 */ function creatInsertStr (url, width, height, id, align, classname, type) { var str; switch (type) { case 'iframe': str = ' |