]/.test(html)) {
+ return UM.htmlparser(html).children[0]
+ } else {
+ return new uNode({
+ type:'element',
+ children:[],
+ tagName:html
+ })
+ }
+ };
+ uNode.createText = function (data,noTrans) {
+ return new UM.uNode({
+ type:'text',
+ 'data':noTrans ? data : utils.unhtml(data || '')
+ })
+ };
+ function nodeToHtml(node, arr, formatter, current) {
+ switch (node.type) {
+ case 'root':
+ for (var i = 0, ci; ci = node.children[i++];) {
+ //插入新行
+ if (formatter && ci.type == 'element' && !dtd.$inlineWithA[ci.tagName] && i > 1) {
+ insertLine(arr, current, true);
+ insertIndent(arr, current)
+ }
+ nodeToHtml(ci, arr, formatter, current)
+ }
+ break;
+ case 'text':
+ isText(node, arr);
+ break;
+ case 'element':
+ isElement(node, arr, formatter, current);
+ break;
+ case 'comment':
+ isComment(node, arr, formatter);
+ }
+ return arr;
+ }
+
+ function isText(node, arr) {
+ if(node.parentNode.tagName == 'pre'){
+ //源码模式下输入html标签,不能做转换处理,直接输出
+ arr.push(node.data)
+ }else{
+ arr.push(notTransTagName[node.parentNode.tagName] ? utils.html(node.data) : node.data.replace(/[ ]{2}/g,' '))
+ }
+
+ }
+
+ function isElement(node, arr, formatter, current) {
+ var attrhtml = '';
+ if (node.attrs) {
+ attrhtml = [];
+ var attrs = node.attrs;
+ for (var a in attrs) {
+ //这里就针对
+ //'
+ //这里边的\"做转换,要不用innerHTML直接被截断了,属性src
+ //有可能做的不够
+ attrhtml.push(a + (attrs[a] !== undefined ? '="' + (notTransAttrs[a] ? utils.html(attrs[a]).replace(/["]/g, function (a) {
+ return '"'
+ }) : utils.unhtml(attrs[a])) + '"' : ''))
+ }
+ attrhtml = attrhtml.join(' ');
+ }
+ arr.push('<' + node.tagName +
+ (attrhtml ? ' ' + attrhtml : '') +
+ (dtd.$empty[node.tagName] ? '\/' : '' ) + '>'
+ );
+ //插入新行
+ if (formatter && !dtd.$inlineWithA[node.tagName] && node.tagName != 'pre') {
+ if(node.children && node.children.length){
+ current = insertLine(arr, current, true);
+ insertIndent(arr, current)
+ }
+
+ }
+ if (node.children && node.children.length) {
+ for (var i = 0, ci; ci = node.children[i++];) {
+ if (formatter && ci.type == 'element' && !dtd.$inlineWithA[ci.tagName] && i > 1) {
+ insertLine(arr, current);
+ insertIndent(arr, current)
+ }
+ nodeToHtml(ci, arr, formatter, current)
+ }
+ }
+ if (!dtd.$empty[node.tagName]) {
+ if (formatter && !dtd.$inlineWithA[node.tagName] && node.tagName != 'pre') {
+
+ if(node.children && node.children.length){
+ current = insertLine(arr, current);
+ insertIndent(arr, current)
+ }
+ }
+ arr.push('<\/' + node.tagName + '>');
+ }
+
+ }
+
+ function isComment(node, arr) {
+ arr.push('');
+ }
+
+ function getNodeById(root, id) {
+ var node;
+ if (root.type == 'element' && root.getAttr('id') == id) {
+ return root;
+ }
+ if (root.children && root.children.length) {
+ for (var i = 0, ci; ci = root.children[i++];) {
+ if (node = getNodeById(ci, id)) {
+ return node;
+ }
+ }
+ }
+ }
+
+ function getNodesByTagName(node, tagName, arr) {
+ if (node.type == 'element' && node.tagName == tagName) {
+ arr.push(node);
+ }
+ if (node.children && node.children.length) {
+ for (var i = 0, ci; ci = node.children[i++];) {
+ getNodesByTagName(ci, tagName, arr)
+ }
+ }
+ }
+ function nodeTraversal(root,fn){
+ if(root.children && root.children.length){
+ for(var i= 0,ci;ci=root.children[i];){
+ nodeTraversal(ci,fn);
+ //ci被替换的情况,这里就不再走 fn了
+ if(ci.parentNode ){
+ if(ci.children && ci.children.length){
+ fn(ci)
+ }
+ if(ci.parentNode) i++
+ }
+ }
+ }else{
+ fn(root)
+ }
+
+ }
+ uNode.prototype = {
+
+ /**
+ * 当前节点对象,转换成html文本
+ * @method toHtml
+ * @return { String } 返回转换后的html字符串
+ * @example
+ * ```javascript
+ * node.toHtml();
+ * ```
+ */
+
+ /**
+ * 当前节点对象,转换成html文本
+ * @method toHtml
+ * @param { Boolean } formatter 是否格式化返回值
+ * @return { String } 返回转换后的html字符串
+ * @example
+ * ```javascript
+ * node.toHtml( true );
+ * ```
+ */
+ toHtml:function (formatter) {
+ var arr = [];
+ nodeToHtml(this, arr, formatter, 0);
+ return arr.join('')
+ },
+
+ /**
+ * 获取节点的html内容
+ * @method innerHTML
+ * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点
+ * @return { String } 返回节点的html内容
+ * @example
+ * ```javascript
+ * var htmlstr = node.innerHTML();
+ * ```
+ */
+
+ /**
+ * 设置节点的html内容
+ * @method innerHTML
+ * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点
+ * @param { String } htmlstr 传入要设置的html内容
+ * @return { UM.uNode } 返回节点本身
+ * @example
+ * ```javascript
+ * node.innerHTML('text ');
+ * ```
+ */
+ innerHTML:function (htmlstr) {
+ if (this.type != 'element' || dtd.$empty[this.tagName]) {
+ return this;
+ }
+ if (utils.isString(htmlstr)) {
+ if(this.children){
+ for (var i = 0, ci; ci = this.children[i++];) {
+ ci.parentNode = null;
+ }
+ }
+ this.children = [];
+ var tmpRoot = UM.htmlparser(htmlstr);
+ for (var i = 0, ci; ci = tmpRoot.children[i++];) {
+ this.children.push(ci);
+ ci.parentNode = this;
+ }
+ return this;
+ } else {
+ var tmpRoot = new UM.uNode({
+ type:'root',
+ children:this.children
+ });
+ return tmpRoot.toHtml();
+ }
+ },
+
+ /**
+ * 获取节点的纯文本内容
+ * @method innerText
+ * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点
+ * @return { String } 返回节点的存文本内容
+ * @example
+ * ```javascript
+ * var textStr = node.innerText();
+ * ```
+ */
+
+ /**
+ * 设置节点的纯文本内容
+ * @method innerText
+ * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点
+ * @param { String } textStr 传入要设置的文本内容
+ * @return { UM.uNode } 返回节点本身
+ * @example
+ * ```javascript
+ * node.innerText('text ');
+ * ```
+ */
+ innerText:function (textStr,noTrans) {
+ if (this.type != 'element' || dtd.$empty[this.tagName]) {
+ return this;
+ }
+ if (textStr) {
+ if(this.children){
+ for (var i = 0, ci; ci = this.children[i++];) {
+ ci.parentNode = null;
+ }
+ }
+ this.children = [];
+ this.appendChild(uNode.createText(textStr,noTrans));
+ return this;
+ } else {
+ return this.toHtml().replace(/<[^>]+>/g, '');
+ }
+ },
+
+ /**
+ * 获取当前对象的data属性
+ * @method getData
+ * @return { Object } 若节点的type值是elemenet,返回空字符串,否则返回节点的data属性
+ * @example
+ * ```javascript
+ * node.getData();
+ * ```
+ */
+ getData:function () {
+ if (this.type == 'element')
+ return '';
+ return this.data
+ },
+
+ /**
+ * 获取当前节点下的第一个子节点
+ * @method firstChild
+ * @return { UM.uNode } 返回第一个子节点
+ * @example
+ * ```javascript
+ * node.firstChild(); //返回第一个子节点
+ * ```
+ */
+ firstChild:function () {
+// if (this.type != 'element' || dtd.$empty[this.tagName]) {
+// return this;
+// }
+ return this.children ? this.children[0] : null;
+ },
+
+ /**
+ * 获取当前节点下的最后一个子节点
+ * @method lastChild
+ * @return { UM.uNode } 返回最后一个子节点
+ * @example
+ * ```javascript
+ * node.lastChild(); //返回最后一个子节点
+ * ```
+ */
+ lastChild:function () {
+// if (this.type != 'element' || dtd.$empty[this.tagName] ) {
+// return this;
+// }
+ return this.children ? this.children[this.children.length - 1] : null;
+ },
+
+ /**
+ * 获取和当前节点有相同父亲节点的前一个节点
+ * @method previousSibling
+ * @return { UM.uNode } 返回前一个节点
+ * @example
+ * ```javascript
+ * node.children[2].previousSibling(); //返回子节点node.children[1]
+ * ```
+ */
+ previousSibling : function(){
+ var parent = this.parentNode;
+ for (var i = 0, ci; ci = parent.children[i]; i++) {
+ if (ci === this) {
+ return i == 0 ? null : parent.children[i-1];
+ }
+ }
+
+ },
+
+ /**
+ * 获取和当前节点有相同父亲节点的后一个节点
+ * @method nextSibling
+ * @return { UM.uNode } 返回后一个节点,找不到返回null
+ * @example
+ * ```javascript
+ * node.children[2].nextSibling(); //如果有,返回子节点node.children[3]
+ * ```
+ */
+ nextSibling : function(){
+ var parent = this.parentNode;
+ for (var i = 0, ci; ci = parent.children[i++];) {
+ if (ci === this) {
+ return parent.children[i];
+ }
+ }
+ },
+
+ /**
+ * 用新的节点替换当前节点
+ * @method replaceChild
+ * @param { UM.uNode } target 要替换成该节点参数
+ * @param { UM.uNode } source 要被替换掉的节点
+ * @return { UM.uNode } 返回替换之后的节点对象
+ * @example
+ * ```javascript
+ * node.replaceChild(newNode, childNode); //用newNode替换childNode,childNode是node的子节点
+ * ```
+ */
+ replaceChild:function (target, source) {
+ if (this.children) {
+ if(target.parentNode){
+ target.parentNode.removeChild(target);
+ }
+ for (var i = 0, ci; ci = this.children[i]; i++) {
+ if (ci === source) {
+ this.children.splice(i, 1, target);
+ source.parentNode = null;
+ target.parentNode = this;
+ return target;
+ }
+ }
+ }
+ },
+
+ /**
+ * 在节点的子节点列表最后位置插入一个节点
+ * @method appendChild
+ * @param { UM.uNode } node 要插入的节点
+ * @return { UM.uNode } 返回刚插入的子节点
+ * @example
+ * ```javascript
+ * node.appendChild( newNode ); //在node内插入子节点newNode
+ * ```
+ */
+ appendChild:function (node) {
+ if (this.type == 'root' || (this.type == 'element' && !dtd.$empty[this.tagName])) {
+ if (!this.children) {
+ this.children = []
+ }
+ if(node.parentNode){
+ node.parentNode.removeChild(node);
+ }
+ for (var i = 0, ci; ci = this.children[i]; i++) {
+ if (ci === node) {
+ this.children.splice(i, 1);
+ break;
+ }
+ }
+ this.children.push(node);
+ node.parentNode = this;
+ return node;
+ }
+
+
+ },
+
+ /**
+ * 在传入节点的前面插入一个节点
+ * @method insertBefore
+ * @param { UM.uNode } target 要插入的节点
+ * @param { UM.uNode } source 在该参数节点前面插入
+ * @return { UM.uNode } 返回刚插入的子节点
+ * @example
+ * ```javascript
+ * node.parentNode.insertBefore(newNode, node); //在node节点后面插入newNode
+ * ```
+ */
+ insertBefore:function (target, source) {
+ if (this.children) {
+ if(target.parentNode){
+ target.parentNode.removeChild(target);
+ }
+ for (var i = 0, ci; ci = this.children[i]; i++) {
+ if (ci === source) {
+ this.children.splice(i, 0, target);
+ target.parentNode = this;
+ return target;
+ }
+ }
+
+ }
+ },
+
+ /**
+ * 在传入节点的后面插入一个节点
+ * @method insertAfter
+ * @param { UM.uNode } target 要插入的节点
+ * @param { UM.uNode } source 在该参数节点后面插入
+ * @return { UM.uNode } 返回刚插入的子节点
+ * @example
+ * ```javascript
+ * node.parentNode.insertAfter(newNode, node); //在node节点后面插入newNode
+ * ```
+ */
+ insertAfter:function (target, source) {
+ if (this.children) {
+ if(target.parentNode){
+ target.parentNode.removeChild(target);
+ }
+ for (var i = 0, ci; ci = this.children[i]; i++) {
+ if (ci === source) {
+ this.children.splice(i + 1, 0, target);
+ target.parentNode = this;
+ return target;
+ }
+
+ }
+ }
+ },
+
+ /**
+ * 从当前节点的子节点列表中,移除节点
+ * @method removeChild
+ * @param { UM.uNode } node 要移除的节点引用
+ * @param { Boolean } keepChildren 是否保留移除节点的子节点,若传入true,自动把移除节点的子节点插入到移除的位置
+ * @return { * } 返回刚移除的子节点
+ * @example
+ * ```javascript
+ * node.removeChild(childNode,true); //在node的子节点列表中移除child节点,并且吧child的子节点插入到移除的位置
+ * ```
+ */
+ removeChild:function (node,keepChildren) {
+ if (this.children) {
+ for (var i = 0, ci; ci = this.children[i]; i++) {
+ if (ci === node) {
+ this.children.splice(i, 1);
+ ci.parentNode = null;
+ if(keepChildren && ci.children && ci.children.length){
+ for(var j= 0,cj;cj=ci.children[j];j++){
+ this.children.splice(i+j,0,cj);
+ cj.parentNode = this;
+
+ }
+ }
+ return ci;
+ }
+ }
+ }
+ },
+
+ /**
+ * 获取当前节点所代表的元素属性,即获取attrs对象下的属性值
+ * @method getAttr
+ * @param { String } attrName 要获取的属性名称
+ * @return { * } 返回attrs对象下的属性值
+ * @example
+ * ```javascript
+ * node.getAttr('title');
+ * ```
+ */
+ getAttr:function (attrName) {
+ return this.attrs && this.attrs[attrName.toLowerCase()]
+ },
+
+ /**
+ * 设置当前节点所代表的元素属性,即设置attrs对象下的属性值
+ * @method setAttr
+ * @param { String } attrName 要设置的属性名称
+ * @param { * } attrVal 要设置的属性值,类型视设置的属性而定
+ * @return { * } 返回attrs对象下的属性值
+ * @example
+ * ```javascript
+ * node.setAttr('title','标题');
+ * ```
+ */
+ setAttr:function (attrName, attrVal) {
+ if (!attrName) {
+ delete this.attrs;
+ return;
+ }
+ if(!this.attrs){
+ this.attrs = {};
+ }
+ if (utils.isObject(attrName)) {
+ for (var a in attrName) {
+ if (!attrName[a]) {
+ delete this.attrs[a]
+ } else {
+ this.attrs[a.toLowerCase()] = attrName[a];
+ }
+ }
+ } else {
+ if (!attrVal) {
+ delete this.attrs[attrName]
+ } else {
+ this.attrs[attrName.toLowerCase()] = attrVal;
+ }
+
+ }
+ },
+ hasAttr: function( attrName ){
+ var attrVal = this.getAttr( attrName );
+ return ( attrVal !== null ) && ( attrVal !== undefined );
+ },
+ /**
+ * 获取当前节点在父节点下的位置索引
+ * @method getIndex
+ * @return { Number } 返回索引数值,如果没有父节点,返回-1
+ * @example
+ * ```javascript
+ * node.getIndex();
+ * ```
+ */
+ getIndex:function(){
+ var parent = this.parentNode;
+ for(var i= 0,ci;ci=parent.children[i];i++){
+ if(ci === this){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ /**
+ * 在当前节点下,根据id查找节点
+ * @method getNodeById
+ * @param { String } id 要查找的id
+ * @return { UM.uNode } 返回找到的节点
+ * @example
+ * ```javascript
+ * node.getNodeById('textId');
+ * ```
+ */
+ getNodeById:function (id) {
+ var node;
+ if (this.children && this.children.length) {
+ for (var i = 0, ci; ci = this.children[i++];) {
+ if (node = getNodeById(ci, id)) {
+ return node;
+ }
+ }
+ }
+ },
+
+ /**
+ * 在当前节点下,根据元素名称查找节点列表
+ * @method getNodesByTagName
+ * @param { String } tagNames 要查找的元素名称
+ * @return { Array } 返回找到的节点列表
+ * @example
+ * ```javascript
+ * node.getNodesByTagName('span');
+ * ```
+ */
+ getNodesByTagName:function (tagNames) {
+ tagNames = utils.trim(tagNames).replace(/[ ]{2,}/g, ' ').split(' ');
+ var arr = [], me = this;
+ utils.each(tagNames, function (tagName) {
+ if (me.children && me.children.length) {
+ for (var i = 0, ci; ci = me.children[i++];) {
+ getNodesByTagName(ci, tagName, arr)
+ }
+ }
+ });
+ return arr;
+ },
+
+ /**
+ * 根据样式名称,获取节点的样式值
+ * @method getStyle
+ * @param { String } name 要获取的样式名称
+ * @return { String } 返回样式值
+ * @example
+ * ```javascript
+ * node.getStyle('font-size');
+ * ```
+ */
+ getStyle:function (name) {
+ var cssStyle = this.getAttr('style');
+ if (!cssStyle) {
+ return ''
+ }
+ var reg = new RegExp('(^|;)\\s*' + name + ':([^;]+)','i');
+ var match = cssStyle.match(reg);
+ if (match && match[0]) {
+ return match[2]
+ }
+ return '';
+ },
+
+ /**
+ * 给节点设置样式
+ * @method setStyle
+ * @param { String } name 要设置的的样式名称
+ * @param { String } val 要设置的的样值
+ * @example
+ * ```javascript
+ * node.setStyle('font-size', '12px');
+ * ```
+ */
+ setStyle:function (name, val) {
+ function exec(name, val) {
+ var reg = new RegExp('(^|;)\\s*' + name + ':([^;]+;?)', 'gi');
+ cssStyle = cssStyle.replace(reg, '$1');
+ if (val) {
+ cssStyle = name + ':' + utils.unhtml(val) + ';' + cssStyle
+ }
+
+ }
+
+ var cssStyle = this.getAttr('style');
+ if (!cssStyle) {
+ cssStyle = '';
+ }
+ if (utils.isObject(name)) {
+ for (var a in name) {
+ exec(a, name[a])
+ }
+ } else {
+ exec(name, val)
+ }
+ this.setAttr('style', utils.trim(cssStyle))
+ },
+ hasClass: function( className ){
+ if( this.hasAttr('class') ) {
+ var classNames = this.getAttr('class').split(/\s+/),
+ hasClass = false;
+ $.each(classNames, function(key, item){
+ if( item === className ) {
+ hasClass = true;
+ }
+ });
+ return hasClass;
+ } else {
+ return false;
+ }
+ },
+ addClass: function( className ){
+
+ var classes = null,
+ hasClass = false;
+
+ if( this.hasAttr('class') ) {
+
+ classes = this.getAttr('class');
+ classes = classes.split(/\s+/);
+
+ classes.forEach( function( item ){
+
+ if( item===className ) {
+ hasClass = true;
+ return;
+ }
+
+ } );
+
+ !hasClass && classes.push( className );
+
+ this.setAttr('class', classes.join(" "));
+
+ } else {
+ this.setAttr('class', className);
+ }
+
+ },
+ removeClass: function( className ){
+ if( this.hasAttr('class') ) {
+ var cl = this.getAttr('class');
+ cl = cl.replace(new RegExp('\\b' + className + '\\b', 'g'),'');
+ this.setAttr('class', utils.trim(cl).replace(/[ ]{2,}/g,' '));
+ }
+ },
+ /**
+ * 传入一个函数,递归遍历当前节点下的所有节点
+ * @method traversal
+ * @param { Function } fn 遍历到节点的时,传入节点作为参数,运行此函数
+ * @example
+ * ```javascript
+ * traversal(node, function(){
+ * console.log(node.type);
+ * });
+ * ```
+ */
+ traversal:function(fn){
+ if(this.children && this.children.length){
+ nodeTraversal(this,fn);
+ }
+ return this;
+ }
+ }
+})();
+
+//html字符串转换成uNode节点
+//by zhanyi
+var htmlparser = UM.htmlparser = function (htmlstr,ignoreBlank) {
+ //todo 原来的方式 [^"'<>\/] 有\/就不能配对上 这样的标签了
+ //先去掉了,加上的原因忘了,这里先记录
+ var re_tag = /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\s\/>]+)\s*((?:(?:"[^"]*")|(?:'[^']*')|[^"'<>])*)\/?>))/g,
+ re_attr = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g;
+
+ //ie下取得的html可能会有\n存在,要去掉,在处理replace(/[\t\r\n]*/g,'');代码高量的\n不能去除
+ var allowEmptyTags = {
+ b:1,code:1,i:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,span:1,
+ sub:1,img:1,sup:1,font:1,big:1,small:1,iframe:1,a:1,br:1,pre:1
+ };
+ htmlstr = htmlstr.replace(new RegExp(domUtils.fillChar, 'g'), '');
+ if(!ignoreBlank){
+ htmlstr = htmlstr.replace(new RegExp('[\\r\\t\\n'+(ignoreBlank?'':' ')+']*<\/?(\\w+)\\s*(?:[^>]*)>[\\r\\t\\n'+(ignoreBlank?'':' ')+']*','g'), function(a,b){
+ //br暂时单独处理
+ if(b && allowEmptyTags[b.toLowerCase()]){
+ return a.replace(/(^[\n\r]+)|([\n\r]+$)/g,'');
+ }
+ return a.replace(new RegExp('^[\\r\\n'+(ignoreBlank?'':' ')+']+'),'').replace(new RegExp('[\\r\\n'+(ignoreBlank?'':' ')+']+$'),'');
+ });
+ }
+
+ var notTransAttrs = {
+ 'href':1,
+ 'src':1
+ };
+
+ var uNode = UM.uNode,
+ needParentNode = {
+ 'td':'tr',
+ 'tr':['tbody','thead','tfoot'],
+ 'tbody':'table',
+ 'th':'tr',
+ 'thead':'table',
+ 'tfoot':'table',
+ 'caption':'table',
+ 'li':['ul', 'ol'],
+ 'dt':'dl',
+ 'dd':'dl',
+ 'option':'select'
+ },
+ needChild = {
+ 'ol':'li',
+ 'ul':'li'
+ };
+
+ function text(parent, data) {
+
+ if(needChild[parent.tagName]){
+ var tmpNode = uNode.createElement(needChild[parent.tagName]);
+ parent.appendChild(tmpNode);
+ tmpNode.appendChild(uNode.createText(data));
+ parent = tmpNode;
+ }else{
+
+ parent.appendChild(uNode.createText(data));
+ }
+ }
+
+ function element(parent, tagName, htmlattr) {
+ var needParentTag;
+ if (needParentTag = needParentNode[tagName]) {
+ var tmpParent = parent,hasParent;
+ while(tmpParent.type != 'root'){
+ if(utils.isArray(needParentTag) ? utils.indexOf(needParentTag, tmpParent.tagName) != -1 : needParentTag == tmpParent.tagName){
+ parent = tmpParent;
+ hasParent = true;
+ break;
+ }
+ tmpParent = tmpParent.parentNode;
+ }
+ if(!hasParent){
+ parent = element(parent, utils.isArray(needParentTag) ? needParentTag[0] : needParentTag)
+ }
+ }
+ //按dtd处理嵌套
+// if(parent.type != 'root' && !dtd[parent.tagName][tagName])
+// parent = parent.parentNode;
+ var elm = new uNode({
+ parentNode:parent,
+ type:'element',
+ tagName:tagName.toLowerCase(),
+ //是自闭合的处理一下
+ children:dtd.$empty[tagName] ? null : []
+ });
+ //如果属性存在,处理属性
+ if (htmlattr) {
+ var attrs = {}, match;
+ while (match = re_attr.exec(htmlattr)) {
+ attrs[match[1].toLowerCase()] = notTransAttrs[match[1].toLowerCase()] ? (match[2] || match[3] || match[4]) : utils.unhtml(match[2] || match[3] || match[4])
+ }
+ elm.attrs = attrs;
+ }
+
+ parent.children.push(elm);
+ //如果是自闭合节点返回父亲节点
+ return dtd.$empty[tagName] ? parent : elm
+ }
+
+ function comment(parent, data) {
+ parent.children.push(new uNode({
+ type:'comment',
+ data:data,
+ parentNode:parent
+ }));
+ }
+
+ var match, currentIndex = 0, nextIndex = 0;
+ //设置根节点
+ var root = new uNode({
+ type:'root',
+ children:[]
+ });
+ var currentParent = root;
+
+ while (match = re_tag.exec(htmlstr)) {
+ currentIndex = match.index;
+ try{
+ if (currentIndex > nextIndex) {
+ //text node
+ text(currentParent, htmlstr.slice(nextIndex, currentIndex));
+ }
+ if (match[3]) {
+
+ if(dtd.$cdata[currentParent.tagName]){
+ text(currentParent, match[0]);
+ }else{
+ //start tag
+ currentParent = element(currentParent, match[3].toLowerCase(), match[4]);
+ }
+
+
+ } else if (match[1]) {
+ if(currentParent.type != 'root'){
+ if(dtd.$cdata[currentParent.tagName] && !dtd.$cdata[match[1]]){
+ text(currentParent, match[0]);
+ }else{
+ var tmpParent = currentParent;
+ while(currentParent.type == 'element' && currentParent.tagName != match[1].toLowerCase()){
+ currentParent = currentParent.parentNode;
+ if(currentParent.type == 'root'){
+ currentParent = tmpParent;
+ throw 'break'
+ }
+ }
+ //end tag
+ currentParent = currentParent.parentNode;
+ }
+
+ }
+
+ } else if (match[2]) {
+ //comment
+ comment(currentParent, match[2])
+ }
+ }catch(e){}
+
+ nextIndex = re_tag.lastIndex;
+
+ }
+ //如果结束是文本,就有可能丢掉,所以这里手动判断一下
+ //例如 sdfsdfsdf sdfsdfsdfsdf
+ if (nextIndex < htmlstr.length) {
+ text(currentParent, htmlstr.slice(nextIndex));
+ }
+ return root;
+};
+/**
+ * @file
+ * @name UM.filterNode
+ * @short filterNode
+ * @desc 根据给定的规则过滤节点
+ * @import editor.js,core/utils.js
+ * @anthor zhanyi
+ */
+var filterNode = UM.filterNode = function () {
+ function filterNode(node,rules){
+ switch (node.type) {
+ case 'text':
+ break;
+ case 'element':
+ var val;
+ if(val = rules[node.tagName]){
+ if(val === '-'){
+ node.parentNode.removeChild(node)
+ }else if(utils.isFunction(val)){
+ var parentNode = node.parentNode,
+ index = node.getIndex();
+ val(node);
+ if(node.parentNode){
+ if(node.children){
+ for(var i = 0,ci;ci=node.children[i];){
+ filterNode(ci,rules);
+ if(ci.parentNode){
+ i++;
+ }
+ }
+ }
+ }else{
+ for(var i = index,ci;ci=parentNode.children[i];){
+ filterNode(ci,rules);
+ if(ci.parentNode){
+ i++;
+ }
+ }
+ }
+
+
+ }else{
+ var attrs = val['$'];
+ if(attrs && node.attrs){
+ var tmpAttrs = {},tmpVal;
+ for(var a in attrs){
+ tmpVal = node.getAttr(a);
+ //todo 只先对style单独处理
+ if(a == 'style' && utils.isArray(attrs[a])){
+ var tmpCssStyle = [];
+ utils.each(attrs[a],function(v){
+ var tmp;
+ if(tmp = node.getStyle(v)){
+ tmpCssStyle.push(v + ':' + tmp);
+ }
+ });
+ tmpVal = tmpCssStyle.join(';')
+ }
+ if(tmpVal){
+ tmpAttrs[a] = tmpVal;
+ }
+
+ }
+ node.attrs = tmpAttrs;
+ }
+ if(node.children){
+ for(var i = 0,ci;ci=node.children[i];){
+ filterNode(ci,rules);
+ if(ci.parentNode){
+ i++;
+ }
+ }
+ }
+ }
+ }else{
+ //如果不在名单里扣出子节点并删除该节点,cdata除外
+ if(dtd.$cdata[node.tagName]){
+ node.parentNode.removeChild(node)
+ }else{
+ var parentNode = node.parentNode,
+ index = node.getIndex();
+ node.parentNode.removeChild(node,true);
+ for(var i = index,ci;ci=parentNode.children[i];){
+ filterNode(ci,rules);
+ if(ci.parentNode){
+ i++;
+ }
+ }
+ }
+ }
+ break;
+ case 'comment':
+ node.parentNode.removeChild(node)
+ }
+
+ }
+ return function(root,rules){
+ if(utils.isEmptyObject(rules)){
+ return root;
+ }
+ var val;
+ if(val = rules['-']){
+ utils.each(val.split(' '),function(k){
+ rules[k] = '-'
+ })
+ }
+ for(var i= 0,ci;ci=root.children[i];){
+ filterNode(ci,rules);
+ if(ci.parentNode){
+ i++;
+ }
+ }
+ return root;
+ }
+}();
+///import core
+/**
+ * @description 插入内容
+ * @name baidu.editor.execCommand
+ * @param {String} cmdName inserthtml插入内容的命令
+ * @param {String} html 要插入的内容
+ * @author zhanyi
+ */
+UM.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 = UM.htmlparser(html);
+ //如果给了过滤规则就先进行过滤
+ if(me.options.filterRules){
+ UM.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 ? '' : ' ')+'
';
+ range.setStart(me.body.firstChild,0).collapse(true)
+
+ }
+ }
+ }
+ !range.collapsed && range.deleteContents();
+ if(range.startContainer.nodeType == 1){
+ var child = range.startContainer.childNodes[range.startOffset],pre;
+ if(child && domUtils.isBlockElm(child) && (pre = child.previousSibling) && domUtils.isBlockElm(pre)){
+ range.setEnd(pre,pre.childNodes.length).collapse();
+ while(child.firstChild){
+ pre.appendChild(child.firstChild);
+ }
+ domUtils.remove(child);
+ }
+ }
+
+ }
+
+
+ var child,parent,pre,tmp,hadBreak = 0, nextNode;
+ //如果当前位置选中了fillchar要干掉,要不会产生空行
+ if(range.inFillChar()){
+ child = range.startContainer;
+ if(domUtils.isFillChar(child)){
+ range.setStartBefore(child).collapse(true);
+ domUtils.remove(child);
+ }else if(domUtils.isFillChar(child,true)){
+ child.nodeValue = child.nodeValue.replace(fillCharReg,'');
+ range.startOffset--;
+ range.collapsed && range.collapse(true)
+ }
+ }
+ while ( child = div.firstChild ) {
+ if(hadBreak){
+ var p = me.document.createElement('p');
+ while(child && (child.nodeType == 3 || !dtd.$block[child.tagName])){
+ nextNode = child.nextSibling;
+ p.appendChild(child);
+ child = nextNode;
+ }
+ if(p.firstChild){
+
+ child = p
+ }
+ }
+ range.insertNode( child );
+ nextNode = child.nextSibling;
+ if ( !hadBreak && child.nodeType == domUtils.NODE_ELEMENT && domUtils.isBlockElm( child ) ){
+
+ parent = domUtils.findParent( child,function ( node ){ return domUtils.isBlockElm( node ); } );
+ if ( parent && parent.tagName.toLowerCase() != 'body' && !(dtd[parent.tagName][child.nodeName] && child.parentNode === parent)){
+ if(!dtd[parent.tagName][child.nodeName]){
+ pre = parent;
+ }else{
+ tmp = child.parentNode;
+ while (tmp !== parent){
+ pre = tmp;
+ tmp = tmp.parentNode;
+
+ }
+ }
+
+
+ domUtils.breakParent( child, pre || tmp );
+ //去掉break后前一个多余的节点 |<[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{
+ if(browser.ie9below && range.startContainer.nodeType == 1 && !range.startContainer.childNodes[range.startOffset]){
+ var start = range.startContainer,pre = start.childNodes[range.startOffset-1];
+ if(pre && pre.nodeType == 1 && dtd.$empty[pre.tagName]){
+ var txt = this.document.createTextNode(domUtils.fillChar);
+ range.insertNode(txt).setStart(txt,0).collapse(true);
+ }
+ }
+ setTimeout(function(){
+ range.select(true);
+ })
+
+ }catch(e){}
+
+
+ setTimeout(function(){
+ range = me.selection.getRange();
+ range.scrollIntoView();
+ me.fireEvent('afterinserthtml');
+ },200);
+ }
+};
+
+///import core
+///import plugins\inserthtml.js
+///commands 插入图片,操作图片的对齐方式
+///commandsName InsertImage,ImageNone,ImageLeft,ImageRight,ImageCenter
+///commandsTitle 图片,默认,居左,居右,居中
+///commandsDialog dialogs\image
+/**
+ * Created by .
+ * User: zhanyi
+ * for image
+ */
+UM.commands['insertimage'] = {
+ execCommand:function (cmd, opt) {
+ opt = utils.isArray(opt) ? opt : [opt];
+ if (!opt.length) {
+ return;
+ }
+ var me = this;
+ 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(''), true);
+ }
+};
+///import core
+///commands 段落格式,居左,居右,居中,两端对齐
+///commandsName JustifyLeft,JustifyCenter,JustifyRight,JustifyJustify
+///commandsTitle 居左对齐,居中对齐,居右对齐,两端对齐
+/**
+ * @description 居左右中
+ * @name UM.execCommand
+ * @param {String} cmdName justify执行对齐方式的命令
+ * @param {String} align 对齐方式:left居左,right居右,center居中,justify两端对齐
+ * @author zhanyi
+ */
+UM.plugins['justify']=function(){
+ var me = this;
+ $.each('justifyleft justifyright justifycenter justifyfull'.split(' '),function(i,cmdName){
+ me.commands[cmdName] = {
+ execCommand:function (cmdName) {
+ return this.document.execCommand(cmdName);
+ },
+ queryCommandValue: function (cmdName) {
+ var val = this.document.queryCommandValue(cmdName);
+ return val === true || val === 'true' ? cmdName.replace(/justify/,'') : '';
+ },
+ queryCommandState: function (cmdName) {
+ return this.document.queryCommandState(cmdName) ? 1 : 0
+ }
+ };
+ })
+};
+
+///import core
+///import plugins\removeformat.js
+///commands 字体颜色,背景色,字号,字体,下划线,删除线
+///commandsName ForeColor,BackColor,FontSize,FontFamily,Underline,StrikeThrough
+///commandsTitle 字体颜色,背景色,字号,字体,下划线,删除线
+/**
+ * @description 字体
+ * @name UM.execCommand
+ * @param {String} cmdName 执行的功能名称
+ * @param {String} value 传入的值
+ */
+UM.plugins['font'] = function () {
+ var me = this,
+ fonts = {
+ 'forecolor': 'forecolor',
+ 'backcolor': 'backcolor',
+ 'fontsize': 'fontsize',
+ 'fontfamily': 'fontname'
+ },
+ cmdNameToStyle = {
+ 'forecolor': 'color',
+ 'backcolor': 'background-color',
+ 'fontsize': 'font-size',
+ 'fontfamily': 'font-family'
+ },
+ cmdNameToAttr = {
+ 'forecolor': 'color',
+ 'fontsize': 'size',
+ 'fontfamily': 'face'
+ };
+ me.setOpt({
+ 'fontfamily': [
+ { 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'},
+ { name: 'sans-serif',val:'sans-serif'}
+ ],
+ 'fontsize': [10, 12, 16, 18,24, 32,48]
+ });
+
+ me.addOutputRule(function (root) {
+ utils.each(root.getNodesByTagName('font'), function (node) {
+ if (node.tagName == 'font') {
+ var cssStyle = [];
+ for (var p in node.attrs) {
+ switch (p) {
+ case 'size':
+ var val = node.attrs[p];
+ $.each({
+ '10':'1',
+ '12':'2',
+ '16':'3',
+ '18':'4',
+ '24':'5',
+ '32':'6',
+ '48':'7'
+ },function(k,v){
+ if(v == val){
+ val = k;
+ return false;
+ }
+ });
+ cssStyle.push('font-size:' + val + '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(';')
+ };
+ }
+ node.tagName = 'span';
+ if(node.parentNode.tagName == 'span' && node.parentNode.children.length == 1){
+ $.each(node.attrs,function(k,v){
+
+ node.parentNode.attrs[k] = k == 'style' ? node.parentNode.attrs[k] + v : v;
+ })
+ node.parentNode.removeChild(node,true);
+ }
+ });
+ });
+ for(var p in fonts){
+ (function (cmd) {
+ me.commands[cmd] = {
+ execCommand: function (cmdName,value) {
+ if(value == 'transparent'){
+ return;
+ }
+ var rng = this.selection.getRange();
+ if(rng.collapsed){
+ var span = $(' ').css(cmdNameToStyle[cmdName],value)[0];
+ rng.insertNode(span).setStart(span,0).setCursor();
+ }else{
+ if(cmdName == 'fontsize'){
+ value = {
+ '10':'1',
+ '12':'2',
+ '16':'3',
+ '18':'4',
+ '24':'5',
+ '32':'6',
+ '48':'7'
+ }[(value+"").replace(/px/,'')]
+ }
+ this.document.execCommand(fonts[cmdName],false, value);
+ if(browser.gecko){
+ $.each(this.$body.find('a'),function(i,a){
+ var parent = a.parentNode;
+ if(parent.lastChild === parent.firstChild && /FONT|SPAN/.test(parent.tagName)){
+ var cloneNode = parent.cloneNode(false);
+ cloneNode.innerHTML = a.innerHTML;
+ $(a).html('').append(cloneNode).insertBefore(parent);
+
+ $(parent).remove();
+ }
+ });
+ }
+ if(!browser.ie){
+ var nativeRange = this.selection.getNative().getRangeAt(0);
+ var common = nativeRange.commonAncestorContainer;
+ var rng = this.selection.getRange(),
+ bk = rng.createBookmark(true);
+
+ $(common).find('a').each(function(i,n){
+ var parent = n.parentNode;
+ if(parent.nodeName == 'FONT'){
+ var font = parent.cloneNode(false);
+ font.innerHTML = n.innerHTML;
+ $(n).html('').append(font);
+ }
+ });
+ rng.moveToBookmark(bk).select()
+ }
+ return true
+ }
+
+ },
+ queryCommandValue: function (cmdName) {
+ var start = me.selection.getStart();
+ var val = $(start).css(cmdNameToStyle[cmdName]);
+ if(val === undefined){
+ val = $(start).attr(cmdNameToAttr[cmdName])
+ }
+ return val ? utils.fixColor(cmdName,val).replace(/px/,'') : '';
+ },
+ queryCommandState: function (cmdName) {
+ return this.queryCommandValue(cmdName)
+ }
+ };
+ })(p);
+ }
+};
+///import core
+///commands 超链接,取消链接
+///commandsName Link,Unlink
+///commandsTitle 超链接,取消链接
+///commandsDialog dialogs\link
+/**
+ * 超链接
+ * @function
+ * @name UM.execCommand
+ * @param {String} cmdName link插入超链接
+ * @param {Object} options url地址,title标题,target是否打开新页
+ * @author zhanyi
+ */
+/**
+ * 取消链接
+ * @function
+ * @name UM.execCommand
+ * @param {String} cmdName unlink取消链接
+ * @author zhanyi
+ */
+
+UM.plugins['link'] = function(){
+ var me = this;
+
+ me.setOpt('autourldetectinie',false);
+ //在ie下禁用autolink
+ if(browser.ie && this.options.autourldetectinie === false){
+ this.addListener('keyup',function(cmd,evt){
+ var me = this,keyCode = evt.keyCode;
+ if(keyCode == 13 || keyCode == 32){
+ var rng = me.selection.getRange();
+ var start = rng.startContainer;
+ if(keyCode == 13){
+ if(start.nodeName == 'P'){
+ var pre = start.previousSibling;
+ if(pre && pre.nodeType == 1){
+ var pre = pre.lastChild;
+ if(pre && pre.nodeName == 'A' && !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);
+ }
+ }
+ }
+
+ }
+
+
+ });
+ }
+
+ this.addOutputRule(function(root){
+ $.each(root.getNodesByTagName('a'),function(i,a){
+ var _href = a.getAttr('_href');
+ if(!/^(ftp|https?|\/|file)/.test(_href)){
+ _href = 'http://' + _href;
+ }
+ a.setAttr('href', _href);
+ a.setAttr('_href')
+ if(a.getAttr('title')==''){
+ a.setAttr('title')
+ }
+ })
+ });
+ this.addInputRule(function(root){
+ $.each(root.getNodesByTagName('a'),function(i,a){
+ a.setAttr('_href', a.getAttr('href'));
+ })
+ });
+ me.commands['link'] = {
+ execCommand : function( cmdName, opt ) {
+
+ var me = this;
+ var rng = me.selection.getRange();
+ opt._href && (opt._href = utils.unhtml(opt._href, /[<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g));
+ opt.href && (opt.href = utils.unhtml(opt.href, /[<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g));
+ if(rng.collapsed){
+ var start = rng.startContainer;
+ if(start = domUtils.findParentByTagName(start,'a',true)){
+ $(start).attr(opt);
+ rng.selectNode(start).select()
+ }else{
+ rng.insertNode($('' + opt.href +' ').attr(opt)[0]).select()
+
+ }
+
+ }else{
+ me.document.execCommand('createlink',false,'_umeditor_link');
+ utils.each(domUtils.getElementsByTagName(me.body,'a',function(n){
+
+ return n.getAttribute('href') == '_umeditor_link'
+ }),function(l){
+ if($(l).text() == '_umeditor_link'){
+ $(l).text(opt.href);
+ }
+ domUtils.setAttributes(l,opt);
+ rng.selectNode(l).select()
+ })
+ }
+
+ },
+ queryCommandState:function(){
+ return this.queryCommandValue('link') ? 1 : 0;
+ },
+ queryCommandValue:function(){
+ var path = this.selection.getStartElementPath();
+ var result;
+ $.each(path,function(i,n){
+ if(n.nodeName == "A"){
+ result = n;
+ return false;
+ }
+ })
+ return result;
+ }
+ };
+ me.commands['unlink'] = {
+ execCommand : function() {
+ this.document.execCommand('unlink');
+ }
+ };
+};
+///import core
+///commands 打印
+///commandsName Print
+///commandsTitle 打印
+/**
+ * @description 打印
+ * @name baidu.editor.execCommand
+ * @param {String} cmdName print打印编辑器内容
+ * @author zhanyi
+ */
+UM.commands['print'] = {
+ execCommand : function(){
+ var me = this,
+ id = 'editor_print_' + +new Date();
+
+ $('').attr('id', id)
+ .css({
+ width:'0px',
+ height:'0px',
+ 'overflow':'hidden',
+ 'float':'left',
+ 'position':'absolute',
+ top:'-10000px',
+ left:'-10000px'
+ })
+ .appendTo(me.$container.find('.edui-dialog-container'));
+
+ var w = window.open('', id, ''),
+ d = w.document;
+ d.open();
+ d.write(''+this.getContent(null,null,true)+'
');
+ d.close();
+ },
+ notNeedUndo : 1
+};
+///import core
+///commands 格式
+///commandsName Paragraph
+///commandsTitle 段落格式
+/**
+ * 段落样式
+ * @function
+ * @name UM.execCommand
+ * @param {String} cmdName paragraph插入段落执行命令
+ * @param {String} style 标签值为:'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
+ * @param {String} attrs 标签的属性
+ * @author zhanyi
+ */
+UM.plugins['paragraph'] = function() {
+ var me = this;
+ me.setOpt('paragraph',{'p':'', 'h1':'', 'h2':'', 'h3':'', 'h4':'', 'h5':'', 'h6':''});
+ me.commands['paragraph'] = {
+ execCommand : function( cmdName, style ) {
+ return this.document.execCommand('formatBlock',false,'<' + style + '>');
+ },
+ queryCommandValue : function() {
+ try{
+ var val = this.document.queryCommandValue('formatBlock')
+ }catch(e){
+ }
+ return val ;
+ }
+ };
+};
+
+///import core
+///import plugins\inserthtml.js
+///commands 分割线
+///commandsName Horizontal
+///commandsTitle 分隔线
+/**
+ * 分割线
+ * @function
+ * @name UM.execCommand
+ * @param {String} cmdName horizontal插入分割线
+ */
+UM.plugins['horizontal'] = function(){
+ var me = this;
+ me.commands['horizontal'] = {
+ execCommand : function( ) {
+ this.document.execCommand('insertHorizontalRule');
+ var rng = me.selection.getRange().txtToElmBoundary(true),
+ start = rng.startContainer;
+ if(domUtils.isBody(rng.startContainer)){
+ var next = rng.startContainer.childNodes[rng.startOffset];
+ if(!next){
+ next = $('
').appendTo(rng.startContainer).html(browser.ie ? ' ' : ' ')[0]
+ }
+ rng.setStart(next,0).setCursor()
+ }else{
+
+ while(dtd.$inline[start.tagName] && start.lastChild === start.firstChild){
+
+ var parent = start.parentNode;
+ parent.appendChild(start.firstChild);
+ parent.removeChild(start);
+ start = parent;
+ }
+ while(dtd.$inline[start.tagName]){
+ start = start.parentNode;
+ }
+ if(start.childNodes.length == 1 && start.lastChild.nodeName == 'HR'){
+ var hr = start.lastChild;
+ $(hr).insertBefore(start);
+ rng.setStart(start,0).setCursor();
+ }else{
+ hr = $('hr',start)[0];
+ domUtils.breakParent(hr,start);
+ var pre = hr.previousSibling;
+ if(pre && domUtils.isEmptyBlock(pre)){
+ $(pre).remove()
+ }
+ rng.setStart(hr.nextSibling,0).setCursor();
+ }
+
+ }
+ }
+ };
+
+};
+
+
+///import core
+///commands 清空文档
+///commandsName ClearDoc
+///commandsTitle 清空文档
+/**
+ *
+ * 清空文档
+ * @function
+ * @name UM.execCommand
+ * @param {String} cmdName cleardoc清空文档
+ */
+
+UM.commands['cleardoc'] = {
+ execCommand : function() {
+ var me = this,
+ range = me.selection.getRange();
+ me.body.innerHTML = ""+(ie ? "" : " ")+"
";
+ range.setStart(me.body.firstChild,0).setCursor(false,true);
+ setTimeout(function(){
+ me.fireEvent("clearDoc");
+ },0);
+
+ }
+};
+
+
+///import core
+///commands 撤销和重做
+///commandsName Undo,Redo
+///commandsTitle 撤销,重做
+/**
+ * @description 回退
+ * @author zhanyi
+ */
+
+UM.plugins['undo'] = function () {
+ var saveSceneTimer;
+ var me = this,
+ maxUndoCount = me.options.maxUndoCount || 20,
+ maxInputCount = me.options.maxInputCount || 20,
+ fillchar = new RegExp(domUtils.fillChar + '|<\/hr>', '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 = UM.htmlparser(scene.content.replace(fillchar, ''));
+ me.options.autoClearEmptyNode = false;
+ me.filterInputRule(root,true);
+ me.options.autoClearEmptyNode = orgState;
+ //trace:873
+ //去掉展位符
+ me.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,me.body).moveToAddress(scene.address);
+ if(browser.ie && rng.collapsed && rng.startContainer.nodeType == 1){
+ var tmpNode = rng.startContainer.childNodes[rng.startOffset];
+ if( !tmpNode || tmpNode.nodeType == 1 && dtd.$empty[tmpNode]){
+ rng.insertNode(me.document.createTextNode(' ')).collapse(true);
+ }
+ }
+ 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 = UM.htmlparser(me.body.innerHTML,true);
+ me.options.autoClearEmptyNode = false;
+ me.filterOutputRule(root,true);
+ me.options.autoClearEmptyNode = orgState;
+ var cont = root.toHtml();
+ 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.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 () {
+ $(this.body).on('compositionstart', function () {
+ inputType = true;
+ }).on('compositionend', function () {
+ inputType = false;
+ })
+ });
+ //快捷键
+ me.addshortcutkey({
+ "Undo":"ctrl+90", //undo
+ "Redo":"ctrl+89,shift+ctrl+z" //redo
+
+ });
+ var isCollapsed = true;
+ me.addListener('keydown', 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){
+
+ if (cont.selection.getRange().collapsed)
+ cont.fireEvent('contentchange');
+ cont.undoManger.save(false,true);
+ cont.fireEvent('selectionchange');
+ }
+ saveSceneTimer = setTimeout(function(){
+ if(inputType){
+ var interalTimer = setInterval(function(){
+ if(!inputType){
+ save(me);
+ clearInterval(interalTimer)
+ }
+ },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;
+ }
+ }
+ });
+
+};
+
+///import core
+///import plugins/inserthtml.js
+///import plugins/undo.js
+///import plugins/serialize.js
+///commands 粘贴
+///commandsName PastePlain
+///commandsTitle 纯文本粘贴模式
+/**
+ * @description 粘贴
+ * @author zhanyi
+ */
+UM.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));
+ this.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:" +
+ //要在现在光标平行的位置加入,否则会出现跳动的问题
+ $(bk.start).position().top + '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;
+
+
+ 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 = '
';
+ domUtils.remove(pN);
+ }
+ }
+ var divs = div.querySelectorAll('#baidu_pastebin');
+ for (var i = 0, di; di = divs[i++];) {
+ var tmpP = me.document.createElement('p');
+ di.parentNode.insertBefore(tmpP, di);
+ while (di.firstChild) {
+ tmpP.appendChild(di.firstChild);
+ }
+ domUtils.remove(di);
+ }
+
+ var metas = div.querySelectorAll('meta');
+ for (var i = 0, ci; ci = metas[i++];) {
+ domUtils.remove(ci);
+ }
+
+ var brs = div.querySelectorAll('br');
+ for (i = 0; ci = brs[i++];) {
+ if (/^apple-/i.test(ci.className)) {
+ domUtils.remove(ci);
+ }
+ }
+ }
+ if (browser.gecko) {
+ var dirtyNodes = div.querySelectorAll('[_moz_dirty]');
+ for (i = 0; ci = dirtyNodes[i++];) {
+ ci.removeAttribute('_moz_dirty');
+ }
+ }
+ if (!browser.ie) {
+ var spans = div.querySelectorAll('span.Apple-style-span');
+ for (var i = 0, ci; ci = spans[i++];) {
+ domUtils.remove(ci, true);
+ }
+ }
+
+ //ie下使用innerHTML会产生多余的\r\n字符,也会产生 这里过滤掉
+ html = div.innerHTML;//.replace(/>(?:(\s| )*?)<');
+
+ //过滤word粘贴过来的冗余属性
+ html = UM.filterWord(html);
+ //取消了忽略空白的第二个参数,粘贴过来的有些是有空白的,会被套上相关的标签
+ var root = UM.htmlparser(html);
+ //如果给了过滤规则就先进行过滤
+ if (me.options.filterRules) {
+ UM.filterNode(root, me.options.filterRules);
+ }
+ //执行默认的处理
+ me.filterInputRule(root);
+ //针对chrome的处理
+ if (browser.webkit) {
+ var br = root.lastChild();
+ if (br && br.type == 'element' && br.tagName == 'br') {
+ root.removeChild(br)
+ }
+ utils.each(me.body.querySelectorAll('div'), function (node) {
+ if (domUtils.isEmptyBlock(node)) {
+ domUtils.remove(node)
+ }
+ })
+ }
+ html = {'html': root.toHtml()};
+ me.fireEvent('beforepaste', html, root);
+ //抢了默认的粘贴,那后边的内容就不执行了,比如表格粘贴
+ if(!html.html){
+ return;
+ }
+
+ me.execCommand('insertHtml', html.html, true);
+ me.fireEvent("afterpaste", html);
+ }
+ }
+
+
+ me.addListener('ready', function () {
+ $(me.body).on( 'cut', function () {
+ var range = me.selection.getRange();
+ if (!range.collapsed && me.undoManger) {
+ me.undoManger.save();
+ }
+ }).on(browser.ie || browser.opera ? 'keydown' : 'paste', function (e) {
+ //ie下beforepaste在点击右键时也会触发,所以用监控键盘才处理
+ if ((browser.ie || browser.opera) && ((!e.ctrlKey && !e.metaKey) || e.keyCode != '86')) {
+ return;
+ }
+ getClipboardData.call(me, function (div) {
+ filter(div);
+ });
+ });
+
+ });
+};
+
+
+///import core
+///commands 有序列表,无序列表
+///commandsName InsertOrderedList,InsertUnorderedList
+///commandsTitle 有序列表,无序列表
+/**
+ * 有序列表
+ * @function
+ * @name UM.execCommand
+ * @param {String} cmdName insertorderlist插入有序列表
+ * @param {String} style 值为:decimal,lower-alpha,lower-roman,upper-alpha,upper-roman
+ * @author zhanyi
+ */
+/**
+ * 无序链接
+ * @function
+ * @name UM.execCommand
+ * @param {String} cmdName insertunorderlist插入无序列表
+ * * @param {String} style 值为:circle,disc,square
+ * @author zhanyi
+ */
+
+UM.plugins['list'] = function () {
+ var me = this;
+
+ me.setOpt( {
+ 'insertorderedlist':{
+ 'decimal':'',
+ 'lower-alpha':'',
+ 'lower-roman':'',
+ 'upper-alpha':'',
+ 'upper-roman':''
+ },
+ 'insertunorderedlist':{
+ 'circle':'',
+ 'disc':'',
+ 'square':''
+ }
+ } );
+
+ this.addInputRule(function(root){
+ utils.each(root.getNodesByTagName('li'), function (node) {
+ if(node.children.length == 0){
+ node.parentNode.removeChild(node);
+ }
+ })
+ });
+ me.commands['insertorderedlist'] =
+ me.commands['insertunorderedlist'] = {
+ execCommand:function (cmdName) {
+ this.document.execCommand(cmdName);
+ var rng = this.selection.getRange(),
+ bk = rng.createBookmark(true);
+
+ this.$body.find('ol,ul').each(function(i,n){
+ var parent = n.parentNode;
+ if(parent.tagName == 'P' && parent.lastChild === parent.firstChild){
+ $(n).children().each(function(j,li){
+ var p = parent.cloneNode(false);
+ $(p).append(li.innerHTML);
+ $(li).html('').append(p);
+ });
+ $(n).insertBefore(parent);
+ $(parent).remove();
+ }
+
+ if(dtd.$inline[parent.tagName]){
+ if(parent.tagName == 'SPAN'){
+
+ $(n).children().each(function(k,li){
+ var span = parent.cloneNode(false);
+ if(li.firstChild.nodeName != 'P'){
+
+ while(li.firstChild){
+ span.appendChild(li.firstChild)
+ };
+ $('
').appendTo(li).append(span);
+ }else{
+ while(li.firstChild){
+ span.appendChild(li.firstChild)
+ };
+ $(li.firstChild).append(span);
+ }
+ })
+
+ }
+ domUtils.remove(parent,true)
+ }
+ });
+
+
+
+
+ rng.moveToBookmark(bk).select();
+ return true;
+ },
+ queryCommandState:function (cmdName) {
+ return this.document.queryCommandState(cmdName);
+ }
+ };
+};
+
+
+///import core
+///import plugins/serialize.js
+///import plugins/undo.js
+///commands 查看源码
+///commandsName Source
+///commandsTitle 查看源码
+(function (){
+ var sourceEditors = {
+ textarea: function (editor, holder){
+ var textarea = holder.ownerDocument.createElement('textarea');
+ textarea.style.cssText = 'resize:none;border:0;padding:0;margin:0;overflow-y:auto;outline:0';
+ // todo: IE下只有onresize属性可用... 很纠结
+ if (browser.ie && browser.version < 8) {
+
+ textarea.style.width = holder.offsetWidth + 'px';
+ textarea.style.height = holder.offsetHeight + 'px';
+ holder.onresize = function (){
+ textarea.style.width = holder.offsetWidth + 'px';
+ textarea.style.height = holder.offsetHeight + 'px';
+ };
+ }
+ holder.appendChild(textarea);
+ return {
+ container : textarea,
+ setContent: function (content){
+ textarea.value = content;
+ },
+ getContent: function (){
+ return textarea.value;
+ },
+ select: function (){
+ var range;
+ if (browser.ie) {
+ range = textarea.createTextRange();
+ range.collapse(true);
+ range.select();
+ } else {
+ //todo: chrome下无法设置焦点
+ textarea.setSelectionRange(0, 0);
+ textarea.focus();
+ }
+ },
+ dispose: function (){
+ holder.removeChild(textarea);
+ // todo
+ holder.onresize = null;
+ textarea = null;
+ holder = null;
+ }
+ };
+ }
+ };
+
+ UM.plugins['source'] = function (){
+ var me = this;
+ var opt = this.options;
+ var sourceMode = false;
+ var sourceEditor;
+
+ opt.sourceEditor = 'textarea';
+
+ me.setOpt({
+ sourceEditorFirst:false
+ });
+ function createSourceEditor(holder){
+ return sourceEditors.textarea(me, holder);
+ }
+
+ var bakCssText;
+ //解决在源码模式下getContent不能得到最新的内容问题
+ var oldGetContent = me.getContent,
+ bakAddress;
+
+ me.commands['source'] = {
+ execCommand: function (){
+
+ sourceMode = !sourceMode;
+ if (sourceMode) {
+ bakAddress = me.selection.getRange().createAddress(false,true);
+ me.undoManger && me.undoManger.save(true);
+ if(browser.gecko){
+ me.body.contentEditable = false;
+ }
+
+// bakCssText = me.body.style.cssText;
+ me.body.style.cssText += ';position:absolute;left:-32768px;top:-32768px;';
+
+
+ me.fireEvent('beforegetcontent');
+ var root = UM.htmlparser(me.body.innerHTML);
+ me.filterOutputRule(root);
+ root.traversal(function (node) {
+ if (node.type == 'element') {
+ switch (node.tagName) {
+ case 'td':
+ case 'th':
+ case 'caption':
+ if(node.children && node.children.length == 1){
+ if(node.firstChild().tagName == 'br' ){
+ node.removeChild(node.firstChild())
+ }
+ };
+ break;
+ case 'pre':
+ node.innerText(node.innerText().replace(/ /g,' '))
+
+ }
+ }
+ });
+
+ me.fireEvent('aftergetcontent');
+
+ var content = root.toHtml(true);
+
+ sourceEditor = createSourceEditor(me.body.parentNode);
+
+ sourceEditor.setContent(content);
+
+ var getStyleValue=function(attr){
+ return parseInt($(me.body).css(attr));
+ };
+ $(sourceEditor.container).width($(me.body).width()+getStyleValue("padding-left")+getStyleValue("padding-right"))
+ .height($(me.body).height());
+ setTimeout(function (){
+ sourceEditor.select();
+ });
+ //重置getContent,源码模式下取值也能是最新的数据
+ me.getContent = function (){
+ return sourceEditor.getContent() || '' + (browser.ie ? '' : ' ')+'
';
+ };
+ } else {
+ me.$body.css({
+ 'position':'',
+ 'left':'',
+ 'top':''
+ });
+// me.body.style.cssText = bakCssText;
+ var cont = sourceEditor.getContent() || '' + (browser.ie ? '' : ' ')+'
';
+ //处理掉block节点前后的空格,有可能会误命中,暂时不考虑
+ cont = cont.replace(new RegExp('[\\r\\t\\n ]*<\/?(\\w+)\\s*(?:[^>]*)>','g'), function(a,b){
+ if(b && !dtd.$inlineWithA[b.toLowerCase()]){
+ return a.replace(/(^[\n\r\t ]*)|([\n\r\t ]*$)/g,'');
+ }
+ return a.replace(/(^[\n\r\t]*)|([\n\r\t]*$)/g,'')
+ });
+ me.setContent(cont);
+ sourceEditor.dispose();
+ sourceEditor = null;
+ //还原getContent方法
+ me.getContent = oldGetContent;
+ var first = me.body.firstChild;
+ //trace:1106 都删除空了,下边会报错,所以补充一个p占位
+ if(!first){
+ me.body.innerHTML = ''+(browser.ie?'':' ')+'
';
+ }
+ //要在ifm为显示时ff才能取到selection,否则报错
+ //这里不能比较位置了
+ me.undoManger && me.undoManger.save(true);
+ if(browser.gecko){
+ me.body.contentEditable = true;
+ }
+ try{
+ me.selection.getRange().moveToAddress(bakAddress).select();
+ }catch(e){}
+
+ }
+ this.fireEvent('sourcemodechanged', sourceMode);
+ },
+ queryCommandState: function (){
+ return sourceMode|0;
+ },
+ notNeedUndo : 1
+ };
+ var oldQueryCommandState = me.queryCommandState;
+
+
+ me.queryCommandState = function (cmdName){
+ cmdName = cmdName.toLowerCase();
+ if (sourceMode) {
+ //源码模式下可以开启的命令
+ return cmdName in {
+ 'source' : 1,
+ 'fullscreen' : 1
+ } ? oldQueryCommandState.apply(this, arguments) : -1
+ }
+ return oldQueryCommandState.apply(this, arguments);
+ };
+
+ };
+
+})();
+///import core
+///import plugins/undo.js
+///commands 设置回车标签p或br
+///commandsName EnterKey
+///commandsTitle 设置回车标签p或br
+/**
+ * @description 处理回车
+ * @author zhanyi
+ */
+UM.plugins['enterkey'] = function() {
+ var hTag,
+ me = this,
+ tag = me.options.enterTag;
+ me.addListener('keyup', function(type, evt) {
+
+ var keyCode = evt.keyCode || evt.which;
+ if (keyCode == 13) {
+ var range = me.selection.getRange(),
+ start = range.startContainer,
+ doSave;
+
+ //修正在h1-h6里边回车后不能嵌套p的问题
+ if (!browser.ie) {
+
+ if (/h\d/i.test(hTag)) {
+ if (browser.gecko) {
+ var h = domUtils.findParentByTagName(start, [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption','table'], true);
+ if (!h) {
+ me.document.execCommand('formatBlock', false, '');
+ 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);
+ }
+
+ }
+
+ }
+
+ }
+ });
+
+ browser.ie && me.addListener('setDisabled',function(){
+ $(me.body).find('p').each(function(i,p){
+ if(domUtils.isEmptyBlock(p)){
+ p.innerHTML = ' '
+ }
+ })
+ })
+};
+
+///import core
+///commands 预览
+///commandsName Preview
+///commandsTitle 预览
+/**
+ * 预览
+ * @function
+ * @name UM.execCommand
+ * @param {String} cmdName preview预览编辑器内容
+ */
+UM.commands['preview'] = {
+ execCommand : function(){
+ var w = window.open('', '_blank', ''),
+ d = w.document,
+ c = this.getContent(null,null,true),
+ path = this.getOpt('UMEDITOR_HOME_URL'),
+ formula = c.indexOf('mathquill-embedded-latex')!=-1 ?
+ ' ' +
+ '' +
+ '':'';
+ d.open();
+ d.write('
' + formula + ''+c+'
');
+ d.close();
+ },
+ notNeedUndo : 1
+};
+
+///import core
+///commands 加粗,斜体,上标,下标
+///commandsName Bold,Italic,Subscript,Superscript
+///commandsTitle 加粗,加斜,下标,上标
+/**
+ * b u i等基础功能实现
+ * @function
+ * @name UM.execCommands
+ * @param {String} cmdName bold加粗。italic斜体。subscript上标。superscript下标。
+*/
+UM.plugins['basestyle'] = function(){
+ var basestyles = ['bold','underline','superscript','subscript','italic','strikethrough'],
+ me = this;
+ //添加快捷键
+ me.addshortcutkey({
+ "Bold" : "ctrl+66",//^B
+ "Italic" : "ctrl+73", //^I
+ "Underline" : "ctrl+shift+85",//^U
+ "strikeThrough" : 'ctrl+shift+83' //^s
+ });
+ //过滤最后的产出数据
+ me.addOutputRule(function(root){
+ $.each(root.getNodesByTagName('b i u strike s'),function(i,node){
+ switch (node.tagName){
+ case 'b':
+ node.tagName = 'strong';
+ break;
+ case 'i':
+ node.tagName = 'em';
+ break;
+ case 'u':
+ node.tagName = 'span';
+ node.setStyle('text-decoration','underline');
+ break;
+ case 's':
+ case 'strike':
+ node.tagName = 'span';
+ node.setStyle('text-decoration','line-through')
+ }
+ });
+ });
+ $.each(basestyles,function(i,cmd){
+ me.commands[cmd] = {
+ execCommand : function( cmdName ) {
+ var rng = this.selection.getRange();
+ if(rng.collapsed && this.queryCommandState(cmdName) != 1){
+ var node = this.document.createElement({
+ 'bold':'strong',
+ 'underline':'u',
+ 'superscript':'sup',
+ 'subscript':'sub',
+ 'italic':'em',
+ 'strikethrough':'strike'
+ }[cmdName]);
+ rng.insertNode(node).setStart(node,0).setCursor(false);
+ return true;
+ }else{
+ return this.document.execCommand(cmdName)
+ }
+
+ },
+ queryCommandState : function(cmdName) {
+ if(browser.gecko){
+ return this.document.queryCommandState(cmdName)
+ }
+ var path = this.selection.getStartElementPath(),result = false;
+ $.each(path,function(i,n){
+ switch (cmdName){
+ case 'bold':
+ if(n.nodeName == 'STRONG' || n.nodeName == 'B'){
+ result = 1;
+ return false;
+ }
+ break;
+ case 'underline':
+ if(n.nodeName == 'U' || n.nodeName == 'SPAN' && $(n).css('text-decoration') == 'underline'){
+ result = 1;
+ return false;
+ }
+ break;
+ case 'superscript':
+ if(n.nodeName == 'SUP'){
+ result = 1;
+ return false;
+ }
+ break;
+ case 'subscript':
+ if(n.nodeName == 'SUB'){
+ result = 1;
+ return false;
+ }
+ break;
+ case 'italic':
+ if(n.nodeName == 'EM' || n.nodeName == 'I'){
+ result = 1;
+ return false;
+ }
+ break;
+ case 'strikethrough':
+ if(n.nodeName == 'S' || n.nodeName == 'STRIKE' || n.nodeName == 'SPAN' && $(n).css('text-decoration') == 'line-through'){
+ result = 1;
+ return false;
+ }
+ break;
+ }
+ })
+ return result
+ }
+ };
+ })
+};
+
+
+///import core
+///import plugins/inserthtml.js
+///commands 视频
+///commandsName InsertVideo
+///commandsTitle 插入视频
+///commandsDialog dialogs\video
+UM.plugins['video'] = function (){
+ var me =this,
+ div;
+
+ /**
+ * 创建插入视频字符窜
+ * @param url 视频地址
+ * @param width 视频宽度
+ * @param height 视频高度
+ * @param align 视频对齐
+ * @param toEmbed 是否以flash代替显示
+ * @param addParagraph 是否需要添加P 标签
+ */
+ function creatInsertStr(url,width,height,id,align,toEmbed){
+ return !toEmbed ?
+
+ ' '
+
+ :
+ '';
+ }
+
+ function switchImgAndEmbed(root,img2embed){
+ utils.each(root.getNodesByTagName(img2embed ? 'img' : 'embed'),function(node){
+ if(node.getAttr('class') == 'edui-faked-video'){
+
+ var html = creatInsertStr( img2embed ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',img2embed);
+ node.parentNode.replaceChild(UM.uNode.createElement(html),node)
+ }
+ })
+ }
+
+ me.addOutputRule(function(root){
+ switchImgAndEmbed(root,true)
+ });
+ me.addInputRule(function(root){
+ switchImgAndEmbed(root)
+ });
+
+ me.commands["insertvideo"] = {
+ execCommand: function (cmd, videoObjs){
+ videoObjs = utils.isArray(videoObjs)?videoObjs:[videoObjs];
+ var html = [],id = 'tmpVedio';
+ for(var i=0,vi,len = videoObjs.length;i'](?:(amp|lt|quot|gt|#39|nbsp);)?/g);
+ html.push(creatInsertStr( vi.url, vi.width || 420, vi.height || 280, id + i,vi.align,false));
+ }
+ me.execCommand("inserthtml",html.join(""),true);
+
+ },
+ queryCommandState : function(){
+ var img = me.selection.getRange().getClosedNode(),
+ flag = img && (img.className == "edui-faked-video");
+ return flag ? 1 : 0;
+ }
+ };
+};
+///import core
+///commands 全选
+///commandsName SelectAll
+///commandsTitle 全选
+/**
+ * 选中所有
+ * @function
+ * @name UM.execCommand
+ * @param {String} cmdName selectall选中编辑器里的所有内容
+ * @author zhanyi
+*/
+UM.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"
+ });
+};
+
+//UM.plugins['removeformat'] = function () {
+// var me = this;
+// me.commands['removeformat'] = {
+// execCommand: function () {
+// me.document.execCommand('removeformat');
+//
+// /* 处理ie8和firefox选区有链接时,清除格式的bug */
+// if (browser.gecko || browser.ie8 || browser.webkit) {
+// var nativeRange = this.selection.getNative().getRangeAt(0),
+// common = nativeRange.commonAncestorContainer,
+// rng = me.selection.getRange(),
+// bk = rng.createBookmark();
+//
+// function isEleInBookmark(node, bk){
+// if ( (domUtils.getPosition(node, bk.start) & domUtils.POSITION_FOLLOWING) &&
+// (domUtils.getPosition(bk.end, node) & domUtils.POSITION_FOLLOWING) ) {
+// return true;
+// } else if ( (domUtils.getPosition(node, bk.start) & domUtils.POSITION_CONTAINS) ||
+// (domUtils.getPosition(node, bk.end) & domUtils.POSITION_CONTAINS) ) {
+// return true;
+// }
+// return false;
+// }
+//
+// $(common).find('a').each(function (k, a) {
+// if ( isEleInBookmark(a, bk) ) {
+// a.removeAttribute('style');
+// }
+// });
+//
+// }
+// }
+// };
+//
+//};
+//
+
+
+UM.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
+ var node = range.startContainer,
+ tmp,
+ collapsed = range.collapsed;
+ while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){
+ tmp = node.parentNode;
+ range.setStartBefore(node);
+ //trace:937
+ //更新结束边界
+ if(range.startContainer === range.endContainer){
+ range.endOffset--;
+ }
+ domUtils.remove(node);
+ node = tmp;
+ }
+
+ if(!collapsed){
+ node = range.endContainer;
+ while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){
+ tmp = node.parentNode;
+ range.setEndBefore(node);
+ domUtils.remove(node);
+
+ node = tmp;
+ }
+
+
+ }
+ }
+
+
+
+ range = this.selection.getRange();
+ if(!range.collapsed) {
+ doRemove( range );
+ range.select();
+ }
+
+ }
+
+ };
+
+};
+/*
+ * 处理特殊键的兼容性问题
+ */
+UM.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]
+ if(rng.endContainer && rng.endContainer.nodeType == 1){
+ tmpNode = rng.endContainer.childNodes[rng.endOffset];
+ if(tmpNode && domUtils.isBr(tmpNode)){
+ rng.setEndAfter(tmpNode);
+ }
+ }
+ if(rng.startOffset == 0){
+ tmpNode = rng.startContainer;
+ if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){
+ tmpNode = rng.endContainer;
+ if(rng.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){
+ me.fireEvent('saveScene');
+ me.body.innerHTML = ''+(browser.ie ? '' : ' ')+'
';
+ rng.setStart(me.body.firstChild,0).setCursor(false,true);
+ me._selectionChange();
+ return;
+ }
+ }
+ }
+ }
+
+ //处理backspace
+ if (keyCode == 8) {
+ rng = me.selection.getRange();
+ collapsed = rng.collapsed;
+ if(me.fireEvent('delkeydown',evt)){
+ return;
+ }
+ var start,end;
+ //避免按两次删除才能生效的问题
+ if(rng.collapsed && rng.inFillChar()){
+ start = rng.startContainer;
+
+ if(domUtils.isFillChar(start)){
+ rng.setStartBefore(start).shrinkBoundary(true).collapse(true);
+ domUtils.remove(start)
+ }else{
+ start.nodeValue = start.nodeValue.replace(new RegExp('^' + domUtils.fillChar ),'');
+ rng.startOffset--;
+ rng.collapse(true).select(true)
+ }
+ }
+ //解决选中control元素不能删除的问题
+ if (start = rng.getClosedNode()) {
+ me.fireEvent('saveScene');
+ rng.setStartBefore(start);
+ domUtils.remove(start);
+ rng.setCursor();
+ me.fireEvent('saveScene');
+ domUtils.preventDefault(evt);
+ return;
+ }
+ //阻止在table上的删除
+ if (!browser.ie) {
+ start = domUtils.findParentByTagName(rng.startContainer, 'table', true);
+ end = domUtils.findParentByTagName(rng.endContainer, 'table', true);
+ if (start && !end || !start && end || start !== end) {
+ evt.preventDefault();
+ return;
+ }
+ }
+ start = rng.startContainer;
+ if(rng.collapsed && start.nodeType == 1){
+ var currentNode = start.childNodes[rng.startOffset-1];
+ if(currentNode && currentNode.nodeType == 1 && currentNode.tagName == 'BR'){
+ me.fireEvent('saveScene');
+ rng.setStartBefore(currentNode).collapse(true);
+ domUtils.remove(currentNode);
+ rng.select();
+ me.fireEvent('saveScene');
+ }
+ }
+
+ //trace:3613
+ if(browser.chrome){
+ if(rng.collapsed){
+
+ while(rng.startOffset == 0 && !domUtils.isEmptyBlock(rng.startContainer)){
+ rng.setStartBefore(rng.startContainer)
+ }
+ var pre = rng.startContainer.childNodes[rng.startOffset-1];
+ if(pre && pre.nodeName == 'BR'){
+ rng.setStartBefore(pre);
+ me.fireEvent('saveScene');
+ $(pre).remove();
+ rng.setCursor();
+ me.fireEvent('saveScene');
+ }
+
+ }
+ }
+ }
+ //trace:1634
+ //ff的del键在容器空的时候,也会删除
+ if(browser.gecko && keyCode == 46){
+ var range = me.selection.getRange();
+ if(range.collapsed){
+ start = range.startContainer;
+ if(domUtils.isEmptyBlock(start)){
+ var parent = start.parentNode;
+ while(domUtils.getChildCount(parent) == 1 && !domUtils.isBody(parent)){
+ start = parent;
+ parent = parent.parentNode;
+ }
+ if(start === parent.lastChild)
+ evt.preventDefault();
+ return;
+ }
+ }
+ }
+ });
+ me.addListener('keyup', function(type, evt) {
+ var keyCode = evt.keyCode || evt.which,
+ rng,me = this;
+ if(keyCode == 8){
+ if(me.fireEvent('delkeyup')){
+ return;
+ }
+ rng = me.selection.getRange();
+ if(rng.collapsed){
+ var tmpNode,
+ autoClearTagName = ['h1','h2','h3','h4','h5','h6'];
+ if(tmpNode = domUtils.findParentByTagName(rng.startContainer,autoClearTagName,true)){
+ if(domUtils.isEmptyBlock(tmpNode)){
+ var pre = tmpNode.previousSibling;
+ if(pre && pre.nodeName != 'TABLE'){
+ domUtils.remove(tmpNode);
+ rng.setStartAtLast(pre).setCursor(false,true);
+ return;
+ }else{
+ var next = tmpNode.nextSibling;
+ if(next && next.nodeName != 'TABLE'){
+ domUtils.remove(tmpNode);
+ rng.setStartAtFirst(next).setCursor(false,true);
+ return;
+ }
+ }
+ }
+ }
+ //处理当删除到body时,要重新给p标签展位
+ if(domUtils.isBody(rng.startContainer)){
+ var tmpNode = domUtils.createElement(me.document,'p',{
+ 'innerHTML' : browser.ie ? domUtils.fillChar : ' '
+ });
+ 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()
+ }
+
+ }
+ }
+
+ })
+};
+/**
+ * 自动保存草稿
+ */
+UM.plugins['autosave'] = function() {
+
+
+ var me = this,
+ //无限循环保护
+ lastSaveTime = new Date(),
+ //最小保存间隔时间
+ MIN_TIME = 20,
+ //auto save key
+ saveKey = null;
+
+
+ //默认间隔时间
+ me.setOpt('saveInterval', 500);
+
+ //存储媒介封装
+ var LocalStorage = UM.LocalStorage = ( function () {
+
+ var storage = window.localStorage || getUserData() || null,
+ LOCAL_FILE = "localStorage";
+
+ return {
+
+ saveLocalData: function ( key, data ) {
+
+ if ( storage && data) {
+ storage.setItem( key, data );
+ return true;
+ }
+
+ return false;
+
+ },
+
+ getLocalData: function ( key ) {
+
+ if ( storage ) {
+ return storage.getItem( key );
+ }
+
+ return null;
+
+ },
+
+ removeItem: function ( key ) {
+
+ storage && storage.removeItem( key );
+
+ }
+
+ };
+
+ function getUserData () {
+
+ var container = document.createElement( "div" );
+ container.style.display = "none";
+
+ if( !container.addBehavior ) {
+ return null;
+ }
+
+ container.addBehavior("#default#userdata");
+
+ return {
+
+ getItem: function ( key ) {
+
+ var result = null;
+
+ try {
+ document.body.appendChild( container );
+ container.load( LOCAL_FILE );
+ result = container.getAttribute( key );
+ document.body.removeChild( container );
+ } catch ( e ) {
+ }
+
+ return result;
+
+ },
+
+ setItem: function ( key, value ) {
+
+ document.body.appendChild( container );
+ container.setAttribute( key, value );
+ container.save( LOCAL_FILE );
+ document.body.removeChild( container );
+
+ },
+// 暂时没有用到
+// clear: function () {
+//
+// var expiresTime = new Date();
+// expiresTime.setFullYear( expiresTime.getFullYear() - 1 );
+// document.body.appendChild( container );
+// container.expires = expiresTime.toUTCString();
+// container.save( LOCAL_FILE );
+// document.body.removeChild( container );
+//
+// },
+
+ removeItem: function ( key ) {
+
+ document.body.appendChild( container );
+ container.removeAttribute( key );
+ container.save( LOCAL_FILE );
+ document.body.removeChild( container );
+
+ }
+
+ };
+
+ }
+
+ } )();
+
+ function save ( editor ) {
+
+ var saveData = null;
+
+ if ( new Date() - lastSaveTime < MIN_TIME ) {
+ return;
+ }
+
+ if ( !editor.hasContents() ) {
+ //这里不能调用命令来删除, 会造成事件死循环
+ saveKey && LocalStorage.removeItem( saveKey );
+ return;
+ }
+
+ lastSaveTime = new Date();
+
+ editor._saveFlag = null;
+
+ saveData = me.body.innerHTML;
+
+ if ( editor.fireEvent( "beforeautosave", {
+ content: saveData
+ } ) === false ) {
+ return;
+ }
+
+ LocalStorage.saveLocalData( saveKey, saveData );
+
+ editor.fireEvent( "afterautosave", {
+ content: saveData
+ } );
+
+ }
+
+ me.addListener('ready', function(){
+ var _suffix = "-drafts-data",
+ key = null;
+
+ if ( me.key ) {
+ key = me.key + _suffix;
+ } else {
+ key = ( me.container.parentNode.id || 'ue-common' ) + _suffix;
+ }
+
+ //页面地址+编辑器ID 保持唯一
+ saveKey = ( location.protocol + location.host + location.pathname ).replace( /[.:\/]/g, '_' ) + key;
+ });
+
+ me.addListener('contentchange', function(){
+
+ if ( !saveKey ) {
+ return;
+ }
+
+ if ( me._saveFlag ) {
+ window.clearTimeout( me._saveFlag );
+ }
+
+ if ( me.options.saveInterval > 0 ) {
+
+ me._saveFlag = window.setTimeout( function () {
+
+ save( me );
+
+ }, me.options.saveInterval );
+
+ } else {
+
+ save(me);
+
+ }
+
+ })
+
+
+ me.commands['clearlocaldata'] = {
+ execCommand:function (cmd, name) {
+ if ( saveKey && LocalStorage.getLocalData( saveKey ) ) {
+ LocalStorage.removeItem( saveKey )
+ }
+ },
+ notNeedUndo: true,
+ ignoreContentChange:true
+ };
+
+ me.commands['getlocaldata'] = {
+ execCommand:function (cmd, name) {
+ return saveKey ? LocalStorage.getLocalData( saveKey ) || '' : '';
+ },
+ notNeedUndo: true,
+ ignoreContentChange:true
+ };
+
+ me.commands['drafts'] = {
+ execCommand:function (cmd, name) {
+ if ( saveKey ) {
+ me.body.innerHTML = LocalStorage.getLocalData( saveKey ) || ''+(browser.ie ? ' ' : ' ')+'
';
+ me.focus(true);
+ }
+ },
+ queryCommandState: function () {
+ return saveKey ? ( LocalStorage.getLocalData( saveKey ) === null ? -1 : 0 ) : -1;
+ },
+ notNeedUndo: true,
+ ignoreContentChange:true
+ }
+
+};
+
+/**
+ * @description
+ * 1.拖放文件到编辑区域,自动上传并插入到选区
+ * 2.插入粘贴板的图片,自动上传并插入到选区
+ * @author Jinqn
+ * @date 2013-10-14
+ */
+UM.plugins['autoupload'] = function () {
+
+ var me = this;
+
+ me.setOpt('pasteImageEnabled', true);
+ me.setOpt('dropFileEnabled', true);
+ var sendAndInsertImage = function (file, editor) {
+ //模拟数据
+ var fd = new FormData();
+ fd.append(editor.options.imageFieldName || 'upfile', file, file.name || ('blob.' + file.type.substr('image/'.length)));
+ fd.append('type', 'ajax');
+ var xhr = new XMLHttpRequest();
+ xhr.open("post", me.options.imageUrl, true);
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ xhr.addEventListener('load', function (e) {
+ try {
+ var json = eval('('+e.target.response+')'),
+ link = json.url,
+ picLink = me.options.imagePath + link;
+ editor.execCommand('insertimage', {
+ src: picLink,
+ _src: picLink
+ });
+ } catch (er) {
+ }
+ });
+ xhr.send(fd);
+ };
+
+ function getPasteImage(e) {
+ return e.clipboardData && e.clipboardData.items && e.clipboardData.items.length == 1 && /^image\//.test(e.clipboardData.items[0].type) ? e.clipboardData.items : null;
+ }
+
+ function getDropImage(e) {
+ return e.dataTransfer && e.dataTransfer.files ? e.dataTransfer.files : null;
+ }
+
+ me.addListener('ready', function () {
+ if (window.FormData && window.FileReader) {
+ var autoUploadHandler = function (e) {
+ var hasImg = false,
+ items;
+ //获取粘贴板文件列表或者拖放文件列表
+ items = e.type == 'paste' ? getPasteImage(e.originalEvent) : getDropImage(e.originalEvent);
+ if (items) {
+ var len = items.length,
+ file;
+ while (len--) {
+ file = items[len];
+ if (file.getAsFile) file = file.getAsFile();
+ if (file && file.size > 0 && /image\/\w+/i.test(file.type)) {
+ sendAndInsertImage(file, me);
+ hasImg = true;
+ }
+ }
+ if (hasImg) return false;
+ }
+
+ };
+ me.getOpt('pasteImageEnabled') && me.$body.on('paste', autoUploadHandler);
+ me.getOpt('dropFileEnabled') && me.$body.on('drop', autoUploadHandler);
+
+ //取消拖放图片时出现的文字光标位置提示
+ me.$body.on('dragover', function (e) {
+ if (e.originalEvent.dataTransfer.types[0] == 'Files') {
+ return false;
+ }
+ });
+ }
+ });
+
+};
+/**
+ * 公式插件
+ */
+UM.plugins['formula'] = function () {
+ var me = this;
+
+ function getActiveIframe() {
+ return me.$body.find('iframe.edui-formula-active')[0] || null;
+ }
+
+ function blurActiveIframe(){
+ var iframe = getActiveIframe();
+ iframe && iframe.contentWindow.formula.blur();
+ }
+
+ me.addInputRule(function (root) {
+ $.each(root.getNodesByTagName('span'), function (i, node) {
+ if (node.hasClass('mathquill-embedded-latex')) {
+ var firstChild, latex = '';
+ while(firstChild = node.firstChild()){
+ latex += firstChild.data;
+ node.removeChild(firstChild);
+ }
+ node.tagName = 'iframe';
+ node.setAttr({
+ 'frameborder': '0',
+ 'src': me.getOpt('UMEDITOR_HOME_URL') + 'dialogs/formula/formula.html',
+ 'data-latex': utils.unhtml(latex)
+ });
+ }
+ });
+ });
+ me.addOutputRule(function (root) {
+ $.each(root.getNodesByTagName('iframe'), function (i, node) {
+ if (node.hasClass('mathquill-embedded-latex')) {
+ node.tagName = 'span';
+ node.appendChild(UM.uNode.createText(node.getAttr('data-latex')));
+ node.setAttr({
+ 'frameborder': '',
+ 'src': '',
+ 'data-latex': ''
+ });
+ }
+ });
+ });
+ me.addListener('click', function(){
+ blurActiveIframe();
+ });
+ me.addListener('afterexeccommand', function(type, cmd){
+ if(cmd != 'formula') {
+ blurActiveIframe();
+ }
+ });
+
+ me.commands['formula'] = {
+ execCommand: function (cmd, latex) {
+ var iframe = getActiveIframe();
+ if (iframe) {
+ iframe.contentWindow.formula.insertLatex(latex);
+ } else {
+ me.execCommand('inserthtml', '' + latex + ' ');
+ browser.ie && browser.ie9below && setTimeout(function(){
+ var rng = me.selection.getRange(),
+ startContainer = rng.startContainer;
+ if(startContainer.nodeType == 1 && !startContainer.childNodes[rng.startOffset]){
+ rng.insertNode(me.document.createTextNode(' '));
+ rng.setCursor()
+ }
+ },100)
+ }
+ },
+ queryCommandState: function (cmd) {
+ return 0;
+ },
+ queryCommandValue: function (cmd) {
+ var iframe = getActiveIframe();
+ return iframe && iframe.contentWindow.formula.getLatex();
+ }
+ }
+
+};
+
+/**
+ * @file xssFilter.js
+ * @desc xss过滤器
+ * @author robbenmu
+ */
+
+UM.plugins.xssFilter = function() {
+
+ var config = UMEDITOR_CONFIG;
+ var whiteList = config.whiteList;
+
+ function filter(node) {
+
+ var tagName = node.tagName;
+ var attrs = node.attrs;
+
+ if (!whiteList.hasOwnProperty(tagName)) {
+ node.parentNode.removeChild(node);
+ return false;
+ }
+
+ UM.utils.each(attrs, function (val, key) {
+
+ if (whiteList[tagName].indexOf(key) === -1) {
+ node.setAttr(key);
+ }
+ });
+ }
+
+ // 添加inserthtml\paste等操作用的过滤规则
+ if (whiteList && config.xssFilterRules) {
+ this.options.filterRules = function () {
+
+ var result = {};
+
+ UM.utils.each(whiteList, function(val, key) {
+ result[key] = function (node) {
+ return filter(node);
+ };
+ });
+
+ return result;
+ }();
+ }
+
+ var tagList = [];
+
+ UM.utils.each(whiteList, function (val, key) {
+ tagList.push(key);
+ });
+
+ // 添加input过滤规则
+ //
+ if (whiteList && config.inputXssFilter) {
+ this.addInputRule(function (root) {
+
+ root.traversal(function(node) {
+ if (node.type !== 'element') {
+ return false;
+ }
+ filter(node);
+ });
+ });
+ }
+ // 添加output过滤规则
+ //
+ if (whiteList && config.outputXssFilter) {
+ this.addOutputRule(function (root) {
+
+ root.traversal(function(node) {
+ if (node.type !== 'element') {
+ return false;
+ }
+ filter(node);
+ });
+ });
+ }
+
+};
+(function ($) {
+ //对jquery的扩展
+ $.parseTmpl = function parse(str, data) {
+ var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + 'with(obj||{}){__p.push(\'' + str.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/<%=([\s\S]+?)%>/g,function (match, code) {
+ return "'," + code.replace(/\\'/g, "'") + ",'";
+ }).replace(/<%([\s\S]+?)%>/g,function (match, code) {
+ return "');" + code.replace(/\\'/g, "'").replace(/[\r\n\t]/g, ' ') + "__p.push('";
+ }).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/\t/g, '\\t') + "');}return __p.join('');";
+ var func = new Function('obj', tmpl);
+ return data ? func(data) : func;
+ };
+ $.extend2 = function (t, s) {
+ var a = arguments,
+ notCover = $.type(a[a.length - 1]) == 'boolean' ? a[a.length - 1] : false,
+ len = $.type(a[a.length - 1]) == 'boolean' ? a.length - 1 : a.length;
+ for (var i = 1; i < len; i++) {
+ var x = a[i];
+ for (var k in x) {
+ if (!notCover || !t.hasOwnProperty(k)) {
+ t[k] = x[k];
+ }
+ }
+ }
+ return t;
+ };
+
+ $.IE6 = !!window.ActiveXObject && parseFloat(navigator.userAgent.match(/msie (\d+)/i)[1]) == 6;
+
+ //所有ui的基类
+ var _eventHandler = [];
+ var _widget = function () {
+ };
+ var _prefix = 'edui';
+ _widget.prototype = {
+ on: function (ev, cb) {
+ this.root().on(ev, $.proxy(cb, this));
+ return this;
+ },
+ off: function (ev, cb) {
+ this.root().off(ev, $.proxy(cb, this));
+ return this;
+ },
+ trigger: function (ev, data) {
+ return this.root().trigger(ev, data) === false ? false : this;
+ },
+ root: function ($el) {
+ return this._$el || (this._$el = $el);
+ },
+ destroy: function () {
+
+ },
+ data: function (key, val) {
+ if (val !== undefined) {
+ this.root().data(_prefix + key, val);
+ return this;
+ } else {
+ return this.root().data(_prefix + key)
+ }
+ },
+ register: function (eventName, $el, fn) {
+ _eventHandler.push({
+ 'evtname': eventName,
+ '$els': $.isArray($el) ? $el : [$el],
+ handler: $.proxy(fn, $el)
+ })
+ }
+ };
+
+ //从jq实例上拿到绑定的widget实例
+ $.fn.edui = function (obj) {
+ return obj ? this.data('eduiwidget', obj) : this.data('eduiwidget');
+ };
+
+ function _createClass(ClassObj, properties, supperClass) {
+ ClassObj.prototype = $.extend2(
+ $.extend({}, properties),
+ (UM.ui[supperClass] || _widget).prototype,
+ true
+ );
+ ClassObj.prototype.supper = (UM.ui[supperClass] || _widget).prototype;
+ //父class的defaultOpt 合并
+ if( UM.ui[supperClass] && UM.ui[supperClass].prototype.defaultOpt ) {
+
+ var parentDefaultOptions = UM.ui[supperClass].prototype.defaultOpt,
+ subDefaultOptions = ClassObj.prototype.defaultOpt;
+
+ ClassObj.prototype.defaultOpt = $.extend( {}, parentDefaultOptions, subDefaultOptions || {} );
+
+ }
+ return ClassObj
+ }
+
+ var _guid = 1;
+
+ function mergeToJQ(ClassObj, className) {
+ $[_prefix + className] = ClassObj;
+ $.fn[_prefix + className] = function (opt) {
+ var result, args = Array.prototype.slice.call(arguments, 1);
+
+ this.each(function (i, el) {
+ var $this = $(el);
+ var obj = $this.edui();
+ if (!obj) {
+ ClassObj(!opt || !$.isPlainObject(opt) ? {} : opt, $this);
+ $this.edui(obj)
+ }
+ if ($.type(opt) == 'string') {
+ if (opt == 'this') {
+ result = obj;
+ } else {
+ result = obj[opt].apply(obj, args);
+ if (result !== obj && result !== undefined) {
+ return false;
+ }
+ result = null;
+ }
+
+ }
+ });
+
+ return result !== null ? result : this;
+ }
+ }
+
+ UM.ui = {
+ define: function (className, properties, supperClass) {
+ var ClassObj = UM.ui[className] = _createClass(function (options, $el) {
+ var _obj = function () {
+ };
+ $.extend(_obj.prototype, ClassObj.prototype, {
+ guid: className + _guid++,
+ widgetName: className
+ }
+ );
+ var obj = new _obj;
+ if ($.type(options) == 'string') {
+ obj.init && obj.init({});
+ obj.root().edui(obj);
+ obj.root().find('a').click(function (evt) {
+ evt.preventDefault()
+ });
+ return obj.root()[_prefix + className].apply(obj.root(), arguments)
+ } else {
+ $el && obj.root($el);
+ obj.init && obj.init(!options || $.isPlainObject(options) ? $.extend2(options || {}, obj.defaultOpt || {}, true) : options);
+ try{
+ obj.root().find('a').click(function (evt) {
+ evt.preventDefault()
+ });
+ }catch(e){
+ }
+
+ return obj.root().edui(obj);
+ }
+
+ },properties, supperClass);
+
+ mergeToJQ(ClassObj, className);
+ }
+ };
+
+ $(function () {
+ $(document).on('click mouseup mousedown dblclick mouseover', function (evt) {
+ $.each(_eventHandler, function (i, obj) {
+ if (obj.evtname == evt.type) {
+ $.each(obj.$els, function (i, $el) {
+ if ($el[0] !== evt.target && !$.contains($el[0], evt.target)) {
+ obj.handler(evt);
+ }
+ })
+ }
+ })
+ })
+ })
+})(jQuery);
+//button 类
+UM.ui.define('button', {
+ tpl: '<<%if(!texttype){%>div class="edui-btn edui-btn-<%=icon%> <%if(name){%>edui-btn-name-<%=name%><%}%>" unselectable="on" onmousedown="return false" <%}else{%>a class="edui-text-btn"<%}%><% if(title) {%> data-original-title="<%=title%>" <%};%>> ' +
+ '<% if(icon) {%>
<% }; %><%if(text) {%><%=text%> <%}%>' +
+ '<%if(caret && text){%> <%}%>' +
+ '<% if(caret) {%> <% };%><%if(!texttype){%>div<%}else{%>a<%}%>>',
+ defaultOpt: {
+ text: '',
+ title: '',
+ icon: '',
+ width: '',
+ caret: false,
+ texttype: false,
+ click: function () {
+ }
+ },
+ init: function (options) {
+ var me = this;
+
+ me.root($($.parseTmpl(me.tpl, options)))
+ .click(function (evt) {
+ me.wrapclick(options.click, evt)
+ });
+
+ me.root().hover(function () {
+ if(!me.root().hasClass("edui-disabled")){
+ me.root().toggleClass('edui-hover')
+ }
+ })
+
+ return me;
+ },
+ wrapclick: function (fn, evt) {
+ if (!this.disabled()) {
+ this.root().trigger('wrapclick');
+ $.proxy(fn, this, evt)()
+ }
+ return this;
+ },
+ label: function (text) {
+ if (text === undefined) {
+ return this.root().find('.edui-button-label').text();
+ } else {
+ this.root().find('.edui-button-label').text(text);
+ return this;
+ }
+ },
+ disabled: function (state) {
+ if (state === undefined) {
+ return this.root().hasClass('edui-disabled')
+ }
+ this.root().toggleClass('edui-disabled', state);
+ if(this.root().hasClass('edui-disabled')){
+ this.root().removeClass('edui-hover')
+ }
+ return this;
+ },
+ active: function (state) {
+ if (state === undefined) {
+ return this.root().hasClass('edui-active')
+ }
+ this.root().toggleClass('edui-active', state)
+
+ return this;
+ },
+ mergeWith: function ($obj) {
+ var me = this;
+ me.data('$mergeObj', $obj);
+ $obj.edui().data('$mergeObj', me.root());
+ if (!$.contains(document.body, $obj[0])) {
+ $obj.appendTo(me.root());
+ }
+ me.on('click',function () {
+ me.wrapclick(function () {
+ $obj.edui().show();
+ })
+ }).register('click', me.root(), function (evt) {
+ $obj.hide()
+ });
+ }
+});
+//toolbar 类
+(function () {
+ UM.ui.define('toolbar', {
+ tpl: ''
+ ,
+ init: function () {
+ var $root = this.root($(this.tpl));
+ this.data('$btnToolbar', $root.find('.edui-btn-toolbar'))
+ },
+ appendToBtnmenu : function(data){
+ var $cont = this.data('$btnToolbar');
+ data = $.isArray(data) ? data : [data];
+ $.each(data,function(i,$item){
+ $cont.append($item)
+ })
+ }
+ });
+})();
+
+//menu 类
+UM.ui.define('menu',{
+ show : function($obj,dir,fnname,topOffset,leftOffset){
+
+ fnname = fnname || 'position';
+ if(this.trigger('beforeshow') === false){
+ return;
+ }else{
+ this.root().css($.extend({display:'block'},$obj ? {
+ top : $obj[fnname]().top + ( dir == 'right' ? 0 : $obj.outerHeight()) - (topOffset || 0),
+ left : $obj[fnname]().left + (dir == 'right' ? $obj.outerWidth() : 0) - (leftOffset || 0)
+ }:{}))
+ this.trigger('aftershow');
+ }
+ },
+ hide : function(all){
+ var $parentmenu;
+ if(this.trigger('beforehide') === false){
+ return;
+ } else {
+
+ if($parentmenu = this.root().data('parentmenu')){
+ if($parentmenu.data('parentmenu')|| all)
+ $parentmenu.edui().hide();
+ }
+ this.root().css('display','none');
+ this.trigger('afterhide');
+ }
+ },
+ attachTo : function($obj){
+ var me = this;
+ if(!$obj.data('$mergeObj')){
+ $obj.data('$mergeObj',me.root());
+ $obj.on('wrapclick',function(evt){
+ me.show()
+ });
+ me.register('click',$obj,function(evt){
+ me.hide()
+ });
+ me.data('$mergeObj',$obj)
+ }
+ }
+});
+//dropmenu 类
+UM.ui.define('dropmenu', {
+ tmpl: '',
+ defaultOpt: {
+ data: [],
+ click: function () {
+
+ }
+ },
+ init: function (options) {
+ var me = this;
+ var eventName = {
+ click: 1,
+ mouseover: 1,
+ mouseout: 1
+ };
+
+ this.root($($.parseTmpl(this.tmpl, options))).on('click', 'li[class!="edui-disabled edui-divider edui-dropdown-submenu"]',function (evt) {
+ $.proxy(options.click, me, evt, $(this).data('value'), $(this))()
+ }).find('li').each(function (i, el) {
+ var $this = $(this);
+ if (!$this.hasClass("edui-disabled edui-divider edui-dropdown-submenu")) {
+ var data = options.data[i];
+ $.each(eventName, function (k) {
+ data[k] && $this[k](function (evt) {
+ $.proxy(data[k], el)(evt, data, me.root)
+ })
+ })
+ }
+ })
+
+ },
+ disabled: function (cb) {
+ $('li[class!=edui-divider]', this.root()).each(function () {
+ var $el = $(this);
+ if (cb === true) {
+ $el.addClass('edui-disabled')
+ } else if ($.isFunction(cb)) {
+ $el.toggleClass('edui-disabled', cb(li))
+ } else {
+ $el.removeClass('edui-disabled')
+ }
+
+ });
+ },
+ val: function (val) {
+ var currentVal;
+ $('li[class!="edui-divider edui-disabled edui-dropdown-submenu"]', this.root()).each(function () {
+ var $el = $(this);
+ if (val === undefined) {
+ if ($el.find('em.edui-dropmenu-checked').length) {
+ currentVal = $el.data('value');
+ return false
+ }
+ } else {
+ $el.find('em').toggleClass('edui-dropmenu-checked', $el.data('value') == val)
+ }
+ });
+ if (val === undefined) {
+ return currentVal
+ }
+ },
+ addSubmenu: function (label, menu, index) {
+ index = index || 0;
+
+ var $list = $('li[class!=edui-divider]', this.root());
+ var $node = $('').append(menu);
+
+ if (index >= 0 && index < $list.length) {
+ $node.insertBefore($list[index]);
+ } else if (index < 0) {
+ $node.insertBefore($list[0]);
+ } else if (index >= $list.length) {
+ $node.appendTo($list);
+ }
+ }
+}, 'menu');
+//splitbutton 类
+///import button
+UM.ui.define('splitbutton',{
+ tpl :'data-original-title="<%=title%>"<%}%>>
<%if(icon){%>
<%}%><%if(text){%><%=text%><%}%>
'+
+ '
'+
+ '
<\/div>'+
+ '
'+
+ '
',
+ defaultOpt:{
+ text:'',
+ title:'',
+ click:function(){}
+ },
+ init : function(options){
+ var me = this;
+ me.root( $($.parseTmpl(me.tpl,options)));
+ me.root().find('.edui-btn:first').click(function(evt){
+ if(!me.disabled()){
+ $.proxy(options.click,me)();
+ }
+ });
+ me.root().find('.edui-dropdown-toggle').click(function(){
+ if(!me.disabled()){
+ me.trigger('arrowclick')
+ }
+ });
+ me.root().hover(function () {
+ if(!me.root().hasClass("edui-disabled")){
+ me.root().toggleClass('edui-hover')
+ }
+ });
+
+ return me;
+ },
+ wrapclick:function(fn,evt){
+ if(!this.disabled()){
+ $.proxy(fn,this,evt)()
+ }
+ return this;
+ },
+ disabled : function(state){
+ if(state === undefined){
+ return this.root().hasClass('edui-disabled')
+ }
+ this.root().toggleClass('edui-disabled',state).find('.edui-btn').toggleClass('edui-disabled',state);
+ return this;
+ },
+ active:function(state){
+ if(state === undefined){
+ return this.root().hasClass('edui-active')
+ }
+ this.root().toggleClass('edui-active',state).find('.edui-btn:first').toggleClass('edui-active',state);
+ return this;
+ },
+ mergeWith:function($obj){
+ var me = this;
+ me.data('$mergeObj',$obj);
+ $obj.edui().data('$mergeObj',me.root());
+ if(!$.contains(document.body,$obj[0])){
+ $obj.appendTo(me.root());
+ }
+ me.root().delegate('.edui-dropdown-toggle','click',function(){
+ me.wrapclick(function(){
+ $obj.edui().show();
+ })
+ });
+ me.register('click',me.root().find('.edui-dropdown-toggle'),function(evt){
+ $obj.hide()
+ });
+ }
+});
+/**
+ * Created with JetBrains PhpStorm.
+ * User: hn
+ * Date: 13-7-10
+ * Time: 下午3:07
+ * To change this template use File | Settings | File Templates.
+ */
+UM.ui.define('colorsplitbutton',{
+
+ tpl : '
data-original-title="<%=title%>"<%}%>>
<%if(icon){%>
<%}%>
style="background: <%=color%>"<%}%>>
<%if(text){%><%=text%><%}%>
'+
+ '
'+
+ '
<\/div>'+
+ '
'+
+ '
',
+ defaultOpt: {
+ color: ''
+ },
+ init: function( options ){
+
+ var me = this;
+
+ me.supper.init.call( me, options );
+
+ },
+ colorLabel: function(){
+ return this.root().find('.edui-splitbutton-color-label');
+ }
+
+}, 'splitbutton');
+//popup 类
+UM.ui.define('popup', {
+ tpl: '',
+ defaultOpt: {
+ stopprop:false,
+ subtpl: '',
+ width: '',
+ height: ''
+ },
+ init: function (options) {
+ this.root($($.parseTmpl(this.tpl, options)));
+ return this;
+ },
+ mergeTpl: function (data) {
+ return $.parseTmpl(this.tpl, {subtpl: data});
+ },
+ show: function ($obj, posObj) {
+ if (!posObj) posObj = {};
+
+ var fnname = posObj.fnname || 'position';
+ if (this.trigger('beforeshow') === false) {
+ return;
+ } else {
+ this.root().css($.extend({display: 'block'}, $obj ? {
+ top: $obj[fnname]().top + ( posObj.dir == 'right' ? 0 : $obj.outerHeight()) - (posObj.offsetTop || 0),
+ left: $obj[fnname]().left + (posObj.dir == 'right' ? $obj.outerWidth() : 0) - (posObj.offsetLeft || 0),
+ position: 'absolute'
+ } : {}));
+
+ this.root().find('.edui-popup-caret').css({
+ top: posObj.caretTop || 0,
+ left: posObj.caretLeft || 0,
+ position: 'absolute'
+ }).addClass(posObj.caretDir || "up")
+
+ }
+ this.trigger("aftershow");
+ },
+ hide: function () {
+ this.root().css('display', 'none');
+ this.trigger('afterhide')
+ },
+ attachTo: function ($obj, posObj) {
+ var me = this
+ if (!$obj.data('$mergeObj')) {
+ $obj.data('$mergeObj', me.root());
+ $obj.on('wrapclick', function (evt) {
+ me.show($obj, posObj)
+ });
+ me.register('click', $obj, function (evt) {
+ me.hide()
+ });
+ me.data('$mergeObj', $obj)
+ }
+ },
+ getBodyContainer: function () {
+ return this.root().find(".edui-popup-body");
+ }
+});
+//scale 类
+UM.ui.define('scale', {
+ tpl: '
' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ '
',
+ defaultOpt: {
+ $doc: $(document),
+ $wrap: $(document)
+ },
+ init: function (options) {
+ if(options.$doc) this.defaultOpt.$doc = options.$doc;
+ if(options.$wrap) this.defaultOpt.$wrap = options.$wrap;
+ this.root($($.parseTmpl(this.tpl, options)));
+ this.initStyle();
+ this.startPos = this.prePos = {x: 0, y: 0};
+ this.dragId = -1;
+ return this;
+ },
+ initStyle: function () {
+ utils.cssRule('edui-style-scale', '.edui-scale{display:none;position:absolute;border:1px solid #38B2CE;cursor:hand;}' +
+ '.edui-scale span{position:absolute;left:0;top:0;width:7px;height:7px;overflow:hidden;font-size:0px;display:block;background-color:#3C9DD0;}'
+ + '.edui-scale .edui-scale-hand0{cursor:nw-resize;top:0;margin-top:-4px;left:0;margin-left:-4px;}'
+ + '.edui-scale .edui-scale-hand1{cursor:n-resize;top:0;margin-top:-4px;left:50%;margin-left:-4px;}'
+ + '.edui-scale .edui-scale-hand2{cursor:ne-resize;top:0;margin-top:-4px;left:100%;margin-left:-3px;}'
+ + '.edui-scale .edui-scale-hand3{cursor:w-resize;top:50%;margin-top:-4px;left:0;margin-left:-4px;}'
+ + '.edui-scale .edui-scale-hand4{cursor:e-resize;top:50%;margin-top:-4px;left:100%;margin-left:-3px;}'
+ + '.edui-scale .edui-scale-hand5{cursor:sw-resize;top:100%;margin-top:-3px;left:0;margin-left:-4px;}'
+ + '.edui-scale .edui-scale-hand6{cursor:s-resize;top:100%;margin-top:-3px;left:50%;margin-left:-4px;}'
+ + '.edui-scale .edui-scale-hand7{cursor:se-resize;top:100%;margin-top:-3px;left:100%;margin-left:-3px;}');
+ },
+ _eventHandler: function (e) {
+ var me = this,
+ $doc = me.defaultOpt.$doc;
+ switch (e.type) {
+ case 'mousedown':
+ var hand = e.target || e.srcElement, hand;
+ if (hand.className.indexOf('edui-scale-hand') != -1) {
+ me.dragId = hand.className.slice(-1);
+ me.startPos.x = me.prePos.x = e.clientX;
+ me.startPos.y = me.prePos.y = e.clientY;
+ $doc.bind('mousemove', $.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;
+ me.updateTargetElement();
+ }
+ break;
+ case 'mouseup':
+ if (me.dragId != -1) {
+ me.dragId = -1;
+ me.updateTargetElement();
+ var $target = me.data('$scaleTarget');
+ if ($target.parent()) me.attachTo(me.data('$scaleTarget'));
+ }
+ $doc.unbind('mousemove', $.proxy(me._eventHandler, me));
+ break;
+ default:
+ break;
+ }
+ },
+ updateTargetElement: function () {
+ var me = this,
+ $root = me.root(),
+ $target = me.data('$scaleTarget');
+ $target.css({width: $root.width(), height: $root.height()});
+ me.attachTo($target);
+ },
+ updateContainerStyle: function (dir, offset) {
+ var me = this,
+ $dom = me.root(),
+ tmp,
+ 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]
+ ];
+
+ if (rect[dir][0] != 0) {
+ tmp = parseInt($dom.offset().left) + offset.x;
+ $dom.css('left', me._validScaledProp('left', tmp));
+ }
+ if (rect[dir][1] != 0) {
+ tmp = parseInt($dom.offset().top) + offset.y;
+ $dom.css('top', me._validScaledProp('top', tmp));
+ }
+ if (rect[dir][2] != 0) {
+ tmp = $dom.width() + rect[dir][2] * offset.x;
+ $dom.css('width', me._validScaledProp('width', tmp));
+ }
+ if (rect[dir][3] != 0) {
+ tmp = $dom.height() + rect[dir][3] * offset.y;
+ $dom.css('height', me._validScaledProp('height', tmp));
+ }
+ },
+ _validScaledProp: function (prop, value) {
+ var $ele = this.root(),
+ $wrap = this.defaultOpt.$doc,
+ calc = function(val, a, b){
+ return (val + a) > b ? b - a : value;
+ };
+
+ value = isNaN(value) ? 0 : value;
+ switch (prop) {
+ case 'left':
+ return value < 0 ? 0 : calc(value, $ele.width(), $wrap.width());
+ case 'top':
+ return value < 0 ? 0 : calc(value, $ele.height(),$wrap.height());
+ case 'width':
+ return value <= 0 ? 1 : calc(value, $ele.offset().left, $wrap.width());
+ case 'height':
+ return value <= 0 ? 1 : calc(value, $ele.offset().top, $wrap.height());
+ }
+ },
+ show: function ($obj) {
+ var me = this;
+ if ($obj) me.attachTo($obj);
+ me.root().bind('mousedown', $.proxy(me._eventHandler, me));
+ me.defaultOpt.$doc.bind('mouseup', $.proxy(me._eventHandler, me));
+ me.root().show();
+ me.trigger("aftershow");
+ },
+ hide: function () {
+ var me = this;
+ me.root().unbind('mousedown', $.proxy(me._eventHandler, me));
+ me.defaultOpt.$doc.unbind('mouseup', $.proxy(me._eventHandler, me));
+ me.root().hide();
+ me.trigger('afterhide')
+ },
+ attachTo: function ($obj) {
+ var me = this,
+ imgPos = $obj.offset(),
+ $root = me.root(),
+ $wrap = me.defaultOpt.$wrap,
+ posObj = $wrap.offset();
+
+ me.data('$scaleTarget', $obj);
+ me.root().css({
+ position: 'absolute',
+ width: $obj.width(),
+ height: $obj.height(),
+ left: imgPos.left - posObj.left - parseInt($wrap.css('border-left-width')) - parseInt($root.css('border-left-width')),
+ top: imgPos.top - posObj.top - parseInt($wrap.css('border-top-width')) - parseInt($root.css('border-top-width'))
+ });
+ },
+ getScaleTarget: function () {
+ return this.data('$scaleTarget')[0];
+ }
+});
+//colorpicker 类
+UM.ui.define('colorpicker', {
+ tpl: function (opt) {
+ var COLORS = (
+ 'ffffff,000000,eeece1,1f497d,4f81bd,c0504d,9bbb59,8064a2,4bacc6,f79646,' +
+ 'f2f2f2,7f7f7f,ddd9c3,c6d9f0,dbe5f1,f2dcdb,ebf1dd,e5e0ec,dbeef3,fdeada,' +
+ 'd8d8d8,595959,c4bd97,8db3e2,b8cce4,e5b9b7,d7e3bc,ccc1d9,b7dde8,fbd5b5,' +
+ 'bfbfbf,3f3f3f,938953,548dd4,95b3d7,d99694,c3d69b,b2a2c7,92cddc,fac08f,' +
+ 'a5a5a5,262626,494429,17365d,366092,953734,76923c,5f497a,31859b,e36c09,' +
+ '7f7f7f,0c0c0c,1d1b10,0f243e,244061,632423,4f6128,3f3151,205867,974806,' +
+ 'c00000,ff0000,ffc000,ffff00,92d050,00b050,00b0f0,0070c0,002060,7030a0,').split(',');
+
+ var html = '
' +
+ '
' +
+ ''+opt.lang_themeColor+' ' +
+ '';
+
+ for (var i = 0; i < COLORS.length; i++) {
+ if (i && i % 10 === 0) {
+ html += ' ' + (i == 60 ? ''+opt.lang_standardColor+' ' : '') + '';
+ }
+ html += i < 70 ? ' ' : '';
+ }
+ html += '
';
+ return html;
+ },
+ init: function (options) {
+ var me = this;
+ me.root($($.parseTmpl(me.supper.mergeTpl(me.tpl(options)),options)));
+
+ me.root().on("click",function (e) {
+ me.trigger('pickcolor', $(e.target).data('color'));
+ });
+ }
+}, 'popup');
+/**
+ * Created with JetBrains PhpStorm.
+ * User: hn
+ * Date: 13-5-29
+ * Time: 下午8:01
+ * To change this template use File | Settings | File Templates.
+ */
+
+(function(){
+
+ var widgetName = 'combobox',
+ itemClassName = 'edui-combobox-item',
+ HOVER_CLASS = 'edui-combobox-item-hover',
+ ICON_CLASS = 'edui-combobox-checked-icon',
+ labelClassName = 'edui-combobox-item-label';
+
+ UM.ui.define( widgetName, ( function(){
+
+ return {
+ tpl: "",
+ defaultOpt: {
+ //记录栈初始列表
+ recordStack: [],
+ //可用项列表
+ items: [],
+ //item对应的值列表
+ value: [],
+ comboboxName: '',
+ selected: '',
+ //自动记录
+ autoRecord: true,
+ //最多记录条数
+ recordCount: 5
+ },
+ init: function( options ){
+
+ var me = this;
+
+ $.extend( me._optionAdaptation( options ), me._createItemMapping( options.recordStack, options.items ), {
+ itemClassName: itemClassName,
+ iconClass: ICON_CLASS,
+ labelClassName: labelClassName
+ } );
+
+ this._transStack( options );
+
+ me.root( $( $.parseTmpl( me.tpl, options ) ) );
+
+ this.data( 'options', options ).initEvent();
+
+ },
+ initEvent: function(){
+
+ var me = this;
+
+ me.initSelectItem();
+
+ this.initItemActive();
+
+ },
+ /**
+ * 初始化选择项
+ */
+ initSelectItem: function(){
+
+ var me = this,
+ labelClass = "."+labelClassName;
+
+ me.root().delegate('.' + itemClassName, 'click', function(){
+
+ var $li = $(this),
+ index = $li.attr('data-item-index');
+
+ me.trigger('comboboxselect', {
+ index: index,
+ label: $li.find(labelClass).text(),
+ value: me.data('options').value[ index ]
+ }).select( index );
+
+ me.hide();
+
+ return false;
+
+ });
+
+ },
+ initItemActive: function(){
+ var fn = {
+ mouseenter: 'addClass',
+ mouseleave: 'removeClass'
+ };
+ if ($.IE6) {
+ this.root().delegate( '.'+itemClassName, 'mouseenter mouseleave', function( evt ){
+ $(this)[ fn[ evt.type ] ]( HOVER_CLASS );
+ }).one('afterhide', function(){
+ });
+ }
+ },
+ /**
+ * 选择给定索引的项
+ * @param index 项索引
+ * @returns {*} 如果存在对应索引的项,则返回该项;否则返回null
+ */
+ select: function( index ){
+
+ var itemCount = this.data('options').itemCount,
+ items = this.data('options').autowidthitem;
+
+ if ( items && !items.length ) {
+ items = this.data('options').items;
+ }
+
+ if( itemCount == 0 ) {
+ return null;
+ }
+
+ if( index < 0 ) {
+
+ index = itemCount + index % itemCount;
+
+ } else if ( index >= itemCount ) {
+
+ index = itemCount-1;
+
+ }
+
+ this.trigger( 'changebefore', items[ index ] );
+
+ this._update( index );
+
+ this.trigger( 'changeafter', items[ index ] );
+
+ return null;
+
+ },
+ selectItemByLabel: function( label ){
+
+ var itemMapping = this.data('options').itemMapping,
+ me = this,
+ index = null;
+
+ !$.isArray( label ) && ( label = [ label ] );
+
+ $.each( label, function( i, item ){
+
+ index = itemMapping[ item ];
+
+ if( index !== undefined ) {
+
+ me.select( index );
+ return false;
+
+ }
+
+ } );
+
+ },
+ /**
+ * 转换记录栈
+ */
+ _transStack: function( options ) {
+
+ var temp = [],
+ itemIndex = -1,
+ selected = -1;
+
+ $.each( options.recordStack, function( index, item ){
+
+ itemIndex = options.itemMapping[ item ];
+
+ if( $.isNumeric( itemIndex ) ) {
+
+ temp.push( itemIndex );
+
+ //selected的合法性检测
+ if( item == options.selected ) {
+ selected = itemIndex;
+ }
+
+ }
+
+ } );
+
+ options.recordStack = temp;
+ options.selected = selected;
+ temp = null;
+
+ },
+ _optionAdaptation: function( options ) {
+
+ if( !( 'itemStyles' in options ) ) {
+
+ options.itemStyles = [];
+
+ for( var i = 0, len = options.items.length; i < len; i++ ) {
+ options.itemStyles.push('');
+ }
+
+ }
+
+ options.autowidthitem = options.autowidthitem || options.items;
+ options.itemCount = options.items.length;
+
+ return options;
+
+ },
+ _createItemMapping: function( stackItem, items ){
+
+ var temp = {},
+ result = {
+ recordStack: [],
+ mapping: {}
+ };
+
+ $.each( items, function( index, item ){
+ temp[ item ] = index;
+ } );
+
+ result.itemMapping = temp;
+
+ $.each( stackItem, function( index, item ){
+
+ if( temp[ item ] !== undefined ) {
+ result.recordStack.push( temp[ item ] );
+ result.mapping[ item ] = temp[ item ];
+ }
+
+ } );
+
+ return result;
+
+ },
+ _update: function ( index ) {
+
+ var options = this.data("options"),
+ newStack = [],
+ newChilds = null;
+
+ $.each( options.recordStack, function( i, item ){
+
+ if( item != index ) {
+ newStack.push( item );
+ }
+
+ } );
+
+ //压入最新的记录
+ newStack.unshift( index );
+
+ if( newStack.length > options.recordCount ) {
+ newStack.length = options.recordCount;
+ }
+
+ options.recordStack = newStack;
+ options.selected = index;
+
+ newChilds = $( $.parseTmpl( this.tpl, options ) );
+
+ //重新渲染
+ this.root().html( newChilds.html() );
+
+ newChilds = null;
+ newStack = null;
+
+ }
+ };
+
+ } )(), 'menu' );
+
+})();
+
+/**
+ * Combox 抽象基类
+ * User: hn
+ * Date: 13-5-29
+ * Time: 下午8:01
+ * To change this template use File | Settings | File Templates.
+ */
+
+(function(){
+
+ var widgetName = 'buttoncombobox';
+
+ UM.ui.define( widgetName, ( function(){
+
+ return {
+ defaultOpt: {
+ //按钮初始文字
+ label: '',
+ title: ''
+ },
+ init: function( options ) {
+
+ var me = this;
+
+ var btnWidget = $.eduibutton({
+ caret: true,
+ name: options.comboboxName,
+ title: options.title,
+ text: options.label,
+ click: function(){
+ me.show( this.root() );
+ }
+ });
+
+ me.supper.init.call( me, options );
+
+ //监听change, 改变button显示内容
+ me.on('changebefore', function( e, label ){
+ btnWidget.eduibutton('label', label );
+ });
+
+ me.data( 'button', btnWidget );
+
+ me.attachTo(btnWidget)
+
+ },
+ button: function(){
+ return this.data( 'button' );
+ }
+ }
+
+ } )(), 'combobox' );
+
+})();
+
+/*modal 类*/
+UM.ui.define('modal', {
+ tpl: '
' +
+ '' +
+ '
' +
+ '
' +
+ '<% if(cancellabel || oklabel) {%>' +
+ '' +
+ '<%}%>
',
+ defaultOpt: {
+ title: "",
+ cancellabel: "",
+ oklabel: "",
+ width: '',
+ height: '',
+ backdrop: true,
+ keyboard: true
+ },
+ init: function (options) {
+ var me = this;
+
+ me.root($($.parseTmpl(me.tpl, options || {})));
+
+ me.data("options", options);
+ if (options.okFn) {
+ me.on('ok', $.proxy(options.okFn, me))
+ }
+ if (options.cancelFn) {
+ me.on('beforehide', $.proxy(options.cancelFn, me))
+ }
+
+ me.root().delegate('[data-hide="modal"]', 'click', $.proxy(me.hide, me))
+ .delegate('[data-ok="modal"]', 'click', $.proxy(me.ok, me));
+
+ $('[data-hide="modal"],[data-ok="modal"]',me.root()).hover(function(){
+ $(this).toggleClass('edui-hover')
+ });
+ },
+ toggle: function () {
+ var me = this;
+ return me[!me.data("isShown") ? 'show' : 'hide']();
+ },
+ show: function () {
+
+ var me = this;
+
+ me.trigger("beforeshow");
+
+ if (me.data("isShown")) return;
+
+ me.data("isShown", true);
+
+ me.escape();
+
+ me.backdrop(function () {
+ me.autoCenter();
+ me.root()
+ .show()
+ .focus()
+ .trigger('aftershow');
+ })
+ },
+ showTip: function ( text ) {
+ $( '.edui-modal-tip', this.root() ).html( text ).fadeIn();
+ },
+ hideTip: function ( text ) {
+ $( '.edui-modal-tip', this.root() ).fadeOut( function (){
+ $(this).html('');
+ } );
+ },
+ autoCenter: function () {
+ //ie6下不用处理了
+ !$.IE6 && this.root().css("margin-left", -(this.root().width() / 2));
+ },
+ hide: function () {
+ var me = this;
+
+ me.trigger("beforehide");
+
+ if (!me.data("isShown")) return;
+
+ me.data("isShown", false);
+
+ me.escape();
+
+ me.hideModal();
+ },
+ escape: function () {
+ var me = this;
+ if (me.data("isShown") && me.data("options").keyboard) {
+ me.root().on('keyup', function (e) {
+ e.which == 27 && me.hide();
+ })
+ }
+ else if (!me.data("isShown")) {
+ me.root().off('keyup');
+ }
+ },
+ hideModal: function () {
+ var me = this;
+ me.root().hide();
+ me.backdrop(function () {
+ me.removeBackdrop();
+ me.trigger('afterhide');
+ })
+ },
+ removeBackdrop: function () {
+ this.$backdrop && this.$backdrop.remove();
+ this.$backdrop = null;
+ },
+ backdrop: function (callback) {
+ var me = this;
+ if (me.data("isShown") && me.data("options").backdrop) {
+ me.$backdrop = $('
').click(
+ me.data("options").backdrop == 'static' ?
+ $.proxy(me.root()[0].focus, me.root()[0])
+ : $.proxy(me.hide, me)
+ )
+ }
+ me.trigger('afterbackdrop');
+ callback && callback();
+
+ },
+ attachTo: function ($obj) {
+ var me = this
+ if (!$obj.data('$mergeObj')) {
+
+ $obj.data('$mergeObj', me.root());
+ $obj.on('click', function () {
+ me.toggle($obj)
+ });
+ me.data('$mergeObj', $obj)
+ }
+ },
+ ok: function () {
+ var me = this;
+ me.trigger('beforeok');
+ if (me.trigger("ok", me) === false) {
+ return;
+ }
+ me.hide();
+ },
+ getBodyContainer: function () {
+ return this.root().find('.edui-modal-body')
+ }
+});
+
+
+/*tooltip 类*/
+UM.ui.define('tooltip', {
+ tpl: '
',
+ init: function (options) {
+ var me = this;
+ me.root($($.parseTmpl(me.tpl, options || {})));
+ },
+ content: function (e) {
+ var me = this,
+ title = $(e.currentTarget).attr("data-original-title");
+
+ me.root().find('.edui-tooltip-inner')['text'](title);
+ },
+ position: function (e) {
+ var me = this,
+ $obj = $(e.currentTarget);
+
+ me.root().css($.extend({display: 'block'}, $obj ? {
+ top: $obj.outerHeight(),
+ left: (($obj.outerWidth() - me.root().outerWidth()) / 2)
+ } : {}))
+ },
+ show: function (e) {
+ if ($(e.currentTarget).hasClass('edui-disabled')) return;
+
+ var me = this;
+ me.content(e);
+ me.root().appendTo($(e.currentTarget));
+ me.position(e);
+ me.root().css('display', 'block');
+ },
+ hide: function () {
+ var me = this;
+ me.root().css('display', 'none')
+ },
+ attachTo: function ($obj) {
+ var me = this;
+
+ function tmp($obj) {
+ var me = this;
+
+ if (!$.contains(document.body, me.root()[0])) {
+ me.root().appendTo($obj);
+ }
+
+ me.data('tooltip', me.root());
+
+ $obj.each(function () {
+ if ($(this).attr("data-original-title")) {
+ $(this).on('mouseenter', $.proxy(me.show, me))
+ .on('mouseleave click', $.proxy(me.hide, me))
+
+ }
+ });
+
+ }
+
+ if ($.type($obj) === "undefined") {
+ $("[data-original-title]").each(function (i, el) {
+ tmp.call(me, $(el));
+ })
+
+ } else {
+ if (!$obj.data('tooltip')) {
+ tmp.call(me, $obj);
+ }
+ }
+ }
+});
+
+/*tab 类*/
+UM.ui.define('tab', {
+ init: function (options) {
+ var me = this,
+ slr = options.selector;
+
+ if ($.type(slr)) {
+ me.root($(slr, options.context));
+ me.data("context", options.context);
+
+ $(slr, me.data("context")).on('click', function (e) {
+ me.show(e);
+ });
+ }
+ },
+ show: function (e) {
+
+ var me = this,
+ $cur = $(e.target),
+ $ul = $cur.closest('ul'),
+ selector,
+ previous,
+ $target,
+ e;
+
+ selector = $cur.attr('data-context');
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '');
+
+ var $tmp = $cur.parent('li');
+
+ if (!$tmp.length || $tmp.hasClass('edui-active')) return;
+
+ previous = $ul.find('.edui-active:last a')[0];
+
+ e = $.Event('beforeshow', {
+ target: $cur[0],
+ relatedTarget: previous
+ });
+
+ me.trigger(e);
+
+ if (e.isDefaultPrevented()) return;
+
+ $target = $(selector, me.data("context"));
+
+ me.activate($cur.parent('li'), $ul);
+ me.activate($target, $target.parent(), function () {
+ me.trigger({
+ type: 'aftershow', relatedTarget: previous
+ })
+ });
+ },
+ activate: function (element, container, callback) {
+ if (element === undefined) {
+ return $(".edui-tab-item.edui-active",this.root()).index();
+ }
+
+ var $active = container.find('> .edui-active');
+
+ $active.removeClass('edui-active');
+
+ element.addClass('edui-active');
+
+ callback && callback();
+ }
+});
+
+
+//button 类
+UM.ui.define('separator', {
+ tpl: '
',
+ init: function (options) {
+ var me = this;
+ me.root($($.parseTmpl(me.tpl, options)));
+ return me;
+ }
+});
+/**
+ * @file adapter.js
+ * @desc adapt ui to editor
+ * @import core/Editor.js, core/utils.js
+ */
+
+(function () {
+ var _editorUI = {},
+ _editors = {},
+ _readyFn = [],
+ _activeWidget = null,
+ _widgetData = {},
+ _widgetCallBack = {},
+ _cacheUI = {},
+ _maxZIndex = null;
+
+ utils.extend(UM, {
+ defaultWidth : 500,
+ defaultHeight : 500,
+ registerUI: function (name, fn) {
+ utils.each(name.split(/\s+/), function (uiname) {
+ _editorUI[uiname] = fn;
+ })
+ },
+
+ setEditor : function(editor){
+ !_editors[editor.id] && (_editors[editor.id] = editor);
+ },
+ registerWidget : function(name,pro,cb){
+ _widgetData[name] = $.extend2(pro,{
+ $root : '',
+ _preventDefault:false,
+ root:function($el){
+ return this.$root || (this.$root = $el);
+ },
+ preventDefault:function(){
+ this._preventDefault = true;
+ },
+ clear:false
+ });
+ if(cb){
+ _widgetCallBack[name] = cb;
+ }
+ },
+ getWidgetData : function(name){
+ return _widgetData[name]
+ },
+ setWidgetBody : function(name,$widget,editor){
+ if(!editor._widgetData){
+
+ utils.extend(editor,{
+ _widgetData : {},
+ getWidgetData : function(name){
+ return this._widgetData[name];
+ },
+ getWidgetCallback : function(widgetName){
+ var me = this;
+ return function(){
+ return _widgetCallBack[widgetName].apply(me,[me,$widget].concat(Array.prototype.slice.call(arguments,0)))
+ }
+ }
+ })
+
+ }
+ var pro = _widgetData[name];
+ if(!pro){
+ return null;
+ }
+ pro = editor._widgetData[name];
+ if(!pro){
+ pro = _widgetData[name];
+ pro = editor._widgetData[name] = $.type(pro) == 'function' ? pro : utils.clone(pro);
+ }
+
+ pro.root($widget.edui().getBodyContainer());
+
+ pro.initContent(editor,$widget);
+ if(!pro._preventDefault){
+ pro.initEvent(editor,$widget);
+ }
+
+ pro.width && $widget.width(pro.width);
+
+
+ },
+ setActiveWidget : function($widget){
+ _activeWidget = $widget;
+ },
+ getEditor: function (id, options) {
+ var editor = _editors[id] || (_editors[id] = this.createEditor(id, options));
+ _maxZIndex = _maxZIndex ? Math.max(editor.getOpt('zIndex'), _maxZIndex):editor.getOpt('zIndex');
+ return editor;
+ },
+ setTopEditor: function(editor){
+ $.each(_editors, function(i, o){
+ if(editor == o) {
+ editor.$container && editor.$container.css('zIndex', _maxZIndex + 1);
+ } else {
+ o.$container && o.$container.css('zIndex', o.getOpt('zIndex'));
+ }
+ });
+ },
+ clearCache : function(id){
+ if ( _editors[id]) {
+ delete _editors[id]
+ }
+ },
+ delEditor: function (id) {
+ var editor;
+ if (editor = _editors[id]) {
+ editor.destroy();
+ }
+ },
+ ready: function( fn ){
+ _readyFn.push( fn );
+ },
+ createEditor: function (id, opt) {
+ var editor = new UM.Editor(opt);
+ var T = this;
+
+ editor.langIsReady ? $.proxy(renderUI,T)() : editor.addListener("langReady", $.proxy(renderUI,T));
+ function renderUI(){
+
+
+ var $container = this.createUI('#' + id, editor);
+ editor.key=id;
+ editor.ready(function(){
+ $.each( _readyFn, function( index, fn ){
+ $.proxy( fn, editor )();
+ } );
+ });
+ var options = editor.options;
+ if(options.initialFrameWidth){
+ options.minFrameWidth = options.initialFrameWidth
+ }else{
+ options.minFrameWidth = options.initialFrameWidth = editor.$body.width() || UM.defaultWidth;
+ }
+
+ $container.css({
+ width: options.initialFrameWidth,
+ zIndex:editor.getOpt('zIndex')
+ });
+
+ //ie6下缓存图片
+ UM.browser.ie && UM.browser.version === 6 && document.execCommand("BackgroundImageCache", false, true);
+
+ editor.render(id);
+
+
+ //添加tooltip;
+ $.eduitooltip && $.eduitooltip('attachTo', $("[data-original-title]",$container)).css('z-index',editor.getOpt('zIndex')+1);
+
+ $container.find('a').click(function(evt){
+ evt.preventDefault()
+ });
+
+ editor.fireEvent("afteruiready");
+ }
+
+ return editor;
+
+ },
+ createUI: function (id, editor) {
+ var $editorCont = $(id),
+ $container = $('
').insertBefore($editorCont);
+ editor.$container = $container;
+ editor.container = $container[0];
+
+ editor.$body = $editorCont;
+
+ //修正在ie9+以上的版本中,自动长高收起时的,残影问题
+ if(browser.ie && browser.ie9above){
+ var $span = $('
');
+ $span.insertAfter($container);
+ }
+ //初始化注册的ui组件
+ $.each(_editorUI,function(n,v){
+ var widget = v.call(editor,n);
+ if(widget){
+ _cacheUI[n] = widget;
+ }
+
+ });
+
+ $container.find('.edui-editor-body').append($editorCont).before(this.createToolbar(editor.options, editor));
+
+ $container.find('.edui-toolbar').append($('
'));
+
+
+ return $container;
+ },
+ createToolbar: function (options, editor) {
+ var $toolbar = $.eduitoolbar(), toolbar = $toolbar.edui();
+ //创建下来菜单列表
+
+ if (options.toolbar && options.toolbar.length) {
+ var btns = [];
+ $.each(options.toolbar,function(i,uiNames){
+ $.each(uiNames.split(/\s+/),function(index,name){
+ if(name == '|'){
+ $.eduiseparator && btns.push($.eduiseparator());
+ }else{
+ var ui = _cacheUI[name];
+ if(name=="fullscreen"){
+ ui&&btns.unshift(ui);
+ }else{
+ ui && btns.push(ui);
+ }
+ }
+
+ });
+ btns.length && toolbar.appendToBtnmenu(btns);
+ });
+ } else {
+ $toolbar.find('.edui-btn-toolbar').remove()
+ }
+ return $toolbar;
+ }
+
+ })
+
+
+})();
+
+
+
+UM.registerUI('bold italic redo undo underline strikethrough superscript subscript insertorderedlist insertunorderedlist ' +
+ 'cleardoc selectall link unlink print preview justifyleft justifycenter justifyright justifyfull removeformat horizontal drafts',
+ function(name) {
+ var me = this;
+ var $btn = $.eduibutton({
+ icon : name,
+ click : function(){
+ me.execCommand(name);
+ },
+ title: this.getLang('labelMap')[name] || ''
+ });
+
+ this.addListener('selectionchange',function(){
+ var state = this.queryCommandState(name);
+ $btn.edui().disabled(state == -1).active(state == 1)
+ });
+ return $btn;
+ }
+);
+
+
+/**
+ * 全屏组件
+ */
+
+(function(){
+
+ //状态缓存
+ var STATUS_CACHE = {},
+ //状态值列表
+ STATUS_LIST = [ 'width', 'height', 'position', 'top', 'left', 'margin', 'padding', 'overflowX', 'overflowY' ],
+ CONTENT_AREA_STATUS = {},
+ //页面状态
+ DOCUMENT_STATUS = {},
+ DOCUMENT_ELEMENT_STATUS = {},
+
+ FULLSCREENS = {};
+
+
+ UM.registerUI('fullscreen', function( name ){
+
+ var me = this,
+ $button = $.eduibutton({
+ 'icon': 'fullscreen',
+ 'title': (me.options.labelMap && me.options.labelMap[name]) || me.getLang("labelMap." + name),
+ 'click': function(){
+ //切换
+ me.execCommand( name );
+ UM.setTopEditor(me);
+ }
+ });
+
+ me.addListener( "selectionchange", function () {
+
+ var state = this.queryCommandState( name );
+ $button.edui().disabled( state == -1 ).active( state == 1 );
+
+ } );
+
+ //切换至全屏
+ me.addListener('ready', function(){
+
+ me.options.fullscreen && Fullscreen.getInstance( me ).toggle();
+
+ });
+
+ return $button;
+
+ });
+
+ UM.commands[ 'fullscreen' ] = {
+
+ execCommand: function (cmdName) {
+
+ Fullscreen.getInstance( this ).toggle();
+
+ },
+ queryCommandState: function (cmdName) {
+
+ return this._edui_fullscreen_status;
+ },
+ notNeedUndo: 1
+
+ };
+
+ function Fullscreen( editor ) {
+
+ var me = this;
+
+ if( !editor ) {
+ throw new Error('invalid params, notfound editor');
+ }
+
+ me.editor = editor;
+
+ //记录初始化的全屏组件
+ FULLSCREENS[ editor.uid ] = this;
+
+ editor.addListener('destroy', function(){
+ delete FULLSCREENS[ editor.uid ];
+ me.editor = null;
+ });
+
+ }
+
+ Fullscreen.prototype = {
+
+ /**
+ * 全屏状态切换
+ */
+ toggle: function(){
+
+ var editor = this.editor,
+ //当前编辑器的缩放状态
+ _edui_fullscreen_status = this.isFullState();
+ editor.fireEvent('beforefullscreenchange', !_edui_fullscreen_status );
+
+ //更新状态
+ this.update( !_edui_fullscreen_status );
+
+ !_edui_fullscreen_status ? this.enlarge() : this.revert();
+
+ editor.fireEvent('afterfullscreenchange', !_edui_fullscreen_status );
+ if(editor.body.contentEditable === 'true'){
+ editor.fireEvent( 'fullscreenchanged', !_edui_fullscreen_status );
+ }
+
+ editor.fireEvent( 'selectionchange' );
+
+ },
+ /**
+ * 执行放大
+ */
+ enlarge: function(){
+
+ this.saveSataus();
+
+ this.setDocumentStatus();
+
+ this.resize();
+
+ },
+ /**
+ * 全屏还原
+ */
+ revert: function(){
+
+ //还原CSS表达式
+ var options = this.editor.options,
+ height = /%$/.test(options.initialFrameHeight) ? '100%' : (options.initialFrameHeight - this.getStyleValue("padding-top")- this.getStyleValue("padding-bottom") - this.getStyleValue('border-width'));
+
+ $.IE6 && this.getEditorHolder().style.setExpression('height', 'this.scrollHeight <= ' + height + ' ? "' + height + 'px" : "auto"');
+
+ //还原容器状态
+ this.revertContainerStatus();
+
+ this.revertContentAreaStatus();
+
+ this.revertDocumentStatus();
+
+ },
+ /**
+ * 更新状态
+ * @param isFull 当前状态是否是全屏状态
+ */
+ update: function( isFull ) {
+ this.editor._edui_fullscreen_status = isFull;
+ },
+ /**
+ * 调整当前编辑器的大小, 如果当前编辑器不处于全屏状态, 则不做调整
+ */
+ resize: function(){
+
+ var $win = null,
+ height = 0,
+ width = 0,
+ borderWidth = 0,
+ paddingWidth = 0,
+ editor = this.editor,
+ me = this,
+ bound = null,
+ editorBody = null;
+
+ if( !this.isFullState() ) {
+ return;
+ }
+
+ $win = $( window );
+ width = $win.width();
+ height = $win.height();
+ editorBody = this.getEditorHolder();
+ //文本编辑区border宽度
+ borderWidth = parseInt( domUtils.getComputedStyle( editorBody, 'border-width' ), 10 ) || 0;
+ //容器border宽度
+ borderWidth += parseInt( domUtils.getComputedStyle( editor.container, 'border-width' ), 10 ) || 0;
+ //容器padding
+ paddingWidth += parseInt( domUtils.getComputedStyle( editorBody, 'padding-left' ), 10 ) + parseInt( domUtils.getComputedStyle( editorBody, 'padding-right' ), 10 ) || 0;
+
+ //干掉css表达式
+ $.IE6 && editorBody.style.setExpression( 'height', null );
+
+ bound = this.getBound();
+
+ $( editor.container ).css( {
+ width: width + 'px',
+ height: height + 'px',
+ position: !$.IE6 ? 'fixed' : 'absolute',
+ top: bound.top,
+ left: bound.left,
+ margin: 0,
+ padding: 0,
+ overflowX: 'hidden',
+ overflowY: 'hidden'
+ } );
+
+ $( editorBody ).css({
+ width: width - 2*borderWidth - paddingWidth + 'px',
+ height: height - 2*borderWidth - ( editor.options.withoutToolbar ? 0 : $( '.edui-toolbar', editor.container ).outerHeight() ) - $( '.edui-bottombar', editor.container).outerHeight() + 'px',
+ overflowX: 'hidden',
+ overflowY: 'auto'
+ });
+
+ },
+ /**
+ * 保存状态
+ */
+ saveSataus: function(){
+
+ var styles = this.editor.container.style,
+ tmp = null,
+ cache = {};
+
+ for( var i= 0, len = STATUS_LIST.length; i
offset) {
+ setFloating();
+ }else{
+ unsetFloating();
+ }
+ }
+ var defer_updateFloating = utils.defer(function(){
+ updateFloating();
+ },browser.ie ? 200 : 100,true);
+
+ me.addListener('destroy',function(){
+ $(window).off('scroll resize',updateFloating);
+ me.removeListener('keydown', defer_updateFloating);
+ });
+
+ if(checkHasUI(me)){
+ toolbarBox = $('.edui-toolbar',me.container)[0];
+ me.addListener("afteruiready",function(){
+ setTimeout(function(){
+ orgTop = $(toolbarBox).offset().top;
+ },100);
+ });
+ bakCssText = toolbarBox.style.cssText;
+ placeHolder.style.height = toolbarBox.offsetHeight + 'px';
+ if(LteIE6){
+ fixIE6FixedPos();
+ }
+
+ $(window).on('scroll resize',updateFloating);
+ me.addListener('keydown', defer_updateFloating);
+ me.addListener('resize', function(){
+ unsetFloating();
+ placeHolder.style.height = toolbarBox.offsetHeight + 'px';
+ updateFloating();
+ });
+
+ me.addListener('beforefullscreenchange', function (t, enabled){
+ if (enabled) {
+ unsetFloating();
+ isFullScreening = enabled;
+ }
+ });
+ me.addListener('fullscreenchanged', function (t, enabled){
+ if (!enabled) {
+ updateFloating();
+ }
+ isFullScreening = enabled;
+ });
+ me.addListener('sourcemodechanged', function (t, enabled){
+ setTimeout(function (){
+ updateFloating();
+ },0);
+ });
+ me.addListener("clearDoc",function(){
+ setTimeout(function(){
+ updateFloating();
+ },0);
+
+ })
+ }
+ })
+
+
+});
+UM.registerUI('source',function(name){
+ var me = this;
+ me.addListener('fullscreenchanged',function(){
+ me.$container.find('textarea').width(me.$body.width() - 10).height(me.$body.height())
+
+ });
+ var $btn = $.eduibutton({
+ icon : name,
+ click : function(){
+ me.execCommand(name);
+ UM.setTopEditor(me);
+ },
+ title: this.getLang('labelMap')[name] || ''
+ });
+
+ this.addListener('selectionchange',function(){
+ var state = this.queryCommandState(name);
+ $btn.edui().disabled(state == -1).active(state == 1)
+ });
+ return $btn;
+});
+
+UM.registerUI('paragraph fontfamily fontsize', function( name ) {
+
+ var me = this,
+ label = (me.options.labelMap && me.options.labelMap[name]) || me.getLang("labelMap." + name),
+ options = {
+ label: label,
+ title: label,
+ comboboxName: name,
+ items: me.options[ name ] || [],
+ itemStyles: [],
+ value: [],
+ autowidthitem: []
+ },
+ $combox = null,
+ comboboxWidget = null;
+ if(options.items.length == 0){
+ return null;
+ }
+ switch ( name ) {
+
+ case 'paragraph':
+ options = transForParagraph( options );
+ break;
+
+ case 'fontfamily':
+ options = transForFontfamily( options );
+ break;
+
+ case 'fontsize':
+ options = transForFontsize( options );
+ break;
+
+ }
+
+ //实例化
+ $combox = $.eduibuttoncombobox(options).css('zIndex',me.getOpt('zIndex') + 1);
+ comboboxWidget = $combox.edui();
+
+ comboboxWidget.on('comboboxselect', function( evt, res ){
+ me.execCommand( name, res.value );
+ }).on("beforeshow", function(){
+ if( $combox.parent().length === 0 ) {
+ $combox.appendTo( me.$container.find('.edui-dialog-container') );
+ }
+ UM.setTopEditor(me);
+ });
+
+
+ //状态反射
+ this.addListener('selectionchange',function( evt ){
+
+ var state = this.queryCommandState( name ),
+ value = this.queryCommandValue( name );
+
+ //设置按钮状态
+ comboboxWidget.button().edui().disabled( state == -1 ).active( state == 1 );
+ if(value){
+ //设置label
+ value = value.replace(/['"]/g, '').toLowerCase().split(/['|"]?\s*,\s*[\1]?/);
+
+ comboboxWidget.selectItemByLabel( value );
+ }
+
+
+ });
+
+ return comboboxWidget.button().addClass('edui-combobox');
+
+ /**
+ * 宽度自适应工具函数
+ * @param word 单词内容
+ * @param hasSuffix 是否含有后缀
+ */
+ function wordCountAdaptive ( word, hasSuffix ) {
+
+ var $tmpNode = $('' ).html( word ).css( {
+ display: 'inline',
+ position: 'absolute',
+ top: -10000000,
+ left: -100000
+ } ).appendTo( document.body),
+ width = $tmpNode.width();
+
+ $tmpNode.remove();
+ $tmpNode = null;
+
+ if( width < 50 ) {
+
+ return word;
+
+ } else {
+
+ word = word.slice( 0, hasSuffix ? -4 : -1 );
+
+ if( !word.length ) {
+ return '...';
+ }
+
+ return wordCountAdaptive( word + '...', true );
+
+ }
+
+ }
+
+
+ //段落参数转换
+ function transForParagraph ( options ) {
+
+ var tempItems = [];
+
+ for( var key in options.items ) {
+
+ options.value.push( key );
+ tempItems.push( key );
+ options.autowidthitem.push( wordCountAdaptive( key ) );
+
+ }
+
+ options.items = tempItems;
+ options.autoRecord = false;
+
+ return options;
+
+ }
+
+ //字体参数转换
+ function transForFontfamily ( options ) {
+
+ var temp = null,
+ tempItems = [];
+
+ for( var i = 0, len = options.items.length; i < len; i++ ) {
+
+ temp = options.items[ i ].val;
+ tempItems.push( temp.split(/\s*,\s*/)[0] );
+ options.itemStyles.push('font-family: ' + temp);
+ options.value.push( temp );
+ options.autowidthitem.push( wordCountAdaptive( tempItems[ i ] ) );
+
+ }
+
+ options.items = tempItems;
+
+ return options;
+
+ }
+
+ //字体大小参数转换
+ function transForFontsize ( options ) {
+
+ var temp = null,
+ tempItems = [];
+
+ options.itemStyles = [];
+ options.value = [];
+
+ for( var i = 0, len = options.items.length; i < len; i++ ) {
+
+ temp = options.items[ i ];
+ tempItems.push( temp );
+ options.itemStyles.push('font-size: ' + temp +'px');
+
+ }
+
+ options.value = options.items;
+ options.items = tempItems;
+ options.autoRecord = false;
+
+ return options;
+
+ }
+
+});
+
+
+UM.registerUI('forecolor backcolor', function( name ) {
+ function getCurrentColor() {
+ return domUtils.getComputedStyle( $colorLabel[0], 'background-color' );
+ }
+
+ var me = this,
+ $colorPickerWidget = null,
+ $colorLabel = null,
+ $btn = null;
+
+ //querycommand
+ this.addListener('selectionchange', function(){
+
+ var state = this.queryCommandState( name );
+ $btn.edui().disabled( state == -1 ).active( state == 1 );
+
+ });
+
+ $btn = $.eduicolorsplitbutton({
+ icon: name,
+ caret: true,
+ name: name,
+ title: me.getLang("labelMap")[name],
+ click: function() {
+ me.execCommand( name, getCurrentColor() );
+ }
+ });
+
+ $colorLabel = $btn.edui().colorLabel();
+
+ $colorPickerWidget = $.eduicolorpicker({
+ name: name,
+ lang_clearColor: me.getLang('clearColor') || '',
+ lang_themeColor: me.getLang('themeColor') || '',
+ lang_standardColor: me.getLang('standardColor') || ''
+ })
+ .on('pickcolor', function( evt, color ){
+ window.setTimeout( function(){
+ $colorLabel.css("backgroundColor", color);
+ me.execCommand( name, color );
+ }, 0 );
+ })
+ .on('show',function(){
+ UM.setActiveWidget( colorPickerWidget.root() );
+ }).css('zIndex',me.getOpt('zIndex') + 1);
+
+ $btn.edui().on('arrowclick',function(){
+ if(!$colorPickerWidget.parent().length){
+ me.$container.find('.edui-dialog-container').append($colorPickerWidget);
+ }
+ $colorPickerWidget.edui().show($btn,{
+ caretDir:"down",
+ offsetTop:-5,
+ offsetLeft:8,
+ caretLeft:11,
+ caretTop:-8
+ });
+ UM.setTopEditor(me);
+ }).register('click', $btn, function () {
+ $colorPickerWidget.edui().hide()
+ });
+
+ return $btn;
+
+});
+
+})(jQuery)
diff --git a/addons/umeditor/assets/umeditor.min.js b/addons/umeditor/assets/umeditor.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..bf29d137c49e1bc2a078c837028e43a31b7ea5e2
--- /dev/null
+++ b/addons/umeditor/assets/umeditor.min.js
@@ -0,0 +1 @@
+(function($){UMEDITOR_CONFIG=window.UMEDITOR_CONFIG||{};window.UM={list:{},plugins:{},commands:{},I18N:{},version:"1.2.2"};var dom=UM.dom={};var browser=UM.browser=function(){var agent=navigator.userAgent.toLowerCase(),opera=window.opera,browser={ie:/(msie\s|trident.*rv:)([\w.]+)/.test(agent),opera:!!opera&&opera.version,webkit:agent.indexOf(" applewebkit/")>-1,mac:agent.indexOf("macintosh")>-1,quirks:document.compatMode=="BackCompat"};browser.gecko=navigator.product=="Gecko"&&!browser.webkit&&!browser.opera&&!browser.ie;var version=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;browser.ie9Compat=document.documentMode==9;browser.ie8=!!document.documentMode;browser.ie8Compat=document.documentMode==8;browser.ie7Compat=version==7&&!document.documentMode||document.documentMode==7;browser.ie6Compat=version<7||browser.quirks;browser.ie9above=version>8;browser.ie9below=version<9}if(browser.gecko){var geckoRelease=agent.match(/rv:([\d\.]+)/);if(geckoRelease){geckoRelease=geckoRelease[1].split(".");version=geckoRelease[0]*1e4+(geckoRelease[1]||0)*100+(geckoRelease[2]||0)*1}}if(/chrome\/(\d+\.\d)/i.test(agent)){browser.chrome=+RegExp["$1"]}if(/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent)&&!/chrome/i.test(agent)){browser.safari=+(RegExp["$1"]||RegExp["$2"])}if(browser.opera)version=parseFloat(opera.version());if(browser.webkit)version=parseFloat(agent.match(/ applewebkit\/(\d+)/)[1]);browser.version=version;browser.isCompatible=!browser.mobile&&(browser.ie&&version>=6||browser.gecko&&version>=10801||browser.opera&&version>=9.5||browser.air&&version>=1||browser.webkit&&version>=522||false);return browser}();var ie=browser.ie,webkit=browser.webkit,gecko=browser.gecko,opera=browser.opera;var utils=UM.utils={each:function(obj,iterator,context){if(obj==null)return;if(obj.length===+obj.length){for(var i=0,l=obj.length;i=start&&v===item){index=i;return false}});return index},removeItem:function(array,item){for(var i=0,l=array.length;i'](?:(amp|lt|quot|gt|#39|nbsp);)?/g,function(a,b){if(b){return a}else{return{"<":"<","&":"&",'"':""",">":">","'":"'"}[a]}}):""},html:function(str){return str?str.replace(/&((g|l|quo)t|amp|#39);/g,function(m){return{"<":"<","&":"&",""":'"',">":">","'":"'"}[m]}):""},cssStyleToDomStyle:function(){var test=document.createElement("div").style,cache={float:test.cssFloat!=undefined?"cssFloat":test.styleFloat!=undefined?"styleFloat":"float"};return function(cssName){return cache[cssName]||(cache[cssName]=cssName.toLowerCase().replace(/-./g,function(match){return match.charAt(1).toUpperCase()}))}}(),loadFile:function(){var tmpList=[];function getItem(doc,obj){try{for(var i=0,ci;ci=tmpList[i++];){if(ci.doc===doc&&ci.url==(obj.src||obj.href)){return ci}}}catch(e){return null}}return function(doc,obj,fn){var item=getItem(doc,obj);if(item){if(item.ready){fn&&fn()}else{item.funs.push(fn)}return}tmpList.push({doc:doc,url:obj.src||obj.href,funs:[fn]});if(!doc.body){var html=[];for(var p in obj){if(p=="tag")continue;html.push(p+'="'+obj[p]+'"')}doc.write("<"+obj.tag+" "+html.join(" ")+" >"+obj.tag+">");return}if(obj.id&&doc.getElementById(obj.id)){return}var element=doc.createElement(obj.tag);delete obj.tag;for(var p in obj){element.setAttribute(p,obj[p])}element.onload=element.onreadystatechange=function(){if(!this.readyState||/loaded|complete/.test(this.readyState)){item=getItem(doc,obj);if(item.funs.length>0){item.ready=1;for(var fi;fi=item.funs.pop();){fi()}}element.onload=element.onreadystatechange=null}};element.onerror=function(){throw Error("The load "+(obj.href||obj.src)+" fails,check the url settings of file umeditor.config.js ")};doc.getElementsByTagName("head")[0].appendChild(element)}}(),isEmptyObject:function(obj){if(obj==null)return true;if(this.isArray(obj)||this.isString(obj))return obj.length===0;for(var key in obj)if(obj.hasOwnProperty(key))return false;return true},fixColor:function(name,value){if(/color/i.test(name)&&/rgba?/.test(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}value=value.toUpperCase()}return value},clone:function(source,target){var tmp;target=target||{};for(var i in source){if(source.hasOwnProperty(i)){tmp=source[i];if(typeof tmp=="object"){target[i]=utils.isArray(tmp)?[]:{};utils.clone(source[i],target[i])}else{target[i]=tmp}}}return target},transUnitToPx:function(val){if(!/(pt|cm)/.test(val)){return val}var unit;val.replace(/([\d.]+)(\w+)/,function(str,v,u){val=v;unit=u});switch(unit){case"cm":val=parseFloat(val)*25;break;case"pt":val=Math.round(parseFloat(val)*96/72)}return val+(val?"px":"")},cssRule:browser.ie&&browser.version!=11?function(key,style,doc){var indexList,index;doc=doc||document;if(doc.indexList){indexList=doc.indexList}else{indexList=doc.indexList={}}var sheetStyle;if(!indexList[key]){if(style===undefined){return""}sheetStyle=doc.createStyleSheet("",index=doc.styleSheets.length);indexList[key]=index}else{sheetStyle=doc.styleSheets[indexList[key]]}if(style===undefined){return sheetStyle.cssText}sheetStyle.cssText=style||""}:function(key,style,doc){doc=doc||document;var head=doc.getElementsByTagName("head")[0],node;if(!(node=doc.getElementById(key))){if(style===undefined){return""}node=doc.createElement("style");node.id=key;head.appendChild(node)}if(style===undefined){return node.innerHTML}if(style!==""){node.innerHTML=style}else{head.removeChild(node)}}};utils.each(["String","Function","Array","Number","RegExp","Object"],function(v){UM.utils["is"+v]=function(obj){return Object.prototype.toString.apply(obj)=="[object "+v+"]"}});var EventBase=UM.EventBase=function(){};EventBase.prototype={addListener:function(types,listener){types=utils.trim(types).split(" ");for(var i=0,ti;ti=types[i++];){getListener(this,ti,true).push(listener)}},removeListener:function(types,listener){types=utils.trim(types).split(" ");for(var i=0,ti;ti=types[i++];){utils.removeItem(getListener(this,ti)||[],listener)}},fireEvent:function(){var types=arguments[0];types=utils.trim(types).split(" ");for(var i=0,ti;ti=types[i++];){var listeners=getListener(this,ti),r,t,k;if(listeners){k=listeners.length;while(k--){if(!listeners[k])continue;t=listeners[k].apply(this,arguments);if(t===true){return t}if(t!==undefined){r=t}}}if(t=this["on"+ti.toLowerCase()]){r=t.apply(this,arguments)}}return r}};function getListener(obj,type,force){var allListeners;type=type.toLowerCase();return(allListeners=obj.__allListeners||force&&(obj.__allListeners={}))&&(allListeners[type]||force&&(allListeners[type]=[]))}var dtd=dom.dtd=function(){function _(s){for(var k in s){s[k.toUpperCase()]=s[k]}return s}var X=utils.extend2;var A=_({isindex:1,fieldset:1}),B=_({input:1,button:1,select:1,textarea:1,label:1}),C=X(_({a:1}),B),D=X({iframe:1},C),E=_({hr:1,ul:1,menu:1,div:1,blockquote:1,noscript:1,table:1,center:1,address:1,dir:1,pre:1,h5:1,dl:1,h4:1,noframes:1,h6:1,ol:1,h1:1,h3:1,h2:1}),F=_({ins:1,del:1,script:1,style:1}),G=X(_({b:1,acronym:1,bdo:1,var:1,"#":1,abbr:1,code:1,br:1,i:1,cite:1,kbd:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,dfn:1,span:1}),F),H=X(_({sub:1,img:1,embed:1,object:1,sup:1,basefont:1,map:1,applet:1,font:1,big:1,small:1}),G),I=X(_({p:1}),H),J=X(_({iframe:1}),H,B),K=_({img:1,embed:1,noscript:1,br:1,kbd:1,center:1,button:1,basefont:1,h5:1,h4:1,samp:1,h6:1,ol:1,h1:1,h3:1,h2:1,form:1,font:1,"#":1,select:1,menu:1,ins:1,abbr:1,label:1,code:1,table:1,script:1,cite:1,input:1,iframe:1,strong:1,textarea:1,noframes:1,big:1,small:1,span:1,hr:1,sub:1,bdo:1,var:1,div:1,object:1,sup:1,strike:1,dir:1,map:1,dl:1,applet:1,del:1,isindex:1,fieldset:1,ul:1,b:1,acronym:1,a:1,blockquote:1,i:1,u:1,s:1,tt:1,address:1,q:1,pre:1,p:1,em:1,dfn:1}),L=X(_({a:0}),J),M=_({tr:1}),N=_({"#":1}),O=X(_({param:1}),K),P=X(_({form:1}),A,D,E,I),Q=_({li:1,ol:1,ul:1}),R=_({style:1,script:1}),S=_({base:1,link:1,meta:1,title:1}),T=X(S,R),U=_({head:1,body:1}),V=_({html:1});var block=_({address:1,blockquote:1,center:1,dir:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,isindex:1,menu:1,noframes:1,ol:1,p:1,pre:1,table:1,ul:1}),empty=_({area:1,base:1,basefont:1,br:1,col:1,command:1,dialog:1,embed:1,hr:1,img:1,input:1,isindex:1,keygen:1,link:1,meta:1,param:1,source:1,track:1,wbr:1});return _({$nonBodyContent:X(V,U,S),$block:block,$inline:L,$inlineWithA:X(_({a:1}),L),$body:X(_({script:1,style:1}),block),$cdata:_({script:1,style:1}),$empty:empty,$nonChild:_({iframe:1,textarea:1}),$listItem:_({dd:1,dt:1,li:1}),$list:_({ul:1,ol:1,dl:1}),$isNotEmpty:_({table:1,ul:1,ol:1,dl:1,iframe:1,area:1,base:1,col:1,hr:1,img:1,embed:1,input:1,link:1,meta:1,param:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1}),$removeEmpty:_({a:1,abbr:1,acronym:1,address:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,s:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,var:1}),$removeEmptyBlock:_({p:1,div:1}),$tableContent:_({caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1,table:1}),$notTransContent:_({pre:1,script:1,style:1,textarea:1}),html:U,head:T,style:N,script:N,body:P,base:{},link:{},meta:{},title:N,col:{},tr:_({td:1,th:1}),img:{},embed:{},colgroup:_({thead:1,col:1,tbody:1,tr:1,tfoot:1}),noscript:P,td:P,br:{},th:P,center:P,kbd:L,button:X(I,E),basefont:{},h5:L,h4:L,samp:L,h6:L,ol:Q,h1:L,h3:L,option:N,h2:L,form:X(A,D,E,I),select:_({optgroup:1,option:1}),font:L,ins:L,menu:Q,abbr:L,label:L,table:_({thead:1,col:1,tbody:1,tr:1,colgroup:1,caption:1,tfoot:1}),code:L,tfoot:M,cite:L,li:P,input:{},iframe:P,strong:L,textarea:N,noframes:P,big:L,small:L,span:_({"#":1,br:1,b:1,strong:1,u:1,i:1,em:1,sub:1,sup:1,strike:1,span:1}),hr:L,dt:L,sub:L,optgroup:_({option:1}),param:{},bdo:L,var:L,div:P,object:O,sup:L,dd:P,strike:L,area:{},dir:Q,map:X(_({area:1,form:1,p:1}),A,F,E),applet:O,dl:_({dt:1,dd:1}),del:L,isindex:{},fieldset:X(_({legend:1}),K),thead:M,ul:Q,acronym:L,b:L,a:X(_({a:1}),J),blockquote:X(_({td:1,tr:1,tbody:1,li:1}),P),caption:L,i:L,u:L,tbody:M,s:L,address:X(D,I),tt:L,legend:L,q:L,pre:X(G,C),p:X(_({a:1}),L),em:L,dfn:L})}();function getDomNode(node,start,ltr,startFromChild,fn,guard){var tmpNode=startFromChild&&node[start],parent;!tmpNode&&(tmpNode=node[ltr]);while(!tmpNode&&(parent=(parent||node).parentNode)){if(parent.tagName=="BODY"||guard&&!guard(parent)){return null}tmpNode=parent[ltr]}if(tmpNode&&fn&&!fn(tmpNode)){return getDomNode(tmpNode,start,ltr,false,fn)}return tmpNode}var attrFix=ie&&browser.version<9?{tabindex:"tabIndex",readonly:"readOnly",for:"htmlFor",class:"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder"}:{tabindex:"tabIndex",readonly:"readOnly"},styleBlock=utils.listToMap(["-webkit-box","-moz-box","block","list-item","table","table-row-group","table-header-group","table-footer-group","table-row","table-column-group","table-column","table-cell","table-caption"]);var domUtils=dom.domUtils={NODE_ELEMENT:1,NODE_DOCUMENT:9,NODE_TEXT:3,NODE_COMMENT:8,NODE_DOCUMENT_FRAGMENT:11,POSITION_IDENTICAL:0,POSITION_DISCONNECTED:1,POSITION_FOLLOWING:2,POSITION_PRECEDING:4,POSITION_IS_CONTAINED:8,POSITION_CONTAINS:16,fillChar:ie&&browser.version=="6"?"\ufeff":"",keys:{8:1,46:1,16:1,17:1,18:1,37:1,38:1,39:1,40:1,13:1},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},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")},getPosition:function(nodeA,nodeB){if(nodeA===nodeB){return 0}var node,parentsA=[nodeA],parentsB=[nodeB];node=nodeA;while(node=node.parentNode){if(node===nodeB){return 10}parentsA.push(node)}node=nodeB;while(node=node.parentNode){if(node===nodeA){return 20}parentsB.push(node)}parentsA.reverse();parentsB.reverse();if(parentsA[0]!==parentsB[0]){return 1}var i=-1;while(i++,parentsA[i]===parentsB[i]){}nodeA=parentsA[i];nodeB=parentsB[i];while(nodeA=nodeA.nextSibling){if(nodeA===nodeB){return 4}}return 2},getNodeIndex:function(node,ignoreTextNode){var preNode=node,i=0;while(preNode=preNode.previousSibling){if(ignoreTextNode&&preNode.nodeType==3){if(preNode.nodeType!=preNode.nextSibling.nodeType){i++}continue}i++}return i},inDoc:function(node,doc){return domUtils.getPosition(node,doc)==10},findParent:function(node,filterFn,includeSelf){if(node&&!domUtils.isBody(node)){node=includeSelf?node:node.parentNode;while(node){if(!filterFn||filterFn(node)||domUtils.isBody(node)){return filterFn&&!filterFn(node)&&domUtils.isBody(node)?null:node}node=node.parentNode}}return null},findParentByTagName:function(node,tagNames,includeSelf,excludeFn){tagNames=utils.listToMap(utils.isArray(tagNames)?tagNames:[tagNames]);return domUtils.findParent(node,function(node){return tagNames[node.tagName]&&!(excludeFn&&excludeFn(node))},includeSelf)},findParents:function(node,includeSelf,filterFn,closerFirst){var parents=includeSelf&&(filterFn&&filterFn(node)||!filterFn)?[node]:[];while(node=domUtils.findParent(node,filterFn)){parents.push(node)}return closerFirst?parents:parents.reverse()},insertAfter:function(node,newNode){return node.parentNode.insertBefore(newNode,node.nextSibling)},remove:function(node,keepChildren){var parent=node.parentNode,child;if(parent){if(keepChildren&&node.hasChildNodes()){while(child=node.firstChild){parent.insertBefore(child,node)}}parent.removeChild(node)}return node},getNextDomNode:function(node,startFromChild,filterFn,guard){return getDomNode(node,"firstChild","nextSibling",startFromChild,filterFn,guard)},getPreDomNode:function(node,startFromChild,filterFn,guard){return getDomNode(node,"lastChild","previousSibling",startFromChild,filterFn,guard)},isBookmarkNode:function(node){return node.nodeType==1&&node.id&&/^_baidu_bookmark_/i.test(node.id)},getWindow:function(node){var doc=node.ownerDocument||node;return doc.defaultView||doc.parentWindow},getCommonAncestor:function(nodeA,nodeB){if(nodeA===nodeB)return nodeA;var parentsA=[nodeA],parentsB=[nodeB],parent=nodeA,i=-1;while(parent=parent.parentNode){if(parent===nodeB){return parent}parentsA.push(parent)}parent=nodeB;while(parent=parent.parentNode){if(parent===nodeA)return parent;parentsB.push(parent)}parentsA.reverse();parentsB.reverse();while(i++,parentsA[i]===parentsB[i]){}return i==0?null:parentsA[i-1]},clearEmptySibling:function(node,ignoreNext,ignorePre){function clear(next,dir){var tmpNode;while(next&&!domUtils.isBookmarkNode(next)&&(domUtils.isEmptyInlineElement(next)||!new RegExp("[^\t\n\r"+domUtils.fillChar+"]").test(next.nodeValue))){tmpNode=next[dir];domUtils.remove(next);next=tmpNode}}!ignoreNext&&clear(node.nextSibling,"nextSibling");!ignorePre&&clear(node.previousSibling,"previousSibling")},split:function(node,offset){var doc=node.ownerDocument;if(browser.ie&&offset==node.nodeValue.length){var next=doc.createTextNode("");return domUtils.insertAfter(node,next)}var retval=node.splitText(offset);if(browser.ie8){var tmpNode=doc.createTextNode("");domUtils.insertAfter(retval,tmpNode);domUtils.remove(tmpNode)}return retval},isWhitespace:function(node){return!new RegExp("[^ \t\n\r"+domUtils.fillChar+"]").test(node.nodeValue)},getXY:function(element){var x=0,y=0;while(element.offsetParent){y+=element.offsetTop;x+=element.offsetLeft;element=element.offsetParent}return{x:x,y:y}},isEmptyInlineElement:function(node){if(node.nodeType!=1||!dtd.$removeEmpty[node.tagName]){return 0}node=node.firstChild;while(node){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},isBlockElm:function(node){return node.nodeType==1&&(dtd.$block[node.tagName]||styleBlock[domUtils.getComputedStyle(node,"display")])&&!dtd.$nonChild[node.tagName]},getElementsByTagName:function(node,name,filter){if(filter&&utils.isString(filter)){var className=filter;filter=function(node){var result=false;$.each(utils.trim(className).replace(/[ ]{2,}/g," ").split(" "),function(i,v){if($(node).hasClass(v)){result=true;return false}});return result}}name=utils.trim(name).replace(/[ ]{2,}/g," ").split(" ");var arr=[];for(var n=0,ni;ni=name[n++];){var list=node.getElementsByTagName(ni);for(var i=0,ci;ci=list[i++];){if(!filter||filter(ci))arr.push(ci)}}return arr},unSelectable:ie&&browser.ie9below||browser.opera?function(node){node.onselectstart=function(){return false};node.onclick=node.onkeyup=node.onkeydown=function(){return false};node.unselectable="on";node.setAttribute("unselectable","on");for(var i=0,ci;ci=node.all[i++];){switch(ci.tagName.toLowerCase()){case"iframe":case"textarea":case"input":case"select":break;default:ci.unselectable="on";node.setAttribute("unselectable","on")}}}:function(node){node.style.MozUserSelect=node.style.webkitUserSelect=node.style.msUserSelect=node.style.KhtmlUserSelect="none"},removeAttributes:function(node,attrNames){attrNames=utils.isArray(attrNames)?attrNames:utils.trim(attrNames).replace(/[ ]{2,}/g," ").split(" ");for(var i=0,ci;ci=attrNames[i++];){ci=attrFix[ci]||ci;switch(ci){case"className":node[ci]="";break;case"style":node.style.cssText="";!browser.ie&&node.removeAttributeNode(node.getAttributeNode("style"))}node.removeAttribute(ci)}},createElement:function(doc,tag,attrs){return domUtils.setAttributes(doc.createElement(tag),attrs)},setAttributes:function(node,attrs){for(var attr in attrs){if(attrs.hasOwnProperty(attr)){var value=attrs[attr];switch(attr){case"class":node.className=value;break;case"style":node.style.cssText=node.style.cssText+";"+value;break;case"innerHTML":node[attr]=value;break;case"value":node.value=value;break;default:node.setAttribute(attrFix[attr]||attr,value)}}}return node},getComputedStyle:function(element,styleName){return utils.transUnitToPx(utils.fixColor(styleName,$(element).css(styleName)))},preventDefault:function(evt){evt.preventDefault?evt.preventDefault():evt.returnValue=false},removeStyle:function(element,name){if(browser.ie){if(name=="color"){name="(^|;)"+name}element.style.cssText=element.style.cssText.replace(new RegExp(name+"[^:]*:[^;]+;?","ig"),"")}else{if(element.style.removeProperty){element.style.removeProperty(name)}else{element.style.removeAttribute(utils.cssStyleToDomStyle(name))}}if(!element.style.cssText){domUtils.removeAttributes(element,["style"])}},getStyle:function(element,name){var value=element.style[utils.cssStyleToDomStyle(name)];return utils.fixColor(name,value)},setStyle:function(element,name,value){element.style[utils.cssStyleToDomStyle(name)]=value;if(!utils.trim(element.style.cssText)){this.removeAttributes(element,"style")}},removeDirtyAttr:function(node){for(var i=0,ci,nodes=node.getElementsByTagName("*");ci=nodes[i++];){ci.removeAttribute("_moz_dirty")}node.removeAttribute("_moz_dirty")},getChildCount:function(node,fn){var count=0,first=node.firstChild;fn=fn||function(){return 1};while(first){if(fn(first)){count++}first=first.nextSibling}return count},isEmptyNode:function(node){return!node.firstChild||domUtils.getChildCount(node,function(node){return!domUtils.isBr(node)&&!domUtils.isBookmarkNode(node)&&!domUtils.isWhitespace(node)})==0},isBr:function(node){return node.nodeType==1&&node.tagName=="BR"},isEmptyBlock:function(node,reg){if(node.nodeType!=1)return 0;reg=reg||new RegExp("[ \t\r\n"+domUtils.fillChar+"]","g");if(node[browser.ie?"innerText":"textContent"].replace(reg,"").length>0){return 0}for(var n in dtd.$isNotEmpty){if(node.getElementsByTagName(n).length){return 0}}return 1},isCustomeNode:function(node){return node.nodeType==1&&node.getAttribute("_ue_custom_node_")},fillNode:function(doc,node){var tmpNode=browser.ie?doc.createTextNode(domUtils.fillChar):doc.createElement("br");node.innerHTML="";node.appendChild(tmpNode)},isBoundaryNode:function(node,dir){var tmp;while(!domUtils.isBody(node)){tmp=node;node=node.parentNode;if(tmp!==node[dir]){return false}}return true},isFillChar:function(node,isInStart){return node.nodeType==3&&!node.nodeValue.replace(new RegExp((isInStart?"^":"")+domUtils.fillChar),"").length},isBody:function(node){return $(node).hasClass("edui-body-container")}};var fillCharReg=new RegExp(domUtils.fillChar,"g");(function(){var guid=0,fillChar=domUtils.fillChar,fillData;function updateCollapse(range){range.collapsed=range.startContainer&&range.endContainer&&range.startContainer===range.endContainer&&range.startOffset==range.endOffset}function selectOneNode(rng){return!rng.collapsed&&rng.startContainer.nodeType==1&&rng.startContainer===rng.endContainer&&rng.endOffset-rng.startOffset==1}function setEndPoint(toStart,node,offset,range){if(node.nodeType==1&&(dtd.$empty[node.tagName]||dtd.$nonChild[node.tagName])){offset=domUtils.getNodeIndex(node)+(toStart?0:1);node=node.parentNode}if(toStart){range.startContainer=node;range.startOffset=offset;if(!range.endContainer){range.collapse(true)}}else{range.endContainer=node;range.endOffset=offset;if(!range.startContainer){range.collapse(false)}}updateCollapse(range);return range}var Range=dom.Range=function(document,body){var me=this;me.startContainer=me.startOffset=me.endContainer=me.endOffset=null;me.document=document;me.collapsed=true;me.body=body};function removeFillData(doc,excludeNode){try{if(fillData&&domUtils.inDoc(fillData,doc)){if(!fillData.nodeValue.replace(fillCharReg,"").length){var tmpNode=fillData.parentNode;domUtils.remove(fillData);while(tmpNode&&domUtils.isEmptyInlineElement(tmpNode)&&(browser.safari?!(domUtils.getPosition(tmpNode,excludeNode)&domUtils.POSITION_CONTAINS):!tmpNode.contains(excludeNode))){fillData=tmpNode.parentNode;domUtils.remove(tmpNode);tmpNode=fillData}}else{fillData.nodeValue=fillData.nodeValue.replace(fillCharReg,"")}}}catch(e){}}function mergeSibling(node,dir){var tmpNode;node=node[dir];while(node&&domUtils.isFillChar(node)){tmpNode=node[dir];domUtils.remove(node);node=tmpNode}}function execContentsAction(range,action){var start=range.startContainer,end=range.endContainer,startOffset=range.startOffset,endOffset=range.endOffset,doc=range.document,frag=doc.createDocumentFragment(),tmpStart,tmpEnd;if(start.nodeType==1){start=start.childNodes[startOffset]||(tmpStart=start.appendChild(doc.createTextNode("")))}if(end.nodeType==1){end=end.childNodes[endOffset]||(tmpEnd=end.appendChild(doc.createTextNode("")))}if(start===end&&start.nodeType==3){frag.appendChild(doc.createTextNode(start.substringData(startOffset,endOffset-startOffset)));if(action){start.deleteData(startOffset,endOffset-startOffset);range.collapse(true)}return frag}var current,currentLevel,clone=frag,startParents=domUtils.findParents(start,true),endParents=domUtils.findParents(end,true);for(var i=0;startParents[i]==endParents[i];){i++}for(var j=i,si;si=startParents[j];j++){current=si.nextSibling;if(si==start){if(!tmpStart){if(range.startContainer.nodeType==3){clone.appendChild(doc.createTextNode(start.nodeValue.slice(startOffset)));if(action){start.deleteData(startOffset,start.nodeValue.length-startOffset)}}else{clone.appendChild(!action?start.cloneNode(true):start)}}}else{currentLevel=si.cloneNode(false);clone.appendChild(currentLevel)}while(current){if(current===end||current===endParents[j]){break}si=current.nextSibling;clone.appendChild(!action?current.cloneNode(true):current);current=si}clone=currentLevel}clone=frag;if(!startParents[i]){clone.appendChild(startParents[i-1].cloneNode(false));clone=clone.firstChild}for(var j=i,ei;ei=endParents[j];j++){current=ei.previousSibling;if(ei==end){if(!tmpEnd&&range.endContainer.nodeType==3){clone.appendChild(doc.createTextNode(end.substringData(0,endOffset)));if(action){end.deleteData(0,endOffset)}}}else{currentLevel=ei.cloneNode(false);clone.appendChild(currentLevel)}if(j!=i||!startParents[i]){while(current){if(current===start){break}ei=current.previousSibling;clone.insertBefore(!action?current.cloneNode(true):current,clone.firstChild);current=ei}}clone=currentLevel}if(action){range.setStartBefore(!endParents[i]?endParents[i-1]:!startParents[i]?startParents[i-1]:endParents[i]).collapse(true)}tmpStart&&domUtils.remove(tmpStart);tmpEnd&&domUtils.remove(tmpEnd);return frag}Range.prototype={deleteContents:function(){var txt;if(!this.collapsed){execContentsAction(this,1)}if(browser.webkit){txt=this.startContainer;if(txt.nodeType==3&&!txt.nodeValue.length){this.setStartBefore(txt).collapse(true);domUtils.remove(txt)}}return this},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},setStart:function(node,offset){return setEndPoint(true,node,offset,this)},setEnd:function(node,offset){return setEndPoint(false,node,offset,this)},setStartAfter:function(node){return this.setStart(node.parentNode,domUtils.getNodeIndex(node)+1)},setStartBefore:function(node){return this.setStart(node.parentNode,domUtils.getNodeIndex(node))},setEndAfter:function(node){return this.setEnd(node.parentNode,domUtils.getNodeIndex(node)+1)},setEndBefore:function(node){return this.setEnd(node.parentNode,domUtils.getNodeIndex(node))},setStartAtFirst:function(node){return this.setStart(node,0)},setStartAtLast:function(node){return this.setStart(node,node.nodeType==3?node.nodeValue.length:node.childNodes.length)},setEndAtFirst:function(node){return this.setEnd(node,0)},setEndAtLast:function(node){return this.setEnd(node,node.nodeType==3?node.nodeValue.length:node.childNodes.length)},selectNode:function(node){return this.setStartBefore(node).setEndAfter(node)},selectNodeContents:function(node){return this.setStart(node,0).setEndAtLast(node)},cloneRange:function(){var me=this;return new Range(me.document).setStart(me.startContainer,me.startOffset).setEnd(me.endContainer,me.endOffset)},collapse:function(toStart){var me=this;if(toStart){me.endContainer=me.startContainer;me.endOffset=me.startOffset}else{me.startContainer=me.endContainer;me.startOffset=me.endOffset}me.collapsed=true;return me},shrinkBoundary:function(ignoreEnd){var me=this,child,collapsed=me.collapsed;function check(node){return node.nodeType==1&&!domUtils.isBookmarkNode(node)&&!dtd.$empty[node.tagName]&&!dtd.$nonChild[node.tagName]}while(me.startContainer.nodeType==1&&(child=me.startContainer.childNodes[me.startOffset])&&check(child)){me.setStart(child,0)}if(collapsed){return me.collapse(true)}if(!ignoreEnd){while(me.endContainer.nodeType==1&&me.endOffset>0&&(child=me.endContainer.childNodes[me.endOffset-1])&&check(child)){me.setEnd(child,child.childNodes.length)}}return me},trimBoundary:function(ignoreEnd){this.txtToElmBoundary();var start=this.startContainer,offset=this.startOffset,collapsed=this.collapsed,end=this.endContainer;if(start.nodeType==3){if(offset==0){this.setStartBefore(start)}else{if(offset>=start.nodeValue.length){this.setStartAfter(start)}else{var textNode=domUtils.split(start,offset);if(start===end){this.setEnd(textNode,this.endOffset-offset)}else if(start.parentNode===end){this.endOffset+=1}this.setStartBefore(textNode)}}if(collapsed){return this.collapse(true)}}if(!ignoreEnd){offset=this.endOffset;end=this.endContainer;if(end.nodeType==3){if(offset==0){this.setEndBefore(end)}else{offset=container.nodeValue.length){r["set"+c.replace(/(\w)/,function(a){return a.toUpperCase()})+"After"](container)}}}if(ignoreCollapsed||!this.collapsed){adjust(this,"start");adjust(this,"end")}return this},insertNode:function(node){var first=node,length=1;if(node.nodeType==11){first=node.firstChild;length=node.childNodes.length}this.trimBoundary(true);var start=this.startContainer,offset=this.startOffset;var nextNode=start.childNodes[offset];if(nextNode){start.insertBefore(node,nextNode)}else{start.appendChild(node)}if(first.parentNode===this.endContainer){this.endOffset=this.endOffset+length}return this.setStartBefore(first)},setCursor:function(toEnd,noFillData){return this.collapse(!toEnd).select(noFillData)},createBookmark:function(serialize,same){var endNode,startNode=this.document.createElement("span");startNode.style.cssText="display:none;line-height:0px;";startNode.appendChild(this.document.createTextNode(""));startNode.id="_baidu_bookmark_start_"+(same?"":guid++);if(!this.collapsed){endNode=startNode.cloneNode(true);endNode.id="_baidu_bookmark_end_"+(same?"":guid++)}this.insertNode(startNode);if(endNode){this.collapse().insertNode(endNode).setEndBefore(endNode)}this.setStartAfter(startNode);return{start:serialize?startNode.id:startNode,end:endNode?serialize?endNode.id:endNode:null,id:serialize}},moveToBookmark:function(bookmark){var start=bookmark.id?this.document.getElementById(bookmark.start):bookmark.start,end=bookmark.end&&bookmark.id?this.document.getElementById(bookmark.end):bookmark.end;this.setStartBefore(start);domUtils.remove(start);if(end){this.setEndBefore(end);domUtils.remove(end)}else{this.collapse(true)}return this},adjustmentBoundary:function(){if(!this.collapsed){while(!domUtils.isBody(this.startContainer)&&this.startOffset==this.startContainer[this.startContainer.nodeType==3?"nodeValue":"childNodes"].length&&this.startContainer[this.startContainer.nodeType==3?"nodeValue":"childNodes"].length){this.setStartAfter(this.startContainer)}while(!domUtils.isBody(this.endContainer)&&!this.endOffset&&this.endContainer[this.endContainer.nodeType==3?"nodeValue":"childNodes"].length){this.setEndBefore(this.endContainer)}}return this},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},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){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);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);try{nativeRange.select()}catch(e){}return this}:function(notInsertFillData){function checkOffset(rng){function check(node,offset,dir){if(node.nodeType==3&&node.nodeValue.length ');this.cloneRange().insertNode($span.get(0));var winScrollTop=$(window).scrollTop(),winHeight=$(window).height(),spanTop=$span.offset().top;if(spanTopwinScrollTop+winHeight){if(spanTop>winScrollTop+winHeight){window.scrollTo(0,spanTop-winHeight+$span.height())}else{window.scrollTo(0,winScrollTop-spanTop)}}$span.remove()},getOffset:function(){var bk=this.createBookmark();var offset=$(bk.start).css("display","inline-block").offset();this.moveToBookmark(bk);return offset}}})();(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{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}}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}function _getIERange(sel,txtRange){var ieRange;try{ieRange=sel.getNative(txtRange).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,body){var me=this;me.document=doc;me.body=body;if(browser.ie9below){$(body).on("beforedeactivate",function(){me._bakIERange=me.getIERange()}).on("activate",function(){try{var ieNativRng=_getIERange(me);if((!ieNativRng||!me.rangeInBody(ieNativRng))&&me._bakIERange){me._bakIERange.select()}}catch(ex){}me._bakIERange=null})}};Selection.prototype={hasNativeRange:function(){var rng;if(!browser.ie||browser.ie9above){var nativeSel=this.getNative();if(!nativeSel.rangeCount){return false}rng=nativeSel.getRangeAt(0)}else{rng=_getIERange(this)}return this.rangeInBody(rng)},getNative:function(txtRange){var doc=this.document;try{return!doc?null:browser.ie9below||txtRange?doc.selection:domUtils.getWindow(doc).getSelection()}catch(e){return null}},getIERange:function(txtRange){var ieRange=_getIERange(this,txtRange);if(!ieRange||!this.rangeInBody(ieRange,txtRange)){if(this._bakIERange){return this._bakIERange}}return ieRange},rangeInBody:function(rng,txtRange){var node=browser.ie9below||txtRange?rng.item?rng.item():rng.parentElement():rng.startContainer;return node===this.body||domUtils.inDoc(node,this.body)},cache:function(){this.clear();this._cachedRange=this.getRange();this._cachedStartElement=this.getStart();this._cachedStartElementPath=this.getStartElementPath()},getStartElementPath:function(){if(this._cachedStartElementPath){return this._cachedStartElementPath}var start=this.getStart();if(start){return domUtils.findParents(start,true,null,true)}return[]},clear:function(){this._cachedStartElementPath=this._cachedRange=this._cachedStartElement=null},isFocus:function(){return this.hasNativeRange()},getRange:function(){var me=this;function optimze(range){var child=me.body.firstChild,collapsed=range.collapsed;while(child&&child.firstChild){range.setStart(child,0);child=child.firstChild}if(!range.startContainer){range.setStart(me.body,0)}if(collapsed){range.collapse(true)}}if(me._cachedRange!=null){return this._cachedRange}var range=new dom.Range(me.document,me.body);if(browser.ie9below){var nativeRange=me.getIERange();if(nativeRange&&this.rangeInBody(nativeRange)){try{transformIERangeToRange(nativeRange,range)}catch(e){optimze(range)}}else{optimze(range)}}else{var sel=me.getNative();if(sel&&sel.rangeCount&&me.rangeInBody(sel.getRangeAt(0))){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{if(this._bakRange&&(this._bakRange.startContainer===this.body||domUtils.inDoc(this._bakRange.startContainer,this.body))){return this._bakRange}optimze(range)}}return this._bakRange=range},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){return this.document.body.firstChild}if(range.item){return range.item(0)}tmpRange=range.duplicate();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{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},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""}}})();(function(){var uid=0,_selectionChangeTimer;function setValue(form,editor){var textarea;if(editor.textarea){if(utils.isString(editor.textarea)){for(var i=0,ti,tis=domUtils.getElementsByTagName(form,"textarea");ti=tis[i++];){if(ti.id=="umeditor_textarea_"+editor.options.textarea){textarea=ti;break}}}else{textarea=editor.textarea}}if(!textarea){form.appendChild(textarea=domUtils.createElement(document,"textarea",{name:editor.options.textarea,id:"umeditor_textarea_"+editor.options.textarea,style:"display:none"}));editor.textarea=textarea}textarea.value=editor.hasContents()?editor.options.allHtmlEnabled?editor.getAllHtml():editor.getContent(null,null,true):""}function loadPlugins(me){for(var pi in UM.plugins){if(me.options.excludePlugins.indexOf(pi)==-1){UM.plugins[pi].call(me);me.plugins[pi]=1}}me.langIsReady=true;me.fireEvent("langReady")}function checkCurLang(I18N){for(var lang in I18N){return lang}}var Editor=UM.Editor=function(options){var me=this;me.uid=uid++;EventBase.call(me);me.commands={};me.options=utils.extend(utils.clone(options||{}),UMEDITOR_CONFIG,true);me.shortcutkeys={};me.inputRules=[];me.outputRules=[];me.setOpt({isShow:true,initialContent:"",initialStyle:"",autoClearinitialContent:false,textarea:"editorValue",focus:false,focusInEnd:true,autoClearEmptyNode:true,fullscreen:false,readonly:false,zIndex:999,enterTag:"p",lang:"zh-cn",langPath:me.options.UMEDITOR_HOME_URL+"lang/",theme:"default",themePath:me.options.UMEDITOR_HOME_URL+"themes/",allHtmlEnabled:false,autoSyncData:true,autoHeightEnabled:true,excludePlugins:""});me.plugins={};if(!utils.isEmptyObject(UM.I18N)){me.options.lang=checkCurLang(UM.I18N);loadPlugins(me)}else{utils.loadFile(document,{src:me.options.langPath+me.options.lang+"/"+me.options.lang+".js",tag:"script",type:"text/javascript",defer:"defer"},function(){loadPlugins(me)})}};Editor.prototype={ready:function(fn){var me=this;if(fn){me.isReady?fn.apply(me):me.addListener("ready",fn)}},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]||""},destroy:function(){var me=this;me.fireEvent("destroy");var container=me.container.parentNode;if(container===document.body){container=me.container}var textarea=me.textarea;if(!textarea){textarea=document.createElement("textarea");container.parentNode.insertBefore(textarea,container)}else{textarea.style.display=""}textarea.style.width=me.body.offsetWidth+"px";textarea.style.height=me.body.offsetHeight+"px";textarea.value=me.getContent();textarea.id=me.key;if(container.contains(textarea)){$(textarea).insertBefore(container)}container.innerHTML="";domUtils.remove(container);UM.clearCache(me.id);for(var p in me){if(me.hasOwnProperty(p)){delete this[p]}}},initialCont:function(holder){if(holder){holder.getAttribute("name")&&(this.options.textarea=holder.getAttribute("name"));if(holder&&/script|textarea/gi.test(holder.tagName)){var newDiv=document.createElement("div");holder.parentNode.insertBefore(newDiv,holder);this.options.initialContent=UM.htmlparser(holder.value||holder.innerHTML||this.options.initialContent).toHtml();holder.className&&(newDiv.className=holder.className);holder.style.cssText&&(newDiv.style.cssText=holder.style.cssText);if(/textarea/i.test(holder.tagName)){this.textarea=holder;this.textarea.style.display="none"}else{holder.parentNode.removeChild(holder);holder.id&&(newDiv.id=holder.id)}holder=newDiv;holder.innerHTML=""}return holder}else{return null}},render:function(container){var me=this,options=me.options,getStyleValue=function(attr){return parseInt($(container).css(attr))};if(utils.isString(container)){container=document.getElementById(container)}if(container){this.id=container.getAttribute("id");UM.setEditor(this);utils.cssRule("edui-style-body",me.options.initialStyle,document);container=this.initialCont(container);container.className+=" edui-body-container";if(options.initialFrameWidth){options.minFrameWidth=options.initialFrameWidth}else{options.minFrameWidth=options.initialFrameWidth=$(container).width()||UM.defaultWidth}if(options.initialFrameHeight){options.minFrameHeight=options.initialFrameHeight}else{options.initialFrameHeight=options.minFrameHeight=$(container).height()||UM.defaultHeight}container.style.width=/%$/.test(options.initialFrameWidth)?"100%":options.initialFrameWidth-getStyleValue("padding-left")-getStyleValue("padding-right")+"px";var height=/%$/.test(options.initialFrameHeight)?"100%":options.initialFrameHeight-getStyleValue("padding-top")-getStyleValue("padding-bottom");if(this.options.autoHeightEnabled){container.style.minHeight=height+"px";container.style.height="";if(browser.ie&&browser.version<=6){container.style.height=height;container.style.setExpression("height","this.scrollHeight <= "+height+' ? "'+height+'px" : "auto"')}}else{$(container).height(height)}container.style.zIndex=options.zIndex;this._setup(container)}},_setup:function(cont){var me=this,options=me.options;cont.contentEditable=true;document.body.spellcheck=false;me.document=document;me.window=document.defaultView||document.parentWindow;me.body=cont;me.$body=$(cont);me.selection=new dom.Selection(document,me.body);me._isEnabled=false;var geckoSel;if(browser.gecko&&(geckoSel=this.selection.getNative())){geckoSel.removeAllRanges()}this._initEvents();for(var form=cont.parentNode;form&&!domUtils.isBody(form);form=form.parentNode){if(form.tagName=="FORM"){me.form=form;if(me.options.autoSyncData){$(cont).on("blur",function(){setValue(form,me)})}else{$(form).on("submit",function(){setValue(this,me)})}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?"":" ")+"
"}if(options.focus){setTimeout(function(){me.focus(me.options.focusInEnd);!me.options.autoClearinitialContent&&me._selectionChange()},0)}if(!me.container){me.container=cont.parentNode}me._bindshortcutKeys();me.isReady=1;me.fireEvent("ready");options.onready&&options.onready.call(me);if(!browser.ie||browser.ie9above){$(me.body).on("blur focus",function(e){var nSel=me.selection.getNative();if(e.type=="blur"){if(nSel.rangeCount>0){me._bakRange=nSel.getRangeAt(0)}}else{try{me._bakRange&&nSel.addRange(me._bakRange)}catch(e){}me._bakRange=null}})}!options.isShow&&me.setHide();options.readonly&&me.setDisabled()},sync:function(formId){var me=this,form=formId?document.getElementById(formId):domUtils.findParent(me.body.parentNode,function(node){return node.tagName=="FORM"},true);form&&setValue(form,me)},setHeight:function(height,notSetHeight){!notSetHeight&&(this.options.initialFrameHeight=height);if(this.options.autoHeightEnabled){$(this.body).css({"min-height":height+"px"});if(browser.ie&&browser.version<=6&&this.container){this.container.style.height=height;this.container.style.setExpression("height","this.scrollHeight <= "+height+' ? "'+height+'px" : "auto"')}}else{$(this.body).height(height)}this.fireEvent("resize")},setWidth:function(width){this.$container&&this.$container.width(width);$(this.body).width(width-$(this.body).css("padding-left").replace("px","")*1-$(this.body).css("padding-right").replace("px","")*1);this.fireEvent("resize")},addshortcutkey:function(cmd,keys){var obj={};if(keys){obj[cmd]=keys}else{obj=cmd}utils.extend(this.shortcutkeys,obj)},_bindshortcutKeys:function(){var me=this,shortcutkeys=this.shortcutkeys;me.addListener("keydown",function(type,e){var keyCode=e.keyCode||e.which;for(var i in shortcutkeys){var tmp=shortcutkeys[i].split(",");for(var t=0,ti;ti=tmp[t++];){ti=ti.split(":");var key=ti[0],param=ti[1];if(/^(ctrl)(\+shift)?\+(\d+)$/.test(key.toLowerCase())||/^(\d+)$/.test(key)){if((RegExp.$1=="ctrl"?e.ctrlKey||e.metaKey:0)&&(RegExp.$2!=""?e[RegExp.$2.slice(1)+"Key"]:1)&&keyCode==RegExp.$3||keyCode==RegExp.$1){if(me.queryCommandState(i,param)!=-1)me.execCommand(i,param);domUtils.preventDefault(e)}}}}})},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=UM.htmlparser(me.body.innerHTML,ignoreBlank);me.filterOutputRule(root);me.fireEvent("aftergetcontent",root);return root.toHtml(formatter)},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)+""},getPlainTxt:function(){var reg=new RegExp(domUtils.fillChar,"g"),html=this.body.innerHTML.replace(/[\n\r]/g,"");html=html.replace(/<(p|div)[^>]*>( | )<\/\1>/gi,"\n").replace(/ /gi,"\n").replace(/<[^>/]+>/g,"").replace(/(\n)?<\/([^>]+)>/g,function(a,b,c){return dtd.$block[c]?"\n":b?b:""});return html.replace(reg,"").replace(/\u00a0/g," ").replace(/ /g," ")},getContentTxt:function(){var reg=new RegExp(domUtils.fillChar,"g");return this.body[browser.ie?"innerText":"textContent"].replace(reg,"").replace(/\u00a0/g," ")},setContent:function(html,isAppendTo,notFireSelectionchange){var me=this;me.fireEvent("beforesetcontent",html);var root=UM.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")}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?" ":" ")+"
"+this.body.innerHTML}else{var p=me.document.createElement("p");while(child){while(child&&(child.nodeType==3||child.nodeType==1&&dtd.p[child.tagName]&&!dtd.$cdata[child.tagName])){tmpNode=child.nextSibling;p.appendChild(child);child=tmpNode}if(p.firstChild){if(!child){me.body.appendChild(p);break}else{child.parentNode.insertBefore(p,child);p=me.document.createElement("p")}}child=child.nextSibling}}}me.fireEvent("aftersetcontent");me.fireEvent("contentchange");!notFireSelectionchange&&me._selectionChange();me._bakRange=me._bakIERange=me._bakNativeRange=null;var geckoSel;if(browser.gecko&&(geckoSel=this.selection.getNative())){geckoSel.removeAllRanges()}if(me.options.autoSyncData){me.form&&setValue(me.form,me)}},focus:function(toEnd){try{var me=this,rng=me.selection.getRange();if(toEnd){rng.setStartAtLast(me.body.lastChild).setCursor(false,true)}else{rng.select(true)}this.fireEvent("focus")}catch(e){}},blur:function(){var sel=this.selection.getNative();sel.empty?sel.empty():sel.removeAllRanges();this.fireEvent("blur")},isFocus:function(){if(this.fireEvent("isfocus")===true){return true}return this.selection.isFocus()},_initEvents:function(){var me=this,cont=me.body,_proxyDomEvent=function(){me._proxyDomEvent.apply(me,arguments)};$(cont).on("click contextmenu mousedown keydown keyup keypress mouseup mouseover mouseout selectstart",_proxyDomEvent).on("focus blur",_proxyDomEvent).on("mouseup keydown",function(evt){if(evt.type=="keydown"&&(evt.ctrlKey||evt.metaKey||evt.shiftKey||evt.altKey)){return}if(evt.button==2)return;me._selectionChange(250,evt)})},_proxyDomEvent:function(evt){return this.fireEvent(evt.type.replace(/^on/,""),evt)},_selectionChange:function(delay,evt){var me=this;var hackForMouseUp=false;var mouseX,mouseY;if(browser.ie&&browser.version<9&&evt&&evt.type=="mouseup"){var range=this.selection.getRange();if(!range.collapsed){hackForMouseUp=true;mouseX=evt.clientX;mouseY=evt.clientY}}clearTimeout(_selectionChangeTimer);_selectionChangeTimer=setTimeout(function(){if(!me.selection.getNative()){return}var ieRange;if(hackForMouseUp&&me.selection.getNative().type=="None"){ieRange=me.document.body.createTextRange();try{ieRange.moveToPoint(mouseX,mouseY)}catch(ex){ieRange=null}}var bakGetIERange;if(ieRange){bakGetIERange=me.selection.getIERange;me.selection.getIERange=function(){return ieRange}}me.selection.cache();if(bakGetIERange){me.selection.getIERange=bakGetIERange}if(me.selection._cachedRange&&me.selection._cachedStartElement){me.fireEvent("beforeselectionchange");me.fireEvent("selectionchange",!!evt);me.fireEvent("afterselectionchange");me.selection.clear()}},delay||50)},_callCmdFn:function(fnName,args){args=Array.prototype.slice.call(args,0);var cmdName=args.shift().toLowerCase(),cmd,cmdFn;cmd=this.commands[cmdName]||UM.commands[cmdName];cmdFn=cmd&&cmd[fnName];if((!cmd||!cmdFn)&&fnName=="queryCommandState"){return 0}else if(cmdFn){return cmdFn.apply(this,[cmdName].concat(args))}},execCommand:function(cmdName){if(!this.isFocus()){var bakRange=this.selection._bakRange;if(bakRange){bakRange.select()}else{this.focus(true)}}cmdName=cmdName.toLowerCase();var me=this,result,cmd=me.commands[cmdName]||UM.commands[cmdName];if(!cmd||!cmd.execCommand){return null}if(!cmd.notNeedUndo&&!me.__hasEnterExecCommand){me.__hasEnterExecCommand=true;if(me.queryCommandState.apply(me,arguments)!=-1){me.fireEvent("saveScene");me.fireEvent("beforeexeccommand",cmdName);result=this._callCmdFn("execCommand",arguments);!cmd.ignoreContentChange&&!me._ignoreContentChange&&me.fireEvent("contentchange");me.fireEvent("afterexeccommand",cmdName);me.fireEvent("saveScene")}me.__hasEnterExecCommand=false}else{result=this._callCmdFn("execCommand",arguments);!me.__hasEnterExecCommand&&!cmd.ignoreContentChange&&!me._ignoreContentChange&&me.fireEvent("contentchange")}!me.__hasEnterExecCommand&&!cmd.ignoreContentChange&&!me._ignoreContentChange&&me._selectionChange();return result},queryCommandState:function(cmdName){try{return this._callCmdFn("queryCommandState",arguments)}catch(e){return 0}},queryCommandValue:function(cmdName){try{return this._callCmdFn("queryCommandValue",arguments)}catch(e){return null}},hasContents:function(tags){if(tags){for(var i=0,ci;ci=tags[i++];){if(this.body.getElementsByTagName(ci).length>0){return true}}}if(!domUtils.isEmptyBlock(this.body)){return true}tags=["div"];for(i=0;ci=tags[i++];){var nodes=domUtils.getElementsByTagName(this.body,ci);for(var n=0,cn;cn=nodes[n++];){if(domUtils.isCustomeNode(cn)){return true}}}return false},reset:function(){this.fireEvent("reset")},isEnabled:function(){return this._isEnabled!=true},setEnabled:function(){var me=this,range;me.body.contentEditable=true;if(me.lastBk){range=me.selection.getRange();try{range.moveToBookmark(me.lastBk);delete me.lastBk}catch(e){range.setStartAtFirst(me.body).collapse(true)}range.select(true)}if(me.bkqueryCommandState){me.queryCommandState=me.bkqueryCommandState;delete me.bkqueryCommandState}if(me._bkproxyDomEvent){me._proxyDomEvent=me._bkproxyDomEvent;delete me._bkproxyDomEvent}me.fireEvent("setEnabled")},enable:function(){return this.setEnabled()},setDisabled:function(except,keepDomEvent){var me=this;me.body.contentEditable=false;me._except=except?utils.isArray(except)?except:[except]:[];if(!me.lastBk){me.lastBk=me.selection.getRange().createBookmark(true)}if(!me.bkqueryCommandState){me.bkqueryCommandState=me.queryCommandState;me.queryCommandState=function(type){if(utils.indexOf(me._except,type)!=-1){return me.bkqueryCommandState.apply(me,arguments)}return-1}}if(!keepDomEvent&&!me._bkproxyDomEvent){me._bkproxyDomEvent=me._proxyDomEvent;me._proxyDomEvent=function(){return false}}me.fireEvent("selectionchange");me.fireEvent("setDisabled",me._except)},disable:function(except){return this.setDisabled(except)},_setDefaultContent:function(){function clear(){var me=this;if(me.document.getElementById("initContent")){me.body.innerHTML=""+(ie?"":" ")+"
";me.removeListener("firstBeforeExecCommand focus",clear);setTimeout(function(){me.focus();me._selectionChange()},0)}}return function(cont){var me=this;me.body.innerHTML=''+cont+"
";me.addListener("firstBeforeExecCommand focus",clear)}}(),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)}setTimeout(function(){range.select(true)},100);me.container.style.display=""}},show:function(){return this.setShow()},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()},getLang:function(path){var lang=UM.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},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.body.getElementsByTagName(ci).length}}return count},addInputRule:function(rule,ignoreUndo){rule.ignoreUndo=ignoreUndo;this.inputRules.push(rule)},filterInputRule:function(root,isUndoLoad){for(var i=0,ci;ci=this.inputRules[i++];){if(isUndoLoad&&ci.ignoreUndo){continue}ci.call(this,root)}},addOutputRule:function(rule,ignoreUndo){rule.ignoreUndo=ignoreUndo;this.outputRules.push(rule)},filterOutputRule:function(root,isUndoLoad){for(var i=0,ci;ci=this.outputRules[i++];){if(isUndoLoad&&ci.ignoreUndo){continue}ci.call(this,root)}}};utils.inherits(Editor,EventBase)})();var filterWord=UM.filterWord=function(){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(/]*>[\s\S]*?.<\/v:shape>/gi,function(str){if(browser.opera){return""}try{if(/Bitmap/i.test(str)){return""}var width=str.match(/width:([ \d.]*p[tx])/i)[1],height=str.match(/height:([ \d.]*p[tx])/i)[1],src=str.match(/src=\s*"([^"]*)"/i)[1];return' '}catch(e){return""}}).replace(/<\/?div[^>]*>/g,"").replace(/v:\w+=(["']?)[^'"]+\1/g,"").replace(/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|xml|meta|link|style|\w+:\w+)(?=[\s\/>]))[^>]*>/gi,"").replace(/]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi,"
$1
").replace(/\s+(class|lang|align)\s*=\s*(['"]?)([\w-]+)\2/gi,function(str,name,marks,val){return name=="class"&&val=="MsoListParagraph"?str:""}).replace(/<(font|span)[^>]*>(\s*)<\/\1>/gi,function(a,b,c){return c.replace(/[\t\r\n ]+/g," ")}).replace(/(<[a-z][^>]*)\sstyle=(["'])([^\2]*?)\2/gi,function(str,tag,tmp,style){var n=[],s=style.replace(/^\s+|\s+$/,"").replace(/'/g,"'").replace(/"/gi,"'").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":case"mso-height":case"mso-width":case"mso-vertical-align-alt":if(!/]/.test(html)){return UM.htmlparser(html).children[0]}else{return new uNode({type:"element",children:[],tagName:html})}};uNode.createText=function(data,noTrans){return new UM.uNode({type:"text",data:noTrans?data:utils.unhtml(data||"")})};function nodeToHtml(node,arr,formatter,current){switch(node.type){case"root":for(var i=0,ci;ci=node.children[i++];){if(formatter&&ci.type=="element"&&!dtd.$inlineWithA[ci.tagName]&&i>1){insertLine(arr,current,true);insertIndent(arr,current)}nodeToHtml(ci,arr,formatter,current)}break;case"text":isText(node,arr);break;case"element":isElement(node,arr,formatter,current);break;case"comment":isComment(node,arr,formatter)}return arr}function isText(node,arr){if(node.parentNode.tagName=="pre"){arr.push(node.data)}else{arr.push(notTransTagName[node.parentNode.tagName]?utils.html(node.data):node.data.replace(/[ ]{2}/g," "))}}function isElement(node,arr,formatter,current){var attrhtml="";if(node.attrs){attrhtml=[];var attrs=node.attrs;for(var a in attrs){attrhtml.push(a+(attrs[a]!==undefined?'="'+(notTransAttrs[a]?utils.html(attrs[a]).replace(/["]/g,function(a){return"""}):utils.unhtml(attrs[a]))+'"':""))}attrhtml=attrhtml.join(" ")}arr.push("<"+node.tagName+(attrhtml?" "+attrhtml:"")+(dtd.$empty[node.tagName]?"/":"")+">");if(formatter&&!dtd.$inlineWithA[node.tagName]&&node.tagName!="pre"){if(node.children&&node.children.length){current=insertLine(arr,current,true);insertIndent(arr,current)}}if(node.children&&node.children.length){for(var i=0,ci;ci=node.children[i++];){if(formatter&&ci.type=="element"&&!dtd.$inlineWithA[ci.tagName]&&i>1){insertLine(arr,current);insertIndent(arr,current)}nodeToHtml(ci,arr,formatter,current)}}if(!dtd.$empty[node.tagName]){if(formatter&&!dtd.$inlineWithA[node.tagName]&&node.tagName!="pre"){if(node.children&&node.children.length){current=insertLine(arr,current);insertIndent(arr,current)}}arr.push(""+node.tagName+">")}}function isComment(node,arr){arr.push("\x3c!--"+node.data+"--\x3e")}function getNodeById(root,id){var node;if(root.type=="element"&&root.getAttr("id")==id){return root}if(root.children&&root.children.length){for(var i=0,ci;ci=root.children[i++];){if(node=getNodeById(ci,id)){return node}}}}function getNodesByTagName(node,tagName,arr){if(node.type=="element"&&node.tagName==tagName){arr.push(node)}if(node.children&&node.children.length){for(var i=0,ci;ci=node.children[i++];){getNodesByTagName(ci,tagName,arr)}}}function nodeTraversal(root,fn){if(root.children&&root.children.length){for(var i=0,ci;ci=root.children[i];){nodeTraversal(ci,fn);if(ci.parentNode){if(ci.children&&ci.children.length){fn(ci)}if(ci.parentNode)i++}}}else{fn(root)}}uNode.prototype={toHtml:function(formatter){var arr=[];nodeToHtml(this,arr,formatter,0);return arr.join("")},innerHTML:function(htmlstr){if(this.type!="element"||dtd.$empty[this.tagName]){return this}if(utils.isString(htmlstr)){if(this.children){for(var i=0,ci;ci=this.children[i++];){ci.parentNode=null}}this.children=[];var tmpRoot=UM.htmlparser(htmlstr);for(var i=0,ci;ci=tmpRoot.children[i++];){this.children.push(ci);ci.parentNode=this}return this}else{var tmpRoot=new UM.uNode({type:"root",children:this.children});return tmpRoot.toHtml()}},innerText:function(textStr,noTrans){if(this.type!="element"||dtd.$empty[this.tagName]){return this}if(textStr){if(this.children){for(var i=0,ci;ci=this.children[i++];){ci.parentNode=null}}this.children=[];this.appendChild(uNode.createText(textStr,noTrans));return this}else{return this.toHtml().replace(/<[^>]+>/g,"")}},getData:function(){if(this.type=="element")return"";return this.data},firstChild:function(){return this.children?this.children[0]:null},lastChild:function(){return this.children?this.children[this.children.length-1]:null},previousSibling:function(){var parent=this.parentNode;for(var i=0,ci;ci=parent.children[i];i++){if(ci===this){return i==0?null:parent.children[i-1]}}},nextSibling:function(){var parent=this.parentNode;for(var i=0,ci;ci=parent.children[i++];){if(ci===this){return parent.children[i]}}},replaceChild:function(target,source){if(this.children){if(target.parentNode){target.parentNode.removeChild(target)}for(var i=0,ci;ci=this.children[i];i++){if(ci===source){this.children.splice(i,1,target);source.parentNode=null;target.parentNode=this;return target}}}},appendChild:function(node){if(this.type=="root"||this.type=="element"&&!dtd.$empty[this.tagName]){if(!this.children){this.children=[]}if(node.parentNode){node.parentNode.removeChild(node)}for(var i=0,ci;ci=this.children[i];i++){if(ci===node){this.children.splice(i,1);break}}this.children.push(node);node.parentNode=this;return node}},insertBefore:function(target,source){if(this.children){if(target.parentNode){target.parentNode.removeChild(target)}for(var i=0,ci;ci=this.children[i];i++){if(ci===source){this.children.splice(i,0,target);target.parentNode=this;return target}}}},insertAfter:function(target,source){if(this.children){if(target.parentNode){target.parentNode.removeChild(target)}for(var i=0,ci;ci=this.children[i];i++){if(ci===source){this.children.splice(i+1,0,target);target.parentNode=this;return target}}}},removeChild:function(node,keepChildren){if(this.children){for(var i=0,ci;ci=this.children[i];i++){if(ci===node){this.children.splice(i,1);ci.parentNode=null;if(keepChildren&&ci.children&&ci.children.length){for(var j=0,cj;cj=ci.children[j];j++){this.children.splice(i+j,0,cj);cj.parentNode=this}}return ci}}}},getAttr:function(attrName){return this.attrs&&this.attrs[attrName.toLowerCase()]},setAttr:function(attrName,attrVal){if(!attrName){delete this.attrs;return}if(!this.attrs){this.attrs={}}if(utils.isObject(attrName)){for(var a in attrName){if(!attrName[a]){delete this.attrs[a]}else{this.attrs[a.toLowerCase()]=attrName[a]}}}else{if(!attrVal){delete this.attrs[attrName]}else{this.attrs[attrName.toLowerCase()]=attrVal}}},hasAttr:function(attrName){var attrVal=this.getAttr(attrName);return attrVal!==null&&attrVal!==undefined},getIndex:function(){var parent=this.parentNode;for(var i=0,ci;ci=parent.children[i];i++){if(ci===this){return i}}return-1},getNodeById:function(id){var node;if(this.children&&this.children.length){for(var i=0,ci;ci=this.children[i++];){if(node=getNodeById(ci,id)){return node}}}},getNodesByTagName:function(tagNames){tagNames=utils.trim(tagNames).replace(/[ ]{2,}/g," ").split(" ");var arr=[],me=this;utils.each(tagNames,function(tagName){if(me.children&&me.children.length){for(var i=0,ci;ci=me.children[i++];){getNodesByTagName(ci,tagName,arr)}}});return arr},getStyle:function(name){var cssStyle=this.getAttr("style");if(!cssStyle){return""}var reg=new RegExp("(^|;)\\s*"+name+":([^;]+)","i");var match=cssStyle.match(reg);if(match&&match[0]){return match[2]}return""},setStyle:function(name,val){function exec(name,val){var reg=new RegExp("(^|;)\\s*"+name+":([^;]+;?)","gi");cssStyle=cssStyle.replace(reg,"$1");if(val){cssStyle=name+":"+utils.unhtml(val)+";"+cssStyle}}var cssStyle=this.getAttr("style");if(!cssStyle){cssStyle=""}if(utils.isObject(name)){for(var a in name){exec(a,name[a])}}else{exec(name,val)}this.setAttr("style",utils.trim(cssStyle))},hasClass:function(className){if(this.hasAttr("class")){var classNames=this.getAttr("class").split(/\s+/),hasClass=false;$.each(classNames,function(key,item){if(item===className){hasClass=true}});return hasClass}else{return false}},addClass:function(className){var classes=null,hasClass=false;if(this.hasAttr("class")){classes=this.getAttr("class");classes=classes.split(/\s+/);classes.forEach(function(item){if(item===className){hasClass=true;return}});!hasClass&&classes.push(className);this.setAttr("class",classes.join(" "))}else{this.setAttr("class",className)}},removeClass:function(className){if(this.hasAttr("class")){var cl=this.getAttr("class");cl=cl.replace(new RegExp("\\b"+className+"\\b","g"),"");this.setAttr("class",utils.trim(cl).replace(/[ ]{2,}/g," "))}},traversal:function(fn){if(this.children&&this.children.length){nodeTraversal(this,fn)}return this}}})();var htmlparser=UM.htmlparser=function(htmlstr,ignoreBlank){var re_tag=/<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\s\/>]+)\s*((?:(?:"[^"]*")|(?:'[^']*')|[^"'<>])*)\/?>))/g,re_attr=/([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g;var allowEmptyTags={b:1,code:1,i:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,span:1,sub:1,img:1,sup:1,font:1,big:1,small:1,iframe:1,a:1,br:1,pre:1};htmlstr=htmlstr.replace(new RegExp(domUtils.fillChar,"g"),"");if(!ignoreBlank){htmlstr=htmlstr.replace(new RegExp("[\\r\\t\\n"+(ignoreBlank?"":" ")+"]*?(\\w+)\\s*(?:[^>]*)>[\\r\\t\\n"+(ignoreBlank?"":" ")+"]*","g"),function(a,b){if(b&&allowEmptyTags[b.toLowerCase()]){return a.replace(/(^[\n\r]+)|([\n\r]+$)/g,"")}return a.replace(new RegExp("^[\\r\\n"+(ignoreBlank?"":" ")+"]+"),"").replace(new RegExp("[\\r\\n"+(ignoreBlank?"":" ")+"]+$"),"")})}var notTransAttrs={href:1,src:1};var uNode=UM.uNode,needParentNode={td:"tr",tr:["tbody","thead","tfoot"],tbody:"table",th:"tr",thead:"table",tfoot:"table",caption:"table",li:["ul","ol"],dt:"dl",dd:"dl",option:"select"},needChild={ol:"li",ul:"li"};function text(parent,data){if(needChild[parent.tagName]){var tmpNode=uNode.createElement(needChild[parent.tagName]);parent.appendChild(tmpNode);tmpNode.appendChild(uNode.createText(data));parent=tmpNode}else{parent.appendChild(uNode.createText(data))}}function element(parent,tagName,htmlattr){var needParentTag;if(needParentTag=needParentNode[tagName]){var tmpParent=parent,hasParent;while(tmpParent.type!="root"){if(utils.isArray(needParentTag)?utils.indexOf(needParentTag,tmpParent.tagName)!=-1:needParentTag==tmpParent.tagName){parent=tmpParent;hasParent=true;break}tmpParent=tmpParent.parentNode}if(!hasParent){parent=element(parent,utils.isArray(needParentTag)?needParentTag[0]:needParentTag)}}var elm=new uNode({parentNode:parent,type:"element",tagName:tagName.toLowerCase(),children:dtd.$empty[tagName]?null:[]});if(htmlattr){var attrs={},match;while(match=re_attr.exec(htmlattr)){attrs[match[1].toLowerCase()]=notTransAttrs[match[1].toLowerCase()]?match[2]||match[3]||match[4]:utils.unhtml(match[2]||match[3]||match[4])}elm.attrs=attrs}parent.children.push(elm);return dtd.$empty[tagName]?parent:elm}function comment(parent,data){parent.children.push(new uNode({type:"comment",data:data,parentNode:parent}))}var match,currentIndex=0,nextIndex=0;var root=new uNode({type:"root",children:[]});var currentParent=root;while(match=re_tag.exec(htmlstr)){currentIndex=match.index;try{if(currentIndex>nextIndex){text(currentParent,htmlstr.slice(nextIndex,currentIndex))}if(match[3]){if(dtd.$cdata[currentParent.tagName]){text(currentParent,match[0])}else{currentParent=element(currentParent,match[3].toLowerCase(),match[4])}}else if(match[1]){if(currentParent.type!="root"){if(dtd.$cdata[currentParent.tagName]&&!dtd.$cdata[match[1]]){text(currentParent,match[0])}else{var tmpParent=currentParent;while(currentParent.type=="element"&¤tParent.tagName!=match[1].toLowerCase()){currentParent=currentParent.parentNode;if(currentParent.type=="root"){currentParent=tmpParent;throw"break"}}currentParent=currentParent.parentNode}}}else if(match[2]){comment(currentParent,match[2])}}catch(e){}nextIndex=re_tag.lastIndex}if(nextIndex"+(browser.ie?"":" ")+"";range.setStart(me.body.firstChild,0).collapse(true)}}}!range.collapsed&&range.deleteContents();if(range.startContainer.nodeType==1){var child=range.startContainer.childNodes[range.startOffset],pre;if(child&&domUtils.isBlockElm(child)&&(pre=child.previousSibling)&&domUtils.isBlockElm(pre)){range.setEnd(pre,pre.childNodes.length).collapse();while(child.firstChild){pre.appendChild(child.firstChild)}domUtils.remove(child)}}}var child,parent,pre,tmp,hadBreak=0,nextNode;if(range.inFillChar()){child=range.startContainer;if(domUtils.isFillChar(child)){range.setStartBefore(child).collapse(true);domUtils.remove(child)}else if(domUtils.isFillChar(child,true)){child.nodeValue=child.nodeValue.replace(fillCharReg,"");range.startOffset--;range.collapsed&&range.collapse(true)}}while(child=div.firstChild){if(hadBreak){var p=me.document.createElement("p");while(child&&(child.nodeType==3||!dtd.$block[child.tagName])){nextNode=child.nextSibling;p.appendChild(child);child=nextNode}if(p.firstChild){child=p}}range.insertNode(child);nextNode=child.nextSibling;if(!hadBreak&&child.nodeType==domUtils.NODE_ELEMENT&&domUtils.isBlockElm(child)){parent=domUtils.findParent(child,function(node){return domUtils.isBlockElm(node)});if(parent&&parent.tagName.toLowerCase()!="body"&&!(dtd[parent.tagName][child.nodeName]&&child.parentNode===parent)){if(!dtd[parent.tagName][child.nodeName]){pre=parent}else{tmp=child.parentNode;while(tmp!==parent){pre=tmp;tmp=tmp.parentNode}}domUtils.breakParent(child,pre||tmp);var pre=child.previousSibling;domUtils.trimWhiteTextNode(pre);if(!pre.childNodes.length){domUtils.remove(pre)}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)}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)}}}try{if(browser.ie9below&&range.startContainer.nodeType==1&&!range.startContainer.childNodes[range.startOffset]){var start=range.startContainer,pre=start.childNodes[range.startOffset-1];if(pre&&pre.nodeType==1&&dtd.$empty[pre.tagName]){var txt=this.document.createTextNode(domUtils.fillChar);range.insertNode(txt).setStart(txt,0).collapse(true)}}setTimeout(function(){range.select(true)})}catch(e){}setTimeout(function(){range=me.selection.getRange();range.scrollIntoView();me.fireEvent("afterinserthtml")},200)}};UM.commands["insertimage"]={execCommand:function(cmd,opt){opt=utils.isArray(opt)?opt:[opt];if(!opt.length){return}var me=this;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(""),true)}};UM.plugins["justify"]=function(){var me=this;$.each("justifyleft justifyright justifycenter justifyfull".split(" "),function(i,cmdName){me.commands[cmdName]={execCommand:function(cmdName){return this.document.execCommand(cmdName)},queryCommandValue:function(cmdName){var val=this.document.queryCommandValue(cmdName);return val===true||val==="true"?cmdName.replace(/justify/,""):""},queryCommandState:function(cmdName){return this.document.queryCommandState(cmdName)?1:0}}})};UM.plugins["font"]=function(){var me=this,fonts={forecolor:"forecolor",backcolor:"backcolor",fontsize:"fontsize",fontfamily:"fontname"},cmdNameToStyle={forecolor:"color",backcolor:"background-color",fontsize:"font-size",fontfamily:"font-family"},cmdNameToAttr={forecolor:"color",fontsize:"size",fontfamily:"face"};me.setOpt({fontfamily:[{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"},{name:"sans-serif",val:"sans-serif"}],fontsize:[10,12,16,18,24,32,48]});me.addOutputRule(function(root){utils.each(root.getNodesByTagName("font"),function(node){if(node.tagName=="font"){var cssStyle=[];for(var p in node.attrs){switch(p){case"size":var val=node.attrs[p];$.each({10:"1",12:"2",16:"3",18:"4",24:"5",32:"6",48:"7"},function(k,v){if(v==val){val=k;return false}});cssStyle.push("font-size:"+val+"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(";")}}node.tagName="span";if(node.parentNode.tagName=="span"&&node.parentNode.children.length==1){$.each(node.attrs,function(k,v){node.parentNode.attrs[k]=k=="style"?node.parentNode.attrs[k]+v:v});node.parentNode.removeChild(node,true)}})});for(var p in fonts){(function(cmd){me.commands[cmd]={execCommand:function(cmdName,value){if(value=="transparent"){return}var rng=this.selection.getRange();if(rng.collapsed){var span=$(" ").css(cmdNameToStyle[cmdName],value)[0];rng.insertNode(span).setStart(span,0).setCursor()}else{if(cmdName=="fontsize"){value={10:"1",12:"2",16:"3",18:"4",24:"5",32:"6",48:"7"}[(value+"").replace(/px/,"")]}this.document.execCommand(fonts[cmdName],false,value);if(browser.gecko){$.each(this.$body.find("a"),function(i,a){var parent=a.parentNode;if(parent.lastChild===parent.firstChild&&/FONT|SPAN/.test(parent.tagName)){var cloneNode=parent.cloneNode(false);cloneNode.innerHTML=a.innerHTML;$(a).html("").append(cloneNode).insertBefore(parent);$(parent).remove()}})}if(!browser.ie){var nativeRange=this.selection.getNative().getRangeAt(0);var common=nativeRange.commonAncestorContainer;var rng=this.selection.getRange(),bk=rng.createBookmark(true);$(common).find("a").each(function(i,n){var parent=n.parentNode;if(parent.nodeName=="FONT"){var font=parent.cloneNode(false);font.innerHTML=n.innerHTML;$(n).html("").append(font)}});rng.moveToBookmark(bk).select()}return true}},queryCommandValue:function(cmdName){var start=me.selection.getStart();var val=$(start).css(cmdNameToStyle[cmdName]);if(val===undefined){val=$(start).attr(cmdNameToAttr[cmdName])}return val?utils.fixColor(cmdName,val).replace(/px/,""):""},queryCommandState:function(cmdName){return this.queryCommandValue(cmdName)}}})(p)}};UM.plugins["link"]=function(){var me=this;me.setOpt("autourldetectinie",false);if(browser.ie&&this.options.autourldetectinie===false){this.addListener("keyup",function(cmd,evt){var me=this,keyCode=evt.keyCode;if(keyCode==13||keyCode==32){var rng=me.selection.getRange();var start=rng.startContainer;if(keyCode==13){if(start.nodeName=="P"){var pre=start.previousSibling;if(pre&&pre.nodeType==1){var pre=pre.lastChild;if(pre&&pre.nodeName=="A"&&!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)}}}}})}this.addOutputRule(function(root){$.each(root.getNodesByTagName("a"),function(i,a){var _href=a.getAttr("_href");if(!/^(ftp|https?|\/|file)/.test(_href)){_href="http://"+_href}a.setAttr("href",_href);a.setAttr("_href");if(a.getAttr("title")==""){a.setAttr("title")}})});this.addInputRule(function(root){$.each(root.getNodesByTagName("a"),function(i,a){a.setAttr("_href",a.getAttr("href"))})});me.commands["link"]={execCommand:function(cmdName,opt){var me=this;var rng=me.selection.getRange();opt._href&&(opt._href=utils.unhtml(opt._href,/[<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g));opt.href&&(opt.href=utils.unhtml(opt.href,/[<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g));if(rng.collapsed){var start=rng.startContainer;if(start=domUtils.findParentByTagName(start,"a",true)){$(start).attr(opt);rng.selectNode(start).select()}else{rng.insertNode($(""+opt.href+" ").attr(opt)[0]).select()}}else{me.document.execCommand("createlink",false,"_umeditor_link");utils.each(domUtils.getElementsByTagName(me.body,"a",function(n){return n.getAttribute("href")=="_umeditor_link"}),function(l){if($(l).text()=="_umeditor_link"){$(l).text(opt.href)}domUtils.setAttributes(l,opt);rng.selectNode(l).select()})}},queryCommandState:function(){return this.queryCommandValue("link")?1:0},queryCommandValue:function(){var path=this.selection.getStartElementPath();var result;$.each(path,function(i,n){if(n.nodeName=="A"){result=n;return false}});return result}};me.commands["unlink"]={execCommand:function(){this.document.execCommand("unlink")}}};UM.commands["print"]={execCommand:function(){var me=this,id="editor_print_"+ +new Date;$('').attr("id",id).css({width:"0px",height:"0px",overflow:"hidden",float:"left",position:"absolute",top:"-10000px",left:"-10000px"}).appendTo(me.$container.find(".edui-dialog-container"));var w=window.open("",id,""),d=w.document;d.open();d.write(""+this.getContent(null,null,true)+"
diff --git a/application/admin/view/cms/archives/recyclebin.html b/application/admin/view/cms/archives/recyclebin.html
new file mode 100644
index 0000000000000000000000000000000000000000..ab39d45a1b57e667bbb479f9f50be5eb5f8067c1
--- /dev/null
+++ b/application/admin/view/cms/archives/recyclebin.html
@@ -0,0 +1,23 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/cms/block/add.html b/application/admin/view/cms/block/add.html
new file mode 100644
index 0000000000000000000000000000000000000000..c56d17293d95a4cf783a13a8a2eeac04541c7d7c
--- /dev/null
+++ b/application/admin/view/cms/block/add.html
@@ -0,0 +1,66 @@
+
diff --git a/application/admin/view/cms/block/edit.html b/application/admin/view/cms/block/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..ac4196b29c6e62f0d42ed0f804ca3260f12d08e8
--- /dev/null
+++ b/application/admin/view/cms/block/edit.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/block/index.html b/application/admin/view/cms/block/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..2206b204f6cb8dad66fc34ed01f6b14b5bdf8da4
--- /dev/null
+++ b/application/admin/view/cms/block/index.html
@@ -0,0 +1,28 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/cms/channel/add.html b/application/admin/view/cms/channel/add.html
new file mode 100644
index 0000000000000000000000000000000000000000..4d1bfaa38a66ca321543edf847653936199f31b2
--- /dev/null
+++ b/application/admin/view/cms/channel/add.html
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/channel/edit.html b/application/admin/view/cms/channel/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..73abf8989ec951892cab611139747c15c55dd160
--- /dev/null
+++ b/application/admin/view/cms/channel/edit.html
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/channel/index.html b/application/admin/view/cms/channel/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..1466c35e5f95ccfb093bd7b973216dcdf6874e8d
--- /dev/null
+++ b/application/admin/view/cms/channel/index.html
@@ -0,0 +1,28 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/cms/comment/add.html b/application/admin/view/cms/comment/add.html
new file mode 100644
index 0000000000000000000000000000000000000000..9a7118b0c808ab86c2940b4598fd23a1f693b737
--- /dev/null
+++ b/application/admin/view/cms/comment/add.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/comment/edit.html b/application/admin/view/cms/comment/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..3f12aad98b95d475fa7a950268577d9da554194f
--- /dev/null
+++ b/application/admin/view/cms/comment/edit.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/comment/index.html b/application/admin/view/cms/comment/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..e33e5f01ee5fcfaf422857982a487c84105454c5
--- /dev/null
+++ b/application/admin/view/cms/comment/index.html
@@ -0,0 +1,32 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/cms/fields/add.html b/application/admin/view/cms/fields/add.html
new file mode 100644
index 0000000000000000000000000000000000000000..fde627395825dc4341e0ce3d87dc8ed69e52b8a3
--- /dev/null
+++ b/application/admin/view/cms/fields/add.html
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/fields/edit.html b/application/admin/view/cms/fields/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..de46ee5e67afe2a2aa75742764ca86c6d78d27c2
--- /dev/null
+++ b/application/admin/view/cms/fields/edit.html
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/fields/index.html b/application/admin/view/cms/fields/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..d042f87a17c2b7316b301fed5a58ce41577c0a78
--- /dev/null
+++ b/application/admin/view/cms/fields/index.html
@@ -0,0 +1,28 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/cms/modelx/add.html b/application/admin/view/cms/modelx/add.html
new file mode 100644
index 0000000000000000000000000000000000000000..33c1c82b3d0dce6b9aaa4151132af01cfc3929cb
--- /dev/null
+++ b/application/admin/view/cms/modelx/add.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/modelx/edit.html b/application/admin/view/cms/modelx/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..3f53885054dc6def6fffd7b4ca6522b7fad7eb84
--- /dev/null
+++ b/application/admin/view/cms/modelx/edit.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/modelx/index.html b/application/admin/view/cms/modelx/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..543991629fae405a0bd8f9b6e2b238f68e9bc5dd
--- /dev/null
+++ b/application/admin/view/cms/modelx/index.html
@@ -0,0 +1,24 @@
+
+ {:build_heading()}
+
+
+
+
+
+
+ {:build_toolbar('refresh,add,edit,del')}
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/modelx/tpl.html b/application/admin/view/cms/modelx/tpl.html
new file mode 100644
index 0000000000000000000000000000000000000000..7b49a6b46083cee3b9e151feb9ad33ddacb94237
--- /dev/null
+++ b/application/admin/view/cms/modelx/tpl.html
@@ -0,0 +1,66 @@
+
+
+
\ No newline at end of file
diff --git a/application/admin/view/cms/page/add.html b/application/admin/view/cms/page/add.html
new file mode 100644
index 0000000000000000000000000000000000000000..48adf679a207ff5381d9f2574bac06ac59961685
--- /dev/null
+++ b/application/admin/view/cms/page/add.html
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/page/edit.html b/application/admin/view/cms/page/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..63fd1ed72a41201279cc2e85f21d1344d80b9f16
--- /dev/null
+++ b/application/admin/view/cms/page/edit.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/page/index.html b/application/admin/view/cms/page/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..c968a2213a9e14b9df01e3561186835b19134cba
--- /dev/null
+++ b/application/admin/view/cms/page/index.html
@@ -0,0 +1,28 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/cms/tags/add.html b/application/admin/view/cms/tags/add.html
new file mode 100644
index 0000000000000000000000000000000000000000..5b6a2fac1c8c6ca820c1c0b298a1df11b3ec1380
--- /dev/null
+++ b/application/admin/view/cms/tags/add.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/tags/edit.html b/application/admin/view/cms/tags/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..97ff20cf6a2dab879145e80797efec6540017f70
--- /dev/null
+++ b/application/admin/view/cms/tags/edit.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
diff --git a/application/admin/view/cms/tags/index.html b/application/admin/view/cms/tags/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..a0379d73a704555938c81261fa16db7a95dbe27b
--- /dev/null
+++ b/application/admin/view/cms/tags/index.html
@@ -0,0 +1,21 @@
+
+ {:build_heading()}
+
+
+
+
+
+
+ {:build_toolbar('refresh,delete')}
+
+
+
+
+
+
+
+
diff --git a/application/extra/addons.php b/application/extra/addons.php
index e74b2f9ccd6ca2aa4bc6f14d2127386ed8b24782..39f88aa8498424330c000ca8b2dedb178ab0a2b1 100644
--- a/application/extra/addons.php
+++ b/application/extra/addons.php
@@ -4,8 +4,21 @@ return array (
'autoload' => false,
'hooks' =>
array (
+ 'addon_after_upgrade' =>
+ array (
+ 0 => 'cms',
+ ),
),
'route' =>
array (
+ '/cms$' => 'cms/index/index',
+ '/cms/c/[:diyname]' => 'cms/channel/index',
+ '/cms/t/[:name]' => 'cms/tags/index',
+ '/cms/a/[:diyname]' => 'cms/archives/index',
+ '/cms/p/[:diyname]' => 'cms/page/index',
+ '/cms/s' => 'cms/search/index',
+ '/third$' => 'third/index/index',
+ '/third/connect/[:platform]' => 'third/index/connect',
+ '/third/callback/[:platform]' => 'third/index/callback',
),
);
\ No newline at end of file
diff --git a/public/assets/js/addons.js b/public/assets/js/addons.js
index d2c1d20a916e5c3e1b297ec9df356442c5e33b53..ba925d030220a9782d07980b8e8af6201f05fba5 100644
--- a/public/assets/js/addons.js
+++ b/public/assets/js/addons.js
@@ -1,3 +1,113 @@
define([], function () {
-
+ window.UMEDITOR_HOME_URL = Config.__CDN__ + "/assets/addons/umeditor/";
+require.config({
+ paths: {
+ 'umeditor': '../addons/umeditor/umeditor.min',
+ 'umeditor.config': '../addons/umeditor/umeditor.config',
+ 'umeditor.lang': '../addons/umeditor/lang/zh-cn/zh-cn',
+ },
+ shim: {
+ 'umeditor': {
+ deps: [
+ 'umeditor.config',
+ 'css!../addons/umeditor/themes/default/css/umeditor.css'
+ ],
+ exports: 'UM',
+ },
+ 'umeditor.lang': ['umeditor']
+ }
+});
+
+//修改上传的接口调用
+require(['upload', 'umeditor', 'umeditor.lang'], function (Upload, UME, undefined) {
+ //监听上传文本框的事件
+ $(document).on("edui.file.change", ".edui-image-file", function (e, up, me, input, callback) {
+ for (var i = 0; i < this.files.length; i++) {
+ Upload.api.send(this.files[i], function (data) {
+ var url = data.url;
+ me.uploadComplete(JSON.stringify({url: url, state: "SUCCESS"}));
+ });
+ }
+ up.updateInput(input);
+ me.toggleMask("Loading....");
+ callback && callback();
+ });
+ //重写编辑器加载
+ UME.plugins['autoupload'] = function () {
+ var me = this;
+ me.setOpt('pasteImageEnabled', true);
+ me.setOpt('dropFileEnabled', true);
+ var sendAndInsertImage = function (file, editor) {
+ try {
+ Upload.api.send(file, function (data) {
+ var url = data.url;
+ editor.execCommand('insertimage', {
+ src: url,
+ _src: url
+ });
+ });
+ } catch (er) {
+ }
+ };
+
+ function getPasteImage(e) {
+ return e.clipboardData && e.clipboardData.items && e.clipboardData.items.length == 1 && /^image\//.test(e.clipboardData.items[0].type) ? e.clipboardData.items : null;
+ }
+
+ function getDropImage(e) {
+ return e.dataTransfer && e.dataTransfer.files ? e.dataTransfer.files : null;
+ }
+
+ me.addListener('ready', function () {
+ if (window.FormData && window.FileReader) {
+ var autoUploadHandler = function (e) {
+ var hasImg = false,
+ items;
+ //获取粘贴板文件列表或者拖放文件列表
+ items = e.type == 'paste' ? getPasteImage(e.originalEvent) : getDropImage(e.originalEvent);
+ if (items) {
+ var len = items.length,
+ file;
+ while (len--) {
+ file = items[len];
+ if (file.getAsFile)
+ file = file.getAsFile();
+ if (file && file.size > 0 && /image\/\w+/i.test(file.type)) {
+ sendAndInsertImage(file, me);
+ hasImg = true;
+ }
+ }
+ if (hasImg)
+ return false;
+ }
+
+ };
+ me.getOpt('pasteImageEnabled') && me.$body.on('paste', autoUploadHandler);
+ me.getOpt('dropFileEnabled') && me.$body.on('drop', autoUploadHandler);
+
+ //取消拖放图片时出现的文字光标位置提示
+ me.$body.on('dragover', function (e) {
+ if (e.originalEvent.dataTransfer.types[0] == 'Files') {
+ return false;
+ }
+ });
+ }
+ });
+
+ };
+ $(".editor").each(function () {
+ var id = $(this).attr("id");
+ $(this).removeClass('form-control');
+ UME.list[id] = UME.getEditor(id, {
+ serverUrl: Fast.api.fixurl('/addons/umeditor/api/'),
+ initialFrameWidth: '100%',
+ zIndex: 90,
+ xssFilterRules: false,
+ outputXssFilter: false,
+ inputXssFilter: false,
+ imageUrl: '',
+ imagePath: Config.upload.cdnurl
+ });
+ });
+});
});
\ No newline at end of file
diff --git a/public/assets/js/backend/cms/archives.js b/public/assets/js/backend/cms/archives.js
new file mode 100644
index 0000000000000000000000000000000000000000..845b86705f70366955ce54227aae21a2c3149a3d
--- /dev/null
+++ b/public/assets/js/backend/cms/archives.js
@@ -0,0 +1,411 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function ($, undefined, Backend, Table, Form, Template) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'cms/archives/index',
+ add_url: 'cms/archives/add',
+ edit_url: 'cms/archives/edit',
+ del_url: 'cms/archives/del',
+ multi_url: 'cms/archives/multi',
+ dragsort_url: '',
+ table: 'archives',
+ }
+ });
+
+ var table = $("#table");
+
+ //在表格内容渲染完成后回调的事件
+ table.on('post-body.bs.table', function (e, settings, json, xhr) {
+ $(".btn-editone", this)
+ .off("click")
+ .removeClass("btn-editone")
+ .addClass("btn-addtabs")
+ .prop("title", __('Edit'));
+ });
+ //当双击单元格时
+ table.on('dbl-click-row.bs.table', function (e, row, element, field) {
+ $(".btn-addtabs", element).trigger("click");
+ });
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'weigh',
+ searchFormVisible: Fast.api.query("model_id") ? true : false,
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id'), sortable: true},
+ {
+ field: 'model_id',
+ title: __('Model_id'),
+ visible: false,
+ addclass: 'selectpage',
+ extend: 'data-source="cms/modelx/index"',
+ formatter: Table.api.formatter.search
+ },
+ {
+ field: 'channel_id',
+ title: __('Channel_id'),
+ visible: false,
+ addclass: 'selectpage',
+ extend: 'data-source="cms/channel/index"',
+ formatter: Table.api.formatter.search
+ },
+ {
+ field: 'channel.name',
+ title: __('Channel'),
+ operate: false,
+ formatter: function (value, row, index) {
+ return '' + value + ' ';
+ }
+ },
+ {
+ field: 'title', title: __('Title'), align: 'left', formatter: function (value, row, index) {
+ return '' + value + '
' + Table.api.formatter.flag.call(this, row['flag'], row, index);
+ }
+ },
+ {field: 'image', title: __('Image'), operate: false, formatter: Table.api.formatter.image},
+ {field: 'views', title: __('Views'), operate: 'BETWEEN', sortable: true},
+ {field: 'comments', title: __('Comments'), operate: 'BETWEEN', sortable: true},
+ {field: 'weigh', title: __('Weigh'), operate: false},
+ {
+ field: 'url', title: __('Url'), operate: false, formatter: function (value, row, index) {
+ return ' ';
+ }
+ },
+ {
+ field: 'createtime',
+ title: __('Createtime'),
+ visible: false,
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'updatetime',
+ title: __('Updatetime'),
+ sortable: true,
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {field: 'status', title: __('Status'), operate: false, formatter: Table.api.formatter.status},
+ {
+ field: 'operate',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+
+ $(document).on("click", "a.btn-channel", function () {
+ $("#archivespanel").toggleClass("col-md-9", $("#channelbar").hasClass("hidden"));
+ $("#channelbar").toggleClass("hidden");
+ });
+
+ require(['jstree'], function () {
+ //全选和展开
+ $(document).on("click", "#checkall", function () {
+ $("#channeltree").jstree($(this).prop("checked") ? "check_all" : "uncheck_all");
+ });
+ $(document).on("click", "#expandall", function () {
+ $("#channeltree").jstree($(this).prop("checked") ? "open_all" : "close_all");
+ });
+ $('#channeltree').on("changed.jstree", function (e, data) {
+ console.log(data);
+ console.log(data.selected);
+ var options = table.bootstrapTable('getOptions');
+ options.pageNumber = 1;
+ options.queryParams = function (params) {
+ params.filter = JSON.stringify(data.selected.length > 0 ? {channel_id: data.selected.join(",")} : {});
+ params.op = JSON.stringify(data.selected.length > 0 ? {channel_id: 'in'} : {});
+ return params;
+ };
+ table.bootstrapTable('refresh', {});
+ return false;
+ });
+ $('#channeltree').jstree({
+ "themes": {
+ "stripes": true
+ },
+ "checkbox": {
+ "keep_selected_style": false,
+ },
+ "types": {
+ "channel": {
+ "icon": "fa fa-th",
+ },
+ "list": {
+ "icon": "fa fa-list",
+ },
+ "link": {
+ "icon": "fa fa-link",
+ },
+ "disabled": {
+ "check_node": false,
+ "uncheck_node": false
+ }
+ },
+ 'plugins': ["types", "checkbox"],
+ "core": {
+ "multiple": true,
+ 'check_callback': true,
+ "data": Config.channelList
+ }
+ });
+ });
+
+ $(document).on('click', '.btn-move', function () {
+ var ids = Table.api.selectedids(table);
+ Layer.open({
+ title: __('Move'),
+ content: Template("channeltpl", {}),
+ btn: [__('Move')],
+ yes: function (index, layero) {
+ var channel_id = $("select[name='channel']", layero).val();
+ if (channel_id == 0) {
+ Toastr.error(__('Please select channel'));
+ return;
+ }
+ Fast.api.ajax({
+ url: "cms/archives/move/ids/" + ids.join(","),
+ type: "post",
+ data: {channel_id: channel_id},
+ }, function () {
+ table.bootstrapTable('refresh', {});
+ Layer.close(index);
+ });
+ },
+ success: function (layero, index) {
+ }
+ });
+ });
+ },
+ content: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'cms/archives/content/model_id/' + Config.model_id,
+ add_url: '',
+ edit_url: 'cms/archives/edit',
+ del_url: 'cms/archives/del',
+ multi_url: '',
+ table: '',
+ }
+ });
+
+ var table = $("#table");
+ //在表格内容渲染完成后回调的事件
+ table.on('post-body.bs.table', function (e, settings, json, xhr) {
+ $(".btn-editone", this)
+ .off("click")
+ .removeClass("btn-editone")
+ .addClass("btn-addtabs")
+ .prop("title", __('Edit'));
+ });
+ //默认字段
+ var columns = [
+ {checkbox: true},
+ //这里因为涉及到关联多个表,因为用了两个字段来操作,一个隐藏,一个搜索
+ {field: 'main.id', title: __('Id'), visible: false},
+ {field: 'id', title: __('Id'), operate: false},
+ {field: 'channel_id', title: __('Channel_id'), formatter: Table.api.formatter.search},
+ {field: 'channel_name', title: __('Channel_name'), operate: false}
+ ];
+ //动态追加字段
+ $.each(Config.fields, function (i, j) {
+ var data = {field: j.field, title: j.title, operate: 'like'};
+ //如果是图片,加上formatter
+ if (j.type == 'image') {
+ data.formatter = Table.api.formatter.image;
+ } else if (j.type == 'images') {
+ data.formatter = Table.api.formatter.images;
+ } else if (j.type == 'radio' || j.type == 'check' || j.type == 'select' || j.type == 'selects') {
+ data.formatter = Controller.api.formatter.content;
+ data.extend = j.content;
+ }
+ columns.push(data);
+ });
+ //追加操作字段
+ columns.push({
+ field: 'operate',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ formatter: Table.api.formatter.operate
+ });
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: columns
+ })
+ ;
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'cms/archives/recyclebin',
+ pk: 'id',
+ sortName: 'weigh',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'title', title: __('Title'), align: 'left'},
+ {field: 'image', title: __('Image'), operate: false, formatter: Table.api.formatter.image},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'cms/archives/restore'
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'cms/archives/destroy'
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+
+ $(document).on('click', '.btn-destroyall', function () {
+ var that = this;
+ Layer.confirm(__('Are you sure you want to truncate?'), function () {
+ Fast.api.ajax($(that).attr("href"), function () {
+ Layer.closeAll();
+ table.bootstrapTable('refresh');
+ }, function () {
+ Layer.closeAll();
+ });
+ });
+ return false;
+ });
+ $(document).on('click', '.btn-restoreall,.btn-restoreit,.btn-destroyit', function () {
+ Fast.api.ajax($(this).attr("href"), function () {
+ table.bootstrapTable('refresh');
+ });
+ return false;
+ });
+ },
+ add: function () {
+ $(document).on('change', '#c-channel_id', function () {
+ Fast.api.ajax({
+ url: 'cms/archives/get_channel_fields',
+ data: {channel_id: $(this).val()}
+ }, function (data) {
+ $("#extend").html(data.html);
+ Form.api.bindevent($("#extend"));
+ return false;
+ });
+ localStorage.setItem('last_channel_id', $(this).val());
+ });
+ var last_channel_id = localStorage.getItem('last_channel_id');
+ if (last_channel_id) {
+ $("#c-channel_id option[value='" + last_channel_id + "']").prop("selected", true);
+ }
+ $("#c-channel_id").trigger("change");
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ Fast.api.ajax({
+ url: 'cms/archives/get_channel_fields',
+ data: {channel_id: $("#c-channel_id").val(), archives_id: $("#archive-id").val()}
+ }, function (data) {
+ $("#extend").html(data.html);
+ Form.api.bindevent($("#extend"));
+ return false;
+ });
+ },
+ api: {
+ formatter: {
+ content: function (value, row, index) {
+ var extend = this.extend;
+ if (!value) {
+ return '';
+ }
+ var valueArr = value.toString().split(/,/);
+ var result = [];
+ $.each(valueArr, function (i, j) {
+ result.push(typeof extend[j] !== 'undefined' ? extend[j] : j);
+ });
+ return result.join(',');
+ }
+ },
+ bindevent: function () {
+ $.validator.config({
+ rules: {
+ diyname: function (element) {
+ if (element.value.toString().match(/^\d+$/)) {
+ return __('Can not be digital');
+ }
+ return $.ajax({
+ url: 'cms/archives/check_element_available',
+ type: 'POST',
+ data: {id: $("#archive-id").val(), name: element.name, value: element.value},
+ dataType: 'json'
+ });
+ }
+ }
+ });
+ Form.api.bindevent($("form[role=form]"), function () {
+ var obj = top.window.$("ul.nav-addtabs li.active");
+ top.window.Toastr.success(__('Operation completed'));
+ top.window.$(".sidebar-menu a[url$='/cms/archives'][addtabs]").click();
+ top.window.$(".sidebar-menu a[url$='/cms/archives'][addtabs]").dblclick();
+ obj.find(".fa-remove").trigger("click");
+ });
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/cms/block.js b/public/assets/js/backend/cms/block.js
new file mode 100644
index 0000000000000000000000000000000000000000..168f2b831662f1e264b14a225005d559cd49bc31
--- /dev/null
+++ b/public/assets/js/backend/cms/block.js
@@ -0,0 +1,57 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'cms/block/index',
+ add_url: 'cms/block/add',
+ edit_url: 'cms/block/edit',
+ del_url: 'cms/block/del',
+ multi_url: 'cms/block/multi',
+ table: 'block',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', sortable: true, title: __('Id')},
+ {field: 'type', title: __('Type'), formatter:Table.api.formatter.search},
+ {field: 'name', title: __('Name')},
+ {field: 'title', title: __('Title')},
+ {field: 'image', title: __('Image'), formatter: Table.api.formatter.image},
+ {field: 'url', title: __('Url'), formatter: Table.api.formatter.url},
+ {field: 'createtime', title: __('Createtime'), sortable: true, operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), sortable: true, operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'status', title: __('Status'), formatter: Table.api.formatter.status},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/cms/channel.js b/public/assets/js/backend/cms/channel.js
new file mode 100644
index 0000000000000000000000000000000000000000..06d3d925afefb8afde16a38c574d578b4a6316ab
--- /dev/null
+++ b/public/assets/js/backend/cms/channel.js
@@ -0,0 +1,164 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'cms/channel/index',
+ add_url: 'cms/channel/add',
+ edit_url: 'cms/channel/edit',
+ del_url: 'cms/channel/del',
+ multi_url: 'cms/channel/multi',
+ dragsort_url: '',
+ table: 'channel',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'weigh',
+ pagination: false,
+ escape: false,
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {
+ field: 'type',
+ title: __('Type'),
+ custom: {channel: 'info', list: 'success', link: 'primary'},
+ formatter: Table.api.formatter.flag
+ },
+ {field: 'model_name', title: __('Model_name'), operate: false},
+ {field: 'name', title: __('Name'), align: 'left'},
+ {
+ field: 'url', title: __('Url'), formatter: function (value, row, index) {
+ return ' ';
+ }
+ },
+ {field: 'items', sortable: true, title: __('Items')},
+ {
+ field: 'weigh',
+ sortable: true,
+ title: __('Weigh'),
+ formatter: function (value, row, index) {
+ return ' ';
+ }
+ },
+ {
+ field: 'createtime',
+ title: __('Createtime'),
+ visible: false,
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'updatetime',
+ title: __('Updatetime'),
+ visible: false,
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {field: 'status', title: __('Status'), formatter: Table.api.formatter.status},
+ {
+ field: 'operate',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ],
+ search: false,
+ commonSearch: false
+ });
+
+ $(document).on("change", ".text-weigh", function () {
+ $(this).data("params", {weigh: $(this).val()});
+ Table.api.multi('', [$(this).data("id")], table, this);
+ return false;
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ $("input[name='row[type]']:first").trigger("click");
+ $("select[name='row[model_id]']").trigger("change");
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ $("input[name='row[type]']:checked").trigger("fa.event.typeupdated", "edit");
+ },
+ api: {
+ bindevent: function () {
+ $.validator.config({
+ rules: {
+ single: function (element) {
+ return !$("#c-name").val().match(/\n/);
+ },
+ channelname: function (element) {
+ if (element.value.toString().match(/^\d+$/)) {
+ return __('Can not be digital');
+ }
+ return $.ajax({
+ url: 'cms/channel/check_element_available',
+ type: 'POST',
+ data: {id: $("#c-name").val(), name: element.name, value: element.value},
+ dataType: 'json'
+ });
+ },
+ diyname: function (element) {
+ if (element.value.toString().match(/^\d+$/)) {
+ return __('Can not be digital');
+ }
+ return $.ajax({
+ url: 'cms/channel/check_element_available',
+ type: 'POST',
+ data: {id: $("#channel-id").val(), name: element.name, value: element.value},
+ dataType: 'json'
+ });
+ }
+ }
+ });
+ //不可见的元素不验证
+ $("form[role=form]").data("validator-options", {ignore: ':hidden'});
+ $(document).on("click fa.event.typeupdated", "input[name='row[type]']", function (e, ref) {
+ $(".tf").addClass("hidden");
+ $(".tf.tf-" + $(this).val()).removeClass("hidden");
+ if (typeof ref == 'undefined') {
+ $("select[name='row[model_id]']").trigger("change");
+ }
+ if ($(this).val() == 'link') {
+ $("#parent_id option[data-model]").prop("disabled", false);
+ }
+ });
+ Form.api.bindevent($("form[role=form]"));
+ $(document).on("change", "select[name='row[model_id]']", function () {
+ var parentChannel = $("#parent_id");
+ $("option[value=0]", parentChannel).prop("selected", true);
+ $("option[data-model]", parentChannel).prop("disabled", true);
+ $("option[data-model='" + $(this).val() + "']", parentChannel).prop("disabled", false);
+ var data = $("option:selected", this).data();
+ var type = $("input[name='row[type]']:checked").val();
+ if (type == 'channel') {
+ $("input[name='row[channeltpl]']").val(data.channeltpl);
+ } else if (type == 'list') {
+ $("input[name='row[listtpl]']").val(data.listtpl);
+ $("input[name='row[showtpl]']").val(data.showtpl);
+ }
+ });
+
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/cms/comment.js b/public/assets/js/backend/cms/comment.js
new file mode 100644
index 0000000000000000000000000000000000000000..53d92cfd3f6b1ce1fc66f50bc1f72dafb0fd2ef0
--- /dev/null
+++ b/public/assets/js/backend/cms/comment.js
@@ -0,0 +1,62 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'cms/comment/index',
+ add_url: 'cms/comment/add',
+ edit_url: 'cms/comment/edit',
+ del_url: 'cms/comment/del',
+ multi_url: 'cms/comment/multi',
+ table: 'comment',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', sortable: true, title: __('Id')},
+ {field: 'type', title: __('Type'), visible: false, searchList: {"archives": __('archives'), "page": __('page')}},
+ {field: 'type_text', title: __('Type'), operate: false},
+ {field: 'aid', sortable: true, title: __('Aid'), formatter: Table.api.formatter.search},
+ {field: 'pid', sortable: true, title: __('Pid'), formatter: Table.api.formatter.search, visible: false},
+ {field: 'user_id', sortable: true, title: __('User_id'), formatter: Table.api.formatter.search},
+ {field: 'archives.title', title: __('Title'), operate: false},
+ {field: 'comments', sortable: true, title: __('Comments')},
+ {field: 'ip', title: __('Ip'), formatter: Table.api.formatter.search},
+ {field: 'useragent', title: __('Useragent'), visible: false},
+ {field: 'subscribe', sortable: true, title: __('Subscribe'), visible: false},
+ {field: 'createtime', sortable: true, title: __('Createtime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', sortable: true, title: __('Updatetime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'status', title: __('Status'), searchList: {"normal": __('normal'), "hidden": __('hidden')}, formatter: Table.api.formatter.status},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/cms/fields.js b/public/assets/js/backend/cms/fields.js
new file mode 100644
index 0000000000000000000000000000000000000000..c9207857df67cc601375cf5c300dcaedb861ff7b
--- /dev/null
+++ b/public/assets/js/backend/cms/fields.js
@@ -0,0 +1,65 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'cms/fields/index/model_id/' + Config.model_id,
+ add_url: 'cms/fields/add/model_id/' + Config.model_id,
+ edit_url: 'cms/fields/edit/model_id/' + Config.model_id,
+ del_url: 'cms/fields/del/model_id/' + Config.model_id,
+ multi_url: 'cms/fields/multi/model_id/' + Config.model_id,
+ table: 'fields',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'weigh',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', sortable: true, title: __('Id')},
+ {field: 'model_id', visible: false, operate: false, title: __('Model_id')},
+ {field: 'name', title: __('Name')},
+ {field: 'type', title: __('Type')},
+ {field: 'title', title: __('Title')},
+ {field: 'weigh', title: __('Weigh'), visible: false},
+ {field: 'createtime', title: __('Createtime'), visible: false, operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), visible: false, operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'status', title: __('Status'), formatter: Table.api.formatter.status},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ],
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ //不可见的元素不验证
+ $("form#add-form").data("validator-options", {ignore: ':hidden'});
+ $(document).on("change", "#c-type", function () {
+ $(".tf").addClass("hidden");
+ $(".tf.tf-" + $(this).val()).removeClass("hidden");
+
+ });
+ Form.api.bindevent($("form[role=form]"));
+ $("#c-type").trigger("change");
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/cms/modelx.js b/public/assets/js/backend/cms/modelx.js
new file mode 100644
index 0000000000000000000000000000000000000000..a8df73d77d2957be650602629e5ec34825913819
--- /dev/null
+++ b/public/assets/js/backend/cms/modelx.js
@@ -0,0 +1,103 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'cms/modelx/index',
+ add_url: 'cms/modelx/add',
+ edit_url: 'cms/modelx/edit',
+ del_url: 'cms/modelx/del',
+ multi_url: 'cms/modelx/multi',
+ table: 'model',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name')},
+ {field: 'table', title: __('Table')},
+ {field: 'channeltpl', title: __('Channeltpl')},
+ {field: 'listtpl', title: __('Listtpl')},
+ {field: 'showtpl', title: __('Showtpl')},
+ {
+ field: 'createtime',
+ sortable: true,
+ title: __('Createtime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'updatetime',
+ sortable: true,
+ title: __('Updatetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'datalist', title: __('Operate'), table: table,
+ buttons: [
+ {
+ name: 'index',
+ text: __('Main list'),
+ classname: 'btn btn-xs btn-success btn-addtabs',
+ icon: 'fa fa-file',
+ url: 'cms/archives/index?model_id={ids}'
+ },
+ {
+ name: 'content',
+ text: __('Addon list'),
+ classname: 'btn btn-xs btn-success btn-addtabs',
+ icon: 'fa fa-file',
+ url: 'cms/archives/content/model_id/{ids}'
+ },
+ {
+ name: 'fields',
+ text: __('Fields'),
+ classname: 'btn btn-xs btn-info btn-fields btn-addtabs',
+ icon: 'fa fa-list',
+ url: 'cms/fields/index/model_id/{ids}'
+ },
+ ],
+ formatter: Table.api.formatter.buttons
+ },
+ {
+ field: 'operate',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/cms/page.js b/public/assets/js/backend/cms/page.js
new file mode 100644
index 0000000000000000000000000000000000000000..455fe87effa79fbb52fabdcbbc812d14fdccc9d4
--- /dev/null
+++ b/public/assets/js/backend/cms/page.js
@@ -0,0 +1,61 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'cms/page/index',
+ add_url: 'cms/page/add',
+ edit_url: 'cms/page/edit',
+ del_url: 'cms/page/del',
+ multi_url: 'cms/page/multi',
+ table: 'page',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'weigh',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', sortable: true, title: __('Id')},
+ {field: 'title', title: __('Title')},
+ {field: 'flag', title: __('Flag'), formatter: Table.api.formatter.flag},
+ {field: 'image', title: __('Image'), formatter: Table.api.formatter.image},
+ {field: 'views', sortable: true, title: __('Views'), operate: 'BETWEEN'},
+ {field: 'comments', sortable: true, title: __('Comments'), operate: 'BETWEEN'},
+ {field: 'url', title: __('Url'), formatter: function(value, row, index){
+ return ' ';
+ }},
+ {field: 'createtime', sortable: true, title: __('Createtime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', sortable: true, title: __('Updatetime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'weigh', sortable: true, title: __('Weigh')},
+ {field: 'status', title: __('Status'), formatter: Table.api.formatter.status},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/cms/tags.js b/public/assets/js/backend/cms/tags.js
new file mode 100644
index 0000000000000000000000000000000000000000..db949caef27d58f3e61ac95ed36cb03783212c2d
--- /dev/null
+++ b/public/assets/js/backend/cms/tags.js
@@ -0,0 +1,54 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'cms/tags/index',
+ add_url: 'cms/tags/add',
+ edit_url: '',
+ del_url: 'cms/tags/del',
+ multi_url: 'cms/tags/multi',
+ table: 'tags',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', sortable: true, title: __('Id')},
+ {field: 'name', sortable: true, title: __('Name')},
+ {field: 'nums', sortable: true, title: __('Nums')},
+ {field: 'url', title: __('Url'), formatter: function(value, row, index){
+ return ' ';
+ }},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
+
+ -
+
+ {$comment.user.nickname}
+ {$comment.createtime|human_date} 回复TA
+
+
+
+
+ {/cms:commentlist} +{$comment.content}
+